ipcRenderer not receiving messages - javascript

I'm trying to send a message when the 'q' key is pressed from my index.js file to the script on index.html, but I don't really know why It's not working properly.
Here is my js file
const url = require('url');
const path = require('path');
const {app, BrowserWindow, globalShortcut, ipcMain, webContents} = require('electron');
let mainWindow;
app.on('ready', function(){
// Create new window
mainWindow = new BrowserWindow({
backgroundColor: '#000000',
fullscreen : true,
frame : false,
icon : __dirname + "/res/icon.jpg",
webPreferences: {
nodeIntegration : true
}
});
// Load html in window
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes:true
}))
globalShortcut.register('Esc', () => {
app.quit();
});
globalShortcut.register('q', () => {
leftLight();
});
});
function leftLight() {
mainWindow && mainWindow.webContents.send('key-pressed-q');
console.log("Sending q pressed to html...");
}
And the html
<!DOCTYPE html>
<html lang="en">
<meta name="viewport" content="width=device-width, initial-scale=1">
<head>
<link rel="stylesheet" href="styles.css">
<title>Document</title>
</head>
<body>
<div class = rect_green> <h2 class=blocktext >LEFT FENCER</h2></div>
<div class = rect_red><h2 class=blocktext> RIGHT FENCER</h2> </div>
<div class = crono> <h2 class=crontext>3:00</h2></div>
</body>
<script type="text/javascript">
var ipc = require('electron').ipcRenderer;
ipc.on('key-pressed-q', (e) => {
//var element = document.getElementsByClassName("rect_green");
//element.style["background-color"] = "yellow";
console.log("q pressed in html file");
});
</script>
</html>
The key pressed is detected, but the message is not received by the ipcRenderer. Any mistakes on my code?

It seems like you've got the syntax of .webContents.send( wrong.
You need to provide a channel for your message, E.g. .webContents.send('channel', 'msg'), then you listen for that channel in your page.
A channel can be whatever you want. For example:
Electron js file:
mainWindow.webContents.send('channelNameCanBeAnything', 'key-pressed-q');
Html file:
ipc.on('channelNameCanBeAnything', (msgStr) => {
console.log("q pressed in html file");
console.log(msgStr); // Will output 'key-pressed-q'.
});
See the docs

Related

firebase auth signInWithCustomToken method not working in iPhone

I am developing one PWA of the ionic capacitor and there is a requirement to load another website in an iframe so from one of the ionic app component I called another site.
iframe.page.html
<ion-header>
<ion-toolbar>
<ion-buttons slot="end" (click)="goBack()">
Close
<ion-icon slot="icon-only" name="close-outline"></ion-icon>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<iframe #iframe height="100%" width="100%" title="test"></iframe>
</ion-content>
iframe.page.ts
export class IframePage implements OnInit, AfterViewInit {
userId = localStorage.getItem('userId');
gameData: any;
gameUrl: any;
docId;
#ViewChild('iframe') iframe: ElementRef;
constructor(private navCtrl: NavController,
private authSrv: AuthService,
private commanSrv: CommannService,
private router:Router) {
firebase.analytics().logEvent('Web_game');
this.iframe.nativeElement.setAttribute('src', 'anotherdomain.com?UID=sadsajdhsakjhdasjhkjsd');
window.addEventListener('message', (event) => {
console.log(event.data);
if (event.data.res === 'win') {
// let routename = commanSrv.getLastRoute();
// navCtrl.navigateForward(routename || 'home_tab');
this.router.navigate(['arcade-outcome', { type: 'arcade_win' }]);
} else if (event.data.res === 'loss'){
this.router.navigate(['arcade-outcome', { type: 'arcade_lose' }]);
} else {
// if (event.data === 'closed') {
let routename = commanSrv.getLastRoute();
navCtrl.navigateBack(routename || 'home_tab');
// }
}
});
}
}
And now
another site is made up of HTML and javascript and here is code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="assets/icon/favicon.png" />
<link rel="stylesheet" type="text/css" href="./assets/css/custom.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.4.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.4.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.4.3/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.4.3/firebase-database.js"></script>
<script src="scripts/firebase.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
<title>HTML 5 game application</title>
</head>
<body>
<p>Loader screen</p>
<div class="loader"></div>
<script>
$(document).ready(function(){
const serverUrl = 'https://us-central1-domain.cloudfunctions.net/';
var token;
var xhttp = new XMLHttpRequest();
var gamePlayData;
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const userId = urlParams.get('UID')
const gamePlay = urlParams.get('gameplay')
const mode = urlParams.get('mode')
function getUserDetails(token) {
console.log("getUserDetails start token ", token);
console.log(firebase);
firebase.auth().signInWithCustomToken(token).then((userCredential) => { // execution stop from here.
console.log("getUserDetails end");
var user = userCredential.user;
if (user !== null) {
window.location.replace(`anotherdomain.com/start.html?id=${userId}&gamePlay=${gamePlay}`);
}
})
.catch((error) => {
console.log('error in catch: ', error);
var errorCode = error.code;
var errorMessage = error.message;
// window.history.back();
alert('User is not logged in.')
// parent.postMessage('closed', '*');
});
}
function checkAuth() {
console.log("ajax call start");
$.ajax({
type: "POST",
url: serverUrl + 'checkAuthStatus',
data: { uid: userId },
success: function (response) {
console.log("ajax call end");
//if request if made successfully then the response represent the data
getUserDetails(response.result);
},
error: function (err) {
console.log(err);
}
});
}
checkAuth();
});
</script>
From the line
firebase.auth().signInWithCustomToken(token).then(() => {
Execution cancelled and iframe got closed , window.addEventListener('message', (event) => { got called navigated to ionic application back.
The surprising is, this issue only occurs in iPhone whereas for android it is working fine.
When navigating to another domain site 3rd time then it working and got the success in firebase.auth().signInWithCustomToken(token).then((userCredential) => { .
Please help me.

CSS and Image not showing in rendered pdf using html-pdf-node

I am trying to generate html to pdf in Node.js using html-pdf-node package. The page is working fine if I open the html file in the browser but when I generate it to pdf using html-pdf-node, the images and the css is not rendered in the pdf.
Here is my code:
template.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type='text/css' href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" type='text/css' href="../css/style.css">
</head>
<body>
<div class="container">
<div class="text-center">
<img src="../images/logo.png" class="img-fluid" alt="Logo image">
</div>
<div class="container align-items-center atd-title text-center">
<h3>Title Here</h3>
</div>
<div class="container align-items-center atd-container">
<div class="row">
<div class="col-lg-12">
<p>Sir:</p>
<p class="atd-paragraph">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</div>
</div>
</div>
</div>
</body>
</html>
service.js
let fs = require('fs');
let path = require('path');
let ejs = require('ejs');
let html_to_pdf = require('html-pdf-node');
// Read HTML Template
let template = fs.readFileSync(path.resolve(__dirname, "../path/to/template.html"), 'utf8');
let html = ejs.render(template, {name: "test"});
let options = { format: 'A4' };
let file = { content: html };
let pdf = await html_to_pdf.generatePdf(file, options);
return pdf;
That's because the HTML string is being passed to html-pdf-node, the other assets like images and CSS are not. html-pdf-node uses Puppeteer as a headless browser to render the web page before saving it as PDF, when it tries to resolve the assets it sends HTTP requests that just fail.
You have two options to solve this:
Create a standalone HTML file with inline CSS and images as data URLs
Open a web server so that the assets can be resolved without being embedded
The simplest option is the second one, here is a minimal example:
const express = require('express')
const html_to_pdf = require('html-pdf-node')
const ejs = require('ejs')
const fs = require('fs')
const path = require('path')
const app = express()
const port = 3000
const template = fs.readFileSync(path.resolve(__dirname, "./index.html"), 'utf8')
const content = ejs.render(template, { title: "Awesome title!" })
fs.writeFile(path.resolve(__dirname, "./public/index.html"), content, () => {
app.use(express.static('src/public'))
const server = app.listen(port, async () => {
const url = `http://localhost:${port}`
const options = { format: 'A4', path: 'output.pdf' }
const file = { url }
await html_to_pdf.generatePdf(file, options)
server.close()
})
})
I've created a working project here: https://github.com/Guerric-P/html-pdf-node-demo

VIDEO CHAT REACT APP: Uncaught (in promise) TypeError: Cannot read property 'append' of null

I've tried reading through other similar questions but nothing that I've found seems to do the trick.
I keep receiving this error:
Uncaught (in promise) TypeError: Cannot read property 'append' of null
at addVideoStream (script.js:33)
at script.js:17
Chrome has asked me for camera and audio permission. To test what was wrong, I set myVideo.muted = false to see if it was also not receiving my audio but that seems to work.
I don't know how to make my video stream not be null. Please help.
Here is my entire script.js code:
const socket = io("/"); // connects to root path of our app
const videoGrid = document.getElementById("video-grid");
const myPeer = new Peer(undefined, {
host: "/",
port: "3001",
});
const myVideo = document.createElement("video");
myVideo.muted = true; // so we don't hear our own voice play back to us
navigator.mediaDevices
.getUserMedia({
video: true,
audio: true,
})
.then((stream) => {
addVideoStream(myVideo, stream);
});
myPeer.on("open", (id) => {
socket.emit("join-room", ROOM_ID, id);
});
socket.on("user-connected", (userId) => {
console.log("User connected: " + userId);
});
function addVideoStream(video, stream) {
video.srcObject = stream;
video.addEventListener("loadedmetadata", () => {
video.play();
});
videoGrid.append(video);
}
and my html code:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script>
const ROOM_ID = "<%= roomId %>";
</script>
<script
defer
src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js"
></script>
<script src="/socket.io/socket.io.js" defer></script>
<script src="script.js" defer></script>
<title>Document</title>
<style>
#video-grid {
display: grid;
grid-template-columns: repeat(auto-fill, 300px);
grid-auto-rows: 300px;
}
video {
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
</head>
<body>
<div id="#video-grid"></div>
</body>
</html>
Thanks for the help and patience, I'm new to this. I did my best trying to research but wasn't able to find anything as of now.
Your id attribute's value should be video-grid instead of #video-grid. Your error is due to a typo.

how to pass dynamic URL in manifest.json in PWA

I am using PWA to add to home screen task And I doing this in php. When I click "Add to home screen button" then script run. I made changes manifest.json according php as manifest.php. I am testing it on localhost by change https by ngrok.
I am trying to pass dynamic url in manifest file.
index.html is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="manifest" href="manifest.php">
<link rel="icon" href="favicon.ico" type="image/gif" sizes="16x16">
</head>
<body>
<h1>Hey!!</h1>
<div class="add-to">
<button class="add-to-btn">Add to home screen</button>
</div>
<script>
if ('serviceWorker' in navigator) {
console.log("Will the service worker register?");
navigator.serviceWorker.register('service-worker.js')
.then(function(reg){
console.log("Yes, it did.");
}).catch(function(err) {
console.log("No it didn't. This happened:", err)
});
}
let deferredPrompt;
var div = document.querySelector('.add-to');
var button = document.querySelector('.add-to-btn');
//div.style.display = 'none';
window.addEventListener('beforeinstallprompt', (e) => {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
div.style.display = 'block';
button.addEventListener('click', (e) => {
// hide our user interface that shows our A2HS button
//div.style.display = 'none';
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
});
});
</script>
</body>
</html>
manifest.php is:
<?php
$starturl = 'https://621b16b2b7c5.ngrok.io/add_to_home_screen4/images/icon192.PNG';
$manifest =
[
"short_name"=> "BetaPage",
"name"=> "BetaPage",
"theme_color"=> "#4A90E2",
"background_color"=> "#F7F8F9",
"display"=> "standalone",
"icons"=>
[
[
"src"=> "images/launcher-icon-1x.png",
"type"=> "image/png",
"sizes"=> "48x48"
],
[
"src"=> "images/launcher-icon-2x.png",
"type"=> "image/png",
"sizes"=> "96x96"
],
[
"src"=> "images/chat1.png",
"type"=> "image/png",
"sizes"=> "144x144"
],
[
"src"=> "images/icon192.png",
"type"=> "image/png",
"sizes"=> "192x192"
]
],
"start_url"=> $starturl
];
header('Content-Type: application/json');
echo json_encode($manifest);
When I reload the webpage then below error occur:
I have to press ctrl+F5 each time to run the code. Why?
I got my solution. MY service-worker.js file was not correct. Now I paste below code in service-worker.js and it wored.
self.addEventListener('fetch', function(event) {});

Mixpanel mock continuously comes back as undefined

I have a very basic static app that has business logic to redirect a user based on what element they click in the UI. I added Mixpanel, and track an event before the user is redirected. I'm trying to create tests using the Jest testing framework, but am having difficulties mocking the track method invocation on mixpanel.
The crux of the issue is I'm unable to mock mixpanel while running tests. I've read the Jest documentation and searched the community for answers, but every time I run tests, it fails with TypeError: Cannot read property 'track' of undefined. You'll have to forgive me if it is something obvious, JavaScript is not my native programming language, so when it comes time to build tests, I'm rusty at it. :)
index.html
<!doctype html>
<html class="no-js" lang="">
<head>
<!-- start Mixpanel -->
<script type="text/javascript">...Mixpanel script</script>
<script src="js/scripts.js"></script>
<script type="text/javascript">
const { sources } = window.parseSourcesFromURL(window.location.href)
const sourceObj = window.convertToObj(sources)
mixpanel.track("Page View", sourceObj)
</script>
<!-- end Mixpanel -->
</head>
<body>
<div>
<div class="age-links">
<button onClick=redirectFunc(true)>YES</button>
<button onClick=redirectFunc(false)>NO</button>
</div>
</div>
</body>
</html>
js/scripts.js
(function() {
const convertToObj = () => ...
const getTrackingData = () => ...
const parseSourcesFromURL = () => ...
const redirectFunc = (p) => {
const { sources, link1, link2 } = parseSourcesFromURL(window.location.href)
const redirect = `${p ? link1 : link2}?${sources.join('&')}`
const mixpanelTrackingData = getTrackingData(sources, p, redirect)
mixpanel.track('Button Clicked', mixpanelTrackingData, () => {
window.location.href = redirect;
})
}
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined')
module.exports = {
....
};
else
window.utmSourcesToObject = utmSourcesToObject;
window.parseReferrerForLinksAndUTM = parseReferrerForLinksAndUTM;
window.redirectBasedOnAge = redirectBasedOnAge;
})();
js/scripts.test.js
const { redirectFunc, parseSourcesFromURL } = require('./js/scripts')
const testURL = 'https://test.com/'
describe('parseReferrerForLinksAndUTM', () => {
beforeEach(() => {
global.window = Object.create(window)
Object.defineProperty(window, 'location', {
value: { href: testURL },
writable: true
})
### THIS DOESNT WORK ###
Object.defineProperty(window, 'mixpanel', {
track: jest.fn()
})
})
const { sources, link1, link2 } = parseSourcesFromURL(testURL)
test('redirect link is correct', () => {
### THIS DOESNT WORK ###
global.mixpanel = Object.create({})
global.mixpanel.track = jest.fn()
expect(link1).toBe('https://link1.com')
})
})

Categories