Compare commits
3 Commits
main
...
feature/tm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bc83446b5 | ||
|
|
12686f0712 | ||
|
|
c9cc19c704 |
@ -1,13 +1,22 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { UpdateProfile } from '@/components/auth';
|
import { UpdateProfile } from '@/components/auth';
|
||||||
import { BottomNav } from '@/components/navigation';
|
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';
|
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 (
|
return (
|
||||||
<>
|
<Provider>
|
||||||
<UpdateProfile />
|
<UpdateProfile />
|
||||||
<main className="grow">{children}</main>
|
<main className="grow">{children}</main>
|
||||||
<BottomNav />
|
<BottomNav />
|
||||||
</>
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,21 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { BackButton } from './back-button';
|
import { BackButton } from './back-button';
|
||||||
|
import { cn } from '@repo/ui/lib/utils';
|
||||||
|
import { isTMA } from '@telegram-apps/sdk-react';
|
||||||
|
|
||||||
type Props = { title: string | undefined };
|
type Props = { title: string | undefined };
|
||||||
|
|
||||||
export function PageHeader(props: Readonly<Props>) {
|
export function PageHeader(props: Readonly<Props>) {
|
||||||
|
const isTG = isTMA('simple');
|
||||||
|
|
||||||
return (
|
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">
|
<div
|
||||||
<BackButton />
|
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}
|
{props.title}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,2 +1,4 @@
|
|||||||
|
export * from './use-back-button';
|
||||||
export * from './use-client-once';
|
export * from './use-client-once';
|
||||||
export * from './use-did-mount';
|
export * from './use-did-mount';
|
||||||
|
export * from './use-viewport';
|
||||||
|
|||||||
36
apps/web/hooks/telegram/use-back-button.ts
Normal file
36
apps/web/hooks/telegram/use-back-button.ts
Normal 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;
|
||||||
|
}
|
||||||
12
apps/web/hooks/telegram/use-viewport.ts
Normal file
12
apps/web/hooks/telegram/use-viewport.ts
Normal 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;
|
||||||
|
}
|
||||||
5
apps/web/providers/empty.tsx
Normal file
5
apps/web/providers/empty.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { type PropsWithChildren } from 'react';
|
||||||
|
|
||||||
|
export function EmptyProvider({ children }: Readonly<PropsWithChildren>) {
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable sonarjs/function-return-type */
|
/* eslint-disable sonarjs/function-return-type */
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useClientOnce, useDidMount } from '@/hooks/telegram';
|
import { useBackButton, useClientOnce, useDidMount, useViewport } from '@/hooks/telegram';
|
||||||
import { setLocale } from '@/utils/i18n/locale';
|
import { setLocale } from '@/utils/i18n/locale';
|
||||||
import { init } from '@/utils/telegram/init';
|
import { init } from '@/utils/telegram/init';
|
||||||
import { initData, useSignal } from '@telegram-apps/sdk-react';
|
import { initData, useSignal } from '@telegram-apps/sdk-react';
|
||||||
@ -28,6 +28,9 @@ function RootInner({ children }: PropsWithChildren) {
|
|||||||
init(debug);
|
init(debug);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useViewport();
|
||||||
|
useBackButton();
|
||||||
|
|
||||||
const initDataUser = useSignal(initData.user);
|
const initDataUser = useSignal(initData.user);
|
||||||
|
|
||||||
// Set the user locale.
|
// Set the user locale.
|
||||||
|
|||||||
@ -1,17 +1,19 @@
|
|||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
/* eslint-disable promise/prefer-await-to-then */
|
/* eslint-disable promise/prefer-await-to-then */
|
||||||
|
|
||||||
import {
|
import {
|
||||||
backButton,
|
backButton,
|
||||||
$debug as debugSDK,
|
$debug as debugSDK,
|
||||||
initData,
|
initData,
|
||||||
init as initSDK,
|
init as initSDK,
|
||||||
miniApp,
|
miniApp,
|
||||||
|
swipeBehavior,
|
||||||
} from '@telegram-apps/sdk-react';
|
} from '@telegram-apps/sdk-react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the application and configures its dependencies.
|
* 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.
|
// Set @telegram-apps/sdk-react debug mode.
|
||||||
if (debug) debugSDK.set(debug);
|
if (debug) debugSDK.set(debug);
|
||||||
|
|
||||||
@ -20,10 +22,18 @@ export function init(debug: boolean): void {
|
|||||||
initSDK();
|
initSDK();
|
||||||
|
|
||||||
// Mount all components used in the project.
|
// Mount all components used in the project.
|
||||||
if (backButton.isSupported()) backButton.mount();
|
if (backButton.isSupported()) {
|
||||||
|
backButton.mount();
|
||||||
|
}
|
||||||
|
|
||||||
miniApp.mount();
|
miniApp.mount();
|
||||||
|
|
||||||
initData.restore();
|
initData.restore();
|
||||||
|
|
||||||
|
if (swipeBehavior.mount.isAvailable()) {
|
||||||
|
swipeBehavior.mount();
|
||||||
|
}
|
||||||
|
|
||||||
// Add Eruda if needed.
|
// Add Eruda if needed.
|
||||||
if (debug) import('eruda').then((library) => library.default.init()).catch(console.error);
|
if (debug) import('eruda').then((library) => library.default.init()).catch(console.error);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user