Using electron to show value on touch bar slider - node.js

I would like to show the value from the TouchBarSlider according to where I move it to. An example example of TouchBar can be followed here. I still cannot figure out how to display the value using their given method change from TouchBarSlider.
My current main.js looks like the following.
const {app, BrowserWindow, TouchBar} = require('electron')
const {TouchBarLabel, TouchBarSlider} = TouchBar
const slider = new TouchBarSlider({label: 'angle',
minValue: 0,
maxValue: 360})
const result = new TouchBarLabel()
result.label = '30' + ' deg';
const updateBar = () => {
let timeout = 100;
if (slider.change()){
result.label = slider.values.toString() + ' deg'
}
setTimeout(updateBar, timeout)
}
const touchBar = new TouchBar([
slider, // add slider
result // add display for slider value but doesn't work yet
])
let window;
app.once('ready', () => {
window = new BrowserWindow({
width: 300,
height: 200
});
window.loadURL('about:blank')
window.setTouchBar(touchBar);
})
// Quit when all windows are closed and no other one is listening to this.
app.on('window-all-closed', () => {
app.quit();
});
I also have example repository here. You can just replace my given main.js in the project in order to try things out. My electron version is 1.6.4 and node version is 7.4.0

const { app, BrowserWindow, TouchBar } = require('electron');
const path = require('path')
const url = require('url')
const {TouchBarButton, TouchBarLabel, TouchBarSlider} = TouchBar
const result = new TouchBarLabel();
result.label = '30' + ' deg';
const slider = new TouchBarSlider({
label: 'angle',
minValue: 0,
maxValue: 360,
change: (val) => result.label = val.toString() + ' deg' // register event handler here!
});
const touchBar = new TouchBar([
slider, // add slider
result // add display for slider value
]);
let window;
app.once('ready', () => {
window = new BrowserWindow({
width: 300,
height: 200
});
window.loadURL('about:blank');
window.setTouchBar(touchBar);
});
// Quit when all windows are closed and no other one is listening to this.
app.on('window-all-closed', () => {
app.quit();
});
Working code. Hope this helps! ;)

Related

Discord Node js Canvas Error: Unsupported image type

I have been trying to fix this thing for over a week now, searching in google and youtube for this damn error and no solution have been found. I know Im at first days of node js so my code might be not perfect, but the canvas one were taken from people that did tutorials and I have try as many of them but the result is always the same error no matter what. Apparently the error going away if I remove every related displayAvatarURL code, which sucks because I can't use the user avatar in my welcome image. I have try to change formats, changing code, changing background image with a black one made with Gimp (not that matter because the problem seem is avatar)and removed background to check again. Nothing work. The bot will crash ALWAYS as soon a real user join probably because the avatar image and it DOESN'T crash when invite a bot for testing (because it doesnt have custom avatars apparently?). Thank you for the help.
Error:
node:events:505
throw er; // Unhandled 'error' event
^
Error: Unsupported image type
at setSource (C:**\Desktop\lolinya_bot_js\node_modules\canvas\lib\image.js:91:13)
at C:**\Desktop\lolinya_bot_js\node_modules\canvas\lib\image.js:59:11
at C:**\Desktop\lolinya_bot_js\node_modules\simple-get\index.js:97:7
at IncomingMessage. (C:**\Desktop\lolinya_bot_js\node_modules\simple-concat\index.js:88:13)
at Object.onceWrapper (node:events:641:28)
at IncomingMessage.emit (node:events:539:35)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
Emitted 'error' event on Client instance at:
at emitUnhandledRejectionOrErr (node:events:384:10)
at processTicksAndRejections (node:internal/process/task_queues:85:21)
Index.js:
const {
Client,
GatewayIntentBits,
Routes,
// InteractionType,
} = require('discord.js');
const Discord = require('discord.js');
const { REST } = require('#discordjs/rest');
const fs = require('node:fs');
// const { Console } = require('node:console');
const generateImage = require('../generateImage.js');
dotenv.config();
// - CONFIG TOKEN, CLIENT AND GUILD ID
const TOKEN = process.env.TOKEN;
const CLIENT_ID = process.env.CLIENT_ID;
const GUILD_ID = process.env.GUILD_ID;
const WELCOME_ID = process.env.WELCOME_ID;
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
],
});
// - CONFIG SLASH COMMANDS -
const commands = [];
const commandFiles = fs.readdirSync('./src/commands')
.filter(file => file.endsWith('js'));
client.slashcommands = new Discord.Collection();
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.slashcommands.set(command.data.name, command);
commands.push(command.data.toJSON());
}
const rest = new REST({ version: '10' }).setToken(TOKEN);
// - CLIENT EMITTERS -
client.on('ready', () => {
console.log(`${client.user.tag} has logged in.`);
});
client.on('guildMemberAdd', async (member) => {
const img = await generateImage(member);
member.guild.channels.cache.get(WELCOME_ID).send({
content: `<#${member.id}> Welcome to the server!`,
files: [img]
});
});
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
const slashcmd = client.slashcommands.get(interaction.commandName);
await slashcmd.run({ client, interaction });
});
// - INITIALIZE THE BOT AND ALSO REFRESH SLASH COMMANDS LIST -
(async () => {
try {
console.log('Started refreshing application (/) commands.');
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), {
body: commands,
});
console.log('Successfully reloaded application (/) commands.');
client.login(TOKEN);
} catch (err) {
console.error(err);
}
})();
generateImage.js:
const { createCanvas, loadImage, registerFont } = require('canvas');
registerFont('./font/Cat paw.ttf', {family: 'neko'});
const Discord = require('discord.js');
const { AttachmentBuilder } = require('discord.js');
const background = "https://i.imgur.com/VZblp7S.jpg";
const dim = {
height: 675,
width: 1200,
margin: 50,
}
const av = {
size: 256,
x: 480,
y: 170,
}
const generateImage = async (member) => {
let canvas = await createCanvas(dim.width, dim.height);
let ctx = await canvas.getContext('2d');
let username = member.user.username;
let discrim = member.user.discriminator;
// let avatarURL = member.displayAvatarURL({format: 'jpg', dynamic: true, size: av.size})
// Draw the canvas for our image
// const canvas = Canvas.createCanvas(dim.width, dim.height);
// const ctx = canvas.getContext('2d');
const backimg = await loadImage(background);
let x = 0 //canvas.width / 2 - backimg.width / 2;
let y = 0 //canvas.height / 2 - backimg.height / 2;
ctx.drawImage(backimg, x, y);
// Draw a semi-transparent box for text readability
ctx.fillStyle = "rgba(0,0,0,0.7)"
ctx.fillRect(
dim.margin,
dim.margin,
dim.width - 2 * dim.margin,
dim.height - 2 * dim.margin
); //fillRect(posX,posY, width, height)
ctx.save();
ctx.beginPath();
ctx.arc(
av.x + av.size / 2,
av.y + av.size / 2,
av.size / 2, 0,
Math.PI * 2,
false
); //arc(centerX, centerY, radius, startAngle, endAngle, clockwise)
ctx.clip();
let avimg = await loadImage(member.displayAvatarURL({ format: 'png' }));
ctx.drawImage(avimg, av.x, av.y);
ctx.restore();
// Config our welcome text
ctx.fillStyle = 'pink';
ctx.textAlign = 'center';
// Draw the welcome text
ctx.font = '80px Cat paw';
ctx.fillText("Welcome to the Server", dim.width / 2, dim.margin + 70)
// Draw the username text
ctx.font = '100px Cat paw';
ctx.fillText(`${username} #${discrim}`, dim.width / 2, dim.height - dim.margin - 125);
// Draw the server name text
ctx.font = '40px Cat paw';
ctx.fillText(`You are the member #${member.guild.memberCount}!`, dim.width / 2, dim.height - dim.margin - 50);
let attachment = new AttachmentBuilder(canvas.toBuffer(), { name: 'welcome.png' })
return attachment;
}
module.exports = generateImage ```
If you get the unsupported image type error with the avatar URL -> On discord.js v14 format was replaced with extension so you'll have to change that
I have the same issue, it comes from the fact that
member.displayAvatarURL({ format: 'png' })
returns a .webp instead of returning a .png. It's strange, maybe it's bug from Discord.js v14.
I have found an ugly fix:
let avimg = await loadImage("https://cdn.discordapp.com/avatars/" + member.id + "/" > + member.avatar + ".png");

Election JS Close one window and open new window

I am new to electron js. I have a scenario to show a loading/splash screen and then show the login screen.
here is my main.js
// necessary modules for electron application
// importing electron
const { create } = require("domain");
const electron = require("electron");
// initilizing app
const app = electron.app;
// adding window to view
const BrowserWindow = electron.BrowserWindow;
// path module to build file path
const path = require("path")
// to make sure we are using a proper url
const url = require("url")
let {ipcMain} = electron
let toQuit = true; // important to quit
let category = 'main_window' // default window
let win;
app.on("ready", ()=>{
"use strict";
createWindow();
});
app.on("closed", () => {
"use strict";
win = null;
})
app.on('window-all-closed',()=>{
"use strict";
if(process.platform !== 'darwin'){
app.quit();
}
})
app.on("activate", () => {
if (win === null) {
createWindow();
}
});
function createWindow() {
"use strict";
var height;
var width;
var address;
var frame;
var removeMenu;
var title, backgroundColor;
switch (category) {
case "main_window":
height = 200; //Initialize size of BrowserWindow
width = 500; //Initialize size of BrowserWindow
frame = false;
removeMenu = true;
backgroundColor = "#ccc";
address = "Views/SplashScreen/index.html"; //Initialize the address or the file location of your HTML
break;
case "login":
height = 600; //Initialize size of BrowserWindow
width = 400; //Initialize size of BrowserWindow
frame = true;
removeMenu = true;
title = "Login"
address = "Views/Login/index.html"; //Initialize the address or the file location of your HTML
break;
default:
break;
}
win = new BrowserWindow({
height: height, //height and width of BrowserWindow
width: width, //height and width of BrowserWindow
minHeight: height, //minimum height and width of BrowserWindow, you can remove this if you want
minWidth: width, //minimum height and width of BrowserWindow, you can remove this if you want
frame: frame,
backgroundColor: backgroundColor,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true,
},
});
win.loadURL(
url.format({
pathname: path.join(__dirname, address),
protocol: "file",
slashes: true,
})
);
// enabling web dev tools
win.webContents.openDevTools({
mode: "detach",
});
// remove default top menu
win.removeMenu(removeMenu);
win.on("ready-to-show", () => {
win.show();
win.focus();
});
win.on("closed", (e) => {
e.preventDefault(); //We have to prevent the closed event from doing it.
if (toQuit) {
console.log("I am called")
//if the value of toQuit is true, then we want to quit the entire application
win = null;
app.exit(); //quit or exit the entire application
} else {
console.log("hide called");
win.hide(); //just hide the BrowserWindow and don't quit the entire application
toQuit = true; //reset the value of toQuit to true
}
});
}
//call this function from your any Javascript
ipcMain.on('createBrowserWindow', function (e, cat) {
"use strict";
category = cat; //get the category of window on which we want to show
toQuit = false; //set the value to false, meaning we don't want to close the entire application but just hide the current BrowserWindow
createWindow(); //call this function over and over again
});
and the splashscreen.js
const ipcRender = require('electron').ipcRenderer;
let count = 1;
let porgressBar = document.getElementById("progressbar");
let i = 70;
let interval = setInterval(()=>{
if(i >= 400){
clearInterval(interval);
ipcRender.send("createBrowserWindow", "login");
}
porgressBar.style.width = i + "px";
ran = Math.floor(Math.random() * (75 - 0 + 1)) + 0;
console.log(ran);
i = i+ran
},500);
Till now what I achieved is that, I am able to open the new window but the previous window is unable to close. I have tried several methods from stack overflow solutions but none of them worked.
package.json
{
"name": "electron-sms",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "electron ."
},
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "^17.1.2"
},
"dependencies": {
"#electron/remote": "^2.0.8"
}
}
Any workaround, please.
Thanks
I have found a solution to my problem.
In Electron Version >= 16
Install the #electron-remote using npm npm i #electron/remote. as remote has been removed in electron Version 14 and later.
secondly, Add the initialize electron-remote using this require("#electron/remote/main").initialize();
Example
const electron = require("electron");
// initilizing app
const app = electron.app;
// adding window to view
const BrowserWindow = electron.BrowserWindow;
// path module to build file path
const path = require("path")
// to make sure we are using a proper url
const url = require("url")
**require("#electron/remote/main").initialize();**
let {ipcMain} = electron
let toQuit = true; // important to quit
let category = 'main_window' // default window
enable webcontents in main.js
require("#electron/remote/main").enable(win.webContents);
in your renderer,js call it as
require("#electron/remote").getCurrentWindow().close();
You are done!
Happy Coding :)

How do I change the style when feature is modifying and not stop the modify

I want to change the style when the feature is modifying, but once the feature's style has been setting, its modify would be stopped, how can I change the style and it still can modify?
here is the code:
this.modify.on(['modifystart', 'modifyend'], function (evt) {
target.style.cursor = evt.type === 'modifystart' ? 'grabbing' : 'pointer'
const currentFeature = evt.features.array_[0]
const oldStyle = currentFeature.getStyle()
console.log(oldStyle)
console.log(evt.type)
if (evt.type === 'modifystart') {
const moveImage = new Image()
const pinInfo = evt.features.array_[0].get('pinInfo')
moveImage.src = that.moveIcon
moveImage.width = 50
moveImage.height = 70
moveImage.onload = function () {
const iconCanvas = document.createElement('canvas')
iconCanvas.width = moveImage.width
iconCanvas.height = moveImage.height
const iconCanvasCtx = iconCanvas.getContext('2d')
// 背景アイコンを描画
iconCanvasCtx.drawImage(moveImage, 0, -25, 50, 70)
const style = new Style({
image: new Icon({
anchor: [0.5, 0.5],
img: iconCanvas,
imgSize: [moveImage.width, moveImage.height],
scale: that.imgSize / 30
})
})
// const arrayStyle = [style, oldStyle]
currentFeature.setStyle(style)
}
} else if (evt.type === 'modifyend') {
// currentFeature.setStyle(oldStyle)
}
})
Thanks a lot!

Adding image dynamically in public folder in reactjs

I am developing an face detection application,for that I need to collect the users image for reference to detect them later.i have successfully uploaded the image in MySQL databse.now I need upload the image in public folder in react to detect the image in camera.i stuck in uploading image in react public folder.help me out get rid of this problem..
This is the React code where image to be detected in the imgUrl variable
detect = async () => {
const videoTag = document.getElementById("videoTag");
const canvas = document.getElementById("myCanvas");
const displaySize = { width: videoTag.width, height: videoTag.height };
faceapi.matchDimensions(canvas, displaySize);
//setInterval starts here for continuous detection
time = setInterval(async () => {
let fullFaceDescriptions = await faceapi
.detectAllFaces(videoTag)
.withFaceLandmarks()
.withFaceExpressions()
.withFaceDescriptors();
const value = fullFaceDescriptions.length;
this.setState({ detection: value });
fullFaceDescriptions = faceapi.resizeResults(
fullFaceDescriptions,
displaySize
);
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
//Label Images
var dummy = ["praveen", "vikranth", "Gokul", "Rahul"];
const labels = nameArray1;
// const labels = ["praveen", "vikranth", "Gokul", "Rahul"];
if (no_of_times <= 0) {
if (no_of_times === 0) {
labeledFaceDescriptors = await Promise.all(
labels.map(async (label) => {
// fetch image data from urls and convert blob to HTMLImage element
const imgUrl = `/img/${label}.png`; // for testing purpose
// const imgUrl = testImage;
const img = await faceapi.fetchImage(imgUrl);
const fullFaceDescription = await faceapi
.detectSingleFace(img)
.withFaceLandmarks()
.withFaceExpressions()
.withFaceDescriptor();
if (!fullFaceDescription) {
throw new Error(`no faces detected for ${label}`);
}
const faceDescriptors = [fullFaceDescription.descriptor];
return new faceapi.LabeledFaceDescriptors(label, faceDescriptors);
})
);
// console.log(no_of_times);
}
}
const maxDescriptorDistance = 0.7;
no_of_times++;
const faceMatcher = new faceapi.FaceMatcher(
labeledFaceDescriptors,
maxDescriptorDistance
);
const results = fullFaceDescriptions.map((fd) =>
faceMatcher.findBestMatch(fd.descriptor)
);
result = [];
results.forEach((bestMatch, i) => {
const box = fullFaceDescriptions[i].detection.box;
// console.log(box)
const text = bestMatch.toString(); //this for basMatch name detection
var str = "";
//This is for removing names confidence to map value without duplicate
var val = text.replace(/[0-9]/g, "");
for (let i of val) {
if (i !== " ") {
str += i;
} else {
break;
}
}
if (result.includes(str) === false) result.push(str);
const drawBox = new faceapi.draw.DrawBox(box, { label: text });
drawBox.draw(canvas);
faceapi.draw.drawFaceExpressions(canvas, fullFaceDescriptions, 0.85);
});
for (let i = 0; i < fullFaceDescriptions.length; i++) {
const result1 = fullFaceDescriptions[i].expressions.asSortedArray()[i];
// console.log(result[i]);
// console.log(result1.expression);
this.test(result[i], result1.expression);
}
}, 100);
In the above code i am manually putting image in public folder,this need to be done dynamically when the user uploads image.
this is place i get the images in base64 from nodejs
axios.get("/image").then((res) => {
testImage = res.data;
// console.log("from image" + res.data);
imgback = <img src={`data:image/jpeg;base64,${res.data}`} />;
});
This is nodejs code for the get request from reactjs
app.get("/image", (req, res) => {
connection.query("SELECT * FROM images", (error, row, fields) => {
if (!!error) {
console.log("Error in the query");
} else {
console.log("successful query");
var buffer = new Buffer(row[0].image, "binary");
var bufferBase64 = buffer.toString("base64");
res.send(bufferBase64);
}
});
});
my goal is, in the imgUrl variable in react code i need to specify the image folder for that i need to dynamically add image in folder.
Or is there is any other way to directly give image array in the imgUrl variable.please help me to sort out this problem.

puppeteer await page.$$('.className'), but I get only the first 11 element with that class, why?

the code that I am using to scrape a student list:
let collection1 = await page.$$('div.layout-2DM8Md')
console.log("Student Online:")
for (let el of collection1) {
let name = await el.$eval(('div.name-uJV0GL'), node => node.innerText.trim());
console.log(name)
}
It's probably because the contents of rest of those elements are loaded dynamically with a Javascript framework like React or Vue. This means that it only gets loaded when those elements enter the viewport of the browser.
To fix this you will need to write a function that auto scrolls the page so that those elements can get into the viewport and then you have to wait for that function to finish before you collect the data.
The scrolling function:
const autoScroll = async(page) => {
await page.evaluate(async () => {
await new Promise((resolve, reject) => {
var totalHeight = 0;
var distance = 100;
var timer = setInterval(() => {
var scrollHeight = document.body.scrollHeight;
window.scrollBy(0, distance);
totalHeight += distance;
if(totalHeight >= scrollHeight){
clearInterval(timer);
resolve();
}
}, 30);
});
});
}
Then call this function after page.goto() and before you grab the content with page.content(). I also set the viewport width and height then the scrolling goes a little faster:
await page.goto(url, {waitUntil: 'load'});
await page.setViewport({
width: 1200,
height: 800
});
await autoScroll(page); // The scroll function
const html = await page.content()

Resources