Skip to content

Commit

Permalink
Update the template
Browse files Browse the repository at this point in the history
  • Loading branch information
heyqbnk committed Jun 23, 2024
1 parent 585834b commit d9350ca
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 267 deletions.
12 changes: 1 addition & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Mini Apps platform using the following technologies and libraries:
- [React](https://react.dev/)
- [TypeScript](https://www.typescriptlang.org/)
- [TON Connect](https://docs.ton.org/develop/dapps/ton-connect/overview)
- [@tma.js SDK](https://docs.telegram-mini-apps.com/packages/tma-js-sdk)
- [Telegram SDK](https://core.telegram.org/bots/webapps#initializing-mini-apps)
- [Telegram UI](https://github.com/Telegram-Mini-Apps/TelegramUI)
- [Vite](https://vitejs.dev/)

Expand Down Expand Up @@ -71,15 +71,6 @@ link (`http://localhost:5173/reactjs-template` in this example) in your browser:

![Application](assets/application.png)

It is important to note that some libraries in this template, such as `@tma.js/sdk`, are not
intended for use outside of Telegram.

Nevertheless, they appear to function properly. This is because the `src/mockEnv.ts` file, which is
imported in the application's entry point (`src/index.ts`), employs the `mockTelegramEnv` function
to simulate the Telegram environment. This trick convinces the application that it is running in a
Telegram-based environment. Therefore, be cautious not to use this function in production mode
unless you fully understand its implications.

### Run Inside Telegram

Although it is possible to run the application outside of Telegram, it is recommended to develop it
Expand Down Expand Up @@ -243,5 +234,4 @@ project's information.
## Useful Links

- [Platform documentation](https://docs.telegram-mini-apps.com/)
- [@tma.js/sdk-react documentation](https://docs.telegram-mini-apps.com/packages/tma-js-sdk-react)
- [Telegram developers community chat](https://t.me/devs)
74 changes: 12 additions & 62 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
},
"dependencies": {
"@telegram-apps/telegram-ui": "^2.1.4",
"@tma.js/react-router-integration": "^4.0.3",
"@tma.js/sdk-react": "^2.2.3",
"@tonconnect/ui-react": "^2.0.5",
"@twa-dev/sdk": "^7.0.0",
"eruda": "^3.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -35,7 +34,6 @@
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.1",
"gh-pages": "^6.1.1",
"globals": "^15.2.0",
"typescript": "^5.4.5",
"typescript-eslint": "^7.8.0",
"vite": "^5.2.11",
Expand Down
89 changes: 38 additions & 51 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,52 @@
import { useIntegration } from '@tma.js/react-router-integration';
import {
bindMiniAppCSSVars,
bindThemeParamsCSSVars,
bindViewportCSSVars,
initNavigator, useLaunchParams,
useMiniApp,
useThemeParams,
useViewport,
} from '@tma.js/sdk-react';
import WebApp from '@twa-dev/sdk';
import { AppRoot } from '@telegram-apps/telegram-ui';
import { type FC, useEffect, useMemo } from 'react';
import { type FC, useEffect } from 'react';
import {
Navigate,
Route,
Router,
BrowserRouter,
Routes,
useLocation,
useNavigate,
} from 'react-router-dom';

import { routes } from '@/navigation/routes.tsx';

export const App: FC = () => {
const lp = useLaunchParams();
const miniApp = useMiniApp();
const themeParams = useThemeParams();
const viewport = useViewport();

useEffect(() => {
return bindMiniAppCSSVars(miniApp, themeParams);
}, [miniApp, themeParams]);

useEffect(() => {
return bindThemeParamsCSSVars(themeParams);
}, [themeParams]);
function BackButtonManipulator() {
const location = useLocation();
const navigate = useNavigate();

useEffect(() => {
return viewport && bindViewportCSSVars(viewport);
}, [viewport]);
function onClick() {
navigate(-1);
}
WebApp.BackButton.onClick(onClick);

// Create new application navigator and attach it to the browser history, so it could modify
// it and listen to its changes.
const navigator = useMemo(() => initNavigator('app-navigation-state'), []);
const [location, reactNavigator] = useIntegration(navigator);
return () => WebApp.BackButton.offClick(onClick);
}, [navigate]);

// Don't forget to attach the navigator to allow it to control the BackButton state as well
// as browser history.
useEffect(() => {
navigator.attach();
return () => navigator.detach();
}, [navigator]);

return (
<AppRoot
appearance={miniApp.isDark ? 'dark' : 'light'}
platform={['macos', 'ios'].includes(lp.platform) ? 'ios' : 'base'}
>
<Router location={location} navigator={reactNavigator}>
<Routes>
{routes.map((route) => <Route key={route.path} {...route} />)}
<Route path='*' element={<Navigate to='/'/>}/>
</Routes>
</Router>
</AppRoot>
);
};
if (location.pathname === '/') {
WebApp.BackButton.isVisible && WebApp.BackButton.hide();
} else {
!WebApp.BackButton.isVisible && WebApp.BackButton.show();
}
}, [location]);

return null;
}

export const App: FC = () => (
<AppRoot
appearance={WebApp.colorScheme}
platform={['macos', 'ios'].includes(WebApp.platform) ? 'ios' : 'base'}
>
<BrowserRouter>
<BackButtonManipulator/>
<Routes>
{routes.map((route) => <Route key={route.path} {...route} />)}
<Route path='*' element={<Navigate to='/'/>}/>
</Routes>
</BrowserRouter>
</AppRoot>
);
5 changes: 3 additions & 2 deletions src/components/DisplayData/DisplayData.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { isRGB } from '@tma.js/sdk-react';
import { Cell, Checkbox, Section } from '@telegram-apps/telegram-ui';
import type { FC, ReactNode } from 'react';

Expand All @@ -25,13 +24,15 @@ export const DisplayData: FC<DisplayDataProps> = ({ header, rows }) => (
{rows.map((item, idx) => {
let valueNode: ReactNode;

console.log(item);

if (item.value === undefined) {
valueNode = <i>empty</i>;
} else {
if ('type' in item) {
valueNode = <Link to={item.value}>Open</Link>;
} else if (typeof item.value === 'string') {
valueNode = isRGB(item.value)
valueNode = item.value.match(/^#[a-f0-9]{3,6}$/i)
? <RGB color={item.value}/>
: item.value;
} else if (typeof item.value === 'boolean') {
Expand Down
10 changes: 4 additions & 6 deletions src/components/Link/Link.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { classNames, useUtils } from '@tma.js/sdk-react';
import { type FC, type MouseEventHandler, useCallback } from 'react';
import WebApp from '@twa-dev/sdk';
import { Link as RouterLink, type LinkProps } from 'react-router-dom';

import './Link.css';
Expand All @@ -10,8 +10,6 @@ export const Link: FC<LinkProps> = ({
to,
...rest
}) => {
const utils = useUtils();

const onClick = useCallback<MouseEventHandler<HTMLAnchorElement>>((e) => {
propsOnClick?.(e);

Expand All @@ -32,16 +30,16 @@ export const Link: FC<LinkProps> = ({

if (isExternal) {
e.preventDefault();
return utils.openLink(targetUrl.toString());
return WebApp.openLink(targetUrl.toString());
}
}, [to, propsOnClick, utils]);
}, [to, propsOnClick]);

return (
<RouterLink
{...rest}
to={to}
onClick={onClick}
className={classNames(className, 'link')}
className={[className, 'link'].filter(Boolean).join(' ')}
/>
);
};
5 changes: 2 additions & 3 deletions src/components/RGB/RGB.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { classNames, type RGB as RGBType } from '@tma.js/sdk-react';
import type { FC } from 'react';

import './RGB.css';

export type RGBProps = JSX.IntrinsicElements['div'] & {
color: RGBType;
color: string;
};

export const RGB: FC<RGBProps> = ({ color, className, ...rest }) => (
<span {...rest} className={classNames('rgb', className)}>
<span {...rest} className={['rgb', className].filter(Boolean).join(' ')}>
<i className='rgb__icon' style={{ backgroundColor: color }}/>
{color}
</span>
Expand Down
8 changes: 3 additions & 5 deletions src/components/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SDKProvider, useLaunchParams } from '@tma.js/sdk-react';
import { TonConnectUIProvider } from '@tonconnect/ui-react';
import { type FC, useEffect, useMemo } from 'react';
import WebApp from '@twa-dev/sdk';

import { App } from '@/components/App.tsx';
import { ErrorBoundary } from '@/components/ErrorBoundary.tsx';
Expand All @@ -21,7 +21,7 @@ const ErrorBoundaryError: FC<{ error: unknown }> = ({ error }) => (
);

const Inner: FC = () => {
const debug = useLaunchParams().startParam === 'debug';
const debug = WebApp.initDataUnsafe.start_param === 'debug';
const manifestUrl = useMemo(() => {
return new URL('tonconnect-manifest.json', window.location.href).toString();
}, []);
Expand All @@ -35,9 +35,7 @@ const Inner: FC = () => {

return (
<TonConnectUIProvider manifestUrl={manifestUrl}>
<SDKProvider acceptCustomStyles debug={debug}>
<App/>
</SDKProvider>
<App/>
</TonConnectUIProvider>
);
};
Expand Down
5 changes: 1 addition & 4 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import ReactDOM from 'react-dom/client';
import '@twa-dev/sdk';

import { Root } from '@/components/Root';

// Uncomment this import in case, you would like to develop the application even outside
// the Telegram application, just in your browser.
import './mockEnv.ts';

import '@telegram-apps/telegram-ui/dist/styles.css';
import './index.css';

Expand Down
Loading

0 comments on commit d9350ca

Please sign in to comment.