Material UI React JS Select component with multiple value unable to deselect when more than 1 item is selected

So i am trying to implement a multiselect dropdown in material ui with the following conditions
The dropdown will have [0 Apples, 1 Oranges, 2 Grapes]

By default 0 Apples should be selected
None of the options can be unselected.

If 0 Apples is selected and the user selects 1 Oranges or 2 Grapes then 0 Apples will be unselected and either 1 Orange or 2 Grapes will be selected depending on what he selected.

If 1 Oranges is selected then 0 Apples will get unselected.
If 2 Grapes Is selected then 0 Apples will get unselected.

If 1 Oranges is selected 2 Grapes is selected then both of them will get selected.
If 2 Grapes is selected 1 Oranges is selected then both the will get selected.

I am having problems trying to implement the unselect logic for the following cases:
1 Oranges and 2 Grapes is selected then unselect either of them.

And i am not sure where it is not working. The variable actualNewSelectionByUser is empty because he is unselecting so i will read from actualSelected as in value of mui input. I will use this to delete the value in state. But this is not working.

Here is the code sandbox link

link to code sandbox

How to resolve Icons not visible in react native?

I have an existing react native web expo app. And I updated some packages and updated expo. But apparently the icons are not visible anymore.

And of couse I googled a lot. And I tried a lot of different scenario’s. And Of course this question has already be posted. But I am realy stuck because I just made an simple component. And it still does not work.

So this is the simple component:


import { Button } from "react-native-paper";
import React from "react";

export const AccountScreen = ({ navigation }) => {
    return (

        <Button
            icon="camera-outline"
            mode="contained"
            onPress={() => console.log("Pressed")}
        >
            Press me
        </Button>   );
  };
  
  export default AccountScreen;

And package.json looks:

{
  "name": "app",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start:production": "NODE_ENV=production npx expo export:web .env.production --openssl-legacy-provider, react-app-rewired start react-scripts start",
    "start:development": "NODE_ENV=development expo start --openssl-legacy-provider, react-app-rewired start react-scripts start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "lint": "eslint . --ext .js",
    "postinstall": "patch-package",
    "build": "react-scripts build NODE_ENV=production npm run clean && webpack -p",
    "start-webpack": "webpack-dev-server --mode production --open"
  },
  "dependencies": {
    "@ant-design/icons": "4.0.0",
    "@expo-google-fonts/lato": "^0.2.2",
    "@expo-google-fonts/oswald": "^0.2.2",
    "@expo/config": "~9.0.0",
    "@expo/metro-config": "~0.18.11",
    "@expo/vector-icons": "^14.0.2",
    "@expo/webpack-config": "~19.0.1",
    "@react-native-async-storage/async-storage": "1.23.1",
    "@react-navigation/bottom-tabs": "^6.5.4",
    "@react-navigation/native": "^6.1.18",
    "@react-navigation/native-stack": "^6.11.0",
    "@react-navigation/stack": "^6.4.0",
    "babel-plugin-styled-components-react-native-web": "^0.2.2",
    "buffer": "^6.0.3",
    "crypto-browserify": "^3.12.0",
    "css-to-react-native": "^3.2.0",
    "env-cmd": "^10.1.0",
    "expo": "^51.0.28",
    "expo-file-system": "~17.0.1",
    "expo-font": "~12.0.9",
    "expo-linking": "~6.3.1",
    "expo-modules-core": "~1.12.21",
    "expo-screen-orientation": "~7.0.5",
    "expo-status-bar": "~1.12.1",
    "lottie-react-native": "6.7.0",
    "next-transpile-modules": "^10.0.1",
    "patch-package": "^8.0.0",
    "process": "^0.11.10",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-native": "0.74.5",
    "react-native-autocomplete-dropdown": "^3.1.4",
    "react-native-crypto": "^2.2.0",
    "react-native-dotenv": "^3.4.9",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-paper": "^5.1.3",
    "react-native-reanimated": "~3.10.1",
    "react-native-safe-area-context": "4.10.5",
    "react-native-screens": "3.31.1",
    "react-native-size-matters": "^0.4.2",
    "react-native-svg": "15.2.0",
    "react-native-toast-message": "^2.2.0",
    "react-native-toast-notifications": "^3.4.0",
    "react-native-url-polyfill": "^2.0.0",
    "react-native-vector-icons": "^10.1.0",
    "react-native-web": "~0.19.10",
    "react-native-web-lottie": "^1.4.4",
    "react-router-native": "^6.24.1",
    "react-toast-notifier": "^1.0.3",
    "stream-browserify": "^3.0.0",
    "styled-components": "^5.3.6",
    "vm-browserify": "^1.1.2",
    "webpack-cli": "^5.1.4",
    "zod": "^3.22.4"
  },
  "parserOptions": {
    "parser": "@babel/eslint-parser",
    "requireConfigFile": false
  },
  "devDependencies": {
    "@babel/core": "^7.24.0",
    "@expo/metro-runtime": "~3.2.3",
    "@react-native-community/eslint-config": "^3.2.0",
    "eslint": "^8.32.0",
    "prettier": "^2.8.3",
    "react-app-rewired": "^2.2.1",
    "react-refresh": "^0.14.0",
    "webpack": "^5.89.0"
  },
  "browser": {
    "crypto": false,
    "stream": false
  },
  "private": true
}

And I added webpack.config.js:

/* eslint-disable prettier/prettier */
const webpack = require("webpack");
const createExpoWebpackConfigAsync = require("@expo/webpack-config");

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);

  
  config.resolve.fallback = {
    ...config.resolve.fallback,
    stream: require.resolve("stream-browserify"),
    crypto: require.resolve("crypto-browserify"),
    buffer: require.resolve("buffer"),
    process: require.resolve("process/browser"),
    vm: require.resolve("vm-browserify"),

  };

  // Plugins to define global variables and polyfills
  config.plugins = (config.plugins || []).concat([
    new webpack.ProvidePlugin({
      process: "process/browser",
      Buffer: ["buffer", "Buffer"],
    }),
  ]);

  return config;
};

But this all didn’t resolved the issue that the icon made visible again

So maybe there is some conflict about packages? But I don’t know.

Question: how to make the icon visible?

How to link my JS file from a different directory to my EJS file

I have an ejs file in the following directory:

./admin/admin.ejs

and i have plain old JS file in the following directory:

./public/client.js

and an express app in the following directory:

./app.js

that renders the ejs file with the following code:

const express = require("express");
const { Server } = require("socket.io");
const { sessionMiddleware, wrap } = require("./server/sessionStore");
const { createServer } = require("node:http");
const { join } = require("node:path");

const app = express();
const server = createServer(app);

const db = require("./databases/dbChooser");
const config = require("./server/config");
const { banCheckMiddleware } = require("./server/middleware");

const io = new Server(server, config.cors);

const WorkerPool = require("./server/workerPool");
const workers = new WorkerPool(1, "./drawingWorker");

app.use(sessionMiddleware);
app.use(banCheckMiddleware);

app.set("view engine", "ejs");
app.set("views", join(__dirname, "./admin"));

app.get("/", (req, res) => {
  if (!req.session.initialized) {
    req.session.initialized = true;
    req.session.visitCount = 1;
  } else {
    req.session.visitCount = (req.session.visitCount || 0) + 1;
  }
  res.sendFile(join(__dirname, "./public/index.html"));
});

app.use(express.static("public"));
app.use(express.static("admin"));

the ejs renders fine and everything works on surface level, but when i try using the client.js script in my EJS file i get the following error:
Refused to execute script from 'http://127.0.0.1:3000/public/client.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.

My quick fix was to create a separate js file in the admin dir and copy and paste the client js code in it,and that works fine no errors. I also tried doing this:
<script type = "text/javascript" src="../public/client.js"></script>
but that doesnt work.The JS and CSS files inside the admin dir work fine but its when i try to reference another file from a different dir is when it gets angry.

Why is React-Router not rendering a route when I add its path to the end of the localhost:3000 URL?

I’ve been working through this React tutorial and have gotten stuck. (Chapter 16: React Router). My basic boilerplate html components all render properly in App.js UNTIL I wrapped some inside <Routes> tags and added the path="" and element={} attributes. The code below of my App.js file is where I’m at (05:00:38 in the tutorial video)

Note: You’ll notice right away that I’ve already addressed problems and changed some code to overcome discrepancies between the tutorial video (which was made in 2021) and changes made in 2022 to React Router 6. These revisions included changing components to elements, Switch to Routes, etc. In retrospect I realize now I should have picked a more recent tutorial but here we are…

import Header from './Header';
import Nav from './Nav';
import Footer from './Footer';
import Home from './Home';
import NewPost from './NewPost';
import PostPage from './PostPage';
import About from './About';
import Missing from './Missing';
import { Router, Route, Routes, useHistory } from 'react-router-dom';
import { useState, useEffect } from 'react';

function App() {
  return (
    <div className="App">
      <Header />
      <Nav />
      <Routes>
        <Route path="" element={<Home />} />
        <Route path="post" element={<NewPost />} />
        <Route path="post/:id" element={<PostPage />} />
        <Route path="about" element={<About />} />
        <Route path="*" element={<Missing />} />
      </Routes>
      <Footer />
    </div>
  );
}

export default App;

Everything seems fine, i.e. only Header, Nav, Home, and Footer are rendering on "localhost:3000".

Screenshot of localhost:3000

The problem is when I go to "localhost:3000/post: to test and see if Home gets swapped out and re-rendered as NewPost per the tutorial. Instead, I get a blank screen. The same blank screen occurs when I try to navigate to "localhost:3000/post/:1" or "localhost:3000/about".

I suspect the problem lies somewhere in the App.js file above, my index.js file (below), or my NewPost.js file (below that):

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';

ReactDOM
  .createRoot(document.getElementById('root'))
  .render(
    <Router>
      <Routes>
        <Route path="/" element={<App />} />
      </Routes>  
    </Router>
  );
import React from 'react'

const NewPost = () => {
  return (
    <main>
      <h1>NewPost</h1>
    </main>
  )
}

export default NewPost

I’ve searched Stack Overflow and found a few similar problems, mainly: DOM does not render when adding a nested route in react router. Why would this be happening? and react-router-dom <routes> not rendering anything in localhost:3000. Unfortunately I haven’t yet found a fix. Several people suggested removing the exact keyword, which I did since it’s since been removed/deprecated, but it didn’t help. (Those previous issues ended up being resolved by making the React Router 6 syntax updates I noted at the beginning of my post.)

I’ve uploaded my full codebase here in case it’s helpful: https://github.com/pudgyturtle/react-blog I can’t for the life of me figure out what the problem is.

NextJS route handler working when visiting directly via browser searchbar, but doesn’t work when console logging it

Basically, I am trying to access some json placeholder data via my route handler defined in /api/posts/route.js

export async function GET() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  const data = await res.json();

  return Response.json({ data: data });
}

I know that this part is OK because when I navigate to

http://localhost:3000/api/posts

a whole json object with this data appears on the page.

However, when I am trying to get this data via console logging in my

/posts/page.jsx

file, it just logs an empty object. Does anyone know what’s going on here? Thanks!

import React from 'react';

export async function getPosts() {
  const res = await fetch('http://localhost:3000/api/posts');

  const data = await res.json();

  return data.data;
}

const Post = async () => {
  const posts = await getPosts();
  console.log(posts);
  return (
    <div>
      <h1>Hello</h1>
    </div>
  );
};

export default Post;

Checking if username and/or email are in use javaScript

I am creating a webpage for a school proyect and I am having issues with the register tab. A friend is coding the backend on pgAdmin and its running on a Vercel server. The issue is that every time a new user register it says that the email and username are in use when they are not. This is my FunctionsR.js:

var isPassOk;
var isUsernameOk;
var isEmailOk;

function showPass() {
var x = document.getElementById("passwordId");
var y = document.getElementById("checkPasswordId");
var i = document.getElementById("passIconId");
if (x.type === "password") {
    x.type = "text";
    y.type = "text";
    i.classList.remove('bx-show');
    i.classList.add('bx-show');
} else {
    x.type = "password";
    y.type = "password";
    i.classList.remove('bx-show');
    i.classList.add('bx-hide');
}
}

function checkMail() {
var email = document.getElementById("emailId").value;
var alert = document.querySelector(".alertEmail");
var alert2 = document.querySelector(".alertEmail2");

var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,6}$/;
if (!emailPattern.test(email)) {
    alert.style.display = 'block';
    isEmailOk = false;
    return isEmailOk;
}

emailInUse(email).then(errorMessage => {
    if (errorMessage) {
        alert2.style.display = 'block';
        isEmailOk = false;
    } else {
        isEmailOk = true;
    }
    return isEmailOk;
}).catch(error => {
    console.error('Error:', error);
    isEmailOk = false;
    return isEmailOk;
});
}

function emailInUse(email) {
return fetch('https://centinel-ai.vercel.app/api/register', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email })
})
.then(response => response.json())
.then(data => {
    if (data.error && data.error === 'Email already in use') {
        return 'Email already in use'; 
    }
    return null; 
})
.catch(error => {
    console.error('Error:', error);
    return 'An error occurred';
});
}

function checkUsername() {
var username = document.getElementById("usernameId").value;
var alert = document.querySelector(".alertUsername");
var alert2 = document.querySelector(".alertUsername2");

if (username.length > 25 || username.length < 4) {
    alert.style.display = 'block';
    isUsernameOk = false;
}
usernameInUse(username).then(errorMessage => {
    if (errorMessage) {
        alert2.style.display = 'block';
        isUsernameOk = false;
    } else {
        isUsernameOk = true;
    }
    return isUsernameOk;
}).catch(error => {
    console.error('Error:', error);
    isUsernameOk = false;
    return isUsernameOk;
});
}

function usernameInUse(username) {
return fetch('https://centinel-ai.vercel.app/api/register', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ username })
})
.then(response => response.text())
.then(text => {
    try {
        const data = JSON.parse(text);
        if (data.error && data.error === 'Username already in use') {
            return 'Username already in use'; 
        }
        return null; 
    } catch (error) {
        console.error('Error parsing JSON:', error);
        return 'An error occurred';
    }
})
.catch(error => {
    console.error('Error:', error);
    return 'An error occurred';
});   
}

function checkPass() {
var password = document.getElementById("passwordId").value;
var confirmPassword = document.getElementById("checkPasswordId").value;
var errorMessage = document.getElementById("error-message");

if (password !== confirmPassword) {
    errorMessage.style.display = 'block';
    document.getElementById("passwordId").style.color = 'red';
    document.getElementById("checkPasswordId").style.color = 'red';
    isPassOk = false;
} else {
    errorMessage.style.display = 'none';
    document.getElementById("passwordId").style.color = 'white';
    document.getElementById("checkPasswordId").style.color = 'white';
    isPassOk = true;
}
return isPassOk;
}

function registerUser() {

var username = document.getElementById('usernameId').value;
var email = document.getElementById('emailId').value;
var password = document.getElementById('passwordId').value;

if(isPassOk && isUsernameOk && isEmailOk){
    fetch('https://centinel-ai.vercel.app/api/register', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ email, username, password })
    })
        .then(response => response.text())
        .then(message => console.log(message))
        .catch(error => {
            console.error('Error:', error);
            console.error('Status:', error.status);
            console.error('Status Text:', error.statusText);
        });   
}   
}

function onRegisterSubmit(e){
console.log("Submited")
e.preventDefault();

checkPass();
checkMail();
checkUsername();

registerUser();
}

document.addEventListener("DOMContentLoaded", () => {
const registerForm = document.getElementById("register");

registerForm.addEventListener("submit", onRegisterSubmit);
})

I am new to webpage development so I depend on using AI a lot. I can understand almost everything but I can’t troubleshoot very well. Everything helps. Thank you!

Safari IOS struggling to render multiple svg objects

I using an openseadragon and annotorious-openseadragon libraries to work with annotations on my website. Everything is working fine everywhere except Ipad air 4+ safari web-browser. This is what happened when I trying to draw multiply svg objects (screen from browserstack).

image with the bug

You can see all those vertical lines. This is not my job 🙂 Idk why it is so. Its should looks like this

image without bug

this is a snippet to reproduce this bug

// very big svg objects
  var sampleAnnotation = [{"@context":"http://www.w3.org/ns/anno.jsonld","type":"Annotation","body":[{"type":"TextualBody","value":"фывф","purpose":"commenting"}],"target":{"source":"http://localhost:3000/gist/undefined","selector":{"type":"SvgSelector","value":"<svg><path d="M553.3169555664062 681.3240356445312 L556.6597290039062 685.5106811523438 L563.309814453125 690.4487915039062 L581.1146240234375 700.1627197265625 L600.4758911132812 713.045654296875 L629.5269775390625 730.774169921875 L659.92431640625 749.9573974609375 L693.4526977539062 767.5196533203125 L742.8221435546875 797.7689208984375 L792.121826171875 818.44677734375 L841.3558349609375 850.2068481445312 L893.6697998046875 881.9053344726562 L934.832763671875 904.0648193359375 L980.70166015625 926.2005615234375 L1021.7759399414062 948.31396484375 L1045.4112548828125 960.9156494140625 L1070.6075439453125 970.3447875976562 L1089.4627685546875 979.76708984375 L1098.730712890625 982.8129272460938 L1109.6697998046875 992.22412109375 L1112.7156982421875 995.3192138671875 L1111.36865234375 994.57080078125"></path></svg>"}},"id":"#926aed3d-26be-49b5-ab43-6161031f6bd8","zoomLevel":0.8022570765661251},{"@context":"http://www.w3.org/ns/anno.jsonld","type":"Annotation","body":[{"type":"TextualBody","value":"фывыв","purpose":"commenting"}],"target":{"source":"http://localhost:3000/gist/undefined","selector":{"type":"FragmentSelector","conformsTo":"http://www.w3.org/TR/media-frags/","value":"xywh=pixel:377.0811767578125,942.0926513671875,324.386962890625,135.178955078125"}},"id":"#674a21c7-d97f-43e5-acb1-f44c4f98de4d","zoomLevel":0.5571229698375869},{"@context":"http://www.w3.org/ns/anno.jsonld","type":"Annotation","body":[{"type":"TextualBody","value":"sss","purpose":"commenting"}],"target":{"source":"http://localhost:3000/gist/undefined","selector":{"type":"SvgSelector","value":"<svg><line x1="686.9415283203125" y1="372.413818359375" x2="897.4363403320312" y2="569.9550170898438"></line></svg>"},"renderedVia":{"name":"line"}},"id":"#5bbe1f3b-12c0-4084-a4a5-58662cb1fc7c","zoomLevel":0.568465909090909},{"@context":"http://www.w3.org/ns/anno.jsonld","type":"Annotation","body":[{"type":"TextualBody","value":"ddd","purpose":"commenting"}],"target":{"source":"http://localhost:3000/gist/undefined","selector":{"type":"SvgSelector","value":"<svg><path d="M199.18508911132812 471.26763916015625 L199.36708068847656 469.2500305175781 L201.6888885498047 469.3369445800781 L206.23126220703125 469.3780212402344 L210.79876708984375 473.96612548828125 L219.8451690673828 483.0223083496094 L228.8885955810547 494.3298645019531 L240.1836700439453 505.63372802734375 L253.72982788085938 528.2055053710938 L260.5103454589844 537.247314453125 L276.30419921875 555.3018188476562 L289.8521728515625 571.11474609375 L305.6393127441406 591.414794921875 L321.4201354980469 613.9591674804688 L337.1995849609375 629.7429809570312 L348.47088623046875 643.2711791992188 L361.9927062988281 659.0494384765625 L377.768798828125 674.8324584960938 L384.5289611816406 686.1000366210938 L395.7919921875 697.3660278320312 L409.3052978515625 708.6303100585938 L416.0618591308594 715.3896484375 L422.81768798828125 724.3997192382812 L427.32122802734375 724.4028930664062 L434.07568359375 726.66015625 L438.57794189453125 731.1650390625 L440.82879638671875 733.4185180664062 L443.0794677734375 733.4207153320312 L447.5807189941406 737.9244384765625 L449.8309326171875 737.9260864257812 L454.33087158203125 742.4307250976562 L458.8310546875 742.4322509765625 L461.0797119140625 742.4351806640625 L463.328125 742.437744140625 L467.8273010253906 742.4390258789062 L470.07537841796875 742.4415283203125 L472.32427978515625 742.4425659179688 L479.0726318359375 742.4437255859375 L485.8206481933594 742.4447021484375 L492.5684509277344 740.1961059570312 L503.8150939941406 726.699462890625 L512.8118286132812 706.4547729492188 L526.305419921875 681.7137451171875 L539.8001098632812 661.4711303710938 L544.2968139648438 650.2267456054688 L557.7907104492188 632.234619140625 L566.7855834960938 614.2431030273438 L573.531005859375 591.7536010742188 L582.5230712890625 573.7666625976562 L589.2681274414062 555.77685546875 L593.7639770507812 540.0366821289062 L600.5089111328125 526.5458374023438 L602.7555541992188 504.05908203125 L602.7532958984375 488.3199157714844 L602.7511596679688 470.33197021484375 L604.9961547851562 456.84564208984375 L604.993896484375 450.1033630371094 L604.9925537109375 436.61285400390625 L604.9925537109375 432.1150817871094 L604.9925537109375 425.36846923828125 L604.9925537109375 420.8706970214844 L604.9925537109375 409.6263427734375 L604.9925537109375 402.87969970703125 L604.9925537109375 391.63531494140625 L604.9925537109375 384.8887023925781 L604.9925537109375 375.8931884765625 L604.9925537109375 364.6488342285156 L604.9925537109375 362.3999328613281 L604.9925537109375 355.6533203125 L604.9925537109375 351.15557861328125 L604.9925537109375 346.6578063964844 L604.9925537109375 344.408935546875 L604.9925537109375 337.6623229980469 L602.7437133789062 333.16455078125 L602.7437133789062 330.9156799316406 L600.4948120117188 328.66680908203125 L598.2459106445312 326.4179382324219 L595.9970703125 324.1690673828125 L591.4993286132812 319.6712951660156 L589.2504272460938 319.6712951660156 L578.0060424804688 315.1735534667969 L571.2594604492188 315.1735534667969 L557.7661743164062 312.9246826171875 L537.5263061523438 306.17803955078125 L515.0375366210938 303.9291687011719 L492.5487976074219 299.4314270019531 L472.30889892578125 297.18255615234375 L445.3223876953125 292.684814453125 L425.08251953125 292.684814453125 L400.3448791503906 292.684814453125 L377.85614013671875 292.684814453125 L364.3628845214844 292.684814453125 L353.1184997558594 292.684814453125 L339.625244140625 292.684814453125 L328.380859375 297.18255615234375 L314.8876037597656 299.4314270019531 L308.1409912109375 299.4314270019531 L305.8921203613281 301.6802978515625 L308.1409912109375 301.6802978515625 L312.63873291015625 301.6802978515625 L314.8876037597656 303.9291687011719 L317.136474609375 303.9291687011719 L319.3853454589844 306.17803955078125 L321.6342468261719 306.17803955078125 L328.380859375 312.9246826171875 L332.87860107421875 312.9246826171875 L339.625244140625 317.42242431640625 L344.12298583984375 317.42242431640625 L348.6207580566406 319.6712951660156 L357.6162414550781 321.9201965332031 L359.8651123046875 321.9201965332031 L364.3628845214844 321.9201965332031 L368.8606262207031 324.1690673828125 L375.60723876953125 326.4179382324219 L377.85614013671875 328.66680908203125 L384.6027526855469 328.66680908203125 L386.85162353515625 328.66680908203125 L389.1004943847656 328.66680908203125 L398.09600830078125 328.66680908203125 L411.5892639160156 324.1690673828125 L420.58477783203125 319.6712951660156 L429.58026123046875 312.9246826171875 L436.326904296875 310.6758117675781 L440.82464599609375 306.17803955078125 L443.0735168457031 303.9291687011719 L443.0735168457031 301.6802978515625 L445.3223876953125 297.18255615234375 L447.5712585449219 294.9336853027344 L452.06903076171875 294.9336853027344 L458.8156433105469 294.9336853027344 L470.0600280761719 294.9336853027344 L497.0465393066406 294.9336853027344 L526.2819213867188 294.9336853027344 L562.263916015625 294.9336853027344 L600.4948120117188 294.9336853027344 L638.7257080078125 294.9336853027344 L690.4498291015625 290.4359130859375 L742.1739501953125 290.4359130859375 L793.8981323242188 290.4359130859375 L832.1290283203125 290.4359130859375 L865.8621215820312 290.4359130859375 L886.1019897460938 290.4359130859375 L895.0975341796875 290.4359130859375 L904.093017578125 290.4359130859375 L906.3419189453125 290.4359130859375 L917.5863037109375 290.4359130859375 L949.070556640625 297.18255615234375 L978.305908203125 297.18255615234375 L1007.5413208007812 301.6802978515625 L1045.772216796875 301.6802978515625 L1075.007568359375 310.6758117675781 L1104.242919921875 310.6758117675781 L1133.4783935546875 310.6758117675781 L1151.4693603515625 315.1735534667969 L1164.962646484375 315.1735534667969 L1171.709228515625 315.1735534667969 L1169.4603271484375 315.1735534667969 L1162.7137451171875 312.9246826171875 L1160.46484375 312.9246826171875 L1153.71826171875 310.6758117675781 L1149.220458984375 308.42694091796875 L1140.2249755859375 308.42694091796875 L1133.4783935546875 308.42694091796875 L1128.9805908203125 308.42694091796875 L1122.2340087890625 308.42694091796875 L1117.7362060546875 308.42694091796875 L1117.7362060546875 312.9246826171875 L1117.7362060546875 317.42242431640625 L1126.731689453125 324.1690673828125 L1133.4783935546875 324.1690673828125 L1142.473876953125 326.4179382324219 L1146.9715576171875 328.66680908203125 L1151.4693603515625 330.9156799316406 L1153.71826171875 330.9156799316406 L1158.2159423828125 335.4134521484375 L1160.46484375 337.6623229980469 L1164.962646484375 342.1600646972656 L1169.4603271484375 346.6578063964844 L1171.709228515625 348.90667724609375 L1173.9581298828125 351.15557861328125 L1178.455810546875 355.6533203125 L1180.7047119140625 360.15106201171875 L1185.2025146484375 364.6488342285156 L1187.4512939453125 366.897705078125 L1187.4512939453125 369.1465759277344 L1189.7001953125 371.39544677734375 L1194.197998046875 375.8931884765625 L1196.4468994140625 378.14208984375 L1196.4468994140625 378.14208984375"></path></svg>"}},"id":"#7955762b-3c17-4c75-b8c7-63cb71634459","zoomLevel":0.8185909090909089},{"@context":"http://www.w3.org/ns/anno.jsonld","type":"Annotation","body":[{"type":"TextualBody","value":"ss","purpose":"commenting"}],"target":{"source":"http://localhost:3000/gist/undefined","selector":{"type":"SvgSelector","value":"<svg><path d="M346.3718566894531 1295.683349609375 L355.36737060546875 1293.4344482421875 L371.1094970703125 1293.4344482421875 L393.5982666015625 1293.4344482421875 L418.33587646484375 1293.4344482421875 L438.5757751464844 1293.4344482421875 L461.06451416015625 1293.4344482421875 L474.5577697753906 1295.683349609375 L479.0555419921875 1295.683349609375 L488.051025390625 1297.9322509765625 L492.5487976074219 1302.429931640625 L497.0465393066406 1302.429931640625 L503.79315185546875 1302.429931640625 L512.7886352539062 1304.6788330078125 L515.0375366210938 1304.6788330078125 L519.5352783203125 1304.6788330078125 L521.7841796875 1304.6788330078125 L524.0330200195312 1304.6788330078125 L533.028564453125 1309.1766357421875 L535.2774047851562 1309.1766357421875 L542.0240478515625 1309.1766357421875 L544.27294921875 1309.1766357421875 L551.01953125 1309.1766357421875 L557.7661743164062 1311.4254150390625 L562.263916015625 1313.67431640625 L564.5128173828125 1313.67431640625 L571.2594604492188 1313.67431640625 L575.7572021484375 1313.67431640625 L580.2549438476562 1313.67431640625 L584.752685546875 1313.67431640625 L587.0015869140625 1313.67431640625 L587.0015869140625 1315.9232177734375 L589.2504272460938 1315.9232177734375 L591.4993286132812 1315.9232177734375 L595.9970703125 1315.9232177734375 L600.4948120117188 1315.9232177734375 L607.241455078125 1315.9232177734375 L613.988037109375 1315.9232177734375 L622.9835815429688 1315.9232177734375 L631.9790649414062 1315.9232177734375 L645.4723510742188 1318.172119140625 L647.72119140625 1318.172119140625 L658.965576171875 1318.172119140625 L661.2144775390625 1318.172119140625 L667.9610595703125 1318.172119140625 L670.2099609375 1318.172119140625 L672.4588623046875 1318.172119140625 L674.7077026367188 1318.172119140625 L681.454345703125 1318.172119140625 L683.7031860351562 1318.172119140625 L690.4498291015625 1318.172119140625 L694.9475708007812 1318.172119140625 L703.943115234375 1318.172119140625 L710.689697265625 1318.172119140625 L717.4363403320312 1318.172119140625 L724.1829833984375 1318.172119140625 L730.9296264648438 1320.4210205078125 L737.6762084960938 1320.4210205078125 L739.9251098632812 1320.4210205078125 L744.4228515625 1320.4210205078125 L746.6717529296875 1320.4210205078125 L748.9205932617188 1320.4210205078125 L753.4183349609375 1320.4210205078125 L755.667236328125 1320.4210205078125 L757.9161376953125 1320.4210205078125 L766.91162109375 1320.4210205078125 L780.4048461914062 1322.6697998046875 L787.1514892578125 1324.918701171875 L798.3958740234375 1324.918701171875 L805.1425170898438 1324.918701171875 L818.6357421875 1324.918701171875 L827.6312255859375 1324.918701171875 L834.3778686523438 1324.918701171875 L836.6267700195312 1324.918701171875 L836.6267700195312 1324.918701171875"></path></svg>"}},"id":"#1534cb55-8365-485e-8ff8-ab094450740a","zoomLevel":0.8185909090909089}];

window.onload = function () {
  var viewer = OpenSeadragon({
    id: "openseadragon",
    prefixUrl:
      "https://cdn.jsdelivr.net/npm/[email protected]/openseadragon/images/",
    tileSources: {
      type: "image",
      url:
        "https://images.unsplash.com/photo-1719937051124-91c677bc58fc?q=80&w=2072&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
    },
    gestureSettingsTouch: {
      pinchRotate: true
    }
  });

  var anno = OpenSeadragon.Annotorious(viewer, {
    locale: "auto"
  });
  anno.setAnnotations(sampleAnnotation);
};
    .openseadragon-canvas {
      outline:none; 
      background-color:#f4f4f4 !important;
      border-radius:3px;
}
<div id="openseadragon" style="width: 1400px; height: 1800px;"></div>

this is a codepen page to reproduce it on real device link to codepen you can open it as a full page and dragg it to see what I mean.

Any suggestions would be helpful

Prevent onMessage activity calling when command is send in the CommandBot

I have scaffolded the project and want to implement the scenario where user can instruct bot to configure itself for the the current conversation through commands and if no command is sent it should then treat it as query.

I have defined the onMessage handler as follows

import {MessageFactory, TeamsActivityHandler, TurnContext} from "botbuilder";

// An empty teams activity handler.
// You can add your customization code here to extend your bot logic if needed.
export class TeamsBot extends TeamsActivityHandler {
  constructor() {
    super();

    this.onMessage(async (context, next) => {
      const query = TurnContext.removeRecipientMention(context.activity);
      await context.sendActivity(MessageFactory.text(`User Query: ${query}`));
      await next();
    });
  }
}

It logs the command request as well. For example, the template provided HelloWorldCommand class which triggers the function on HelloWorld text, bot builder sdk current.

import {Activity, CardFactory, MessageFactory, TurnContext} from "botbuilder";
import {
  CommandMessage,
  TeamsFxBotCommandHandler,
  TriggerPatterns,
} from "@microsoft/teamsfx";
import {AdaptiveCards} from "@microsoft/adaptivecards-tools";
import helloWorldCard from "./adaptiveCards/helloworldCommand.json";
import {CardData} from "./cardModels";

/**
 * The `HelloWorldCommandHandler` registers a pattern with the `TeamsFxBotCommandHandler` and responds
 * with an Adaptive Card if the user types the `triggerPatterns`.
 */
export class HelloWorldCommandHandler implements TeamsFxBotCommandHandler {
  triggerPatterns: TriggerPatterns = "helloWorld";

  async handleCommandReceived(
    context: TurnContext,
    message: CommandMessage
  ): Promise<string | Partial<Activity> | void> {
    // Render your adaptive card for reply message
    const cardData: CardData = {
      title: "Your Hello World App is Running",
      body: "Congratulations! Your Hello World App is running. Open the documentation below to learn more about how to build applications with the Teams Toolkit.",
    };

    const cardJson = AdaptiveCards.declare(helloWorldCard).render(cardData);
    return MessageFactory.attachment(CardFactory.adaptiveCard(cardJson));
  }
}

teams bot

The onMessage callback only works when the query text doesn’t match command pattern.

Adding specific domain for safari web extension

I am writing a safari web extension at the moment in Xcode. I want tab a button inside my popup window which than calls the firebase firestore database to get some data. Therefore I want to include the firestore library in my popup.js script with import { initializeApp, getFirestore, collection } from 'https://www.gstatic.com/firebasejs/10.10.0/firebase-firestore.js'

But as I am doing this I get the error
Refused to load https://www.gstatic.com/firebasejs/10.10.0/firebase-firestore.js because it does not appear in the script-src directive of the Content Security Policy. even tho I have this specific link inside my manifest and in my info.plist file.

This is my info.plist file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSExtension</key>
    <dict>
        <key>NSExtensionAttributes</key>
        <dict>
            <key>SFSafariToolbarItem</key>
            <dict>
                <key>SFToolbarItemClassName</key>
                <string>ViewController</string>
            </dict>
        </dict>
        <key>NSExtensionMainStoryboard</key>
        <string>MainInterface</string>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.Safari.web-extension</string>
        <key>content-security-policy</key>
        <string>default-src 'self'; script-src 'self' https://www.gstatic.com/firebasejs/10.10.0/firebase-firestore.js;</string>
    </dict>
</dict>
</plist>

And this is my manifest file

{
    "manifest_version": 3,
    "default_locale": "en",

    "name": "__MSG_extension_name__",
    "description": "__MSG_extension_description__",
    "version": "1.0",

    "icons": {
        "48": "images/icon-48.png",
        "96": "images/icon-96.png",
        "128": "images/icon-128.png",
        "256": "images/icon-256.png",
        "512": "images/icon-512.png"
    },

    "background": {
        "scripts": "background.js"
    },

    "content_scripts": [{
        "js": [ "content.js" ],
        "matches": [ "*://example.com/*" ]
    }],

    "action": {
        "default_popup": "popup.html",
        "default_icon": {
            "16": "images/toolbar-icon-16.png",
            "19": "images/toolbar-icon-19.png",
            "32": "images/toolbar-icon-32.png",
            "38": "images/toolbar-icon-38.png",
            "48": "images/toolbar-icon-48.png",
            "72": "images/toolbar-icon-72.png"
        }
    },

    "permissions": [ "nativeMessaging", "activeTab", "tabs" ],
    
    "content_security_policy": {
        "extension_pages": "default-src 'self'; script-src 'self' https://www.gstatic.com/firebasejs/10.10.0/firebase-firestore.js; style-src 'self' 'unsafe-inline';"
      }
}

Can you tell me what I am doing wrong and what the correct way of implementing this domain is?

Using JavaScript to move a div from one page to another on click event

I have a page with several divs, each one a photo of a cat and some text and other info (it’s for a cat adoption agency page). Each div has a onclick which calls a JavaScript function and then transfers to a different page (going from page with many cats to page with a single cat).

I have tried a variety of ways to move the clicked on div to the new page but still not successful. I am currently making 2 calls, one when the user clicks on the cat pic, which saves the div to localstorage and then when the new page is loaded a second function is called to try and read and append that div into the new page. Here are the relevant code pieces.

function loadCatProfile() {
  var cat = localStorage.getItem("catProfile");
  var mydoc = document.getElementById("placeholder");

  mydoc.append(cat);
}

function saveCatProfile(profile) {
  localStorage.setItem("catProfile", profile);
  window.location.href = "/singlecat.html";
}

Multi-Cat page that the user clicks….

<!DOCTYPE html>
<html>
  <head>
    <script src="/core/jscript.js"></script>
  </head>

  <body>
    <div class="profile" onclick="saveCatProfile(this)" style="cursor: pointer">
      <img src="/images/martin.webp" < />
      <p>Martin</p>
      <p>8 meses</p>
    </div>

    <div class="profile" onclick="saveCatProfile(this)" style="cursor: pointer">
      <img class="cat-image" src="/images/vimes.webp" < />
      <p id="cat-name">Sir Vimes</p>
      <p class="cat-age">8 meses</p>
    </div>
  </body>
</html>

New single cat page that tries to read


<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <script src="/core/jscript.js"></script>
  </head>

  <body>
    <main>
      <div id="placeholder">
        <p>test</p>
      </div>
    </main>

    <script>
      loadCatProfile();
    </script>
  </body>
</html>

Tried saving then asigning the saved data to innerHTML of destination page, tried appending the saved div as child, read way too many web pages that were close in helping but not successful. This is a plain html/css javascript website, no frameworks or other libs.

Restore default filter for cloned image in fabric js (seems buggy)

As the title says, I use fabric js. In my scenario, I want to apply filters to an image but also undo them (even after saving). However, this seems to be problematic, because whenever I clone an image to edit it with filters, save it and then want to edit it again (e.g. to change the value of the applied filter), the default value (0) is not taken but the already applied value. Even if I delete the filters in the cloned object and set them to an empty array.
For me this seems to be a bug but maybe I am doing something wrong. Can someone help me?

To illustrate, here is a fiddle: https://jsfiddle.net/z568udwn/
Explanation: An image is loaded. When you click on “start filter” it is cloned in a temporary canvas and after 1 second a filter is automatically applied to it. If you then click on “save filter”, it is applied to the main image and the temporary canvas with the cloned object is deleted. If you now click on “start filter” again, you will see the problem I have tried to describe.

code from fiddle:

var addEvent = function(el, type, handler) {
  if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler);
}

var image_base64 = ' data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/...'
var custom_image;
    var copy_canvas;
    var copy_image;

    const canvas = new fabric.Canvas('c', {
      width: 300,
      height: 300,
      backgroundColor: '#ffffff',
      selectable: false,
      selection: false,
      preserveObjectStacking: true,
      allowTouchScrolling: true,
    });
    canvas.renderAll();

    fabric.Image.fromURL(image_base64, (image) => {
      custom_image = image.set({
        top: 0,
        left: 0,
        selectable: false,
        scalable: false,
        controls: false,
      });
      custom_image.scaleToHeight(300);
      custom_image.scaleToWidth(300);
      canvas.add(custom_image);
      canvas.renderAll();
    });

    addEvent(document.querySelector('#start-edit'), 'click', (e) => {
      copy_canvas = new fabric.Canvas('copy-canvas', {
        width: 300,
        height: 300,
        backgroundColor: '#aaaaaa',
        selectable: false,
        selection: false,
        preserveObjectStacking: true,
        allowTouchScrolling: true,
      });
      copy_canvas.renderAll();

      custom_image.clone((img_clone) => {
        img_clone = img_clone.toDataURL();
        fabric.Image.fromURL(img_clone, (image) => {
          copy_image = image.set({
            top: 0,
            left: 0,
            selectable: false,
            scalable: false,
            controls: false,
          });
          copy_image.filters = [];
          copy_image.applyFilters();
          copy_image.scaleToHeight(300);
          copy_image.scaleToWidth(300);
          copy_canvas.add(copy_image);
          copy_canvas.renderAll();

          setTimeout(() => {
            image.filters = [new fabric.Image.filters.Saturation({
              saturation: 0.5
            })];
            image.applyFilters();
            copy_canvas.renderAll();
          }, 1000);
        });
        
      });
    });

    addEvent(document.querySelector('#finish-edit'), 'click', (e) => {
      custom_image.filters = copy_image.filters;
      custom_image.applyFilters();
      canvas.renderAll();
      copy_canvas.dispose();
    });

Web USB / Serial API + led strip KAA332-LH

I wonder if anyone has any experience with the Web USB and controlling a LED strip. I have a basic LED strip. I can connect the device from the browser js, but when I try to do device.open() I’m getting error:
DOMException: Failed to execute ‘open’ on ‘USBDevice’: Access denied.

Funnily enough, when I try to use the Web Serial API, I can open the port and getInfo(). I’m also trying to send some data, but I have no clue what payload to add to simply switch off/on the leds…

Ideally I’d like to stick to Web USB API… any idea how to overcome the Access denied problem?

manufacturerName: "Prolific Technology Inc."
productId: 9123
productName: "KAA332-LH"
serialNumber: "KAA332LH2207"
vendorId: 1659

enter image description here

Blur event flow and synchronization of DOM updates

The following code has this behavior when I focus on the input and then click the delete button:

  1. Mousedown callback function is triggered, however input does not blur immediately cause of ev.preventDefault()

  2. Container gets removed by (at least it should be) the mousedown function.

  3. Blur callback function is then triggered since the removal of the container caused the input to lose focus

  4. It prints the container element in the console, even though I was expecting null. Wasn’t it removed by the mousedown callback function?

  5. It then (in my understanding) removes the container element that for some reason was not removed by the mousedown func.

  6. the mousedown func then doesn’t find an element to remove so it throws a DOMException.

I am not sure if the process happens exactly like I described it. If I comment out the container.remove line in the blur func, first the element will be printed in the console by the blur func and after “null” will be printed by the mousedown func.

I cannot understand how the blur func is seemingly called before the mousedown one. For the blur func to be called the container has to be removed. So how does the blur func find it in the DOM again and how does it remove it if it’s already been removed?

const inp = document.querySelector("input");
const container = document.querySelector("#container");
const btn = document.querySelector("button");

btn.addEventListener("mousedown", (ev) => {
  ev.preventDefault();
  console.log('Before remove',document.querySelector("#container"));  
  container.remove();
  console.log('After remove',document.querySelector("#container"));
});

inp.addEventListener("blur", () => {
  console.log('In blur',document.querySelector("#container"));
  container.remove();
});
<div id="container">
  <input />
  <button>Delete</button>
</div>

using mui-file-input in react-hook-form using react hook form persist to storage data

i have issue when i change mui-file-input, useFormPersist save the
value in storage with array of empty objects and when i reload the
page, i got error because the value not true and the input expected
value be [] or array of objects and has file data, i tried also to prevent
useFormPersist from saving the file input value in storage, it’s not worked also
because this file inside array also

`import { SetFieldValue } from ‘react-hook-form’;
import { MuiFileInput } from ‘mui-file-input’;

   interface FormPersistConfig {
   storage?: Storage;
   watch: (names?: string | string[]) => any;
   setValue: SetFieldValue<any>;
   exclude?: string[];
   onDataRestored?: (data: any) => void;
   validate?: boolean;
   dirty?: boolean;
   onTimeout?: () => void;
   timeout?: number;
  }

declare const useFormPersist: (name: string, { storage, watch, setValue, exclude,
onDataRestored, validate, dirty, onTimeout, timeout }: FormPersistConfig) => {
clear: () => void;
};

export { FormPersistConfig, useFormPersist as default };
const BookingVisa = () => {
       const {
         unregister,
         register,
          control,
          handleSubmit,
          watch,
          setValue,
          clearErrors,
          setError,
           getValues,
           reset,
           formState: { errors },
        } = useForm<BookingInfo>({

    resolver: yupResolver(bookingInfoSchema),
    mode: 'all',
   })

   const [excludeFields, setExcludeFields] = useState<string[]>([]);
   const passengers = watch('passengers') || [];

   useEffect(() => {
     const newExcludeFields = passengers.flatMap((passenger, index) => {
      return [`passengers[${index}].file`, `passengers[${index}].document`];
    });
     setExcludeFields(newExcludeFields);
    }, [passengers]);

   useFormPersist(`bookVisa-${searchId}`, {
       watch,
       setValue,
       exclude: [ ...excludeFields] ,    
})
     const handleFilesChange = async(files: any, index: number, name: any, field: 
         any, inputNum: any) => {
    if(files.length > 3){
        return showMessage(trans(`visa.file${index}.error.length`), 'error')
    }
    field?.onChange(files);
   const form = new FormData()
        for (let i = 0; i < files.length; i++) {
            const reader = new FileReader();
                form.append(`files[${i}]`, files[i]);
            reader.readAsDataURL(files[i]);
        }
        const data = await dispatch(SettingService().uploadImage(form))
        if (data.payload.urls) {
            setValue(`passengers[${index}].${name + 's'}`, data.payload.urls);
            // showMessage(trans(`visa.file${inputNum}.media.success`), 'success')
            if(name === 'file'){
                clearErrors(`passengers[${index}].file`);
            }
        }else{
            setValue(`passengers[${index}].${name + 's'}`, []);
            setValue(`passengers[${index}].${name}`, []);
            showMessage(trans(`visa.file${inputNum}.media.error`), 'error')
            if(name === 'file'){
                setError(`passengers[${index}].file`, { type: "manual", message: 
                      trans(`visa.file${inputNum}.error`) })
            }
            field?.onChange([]);
        }                    
};

return (
 <from id="fromId" method={'post'} onSubmit={handleSubmit(onSubmit)}>
<Controller
     name={`passengers[${index}].file`}
     control={control}
    // defaultValue={[]}
    render={({ field }: any) => {
          return(
              <MuiFileInput
                  label={trans('File Upload 122')}
                  {...field}
                   multiple
                  sx={{ width: '100%' }}
                  inputProps={{ accept: 'image/*,.pdf', maxFiles: 3 }} 
                  onChange={(values: any) => {
                         handleFilesChange(values, index, 'file', field, 1);
                    }}
                   value={field.value}                                            
                  clearIconButtonProps={{ children: <CloseIcon fontSize="small" /> }}
                  error={!!errors.passengers?.length ? 
                        !!errors.passengers[index]?.file : false}
                  helperText={(errors.passengers?.length && 
                                errors.passengers[index]?.file) ? 
                               trans(errors.passengers[index]?.file.message) : 
                               trans('visa.file1.helpertext')}

                 />
             )}}
         />
 </form>
)}

`