How to retarget 3D pose landmarks (points in 3d space) onto a rigged humanoid model in Three.js?

I’m trying to implement a 3D avatar in Three.js by extracting 3D pose landmarks of a person (frame-by-frame) from a video (using MediaPipe / PoseFormat). I currently have a .pose file that provides per-frame landmarks for body, left hand, and right hand extracted from a video. Each landmark has (x,y,z) plus a confidence score c. Because they originally come in pixel units, I’ve normalized them so I can render them in 3D space.

What I’ve Done So Far:

Stick Figure Animation: I created small spheres for each joint (e.g. shoulder, elbow, wrist) and connected them with cylinders to form a “stick figure.” By positioning each sphere at a landmark’s (x,y,z) and drawing a cylinder between spheres, I see a rough character that does move correctly, mimicking the person in the video correctly.

Loaded a Rigged 3D Model: I’ve imported a .gltf humanoid model that has a skeleton (bones for each body part).

like:

model.traverse((child) => {
  if (child.isBone) {
    bonesMap[child.name] = child;
  }
});

Attempt to Retarget: Per frame, I compute direction vectors for limbs (e.g. upperArm → foreArm = (elbowPos – shoulderPos)) in world space. Then I try to set the bone’s rotation via a function like:

function setBoneDirection(bone, parentPos, childPos) {
  const direction = new THREE.Vector3()
    .subVectors(childPos, parentPos)
    .normalize();
  // Then set the bone’s quaternion somehow...
}

The bones do move, but the directions are off and the arm/forearm flips awkwardly. The elbow bends somewhat correctly but twists in the wrong orientation.

My Main Questions:

Local vs. World Space: My landmarks are in world space, but each bone’s transform in a skeleton is defined in local space (relative to its parent). So if I move the upper arm, the lower arm’s rotation is affected. How do I properly convert my pose data to each bone’s local space so that the chain moves correctly?

Bind Pose / Rest Pose Directions: The rig’s bones likely aren’t aligned along
(0,1,0) (0,1,0) or (0,−1,0) (0,−1,0) in their neutral (bind) pose. How do I figure out each bone’s default axis so I can compute the correct rotation offset?

Robust Approach / Library: Is there a library, algorithm, or code pattern that:

  1. Transforms the landmarks from world space → parent bone’s local space
  2. Determines a bone’s “rest pose direction” by measuring it in the rig’s bind pose
  3. Computes the final rotation for all bones so that the model matches my stick-figure animation?

Here is my current implementation in StackBlitz containing the stickfigure animation and 3d model retargeting attempt: https://stackblitz.com/~/github.com/AzizStark/3DAvatar

Code example: https://github.com/AzizStark/3DAvatar

Any helpful suggestions or code samples on accurately applying frame-by-frame landmark data to a rigged model in Three.js would be super helpful. Thank you!

The side menu bar(sticky) is overflowing unless I scroll

I am building a React app with a MainLayout component that sets consistent padding for all pages using utility classes (e.g., Tailwind CSS). Here is my MainLayout code:

import React from "react";
import Navbar from "./Navbar";
import { Outlet } from "react-router-dom";

function MainLayout() {
  return (
    // <div className="px-4 md:px-24 lg:px-32 xl:px-42 2xl:px-60">
    <div className="px-4 md:px-8 lg:px-16 lx:px-32 2xl:px-64">
      <Navbar />
      <Outlet />
    </div>
  );
}

export default MainLayout;

On one of my pages, PostListPage, I have a FilterSideMenu component that appears alongside a list of posts. Here’s the PostListPage layout:

import React, { useState } from "react";
import PostList from "../components/PostList";
import FilterSideMenu from "../components/FilterSideMenu";

function PostListPage() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <div className="mb-10 mt-6">
        <h1 className="text-2xl mb-6">Example Blog</h1>

        <button
          onClick={() => setOpen((prev) => !prev)}
          className="bg-secondaryColor px-4 py-2 md:hidden mt-6 mb-6 rounded-lg dark:text-black"
        >
          {open ? "Close" : "Filter or Search"}
        </button>

        <div className="flex flex-col-reverse gap-8 md:flex-row justify-between">
          <div>
            <PostList />
          </div>
          <div className={`${open ? "block" : "hidden"} md:block`}>
            <FilterSideMenu />
          </div>
        </div>
      </div>
    </>
  );
}

export default PostListPage;

And here’s the FilterSideMenu:

import React from "react";
import { Link } from "react-router-dom";
import Search from "./Search";

function FilterSideMenu() {
  return (
    <div className="px-6 h-max sticky top-10 dark:bg-gray-600 bg-gray-100 p-4 rounded-2xl">
      <div className="flex flex-col gap-8">
        <div>
          <span className="font-medium mb-2 block">Search</span>
          <Search />
        </div>
        <div className="flex flex-row md:gap-4 md:flex-col gap-32">
          <div>
            <span className="font-medium">Filter</span>
            <div className="flex flex-col gap-2 mt-2 text-sm">
              <label
                htmlFor="newest"
                className="flex items-center gap-2 cursor-pointer"
              >
                <input
                  type="radio"
                  id="newest"
                  name="sort"
                  value="newest"
                  className="w-4 h-4 rounded-sm border-[1.5px] appearance-none checked:bg-secondaryColor border-black dark:border-gray-300"
                />
                Newest
              </label>
              <label
                htmlFor=""
                name="sort"
                value="popular"
                className="flex items-center gap-2 cursor-pointer"
              >
                <input
                  type="radio"
                  className="w-4 h-4 rounded-sm border-[1.5px] appearance-none checked:bg-secondaryColor border-black dark:border-gray-300"
                />
                Most Popular
              </label>
              <label
                htmlFor=""
                name="sort"
                value="trending"
                className="flex items-center gap-2 cursor-pointer "
              >
                <input
                  type="radio"
                  className="w-4 h-4 rounded-sm border-[1.5px] appearance-none checked:bg-secondaryColor border-black dark:border-gray-300"
                />
                Trending
              </label>
              <label
                htmlFor=""
                name="sort"
                value="oldest"
                className="flex items-center gap-2 cursor-pointer "
              >
                <input
                  type="radio"
                  className="w-4 h-4 rounded-sm border-[1.5px] appearance-none checked:bg-secondaryColor border-black dark:border-gray-300"
                />
                Oldest
              </label>
            </div>
          </div>
          <div className="">
            <span className="font-medium">Categories</span>
            <div className="flex flex-col underline gap-2 mt-4 text-sm">
              <Link to="/posts?cat=all">All</Link>
              <Link to="/posts?cat=categ1">Categ1</Link>
              <Link to="/posts?cat=categ1">Categ2</Link>
              <Link to="/posts?cat=categ1">Categ3</Link>
              <Link to="/posts?cat=categ1">Categ4</Link>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default FilterSideMenu;

The issue arises when I visit the /posts page. The sidebar (FilterSideMenu) initially appears outside the viewport horizontally, but after I scroll a bit, it adjusts itself and comes inside the viewport. The expected behavior is that it should respect the padding defined in MainLayout (px-4 md:px-8 lg:px-16 lx:px-32 2xl:px-64) right from the beginning.

Verified that the FilterSideMenu component is wrapped inside the MainLayout’s padding.
Checked the CSS classes and styles for conflicting margins or padding.
Used browser developer tools to observe layout behavior and noticed that the issue resolves after a slight scroll, indicating a potential reflow/repaint issue.

The FilterSideMenu should respect the padding applied by MainLayout immediately when the page loads, without requiring a scroll.

PHP Cross-Domain POST Request – Session Cookie Not Persisting After Redirect

I am trying to send a cross-domain POST request from from.com to to.com using AJAX. The goal is to submit a form from from.com to to.com/process.php, where a PHP session is started, and a PHP session cookie (PHPSESSID) is generated and stored in the browser. After the session is created, the browser is redirected via JavaScript to to.com/order.php.

The POST request to to.com/process.php correctly generates a new PHP session ID and returns a Set-Cookie header with the updated PHPSESSID.
However, after the JavaScript redirect to to.com/order.php, the browser sends back a different session ID (an old/wrong one), even though a new one was generated in the process.php.

AJAX Request (from.com):

$.ajax({
    type: "POST",
    url: "https://to.com/process.php",
    data: $("#myForm").serialize(),
    xhrFields: {
        withCredentials: true  // Allow sending cookies with the request
    },
    success: function (response) {
        window.location.href = "https://to.com/order.php";
    }
});

to.com/process.php

<?php
header('Access-Control-Allow-Origin: https://from.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-Requested-With');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

ini_set('session.use_strict_mode', 1);
session_start();
session_regenerate_id(true);

setcookie(
    'PHPSESSID',
    session_id(),
    [
        'expires' => time() + 3600,
        'path' => '/',
        'domain' => 'to.com',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'None'
    ]
);

$_SESSION['user'] = 'John Doe';
error_log("New Session ID in process.php: " . session_id());

echo json_encode(["status" => "success"]);
exit;
?>

to.com/order.php

<?php
header('Access-Control-Allow-Origin: https://from.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, X-Requested-With');

// Handle preflight OPTIONS request
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

ini_set('session.use_strict_mode', 1);
session_start();
session_regenerate_id(true);

setcookie(
    'PHPSESSID',
    session_id(),
    [
        'expires' => time() + 3600,
        'path' => '/',
        'domain' => 'to.com',
        'secure' => true,
        'httponly' => true,
        'samesite' => 'None'
    ]
);

$_SESSION['user'] = 'John Doe';
error_log("New Session ID in process.php: " . session_id());

echo json_encode(["status" => "success"]);
exit;
?>

The response headers from process.php correctly show the Set-Cookie header with a new PHPSESSID.
Why is the new session ID not being sent back correctly after a cross-domain POST request followed by a JavaScript redirect?
How can I ensure the newly generated session ID persists correctly across the redirect?

How to split a large file .xls / .xlsx into chunks using js, and then build in PHP (Laravel)?

Users send large Excel files from the site. I cut the file into chunks, upload to the server (PHP).

On the server side, merged chunks into a single file.xls, but when opening the message “content that could not be read was found in the book”.

I would appreciate it if you could answer my questions:

Question 1: Am I splitting the file correctly .xls in chunks and upload to server?
Question 2: How to assemble chunks into a single file .xls on the server side (PHP)?

My code example

HTML

<form>
 <div>
  <input type="file" name="upload_file" id="upload_file">
 </div>
 <br>
 <div>
  <buttton class="btn btn-secondary mt-3" id="but">Send</buttton>
 </div>
</form>

JS

let chunkList = [];

let fileInput = document.getElementById('upload_file');
fileInput.addEventListener('change', function (event) {

    let file = event.target.files[0];
    let chunkSize = 1048576;
    let currentChunk = 0;
    let countChunks = Math.ceil(file.size / chunkSize)
    let suffix = 'xls';
    const hash = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;

    for(let i = 0; i < countChunks; i++){
        const item = {
            chunk: file.slice(currentChunk, currentChunk + chunkSize),
            fileName: `${hash}_${i}.${suffix}`
        }
        currentChunk += chunkSize
        chunkList.push(item)
    }
})

let token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
let my_but = document.getElementById('but');

my_but.addEventListener('click', async function (event) {

    let file = document.getElementById('upload_file').files[0];

    if (file === undefined || chunkList.length < 1) return;

    for (const item of chunkList) {
        const formData = new FormData()
        formData.append('chunk', item.chunk)
        formData.append('filename', item.fileName)

        let resp = await sendChunkFile(formData);
        console.log(resp)
    }
})

async function sendChunkFile(formData){
    let response = await fetch('/api/chunks-file-upload', {
        headers: {"X-CSRF-TOKEN": token},
        method: 'POST',
        credentials: "same-origin",
        body: formData
    });

    return await response.json();
}

Server PHP (Laravel)

$pathChunks = 'chunks/';
$pathMerge = 'merge-file-chunks/';

$chunkNames = Storage::disk('local')->files($pathChunks);

foreach ($chunkNames as $chunkName) {
     $result = Storage::disk('local')->append(
         $pathMerge.'file.xls',
         Storage::disk('local')->get($pathChunks.basename($chunkName))
     );
}

typeorm trying to delete relation table data when there is no change

I have project entity which has systemInstances. And systemInstance have a manytomany child and parent relation. When I try to update Project entity with same systemInstances, typeorm giving this error

 ERROR [ProjectController] Failed to update project version in project.service.ts: QueryFailedError: update or delete on table "system_instance" violates foreign key constraint "FK_3108b2b6c17bb0ed49ad71b131c" on table "system_instance_relationship"

as far as I understand typeorm trying to delete relation data from system_instance_relation table but Im not changing anything inside of the systemInstance, actually Im just passing the same object to save method.

when I save Project into db, systemInstances should be also updated with relations.

Here is my code

  async updateDraftVersion(toUpdate: UpdateProjectDto, user: User) {
    try {
          const id = toUpdate.id;
          const project = await this.projectRepository.findOne({
            where: {
              id: id,
            },
            relations: [
              'createdBy',
              'createdBy.userRole',
              'systemInstances',
              'systemInstances.parent',
              'systemInstances.children',
              'systemInstances.createdBy',
              'systemInstances.createdBy.userRole',
              'systemInstances.systemTemplate',
              'systemInstances.systemTemplate.systemCategory',
              'systemInstances.softwarePackages',
            ],
          });
          if (!project) {
            throw new APIError(
              HttpStatus.NOT_FOUND,
              `Can not found project with Id: ${id}`,
            );
          }

          project.name = toUpdate.name;
          project.description = toUpdate.description; 
          project.yardNumber = toUpdate.yardNumber;

          const updatedItem = await this.projectRepository.save(project);
          

          return updatedItem;
    } catch (e) {
      if (e instanceof APIError) {
        throw e;
      } else {
        throw new APIError(
          HttpStatus.INTERNAL_SERVER_ERROR,
          `Failed to update project version in project.service.ts: ${e}`,
        );
      }
    }
  }

here is my Project Entity

@Entity()
export class Project extends BaseEntity {
  @Column({ type: 'text', nullable: false })
  yardNumber: string;

  @Column({ type: 'text', nullable: false })
  name: string;

  @Column({ type: 'text', nullable: false })
  description: string;

  @Column({ type: 'text', default: VersionStatus.DRAFT, nullable: false })
  status: string;

  @Column({ type: 'numeric', default: 1, nullable: false })
  version: number;

  @OneToMany(() => SystemInstance, (system) => system.project, { cascade: true, onDelete:'CASCADE', onUpdate:'CASCADE' })
  systemInstances: SystemInstance[];
}

and system.instance.entity

@Entity()
export class SystemInstance extends BaseEntity {
  @Column({ type: 'text', nullable: false })
  systemId: string;

  @Column({ type: 'text', nullable: false })
  name: string;

  @Column({ type: 'text', nullable: false })
  description: string;

  @ManyToOne(() => SystemTemplate, (systemTemplate) => systemTemplate.systems)
  systemTemplate: SystemTemplate;

  @ManyToOne(() => Project, (project) => project.systemInstances,
   { orphanedRowAction: 'delete' }
  )
  project: Project;

  @ManyToMany(() => SystemInstance, (system) => system.children)
  @JoinTable({
    name: 'system_instance_relationship',
    joinColumn: { name: 'child_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'parent_id', referencedColumnName: 'id' },
  })
  parent: SystemInstance;

  @ManyToMany(() => SystemInstance, (system) => system.parent, { cascade: true, orphanedRowAction: 'delete' })
  @JoinTable({
    name: 'system_instance_relationship',
    joinColumn: { name: 'parent_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'child_id', referencedColumnName: 'id' },
  })
  children: SystemInstance[];

  @ManyToMany(
    () => SoftwarePackage,
    (softwarePackage) => softwarePackage.systemTemplates,
  )
  @JoinTable({
    name: 'system_instance_software_package',
    joinColumn: { name: 'system_instance_id', referencedColumnName: 'id' },
    inverseJoinColumn: {
      name: 'software_package_id',
      referencedColumnName: 'id',
    },
  })
  softwarePackages: SoftwarePackage[];
}

MineFlayer bot Error: read ECONNRESET as I was trying to log it in to my server

I was following a tutorial made by this guy: https://www.youtube.com/watch?v=P7TIRIDuGjc

I’ve written the exact code he had written, with only the ‘version’ added on

const mineflayer = require("mineflayer");

var settings = {
    username: 'TestBot',
    host: 'localhost',
    version: '1.21.4'
};

const bot = mineflayer.createBot(settings);

And have also created a localhost server with online-mode=false on Minecraft. I’ve set myself to Op, yet when I run the code node simple-bot.js it returned this error message which frankly I don’t understand, I have a feeling it’s a network issue but how to debug I have no idea.

Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
  errno: -4077,
  code: 'ECONNRESET',
  syscall: 'read'
}

I’ve only just began learning to make Minecraft Bots, and tbh I only have intermediate skills in JS and Node, so when I search up online a lot of the answers are either too complicated or the issues were too different for me to grasp. Please help

Mapping through these JSON elements

Struggling with this a little bit. I have a json file that looks like following with a number of items nested in an array.

"projects": [
    {
      "projectOne": {
        "id": "id1",
        "company": "company1",
        "heading": "heading",
        "link": "link",
        "heroImage": "imageLink"
      }
    },
        {
      "projectTwo": {
        "id": "id2",
        "company": "company2",
        "heading": "heading",
        "link": "link",
        "heroImage": "imageLink"
      }
    },

I’d like to map through each of the projects so I’m using this to access the projects in my JSON. I’d like to name each one so I can access it easier later in other places.

  const projects = props.cmsData.projects

  {projects.map(project => {
     return <WorkGridItem {...project} key={project.id} />
  })}

And then in my component I’m using this

export default function WorkGridItem(props) {
  return (
    <div className={`${styles.item} fadeIn`} id={props.id}>
      <div>
        {props.heroImage && (
          <div className={`${styles.imageContainer}`}>
            <Image
              src={props.heroImage}
              fill
              alt={props.id} />
          </div>
        )
        }
      </div>

However, it’s not accessing the elements. I kind of know why, because it’s actually just mapping through the titles “projectOne” “projectTwo” etc, but I don’t know how to get it to go into the element to get the id and heroImage.

Unable to create a framebuffer with an RGBA32F texture

I’m unable to create a framebuffer from a texture with internal format RGBA32F.

The following code logs test.js:38 Framebuffer is incomplete. Status: 36054 in the console

function main() {
    const canvas = document.getElementById('canvas');
    const gl = canvas.getContext('webgl2'); // Use webgl2 for native RGBA32F support
    if (!gl) {
        console.error("WebGL 2.0 not supported.");
        return;
    }

    const targetTextureWidth = 256;
    const targetTextureHeight = 256;
    const targetTexture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, targetTexture);

    {
        const level = 0;
        const internalFormat = gl.RGBA32F;
        const border = 0;
        const format = gl.RGBA;
        const type = gl.FLOAT;
        const data = null;
        gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, targetTextureWidth, targetTextureHeight, border, format, type, data);
    }

    // Create and bind the framebuffer
    const fb = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);

    // attach the texture as the first color attachment
    const attachmentPoint = gl.COLOR_ATTACHMENT0;
    const level = 0;
    gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, targetTexture, level);

    // Check framebuffer status
    const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    if (status !== gl.FRAMEBUFFER_COMPLETE) {
        console.error("Framebuffer is incomplete. Status: " + status);
        return;
    }
    console.log("Framebuffer is complete!");
}
main();

If I use a different combination of internalFormat, format and type from https://registry.khronos.org/webgl/specs/latest/2.0/#TEXTURE_TYPES_FORMATS_FROM_DOM_ELEMENTS_TABLE, the framebuffer will be completed.

Use HTML table cell value as wepage title

I have an HTML table cell that holds a dynamically created invoice number that consists of letters, dashes, and numbers.

I need to get the value of that cell and use it as the webpage’s title.

The page will be saved as a .pdf, with the invoice number as its file name.

The table ‘id’ is “invoice_details” and the cell ‘id’ is “invoice_number”.

Hope you can help.

AJAX implementation doesn’t work properly for “like” button ASP.NET Core 2.1

I want to implement “like” button (only like, not dislike) in my project written on ASP.NET Core 2.1 version. This is discount classified site and want visitors to be able to like posts they want. Since I don’t have any issue with namespace, I’ll only provide action method in the controller from backend, which is as follows:

 [HttpPost]
 public async Task<IActionResult> AddLike(int Id)
        {
            AdminPostModel postModel = new AdminPostModel();
            postModel.Post = await _offerDbContext.Posts.SingleOrDefaultAsync(x => x.Id == Id);
            var UserIP = _accessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
            var Myagent = Request.Headers["User-Agent"].ToString().Substring(0, 40);
            string MyVisit = UserIP + " " + Myagent;
            postModel.Visitinfos = await _offerDbContext.Visitinfos.ToListAsync();
            Visitinfo visitinfo = new Visitinfo();
            visitinfo.PostNumber = Id;
            visitinfo.Deviceinfo = MyVisit;
           if(postModel.Visitinfos.Any(x => x.PostNumber == visitinfo.PostNumber && x.Deviceinfo == visitinfo.Deviceinfo))
            {
                ViewBag.Message = "Eyni elanı bir dəfədən çox bəyənə bilməzsiniz";
                return Json(postModel.Post.LikeCount);
            }
            else
            {
                _offerDbContext.Visitinfos.Add(visitinfo);
                 postModel.Post.LikeCount++;
                await _offerDbContext.SaveChangesAsync();
                return Json(postModel.Post.LikeCount);
            }
        }

Please, don’t confuse yourself with user IP or user-agent details which is not related to my problem. I returned JSON with the result of number of likes (LikeCount) which is the property of Post model, and accessed it through view model in this action.
Here is posts parts of cshtml view:

  @foreach (Post item in Model)
{
  <div class="postcontent">
                              <div class="row">
                                    <div class="col-lg-12 col-md-12">
                                        <div class="uppart">
                                            <h6>@item.Title</h6>
                                        </div>
                                        <div class="imgframe">
                                            @if (item.URL != null)
                                            {
                                                <a href="@item.URL" target="_blank"> <img class="postimg" src="~/images/@item.Image"></a>
                                            }
                                            else
                                            {
                                                <a asp-action="Detailed" asp-controller="Detailed" asp-route-id="@item.Id" target="_blank"><img class="postimg" src="~/images/@item.Image"></a>
                                            }
                                        </div>
                                        <div class="posttext">
                                            <p>
                                                @item.Description
                                            </p>
                                            <p class="formore">
                                               
                                                    <a href="@item.URL" target="_blank">ƏTRAFLI</a>
                                            </p>    
                                        </div>
                                        <div class="dates">
                                            <p class="postdate">Tarix: @item.CreatedDate.ToString("dd/MM/yyyy")</p>
                                            @if (item.ExpirationDate.ToString("dd/MM/yyyy") == "01.01.2021" || item.ExpirationDate.ToString("dd/MM/yyyy") == "01/01/2019")
                                            {
                                                <p class="expdate">Bitme tarix: Naməlum</p>
                                            }
                                            else
                                            {
                                                <p class="expdate">Bitme tarix: @item.ExpirationDate.ToString("dd/MM/yyyy") </p>
                                            }
                                            **<button onclick="IncreaseLike(@item.Id)">Like</button>
                                            <p class="like"></p>**
                                        </div>
                                    </div>
                                </div>

As you see, within button tag, I called IncreaseLike() function for Post Id, which is used in Javascript part like below:

@section Script{
    <script>
        function IncreaseLike(id) {
            $.ajax({
                url: "/Home/AddLike",
                type: "POST",
                data: { id: id },
            }).done(function (result) {
                $(".like").append(result);
            }
               )
            };
        
    </script>
}

The aim of using AJAX is to interrupt page loading after clicking on “like” button. But when running application, after clicking on “like” button it adds new 1 next to previous 1 instead of updating figure on its place. And it applies it for all posts of the page instead of only particular clicked one. Maybe it’s because I append it to a class (.like), but I don’t want to define different Id for each post in the page, how can I implement ajax so that it would append to only chosen post, and only one time by increasing like number, not to place new next to the number? There is no issue with database as it works without using ajax and using asp-action and asp-controller tag helpers, but this makes the page load in each click. Please, read my code carefully, and assist in finding issue which probably comes from JS part (AJAX).

Javascript cannot map object with duplicate values

I need to style specific elements by id using given object.

const projectSkillsMap = {
  'project1': ['skill_2', 'skill4', 'skill5'],
  'project2': ['skill1', 'skill_2', 'skill4', 'skill5', 'skill6'],
  'project3': ['skill1', 'skill_2', 'skill3', 'skill4', 'skill5', 'skill6']
}

function chooseProject(key) {
  // adding accet to chosen group
  Object.keys(projectSkillsMap).map((i) => {
    if (i == key) {
      Object.entries(projectSkillsMap).map((il, value) => {
        if (il == i) {
          document.getElementById(value).classList.toggle('button_click')
        }
      })
    }
  })

  // removing accents from other groups
  Object.keys(projectSkillsMap).map((i) => {
    if (i !== key) {
      projectSkillsMap[`${i}`].map((el) => document.getElementById(`${el}`).classList.remove('button_click'))
    }
  })

  Object.values(projectSkillsMap).map((el) => {
    if (el !== key) {
      document.getElementById(el).classList.remove('button_click')
    }
  })
}

When user clicks on a button the chooseProject() function is triggered with one of the object keys. The problem is that document.getElementById(value).classList.toggle('button_click') does not work because of duplicate values in my object.

I realized that when I changed my object and left only unique values for each key then the code work as expected.

Is there any way I can make it work with duplicate values?

Is it possible to receive FCM in .NET Core MVC

I want to implement chats in my .NET Core MVC app and I have successfully implemented sending messages using the FirebaseAdmin package, however when trying to setup receiving messages using JS a few problems occur.

  1. I can not use importScripts in the firebase-messaging-sw.js service worker I think is neccessary.
  2. Registering the service worker in the site.js file does not work.
  3. I Have to use CDNs because importing firebase packages into the JS normally does not work
  4. Even when I have imported and setup everything I can not retrieve the Firebase Token

Here is some of my code:

  1. site.js file in wwwroot/site.js:
if ('serviceWorker' in navigator && 'PushManager' in window) {
   window.addEventListener('load', () => {
       navigator.serviceWorker.register('/firebase-messaging-sw.js')
           .then(registration => {
               console.log('ServiceWorker registration successful with scope: ', registration.scope);
           })
           .catch(error => {
               console.log('ServiceWorker registration failed:', error);
           });
   });
}
  1. Chats view:
@model List<ContactViewModel>
@using Market.Services.Chats
@inject IChatsService _chatsService

@{
    ViewData["Title"] = "Chats";
}

<section class="chats-section">
    <div class="contacts-container">
        @foreach(ContactViewModel contact in Model)
        {
            <partial name="_ContactPartial" model="contact" />
        }
    </div>

    <div class="chat-container">
        <div id="chat-contact-info-container" class="hidden">
            <h2 id="info-email"></h2>
            <div class="row">
                <h1 id="info-name"></h1>
                <div class="contact-profile-picture">
                    <img id="info-picture" alt="contact-picture" />
                </div>
            </div>
        </div>

        <form class="chat-form">
            <input class="chat-input" id="chat-form-input" placeholder="Type here..."/>
            <button class="chat-button" id="chat-form-button" type="submit">Send</button>
        </form>
    </div>
</section>

<script type="module">
    import { initializeApp } from 'https://www.gstatic.com/firebasejs/11.1.0/firebase-app.js';
    import { getMessaging, getToken, onMessage } from 'https://www.gstatic.com/firebasejs/11.1.0/firebase-messaging.js';
    // TODO: Add SDKs for Firebase products that you want to use
    // https://firebase.google.com/docs/web/setup#available-libraries

    // Your web app's Firebase configuration
    // For Firebase JS SDK v7.20.0 and later, measurementId is optional
    const firebaseConfig = {};

    // Initialize Firebase
    const app = initializeApp(firebaseConfig);

    const messaging = getMessaging(app);

    // Request permission to receive notifications
    Notification.requestPermission().then((permission) => {
        if (permission === "granted") {
            console.log("Notification permission granted.");

            // Get the FCM token
            getToken(messaging).then((currentToken) => {
                if (currentToken) {
                    console.log("FCM Token:", currentToken);
                    // You can send this token to your server for later use
                } else {
                    console.log("No registration token available. Request permission to generate one.");
                }
            }).catch((err) => {
                console.log("An error occurred while retrieving the token. ", err);
            });
        } else {
            console.log("Notification permission denied.");
        }
    });

    // Handle incoming messages (foreground)
    onMessage(messaging, (payload) => {
        console.log("Message received: ", payload);
    });

    // Handle background messages
    //messaging.onBackgroundMessage((payload) => {});

</script>

<script>
    let contactsData = @Html.Raw(Json.Serialize(Model));

    let contacts = document.getElementsByClassName("contact-container");
    let info = document.getElementById("chat-contact-info-container");
    let infoEmail = document.getElementById("info-email");
    let infoName = document.getElementById("info-name");
    let infoPicture = document.getElementById("info-picture");
    let selected = null;


    Array.from(contacts).forEach(contact => {
        contact.addEventListener("click", function () {
            let attribute = contact.getAttribute("data-id");
            info.classList.remove("hidden");

            if (selected != attribute) {
                selected = attribute;

                // Find the selected contact using JavaScript
                let selectedContact = contactsData.find(c => c.id == selected);

                if (selectedContact) {
                    //Load profile picture


                    // Display the selected contact details
                    infoEmail.innerHTML = selectedContact.email;
                    infoName.innerHTML = `${selectedContact.firstName} ${selectedContact.lastName}`;
                    infoPicture.src = selectedContact.profilePictureURL;

                    console.log("Selected contact:", selectedContact);
                }
            }
        });
    });

    //Sending message logic
    let input = document.getElementById("chat-form-input");
    let button = document.getElementById("chat-form-button");

    button.addEventListener("click", async (e) => {
        //Send message using service
        e.preventDefault();
        let selectedContact = contactsData.find(c => c.id == selected);

        // Validate input
        if (!input.value || !selectedContact || !selectedContact.deviceToken) {
            alert("Please select a contact and enter a message.");
            return;
        }

        const payload = {
            DeviceToken: selectedContact.deviceToken, // Replace with actual token
            Title: "New Message",
            Body: input.value,
            Id: selectedContact.id, // Replace with actual contact ID
            Status: "unread" // Example status
        };

        console.log(payload);

        try {
            const response = await fetch("/Chats/Send", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json"
                },
                body: JSON.stringify(payload)
            });

            if (response.ok) {
                const result = await response.json();
                console.log(result.message);
                alert("Message sent successfully.");
                input.value = ""; // Clear the input field
            } else {
                console.error("Failed to send message.");
                alert("Failed to send message. Please try again.");
            }
        } catch (error) {
            console.error("Error sending message:", error);
            alert("An error occurred while sending the message.");
        }

    });

</script>

  1. firebase-messaging-sw.js in wwwroot/firebase-messaging-sw.js:
importScripts('https://www.gstatic.com/firebasejs/11.1.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/11.1.0/firebase-messaging-compat.js');

// Initialize Firebase
const firebaseConfig = {};

const messaging = firebase.messaging();

// Background message handler (commented out for now)
messaging.onBackgroundMessage(function (payload) {
    console.log("Received background message ", payload);
    const notificationTitle = payload.notification.title;
    const notificationOptions = {
        body: payload.notification.body,
        icon: payload.notification.icon,
    };

    self.registration.showNotification(notificationTitle, notificationOptions);
});

The whole project can be found here:
https://github.com/gabigoranov/farmers-market/tree/main/MarketPortal

How to secure a Nextjs API call with supabase service key?

I am creating an api call in a Nextjs (with Supabase) application which need to be sercured. For my application a user should be logged which is enforced by the middleware and the await supabase.auth.getUser() call.

However, I would like to call the API from an external service or Edge function. A solution would be to make an exception for the /api path to not check for the logged user, but that would not be safe.

So I created some code to check whether the Service role key of Supabase is passed with the api call:

const isApiRequest = request.nextUrl.pathname.startsWith("/api");
// If the request is for /api, enforce authentication header
if (isApiRequest) {
  const authHeader = request.headers.get("authorization");

  if (authHeader?.startsWith("Bearer ")) {
    const token = authHeader.replace("Bearer ", "").trim();
    const { data, error } = await supabase.auth.getUser(token);

    if (!data.user || error) {
      return new NextResponse("Unauthorized", { status: 401 });
    }
  } else {
    return new NextResponse("Unauthorized", { status: 401 });
  }
}

However, this code does not work. The getUser(token) does not work like this. How can I solve this?

Why does every object in BabylonJS require a name?

I wonder why does every object you create (Box, Sphere, Camera, Light, etc) require a name to be specified?

I’m new to BabylonJS, but have used ThreeJS before, where there is no such a requirement. So, I wonder why such a design decision in BabylonJS?

I understand that these names allow me to look up objects by name. But what if I never intend to look up a specific object – why do I still need to specify a name?

In addition to the name all objects also seem to have an id. But setting of the id is not required. Though apparently these id‘s are the same as name. Looks like you can look up objects also by id. I’m even more puzzled now.

More specifically I would like to know:

  • Do these names have to be unique? What will happen if they are not?
  • What to do if I don’t care about a name? Use empty string?
  • Perhaps I should care about always using some sensible name? Why?
  • What’s the difference between name and id?

appendChild not working in tauri application?

I am new to tauri, I ran into a problem where appendChild in javascript will not work

js:

const { invoke } = window.__TAURI__.core;

let NoteInputEl;

async function ModNote(){
document.querySelector("#hd_1").textContent = "added";
var list = document.querySelector("#text_list");
let new_note = document.createElement("li");
new_note.textContent = await invoke("Note", {note: NoteInputEl.value});
list.appendChild(new_note);
} 


window.addEventListener("DOMContentLoaded", () => {
NoteInputEl = document.querySelector("#note-input");

document.querySelector("#note-form").addEventListener("submit", (e) => {
e.preventDefault();
ModNote();

NoteInputEl.value="";
});

});

index.html:

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri App</title>
<script type="module" src="/main.js" defer></script>
</head>

 <body>
  <main class="container">
  <h1>Welcome to Tauri</h1>
 
  <form class="row" id="note-form">
    <input id="note-input" placeholder="Enter a note..." />
    <button type="submit">Add</button>
  </form>
  <ul id="text_list">
    
  </ul>
  <p id="hd_1"></p>
</main>
</body>
</html>

lib.rs:

use chrono::Local;

#[tauri::command]
fn note(note: &str) -> String {
let sys_time = Local::now(); // Get the current local time

format!("{} - Created at {}", note, sys_time.format("%Y-%m-%d"))
}


#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
    .plugin(tauri_plugin_opener::init())
    .invoke_handler(tauri::generate_handler![note])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
 }

There isn’t any error raised when I run it with tauri dev, the hd_1 is getting changed, is just that the appendChild is not updating the list with new entry when i press the button and submit the form, and when I went to test it by opening the index.html with google, the main.js wouldn’t get read, so i really have no idea what is the issue.