Issues with Image Cropping and AJAX Submission in iOS Safari

I’m encountering some issues with my web project, particularly when using iOS Safari on certain iPhone models. The project involves cropping an image selected by the user, embedding it into a template, and then submitting it to a server via AJAX. Here are the problems I’m facing:

Problem 1: Image Cropping

Sometimes, after cropping the image using the Cropper.js library, the cropped image is not loaded onto the canvas. This issue appears inconsistently and is specific to iOS Safari.

Problem 2: AJAX Submission

After successful submission of the form, everything is saved on the server as expected. However, the AJAX error block is executed without any error response from the server. When I print the error, it’s undefined. This issue also occurs sporadically on iOS Safari.

Why is the array empty? Ionic Angular [duplicate]

  async init() {
    const timeArray = await this.getTimestampFromFirestore();
    console.log('Time Array: ', timeArray);
    this.showHighlightedDates(timeArray);
  }

  async getTimestampFromFirestore() {
    const userz = await this.storageService.get('username');
    const userProfileCollection = collection(this.firestore, 'timestamps');
    const filteredWorkersCollection = query(
      userProfileCollection,
      where('name', '==', userz)
    );

    this.timestampInterface = collectionData(filteredWorkersCollection).pipe(
      map((data) => data.map((x) => x))
    ) as Observable<TimestampsInterfaceFirestore[]>;

    const timeArray: TimestampsInterfaceFirestore[] = [];
    this.highlightedDates.length = 0;

    this.timestampInterface.forEach((data) => {
      data.forEach((element) => {
        timeArray.push({
          name: element.name,
          date: element.date,
          time: element.time,
          type: element.type,
        });
      });
    });

    return timeArray;
  }

  showHighlightedDates(times: TimestampsInterfaceFirestore[]) {
    console.log('Array: ', times);

    for (const i of times) {
      console.log(i);
    }

    for (let i = 0; i < times.length; i++) {
      console.log(times[i]);   
    }
  }

How is it possible that the I can’t iterate through the array?

console.log(‘Time Array: ‘, timeArray); gives me the array with length of 8
console.log(‘Array: ‘, times); is the same.

But after that I can’t iterate throught this array. Why is this?
If I do: array.length it gives me 0 even it is not 0.

EDIT:

I changed the getTimestampsFromFirestore to this and then it worked:

async getTimestampFromFirestore(): Promise<TimestampsInterfaceFirestore[]> {
    const userz = await this.storageService.get('username');
    const userProfileCollection = collection(this.firestore, 'timestamps');
    const filteredWorkersCollection = query(
      userProfileCollection,
      where('name', '==', userz)
    );

    try {
      const data = await getDocs(filteredWorkersCollection);
      const timeArray: TimestampsInterfaceFirestore[] = [];

      data.forEach((doc) => {
        const element = doc.data() as TimestampsInterfaceFirestore;
        timeArray.push({
          name: element.name,
          date: element.date,
          time: element.time,
          type: element.type,
        });
      });

      return timeArray;
    } catch (error) {
      console.error('Error fetching data from Firestore:', error);
      throw error;
    }
  }```

Chrome extension file sort

i’m working on extension for chrome and i want to ask why it can not work.
Here’s a js script:

chrome.downloads.onDeterminingFilename.addListener(function (item, suggest) {
var extension = item.filename.split('.').pop().toLowerCase();
var folder = 'X:\Images';  // Set the full path to the Images folder

if (extension === 'jpg' || extension === 'jpeg' || extension === 'png' || extension === 'gif') {
    // No need to change folder as it's already set to X:Images
} else if (extension === 'mp3' || extension === 'wav' || extension === 'flac') {
    folder = 'X:\Audio'; // Set the full path to the Audio folder
} else if (extension === 'pdf' || extension === 'docx' || extension === 'txt') {
    folder = 'X:\Documents'; // Set the full path to the Documents folder
}

suggest({ filename: folder + '\' + item.filename }); // Use backslashes to create the full file path

});

I’s a simple file sorting extension and when i was testing it image loaded to the default folder of browser downloads. I’m new to js and want to know what you think about this.

I’ve tried to ask chatgpt or search for some info on internet but i don’t know how to ask correct

1 API Call, producing 2 different results with different array lengths. Why?

I am calling an API using axios , if I check what response data comes back I notice some discrepancies, and I do not know why this happens.

The first log is logging response.data
The second log is logging (at the bottom response.data.hourly.

As you can see the when logging just the data the hourly propery has 143 items in the array.

When logging the hourly directly there is 168 items in the array.

enter image description here

Does anyone know why this is happenin?

I am expecting to see the two arrays to be the same.

Error: [Error: ENOENT: no such file or directory, open ‘./1695556319341.mp3’]

I’m trying to convert an mp4 file to an mp3 file and then directly upload it to Firebase storage without saving it locally in my machine, How can I do that currently I’m getting an error when I try to do that the error is “Error: [Error: ENOENT: no such file or directory, open ‘./1695556319341.mp3’]” How can i fix this issue with my Node.js code and make things work?

import { initializeApp } from "firebase/app";
import { getStorage, ref, getDownloadURL, uploadBytesResumable } from "firebase/storage";
import serviceAccount from '../firebase/serviceAccountKey';
import { path as ffmpegPath } from '@ffmpeg-installer/ffmpeg';
import ffmpeg from 'fluent-ffmpeg';
import { readFile, unlink } from 'fs/promises';

initializeApp(serviceAccount);
ffmpeg.setFfmpegPath(ffmpegPath);

async function convertMP4ToMP3AndUploadToFirebase(inputPath: any, firebaseStoragePath: any) {
    const date = Date.now();
    const outputPath = `./${date}.mp3`;

    try {
        await ffmpeg(inputPath)
            .output(outputPath)
            .audioCodec('libmp3lame')
            .format('mp3')
            .run();

        const storage = getStorage();
        const storageRef = ref(storage, firebaseStoragePath);

        const fileBuffer = await readFile(outputPath);
        const metadata = { contentType: 'audio/mpeg' };
        const uploadTask = uploadBytesResumable(storageRef, fileBuffer, metadata);
        const snapshot = await uploadTask;
        const downloadURL = await getDownloadURL(snapshot.ref);
        await unlink(outputPath);

        console.log('MP4 file converted to MP3 and uploaded to Firebase Storage successfully!');
        console.log('Download URL:', downloadURL);
    } catch (error) {
        console.error('Error:', error);
    }
}

const inputPath = './video.mp4';
const date = Date.now();
const firebaseStoragePath = `./${date}.mp3`;

convertMP4ToMP3AndUploadToFirebase(inputPath, firebaseStoragePath);

how Do I make a new line in React Like a terminal

What am I using

React, CSS modules

Hi There I am making a Portfolio Terminal website

So, I want to make a feature where the user creates a new Line like the terminal does so, when you press enter in the terminal it creates a new line like this: Terminal New Line Image

So, as I was saying I want this same functionality but there is a problem I face where when I press enter and then try to do another command it doesn’t do the command

I hope I made this clear

here is my JSX code:

import { useEffect, useRef, useState } from "react";
import styles from "../css/TerminalPage.module.css";

function TerminalPage() {
  const [textInput, setTextInput] = useState("");
  const [helpValues, setHelpValues] = useState("");
  const [newLine, setNewLine] = useState("");
  const inputRef = useRef(null);
  const help = {
    about: "My Name Is Ammar Ehab and I am a Full-Stack Developer",
    social: {
      title: "YouTube",
      url: "www.youtube.com",
    },
    projects: {
      title: "Projects",
      url: "www.yourprojectsurl.com", // Replace with your actual projects URL
    },
  };

  useEffect(() => {
    function handleKeyDown(event) {
      if (event.ctrlKey && event.keyCode === 76) {
        event.preventDefault();
        setHelpValues("");
      }
    }

    function handleClick() {
      inputRef.current.focus();
    }
    // Add the event listener when the component mounts
    window.addEventListener("keydown", handleKeyDown);
    window.addEventListener("click", handleClick);

    // Remove the event listener when the component unmounts
    return () => {
      window.removeEventListener("keydown", handleKeyDown);
      window.removeEventListener("click", handleClick);
    };
  }, []);

  function renderSocialLink() {
    const socialTitle = help.social.title;
    const socialUrl = help.social.url;

    return (
      <div className={styles.gridContainer}>
        <div className={styles.gridItem}>
          <span>{socialTitle}</span>
        </div>
        <div className={styles.gridItem}>
          <span className={styles.gridItemUrl}>{socialUrl}</span>
        </div>
      </div>
    );
  }
  function checkHelpCommand() {
    const trimmedInput = textInput.trim().toLowerCase();

    if (trimmedInput === "help") {
      const commands = Object.keys(help);
      setHelpValues(
        commands.map((command, index) => <span key={index}>{command}</span>)
      );
    } else if (trimmedInput === "about") {
      setHelpValues(help.about);
    } else if (trimmedInput === "social") {
      setHelpValues(renderSocialLink());
    } else if (trimmedInput === "clear") {
      setHelpValues("");
    } else if (trimmedInput === "") {
      setNewLine("newLine");
    } else {
      setHelpValues(
        `command not found ${trimmedInput}. Type "help" for more information`
      );
    }
  }

  function handleSubmit(e) {
    e.preventDefault();
    checkHelpCommand();
    setTextInput("");
  }

  return (
    <div className={styles.terminalContainer}>
      <form onSubmit={(e) => handleSubmit(e)}>
        <div className={styles.terminalInputContainer}>
          <div>
            <span className={styles.terminalKeyword}>
              guest<span>@</span>ammar.com:<span>~$</span>
            </span>
          </div>
          <input
            value={textInput}
            onChange={(e) => setTextInput(e.target.value)}
            ref={inputRef}
          />
        </div>

        <div>
          <div>
            <div className={styles.textareaOutput}>
              {Array.isArray(helpValues)
                ? helpValues.map((element, index) => (
                    <div key={index} className={styles.commandBlock}>
                      {element}
                    </div>
                  ))
                : helpValues}
            </div>
          </div>
          <div style={{ display: "block" }}>
            {newLine === "newLine" ? (
              <div className={styles.terminalInputContainer}>
                <div>
                  <span className={styles.terminalKeyword}>
                    guest<span>@</span>ammar.com:<span>~$</span>
                  </span>
                </div>
                <input
                  value={textInput}
                  onChange={(e) => setTextInput(e.target.value)}
                  ref={inputRef}
                />
              </div>
            ) : null}
          </div>
        </div>
      </form>
    </div>
  );
}

export default TerminalPage;

and here are my styles if needed:

:root {
  --main-text-color: #a16b56;
  --text-input-color: #73abad;
  --main-color: #e2d7a7;
  --text-url-hover: #1a4645;
  --text-url-color: #f8bc24;
  --user-text-color: rgb(81, 153, 117);
}

.terminalContainer {
  margin: 10px 0 0 10px;
}

.terminalContainer * {
  color: var(--text-color);
}

.terminalContainer .input-container {
  position: relative;
}

.terminalContainer .input-container::before {
  content: "visitor@Ammar:$ ~ ";
  color: white;
  background-color: #333;
  padding: 5px;
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
}

.terminalContainer input {
  border: none;
  outline: none;
  resize: none;
  background-color: var(--main-color);
  color: var(--text-input-color);
  /* Add a text-shadow for the glow effect */
  text-shadow: 0 0 5px rgba(115, 171, 173, 0.5); /* Adjust the values as needed */
}

.terminalContainer input:hover {
  border: none;
  outline: none;
  cursor: text;
}

.terminalContainer textarea:hover,
.terminalContainer input:hover {
  border: none;
  outline: none;
  cursor: text;
}

.terminalInputContainer {
  display: flex;
  align-items: center;
}

.terminalInputContainer div .terminalKeyword {
  letter-spacing: -1px;
  font-size: large;
}

.terminalKeyword {
  color: var(--user-text-color);
}

.terminalKeyword span {
  color: var(--main-text-color);
}

.terminalInputContainer input {
  width: 100%;
  margin: 0 0 0 5px;
  height: 100px;
  font-size: 1.2rem;
  color: var(--text-input-color);
}

.textareaOutput {
  background-color: var(--main-color);
  resize: none;
  border: none;
  font-size: 1.1rem;
}

.gridContainer {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-top: 10px;
  width: 500px;
}

.gridItemUrl {
  transition: all 0.2s ease;
  width: fit-content;
  color: var(--text-url-color);
  padding: 5px;
  transform: translateY(-5px);
  cursor: pointer;
}

.gridItemUrl:hover {
  background-color: var(--text-url-hover);
}

/* Grid items within the container */
.gridItem {
  background-color: var(--main-color);
  padding: 10px;
  border-radius: 5px;
  color: var(--main-text-color);
}

.gridItem span {
  display: block; /* Display URLs on a new line */
  font-size: 1rem;
  font-weight: bold;
}

.commandBlock {
  background-color: var(--main-color);
  padding: 10px;
  border-radius: 5px;
  margin-bottom: 5px;
  color: var(--text-input-color);
  font-size: 1rem;
  font-weight: bold;
  text-shadow: 0 0 5px rgba(115, 171, 173, 0.5),
    0 0 10px rgba(115, 171, 173, 0.5), 0 0 15px rgba(115, 171, 173, 0.5);
}

How to use regular javascript Ajax call JSF backend controller’s method

As everyone may known. Regular PrimeFaces-13 Ajax framework not support page level event such as “unload” or “beforeunload” when user is leaving current page in browser.

my javascript as:

<h:head>
  <title>Customer Details View</title>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
  <script type="text/javascript">
    $(window).unload(function () {
        $.ajax({
            type: 'GET',
            async: false,
            url: '#{customerSWController.leavingCustomerView()}'
        });
    });
  </script>
</h:head>

in my xhtml file

I’m trying to use header javascript to catch page “unload” event and then call my JSF backend bean method such as: #{backendController.leaveViewPage()} that I did it in p:ajax tag.

but unfortunately, I never get it works.

Any one have idea, please let me know.

A function which can return closest element based on a cursor x, y value from the domNodes

I am using react-dnd package in Next.js for my dnd project. In the canDrop function I want a javascript function which can return me some value based on some parameter. Here is the problem:

Inputs: function will have 3 parameters. dragX, dragY and childrenArray. dragX and dragY are the co-ordinates of x and y position of the mouse when an element is being dragged and childrenArray I am making it from domNodes, which can be very deeply nested.

Outputs : I want 3 outputs.

  1. If cursor is on a childNode return that node or if not return null.
  2. closestNode according to the cursor position from left or right or bottom or top
  3. closestCorner of the colosestNode ( corners are left, right , bottom and top )

RegExp no whitespace allow

i want to check if string includes whitespace with RegExp but i want to use regexp pattern as a string, so:

new RegExp('^S+$').test("test")
new RegExp('^S+$').test("te st")

both gives false.

How to grab text that user typing on any webpage inside any message box and replace that text with some other text

Like grammerly I want to grab the area whee user is typing and want to grab the text and replace it with some other text. Due to diffrence arrangments of elemnts on various website I am not able to find a single way to grab that text. Is there any way to grab that text and to replace it with some other text?

I want a JS code that I can write in my chrome extension that can help me to grab text from any webpage.

How to check if a union type parameter (T | [string, T][]) is of type T and not [string, T][]?

I want to write a function that gets a parameter of type T | [string, T][] and checks if the parameter is of type T and not of type [string, T][].
example:

const example: null | [string, null][] = [['addr1', null], ['addr2', null] ] 
it's type is not null (null is T)

T is not class, it is usually string, number, string[]….

My first implementation was:

function isTypeT<T>(response: T | [string,T][], singleResType: new () => T): boolean {
  return response instanceof singleResType;
}

but it requires that the type T must have a constructor.
(typeof function will not help because :

typeof string[] == typeof [string, string[]][] == object

)

I also thought about this:

function isTypeT<T>(response: T | [string, T][], singleRes: T): boolean {
    if (Array.isArray(response) && Array.isArray(singleRes)) {
        return isTypeT(response[0], singleRes[0]);
    } 
     else if (typeof response !== typeof singleRes || Array.isArray(response) || Array.isArray(singleRes)) {
        return false;
    }
    return true;
}

but passing a sample object every time to check the function doesn’t seem like a good typescript implementation.

So, I would appreciate it if anyone could suggest another way to check the types.

How to display input like “0.052” in calculator display?

I’m building calculator from the odin project. I have problem with addEventListener for buttons elements.
I have to handle situation when user input something like 0.53. I don’t know what condition i have to use in if statement for that to work.
Here is a link to my code:
Codepen link

I tried this code first but it didn’t work.

buttons.forEach((btn) =>
  btn.addEventListener("click", function (e) {
    displayValue = e.target.innerText;
    if (display.innerText.charAt(0) == 0 && display.innerText.charAt(1) == 0) {
      display.innerText = +[display.innerText].shift().toString();
      // display.innerText = display.innerText.replace(/^0+/, "");
    } else if (
      display.innerText.charAt(0) == 0 &&
      display.innerText.charAt(1) >= 1
    ) {
      display.innerText = +[display.innerText].shift().toString();
    }
    display.innerText = display.innerText + displayValue;
  })
);

Invoke Program/Script from JavaScript using Custom Protocol

I need the ability to invoke either a compiled program (e.g. C++) or a Script from JavaScript where it will be possible both to pass to and receive from the Program/Script large chunks of data (more specific, a rather long JSON) whose size could exceed hundreds of KBs.

I already have a working Custome Protocol that invokes a Batch File but this option is not suitable since there are limitations to the size of data that can be conveyed to the script and the script can only return an integer value.

So far, I was unable to find any reference that would provide a clear answer to this question. The easiest solution (for me) would be to user a PowerShell script but I saw some posts stating that such script is activated from the cmd and hence would display the same limitations as a Batch script. Also, I infer from those posts that the same might happen if I use a compiled program (i.e. being activated from cmd).

I’d very much appreciate suggestions related to the above alternative approaches and, if non of them would work, a different approach that may provide a reliable solution.

NOTE: I’m not asking for code but for a feasible direction to engage into.

Thanks.

Could you please tell me what’s wrong this javascript code

This code is supposed to calculate the sum, substract, multiply, divide at the same time when the user types in x and y but it’s showing Nan

function perform(x, y) {
  x = prompt("enter first no. ")
  y = prompt(" enter second no. ")

  function sum(x, y) {
    console.log(parseInt(x + y));
  }

  sum();

  function minus(x, y) {
    console.log(parseInt(x - y));
  }

  minus();

  function multiply(x, y) {
    console.log(parseInt(x * y));
  }

  multiply();
  
  function divide(x, y) {
    console.log(parseInt(x / y));
  }

  divide();
}

Pixelated image animation/transition when they enter viewport with lazy loading

In short, I’d like my images to appear pixelated and transition to fully rendered versions after a small delay. The only example I can find right now is the one below, which does it great…

Example: https://aino.agency/

This is the desired effect. So pixelated, then a small animation/transition as the image appears rendered.

I have two code examples, both use the approach of having a smaller 64×64 image that is stretched then uses image-rendering: pixelated to give the initial pixelated effect.

The 1st example, which is embed in the post, uses JS to swap out the image when loaded but this happens too fast and also loads all the images even when they’re not in the viewport. So I need a way for that to happen and also enforce the transition. This is for a creative site so it’s ok to delay the image slight for the effect as it’s not a ‘fun’ landing page.

In the 2nd, CodePen version below, I thought I could display a 2nd image over the top of the loading="lazy" images. Then when the image is loaded, add a class to the parent div which in turn could run a simple CSS animations to transition to the fully loaded image – which I’ve currently got set on :hover to demo.

https://codepen.io/moy/pen/QWzQPbG

Really open to peoples ideas on this and the best approach, as I know it’s not too conventional!

document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.srcset = lazyImage.dataset.srcset;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to event handlers here
  }
});
img {
  display: block;
  width: 100%;
  min-width: 100%;
}

.grid {
  display: flex;
  flex-wrap: wrap;
  column-gap: 8px;
  row-gap: 8px;
  margin: auto;
  max-width: 1000px;
}

.grid__item {
  position: relative;
  image-rendering: pixelated;
  width: calc(50% - 4px);
}
<div class="grid">
  <div class="grid__item">
    <img class="lazy" src="https://haddawaynshite.com/lazy-images/bruce--small.jpg" data-src="https://haddawaynshite.com/lazy-images/bruce.jpg" data-srcset="https://haddawaynshite.com/lazy-images/bruce.jpg 2x, https://haddawaynshite.com/lazy-images/bruce.jpg 1x" alt="ALT TEXT">
  </div>
  <div class="grid__item">
    <img class="lazy" src="https://haddawaynshite.com/lazy-images/grace--small.jpg" data-src="https://haddawaynshite.com/lazy-images/grace.jpg" data-srcset="https://haddawaynshite.com/lazy-images/grace.jpg 2x, https://haddawaynshite.com/lazy-images/grace.jpg 1x" alt="ALT TEXT">
  </div>
  <div class="grid__item">
    <img class="lazy" src="https://haddawaynshite.com/lazy-images/nirvana--small.jpg" data-src="https://haddawaynshite.com/lazy-images/nirvana.jpg" data-srcset="https://haddawaynshite.com/lazy-images/nirvana.jpg 2x, https://haddawaynshite.com/lazy-images/nirvana.jpg 1x" alt="ALT TEXT">
  </div>
  <div class="grid__item">
    <img class="lazy" src="https://haddawaynshite.com/lazy-images/nwa--small.jpg" data-src="https://haddawaynshite.com/lazy-images/nwa.jpg" data-srcset="https://haddawaynshite.com/lazy-images/nwa.jpg 2x, https://haddawaynshite.com/lazy-images/nwa.jpg 1x" alt="ALT TEXT">
  </div>
  <div class="grid__item">
    <img class="lazy" src="https://haddawaynshite.com/lazy-images/zep--small.jpg" data-src="https://haddawaynshite.com/lazy-images/zep.jpg" data-srcset="https://haddawaynshite.com/lazy-images/zep.jpg 2x, https://haddawaynshite.com/lazy-images/zep.jpg 1x" alt="ALT TEXT">
  </div>
  <div class="grid__item">
    <img class="lazy" src="https://haddawaynshite.com/lazy-images/beatles--small.jpg" data-src="https://haddawaynshite.com/lazy-images/beatles.jpg" data-srcset="https://haddawaynshite.com/lazy-images/beatles.jpg 2x, https://haddawaynshite.com/lazy-images/beatles.jpg 1x" alt="ALT TEXT">
  </div>
</div>