Skip to content

Commit

Permalink
Add TelegramUI
Browse files Browse the repository at this point in the history
  • Loading branch information
heyqbnk committed May 22, 2024
1 parent 5daae96 commit 8fd14d5
Show file tree
Hide file tree
Showing 14 changed files with 765 additions and 243 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"predeploy": "pnpm run build"
},
"dependencies": {
"@telegram-apps/telegram-ui": "^2.1.3",
"@tma.js/react-router-integration": "^2.0.0",
"@tma.js/sdk-react": "^2.1.4",
"@tonconnect/ui-react": "^2.0.2",
Expand Down
540 changes: 536 additions & 4 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

16 changes: 6 additions & 10 deletions src/components/DisplayData/DisplayData.css
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
.display-data__header {
font-weight: 400;
}

.display-data__line {
display: flex;
align-items: center;
margin-bottom: 8px;
gap: 10px;
flex-flow: wrap;
padding: 16px 24px;
}

.display-data__line-title {
border: 1px solid var(--tg-theme-accent-text-color);
background-color: var(--tg-theme-bg-color);
border-radius: 5px;
padding: 2px 8px 4px;
box-sizing: border-box;
color: var(--tg-theme-subtitle-text-color);
}

.display-data__line-value {
Expand Down
54 changes: 37 additions & 17 deletions src/components/DisplayData/DisplayData.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,60 @@
import { isRGB, type RGB as RGBType } from '@tma.js/sdk-react';
import { isRGB } from '@tma.js/sdk-react';
import {
Checkbox,
Section,
Subheadline,
Text,
} from '@telegram-apps/telegram-ui';
import type { FC, ReactNode } from 'react';

import { RGB } from '@/components/RGB/RGB.tsx';
import { Link } from '@/components/Link/Link.tsx';

import './DisplayData.css';

export interface DisplayDataRow {
title: string;
value?: RGBType | string | boolean | ReactNode;
}
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> = ({ rows }) => (
<div>
{rows.map(({ title, value }, idx) => {
export const DisplayData: FC<DisplayDataProps> = ({ header, rows }) => (
<Section>
{header && <Section.Header className="display-data__header">
{header}
</Section.Header>}
{rows.map((item, idx) => {
let valueNode: ReactNode;

if (value === undefined) {
if (item.value === undefined) {
valueNode = <i>empty</i>;
} else if (typeof value === 'string' && isRGB(value)) {
valueNode = <RGB color={value} />;
} else if (typeof value === 'boolean') {
valueNode = value ? '✔️' : '❌';
} else {
valueNode = value;
if ('type' in item) {
valueNode = <Link to={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 (
<div className="display-data__line" key={idx}>
<span className="display-data__line-title">{title}</span>
<span className="display-data__line-value">{valueNode}</span>
<Subheadline className="display-data__line-title" level={'2'}>{item.title}</Subheadline>
<Text className="display-data__line-value">{valueNode}</Text>
</div>
);
})}
</div>
</Section>
);
9 changes: 6 additions & 3 deletions src/components/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SDKProvider, useLaunchParams } from '@tma.js/sdk-react';
import { TonConnectUIProvider } from '@tonconnect/ui-react';
import { AppRoot } from '@telegram-apps/telegram-ui';
import { type FC, useEffect, useMemo } from 'react';

import { App } from '@/components/App.tsx';
Expand Down Expand Up @@ -35,9 +36,11 @@ const Inner: FC = () => {

return (
<TonConnectUIProvider manifestUrl={manifestUrl}>
<SDKProvider acceptCustomStyles debug={debug}>
<App/>
</SDKProvider>
<AppRoot>
<SDKProvider acceptCustomStyles debug={debug}>
<App/>
</SDKProvider>
</AppRoot>
</TonConnectUIProvider>
);
};
Expand Down
22 changes: 1 addition & 21 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,25 +1,5 @@
body {
font-family: -apple-system, BlinkMacSystemFont, 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
line-height: 1.5;

background: var(--tg-theme-secondary-bg-color, white);
color: var(--tg-theme-text-color, black);
}

blockquote {
padding: 0;
margin: 0;
}

blockquote p {
padding: 15px;
background: #eee;
border-radius: 5px;
}

pre {
overflow: auto;
}
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import ReactDOM from 'react-dom/client';

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

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

ReactDOM.createRoot(document.getElementById('root')!).render(<Root />);
60 changes: 36 additions & 24 deletions src/pages/IndexPage/IndexPage.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import { Section, Cell, Image } from '@telegram-apps/telegram-ui';
import type { FC } from 'react';

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

import tonSvg from './ton.svg';

import './IndexPage.css';

export const IndexPage: FC = () => (
<Page title="Home Page">
<p>
This page is a home page in this boilerplate. You can use the links below to visit other
pages with their own functionality.
</p>
<ul className="index-page__links">
{routes.map(({ path, title, icon }) => title && (
<li className="index-page__link-item" key={path}>
<Link className="index-page__link" to={path}>
{icon && (
<i className="index-page__link-icon">
{icon}
</i>
)}
{title}
</Link>
</li>
))}
</ul>
</Page>
);
export const IndexPage: FC = () => {
return (
<>
<Section
header="Features"
footer="You can use these pages to learn more about features, provided by Telegram Mini Apps and other useful projects"
>
<Link to="/ton-connect">
<Cell
before={<Image src={tonSvg} style={{ backgroundColor: '#007AFF' }}/>}
subtitle="Connect your TON wallet"
>
TON Connect
</Cell>
</Link>
</Section>
<Section
header="Application Launch Data"
footer="These pages help developer to learn more about current launch information"
>
<Link to="/init-data">
<Cell subtitle="User data, chat information, technical data">Init Data</Cell>
</Link>
<Link to="/launch-params">
<Cell subtitle="Platform identifier, Mini Apps version, etc.">Launch Parameters</Cell>
</Link>
<Link to="/theme-params">
<Cell subtitle="Telegram application palette information">Theme Parameters</Cell>
</Link>
</Section>
</>
);
};
1 change: 1 addition & 0 deletions src/pages/IndexPage/ton.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 21 additions & 53 deletions src/pages/InitDataPage/InitDataPage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { type FC, type ReactNode, useMemo } from 'react';
import { type FC, useMemo } from 'react';
import { useInitData, useLaunchParams, type User } from '@tma.js/sdk-react';
import { Placeholder } from '@telegram-apps/telegram-ui';

import { DisplayData, type DisplayDataRow } from '@/components/DisplayData/DisplayData.tsx';
import { Link } from '@/components/Link/Link.tsx';
import { Page } from '@/components/Page/Page.tsx';

import './InitDataPage.css';

Expand Down Expand Up @@ -77,57 +76,26 @@ export const InitDataPage: FC = () => {
];
}, [initData]);

let contentNode: ReactNode;

if (!initDataRows) {
contentNode = <i>Application was launched with missing init data</i>;
} else {
contentNode = (
<>
<div className="init-data-page__section">
<h2 className="init-data-page__section-title">Init data</h2>
<DisplayData rows={initDataRows} />
</div>

<div className="init-data-page__section">
<h2 className="init-data-page__section-title">User</h2>
{userRows
? <DisplayData rows={userRows} />
: <i>User information missing</i>}
</div>

<div className="init-data-page__section">
<h2 className="init-data-page__section-title">Receiver</h2>
{receiverRows
? <DisplayData rows={receiverRows} />
: <i>Receiver information missing</i>}
</div>

<div className="init-data-page__section">
<h2 className="init-data-page__section-title">Chat</h2>
{chatRows
? <DisplayData rows={chatRows} />
: <i>Chat information missing</i>}
</div>
</>
);
return (
<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>
)
}

return (
<Page
title="Init Data"
disclaimer={(
<>
This page displays application
{' '}
<Link to="https://docs.telegram-mini-apps.com/platform/init-data">
init data
</Link>
.
</>
)}
>
{contentNode}
</Page>
);
<>
<DisplayData header={'InitData'} rows={initDataRows}/>
{userRows && <DisplayData header={'User'} rows={userRows}/>}
{receiverRows && <DisplayData header={'Receiver'} rows={receiverRows}/>}
{chatRows && <DisplayData header={'Chat'} rows={chatRows}/>}
</>
)
};
25 changes: 25 additions & 0 deletions src/pages/LaunchParamsPage/LaunchParamsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@ import { Page } from '@/components/Page/Page.tsx';
export const LaunchParamsPage: FC = () => {
const lp = useLaunchParams();

return (
<DisplayData
header="Launch Params"
footer={
<>
This page displays application
{' '}
<Link to="https://docs.telegram-mini-apps.com/platform/launch-parameters">
launch parameters
</Link>
.
</>
}
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.showSettings },
{ title: 'tgWebAppData', type: 'link', value: '/init-data' },
{ title: 'tgWebAppThemeParams', type: 'link', value: '/theme-params' },
]}
/>
);

return (
<Page
title="Launch Params"
Expand Down
Loading

0 comments on commit 8fd14d5

Please sign in to comment.