Issue with Safari and Service Worker Push Notification Opening Window

I’m adding push notifications to my React Web App and I’m having some issues with Safari. First here is the click event listener in my service worker js file (sw.js):

self.addEventListener('notificationclick', (event) => {
  const data = event.notification.data;
  const url = data.url || 'http://localhost:3356';

  console.log({ data, url });

  event.notification.close();

  event.waitUntil(
    self.clients
      .matchAll({
        type: 'window',
        includeUncontrolled: true,
      })
      .then((clientList) => {
        console.log('total clients: ', clientList.length);
        for (const client of clientList) {
          console.log({ clientUrl: client.url });
          if (client.url === url + '/' && 'focus' in client)
            return client.focus();
        }
        if (self.clients.openWindow) {
          console.log('Opening a new window', url);
          return self.clients.openWindow(url);
        }
        console.log('No clients to focus');
        return;
      })
      .catch((error) => console.log({ error }))
  );

This is mostly working fine specially in chrome. However the issue I’m having in Safari is that if the web app is not open in any window and/or tab when I click on the notification, safari does not open the web app I’m taken to the last active tab/window. If I have multiple tabs open and one of the tabs is the WebApp then Safari switches and focuses to the correct tab. But it seems that clients.openWindow is not working. the Log Message ‘Opening New Window’ does show up and no error logs shows up.

Any help would be greatly appreciated. Thanks

html2canvas 1.4.1 screenshot error element using background-image:data:image/svg+xml;base64,

I use the html2canvas library to capture screenshots by passing in a className and save the image file as a blob. However, when the image is saved or downloaded, there is an issue with elements that have background-image: url(data:image/svg+xml;base64,…) (SVG image), but PNG images are not affected. I am using html2canvas version 1.4.1.

  function captureImg(className) {
        const bannerElement = document.querySelector('.' + className);
        return html2canvas(bannerElement, {
            scale: 2,
            backgroundColor: null,
        }).then(canvas => {
            return new Promise((resolve, reject) => {
                canvas.toBlob(blob => {
                    if (blob) {
                        const file = new File([blob], 'banner-screenshot.png', {
                            type: 'image/png'
                        });
                        resolve(file);
                    } else {
                        reject(new Error('Failed to convert canvas to blob'));
                    }
                }, 'image/png');
            });
        }).finally(() => {

        }).catch(error => {
            console.error('Error capturing the banner:', error);
        });
    }

    function captureImgNow() {
        captureImg('basic-box').then(file => {
            const formData = new FormData();
            formData.append('file_img', file);
            formData.append('error_now', error_now);
            formData.append('user_learn_id', user_learn_id);
            formData.append('lesson_id', lesson_id);
            formData.append('detail_id', detail_id);
            formData.append('type', 'wrong');
            formData.append('max_error', max_error);
            $.ajax({
                url: '/save-user-note-exam-failed',
                method: 'POST',
                contentType: 'application/json',
                data: formData,
                contentType: false,
                processData: false,
                cache: false,
                success: function (response) {
                    console.log('captureImgNow');
                },
                error: function (xhr) {
                }
            });
        })
    }

This is the image I want
Desired image
This is result
Result image
This this CSS
CSS image

I tried dom-to-image, but the speed is quite slow and not suitable for my project.

 <img width="200px" height="200px" style="z-index: 1000; position: absolute; top: 50%; left: 50%;" src="<%= item.image_background_gray == null ? item.image_background : item.image_background_gray%>" alt="test">

This is image test
test img
This is result test
Result test

Update the array based on Checkbox status in ReactJs

I want to update the filterCandidates array based on the total experience of the candidate when the selected checkbox is checked and remove the candidate data from the array when unchecked, below is the code snippet

import { useState } from "react";

function ExperienceFilter({ candidates }) {
  const [filteredCandidates, setFilteredCandidates] = useState([]);
  const experienceOptions = [
    { value: "1-2", label: "1-2 Years" },
    { value: "3-4", label: "3-4 Years" },
    { value: "5-6", label: "5-6 Years" },
    { value: "7-8", label: "7-8 Years" },
    { value: "9-10", label: "9-10 Years" },
  ];

  function handleChange(e) {
    const { value, checked } = e.target;
    const experiencedCandidates = candidates.filter(
      (candidate) => candidate.totalExperience == value
    );

    if (checked) {
      setFilteredCandidates([...filteredCandidates, experiencedCandidates]);
    }

    if (!checked) {
      setFilteredCandidates((prev) => prev.totalExperience != value);
    }
  }
  return (
    <div>
      <div class="flex flex-col space-y-3 bg-green-600  px-5 pr-20 py-10">
        <div>Years of Experience</div>
        {experienceOptions.map((option, index) => (
          <label key={index}>
            <input
              type="checkbox"
              value={option.value}
              name={option.label}
              onChange={handleChange}
            />
            {option.label}
          </label>
        ))}
      </div>
    </div>
  );
}

export default ExperienceFilter;

How use 3rd party plugins with standalone Prettier API?

I’m writing a web extension to use at work that converts text into formatted code blocks using Prism and Prettier. We primarily use TypeScript and Java. Since the TypeScript plugin is included in Prettier, implementing that was easy enough. However, the Java plugin is 3rd-party and I cannot find any instructions on how to implement it with standalone Prettier.

No matter what I try, the farthest I’ve gotten is seeing ConfigError: Couldn't resolve parser "java". Plugins must be explicitly added to the standalone bundle. in the browser console.

The included plugins can be simply imported with a require() statement. However, trying this with the java plugin throws Error: Can't walk dependency graph: Cannot find module 'prettier-plugin-java' from 'C:UserschrisWebstormProjectsagility-code-chunksformat.js' during the build. I have tried both require("prettier-plugin-java") and require(./node_modules/prettier-plugin-java).

From there, I pivoted to trying a .prettierrc.json/.prettierrc.js, but it doesn’t seem to register either, I assume because I am using the API and not the CLI.

Here is my current state (testing in a dummy HTMl before implementing in the extension):

codeblock.html

<html style="background-color: #fff">
<head>
    <link href="themes/prism.css" rel="stylesheet"/>
    <title>Code Block</title>
    <header></header>
    <script src="bundle.js"></script>
</head>
<body>
<header data-plugin-header="show-language"></header>
<pre><code class="language-java">
<!--  Purposefully formatted poorly to ensure Prettier is working  -->
      package com.example;

    public class Main {

        public static void main(String[] args) {
                        System.out.println("Hello World!");

                }
    }
</code></pre>
<script src="prism.js"></script>
</body>
</html>

format.js

const prettier = require("prettier");
const typescript = require("./node_modules/prettier/plugins/typescript");
const babel = require("./node_modules/prettier/plugins/babel");
const estree = require("./node_modules/prettier/plugins/estree");
const html = require("./node_modules/prettier/plugins/html");
const markdown = require("./node_modules/prettier/plugins/markdown");
const postcss = require("./node_modules/prettier/plugins/postcss");
const yaml = require("./node_modules/prettier/plugins/yaml");

/* Takes in code string and language and attempts to reformat using Prettier API */
async function formatCode(code, language) {
    try {
        let parser = language;

        return await prettier.format(code, {
            organizeImportsSkipDestructiveCodeActions: true,
            parser: parser,
            plugins: [typescript, babel, estree, html, markdown, postcss, yaml],
            tabWidth: 2,
            useTabs: true,
            semi: true,
            singleQuote: false,
            trailingComma: "none",
            bracketSpacing: true,
            arrowParens: "always",
        });
    } catch (error) {
        console.error("Error formatting code:", error);
        return code;
    }
}

/* Grabs the code chunk from the HTML, parses the code (text) and language from it, and calls formatCode() */
setTimeout(async () => {
    for (const code of document.querySelectorAll("code")) {
        const language = code.className.replace("language-", "");
        if(language != null && language.trim() !== "") {
            code.parentElement.style.setProperty("--before-content", `'${language.toUpperCase()}'`);
            code.innerText = await formatCode(code.innerText, language);
        }
    }

    Prism.highlightAll();
}, 1000)

build.js

const browserify = require('browserify');
const fs = require('fs');

browserify(['format.js'])
    .transform('babelify', { presets: ['@babel/preset-env'] })
    .bundle((err, buf) => {
        if (err) {
            console.error(err);
        } else {
            fs.writeFileSync('bundle.js', buf);
        }
    });

package.json

{
  "name": "agility-code-chunks",
  "version": "1.0.0",
  "description": "web extension to format code chunks in agility",
  "main": "popup.js",
  "scripts": {
    "build": "node build.js",
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "nop990",
  "license": "MIT",
  "devDependencies": {
    "@babel/preset-env": "^7.25.2",
    "babelify": "^10.0.0",
    "browserify": "^17.0.0",
    "google-java-format": "^1.3.2",
    "prettier": "3.2.5",
    "prettier-plugin-java": "2.6.4",
    "prettier-plugin-organize-imports": "4.0.0"
  },
  "dependencies": {
    "java-parser": "^2.3.2"
  }
}

Change style on MouseOver event in reactJS

I’ve just started learinng react and i dont get that why setHeadingText changes the color onMouseOver event but setColor doesn’t

import React from "react";

function App() {
  const [headingText, setHeadingText] = React.useState("Hello");
  const [color, setColor] = React.useState("white");
  function mouseOver() {
    setColor("black");
    setHeadingText("Yo");
  }
  function mouseOut() {
    setColor("white");
    setHeadingText("Bye");
  }
  return (
    <div className="container">
      <h1>{headingText}</h1>
      <input type="text" placeholder="What's your name?" />
      <button
        style={{ backgroundColor: { color } }}
        onMouseOver={mouseOver}
        onMouseOut={mouseOut}
      >
        Submit
      </button>
    </div>
  );
}

It works if i use conditional like

const [mouseOver, setMouseOver]=useState(false);
function MouseOver(){
setMouseOver(true);
}

and then

style={{backgroundColor: MouseOver ? "black":"white"}}

but why it doesnt work like that what am i doing wrong??

await Promise.all is not working as expect in a for-loop in nodejs [duplicate]

I got the correct print result, but the print time was not as expected, and my expected result was about one log every second in nodejs

const promise1 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 1'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 2'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 3'));
const promise4 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 4'));
const promise5 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 5'));
const promise6 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 5'));
const promise7 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 7'));
const promise8 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 8'));
const promise9 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 9'));
const promise10 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 10'));

const promiseArrays = [
    [promise1, promise2],
    [promise3, promise4],
    [promise5, promise6],
    [promise7, promise8],
    [promise3, promise4],
    [promise9],
    [promise10]
];

async function inOrder() {
    
    for (const promiseArray of promiseArrays) {
        const res = await Promise.all(promiseArray)
        console.log(res.join(""))

        if (res.join("") === 'Promise 9') {
            break
        }
    }
}

inOrder()

I got the correct print result, but the print time was not as expected, and my expected result was about one log every second in nodejs

await Promise.all is not working as expect in a for-loop [duplicate]

const promise1 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 1'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 2'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 3'));
const promise4 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 4'));
const promise5 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 5'));
const promise6 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 5'));
const promise7 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 7'));
const promise8 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 8'));
const promise9 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 9'));
const promise10 = new Promise((resolve) => setTimeout(resolve, 1000, 'Promise 10'));

const promiseArrays = [
    [promise1, promise2],
    [promise3, promise4],
    [promise5, promise6],
    [promise7, promise8],
    [promise3, promise4],
    [promise9],
    [promise10]
];

async function inOrder() {
    
    for (const promiseArray of promiseArrays) {
        const res = await Promise.all(promiseArray)
        console.log(res.join(""))

        if (res.join("") === 'Promise 9') {
            break
        }
    }
}

inOrder()

I got the correct print result, but the print time was not as expected, and my expected result was about one log every second

I got the correct print result, but the print time was not as expected, and my expected result was about one log every second

How to update the header in papaparse unparse

How to apply the header name in csv. cause when I try to export the csv. the header applying is the key instead the header name.

current output
id, firstName, lastName, sampleLocation

`export default function useReports() {
  const COLUMNS = (reportColumns);

  const process = async (data = {}) => {
    const excel = useExcelExport();
    const workbook = excel.workbook;
    const sheet = excel.addWorksheet(workbook, 'Sheet 1', false);
    const today = format(new Date(), 'yyyyMMdd');

    // Page setup
    sheet.pageSetup.margins = {
      left: 0.25,
      right: 0.15,
      top: 0.5,
      bottom: 0.25,
      header: 0.25,
      footer: 0.25
    };

    const cols = COLUMNS.map(a => ({
      key: a.field,
      header: a.headerName,
      width: 15
    }));

    sheet.columns = cols;

    const csvData = [];
    data['items'].forEach(item => {
      const obj = {};

      cols.forEach(col => {
        obj[col.key] = item[col.key];
      });

      dateFields.forEach((field) => {
        try {
          if (obj[field]) {
            obj[field] = obj[field] ? format(new Date(obj[field]), 'dd-MM-yyyy') : ''
          }
        } catch (e) { }
      });

      if (data['type'] === 'csv') {
        csvData.push(obj);
      }
      sheet.addRow(obj);
    });

    if (data['type'] === 'xslx') {
      excel.setBorder(sheet, '333333');
      excel.saveExcel(workbook, `Report'${today}`)
    } else if (data['type'] === 'csv') {
      const csv = Papa.unparse(csvData);
      excel.saveCSV(csv, `Report'${today}`);
    } else {
    }
  }`

I try to apply this

const csvHeaders = cols.map(col => col.header);
      const csv = Papa.unparse({
        fields: csvHeaders,
        data: csvData
      });

but the header was update but no data display. cause the field key not same.

how to initial and align 2D models with Viewer3D.js (JavaScript)

Although I am not yet familiar with the Viewer3D.js (version 7), we are exploring the possibility of using the APS Viewer API to meet customer needs.
We need to display multiple 2D drawings together in one viewer, and I know we can use Aggregated View API to achieve this.
When I load two 2D drawings in, they will be displayed in the middle of the viewport and fill the viewport.
But this brings about the following three issues.

  1. The positions of the baseline lines X0, X1, X2, Y0, Y1, etc. in the two drawings are misaligned and I need to align them.

  2. one of the 2D drawings has become larger than the original drawing, the distance between the reference lines X0 and X2 has become 943.8. I need to adjust it to the correct value of 910.0

  3. It seems that the units on the drawings have changed to inches(“). I need to adjust the units to centimeters (mm).

Here’s a screenshot of the Viewport, only part of the drawings, but I think it should illustrate the problem.
enter image description here

Below is my initial code:

Autodesk.Viewing.Initializer(options, function () {
        //initialize the viewer object
        const viewerDiv = document.getElementById("AutodeskViewer");
        const view = new Autodesk.Viewing.AggregatedView();
        view.init(viewerDiv);

        const tasks = [];
        UrnArr.forEach(md => tasks.push(loadManifest("urn:"+md)));

        Promise.all(tasks)
            .then(docs => Promise.resolve(docs.map(doc => {
                const bubbles = doc.getRoot().search({ type: 'geometry', role: '2d' });
                const bubble = bubbles[0];
                if (!bubble) return null;

                return bubble;
            })))
            .then(bubbles => {
                view.setNodes(bubbles);
                view.viewer.loadExtension('Autodesk.DocumentBrowser');
                viewer = view;
            });
    });

Can Viewer3D.js solve the above three issues?
If you have any solutions or related blog posts, please give them to me. I shall be grateful.

I tried to change the camera, but it affects all 2d models. I think I should manipulate the geometries in models, but how to do that.

Unable to execute while loop

I am writing a code to determine the total cost of entry for the data entered. The code needs to prompt the user for the numbers in each demographic as long as they want to enter a group. If they don’t, then the code spits out the total take of every entry charge they were given. For some reason, when I run the code, it only prompts for the group and then stops. I’m very new to Java to any help is appreciated.

public static void main(String[] args){
    Scanner sc = new Scanner(System.in); //create scanner object
    
    //code prompts user for group
    
    System.out.println("Enter a group? (Yes = 1/No = 0): ");
    int group = sc.nextInt();
    int children = sc.nextInt();
    int adults = sc.nextInt();
    int seniors = sc.nextInt();
    
    //if user enters 1, the following code should execute, prompting for numbers, then give an entry
    // charge
    while (group == 1) {
       System.out.println("Enter the number of children (age 6 - 15): "+children);
       System.out.println("Enter the number of adults (16 - 59): "+adults);
       System.out.println("Enter the number of seniors (age 60+) "+seniors);
       System.out.println("Total entry charge is $");//needs to include calculation
    }
    System.out.println("Total takings: $")//needs to include sum calculation of all charges in while
                                          //loop
}

When I entered the above, this is what I get:

enter image description here

offload long running function in javascript/node

I’d like to await a function, call it

runThirdPartyCall()

however, I don’t know how long this will take ahead of time. If it takes longer than 30 seconds, i’d like to return from the request early, but still be able to reason about what runThirdPartyCall() returns.

Is this possible to do with workers? I see that javascript cannot directly hand over the execution of a function or the promise it returns to another thread or process once it has started, so i’m wondering if there are any alternatives.

I’m stuck wondering about the general problem, when you have a third party call of which you don’t know how long it will take, and if it ends up taking too long you want to go and inform the client/move on to other things

Seeking Advice: Transitioning from Node.js to Spring for Backend Development [closed]

fellow developers!

I am a backend developer with 3 years of experience primarily working with Node.js. I have enjoyed working with JavaScript and the flexibility it offers, but I am considering transitioning to Java and Spring for backend development. I believe this change will open up new opportunities and allow me to expand my skill set.

I would love to hear from those of you who have made a similar transition or who work with Spring. What challenges did you face during the transition? Are there any specific resources, courses, or projects you recommend for learning Java and Spring effectively? Additionally, I am curious about the differences in development workflow and best practices between these two ecosystems.

Any advice, tips, or insights you could share would be greatly appreciated. Thank you!

I’m trying to make the transition

Why does not work the await fetch to the API function?

I’m creating a AI chat using OpenAI API, i following this tutorial but the thing is when i made the call to the api/chat/sendMessage.js i get the 404 error, idk what to do, i made several OpenAI keys and still not working, here is te code in sendMessage.js

import { OpenAIEdgeStream } from "openai-edge-stream";


export const runtime = 'edge';

export default async function handler(req){
    try{
    const {message} = req.json;
    const stream= await OpenAIEdgeStream('https://api.openai.com/v1/chat/completions',
    {
        headers:{'content-type': 'application/json',
        Authorization: `Bearer ${process.env.OPENAI_API_KEY}`
        },
        method: "POST",
        body: JSON.stringify({
            model: "gpt-3.5-turbo",
            messages: [{content: message, role: "user"}],
            stream: true
        }) 
    }
    );
    return new Response(stream);
    
    }catch(e){
        console.log("Un error ha ocurrido al enviar el mensaje", e);
    }
}

And the page.tsx where i send the form(the message the user writes) to the api

"use client";
import Image from 'next/image';
import EmptyState from './components/EmptyState';
import Historial from './components/Historial';
import { useState } from 'react';
import {streamReader} from "openai-edge-stream";

export default function Home() {
  const [messageText, setMessageText] = useState("");
  
  const handleSumbit = async (e) => {
    e.preventDefault();
    console.log("MessageText:", messageText);
    const response = await fetch("/api/chat/sendMessage", {
        method:'POST',
        headers:{
            'content-type': 'application/json',
        },
        body: JSON.stringify({message: messageText}),
        
    });
    
    const data= response.body;
    //const data = await response.json();
    if(!response.ok){
      throw new Error("No sirve la api alv");   
    }
    const reader= data.getReader();
    await streamReader(reader, (message) =>{
        console.log("Message AI:", message)
    });
}

  return (
    <>
    <main className="h-full">
      
      <div className="flex flex-row h-full">
      <div className="w-[30px]">
          <Historial /> 
      </div>
      <div className=" lg:pl-[200px] w-full flex flex-col h-full " >
        <div className="flex-1 overflow-y-auto">
            Body!</div>
            <div >
            <form onSubmit={handleSumbit}> {/* style del form*/}
                <fieldset className="flex gap-2">
                    <textarea 
                    value={messageText}
                    onChange={(e) => setMessageText(e.target.value)}
                    placeholder="Send a Message..." 
                    className="w-full resize-none rounded-md bg-white p-2 text-black border-none focus:outline-none"></textarea>
                    <button type="submit" className="rounded-full p-2 bg-[#2c4277] cursor-pointer hover:bg-[#23355e] transition w-[37px] h-[37px]">
                    <Image src="/enviar.png" alt="enviar" width={35} height={35} />
                    </button>
                </fieldset>
                
            </form>
        </div>
      </div>
      </div>
    </main>
    </>
  );
}

I tried change to response.json() and didn’t work, i change several API keys and also give the 404.