Vue.js multiple components not working well with each other

so I have 2 vue components (ToolBar and ProjectWindow) and 1 view (ProjectsView), The ToolBar is used both in ProjectWindow and in ProjectView.
In the ToolBar I have 2 buttons, one for setting the opacity of a given elemt to 0 (close) and one to set the height of the element to 50px and to move it at the bottom of the screen.
The ProjectWindow is a card that displays some information that it gets through an API call.
And On the ProjectView I have a button in the top right corner (folder).
When I press the folder Button a card is being shown with 3 elements on it (3 of my projects). This card also has the ToolBar element.
When I open the folder card and close it using the toolbar, there’s no problem, I can open it back again pressing the folder button. But if I open one of the 3 projects in the ProjectWindow card and close it, I can no longer open the folder card.

  • This is ToolBar :
<script>
  export default {
    name: 'ToolBar',
    props: {
      card: Object,
      projectWindow: Object,
    },
    data() {
      return {
        isMinimized: false,
      }
    },
    methods: {
      toggleSize() {
        if (this.card) {
          this.card.style.opacity = 10;
          if (this.projectWindow) {
            this.projectWindow.style.opacity = 0;
          }
          this.card.style.transition = "all 0.5s ease-in-out";
          if (this.isMinimized) {
            this.card.style.height = "500px";
          } else {
            this.card.style.marginTop = "auto";
            this.card.style.height = "50px";
            this.card.style.overflow = "hidden";
          }
          this.isMinimized = !this.isMinimized;
        } else {
          console.error("Card element not found");
        }
        if (this.projectWindow) {
          if (this.card) {
            this.card.style.opacity = 0;
          }
          this.projectWindow.style.transition = "all 0.5s ease-in-out";
          if (this.isMinimized) {
            this.card.style.height = "500px";
          } else {
            this.projectWindow.style.marginTop = "auto";
            this.projectWindow.style.height = "50px";
            this.projectWindow.style.overflow = "hidden";
          }
          this.isMinimized = !this.isMinimized
        } else {
          console.error("Project Window not found!")
        }
      },
      close() {
        if (this.card) {
          this.card.style.opacity = 0;
        } else {
          console.error("Card element not found in close func")
          this.$emit('close-project-window')
        }
        if (this.projectWindow) {
          this.projectWindow.style.opacity = 0;
          this.$emit('close-project-window');
        }
      }
    },
  }
</script>

<template>
  <div class="toolbar">
    <h4 v-if="isMinimized" @click="toggleSize" id="maximize" class="bi bi-fullscreen"></h4>
    <h4 v-else @click="toggleSize" id="minimize" class="bi bi-fullscreen-exit"></h4>
    <h4 @click="close" class="bi bi-x-square" style="color: darkred"></h4>
  </div>
</template>

<style lang="scss">
  .toolbar {
    display: flex;
    flex-direction: row;
    margin-left: auto;
    gap: 20px;
  }
</style>
  • This is the ProjectWindow:
<script>
import axios from 'axios';
import { ref, onMounted } from 'vue';
import ToolBar from "@/components/ToolBar.vue";

export default {
  name: 'ProjectWindow',
  components: { ToolBar },
  props: {
    slug: String,
  },
  data() {
    return{
      projectWindow: null
    }
  },
  setup(props) {
    const projectData = ref({
      name: null,
      slug: null,
      description: null,
      gitHub: null,
      isHosted: null,
      hostLink: null,
    });

    onMounted(async () => {
      try {
        const response = await axios.get(`/api/v1/projects/`);
        const project = response.data.find(p => p.slug === props.slug);

        if (project) {
          projectData.value = {
            name: project.name,
            slug: project.slug,
            description: project.description.replace(/\n/g, '<br>'),
            gitHub: project.github,
            isHosted: project.is_hosted,
            hostLink: project.host_link,
          };
        }
      } catch (error) {
        console.error(error);
      }
    });

    return {
      projectData,
    };
  },
  mounted() {
    this.projectWindow = document.getElementById('projectWindow');
  }
};
</script>

<template>
  <section class="container" id="projectWindow">
    <div class="card">
      <div class="card-header">
        <h3 class="title">{{ projectData.name }}</h3>
        <ToolBar :project-window="this.projectWindow"/>
      </div>
      <div class="card-body" id="card-body">
        <div class="description" v-html="projectData.description">
        </div>
      </div>
      <div class="card-footer" id="card-footer" style="display: flex; flex-direction: row; gap: 10px">
        <a :href="projectData.gitHub" target="_blank" class="btn btn-primary">GitHub</a>
        <a v-if="projectData.isHosted" :href="projectData.hostLink" target="_blank" class="btn btn-primary">Website Link</a>
      </div>
    </div>
  </section>
</template>
  • And this is the ProjectView:
<script>
import ProjectWindow from "@/components/ProjectWindow.vue";
import ToolBar from "@/components/ToolBar.vue";

export default {
  name: 'Projects',
  components: {ToolBar, ProjectWindow},
  data() {
    return {
      slug: null,
      isFolderOpen: false,
      card: null,
      projectWindow: null,
      isGameOpen: false,
    }
  },
  watch: {
    isFolderOpen: function () {
      this.card.style.opacity = 1;
    }
  },
  methods: {
    openGame(slug) {
      this.projectWindow = document.getElementById('projectWindow');
      this.card.style.opacity = 10;
      if (this.projectWindow) {
        this.projectWindow.style.opacity = 10;
      } else {
        console.error("No project window in project view")
      }
      this.slug = slug
      this.isGameOpen = !this.isGameOpen
    },
    openFolder() {
      this.card.style.opacity = 1;
      this.isFolderOpen = !this.isFolderOpen
      console.log(this.isFolderOpen)
    },
    closeProjectWindow() {
      this.isGameOpen = false
      this.card = document.getElementById('card');
      console.log(this.card)
    }
  },
  mounted() {
    this.card = document.getElementById('card');
  }
};
</script>

<template>
  <div class="side-container">
    <div v-if="isFolderOpen"><i class="bi bi-folder2-open" @click="openFolder"></i></div>
    <div v-else><i class="bi bi-folder2" @click="openFolder"></i></div>
  </div>
  <div id="projectWindow">
    <ProjectWindow :slug="this.slug" v-if="isGameOpen"/>
  </div>
  <section class="games container" id="card">
    <div class="card"  v-if="isFolderOpen">
      <div class="card-header">
        <h3 class="title">Games</h3>
        <ToolBar :card="card" :project-window="projectWindow" @close-project-window="closeProjectWindow()"/>
      </div>
      <div class="card-body" id="card-body">
        <div class="game">
          <label for="shoot">Shoot The Crow</label>
          <div id="shoot"><i class="bi bi-bullseye" style="color: red" @click="openGame('shootthecrow')"></i></div>
        </div>
        <div class="game">
          <label for="guess">Guess The Number</label>
          <div id="guess"><i class="bi bi-patch-question" style="color: green" @click="openGame('guessthenumber')">
          </i></div>
        </div>
        <div class="game">
          <label for="pig">The Pig Game</label>
          <div id="pig"><i class="bi bi-dice-5-fill" style="color: mediumpurple" @click="openGame('piggame')"></i></div>
        </div>
      </div>
    </div>
  </section>
</template>

Thank you for taking the time to read this. I no longer know what to try.

I tried passing the ProjectWindow to the TooBar component as an html object but that only stopped it for working

How can I enable the Notification module in an in-app Chromium browser? (Uncaught ReferenceError: Notification is not defined)

I’m working on an application that has an in-app browser based on Chromium. I need to allow a user to interact with a certain server (that I don’t have internal access to) through this browser. Some interactions, like clicking on specific buttons, fail with the console message “Uncaught ReferenceError: Notification is not defined”. From what I can surmise, this means the server is trying to send me a notification using the Notifications API, but my browser doesn’t support it. I’ve confirmed that !Notification evaluates to true and "Notification" in window evaluates to false. I’ve also checked for window.chrome.notifications, window.webkitNotifications, and any other kind of notification module that I could find evidence of on the Internet. Nothing related to notifications is loaded, as far as I can tell.

On Firefox, there’s apparently a setting that causes Notification to never be loaded at all. I’m hoping that’s what’s happening here, but I can’t find any evidence of such a setting in Chromium browsers, much less how to disable it.

How can I allow Chromium to recognize Notification?

Why do I get the error “Service not found” when trying to get my jwt

When I trying to call jwt to authenticate via auth0, it throws an error: “Service not found: http://localhost:8000”.

import React, { useContext, useEffect } from 'react'
import Header from '../Header/Header'
import Footer from '../Footer/Footer'
import { Outlet } from "react-router-dom"
import { useAuth0 } from "@auth0/auth0-react"
import UserDetailContext from '../../context/UserDetailContext'
import { useMutation } from "react-query";
import { createUser } from '../../utils/api.js'

const Layout = () => {

    const { isAuthenticated, user, getAccessTokenWithPopup } = useAuth0()
    const { setUserDetails } = useContext(UserDetailContext)

    const { mutate } = useMutation({
        mutationKey: [user?.email],
        mutationFn: (token) => createUser(user?.email, token)
    });

    useEffect(() => {

        const getTokenAndRegister = async () => {
            const res = await getAccessTokenWithPopup({
                authorizationParams: {
                    audience: "http://localhost:8000",
                    scope: "openid profile email"
                }
            })
            localStorage.setItem("access_token", res)
            setUserDetails((prev) => ({ ...prev, token: res }));
            console.log(res)
        }

        isAuthenticated && getTokenAndRegister()
    }, [isAuthenticated]);
    return (
        <>
            <div style={{ background: "var(--black)", overflow: "hidden" }}>
                <Header />
                <Outlet />
            </div>
            <Footer />
        </>
    )
}

export default Layout

auth0Config.js

import {auth} from 'express-oauth2-jwt-bearer'

const  jwtCheck = auth({
    audience: "http://localhost:8000",
    issuerBaseURL: "my url)",
    tokenSigningAlg: "RS256"
})

export default jwtCheck

main.jsx

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { Auth0Provider } from "@auth0/auth0-react"

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <Auth0Provider
    domain="my domain)"
    clientId="rmy id)"
    authorizationParams={{
      redirect_uri: "http://localhost:5173"
    }}
    audience="http://localhost:8000"
    scope="openid profile email"
    >
    <App />
    </Auth0Provider>
  </React.StrictMode>
);

Error

I tried to rewrite the code from scratch but no luck. Also updated all dependencies to the latest versions, the error persists. Instead of a token, I get a service not found.

App Script – Copy and past function is moving data to the row below

I have found a script to copy the range data one sheet (Name My Sheet dataBase) to another sheet (Name My Sheet Destiny) in the first cell and than each one after when it runs.

But, when pasting the data range for “#column1 – #column15”, it copy to row A3 instead of to past to row A2 because in the #column17 i need the formula to calculate the due date of when data it copied.

I did get to explain what is happening and what I need to do to adjust the function?

Thanks.

enter image description here

const app = SpreadsheetApp;
const ss = app.getActiveSpreadsheet();
const sheet1 = ss.getSheetByName("Name My Sheet dataBase");
const lastrowD = sheetD.getLastRow();
const dados = sheet1.getRange("A2:O" + lastrowD).getValues();
const ssB = app.openById("ID My Sheet Destiny");
const sheetB = ssB.getSheetByName("Name My Sheet Destiny");
const lastrowB = sheetB.getLastRow()+1;
sheetB.getRange(lastrowB, 1, lastrowD - 1, 15).setValues(dados);

I am new to React, but I have a tic-tac-toe error

import './App.css';
import Board from './component/Board';


function App() {

  return (
    <div className="App">
    <Board />
    </div>
  );
}

export default App;

import React,{useState} from 'react'
import Board from './Board'

function Game() {
  const [xIsNext, setXIsNext] = useState(true);
  const [history, setHistory] = useState([Array(9).fill(null)]);
  const currentSquares = history[history.length - 1]; //?

  function handlePlay(nextSquares) {
    // TODO
    setHistory([...history, nextSquares]);
    setXIsNext(!xIsNext);
  }

  

  return (
    <div className='game'>
      <div className="game-board">
        <Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
      </div>
      <div className="game-info">
        <ol></ol>
      </div>
    </div>
  )
}

export default Game

import React, { useState } from 'react';
import Square from './Square';

export default function Board({ xIsNext, squares, onPlay }) {
  // const [squares, setSquares] = useState(Array(9).fill(null));

  // const [xIsNext, setXIsNext] = useState(true);

  function handleClick(i) {
    if (squares[i] || calculateWinner(squares)) {
      return;
    }
    const nextSquares = squares.slice();

    if (xIsNext) {
      nextSquares[i] = 'X';
    } else {
      nextSquares[i] = 'O';
    }
    // setSquares(nextSquares);
    // setXIsNext(!xIsNext);
    onPlay(nextSquares);
  }
  function calculateWinner(squares) {
    if (!Array.isArray(squares)) {
      console.error('Invalid squares array. Not an array:', squares);
      return null;
    }

    const lines = [
      [0, 1, 2],
      [3, 4, 5],
      [6, 7, 8],
      [0, 3, 6],
      [1, 4, 7],
      [2, 5, 8],
      [0, 4, 8],
      [2, 4, 6],
    ];

    for (let i = 0; i < lines.length; i++) {
      const [a, b, c] = lines[i];
      if (
        squares[a] &&
        squares[b] &&
        squares[c] &&
        squares[a] === squares[b] &&
        squares[a] === squares[c]
      ) {
        return squares[a];
      }
    }

    console.error('No winner found. Current state of squares:', squares);
    return null;
  }

  const winner = calculateWinner(squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (xIsNext ? 'X' : 'O');
  }

  return (
    <>
      <div className="status">{status}</div>
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </>
  );
}

import React, { useState } from 'react';
import './Square.css';

export default function Square({ value, onSquareClick }) {


    return <button className="square" onClick={onSquareClick}>{value}</button>;
  }


Above is my code. I am a beginner who studies by looking at the official document, and although it seems to have been written in the same way, I keep getting errors like the one in the picture.

enter image description here

enter image description here

What’s the problem? Please help me

I’ve read the official documentation several times, but I just can’t figure it out…

Using Javascript arrays to put random words into a madlib

I am putting together a madlib site for a class and one of the parts of the assignment is to make a button that will randomly assign words from arrays into the madlib. I can’t figure out how to get that to work. I’ve tried a few different things, such as:

let nounArray = ["item1", "item2", "item3"];
function randomWord()
{
    console.log(nounArray[(Math.floor(Math.random() * nounArray.length))]);
}

but it doesn’t seem to work the way I need it to. It keeps returning all of the items in the array, not just picking one. The little story looks like this:

let storyContent = "All of the " + nounArray + " and " + noun2Array + " were gone when he awoke, finding that the " + noun3Array + " now continued uninterrupted in their place. He tried to " + verbArray + " for help, but was " + adjectiveArray + " to find that his mouth was " + adjective2Array + ", the lower half of his face now " + adjective3Array + ", continuous flesh. He tried to " + verb2Array + " his panic by closing his eyes and counting to ten. On the eleventh second of darkness, he realised his mistake."

inside my madlib2() function.

Do I need to do something different with the nounArray, noun2Array, etc., within the storyContent? The main part of the assignment works (the part where you request that a person inputs different words and they are inserted into the story), this is the only part I can’t get to work. Any ideas? I’ll include the full Javascript below just in case.

var noun = [];
var noun2 = [];
var noun3 = [];
var verb = []
var verb2 = []
var adjective = [];
var adjective2 = [];
var adjective3 = [];
var storyContent = ""; //story that will be displayed when run

madlib(); //madlib function

function madlib()
{
    let wordform = document.getElementById("wordform"); //calls the form in the HTML
    let noun = document.getElementById("Noun").value;
    let noun2 = document.getElementById("Noun2").value;
    let noun3 = document.getElementById("Noun3").value;
    let verb = document.getElementById("Verb").value;
    let verb2 = document.getElementById("Verb2").value;
    let adjective = document.getElementById("Adjective").value;
    let adjective2 = document.getElementById("Adjective2").value;
    let adjective3 = document.getElementById("Adjective3").value;

    let storyContent = "All of the " + noun + " and " + noun2 + " were gone when he awoke, finding that the " + noun3 + " now continued uninterrupted in their place. He tried to " + verb + " for help, but was " + adjective + " to find that his mouth was " + adjective2 + ", the lower half of his face now " + adjective3 + ", continuous flesh. He tried to " + verb2 + " his panic by closing his eyes and counting to ten. On the eleventh second of darkness, he realised his mistake."

    document.getElementById("content").innerHTML = storyContent;
}

let generateBtn = document.getElementById("button");
generateBtn.addEventListener('click', madlib);

const nounArray = ["pebbles", "shoes", "trees"];
let noun2Array = ["seats", "books", "houses"];
let noun3Array = ["balls", "games", "spatulas"];
let verbArray = ["bolt", "leap", "fall"];
let verb2Array = ["lay", "sing", "skate"];
let adjectiveArray = ["golden", "chosen", "eerie"];
let adjective2Array = ["cautious", "slim", "probable"];
let adjective3Array = ["wide", "ossified", "overjoyed"];

function madlib2()
{
    let storyContent = "All of the " + nounArray + " and " + noun2Array + " were gone when he awoke, finding that the " + noun3Array + " now continued uninterrupted in their place. He tried to " + verbArray + " for help, but was " + adjectiveArray + " to find that his mouth was " + adjective2Array + ", the lower half of his face now " + adjective3Array + ", continuous flesh. He tried to " + verb2Array + " his panic by closing his eyes and counting to ten. On the eleventh second of darkness, he realised his mistake."

    document.getElementById("content").innerHTML = storyContent;
}

let randomBtn = document.getElementById("button2");
randomBtn.addEventListener('click', madlib2);

function showhide()
{
    var div = document.getElementById("content");
    div.classList.toggle('hidden');
    var div = document.getElementById("end");
    div.classList.toggle('hidden');
    var div = document.getElementById("line");
    div.classList.toggle('hidden');
}

function randomWord()
{
    console.log(nounArray[(Math.floor(Math.random() * nounArray.length))]);
}
randomWord()

I tried the things I mentioned above and they didn’t work.

“@” me impide leer en javascript valor recibido de procedimiento almacenado mysql

-Trabajo con javascript en el front-end, nodejs en el back-end y mysql
-Realizo una petición get desde el front-end.
-En el backend:
-Llamo a un procedimiento almacendado de mysql que pose un parámetro out
-Consulto el valor de ese parámetro y lo envío al front end.
-Consulto el valor recibido en el front-end, obteniendo:
{@dato: 100}
El “@” es imprescindible para obtener un parámetro de salida en procedimiento
almacenado mysql.
El problema es que en, en el front-end no puedo consultar ese valor porque
javascript no admite que las variables o nombres de atributos comiencen
con “@”

Me podrían sugerir como solucionar esto o qué estoy haciendo mal?

count of samples (frames) lost from microphone

I need a counter of lost frames from microphone or an event if samples from microphone are lost. I need this information to perfect timing microphone signal and audio output signal.

I have code:

   $micStream=await navigator.mediaDevices.getUserMedia(
      {
         audio:
         {
            echoCancellation: false,
            noiseSuppression: false,
            autoGainControl: false,
         }
      }
   );
   $micAudioCtx=new AudioContext();
   $micMS=$micAudioCtx.createMediaStreamSource($micStream);

      if($micAudioCtx.audioWorklet && $micAudioCtx.audioWorklet.addModule)
      {
         var $data=`
class RecorderProcessor extends AudioWorkletProcessor
{
   bufferSize=17640;
   written=0;
   buffer=new Float32Array(this.bufferSize);
   frame=0;

   process($inputs)
   {
      var $cd=$inputs[0][0];
      var $cf=currentFrame;
      if(!$cd) return true;

      if(this.frame<$cf && $cf-this.frame<500000)
      {
         for(var $i=this.frame; $i<$cf; $i++)
         {
            this.buffer[this.written++]=0;
            if(this.written===this.bufferSize)
            {
               this.port.postMessage(this.buffer.slice(0, this.bufferSize));
               this.written=0;
            }
         }
      }
      this.frame=$cf+$cd.length;
      for(var $i=0, $c=$cd.length; $i<$c; $i++)
      {
         this.buffer[this.written++]=$cd[$i];
         if(this.written===this.bufferSize)
         {
            this.port.postMessage(this.buffer.slice(0, this.bufferSize));
            this.written=0;
         }
      }
      return true;
   }
}

registerProcessor('VAProcessor', RecorderProcessor);
               `;
         $data='data:text/javascript;base64,'+btoa($data);
         await $micAudioCtx.audioWorklet.addModule($data);
         $micRec=new AudioWorkletNode($micAudioCtx, 'VAProcessor');
         $micRec.port.onmessage=function($e){anyFunctionToProcessSamples($e.data);};

Firefox loses one sample (or a small amount) from microphone in random moments. For example during higher load or launching other applications. I need information that samples was lost and count of lost samples.


BTW. I won’t be able to respond to your questions. I reported it to Stack Overflow support without any reaction…

I will be a grateful for any advice also.

Listen for “Refused to execute script… because its MIME type (‘text/html’) is not executable, and strict MIME type checking is enabled.” error

I have a react app that intermittently on deploying looks to fetch a bundled JavaScript asset that does not exist yet on the server. The error surfaces itself with the error

Refused to execute script from 'https://example.com/mycookscript.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.

Because it is requesting a non existing asset, and my server is returning with a 404 type=text/html page.

How would I listen for this specific error and do some action upon listening to it? I know that I will add a listener with
window.addEventListener('error', function (e) { /*do something*/ }); but I only want to do this thing when the asset responds with HTML for a non existing script.

Additionally this specific error only surfaces on production, adding <script src="/non-existing-asset.js"></script> does not reproduce the error locally.

passing array results from php to jquery after post

I am trying to pass array results from a php submission form back to jquery i can trigger a success or fail message using toast.

i am using


                $ret["icon"] = "success";
                $ret["title"] = "Request Deleted Successfully";
                echo json_encode($ret);

this is the result

{"icon":"success","title":"Request Deleted Successfully"}

but to trigget the toast object i need

Toast.fire({icon: 'success',title: 'Request Deleted Successfully.'})

Looking at the different i only need to remove the commas from the array key but i dont know how to do this in jquery or javascript

Can anyone please help

How to set view’s height responsive?

I have 2 static views: Headline and Bottom navigator (as mentioned in the attached visualization) with 3 rem and 3.5 rem height respectively, and I want to put a responsive view between them (the light blue area). The responsive view is supposed to include list views of elements (green ones) with scroll view.
I have 2 questions:

  1. How can I make the green view responsive as being between two static views? is there any way to calculate its height in a way that it would be the same on different screens?

  2. Every green element is 7 rem in height. How can I display different amounts of (complete) elements in different screens as the maximum as possible according to the wrapper view’s height? I mean that I don’t want that some kind of screen will cut an element between scrolls..

I tried to give percentage height for the top and bottom views but I want their height to be static.

visualization

Angular Routable Modal keeps opening in new page, rather than on parent page

I’m trying to create a routable modal, but the problem is keeps, it navigates to the router link in a new page, then shows the modal.

I’m following the exact same approach here, but have created my own custom modal service.
I must be missing something simple as I can’t work out why it works effortlessly here:

https://stackblitz.com/edit/routable-modals?file=src%2Fapp%2Fmodal-container.component.ts

Route

  {
    path: 'contracts/:id',
    title: 'App | Contract Detail ',
    component: ModalContainerComponent
  },

Modal Container

@Component({
  selector: 'app-modal-container',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './modal-container.component.html',
  styleUrl: './modal-container.component.scss'
})
export class ModalContainerComponent {

  private ngUnsubscribe$: Subject<void> = new Subject<void>()
  private modalService = inject(ModalService) // handle Modals

  constructor(
    private route: ActivatedRoute,
    private router: Router
  ) {
    this.route.params.pipe(takeUntil(this.ngUnsubscribe$)).subscribe((params) => {
      // When the router navigates to this component, open the photo detail modal
       console.log(params['id'])
      this.openModal();
    });
  }

  ngOnDestroy(): void {
    this.ngUnsubscribe$.next();
    this.ngUnsubscribe$.complete();
  }

  // open department filter modal, from this routable modal
  openModal() {
    // Use your existing modal service
    this.modalService.open({
      modalType: 'contract-detail',
      modalComponentType: 'ContractDetailComponent',
      title: 'Contract', 
    });
  }

}

Modal Service (not 3rd party, NgbModule)

@Injectable({
  providedIn: 'root'
})
export class ModalService {
  /* data properties */
  private static mapper: { [key: string]: any } = {
    'ContractDetailComponent': ContractDetailComponent
  }
  private static modalRef: any
  private static modalRefs: { [modalType: string]: any } = {};
  private static modalInstance: any
  private static modalInstances: { [modalType: string]: any } = {};

  /* subjects */
  private static modalNotifier? : Subject<boolean>;

  /* observables */
  public modalNotifier$? : Observable<boolean>;

  // signal store
  private static readonly modalResultSignals: { [modalType: string]: WritableSignal<any> } = { 'empty' : signal<any>( undefined ) }

  /* life-cycle hooks */
  private constructor(
    private applicationRef: ApplicationRef
  ) {}
  protected ngOnDestroy() {
    ModalService.modalInstances = {};
    ModalService.modalRefs = {};
  }

  /* functions */

  /* signal store functions */

  // get modal result signal from store, otherwise initialise with undefined
  public getModalResult(modalType: string){
    if (ModalService.modalResultSignals[modalType] === undefined) {
      ModalService.modalResultSignals[modalType] = signal(undefined)
    }
    return computed(() => ModalService.modalResultSignals[modalType]())
  }

  /* main modal service functions */

  // open modal, and return observable
  public open( options: { 
          modalType : string;
          modalComponentType: string;
          title?: string;   
          size?: string; 
          uniqueItems? : string[]
        }
    ) : void {

    const modalComponentType = ModalService.mapper[options.modalComponentType]
    const modalType = options?.modalType ?? '';

    // initialise the modal lazily, if it doesn't already exist
    if (ModalService.modalInstances[modalType] === undefined) {
      this.initializeModal(modalComponentType);
      this.configureModalInputs(options);
      this.configureModalSubscriptions(); // do this only once!
      this.saveModalInstancesToDictionaries(modalType);
    }

    // otherwise retrieve from dictionary, refresh properties, and insert
    this.getModalInstancesFromDictionaries(modalType)
    this.refreshModalProperties(options);
    this.detectChanges();
    this.openModal();
    this.startModalNotifier();
  }

  // open modal
  private openModal(): void {
    ModalService.modalInstance.open();
  }

  // result - save to signal store
  private resultModal(result: any): void {
    ModalService.modalResultSignals[result.modalType].set(result);
  }

  // submit
  private submitModal() {
    ModalService.modalNotifier?.next(true);
    this.closeModal()
  }

  // close
  private closeModal() {
    ModalService.modalNotifier?.complete
  }

  /* helper functions */

  // initialise the modal lazily, if it doesn't already exist
  private initializeModal(modalComponentType: any): void {
    const rootViewContainerRef = this.applicationRef.components[0].injector.get(ViewContainerRef);
    ModalService.modalRef = rootViewContainerRef.createComponent(modalComponentType);
    ModalService.modalInstance = ModalService.modalRef.instance;
  }

  // configure inputs of modal
  private configureModalInputs(options: any): void {
    ModalService.modalInstance.modalType = options.modalType ?? '';
    ModalService.modalInstance.title = options.title ?? '';
  }

  // configure subscriptions (once only!) 
  private configureModalSubscriptions(): void {
    ModalService.modalInstance.resultEvent.subscribe(($event: any) => this.resultModal($event));
    ModalService.modalInstance.submitEvent.subscribe(() => this.submitModal());
    ModalService.modalInstance.closeEvent.subscribe(() => this.closeModal());
  }

  // save instances to dictionaries
   private saveModalInstancesToDictionaries(modalType: string): void {
    ModalService.modalRefs[modalType] = ModalService.modalRef;
    ModalService.modalInstances[modalType] = ModalService.modalInstance;
  }

  // get instances from dictionaries
  private getModalInstancesFromDictionaries(modalType: string): void {
    ModalService.modalRef = ModalService.modalRefs[modalType]
    ModalService.modalInstance = ModalService.modalInstances[modalType]
  }

  // refresh existing modal properties, if modal instance does happen to already exist
  private refreshModalProperties(options: any): void {
    ModalService.modalInstance.title = options.title ?? '';
  }

   // detect changes
  private detectChanges(): void {
    ModalService.modalRef.hostView.detectChanges();
  }

  // create Subject / Observable instance
  private startModalNotifier(): void {
    ModalService.modalNotifier = new Subject();
    this.modalNotifier$ = ModalService.modalNotifier.asObservable();
  }


}

How to pause blinking christmas lights with a christmas song in CSS/Javascript?

I’m working on a CSS animation where I have blinking lights on a Christmas tree on beat to a Christmas song, and when I press on the button below the tree to pause the songs the lights will also pause blinking. And when I press the button again to play the song the light will resume blinking.

This is what I have so far. I’ve managed to get the lights to blink but when I tried adding audio it doesn’t run.

HTML

<body>

<div class="christmas-tree">

  <div class="tree-top">
    <div class="lights-top">
      <div class="light light-red"></div>
      <div class="light light-yellow"></div>
      <div class="light light-blue"></div>
      <div class="light light-green"></div>
    </div>
  </div>

  <div class="tree-middle">
    <div class="lights-middle">
      <div class="light light-blue"></div>
      <div class="light light-red"></div>
      <div class="light light-green"></div>
      <div class="light light-yellow"></div>
    </div>
  </div>

  <div class="tree-bottom">
    <div class="lights-bottom">
      <div class="light light-green"></div>
      <div class="light light-yellow"></div>
      <div class="light light-red"></div>
      <div class="light light-blue"></div>
    </div>
  </div>
  <div class="play-pause">
    <button onclick="pauseButton()">Pause / Resume</button>
  </div>
</div>

<audio id="christmasSong" controls>
  <source src="I Saw Mommy Kissing Santa Claus Jackson 5-GPNu0H6jNJc-192k-1702586134.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>

</body>

CSS

.christmas-tree {
    top: 10%;
  }

  .play-pause {
    /* top: 50%; */
    padding-top: 30px;  
    left: 23%;
    position: relative;
  }

button {
display: inline-block;
            padding: 10px 20px;
            font-size: 16px;
            text-align: center;
            text-decoration: none;
            background-color: #FF0000;
            color: #FFFFFF;
            border: none;
            border-radius: 5px;
            cursor: pointer;
}

button:hover {
  background-color: #ffffff;
  color: #d21d1d;
}

.tree-top {
    top: 2%;
    left: 14%;
    position: relative;
    width: 0;
    height: 0;
    border-left: 100px solid transparent;
    border-right: 100px solid transparent;
    border-bottom: 160px solid green;
    /* animation: move 2s infinite; */
  }

  .tree-middle {
    margin-top: -15%;
    margin-left: 10%;
    position: relative;
    width: 15px;
    height: 10px;
    border-left: 100px solid transparent;
    border-right: 100px solid transparent;
    border-bottom: 160px solid green;
    /* animation: move 2s infinite; */
  }

  .tree-bottom {
    margin-top: -20%;
    margin-left: 7%;
    position: relative;
    width: 25px;
    height: 25px;
    border-left: 100px solid transparent;
    border-right: 100px solid transparent;
    border-bottom: 160px solid green;
    /* animation: move 2s infinite; */
  }

.lights-top {
    position: absolute;
    bottom: -100px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 10px;
  }

  .lights-middle {
    position: absolute;
    bottom: -115px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 20px;
  }

  .lights-bottom {
    position: absolute;
    bottom: -120px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 25px;
  }

/* BLINKING LIGHTS */
  .light {
    width: 20px;
    height: 25px;
    border-radius: 50%;
    animation: blink 1s infinite alternate;
    animation-play-state: paused;
  }

  .light-red {
    background-color: #f00;
    animation-duration: 0.6s;
  }

  .light-yellow {
    background-color: rgb(246, 255, 0);
    animation-duration: 0.45s;
  }

  .light-blue {
    background-color: rgb(0, 85, 255);
    animation-duration: 0.5s;
  }

  .light-green {
    background-color: rgb(17, 255, 0);
    animation-duration: 0.7s;
  }


  @keyframes blink {
    0% {
      opacity: 1;
    }
    100% {
      opacity: 0.3;
    }
  }

Javascript

let play = false;

const lights = document.querySelectorAll('.light');
    const christmasSong = document.getElementById('christmasSong');
    const audioContext = new (window.AudioContext || window.webkitAudioContext)();

    const gainNode = audioContext.createGain();
    const audioSource = audioContext.createMediaElementSource(christmasSong);
    audioSource.connect(gainNode);
    gainNode.connect(audioContext.destination);

    function pauseButton() {
      if (play === false) {
        lights.forEach(light => {
          light.style.animationPlayState = "running";
        });
        christmasSong.play();
        gainNode.gain.setValueAtTime(1, audioContext.currentTime);
        play = true;
      } else {
        lights.forEach(light => {
          light.style.animationPlayState = "paused";
        });
        christmasSong.pause();
        gainNode.gain.setValueAtTime(0, audioContext.currentTime);
        play = false;
      }
    }

how do i set up and install npm package for a project

Hi there i am trying to play around with packages and installed the date-fns package but cant seem to use it, i have a feeling its because of how my folders are set up but dont know the right way, where should my node modules folder and json package folders be in relation to my folder with all the projects im working on be? my projects are in a folder called projects on my desktop

i have tried moving the projects folder intot he node modules folder that didnt work and i tried moving node modules into the project folder that didnt work

Move element SVG path based on scroll position [closed]

How moving element – example bullet, whatever – Along my svg line?

I need to move an element along a line as in the attached image. Is anyone able to help me?

<svg width="336px" height="992px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Warstwa_1" x="0px" y="0px" style="enable-background:new 0 0 595.28 841.89;" xml:space="preserve" viewBox="158.23 36.24 279.41 769.41">
  <style type="text/css">
    .st0 {
      fill: none;
      stroke: #000000;
      stroke-width: 2;
      stroke-miterlimit: 10;
      stroke-dasharray: 12;
    }
  </style>
  <path class="st0" d="M159.23,804.65c130.77-64.45,162.06-122,164.34-164.34c3.5-64.96-61.55-89.73-111.57-218.61  c-21.22-54.68-46.34-119.4-31.66-183.94C212.2,97.61,412.37,43.48,436.64,37.24"/>
</svg>

example

How moving element – example bullet, whatever – Along my svg line?