Configure multi-line function call indentation in eslint

How do I configure the eslint indent rules for function calls that span multiple lines?

For example, in the following code, with the indent set to 2, eslint complains that the second line of the expect call should be indented 8 spaces instead of 6.

  1. Why 8?
  2. How do I configure this?

  test('#updateEntries fetches entries', () => {
    c.updateEntries();
    expect(mockDataService.fetchTodaysEntries).toHaveBeenCalledWith(mockModel.currentDate,
      expect.any(Function));
  });

For what it’s worth: The actual problem is that there is a conflict between the built-in VS Code formatter and eslint. I actually don’t care whether the indent is 6 or 8, I just want to get rid of the red squiggly lines without either (1) turning all indention off, (2) having to have an “ignore” comment for each multi-line function call, or (3) having to install a different formatter. (I’m pretty sure I can’t configure this aspect of the built-in VS code formatter; but, correct me if I’m wrong.)

How can I reset the table pagination to the beginning whenever the search keyword changes or the page limit is modified?

I’m working with a React and Ant Design (antd) generic table and have created a useTableData hook to supply data to various tables in my application. Currently, the table is functional, but it has some flaws that are noticeable to the end user. Here are a few of them:

  • The table does not reset to page 1 when the search keyword is changed.
  • Changing the page limit does not reset the table to page 1.
  • Altering the page limit also disrupts the serial numbers.

Here is the hook

/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable no-sparse-arrays */
import { useState, useEffect } from 'react';
import { useDispatch } from 'react-redux';

export const useTableData = ({
  fetchFunc,
  defaultColumn,
  sorterDefault,
  tableParams,
  setTableParams,
}) => {
  const [text, setText] = useState('');
  const dispatch = useDispatch();
  const getSorterValue = (key, order) => {
    return key
      ? `${
          key === 'name'
            ? 'firstName'
            : key?.replace(/[A-Z]/g, (letter) => `_${letter?.toLowerCase()}`)
        }:${order === 'ascend' ? 1 : -1}`
      : sorterDefault;
  };

  const handleTableData = (tableConfig = null) => {
    let page = (tableConfig ?? tableParams).pagination?.current;
    let limit = (tableConfig ?? tableParams).pagination?.pageSize;
    let attributes = `${defaultColumn
      .map((el) => el.attributeName)
      .filter((el) => el)
      .join()},id`;
    let sort = getSorterValue(
      (tableConfig ?? tableParams).field,
      (tableConfig ?? tableParams).order
    );

    console.log(attributes);
    dispatch(
      fetchFunc({
        limit,
        page,
        sort,
        search: text,
        attributes,
        is_active:true
      })
    );
  };

  useEffect(() => {
    if (text.length > 3) {
      handleTableData();
    }
    handleTableData();
  }, [, text]);

  const handleTableChange = (pagination, filters, sorter) => {
    setTableParams({
      pagination,
      filters,
      ...sorter,
    });

    handleTableData({
      pagination,
      filters,
      ...sorter,
    });
  };

  const handleLimitChange = (value) => {
    handleTableData({
      ...tableParams,
      pagination: { ...tableParams.pagination, pageSize: value },
    });
    setTableParams({
      ...tableParams,
      pagination: { ...tableParams.pagination, pageSize: value },
    });
  };

  return {
    tableParams,
    setTableParams,
    text,
    setText,
    handleTableData,
    handleTableChange,
    handleLimitChange,
  };
};

So to give more clarity on the props here is the tableParams State

const [tableParams, setTableParams] = useState({
    pagination: {
      current: 1,
      pageSize: 10,
      total: count && count,
    },
  });

const { setText, handleTableChange, handleLimitChange } = useTableData({
    fetchFunc: getModule, // Api call with redux which provides the count and data
    defaultColumn,
    sorterDefault,
    tableParams,
    setTableParams,
  });

<Table
          tableColumns={columnDef}
          data={module}
          handleSorting={handleTableChange}
          onChange={(e) => setText(e.target.value)}
          count={tableParams?.pagination?.total ?? 0}
          limit={tableParams.pagination.pageSize}
          currentPage={tableParams.pagination.current}
          setLimit={handleLimitChange}
         
        />

I believe the issue stems from using a single useEffect, which may be causing these problems. Another issue could be the lack of page resetting.

I tried reseting the page and use different function for different calls but i am getting stack because of the way my useEffect is working

I’d appreciate any insights or guidance on how to address these issues effectively. Thank you for your help!

I hope this helps!

Move mobile list item into view on scroll (using javascript)

I’ve been looking around / scratching my head on how to do the following (using javascript only – ie. no jQuery etc..):

  • I have a li menu that extends beyond the viewport (in this case, a list of decades)
  • each menu item turns ‘active’ when the a content block (representing a decade) scrolls into view.

If the li item is active AND out of the viewport, I would like it to move into the viewport (preferably the centre)…

This should work in both directions. Any help would be hugely appreciated.

enter image description here

I’ve been hunting around for the appropriate code – but found nothing. And… my JS is pretty limited…

Client Components with NextJS

I am trying to create a one page landing page that lets people upload videos and that has a filesize check prior to the upload.

I have this at src/app/page.tsx:

import React from 'react';
import FileUpload from '../FileUpload'; // Adjust the import path as necessary
import Image from 'next/image';

export default function Page() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-center bg-[#f7f1e3] p-8">
      <h1 className="text-4xl font-bold text-[#1d3b2f] mb-10">Title</h1>

      <FileUpload />  {/* Use the FileUpload component here */}


    </main>
  );
}

And at src/FileUpload.tsx, I have this:

// Add this line to explicitly mark this component as a client component
/* @jsxImportSource @next/client */
import React, { useState } from 'react';

const FileUpload = () => {
  const [fileSizeOk, setFileSizeOk] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);

  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      // Check file size (500 MB = 500 * 1024 * 1024 bytes)
      if (file.size <= 500 * 1024 * 1024) {
        setFileSizeOk(true);
        let progress = 0;
        const interval = setInterval(() => {
          setUploadProgress(progress);
          if (progress >= 100) {
            clearInterval(interval);
          } else {
            progress += 10;
          }
        }, 100);
      } else {
        setFileSizeOk(false);
      }
    }
  };

  return (
    <div>
      <input type="file" onChange={handleFileChange} />
      {fileSizeOk && <p className="text-green-500">✔ File size is OK</p>}
      {!fileSizeOk && <p className="text-red-500">✖ File size is too large</p>}
      <div className="bg-gray-200 rounded h-2">
        <div className="bg-[#1d3b2f] h-2 rounded" style={{ width: `${uploadProgress}%` }}></div>
      </div>
    </div>
  );
};

export default FileUpload;

On this particular line:

        <div className="bg-[#1d3b2f] h-2 rounded" style={{ width: `${uploadProgress}%` }}></div>

I get this error:

Cannot find module '@next/client/jsx-runtime' or its corresponding type declarations.ts(2307)

I’m not sure what to do — how can i solve this problem and implement file size checking on the frontend?

Facebook number [closed]

how to get number of anyone by id Facebook Or how to make a script with python that let me have a number of anyone by id of facebook?!

how to get number of anyone by id Facebook Or how to make a script with python that let me have a number of anyone by id of facebook

Arbitrary n introduced during during AppsScript when sending an email

First, all of the code below works fine, there is no issues in terms of functionality .

  function sendEmails() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName("Active");
  var startRow = 2;
  var numRows = sheet.getLastRow() - 1;
  var dataRange = sheet.getRange(startRow, 1, numRows, 6); // Retrieve first six columns, including the timestamp column
  var data = dataRange.getValues();

  var folderId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  var folder = DriveApp.getFolderById(folderId);
  var files = folder.getFilesByName('xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.pdf');

  if (!files.hasNext()) {
    Logger.log('File not found.');
    return;
  }

  var file = files.next();
  var message = sheet.getRange("H2").getValue(); // Retrieve message from cell H2

  var sentEmails = {}; // Object to track emails that have been sent

  // Group emails by domain
  var emailsByDomain = {};
  for (var i = 0; i < data.length; ++i) {
    var row = data[i];
    var emailAddress = row[4]; // Email address from Column E
    var timestamp = row[5]; // Timestamp from Column F

    // Skip if timestamp exists or email address is invalid
    if (timestamp || !emailAddress || emailAddress.indexOf('@') === -1) {
      continue;
    }

    var domain = emailAddress.split('@')[1];
    if (!emailsByDomain[domain]) {
      emailsByDomain[domain] = [];
    }
    emailsByDomain[domain].push({ row: i, email: emailAddress });
  }

  // Process each domain
  for (var domain in emailsByDomain) {
    // Filter out already sent emails
    var unsentEmails = emailsByDomain[domain].filter(emailInfo => !sentEmails[emailInfo.email]);

    // Continue if all emails in the domain have been sent
    if (unsentEmails.length === 0) continue;

    var emailToSend = unsentEmails[Math.floor(Math.random() * unsentEmails.length)]; // Random selection

    var name = data[emailToSend.row][3]; // Name from the selected email row
    var personalizedMessage = message.replace("{name}", name);
    var emailAddress = emailToSend.email;
    var subject = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

    var options = {
      attachments: [file.getAs(MimeType.PDF)]
    };

    try {
      MailApp.sendEmail(emailAddress, subject, personalizedMessage, options);
      Logger.log("Emailed " + name + " (" + emailAddress + ")");

      // Set the background color of the row to light green after sending the email
      sheet.getRange(startRow + emailToSend.row, 1, 1, sheet.getLastColumn()).setBackgroundRGB(200, 255, 200);

      // Update the date in Column F
      var dateCell = sheet.getRange(startRow + emailToSend.row, 6); // Column F is the 6th column
      dateCell.setValue(new Date());

      // Mark this email as sent
      sentEmails[emailAddress] = true;
    } catch (e) {
      Logger.log("Failed to send email to " + name + " (" + emailAddress + "): " + e.message);
    }
  }
}

Input is “Active” tab on GoogleSheets

A       B.      C.      D.      E.      F                ... H
COMPANY SALUTE  LAST    FIRST   EMAIL   Emailed on           Message

I am picking up message and emailing it to E

The problem is … something inserts n making things look great on Mobile devices but cut off on Web.

I tried

  1. Putting text in a cell instead of a range
  2. forcibly removing all n all together

Running out of ideas here. Please help

  1. Actual. All text is in burgundy space
  2. Expected. Text gracefully
    extends yellow space

enter image description here

Eleventy tags – convert to lowercase and sort alphabetically?

I am using the tag filters from eleventy-base-blog:

eleventyConfig.addFilter("getAllTags", collection => {
  let tagSet = new Set();
  for(let item of collection) {
    (item.data.tags || []).forEach(tag => tagSet.add(tag));
  }
  return Array.from(tagSet);
});

eleventyConfig.addFilter("filterTagList", function filterTagList(tags) {
  return (tags || []).filter(tag => ["all", "no-show"].indexOf(tag) === -1);
});

These work as expected. However, I would like to:

  1. Transform tags to lowercase to minimize Output Conflict from tags like JavaScript, Javascript, and javascript.
  2. Sort tags alphabetically for usability.

I stink at JS and after hours of trying, I must admit defeat. Any help would be much appreciated 🙂

State in props is undefined but its correct in return render

i’m tying to make a card game on react to learn more of it’s working. so here i sthe propblem. There is a array state Opponents [name, name1] in opponents.jsx which is going throught props to child component OpponentCards.jsx and return can read the value ro render the correct name of opponent but when i’m trying to deal with it’s value in code before ‘return’ it has undefined value.

I’ve found out that it causing by asyncronus of props but idk how to deal with it in correct way. Also if i refresh vite in vscode and do not refresh page of project it starts working correctly.

Opponents.jsx

import React, { useEffect, useState } from 'react'
import OpponentCards from './OpponentCards'

const Opponents = (props) => {

    const [opponents, setOpponents] = useState([])
    const [numberOfPlayers, setNumberOfPlayers] = useState('two')
    
    let updateUsers = (data) => {

        let usersToChange = data.users
        if(usersToChange.find(item => item === localStorage.getItem('name'))){
            while(String(usersToChange[0]) !== localStorage.getItem('name')){
                usersToChange.push(usersToChange[0])
                usersToChange.splice(0,1)
            }        

        }
        
        setOpponents(usersToChange)
        switch (props.users.length) {
            case 2 :
                setNumberOfPlayers('two') 
                return
            case 3 :
                setNumberOfPlayers('three') 
                return
            case 4 :
                setNumberOfPlayers('four') 
                return
        }
    } 

    props.socket.on('getUsersResponse', (data) => {
        updateUsers(data)
    })


    useEffect(() => updateUsers(props) ,[props.users])


    console.log(opponents) //correct array of opponents

    return (
        <div className={numberOfPlayers+'-players'}>
            <div className="opponent one">
                <OpponentCards opponent = {opponents[1]} number={1}  socket= {props.socket}/>
            </div>

            <div className="opponent two">
                <OpponentCards opponent = {opponents[2]} number={3}  socket= {props.socket}/>
            </div>

            <div className="opponent three">
                <OpponentCards opponent = {opponents[2]} number={3}  socket= {props.socket}/>
            </div>
        </div>
    )
}

export default Opponents

and OpponentCards.jsx

import React, { useEffect, useState } from 'react'
import userLogo from '../../sourses/Untitled.svg'

const OpponentCards = (props) => {

    let [cards, setCards] = useState(0) 
    
    
    let addCard = (name) => {

        if(name === props.opponent){
            setCards(cards => cards +1)
        }
    }


    useEffect(() => {
        props.socket.on('getCardFromDeckToOpponentResponse',(name) => addCard(name))
    },[props.socket])

    console.log(props.opponent)//undefined

    return (
        <>
        <div className="container">
            <h3 className='name'>
                {props.opponent ? props.opponent : 'Player ' + (props.number + 1)}
            </h3>
            <img src={userLogo} />
            <div className="opponentCards">
                {[...Array(cards)].map((elem, index)=> <div key={index} className='card'>x</div>)}
            </div>
        </div>

        </>
    )
}

export default OpponentCards

Dymo Label printer WS_CMD_GET_JOB_STATUS not implemented

if you check the official js library implementation which is
https://raw.githubusercontent.com/dymosoftware/dymo-connect-framework/master/dymo.connect.framework.full.js

there is missing var WS_CMD_GET_JOB_STATUS = “GetJobStatus”; implementation and because of that the function getJobStatus() is never founded because and we are not connected to printer to check statuses while for instance using printAndPollStatus() our printJobStatus would allways return
{status: dymo.label.framework.PrintJobStatus.Unknown, statusMessage: ‘not implemented’}

im happy to explain more : [email protected]

trying to use dymo.connect.framework.full.js to use and check printing status but the implementation doesnt exist

looking for a code snippet for my woocommerce store that adds a product to cart when quantity is changed without clicking add to cart

Im looking for a code snippet for my woocommerce store at shop page, where adds a product to cart when quantity is changed without clicking add to cart.

Example:
A customer is in the shop page (product archive) he wants 5 cups, by default the quantity field should be 0. Then the customer types 5 in the quantity field without clicking “add to cart” there should automatically be 5 cups in the cart.

When the customer changes his mind and wants 3 cups he can go back, type 3 instead of 5 in the quantity field without clicking “add to cart” and he should now have 3 cups in his cart

Basically syncing the quantity field with the cart.

Why does my modal not open in my django project?

I try to create full CRUD for my commenting, but as soon as I added editing and deletion. It stopped wanting to open upon pressing the add comment button. The modal doesn’t open.

Its a newsbulletinboard, it has separate articles that is fetched by API. It is parsed and rendered unto the landingpage. Each article has the oppertunity for each user to comment.

{% extends "base.html" %}

{% block content %}
<div class="container-fluid">
    <div class="row justify-content-center">
        <div class="col-10 mt-3">
            <div class="row">
                {% for news_article in news_article_list %}
                <div class="col-12">
                    <div class="card mb-4" style="width: 100%; margin: auto;">
                        <div class="card-body">
                            <h2 class="card-title">{{ news_article.title }}</h2>
                            <p class="card-text">{{ news_article.content|linebreaks }}</p>
                            <p class="card-text text-muted h6">{{ news_article.created_on }}</p>
                            <hr />
                    
                            <div class="row">
                                <div class="col-12">
                                    <!-- Stored comments according to article-id -->
                                    <div class="comments-section">
                                        {% for comment in news_article.comments.all %}
                                            <div class="comment">
                                                <strong>{{ comment.name }}</strong>
                                                <p>{{ comment.comment_content }}</p>
                                                {% if user.is_authenticated %}
                                                <div class="justify-content-center">
                                                    <button id="edit-comment-btn{{ news_article.id }}" class="btn btn-secondary btn-dark open-comment-form" data-action="edit" data-comment-id="{{ comment.id }}">Edit</button>
                                                    <button id="delete-comment-btn{{ news_article.id }}" class="btn btn-secondary btn-dark open-comment-form" data-article-id="{{ news_article.id }}">Delete</button>
                                                {% endif %}
                                                </div>
                                                <hr>
                                                <small class="text-muted">{{ comment.created_on }}</small>
                                            </div>
                                        {% endfor %}
                                    </div>
                                    {% if user.is_authenticated %}
                                    <button id="open-comment-form-{{ news_article.id }}" class="btn btn-secondary btn-dark open-comment-form" data-article-id="{{ news_article.id }}">Add a Comment</button>
                                    {% endif %}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                {% endfor %}
            </div>
        </div>
    </div>
</div>

<!-- Modal -->
<div class="modal fade" id="comment-modal" tabindex="-1" role="dialog" aria-labelledby="comment-modal-label" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <!-- Modal Header -->
            <div class="modal-header">
                <h5 class="modal-title" id="comment-modal-label">Add a Comment</h5>
                <button type="button" class="close btn btn-secondary btn-dark" data-bs-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <!-- Modal Body -->
            <div class="modal-body">
                <!-- Your form content here -->
                <form id="comment-form" method="POST">
                    {% csrf_token %}
                    
                    <!-- Name Field -->
                    <div class="form-group">
                      
                        <input type="hidden" id="comment_name" name="name" class="form-control" required>
                    </div>
                    
                    <!-- Email Field -->
                    <div class="form-group">
                      
                        <input type="hidden" id="comment_email" name="email" class="form-control" required>
                    </div>
            
                    <!-- Comment Content Field -->
                    <div class="form-group">
                        <label for="comment_content">Comment:</label>
                        <textarea id="comment_content" name="comment_content" class="form-control" placeholder="Your comment" required></textarea>
                    </div>
            
                    <!-- Confirmation Message (Hidden by Default) -->
                    <div id="comment-form-message" class="alert alert-success" style="display: none;">
                        Comment added successfully!
                    </div>
                </form>
            </div>
            <!-- Modal Footer -->
            <div class="modal-footer">
                <!-- Cancel Button -->
                <button type="button" class="btn btn-secondary btn-dark" data-bs-dismiss="modal">Cancel</button>
                <!-- Submit Button -->
                <button id="submit-button" type="button" class="btn btn-dark">Submit</button>
            </div>
        </div>
    </div>
</div>

<!-- Pagination -->
{% if is_paginated %}
<nav aria-label="Page navigation">
    <ul class="pagination justify-content-center">
        {% if page_obj.has_previous %}
        <li><a href="?page={{ page_obj.previous_page_number }}" class="page-link">&laquo; PREV </a></li>
        {% endif %}
        {% if page_obj.has_next %}
        <li><a href="{% url 'news_article_list' %}?page={{ page_obj.next_page_number }}" class="page-link"> NEXT &raquo;</a></li>
        {% endif %}
    </ul>
</nav>
{% endif %}

<script>
    $(document).ready(
    // Function to submit the comment form
    function submitForm() {
        // Validate the form first
        var commentContent = document.getElementById('comment_content').value;

        if (commentContent === '') {
            alert('Comment field is required.');
            return;
        }

        console.log('Form submitted.');
        var form = document.getElementById('comment-form');
        var formData = new FormData(form);
        var articleId = form.dataset.articleId; // Get the article ID from dataset
        console.log("Article ID is set to: ", articleId);

        // Include the article ID in the form data
        formData.append('article_id', articleId);

        // Fetch the current user's name and email (if authenticated)
        var commentName = "{% if user.is_authenticated %}{{ user.username }}{% else %}Anonymous{% endif %}";
        var commentEmail = "{% if user.is_authenticated %}{{ user.email }}{% else %}[email protected]{% endif %}";

        // Update the hidden name and email fields
        formData.append('name', commentName);
        formData.append('email', commentEmail);

        form.action = "{% url 'add_comment_to_article' 0 %}".replace("0", articleId);
        console.log("Form action is: ", form.action);
        var xhr = new XMLHttpRequest();
        xhr.open('POST', form.action, true);

        // Set CSRF token in the request header
        xhr.setRequestHeader('X-CSRFToken', '{{ csrf_token }}');
        console.log("CSRF Token:", document.getElementsByName('csrfmiddlewaretoken')[0].value);

        xhr.onload = function() {
            console.log("XHR status: ", xhr.status);
            console.log("XHR response: ", xhr.responseText);
            var response = JSON.parse(xhr.responseText);
            if (xhr.status === 200 && response.result === 'Comment added successfully') {
                document.getElementById('comment-form-message').style.display = 'block';
                document.getElementById('comment-form').reset();
            } else {
                console.log('Server Response:', response);
                alert('An error occurred. Please check the console for details.');
            }
        };
        xhr.onerror = function() {
            console.error("Request failed");
        };

        xhr.onabort = function() {
            console.error("Request was aborted");
        };

        xhr.send(formData);
    }

// Add event listeners for the "Edit" buttons
var editButtons = document.querySelectorAll('.edit-comment-btn');
editButtons.forEach(function(editButton) {
    editButton.addEventListener('click', function() {
        var commentId = editButton.getAttribute("data-comment-id");
        var form = document.getElementById('comment-form');
        form.dataset.commentId = commentId;  // Store the comment ID in the dataset

        // Fetch the comment content for editing
        $.get(`/Home/EditComment?commentId=${commentId}`, function (data) {
            document.getElementById('comment_content').value = data.commentContent;
            $('#comment-modal').modal('show');
        });
    });
});

);
</script>


{% endblock %}

Event bubbling and Event Propagation with react hooks

I have a handler that toggles a state that determines whether a popover is open or not. To toggle, there is an <span> element that has an onClick. Furthermore, I also have a hook that sets the state of the same popover to false if you click anywhere else on the window. So when I click the asterisk () the state first goes to false, because of the hook changing the state, then to true on the same click because of the asterisk () (so it does not close).

I’ve looked at event.stopPropagation() but either I’m fundamentally not understanding it or implementing it wrong.

Here is my code:

const [openDisclaimerView, setOpenDisclaimerView] = useState(false);

const handleShowDisclaimerView = (event: React.MouseEvent<HTMLSpanElement, MouseEvent>) => {
  console.log('clicked', event);
  event.stopPropagation();
  setOpenDisclaimerView(!openDisclaimerView);
};

return (
  <>
    {formCompleted && srp != null && (
      <div className={styles.totalSRP}>
        <Typography variant="legal1">
          {srpText}
          <span onClick={e => handleShowDisclaimerView(e)}>*</span> ${srp}
        </Typography>
      </div>
    )}
  </>
);
<DisclaimerPopover isOpen={openDisclaimerView} onClose={() => setOpenDisclaimerView(false)} disclaimers={totalSrpDisclaimer ? [totalSrpDisclaimer] : []} />
interface DisclaimerPopoverProps {
  isOpen?: boolean;
  onClose: () => void;
  disclaimers: Disclaimer[];
  priceBarWidth?: number;
}

const DisclaimerPopover = ({ isOpen, onClose, disclaimers, priceBarWidth }: DisclaimerPopoverProps) => {
  const ref = useRef<HTMLDivElement>(null);

  useOutsideClick(ref, onClose); // here is the hook

  useEffect(() => {
    if (!ref.current) {
      return;
    }
    const disclaimerList = ref.current.querySelector(`ul.${styles.disclaimerList}`);
    const topGradient = ref.current.querySelector(`.${styles.topGradient}`) as HTMLElement;
    const bottomGradient = ref.current.querySelector(`.${styles.bottomGradient}`) as HTMLElement;

    const handleScroll = () => {
      if (!disclaimerList) {
        return;
      }
      const { scrollTop, scrollHeight, clientHeight } = disclaimerList;
      topGradient.style.opacity = `${scrollPercentage * 0.9}`;
      bottomGradient.style.opacity = `${1 - scrollPercentage * 0.9}`;
    };

    disclaimerList?.addEventListener('scroll', handleScroll);

    return () => {
      disclaimerList?.removeEventListener('scroll', handleScroll);
    };
  }, []);

  return (
    <section ref={ref} className={cx(styles.disclaimerBox, isOpen && styles.isOpen)} style={priceBarWidth ? { width: `${priceBarWidth}px` } : {}}>
      <div className={cx(styles.disclaimerBoxGradient, styles.topGradient)} style={{ opacity: 0 }} />
      <ul className={cx(styles.disclaimerList)}>
        {disclaimers?.map(disclaimer => (
          <li key={disclaimer.id} className={cx(styles.disclaimerItem)}>
            {disclaimer.description}
          </li>
        ))}
      </ul>
      <button className={cx(styles.closeButton)} aria-label="close overlay" onClick={onClose} />
      <div className={cx(styles.disclaimerBoxGradient, styles.bottomGradient)} style={{ opacity: 1 }} />
    </section>
  );
};

export default DisclaimerPopover;
export const useOutsideClick = (ref: RefObject<HTMLElement>, callback: () => void) => {
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (ref.current && !ref.current.contains(event.target as Node)) {
        callback();
      }
    };

    document.addEventListener('mousedown', handleClickOutside);

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [ref, callback]);
};

Based on your description and code, it seems you’re facing a classic event handling issue in React, where the click event is being captured by both your custom handler and the global click listener set up by the useOutsideClick hook. Here’s a suggested solution:

  1. Modify handleShowDisclaimerView: Instead of toggling the openDisclaimerView state directly, you should determine if the click is coming from the asterisk or elsewhere. If it’s from the asterisk, you want to ensure it only opens or closes the popover, not both.

  2. Revise useOutsideClick Hook: You may need to ensure that the outside click handler doesn’t interfere with your specific handleShowDisclaimerView function.

Here’s how you can adjust your code:

1. Adjust handleShowDisclaimerView

Modify the handler to check the current state and act accordingly:

jsxCopy code

const handleShowDisclaimerView = (event: React.MouseEvent<HTMLSpanElement, MouseEvent>) => { event.stopPropagation(); // Only toggle if the disclaimer is currently not visible if (!openDisclaimerView) { setOpenDisclaimerView(true); } };

2. Adjust useOutsideClick

Ensure that your useOutsideClick function does not close the popover if it is already being handled by handleShowDisclaimerView. You can do this by adding a condition to check whether the popover is already open:

jsxCopy code

export const useOutsideClick = (ref: RefObject<HTMLElement>, callback: () => void, isOpen: boolean) => { useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (isOpen && ref.current && !ref.current.contains(event.target as Node)) { callback(); } }; document.addEventListener(‘mousedown’, handleClickOutside); return () => { document.removeEventListener(‘mousedown’, handleClickOutside); }; }, [ref, callback, isOpen]); };

Now, modify the useOutsideClick usage in your DisclaimerPopover to pass the isOpen state:

jsxCopy code

useOutsideClick(ref, () => setOpenDisclaimerView(false), openDisclaimerView);

Explanation

  • Event Propagation: When you click the asterisk, the event bubbles up to the document level, where your outside click handler is also listening. By stopping the propagation in handleShowDisclaimerView, you prevent the event from reaching the global listener when the asterisk is clicked.

  • Conditional Handling: The useOutsideClick hook now includes a condition to check if the popover is already open. If it’s open, and the click is outside, it will invoke the callback. If the click is inside or the popover is closed, it won’t do anything.

This approach should solve the issue of the popover closing and then reopening immediately when the asterisk is clicked, while still allowing it to close when clicking outside of it.

How to move an HTML element diagonally (only with js if possible)

I want to move an img diagonally with js, right now i can only move up, down, left and right.

This is my code right now to move up, down, left and right

naveJugador (playerShip) the img i want to move

coordenadaX and coordenadaY = X and Y position

velocidadJugador (speed)

document.addEventListener("keydown", (e) => {
    // MOVE UP
    if (e.key === "w" || e.key === "W" || e.key === "ArrowUp") {
        coordenadaY = naveJugador.offsetTop;
        coordenadaY = Math.max(0, coordenadaY - velocidadJugador);
        naveJugador.style.top = coordenadaY + "px";
        comprobarPantalla();
    }
    // MOVE DOWN
    if (e.key === "s" || e.key === "S" || e.key === "ArrowDown") {
        coordenadaY = naveJugador.offsetTop;
        coordenadaY = Math.min(
            viewportHeight - naveJugador.offsetHeight,
            coordenadaY + velocidadJugador
        );
        naveJugador.style.top = coordenadaY + "px";
        comprobarPantalla();
    }
    // MOVE LEFT
    if (e.key === "a" || e.key === "A" || e.key === "ArrowLeft") {
        coordenadaX = naveJugador.offsetLeft;
        coordenadaX = Math.max(
            naveJugador.offsetWidth / 2,
            coordenadaX - velocidadJugador
        );
        naveJugador.style.left = coordenadaX + "px";
        comprobarPantalla();
    }
    // MOVE RIGHT
    if (e.key === "d" || e.key === "D" || e.key === "ArrowRight") {
        coordenadaX = naveJugador.offsetLeft;
        coordenadaX = Math.min(
            viewportWidth - naveJugador.offsetWidth / 2,
            coordenadaX + velocidadJugador
        );
        naveJugador.style.left = coordenadaX + "px";
        comprobarPantalla();
    }
});

English is not my main language :p, so sorry if something is bad explained

I tried something like this, but i was wrong, it doesn’t work

if (
        (e.key === "w" || e.key === "W" || e.key === "ArrowUp") &&
        (e.key === "d" || e.key === "D" || e.key === "ArrowRight")
    ) {
        coordenadaY = naveJugador.offsetTop;
        coordenadaY = Math.max(0, coordenadaY - velocidadJugador);
        naveJugador.style.top = coordenadaY + "px";

        coordenadaX = naveJugador.offsetLeft;
        coordenadaX = Math.min(
            viewportWidth - naveJugador.offsetWidth / 2,
            coordenadaX + velocidadJugador
        );
        naveJugador.style.left = coordenadaX + "px";
        comprobarPantalla();
    }

Didn’t find anything like what i need in other threads

I need to display different images each day automatically [closed]

I have a website with images of people on the home and have a folder with around 500 images. Is there any way I can make it so each day they automatically change?

 <div class="original1">
    <br>
    <h3 class="no-title">Recently Added</h3>
    <div class="no">
        <img src="images/move.png" alt="">
        <a href="files/jamaledwards"><img src="images/deadhome/jamaledwards.png" alt=""></a>
        <a href="files/margaretjohn"><img src="images/deadhome/margaretjohn.png" alt=""></a>
        <a href="files/michaelgambon"><img src="images/deadhome/michaelgambon.png" alt=""></a>
        <a href="files/halroach"><img src="images/deadhome/halroach.png" alt=""></a>
        <a href="files/genekelly"><img src="images/deadhome/genekelly.png" alt=""></a>
        <a href="files/petercushing"><img src="images/deadhome/petercushing.png" alt=""></a>
        <a href="files/jimhenson"><img src="images/deadhome/jimhenson.png" alt=""></a>
        <a href="files/hennyyoungman"><img src="images/deadhome/hennyyoungman.png" alt=""></a>
        <a href="files/donaldpleasence"><img src="images/deadhome/donaldpleasence.png" alt=""></a>
        <a href="files/brookemccarter"><img src="images/deadhome/brookemccarter.png" alt=""></a>
        <a href="#search22"><img src="images/search.png" alt=""></a>
    </div>
</div>
<br>

I want these to change each day without me doing it, can JavaScript do this?

Hey guys! Is there any way to generate a PDF report using SQLite offline with cordova?

I’m a beginner and I’m creating an app with cordova framework7 and sqLite and I need some way to generate a PDF report using SQLite offline with cordova

Olá pessoal! Eu sou iniciante e estou criando um app com cordova framework7 e sqLite e preciso de alguma forma de gerar relatorio em PDF usando SQLite offline com cordova

Is there any way to generate a PDF report using SQLite offline with cordova?