@@ -7,6 +7,10 @@ export const getApiUrl = (): string => { return (getEnv()?.NEXT_PUBLIC_API_HOST || process.env.NEXT_PUBLIC_API_HOST) ?? '' } +export const getIsNewDesignEnabled = (): boolean => { + return (getEnv()?.NEXT_PUBLIC_FF_NEW_DESIGN || process.env.NEXT_PUBLIC_FF_NEW_DESIGN) !== 'false' +} + export enum ModelPagesList { '/chatgpt', '/dalle', @@ -9,6 +9,7 @@ function getProcessEnv(): PublicEnv { NEXT_PUBLIC_API_HOST: process.env.NEXT_PUBLIC_API_HOST ?? '', NEXT_PUBLIC_SESSION_TIME: process.env.NEXT_PUBLIC_SESSION_TIME ?? '', NEXT_PUBLIC_REFETCH_INTERVAL: process.env.NEXT_PUBLIC_REFETCH_INTERVAL ?? '', + NEXT_PUBLIC_FF_NEW_DESIGN: process.env.NEXT_PUBLIC_FF_NEW_DESIGN ?? '', NEXT_PUBLIC_SENTRY_DSN: process.env.NEXT_PUBLIC_SENTRY_DSN ?? '', NEXT_PUBLIC_WS_API_URL: process.env.NEXT_PUBLIC_WS_API_URL ?? '', NEXT_PUBLIC_UNLEASH_URL: process.env.NEXT_PUBLIC_UNLEASH_URL ?? '', @@ -3,6 +3,7 @@ export interface PublicEnv { NEXT_PUBLIC_API_HOST: string NEXT_PUBLIC_SESSION_TIME: string NEXT_PUBLIC_REFETCH_INTERVAL: string + NEXT_PUBLIC_FF_NEW_DESIGN?: string NEXT_PUBLIC_SENTRY_DSN?: string NEXT_PUBLIC_WS_API_URL?: string @@ -87,12 +87,37 @@ .staticTabsWrapper { display: flex; align-items: center; + flex-direction: column; width: calc(24.5% + 2px); margin-left: auto; margin-right: calc(3%); margin-top: 0; } +.newDesignToggle { + margin-top: 12px; + width: 100%; + align-self: stretch; + height: 52px; + min-height: 52px; + background: #151518 !important; + color: #a4aab5; + + svg, + span { + color: #a4aab5 !important; + } +} + +.newDesignToggleMobile { + @extend .newDesignToggle; + margin-top: 0; + + > span:first-child > span { + display: inline !important; + } +} + .tag { display: flex; align-items: center; @@ -18,16 +18,20 @@ import { usePredictPrice } from '#/features/predict-price/model/use-predict-pric import Title from '#/features/title/title' import { NextPageWithLayout } from '#/pages/_app' import { DrawerCustom, Loader } from '#/shared' +import { getIsNewDesignEnabled } from '#/shared/lib/constants/constants' import { c, getDeviceType, getOs } from '#/shared/lib/helpers' import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' import { SvgIcon } from '#/shared/ui/svg' import { ImageMessagesList } from '#/widgets/messages' import { ModelApiView, StaticTabs } from '#/widgets/model-api-view' +import { NewDesignToggle } from '#/views/media/ui' import styles from './image-model.module.scss' import { useDeviceType } from '#/shared/lib/hooks' const ImageModelPage: NextPageWithLayout = () => { + const MEDIA_MODEL_SLUG_KEY = 'media-selected-image-model' + const isNewDesignEnabled = getIsNewDesignEnabled() const deviceOs = getOs() const deviceType = getDeviceType() const { query } = useRouter() @@ -54,6 +58,12 @@ const ImageModelPage: NextPageWithLayout = () => { const { onCreateImage, onLoadImage, image, setImage, pinImageFromUrl } = useImagesUniqInput(version, includeParams, createImage) const { push } = useRouter() + const handleNewDesignToggle = (checked: boolean) => { + if (!isNewDesignEnabled || !checked || !routeSlug || typeof window === 'undefined') return + + localStorage.setItem(MEDIA_MODEL_SLUG_KEY, routeSlug) + void push('/media') + } async function onFetch() { const result = await fetchBotParams() @@ -157,9 +167,15 @@ const ImageModelPage: NextPageWithLayout = () => { {desktop && ( + {isNewDesignEnabled && ( + + )} )} + {!desktop && isNewDesignEnabled && ( + + )} { } export const MediaPage: NextPageWithLayout = () => { + const isNewDesignEnabled = getIsNewDesignEnabled() const deviceOs = getOs() const deviceType = getDeviceType() const { desktop } = useDeviceType(deviceType, deviceOs) @@ -116,7 +118,24 @@ export const MediaPage: NextPageWithLayout = () => { }) useEffect(() => { - if (!session?.access) return + if (isNewDesignEnabled || !session?.access) return + + model_api.getImages(session.access).then((list) => { + const all = Array.isArray(list) ? list : [] + const available = all.filter((model) => !model.blocked) + const savedSlug = typeof window !== 'undefined' ? localStorage.getItem(MEDIA_MODEL_SLUG_KEY) : null + const savedModel = savedSlug ? all.find((model) => model.slug === savedSlug) : undefined + const redirectSlug = + (savedModel && !savedModel.blocked ? savedModel.slug : null) || + available[0]?.slug || + '' + + void push(redirectSlug ? `/images/${redirectSlug}` : '/images') + }) + }, [isNewDesignEnabled, push, session?.access]) + + useEffect(() => { + if (!session?.access || !isNewDesignEnabled) return model_api.getImages(session.access).then((list) => { const available = Array.isArray(list) ? list.filter((model) => !model.blocked) : [] @@ -132,7 +151,7 @@ export const MediaPage: NextPageWithLayout = () => { setSelectedSlug(initial) }) - }, [session?.access]) + }, [isNewDesignEnabled, session?.access]) useEffect(() => { if (!models.length || !selectedSlug) return @@ -186,11 +205,15 @@ export const MediaPage: NextPageWithLayout = () => { void push(`/images/${selectedSlug}`) } + if (!isNewDesignEnabled) { + return null + } + return (
- void @@ -24,16 +24,18 @@ const switchSx = { }, } -export const MediaNewViewSwitch = ({ +export const NewDesignToggle = ({ checked = true, disabled = false, onChange, className, -}: MediaNewViewSwitchProps) => { +}: NewDesignToggleProps) => { return (