Can I use extendscript to import ‘previewed’ audio files into Adobe Premiere Pro?

I have built a simple media player panel for Adobe Premiere Pro that allows users to preview audio files from within the application, rather than trawling through windows explorer and opening in VLC.

I’m using the simple HTML player to play the files back, but what I’d like to do is have the option to import the selected track directly into Premiere.

Everything works as it should, apart from the Import function. When the button is clicked nothing happens, not even the error messages.

Any thoughts?

My current code looks like this:

`const ingestButton = document.createElement('button');
ingestButton.textContent = 'Import';
ingestButton.addEventListener('click', async () => {
  try {
    const file = await entry.getFile(); 
    const filePath = file.path || file.name; 

    if (typeof CSInterface !== 'undefined') {
      const csInterface = new CSInterface();

      csInterface.evalScript(`importFileToPremiere`, (response) => {
        if (response === "success") {
          console.log("File imported successfully into Premiere.");
        } else {
          console.error("Failed to import file into Premiere:", response);
        }
      });
    } else {
      console.warn("CSInterface is not available. Are you running this in a CEP panel?");
    }
  } catch (error) {
    console.error("Error processing file for Premiere:", error);
  }`

with an accompanying .jsx added to the main Premiere.jsx file:

`function importFileToPremiere(filePath) {
        try {
        // Create a File object for the file to be imported
        var fileObj = new File(filePath);

        if (!fileObj.exists) {
            return "The specified file does not exist: " + filePath;
        }

        // Get the active Premiere project
        var project = app.project;

        if (!project) {
            return "No active project found in Adobe Premiere.";
        }

        // Use ImportOptions to import the file
        var importOptions = new ImportOptions(fileObj);

        if (importOptions.canImportAs(ImportAsType.CLIP)) {
            importOptions.importAs = ImportAsType.CLIP;
        }

        project.importMedia([fileObj.fsName], true, project.getInsertionBin(), false);
        return "success";
    } catch (e) {
        return "Error importing file into Premiere: " + e.message;
    }`

Why do OnKeydown and OnClick work differently in my code?

I am creating a Dino game where jumping is triggered by either clicking (anywhere) or pressing space.
I added a last phase (4) where the same keys will still trigger the same function jump(), but then jump() will do something different in phase 4 (there will be something like hitting a boss).

When I use clicks, my code works as intended, but when I use spaces, in the last phase 4, jump() does not perform as intended: it does update isJumping I see the animation I put work, but it doesn’t update the other state variables: craMessage and craLife.

Why don’t Onclick and Onkeypress function the same in this case? What did I do wrong in my code?

Thank you in advance.

// src/App.js
import React, { useState, useEffect } from "react";
import Dino from "./components/Dino";
import Obstacle from "./components/Obstacle";
import Ground from "./components/Ground";

const App = () => {
  const [isJumping, setIsJumping] = useState(false);
  const [obstaclePosition, setObstaclePosition] = useState(1000);
  const [score, setScore] = useState(0);
  const [scoreMessage, setScoreMessage] = useState("");
  const [phase, setPhase] = useState(1);
  const [lastPhase, setLastPhase] = useState(1);
  const [craLife, setCraLife] = useState(1000);
  const [craMessage, setCraMessage] = useState("");
  const [gameOver, setGameOver] = useState(false);

  // Handle jump (both keyboard and mouse)
  const jump = () => {
    if (!isJumping) {
      setIsJumping(true);
      setTimeout(() => setIsJumping(false), 500); // Dino stays in the air for 300ms
      if (phase === 4) {
        //used same variable isJumping for hitting logic
        let hit = Math.floor(Math.random() * 150 + 200); //Boss in phase 4 will be hit between 200 and 350
        setCraMessage(`-${hit}`);
        setCraLife(craLife - hit);
        setTimeout(() => setCraMessage(""), 1000);
      }
    }
  };

  // Function to handle phase changes and difficulty scaling
  const adjustPhase = (score) => {
    if (score >= 10) {
      if (lastPhase !== 4) {
        // Show message only if phase changes
        setPhase(4); // Phase 4: New game components
        setScoreMessage("Phase 4: New Challenges!"); // Show message for Phase 4
        setTimeout(() => setScoreMessage(""), 1000); // Remove message after 1 second
        setLastPhase(4); // Update lastPhase
      }
    } else if (score >= 4) {
      if (lastPhase !== 3) {
        // Show message only if phase changes
        setPhase(3); // Phase 3: Increase speed & randomize obstacle interval
        setScoreMessage("Phase 3: Speeding Up & More Obstacles!"); // Show message for Phase 3
        setTimeout(() => setScoreMessage(""), 1000); // Remove message after 1 second
        setLastPhase(3); // Update lastPhase
      }
    } else if (score >= 2) {
      if (lastPhase !== 2) {
        // Show message only if phase changes
        setPhase(2); // Phase 2: Increase speed
        setScoreMessage("Phase 2: Speed Boost!"); // Show message for Phase 2
        setTimeout(() => setScoreMessage(""), 1000); // Remove message after 1 second
        setLastPhase(2); // Update lastPhase
      }
    } else {
      if (lastPhase !== 1) {
        // Show message only if phase changes
        setPhase(1); // Phase 1: Initial state
        setScoreMessage("Phase 1: Get Ready!"); // Show message for Phase 1
        setTimeout(() => setScoreMessage(""), 1000); // Remove message after 1 second
        setLastPhase(1); // Update lastPhase
      }
    }
  };

  // Move obstacle with changing intervals based on phase
  useEffect(() => {
    if (gameOver || phase === 4) return;

    const baseInterval = 50; // Base interval (500ms for phase 1)
    const speedIncreasePerPhase = 10; // Increase speed per phase (reduce interval by 100ms)
    let interval = baseInterval - (phase - 1) * speedIncreasePerPhase; // Decrease interval as phase increases

    const updateObstaclePosition = () => {
      setObstaclePosition((prev) => {
        if (prev <= -50) {
          setScore((prevScore) => prevScore + 1);
          if (phase === 3) {
            return Math.random() * 500 + 500; // Randomize position between 800 and 1500
          }
          // In other phases, keep the position fixed
          return 1000;
        }
        return prev - 10;
      });
    };

    const intervalId = setInterval(updateObstaclePosition, interval);

    return () => clearInterval(intervalId);
  }, [gameOver, phase]);

  useEffect(() => {
    if (gameOver || phase !== 4 || craLife <= 0) return;
    setScore((prevScore) => prevScore + 10);
  }, [gameOver, phase, craLife]);

  useEffect(() => {
    adjustPhase(score); // Update phase based on score
  }, [score]);

  useEffect(() => {
    // Ensure craLife doesn't go below 0
    if (craLife <= 0) {
      setCraLife(0); // Stop craLife from going negative
      setScoreMessage("You win!");
      setTimeout(() => setGameOver(true), 1000);
      return;
    }

    if (obstaclePosition < 60 && obstaclePosition > 10 && !isJumping) {
      if (phase === 4) {
        if (craLife <= 0) {
          setScoreMessage("You win!"); // If craLife is 0 or less, show win message
          setGameOver(true); // End the game
          return;
        }
      }
      setGameOver(true); // Game ends in other phases regardless of craLife
    }
  }, [obstaclePosition, isJumping, phase, craLife]);

  useEffect(() => {
    const handleKeyDown = (e) => {
      console.log("Keydown triggered:", e.key);
      if (e.key === " ") {
        jump();
      }
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, []);

  return (
    <div
      style={{
        position: "relative",
        height: "300px",
        width: "100%",
        overflow: "hidden",
        background: "#ddd",
      }}
      onClick={jump} // Allow mouse clicks to trigger jumping
    >
      {gameOver ? (
        <h1 style={{ textAlign: "center" }}>Game Over! Score: {score}</h1>
      ) : (
        <>
          <Dino phase={phase} isJumping={isJumping} />
          <Obstacle
            phase={phase}
            position={obstaclePosition}
            isLifted={isJumping}
          />
          <Ground />
          <div style={{ position: "absolute", top: "10px", left: "10px" }}>
            Score: {score}
          </div>
          <div> Message: {scoreMessage} </div>

          {phase === 4 && (
            <>
              <div> Cra Life: {craLife} </div>
              <div
                style={{
                  position: "absolute",
                  top: "50px",
                  right: "80px",
                  color: "red",
                }}
              >
                {craMessage}
              </div>
            </>
          )}
        </>
      )}
    </div>
  );
};

export default App;

How to provide the package.json version to an electron app? (tsc options?)

I would like to access the version of my application defined in package.json while running an electron application.

I am building my application this way:

  • First compiling with npm run build which is basically only running tsc
  • Then creating the application with electron-builder --win

I tried the “usual” way of accessing process.env.npm_package_version, that works when I am running locally because it’s run by npm, but if I run the actual electron build, this variable is undefined. Likewise, I found things like const { version } = require('./package.json'); but I think package.json is not even included in the electron build.

So basically, what I need is, at the npm run build step, to access process.env.npm_package_version at that time and store it so that it is going to be available in electron.

I have another project where I use vite and I was able to accomplish something like that with the following code in vite.config.mts:

    define: {
      APP_VERSION: JSON.stringify(process.env.npm_package_version),
    },

Can I do something similar with the Typescript compiler? Am I overcomplexifying things?

How to create a ‘dynamic` data-attribute, a HTML element with a unique id, in Astro and pass the variables from server to client

In my Astro app I need to pass a variable from the server (frontmatter) to the client.

Like the documentation describe there are two options.

  • use data-attribute
  • use defineVars

As far as I can see now, I can’t use both of them?

I need


type Props = {
  uuid: string;
};

const { uuid } = Astro.props;
---

<div class="my-feature" data-uuid={uuid} id="my-feature"></div>

<script is:inline src={import.meta.env.MY_SCRIPT}></script>

<script>
  import { MyFeatureHelper } from '@/scripts/my-helper';

  let myFeature;

  const ref = document.getElementById('my-feature');
  const uuid = ref?.dataset.uuid;
  console.log(uuid);

  myFeature = new MyFeatureHelper(ref as HTMLDivElement, {
    uuid: uuid,
  });

  myFeaturer.build();

</script>

Above is working fine, it’s passing correct the variable uuid from the server to the client.

I need a dynamic data-attribute id like:

---
const randomId = Math.random().toString(36).slice(2, 11);
---
<div class="my-feature" data-uuid={uuid} id="my-feature" data-id={randomId}></div>

I need the ref: const ref = document.getElementById('my-feature'); to pass the variables from server to client. So how do I pass data-id attribute and its value now?

I can’t use Astro defineVars here, because in that script tag I am also importing a module (import { MyFeatureHelper } from '@/scripts/my-helper';).

Is there a solution for this?

Sending users to correct OAuth login page for multitenant client – Microsoft OneDrive FilePicker 7.2

I am trying to set up OneDrive FilePicker 7.2 in a way that when users choose to connect their personal accounts, they are taken to signup.live.com(or something similar) where you can only sign in with personal accounts) and to login.microsoftonline.com/organizations(or something similar) where they can only use a work/school account when they choose to connect their work account.

I know I can do the first part by setting the endpointHint to api.onedrive.com but then the token returned is for that endpoint and I need to use graph to fetch user details. So that is not an option for me. For the second part, I could not figure out a way at all.

One possible solution could be to use two different applications, one allowing authentication with personal accounts only and the other with work accounts but this creates other problems.

Has anyone encountered this/knows a way around ?

Multi-tenancy Setup

Instability of the components in the Matter JS engine

I am simulating a snooker game via JavaScript using the P5 and Matter JS, I’m almost done but I’m having trouble with some of the ball behaviors.

I added all the balls to the engine world in Matter JS and they work properly, but when a colored ball enters a slot it has to go back to its original place.

I did this by making the holes static, and using the ‘collisionStart’ event I would return the ball to its place when a colored ball collided with a hole.

The problem is that the ball returns to its place correctly but it still retains some movement which makes it move.

Matter.Events.on(engine, 'collisionStart', (event) => {

        const pairs = event.pairs;

        pairs.forEach((pair) => {

            const bodyA = pair.bodyA;
            const bodyB = pair.bodyB;

            for (let i = 0; i < this.coloredBallsInfo.length; i++) {

                if ((bodyA.label === this.coloredBallsInfo[i][0] && bodyB.label === 'pocket') ||
                    (bodyB.label === this.coloredBallsInfo[i][0] && bodyA.label === 'pocket')) {

                    Matter.Body.setPosition(this.coloredBalls[i], { x:this.coloredBallsInfo[i][1],
                                                                    y:this.coloredBallsInfo[i][2] });

                    Matter.Body.setSpeed(this.coloredBalls[i], 0);

                    Matter.Body.setVelocity(this.coloredBalls[i], { x: 0, y: 0 });

                    Matter.Body.setAngularVelocity(this.coloredBalls[i], 0); 
                }
            }
        });
    });

I added all the functions that reset the speed and acceleration to zero but there is still some slight movement.

Uncaught TypeError: Cannot read properties of null (reading ‘clientWidth’)

            <div id=" sliderContainer" class="w-10/12 overflow-hidden">
                <ul id="slider" class="flex w-full">
                    <li class=" p-5">
                        <div class="border rounded-lg p-5">
                            <img th:src="@{'/images/logo.png'}" class="h-28 w-full rounded-lg object-cover" alt="">
                            <h2 class="mt-2 font-bold text-center text-gray-700">Some BigHeadline</h2>

                            <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Tempore maxime illo, incidunt

                            </p>
                            <button class="mt-3 px-6 py-3 rounded-md bg-green-800 text-white">Read More</button>
                        </div>
                    </li>

let sliderContainer = document.getElementById('sliderContainer');
let slider = document.getElementById('slider');
let cards = slider.getElementsByTagName('li');
let elementsToShow = 3;
let sliderContainerWidth = sliderContainer.clientWidth;
let cardWidth = sliderContainerWidth / elementsToShow;
slider.style.width = cards.length * cardWidth + 'px';
for (let index = 0; index < cards.length; index++) {
    const element = cards[index];
    element.style.width = cardWidth + 'px';
}

whenever i am trying to run it is showing cannot read null reference on clienwidth
i have tried adding script to the bottom of the code

UseEffect and SetInterval, creating infinite loop and refreshing the session

I want to keep making my request because whenever I add an item to my cart, the carticon which displays the amount of items in the cart has to update. But this keeps refreshing my session, so when I put this to production you it becomes laggy.
I want to solve this by running it maybe once, and not onclick because the components which could be doing this on click, are just not connected with eachother.

export default function Header({ props }) {
const pollingRef = useRef(0);

const [newItemState, setNewItemState] = useState(0);

    const [itemsState, setItemsState] = useState(props.cart);
    let finalquantity = itemsState.map((item) => item?.quantity || 0);
    // console.log(finalquantity);

    
    const updateCartAmount = async () => {
        try {
            let itemQuantities = itemsState.map((item) => item?.quantity || 0);
            let newItemState = itemQuantities.reduce((acc, sum) => acc + sum, 0);
            console.log(newItemState);

            const response = await axios.get('/cartjson');
            setItemsState(response.data);
            setNewItemState(newItemState);
        } catch (error) {
            console.error('Failed to update cart', error);
        }
    };
    
useEffect(() => {
        pollingRef.current = setInterval(() => {
            updateCartAmount();
            // console.log('polling');
    }, 2000)

    return () => {
        clearInterval(pollingRef.current)
    }
    }, []);

Im using Inertia and i found something about UseRemember but i dont really know if thats something what could solve this. I want to update the quantity but NOT the session tokens

Moleculer micro service rooting not working in case of separate services rooting

when i try ti implement code like that it works:
gateway.service.ts

{
                path: "/api",
                whitelist: [ "**"],
                use: [],
                mergeParams: true,
                authentication: true,
                authorization: true,
                autoAliases: true,
                aliases: {
                    "login": "auth.login",
                },


                bodyParsers: {
                    json: {
                        strict: false,
                        limit: "1MB",
                    },
                    urlencoded: {
                        extended: true,
                        limit: "1MB",
                    },
                },

                
                mappingPolicy: "all", // Available values: "all", "restrict"

                // Enable/disable logging
                logging: true,
            },
 {
                path: "/controller",
                bodyParsers: {
                    json: false,
                    urlencoded: false
                },
                aliases: {
                    "POST /upload": {
                        params: {
                            file: { type: "file", required: true },
                            checkList: { type: "string", default:'' }
                        },
                        type: "multipart",
                        busboyConfig: {
                          limits: {
                            files: 3
                          }
                        },
                        action: "controller.post"
                      }
                },

                busboyConfig: {
                    
                    limits: {
                        files: 3
                    }
                },

                mappingPolicy: "restrict"
            }

but when i separte every rooting for the specific service it not works : like that:

gateway.service.ts

{
                path: "/api",
                whitelist: [ "**"],
                use: [],
                mergeParams: true,
                authentication: true,
                authorization: true,
                autoAliases: true,
                aliases: {
                    "login": "auth.login",
                },


                bodyParsers: {
                    json: {
                        strict: false,
                        limit: "1MB",
                    },
                    urlencoded: {
                        extended: true,
                        limit: "1MB",
                    },
                },

                
                mappingPolicy: "all", // Available values: "all", "restrict"

                // Enable/disable logging
                logging: true,
            },

controller.service.ts
// here it not works but i don’t know why

settings:{
routes:[
{
                path: "/controller",
                bodyParsers: {
                    json: false,
                    urlencoded: false
                },
                aliases: {
                    "POST /upload": {
                        params: {
                            file: { type: "file", required: true },
                            checkList: { type: "string", default:'' }
                        },
                        type: "multipart",
                        busboyConfig: {
                          limits: {
                            files: 3
                          }
                        },
                        action: "controller.post"
                      }
                },

                busboyConfig: {
                    
                    limits: {
                        files: 3
                    }
                },

                mappingPolicy: "restrict"
            }
]
}

i tried to impelement rooting and aliases of every service in it x.service.ts file
it not works when i put every rooting settings in it file , it works only when i put all the settings in the gateway.service.ts file

How to handle select with big number of options in Vue3 using Virtual Scrolling?

I’m using Virtual Scrolling with vue3-virtual-scroll-list to handle 50,000 options (like locations).

The VirtualList component renders only the visible items in the viewport.

The :keeps prop determines how many items are rendered at a time.

:data-sources contains the list of items to render.

LocationItem is a reusable component that renders each item in the list.

The filterLocations method dynamically updates the filteredLocations array based on the search query.

<template>
  <div>
    <input
      v-model="searchQuery"
      @input="filterLocations"
      placeholder="Search locations"
      class="search-input"
    />
    <virtual-list
      :data-key="'id'"
      :data-sources="filteredLocations"
      :data-component="LocationItem"
      :keeps="20"
      tag="div"
      class="virtual-list"
    />
  </div>
</template>

<script>
import { defineComponent } from 'vue';
import VirtualList from "vue3-virtual-scroll-list";

const LocationItem = defineComponent({
  props: {
    data: {
      type: Object, 
      required: true, 
    },
  },
  template: `<div class="list-item">{{ data.name }}</div>`,
});

export default {
  components: { VirtualList },
  data() {
    return {
      locations: Array.from({ length: 50000 }, (_, i) => ({
        id: i + 1,
        name: `Location ${i + 1}`,
      })),
      filteredLocations: [],
      searchQuery: "",
    };
  },
  mounted() {
    this.filteredLocations = this.locations;
  },
  methods: {
    filterLocations() {
      const query = this.searchQuery.toLowerCase();
      this.filteredLocations = this.locations.filter(location =>
        location.name.toLowerCase().includes(query)
      );
    },
  },
};
</script>

<style>
</style>

I get the following warning: Invalid vnode type when creating vnode.

jest not calling inner function as expected

I am currently writing some tests with callbacks, I am trying to get jest to mock the callback without running any intervening code, but am having issues with jest.fn(). The app is built with react if that is relevant.

The origonal is long so I striped it down to this. This code DOES show the issue by its self.
The only difference between the 2 tests is where the call to jest.fn() happens.

// in the real code, this is an import. The issue still shows up with it defined here.
let moduleFunc = jest.fn((func) => {
  console.log('moduleFunc called'); // this is NOT called
  func();
});

test('moduleFunc', () => {
  let myVar = false;

  const innerFunc = () => {
    console.log('innerFunc1 called'); // this is NOT called
    myVar = true;
  };

  moduleFunc(innerFunc);

  expect(moduleFunc).toHaveBeenCalled(); // this passes
  expect(myVar).toBe(true); // this fails
});

test('testFunc', () => {
  let testFunc = jest.fn((func) => {
    console.log('testFunc called'); // this IS called
    func();
  });

  let myVar = false;

  const innerFunc = () => {
    console.log('innerFunc2 called'); // this IS called
    myVar = true;
  };

  testFunc(innerFunc);

  expect(testFunc).toHaveBeenCalled(); // this passes
  expect(myVar).toBe(true); // this passes
});

Why is the inner function only called sometimes, and how do I fix it?

How to handle React Hook Form validation within a custom input component?

I am using React Hook Form to handle form validation in my React project. While everything works fine when using plain elements, I encounter issues when I try to wrap the inputs in a custom component. Specifically, validations such as minLength and maxLength are not being triggered properly. It is always countering the required validation.

Here’s an example of my setup:
Parent Component (Parent.jsx):

import { useForm } from "react-hook-form";
import Input from "./Components/Input.jsx";
import Button from "./Components/Button.jsx";

export default function Parent() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const login = (data) => {
    console.log("Form Data:", data); 
  };

  return (
    <div className="App">
      <div className="container">
        <form onSubmit={handleSubmit(login)}>
          <Input
            type="text"
            name="username"
            {...register("username", {
              required: {
                value: true,
                message: "Username is required",
              },
              minLength: {
                value: 5,
                message: "Too Few Characters",
              },
               maxLength: {
                value: 15,
                message: "username length should not exceed 15",
              },
            })}
          />
          {errors.username && <p className="red">{errors.username.message}</p>}

          <Input
            type="password"
            name="password"
            {...register("password", {
              required: {
                value: true,
                message: "password is required",
              },
              minLength: {
                value: 6,
                message: "Password length should be greater than 6",
              },
              maxLength: {
                value: 15,
                message: "Password length should not exceed 15",
              },
            })}
          />
          {errors.password && <p className="error-red">{errors.password.message}</p>}

          <Button type="submit" />
        </form>
      </div>
    </div>
  );
}

custom Input Component (Input.jsx):

import { forwardRef } from "react";
const Input = forwardRef(function Input(
  { type = "text", name = "", ...props },
  ref
) {
  return (
   <>
      <input
        placeholder=" "
        className="txt-input"
        type={type}
        ref={ref}
        {...props}
      />
      {name && (
        <label className="label-placeholder">
          {name.charAt(0).toUpperCase() + name.slice(1)}
        </label>
      )}
   </>
  );
});

export default Input;

  1. Using forwardRef to forward the ref from React Hook Form to the native .
  2. Passing all props (e.g., onChange, onBlur) from the parent component to the custom component.

Supabase: Error while updating property ‘src of a view managed by: RCTImageView null Value for URI cannot be cast from ReadableNativeMap to String

I am encountering an issue when attempting to render images fetched from Supabase in my React Native application. The error message I receive is:

Error while updating property 'src of a view managed by: RCTImageView, null, Value for URI cannot be cast from ReadableNativeMap to String. 
const loadData = async () => {
    if (!user) return;
  
    try {
      const { data, error } = await supabase
        .from('posts')
        .select('id, description, location, images, created_at')
        .eq('id_user', user.id_user);
  
      if (error) {
        console.error('Error fetching posts:', error);
        return;
      }
  
      console.log('Raw fetched posts data:', data);
  
      if (data && data.length > 0) {

        setPosts(data);
      } else {
        console.log('No posts found in the database.');
      }
    } catch (err) {
      console.error('Unexpected error loading data:', err);
    }
};
{/* Posts Section */}
      {selectedButton === 'posts' && (
        <View style={styles.postsContainer}>
          {posts.map((postItem, index) => (
            <View style={styles.postItem} key={index}>
              <View style={styles.postInfoContainer}>
                <Text style={styles.postInfo}>Me • {formatDate(postItem.date)}</Text>
                <TouchableOpacity onPress={() => toggleMenu(postItem)}>
                  <Icon name="dots-horizontal" size={25} color="black" />
                </TouchableOpacity>
              </View>
              <Text style={styles.postLocation}>
                Located in {postItem.location} • Contact Number #9999999999
              </Text>

              {postItem.description && (
                <Text style={styles.postTitle}>{postItem.description}</Text>
              )}


              {console.log('Post images:', postItem.images)}


              {postItem.images && postItem.images.length > 0 ? (
                <View style={styles.imageContainer}>
                  <TouchableOpacity onPress={() => openImageModal(postItem.images)}>
                    {postItem.images.length === 1 ? (
                      <Image
                        source={{ uri: postItem.images[0] }}
                        style={styles.singleImage}
                        resizeMode="cover"
                        onError={(error) => console.error('Image loading error:', error.nativeEvent.error)}
                      />
                    ) : postItem.images.length === 2 ? (
                      <View style={styles.doubleImageContainer}>
                        {postItem.images.map((image, index) => (
                          <Image
                            key={index}
                            source={{ uri: image }}
                            style={styles.doubleImage}
                            resizeMode="cover"
                          />
                        ))}
                      </View>
                    ) : (
                      <View style={styles.moreImagesContainer}>
                        {postItem.images.slice(0, 3).map((image, index) => (
                          <Image
                            key={index}
                            source={{ uri: image }}
                            style={styles.gridImage}
                            resizeMode="cover"
                          />
                        ))}
                        {postItem.images.length > 3 && (
                          <Text style={styles.imageCountText}>
                            + {postItem.images.length - 3}
                          </Text>
                        )}
                      </View>
                    )}
                  </TouchableOpacity>
                </View>
              ) : (
                <Text style={styles.noImagesText}>No images available</Text>
              )}

              Inline Edit/Delete Options
              {selectedPost && selectedPost.id === postItem.id && (
                <View style={styles.inlineMenuContainer}>
                
                  {/* Edit Button */}
                  <TouchableOpacity onPress={handleEdit} style={styles.inlineMenuItem}>
                    <Icon name="pencil" size={20} color="black" /> 
                    <Text style={styles.menuText}>Edit</Text>
                  </TouchableOpacity>
                  
                  {/* Delete Button */}
                  <TouchableOpacity onPress={handleDelete} style={styles.inlineMenuItem}>
                    <Icon name="trash-can" size={20} color="black" /> 
                    <Text style={styles.menuText}>Delete</Text>
                  </TouchableOpacity>

                </View>
              )}
            </View>
          ))}
        </View>
      )}

I attempted to fetch posts from a Supabase database and render them, including associated images.I expected the images, stored as URIs in the postItem.images array, to display correctly in the Image component.