Compare commits

...

3 Commits

8 changed files with 94 additions and 9 deletions

View File

@ -1,13 +1,22 @@
'use client';
import { UpdateProfile } from '@/components/auth';
import { BottomNav } from '@/components/navigation';
import { EmptyProvider } from '@/providers/empty';
import { TelegramProvider } from '@/providers/telegram';
import { isTMA } from '@telegram-apps/sdk-react';
import { type PropsWithChildren } from 'react';
export default async function Layout({ children }: Readonly<PropsWithChildren>) {
export default function Layout({ children }: Readonly<PropsWithChildren>) {
const isTG = isTMA('simple');
const Provider = isTG ? TelegramProvider : EmptyProvider;
return (
<>
<Provider>
<UpdateProfile />
<main className="grow">{children}</main>
<BottomNav />
</>
</Provider>
);
}

View File

@ -1,13 +1,21 @@
'use client';
import { BackButton } from './back-button';
import { cn } from '@repo/ui/lib/utils';
import { isTMA } from '@telegram-apps/sdk-react';
type Props = { title: string | undefined };
export function PageHeader(props: Readonly<Props>) {
const isTG = isTMA('simple');
return (
<div className="sticky top-0 z-50 flex h-12 items-center rounded-b-lg bg-transparent px-2 font-bold tracking-wide backdrop-blur-md">
<BackButton />
<div
className={cn(
'sticky top-0 z-50 flex h-12 items-center rounded-b-lg bg-transparent font-bold tracking-wide backdrop-blur-md',
isTG ? 'px-4' : 'px-2',
)}
>
{!isTG && <BackButton />}
{props.title}
</div>
);

View File

@ -1,2 +1,4 @@
export * from './use-back-button';
export * from './use-client-once';
export * from './use-did-mount';
export * from './use-viewport';

View File

@ -0,0 +1,36 @@
'use client';
import { backButton } from '@telegram-apps/sdk-react';
import { usePathname, useRouter } from 'next/navigation';
import { useCallback, useEffect } from 'react';
export function useBackButton() {
const { back } = useRouter();
const pathname = usePathname();
const onBackClick = useCallback(() => {
if (pathname !== '/') {
back();
}
}, [pathname, back]);
useEffect(() => {
const off = backButton.onClick(onBackClick);
return off;
}, [onBackClick]);
useEffect(() => {
if (backButton.isMounted()) {
if (isRootLevelPage(pathname)) {
backButton.hide();
} else {
backButton.show();
}
}
}, [pathname]);
}
function isRootLevelPage(path: string) {
return path.split('/').filter(Boolean).length === 1;
}

View File

@ -0,0 +1,12 @@
import { useClientOnce } from './use-client-once';
import { swipeBehavior } from '@telegram-apps/sdk-react';
export function useViewport() {
useClientOnce(() => {
if (swipeBehavior.disableVertical.isAvailable()) {
swipeBehavior.disableVertical();
}
});
return null;
}

View File

@ -0,0 +1,5 @@
import { type PropsWithChildren } from 'react';
export function EmptyProvider({ children }: Readonly<PropsWithChildren>) {
return <>{children}</>;
}

View File

@ -1,7 +1,7 @@
/* eslint-disable sonarjs/function-return-type */
'use client';
import { useClientOnce, useDidMount } from '@/hooks/telegram';
import { useBackButton, useClientOnce, useDidMount, useViewport } from '@/hooks/telegram';
import { setLocale } from '@/utils/i18n/locale';
import { init } from '@/utils/telegram/init';
import { initData, useSignal } from '@telegram-apps/sdk-react';
@ -28,6 +28,9 @@ function RootInner({ children }: PropsWithChildren) {
init(debug);
});
useViewport();
useBackButton();
const initDataUser = useSignal(initData.user);
// Set the user locale.

View File

@ -1,17 +1,19 @@
/* eslint-disable no-console */
/* eslint-disable promise/prefer-await-to-then */
import {
backButton,
$debug as debugSDK,
initData,
init as initSDK,
miniApp,
swipeBehavior,
} from '@telegram-apps/sdk-react';
/**
* Initializes the application and configures its dependencies.
*/
export function init(debug: boolean): void {
export async function init(debug: boolean): Promise<void> {
// Set @telegram-apps/sdk-react debug mode.
if (debug) debugSDK.set(debug);
@ -20,10 +22,18 @@ export function init(debug: boolean): void {
initSDK();
// Mount all components used in the project.
if (backButton.isSupported()) backButton.mount();
if (backButton.isSupported()) {
backButton.mount();
}
miniApp.mount();
initData.restore();
if (swipeBehavior.mount.isAvailable()) {
swipeBehavior.mount();
}
// Add Eruda if needed.
if (debug) import('eruda').then((library) => library.default.init()).catch(console.error);
}