The modal wrapper requires to remove bottoms box shadow effect and during the animation its should look like within a single div

Here I need to implement a model like this and need some animation with slide-down 
So my concern is for wrapping the button. I have to use a separate div and model for another div.
So I need to get to know if it is possible to wrap the icon and show the modal in only one div using clip path because now I am facing the problem in the slide-down animation. 
If you closely see, I have got some slight border below in the wrapped dive at the time of animation, and I have achieved the box shadow in the model the same way it should be there in the wrapped div. How do I achieve this?

enter image description here
expatiation:

my code is reflecting

jsx code for that model

import React, {
  useEffect,
  useRef,
  useState,
  useCallback,
  forwardRef,
} from "react";
import { createPortal } from "react-dom";
import "./MiniEditModal.scss";
interface MiniEditModalProps {
  anchorRef: React.RefObject<HTMLButtonElement>;
  headerProps?: { text: string; color: string; bgColor: string };
  border?: string;
  childContent: JSX.Element;
  cancelButtonProps: { text: string; onClick: () => void };
  proceedButtonProps: { text: string; onClick: () => void };
  footerContent?: JSX.Element;
  showBackdrop?: boolean;
  isWrapped?: boolean;
  isAnimated?: boolean;
  placement?: "left" | "center" | "right";
}
const MiniModel = forwardRef<HTMLDivElement, MiniEditModalProps>(
  (
    {
      anchorRef,
      headerProps,
      border,
      childContent,
      cancelButtonProps,
      proceedButtonProps,
      footerContent,
      showBackdrop = false,
      isWrapped = true,
      isAnimated = false,
      placement = "left", // default placement is bottom
    },
    ref
  ) => {
    const [modalPosition, setModalPosition] = useState({
      top: 0,
      left: 0,
      right: 0,
    });
    const [isVisible, setIsVisible] = useState(false);
    const modalRef = useRef<HTMLDivElement>(null);
    // Simplified positioning based on top or bottom placement
    const calculatePosition = useCallback(() => {
      if (anchorRef.current && modalRef.current) {
        const buttonRect = anchorRef.current.getBoundingClientRect();
        const modalRect = modalRef.current.getBoundingClientRect();
        const right = buttonRect.right;
        const viewportWidth = window.innerWidth;
        const viewportHeight = window.innerHeight;
        let top = buttonRect.bottom + window.scrollY;
        let left;
        switch (placement) {
          case "left":
            left = buttonRect.left;
            break;
          case "right":
            left = buttonRect.right - modalRect.width;
            break;
          case "center":
            left = buttonRect.left + buttonRect.width / 2 - modalRect.width / 2;
            break;
          default:
            left = buttonRect.left;
        }
        // Adjust modal position if it overflows the viewport
        if (left + modalRect.width > viewportWidth) {
          left = viewportWidth - modalRect.width - 10; // Align to the right edge with padding
        } else if (left < 0) {
          left = 10; // Align to the left edge with padding
        }

        if (top + modalRect.height > viewportHeight) {
          top = buttonRect.top - modalRect.height; // Place above the button if there's no space below
        }

        setModalPosition({ top, left, right });
      }
    }, [anchorRef, placement]);
    const closeModal = useCallback(() => {
      cancelButtonProps.onClick();
      document.body.style.overflow = "";
    }, [cancelButtonProps]);
    useEffect(() => {
      calculatePosition();
      const handleKeyDown = (event: KeyboardEvent) => {
        if (event.key === "Escape") {
          closeModal();
        } else if (event.key === "Enter") {
          proceedButtonProps.onClick();
        }
      };
      document.addEventListener("keydown", handleKeyDown);
      return () => {
        document.removeEventListener("keydown", handleKeyDown);
      };
    }, [calculatePosition, closeModal, anchorRef, proceedButtonProps]);
    useEffect(() => {
      const timeoutId = setTimeout(() => setIsVisible(true), 100);
      return () => clearTimeout(timeoutId);
    }, []);
    if (!anchorRef.current) return null;
    return createPortal(
      <>
        {showBackdrop && (
          <span
            className="modal-backdrop"
            onClick={closeModal}
            aria-hidden="true"
            style={{
              position: "fixed",
              top: 0,
              left: 0,
              width: "100%",
              height: "100%",
              backgroundColor: "rgba(0, 0, 0, 0.5)",
              zIndex: 999,
            }}
          />
        )}
        {isWrapped && (
          <div
            className="wrapped-div"
            style={{
              width: "47px",
              height: "70px",
              backgroundColor: "white",
              position: "absolute",
              top: `${modalPosition.top - 50}px`,
              left: `${anchorRef.current.getBoundingClientRect().x}px`,
              zIndex: 1001,
              borderTopLeftRadius: "12px",
              borderTopRightRadius: "12px",
              opacity: isVisible ? 1 : 0,
              visibility: isVisible ? "visible" : "hidden",
              animation:
                isVisible && isAnimated
                  ? "slideDown 0.5s ease, opacity 0.5s ease"
                  : "none",
            }}
          ></div>
        )}
        <div
          className="mini-edit-modal-container"
          ref={ref || modalRef}
          style={{
            position: "absolute",
            top: `${isWrapped ? modalPosition.top + 10 : modalPosition.top}px`,
            left: `${
              isWrapped && placement === "left"
                ? modalPosition.left - 20
                : isWrapped && placement === "right"
                ? modalPosition.left + 30
                : modalPosition.left
            }px`,
            zIndex: 100,
            visibility: isVisible ? "visible" : "hidden",
            animation:
              isVisible && isAnimated
                ? "slideDown 0.5s ease, opacity 0.5s ease"
                : "none",
          }}
        >
          <div className="mini-edit-modal">
            <header
              className="modal-header"
              style={{
                backgroundColor: headerProps?.bgColor || "#434DB8",
                color: headerProps?.color || "#fff",
                borderBottom: border ?? "2px solid transparent",
              }}
            >
              <h2>{headerProps?.text ?? "Header text"}</h2>
            </header>
            <div className="modal-content">{childContent}</div>
            {footerContent ? (
              <footer>{footerContent}</footer>
            ) : (
              <footer className="modal-footer" style={{ borderTop: border }}>
                <button
                  type="button"
                  className="btn-cancel"
                  onClick={cancelButtonProps.onClick}
                >
                  {cancelButtonProps.text}
                </button>
                <button
                  type="button"
                  className="btn-proceed"
                  onClick={proceedButtonProps?.onClick}
                >
                  {proceedButtonProps?.text}
                </button>
              </footer>
            )}
          </div>
        </div>
      </>,
      document.body
    );
  }
);
export default MiniModel;

and for style

.mini-edit-modal-container {
  background: transparent;
  display: flex;
  justify-content: center;
  border-radius: 6px;
  box-shadow: black 0px 2px 4px 0px, black 0px 2px 16px 0px;
}
.mini-edit-modal {
  background-color: white;
  padding: 10px;
  width: 100%;
  height: 100%;
  box-shadow: black 0px 2px 4px 0px, black 0px 2px 16px 0px;
  border-radius: 6px;
  transition: transform 0.3s ease-in-out;
}
.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  background-color: blue;
  color: white;
  font-size: 8px;
  font-weight: 400;
  height: 24px;
  transition: transform 0.3s ease-in-out;
}
.modal-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 5px;
  background-color: gray;
  height: 24px;
  padding-right: 10px;
  transition: transform 0.3s ease-in-out;
}
.btn-proceed,
.btn-cancel {
  width: 40px;
  height: 16px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 10px;
  line-height: 1;
  transition: transform 0.3s ease-in-out;
}
.btn-proceed {
  background-color: white;
  color: blue;
  border: 1px solid blue;
}
.btn-cancel {
  background-color: white;
  color: gray;
  border: 1px solid gray;
}
.edit-form {
  min-height: 55px;
  max-height: 250px;
  padding: 20px;
  overflow: auto;
}
.modal-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background-color: black;
  z-index: 999;
}
@keyframes bounceIn {
  0% {
    transform: scale(0.5);
    opacity: 0;
  }
  60% {
    transform: scale(1.1);
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}
@keyframes slideDown {
  from {
    transform: translateY(-50px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
.wrapped-div {
  width: 55px;
  height: 70px;
  background-color: white;
  position: absolute;
  top: 45px;
  left: 87px;
  z-index: 10;
  border-top-left-radius: 12px;
  border-top-right-radius: 12px;
  box-shadow: black 0px 2px 4px 0px, black 0px 2px 16px 0px;
}
/* For the bottom-left corner */
.wrapped-div::before {
  position: absolute;
  content: "";
  width: 25px;
  height: 25px;
  background: transparent;
  border-radius: 50%;
  bottom: 7px;
  left: -24px;
  box-shadow: 9px 7px 0 white;
}
/* For the bottom-right corner */
.wrapped-div::after {
  position: absolute;
  content: "";
  width: 25px;
  height: 24px;
  background: transparent;
  border-radius: 50%;
  bottom: 10px;
  right: -25px;
  box-shadow: -11px 10px 0 white;
}

enter image description here

Provide an API to an iframe

I’m developing an app on Tauri (for those that don’t know it, you can think on it as a Node.js althernative but backend is written on rust).

This app relies on plugins, the idea is that users could program their own sources of content, to explain it, let’s supose there are this two ways of communication:

  • from plugin to app -> app could ask plugin for a certain string parsed from the internet.
  • from app to plugin -> app binds plugin a fetch method coming from backend, so there is no cors problems for the plugin.

To manage the plugin with a bit of security, I thought to put the plugin into an iframe, so the plugin has no access to filesystem or things other than the deliberately exposed by this API.

Looking for examples I found two:

  • Obsidian: Exposes all things to the plugins, this is advised when enabling community plugins, but I would like to avoid this behaviour.

  • Logseq: Plugins are in iframes, but I coudln’t understand completely how it works, since it’s writen in clojure, I think it works using post messages. I don’t know how to share fetch method using postMessages in an understandable way.

How it’s the preferred way to perform this operation? Thanks!!

How to pause your javascript app when user goes away and unpause when he/she comes back | How to simulate a page freeze and unfreeze

It is possible for a user to navigate away from your app by minimizing the browser window or viewing a different tab at any moment.
If your web app features dynamic content like videos and animations etc, you would ideally want to make sure that the user doesn’t miss or skip any of the important content.
To detect user’s navigation away from your app, it is possible to use either one of the two methods mentioned here.

For the sake of offering the best user experience, we want to automatically pause/freeze our web app during the time user is away and automatically unpause/unfreeze when he/she returns.
This behavior will allow the user to not miss seeing or hearing anything that he/she is expected to see or hear.
In other words, none of the important content will be skipped (i.e. accidentally or otherwise), be it audio or visual.

To achieve this we must,

  1. Get all elements that have playing css animations and change their animationPlayState from running to paused
  2. Get all the playing audio elements and use the .pause() method to pause all of them.
  3. Get all the playing video elements and use the .pause() method to pause all of them.
  4. Get all the setTimeout and setInterval timers and somehow pause them too.

For an experienced developer handling 1, 2 and 3 should be easy enough where the classical approach would be to push every paused element into an array so that they can be unpaused easily when user is back.

If we assume that 1,2 and 3 are handled then what do we do about 4? In other words today’s crucial question is,

How can we pause the ticking of all JavaScript timers and unpause them i.e. make them continue as soon as they are required to do so?

Note that pause means without disregarding the remaining time.
Also note that a coherent and self-contained solution cannot be found among the answers provided at 3969475, 2626005, 7279567, 29981425, 22915959, 21277900, 38395724, 24724852, 56409468, 56555168, 35390402, 60893720, 69531945, 72751790, 62729315, 41604614.

Draggable image element is translucent when dragging [duplicate]

I’m making a javascript implementation of chess. I currently have images for the pieces stored in td elements in a table. With event listeners I’ve made it so they can drag and drop between squares, but the image attached to the cursor is translucent and has a plus with a box symbol underneath it. I’ve attempted using setDragImage, but it provides the same issue. Is there anyway to make it have opacity 1 and remove the symbol? Sorry if this is has already been answered, I tried searching but couldnt find a good solution. Ask if any more information would be helpful and thankyou in advance.

Issue with AJAX Request Triggering Unrelated Method in PHP

I am trying to update the like/upvote button. For that I have created a menthod[Method named: likepost()] in my Controller named Posts. Here is the code for my method.

public function likepost() 
{
  if (IsloggedIn()) {
      // Check if the request is a POST request
      if ($_SERVER['REQUEST_METHOD'] == 'POST') {
          $post_id = $_POST['post_id'];
          $user_id = $_SESSION['user_id']; // Assuming the user is logged in and we are storing the user ID in session
  
          // Check if the user already liked this post
          if ($this->postModel->hasUserLikedPost($post_id, $user_id)) {
              // User has already liked the post, so we need to remove the like
              if ($this->postModel->removeLike($post_id, $user_id)) {
                  // Decrease the like count in the posts table
                  $this->postModel->decrementLikeCount($post_id);
                  echo json_encode(['status' => 'unliked', 'likes_count' => $this->postModel->getLikesCount($post_id)]);
              }
          } else {
              // User has not liked the post, so we add the like
              if ($this->postModel->addLike($post_id, $user_id)) {
                  // Increase the like count in the posts table
                  $this->postModel->incrementLikeCount($post_id);
                  echo json_encode(['status' => 'liked', 'likes_count' => $this->postModel->getLikesCount($post_id)]);
              }
          }
      } else {
          echo json_encode(['status' => 'error', 'message' => 'Invalid request']);
      }
  } else {
      echo json_encode(['status' => 'error', 'message' => 'User not logged in']);
  }
}

Following is the code for my Model:

        public function hasUserLikedPost($user_id, $post_id) {
          echo $this->db->query('SELECT * FROM post_likes WHERE user_id = :user_id AND post_id = :post_id');
          $this->db->bind(':user_id', $user_id);
          $this->db->bind(':post_id', $post_id);
          $row = $this->db->single();
          
          return $row ? true : false;
      }
      
      public function addLike($post_id, $user_id) {
        $this->db->query('INSERT INTO post_likes (post_id, user_id) VALUES (:post_id, :user_id)');
        $this->db->bind(':post_id', $post_id);
        $this->db->bind(':user_id', $user_id);
        return $this->db->execute();
      }
    
      public function removeLike($post_id, $user_id) {
        $this->db->query('DELETE FROM post_likes WHERE post_id = :post_id AND user_id = :user_id');
        $this->db->bind(':post_id', $post_id);
        $this->db->bind(':user_id', $user_id);
        return $this->db->execute();
      }
    
      public function incrementLikeCount($post_id) {
        $this->db->query('UPDATE posts SET likes_count = likes_count + 1 WHERE id = :post_id');
        $this->db->bind(':post_id', $post_id);
        return $this->db->execute();
      }
    
      public function decrementLikeCount($post_id) {
        $this->db->query('UPDATE posts SET likes_count = likes_count - 1 WHERE id = :post_id');
        $this->db->bind(':post_id', $post_id);
        return $this->db->execute();
      }
    
    public function getLikesCount($post_id) {
      $this->db->query('SELECT likes_count FROM posts WHERE id = :post_id');
      $this->db->bind(':post_id', $post_id);
      return $this->db->single()->likes_count;
    }

Here is my view code:

    <button class="btn btn-success" id="upvote" data-post-id='<?php echo $data['post']->id; ?>'>
    <i class="fa fa-thumbs-up"></i> Upvote <span id="display"><?php echo $data['post']->likes_count; ?></span>
  </button>

Following is my AJAX query written in my main.js

        document.addEventListener("DOMContentLoaded", function () {
      let btn = document.getElementById("upvote");
      if (!btn) {
        console.error('Element with ID "upvote" not found');
        return;
    }
      let disp = document.getElementById("display");
      let post_id = btn.getAttribute("data-post-id");
    
      btn.onclick = function () {
          // Create an AJAX request to send the post_id to PHP
          let xhr = new XMLHttpRequest();
          xhr.open("POST", "<?php echo URLROOT;?>/posts/likepost", true);
          xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    
          xhr.onreadystatechange = function () {
              if (xhr.readyState === 4 && xhr.status === 200) {
                  // Handle the response from PHP
                  let response = JSON.parse(xhr.responseText);
                  if (response.status === 'liked') {
                      disp.innerHTML = response.likes_count; // Update the like count
                  } else if (response.status === 'unliked') {
                      disp.innerHTML = response.likes_count; // Update the like count
                  }
              }
          };
    
          // Send the post_id as part of the request
          xhr.send("post_id=" + post_id);
      }
    });

Whenever i am trying to run this i am getting following error in my console:
enter image description here

[![enter image description here][2]][2]


  [1]: https://i.sstatic.net/62YNKpBM.png
  [2]: https://i.sstatic.net/trpt25dy.png

As per this error it is showing error in my another method which is running fine, i am pasting that here for reference as well:

    public function show($id)
        {
                $post = $this->postModel->getPostById($id);
                $user = $this->userModel->getUserById($post->userid);
                $data = [
                'post' => $post,
                'user' => $user,   
                ];
                $this->view('posts/show',$data);
        }

Storybook: Updated values do not update in the UI

I need to be able to set “selectedItem” to the item that is clicked in this storybook-file. As proven by the console.log in “onItemClick”, it logs out the correct item value, but the value in the <h2>Edit field: ${args.selectedItem}</h2> does not update, it stays as null.

How can i fix this?

I am using version 8.2.9 of storybook, and the component itself is an angular element.

import type { Meta, StoryObj } from '@storybook/angular';
import { ListDetailComponent } from './list-detail.component';

const meta: Meta<ListDetailComponent> = {
  component: ListDetailComponent,
  title: 'lib/general/list-detail',
};

export default meta;
type Story = StoryObj<ListDetailComponent>;

export const Default: Story = {
  render: (args) => ({
    props: {
      ...args,
      onItemClick: (item: any) => {
        console.log('item', item)
        args.selectedItem = item;
      },
    },
    template: `
      <rvn-el-list-detail>
        <ion-list slot="list">
          <rvn-el-item (click)="onItemClick('Field 1')">
            <ion-label>Field 1</ion-label>
          </rvn-el-item>
          <rvn-el-item (click)="onItemClick('Field 2')">
            <ion-label>Field 2</ion-label>
          </rvn-el-item>
          <rvn-el-item (click)="onItemClick('Field 3')">
            <ion-label>Field 3</ion-label>
          </rvn-el-item>
        </ion-list>
        <div slot="detail">
          <h2>Edit field: ${args.selectedItem}</h2>
        </div>
      </rvn-el-list-detail>
    `,
  }),
  args: {
    selectedItem: null
  },
};

I have also tried using a local variable like let localSelectedItem, but it still did not update.

How to hide every scrollbar at once with injected CSS (kepping the element scrollable)

I’d like to hide every single scrollbar inside webpages, but each element must remain scrollable.

I’m doing this with a style element that i will inject into every webpage that I visit, but some pages have more than one scrollbar and I can’t style all of them.

I’ve tried with:

::-webkit-scrollbar {
    appearance: none !important;
    width: 0;
    height: 0;
}

but this doesn’t style all scrollbars.

Payment redirecct issues using sslcommerz

There is an issue.After payment it redirect here ‘http://localhost:5173/order/$%7Border._id%7D’ order?._id is not undefined.But Page is error something like the site can’t be reached.
But if i copy this url and open another tab and paste it ,then it is work.Please help me..Thanks in advance.

here is my code

export const createPayment = async (req, res) => {
  if (!req.body) {
    return res.status(400).json({ message: "No request body", success: false });
  }
  if (req.user.isAdmin) {
    return res
      .status(503)
      .json({ message: "Admins cannot make payments", success: false });
  }

  // console.log("payment", data);
  try {
    const order = await Order.findById(req.params.id);
    console.log("order", order);
    if (!order) {
      return res
        .status(404)
        .json({ message: "Order not found", success: false });
    }

    const tran_id = uuidv4();

    const data = {
      total_amount: order.totalPrice,
      currency: "BDT",
      tran_id,
      success_url: `http://localhost:5173/order/${order._id}`, // Redirect here on success
      fail_url: `http://localhost:5173/order/${order._id}`, // Redirect here on failure
      cancel_url: `http://localhost:5173/order/${order._id}`,
      ipn_url: "http://localhost:3030/ipn",
      shipping_method: "Courier",

      product_name: "something",
      product_category: "something",
      product_profile: order.orderItems
        .map((item) => item.imagesUrls[0])
        .join(", "),
      cus_name: order.deliveryAddress.name,
      cus_email: order.deliveryAddress.email,
      cus_address: order.deliveryAddress.address,
      cus_country: "Bangladesh",
      cus_phone: order.deliveryAddress.phone,
      // Add the missing field
      ship_name: order.deliveryAddress.name, // Shipping name
      ship_add1: order.deliveryAddress.address,
      ship_city: "Dhaka",
      ship_state: "Dhaka",
      ship_postcode: 1000,
      ship_country: "Bangladesh",
    };

    const sslcz = new SSLCommerzPayment(store_id, store_password, isLive);
    const apiResponse = await sslcz.init(data);

    // console.log(apiResponse.status);
    // Redirect the user to the payment gateway
    let GatewayPageURL = apiResponse.GatewayPageURL;
    // console.log(GatewayPageURL);
    res.send(GatewayPageURL);
    if (apiResponse.status === "SUCCESS") {
      order.isPaid = true;
      order.isAvailable = false;
      order.paidAt = Date.now();
      order.transactionId = tran_id;
      // order.user = req.user.id;
      const bookIds = order.orderItems.map((item) => item.product);
      const orderType = order.orderItems.map((item) => item.orderType);

      await Promise.all(
        order.orderItems.map(async (item) => {
          await Book.updateOne(
            { _id: item.product },
            { $set: { bookStatus: item.orderType, isAvailable: false } }
          );
        })
      );

      // order.paidAt = Date.now();
      await order.save();
      // console.log("new Order", order);
    }
  } catch (error) {
    return res.status(500).json({ message: error.message, success: false });
  }
};

i want after success payment it will redirect my target page or url

Google Address Autocomplete Dropdown Won’t Go Away After A Selection Is Made

I’m trying to use Google Address Autocomplete inside of a form. The autocomplete functionality works but when a selection is made the dropdown menu remains on the screen and I would like it to go away.

Below is the code I’m using. I’ve tried many things but nothing seems to work properly.

<script>
    var input = document.querySelector('input[name="address"]');
    var options = {
        types: ['address'] // Set to autocomplete only address types
    };

    // Initialize Google Places Autocomplete for the input field
    var autocomplete = new google.maps.places.Autocomplete(input, options);

    // Listen for the place_changed event
    autocomplete.addListener('place_changed', function() {
        var place = autocomplete.getPlace();

        if (place && place.formatted_address) {
            // Populate the input field with the full address
            input.value = place.formatted_address;

            // Dispatch an input event to ensure other listeners pick up the changes
            input.dispatchEvent(new Event('input'));

            // Save the address info to sessionStorage if needed
            var addressInfo = {
                address: place.formatted_address
            };
            sessionStorage.setItem('addressInfo', JSON.stringify(addressInfo));
        } else {
            console.log("No address found for the selected place.");
        }

        // Close the dropdown immediately
        closeDropdown();
    });

    // Function to close the autocomplete dropdown
    function closeDropdown() {
        setTimeout(() => {
            input.blur(); // This should close the dropdown
        }, 200); // Slight delay to ensure place is selected
    }

    // Disable browser's autocomplete and manage focus behavior
    input.addEventListener('focus', function() {
        input.setAttribute('autocomplete', 'off'); // Disable browser's autocomplete
    });

    // Handle clicks outside the input to close dropdown
    document.addEventListener('click', function(event) {
        if (!input.contains(event.target) && document.querySelector('.pac-container')) {
            input.blur(); // Close the dropdown if clicked outside
        }
    });

    // Populate address fields from sessionStorage on load (if needed)
    window.addEventListener('load', function() {
        var addressInfo = getAddressInfo();
        if (addressInfo) {
            input.value = addressInfo.address; // Populate the address field
            input.dispatchEvent(new Event('input')); // Dispatch event to trigger listeners
        }
    });

    function getAddressInfo() {
        var addressInfo = sessionStorage.getItem('addressInfo');
        return addressInfo ? JSON.parse(addressInfo) : null;
    }
</script>
     

Bulk add multiple videos at once to playlist using YouTube v3 api

I am trying to write a script to add every video from a list to a youtube playlist, currently my project works but I hit the quota limit very fast.
The free tier of my GCP project allows 10,000 values per day
[![enter image description here][1]][1]

With playlistitems.update costing 50 units
https://developers.google.com/youtube/v3/determine_quota_cost

Which means I can only make 200 playlist insert requests per day, and I’m running into that limit.

Is there any way to insert multiple videos into a playlist using a single request? Currently my code does the following:

    while (retries < MAX_RETRIES) {
        try {
            await youtube.playlistItems.insert({
                part: 'snippet',
                requestBody: {
                    snippet: {
                        playlistId: playlistId,
                        resourceId: {
                            kind: 'youtube#video',
                            videoId: videoId
                        }
                    }
                }
            });
            console.log(`Added video ${videoId} to playlist.`);
            return; // Success, exit function

Which only inserts one video id at a time, is it possible to insert multiple at once?
[1]: https://i.sstatic.net/DdoaelG4.png

FullCalendar 6 CSS not applied in Next.js 16 using pnpm

I’m working on a Next.js 16 project, and I’m trying to integrate FullCalendar 6 using pnpm. The calendar renders correctly, but none of the CSS styles are applied — the calendar appears unstyled (just plain text and no layout or design).

Here’s my setup:

  • Next.js 16
  • FullCalendar 6
  • Installed using pnpm

Here’s what I’ve done so far:

  1. Installed the required FullCalendar packages:

    pnpm add @fullcalendar/react @fullcalendar/daygrid @fullcalendar/timegrid @fullcalendar/interaction
    
  2. I’m using FullCalendar in my component with the following code:

    'use client'
    import React, { useState, useRef, useEffect } from 'react';
    import FullCalendar from "@fullcalendar/react";
    import dayGridPlugin from "@fullcalendar/daygrid";
    import timeGridPlugin from "@fullcalendar/timegrid";
    import interactionPlugin from "@fullcalendar/interaction";
    import { ArrowLeft, ArrowRight } from 'lucide-react';
    import { useTimelineStore } from '#stores/useTimelineStore.js';
    
    export const CalendarView = () => {
        const [currentDate, setCurrentDate] = useState(new Date());
        const { locale } = useTimelineStore(); // 'en-US' by default
        const calendarRef = useRef(null);
    
        useEffect(() => {
            if (calendarRef.current) {
                const calendarApi = calendarRef.current.getApi();
                calendarApi.setOption('locale', locale);
            }
        }, [locale]);
    
        const handlePrevWeek = () => {
            if (calendarRef.current) {
                calendarRef.current.getApi().prev();
                setCurrentDate(calendarRef.current.getApi().getDate());
            }
        };
    
        const handleNextWeek = () => {
            if (calendarRef.current) {
                calendarRef.current.getApi().next();
                setCurrentDate(calendarRef.current.getApi().getDate());
            }
        };
    
        return (
            <div className="w-full p-4 relative">
                {/* Header */}
                <div className="flex items-center justify-between mb-4">
                    <button onClick={handlePrevWeek} className="p-2">
                        <ArrowLeft className="h-6 w-6 text-gray-500" />
                    </button>
                    <button onClick={handleNextWeek} className="p-2">
                        <ArrowRight className="h-6 w-6 text-gray-500" />
                    </button>
                </div>
    
                {/* FullCalendar Component */}
                <div className='w-full'>
                    <FullCalendar
                        ref={calendarRef}
                        plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
                        initialView="timeGridWeek"
                        headerToolbar={{
                            left: '',
                            center: 'title',
                            right: 'dayGridMonth,timeGridWeek'
                        }}
                        locale={locale}
                        events={[]}
                        nowIndicator={true}
                        height={800}
                        slotMinTime="00:00:00"
                        slotMaxTime="24:00:00"
                        allDaySlot={false}
                        slotDuration="01:00:00"
                        selectable={true}
                        selectMirror={false}
                        editable={true}
                        dayHeaders={true}
                        timeZone="UTC"
                        firstDay={1}
                        dayHeaderFormat={{ weekday: 'long', day: 'numeric' }}
                    />
                </div>
            </div>
        );
    };
    
    
  3. I read that in FullCalendar 6, CSS is now encapsulated in the Shadow DOM, so there’s no need to import the styles manually. However, despite this, the calendar still appears unstyled in my app.

Has anyone encountered this issue, and do you know what might be causing the FullCalendar styles not to apply? Any help or guidance would be appreciated!

exemple no show css

Thanks in advance!

Pre-compile VueJS templates to render functions with esbuild

I’m using esbuild to build my VueJS app. I’m trying to move away from the VueJS build that contains the compiler because of security vulnerabilities (notably CSP). But when I try to load my app, I have this error message:

[Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js". 
  at <App>

My question is: is there a way, with esbuild, to pre-compile my template-based SFCs to render functions?

I’m using unplugin + unplugin-vue at the moment, but it seems it’s not enough somehow?

Creating a custom tool for the forge viewer to only trigger the box-selection tool on control + drag events

I am trying to achieve the following:

  • Holding Control AND single clicking should allow for multi-select (cumulative selection)

  • Holding Control THEN dragging the mouse should trigger the box-selection tool

The problem I am facing is that if I want to allow the default implementation (cummulative selection) when the mouse is not being dragged I must stop the propagation of the event after a control key is pressed.

Because a user would press control before starting to drag the mouse I don’t currently see any way of only enabling box-selection once dragging begins. Is this something possible? Am I looking in the completely wrong direction? Or have I hit a dead-end?

My implementation:


/**
 * Custom forge viewer tool to restrict box-selection to ctrl key + mouse drag action
 * @param viewer Reference to the forge viewer instance
 * @see {@link https://aps.autodesk.com/blog/custom-tools-forge-viewer|Forge Documentation}
 */
export const getCustomBoxSelectionTool = (viewer) => {
  if (!viewer?.toolController) return null;

  let isDragging = false;

  const boxSelectionTool: NonNullable<CustomToolType> = {
    active: false,
    getName: () => 'custom-box-selection,
    getNames: () => ['custom-box-selection'],
    activate: async () => {
      boxSelectionTool.active = true;
    },
    deactivate: () => {
      boxSelectionTool.active = false;
    },
    getPriority: () => 1, // Set priority in the tool chain

    handleKeyDown: (event, _key) => {
      if (!event.ctrlKey) return false;

      if (isDragging) {
        viewer.toolController.activateTool('box-selection');
        return false; // Allow propagation
      } else {
        // Prevent default box-selection behaviour
        viewer.toolController.deactivateTool('box-selection');
        // !! This prevents the event propagating to the mousemove event (as dragging would happen after pressing control)
        return true; // Stop propagation
      }
    },

    handleKeyUp: (event, _key) => {
      if (event.ctrlKey) {
        viewer.toolController.deactivateTool('box-selection');
      }

      return false; // Allow propagation
    },

    handleButtonDown: (_event, button) => {
      // Check for left click (0 = left, 1 = middle, 2 = right)
      if (button === 0) {
        isDragging = true;
      }
      return false; // Allow propagation
    },

    handleButtonUp: (_event, button) => {
      // Check for left click (0 = left, 1 = middle, 2 = right)
      if (button === 0) {
        isDragging = false;
      }

      viewer.toolController.deactivateTool('box-selection');
      return false; // Allow propagation
    },

    handleMouseMove: event => {
      if (event.ctrlKey && isDragging) {
        viewer.toolController.activateTool('box-selection');
      }

      return false; // Allow propagation
    }
  };

  return boxSelectionTool;
};

Due to stopping the propagation in the the handleKeyDown function, the flow never makes it into the handleMouseMove function. I’ve tried using different combination of handlers including the handleSingleClick but I never end up with the desired end result.

How to include Astro’s getStaticPaths() function in every page when creating multi-lingual website?

In my Astro website I have a folder /src/pages/[lang] in which I created a bunch of files such as index.astro and about.astro.

I have included the function getStaticPaths() in the frontmatter of every single one of those pages to generate the language part (/en/ or /de/) of the URL:

---
export function getStaticPaths() {
    return [
         {params: {lang: 'en'}},
         {params: {lang: 'de'}},
     ];
 }
---

Is there a way to import this function into all of my pages so I don’t have to include it every time? I tried importing it like a component or layout but that didn’t work.

How can this be done?

Getting data on button click, waiting for it to be stored and then updating component

I have a Wails app (React frontend – Go backend), and I am trying to do the following:

Receive button click -> Do a query on the backend -> receive response from backend -> store response on localStorage -> render page again, so it displays the updated values;

But it only works if I click the query button twice, I believe this happens because I am executing a request and then immediately updating the screen. This leaves me with the question of how to make it so the program awaits for the backend’s response before proceeding to update

function App() {

    const query = (_command) => {
        QueryBackend(_command)
        setState(state + 1)
    }

    const [state, setState] = useState(0)

    return (
        <div id="App">
            <div>
                <p> Hello, World! </p>
                <button onClick={() => query('SELECT CODSEN FROM NCMTAB')}>Query a Hello, World!</button>    
                <ul>
                    <DebugItem />
                </ul>
            </div>
        </div>
    )
};

function QueryBackend(_command) {
    Query(_command).then((res) => {
      localStorage.setItem('debugItems', res)
    })
};

function DebugItem() {
    var values = localStorage.getItem('debugItems') || `"empty": "empty"`
    return (
        <li>{values}</li>
    ) 
};


export default App

I believe I will have to structurally change my code, since I’m not very experienced in React, but I tried searching for answers everywhere (React docs, articles, etc.) and I could not for the life of me find someone that has the same situation as me.