Where is the iOS WKWebView Camera integration enabled?

I have tried the code and options in the answers here iOS WKWebview: Always allow camera permission
to make a webcam integration in Javascript as usual.

I still can’t get it to work – console log showing “getUserMedia is not implemented in this browser”.

The app delegate class:

import Foundation
import WebKit
class MyDelegate: NSObject, WKUIDelegate {

    // Handle media capture permissions
    func webView(_ webView: WKWebView,
                 requestMediaCapturePermissionFor origin: WKSecurityOrigin,
                 initiatedByFrame frame: WKFrameInfo,
                 type: WKMediaCaptureType,
                 decisionHandler: @escaping (WKPermissionDecision) -> Void) {
        // Always grant permission for demonstration purposes
        decisionHandler(.grant)
        
    }
    
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
            print("JavaScript alert with message: (message)")
            completionHandler()
        }

}

The ContentView Swift for main swiftUI:

import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    let htmlFileName: String
    let delegate = MyDelegate()

    func makeUIView(context: Context) -> WKWebView {
        let webViewConfiguration = WKWebViewConfiguration();
                webViewConfiguration.allowsInlineMediaPlayback = true;
        let webView = WKWebView(frame:.zero, configuration:webViewConfiguration)
        webView.configuration.preferences.javaScriptEnabled = true;
        webView.uiDelegate = delegate
        webView.isInspectable = true   //////////////// DEBUGGING purpose
        webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
        return webView
    }

    func updateUIView(_ webView: WKWebView, context: Context) {
        if let url = Bundle.main.url(forResource: htmlFileName, withExtension: "html") {
            
            webView.loadFileURL(url, allowingReadAccessTo: url)
            
        }
    }
    
}

struct ContentView: View {
    var body: some View {
        WebView(htmlFileName: "index") // Replace "index" with your HTML file name
            .edgesIgnoringSafeArea(.all)
    }
}

Output on the map leaflet js big data from .shp-file

I have a shp file with big data-polygon that needs to be displayed on a leaflet map. First, I tried to convert .shp to geoJson. The data was displayed, but the load on the client device was very high – everything was freezes very much. After that, I tried to convert shp to mbiles using qgis, the map stopped freezes, but loading the mbiles file takes a long time. Perhaps there is some general approach to displaying big data in leaflet?

Loading a model with GLTFLoader through Web Worker causes mesh deformation on SkinnedMesh

My page is taking a long time to load because of the loading of the models that I do as soon as the page loads

During loading in the main thread, page interactions, such as hover effects, etc., stop working

One of the ideas I had to try to solve this was to load the models through the web worker

The page freezing decreased a lot, to almost 0!

However, when I added the models to the scene, they were all deformed

Example of a working model (loaded from the main thread) and the same models, loaded by the web worker

I’ve tried to debug this a lot but I have no idea what it could be or what it might have to do with it

This is the minimal reproducible example

index.html

<body>
    <canvas id="canvas-container"></canvas>

    <button id="default-intantiating-button" class="
        h-8 w-40
        bg-green-600
        rounded-md

        hover:bg-yellow-600
        ">
        <span> default loading </span>
    </button>

    <button id="web-worker-intantiating-button" class="
        h-8 w-40
        bg-green-600
        rounded-md

        hover:bg-yellow-600
        ">
        <span> Web Worker loading </span>
    </button>

</body>

<script type="importmap">
    {
        "imports": {
            "three": "https://esm.sh/[email protected]/build/three.module.js",
            "three/addons/": "https://esm.sh/[email protected]/examples/jsm/"
        }
    }
</script>

<script src="https://cdn.tailwindcss.com"></script>

<script type="module">
    // base libs
    import * as THREE from 'three';
    import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
    import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';

    // dependencies
    let _glbLoader = new GLTFLoader();
    // state
    let _isSceneInstantiated = false;
    // models
    let _itemsContainer = undefined;
    let _baseSkeleton = undefined;
    // animation
    let _clock = new THREE.Clock();
    let _skeletonMixer = undefined;
    // parts
    let _scene = undefined;
    let _camera = undefined;
    let _renderer = undefined;


    let InstantiateScene = (hasToLoadWithWebWorker = true) =>
    {
        if (!_isSceneInstantiated)
        {
            _isSceneInstantiated = true;

            let canvas = document.getElementById('canvas-container');
            canvas.classList.remove('hidden');
            let rect = canvas.getBoundingClientRect();

            _scene = new THREE.Scene();
            _camera = new THREE.PerspectiveCamera(30, rect.width / rect.height, 0.1, 1000);
            _renderer = new THREE.WebGLRenderer({ canvas: canvas, });
            _renderer.setSize(rect.width, rect.height);
            _renderer.setAnimationLoop(animate);
            const geometry = new THREE.BoxGeometry(0.4, 0.4, 0.4);
            const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
            const cube = new THREE.Mesh(geometry, material);
            _scene.add(cube);
            _camera.position.z = 5;

            function animate()
            {
                cube.rotation.x += 0.01;
                cube.rotation.y += 0.01;

                let deltaTime = (60.0 / 1000.0);

                if (_clock)
                    deltaTime = _clock.getDelta();

                if (_skeletonMixer)
                    _skeletonMixer.update(deltaTime);

                if (_renderer)
                    _renderer.render(_scene, _camera);
            }

            _scene.background = new THREE.Color("rgb(10, 80, 10)");

            SetupInitialState(hasToLoadWithWebWorker);
        }
    }

    let DestroyScene = () =>
    {
        if (_isSceneInstantiated)
        {
            _isSceneInstantiated = false;

            _scene = undefined;
            _camera = undefined;
            _renderer = undefined;

            let canvas = document.getElementById('canvas-container');
            canvas.classList.add('hidden');
        }
    }

    let SetupInitialState = (hasToLoadWithWebWorker = true) =>
    {
        _itemsContainer = new THREE.Group();
        _scene.add(_itemsContainer);

        _itemsContainer.position.set(0, -1, 0);

        InstantiateLights();

        let onFinishCallback = () =>
        {
            let blueMaterial = new THREE.MeshStandardMaterial({ color: 0x0000ff });
            let redMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });

            InstantiateDynamicBodyPart('default-male-body-01-model-01.glb', blueMaterial, hasToLoadWithWebWorker);
            InstantiateDynamicBodyPart('default-male-shirt-01-model-01.glb', redMaterial, hasToLoadWithWebWorker);
        }

        InstantiateBaseSkeleton(onFinishCallback, hasToLoadWithWebWorker)
    }

    let InstantiateLights = () =>
    {
        const mainUpLight = new THREE.DirectionalLight(0xffffff, 2);
        const secondaryUpLight = new THREE.DirectionalLight(0xffffff, 1);

        mainUpLight.position.set(20, 30, 10);
        mainUpLight.target.position.set(0, 0, 0);
        mainUpLight.castShadow = true;

        secondaryUpLight.position.set(-20, 30, -10);
        secondaryUpLight.target.position.set(0, 0, 0);
        secondaryUpLight.castShadow = true;

        const reverseLight1 = new THREE.DirectionalLight(0xffffff, 1);
        const reverseLight2 = new THREE.DirectionalLight(0xffffff, 1);

        reverseLight1.position.set(20, -30, -10);
        reverseLight1.target.position.set(0, 0, 0);
        reverseLight1.castShadow = false;
        reverseLight2.position.set(-20, -30, 10);
        reverseLight2.target.position.set(0, 0, 0);
        reverseLight2.castShadow = false;

        const ambientLight = new THREE.AmbientLight(0xaaaaaa); // soft white light

        _scene.add(ambientLight);
        _scene.add(mainUpLight);
    }

    let InstantiateBaseSkeleton = async (onFinishCallback, hasToLoadWithWebWorker = true) =>
    {
        let onFinishCallback2 = (baseModel) =>
        {
            if (baseModel)
            {
                _itemsContainer.add(baseModel);

                let skeletonHelper = new THREE.SkeletonHelper(_scene);
                _scene.add(skeletonHelper)

                let baseBones = [];

                baseModel.traverse(
                    (object) =>
                    {
                        switch (object.type)
                        {
                            case 'Bone':
                                baseBones.push(object);
                                break;
                        }
                    });

                _baseSkeleton = new THREE.Skeleton(baseBones);

                let charAnimationGroup = new THREE.AnimationObjectGroup(baseModel);
                _skeletonMixer = new THREE.AnimationMixer(charAnimationGroup);

                if (baseModel.animations.length > 0)
                {
                    let currentAnimation = _skeletonMixer.clipAction(baseModel.animations[1]);
                    currentAnimation.play();
                }

                let finalScale = 1;
                let finalPositionX = 0;
                let finalPositionY = 0;

                baseModel.scale.set(finalScale, finalScale, finalScale);
                baseModel.position.set(finalPositionX, 0, finalPositionY);
            }

            onFinishCallback();
        };

        let baseModel = await LoadObject3D('default-skeleton-01.glb', onFinishCallback2, hasToLoadWithWebWorker);
    }

    let InstantiateDynamicBodyPart = (
        modelFileName,
        baseMaterial,
        hasToLoadWithWebWorker = true) =>
    {
        let onFinishCallback = (baseModel) =>
        {
            if (baseModel)
            {
                let skinnedMeshesList = [];

                baseModel.traverse(
                    (object) =>
                    {
                        switch (object.type)
                        {
                            case 'SkinnedMesh':
                                skinnedMeshesList.push(object);
                                break;
                        }
                    });

                InjectMaterial(baseModel, baseMaterial);

                skinnedMeshesList.map(
                    (skinnedMesh) =>
                    {
                        _itemsContainer.add(skinnedMesh);
                        skinnedMesh.skeleton = _baseSkeleton;
                    });
            }
        }

        LoadObject3D(modelFileName, onFinishCallback, hasToLoadWithWebWorker);
    }

    let InjectMaterial = (baseModel, material) =>
    {
        if (baseModel)
        {
            baseModel.traverse(
                (object) =>
                {
                    if (object.isMesh)
                        object.material = material;
                });
        }
    }

    let GetRandomId = (length) =>
    {
        let result = '';

        const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
        const charactersLength = characters.length;
        let counter = 0;
        while (counter < length)
        {
            result += characters.charAt(Math.floor(Math.random() * charactersLength));
            counter += 1;
        }

        return result;
    }

    let LoadObject3D = (assetSubPath, onFinishCallback, hasToLoadWithWebWorker = true) =>
    {
        let value = undefined;

        let assetsRootPath = 'https://y87vj9.csb.app/public/';
        let assetPath = assetsRootPath + assetSubPath;

        if (!hasToLoadWithWebWorker)
        {
            if (!value)
            {
                console.log('[default loading] > loading model... | assetPath =', assetPath);

                let onSuccessCallback =
                    (modelGLTF) =>
                    {
                        console.log('[default loading] >>> model loaded! | assetPath =', assetPath);

                        let moodelObject3D = SkeletonUtils.clone(modelGLTF.scene.clone());
                        moodelObject3D.animations = modelGLTF.animations;

                        onFinishCallback(moodelObject3D);
                    };

                _glbLoader.load(assetPath, onSuccessCallback);
            };
        }
        else
        {
            if (typeof Worker !== 'undefined')
            {
                let requestId = GetRandomId(16);
                _webworkersCallbacksById[requestId] = onFinishCallback;

                let webworkerRequest =
                {
                    RequestId: requestId,
                    ProcessName: 'LoadModel',
                    Params: [assetPath],
                }

                _worker.postMessage(JSON.stringify(webworkerRequest));
            }
            else
            {
                // Web workers are not supported in this environment.
                // You should add a fallback so that your program still executes correctly.
                console.error('$$q> AssetsService.GetAsset | Web workers are not supported in this environment!');
            }
        }
    }




    // region Worker
    // state
    let _webworkersCallbacksById = {};

    let HandleWebworkerMessage = (data) =>
    {
        // let webworkerResponse = JSON.parse(data);
        let webworkerResponse = JSON.parse(data.data);
        let requestId = webworkerResponse.RequestId;
        let baseModel = undefined;

        if (webworkerResponse.RawResponse)
        {
            let object3DJSON = webworkerResponse.RawResponse;

            const loader = new THREE.ObjectLoader();
            baseModel = loader.parse(object3DJSON);
        }
        else
            console.error('$> webworkerResponse.RawResponse is undefined! ');

        let isCallbackRegistered = requestId in _webworkersCallbacksById;

        if (isCallbackRegistered)
        {
            let callback = _webworkersCallbacksById[requestId];

            callback(baseModel);
            delete _webworkersCallbacksById[requestId];
        }
        else
            console.error('$> Unexpected requestId! requestId = ', requestId);
    }

    const _worker = new Worker("/model-loading-worker.js", { type: 'module' });
    _worker.onmessage = HandleWebworkerMessage;
    //end region Worker

    let DefaultIntantiatingButton = () =>
    {
        DestroyScene();
        InstantiateScene(false);
    }
    
    let WebWorkerIntantiatingButton = () =>
    {
        DestroyScene();
        InstantiateScene(true);
    }

    let SetupButtons = () =>
    {
        let defaultIntantiatingButton = document.querySelector('#default-intantiating-button');
        let webWorkerIntantiatingButton = document.querySelector('#web-worker-intantiating-button');

        defaultIntantiatingButton.onclick = DefaultIntantiatingButton;
        webWorkerIntantiatingButton.onclick = WebWorkerIntantiatingButton;
    }

    SetupButtons();
    DefaultIntantiatingButton();

</script>

model-loading-worker.js

import { GLTFLoader } from 'https://esm.sh/[email protected]/examples/jsm/loaders/GLTFLoader.js';


// dependencies
let _glbLoader = new GLTFLoader();

let HandleMessage = async (request) =>
{
    let response = {};
    response.RequestId = request.RequestId;

    switch (request.ProcessName)
    {
        case 'LoadModel':
            {
                let assetPath = request.Params[0];
                console.log('[web worker] > loading model... | assetPath =', assetPath);

                let onSuccessCallback =
                    (modelGLTF) =>
                    {
                        console.log('[web worker] >>> model loaded! | assetPath =', assetPath);

                        let finalAssetValue = modelGLTF.scene;

                        finalAssetValue.animations = modelGLTF.animations;

                        let finalAssetValueObject3DJSON = finalAssetValue.toJSON()
                        response.RawResponse = finalAssetValueObject3DJSON;
                    }

                await _glbLoader.loadAsync(assetPath).then(onSuccessCallback);

                break
            }

        default:
            {
                console.error('Unexpected request.ProcessName! | request.ProcessName =', request.ProcessName);
                break;
            }
    }

    return response;
}

addEventListener(
    'message',
    async ({ data }) =>
    {
        let webworkerRequest = JSON.parse(data, function (key, value)
        {
            return value;
        });

        let response = await HandleMessage(webworkerRequest);
        data = JSON.stringify(response);

        postMessage(data);
    });

I’ll leave a link below to a practical example on codesandbox with reproduction (change between loading modes by changing the state of the checkbox in the lower right corner and then press “Instatiate Scene”. The buttons have a yellow hover to test with the mouse if the page is really stuck during loading, as well as the cube animation)

https://codesandbox.io/p/sandbox/y87vj9

Any help or guidance will be very welcome, I’ve been trying to find a way to improve the optimization of this page for about 2 weeks, and this was the only thing that had a good result in performance, however, it’s not working.

Auto hide animation after x seconds

I have a a react project where i am importing a third party lib which has some reusable components like input etc. I want to update the styles of the component and a animation to the border. I was able to make it work and here is the demo

Demo

Now my requirement is, i want to hide this animation after 10 sec. Basically stop animation after 10 sec and remove the border-image animation. Is there a way to do this just by using css ? I tried making border-image: none after 100% of keyframe but nothing worked. Please help.

I am not able run vite project in which I am using react 19 and tailwind css version 4 [closed]

Error I get when I run npm run dev or yarn dev:

failed to load config from C:fekey-nest-FEvite.config.ts
error when starting dev server:
Error: Cannot find module ‘../lightningcss.win32-x64-msvc.node’
Require stack:

  • C:fekey-nest-FEnode_moduleslightningcssnodeindex.js
    at Function._resolveFilename (node:internal/modules/cjs/loader:1225:15)
    at Function._load (node:internal/modules/cjs/loader:1055:27)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:220:24)
    at Module.require (node:internal/modules/cjs/loader:1311:12)
    at require (node:internal/modules/helpers:136:16)
    at Object.<anonymous> (C:fekey-nest-FEnode_moduleslightningcssnodeindex.js:22:22)
    at Module._compile (node:internal/modules/cjs/loader:1554:14)
    at Object..js (node:internal/modules/cjs/loader:1706:10)
    at Module.load (node:internal/modules/cjs/loader:1289:32)

I have tried unistalling node modules and reinstall and tried addin lightningcss

i have node version 22.14.0

Can anyone help me??

how to use hooks like useLocation with @react-router/fs-routes

I have a react app using react-router / nx / vite. When I setup the project, I choose ssr: true, and I now have the following

react-router.config.ts

import type { Config } from "@react-router/dev/config";

export default {
  ssr: true,
} satisfies Config;

routes.tsx

import { type RouteConfig } from "@react-router/dev/routes";
import { flatRoutes } from "@react-router/fs-routes";

export default flatRoutes() satisfies RouteConfig;

root.tsx

import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
  type MetaFunction,
  type LinksFunction,
} from 'react-router';

import '../styles.css';
import EntryCommon from './entry.common';

export const meta: MetaFunction = () => [
  {
    title: 'New Nx React Router App',
  },
];

export const links: LinksFunction = () => [
  { rel: 'preconnect', href: 'https://fonts.googleapis.com' },
  {
    rel: 'preconnect',
    href: 'https://fonts.gstatic.com',
    crossOrigin: 'anonymous',
  },
  {
    rel: 'stylesheet',
    href: 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap',
  },
];

export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <EntryCommon>{children}</EntryCommon>
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

export default function App() {
  return <Outlet />;
}

Now, the issue I face is, when, inside a route in my apps/routes/ folder (for exemple the default _index.ts), I use a hook like useLocation or useNavigate my app will not work and return an error

chunk-KNED5TY2.mjs:188
Uncaught Error: useNavigate() may be used only in the context of a component.

But I dont get why would I need to wrap around a Router since I use route file convention.

What is the correct setup ?

Thank you

React useEffect, DOM, mount, rendering [duplicate]

I’m currently learning React and I don’t understand what the above concepts mean

useEffect(function, deps)

useEffect (() => {
  console.log('mout')
}, []);


useEffect (() => {
  console.log('rendering')
});

useEffect (() =>{
  console.log(name);
  console.log("update");
}[name]);

useEffect (() => {
  console.log('rendering')
  return () =>{
    console.log("what the");
  }
});
useEffect (() => {
  console.log('rendering')
  return () =>{
    console.log("what the");
  }
}[]);

useEffect (() => {
  console.log('rendering')
  return () =>{
    console.log("what the");
  }
}[name, age <- ????]);

The five concepts above are all different, so it’s hard to understand what’s going on.
Even if I ask gpt, I can’t understand because I don’t have the basic concepts.

How to resolve React hydration mismatch error to render third party data dumped from script tag?

The following third-party code is written in the CK editor in drupal in source mode:

    <script>
    window.page = 'gidd';
    </script><!-- On new release, please update the bundle count so that cache is busted --><!-- Add react-website-component script and styles here -->
 <script defer="" src="https://release-website-components.idmcdb.org/js/runtime.bundle.js?bundle=3"></script>
<script defer="" src="https://release-website-components.idmcdb.org/js/main.bundle.js?bundle=3"></script>
<link href="https://release-website-components.idmcdb.org/css/main.css?bundle=3" rel="stylesheet"><!-- end -->

Now, in the following React component (DatabasePage), we’re showing the third party data, that is rendering fine in frontend:

import { graphql } from "gatsby";
import React from "react";
import { Col, Container, Row } from "react-bootstrap";
import ExtractRichText from "../../molecules/ExtractRichText";
import "./database.scss";
import Seo from "../../atoms/seo";

const DatabasePage = ({ data }) => {
  return (
    <>
      <Container className="database-container">
        <Row>
          <Col>
            {/* <ExtractRichText
              richText={data?.nodeDatabasePage?.body?.value}
            ></ExtractRichText> */}
            <div
              dangerouslySetInnerHTML={{
                __html: data.nodeDatabasePage.body.value,
              }}
            />
          </Col>
        </Row>
      </Container>
    </>
  );
};

export default DatabasePage;

export const pageQuery = graphql`
  query ($id: String!) {
    nodeDatabasePage(id: { eq: $id }) {
      title
      body {
        value
      }
      field_meta_tags {
        description
        keywords
      }
      path {
        alias
      }
      relationships {
        field_metatag_image {
          url
        }
      }
    }
  }
`;

export const Head = ({ data }) => (
  <Seo
    title={data?.nodeDatabasePage?.title}
    image={data?.nodeDatabasePage?.relationships?.field_metatag_image?.url}
    description={data?.nodeDatabasePage?.field_meta_tags?.description}
    keywords={data?.nodeDatabasePage?.field_meta_tags?.keywords}
    url={data?.nodeDatabasePage?.path?.alias}
  />
);

Now we’ve modified the above component to the following:

import { graphql } from "gatsby";
import React from "react";
import { Col, Container, Row } from "react-bootstrap";
import ExtractRichText from "../../molecules/ExtractRichText";
import "./database.scss";
import Seo from "../../atoms/seo";

const DatabasePage = ({ data }) => {
  return (
    <>
      <Container className="database-container">
        <Row>
          <Col>
            <ExtractRichText
              richText={data?.nodeDatabasePage?.body?.value}
            ></ExtractRichText>
          </Col>
        </Row>
      </Container>
    </>
  );
};

export default DatabasePage;

export const pageQuery = graphql`
  query ($id: String!) {
    nodeDatabasePage(id: { eq: $id }) {
      title
      body {
        value
      }
      field_meta_tags {
        description
        keywords
      }
      path {
        alias
      }
      relationships {
        field_metatag_image {
          url
        }
      }
    }
  }
`;

export const Head = ({ data }) => (
  <Seo
    title={data?.nodeDatabasePage?.title}
    image={data?.nodeDatabasePage?.relationships?.field_metatag_image?.url}
    description={data?.nodeDatabasePage?.field_meta_tags?.description}
    keywords={data?.nodeDatabasePage?.field_meta_tags?.keywords}
    url={data?.nodeDatabasePage?.path?.alias}
  />
);

We’ve used ExtractRichText component, that’s handing parsing the code and render in the frontend.

Now the ExtractRichText component looks like following:

import * as React from "react";
import parse from "html-react-parser";
import { useFileFile } from "../../hooks/useFileFile";
import { useMediaFileFile } from "../../hooks/useMediaFileFile";
import "./extractRichText.scss"
export const ExtractRichText = ({ richText, extraClasses }) => {
  const drupalIDs = useFileFile().map((e) => e?.node?.drupal_id);
  const allFiles = useFileFile().map((e) => e?.node);
  const allMediafiles = useMediaFileFile().map((e) => e?.node);
  let body = "";
  if (richText) {
    body = extractImage(drupalIDs, richText, extraClasses, allFiles, allMediafiles);
  }
  return <div className={`rich-text ${extraClasses}`}>{body}</div>;
};
function extractImage(drupalIDs, body, extraClasses, allFiles, allMediafiles) {
  return parse(body, {
    transform: (node) => {
      if (node.type === "img" || node.type === "drupal-entity" || node.type === "drupal-media") {
        const currentFile = allFiles.find((file) => node.props["data-entity-uuid"] === file?.drupal_id);
        let imageUrl = currentFile?.publicUrl;
        let mediaUrl;
        let alt;
        if (node.type === "drupal-media") {
          const currentMedia = allMediafiles.find((media) => node.props["data-entity-uuid"] === media?.drupal_id);
          mediaUrl = currentMedia?.relationships?.field_media_image?.publicUrl;
          alt = currentMedia?.field_media_image?.alt;
        }
        const imgAlign = node.props["data-align"] || "";
        const height = node.props["height"];
        const width = node.props["width"];
        let src = imageUrl || mediaUrl || node.props["src"];
        if (src === node.props["src"]) {
          const isRelative = !/^https?:///i.test(src);
          if (isRelative) {
            const base = process.env.GATSBY_DRUPAL_URL.replace(//+$/, '');
            const path = src.replace(/^/+/, '');
            src = `${base}/${path}`;
          }
        }
        const imgStyles = {};
        if (width) {
          imgStyles.width = `${width}px !important`;
        } else {
          // imgStyles.width = `100%`;
        }
        if (height) {
          imgStyles.height = `auto`;
        } else {
          // imgStyles.height = `100%`;
        }
        return (
          <span className={`imgAlign-${imgAlign}`}>
            <img
              style={imgStyles}
              loading="lazy"
              className={`${extraClasses ?? ''} ${node?.type == 'drupal-media' ? 'w-100' : ''}`}
              alt={node?.props?.alt || alt || "image"}
              src={`${src}`}
            />
          </span>
        );
      }
      if (node.type === 'a' && node.props["data-entity-type"] === 'file') {
        const currentFile = allFiles.find((file) => node.props["data-entity-uuid"] === file?.drupal_id);
        const href = node.props["href"] || "";
        const fallbackImage = process.env.GATSBY_DRUPAL_URL + href;
        return (
          <a
            href={`${currentFile?.url || fallbackImage}`}
            target={`${node.props["target"] || ""}`}
            class={`${node.props["className"] || ""}`}
            aria-label={`${node.props['aria-label'] || ""}`}
            id={`${node.props["id"] || ""}`}
            rel={`${node.props["rel"] || ""}`}
          >{`${node.props["children"] || "Link"}`}</a>
        );
      }
      return node;
    },
  });
}
export default ExtractRichText;

But, after using ExtractRichText in DatabasePage component, we’re getting the following runtime errors and third party data are not showing as well:

throw new Error('Text content does not match server-rendered HTML.');
throw new Error('Hydration failed because the initial UI does not match what was ' + 'rendered on the server.');
var recoverableError = createCapturedValueAtFiber(new Error('There was an error while hydrating. Because the error happened outside ' + 'of a Suspense boundary, the entire root will switch to ' + 'client rendering.'), workInProgress); 

My assumption:
This happens because the HTML generated on the server (SSR) differs from what the client renders during hydration, and React throws a hydration error when it can’t reconcile them.

Conext: We’re dumping third-party code is written in the CK editor in
drupal in source mode.

How to fix these above errors and ensure that third-party data is rendering fine in front end?

performance language and framework [closed]

What is the best programming language and framework in the future list? I want to know that very much, Curiosity.

I hope I got the best solution in here that’s perfect and right information.
Many places and resources try it, but I think it is not perfect. Finally, I realized that I could ask a question for Stack Overflow developer team.

Error importing lodash in components when using Histoire

I’m using lodash for a number of things, and all works well. That is, until I try to write stories in Histoire. Everything works, except for lodash. Anytime a component uses lodash, I get one of two errors, depending on how I try to import

import cloneDeep from 'lodash/cloneDeep':

“The requested modules ‘xxxxx/lodash/cloneDeep.js’ does not provide an
export named ‘default'”

import { cloneDeep } from 'lodash':

The requested module ‘xxxxx/lodash/lodash.js’ does not provide an export named ‘clondeDeep'”

What is it about lodash that Histoire doesn’t like, and how do I get around it?

Why do I keep getting invalid email from my input field? EmailJS

I am currently developing an e-portfolio website while building and reaching the final steps for the website I have run into a problem with my input field section where I am giving employers a chance to connect with me through the website. However, as I have coded it I keep getting an “invalid email” popup but I am not sure as to why. Below I have provided a snippet of the code, as well as a screenshot of the invalid email error message, albeit with my actual email address marked out.enter image description here

import { useState, useEffect } from "react"
import "./style.css"
import BackgroundLines from "../BackgroundLines"
import ParaWriting from "../ParaWriting"
import { motion, useAnimation } from "framer-motion"
import ArrowUpRightIcon from "../../assets/Icon/arrow-up-right.svg"
import { useInView } from "react-intersection-observer"
import Button from "../Button"
import Time from "../Time"

// emailjs
import emailjs from "@emailjs/browser"

// JSON
import emailjsconfig from "../../constants/emailjs.json"
import Alert from "../Alert"

export default function Footer() {
  const controls = useAnimation()
  const [ref, inView] = useInView()
  const [isSending, setIsSending] = useState(false)
  const [sendStatus, setSendStatus] = useState({ processed: false, message: "", variant: "success" })
  const [hasAnimated, setHasAnimated] = useState(false)
  const [fieldValues, setFieldValues] = useState({
    name: false,
    email: false,
    message: false,
  })  

  const handleComplete = () => {
    setHasAnimated(true)
  }

  useEffect(() => {
    // Start animation when the component is in view
    if (inView && !hasAnimated) {
      controls.start("visible")
    }
  }, [inView, controls])

  const opacityVariant = {
    hidden: { opacity: 0 },
    visible: { opacity: 1 },
  }

  const inputFieldLineVariant = {
    hidden: { width: "0%" },
    visible: {
      width: "100%",
    },
  }

  const inputFields = [
    {
      label: "Name",
      type: "text",
      id: "name",
      placeholder: "Enter name",
      stateKey: "name",
    },
    {
      label: "Email",
      type: "email",
      id: "email",
      placeholder: "[email protected]",
      stateKey: "email",
    },
    {
      label: "Message",
      type: "textarea",
      id: "message",
      placeholder: "Your message",
      rows: "8",
      wrap: "soft",
      stateKey: "message",
    },
  ]

  const handleInputClick = (stateKey) => {
    setFieldValues({
      ...fieldValues,
      [stateKey]: true,
    })
  }

  const timeoutAlert = () =>
    setTimeout(() => {
      setSendStatus({ ...sendStatus, processed: false })
    }, 5000)

  const sendEmail = async () => {
    const requiredFields = ["name", "email", "message"]
    const missingFields = requiredFields.filter((field) => !fieldValues[field])

    if (missingFields.length > 0) {
      setSendStatus({ processed: true, variant: "error", message: "Not all fields were filled" })
      timeoutAlert()
      return
    }

    const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/
    if (!emailRegex.test(fieldValues.email)) {
      setSendStatus({ processed: true, variant: "error", message: "Invalid email" })
      return
    }

    setIsSending(true)
    try {
      const { serviceId, templateid, publicKey } = emailjsconfig

      console.log("trigger")

      const templateParams = {
        name: fieldValues.name,
        email: fieldValues.email,
        message: fieldValues.message,
      }

      const response = await emailjs.send(serviceId, templateid, templateParams, publicKey)

      console.log("Email sent successfully:", response)
      setIsSending(false)
      setSendStatus({ processed: true, variant: "success", message: "Success!" })
    } catch (error) {
      console.error("Error sending email:", error)
      setIsSending(false)
      setSendStatus({ processed: true, variant: "error", message: "Error" })
    }

    timeoutAlert()
  }

  return (
    <footer ref={ref} className="footer" id="contact">
      <BackgroundLines />

      <div className="footer--grid">
        <div className="footer--grid--heading">
          <h2>
            <ParaWriting stagger={0.08} text={"Get in "} sec={"touch"} />
          </h2>
        </div>
        <div className="footer--grid--form">
          {inputFields.map((field, index) => (
            <motion.div key={index} initial="hidden" animate={controls} variants={opacityVariant} transition={{ duration: 1, delay: 0.5 * (index + 1) }} className="input--div">
              <label htmlFor={field.id}>{field.label}</label>
              {field.type === "textarea" ? <textarea name={field.id} id={field.id} placeholder={field.placeholder} rows={field.rows} wrap={field.wrap} onFocus={() => handleInputClick(field.stateKey)}></textarea> : <input type={field.type} name={field.id} id={field.id} placeholder={field.placeholder} onClick={() => handleInputClick(field.stateKey)} />}
              <motion.div
                initial="hidden"
                animate={controls}
                variants={inputFieldLineVariant}
                transition={{
                  type: "spring",
                  stiffness: 20,
                  duration: 1,
                  delay: 0.5 * (index + 1),
                }}
                className="input--div--line"
              >
                <motion.div
                  initial="hidden"
                  animate={fieldValues[field.stateKey] && "visible"}
                  variants={inputFieldLineVariant}
                  transition={{
                    type: "spring",
                    stiffness: 20,
                    duration: 1,
                  }}
                ></motion.div>
              </motion.div>
            </motion.div>
          ))}
          <motion.div initial="hidden" animate={controls} variants={opacityVariant} transition={{ duration: 1, delay: 2 }} className="footer--grid--form--btn">
            <Button label={`${isSending ? "Sending it through" : "SEND MESSAGE"}`} icon={ArrowUpRightIcon} onClick={sendEmail} />
          </motion.div>
        </div>
      </div>

      <motion.div initial="hidden" animate={controls} variants={opacityVariant} transition={{ duration: 1, delay: 2.5 }} className="footer--bottom" onAnimationComplete={() => handleComplete()}>
        <p>Copyright © {new Date().getFullYear()} Cameron Watkins</p>
        <p>
          <Time delay={3} />
        </p>
        <p></p>
      </motion.div>
      <Alert isVisible={sendStatus.processed} text={sendStatus.message} variant={sendStatus.variant} />
    </footer>
  )
}

If any additional information is needed I’m more than happy to supply the GitHub repo, thanks in advance.

QML DoubleTap Handler firing twice?

I have a QML object called Vertex that gets created dynamically in a Repeater on a Canvas. It’s essentially a rectangle with some event functions on it. On a doubleTap, I want the doubleTap handler to call a function in the Canvas. But what’s happening is that the function seems to be getting called twice — once with the right parameters and once with some sketchy parameters.

Here’s the tapHandler code in Vertex.qml

TapHandler {
    onTapped: {
        selected = !selected;
    }
    onDoubleTapped: {
        console.log("Double click on "+tag);
        parent.parent.interceptDoubleClick(parent);
    }
}

Here’s the code that gets called in main.qml.

            function interceptDoubleClick(myVert) {
                console.log("intercepted!    Passed "+myVert.tag);
                console.log("myVert is "+myVert);
            }

Here’s the output.

qml: Double click on v2
qml: intercepted!    Passed v2
qml: myVert is Vertex_QMLTYPE_1(0x600001e9c0e0)
qml: Double click on 
qml: intercepted!    Passed 
qml: myVert is Vertex_QMLTYPE_1(0x600001ebcc40)

Note that the first time through, it correctly passes itself, and in the main.qml file I can query myVert.tag and get the correct value from tag. But then it fires again, and it seems to pass another Vertex object, but it is different and doesn’t have anything stored in myVert.tag.

Why is this firing twice (and where’s that second Vertex object coming from)?

Thanks,
bc

I’m working on a website, and I have an image carousel, but the timed intervals aren’t working. Does anyone know how I could make it work?

This is all of the code I have so far:

    <html> 
<head>
    <script src="script.js"></script>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title> UNTITLEDWEB.SITE </title>
</head>
<body> 
 <section class="container">
        <div class="slider-wrapper">
            <div class="slider">
                <img id="slide-1" src="4-Large.webp">
                <img id="slide-2" src="large.jpg">
                <img id="slide-3" src="DeepSixDrone_1.jpeg">
            </div>
            <div class="slider-nav">
                <a href="#slide-1"></a>
                <a href="#slide-2"></a>
                <a href="#slide-3"></a>
            </div>
        </div>
    </section>
</body>

here’s the css
how do I give the slides 5 second intervals?
I’m just going to put some random words here because it says I need more.

.container {
padding: 0rem;
}
.slider-wrapper {
position: relative;
max-width: auto;
margin: 0 auto;
}
.slider {
display: flex;
aspect-ratio: 16 / 6.5;
overflow-x: hidden;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
box-shadow: 0 1.5rem 3rem -0.75rem #00000036;
}
.slider img {
flex: 1 0 100%;
scroll-snap-align: start;
object-fit: cover;
}
.slider-nav {
display: flex;
column-gap: 1rem;
position: absolute;
bottom: 1.25rem;
left: 50%;
transform: translateX(-50%);
z-index: 1;
}
.slider-nav a {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
background-color: #fff;
opacity: 0.75;
transition: opacity ease 250ms;
}
.slider-nav a:hover {
opacity: 1;

that’s all the code I have. I’ve tried a lot of different things to get the intervals to work, but nothing has worked so far.

that is all

Is there a way to assign a WooCommerce $product SKU a class id (for a copy to clipboard button)?

First, I want to say that I’m brand new to this, so please forgive any naivete that I may have:

I’m trying to use a button to “copy-to-clipboard” a WooCommerce product SKU (on single product page). The button will then open a different page where the SKU can be pasted.

I’ve been able to display the SKU on the page with this:
(In the photo the SKU is “Bespoke Item Code: CB_BL_BrTW_01”)

/*Display SKU on Single Product Page */

add_action('woocommerce_after_add_to_cart_form', 'wdm_show_sku');
function wdm_show_sku(){
global $product;
echo $product->get_sku();
}

And I’ve made the button that opens the page and target anchor:

/**BUTTON LINK TO Customization Page from Single Product Page*/

add_action('woocommerce_after_add_to_cart_form', 'button_link_to_bespoke_page');
function button_link_to_bespoke_page(){
echo '<a href="https://www.website.com/page/#anchortojump" target="_blank">
    <button type="button" style="font-size:10px;padding-left:15px;padding-right:15px;margin-left:20px;margin-right:20px">CUSTOMIZE</button>
    </a>';
}

And I found this code that I would like to use this code to copy the SKU to the clipboard (and eventually – somehow- get it pasted into the form field of the target page):

<button onclick="copyText()">CUSTOMIZE</button>

<script>
function copyText() {
  // Get the div element
  var divElement = document.getElementById("copytextid");

  // Create a range object
  var range = document.createRange();

  // Select the contents of the div element
  range.selectNode(divElement);

  // Add the range to the user's selection
  window.getSelection().addRange(range);

  // Copy the selected text to the clipboard
  document.execCommand("copy");

}
</script>

I tried to inspect the page to see if the SKU already has an id, but had no luck (id: “”). Is there any way to give the SKU an id? Or change the last code (document.getElementBy) to find the SKU (which will obviously vary by product/page)?

Thanks!
enter image description here

How to remove label borders in leaflet javascript

I was able to change the size of the circleMarker to a small green dot but the label white space and border covers my study area.
How can I remove the label mylabel borders leaving just the text. Using leaflet and R I can remove it but I am not familiar with
javascript yet. Mock example below:

library(leaflet)
library(htmlwidgets)

leaflet() %>%
  addTiles() %>%
  setView(lng = -121.2722, lat = 38.1341, zoom = 10) %>%
  addMiniMap(tiles = providers$OpenStreetMap, position = 'topleft', width = 250, height = 420) %>%
  onRender("
function(el, x) {
  var map = this;
  if (map.minimap && map.minimap._miniMap) {
    var mini = map.minimap._miniMap;

 L.circleMarker([37.79577, -121.58426],{radius: 2},)
      .setStyle({color: 'green'})
      .bindTooltip('mylabel', {permanent: true, direction: 'right'})
       .addTo(mini);
  }
}
")