Blank screen when lazy loading many images in NextJS tsx + Tailwindcss

I am displaying a series of images hosted in CDN on my NextJS page in the “masonry layout” structure (Just like Pinterest). As shown in Layout.

When I try to load it on my desktop it’s working fine. But only when I load it on my iPhone or lower screen sizes, the screen turns blank

or it displays “A problem repeatedly occurred”(problem message) Can you please tell me how to fix it or debug it.

The code is as below for this page. All of this happens inside a [slug] folder for multi page rendering.

'use client'
import React, { useEffect, useState } from 'react'
import Image from 'next/image'
import { useParams, useRouter } from 'next/navigation'
import { IoDownloadOutline } from "react-icons/io5";
import { useInView } from 'react-intersection-observer';
import LoadingSpinner from '../../components/LoadingSpinner'
import { RiGeminiFill } from "react-icons/ri";

interface Wallpaper {
  id: string | number
  thumbnail_url: string
  downloads: number
  categories: Array<string>
  resolution_count: number
}

function CategoryPage() {
  const [wallpapers, setWallpapers] = useState<Wallpaper[]>([])
  const [page, setPage] = useState(1)
  const [hasMore, setHasMore] = useState(true)
  const { ref, inView } = useInView()
  const params = useParams()
  const router = useRouter()
  const [initialLoading, setInitialLoading] = useState(true)

  useEffect(() => {
    const fetchWallpapers = async () => {
      try {
        const response = await fetch(`${process.env.BACKEND_PUBLIC_API_URL}/fetch_wallpapers/category/${params.category}?page=${page}`)
        const data = await response.json()
        
        if (data.length === 0) {
          setHasMore(false)
          return
        }

        setWallpapers(prev => {
          const existingIds = new Set(prev.map((w: Wallpaper) => w.id))
          const newWallpapers = data.filter((w: Wallpaper) => !existingIds.has(w.id))
          return [...prev, ...newWallpapers]
        })
      } catch (error) {
        console.error('Error fetching wallpapers:', error)
      } finally {
        setInitialLoading(false)
        setIsLoading(false)
      }
    }

    if (hasMore) {
      fetchWallpapers()
    }
  }, [params.category, page, hasMore])

  const [isLoading, setIsLoading] = useState(false)

  useEffect(() => {
    if (inView && hasMore && !isLoading) {
      setIsLoading(true)
      setPage(prev => prev + 1)
    }
  }, [inView, hasMore, isLoading])
  
  useEffect(() => {
    setWallpapers([])
    setPage(1)
    setHasMore(true)
    setIsLoading(false)
  }, [params.category])

  const handleWallpaperClick = (wallpaper: Wallpaper) => {
    router.push(`/wallzone/wallpaper_view/${wallpaper.id}?categories=${wallpaper.categories.join(',')}`)
  }

  return (
    <div className="p-4 bg-paper-white min-h-screen pt-20
    max-sm:p-1 max-sm:pt-20">
      {initialLoading ? (
        <div className="h-[calc(100vh-80px)] flex items-center">
          <LoadingSpinner />
        </div>
      ) : (
        <div className="gap-3
        max-sm:columns-2 max-sm:gap-1 
        md:columns-3 
        lg:columns-5 
        2xl:columns-6 2xl:gap-4 [column-fill:_balance]">
          {wallpapers.map((wallpaper) => (
            <div key={wallpaper.id} className="break-inside-avoid mb-4" onContextMenu={(e) => e.preventDefault()}>
              <div 
                className="relative w-full overflow-hidden rounded-lg group cursor-pointer" 
                onClick={() => handleWallpaperClick(wallpaper)}
              >
                {wallpaper.thumbnail_url && (<Image
                  src={wallpaper.thumbnail_url}
                  alt={wallpaper.id.toString()}
                  width={0}
                  height={0}
                  loading="lazy"
                  className="w-full h-auto lg:hover:scale-105 lg:transition-transform lg:duration-300"
                  sizes="(max-width: 640px) 90vw,
                         (max-width: 768px) 45vw,
                         (max-width: 1024px) 30vw,
                         22vw"
                  style={{
                    width: '100%',
                    height: 'auto',
                    minHeight: '100px',
                  }}
                  unoptimized
                />)}
                {wallpaper.resolution_count === 4 && (
                  <div className="absolute top-2 right-2">
                    <RiGeminiFill className="text-yellow-400 text-xl" />
                  </div>
                )}
                <button className="absolute flex items-center rounded-full px-2 shadow-md text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300
                max-lg:bottom-2 max-lg:right-2 
                lg:bottom-1 lg:right-1">
                  <IoDownloadOutline className="mr-1" />
                  {wallpaper.downloads}
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
      {isLoading && !initialLoading && (
        <div className="py-4">
          <LoadingSpinner />
        </div>
      )}
    </div>
  )
}

export default CategoryPage

“SyntaxError: Cannot use import statement outside a module” when running compiled javascript code with Node.js

I am using TypeScript to build a Node.js application. After compiling the code, when I run the output JavaScript file using npm start, it throws the following error:

When I run the following command:

npm start

I get this error:

SyntaxError: Cannot use import statement outside a module

My app.ts (mainfile):

import "reflect-metadata"

import express from 'express';
import dotenv from 'dotenv';
import { useExpressServer } from 'routing-controllers';
import { connectDB } from './config/db';
import { CONNECTED_MESSAGE } from './common';
import { ENV_DETAILS } from './env';


dotenv.config();

// Create an instance of an Express app
const app = express();

// Configure built-in middleware to parse various types of request bodies
app.use(express.json()); // For parsing application/json
app.use(express.urlencoded({ extended: true })); // For parsing application/x-www-form-urlencoded


// Configure routing-controllers with the Express app
useExpressServer(app, {
  controllers: ENV_DETAILS.dirs.controllers
});

// Connect to the database and start the server
const port =  3000;
connectDB().then(() => {
  app.listen(port, () => {
    console.log(CONNECTED_MESSAGE.listenPort, `${port}`);
  });
});

My package.json File:

"scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "start": "node dist/app.js",
    "dev": "tsx src/app.ts",
    "build": "tsc && tsc-alias"
  },

My tsconfig.json File:

{
  "compilerOptions": {
    "module": "ESNext",
    "target": "ESNext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "resolveJsonModule": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "baseUrl": ".",
    "paths": {
      "@src/*": [
        "src/*"
      ]
    }
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules",
    "dist"
  ]
}

Environment : Node.js version: 20.12.2 and npm version: 6.14.11

I expect the command npm start to execute the compiled code without throwing an error.
Are there any issues with my configuration, or am I missing something critical?
How can I resolve this Error?

Getting a “The file for this url was not found” error on tus/server

I have a @tus/server backend with a react uppy frontend. And when uploading I’m getting this response

“The file for this url was not found”

Im runnin multiple containers and the vps is behind nginx.

In the frontend I’m using uppy like this

const [uppy] = useState(() => new Uppy().use(Tus, { endpoint: 'https://app.chatzu.ai/files/' }));

the frontend does these requests in order

Request URL:
https://app.chatzu.ai/files
Request Method:
POST
Status Code:
301 Moved Permanently
Remote Address:
<IP>
Referrer Policy:
strict-origin-when-cross-origin


Request URL:
https://app.chatzu.ai/files/
Request Method:
GET
Status Code:
404 Not Found
Remote Address:
<IP>
Referrer Policy:
strict-origin-when-cross-origin

Nginx conf


    location /files/ {
        proxy_pass http://172.17.0.4:1080;
     # Disable request and response buffering
        proxy_request_buffering  off;
        proxy_buffering          off;
        proxy_http_version       1.1;

        # Add X-Forwarded-* headers
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header         Upgrade $http_upgrade;
        proxy_set_header         Connection "upgrade";
        client_max_body_size     0;

}

and my tus server code

const { Server } = require('@tus/server');
const { FileStore } = require('@tus/file-store');
const express = require('express');

const host = '0.0.0.0';
const port = 1080;
const app = express();
const uploadApp = express();

const server = new Server({
  path: '/files',
  datastore: new FileStore({ directory: '/files' }),
});

// Middleware to log all incoming requests
uploadApp.use((req, res, next) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.originalUrl}`);
  next(); // Pass control to the next middleware or route handler
});

uploadApp.all('*', server.handle.bind(server));
app.use('/files', uploadApp);

app.listen(port, host, () => {
  console.log(`Server listening on http://${host}:${port}`);
});

Thanks

How to intercept and modify user input in a Chrome extension before sending it to ChatGPT?

I am developing a Chrome extension to intercept user messages sent to ChatGPT. The goal is to verify whether the message contains sensitive data before sending it to the ChatGPT API.

Here’s the flow I want to achieve:

  1. When the user types a message and clicks “Send” (or presses Enter), the Chrome extension intercepts the message.

  2. The extension sends the intercepted message to my backend API.

  3. The backend API analyzes the message to determine if it contains sensitive data.

  4. If sensitive data is found, the backend masks the sensitive content and returns the modified
    message.

  5. The modified (or original) message is then sent to ChatGPT.

I would like to know:

  1. How can I intercept the message from the ChatGPT input box before it’s sent?

  2. How can I send this intercepted message to my backend API from the extension and wait for the response?

  3. Once the response is received, how can I modify the original input to send the filtered message to ChatGPT?

Here’s what I’ve tried so far:

  1. I’ve looked into using chrome.webRequest but it seems more suited for network requests rather than DOM manipulation.
  2. I’ve considered injecting a content script to access the DOM and listen to input events, but I’m unsure how to modify the message programmatically before submission.

Content.js

// content.js
console.log("ChatGPT Message Interceptor content script loaded.");

// Wait for the DOM to be fully loaded
document.addEventListener("DOMContentLoaded", () => {
  const sendButton = document.querySelector('[aria-label="Send prompt"]'); // Adjust the selector based on the actual element
  const inputField = document.querySelector("textarea"); // Adjust if necessary

  if (sendButton && inputField) {
    console.log("Send button and input field found.");

    // Listen for the click event on the send button
    sendButton.addEventListener("click", async (event) => {
      event.preventDefault(); // Prevent sending the message directly

      const userMessage = inputField.value;
      console.log("Intercepted message:", userMessage);

      // Send the message to your backend API for verification and filtering
      try {
        const response = await fetch("http://localhost:3001/verify", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ message: userMessage }),
        });

        const data = await response.json();

        if (data.isSensitive) {
          // If the message is sensitive, show the filtered version
          console.log(
            "Sensitive data detected. Filtered message:",
            data.filteredMessage
          );

          // Set the filtered message in the input field
          inputField.value = data.filteredMessage;
        } else {
          console.log("No sensitive data detected.");
        }

        // Trigger the send button again with the filtered message
        sendButton.click(); // Resend the message (either original or filtered)
      } catch (error) {
        console.error("Error while sending message to backend:", error);
      }
    });
  } else {
    console.log("Send button or input field not found.");
  }
});

manifest.json

{
    "manifest_version": 3,
    "name": "ChatGPT Message Interceptor",
    "version": "1.0",
    "description": "Intercept and modify messages sent to ChatGPT",
    "permissions": [
      "activeTab",
      "storage"
    ],
    "host_permissions": [
        "http://localhost:3001/*"  // This grants access to your local API
      ],
    "content_scripts": [
      {
        "matches": ["https://chatgpt.com/*", "https://*.chat.openai.com/*"],
        "js": ["content.js"]
      }
    ],
    "background": {
      "service_worker": "background.js"
    },
    "action": {
      "default_popup": "popup.html",
      "default_icon": {
        "16": "images/icon-16.png",
        "48": "images/icon-48.png",
        "128": "images/icon-128.png"
      }
    }
  }

background.js

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  console.log("Message received in background script:", message);

  if (message.action === "logMessage") {
    console.log("Log message from content script:", message.data);
    sendResponse({ status: "Message logged" });
  }
});

popup.js

document.getElementById("activateButton").addEventListener("click", () => {
  chrome.runtime.sendMessage({ action: "activateInterceptor" }, (response) => {
    alert("Interceptor activated!");
  });
});

popup.html

<!DOCTYPE html>
<html>

<head>
    <title>ChatGPT Message Interceptor</title>
    <style>
        body {
            width: 200px;
            padding: 10px;
        }

        button {
            width: 100%;
            padding: 10px;
            font-size: 16px;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <h3>Activate Interceptor</h3>
    <button id="activateButton">Activate</button>
    <script src="popup.js"></script>
</body>

</html>

How to render my components in a tree structure, like default file structure in IDE using React

I have a component, which is called TreeNode, it is 1 file in my tree stucture.

import React from "react";
import classes from "./TreeNode.module.css"

function TreeNode({children, title}){
    return(
        <div>
            <div className={classes.treeNode}>
                <div className={classes.treeNodeType}>
                    <svg xmlns="http://www.w3.org/2000/svg" fill="#3B4045" x="0px" y="0px" width="20" height="20" viewBox="0 0 20 20">
                        <path d="M20,6h-8l-2-2H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8C22,6.9,21.1,6,20,6z"></path>
                    </svg>
                </div>
                <div className={classes.treeNodeTitle}>
                    {title}
                </div>
            </div>
        </div>
    )
}

export default TreeNode;

And i have file, which contain mock-objects of file, i want to drow in my page like a tree.

const files = [
    {
        id: 232141332,
        title: "Оборудование",
        type: "FOALDER",
        opened: false,
        level: 0,
        fatherId: null,
        children: [
            {
                id: 734573086,
                title: "MA5600",
                type: "FOALDER",
                opened: false,
                level: 1,
                fatherId: 232141332,
                children: [
                    {
                        id: 867407333,
                        title: "Удаление платы",
                        type: "FILE",
                        opened: false,
                        level: 2,
                        fatherId: 734573086,
                        children: []
                    },
                    {
                        id: 110345245,
                        title: "Добавление платы",
                        type: "FILE",
                        opened: false,
                        level: 2,
                        fatherId: 734573086,
                        children: []
                    }
                ]
            },
            {
                id: 222225454,
                title: "C300M",
                type: "FOALDER",
                opened: false,
                level: 1,
                fatherId: 232141332,
                children: [
                    {
                        id: 333334256,
                        title: "Не найдена опция TR-82",
                        type: "FILE",
                        opened: false,
                        level: 2,
                        fatherId: 222225454,
                        children: []
                    }
                ]
            }
        ]
    }
]

export default files;

How to write my Main.jsx file to render all this files.

import files from "../../mock/files";
import "../../styles/Main.css"
import TreeNode from "../treenode/TreeNode";

function Main() {
    return (
      <div className="wrapper">
        <div className="tree">
            {
                files.map((file) => {
                    //code
                })
            }
        </div>
      </div>
    );
  }
  
  export default Main;

Maybe I need to refactor some code, i don’t know, but the second day I can’t do this.

“QUOTA_BYTES quota exceeded” error in React app using IndexedDB

I have a React app that uses IndexedDB to store some user-entered values before sending it off to the backend. I am repeatedly getting Uncaught (in promise) Error: QUOTA_BYTES quota exceeded every time I update an input, even without actually submitting any of the data to IndexedDB.

I’ve cleared the storage so that I’m using 0B out of 373800 MB storage quota and yet the errors persist.

Here is the code I have that I believe would be relevant to the issue:

export default function Personalize() {
    const [formData, setFormData] = useState({});
    
    // Initial data fetch and formData setup
    useEffect(() => {
        fetch(`${host}/api/products/${productId}`)
          .then(response => response.json())
          .then(data => {
            const initialFormData = data.personalizations.reduce((acc, variable) => {
              acc[variable.name] = variable.type === 'list' ? [] : '';
              return acc;
            }, {});
            
            data.preview.forEach(variable => {
              if (variable.key) {
                initialFormData[variable.key] = variable.default;
              }
            });
            setFormData(initialFormData);
          });
    }, [productId]);

    // This triggers the error on every change
    const handleChange = (name, value) => {
        setFormData((prevData) => ({
          ...prevData,
          [name]: value,
        }));
    };

    // IndexedDB setup - only used on form submit
    const openDB = () => {
        return new Promise((resolve, reject) => {
            const request = indexedDB.open("PreviewAppDB", 1);
            request.onupgradeneeded = (event) => {
                const db = event.target.result;
                if (!db.objectStoreNames.contains("choices")) {
                    db.createObjectStore("choices", {keyPath: "key"});
                }
            };
            request.onsuccess = (event) => resolve(event.target.result);
            request.onerror = (event) => reject("Failed to open IndexedDB");
        });
    };

    const handleSubmit = async (e) => {
        e.preventDefault();
        const db = await openDB();
        return new Promise((resolve, reject) => {
            const transaction = db.transaction("choices", "readwrite");
            const store = transaction.objectStore("choices");
            const request = store.put({ key: "choices", value: formData });
            request.onsuccess = () => {
                resolve(true);
                window.location.href = `/products/${productId}/preview`;
            };
            request.onerror = () => reject("Failed to save choices to IndexedDB");
        });
    };

    // Render form inputs that use handleChange
    return (
        <input
            type="text"
            value={formData[name] || ''}
            onChange={(e) => handleChange(name, e.target.value)}
        />
        // ... more form elements
    );
}

Any ideas on what would be causing the repeated errors or how I could troubleshoot more?

Highcharts yAxis Categories Not Aligning Closest to Axis Line

I want to adjust the positioning of the yAxis categories. Specifically, I want the first category (“Low”) to start right at the xAxis line without any padding or space before it.

Highcharts.chart("container", {
  chart: {
    type: "line",
  },
  title: {
    text: "Monthly Data",
  },
  xAxis: {},
  yAxis: [{
      opposite: true,
      categories: ["Low", "Meduim", "High"],
      title: {
        text: "Severity",
      },
    },
    {
      title: {
        text: "Measurment",
      },
    },
  ],
  series: [{
      yAxis: 0,
      name: "Severity",
      data: [0, 1, 0, 1, 0, 0, 0, 1, 1],
    },
    {
      yAxis: 1,
      name: "Measurment",
      data: [0, 5, 20, 5, 2, 5, 1],
    },
  ],
  tooltip: {
    shared: true,
    valueSuffix: "",
  },
})
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>

<div id="container" style="height: 300px; margin-top: 1em"></div>
<button id="button">Export chart</button>

How to locally test javascript that contains classes that require secure context

On Mac, I am trying to test some website javascript that involves AudioWorkletProcessor.

Apparently this class is “only available in a secure context.”

I’m assuming this means that the browser running the javascript that contains it must believe it is secure (https) with a valid certificate.

I am testing using firebase serve which makes the site available at localhost:5000 but it doesn’t use or offer https.

As far as I understand my options are:

  1. Use ngrok to create an https tunnel to localhost:5000

Cannot, because it is a paid feature and I don’t want to get into that.

  1. Use http-server like this:

    openssl req -nodes -new -x509 -keyout server.key -out server.cert

    http-server -S -C server.cert -K server.key -p 5000 ./public

… but this does not work because the cert is not valid, so we would need add the bad cert to my keychain which I also don’t like.

Is there some other way to test javascript that uses classes that require a secure context? Maybe some kind of fake/test browser??

Thanks.

Javascript in NextJS – How To Structure?

Hoping someone can help! I’m building a nextJS website and wanting to incorporate some javascript. I want this javascript to run each time a user navigates to a separate page.

Let’s say I want to log something to the console each time.

I’ve written a script here using React. I believe I have to use useEffect?

import React, { useEffect } from 'react'

const Alerter = () => {
  useEffect(() => {
    console.log("Page Rendered !!");
  }, [])
}

export default Alerter

Then, do I have to import that on each individual page.js, and then also run it? Such as the below


import buttonStyles from '../components/global/button.module.css'

//Scripts
import Alerter from '../scripts/runAlert'

export default function LoginPage() {
  return (
    <div>
      <form>
        <button className={buttonStyles.button} formAction={login}>Log in</button>
      </form>
      <Alerter />
    </div>
  )
}

Is there a cleaner way?

App not opening in react-native on click of notification

I am using React Native Notifee for displaying notifications and encountering an issue where the app does not open upon clicking a notification.

This problem occurs in two specific scenarios:

When the app is in the background.
When the app is in the quit state.
In both cases, the notification is successfully received. However, clicking on the notification causes it to simply disappear without launching the app.

This is my index.js code

 /**
 * @format
 */
import {AppRegistry} from 'react-native';
import 'react-native-get-random-values';
import 'react-native-url-polyfill/auto';

import {ReadableStream} from 'web-streams-polyfill';

import notifee, {AndroidImportance, AndroidStyle, EventType} from '@notifee/react-native';
import messaging from '@react-native-firebase/messaging';

import App from './App';
import {name as appName} from './app.json';

globalThis.ReadableStream = ReadableStream;
// Register background handler

const displayNotification = async remoteMessage => {
  
};

messaging().setBackgroundMessageHandler(async remoteMessage => {
  console.log('Message handled in the background! na', remoteMessage);
  displayNotification(remoteMessage);
});

notifee.onBackgroundEvent(async ({type, detail}) => {
  if (type === EventType.ACTION_PRESS) {
    console.log('Notification clicked in background new:', detail);
    global.notificationData = detail;
  }
});


messaging()
  .getInitialNotification()
  .then(remoteMessage => {
    if (remoteMessage) {
      console.log('Notification clicked in quit state:', remoteMessage);
      global.notificationData = remoteMessage.data;
    }
  });

AppRegistry.registerComponent(appName, () => App);

Now using global.notificationData, I am using this data for navigation to specific screen.

Is it possible to sync data in background React Native?

I’m struggling with a functionality in my app since few weeks.

I will explain my project ; I have a react native app, that connect multiples user. A user can create an event, like a meeting, and the other user get a notification. The event is added in the native calendar of the user who created the meeting (let’s call him user 1), and I want to add it also in the user who is invited to the meeting (let’s call him user 2). My functionality to sync events in the native calendar for the user 2 is working fine, when the user open the app, or the app state change. But I want to sync the native calendar of user 2 even if he not open the app, like in background.

So for that, I’ve two solution in my mind. The best one is the notifications. So when the user 1 create a meeting, user 2 always get a notification and my idea is when the notification is shown, I can sync the calendar. So for notifications, I use firebase, and the notifications are shown in background, but my code is not executed. The problem is that I’ve some error with my code running background messages. My error say that I run multiple HeadlessTask with the id ReactNativeFirebaseMessagingHeadlessTask. I don’t know why I get this error, but i still have the background notification, but not with the console.log(). So I give up this idea with the notifications.

Here is my code to register background notifications :

import * as React from 'react';
import { useState, useEffect } from 'react';

import { API_KEY, PROJECT_ID, STORAGE_BUCKET, MESSAGING_SENDER_ID, APP_ID } from '@env';

import firebase from '@react-native-firebase/app';
import messaging from '@react-native-firebase/messaging';
import { AppRegistry } from 'react-native';

import { syncCalendarEventId } from '../utils/calendarSync';

const register = async () => {
    const firebaseConfig = {
      apiKey: `${API_KEY}`,
      projectId: `${PROJECT_ID}`,
      storageBucket: `${STORAGE_BUCKET}`,
      messagingSenderId: `${MESSAGING_SENDER_ID}`,
      appId: `${APP_ID}`,
      // databaseURL: '...',
      // authDomain: '...',
    };

    firebase
    .initializeApp(firebaseConfig)
    .then(() => {
        registerBackgroundMessage();
    })
    .catch(error => {
    });
};

export async function initializeNotifications() {
    await register();

    if (!firebase.apps.length) {
        register();
    } else {
        registerBackgroundMessage();
    }
}

// Request user permission for notifications
export async function requestUserPermission() {
    const authStatus = await messaging().requestPermission();
    const enabled =
        authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
        authStatus === messaging.AuthorizationStatus.PROVISIONAL;

    if (enabled) {
        const token = await messaging().getToken();
        return token;
    }
}

// Register background handler
const registerBackgroundMessage = () => {
    console.log("bg")
    if(Platform.OS === 'ios'){
        messaging().setBackgroundMessageHandler(async remoteMessage => {
            console.log('Notification reçue en fond ! : ', remoteMessage);
            if(remoteMessage.data && remoteMessage.data.sync_required == 1){
                syncCalendarEventId();
            }
        });
    } else if(Platform.OS === 'android'){
        const headlessNotificationHandler = async (remoteMessage) => {
            console.log('Notification reçue en fond ! : ', remoteMessage);
            // Ajoutez ici toute logique que vous souhaitez traiter en arrière-plan
        };
        
        // Enregistrez la tâche headless
        AppRegistry.registerHeadlessTask(
            'ReactNativeFirebaseMessagingHeadlessTask', 
            () => headlessNotificationHandler
        );
    }
};

The second idea I get (but the worst I think) is to try syncing the event every 30 minutes or every hour. I try to do that with the react-native-background-fetch library, but still not working. I don’t know why, but my code is not running event after 20 or 25 minutes. Here is my code for this library :

  useEffect(() => {
    const configureBackgroundFetch = async () => {
      console.log("configure bg");
      BackgroundFetch.configure(
        {
          minimumFetchInterval: 15,
          stopOnTerminate: false,
          startOnBoot: true,
        },
        async (taskId) => {
          console.log("sync")
          syncCalendarEventId();
          console.log(`Tâche de fetch avec ID ${taskId} exécutée`);
          BackgroundFetch.finish(taskId);
        },
        (error) => {
          console.error('Erreur de configuration BackgroundFetch:', error);
        }
      );
      
      console.log("fetch start");
      BackgroundFetch.start();
      console.log("fetch started");
    };

    configureBackgroundFetch();

  }, []);

For information, the useEffect is in my App.js file. And for the background fetch library, I already install it properly I think.

  • I checked background fetch, background precessing, and background notifications in xcode
  • I updated the file Info.plist with the code below :
    <key>UIBackgroundModes</key>
    <array>
        <string>remote-notification</string>
        <string>fetch</string>
        <string>processing</string>
    </array>

So my question is : Is it possible to create a function like a calendar sync in background, or I just let the sync when the user opens my app ?

Thank you for your precious help 🙂

Why won’t console.log run in if statement

I’m using supabase to authenticate users. I’m trying to return a message to the console if it fails however I can’t get the console.log to work. I know the function is working because I can get it to redirect if there’s an error, but I want to return the message as well

'use server'

import { revalidatePath } from 'next/cache'
import { redirect } from 'next/navigation'

import { createClient } from '../../utils/supabase/server'

export async function login() {
  const supabase = await createClient()

  const { data, error } = await supabase.auth.signInAnonymously()

  if (error) {
    console.log(error)
    // redirect('/anonlogin')
  } else {
    revalidatePath('/', 'layout')
    redirect('/')
  }
}

Updating data ot attribute using a lambda in jQuery

I have the following code:

let value = $(this).data('value');
value = System.decrypt(value, key);
$(this).data('value', value);

I’d like it to support chaining:

$(this)
    .data('value', (value) => System.decrypt(value, key))
    .css(…)
    .prop(…);

But as far as I see, jQuery doesn’t have a lambda version of .data(). Is there a simple way to achieve this, or I should write a plugin?

I can’t get the red triangle to fix on bottom with same size

I wrote this code for a flag “NZ REDPEAK FLAG”, I have the two black and blue triangles done. But this red triangle is supposed to be an isosceles triangle, congruent to the empty space in the center but smaller and the base (different length side) to be fixed on the bottom.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NZ REDPEAK FLAG</title>
<style>
    .flag-base {
        height: 400px;
        width: 600px;
        position: relative;
    }

    .blue-part {
        height: 0px;
        width: 0px;
        position: absolute;
        left: 300px;
        border-right: 300px solid blue;
        border-bottom: 400px solid transparent;
    }

    .black-part { 
        height: 0px;
        width: 0px;
        position: absolute;
        border-left: 300px solid black;
        border-bottom: 400px solid transparent;
    }

    .red-part {
        height: 0;
        width: 0;
        border-right: 250px solid transparent;
        border-left: 250px solid transparent;
        border-bottom: 300px solid red;
        margin-left: auto;
        margin-right: auto;
    }
 </style>
 </head>
 <body>
 <div class="flag-base">
    <div class="blue-part"></div>
    <div class="black-part"></div>
    <div class="red-part"></div>
 </div>
 </body>
 </html>

Maybe because the triangles dont have height or width, is why it gets distorted when I set position to relative. I got the two right angle triangles on the left and right, where the base is the top of div and height are on the left and right respectively. Causing the hypotenuses of both making an empty space of isosceles triangle. After which I tried making a triangle with same angles as the space but smaller, to be centered on the bottom. But I got the triangle, just can’t seem to get it to stay on bottom.

Goal:

enter image description here

React state is not updating 2d array

I’m building a React application that asks the user for an input, and if correct (enter “3”), we render a 10×10 grid of buttons, each tied to a click handler.

Code sandbox url

When any button is clicked, it should print to the console the internal representation of the 2d grid array, ie , the state value of grid.

enter image description here

Here is the basic code:

The Grid component, which takes a 2d grid array, and creates a button array. Each cell is { onClick: (...) }

const Grid = ({ grid }) =>
  grid.flat().map((cell, index) => (
    <button key={index} onClick={() => cell.onClick(index)}>
      {index}
    </button>
  ));

Here is the Input component, which uses setInput from parent

const Input = ({ setInput }) => {
  const [_input, _setInput] = React.useState("");
  return (
    <div>
      <input onChange={(e) => _setInput(e.target.value || "")} />
      <button onClick={() => setInput(_input)}>Play</button>
    </div>
  );
};

Here is the main App component. It renders the Input, and based on a useEffect hook, if the input is valid (its 3), it updates the valid state, and also should create the grid state.

const App = () => {
  const [valid, setValid] = React.useState(false);
  const [grid, setGrid] = React.useState([]);
  const [input, setInput] = React.useState(null);

  const reveal = () => {
    console.log("grid is ", grid);
  };

  const createGrid = () => {
    if (input !== "3") return [];

    const arr = Array.from({ length: 10 }, () =>
      Array.from({ length: 10 }, () => ({
        onClick: () => reveal(),
      }))
    );
    console.log("setting grid to ", [...arr]);
    setGrid([...arr]);
  };

  React.useEffect(() => {
    setValid(input == "3");
    createGrid();
  }, [input]);

  return (
    <div>
      <Input setInput={setInput} />
      {valid && <Grid grid={grid} />}
    </div>
  );
};

export default App;

I can see that when the component is initially rendered, and we enter “3”, the grid state does get set, but when I click on a button, the reveal function prints that the grid state is []. Why is this happening?

enter image description here