Undefined while getting session in api, next-auth

I’m trying to create a menu. If the user role is “1000”, i want to add “AddNewUser” item to menu, otherwise this section shouldn’t be appear. I can get session on my dashboard.jsx so normally session is correct, but i can’t get it in my api. How can i fix that?

Here is my session information coming from dashboard:
enter image description here

Here is terminal:

enter image description here

nextauth:

import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import sql from "mssql";
import db from "../../../../../lib/db";
import bcrypt from 'bcryptjs';

const handler = NextAuth({
  secret: process.env.NEXTAUTH_SECRET,
  pages: {
    signIn: '/auth/login-1',
  },
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        email: { label: 'Email', type: 'email', placeholder: '[email protected]' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        try {
          const pool = await sql.connect(db);
          const sqlRequest = pool.request();

          const userQuery = `
            SELECT id, first_name, last_name, email, password, role_id, location_id FROM [inventory].[user] WHERE email = @Email
          `;

          sqlRequest.input('Email', sql.VarChar, credentials.email);
          const result = await sqlRequest.query(userQuery);
          const user = result.recordset[0];

          if (user) {
            const isValidPassword = bcrypt.compareSync(credentials.password, user.password);

            if (isValidPassword) {
              console.log("User Role Assigned:", user.role_id);
              return {
                id: user.id,
                name: `${user.first_name} ${user.last_name}`,
                email: user.email,
                role: user.role_id,
                location: user.location_id
              };
            }
          }

          return null;
        } catch (error) {
          console.error('An error occurred during authorization:', error);
          return null;
        }
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.role = user.role;
        token.location = user.location;
      }
      return token;
    },
    async session({ session, token }) {
      if (token) {
        session.user.role = token.role;
        session.user.location = token.location;
      }
      return session;
    },
  },
});


export { handler, handler as GET, handler as POST };

api:

import { NextResponse } from "next/server";
import { getMenus } from "./menu-items";
import { getServerSession } from "next-auth/next"

export async function GET(req, { params }) {
  const session = await getServerSession({ req });

  if (!session || !session.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const user = session.user;
  console.log("role:", user.role);

  const menus = await getMenus(params?.locale ?? "en-US", user.role);
  return NextResponse.json(menus, { status: 200 });
}

menu-item:

import { getDictionary } from "@app/[lang]/dictionaries";

export async function getMenus(locale, userRole) {
  const dictionary = await getDictionary(locale);
  const { sidebar } = dictionary;

  const baseMenu = [
    {
      path: `/${locale}/dashboards/dashboard`,
      label: sidebar.menuItem.dashboard,
      icon: "dashboard",
    },
    {
      path: `/${locale}/dashboards/misc`,
      label: sidebar.menuItem.addNewMachine,
      icon: "editor",
    },
    {
      path: `/${locale}/dashboards/addThirdPartyData`,
      label: sidebar.menuItem.addData,
      collapsible: true,
      icon: "editor",
    },
    {
      path: `/${locale}/dashboards/listing`,
      label: sidebar.menuItem.machineList,
      icon: "listing",
    },
    {
      path: `/${locale}/modules/maps/clustering`,
      label: sidebar.menu.maps,
      icon: "map",
    },
  ];

  console.log(userRole);

  if (userRole === 1000) {
    console.log("Role check passed, adding addNewUser to menu"); 
    baseMenu.push({
      path: `/${locale}/dashboards/addNewUser`,
      label: sidebar.menuItem.addNewUser,
      icon: "user",
    });
  } else {
    console.log("Role check failed, addNewUser not added to menu"); 
  }

  return [
    {
      label: sidebar.menu.home,
      children: baseMenu,
    },
  ];

 
}

How can I read from a database or array, and show results in a datatable?

I’ve got a sample datatable to display two entries.

The Javascript file used, and what holds the 2 entries is:

var data = [
[
        "Tiger Nixon (3)",
        "System Architect",
        "Edinburgh",
        "5421",
        "2011/04/25",
        "$3,120"
    ],
[
        "Garrett Winters (4)",
        "Director",
        "Edinburgh",
        "8422",
        "2011/07/25",
        "$5,300"
    ]
]
//And the table initialisation
$('#example').DataTable( {
data: data
} );

I would like to ask/enquire, how can I read from a database or array, and show it’s content?
As I’m new to datatables, I don’t know how to insert a database or array.

Could anyone please help?
Thank You.

Ordinally, I tried to insert a for and next loop, before modifying it to ready an array. But it just listed the whole table in the html file, which has about 50 entries.

For the basic for/next loop, in the javascript file, I tried:-

var data = [
[
        "Tiger Nixon (3)",
        "System Architect",
        "Edinburgh",
        "5421",
        "2011/04/25",
        "$3,120"
    ],
[
        "Garrett Winters (4)",
        "Director",
        "Edinburgh",
        "8422",
        "2011/07/25",
        "$5,300"
    ],
for ($q=0; $q=50; $q++)
        "header line: ".$q,
        "description: ".$q,
        "Edinburgh (w)",
        "8422 (x)",
        "2011/07/25 (y)",
        "$5,300 (z)"
    ]
]
//And the table initialisation
$('#example').DataTable( {
data: data
 

access github api from bowser

I am building a web application that should use github to store content and build websites. The last few days I tried to understand all the neccassery parts of the github api and also complete the oauth process, so I have a user token on my server. This is also nessaccery to store some information of the user on my database, but for most stuff the server would only be a proxy, so I would prefer to do request from the user web browser directly to github to avoid uneccassery jumps and load time.

As I could find out, the user access token is valid for about 8h, so it wouldn’t be smart to store it in the browser, but I couldn’t find any information on how to get a token like a JWT to use it in the browser. The only thing I found was to create an app JWT, but this does not have access to everything and if something has changed in github it should be mapped to the user and not to the app.

Is there a secure way to make requests to github on behalf of the user?

Cypress Framework Project Setup: How to setup the cypress framework in Visual studio code

Cypress Framework Project Setup:

  1. Install the Node.js : https://nodejs.org/en/download/prebuilt-installer [You can select the OS type from drop-down]
  2. IDE-Install the Visual Studio Code: https://code.visualstudio.com/download
  3. Create a Workspace on you local drive. E.g.-D:WorkspaceCypress-project
  4. Open Visual Studio Code
  5. From Menu-Open Terminal->New Terminal
  6. Run the following 3 commands in the same sequence:
  1. D:WorkspaceCypress-project> npm init
  2. D:WorkspaceCypress-project> npm install cypress –save-dev
  3. D:WorkspaceCypress-project> npx cypress open
  1. npm init-Used to create the package.json file
  2. npm install cypress –save-dev -It will create the node_module which holds all the required dependencies.
  3. npx cypress open -It opens the Cypress window and provide option to run the suite/testcase file.
  1. create new spec -When Cypress Window open then select the “create new spec” and create the spec. It will create the Cypress folder structure in “Visual Studio Code” IDE.

Now, all setup are done. You are good to go and proceed with code writing. “Happy Learning”!!

enter image description here

assistance with Javascript code for a game

I am working on a non-graded class activity and I am stumped. My variation on Two truths and a lie is that I will present 3 statements (one is a lie) and the user will try to spot the lie. I am new to Javascript/HTML and I am unsure how to randomly pull two questions from the truth array and one from the lie array. I will then need to shuffle the answers. If anyone could help or point me in the direction of tutorials, I would appreciate it.

This is my psuedo code

<!doctype html>

const True-questions=[ “My favorite color is purple”, “I am an avid reader”, “I love to craft”, “I am a bit of a nerd”, “I am the youngest of 9”, “I am a Gemini”];

const False-questions=[“I hate animals”, “I like to eat seafood”, “I wanted to be a Geologist”, “I was born in KY”];

Two truths and a Lie

Hello! Here is a game to use to get to know me just a bit. I have a list of three questions above and it is your job to spot the lie. Simply enter the number 1, 2, or 3 and the game will display a message “Yes!”, if you are correct and “Sorry, not this time”, if you are wrong. It will also inquire if you would like to try again. May the odds be in your favor.

/* I have more code but it isn’t formatted to be read as code so the field rejects it */

How to send the fetched URL when piping request?

I’ve set up a small proxy using Node and ExpressJS. Basically, the user sends a request to http://localhost:3000?url=https://example.org and the proxy fetches the specified URL as a request with the axios module. The user chooses the method, body and headers to be used by placing them in the request to the proxy.

Here is the code:

const express = require('express');
const axios = require('axios');
import { Request as ExpressRequest, Response as ExpressResponse } from 'express';

const VERBOSE = true;

const FORBIDDEN_REQ_HEADERS = [
    "host", "x-forwarded-for", "x-forwarded-host", "x-forwarded-proto", "x-forwarded-port", "forwarded"
];

const FORBIDDEN_RES_HEADERS = [
    "content-length", "content-encoding", "transfer-encoding", "content-security-policy-report-only", "content-security-policy"
];

const DEFAULT_RES_HEADERS = {
    "access-control-allow-origin": "*",
    "access-control-allow-headers": "*",
    "access-control-expose-headers": "*",
    "access-control-allow-methods": "*",
    "access-control-allow-credentials": "true"
};

const app = express();

app.all('/', async (req: ExpressRequest, res: ExpressResponse) => {
    const url = new URL(req.url ? req.url : '', "https://" + req.headers.host).searchParams.get("url") || "";

    // test whether the URL provided as a query is valid or not
    try {
        new URL(url);
    } catch (err: any) {
        console.error(err.message);
        res.writeHead(400).end(JSON.stringify({ error: 'Invalid URL' }));
        return;
    }

    // construction of the headers object with allowed request headers
    const reqHeaders = Object.fromEntries(
        Object.entries(req.headers)
            .filter(([key]) => !FORBIDDEN_REQ_HEADERS.includes(key.toLowerCase()))
            .map(([key, value]) => [key, Array.isArray(value) ? value.join(', ') : value ?? ''])
    );

    // construction of body as a buffer
    const body = req.method === "GET" || req.method === "HEAD" ? undefined : await new Promise<Buffer>((resolve, reject) => {
        const chunks: Uint8Array[] = [];
        req.on('data', chunk => chunks.push(chunk));
        req.on('end', () => resolve(Buffer.concat(chunks)));
        req.on('error', reject);
    });

    if (VERBOSE) {
        console.log(`n==> Sending ${req.method} request to ${url}`);
        console.log(`> with headers ${JSON.stringify(reqHeaders)}`);
        if (body) {
            try {
                console.log(`> with body ${JSON.stringify(JSON.parse(body.toString()))}`);
            } catch (err) {
                console.log(`> with body ${body.toString()}`);
            }
        }
    }

    try {
        const proxyResponse = await axios({
            url,
            method: req.method,
            headers: reqHeaders,
            data: body,
            responseType: 'stream'
        });

        // construction of response headers object with allowed response headers
        const resHeaders: Record<string, string> = {};
        for (const [key, value] of Object.entries(proxyResponse.headers)) {
            if (!FORBIDDEN_RES_HEADERS.includes(key.toLowerCase())) {
                resHeaders[key.toLowerCase()] = Array.isArray(value) ? value.join(', ') : value as string;
            }
        }

        // headers like access-control-allow-origin must not be set by the proxy request
        Object.assign(resHeaders, DEFAULT_RES_HEADERS);

        if (VERBOSE) {
            console.log('n==> Response received:');
            console.log(`> with url ${proxyResponse.request.res.responseUrl}`)
            console.log(`> with status ${proxyResponse.status}`);
            console.log(`> with headers ${JSON.stringify(resHeaders)}`);
        }

        res.writeHead(proxyResponse.status, resHeaders);
        proxyResponse.data.pipe(res);

    } catch (error: any) {
        console.error(error);
        res.writeHead(500).end(JSON.stringify({ error: error.message }));
    }
});

const PORT = 3000;
app.listen(PORT, () => {
    if (VERBOSE) console.log(`Proxy server is running on port ${PORT}!`);
});

module.exports = app;

When the client requests the proxy from an external script using fetch, for example, Response.url is set to http://localhost:3000?url=https://example.org, which is normal behavior, and we could simply use Response.url.replace('http://localhost:3000?url=', '') to retrieve the correct URL.

However, this doesn’t work with redirects: i.e., when the user has sent a request that requires one or more redirects, it returns the original URL to the client instead of the final URL that can be accessed at proxyResponse.request.res.responseUrl.

Here’s an example to illustrate what I’ve explained above. Let’s say the user wants to fetch https://httpbin.org/redirect-to?url=https://example.org, which causes a redirect to https://example.org. Using the proxy, he will have to request the following URL: http://localhost:3000?url=https://example.org.

(async function () {
    const proxy = 'http://localhost:3000';

    const res = await fetch(`${proxy}?url=https://httpbin.org/redirect-to?url=https://example.org`, {
        method: 'GET',
        redirect: "follow"
    });

    console.log(res.url);
     // wanted https://example.org
     // got http://localhost:3000?url=https://httpbin.org/redirect-to?url=https://example.org
})();

Is there a way to make my proxy send a response whose URL is the final URL (e.g. https://example.org) instead of the URL requested by the user (e.g. http://localhost:3000?url=https://example.org)?

setInterval not being executed at all Node JS (not a duplicate) with puppeteer

It’s been the third day of debugging my program in one specific spot, with no luck. I could not find an answer nowhere on forums or charGPT. So, I am trying to set an interval for a specific check on a page with puppeteer (to be precise, on whether captcha is solved and token is present in DOM). For this, I set up an interval, that checks if captcha is solved every 7 seconds. If it is solved it starts a request interval to the API of this website, and if not, it clears that interval and effectively waits until captcha is solved. However, the program is not even evaluating what’s inside the callback for setInterval, it simply skips it and stalls indefinitely. Here are some functions from the module and the function where it happens.

let checkIntervalId = null; 
let captchaIntervalId = null; 
const checkInterval = 1200; 
const captchaInterval = 7000; 
let captchaToken = null;


async function asyncCaptchaInterval(date, page) {
    console.log('page and date inside captcha set interval');
    captchaToken = await getCaptchaToken(page);
    if (captchaToken) {
        startRequestInterval(date);
        console.log('request interval started');
    } else {
        if(checkIntervalId){
            clearInterval(checkIntervalId);
            checkIntervalId = null;
        }
    }
}




function syncCaptchaInterval(date, page) {
    console.log('inside synccaptchainterval');
    asyncCaptchaInterval(date, page).then(()=> console.log('async captcha interval resolved meaning that it did work'))
}



function startCaptchaCheckInterval (date, page) {
    console.log('page and date inside captcha start check interval', page, date);
    console.log('jsut about to set an interval for captcha');
    captchaIntervalId = setInterval(() => { // 
        syncCaptchaInterval(date, page);
    }, captchaInterval);
    console.log('set an interval for captcha'); // the program stalls after logging this, I think it just returns undefined to where this module was called from 
}




export function startCatching (date, page) { // This is what is called from the main program

    startCaptchaCheckInterval(date, page);
} 

Last 3 lines of logs:
page and date inside captcha start check interval CDP Page, my_date
jsut about to set an interval for captcha
set an interval for captcha

so it doesnt even go inside the callback of set interval, it effectively skips it and logs nothing from the inside.

At first I thought it might be because setInterval does not accept async callbacks. My first version was: captchaIntervalId = setInterval(async () => { logic }, interval). Then I read it somewhere that setInterval does not accept promises, so i rewrote it with sync callback calling sync function calling async function without await. Wasn’t of any help either. It’s been the third day of madness…

Browsers try to open nonexistent file when running JavaScript

I try to open a local HTML file (say C:/…/code/index.html), that has a script tag linking to a separate file called script.js.
It all works fine and dandy until I try to run a function declared in said file. And then my browser freaks out and opens the URL C:/.../code/0, or with some other number.

I tried other browsers, but neither Chrome nor Edge worked. The culprit I think is a for loop in my function.

for (let location in key_locations)

When I remove the ‘let’, it does the opening of a nonexistant file. (i.e. C:/…/code/0).
The number might be correlated with the output of the function but it is not what the function returns.

Need to update a state variable using setValue in axios which is initialized as a object

Hi I am learning React

Please go through my code, How do I set the state of a get response in axios?

const [state,setState] = useState({
bookingId: '', // This will contain booking ID from Input Field
bookingData: null, // This will contain booking data received from axios
infoMessage: ''
})

const onSubmit = (event) => {
event.preventDefault();
axios.get(url+state.bookingId).then((response.data)=>{
console.log(response.data);
setState({bookingData: response.data});
setState({infoMessage: ''});
console.log(state)
}).then((error)=>{
setState({bookingData: ''});
setState({infoMessage: `${state.bookingId} Not Found`});
})
})
<tr>
<td>{state.bookingData.id}</td>
<td>{state.bookingData.emailId}</td>
</tr>

I referred this thread How to set state of response from axios in react

But I couldn’t find a solution, still I am unable to get the response data inside state value

ReactJS regex doesn’t work on a splitted string

So basically i wanted to validate a name from text first taken from .txt file and then splitted.
Text looks somewhat like this:

Paris
Museum
1
...

and the code looks like this:

const handleValidation = (data:string) => {
    let pattern = /^[a-zA-Z0-9]{1,10}$/;
    let title = data.split('n')[0];

    console.log(title);  // returns "Paris" and is a string
    console.log(pattern.test(title));  // returns false
    console.log(pattern.test("Paris"));  // returns true
}

But when instead of title I input “Paris” then it works for some reason, even though they should act the same.
Anyone knows what could be cause of this problem?

Discordjs Interaction.followUp() not working

I’m making a discord bot command which returns members of a role. The interaction.deferReply() works fine but the interaction.followUp(...) doesn’t seem to work.
The interaction is stuck on ‘— Bot is thinking…’, and no errors messages are thrown.

I tried debugging my code using console.log to give me an idea of where my code is crashing, but it tells me everything’s fine.

So I have no idea what’s wrong

Heres the code,

const { SlashCommandBuilder, EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder, MessageButton } = require('@discordjs/builders')
const Data = require('../../data/data.json') // Data storage (Not used in this command)

Command Data

module.exports = {
    data: new SlashCommandBuilder()
        .setName('inrole')
        .setDescription('Retrieve members of a role.')
        .addRoleOption(option => 
            option.setName("role")
                .setDescription("Which role members to retrieve.")
                .setRequired(true)
        )
        .addStringOption(option =>
            option.setName("private")
                .setDescription("Send a private or public message?")
                .addChoices(
                    { name: 'Public', value: '1' },
                    { name: 'Private', value: '2' },)
        )
        .addIntegerOption(option =>
            option.setName("offset")
                .setDescription("Page offset, default is 0. Each page contains 10 users max.")
                .setMinValue(0)
        ),

Command Definition

    async execute(interaction, client) { // Function that defines the command
        await interaction.deferReply()
        let guild = interaction.guild;
        await guild.members.fetch()

        var role = guild.roles.cache.get(interaction.options.getRole('role').id)

        var p = interaction.options.getString("private")
        if (p == '2') p = true; else p = false

        var n = interaction.options.getInteger("offset") ?? 0


        var mList = role.members.map(x => '<@' + x.id + '> ||' + x.username + '||').slice(n*10,n*10+10).join('n')

        if ((mList === "") && n > 0) {
            mList = "Page is empty."
        } else if (mList === "") {
            mList = "No one has this role."
        }

        let len = role.members.map(x => '<@' + x.id + '> ||' + x.username + '||').slice(n*10,n*10+10).length
        mList = '-# Page: ' + (Number(n) + 1) + ' | Showing ' + len + ' member' + (len != 1 ? 's' : '') + 'n** **n' + mList + "n** **"

        var embed = new EmbedBuilder()
            .setTitle('Users in the `' + role.name + '` role')
            .setDescription(mList)
            .setFooter({text: 'Total Members: ' + role.members.size})
        
        await interaction.followUp({embeds: ,ephemeral: p})
   }
}

Any ideas? Thanks.

React Keyckloak Always 401 response when fetching Token after Client authentitifcation is switched to ON

I’m using React and trying to integrate Keycloak with it using ReactKeycloakWeb and Keycloak JS. I added the following configuration, which usually works fine:

const keycloakConfig = {
  realm: "webapp", // Realm as configured in Keycloak
  url: "http://localhost:8080",
  clientId: "webapp-client", // Client ID as configured in the realm in Keycloak
};

const keycloak = new Keycloak(keycloakConfig);

const App = () => {
  return (
    <ErrorBoundary>
      <ReactKeycloakProvider
        authClient={keycloak}
        initOptions={{
          onLoad: "login-required",
        }}
      >
        <ThemeProvider theme={mdTheme}>
          <CssBaseline />
          <Root />
          <Toaster />
        </ThemeProvider>
      </ReactKeycloakProvider>
    </ErrorBoundary>
  );
};

export default App;

I created a user manually in Keycloak, and I was able to successfully connect to the application. However, I have many users, and I cannot create each user manually every time. So, I created users via the Keycloak API.

The problem is that to access the Keycloak API, I have to switch client authentication to ON, like this:
enter image description here

After enabling this, a new window appears in Keycloak for adding a secret key under “Credentials”:
enter image description here

However, after adding this parameter, I am unable to connect to my app via React.

enter image description here
Even if I change the Keycloak web configuration like this:

const keycloakConfig = {
  realm: "webapp", // Realm as configured in Keycloak
  url: "http://localhost:8080",
  clientId: "webapp-client", // Client ID as configured in the realm in Keycloak
  credentials: {
    secret: 'hM6oswdupEMFkRzkBuhOfTPhC64s8G9R', // Only include this for confidential clients
  },
};

The same error appears, and the ReactKeycloakWeb package does not pass the client secret in the payload:

enter image description here

Is there a solution, or does the ReactKeycloakWeb package not work when client authentication is ON?

Laravel translation not working with javascript variable

I worked on a Laravel project, to get the content of a div with Ajax call and Jquery, I did like that in blade template:

    results[k].items.map((result,index) => (
                                                $(".kf_opponents_wrap2").append(

                                    '<div class="kf_opponents_wrap">
                                    <h6 class="kf_h4">
                                        <em>'+((result.fixture.status.elapsed == null ||   result.fixture.status.elapsed == 90) ? getMatchTime(result.fixture.timestamp) : result.fixture.status.elapsed)+'</em>
                                    </h6>
                                        <div class="kf_opponents_dec">
                                            <span><img src="'+result.teams.home.logo+'" alt=""></span>
                                            <div class="text">
                                                <h6><a href="#">'+result.teams.home.name+'</a></h6>
                                            </div>

    ......
    )

Until now everything is ok and the div is correctly displayed using Ajax call, the next issue is how to make translation inside append and using javascript variable and not php variable inside the Laravel function echo __('.....');

<a href="#">echo __('+result.teams.home.name+');</a> // I know is wrong because is confusion between client side and server side.

I tried to use https://github.com/rmariuzzo/Laravel-JS-Localization but is not working for me at all.

My question is how to use Laravel translation inside javascript using javascript variable inside or another way to use php or get the translation from DB? Any idea?

The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission

We have a project built with react-native and compiled for pwa using react-native-web.
we’re getting an error when trying to play an audio:
The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
here is part of the code for playing the said audio, it’s inside our audio controller class:

let playingAudio!: HTMLAudioElement;
let playtime = 0;
async play(path: string) {
    if (!store) throw NO_STORE_ERROR;
    const res = await get(path, store);
    this.playingAudio = new Audio(res);
    document.body.appendChild(this.playingAudio);
    this.playingAudio.currentTime = this.playtime;
    await this.playingAudio.play();
    this.playingAudio.addEventListener('ended', () => {
        this.stop();
    });
}

according to our Sentry records it only happened in IOS Safari. I found out when I searched about the error that it could happen if the code is run without user interaction (like press). but I literally call the play function on onPress.
here is the component we’re using this:

export const VoiceItem = memo(
    (
        props: FileItemProps & {style?: StyleProp<ViewStyle>; onVoicePlay?(): void},
    ) => {
        const {
            itemType,
            time,
            hasMoreGap,
            style,
            onVoicePlay,
            deletePress,
            chatStatus,
        } = props;
        const controller = useMemo(() => new AudioController(), []);
        const pathRef = useRef<string>();

        const [state, setState] = useState<AudioPlayChangeEventType>({
            playState: PlayStatus.Stopped,
            playTime: 0,
            duration: 0,
        });

        useEffect(() => {
            controller.addPlayListener(setState);
        }, []);

        const getIcon = () => {
            if (canceled || isError) return 'Download';
            else if (loading) return 'Close';
            else if (state.playState === PlayStatus.Playing) return 'Pause';
            else return 'Play';
        };

        const handlePress = () => {
            switch (state.playState) {
                case PlayStatus.Paused:
                    controller.resume();
                    break;
                case PlayStatus.Playing:
                    controller.pause();
                    break;
                case PlayStatus.Stopped:
                    if (pathRef.current) {
                        controller.play(pathRef.current);
                        onVoicePlay?.();
                    }
                    break;
            }
        };

        return (
            <Pressable
                onLongPress={() => {
                    /*logic for actions bottom sheet*/
                }}
            >
                <Progress
                    max={100}
                    value={progress}
                    size={50}
                    hide={!loading || canceled}
                >
                    <Pressable
                        style={[
                            styles.itemButton,
                            {backgroundColor: tokens.PRIMARY.REGULAR},
                        ]}
                        onPress={handlePress}
                    >
                        <Icon name={getIcon()} color='white' size={18} />
                    </Pressable>
                </Progress>
                <Slider
                    {...SLIDER_PROPS}
                />
            </Pressable>
        );
    },
);