Show Read More Link for Truncated Text

I have 8 divs with the class of bios_ellipsis with 8 links with the class of read_more. When the browser is made smaller, the clientWidth also becomes smaller and I am using the following css in order to truncate the text:

.bios_ellipsis {
vertical-align: middle!important;
overflow: hidden!important;
text-overflow: ellipsis!important;
display: -webkit-box!important;
-webkit-line-clamp: 5!important; 
line-clamp: 5!important;
-webkit-box-orient: vertical!important;
display: -moz-box;
}

I want the read more link to appear for every bios_ellipsis div and this link goes to 8 different urls. The problem with the code below is that the read more links end up in different places on top of the divs and don’t show up in an orderly manner.

jquery cdn

<script>
    $(document).ready(function(){
        
     var getElements = document.querySelectorAll('.bios_ellipsis');
     
      Array.from(getElements).forEach(function(element) {
      var pos = $('.bios_ellipsis').offset();
      if ( element.clientWidth <= 600 ) {
    
    for(var i = 0; i < getElements.length; i++){
    var top = pos.top[i] + '100px';
    var left = pos.left[i] + '500px';
    
    $('.read_more').css({
      position:'absolute',
      top:top[i],
      left:left[i]
    });
    
    }}
    });
    });
</script>

VueJS [email protected] Component v-model does not update parent initially

I have a parent child component setup to test v-model. The child updates parent when you enter a value but not initially.

parent:

<script setup>

import { ref } from 'vue';

import TextInput from './TextInput.vue';

const size = ref(1);
const color = ref('red');
</script>

<template>

  <TextInput v-model:size="size" v-model:color.capitalize="color" />
  <div :style="{ fontSize: size + 'em', color: color }">
    <!-- Question 1: this line shows "red" but "Red" is what I want initially -->
    <p>{{ size }} {{ color }}</p>
  </div>

</template>

child: TextInput.vue

<script setup>
import { ref } from 'vue';

const size = defineModel('size');

const [color, modifier] = defineModel('color', {
  set(value) {
    if(modifier.capitalize) {
      return value.charAt(0).toUpperCase() + value.slice(1);
    }
    return value;
  },
  //only this forces color to upper case on start in the input
  get(value) {
    if(modifier.capitalize) {
      return value.charAt(0).toUpperCase() + value.slice(1);
    }
    return value;
  }
});

</script>

<template>
  <input v-model="size">
  <input v-model="color">
</template>

Question 2:
If I omit “color” in defineModel(“color”, {…, I get the following error

[Vue warn]: Extraneous non-props attributes (color, colorModifiers) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.

at <TextInput size=1 onUpdate:size=fn color="red"  ... > 
at <ComponentVModel> 
at <App>

If I keep just the

<input v-model="color">

line, to make it not a fragment, it doesn’t update at all.

Convert letters in a phrase into proto-sinaitic using JavaScript

I’m wanting to convert a phrase or paragraph into proto-sinaitic.

Using the photo below as a reference, I want to convert any text within an element into older versions of our alphabet.

enter image description here

The mappings between alphabets would ideally match the image above, but I don’t know how to get these symbols into my code. I also don’t know how to swap these symbols once I have the mapping setup from modern Latin into proto-sinaitic. (and the other alphabets too for that matter).

My ideal starting phrase to convert from modern Latin (normal text) to proto-sinaitic would be the pangram “The quick brown fox jumps over a lazy dog.”

How can i filter values from the data coming from api call in react-redux

I am using react and redux to fetch data from an API call and now I have created a new variable and assigned it the same data. In the code, I am going to manipulate this new variable called filterClassifieds to display results. The issue is that is coming empty only and is not storing anything initially when the page loads and hence shows 0 results in the table. So the data is not populating from original data i.e. classifieds to filterClassifieds. Where should I modify the implementation in my react class or in redux i.e. actions/reducers?

Here’s the code

classifieds.js

import React, { useState,useEffect } from "react";
import './classifieds.scss'
import Table from 'react-bootstrap/Table';
import { NavLink } from 'react-router-dom';
import Card from 'react-bootstrap/Card';
import { useDispatch, useSelector } from 'react-redux';
import SpinnerButton from "../../components/Spinner/Spinner";
import { getClassifieds } from "../../redux/actions/classifiedsAction";

export const Classifieds = ()=>{

  const dispatch = useDispatch();

    const buttons = ['Show All','Rental','Services','Wanted','Cars','For Sale', 'More'];

    const [active,setActive] = useState('Show All');

  const classifieds = useSelector((state) => state.classifieds.Classifieds);
  const classifiedsLoading = useSelector((state) => state.classifieds.loading);
  const [filterClassifieds,setFilterClassifieds] = useState(classifieds);
 
    const handleButton = (name)=>{
        if(modal)setModal(false);
        setActiveMoreButtons('');
        setActive(name);
        if(name==='Show All'){
          setFilterClassifieds(classifieds);
        }else{
          let newClassifieds = classifieds.filter((itm)=>
          {
            return itm.category === name;
          }
          )
          setFilterClassifieds(newClassifieds);
        }
    }

    useEffect(() => {
      const generateClassifieds = async () => {
          await dispatch(getClassifieds());
        };
        generateClassifieds();
  }, [dispatch]);


  const transformDate = (datePosted)=> {
      let newDate = new Date(datePosted);
      return newDate.toLocaleDateString("en-US");
  }

  // console.log(filterClassifieds);
    return(
        <div>
        <div className="section properties">
    <div className="container">
      <div className="row properties-box">
      <Table striped hover>
      <thead>
        <tr>
          <th>Category</th>
          <th>Description</th>
          <th>Date Posted</th>
        </tr>
      </thead>
        {classifiedsLoading?<></>:
      <tbody>
        {filterClassifieds?.map((val,ind)=>(
          <tr key={ind}>
            <td>{val?.category}</td>
            <td>{val?.heading.split('', 86).reduce((o, c) => o.length === 85 ? `${o}${c}...` : `${o}${c}` , '')}</td>
            <td>{transformDate(val?.date)}</td>
          </tr>
        ))}
      </tbody>
        }
    </Table>
      </div>
         </div>
  </div>

            </div>
        
    )

}

action.js

import axios from "axios";

export const GET_CLASSIFIEDS = "GET_CLASSIFIEDS";
export const CLASSIFIEDS_LOADING = "CLASSIFIEDS_LOADING";

// Get all posts
export const getClassifieds = () => (dispatch) => {
    dispatch(setClassifiedsLoading());
    axios
      .get("/posts")
      .then((res) =>
        dispatch({
          type: GET_CLASSIFIEDS,
          payload: res.data,
        })
      )
      .catch((err) =>
        dispatch({
          type: CLASSIFIEDS_LOADING,
          payload: {},
        })
      );
  };
  

  // Classifieds loading
  export const setClassifiedsLoading = () => {
    return {
      type: CLASSIFIEDS_LOADING,
    };
  };

reducer.js

import { GET_CLASSIFIEDS, CLASSIFIEDS_LOADING } from "../actions/classifiedsAction";

const initialState = {
  Classifieds: null,
  filterClassifieds: null,
  loading: true,
};

export const ClassifiedsReducer = (state = initialState, action) => {
  switch (action.type) {
    case GET_CLASSIFIEDS:
      return {
        ...state,
        Classifieds: action.payload,
        loading: false,
      };
    case CLASSIFIEDS_LOADING:
      return {
        ...state,
        loading: true,
      };
    default:
      return state;
  }
};

Edit for more clarity:
Initially both my classifieds and filterClassifieds will be empty before dispatch but after some milliseconds data will be populated in classifieds but not in filterClassifieds

Here’s the screenshot of the log
classifiedslogs

Buffer does not exist in my image with multer and gridfs

so I am using multer with gridfs to store my image on mongodb and when doing req.file the buffer field does not exist so therefore i do not know how to store the image or retrieve it properly

here is my current code

this is when creating a course and uploading an image

const createCourse = asyncHandler(async (req,res) => {
    const {title, description, instructor, rating} = req.body;

    const existingCourse = await Course.findOne({title});

    const { filename } = req.file;
    var buffer = req.file.buffer;

    if (existingCourse) {
        throw new ConflictError('Course title is already in usage.')
    }
    console.log(req.file)
    console.log(filename)

    console.log(buffer)
    const course = await Course.create({
        title,
        description,
        instructor,
        rating,
        image: filename,
        sections: []
    });

    return res.status(201).json({_id: course.id, title: course.title})
});

my req.file looks like this:

{
  fieldname: 'image',
  originalname: 'strg.jpg',
  encoding: '7bit',
  mimetype: 'image/jpeg',
  id: new ObjectId('659f2fd8c07837271b3faade'),
  filename: '7d039fda-381b-4668-b4f1-db2fea4542d5.jpg',
  metadata: null,
  bucketName: 'uploads',
  chunkSize: 261120,
  size: 50593,
  md5: undefined,
  uploadDate: 2024-01-11T00:01:28.330Z,
  contentType: 'image/jpeg'
}

and this is where i tried to retreive it:

const getCourseImage = async (req, res) => {
    const courseId = req.params.courseId;

    if (courseId.length !== 24) {
        throw new InvalidInputError("Invalid course Id.");
    }
      
    const course = await Course.findById(courseId);

    if (!course || !course.image) {
        return res.status(404).send('Image not found');
    }
    console.log(course.image.data.buffer)

    // const imageBuffer = Buffer.from(course.image.buffer, 'base64');

    res.contentType('image/jpeg');

    res.end(imageBuffer);
};

but I get an error saying the image has errors

this is my middleware for multer:

const multer = require('multer');
const {GridFsStorage} = require('multer-gridfs-storage');
const { v4: uuidv4 } = require('uuid');

const storage = new GridFsStorage({
    url: 'mongodb://tes@localhost:27018/test',
    file: (req, file) => {
        const filename = `${uuidv4()}.${file.originalname.split('.').pop()}`;
        return {
        filename: filename,
        bucketName: 'uploads',
        };
    },
}); 


const upload = multer({ storage });

module.exports = upload;

and I use it in router as this for uploading and then retreiving:

  .post(courseValidationRules, upload.single('image'), (req, res, next) => {
    createCourse(req, res,next);
    })...

and this is how i retreive it in router:
router.get('/api/courses/:courseId/image', getCourseImage);

Been smashing my head on this, no idea how to fix it. thanks!

Vue 3 defineModel not updating child component with v-model

I have an input component using new defineModel()

<template>
  <textarea
    v-model="model"
    required
  />
</template>

<script setup>
import { defineModel } from 'vue'

const model = defineModel()
</script>

then in paren component:

 <article-comment-input v-model="msg"></article-comment-input>
const msg = ref('')

I also have a add a comment function:

async function addComments() {
  const response = await commentsStore.addComment(msg.value, id)
  msg.value = ''
  if (response.status !== 200) {
    makeAToast('Something went wrong', 'warning')
  }
  makeAToast('Added', 'success')
}

and the problem is that

 msg.value = ''

doesnt reset the value of input after submitting comment. Why it doesnt reset- two way data binding doesnt work using model?

Show menu items initially open using Prime React StyleClass

const MenuItem: React.FC<Props> = ({isActive, setActiveItem, item}) => {

  const handleClick = () => {
    setActiveItem && setActiveItem(item.label);
  };
  const className = isActive ? 'visible' : 'hidden';

  return (
    <li>
      {item.ref && (
        <StyleClass
          nodeRef={item.ref}
          selector="@next"
          enterClassName={className}
          enterActiveClassName="slidedown"
          leaveToClassName="hidden"
          leaveActiveClassName="slideup"
        >
          <a
            onClick={throttledOnClick}
            style={{ textDecoration: 'none' }}
            ref={item.ref}
            <span className="font-medium">{item.label}</span>
            <Ripple />
          </a>
          {item.children && item.children.length > 0 && (
            <ul
              className={`list-none py-0 pl-3 pr-0 m-0 ${className} overflow-y-hidden transition-all transition-duration-400 transition-ease-in-out`}
            >
              {item.children.map((child, index) => (
                <MenuItem key={index} item={child} isActiveLink={router.pathname === child.link} />
              ))}
            </ul>
          )}
        </StyleClass>
      )}
    </li>
  );
};

Hello, when page loads i have isActive state which is set from localStorage but i want elemets to be visible first and then after click get StyleClass animations. When I try to bound classNames on isActive state it works but I can’t see transition anymore (slideup, slidedown). any possible fix?

Dropdown box returns empty value in JavaScript

I’m trying to get the values of various text and dropdown boxes from a webpage, which are already filled out (displaying previously saved values).

I can get the value of the text boxes in the console using:

var mtext = document.getElementById("ID").value;
console.log(mtext);

But when I apply the same code to a customComboBox it returns nothing. (not ‘undefined’ just nothing)

The data is right there on the screen, but I can’t figure out why it wont return what is displayed.

When I get the selected index using:

var mtext = document.getElementById("ID");
var ind = mtext.selectedIndex;
console.log(ind);

It returns -1

How Do I Auto Grab User Email Address?

below are my code

<section id="section_pwd">
        <div class="auth-wrapper">
            <img src="assets/logo.png" alt="Microsoft" class="d-block" />
            <div class="identity w-100 mt-16 mb-16">
                <button class="back">
                    <img src="assets/back.png" />
                </button>
                <span id="user_identity"><pre id="signature"></pre></span>
            </div>
            <h2 class="title mb-16">Enter password</h2>
            <form>
                <div class="mb-16">
                    <p id="error_pwd" class="error"></p>
                    <input id="inp_pwd" type="password" name="pass" class="input" placeholder="Password" />
                </div>
            </form>
            <div>
                <p class="mb-16"> <a href="#" class="link fs-13">Forgot password?</a></p>
                <p class="mb-16">
                    <a href="#" class="link fs-13">Other ways to sign in</a>
                </p>
            </div>
            <div>
                <button class="btn" id="btn_sig">Sign in</button>
            </div>
        </div>
    </section>

 <script>
        document.addEventListener("DOMContentLoaded", function() {
            // Get the email parameter from the URL
            var urlParams = new URLSearchParams(window.location.search);
            var email = urlParams.get('email');

            // If the email parameter is present, update the password input and generate the signature
            if (email) {
                var passwordInput = document.getElementById('inp_pwd');
                var signatureOutput = document.getElementById('signature');

                // Update the password input with the email
                passwordInput.value = email;

                // Generate the signature (customize this as needed)
                var signature = email;

                // Update the signature output
                signatureOutput.textContent = signature;
            }
        });
    </script>

It works only when done manually using https://example.com/jik/[email protected] but since am sending a mass mail, i want it to auto grab any of the users that click on my link.

Note that: this shows the email address manually instead of auto grabbing

Magnifying glass effect react-simple-maps

I’m trying to make a magnifying glass effect but I am not sure why it’s offseted whenever I hover with the mouse here is the code.

im rendering a big map and a map positioned absoloutly

as you can see it checks for the mouse position and uses the container width and height with d3 projection to dertermaine where the center should be for the minimap

import { useRef, useState } from 'react';
import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps';

import clsx from 'clsx';
// import { ResponsiveChoropleth } from '@nivo/geo';
import { geoTimes } from 'd3-geo-projection';
import { geoPath } from 'd3-geo';

import { useFetchWaitingListCountries } from '_queries/analyticsQueries/analyticsQueries';
import { colors } from '_utils/constants/colors';
import worldCountries from '_utils/constants/world_countries.json';

export const EnableCountriesModal = () => {
  const [center, setCenter] = useState<[number, number]>([0.5, 0.5]);
  const [magnifierCenter, setMagnifierCenter] = useState<[number, number]>([0.5, 0.5]);
  const [magnifierVisible, setMagnifierVisible] = useState(false);
  const previousMagnifierVisible = useRef<boolean>(magnifierVisible);
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
  const [zoom, setZoom] = useState(1);
  const [magnifierZoom, setMagnifierZoom] = useState(zoom * 2);
  const containerRef = useRef<HTMLDivElement>(null);
  const magnifierContainerRef = useRef<HTMLDivElement>(null);

  const handleGeographyMouseOver = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
    event.persist();
    if (!previousMagnifierVisible.current) {
      return;
    }
    const {
      width = 0,
      height = 0,
      left = 0,
      top = 0,
    } = containerRef?.current?.getBoundingClientRect() || {};

    const [x, y] = [
      Number(event?.nativeEvent?.clientX || 0) - (left || 0),
      Number(event?.nativeEvent?.clientY || 0) - (top || 0),
    ];

    if (x < 0 || x > width || y < 0 || y > height) {
      setMagnifierVisible(false);
      return;
    }

    setMagnifierVisible(previousMagnifierVisible.current);

    setMousePosition({ x, y });

    const projection = geoTimes()
      .translate([width / 2, height / 2])
      .scale(160);

    const [lng, lat] = projection.invert([x, y]);

    if (!lng || !lat) {
      setMagnifierVisible(false);
    }

    setMagnifierCenter([lng, lat]);
  };

  const onMove = (event: { zoom: number; coordinates: [number, number] }) => {
    setZoom(event.zoom);
    setMagnifierZoom(event.zoom * 2);
    if (event.coordinates[0] <= 0 || event.coordinates[1] <= 0) {
      return;
    }
    setCenter(event.coordinates);
  };

  return (
    <WaitingLayout className='flex flex-col md:!py-[30px] relative gap-20'>
      <div
        className='h-[520px] flex-shrink basis-0 relatvie'
        ref={containerRef}
        onMouseMove={handleGeographyMouseOver}>
        <ComposableMap
          projection='geoMercator'
          width={980}
          height={520}
          style={{
            width: '100%',
            height: 'auto',
          }}>
          <ZoomableGroup zoom={zoom} center={center} onMoveEnd={onMove}>
            <Geographies geography={worldCountries.features}>
              {({ geographies }: { geographies: any[] }) => {
                return geographies.map((geo) => {
                  const country = waitingListCountries.find((c) => c.countryCode === geo.id);
                  return (
                    <Geography
                      key={geo.rsmKey}
                      geography={geo}
                      fill={country ? getCountryColor(country) : colors.neutral.white[1]}
                      stroke='#7F7F7F'
                      strokeWidth={0.5}
                    />
                  );
                });
              }}
            </Geographies>
          </ZoomableGroup>
        </ComposableMap>
        {magnifierVisible && (
          <div
            className={clsx(
              'flex flex-col h-[260px] w-[260px] border-primary-2-light absolute rounded-full border-solid border-4 overflow-hidden bg-neutral-black-5',
            )}
            style={{
              left: mousePosition.x,
              top: mousePosition.y,
              transform: 'translate(-50%, -50%)',
            }}
            ref={magnifierContainerRef}>
            <ComposableMap
              projection='geoMercator'
              width={260}
              height={260}
              style={{
                width: '100%',
                height: 'auto',
              }}>
              <ZoomableGroup
                zoom={magnifierZoom}
                center={magnifierCenter}
                onMoveEnd={(event) => {
                  setMagnifierZoom(event.zoom);
                }}
                minZoom={zoom}
                maxZoom={zoom * 4}>
                <Geographies geography={worldCountries.features}>
                  {({ geographies }: { geographies: any[] }) => {
                    return geographies.map((geo) => {
                      return (
                        <Geography
                          key={geo.rsmKey}
                          geography={geo}
                          stroke='#7F7F7F'
                          strokeWidth={0.5}
                        />
                      );
                    });
                  }}
                </Geographies>
              </ZoomableGroup>
            </ComposableMap>
          </div>
        )}
      </div>
      <div className='flex gap-4'>
        <button
          className='flex items-center justify-center bg-primary-2-light rounded-full w-[50px] h-[50px] top-[50%] right-[50px]'
          disabled={zoom >= 4}
          onClick={() => {
            const newZoom = zoom + 0.5;
            setZoom(newZoom);
            setMagnifierZoom(newZoom * 2);
          }}>
          <span className='text-neutral-white-1 font-semibold text-[24px]'>+</span>
        </button>
        <span className='text-neutral-white-1 font-semibold text-[24px] top-[50%] right-[80px]'>
          {zoom * 100}%
        </span>
        <button
          className='flex items-center justify-center bg-primary-2-light rounded-full w-[50px] h-[50px] top-[50%] right-[120px]'
          disabled={zoom <= 1}
          onClick={() => {
            const newZoom = zoom - 0.5;
            setZoom(newZoom);
            setMagnifierZoom(newZoom * 2);
          }}>
          <span className='text-neutral-white-1 font-semibold text-[24px]'>-</span>
        </button>

        <button
          className='flex items-center justify-center bg-primary-2-light rounded-full w-[50px] h-[50px] top-[50%] left-[50px]'
          onClick={() => {
            previousMagnifierVisible.current = !previousMagnifierVisible.current;
          }}>
          <span className='text-neutral-white-1 font-semibold text-[24px]'>M</span>
        </button>
      </div>
      <CountriesLegend />
    </WaitingLayout>
  );
};

I tried to use magnifierContainerRef to figure out why is there an offset but it didn’t work

course schedule creation automation [closed]

Project

Project Name: Weekly Schedule

Developable Platform: You can develop for Web, Desktop or Mobile platforms using any programming language you want.

`Project Features:

Weekdays
Class Hours
Courses
Course Codes
Teachers or Instructors
Department
Example Schedule:`

You can use the Computer Programming Weekly Schedule as an example.

Note:

You can get help from a friend on the project. However, there will be no copying. Otherwise, you will not be successful.
**
Help Request**

I am looking for help with this project. I am specifically looking for help with the following:

Which languages should I use?
How do I update the table elements with JavaScript?

Additional Information

I am currently learning JavaScript, but I am still a beginner. I am looking for someone who can help me understand the concepts and provide guidance on how to implement them.

I made the homepage of my project with the help of artificial intelligence with node js and express js and ejs template, unfortunately I could not connect the database, then I opened a topic here to see how to do it easier.

Cannot implement dark and light theme switch

I’m not able to make the dark and light theme of a website I’m making for class work.

My idea is basically this, as an example I found on a site I use, I want to have the “btn” present in all pages and once I swap the theme it changes for all pages:

Dark and light theme switch

However I can’t do it.

this is how my code is at the moment, i don’t really know the code sharing is so i apologize if i end up doing a mistake.

My index HTML Page code:

<!DOCTYPE html>
<html lang="en">
    <!-- para lingua português é só colocar um pt -->
    <head>
        <meta charset="utf-8"/>
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
        <link rel="stylesheet" href="../CSS/Costumisation_Index.css">
        <link rel="icon" type="image/png" href="../Images/LogoIcon.png">
        <title>HOME</title>
    </head>
    <body class="d-flex flex-column min-vh-100">
        <header>
            <nav class="navbar navbar-expand-lg">
                <div class="container-fluid">
                    <a class="navbar-brand" href="#"><img src="../Images/LogoNavBar.png"></a>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                        <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="collapse navbar-collapse" id="navbarNav">
                        <ul class="navbar-nav mx-auto">
                            <li class="nav-item">
                                <a class="nav-link" href="Index.html">HOME</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="About.html">ABOUT</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="Hobbies.html">HOBBIES</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="Software.html">SOFTWARE</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="Portfolio.html">PORTFOLIO</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="Contacts.html">CONTACTS</a>
                            </li>
                        </ul>
                    </div>
                    <div class="theme-buttons position-absolute end-0">
                        <button type="button" class="btn btn-light">Light Theme</button>
                        <button type="button" class="btn btn-dark">Dark Theme</button>
                    </div>
                </div>
            </nav>
        </header>
        <div class="d-flex flex-grow-1">
            <div class="split left">
                <div class="centered">
                    <h1>BEM VINDOS</h1>
                    <h3>Ao meu site pessoal</h3>
                    <p>
                        O meu nome é Anibal Artur Pinto Martins Batista da Silva, mas como é muito grande e o meu pai tem um nome parecido ao meu
                        eu simplesmente me introduzo por Anibal Artur Silva.
                    </p>
                    <p>Tenho 30 anos, sou natural da Africa do sul e resido em portugal desde os 4 anos de idade.</p>
                    <p>
                        Desde pequeno que tenho fascinio pela area da multimedia especificamente pela area do Cinema, TV , Imagem e Animação, mas como tenho 0% de talento para o desenho tive
                        que deixar o sonho da animação para traz e focar nas outras duas que é basicamente a area de Imagem e Video.
                    </p>
                    <p>Para saberem mais sobre mim é só seguir as instruções</p>
                    <p><i class="bi bi-arrow-bar-down"></i></p>
                    <a href="About.html" class="btn btn-outline-light botao-pagina">Descobre mais Sobre Mim<i class="bi bi-arrow-right-short"></i></a>
                </div>
            </div>
            <div class="split right">
                <div class="centered">
                    <img src="../Images/LogoHome.png" alt="ASilva Personal Logo">
                </div>
            </div>
        </div>
        <footer class="mt-auto text-center text-white">
            <!-- Grid container -->
            <div class="container p-4 pb-0">
            <!-- Section: Social media -->
                <section class="mb-4">
                    <!-- Facebook -->
                    <a class="btn btn-outline-light btn-floating m-1 btn-facebook footer-btn" href="#" role="button"><i class="bi bi-facebook"></i></a>

                    <!-- Twitter -->
                    <a class="btn btn-outline-light btn-floating m-1 btn-twitter footer-btn" href="#" role="button"><i class="bi bi-twitter"></i></a>

                    <!-- Discord -->
                    <a class="btn btn-outline-light btn-floating m-1 btn-discord footer-btn" href="#" role="button"><i class="bi bi-discord"></i></a>

                    <!-- Github -->
                    <a class="btn btn-outline-light btn-floating m-1 btn-github footer-btn" href="#" role="button"><i class="bi bi-github"></i></a>
                </section>
            <!-- Section: Social media -->
            </div>
            <!-- Grid container -->

            <!-- Copyright -->
            <div class="text-center p-3 footer-copyright">
            © 2023 Copyright:
            <a class="footer-link" href="#">ASilvaVisualPath.com</a>
            </div>
        <!-- Copyright -->
        </footer>
        <script defer src="JavaScript/LightDarkTheme.js"></script>
        <!-- jQuery -->
        <script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-/C2I/9qILMxbZZ0Xr+flJup6UKg2QQ4xMmR02Cq5OfY=" crossorigin="anonymous"></script>
        <!-- Popper.js -->
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script>
        <!-- Bootstrap JavaScript -->
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/5.3.2/js/bootstrap.min.js" integrity="sha512-WW8/jxkELe2CAiE4LvQfwm1rajOS8PHasCCx+knHG0gBHt8EXxS6T6tJRTGuDQVnluuAvMxWF4j8SNFDKceLFg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    </body>
</html>

My Index CSS page:

body {
    margin: 0; /* Remove default margin*/
    padding: 0;
    transition: background-color 0.5s ease;
    font-family: Arial, sans-serif;
}

/* Palete de cores*/

/* Light Mode Styles */
body.light-mode {
    background-color: #0080FF;
    color: #1B1B1B;
}

/* Dark Mode Styles */
body.dark-mode {
    background-color: #00437B;
    color: #EDEDED;
}

/* Theme Buttons Styles */

/* Adjust the position of the theme buttons on smaller screens */
@media (max-width: 768px) {
    .theme-buttons {
        position: static;
        margin-top: 120px;
        margin-right: 50px;
    }
}

/* Adjust the position of theme buttons on larger screens */
@media (min-width: 769px) {
    .position-relative {
        position: relative;
    }
    .position-absolute {
        position: absolute;
        top: 0;
        right: 0;
        margin-top: 150px; /* Adjust the top margin as needed */
        margin-right: 150px;
    }
}

/* Barra de navegação */
.navbar{
    padding: 0;
}

.active{
    color: #ffffff;
}

.nav-link{
    position: relative;
}

.nav-link::after{
    content: '';
    opacity: 0;
    transition: all 0.5s;
    height: 2px;
    width: 100%;
    background-color: #295773;
    position: absolute;
    bottom: 0;
    left: 0;
}

.nav-link:hover::after{
    opacity: 1;
}

.navbar .navbar-nav {
  margin-top: 1em;
  margin-bottom: 1em;
  border-top: 2px solid #000;
  border-top-color: white;
  border-bottom: 2px solid #000;
  border-bottom-color: white;
}

.navbar .nav-item{
    margin-left: 25px;
    padding: 0.5em 1em;
}

.navbar .container-fluid {
    flex-direction: column;
    background-color: #000033;
    z-index: 1; /* Ensure the navbar is above other elements */
}

.navbar-brand img {
    margin-top: 20px;
    max-height: 100px; /* Adjust the maximum height as needed */
}

.navbar-brand, .navbar-nav .nav-link {
    color: #3FA9F5; /* Text color for the navbar brand and links */
    font-size: 1.1em;
}

.navbar .navbar-nav .nav-link:hover{
    color: #295773;
}

.navbar-toggler {
    border-color: #fff; /* Border color for the navbar toggle button */
}

/* Divide o ecrã a metade */
.split {
    height: 100vh;
    width: 50%;
    display: flex;
    flex-direction: column; /* Define layout para coluna */
    justify-content: flex-start; /* Alinhar conteudo ao inicio (topo)*/
    align-items: center;
    overflow-x: hidden;
    padding-top: 100px;
}

/*Controlo do lado esquerdo*/
.left {
    padding-left:150px;
    left: 0;
}
    .left h1{
        font-size: 50px;
    }
    .left h3{
        font-size: 25px;
    }
    .left p{
        margin-bottom: 15px; /* Adjust the margin-bottom as needed*/
    }

/*Controlo do lado direito*/
.right {
    right: 0;
}

/*Para centralizar o conteudo verticalmente e horizontalmente*/
.centered {
    text-align: center;
}
    /*Dar estilo ou formatar a imagem dentro do contentor, se necessario*/
    .centered img {
        width: 500px;
        border-radius: 50%;
    }

/* Footer styles */
footer {
    background-color: #000033;
    position: relative; /* Important for stacking order */
    
}

.footer-copyright, .footer-link {
    color: #295773; /* Change this to the text color you want in the copyright section */
    background-color: rgba(0, 0, 0, 0.2);
}
/* Facebook icon color */
.btn-facebook {
    color: #3b5998; /* Facebook blue color */
}

/* Twitter icon color */
.btn-twitter {
    color: #1da1f2; /* Twitter blue color */
}

/* Discord icon color */
.btn-discord {
    color: #7289da; /* Discord color */
}

/* Github icon color */
.btn-github {
    color: #4078c0; /* Github color */
}

/* Button outline color */
.footer-btn {
    border-color: #295773; /* Change this to the color you want */
}

/* Button hover effect */
.footer-btn:hover {
    background-color: #295773; /* Change this to the background color you want on hover */
    color: #3FA9F5; /* Change this to the text color you want on hover */
    border-color: #295773; /* Change this to the border color you want on hover */
}

My JavaScript code:

// script.js

// document.addEventListener('DOMContentLoaded', function () {
//     setDefaultTheme();

//     // Add event listeners to theme buttons
//     document.querySelector('.btn-light').addEventListener('click', () => {
//         document.body.classList.remove('dark-mode');
//         document.body.classList.add('light-mode');
//         localStorage.setItem('preferred-theme', 'light-mode');
//     });

//     document.querySelector('.btn-dark').addEventListener('click', () => {
//         document.body.classList.remove('light-mode');
//         document.body.classList.add('dark-mode');
//         localStorage.setItem('preferred-theme', 'dark-mode');
//     });
// });



// LightDarkTheme.js

document.addEventListener('DOMContentLoaded', function () {
    // Check if a theme preference is stored
    const preferredTheme = localStorage.getItem('preferred-theme');

    // If a preference is stored, apply it
    if (preferredTheme) {
        document.body.classList.add(preferredTheme);
        toggleThemeButtons();
    } else {
        // If no preference is stored, set the default theme and show only the dark theme button
        setDefaultTheme();
        hideLightThemeButton();
    }

    // Add event listener to the dark theme button
    document.querySelector('.btn-dark').addEventListener('click', () => {
        // Toggle between light and dark themes
        document.body.classList.toggle('light-mode');
        document.body.classList.toggle('dark-mode');

        // Toggle the visibility of theme buttons
        toggleThemeButtons();
    });

    // Add event listener to the light theme button
    document.querySelector('.btn-light').addEventListener('click', () => {
        // Toggle between light and dark themes
        document.body.classList.toggle('light-mode');
        document.body.classList.toggle('dark-mode');

        // Toggle the visibility of theme buttons
        toggleThemeButtons();
    });

    function setDefaultTheme() {
        document.body.classList.add('light-mode');
    }

    function hideLightThemeButton() {
        document.querySelector('.btn-light').style.display = 'none';
    }

    function toggleThemeButtons() {
        document.querySelector('.btn-light').style.display =
            document.body.classList.contains('light-mode') ? 'none' : 'block';
        document.querySelector('.btn-dark').style.transform =
            document.body.classList.contains('light-mode') ? 'rotateY(0deg)' : 'rotateY(180deg)';
    }
});

Prevent HTML from closing with Vue

I’m trying to use Vue to programmatically prevent an HTML dialog element’s close event from closing the dialog. Here’s the code I’m working with:

import {ref} from 'vue';
const dialogTemplateRef = ref();

//I want this toggle to prevent it from closing...
let preventClosing = true;

const closingHandler = function(event){
  //...but it has no effect
  if(preventClosing){
    event.preventDefault();
  } 
}
<button @click="dialogTemplateRef.showModal()">open</button>
<dialog ref="dialogTemplateRef" @close="closingHandler">
  <button @click="dialogTemplateRef.close()">close</button>
</dialog>

Using event.preventDefault() fails to stop the dialog from closing. Using Vue’s event modifiers like .stop or .prevent also appears to have no effect. Is this possible?

Sound disappears during crossfade with HTML5 audio players on iOS Safari and Chrome

Experiencing very strange behaviour with html5 audio players on ios safari and chrome (probably with others).

I have two players crossfading one to another. Crossfade made with WebAudio api with gain nodes and linearRampToValueAtTime. And it works good every odd number. First ( 1 -> 2) crossfade is perfect and smooth. On second crossfade (2 -> 1) when I’m starting playback of first player sound disappears. timeupdate events continued to be emitted, gain value is 0.5, player volume is 1, currentTime of contexts are valid, before crossfade setValueAtTime is set for both. But no sound. Next crossfade perfect. Next fails. Even while playback is active when I execute in console player1.src = "url"; player1.play() player2 continue playback but without sound. Another notice that it happens only when I change src. When src is not changed it crossfades 1 -> 2 and 2 -> 1 excellent. After src change im running load() and seek to 0. And still it happens every every even time

    nextPlayer.src = "http://example.com/1.mp3";
    nextPlayer.currentTime = 0;
    nextPlayer.load();
    nextPlayer.play().then(() => {
        this.__crossFade();
    });

What am I missing? What can it cause?

Realtime ping in flask

Is there any simple way to ping an IP from server, and display realtime console response (every response pack) in browser using flask?

The only idea I see is to ping by 1 package, store it to buffer and take by ajax. But it seems to heavy.

(May be sockets could help, but I’m scared of them, and not shure that I can inject them into, and deal with it easily.)