remove all official template trash

This commit is contained in:
vchikalkin 2024-12-11 15:53:38 +03:00
parent 9ab9880c0f
commit c43a609b8d
39 changed files with 98 additions and 1187 deletions

View File

@ -1,3 +0,0 @@
body {
background: var(--tg-theme-secondary-bg-color, white);
}

View File

@ -1 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.1839 17.7069C13.6405 18.6507 13.3688 19.1226 13.0591 19.348C12.4278 19.8074 11.5723 19.8074 10.941 19.348C10.6312 19.1226 10.3595 18.6507 9.81613 17.7069L5.52066 10.2464C4.76864 8.94024 4.39263 8.28717 4.33762 7.75894C4.2255 6.68236 4.81894 5.65591 5.80788 5.21589C6.29309 5 7.04667 5 8.55383 5H15.4462C16.9534 5 17.7069 5 18.1922 5.21589C19.1811 5.65591 19.7745 6.68236 19.6624 7.75894C19.6074 8.28717 19.2314 8.94024 18.4794 10.2464L14.1839 17.7069ZM11.1 16.3412L6.56139 8.48002C6.31995 8.06185 6.19924 7.85276 6.18146 7.68365C6.14523 7.33896 6.33507 7.01015 6.65169 6.86919C6.80703 6.80002 7.04847 6.80002 7.53133 6.80002H7.53134L11.1 6.80002V16.3412ZM12.9 16.3412L17.4387 8.48002C17.6801 8.06185 17.8008 7.85276 17.8186 7.68365C17.8548 7.33896 17.665 7.01015 17.3484 6.86919C17.193 6.80002 16.9516 6.80002 16.4687 6.80002L12.9 6.80002V16.3412Z" fill="#ffffff"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,5 +0,0 @@
'use client';
import { ErrorPage } from '@/components/ErrorPage';
export default ErrorPage;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,121 +0,0 @@
'use client';
import { useMemo } from 'react';
import { useSignal, initData, type User } from '@telegram-apps/sdk-react';
import { List, Placeholder } from '@telegram-apps/telegram-ui';
import {
DisplayData,
type DisplayDataRow,
} from '@/components/DisplayData/DisplayData';
import { Page } from '@/components/Page';
function getUserRows(user: User): DisplayDataRow[] {
return [
{ title: 'id', value: user.id.toString() },
{ title: 'username', value: user.username },
{ title: 'photo_url', value: user.photoUrl },
{ title: 'last_name', value: user.lastName },
{ title: 'first_name', value: user.firstName },
{ title: 'is_bot', value: user.isBot },
{ title: 'is_premium', value: user.isPremium },
{ title: 'language_code', value: user.languageCode },
{ title: 'allows_to_write_to_pm', value: user.allowsWriteToPm },
{ title: 'added_to_attachment_menu', value: user.addedToAttachmentMenu },
];
}
export default function InitDataPage() {
const initDataRaw = useSignal(initData.raw);
const initDataState = useSignal(initData.state);
const initDataRows = useMemo<DisplayDataRow[] | undefined>(() => {
if (!initDataState || !initDataRaw) {
return;
}
const {
authDate,
hash,
queryId,
chatType,
chatInstance,
canSendAfter,
startParam,
} = initDataState;
return [
{ title: 'raw', value: initDataRaw },
{ title: 'auth_date', value: authDate.toLocaleString() },
{ title: 'auth_date (raw)', value: authDate.getTime() / 1000 },
{ title: 'hash', value: hash },
{
title: 'can_send_after',
value: initData.canSendAfterDate()?.toISOString(),
},
{ title: 'can_send_after (raw)', value: canSendAfter },
{ title: 'query_id', value: queryId },
{ title: 'start_param', value: startParam },
{ title: 'chat_type', value: chatType },
{ title: 'chat_instance', value: chatInstance },
];
}, [initDataState, initDataRaw]);
const userRows = useMemo<DisplayDataRow[] | undefined>(() => {
return initDataState && initDataState.user
? getUserRows(initDataState.user)
: undefined;
}, [initDataState]);
const receiverRows = useMemo<DisplayDataRow[] | undefined>(() => {
return initDataState && initDataState.receiver
? getUserRows(initDataState.receiver)
: undefined;
}, [initDataState]);
const chatRows = useMemo<DisplayDataRow[] | undefined>(() => {
if (!initDataState?.chat) {
return;
}
const {
id,
title,
type,
username,
photoUrl,
} = initDataState.chat;
return [
{ title: 'id', value: id.toString() },
{ title: 'title', value: title },
{ title: 'type', value: type },
{ title: 'username', value: username },
{ title: 'photo_url', value: photoUrl },
];
}, [initData]);
if (!initDataRows) {
return (
<Page>
<Placeholder
header="Oops"
description="Application was launched with missing init data"
>
<img
alt="Telegram sticker"
src="https://xelene.me/telegram.gif"
style={{ display: 'block', width: '144px', height: '144px' }}
/>
</Placeholder>
</Page>
);
}
return (
<Page>
<List>
<DisplayData header={'Init Data'} rows={initDataRows}/>
{userRows && <DisplayData header={'User'} rows={userRows}/>}
{receiverRows && <DisplayData header={'Receiver'} rows={receiverRows}/>}
{chatRows && <DisplayData header={'Chat'} rows={chatRows}/>}
</List>
</Page>
);
};

View File

@ -1,33 +0,0 @@
'use client';
import { useLaunchParams } from '@telegram-apps/sdk-react';
import { List } from '@telegram-apps/telegram-ui';
import { DisplayData } from '@/components/DisplayData/DisplayData';
import { Page } from '@/components/Page';
export default function LaunchParamsPage() {
const lp = useLaunchParams();
return (
<Page>
<List>
<DisplayData
rows={[
{ title: 'tgWebAppPlatform', value: lp.platform },
{ title: 'tgWebAppShowSettings', value: lp.showSettings },
{ title: 'tgWebAppVersion', value: lp.version },
{ title: 'tgWebAppBotInline', value: lp.botInline },
{ title: 'tgWebAppStartParam', value: lp.startParam },
{ title: 'tgWebAppData', type: 'link', value: '/init-data' },
{
title: 'tgWebAppThemeParams',
type: 'link',
value: '/theme-params',
},
]}
/>
</List>
</Page>
);
};

View File

@ -1,17 +1,15 @@
import { Root } from '@/components/Root/Root';
import { I18nProvider } from '@/core/i18n/provider';
import { Root } from '@/components/telegram';
import { I18nProvider } from '@/utils/i18n/provider';
import { type Metadata } from 'next';
import { getLocale } from 'next-intl/server';
import { type PropsWithChildren } from 'react';
import '@telegram-apps/telegram-ui/dist/styles.css';
import './_assets/globals.css';
export const metadata: Metadata = {
description: 'Your application description goes here',
title: 'Your Application Title Goes Here',
};
export default async function RootLayout({ children }: PropsWithChildren) {
export default async function RootLayout({ children }: Readonly<PropsWithChildren>) {
const locale = await getLocale();
return (

View File

@ -1,35 +1,14 @@
'use client';
import { Link } from '@/components/Link/Link';
import { LocaleSwitcher } from '@/components/LocaleSwitcher/LocaleSwitcher';
import { Page } from '@/components/Page';
import { Cell, List, Section } from '@telegram-apps/telegram-ui';
import { useTranslations } from 'next-intl';
import { initData, isMiniAppDark, useSignal } from '@telegram-apps/sdk-react';
export default function Home() {
const t = useTranslations('i18n');
export default function InitDataPage() {
const initDataState = useSignal(initData.state);
const isDark = isMiniAppDark();
return (
<Page back={false}>
<List>
<Section
footer="These pages help developer to learn more about current launch information"
header="Application Launch Data"
>
<Link href="/init-data">
<Cell subtitle="User data, chat information, technical data">Init Data</Cell>
</Link>
<Link href="/launch-params">
<Cell subtitle="Platform identifier, Mini Apps version, etc.">Launch Parameters</Cell>
</Link>
<Link href="/theme-params">
<Cell subtitle="Telegram application palette information">Theme Parameters</Cell>
</Link>
</Section>
<Section footer={t('footer')} header={t('header')}>
<LocaleSwitcher />
</Section>
</List>
</Page>
<code style={{ color: isDark ? 'white' : 'black' }}>
{JSON.stringify(initDataState, null, 2)}
</code>
);
}

View File

@ -1,30 +0,0 @@
'use client';
import { useSignal, themeParams } from '@telegram-apps/sdk-react';
import { List } from '@telegram-apps/telegram-ui';
import { DisplayData } from '@/components/DisplayData/DisplayData';
import { Page } from '@/components/Page';
export default function ThemeParamsPage() {
const tp = useSignal(themeParams.state);
return (
<Page>
<List>
<DisplayData
rows={
Object
.entries(tp)
.map(([title, value]) => ({
title: title
.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`)
.replace(/background/, 'bg'),
value,
}))
}
/>
</List>
</Page>
);
};

View File

@ -1,105 +0,0 @@
'use client';
import { openLink } from '@telegram-apps/sdk-react';
import { Page } from '@/components/Page';
import { TonConnectButton, useTonWallet } from '@tonconnect/ui-react';
import {
Avatar,
Cell,
List,
Navigation,
Placeholder,
Section,
Text,
Title,
} from '@telegram-apps/telegram-ui';
import { DisplayData } from '@/components/DisplayData/DisplayData';
import './styles.css';
export default function TONConnectPage() {
const wallet = useTonWallet();
if (!wallet) {
return (
<Page>
<Placeholder
className="ton-connect-page__placeholder"
header="TON Connect"
description={
<>
<Text>
To display the data related to the TON Connect, it is required
to connect your wallet
</Text>
<TonConnectButton className="ton-connect-page__button"/>
</>
}
/>
</Page>
);
}
const {
account: { chain, publicKey, address },
device: {
appName,
appVersion,
maxProtocolVersion,
platform,
features,
},
} = wallet;
return (
<Page>
<List>
{'imageUrl' in wallet && (
<>
<Section>
<Cell
before={
<Avatar src={wallet.imageUrl} alt="Provider logo" width={60}
height={60}/>
}
after={<Navigation>About wallet</Navigation>}
subtitle={wallet.appName}
onClick={(e) => {
e.preventDefault();
openLink(wallet.aboutUrl);
}}
>
<Title level="3">{wallet.name}</Title>
</Cell>
</Section>
<TonConnectButton className="ton-connect-page__button-connected"/>
</>
)}
<DisplayData
header="Account"
rows={[
{ title: 'Address', value: address },
{ title: 'Chain', value: chain },
{ title: 'Public Key', value: publicKey },
]}
/>
<DisplayData
header="Device"
rows={[
{ title: 'App Name', value: appName },
{ title: 'App Version', value: appVersion },
{ title: 'Max Protocol Version', value: maxProtocolVersion },
{ title: 'Platform', value: platform },
{
title: 'Features',
value: features
.map(f => typeof f === 'object' ? f.name : undefined)
.filter(v => v)
.join(', '),
},
]}
/>
</List>
</Page>
);
};

View File

@ -1,16 +0,0 @@
.ton-connect-page__placeholder {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.ton-connect-page__button {
margin: 16px auto 0;
}
.ton-connect-page__button-connected {
margin: 16px 24px 16px auto;
}

View File

@ -1,59 +0,0 @@
import { isRGB } from '@telegram-apps/sdk-react';
import { Cell, Checkbox, Section } from '@telegram-apps/telegram-ui';
import type { FC, ReactNode } from 'react';
import { RGB } from '@/components/RGB/RGB';
import { Link } from '@/components/Link/Link';
import './styles.css';
export type DisplayDataRow =
& { title: string }
& (
| { type: 'link'; value?: string }
| { value: ReactNode }
)
export interface DisplayDataProps {
header?: ReactNode;
footer?: ReactNode;
rows: DisplayDataRow[];
}
export const DisplayData: FC<DisplayDataProps> = ({ header, rows }) => (
<Section header={header}>
{rows.map((item, idx) => {
let valueNode: ReactNode;
if (item.value === undefined) {
valueNode = <i>empty</i>;
} else {
if ('type' in item) {
valueNode = <Link href={item.value}>Open</Link>;
} else if (typeof item.value === 'string') {
valueNode = isRGB(item.value)
? <RGB color={item.value}/>
: item.value;
} else if (typeof item.value === 'boolean') {
valueNode = <Checkbox checked={item.value} disabled/>;
} else {
valueNode = item.value;
}
}
return (
<Cell
className='display-data__line'
subhead={item.title}
readOnly
multiline={true}
key={idx}
>
<span className='display-data__line-value'>
{valueNode}
</span>
</Cell>
);
})}
</Section>
);

View File

@ -1,15 +0,0 @@
.display-data__header {
font-weight: 400;
}
.display-data__line {
padding: 16px 24px;
}
.display-data__line-title {
color: var(--tg-theme-subtitle-text-color);
}
.display-data__line-value {
word-break: break-word;
}

View File

@ -1,39 +0,0 @@
import {
Component,
type ComponentType,
type GetDerivedStateFromError,
type PropsWithChildren,
} from 'react';
export interface ErrorBoundaryProps extends PropsWithChildren {
fallback: ComponentType<{ error: Error }>;
}
interface ErrorBoundaryState {
error?: Error;
}
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
state: ErrorBoundaryState = {};
// eslint-disable-next-line max-len
static getDerivedStateFromError: GetDerivedStateFromError<ErrorBoundaryProps, ErrorBoundaryState> = (error) => ({ error });
componentDidCatch(error: Error) {
this.setState({ error });
}
render() {
const {
state: {
error,
},
props: {
fallback: Fallback,
children,
},
} = this;
return error ? <Fallback error={error}/> : children;
}
}

View File

@ -1,26 +0,0 @@
import { useEffect } from 'react';
export function ErrorPage({
error,
reset,
}: {
error: Error & { digest?: string }
reset?: () => void
}) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error);
}, [error]);
return (
<div>
<h2>An unhandled error occurred!</h2>
<blockquote>
<code>
{error.message}
</code>
</blockquote>
{reset && <button onClick={() => reset()}>Try again</button>}
</div>
);
}

View File

@ -1,48 +0,0 @@
import { openLink, classNames } from '@telegram-apps/sdk-react';
import { type FC, type MouseEventHandler, type JSX, useCallback } from 'react';
import { type LinkProps as NextLinkProps, default as NextLink } from 'next/link';
import './styles.css';
export interface LinkProps extends NextLinkProps, Omit<JSX.IntrinsicElements['a'], 'href'> {
}
export const Link: FC<LinkProps> = ({
className,
onClick: propsOnClick,
href,
...rest
}) => {
const onClick = useCallback<MouseEventHandler<HTMLAnchorElement>>((e) => {
propsOnClick?.(e);
// Compute if target path is external. In this case we would like to open link using
// TMA method.
let path: string;
if (typeof href === 'string') {
path = href;
} else {
const { search = '', pathname = '', hash = '' } = href;
path = `${pathname}?${search}#${hash}`;
}
const targetUrl = new URL(path, window.location.toString());
const currentUrl = new URL(window.location.toString());
const isExternal = targetUrl.protocol !== currentUrl.protocol
|| targetUrl.host !== currentUrl.host;
if (isExternal) {
e.preventDefault();
openLink(targetUrl.toString());
}
}, [href, propsOnClick]);
return (
<NextLink
{...rest}
href={href}
onClick={onClick}
className={classNames(className, 'link')}
/>
);
};

View File

@ -1,4 +0,0 @@
.link {
text-decoration: none;
color: var(--tg-theme-link-color);
}

View File

@ -1,26 +0,0 @@
'use client';
import { Select } from '@telegram-apps/telegram-ui';
import { useLocale } from 'next-intl';
import { FC } from 'react';
import { localesMap } from '@/core/i18n/config';
import { setLocale } from '@/core/i18n/locale';
import { Locale } from '@/core/i18n/types';
export const LocaleSwitcher: FC = () => {
const locale = useLocale();
const onChange = (value: string) => {
const locale = value as Locale;
setLocale(locale);
};
return (
<Select value={locale} onChange={({ target }) => onChange(target.value)}>
{localesMap.map((locale) => (
<option key={locale.key} value={locale.key}>{locale.title}</option>
))}
</Select>
);
};

View File

@ -1,31 +0,0 @@
'use client';
import { backButton } from '@telegram-apps/sdk-react';
import { PropsWithChildren, useEffect } from 'react';
import { useRouter } from 'next/navigation';
export function Page({ children, back = true }: PropsWithChildren<{
/**
* True if it is allowed to go back from this page.
* @default true
*/
back?: boolean
}>) {
const router = useRouter();
useEffect(() => {
if (back) {
backButton.show();
} else {
backButton.hide();
}
}, [back]);
useEffect(() => {
return backButton.onClick(() => {
router.back();
});
}, [router]);
return <>{children}</>;
}

View File

@ -1,15 +0,0 @@
import { classNames, type RGB as RGBType } from '@telegram-apps/sdk-react';
import type { FC } from 'react';
import './styles.css';
export type RGBProps = JSX.IntrinsicElements['div'] & {
color: RGBType;
};
export const RGB: FC<RGBProps> = ({ color, className, ...rest }) => (
<span {...rest} className={classNames('rgb', className)}>
<i className='rgb__icon' style={{ backgroundColor: color }}/>
{color}
</span>
);

View File

@ -1,12 +0,0 @@
.rgb {
display: inline-flex;
align-items: center;
gap: 5px;
}
.rgb__icon {
width: 18px;
aspect-ratio: 1;
border: 1px solid #555;
border-radius: 50%;
}

View File

@ -1,63 +0,0 @@
'use client';
import { ErrorBoundary } from '@/components/ErrorBoundary';
import { ErrorPage } from '@/components/ErrorPage';
import { setLocale } from '@/core/i18n/locale';
import { init } from '@/core/init';
import { useClientOnce } from '@/hooks/useClientOnce';
import { useDidMount } from '@/hooks/useDidMount';
import { useTelegramMock } from '@/hooks/useTelegramMock';
import { initData, miniApp, useLaunchParams, useSignal } from '@telegram-apps/sdk-react';
import { AppRoot } from '@telegram-apps/telegram-ui';
import { type PropsWithChildren, useEffect } from 'react';
import './styles.css';
export function Root(props: PropsWithChildren) {
// Unfortunately, Telegram Mini Apps does not allow us to use all features of
// the Server Side Rendering. That's why we are showing loader on the server
// side.
const didMount = useDidMount();
return didMount ? (
<ErrorBoundary fallback={ErrorPage}>
<RootInner {...props} />
</ErrorBoundary>
) : (
<div className="root__loading">Loading</div>
);
}
function RootInner({ children }: PropsWithChildren) {
const isDevelopment = process.env.NODE_ENV === 'development';
// Mock Telegram environment in development mode if needed.
if (isDevelopment) {
// eslint-disable-next-line react-hooks/rules-of-hooks
useTelegramMock();
}
const lp = useLaunchParams();
const debug = isDevelopment || lp.startParam === 'debug';
// Initialize the library.
useClientOnce(() => {
init(debug);
});
const isDark = useSignal(miniApp.isDark);
const initDataUser = useSignal(initData.user);
// Set the user locale.
useEffect(() => {
initDataUser && setLocale(initDataUser.languageCode);
}, [initDataUser]);
return (
<AppRoot
appearance={isDark ? 'dark' : 'light'}
platform={['ios', 'macos'].includes(lp.platform) ? 'ios' : 'base'}
>
{children}
</AppRoot>
);
}

View File

@ -1,10 +0,0 @@
.root__loading {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}

View File

@ -0,0 +1,45 @@
/* eslint-disable sonarjs/function-return-type */
'use client';
import { useClientOnce, useDidMount, useTelegramMock } from '@/hooks/telegram';
import { setLocale } from '@/utils/i18n/locale';
import { init } from '@/utils/init';
import { initData, useLaunchParams, useSignal } from '@telegram-apps/sdk-react';
import { type PropsWithChildren, useEffect } from 'react';
export function Root(props: Readonly<PropsWithChildren>) {
// Unfortunately, Telegram Mini Apps does not allow us to use all features of
// the Server Side Rendering. That's why we are showing loader on the server
// side.
const didMount = useDidMount();
if (!didMount) return <div>Loading</div>;
return <RootInner {...props} />;
}
function RootInner({ children }: PropsWithChildren) {
const isDevelopment = process.env.NODE_ENV === 'development';
// Mock Telegram environment in development mode if needed.
if (isDevelopment) {
// eslint-disable-next-line react-hooks/rules-of-hooks
useTelegramMock();
}
const lp = useLaunchParams();
const debug = isDevelopment || lp.startParam === 'debug';
// Initialize the library.
useClientOnce(() => {
init(debug);
});
const initDataUser = useSignal(initData.user);
// Set the user locale.
useEffect(() => {
if (initDataUser) setLocale(initDataUser.languageCode);
}, [initDataUser]);
return children;
}

View File

@ -0,0 +1 @@
export * from './Root';

View File

@ -1,18 +0,0 @@
import { NextIntlClientProvider } from "next-intl";
import { getMessages } from "next-intl/server";
import React from "react";
import { timeZone } from "./config";
const I18nProvider: React.FC<React.PropsWithChildren> = async ({
children,
}) => {
const messages = await getMessages();
return (
<NextIntlClientProvider messages={messages} timeZone={timeZone}>
{children}
</NextIntlClientProvider>
);
};
export { I18nProvider };

View File

@ -0,0 +1,3 @@
export * from './use-client-once';
export * from './use-did-mount';
export * from './use-telegram-mock';

View File

@ -1,9 +1,9 @@
import { useRef } from 'react';
export function useClientOnce(fn: () => void): void {
export function useClientOnce(callback: () => void): void {
const canCall = useRef(true);
if (typeof window !== 'undefined' && canCall.current) {
canCall.current = false;
fn();
callback();
}
}
}

View File

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
/**
* @return True, if component was mounted.
* @returns True, if component was mounted.
*/
export function useDidMount(): boolean {
const [didMount, setDidMount] = useState(false);
@ -11,4 +11,4 @@ export function useDidMount(): boolean {
}, []);
return didMount;
}
}

View File

@ -1,4 +1,5 @@
import { useClientOnce } from '@/hooks/useClientOnce';
/* eslint-disable no-console */
import { useClientOnce } from '@/hooks/telegram/use-client-once';
import {
isTMA,
type LaunchParams,

View File

@ -1,6 +1,6 @@
import createNextIntlPlugin from 'next-intl/plugin';
const withNextIntl = createNextIntlPlugin('./core/i18n/i18n.ts');
const withNextIntl = createNextIntlPlugin('./utils/i18n/i18n.ts');
const nextConfig = withNextIntl({
reactStrictMode: true,

View File

@ -18,7 +18,6 @@
"@apollo/client": "catalog:",
"@repo/ui": "workspace:*",
"@telegram-apps/sdk-react": "^2.0.19",
"@telegram-apps/telegram-ui": "^2.1.8",
"graphql": "catalog:",
"next": "catalog:",
"next-intl": "^3.26.0",

View File

@ -3,7 +3,7 @@ import { getLocale } from './locale';
import { type Locale } from './types';
import { getRequestConfig } from 'next-intl/server';
const i18nRequestConfig = getRequestConfig(async () => {
const requestConfig = getRequestConfig(async () => {
const locale = (await getLocale()) as Locale;
return {
@ -15,4 +15,4 @@ const i18nRequestConfig = getRequestConfig(async () => {
};
});
export default i18nRequestConfig;
export default requestConfig;

View File

@ -1,21 +1,20 @@
//use server is required
"use server";
// use server is required
'use server';
import { cookies } from "next/headers";
import { defaultLocale } from "./config";
import type { Locale } from "./types";
import { defaultLocale } from './config';
import { type Locale } from './types';
import { cookies } from 'next/headers';
// In this example the locale is read from a cookie. You could alternatively
// also read it from a database, backend service, or any other source.
const COOKIE_NAME = "NEXT_LOCALE";
const COOKIE_NAME = 'NEXT_LOCALE';
const getLocale = async () => {
return cookies().get(COOKIE_NAME)?.value || defaultLocale;
};
const setLocale = async (locale?: string) => {
cookies().set(COOKIE_NAME, locale as Locale || defaultLocale);
cookies().set(COOKIE_NAME, (locale as Locale) || defaultLocale);
};
export { getLocale, setLocale };

View File

@ -0,0 +1,14 @@
/* eslint-disable canonical/id-match */
import { timeZone } from './config';
import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';
import { type PropsWithChildren } from 'react';
export async function I18nProvider({ children }: Readonly<PropsWithChildren>) {
const messages = await getMessages();
return (
<NextIntlClientProvider messages={messages} timeZone={timeZone}>
{children}
</NextIntlClientProvider>
);
}

View File

@ -1,4 +1,4 @@
import type { locales } from "./config";
import { type locales } from './config';
type Locale = (typeof locales)[number];

View File

@ -1,6 +1,8 @@
/* eslint-disable no-console */
/* eslint-disable promise/prefer-await-to-then */
import {
$debug,
backButton,
$debug as debugSDK,
initData,
init as initSDK,
miniApp,
@ -13,7 +15,7 @@ import {
*/
export function init(debug: boolean): void {
// Set @telegram-apps/sdk-react debug mode.
$debug.set(debug);
debugSDK.set(debug);
// Initialize special event handlers for Telegram Desktop, Android, iOS, etc.
// Also, configure the package.
@ -37,5 +39,7 @@ export function init(debug: boolean): void {
});
// Add Eruda if needed.
debug && import('eruda').then((library) => library.default.init()).catch(console.error);
if (debug) {
import('eruda').then((library) => library.default.init()).catch(console.error);
}
}

452
pnpm-lock.yaml generated
View File

@ -146,9 +146,6 @@ importers:
'@telegram-apps/sdk-react':
specifier: ^2.0.19
version: 2.0.19(@types/react@19.0.1)(react@19.0.0)
'@telegram-apps/telegram-ui':
specifier: ^2.1.8
version: 2.1.8(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
graphql:
specifier: 'catalog:'
version: 16.9.0
@ -1135,21 +1132,6 @@ packages:
resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@floating-ui/core@1.6.8':
resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==}
'@floating-ui/dom@1.6.12':
resolution: {integrity: sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==}
'@floating-ui/react-dom@2.1.2':
resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==}
peerDependencies:
react: '>=16.8.0'
react-dom: '>=16.8.0'
'@floating-ui/utils@0.2.8':
resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==}
'@formatjs/ecma402-abstract@2.3.1':
resolution: {integrity: sha512-Ip9uV+/MpLXWRk03U/GzeJMuPeOXpJBSB5V1tjA6kJhvqssye5J5LoYLc7Z5IAHb7nR62sRoguzrFiVCP/hnzw==}
@ -1723,9 +1705,6 @@ packages:
engines: {node: '>=18'}
hasBin: true
'@radix-ui/primitive@1.1.0':
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
'@radix-ui/react-compose-refs@1.1.0':
resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==}
peerDependencies:
@ -1735,111 +1714,6 @@ packages:
'@types/react':
optional: true
'@radix-ui/react-context@1.1.1':
resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@radix-ui/react-dialog@1.1.2':
resolution: {integrity: sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-dismissable-layer@1.1.1':
resolution: {integrity: sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-focus-guards@1.1.1':
resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@radix-ui/react-focus-scope@1.1.0':
resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-id@1.1.0':
resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@radix-ui/react-portal@1.1.2':
resolution: {integrity: sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-presence@1.1.1':
resolution: {integrity: sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-primitive@2.0.0':
resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==}
peerDependencies:
'@types/react': '*'
'@types/react-dom': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@types/react-dom':
optional: true
'@radix-ui/react-slot@1.1.0':
resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==}
peerDependencies:
@ -1849,42 +1723,6 @@ packages:
'@types/react':
optional: true
'@radix-ui/react-use-callback-ref@1.1.0':
resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@radix-ui/react-use-controllable-state@1.1.0':
resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@radix-ui/react-use-escape-keydown@1.1.0':
resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@radix-ui/react-use-layout-effect@1.1.0':
resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
peerDependencies:
'@types/react': '*'
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
'@types/react':
optional: true
'@repeaterjs/repeater@3.0.4':
resolution: {integrity: sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==}
@ -2019,13 +1857,6 @@ packages:
'@telegram-apps/signals@1.1.0':
resolution: {integrity: sha512-5qN7cU8t3l7n0cKcnzc/1TYKJTwAggUinfwbLHL1SYmB47pBHjCvfsRiYliFohk6lb635SBmNuVZL6LHFmGZaw==}
'@telegram-apps/telegram-ui@2.1.8':
resolution: {integrity: sha512-Y4mIRzBJDerFvF6yzsfwHpu2tKEMHnnnQgdnLTwIdXNVPq/sJTaY66Qxbh9eeO5+tct01VcAx4E70/1fMvnp8A==}
engines: {node: '>=18.0.0', npm: '>=7.0.0'}
peerDependencies:
react: ^18.2.0
react-dom: ^18.2.0
'@telegram-apps/toolkit@1.0.0':
resolution: {integrity: sha512-fSVoveLuMzwRKWeXEufMSXxH+HvjsFKb1DeT3pG5qLpnb2rdtejnNcwAt6WEPtiZ3a4YntYaFuR3KYgVv0ZxeQ==}
@ -2054,9 +1885,6 @@ packages:
'@types/react-dom':
optional: true
'@twa-dev/types@7.10.0':
resolution: {integrity: sha512-BXHyNLXy+cPbOZ2qQq5ArPKcP4kUfuX3YBSFT0XUxtMNWAzvyMuYAiq59UTfQ8OnELXlfChrAoIT3c2pujBtcQ==}
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
@ -2305,12 +2133,6 @@ packages:
resolution: {integrity: sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==}
engines: {node: '>=8'}
'@xelene/vaul-with-scroll-fix@0.1.4':
resolution: {integrity: sha512-R9J7y92rzZKIQLtFHKtzRsb4x8G26cvwGIDSf7OQZCdROFt7xic4Yz1BlFYjm8oiQsYV4SFSQfOzatZjvxz5XQ==}
peerDependencies:
react: ^16.8 || ^17.0 || ^18.0
react-dom: ^16.8 || ^17.0 || ^18.0
acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@ -2377,10 +2199,6 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
aria-hidden@1.2.4:
resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
engines: {node: '>=10'}
aria-query@5.3.0:
resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
@ -2854,9 +2672,6 @@ packages:
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
engines: {node: '>=8'}
detect-node-es@1.1.0:
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
@ -3458,10 +3273,6 @@ packages:
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
engines: {node: '>= 0.4'}
get-nonce@1.0.1:
resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
engines: {node: '>=6'}
get-set-props@0.1.0:
resolution: {integrity: sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==}
engines: {node: '>=0.10.0'}
@ -4597,36 +4408,6 @@ packages:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
engines: {node: '>=0.10.0'}
react-remove-scroll-bar@2.3.6:
resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==}
engines: {node: '>=10'}
peerDependencies:
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
'@types/react':
optional: true
react-remove-scroll@2.6.0:
resolution: {integrity: sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==}
engines: {node: '>=10'}
peerDependencies:
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
'@types/react':
optional: true
react-style-singleton@2.2.1:
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
engines: {node: '>=10'}
peerDependencies:
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
'@types/react':
optional: true
react@19.0.0:
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
engines: {node: '>=0.10.0'}
@ -5331,31 +5112,11 @@ packages:
urlpattern-polyfill@8.0.2:
resolution: {integrity: sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==}
use-callback-ref@1.3.2:
resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==}
engines: {node: '>=10'}
peerDependencies:
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
'@types/react':
optional: true
use-intl@3.26.0:
resolution: {integrity: sha512-HGXmpjGlbEv1uFZPfm557LK8p/hv0pKF9UwnrJeHUTxQx6bUGzMgpmPRLCVY3zkr7hfjy4LPwQJfk4Fhnn+dIg==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
use-sidecar@1.1.2:
resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
engines: {node: '>=10'}
peerDependencies:
'@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
'@types/react':
optional: true
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@ -6576,23 +6337,6 @@ snapshots:
dependencies:
levn: 0.4.1
'@floating-ui/core@1.6.8':
dependencies:
'@floating-ui/utils': 0.2.8
'@floating-ui/dom@1.6.12':
dependencies:
'@floating-ui/core': 1.6.8
'@floating-ui/utils': 0.2.8
'@floating-ui/react-dom@2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@floating-ui/dom': 1.6.12
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
'@floating-ui/utils@0.2.8': {}
'@formatjs/ecma402-abstract@2.3.1':
dependencies:
'@formatjs/fast-memoize': 2.2.5
@ -7439,108 +7183,12 @@ snapshots:
dependencies:
playwright: 1.49.1
'@radix-ui/primitive@1.1.0': {}
'@radix-ui/react-compose-refs@1.1.0(@types/react@19.0.1)(react@19.0.0)':
dependencies:
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.1
'@radix-ui/react-context@1.1.1(@types/react@19.0.1)(react@19.0.0)':
dependencies:
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.1
'@radix-ui/react-dialog@1.1.2(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@radix-ui/primitive': 1.1.0
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-context': 1.1.1(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-id': 1.1.0(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-portal': 1.1.2(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-presence': 1.1.1(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-slot': 1.1.0(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.1)(react@19.0.0)
aria-hidden: 1.2.4
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
react-remove-scroll: 2.6.0(@types/react@19.0.1)(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.1
'@types/react-dom': 19.0.1
'@radix-ui/react-dismissable-layer@1.1.1(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@radix-ui/primitive': 1.1.0
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.0.1)(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.1
'@types/react-dom': 19.0.1
'@radix-ui/react-focus-guards@1.1.1(@types/react@19.0.1)(react@19.0.0)':
dependencies:
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.1
'@radix-ui/react-focus-scope@1.1.0(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.1)(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.1
'@types/react-dom': 19.0.1
'@radix-ui/react-id@1.1.0(@types/react@19.0.1)(react@19.0.0)':
dependencies:
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.1)(react@19.0.0)
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.1
'@radix-ui/react-portal@1.1.2(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.1)(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.1
'@types/react-dom': 19.0.1
'@radix-ui/react-presence@1.1.1(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.0.1)(react@19.0.0)
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.1)(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.1
'@types/react-dom': 19.0.1
'@radix-ui/react-primitive@2.0.0(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@radix-ui/react-slot': 1.1.0(@types/react@19.0.1)(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.1
'@types/react-dom': 19.0.1
'@radix-ui/react-slot@1.1.0(@types/react@19.0.1)(react@19.0.0)':
dependencies:
'@radix-ui/react-compose-refs': 1.1.0(@types/react@19.0.1)(react@19.0.0)
@ -7548,32 +7196,6 @@ snapshots:
optionalDependencies:
'@types/react': 19.0.1
'@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.1)(react@19.0.0)':
dependencies:
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.1
'@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.0.1)(react@19.0.0)':
dependencies:
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.1)(react@19.0.0)
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.1
'@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.0.1)(react@19.0.0)':
dependencies:
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.1)(react@19.0.0)
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.1
'@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.1)(react@19.0.0)':
dependencies:
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.1
'@repeaterjs/repeater@3.0.4': {}
'@repeaterjs/repeater@3.0.6': {}
@ -7683,18 +7305,6 @@ snapshots:
'@telegram-apps/signals@1.1.0': {}
'@telegram-apps/telegram-ui@2.1.8(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@swc/helpers': 0.5.13
'@twa-dev/types': 7.10.0
'@xelene/vaul-with-scroll-fix': 0.1.4(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
transitivePeerDependencies:
- '@types/react'
- '@types/react-dom'
'@telegram-apps/toolkit@1.0.0': {}
'@telegram-apps/transformers@1.2.0':
@ -7725,8 +7335,6 @@ snapshots:
'@types/react': 19.0.1
'@types/react-dom': 19.0.1
'@twa-dev/types@7.10.0': {}
'@types/aria-query@5.0.4': {}
'@types/babel__core@7.20.5':
@ -8073,15 +7681,6 @@ snapshots:
dependencies:
tslib: 2.8.1
'@xelene/vaul-with-scroll-fix@0.1.4(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@radix-ui/react-dialog': 1.1.2(@types/react-dom@19.0.1)(@types/react@19.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
transitivePeerDependencies:
- '@types/react'
- '@types/react-dom'
acorn-jsx@5.3.2(acorn@8.14.0):
dependencies:
acorn: 8.14.0
@ -8135,10 +7734,6 @@ snapshots:
argparse@2.0.1: {}
aria-hidden@1.2.4:
dependencies:
tslib: 2.8.1
aria-query@5.3.0:
dependencies:
dequal: 2.0.3
@ -8667,8 +8262,6 @@ snapshots:
detect-libc@2.0.3:
optional: true
detect-node-es@1.1.0: {}
didyoumean@1.2.2: {}
dir-glob@3.0.1:
@ -9542,8 +9135,6 @@ snapshots:
has-symbols: 1.0.3
hasown: 2.0.2
get-nonce@1.0.1: {}
get-set-props@0.1.0: {}
get-stream@8.0.1: {}
@ -10653,34 +10244,6 @@ snapshots:
react-refresh@0.14.2: {}
react-remove-scroll-bar@2.3.6(@types/react@19.0.1)(react@19.0.0):
dependencies:
react: 19.0.0
react-style-singleton: 2.2.1(@types/react@19.0.1)(react@19.0.0)
tslib: 2.8.1
optionalDependencies:
'@types/react': 19.0.1
react-remove-scroll@2.6.0(@types/react@19.0.1)(react@19.0.0):
dependencies:
react: 19.0.0
react-remove-scroll-bar: 2.3.6(@types/react@19.0.1)(react@19.0.0)
react-style-singleton: 2.2.1(@types/react@19.0.1)(react@19.0.0)
tslib: 2.8.1
use-callback-ref: 1.3.2(@types/react@19.0.1)(react@19.0.0)
use-sidecar: 1.1.2(@types/react@19.0.1)(react@19.0.0)
optionalDependencies:
'@types/react': 19.0.1
react-style-singleton@2.2.1(@types/react@19.0.1)(react@19.0.0):
dependencies:
get-nonce: 1.0.1
invariant: 2.2.4
react: 19.0.0
tslib: 2.8.1
optionalDependencies:
'@types/react': 19.0.1
react@19.0.0: {}
read-cache@1.0.0:
@ -11442,27 +11005,12 @@ snapshots:
urlpattern-polyfill@8.0.2: {}
use-callback-ref@1.3.2(@types/react@19.0.1)(react@19.0.0):
dependencies:
react: 19.0.0
tslib: 2.8.1
optionalDependencies:
'@types/react': 19.0.1
use-intl@3.26.0(react@19.0.0):
dependencies:
'@formatjs/fast-memoize': 2.2.5
intl-messageformat: 10.7.10
react: 19.0.0
use-sidecar@1.1.2(@types/react@19.0.1)(react@19.0.0):
dependencies:
detect-node-es: 1.1.0
react: 19.0.0
tslib: 2.8.1
optionalDependencies:
'@types/react': 19.0.1
util-deprecate@1.0.2: {}
validate-npm-package-license@3.0.4: