jquery button registers multiple clicks instantly

I have a button in my form that is intended to check whether or not the authorization information has been entered correctly. It does this by firing off an ajax call to a controller in my Ruby on Rails application and checking the result. The problem is that even when I click the button only once, it immediately registers multiple clicks – sometimes as many as 5! – and fires that ajax call multiple times, which hits the API I’m checking multiple times as well. Here is what I have in my html.erb file:

<%- content_for :js do -%>
  <%= javascript_tag nonce: true do -%>
    $( document ).on('turbolinks:load', function() {
      var $form = $("form");
      var $buttons = $('#soap-access, #rest-access, #email-access, #audview-access', $form);
      var $jobSchedule = $('#client_job_schedule', $form);

      $buttons.click(function (e) {
        var $button = $(this);
        $button.prop('disabled', true);
        var $parent = $button.parent();
        var $spinner = $('.fa-sign-in', $parent);
        var $signIn = $('.fa-spinner', $parent);
        var $success = $('.fa-check', $parent);
        var $error = $('.fa-times', $parent);

        var data = {};
        var $endpoint = '';

        // add stuff to data

        $signIn.toggleClass('d-none');
        $spinner.toggleClass('d-none');
        $success.addClass('d-none');
        $error.addClass('d-none');

        $.ajax({
          type: "GET",
          url: "<%= api_authentication_clients_path %>",
          data: data
        })
          .done(function () {
            $success.removeClass('d-none');
          })
          .fail(function (jqXHR) {
            $error.removeClass('d-none');
            if (jqXHR.responseJSON && jqXHR.responseJSON.message) {
              alert(jqXHR.responseJSON.message);
            } else {
              alert('Error trying to authenticate');
            }
          })
          .always(function () {
            $button.prop('disabled', false);
            $spinner.toggleClass('d-none');
            $signIn.toggleClass('d-none');
          });
      });
    });
  <% end -%>
<% end %>

You can see that I add the ‘disabled’ prop very first thing, and remove it at the end.

I also tried taking out the removal of the disabled prop at the end just in case it was somehow getting re-enabled immediately. The button is indeed visually disabled, but the extra clicks have already been registered and all the ajax calls still happen, one after another.

I’ve also tried things like e.stopImmediatePropagation(); and e.preventDefault(); to no avail.

WebSocket not connecting from Safari browser but works on all others

I have a pretty vanilla web socket example. Server is node using ws:

const express = require('express');
const WebSocket = require('ws');
const app = express();
const server_socket = new WebSocket.Server({ server: server, path: '/ws' });
server_socket.on('connection', function(ws) {
  console.log("client joined");
  ws.on('error', (error) => {console.error('Error');});
  ws.on('close', () => {console.log('client left');});
}

Client is javascript:

  const socket = new WebSocket('ws://3.17.155.18/ws');
  socket.addEventListener('open', () => {
    console.log('WebSocket connection opened');
  });

This works great in Chrome, Firefox, Opera and Brave, but not Safari. Safari fails with

WebSocket connection to ‘ws://3.17.155.18/ws’ failed: There was a bad
response from the server.

But the server doesn’t log any connection attempt at all.

When I look in the browser’s web inspector they all make identical calls to the web socket with the exception for the following headers that all other browsers have that Safari doesn’t:

  • accept-encoding = gzip, deflate
  • accept-language = en-US,en;q=0.9
  • host = 3.17.155.18
  • sec-websocket-extensions = permessage-deflate; client_max_window_bits

(actually that last header Safari has, but only with a value of “permessage-deflate”)

I see no way to change the headers Safari sends, so am wondering if there is configuration on the server that would accept Safari’s headers. I have to imagine there’s a way to get such a simple websockets example working in Safari.

How to initialize Firebase and its Auth before useEffect hook of AuthContext?

I am beginner in ReactNative and firebase, and trying to create Authentication System. However, my project is giving me an error in AuthContext.tsx:

Cannot read property auth of undefined in onAuthStateChanged Observer

This is due to the fact that the useEffect of AuthContext executes before Firebase initialization.

As during this time, the auth is not ready when consumed by the onAuthStateChanged observer, useEffect throws error. I have tried adding loading or auth in the dependency array of useeffect, still it is not working.

Here is my firebase config:

firebase.ts

// Import the functions you need from the SDKs you need
import { initializeApp } from "@firebase/app";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

import { initializeAuth, getReactNativePersistence, getAuth } from "@firebase/auth";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { getFirestore } from "@firebase/firestore";
import firebase from "firebase/compat/app";
// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "apikey",
  authDomain: "eample.firebaseapp.com",
  projectId: "exampleId",
  storageBucket: "example.firebasestorage.app",
  messagingSenderId: "id",
  appId: "appid"
};




// Initialize Firebase

const app =   initializeApp(firebaseConfig);
console.log('it is called');
 const auth =  initializeAuth(app,{
    persistence : getReactNativePersistence(AsyncStorage)
})

 const firestore = getFirestore(app);


  export {app, auth, firestore}

AuthContext.tsx

import { createContext, useContext, useEffect, useState } from "react";
import { AuthContextType, UserType } from "../types";
import { signInWithEmailAndPassword } from "firebase/auth/cordova";
import { auth,firestore } from "../config/firebase";

import { onAuthStateChanged } from "@firebase/auth";
import { useNavigation } from "@react-navigation/native";
import { Text } from "react-native";


 const AuthContext = createContext<AuthContextType | null>(null);

export const AuthProvider:React.FC<{children:React.ReactNode}> = ({children}) => {
    const [user,setUser] = useState<UserType>(null);

    const [loading, setLoading] = useState(true);
    //const navigation:any = useNavigation();
   
   useEffect(()=>{
    const unsub = onAuthStateChanged(auth,(firebaseUser)=> {
     console.log('firebase User',firebaseUser);
    setLoading(false);
   })

    return () => unsub();
   },[]);


    const login = async (email:string,password:string) => {
        try {
         await signInWithEmailAndPassword(auth,email,password);
         return {success:true} 
        }
        catch(error:any){
        let msg = error.message;
        return {success:false,msg}
        }
    }

  
const contextValue:AuthContextType = {
    user,
    setUser,
    login,
};
if (loading) {
  return <Text>Loading...</Text>; // Or a loading spinner
}
return (
    <AuthContext.Provider value={contextValue}>
            {!loading && children}
    </AuthContext.Provider> 
);
 
}

export const useAuth = ():AuthContextType => {
   const context = useContext(AuthContext);
   if(!context) {
    throw new Error("useAuth must be wrapped inside AuthProvider");
   }
   return context;
}

App.tsx

import React from 'react';
import './gesture-handler';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import StackNavigator from './navigation/StackNavigation';
import { AuthProvider } from './context/AuthContext';

function App() {
 
  return (
    <AuthProvider>
    <NavigationContainer>
     
      <StackNavigator />
      
    </NavigationContainer>
    </AuthProvider>
    
   
  );
}



export default App;

Sending hcaptcha token to Discord using selenium

There was a similar question on stack overflow in the 21st year

Submitting hcaptcha captcha token to Discord to create an account using selenium

but, firstly, they did not give a clear answer, and secondly, everything has changed in 4 years, and the scripts that were offered there no longer work. What’s the point. I’m trying to create a bot in discord automatically using python and the selenium library, but to do this, after entering the name of the bot, you need to go through a captcha. To bypass this, I use the 2captcha service, which works according to the principle: I send a sitekey to discord, he sends me a solution in the form of a string that needs to be inserted into the response field (h-captcha-response). The problem is that, unlike other sites, discord checks the correctness of the completed captcha itself, without the “Send”, “Verify”, etc. buttons. I’ve been puzzling over how to get around this for a very long time. The neural networks replied that there was a hidden script in the discord to check the captcha, and you need to activate the trigger to make it count. They did not find the trigger itself, even after completely removing the HTML code of the site. I also tried to find it myself, but I couldn’t. Please help, it was because of this problem that I abandoned my project the previous year, decided to return now with renewed vigor, and still could not figure it out. I will attach the code that already exists below. Just after the comment # Inserting into the code and activating the captcha check there must be a code that I couldn’t write

async def _process_log_entry(entry: dict):
    message = entry.get("message", "")
    if 'captcha' not in message or 'sitekey' not in message:
        return None
    try:
        data = json.loads(message)
        post_data = (data.get("message", {})
                     .get("params", {})
                     .get("request", {})
                     .get("postData"))
        if not post_data:
            return None
        events = json.loads(post_data).get("events", [])
        if events:
            return events[0].get("properties", {}).get("sitekey")
    except (json.JSONDecodeError, AttributeError, TypeError, KeyError) as e:
        return None
    return None


async def get_sitekey(driver: webdriver.Chrome, timeout=5):
    for attempt in range(timeout):
        try:
            log_entries = driver.get_log("performance")
            for entry in log_entries:
                if sitekey := await _process_log_entry(entry):
                    return sitekey
            await asyncio.sleep(1)
            return None
        except selenium.common.exceptions.InvalidArgumentException as e:
            await asyncio.sleep(1)
            return None
    return None


# FIXME
async def bypass_captcha(driver, sitekey):
    loop = asyncio.get_running_loop()
    solve = TwoCaptcha(tk.captcha_api_key)

    with concurrent.futures.ThreadPoolExecutor() as pool:
        for _ in range(3):
            try:
                result = await loop.run_in_executor(pool,
                                                    lambda: solve.hcaptcha(sitekey=sitekey, url=driver.current_url))
            except (ApiException, twocaptcha.api.ApiException, twocaptcha.solver.ApiException,
                    twocaptcha.solver.TimeoutException) as e:
                print(e)
                continue
            break
        else:
            raise ApiException("All attempts to solve the captcha were unsuccessful")

        hcaptcha_solution = result['code']

        # Inserting into the code and activating the captcha check
    return solve

Plus this piece of code (if needed):

chrome_options = webdriver.ChromeOptions()
chrome_options.set_capability(
    "goog:loggingPrefs", {"performance": "ALL", "browser": "ALL"}
)
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://discord.com/developers/applications")

Thank you in advance for your help

P.S. I assume that you may need JS for the solution, so I’ll add it to the tags.

GSAP ScrollSmother – migrate css sticky to pin

This is my section before scrollsmoother library:

<section class="history">

    <div class="history__wrap">
        <div class="history-text">
            <p>estd 1954</p>
        </div>
        <div class="history-camera">
            <img src="https://lawngreen-spider-414307.hostingersite.com/wp-content/themes/bricko/assets/img/vintage-camera.svg" alt="">

        </div>
        <div class="history-heading">
            <h2>History</h2>
        </div>
    </div>


    <div class="history-film">
        <div class="history-film-mask">

            <div class="history-film__item">
                <ul class="history-film__dots">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
                <div class="history-film__content">
                    <div class="history-film__text">
                        <h2>1968</h2>
                        <p>Sve je počelo 1968. godine, u maloj ulici na obodu grada. Naš deda, Radomir, otvorio je prvu radnju sa samo jednom stolicom, starim ogledalom i makazama koje je dobio na poklon. Kroz vitraž prozor upadala je svetlost koja je osvetljavala prve mušterije — radnike, đake, prolaznike koji su tražili malo razgovora i dobru frizuru.</p>
                    </div>
                </div>
                <ul class="history-film__dots">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
            </div>
            <div class="history-film__item">
                <ul class="history-film__dots">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
                <div class="history-film__content">
                    <div class="history-film__img">

                        <img src="https://lawngreen-spider-414307.hostingersite.com/wp-content/themes/bricko/assets/img/radomir.png" alt="">

                    </div>
                </div>
                <ul class="history-film__dots">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
            </div>
            <div class="history-film__item">
                <ul class="history-film__dots">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
                <div class="history-film__content">
                    <div class="history-film__text">


                        <h2>1968</h2>
                        <p>Godine su prolazile, i berbernica je rasla zajedno sa komšilukom. Prvu električnu mašinu dobili smo sedamdesetih, a ogledalo je zamenilo novo, šire, ali su makaze ostale iste. I duh. Danas, kada uđete u našu radnju, još uvek možete osetiti miris starog losiona, čuti zvuk radio aparata i videti fotografije koje pričaju priču dužu od pola veka.</p>
                    </div>
                </div>
                <ul class="history-film__dots">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
            </div>
            <div class="history-film__item large">
                <ul class="history-film__dots">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
                <div class="history-film__content">
                    <div class="history-film__img">

                        <img src="https://lawngreen-spider-414307.hostingersite.com/wp-content/themes/bricko/assets/img/family.png" alt="">

                    </div>
                </div>
                <ul class="history-film__dots">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                    <li></li>
                </ul>
            </div>
       
    </div>
</section>
<div class="next-block"></div>


.history {
  min-height: 400dvh;
  display: flex;
  /* align-items: center; */
  justify-content: flex-start;
  flex-direction: column;
  position: relative;
}

.history__wrap {
  overflow: hidden;
  min-height: 100dvh;
  width: 100vw;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  position: sticky;
  top: 0;
}

.history-text {
  text-align: center;
  margin-bottom: 40px;
}

.history-text p {
  color: var(--color-tamarillo);
  font-size: 15px;
  line-height: 22px;
  font-weight: 500;
  text-transform: uppercase;
}

.history-camera {
  text-align: center;
  position: relative;
  z-index: 2;
  width: 100%;
}

.history-heading {
  transform: rotate(-12deg);
  text-align: center;
}

.history-heading h2 {
  font-family: "PP Playground", sans-serif;
  font-size: 253px;
  line-height: 364px;
  font-weight: 500;
  color: var(--color-tamarillo);
  margin-top: -150px;
  margin-left: -110px;
}

.history-film {
  background-color: var(--color-black);
  clip-path: ellipse(300% 40% at 50% 50%);
  display: flex;
  align-items: center;
  -ms-flex-wrap: nowrap;
  flex-wrap: nowrap;
  min-height: 100dvh;
  width: 100%;
  position: relative;
  overflow-x: hidden;
  position: sticky;
  top: 30px;
  left: 0%;
  opacity: 0;
  transition: opacity 0.4s ease-out;
  scale: 0.5;
  transform-origin: center !important;
  margin-top: -100%;
}

.history-film__img {
  width: 100%;
  text-align: center;
}

.history-film__img img {
  /* clip-path: ellipse(200% 50% at 0% 50%); */
  height: 100%;
  width: 100%;
  max-width: 70%;
  object-fit: cover;
  object-position: top;
}

.history-film::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 15%;
  height: 100%;
  background: linear-gradient(
    to right,
    var(--color-black) 0%,
    transparent 100%
  );
  z-index: 3;
}

.history-film::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 10%;
  height: 100%;
  background: linear-gradient(to left, var(--color-black) 0%, transparent 100%);
  z-index: 3;
}

.history-film__item {
  min-width: 50vw;
  height: 80dvh;
  background-color: var(--color-black-light);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-direction: column;
  padding: 50px 0px;
}

.history-film__item.large {
  min-width: 100vw;
}

.history-film__content {
  display: flex;
  justify-content: center;
  width: 100%;
  padding: 50px 20px;
  flex: 1;
  height: calc(100% - 100px);
}

.history-film__text {
  max-width: 90%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 25px 0px;
}
.history-film__content h2 {
  font-family: "PP Playground", sans-serif;
  font-size: 9em;
  line-height: 1;
  font-weight: 500;
  color: var(--color-warm-white);
}

.history-film__content p {
  font-size: 1.2em;
  line-height: 1.467;
  font-weight: 500;
  color: var(--color-warm-white);
  text-transform: uppercase;
}

.history-film__dots {
  display: flex;
  align-items: center;
  justify-content: space-around;
  list-style: none;
  margin: 0;
  padding: 0;
  width: 100%;
}

.history-film__dots li {
  width: 3.05vw;
  height: 3.05vw;
  background-color: var(--color-black);
}

.history-film-mask {
  display: flex;
  align-items: center;
  -ms-flex-wrap: nowrap;
  flex-wrap: nowrap;
  position: relative;
}



 // CAMERA SCALE
    const historyElement = document.querySelector('.history');
    const historyHeight = historyElement.offsetHeight;
    const cameraTl = gsap.timeline({
        scrollTrigger: {
            trigger: ".history",
            start: "top top",
            end: `bottom-=${historyHeight / 1.5}px top`,
            scrub: 1,
            onLeave: () => {
                document.querySelector('.history__wrap').style.opacity = 0;
                document.querySelector('.history-film').style.opacity = 1;
               
                historyElement.style.backgroundColor = '#171819';


            },

            onEnterBack: () => {
                document.querySelector('.history__wrap').style.opacity = 1;
                document.querySelector('.history-film').style.opacity = 0;
                historyElement.style.backgroundColor = '#faf2dd';
                
            }
        }
    });

    const scaleValue = window.matchMedia("(max-width: 991px)").matches ? 10 : 22;

    cameraTl.to(".history-camera > img", {
        x: 0,
        y: 0,
        scale: scaleValue,
        ease: "none",
    }).to(".history-film", {
        marginTop: 0,
        y: 0,
        opacity: 1,
        ease: "none",
        duration: 0.5,
        delay: 0,
        scale: 1,

    }, '-=0.2');

    // FILM HISTORY
    const filmHistory = gsap.utils.toArray(".history-film__item");
    const filmItemWidth = filmHistory.reduce((diff, item) => {
        return diff + item.offsetWidth;
    }, 0);
    const filmTl = gsap.timeline({
        scrollTrigger: {
            trigger: ".history",
            scrub: 3,
            // markers: true,
            start: `top+=${historyHeight - (historyHeight / 2.5) + 100}px bottom`,
            end: () => `bottom bottom`,
           
            onLeave: () => {
                document.querySelector('.site-header').classList.remove('white');
            },
            onEnterBack: () => {
                document.querySelector('.site-header').classList.add('white');
            },
        }
    });

    filmTl.to(filmHistory, {
        x: () => `-${filmItemWidth - window.innerWidth}px`,
        ease: "none"
    });

    // NEXT BLOCK BG COLOR
    gsap.to('.next-block', {
        scrollTrigger: {
            trigger: '.next-block',
            pinnedContainer: ".history",
            start: 'top 50%',
            toggleActions: 'play none reset none',
        }
    });

Can any help me?

I try to solve sticky problem with gsap because i use lenis.js before, but after gsap become free i want to migrate on new way of smooth scrolling.

Lenis.js and GSAP handle smooth scrolling in different ways:

Lenis.js uses a custom scroll wrapper and requestAnimationFrame, which means it’s not using native browser scroll.

GSAP’s ScrollSmoother (the new free plugin you’re referring to) also uses a scroll proxy, but it’s designed to integrate deeply with GSAP animations.

Because both libraries override the native scroll behavior, switching from Lenis to GSAP’s ScrollSmoother can break sticky positioning (position: sticky) if not configured properly.

Only update value when pushbar closes

I have a simple app rendering the value from a switch input inside a pushbar.

I’d like it so the values only update when the pushbar closes.

Note for the full app, there are multiple inputs that should only update when the pushbar closes.

I think using gargoyle is the best approach, although I don’t have much familiarity with it. Or possibly freezeReactiveVal?

library(shiny)
library(bslib)
library(pushbar)

ui <- page_fluid(
  pushbar_deps(),
  actionButton("open", "Open pushbar"),
  pushbar(
    id = "myPushbar",
    from = "right",
    input_switch("switch", "Test Switch")
  ),
  verbatimTextOutput("preview")
)

server <- function(input, output, session){
  setup_pushbar()
  observeEvent(input$open, {
    pushbar_open(id = "myPushbar")
  })
  output$preview <- renderPrint({input$switch})
}

shinyApp(ui, server)

p5js filter shader causing graphics object transparency to turn black

I’m attempting to simulate wind blowing across plants on a p5js sketch and came across a lovely fragment shader that does pretty much what I want (// https://github.com/GameMakerDiscord/wind-shader
).

However, the issue I’m struggling with is when I attempt to apply that shader to individual graphics objects with transparency, as the entire surface turns black and unfortunately I’m not seeing exactly what the fix would be. I’ve played with varying methods of discard when the alpha is 0 but must not be doing it quite right.

Here is the basic sketch with the shader being applied to a single image – works fine except the background is also being distorted. Not very good at simulating grass, but wanted to include the minimum working example.

let gfx, gfx2;
let wind_fs;

function setup() {
  createCanvas(500, 500);
  
  gfx = createGraphics(width, height);
  gfx2 = createGraphics(width, height);
  
  for (let _ = 0; _ < 10; _++) {
    gfx.fill(random(255));
    gfx.circle(random(width), random(height), random(10, 50));
  }
  
  wind_fs = createFilterShader(wind_src);
}

function draw() {
  background(220);
  image(gfx, 0, 0);
  
  wind_fs.setUniform("_time", millis() * 0.001);
  filter(wind_fs);
}

// https://github.com/GameMakerDiscord/wind-shader
let wind_src = `precision mediump float;
varying vec2 vTexCoord;
uniform sampler2D tex0;
uniform float _time;

void main() {

  // Shift the texture coordinates
  vec2 uv = vTexCoord;

  vec2 Size = vec2(256, 128);
  vec2 Wave = vec2(48, 5);

  uv = vTexCoord + vec2(cos((uv.y / Wave.x + _time) * 6.2831) * Wave.y, 0) / Size * (1.0 - vTexCoord.y);

  // Get the texture pixel color
  vec3 pixel_color = texture2D(tex0, uv).rgb;

  // Fragment shader output
  gl_FragColor = vec4(pixel_color, 1.0);
}
`;
html, body {
  margin: 0;
  padding: 0;
}
canvas {
  display: block;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <main>
    </main>
    <script src="sketch.js"></script>
  </body>
</html>

Here is what I would like to do. I’m assuming that to properly handle each individual plant (simulated by the green rects, though I’d be drawing an actual plant to the graphics object) that I would need to apply the shader individually to each one in order to have it not oddly distort the overall scene. The circles indicate a background that’d be drawn to the scene that I don’t want to distort.

let gfx, gfx2;
let wind_fs;

function setup() {
  createCanvas(500, 500);
      
  gfx = createGraphics(width, height);
  gfx2 = createGraphics(50, 100);
  
  // the background
  for (let _ = 0; _ < 10; _++) {
    gfx.fill(random(255));
    gfx.circle(random(width), random(height), random(10, 50));
  }
  
  // the grass
  gfx2.fill(color(0,255,0));
  gfx2.rect(15, 50, 10, 50);
      
  wind_fs = gfx2.createFilterShader(wind_src);
}

function draw() {
  background(220);
  image(gfx, 0, 0);
      
  for (let i = 0; i < 5; i++) {
    wind_fs.setUniform("_time", millis() * 0.001);
    gfx2.filter(wind_fs);
    image(gfx2, gfx2.width * i *2, 20);
  }
}

    // https://github.com/GameMakerDiscord/wind-shader
    let wind_src = `precision mediump float;
    varying vec2 vTexCoord;
    uniform sampler2D tex0;
    uniform float _time;

    void main() {

      // Shift the texture coordinates
      vec2 uv = vTexCoord;

      vec2 Size = vec2(256, 128);
      vec2 Wave = vec2(48, 5);

      uv = vTexCoord + vec2(cos((uv.y / Wave.x + _time) * 6.2831) * Wave.y, 0) / Size * (1.0 - vTexCoord.y);

      // Get the texture pixel color
      vec3 pixel_color = texture2D(tex0, uv).rgb;

      // Fragment shader output
      gl_FragColor = vec4(pixel_color, 1.0);
    }
    `;
html, body {
      margin: 0;
      padding: 0;
    }
    canvas {
      display: block;
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/addons/p5.sound.min.js"></script>
        <link rel="stylesheet" type="text/css" href="style.css">
        <meta charset="utf-8" />

      </head>
      <body>
        <main>
        </main>
        <script src="sketch.js"></script>
      </body>
    </html>

Things I’ve tried:

Each entry displays “Entry added X seconds ago” where X is the amount of seconds

I’m breaking my head to perform something like this: a message log where some actions are posted and I wanted to implement a feature to the log that displays how many seconds since the log entry was sent. (The seconds must update every second)

Appreciated.

const app = Vue.createApp({
    data() {
        return {
            log: []
        }
    },

    methods: {
        add() {
            const {log} = this

            log.push(`Entry added X seconds ago!`)
        }
    }
})

app.mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.5.4/vue.global.min.js"></script>
<div id="app">
    <div v-for="l of log">
        <div v-html="l"></div>
    </div>
    <div style="margin-top: 1rem"><i>Click the button to add a new entry </i><button @click="add()">+</button></div>
</div>

single and double quotes in json.parse

How can I pass a list of characters from Django to Javascript?

I’m passing a dictionary from Django to Javascript in the render function. In javascript I parse the data as always using the code

const dates = JSON.parse("{{dates|safe}}")

This works for numbers, but for strings I get some error

JSON.parse: unexpected character at line 1 column 2 of the JSON data

I could pinpoint the problem down to:

const this_works = JSON.parse('["1","2"]')
const this_throws = JSON.parse("['1','2']")

But I can’t use the ‘ as the outermost character here as the {{}} notation seems to require “. What is the workaround to this problem?

jQuery-ui dialog dynamic buttons, change text and function

So I have a default dialog with 2 buttons defined. In my code, it looks the following:

    var defaultButtons = [{
    text: "default"
},

    {
        text: "default"
    }
    ];
    
    $(document).ready(function () {
        $("#dialog-confirm-dynamic").dialog({
            position: {
                my: "center 10%+center",
                at: null,
                of: window
            },
            autoOpen: false,
            resizable: false,
            maxWidth: 250,
            maxHeight: 150,
            width: 250,
            height: "auto",
            modal: true,
            buttons: defaultButtons
        });
    });
    
    function showConfirm() {
        document.getElementById("confirm-dyn-inner").innerHTML = "Are you sure to do this ?";
        $("#dialog-confirm-dynamic").dialog({ title: "Delete" });
        defaultButtons[] = [{
            text: "Delete",
            click: function () {
                document.form.submit();
            }
        },
            {
                text: "Cancel",
                click: function () {
                    $(this).dialog("close");
                }
            }
        ];
        $("#dialog-confirm-dynamic").dialog("open");
    }

In showConfirm() I’m trying to change the text and behaviour of the buttons, but I suspect that they have already been rendered and changing values of the array, even before “open” is not changing anything.

What is the best way to approach this?
TIA

Please help me understand the below [closed]

The question is to “In a TableViewer component you rendered earlier, render all the comments/data pulled from the backend #hint: create columns array and pass it along with other props to TableViewer component”

I have never worked with react or js like this before so its very new to me .

I am unsure if i should add the const column part in Mycomponet.js file or my premade Tableviewer.js file

Please can you help me understand how I can solve this , Its confusing me alot .

I have tried the to create the below code from my component

import React, { Component } from 'react';
import TableViewer from '../utilities/TableViewer';

class MyComponent extends Component {
    state = {
        message: '',
        response: '',
        tableData: [],
        columns: [
            { title: 'ID', field: 'id' },
            { title: 'Comment', field: 'text' }
        ]
    };

    handleChange = (event) => {
        this.setState({ message: event.target.value });
    };

    handleSubmit = async () => {
        const { message } = this.state;
        const response = await fetch('/api/message', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ message }),
        });
        const data = await response.json();
        this.setState({ response: data.message });
    };

    getMessage = async () => {
        try {
            const response = await fetch('/comments'); // Fetch comments from the backend
            const data = await response.json();
            this.setState({ tableData: data }); // Store the fetched comments in state
        } catch (error) {
            console.error('Error fetching comments:', error);
        }
    }

    componentDidMount() {
        this.getMessage(); // Fetch comments when the component mounts
    }

    render() {
        const { message, response, tableData, columns } = this.state;

        return (
            <div>
                <h1>Threat Portal Mockup</h1>
                <input
                    type="text"
                    value={message}
                    onChange={this.handleChange}
                    placeholder="Enter a message"
                />
                <button onClick={this.handleSubmit}>Submit</button>
                <p>Response: {response}</p>

                {/* New section for TableViewer */}
                <div className="table-viewer-section">
                    <h2>Table Viewer Section</h2>
                    <TableViewer
                        data={tableData} // Pass the fetched comments data
                        columns={columns} // Pass the defined columns
                        keyField={"id"} // Use 'id' as the unique key field
                    />
                </div>
            </div>
        );
    }
}

export default MyComponent;

Excluding package using externals causes “Cannot use ‘in’ operator to search for ‘core’ in undefined” error

I am creating a razor class library that wraps the azure-maps-control npm package.

I use TypeScript to build the *.js and Webpack to bundle the *.js.

When I use the RCL in my Blazor web app it works great.

However, I don’t want to distribute the azure-maps-control with my RCL
So I add this line to webpack.config.js:

externals: 'azure-maps-control'

When I do that and build, I now get the “Cannot use ‘in’ operator to search for ‘core’ in undefined” error.

index.js:

import * as atlas from "azure-maps-control";

export interface Authentication {
    authType: atlas.AuthenticationType;
    aadAppId: string;
    aadTenant: string;
    clientId: string;
    subscriptionKey: string;
}

export class core {
    private static maps: Map<string, atlas.Map> = new Map<string, atlas.Map>();

    public static addMap(
        mapId: string,
        configuration: Authentication): void {

        if (this.maps.has(mapId)) {
            console.error(`Map with ID ${mapId} already exists.`);
            return;
        }
        const map = new atlas.Map(mapId, {
            authOptions: {
                authType: configuration.authType,
                subscriptionKey: configuration.subscriptionKey,
                aadAppId: configuration.aadAppId,
                aadTenant: configuration.aadTenant,
                clientId: configuration.clientId,
            },
            center: [-122.33, 47.6],
            zoom: 12,
            view: "Auto",
        });
        this.maps.set(mapId, map);
    }
}

webpack.config.js:

const path = require('path');

module.exports = {
    entry: "./dist/index.js",
    output: {
        path: `${__dirname}/wwwroot/dist`,
        filename: "bundle.js",
        library: 'azMaps'
    },
    externals: 'azure-maps-control'
};

bundle.js:

var azMaps;(()=>{"use strict";var e={d:(a,t)=>{for(var o in t)e.o(t,o)&&!e.o(a,o)&&Object.defineProperty(a,o,{enumerable:!0,get:t[o]})},o:(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},a={};e.r(a),e.d(a,{core:()=>o});const t=azure-maps-control;class o{static maps=new Map;static addMap(e,a){if(this.maps.has(e))return void console.error(`Map with ID ${e} already exists.`);const o=new t.Map(e,{authOptions:{authType:a.authType,subscriptionKey:a.subscriptionKey,aadAppId:a.aadAppId,aadTenant:a.aadTenant,clientId:a.clientId},center:[-122.33,47.6],zoom:12,view:"Auto"});this.maps.set(e,o)}}azMaps=a})();

If I remove externals: 'azure-maps-control' it works fine, but the package gets bundled.

Any suggestions?

Axios and fetch return different values for a nested object

If I make the same API request in axios and fetch, I get different values for a deeply nested value, even though the network tab shows the correct value for both network calls:

    const { data } = await axios.get(`/my/api/path/`, {
      headers: {
        Accept: 'application/json'
      }
    });
    const axiosIntermediatePath = data.root.nested.path;
    console.log('axiosIntermediatePath:', axiosIntermediatePath);

    const fetchResponse = await fetch(`/my/api/path/`, {
      headers: {
        Accept: 'application/json'
      }
    });
    const fetchData = await fetchResponse.json();
    const fetchIntermediatePath = fetchData.root.nested.path
    console.log('fetchIntermediatePath:', fetchIntermediatePath);
axiosIntermediatePath: 
{
  ...
  "foo": {
    "bar": "",
  },
  ...
}
fetchIntermediatePath: 
{
  ...
  "foo": {
    "bar": "myCorrectData",
  },
  ...
}

Even stranger, if I then immediately access the property, it
returns correctly:

    console.log('axiosEditor:', axiosIntermediatePath.foo.bar);
    console.log('fetchEditor:', fetchIntermediatePath.foo.bar);
axiosEditor: myCorrectData
fetchEditor: myCorrectData

I found this problem because I was using axios and assigning data.root to a React.Context variable, then passing it around a bit, and I wasn’t able to access the correct value in a nested component.

Edit: (with some help from the comments) I discovered that this only happens in a Redux action context. The line before the block reproduced above is dispatch(getAPIRequest());. If I remove that line the problem goes away. So the question now is why Redux changes the value returned by the API call, and how to fix it.

Replace multiple matches

Given a JSON object which contains tags identified by {{, I need to find all matches in the payload and replace them. The following code works, but only returns the 1st match, and if I turn on the gim flags to replace all matches, the code breaks. It is worth noting that the application uses ECMA5 engine (SpiderMonkey)

For the sake of demoing, I’m using the window variables, as with the application I am working for, I should also be replacing with workflow variables, so works similarly.

var Obj = {
  hostname: "Test 1 {{window.location.hostname}}",
  protocol: "Test 2 {{window.location.protocol}}"
}
var myObj   = JSON.stringify(Obj)
var regex   = /{{window.location.(.+?)}}/       //gmi flag breaks code
var match   = myObj.match(regex)[1];
var enrich  = Function('return '+"window.location."+match)();
var _Obj    = myObj.replace(regex,enrich)


console.log(JSON.parse(_Obj))

The regex works as follows (https://regex101.com/r/BPFnKK/1) I am using index [1] to select the value.

enter image description here