feat: fix generation

This commit is contained in:
Nevo David 2026-04-15 17:53:37 +07:00
parent ec8c0f6fb9
commit 386fc7b049
4 changed files with 60 additions and 75 deletions

View file

@ -12,6 +12,8 @@ import { FormProvider, useForm } from 'react-hook-form';
import { useUser } from '@gitroom/frontend/components/layout/user.context';
import { VideoContextWrapper } from '@gitroom/frontend/components/videos/video.context.wrapper';
import { useToaster } from '@gitroom/react/toaster/toaster';
import { useModals } from '@gitroom/frontend/components/layout/new-modal';
import { createPortal } from 'react-dom';
export const Modal: FC<{
close: () => void;
@ -73,71 +75,42 @@ export const Modal: FC<{
onSubmit={form.handleSubmit(generate)}
className="flex flex-col gap-[10px]"
>
{createPortal(
<>{data?.credits || 0} credits left</>,
document.querySelector('.top-title-content') || document.createElement('div')
)}
<FormProvider {...form}>
<div className="text-textColor fixed start-0 top-0 bg-primary/80 z-[300] w-full h-full p-[60px] animate-fade justify-center flex bg-black/50">
<div>
<div className="flex gap-[10px] flex-col w-[500px] h-auto bg-sixth border-tableBorder border-2 rounded-xl pb-[20px] px-[20px] relative">
<div className="flex">
<div className="flex-1">
<TopTitle title={'Video Type'}>
<div className="mr-[25px]">
{data?.credits || 0} credits left
</div>
</TopTitle>
</div>
<button
onClick={props.close}
className="outline-none absolute end-[10px] top-[10px] mantine-UnstyledButton-root mantine-ActionIcon-root bg-primary hover:bg-tableBorder cursor-pointer mantine-Modal-close mantine-1dcetaa"
type="button"
>
<svg
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
<div>
<div className="relative h-[400px]">
<div className="absolute left-0 top-0 w-full h-full overflow-hidden overflow-y-auto">
<div className="mt-[10px] flex w-full justify-center items-center gap-[10px]">
<div className="flex-1 flex">
<Button
className="!flex-1"
onClick={() => setPosition('vertical')}
secondary={position === 'horizontal'}
>
<path
d="M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
></path>
</svg>
</button>
</div>
<div className="relative h-[400px]">
<div className="absolute left-0 top-0 w-full h-full overflow-hidden overflow-y-auto">
<div className="mt-[10px] flex w-full justify-center items-center gap-[10px]">
<div className="flex-1 flex">
<Button
className="!flex-1"
onClick={() => setPosition('vertical')}
secondary={position === 'horizontal'}
>
Vertical (Stories, Reels)
</Button>
</div>
<div className="flex-1 flex mt-[10px]">
<Button
className="!flex-1"
onClick={() => setPosition('horizontal')}
secondary={position === 'vertical'}
>
Horizontal (Normal Post)
</Button>
</div>
</div>
<VideoWrapper identifier={type.identifier} />
Vertical (Stories, Reels)
</Button>
</div>
<div className="flex-1 flex mt-[10px]">
<Button
className="!flex-1"
onClick={() => setPosition('horizontal')}
secondary={position === 'vertical'}
>
Horizontal (Normal Post)
</Button>
</div>
</div>
<div className="flex">
<Button type="submit" className="flex-1">
Generate
</Button>
</div>
<VideoWrapper identifier={type.identifier} />
</div>
</div>
<div className="flex">
<Button type="submit" className="flex-1">
Generate
</Button>
</div>
</div>
</FormProvider>
</form>
@ -153,9 +126,9 @@ export const AiVideo: FC<{
const { value, onChange } = props;
const [loading, setLoading] = useState(false);
const [type, setType] = useState<any | null>(null);
const [modal, setModal] = useState(false);
const fetch = useFetch();
const { isTrailing } = useUser();
const modals = useModals();
const loadVideoList = useCallback(async () => {
return (await (await fetch('/media/video-options')).json()).filter(
@ -175,7 +148,21 @@ export const AiVideo: FC<{
const generateVideo = useCallback(
(type: { identifier: string }) => async () => {
setType(type);
setModal(true);
modals.openModal({
title: <div className="top-title-content" />,
children: (close) => (
<Modal
onChange={onChange}
setLoading={setLoading}
close={() => {
close();
setType(null);
}}
type={type}
value={value}
/>
),
});
},
[value, onChange]
);
@ -186,18 +173,6 @@ export const AiVideo: FC<{
return (
<>
{modal && (
<Modal
onChange={onChange}
setLoading={setLoading}
close={() => {
setModal(false);
setType(null);
}}
type={type}
value={props.value}
/>
)}
<div className="relative group">
<div
{...(value.length < 30
@ -247,7 +222,9 @@ export const AiVideo: FC<{
</defs>
</svg>
</div>
<div className="text-[10px] font-[600] iconBreak:hidden block">{t('ai', 'AI')} Video</div>
<div className="text-[10px] font-[600] iconBreak:hidden block">
{t('ai', 'AI')} Video
</div>
</div>
</div>
{value.length >= 30 && !loading && (

View file

@ -17,7 +17,7 @@ import clsx from 'clsx';
import { EventEmitter } from 'events';
interface OpenModalInterface {
title?: string;
title?: any;
closeOnClickOutside?: boolean;
removeLayout?: boolean;
fullScreen?: boolean;

View file

@ -18,6 +18,10 @@ const ALLOWED_MIME_TYPES = new Set<string>([
'image/bmp',
'image/tiff',
'video/mp4',
'audio/mpeg',
'audio/mp4',
'audio/wav',
'audio/ogg',
]);
class CloudflareStorage implements IUploadProvider {

View file

@ -15,6 +15,10 @@ const LOCAL_STORAGE_ALLOWED_MIME = new Set<string>([
'image/bmp',
'image/tiff',
'video/mp4',
'audio/mpeg',
'audio/mp4',
'audio/wav',
'audio/ogg',
]);
export class LocalStorage implements IUploadProvider {
constructor(private uploadDirectory: string) {}