MetaMask Returns ‘-32603 Internal JSON-RPC error’ with No Revert Reason on Polygon Testnet

I’m building a DApp on the Polygon testnet (the new Amoy network) using MetaMask, ethers.js, and a Solidity smart contract. Whenever I try to call my startMaintenance() function (or several others) from my React frontend, I get an immediate error:

code: -32603
message: "Internal JSON-RPC error."

No revert reason is returned—even though I added try/catch and error decoding with interface.parseError(…). Here’s what I’ve confirmed so far:

  1. Role Checks: I’m calling this as a technician account. In theory, my contract’s onlyTechnician check should pass.
  2. Asset Status: The asset is set to “Broken,” so the require(status == ‘Broken’) check should pass too.
  3. Gas / Funds: I have plenty of test MATIC in the technician’s wallet for gas.
  4. ABI & Address: My ABI is up to date, and the contract address is correct on the Amoy testnet.
  5. No Detailed Revert Data: The node or MetaMask is just returning the generic “Internal JSON-RPC error” with no additional info.
    I’ve also checked block explorers for a transaction log, but sometimes the TX isn’t even appearing. Has anyone seen this before on Polygon testnets or had the node fail to pass back revert messages? Any ideas on how to coax out the real error reason or confirm where the transaction is failing?
    This is the function involved in the error:
try {
  const tx = await assetManagerContract.startMaintenance(asset.id, startComment);
  await tx.wait();
  alert("Maintenance started!");
} catch (error) {
  console.error("Error handleStartMaintenance:", error);
  // tried to decode revert data, but all I get is the -32603 internal error
}
function startMaintenance(uint _id, string memory startComment) public onlyTechnician {
    require(_id < nextAssetId, "Asset does not exist");
    require(!assets[_id].isDeleted, "Asset is deleted");
    require(keccak256(bytes(assets[_id].status)) == keccak256(bytes("Broken")),
        "Asset must be broken to start maintenance"
    );
    // ...
    assets[_id].status = "Under Maintenance";
    assets[_id].technician = msg.sender;
    emit MaintenanceStarted(_id, msg.sender);
}

odoo18: in crm Application, how to solve TypeError: Cannot read properties of undefined (reading ‘disconnect’) at MoveNodePlugin.destroy

in odoo 18, after a successful database migration from odoo 16, in the CRM application, inside the default kanban-view, i get this error when i click on a lead to get its form-view :

UncaughtPromiseError > OwlError
Uncaught Promise > An error occured in the owl lifecycle (see this Error's "cause" property)

Occured on localhost:8078 on 2025-04-06 08:35:01 GMT

OwlError: An error occured in the owl lifecycle (see this Error's "cause" property)
    Error: An error occured in the owl lifecycle (see this Error's "cause" property)
        at handleError (http://localhost:8078/web/assets/6/debug/web.assets_web.js:9567:35)
        at App.handleError (http://localhost:8078/web/assets/6/debug/web.assets_web.js:13964:20)
        at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10475:30)
        at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
        at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
        at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
        at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
        at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
        at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
        at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)

Caused by: TypeError: Cannot read properties of undefined (reading 'disconnect')
    at MoveNodePlugin.destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:131906:35)
    at Editor.destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:121094:24)
    at Wysiwyg.<anonymous> (http://localhost:8078/web/assets/6/debug/web.assets_web.js:145711:41)
    at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10471:28)
    at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
    at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
    at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
    at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
    at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)
    at ComponentNode._destroy (http://localhost:8078/web/assets/6/debug/web.assets_web.js:10466:23)

enter image description here

ThreeJS – Decals are not projected on Surface (glb)

It’s the first time I’m working with ThreeJS on a “more complex” model. After Exporting the OBJ from blender into glb format and import it into my project it works fine – positioning is good and I can add Decals. But when moving or rotating the model the decal position stays but the projection is not “on surface” of the model.

Current state:

const helmet = new Helmet(
    logoTexture,
    new THREE.Color(0x0C072D),
    new THREE.Vector3(0, 10, 0)
);
scene.add(await helmet.generate())

import * as THREE from 'three';
import {GLTFLoader} from "three/addons/loaders/GLTFLoader";

const loader = new GLTFLoader();
import {rotationHelper} from "./utils.js";
import {DecalGeometry} from "three/addons/geometries/DecalGeometry";

export class Helmet {

    logoTexture;
    position;
    rotation;
    color;
    texture;
    isLogoFacingRight;
    shouldMirrorLogo;

    constructor(logoTexture = "", color = new THREE.Color(0xffffff), position = new THREE.Vector3(0, 0, 0), rotation = new THREE.Euler(0, 0, 0), isLogoFacingRight = false, shouldMirrorLogo = false) {
        this.logoTexture = logoTexture;
        this.position = position;
        this.rotation = rotation;
        this.color = color;
        this.texture = null;
        this.isLogoFacingRight = true;
        this.shouldMirrorLogo = false;
    }

    /**
     *
     * @param pos       object          {x,y,z} coordinates unit based for placement in the scene
     * @param rot       object          {x:radiant, y:radiant, z:radiant}
     * @param color     THREE.color     like: THREE.Color(0xffffff)
     * @param texture   THREE.texture   generated via TextureLoader
     * @param isLogoFacingRight bool    True if the Logo image shows to the right
     * @param shouldMirrorLogo  bool    True if the Logo should be mirrored on the opposite side of the helmet
     */
    generate() {
        return new Promise(async (resolve, reject) => {

            // Texturen vorladen
            const metalStrapsTexture = await this.#safeLoadTexture('../models/helmet/helmetFootball_metalStraps_baseColor.png');
            const strapTexture = await this.#safeLoadTexture('../models/helmet/helmetFootball_strap_baseColor.png');

            loader.load(
                './models/helmet/helmetFootball.glb',  // Passen Sie den Pfad entsprechend an
                (gltf) => {
                    const model = gltf.scene.children[0];

                    if (this.logoTexture) {
                        this.#createDecals(model);
                    }

                    model.traverse((node) => {
                        ...
                    });


                    // Optional: Position anpassen
                    model.position.set(
                      this.position.x, 
                      this.position.y, 
                      this.position.z
                    );

                    // Rotation anpassen (falls nötig)
                    model.rotation.set(
                        this.rotation.x,
                        this.rotation.y,
                        this.rotation.z
                    );

                    model.updateMatrix();
                    model.updateMatrixWorld(true); // Erzwingt vollständige Matrixaktualisierung nach rotation


                    resolve(model);
                },
                // Ladefortschritt
                (progress) => {
                    console.log('Lade: ', (progress.loaded / progress.total * 100) + '%');
                },
                // Fehlerbehandlung
                (error) => {
                    console.error('Fehler beim Laden des Modells:', error);
                    reject(error);
                }
            );
        });
    }

    async #createDecals(model) {

        const texture = await this.#safeLoadTexture(this.logoTexture);
        if (!texture) {
            console.log("No Logo Texture found")
            return;
        }

        const targetNode = model.getObjectByName('helmetFootball_4');

        if (!targetNode) {
            console.log("No target for decal found")
        }

        const boundingBox = targetNode.geometry.boundingBox;

        const boundingBoxHelper = new THREE.Box3Helper(boundingBox, 0xff0000); // Rot als Farbe
        targetNode.add(boundingBoxHelper);

        // Decal-Parameter
        const decalSize = new THREE.Vector3(8, 8, 8); // Anpassen je nach Logogröße
        const decalOrientation = new THREE.Euler(0, rotationHelper(90), 0);
        const yPosition = (targetNode.geometry.boundingBox.min.y + targetNode.geometry.boundingBox.max.y) / 2 + 5;


        // Decal-Positionen (links und rechts)
        const decalPositions = [
            new THREE.Vector3(targetNode.geometry.boundingBox.max.x, yPosition, 0),
            new THREE.Vector3(targetNode.geometry.boundingBox.min.x, yPosition, 0)
        ];


        decalPositions.forEach((position, index) => {

            // Helfer zur Viasualisierung der Position
            const helperBox = new THREE.Mesh(
                new THREE.BoxGeometry(8, 8, 8), // Größe der Hilfsbox (x, y, z)
                new THREE.MeshBasicMaterial({
                    color: 0x00ff00, // Grüne Farbe
                    wireframe: true  // Nur Drahtgitter-Ansicht
                })
            );
            helperBox.position.copy(position);
            targetNode.add(helperBox);

            // Decal-Geometrie erstellen
            const decalGeometry = new DecalGeometry(
                targetNode,
                position,
                decalOrientation,
                decalSize
            );

            // Decal-Material
            const decalMaterial = new THREE.MeshBasicMaterial({
                map: texture,
                transparent: true,
                depthTest: true,
                opacity: 1
            });

            // Decal-Mesh erstellen
            const decalMesh = new THREE.Mesh(decalGeometry, decalMaterial);

            // Zum Ziel-Mesh hinzufügen
            targetNode.add(decalMesh);
        });
    }

    #safeLoadTexture(path) {
        return new Promise((resolve, reject) => {
            const textureLoader = new THREE.TextureLoader();
            textureLoader.load(
                path,
                (texture) => resolve(texture),
                undefined, // onProgress
                (error) => {
                    console.warn(`Texture not found: ${path}`, error);
                    // Fallback-Textur oder null zurückgeben
                    resolve(null);
                }
            );
        });
    };
}

Logo images (decals) positioned correctly but not projected onto mesh

As far as i understand it creates the decal projection based on another / the old position and then moves it to the right position? If that is the case how could I solve that?

See the correct placement and projection if the model position is set to 0,0,0:
correct placed if model is set to 0,0,0

Sidenote: the meshes are unstyled because with the way I export it now somehow the mesh titles where not implemented.

thanks for your hints.

FormData Content-Type mismatch between operating systems

There seems to be a difference between MIME types on macOS and Windows when using FormData for file uploads.

Windows users are complaining that the file upload doesn’t work and the validation error that comes back is:
“Validation failed (current file type is application/octet-stream, expected type is text/tab-separated-values)”

I’m scratching my head because when I check MDN it seems like the FormData API should be compatible with all browsers, but it’s not behaving the same across operating systems.

https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData

There’s clearly a difference in the Content-Type

Edge macOS

------WebKitFormBoundary3WUJCpBdz1ohAJza
Content-Disposition: form-data; name="transactions"; filename="testdata.tsv"
Content-Type: text/tab-separated-values


------WebKitFormBoundary3WUJCpBdz1ohAJza--

Edge Windows:

------WebKitFormBoundaryACGjxE52TKrSKr1F
Content-Disposition: form-data; name="transactions"; filename="testdata.tsv"
Content-Type: application/octet-stream


------WebKitFormBoundaryACGjxE52TKrSKr1F--

I have an ugly fix, but I have no idea if I might be overlooking something?

    const [file] = this.dropzone.files;

    const formData = new FormData();

    formData.append(
      'file',
      // FormData was sent as application/octet-stream from Windows devices so we need to convert it to text/tab-separated-values
      new Blob([file], { type: 'text/tab-separated-values' }),
      file.name,
    );

This will have a huge impact on my workflow because I now have to assume that there is likely more mismatched behavior between Mac and Windows. How do I you deal with stuff like this? Do I have to start running my automated tests for different operating systems now?

For now I’ve built in monitoring for 400 Bad Request on my access logs so I can catch this kind of stuff earlier, but want to hear how other people deal with these kinds of problems.

How can I prevent row movement between groups within a single table in Tabulator?

I’m still new to using Tabulator.
In my table (id is grid), I’m grouping rows by gender and then by age.
I want to allow row movement only within the same gender and same age group,
but prevent moving rows to a different age group, even if the gender is the same.

The issue described in this GitHub link seems exactly like what I need,
but I’m not sure how to apply it to my case.

Here is my code:

    <body>
        <div id="grid"></div>
        <script>
            function makeGrid() {
                var tableData = [
                    { id: 1, name: "Billy Bob", age: "12", gender: "male", type: "A" },
                    { id: 2, name: "Mary May", age: "11", gender: "female", type: "B" },
                    { id: 3, name: "John Doe", age: "12", gender: "male", type: "A" },
                    { id: 4, name: "Jane Doe", age: "11", gender: "male", type: "A" },
                    { id: 5, name: "Anna Smith", age: "11", gender: "female", type: "B" },
                    { id: 6, name: "Peter Pan", age: "12", gender: "male", type: "A" },
                    { id: 7, name: "Sam Hill", age: "12", gender: "male", type: "A" },
                    { id: 8, name: "Laura Lee", age: "11", gender: "female", type: "B" },
                    { id: 9, name: "James Bond", age: "11", gender: "male", type: "A" },
                    { id: 10, name: "Bruce Wayne", age: "12", gender: "male", type: "A" },
                    { id: 11, name: "Clark Kent", age: "12", gender: "female", type: "B" }
                ];
                var table = new Tabulator("#grid", {
                    height: "311px",
                    layout: "fitColumns",
                    movableRows: true,
                    groupBy: ["gender", "age"],
                    columns: [
                        { title: "Name", field: "name", width: 200 },
                        { title: "Gender", field: "gender" },
                        { title: "Age", field: "age" },
                        { title: "Type", field: "type" }
                    ],
                    data: tableData,
                });
            }
            window.addEventListener('DOMContentLoaded', makeGrid);
        </script>
    </body>

I tried adding the code from the GitHub link directly below the div tag.
There were no errors, but it didn’t work as shown in the example from the link.

thank you.

Define routes in Node.js with TypeScript

I have set up a typical Node.js/Express project with TypeScript.

I have this controller class:

import { Request, Response } from 'express';
import { UserService } from './user.service';
import { plainToInstance } from 'class-transformer';
import { CreateUserDto } from './dtos/create-user.dto';
import { UserDto } from './dtos/user.dto';

export class UserController {
  constructor(private userService: UserService) {}

  async signUp(req: Request, res: Response): Promise<UserDto> {
    const createUserDto = plainToInstance(CreateUserDto, req.body);
    const newUserDto = new UserDto(
      await this.userService.create(createUserDto),
    );
    res.status(201).json({ message: 'User created', user: newUserDto });
    return new UserDto(newUserDto);
  }
}

And I have this route file at this moment:

import { Router } from 'express';
import UserController from './user.controller';

const userRoutes = Router();

userRoutes.post('users/signup', (req, res) => {
  UserController.??
});

export default userRoutes;

I know that somehow I have to bind the method signUp from UserController to the route. But how?

I have found this blog post, where the blogger simply import the controller class in the route file and access the method. But if I do the same, intellisense doesn’t get the signUp method.

Modal not opening after with Livewire 3 upgrade

I updated to Livewire 3.6.2 (finally) from the latest v2. I’ve followed the upgrade guide, and everything works, except my modals.

The modals were shown by doing a dispatchBrowserEvent call, but since that’s been removed, I’ve changed to dispatch:

    public function closeModal(string $modalEvent = 'closeModal'): void
    {
        $this->dispatch($modalEvent);
        $this->isOpen = false;
    }

    public function openModal(string $modalEvent = 'openModal'): void
    {
        $this->dispatch($modalEvent);
        $this->isOpen = true;
    }

and updated my <script> to:

@script
<script>
    $wire.on('openConfirmationModal', () => {
        $("#confirmationModal").show();
    });
    $wire.on('closeConfirmationModal', () => {
        $("#confirmationModal").hide();
    });
</script>
@endscript

The call in this example is $this->openModal('openConfirmationModal');.

The only thing that changed here was $wire.on replaced window.addEventListener(. The rest stayed the same. If I add console.log‘s in the .on listeners, then the element is logged fine. If I do a classList.remove it doesn’t remove the class I specify. It’s almos like I can’t access that element on the DOM. My modal looks like this:

<div id="confirmationModal" tabindex="-1" aria-hidden="true" class="fixed top-0 left-0 right-0 z-50 hidden w-full p-4 overflow-x-hidden overflow-y-auto md:inset-0 h-[calc(100%-1rem)] md:h-full backdrop-blur-sm backdrop-grayscale">
    <div class="relative w-full h-full max-w-2xl md:h-auto mx-auto ">
        <!-- Modal content -->
        <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
            <!-- Modal header -->
            <div class="flex items-start justify-between p-4 border-b rounded-t dark:border-gray-600">
                <h3 class="text-xl font-semibold text-gray-900 dark:text-white">
                    header
                </h3>
            </div>
            <!-- Modal body -->
            <div class="p-6 space-y-6">
                body

            </div>
            <!-- Modal footer -->
            <div class="flex items-center p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
                <button wire:click="saveResults()" data-modal-hide="defaultModal" type="button" class="text-white bg-green-600 hover:bg-green-500 focus:bg-green-500 font-medium rounded-lg text-sm px-4 py-2 text-center dark:bg-green-600 dark:hover:bg-green-700">Confirm</button>
                <button wire:click="closeModal('closeConfirmationModal')" data-modal-hide="defaultModal" type="button" class="text-gray-500 bg-white hover:bg-gray-100 rounded-lg border border-gray-200 text-sm font-medium px-4 py-2 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600">Cancel</button>
            </div>
        </div>
    </div>
</div>

The modal is included in the componend with a @include('results.livewire.confirmation').

Does anyone have ANY idea what I’m possibly doing wrong?

what version of kendo-theme-bootstrap is best compatible with [email protected]

I am work on a react project using kendo-react previously I was working on the older version. Now I wanted to add a property to toggle border to the table. So, I came to know that [email protected] has properties like TableProperties and TableCellProperties to do so. Then I upgrade the package using yarn upgrade and it’s related packages that are

yarn upgrade kendo-react-editor version 5.19.0
yarn add kendo-svg-icons
yarn upgrade @progress/[email protected]
yarn upgrade @progress/[email protected]

Then I used TableProperties and TableCellProperties in my code and it started working.
Now the problem is the CSS is messed up. I guess because I am on the older version of the CSS package that is @progress/kendo-theme-bootstrap”: “^3.4.1”

so what is the best suitable version for this to install to get the css working

I have tried installing the version 6.7.0 and the latest one. but it is not working the build fails show the error
SassError: Undefined operation: “var(–bs-border-width) times 2”.
on line 44 of ../../node_modules/@progress/kendo-theme-bootstrap/scss/button/_variables.scss

  • 2} + #{$kendo-button-border-width * 2} ) !default;
    ——————————————^
    but I have not written this line

So, I need to version of the kendo-theme-bootstrap that can work smoothly
and are their any other dependencies that I need to install or upgrade with this

this is my package.json
“@progress/kendo-data-query”: “^1.5.1”,
“@progress/kendo-drawing”: “^1.10.0”,
“@progress/kendo-editor-common”: “1.3.0”,
“@progress/kendo-licensing”: “^1.1.4”,
“@progress/kendo-react-animation”: “^4.8.0”,
“@progress/kendo-react-buttons”: “^4.8.0”,
“@progress/kendo-react-data-tools”: “^4.8.0”,
“@progress/kendo-react-dateinputs”: “^4.8.0”,
“@progress/kendo-react-dialogs”: “^4.8.0”,
“@progress/kendo-react-dropdowns”: “^4.8.0”,
“@progress/kendo-react-editor”: “^4.8.0”,
“@progress/kendo-react-grid”: “^4.8.0”,
“@progress/kendo-react-inputs”: “^4.8.0”,
“@progress/kendo-react-intl”: “^4.8.0”,
“@progress/kendo-react-layout”: “^4.8.0”,
“@progress/kendo-react-listbox”: “^5.0.1”,
“@progress/kendo-react-pdf”: “^4.8.0”,
“@progress/kendo-react-popup”: “^4.8.0”,
“@progress/kendo-react-progressbars”: “^4.8.0”,
“@progress/kendo-react-sortable”: “^4.8.0”,
“@progress/kendo-react-tooltip”: “^4.8.0”,
“@progress/kendo-react-treeview”: “^4.8.0”,
“@progress/kendo-theme-bootstrap”: “^3.4.1”,

this include the older version that I was working on

Angular-17 Failed to load resource the server responded with a status of 404 Not Found

I built an e-commerce site, but when I upload an image, it doesn’t update. The image path is stored in the database and fetched through the API.

For example,From API got BuyerImage :
“D:/shihab/Office/e-commerce/ecommerce/src/assets/BuyeruserA_638785018821957139.png”

However, if I set it like this:
src=”assets/Buyer/userA_638785018821957139.png”
I don’t get the updated image when I try to update it.

Everything works smoothly when I run ng serve, and there are no issues. However, I’m facing a problem elsewhere. I’ve tried to describe the issue as clearly as possible. If anything is unclear or you need more details, please feel free to ask for further clarification. I’d really appreciate your help in solving this!

After Upload Image I got this problem

after the update, with new Image path API response

The image source paths are correct. But Image is not showing

let vs. var – Which shall I use and why? [duplicate]

I’m seeking clarification on the differences between var and let. While I understand the basic distinctions, such as var being function-scoped and let being block-scoped, I’m still unsure about their practical implications, especially in larger or more complex applications.

Specifically, I have a few questions:

  • How do the scoping differences between var and let affect their
    behavior in real-world code (e.g., within loops, conditionals, or
    functions)?
  • Are there any specific cases where using var might still be
    advantageous, or should I stick to let for consistency and modern
    best practices?
  • For large-scale projects, are there any significant pitfalls,
    performance issues, or readability concerns when using var versus
    let?

I would appreciate any insights, examples, or advice on when it might be better to use one over the other.

What is the difference between “let” and “var”? by @TM..

Just asking for advice

I’m new to JavaScript and I’m looking for some guidance from the experienced members of the community. I’ve noticed that there are two common ways to declare variables: using var and let. While I’ve read that there are differences between the two, I’m still a bit confused about how they behave in different contexts, especially in larger scripts or more complex applications.

Specifically, I have a few questions:

  • I understand that var is function-scoped while let is block-scoped. How does this affect their usage in practical scenarios?

  • Are there particular cases where using var is advantageous, or is it generally recommended to stick with let for consistency?

  • In large-scale projects, what are the potential pitfalls of using one over the other? Is there a significant performance or readability benefit to choosing let exclusively? (Which I’m currenty doing.)

I’d love to hear from those with more experience about when, if ever, it might be necessary or beneficial to use var instead. Any insights, examples, or personal experiences you could share would be appreciated.

What is the best way to take a full-page screenshot using a browser extension?

I’m building a browser extension (using HTML/CSS/JavaScript, with a framework like WXT) and I want to implement a feature that captures a full-page screenshot, not just the visible viewport.

I’ve already explored approaches like:

  1. Using chrome.tabs.captureVisibleTab() — but this only grabs the current visible area.
  2. Manually scrolling the page and stitching screenshots using chrome.tabs.captureVisibleTab()— but this feels janky and complex.
  3. Injecting a content script and attempting to render the page to an Offscreen canvas then attempting to take a full page screenshot – This works but creates CORS issue..

Questions:

  1. What are the best practices or APIs for taking full-page screenshots inside a browser extension?
  2. Are there any well-supported libraries or Chrome APIs that simplify this?
  3. Any performance or compatibility issues I should be aware of?
  4. Would it be a good approach to implement a backend server with puppeteer or playwright and then take the screenshot of the url using the headless browser?

Responsive Image Flow Horizontal Gallery

I’m working on attempting to replicate this gallery: https://preview.themeforest.net/item/core-minimalist-photography-portfolio/full_screen_preview/240185

I have some code that works for me on my desktop, giving a similar effect only displaying 3 images at a time, but it is not responsive. I’d like for it to adjust as the example, cropping down to only displaying the middle image when the viewport is small enough. I thought the percentages would work but it doesn’t adjust to the view port at all and maintains its size regardless of the window size.
I’d like it to be compatible with Bootstrap, but I’m not sure if Bootstrap is interfering with any of my attempts to make this responsive or not.

This is my HTML:

<html lang="en">
<head>
    <meta charset="UTF-8">
  
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1">
    <title>Horizontal Scroll Gallery</title>

    <!-- Bootstrap core CSS -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
    

<nav class="navbar navbar-expand-lg bg-body-tertiary rounded" aria-label="Thirteenth navbar example">
      <div class="container-fluid">
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample11" aria-controls="navbarsExample11" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse d-lg-flex" id="navbarsExample11">
          <a class="navbar-brand col-lg-3 me-0" href="#">Brand</a>
          <ul class="navbar-nav col-lg-6 justify-content-lg-center">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">About</a>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" aria-disabled="true">Disabled</a>
            </li>
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a>
              <ul class="dropdown-menu">
                <li><a class="dropdown-item" href="#">Action</a></li>
                <li><a class="dropdown-item" href="#">Another action</a></li>
                <li><a class="dropdown-item" href="#">Something else here</a></li>
              </ul>
            </li>
          </ul>
          <div class="d-lg-flex col-lg-3 justify-content-lg-end">
            <button class="btn btn-primary">CTA</button>
          </div>
        </div>
      </div>
    </nav>
</head>
<body>
<div class="container-fluid ps-3 pe-3">
  <div class="gallery-container">
       <div class="gallery">
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
                </div>
            </div>
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-seine-boat.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-seine-boat.jpg" alt="">
                </div>
            </div>
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
                </div>
            </div>
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/notre-dame-river-boat.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/notre-dame-river-boat.jpg" alt="">
                </div>
            </div>
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
                </div>
                </div>
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
                </div>
            </div>
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/notre-dame-river-boat.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/notre-dame-river-boat.jpg" alt="">
                </div>
            </div>
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
                </div>
                </div>
            <div class ="units">
                <div>
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
                </div>
                <div >
                 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
                </div>
            </div>
        </div>
    </div>
</div>

Here is my CSS:



 .gallery-container {

     overflow: hidden;
     position: relative;

     width:100%;
     
     
 }
 .gallery {
     display: flex;
     

    width:max-content;
    transition: transform 1s cubic-bezier(0.25, 1, 0.5, 1);


     
 }
 .gallery img {
    
     height: 37rem;
    width:100%;
     object-fit: cover;
     transition: transform 0.8s cubic-bezier(0.25, 1, 0.5, 1), opacity 0.8s ease-in-out;

     flex: 0 0 auto;
     opacity: 0.6;
    padding: 3rem;

 }

 .gallery img.active {
     transform: scale(1.2);
     opacity: 1;
    scroll-snap-align: center;
    flex: none;

 }
        
                
/*Reflected CSS */


/* reflection */
.units > :last-child {
    
  transform: rotatex(180deg) translatey(2.95rem);
  mask-image: linear-gradient(transparent 30%, white 90%);
  -webkit-mask-image: linear-gradient(transparent 30%, white 90%);
  text-shadow: 0 0 8px rgba(255 0 0 / 0.4), -2px -2px 6px rgba(0 255 0 / 0.4),
    2px 2px 4px rgba(0 255 255 / 0.4);
  background-image: unset;

}
/* original design */
.units > * {
  font: bolder 5rem/5rem "EB Garamond";
  background-image: url();
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}
.units {
  width: max-content;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
  padding: 0;
  margin:0;
  display: inline-block;
}

My javscript:


const gallery = document.querySelector('.gallery');
const images = document.querySelectorAll('.gallery img');
let index = 0;
let imageCounter = 2;
let imageWidth;
const galleryContainer = document.querySelector('.gallery-container');

// Function to update the gallery when the window is resized or when the wheel is scrolled
function updateGallery() {
    // Ensure the width is calculated correctly based on the container's width
    imageWidth = galleryContainer.offsetWidth / 6; 
    
    // Apply a smooth translate effect to the gallery
    gallery.style.transform = `translateX(${-index * imageWidth}px)`;
    
    // Update active class on the images (based on scroll position)
    images.forEach(img => img.classList.remove('active'));
    images[imageCounter].classList.add('active');
}

// Event listener for wheel scroll
document.addEventListener('wheel', (event) => {
    if (event.deltaY > 0 && index < images.length - 6) { // Scroll down
        index += 2;
        imageCounter += 2;
    } else if (event.deltaY < 0 && index > 0) { // Scroll up
        index -= 2;
        imageCounter -= 2;
    }
    updateGallery();
});

How does Whasapp render message previews (link, blold, ..etc) if the API returning message as string plain text?

I’m a React JS Developer Who is working with business API. I’ve noticed that API returning message as string or plain text. but in preview they are parsing it ln link, bold, italic …etc format.

in conclusion i just wanted to know how they showing the preview. are they using custom parser or any kind of packages for it ?

here is the preview example:
preview example

How to detect fullscreenchange if it came from pressing f11

I’m creating a function for full screen via pressing f11 or from icon. What is the efficient way to detect if the fullscreenchange event came from pressing f11 below is my code going full screen by pressing icon. What I’m planning is hide BaseScene.fullScreenIcon if user press f11 for full screen

setFullScreenIcon(){

    const displayFullScreenIcon = () => {

      BaseScene.fullScreenIcon = this.add
        .image(0, 0, 'enterFullScreenIcon')
        .setOrigin(.5, 1)
        .setInteractive();

      const fullScreenIconScaleXAndY = BaseScene.windowWidth * .05 / BaseScene.fullScreenIcon.width;
      BaseScene.fullScreenIcon.setScale(fullScreenIconScaleXAndY, fullScreenIconScaleXAndY);

    };

    const toggleFullScreen = () => {
      this.scale.isFullscreen ? this.scale.stopFullscreen() : this.scale.startFullscreen();
    };

    const changeFullScreenIcon = () => {
      BaseScene.fullScreenIcon.setTexture(
        this.scale.isFullscreen ? "exitFullScreenIcon" : "enterFullScreenIcon"
      );
    }
    
    const setupFullScreenHandlers = () => {

      BaseScene.fullScreenIcon.on('pointerdown', toggleFullScreen);

      document.addEventListener("fullscreenchange", changeFullScreenIcon);   

    };
    
    displayFullScreenIcon();
    setupFullScreenHandlers();

  }