Svelte: Expected behavior on change in phone orientation?

I have an app that uses element.ScrollIntoView(). I’ve been using the browser developer tools to see what it looks like on a phone. Unfortunately, I’ve just noticed that when I change phone orientation, the app navigates to the top of the current page–losing your current position on the page.

Is this the expected behavior, or have I done something wrong?

How to target ID on a specific tag in JS?

I am trying to target a specific ID on the sdf-carousel-item tag but it’s giving me an error for some reason. Here is the code:

    const carouselModal = document.querySelector("sdf-carousel-item");
    const carouselSlideOne = carouselModal.querySelector("#first");
    if (carouselSlideOne){
      console.log("carousel slide one is here");
    } else {console.log("carousel slide one not here.")}
<sdf-carousel-item id="first" style="height: auto; display: block; width: 50%;" role="group" aria-roledescription="slide" aria-label="1 of 2" class="first-in-page last-in-page active">test one</sdf-carousel-item>

Here is what I tried:

const carouselModal = document.querySelector("sdf-carousel-item");
const carouselSlideOne = carouselModal.querySelector("#first");
if (carouselSlideOne){
  console.log("carousel slide one is here");
} else {console.log("carousel slide one not here.")}

I keep getting the “I’m not here” messaging which I can’t understand why, since it’s on the same div tag as carouselModal. I’m new to JS so maybe I missed something obvious?

What cookies are set by Google Maps?

I am working on integrating the Google Maps JavaScript API into our website and need to understand which cookies (if any) are set by the API. This is important for configuring our privacy settings and ensuring proper cookie consent management.

What We’ve Observed So Far:

  • We see multiple Google-related cookies (NID, SID, APISID, SAPISID, etc.) appearing in DevTools → Application → Cookies after a user interacts with the map (e.g., searching for a location).

  • Our site also uses Google reCAPTCHA, which loads from google.com, making it unclear whether these cookies are set by Google Maps JavaScript API or reCAPTCHA.

  • In Incognito mode, these cookies do not appear, suggesting they might be third-party cookies.

Questions:

  1. Which specific cookies are set by the Google Maps JavaScript API?

  2. Under what conditions are these cookies created (e.g., map load, user interaction, API feature usage like Places API)?

Discrepancy in Total Coins During Match in React Game

I’m developing a game using React where 3 players (one human and two AIs) start with 50 coins each, making the total pool of coins 150. However, during the match, I noticed a discrepancy in the total number of coins. For example, during one instance, the coin distribution was 40, 43, and 45, which sums up to 128 instead of 150.

Additionally, I have observed that for the AI players, the coins reduce by 4 instead of 2 as intended.

App.js

    import React, { useState, useEffect, useRef } from 'react';
import StartScreen from './components/StartScreen';
import GameBoard from './components/GameBoard';
import WinnerSelectionModal from './components/WinnerSelectionModal';
import CongratulationsModal from './components/CongratulationsModal';
import { aiDecisions } from './utils/gameLogic';
import { createDeck, shuffleDeck, dealCards } from './utils/deck';

const variations = [
  { name: 'Normal', cards: 3 },
  { name: 'Normal-II', cards:4},
];

function App() {
  const [showStartScreen, setShowStartScreen] = useState(true);
  const [selectedVariation, setSelectedVariation] = useState(null);
  const [players, setPlayers] = useState([
    { name: 'You', coins: 50, hand: [], isHuman: true, active: true, usedCoins: 0, isBlind: false, blindCount: 0, hasSeenCards: false, didUserPickBlindUpfront: false, skipTurnThisRound: false },
    { name: 'AI 1', coins: 50, hand: [], isHuman: false, active: true, usedCoins: 0, isBlind: false, blindCount: 0, hasSeenCards: false, skipTurnThisRound: false },
    { name: 'AI 2', coins: 50, hand: [], isHuman: false, active: true, usedCoins: 0, isBlind: false, blindCount: 0, hasSeenCards: false, skipTurnThisRound: false },
  ]);
  const [currentPlayer, setCurrentPlayer] = useState(0);
  const [deck, setDeck] = useState(shuffleDeck(createDeck()));
  const [gamePhase, setGamePhase] = useState('playing');
  const [showAICards, setShowAICards] = useState(false);
  const [dealing, setDealing] = useState(false);
  const [dealtHands, setDealtHands] = useState([]);
  const [showWinnerModal, setShowWinnerModal] = useState(false);
  const [showCongratulationsModal, setShowCongratulationsModal] = useState(false);
  const [winner, setWinner] = useState(null);
  const [blindChoicePhase, setBlindChoicePhase] = useState(false);
  const [roundCount, setRoundCount] = useState(1);
  const [playersSkippedInRound1, setPlayersSkippedInRound1] = useState(0);
  const [showAllCards, setShowAllCards] = useState(false);
  const [currentRoundPool, setCurrentRoundPool] = useState(0); // New state for tracking round pool

  const prizePool = 150;
  const isAITurnProcessing = useRef(false);

  const startGame = (variation) => {
    setSelectedVariation(variation);
    setBlindChoicePhase(true);
    setCurrentRoundPool(0); // Reset round pool at game start
  };

  const handleUserBlindChoice = (choice) => {
    setPlayers((prev) => {
      const updated = [...prev];
      const userIndex = 0;
      let userCoinsDeducted = 0;
      let aiCoinsDeducted = 0;

      if (choice === 'blind') {
        updated[userIndex].isBlind = true;
        updated[userIndex].blindCount = 1;
        updated[userIndex].coins -= 2;
        updated[userIndex].usedCoins += 2;
        userCoinsDeducted = 2;
      } else {
        updated[userIndex].coins -= 1;
        updated[userIndex].usedCoins += 1;
        userCoinsDeducted = 1;
        updated[userIndex].isBlind = false;
        updated[userIndex].hasSeenCards = true;
      }
      updated[userIndex].skipTurnThisRound = true;

      // Deduct 1 coin from each AI
      updated.forEach((p, idx) => {
        if (!p.isHuman && p.active) {
          p.coins -= 1;
          p.usedCoins = 1;
          p.skipTurnThisRound = true;
          aiCoinsDeducted += 1;
        }
      });

      // Update round pool by total deducted
      setCurrentRoundPool((prevPool) => prevPool + userCoinsDeducted + aiCoinsDeducted);

      return updated;
    });

    setBlindChoicePhase(false);
    setCurrentPlayer(0);
    distributeCards(selectedVariation);
  };

  const distributeCards = async (variation) => {
    const newDeck = shuffleDeck(createDeck());
    setDeck(newDeck);
    setDealing(true);
    const hands = dealCards(newDeck, players.length, variation.cards);
    const tempDealtHands = players.map(() => []);
    for (let cycle = 0; cycle < variation.cards; cycle++) {
      for (let playerIndex = 0; playerIndex < players.length; playerIndex++) {
        if (hands[playerIndex][cycle]) {
          tempDealtHands[playerIndex].push(hands[playerIndex][cycle]);
          setDealtHands([...tempDealtHands]);
          await new Promise((resolve) => setTimeout(resolve, 100));
        }
      }
    }
    setPlayers((prev) =>
      prev.map((player, index) => ({
        ...player,
        hand: hands[index] || [],
        active: true,
      }))
    );
    setDealing(false);
    setGamePhase('playing');
    setShowAICards(false);
    setPlayersSkippedInRound1(0);
    await new Promise((resolve) => setTimeout(resolve, 500));
    nextTurn();
  };

  const handlePlayBlind = () => {
    setPlayers((prev) => {
      const updated = [...prev];
      if (updated[currentPlayer].blindCount < 2) {
        updated[currentPlayer].isBlind = true;
        updated[currentPlayer].blindCount += 1;
        updated[currentPlayer].coins -= 2;
        updated[currentPlayer].usedCoins += 2;
        setCurrentRoundPool(prevPool => prevPool + 2); // Add to round pool
      }
      return updated;
    });
  };

  const handleSeeCards = () => {
    setPlayers((prev) => {
      const updated = [...prev];
      updated[currentPlayer].isBlind = false;
      updated[currentPlayer].hasSeenCards = true;
      return updated;
    });
  };

  const handleContinue = () => {
    setPlayers((prev) => {
      const updated = [...prev];
      updated[currentPlayer].coins -= 2;
      updated[currentPlayer].usedCoins += 2;
      setCurrentRoundPool(prevPool => prevPool + 2); // Add to round pool
      return updated;
    });
    nextTurn();
  };

  const handleOut = () => {
    setPlayers((prev) => {
      const updated = [...prev];
      updated[currentPlayer].active = false;
      return updated;
    });
    if (activePlayers() === 1) {
      awardPrizeToWinner();
    } else if (activePlayers() === 2) {
      setGamePhase('showdown');
    }
    nextTurn();
  };

  const handleRevealCards = () => {
    setPlayers((prev) => {
      const updated = [...prev];
      if (updated[currentPlayer].isHuman && !updated[currentPlayer].hasSeenCards) {
        updated[currentPlayer].isBlind = false;
        updated[currentPlayer].hasSeenCards = true;
      }
      return updated;
    });
  };

  const handleBlindShow = () => {
    if (activePlayers() === 2 && players[currentPlayer].isHuman && !players[currentPlayer].hasSeenCards) {
      console.log('Blind Show triggered, setting showAllCards to true');
      setShowAllCards(true);
      setTimeout(() => setShowWinnerModal(true), 2000);
    } else {
      console.log('Blind Show conditions not met:', {
        activePlayers: activePlayers(),
        isHuman: players[currentPlayer].isHuman,
        hasSeenCards: players[currentPlayer].hasSeenCards,
      });
    }
  };

  const handleShow = () => {
    if (activePlayers() === 2 && players[currentPlayer].isHuman) {
      setShowAllCards(true); // Reveal all cards during regular show
      setTimeout(() => setShowWinnerModal(true), 2000);
    }
  };

  const handleSelectWinner = (winnerName) => {
    setShowWinnerModal(false);
    if (winnerName !== null) {
      const updatedPlayers = [...players];
      const activePlayersList = updatedPlayers.filter((p) => p.active);
      if (activePlayersList.length === 2) {
        const winnerPlayer = activePlayersList.find((p) => p.name === winnerName);
        const loserPlayer = activePlayersList.find((p) => p.name !== winnerName);
        if (winnerPlayer && loserPlayer) {
          const winnerGlobalIndex = updatedPlayers.findIndex((p) => p.name === winnerPlayer.name);
          updatedPlayers[winnerGlobalIndex].coins += currentRoundPool; // Use current round pool
          updatedPlayers[winnerGlobalIndex].usedCoins = 0;
          const loserGlobalIndex = updatedPlayers.findIndex((p) => p.name === loserPlayer.name);
          updatedPlayers[loserGlobalIndex].active = false;
          updatedPlayers[loserGlobalIndex].usedCoins = 0;
        }
      }
      setPlayers(updatedPlayers);
      const finalWinner = updatedPlayers.find((p) => p.active);
      setWinner(finalWinner);
      setShowCongratulationsModal(true);
      setTimeout(() => {
        setShowCongratulationsModal(false);
        resetGame();
      }, 5000);
    }
  };

  const handleQuit = () => {
    setPlayers((prev) => {
      const updated = [...prev];
      updated[currentPlayer].active = false;
      return updated;
    });
    awardPrizeToWinner();
  };

  const nextTurn = () => {
    let next = (currentPlayer + 1) % players.length;
    while (!players[next].active) {
      next = (next + 1) % players.length;
    }

    if (roundCount === 1 && players[next].skipTurnThisRound) {
      setPlayers((prev) => {
        const updated = [...prev];
        updated[next].skipTurnThisRound = false;
        return updated;
      });
      setPlayersSkippedInRound1((prev) => prev + 1);
      if (playersSkippedInRound1 + 1 === activePlayers()) {
        setRoundCount(2);
        setCurrentPlayer(0);
        setPlayersSkippedInRound1(0);
      } else {
        setCurrentPlayer(next);
      }
    } else if (players[next].skipTurnThisRound) {
      setPlayers((prev) => {
        const updated = [...prev];
        updated[next].skipTurnThisRound = false;
        return updated;
      });
      next = (next + 1) % players.length;
      while (!players[next].active) {
        next = (next + 1) % players.length;
      }
      if (next === 0) {
        setRoundCount((prev) => prev + 1);
      }
      setCurrentPlayer(next);
    } else {
      if (next === 0) {
        setRoundCount((prev) => prev + 1);
      }
      setCurrentPlayer(next);
    }
  };

  const activePlayers = () => players.filter((p) => p.active).length;

  const awardPrizeToWinner = () => {
    const winnerIndex = players.findIndex((p) => p.active);
    if (winnerIndex !== -1) {
      const updatedPlayers = [...players];
      updatedPlayers[winnerIndex].coins += currentRoundPool; // Use current round pool
      updatedPlayers[winnerIndex].usedCoins = 0;
      updatedPlayers.forEach((p, idx) => {
        if (idx !== winnerIndex) p.usedCoins = 0;
      });
      setPlayers(updatedPlayers);
      setWinner(updatedPlayers[winnerIndex]);
      setShowCongratulationsModal(true);
      setTimeout(() => {
        setShowCongratulationsModal(false);
        resetGame();
      }, 5000);
    }
  };

  const resetGame = () => {
    const totalCoins = players.reduce((sum, p) => sum + p.coins, 0);
    const adjustment = 150 - totalCoins;
    const coinsPerPlayer = Math.floor((150 + adjustment) / 3);

    setSelectedVariation(null);
    setGamePhase('playing');
    setShowAICards(false);
    setShowAllCards(false);
    setDealtHands([]);
    setCurrentPlayer(0);
    setRoundCount(1);
    setPlayersSkippedInRound1(0);
    setCurrentRoundPool(0); // Reset round pool
    setPlayers((prevPlayers) =>
      prevPlayers.map((player) => ({
        ...player,
        hand: [],
        active: true,
        coins: coinsPerPlayer,
        usedCoins: 0,
        isBlind: false,
        blindCount: 0,
        hasSeenCards: false,
        didUserPickBlindUpfront: false,
        skipTurnThisRound: false,
      }))
    );
  };

  // AI player turn logic
  useEffect(() => {
    const current = players[currentPlayer];
    if (
      !current.isHuman &&
      current.active &&
      activePlayers() > 1 &&
      !current.skipTurnThisRound &&
      !isAITurnProcessing.current
    ) {
      isAITurnProcessing.current = true;
      const timer = setTimeout(() => {
        const decisions = aiDecisions(activePlayers());
        setPlayers((prev) => {
          const updated = [...prev];
          const p = updated[currentPlayer];
          if (!p.isHuman && p.active && !p.skipTurnThisRound) {
            const decision = decisions[`ai${currentPlayer}`];
            console.log(`AI ${currentPlayer} - Decision: ${decision}`);
            if (decision && p.coins >= 2) {
              console.log(`AI ${currentPlayer} - Before deduction: Coins = ${p.coins}, UsedCoins = ${p.usedCoins}, CurrentRoundPool = ${currentRoundPool}`);
              p.coins -= 2; // Consistently 2 coins for AI
              p.usedCoins += 2;
              setCurrentRoundPool((prevPool) => prevPool + 2); // Add to round pool - using functional update
              console.log(`AI ${currentPlayer} - After deduction: Coins = ${p.coins}, UsedCoins = ${p.usedCoins}, CurrentRoundPool = ${currentRoundPool}`);
            } else {
              console.log(`AI ${currentPlayer} - Cannot continue, going out: Coins = ${p.coins}, UsedCoins = ${p.usedCoins}`);
              p.active = false;
            }
          }
          return updated;
        });
        if (activePlayers() === 1) {
          awardPrizeToWinner();
        } else if (activePlayers() === 2) {
          setGamePhase('showdown');
        }
        nextTurn();
        isAITurnProcessing.current = false;
      }, 1500);
      return () => {
        clearTimeout(timer);
        isAITurnProcessing.current = false;
      };
    }
  }, [currentPlayer, players]);

  if (showStartScreen) {
    return <StartScreen onStart={() => setShowStartScreen(false)} />;
  }

  return (
    <div className="min-h-screen bg-gray-800 flex flex-col items-center justify-center relative">
      {!selectedVariation ? (
        <div className="text-white">
          <h1 className="text-3xl mb-4">Select a Game Variation</h1>
          <div className="grid grid-cols-3 gap-4">
            {variations.map((variation) => (
              <button
                key={variation.name}
                onClick={() => startGame(variation)}
                className="p-4 bg-blue-600 rounded-lg hover:bg-blue-700"
              >
                {variation.name} ({variation.cards} cards)
              </button>
            ))}
          </div>
        </div>
      ) : blindChoicePhase ? (
        <div className="flex flex-col items-center space-y-4 text-white">
          <h2 className="text-2xl">Do you want to Play Blind or Play Seen?</h2>
          <div className="flex space-x-4">
            <button
              onClick={() => handleUserBlindChoice('blind')}
              className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700"
            >
              Play Blind
            </button>
            <button
              onClick={() => handleUserBlindChoice('seen')}
              className="px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700"
            >
              Play Seen
            </button>
          </div>
        </div>
      ) : (
        <>
          <GameBoard
            players={players}
            currentPlayer={currentPlayer}
            onContinue={handleContinue}
            onOut={handleOut}
            variation={selectedVariation}
            prizePool={prizePool}
            currentRoundPool={currentRoundPool} // Pass the current round pool
            gamePhase={gamePhase}
            onRevealCards={handleRevealCards}
            onBlindShow={handleBlindShow}
            onShow={handleShow}
            onQuit={handleQuit}
            dealing={dealing}
            dealtHands={dealtHands}
            showAICards={showAICards}
            onPlayBlind={handlePlayBlind}
            onSeeCards={handleSeeCards}
            roundCount={roundCount}
            showAllCards={showAllCards}
          />
          {showWinnerModal && (
            <WinnerSelectionModal
              players={players.filter((p) => p.active)}
              onSelectWinner={handleSelectWinner}
            />
          )}
          {showCongratulationsModal && winner && (
            <CongratulationsModal winner={winner} />
          )}
        </>
      )}
    </div>
  );
}

export default App;

GameBoard.js

import React from 'react';
import PlayerPanel from './PlayerPanel';
import Controls from './Controls';
import ReactionButton from './ReactionButton';

function GameBoard({
  players,
  currentPlayer,
  onContinue,
  onOut,
  variation,
  prizePool,
  currentRoundPool, // New prop
  gamePhase,
  onRevealCards,
  onBlindShow,
  onShow,
  onQuit,
  dealing,
  dealtHands,
  showAICards,
  onPlayBlind,
  onSeeCards,
  roundCount,
  showAllCards,
}) {
  const activePlayersCount = players.filter((p) => p.active).length;
  const currentPlayerHasSeen = players[currentPlayer].hasSeenCards;
  const didUserPickBlindUpfront = players[0].didUserPickBlindUpfront || false;

  return (
    <div className="text-center">
      <div className="aquamorphic-bg mx-auto max-w-5xl mt-8">
        <h1 className="text-4xl text-white mb-8">Teen Patti - {variation.name}</h1>
        <div className="flex justify-center space-x-12 mb-4">
          <p className="text-2xl text-yellow-300">Total Prize Pool: {prizePool}</p>
          <p className="text-2xl text-green-300">Current Pot: {currentRoundPool}</p>
        </div>
        <div className="grid grid-cols-3 gap-4">
          {players.map((player, index) => (
            <PlayerPanel
              key={index}
              player={player}
              isCurrent={index === currentPlayer}
              dealing={dealing}
              dealtHand={dealtHands[index] || []}
              showAICards={showAICards}
              showAllCards={showAllCards}
            />
          ))}
        </div>

        <div className="mt-8">
          <ReactionButton />
        </div>

        {gamePhase === 'showdown' && activePlayersCount === 2 && players[currentPlayer].isHuman ? (
          <div className="mt-8 flex space-x-4 justify-center">
            {!currentPlayerHasSeen && (
              <button
                onClick={onRevealCards}
                className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
              >
                Reveal Cards
              </button>
            )}
            {!currentPlayerHasSeen && (
              <button
                onClick={onBlindShow}
                className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700"
              >
                Blind Show
              </button>
            )}
            {currentPlayerHasSeen && (
              <button
                onClick={onShow}
                className="px-6 py-3 bg-purple-600 text-white rounded-lg hover:bg-purple-700"
              >
                Show
              </button>
            )}
            <button
              onClick={onOut}
              className="px-6 py-3 bg-red-600 text-white rounded-lg hover:bg-red-700"
            >
              Out
            </button>
          </div>
        ) : (
          <Controls
            onContinue={onContinue}
            onOut={onOut}
            isHumanTurn={players[currentPlayer].isHuman && players[currentPlayer].active}
            onPlayBlind={onPlayBlind}
            onSeeCards={onSeeCards}
            currentBlindCount={players[currentPlayer].blindCount}
            isUserBlind={players[currentPlayer].isBlind}
            hasSeenCards={currentPlayerHasSeen}
            roundCount={roundCount}
            didUserPickBlindUpfront={didUserPickBlindUpfront}
          />
        )}
      </div>
    </div>
  );
}

export default GameBoard;

Could anyone help me identify what might be causing these discrepancies and suggest a fix? Any help would be greatly appreciated!

URLPattern class in Node v23.10 returns Uncaught ReferenceError: URLPattern is not defined

I’m trying out the URLPattern class in Node v23.10, installed with nvm

When I ran the following in the cli or as an executable

const p = new URLPattern({pathname: 'annotations/:id'})

I got this

Uncaught ReferenceError: URLPattern is not defined

I understand this is an experimental feature, but there’s no guidance in the docs and examples I’ve read as to what flag(s) to run this script with.

Can’t import public key for encrypting content encryption key Crypto Web API

Im trying to encrypt a Content Encryption Key with a certain public key using javascript Crypto Web API but I get this error :

“SyntaxError: Cannot create a key using the specified key usages.”

The arraybuffer is the certificate, but it doesnt matter if its the public key the error stays the same.

Here is my code:

function(arraybuffer){
    crypto.subtle.importKey(            
        "spki",
        arraybuffer,
        {name:"RSASSA-PKCS1-v1_5",hash:{name:"SHA-256"}},
        true,
        ["encrypt"]
    )
    .then(function(key){
        console.log(key);
        return key;
        }
    )
    .catch(function(e){console.log(e)})
}

I think its about keyUsage parameter which I use [“encrypt”], but i need this key to encrypt so Im clueless.

button still refreshing page with event stopPropagation and preventDefault

I have a problem where clicking a button refreshes the page. I even removed the button and directly placed the icon and onClick on the td and used event.preventDefault() and event.stopPropagation() but the refresh still occurs. There is no problem in the rest of the project and I also used BrowserRouter in the main file. On the same page I also had a button for search that was inside the form and it did not cause any problems.

users list component :


export default function UsersList() {
  const users = useSelector((state) => state.users);
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(fetchAllUsers());
  }, []);

  function handleDeleteUser(e, id) {
    // has refreshing problem
    e.stopPropagation();
    e.preventDefault();
    dispatch(deleteUser({ id }));
  }

  return (
    <div className="m-3">
      <div
        className={`my-5 mx-2 p-2 text-sm ${
          users.loading ? "opacity-50" : "opacity-100"
        }`}
      >
        {users.usersList.length === 0 ? (
          <p>no user</p>
        ) : (
          <table className="border-1 border-stone-300 rounded-lg w-full text-center border-collapse table-auto">
            <tbody>
              {users.usersList.map((user) => {
                return (
                  <tr key={user.id} className="border-1 border-stone-300 py-2">
                    <td className="py-3 border-r-1 border-stone-300 px-1">
                      {user.fName}
                    </td>
                    <td className="py-3 border-r-1 border-stone-300 px-1">
                      {user.lName}
                    </td>
                    <td className="py-3 border-r-1 border-stone-300 px-1">
                      {user.phone}
                    </td>
                    <td className="py-3 border-r-1 border-stone-300 px-1">
                      {user.email}
                    </td>
                    <td className="py-3 border-r-1 border-stone-300 px-1">
                      {user.username}
                    </td>
                    <td onClick={(e) => handleDeleteUser(e, user.id)}>❌</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}   

users slice:

         
const initialUser = {
  fName: "",
  lName: "",
  username: null,
  pass: null,
  phone: "",
  email: "",
  age: 0,
  isAuth: false,
};
const initialState = {
  singleUser: initialUser,
  usersList: [],
  loading: false,
  error: null,
};

const isPendingAction = (action) => action.type.endsWith("/pending");
export const deleteUser = createAsyncThunk(
  "users/deleteUser",
  async (payload, { rejectWithValue }) => {
    try {
      const res = await axios.request({
        method: "delete",
        url: HOST + "/" + payload.id,
      });
      return res;
    } catch (e) {
      return rejectWithValue(e.messege);
    }
  }
);
const usersReducer = createSlice({
  name: "users",
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    // ...
    //deleteUser
    builder.addCase(deleteUser.fulfilled, (state, action) => {
      state.loading = false;
      state.usersList = state.usersList.filter(
        (user) => user.id !== action.payload.id
      );
      state.error = null;
    });
    builder.addCase(deleteUser.rejected, (state, action) => {
      state.loading = false;
      state.error = action.payload;
      state.usersList = [];
    });
    builder.addMatcher(isPendingAction, (state) => {
      state.loading = true;
    });
  },
});                ` 

How can I get this javascript to run inside of my html DIV tags?

I have a php file that does some work that I am trying to run inside of my html via javascript. It is working however it does not appear to be respecting the div tag alignment. The script is running inside of Body but outside of Div. The reason I am running it this way is because without it, the php file takes too long to load and I want the page to load in a timely way, otherwise the browser just spins for 20 seconds while the data is fetched from a third party. The way it should work is the page should load quickly, and then when the data from the php page is ready it displays inside the div tags.

<div>

<script>
window.onload = function () {
        fetch("https://www.testdomain.com/test.php")
                .then(response => {
                        if (!response.ok) {
                                throw new Error("Network Response was not ok " + response.statusText);
                        }
                        return response.text();
})
                .then(data => {
                        console.log("PHP Response:", data);
                        const preElement = document.createElement("pre");
                        preElement.textContent = data;
                        document.body.appendChild(preElement).innerHTML = data;
                })
                .catch(error => console.error("Error loading PHP file:", error));
};
</script>

</div>

CORS Issue between JS program and Python

I kept encountering CORS issue on my RedwoodJS program with my customize authentication connecting to Supabase. I noticed that when I pass a request with a header, CORS issue is seen: Access to fetch at 'http://localhost:8087/profile' from origin 'http://localhost:8910' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

But when I removed the headers on my request. It works properly. Example of this is my /login API endpoint.

This is my built in authentication with RedwoodJS:

import { useState, useEffect, useCallback } from 'react'
import { config } from 'src/config'
import { logger } from 'src/loggers/logger'

export const useAuth = () => {
  const [user, setUser] = useState(null)
  const [token, setToken] = useState(localStorage.getItem('token'))
  const [loading, setLoading] = useState(true)

  const logIn = async (email: string, password: string) => {
    try {
      const url = config.REDWOOD_ENV_API_ENDPOINT + '/login'
      logger.info(`Login URL is: ${url}`)
      logger.info(
        `JSON body: ${JSON.stringify({ email: email, password: password })}`
      )

      const response = await fetch(url, {
        method: 'POST',
        body: JSON.stringify({ email: email, password: password }),
      })
      console.log(response)
      const result = await response.json()
      if (result.error) {
        throw new Error(result.error)
      }
      const accessToken = result.access_token
      localStorage.setItem('token', accessToken)
      setToken(accessToken)
      setUser(result.user)
      return result
    } catch (error: any) {
      console.error('Login error:', error)
      throw error
    }
  }

  const logOut = useCallback(() => {
    localStorage.removeItem('token')
    setToken(null)
    setUser(null)
  }, [])

  const getProfile = useCallback(async () => {
    const url = config.REDWOOD_ENV_API_ENDPOINT + '/profile'
    if (!token) {
      setLoading(false)
      return
    }

    logger.info(`Fetching profile from ${url}`)

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          Authorization: `bearer ${token}`,
          'Content-Type': 'application/json',
        },
        mode: 'cors',
      })

      logger.info(`Profile response status: ${response.status}`)

      if (!response.ok) {
        const errorText = await response.text()
        logger.error(`Profile error: ${response.status} - ${errorText}`)
        throw new Error(`HTTP error ${response.status}: ${errorText}`)
      }

      const result = await response.json()
      if (result.error) {
        logger.error(`Profile result error: ${result.error}`)
        logOut()
      } else {
        setUser(result.data.user)
      }
    } catch (error) {
      console.error('Profile fetch error:', error)
      logOut()
    }
    setLoading(false)
  }, [token, logOut])

  useEffect(() => {
    getProfile()
  }, [token, getProfile])

  return { user, token, loading, logIn, logOut }
}

Then this is my Python back-end:

def handle_cors_response(request: Request) -> Response:
    origin = request.headers.get("origin")
    allowed_origins = settings.REDWOOD_URL if isinstance(settings.REDWOOD_URL, list) else [settings.REDWOOD_URL]

    if origin in allowed_origins:
        return Response(
            status_code=204,
            headers={
                "Access-Control-Allow-Origin": origin,
                "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
                "Access-Control-Allow-Headers": "Content-Type, Authorization",
                "Access-Control-Allow-Credentials": "true",
            },
        )
    return Response(
        status_code=403,
        headers={"Content-Type": "application/json"},
        description=json.dumps({"error": "Origin not allowed"}),
    )

def get_response_headers(request: Request, content_type: str = "application/json") -> dict:
    origin = request.headers.get("origin")

    return {
        "Content-Type": content_type,
        "Access-Control-Allow-Origin": origin,
        "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
        "Access-Control-Allow-Headers": "content-Type, authorization",
        "Access-Control-Allow-Credentials": "true",
    }

@app.options("/{path:path}")
async def handle_cors(request: Request):
    return Response(
        status_code=204,
        headers=get_response_headers(request),
    )

@app.get("/profile")
async def profile(request):
    auth_header = request.headers.get("Authorization") or request.headers.get("authorization")

    if not auth_header or not auth_header.startswith("bearer "):
        return Response(
            status_code=401,
            headers=get_response_headers(request),
            description=json.dumps({"error": "Unauthorized"})
        )

    token = auth_header.split("bearer ", 1)[1] if "bearer " in auth_header.lower() else auth_header.split("Bearer ", 1)[1]
    try:
        decoded_token = jwt.decode(token, settings.JWT_SECRET, algorithms=["HS256"], audience="authenticated")

        logger.info(f'Decoded token: {decoded_token}')
        return Response(
            status_code=200,
            headers=get_response_headers(request),
            description=json.dumps({"data": {"user": decoded_token}})
        )
    except jwt.ExpiredSignatureError:
        return Response(
            status_code=401,
            headers=get_response_headers(request),
            description=json.dumps({"error": "Token expired"})
        )
    except jwt.InvalidTokenError:
        return Response(
            status_code=401,
            headers=get_response_headers(request),
            description=json.dumps({"error": "Invalid token"})
        )

I’ve tried doing the following:

  • Changed the get_response_headers to use * for debugging purposes. But error still persist:
def get_response_headers(request: Request, content_type: str = "application/json") -> dict:
    origin = request.headers.get("origin")
    return {
        "Content-Type": content_type,
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*",
        "Access-Control-Allow-Headers": "*",
        "Access-Control-Allow-Credentials": "true",
    }
  • Used bruno to make a request with headers for Authorization as intended. Monitored to be working but CORS issue is shown on RedwoodJS app.

Size of html and performance of javascript

Is it true the size of HTML DOM affect the javascript **performance ** or no ?

For example : i have 200 lines of html and the javascript need the access to two lines of DOM only, is it the same with 10 lines of html and the same javascript ?

Code 1 (200 lines) :

<body>
...........200 lines
<script>
//javascript of code 1 = javascript of code 2
</script>
</body>

Code 2 (10 lines) :

<body>
..........10 lines
<script>
//javascript of code 1 = javascript of code 2
</script>
</body>

React-Virtuoso. The problem with using it together with framer-motion

I have implemented a virtual list using the react-virtuoso library. This list is rendered inside a modal window, and the modal window itself has an animated appearance and disappearance, which I implemented using framer-motion.

And so, when I open the modal window, all the data in the virtual list loads perfectly and everything works as it should. But as soon as I close the modal window, I get an error in the console.:

hook.js:608 react-virtuoso: Zero-sized element, this should not happen

My modal

import { FC } from 'react'
import ReactDOM from 'react-dom'
import clsx from 'clsx'
import { AnimatePresence, motion, Variants } from 'framer-motion'
import { useAppDispatch, useAppSelector } from '../../store/hooks'
import { closeModal } from '../../store/slices/UISlice'

import styles from './Modal.module.sass'

interface ModalProps extends React.PropsWithChildren {
    className?: string
}

const overlayVariants: Variants = {
    initial: {
        opacity: 0,
    },
    animate: {
        opacity: 1,
    },
}

const wrapperVariants: Variants = {
    initial: {
        opacity: 0,
        scale: 0,
        fill: 'blur(5px)',
        transition: {
            duration: 0.5,
            ease: [1, 0, 0, 1],
        },
    },
    animate: {
        opacity: 1,
        scale: 1,
        filter: 'blur(0px)',
        transition: {
            duration: 0.5,
            ease: [1, 0, 0, 1],
        },
    },
}

export const Modal: FC<ModalProps> = ({ className, children }) => {
    const { isModalOpen } = useAppSelector((state) => state.UISlice)
    const dispatch = useAppDispatch()

    return ReactDOM.createPortal(
        <AnimatePresence>
            {isModalOpen && (
                <motion.div
                    variants={overlayVariants}
                    initial='initial'
                    animate='animate'
                    exit='initial'
                    className={clsx(className, styles.overlay)}
                    onClick={() => dispatch(closeModal())}
                >
                    <motion.div
                        variants={wrapperVariants}
                        initial='initial'
                        animate='animate'
                        exit='initial'
                        className={styles.wrapper}
                        onClick={(e) => e.stopPropagation()}
                    >
                        {children}
                    </motion.div>
                </motion.div>
            )}
        </AnimatePresence>,
        document.body
    )
}

Component with react-virtuoso

import { FC } from 'react'
import { motion, Variants } from 'framer-motion'

import styles from './CryptoList.module.sass'
import clsx from 'clsx'
import { Virtuoso } from 'react-virtuoso'
import { IToken } from '../../models/tokenTypes'
import { IOptions } from '../CryptoAddPopup/CryptoAddPopup'

interface CryptoListProps {
    className?: string
    filteredCrypto: IToken[]
    setOptions: React.Dispatch<React.SetStateAction<IOptions>>
    setTokenCount: React.Dispatch<React.SetStateAction<number>>
    setIsOptionsVisible: React.Dispatch<React.SetStateAction<boolean>>
}

const listVariants: Variants = {
    initial: {
        opacity: 0,
    },
    animate: {
        opacity: 1,
    },
}

export const CryptoList: FC<CryptoListProps> = ({
    className,
    filteredCrypto,
    setOptions,
    setTokenCount,
    setIsOptionsVisible,
}) => {
    return (
        <motion.ul
            variants={listVariants}
            initial='initial'
            animate='animate'
            className={clsx(className, styles.list)}
        >
            <Virtuoso
                style={{ height: 400 }}
                data={filteredCrypto}
                totalCount={filteredCrypto.length}
                className={styles.virtual}
                itemContent={(_, token) => (
                    <li
                        className={styles.item}
                        key={token.symbol}
                        onClick={() => {
                            setOptions(() => ({
                                token: token.token,
                                tokenPrice: token.price,
                                priceChangePercent: token.priceChangePercent,
                                symbol: token.symbol,
                                totalPrice: 0,
                            }))
                            setTokenCount(1)
                            setIsOptionsVisible(true)
                        }}
                    >
                        <div className={styles.toke}>{token.token}</div>
                        <div className={styles.price}>{token.price.toFixed(2)}$</div>
                        <div
                            className={clsx(
                                styles.percent,
                                token.priceChangePercent < 0 && styles.red
                            )}
                        >
                            {token.priceChangePercent > 0 && '+'}
                            {token.priceChangePercent.toFixed(2)}%
                        </div>
                    </li>
                )}
            />
        </motion.ul>
    )
}

If I rewrite the modal window like this, I will get rid of this error, but I will also lose the smooth closing of the modal coz I delete AnimatePresence tag. I don’t want to lose animation at all =(

import { FC } from 'react'
import ReactDOM from 'react-dom'
import clsx from 'clsx'
import { AnimatePresence, motion, Variants } from 'framer-motion'
import { useAppDispatch, useAppSelector } from '../../store/hooks'
import { closeModal } from '../../store/slices/UISlice'

import styles from './Modal.module.sass'

interface ModalProps extends React.PropsWithChildren {
    className?: string
}

const overlayVariants: Variants = {
    initial: {
        opacity: 0,
    },
    animate: {
        opacity: 1,
    },
}

const wrapperVariants: Variants = {
    initial: {
        opacity: 0,
        scale: 0,
        fill: 'blur(5px)',
        transition: {
            duration: 0.5,
            ease: [1, 0, 0, 1],
        },
    },
    animate: {
        opacity: 1,
        scale: 1,
        filter: 'blur(0px)',
        transition: {
            duration: 0.5,
            ease: [1, 0, 0, 1],
        },
    },
}

export const Modal: FC<ModalProps> = ({ className, children }) => {
    const { isModalOpen } = useAppSelector((state) => state.UISlice)
    const dispatch = useAppDispatch()

    if (!isModalOpen) return null

    return ReactDOM.createPortal(
        <motion.div
            variants={overlayVariants}
            initial='initial'
            animate='animate'
            exit='initial'
            className={clsx(className, styles.overlay)}
            onClick={() => dispatch(closeModal())}
        >
            <motion.div
                variants={wrapperVariants}
                initial='initial'
                animate='animate'
                exit='initial'
                className={styles.wrapper}
                onClick={(e) => e.stopPropagation()}
            >
                {children}
            </motion.div>
        </motion.div>,
        document.body
    )
}

Maybe someone has already encountered such a problem, please help me solve this problem without losing animation from AnimatePresence

Github repo of this project https://github.com/sparkkkd/crypto-portfolio

I am getting Error: Page closed in playwright

async function sortHackerNewsArticles() {
// launch browser
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage()
  await page.goto("*URL*");
`

I am trying to navigate to a URL and I am getting Error: Page closed. I used a try catch , timeout but it didn’t work.

How come the letter `i` breaks my regex for `preg_replace_callback` but works with javascript [duplicate]

I don’t understand why this particular regex with PHP is failing:

<?php
echo preg_replace_callback(
        '/<a(\s[^>]+)* href="([^"]+)"(\s[^>]+)*>/i',
        function ($matches) {
                print_r($matches);
          return $matches[0];
        },
        '<a href="http://s.c/" title=" tickets for htt://v.c/e r ad Clown album elease Martian Crisis Unit Elrichan Wavelengt" tar="">a</a>'
);

When I run the code above, it echoes nothing to terminal.

But if I delete a single character from somewhere, sometimes the echo will work. For example, if change the word Martian to Martan (ie. drop the letter i), then everything works fine.

What have I misunderstood about my regex pattern? What is so special about the letter i that would break my regex?


However, this works fine in javascript:

'<a href="http://s.c/" title=" tickets for htt://v.c/e r ad Clown album elease Martian Crisis Unit Elrichan Wavelengt" tar="">a</a>'.match(/<a(s[^>]+)* href="([^"]+)"(s[^>]+)*>/i);

The javascript version gives me an array of matches.