JavaScript – check date input for complete date

I have the following code:

<input class="submit-form-on-change type="month" name="@Model.DatePickerFormKey" value="@Model.InitialValue?.ToString("yyyy-MM")">

<script>
    document.addEventListener('DOMContentLoaded', function () {
        document.getElementById('user-filter-content').querySelectorAll('.submit-form-on-change').forEach(function (element) {
            element.addEventListener('change', function () {
                this.form.submit();
            });
        });
    }, false);
</script>

I am able to pick a date via date picker but I would like to be able to also fill the input field using the keyboard.

Now my problem here is that every keystroke triggers the form submit.

Is there any way to check if the value of the input is a full valid date?

So I mean that something like 0202-10 is not possible but 2024-10 or even 1993-10 is.

HTMX – Scroll to bottom of element after swap

I would like to go to the last todo item after adding it, but I can’t get it to work.

Here’s the code:

<button 
    id="button"
    hx-post="/api/todos" 
    hx-include="#field-description, #field-amount"
    hx-target="#todos-container" 
    hx-swap="innerHTML"
    hx-on:click="
        document.getElementById('field-description').value = '';
        document.getElementById('field-amount').value = '';
        document.getElementById('field-description').focus();
    "
    hx-on::afterSwap="document.getElementById('todos').scrollIntoView({ behavior: 'smooth', block: 'end' });"
>
    Add
</button>

How can I check if an array of numbers is an incremental sequence with no jumps?

I am trying to validate if an array of numbers is an incremental sequence with no jumps between numbers. For example:

const items = [1,2,3,4] // Should return true
const items = [1,2,4] // Should return false - jumps from 2 to 4
const items = [5,6,7] // Should return true

The array doesn’t always starts at 1, like the above example which returns true that starts at 5. How could I write a function to validate this so that it returns true or false depending on if the sequence has jumps?

Thanks in advance.

How can I keep the same styling in this Autocomplete MUI when changing the view?

My issue is that when I’m in editMode, the textfield inside the autocomplete changes its styling and also when I choose an option from the dropwdown.

I’ve tried to modify the Textfield inside the autocomplete and the getOptionsLabel but I endup with worse solutions.
What I expect is to be in editMode, and the textfield remains excatly the same as before but for some reason which I cannot find, the styling is different.
So this is image before being in EditMode and the styling that I want to use in the textfield too.
enter image description here

this is the image in editMode
enter image description here

the information is the same but not the position

this is the code

  // Format the value for the Autocomplete component
  const formatValue = (option: Material): ReactElement => (
    <Stack px={3} py={2} width={1}>
      <Typography variant="bodySmall.default">
        {option.libraryRef}
      </Typography>
      <Typography variant="captions.default" color={alpha(palette.primary.main, 0.7)}>
        {option.composition}
        {'manufactureDetail' in option && option.manufactureDetail?.manufactureDetailName ? ` • ${option.manufactureDetail.manufactureDetailName}` : ''}
        {' | '}
        {option.weight}
      </Typography>
    </Stack>
  );

  const handleChange = (
    event: React.SyntheticEvent,
    newValue: Material | { id: string; libraryRef: string; composition: string; weight: string } | null,
  ): void => {
    if (newValue && 'materialSubcategory' in newValue) {
      setSelectedMaterial(newValue);
    }
  };

  return (
    <Stack
      direction="row"
      height={1}
      flexGrow={1}
      alignItems="center"
      boxSizing="border-box"
    >
      {isEditMode ? (
        <Autocomplete
          groupBy={(option) => {
          if ('materialSubcategory' in option && option.materialSubcategory) {
            return option.materialSubcategory.materialSubcategoryName;
          }
          return '';
          }}
          value={selectedMaterial ?? value}
          options={[{ id: 'on-the-fly', libraryRef: 'Material On The Fly', composition: '', weight: '' }, ...materials]}
          getOptionLabel={(option) => `${option.libraryRef} | ${option.composition}${'manufactureDetail' in option && option.manufactureDetail?.manufactureDetailName ? ` • ${option.manufactureDetail.manufactureDetailName}` : ''} | ${option.weight}`}
          renderInput={(params: AutocompleteRenderInputParams): ReactElement => (
            // This is what we see when the dropdown is closed
            <Stack direction="row">
              <TextField
                {...params}
                placeholder={!value ? '' : 'Select Material'}
                inputProps={{
                  ...params.inputProps,
                  readOnly: false,
                }}
                InputProps={{
                  ...params.InputProps,
                  disableUnderline: true,
                  startAdornment: (
                    <ImagePlaceholder
                      sx={{
                        width: THUMBNAIL_SIZE,
                        minWidth: THUMBNAIL_SIZE,
                        height: THUMBNAIL_SIZE,
                        marginRight: 3,
                      }}
                    />
                  ),
                }}
                sx={{
                  [`& .${autocompleteClasses.inputRoot}`]: {
                    ['& input']: {
                      ...theme.typography['bodySmall.default'],
                    },
                  },
                  [`& .${autocompleteClasses.popupIndicator}`]: {
                    right: 12,
                    display: 'flex',
                    alignItems: 'center',
                    width: '16px !important',
                    height: '16px !important',
                    ['&:hover']: {
                    backgroundColor: 'transparent',
                    },
                  },
                }}
              />
            </Stack>
          )}
          renderOption={(props, option) => (
            <>
              {/*this is the materials grouped by MSC name*/}
              <MaterialOption
                option={option}
                props={props}
              />
              {/*this is the material on the fly option with the plus icon*/}
              {'id' in option && option.id === 'on-the-fly' && (
                <MaterialPickerGroup
                  option={option}
                  props={props}
                  setShowMaterialOnTheFlyDialog={setShowMaterialOnTheFlyDialog}
                />
              )}
            </>
          )}

Nestjs GraphQL validate @InputType before processing Guard?

I setup graphql & a app guard for my nestjs project, but has some problem with the process order of request.
This is my dto input for create a Post object

import { InputType, Field } from '@nestjs/graphql';
import { IsNotEmpty, IsNumber } from 'class-validator';

@InputType()
export class CreatePostDto {
    @Field()
    @IsNotEmpty()
    title: string;

    @Field()
    @IsNotEmpty()
    content: string;

    @Field()
    @IsNotEmpty()
    @IsNumber()
    authorId: number;
}

First i try to set authorId as string “4” it return like this
It return the error of input
But i expect it to return unauthorized error (exception throw in app guard). This is full output

{
  "error": {
    "errors": [
      {
        "message": "Float cannot represent non numeric value: "4"",
        "locations": [
          {
            "line": 2,
            "column": 72
          }
        ],
        "extensions": {
          "code": "GRAPHQL_VALIDATION_FAILED",
          "stacktrace": [
            "GraphQLError: Float cannot represent non numeric value: "4"",
            "    at GraphQLScalarType.parseLiteral (D:\Code\NodeJS\fstack\backend\node_modules\graphql\type\scalars.js:169:13)",
            "    at isValidValueNode (D:\Code\NodeJS\fstack\backend\node_modules\graphql\validation\rules\ValuesOfCorrectTypeRule.js:177:30)",
            "    at Object.StringValue (D:\Code\NodeJS\fstack\backend\node_modules\graphql\validation\rules\ValuesOfCorrectTypeRule.js:141:28)",
            "    at Object.enter (D:\Code\NodeJS\fstack\backend\node_modules\graphql\language\visitor.js:301:32)",
            "    at Object.enter (D:\Code\NodeJS\fstack\backend\node_modules\graphql\utilities\TypeInfo.js:391:27)",
            "    at visit (D:\Code\NodeJS\fstack\backend\node_modules\graphql\language\visitor.js:197:21)",
            "    at validate (D:\Code\NodeJS\fstack\backend\node_modules\graphql\validation\validate.js:91:24)",
            "    at processGraphQLRequest (D:\Code\NodeJS\fstack\backend\node_modules\@apollo\server\src\requestPipeline.ts:246:40)",
            "    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)",
            "    at internalExecuteOperation (D:\Code\NodeJS\fstack\backend\node_modules\@apollo\server\src\ApolloServer.ts:1331:12)"
          ]
        }
      }
    ]
  }
}

The auth guard is set as the APP_GUARD and still work well when i post right input( authorId is 4 as number)
It return exception of guard
this is full output

{
  "errors": [
    {
      "message": "Unauthorized",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "createPost"
      ],
      "extensions": {
        "code": "UNAUTHENTICATED",
        "stacktrace": [
          "UnauthorizedException: Unauthorized",
          "    at AuthGuard.canActivate (D:\Code\NodeJS\fstack\backend\src\common\guards\auth.guard.ts:35:10)",
          "    at GuardsConsumer.tryActivate (D:\Code\NodeJS\fstack\backend\node_modules\@nestjs\core\guards\guards-consumer.js:15:34)",
          "    at canActivateFn (D:\Code\NodeJS\fstack\backend\node_modules\@nestjs\core\helpers\external-context-creator.js:155:59)",
          "    at target (D:\Code\NodeJS\fstack\backend\node_modules\@nestjs\core\helpers\external-context-creator.js:73:37)",
          "    at Object.createPost (D:\Code\NodeJS\fstack\backend\node_modules\@nestjs\core\helpers\external-proxy.js:9:30)",
          "    at field.resolve (D:\Code\NodeJS\fstack\backend\node_modules\@apollo\server\src\utils\schemaInstrumentation.ts:82:22)",
          "    at executeField (D:\Code\NodeJS\fstack\backend\node_modules\graphql\execution\execute.js:492:20)",
          "    at D:\Code\NodeJS\fstack\backend\node_modules\graphql\execution\execute.js:377:22",
          "    at promiseReduce (D:\Code\NodeJS\fstack\backend\node_modules\graphql\jsutils\promiseReduce.js:23:9)",
          "    at executeFieldsSerially (D:\Code\NodeJS\fstack\backend\node_modules\graphql\execution\execute.js:373:43)"
        ],
        "originalError": {
          "message": "Unauthorized",
          "statusCode": 401
        }
      }
    }
  ],
  "data": null
}

It seem that graphql validate inputType for graphql query process before the app guard. Is that a bug or i use it wrong

Redirect Instagram Story Link to Open in Default Browser on Android for Amazon App Redirection

I’m working on a system with the following goals:

  1. Create a short link that points to an Amazon product URL.
  2. When someone clicks this link, it should ideally open directly in the Amazon app if it’s installed on their device.

Current Approach

To achieve this, I’m serving a short link that, when clicked, returns HTML and JavaScript designed to redirect users to the Amazon app if it’s installed. Here’s the core HTML and JavaScript I’m using for the redirection:

    const htmlResponse = `
      <!DOCTYPE html>
      <html>
        <head>
          <script>
              window.location.href = '${urls.redirectUrl}';              
          </script>
        </head>
        <body>
          <p>Redirecting</p>
        </body>
      </html>
    `;
    res.setHeader('Content-Type', 'text/html');
    res.send(htmlResponse);

Results So Far

-> Directly Clicking the Link: This setup works well in most cases, directly opening the Amazon app as expected on both iOS and Android when the link is clicked from most browsers.

-> Shared on Instagram Story:

> iOS: When the Instagram Story is clicked by an iOS user, links opens in the Instagram InApp Browser, and it redirects correctly to the Amazon app, likely due to Apple’s support for Universal Links, which Instagram respects.
> Android: On Android, however, clicking the link from an Instagram Story opens it within Instagram’s in-app browser. Here, the link doesn’t redirect to the Amazon app. Instead, it simply opens within Instagram’s browser, likely because Android's Instagram browser blocks intents and app redirections.

Solutions I have tried based on a few questions asked on StackOverflow

  1. How open default browser from instagram in-app browser page link?
  2. Redirect website from facebook web browser to mobile’s default browser
  3. Redirecting from Facebook/Instagram in-app browser to default browser on iOS

Based on these, I have tried a few solutions, like

Solution 1

Redirection when the request is coming from Android & Instagram, assuming that, it will open the Amazon App, but it’s not


<script>
  window.location.href = 
'intent://www.amazon.com/dp/B0CM5J4X7W#Intent;scheme=https;package=com.amazon.mobile.shopping.web;end';
</script>;

or


<script>
  window.location.href = 
'intent://www.amazon.com/dp/B0CM5J4X7W#Intent;scheme=https;package=com.amazon.mShop.android.shopping;end';
</script>;

Solution 2

Tried to open the URL in the default browser, but looks like Instagram has blocked this redirection to the default browser as well.


<script>
  window.location.href = `googlechrome://${link}`;
</script>;

or


<script>
  window.location.href = `intent://${link}#Intent;scheme=https;end`;
</script>;

Solution 3

When the request is coming from Android & Instagram, return a file download response. As the InApp browser doesn’t handle file download, so I was assuming that it would redirect to Default, but in the case of Instagram Story, this redirection also doesn’t happen. But if we share the Link via Inbox with someone, and click that link, it opens in the default browser as it’s a file download link.
Here’s the code for that.


router.get(
  '/:id.docx',
  async (req: Request, res: Response) => {
    try {
      const { id } = req.params;
      const userAgent = req.headers['user-agent']?.toLowerCase().trim() || '';
      const isInstagram = userAgent?.includes('instagram');
      const isAndroid = userAgent?.includes('android');

      const file = bucket.file('dummy/dummy.docx');
      res.header('Access-Control-Allow-Origin', '*');
      res.header('Access-Control-Allow-Headers', 'X-Requested-With');
      res.setHeader(
        'Content-Type',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      );
      res.setHeader(
        'Content-Disposition',
        'attachment; filename="dummy.docx"',
      );
      res.setHeader('Content-Transfer-Encoding', 'binary');
      res.setHeader('Accept-Ranges', 'bytes');
      res.setHeader('Cache-Control', 'no-store, must-revalidate');
      res.setHeader('Pragma', 'no-cache');
      // Stream the file to the response
      file
        .createReadStream()
        .on('error', (err) => {
          console.error('Error fetching file:', err);
          res.status(500).send('Error downloading file.');
        })
        .pipe(res);
      return;
    } catch (firebaseError) {
      console.error(firebaseError);
      res.status(303).redirect(notFound);
    }
  },
);

Question
Is there any way on Android to programmatically trigger Instagram’s in-app browser to open my link in the default browser when clicked from a Story?

If users were redirected to their default browser from Instagram’s in-app browser, the Amazon app redirection would work as intended. Any workaround or solution that helps to open the link in the default browser directly from an Instagram Story on Android would be greatly appreciated.

Thank you for any suggestions or guidance!

How can I locate the source file for a React modal in BigBlueButton for external video sharing?

I’m working on a development environment for BigBlueButton (BBB) and need to modify a modal that allows users to share external videos (from sources like YouTube or Vimeo) in a BBB meeting. Here’s what I’m facing:

What I’ve found so far:
In the browser console, I see the following HTML when the “Share an external video” modal is open:

`

Share an external video

External Video URL

Note: Shared external videos won’t be recorded. Supported sources include YouTube, Vimeo, …
Share new video

`

What I need help with:
I need to identify the source file where this modal is defined. I suspect it might be a React component, possibly named something like VideoModal or similar, based on the modal’s functionality.
Suggestions for a structured approach to locate unminified source files in BigBlueButton, particularly those related to UI components that Meteor bundles into production. Is there a specific path or naming convention used in BBB for such React components?

Environment: Ubuntu-based server running BBB and Meteor

Any help in locating this file or understanding how BBB organizes its React components would be greatly appreciated!

Where I’ve searched:
BigBlueButton server files – Specifically under /usr/lib/bigbluebutton and other likely paths for BBB’s UI code, but I couldn’t find any file directly linked to video-modal-input or external-video-note.
Meteor bundle directory – I ran a find command and located a minified JavaScript file at:

/usr/share/meteor/bundle/programs/web.browser/aafff60feb40ee701a9aa56832dbaabc299e5b6d.js

Opening this file in an editor, I saw minified React and JavaScript code, but due to its minification, it’s challenging to trace specific components.

How to Load and Parse a Large PDF from Stream Chunk by Chunk Without Loading It Completely into Memory?

I’m currently working on a project that involves loading and parsing a large PDF file (over 2GB) from a stream without loading the entire file into memory. I have created a ReadStream from Google Cloud Storage (GCS) / S3 and want to efficiently read the PDF in chunks, extracting text and other relevant information for further processing.

What I tried

I tried various PDF-parsing libraries like pdf-lib, pdf-parse, and pdf2json, but they don’t seem to support parsing using streams. They first completely load the PDF into memory and then parse it.

What I expected
I was hoping to find a library or method that allows me to process a large PDF file without exhausting memory resources.

Additionally, I would like to know how this approach can be extended to handle other document types, such as CSV, DOCX, or Excel files.

If anyone has experience with handling large PDFs or other document types in this manner or can share best practices for stream processing, I would greatly appreciate your insights!

is there is any way possible to download multiple files(.pkpass) on iphone?

I am trying to download multiple boarding passses in ios using blob.

initially I am using this

private downloadMultipleFiles(boardingPassURLs : string[]): void{
    boardingPassURLs.forEach((url) => {
      this.downloadFileService.downloadFileFromURL(url).subscribe((blob) => {
        const a = document.createElement('a');
        const objectUrl = URL.createObjectURL(blob);
        a.href = objectUrl;
        a.download = 'filenameXYZ.pkpass';
        a.click();
        URL.revokeObjectURL(objectUrl);
      });
    });
    this.loaderService.setIsLoaderVisible(false);
  }

  downloadFileFromURL(url: string) {
    return this.http.get(url, { responseType: 'blob' });
  }

It works on windows for all browsers.
But when i chcecked iphone in safari it says

“Safari can not download this file.”

I have tried these approaches which is mentioned below but it did’nt worked out either.

  1. Tried with adding timeouts
  private downloadMultipleFiles(boardingPassURLs : string[]): void{
    boardingPassURLs.forEach((url) => {
      setTimeout(() => {
        this.downloadFileService.downloadFileFromURL(url).subscribe((blob) => {
          const a = document.createElement('a');
          const objectUrl = URL.createObjectURL(blob);
          a.href = objectUrl;
          a.download = 'filenameXYZ.pkpass';
          a.click();
          URL.revokeObjectURL(objectUrl);
        });
      },500);
    });
    this.loaderService.setIsLoaderVisible(false);
  }
  1. Added MIME content Type
private downloadMultipleFiles(boardingPassURLs: string[]): void {
    boardingPassURLs.forEach((url, index) => {
      setTimeout(() => {
        this.downloadFileService.downloadFileFromURL(url).subscribe((blob) => {
          const modifiedBlob = new Blob([blob], { type: 'application/octet-stream' });
          const objectUrl = URL.createObjectURL(modifiedBlob);
          const a = document.createElement('a');
          a.href = objectUrl;
          a.download = 'filenameXYZ.pkpass';
          a.click();
          URL.revokeObjectURL(objectUrl);
        });
      }, index * 500);
    });
    this.loaderService.setIsLoaderVisible(false);
  }

  downloadFileFromURL(url: string) {
    const headers = new HttpHeaders({
      Accept: 'application/octet-stream',
    });

    return this.http.get(url, { headers,responseType: 'blob' });
  }

In this scenario only the initial file was downlaoding, and that too was blank.

  1. Tried MIME Type – ‘application/vnd.apple.pkpass’
    But it gaves the same error as > “Safari can not download this file.”

  2. Tried using Iframes

private downloadMultipleFiles(boardingPassURLs: string[]): void {
    const iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
  
    boardingPassURLs.forEach((url, index) => {
      setTimeout(() => {
        this.downloadFileService.downloadFileFromURL(url).subscribe((blob) => {
          const objectUrl = URL.createObjectURL(blob);
  
          const a = iframe.contentWindow?.document.createElement('a');
          if (a) {
            a.href = objectUrl;
            a.download = 'filenameXYZ.pkpass';
            a.click();
          }
  
          URL.revokeObjectURL(objectUrl);
        });
      }, index * 500);
    });
    this.loaderService.setIsLoaderVisible(false);
  }

It did’nt worked either.

How to fix header on mobile devices [closed]

I have site, and when I open it from my phone I get this header
header
How to fix it?(on pc it works correctly )
It will be easier if I give you link on site, I can’t write code from phone. Sorry

my site

.header {
    background: #19191986;
    backdrop-filter: blur(3px);
    height: 60px;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    transition: all 0.3s ease;
    z-index: 99999999;
}

Please better check site, not code

Communication between AutoHotkey and Chrome Script (Tampermonkey/Greasemonkey)?

i have following Scenario:
Im created a custom Tampermonkey script to control all videos in the current active Chrome Tab back/pause/forward/playbackrates.

Now im trying to also use them from my Streamdeck while in a game on my other monitor.

I already got Streamdeck connected to AutoHotkey to call any function in AutoHotkey without using any weird hotkey combinations, by using a express server and a custom plugin for the streamdeck.

Now my question, is it possible to somehow either receive, or if not possible, poll commands with a Tampermonkey script form a locally hosted SOMETHING?

I Tried websocket, fetch, xmlhttprequest … but always the same stuff… error with CORS i believe. It doesn’t allow me to subscribe to or poll my locally hosted stuff.
I’m not experienced in the CORS stuff etc. Anybody got a working js + ahk script that can somehow communicate or any alternative ideas on what i could try?

btw im using ahk2, but ahk isnt the problem

Thank you

submitting array using react hook form and react server actions

I’m trying to submit an array for a field called services using reack-hook-form but it’s returning as a separate value when submitted. { customerId: '', title: '', message: '', serviceAt: '', 'services.0.id': '1', amount: '5.25' }

This works if I change it to use the onSubmit method but I want to use the actions method so the form can be used with JS.

"use client";

import { CaretSortIcon, CheckIcon, PlusIcon } from "@radix-ui/react-icons";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { format } from "date-fns";
import { CalendarIcon } from "lucide-react";
import { useReducer, useState } from "react";
import { Controller, useFieldArray } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";

import { Button } from "app/components/ui/button";
import { Calendar } from "app/components/ui/calendar";
import {
    Command,
    CommandEmpty,
    CommandGroup,
    CommandInput,
    CommandItem,
    CommandList,
} from "app/components/ui/command";
import { FullScreenModal } from "app/components/ui/full-screen-modal";
import { InputField } from "app/components/ui/input";
import { Label } from "app/components/ui/label";
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from "app/components/ui/popover";
import { Separator } from "app/components/ui/separator";
import { Textarea } from "app/components/ui/textarea";
import ServiceField from "../../components/ServiceField";

import createCustomerByName from "app/actions/mutations/createCustomerByName";
import { createProposalMutation } from "app/actions/mutations/createProposal";
import getCustomersQuery from "app/actions/queries/getCustomers";
import { useSlyderzForm } from "app/hooks/useSlyderzForm";
import { cn, formatNumberToCurrency } from "app/lib/utils";
import { ProposalServicesReducer, initialState } from "reducers/proposal-services-reducer";

export const createProposalSchema = z.object({
    // title: z.string(),
    // amount: z.string(),
    // description: z.string().optional(),
    // customerId: z.string(),
    // serviceAt: z.string(),
    services: z.array(z.any()),
});

interface ProposalModalProps {
    closeModal: () => void;
}
function ProposalModalCreateForm(props: ProposalModalProps) {
    const [open, setOpen] = useState<boolean>(false);
    const [newCustomerName, setNewCustomerName] = useState<string>("");
    const queryClient = useQueryClient()
    const [state, dispatch] = useReducer(ProposalServicesReducer, initialState)

    const { data: customers = [] } = useQuery({
        queryKey: ["customers"],
        queryFn: () => getCustomersQuery(),
    });

    const createCustomer = useMutation({
        mutationFn: createCustomerByName,
        onSuccess: () => {
            queryClient.invalidateQueries({ queryKey: ["customers"] });
            setOpen(false)
        },
    });
    const createProposal = useMutation({
        mutationFn: createProposalMutation,
        onSuccess: () => {
            queryClient.invalidateQueries({ queryKey: ["proposals"] });
        },
    });

    const { control, register, setValue, handleSubmit, formState: { errors } } = useSlyderzForm(createProposalSchema, {
        title: "",
        services: [{ id: 1 }]
    });
    const { append, fields } = useFieldArray({
        control,
        name: "services"
    })

    const handleCreateCustomer = async () => {
        if (newCustomerName) {
            const res = await createCustomer.mutateAsync(newCustomerName);

            if (!res.success) {
                toast.error(res.error?.message);
            }

            return
        }

        toast.error("Customer name can't be empty");
    };

    const handleFormSubmit = async (input: FormData) => {
        const res = await createProposal.mutateAsync(input);

        if (!res.success) {
            toast.error(res.error?.message);
            return
        }

        toast.success("Proposal successfully created");
        props.closeModal();
    };
    const onSub = async (data: any) => {
        console.log(data)
        await createProposalMutation(data)
    }
    return (
        <FullScreenModal title="Create Proposal" formId="create-proposal-form">
            <div>
                <form
                    id="create-proposal-form"
                    action={handleFormSubmit}
                    // onSubmit={proposalForm.handleSubmit(onSub)}
                    className="space-y-8 overflow-auto"
                >
                    <Controller
                        control={control}
                        name="customerId"
                        render={({ field }) => (
                            <div className="space-y-2 flex flex-col">
                                <input hidden name="customerId" value={field.value} />
                                <Label>Assign a customer to proposal</Label>
                                <Popover open={open} onOpenChange={setOpen}>
                                    <PopoverTrigger asChild>
                                        <Button
                                            variant="outline"
                                            role="combobox"
                                            className={cn(
                                                "justify-between",
                                                !field.value && "text-muted-foreground",
                                            )}
                                        >
                                            {field.value
                                                ? customers.find(
                                                    (customer) => customer.id === field.value,
                                                )?.firstName
                                                : "Select customer"}
                                            <CaretSortIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                                        </Button>
                                    </PopoverTrigger>
                                    <PopoverContent className="p-0 popover-content-width-full">
                                        <Command>
                                            <CommandInput
                                                placeholder="Search customers..."
                                                onKeyUp={(e: any) => setNewCustomerName(e.target.value)}
                                                required
                                            />
                                            <CommandList>
                                                <CommandEmpty>
                                                    <Button
                                                        variant="ghost"
                                                        className="w-full flex justify-start"
                                                        onClick={handleCreateCustomer}
                                                    >
                                                        <PlusIcon className={cn("h-5 w-5 font-bold pr-2")} />
                                                        <strong>
                                                            Create new customer: {newCustomerName}
                                                        </strong>
                                                    </Button>
                                                </CommandEmpty>
                                                <CommandGroup>
                                                    {customers.map((customer) => (
                                                        <CommandItem
                                                            {...field}
                                                            key={customer.id}
                                                            onSelect={() => {
                                                                setValue("customerId", customer.id);
                                                                setOpen(false);
                                                            }}
                                                            className="capitalize"
                                                        >
                                                            {customer?.firstName}
                                                            <CheckIcon
                                                                className={cn(
                                                                    "ml-auto h-4 w-4",
                                                                    customer.id === field.value
                                                                        ? "opacity-100"
                                                                        : "opacity-0",
                                                                )}
                                                            />
                                                        </CommandItem>
                                                    ))}
                                                </CommandGroup>
                                            </CommandList>
                                        </Command>
                                    </PopoverContent>
                                </Popover>
                            </div>
                        )}
                    />

                    <Separator />

                    <InputField
                        id="title"
                        label="Title"
                        placeholder="Proposal title"
                        {...register("title")}
                    />

                    <Controller
                        control={control}
                        name="message"
                        render={({ field }) => (
                            <div className="space-y-2">
                                <Label>Message</Label>
                                <Textarea
                                    rows={3}
                                    placeholder="Thank you for choosing our services."
                                    {...field}
                                />
                            </div>
                        )}
                    />
                    <Controller
                        control={control}
                        name="serviceAt"
                        render={({ field }) => (
                            <div className="space-y-2">
                                <input hidden readOnly name="serviceAt" value={field.value} />
                                <Label>Service Date</Label>
                                <Popover>
                                    <PopoverTrigger asChild>
                                        <Button
                                            variant={"outline"}
                                            className={cn(
                                                "w-full pl-3 text-left font-normal",
                                                !field.value && "text-muted-foreground",
                                            )}
                                        >
                                            {field.value ? (
                                                format(field.value, "PPP")
                                            ) : (
                                                <span>Pick a date</span>
                                            )}
                                            <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
                                        </Button>
                                    </PopoverTrigger>
                                    <PopoverContent className="w-auto p-0" align="start">
                                        <Calendar
                                            mode="single"
                                            selected={field.value}
                                            onSelect={field.onChange}
                                            // disabled={(date) => disableDaysOff(date)}
                                            initialFocus
                                        />
                                    </PopoverContent>
                                </Popover>
                            </div>
                        )}
                    />

                    <Separator />
                    <h6 className="text-lg font-semibold leading-none tracking-tight">
                        Services
                    </h6>

                    {/* <ServiceField
                        control={control}
                        register={register}
                        dispatch={dispatch}
                    /> */}
                    <button type="button" onClick={() => append({ id: 1 })}>
                        add service
                    </button>

                    {fields.map((f, i) => (
                        <input key={f.id} {...register(`services.${i}.id` as const)} />
                    ))}

                    {/* Proposal amount - hidden field */}
                    <input
                        {...register("amount" as const)}
                        hidden
                        readOnly
                        defaultValue={String(state.amount + 5.25)}
                    />
                </form>

                <section className="pt-10 w-full text-end gap-4 grid">
                    <p>
                        <strong>Subtotal:</strong> {formatNumberToCurrency(state.amount)}
                    </p>
                    <p>
                        <strong>Taxes:</strong> $5.25
                    </p>
                    <p>
                        <strong>Total:</strong> {formatNumberToCurrency(state.amount + 5.25)}
                    </p>
                </section>
            </div>
        </FullScreenModal>
    );
}

export default ProposalModalCreateForm;

After Vue build, get an unexpected token error ‘??’ in web browser

Built a Vue application in Visual Studio using Typescript. Ran the build command for production to get the compiled Javascript file. When I run the script in a browser, I get a syntax error for an unexpected token ‘??’. The ‘??’ only appears in the output file and not in the Typescript code. The nullish coalescing operator is valid Javascript.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing

example from the Vue generated Javascript file

(n ?? (n = e.get(i) === i._trackId))

I’m at a loss as to how to fix this. Suggestions?

JSON PARSE TYPESCRIPT

I am writing an api where I hear a bunch of data from websocket.
I have implemented a callback where every time on.message of websocket is triggered.
I trigger the callback. Since data I get back is does not have a specific type, that is
each message is different in structure, I can not define a typescript interface.
I also do not want to use “any”. What are my options

type OnMessageCallbackFunction = (message: any) => void; 

This is not something I want.
What other options do one has for generic types. I know it is just a syntactical thing and I can easily get away with “any”

Apply constraints of Pan Tilt Zoom to Camera without the stream pausing for a little while

So i am in a bit of a pickle I am using WebRTC to control the PTZ functions of acamera using buttons for movement and zooming.

const constraints = {
    video: {
      pan: true,
      tilt: true,
      zoom: true
    }
  };

const stream = await navigator.mediaDevices.getUserMedia(constraints);
const [videoTrack] = stream.getVideoTracks();
const capabilities = videoTrack.getCapabilities();

After setting the current state where the camera should be I use

const constraints = { advanced: [{ [command]: adjustedValue }] };
await track.applyConstraints(constraints);

the problem is that this pauses my stream as the camera moves, in around 300-600ms the stream runs again in case of a longer movements its restored while the camera is still moving.

I kinda dont want to use OnVif or any HTTP based solution for this. Is there any way for PTZ controls in browser using the WebRTC but without pausing the stream