Camera not working in iPhone in Web Browsers in Blazor WASM

We have written the below code in blazor WASM where we are trying to capture image of user on web browser.

Index.razor

 <div class="v-canvas">
     <video id="videoFeed" width="320" height="240" />
     <canvas class="d-none" id="currentFrame" width="320" height="240" />
 </div>
  <button @onclick="CaptureFrame">
       <span>Capture</span>
   </button>


@code {
 protected override async Task OnInitializedAsync()
 {
     await JSRuntime.InvokeVoidAsync("startVideo", "videoFeed");

 }

 private async Task CaptureFrame()
 {
     await JSRuntime.InvokeAsync<String>("getFrame", "videoFeed", "currentFrame",DotNetObjectReference.Create(this));
 }

}

 [JSInvokable]
 public async Task ProcessImage(string imageString)
 {

    //Some logic

 }

Javascript Code

function startVideo(src) {
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
            let video = document.getElementById(src);
            if ("srcObject" in video) {
                video.srcObject = stream;
            } else {
                video.src = window.URL.createObjectURL(stream);
                video.webkitMatchesSelector.src = window.URL.createObjectURL(stream);
            }
            video.onloadedmetadata = function (e) {
                video.play();
                video.webkitMatchesSelector.play();
                Play(src);
            };

            //mirror image
            video.style.webkitTransform = "scaleX(-1)";
            video.style.transform = "scaleX(-1)";
        });
    }
}


function getFrame(src, dest, dotNetHelper) {
    let video = document.getElementById(src);
    let canvas = document.getElementById(dest);
    canvas.getContext('2d').drawImage(video, 0, 0, 320, 240);

    let dataUrl = canvas.toDataURL("image/jpeg");
    dotNetHelper.invokeMethodAsync('ProcessImage', dataUrl);
}

The above solution is been published on IIS and tested on multiple devices.

This works perfectly on iPad, MacBook, Windows laptops and android phones.
For iPhones in Safari/Chrome, the video does not loads in browsers at all, even after camera permission is given.

The Reference of this code is taken from – https://wellsb.com/csharp/aspnet/blazor-webcam-capture

Hoisting in function and variable in javascript [duplicate]

Not able to understand output of these code snippets.

console.log(typeof double);  // output=> undefined
var double = 5;


var double = function (n){
    return n*2;
}


console.log(typeof double); // output=> function
var double = 5;

function double(n){
    return n*2;
}
console.log(typeof double); // output=> function
var double;

function double(n){
    return n*2;
}

// it is known that function expression are not hoisted. So output of first snippet is justified. But why we are getting ‘function’ as output in second and third snippet

Not able to understand output of 2nd and 3rd code snippet

bunnyCDN implementation in javascript & react js

Solution Here..

This code is a function who upload images to your bunnyCDN and returns a URL to the uploaded file.
then you can access via link and use to store in db…

import axios from "axios";
import moment from "moment";

// BunnyCDN Storage API endpoint and configuration
const StorageEndpoints = process.env.BUNNYCDN_ENDPOINT; // BUNNYCDN_ENDPOINT is your storage zone accessendpoint
const REGION = ""; // If German region, set this to an empty string: ''
const BASE_HOSTNAME = process.env.BUNNYCDN_HOSTNAME;//this is your storage access ex.:- "storage.bunnycdn.com"
const HOSTNAME = REGION ? `${REGION}.${BASE_HOSTNAME}` : BASE_HOSTNAME;
const STORAGE_ZONE_NAME = process.env.BUNNYCDN_STORAGE_ZONE_NAME; //this your storage zone name in your bunny cdn account
const ACCESS_KEY = process.env.ACESS_KEY; // this is your bunnycdn storge password 

// Function for uploading files to BunnyCDN Storage
/**
 * async function FileUploader(event)
 * @param event is images rawdata pass in this fuction 
 */
async function FileUploader(event) {
  // Extracting the file from the event
  const file = event;

  // Checking if the file is an image
  if (!file?.type?.startsWith("image/")) {
    return;
  }

  // Generating a timestamp and constructing the filename for the uploaded image
  const currentTimestamp = moment().format("YYYYMMDD_HHmmss");
  const fileExtension = file.name.split(".").pop();
  const FILENAME_TO_UPLOAD = `image_${currentTimestamp}.${fileExtension}`;

  try {
    // Sending a request to BunnyCDN Storage API to upload the file
    const response = await axios.put(
      `https://${HOSTNAME}/${STORAGE_ZONE_NAME}/${FILENAME_TO_UPLOAD}`,
      file,
      {
        headers: {
          AccessKey: ACCESS_KEY,
          "Content-Type": file.type,
        },
      }
    );
  } catch (error) {
    // Handling errors during the file upload process
    console.error("Error uploading file:", error);
  }

  // Constructing the full image URL using the BunnyCDN Storage endpoint
  const imageUrl = `${StorageEndpoints}${FILENAME_TO_UPLOAD}`;

  // Returning the uploaded image URL
  return await imageUrl;
}

// Exporting the FileUploader function as the default export
export default FileUploader;

Here’s a corrected version of the explanation for my code:

This code defines a function that uploads images to your BunnyCDN storage and returns a URL for accessing the uploaded file. Here’s a breakdown:

  • It imports necessary modules like axios for making HTTP requests and moment for handling timestamps.
  • The function FileUploader takes an image file as input.
  • It checks if the input file is indeed an image.
  • Timestamp and a unique filename for the uploaded image are generated.
  • Using axios, the file is uploaded to BunnyCDN storage via a PUT request.
  • Error handling is implemented for any potential upload errors.
  • The full URL of the uploaded image is constructed using the BunnyCDN endpoint and filename.
  • Finally, the function returns the URL of the uploaded image.
  • Environment variables like process.env.BUNNYCDN_ENDPOINT, process.env.BUNNYCDN_HOSTNAME, process.env.BUNNYCDN_STORAGE_ZONE_NAME, and process.env.ACESS_KEY are utilized for configuration, which are typically set up in your environment or deployment settings.

==> To set up the required environment variables:

  • BUNNYCDN_ENDPOINT should be the URL for accessing your storage zone.
  • BUNNYCDN_HOSTNAME should be the hostname for your BunnyCDN storage access.
  • BUNNYCDN_STORAGE_ZONE_NAME should be the name of your storage zone.
  • ACESS_KEY should be your BunnyCDN storage password.
  • You can find these values in the BunnyCDN dashboard under Storage Zones, FTP & API Access section.

=> Overall, this function provides a convenient way to upload images to BunnyCDN storage in a React project and retrieve URLs for storing in a database or using elsewhere.

this image for upper desction look like this

i hope so my code help full for you..!

I created a function for uploading images to BunnyCDN and retrieving a URL that grants access to the uploaded image. This function is intended for use in a React project and is implemented in JavaScript. You’re hoping for assistance with this code, and I confident that it works perfectly.

preventing popup closed on clicking esc button in react

So basically I have a pop up it is currently closed on clicking the escape button i don’t want it i want if user click on the escape button it should not close how do i do that?

const [state, setState] = useState({
showEftConsent: false,
});

so this is a state which currently set to false but when login it first time it set to true and pop up is shown then when i click on escape button it set my state to false..

  useEffect(() => {
setState({ ...state, showEftConsent: showEftConsent });
}, [showEftConsent]);

this is my useEffect which only run when showEftConsent value is changed

  const handleEftClose = () => {
  setState({ ...state, showEftConsent: false });
  handleCloseWithoutDismiss();
  };

this is a handleEftClose function which is triggered only when i press escape button so when i click escape button it closed so i don’t want it if i click escape button it should not closed it

{state.showEftConsent ? (
    <EftConsentDialog
      isOpen={state.showEftConsent}
      showEftSuccessDialog={auth && auth.get("showEftSuccessDialog")}
      handleClose={() => handleEftClose()}
      disableBackdropClick={true}
      {...props}
    />
  ) : null}

now the handleEftClose function passed to the prop of EftConsentDialog component

import React, { useContext } from 'react'
import ContentDialog from 'components/common/material.components/content.dialog/content.dialog'
import { Button, CircularProgress, Paper, Switch, Typography } from '@material-ui/core';
import { maskAccountNumber } from 'components/common/util/util'
import { GET_ACCOUNTS, GET_ACCOUNT_DETAIL, ENABLE_EFT_CONSENT } from 'view.updater/actions/accounts.actions';
import { checkExecutionStatus, IsMobileWidth, IsZoom150 } from 'components/common/util/util';
import { AppContext } from './container';
import { useState } from 'react';
import OtpInput from "react-otp-input";
import EftConsentSuccessDialog from './eft.consent.success.dialog';



const EftConsentDialog = (props) => {
const { isOpen, showEftSuccessDialog } = props;
const context = useContext(AppContext);
const execStatusGetAccounts = checkExecutionStatus(context, GET_ACCOUNTS);
const execStatusAccountDetail = checkExecutionStatus(context, GET_ACCOUNT_DETAIL);
const enableEftConsent = checkExecutionStatus(context, ENABLE_EFT_CONSENT)

const mobileWidth = IsMobileWidth()
const zoom150 = IsZoom150()

const [state, setState] = useState({
    selectedAccounts: [],
    pin: "",
    enableStatus: false

})


const redirect = (route) => {
    props.handleCloseWithoutDismiss();
    props.push(route)
}

const onAccountChange = (accountNumber, id) => {
    const accounts = [...state.selectedAccounts]
    const findedAccountNumber = accounts && accounts.findIndex((data) => data.accountNumber === accountNumber)
    if (findedAccountNumber !== -1) {
        const index = accounts.indexOf(findedAccountNumber)
        accounts.splice(index, 1)
    }
    else {
        accounts.push({
            accountNumber: accountNumber,
            id: id
        })
    }
    setState({ ...state, selectedAccounts: accounts })
}


const getEftConsent = () => {
    const filteredEftConsent = props && props.accountDetails && props.accountDetails.filter((data, index) => {
        return data.get("eftConsent") === null || data.get("eftConsent") === ""
    })
    return filteredEftConsent && filteredEftConsent.map((data, index) => {

        return <Paper elevation={2} className='w-100 d-flex justify-content-between m-1 p-2' key={index} >
            {
                execStatusGetAccounts && execStatusGetAccounts.status === "PENDING" || execStatusAccountDetail && execStatusAccountDetail.status === "PENDING" ?
                    <div className='w-100 d-flex justify-content-center'>
                        <CircularProgress />
                    </div> :
                    <React.Fragment>
                        <div className='d-flex flex-column'>
                            <div className='fw-bold'> {data.get('accountTitle')}</div>
                            <div> {maskAccountNumber(data.get('accountNumber'))}</div>
                        </div>
                        <div><Switch
                            onChange={() => onAccountChange(data.get("accountNumber"), data.get("id"))}
                            checked={state.selectedAccounts.find((item) => item.accountNumber === data.get("accountNumber")) ? true : false}
                        /></div>
                    </React.Fragment>
            }
        </Paper>
    })
}

const enableSelected = () => {
    props.enableEftConsent()
}

const accounts = state.selectedAccounts && state.selectedAccounts.map((data, index) => {
    return {
        eftFlag: true,
        accountNumber: data.accountNumber,
        id: data.id
    }
})

const accountsTemp = props.allAccounts && props.allAccounts.filter((data, index) => {
    return !data.get("eftConsent")
}).map((data) => {
    return data.get("number")
})



const onPinChange = (value) => {
   if (value.length === 6) {
        const eftAccounts = []
        props.allAccounts && props.allAccounts.toJS() && props.allAccounts.toJS().forEach((data) => {
            
            const findAccount = state.selectedAccounts && state.selectedAccounts.find((item) => item.accountNumber === data.number)
            if(findAccount) {
                eftAccounts.push({
                    eftFlag: true,
                    accountNumber: data.number,
                    id: data.id
                })
            }
            else {
                eftAccounts.push({
                    eftFlag: false,
                    accountNumber: data.number,
                    id: data.id
                })
            }
        })

       
        props.enableEftConsent({
            accounts: eftAccounts,
            pin: value,
            isFirstTimeLogin: true
        })
    }
    setState({ ...state, pin: value })
}

const closeEftSuccessDialog = () => {
    if (state.selectedAccounts.length >= 1) {
        state.selectedAccounts.forEach((data, index) => {
            props.getAccountDetail(data.id)
        })
    }
    props.handleClose()
    props.resetEnableEftConsent()
    // props.handleClose()
    // console.log(state.selectedAccounts)
}

return (
    <ContentDialog
        onClose={props.handleClose}
        hideCloseButton={true}
        dialogIsOpen={isOpen}
        disableBackdropClick={true}

        notMaxHeight
    >
        {
            showEftSuccessDialog ?
                <EftConsentSuccessDialog
                 {...props}
                 closeEftSuccessDialog={closeEftSuccessDialog}
                /> :
                <div className="w-100" style={{ minHeight: 200 }}>
                    {
                        !state.enableStatus ?
                            <React.Fragment>
                                <div className="d-flex align-items-center p-2 justify-content-center flex-column ">
                                    <div>
                                        <Typography variant='h5' color='secondary' className='fw-bold'>Electronic Funds Transfers (EFT) empower you with digital transfers!</Typography>
                                    </div>
                                    <Typography className='pt-3 ' >
                                        Some of your accounts don’t have EFT turned on. By activating EFT, you will be able to utilize all the banking services available through electronic fund transfers.
                                        To activate, toggle any accounts.
                                    </Typography>
                                </div>
                                <div className="d-flex flex-wrap p-2 pt-3 pb-3 w-100 align-items-center justify-content-center">
                                    {
                                        getEftConsent()
                                    }
                                    <Typography className='pt-3 '>
                                        By my consent “Enable selected”, I agree that Soneri Bank Limited may activate all the banking services available through electronic fund transfers by using any payment instruments, channels or modes to execute all Debit transactions for my accounts in electronic form.
                                    </Typography>
                                </div>
                                <div className='d-flex flex-column w-100'>
                                    <div className='w-100'>
                                        <Button fullWidth variant='text' disabled={execStatusGetAccounts && execStatusGetAccounts.status === "PENDING" || execStatusAccountDetail && execStatusAccountDetail.status === "PENDING" ? true : false} color='secondary' onClick={() => setState({ ...state, enableStatus: true })}>Update EFT Status</Button>
                                    </div>
                                </div>

                            </React.Fragment> :
                            <div className='d-flex w-100 justify-content-center flex-column' style={{ maxHeight: 300 }}>
                                <div className='d-flex ps-2 align-items-center cursor-pointer' onClick={() => setState({ ...state, enableStatus: false })}>
                                    <Typography color='secondary' className='pt-1' variant='h6'>
                                        <i className='fa fa-angle-left'></i>
                                    </Typography>
                                    <Typography variant='h6' color='secondary' className='ps-2'>Back</Typography>
                                </div>
                                {/* {accounts.length === 0 ? 'account' : 'accounts' } ({accountsTemp.join(', ')}) */}
                                <Typography className='w-100 d-flex justify-content-center fw-bold' color='secondary' variant='h5' >You are updating EFT status for your account(s)</Typography>
                                <Typography className='w-100 text-center pt-2 fw-bold' variant='body2'>Proceed by inserting your 6-digits security PIN.</Typography>
                                <div className='w-100 d-flex justify-content-center pt-3'>
                                    <OtpInput
                                        isInputSecure={false}
                                        //isDisabled={execStatus.status === "PENDING" ? true : false}
                                        shouldAutoFocus={true}
                                        onChange={onPinChange}
                                        numInputs={6}
                                        isInputNum={true}
                                        value={state.pin}
                                        separator={<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>}
                                        inputStyle={{
                                            width: mobileWidth || zoom150 ? 20 : 40,
                                            height: mobileWidth || zoom150 ? 20 : 40,
                                            backgroundColor: "#EDEDEC",
                                            border: "none",
                                            borderRadius: 10,
                                            fontFamily: "password"
                                        }}
                                        focusStyle={{
                                            borderRadius: 10,
                                            backgroundColor: "#ffffff",
                                            outline: "none",
                                            boxShadow:
                                                "0px 3px 5px -1px rgba(0,0,0,0.2), 0px 5px 8px 0px rgba(0,0,0,0.14), 0px 1px 14px 0px rgba(0,0,0,0.12)",
                                        }}
                                    />
                                    {
                                        enableEftConsent && enableEftConsent.status === "PENDING" ? <div className='ps-2'><CircularProgress /></div> : null
                                    }
                                </div>
                                {enableEftConsent.status === "ERROR" ? (
                                    <div className="text-danger d-flex justify-content-center font-italic pb-2">
                                        <b>
                                            {" "}
                                            {enableEftConsent.errorDetail && typeof enableEftConsent.errorDetail === 'object'
                                                ? enableEftConsent.errorDetail.get("description")
                                                : "Something isn’t working as it should, please try again"}
                                        </b>
                                    </div>
                                ) : null}

                            </div>
                    }



                </div>
        }
    </ContentDialog>
)
  }
  export default EftConsentDialog

this is my whole EftConsentDialog component and remember handleClose function is also called in the closeEftSuccessDialog in the EftConsentDialog component so i think we need a separate function which occurs on onKeyDown event

I tried to do it but it does not work

Prevent React Native Snap Scroll in Flatlist Header

I’m using a question I asked on reddit as a reference. In the thread I was asking how to implement a copy of Spotify’s snap scroll. I won’t go into detail here, but I want to ask a more technical question about the behavior of FlatList in react native.

What I want to achieve is to have a Flatlist that has a “magnetic scroll” or rather called a “snap scroll” but that has a “fluid”/”normal” scroll in the header (ListHeaderComponent). What I don’t understand is why if for example I use the snapToInteravall property this is also applied to the header, honestly it doesn’t seem like correct behavior to me.
Does anyone have any ideas on possible alternative implementations?

I tried two possible approaches without success:
https://snack.expo.dev/@niccolocase/f0c9c3
https://snack.expo.dev/@niccolocase/f0c9c3

OpenLayer draw remove elemnt after drawend

Using basic example cant add element on map
After drawend event its disapear
in drawend listener element is present
Using code from default example page gives same result

private map: OlMap;
  private drawSource: VectorSource = new VectorSource({
    wrapX: false
  });
  private drawLayer: VectorLayer<VectorSource> = new VectorLayer({
    source: this.drawSource
  });
  private raster =  new TileLayer({
    source: new OSM()
  });    
  private drawAction: Draw;
  private snap: Snap;    
  constructor() {
  }    
  ngOnInit(): void {
    this.initMap();
    this.startDraw();
  }    
  private initMap(): void {

    const mapCentre: number[] =  fromLonLat(this.defaultMapCenter);

    this.map = new OlMap({
      layers: [
        this.drawLayer,
        this.raster
      ],
      target: 'map',
      view: new View({
        center: mapCentre,
        zoom: 8, maxZoom: 22,
      }),
      controls: [],
    });
    this.map.addLayer(basemapLayer);
    })
  }
private startDraw() {
    this.drawAction = new Draw({
      source: this.drawSource,
      type: 'Polygon'
    });

    this.map.addInteraction(this.drawAction);
    this.snap = new Snap({source: this.drawSource});
    this.map.addInteraction(this.snap)

})
}

Before drawend
Before drawend

After
After drawend

Implementing Infinite Generation of Shadow Blocks on Drag

I’m working on a feature that allows shadow blocks to be infinitely generated each time they are dragged. I’ve encountered some limitations while trying to use the Blockly API for this purpose. Previously, I managed to implement a similar functionality by customizing the Connection class in my own fork of Blockly (version 7.20211209.4), but I’m exploring ways to achieve this without directly modifying core Blockly files.

Here’s the context of my question:

I’m aiming to replicate a feature I implemented in a previous version of Blockly, where shadow blocks could be infinitely generated upon dragging. This was achieved by forking Blockly and modifying the Connection class, specifically the createShadowBlock_ function.
Given the potential issues with forking and modifying Blockly directly, I’m looking for advice or alternative approaches within the Blockly API that could allow me to implement this feature.
Could anyone provide insights or suggestions on how to achieve infinite shadow block generation using the current Blockly API or through other recommended practices? Any examples or guidance would be greatly appreciated.

Thank you for your help!

enter image description here

I’ve been working on customizing Blockly’s ConnectionChecker to modify the connection logic for my project. However, I’m stuck and can’t seem to find a way forward. Below is the code snippet I’ve been experimenting with:

`import { Connection, ConnectionChecker } from ‘blockly’;

export default class CustomConnectionChecker extends ConnectionChecker {
canConnectWithReason(
a: Connection | null,
b: Connection | null,
isDragging: boolean,
optDistance?: number,
): number {
if (
a?.getShadowState()
&& !isDragging
) {
console.log(‘CustomConnectionChecker’, a, b, isDragging, optDistance);
}
return super.canConnectWithReason(a, b, isDragging, optDistance);
}
}
`

How to resolve npm peer dependencies? [closed]

Why doesn’t npm allow higher version?

From my understanding, requirements like ‘typescript>=4.2.0’ or ‘typescript>=2.7’ means that version of TypeScript should be higher or equal, so 5.3.3 should be OK.

How to resolve errors on the screenshot? I am trying to run npm install latest for all packages hoping it will somehow be resolved.

enter image description here

Why is the .toSorted() function not available on hackerrank?

I needed to solve a coding exercise without mutating the original array (parameter).
Coding Problem:

Given five positive integers, find the minimum and maximum values that can be calculated by summing exactly four of the five integers. Then print the respective minimum and maximum values as a single line of two space-separated long integers.

Example

The minimum sum is and the maximum sum is . The function prints

16 24

Function Description

Complete the miniMaxSum function in the editor below.

miniMaxSum has the following parameter(s):

arr: an array of integers

Print

Print two space-separated integers on one line: the minimum sum and the maximum sum of of elements.

Input Format

A single line of five space-separated integers.

Constraints

Output Format

Print two space-separated long integers denoting the respective minimum and maximum values that can be calculated by summing exactly four of the five integers. (The output can be greater than a 32 bit integer.)

This was my function:

function miniMaxSum(arr) {
    let minSum = 0;
    let maxSum = 0;
    let maxArray = arr.toSorted((a, b) => (b -a));
    let minArray = arr.toSorted((a, b) => (a - b));
  
    // Write your code here
    console.log(maxArray, minArray)
    for(let i = 0; i < arr.length - 1 ; i++){
        minSum += minArray[i];
        maxSum += maxArray[i];
    }
    console.log(minSum, maxSum)
}

I got this error when I tried to run the code

Error message

I used this instead

function miniMaxSum(arr) {
    let minSum = 0;
    let maxSum = 0;
    let maxArray = [...arr].sort((a, b) => (b - a));
    let minArray = [...arr].sort((a, b) => (a - b));
    // Write your code here

    for(let i = 0; i < arr.length - 1 ; i++){
        minSum += minArray[i];
        maxSum += maxArray[i];
    }
    console.log(minSum, maxSum)
}

Success Message

I just want to know why the toSorted() didn’t work

Thank you

web scrapping is not working using google api

The issue is that the code below is returning null. The goal is to pick up data from a specific website using google api.

for the code its using regex to look for the match but the match is always returning null.

function getMinimumWage() {
  // Specify the URL
  var url = "https://www.epi.org/minimum-wage-tracker/#/min_wage/Washington";

  // Fetch the HTML content of the page
  var response = UrlFetchApp.fetch(url);
  var htmlContent = response.getContentText();

  // Use regular expressions to extract the dollar amount before the next </div> following the phrase "Minimum wage"
  var regex = /Minimum wage.*?<p[^>]*class="main"[^>]*>s*([$0-9.]+)s*</p>.*?</div>/s;
  var match = htmlContent.match(regex);

  // Check if a match is found
  if (match && match.length > 1) {
    var minimumWage = match[1];
    Logger.log("Minimum Wage in Washington: " + minimumWage);
  } else {
    Logger.log("Minimum wage not found on the page.");
  }
}

i even tried searching the simple text below and tried displaying but the result is null

var regex = /Most recent increase/; 
var match = htmlContent.match(regex);
Logger.log(match[1]);

JavaScript: await on Promise does not wait? [closed]

My code is approx. as follows:

async myFunc() {
    await myOtherFunc();
    // I assume success of myOtherFunc() here;
    // It follows: Some more code here to be executed only if 
    // myOtherFunc does NOT throw an exception...
}

Now I observed in both Chrome and Firefox: When myOtherFunc returns a Promise<undefined>, the code after await gets executed (and an unhandledrejection event is thrown later).

When myOtherFunc returns some proper stuff, it works as intended: Code after await is NOT executed, the exception gets thrown before.

Is this documented behaviour, has somebody experience or can point me to the docs?
Thank You.

Style the border based on a condition

I have a card that when the user click on it, the border color should change. It’s working fine in the multi select. However, it doesn’t work in single select. I want the border color to change for the active element only if multi select is false. So the user would know they can select only one.

Here’s my code:

const LibraryPicCard: FC<{
    pixList: any;
    thumbnailUrl: string;
    picName: string;
    multiSelect: boolean;
    onCardClick: (fileUrl: string) => void;
}> = ({
    pixList,
    thumbnailUrl,
    picName,
    multiSelect,
    onCardClick
}) => {

    const theme = useTheme();
    const [selected, setSelected] = useState(false);
    const [activeItem, setActiveItem] = useState("");

    return (
        <Card
            sx={{
                maxHeight: 300,
                width: 150,
                border: selected ? `1px solid ${theme.palette.primary.main}` : "none"
            }}
            onClick={()=>{
                onCardClick(thumbnailUrl);
                setActiveItem(thumbnailUrl);
                // setSelected(prevCheck => !prevCheck);

                if (multiSelect) {
                    setSelected(prevCheck => !prevCheck);
                } else {
                    const isSelected = !!pixList.find((element:any) => element._id === activeItem);
                    setSelected(isSelected);
                }
            }}
        >
            <CardMedia
                image={ thumbnailUrl }
                sx={{ height: 150, width: 150 }}
            />
            <CardContent>
                <Typography>{ picName }</Typography>
            </CardContent>
        </Card>
    );
};

export default LibraryPicCard;

Improve Speed Performance for My Landing Page Builder Project Using Grapesjs and React

I’m currently works in landing page builder project using grapesjs, it works properly like what I expected, the only problems is the page is very slow whenever i drag and drop the block/components to the canvas, i add over 20 template blocks/components.

 useEffect(() => {
    getFileAssets();

    const editor = grapesjs.init({
      container: '#gjs',
      allowScripts: 1,
      selectorManager: { escapeName },
      canvas: {
        scripts: ['"https://cdn.jsdelivr.net/npm/npm link name", "another script link"']
      },
      plugins: [
        myPlugin,
        customCodePlugin,
        presetPlugin,
        pluginGrapesjsBlocksBasic,
        gjsForms,
        tailwindPlugin
      ],
      pluginsOpts: {
        [myPlugin]: {},
        [customCodePlugin]: {},
        [presetPlugin]: {},
        [pluginGrapesjsBlocksBasic]: {},
        [gjsForms]: {},
        [tailwindPlugin]: {
          config: templateConfig
        },
      }
    });

    getDataStorage(editor)
    getAllPanels(editor)
    getTitle(editor)

    editor.Panels.addPanel({
      id: 'panel-top',
      el: '.panel__top',
    });

    editor.runCommand('get-tailwindCss')
    const blockManager = editor.Blocks;

    blockManager.render();

    blockManager.getCategories();

    heroGrapesJs.call().map((x) =>
      blockManager.add(x.label,{
        label: `<img src="${x.image}" alt="${x.label}" >`,
        content: x.content,
        category: 'Hero',
        attributes: {
          title: 'Insert Image block',
          src: x.image,
          alt: x.label
        }
      })
    )

    blockManager.render()

    return () => {
      editor.destroy();
    };

  },[templateConfig]);

  return (
    <Stack width="full" height="full">
      <div>
        <div className="panel__top">
          <div className="panel__basic-actions"></div>
          <div className="panel__basic-display"></div>
        </div>
        <div id="gjs"></div>
      </div>
    </Stack>
  );
}

is there a way to improve the speed? or could it be the problem is the way i handle my function? or maybe i installed too many plugins?

the code works fine, the only problem is in the speed performance. I thought the tailwind plugins is the cause of the performance issue, but modifying the plugin is not fix the problem

How to know at what index some substring exists, if substring is given?

Say for example we are provided with this string,


This is a new ball.” (total length = 19) , let the substring be “a new

and also we are given a string with the substring omitted “This is ball.

Taking the string as an array of chars, we can see the substring starts at index : 8 , how can we find this programmatically ?


I thought of using RegExp but I don’t have much knowledge in that. I’m trying to avoid looping over chars as if the innerHTML gets bigger sometimes it may take time, any other approaches

The problem i m trying to solve with this is say I have this text (innerHTML content):

<p>This is a <b>bold</b> text</p>

now the substring being <b>bold</b> and without substring being <p>This is a text</p> .

I want to get the start index so that I can inject a special character there , result be like: (inserted marker : &*)

<p>This is a &*<b>bold</b> text</p>

Any ideas ?