Skip to content

Latest commit

 

History

History

webui

Folders and files

README.md

MadelineProto web UI

The web pages of MadelineProto, the API ID setup (manual, or automatic through my.telegram.org), the login (phone number, bot token, QR code, 2FA password, signup) and the status pages, as a port of the auth pages of tweb (Telegram Web K): the same cards, the same stack (TypeScript, Solid, SCSS modules, Vite), MadelineProto's purple instead of Telegram's blue, and MadelineProto (PHP) as the backend instead of tweb's MTProto worker.

tweb is licensed under the GNU GPL v3, and so is this app (GPL-3.0-or-later): it's compatible with MadelineProto's AGPL v3 (section 13 of both). The files out of tweb keep its copyright header, with "Adapted for MadelineProto" on the ones that were changed.

Liquid glass

Every surface is made of liquid glass, over a slowly drifting field of purple, indigo, pink and blue light (components/liquidGlass.tsx, scss/glass/):

  • the material (scss/glass/_material.scss): a translucent tint over a blurred, saturated backdrop (backdrop-filter), a specular rim (a gradient border, bright where the light comes from), a caustic shadow; wells for the inputs and the code boxes, drops of tinted glass for the buttons and the logo, thick glass for the country dropdown;
  • refraction: on Chromium, the backdrop is also displaced through an SVG lens (#mp-glass-refraction), so the hairlines of the light field bend under the edges of the panes. The other engines drop a backdrop-filter with url() entirely, so it's only set behind html.glass-refraction;
  • the light follows the pointer over the card (--glass-x/--glass-y), except on touch screens and with reduced motion; the light field stops drifting with reduced motion;
  • with prefers-reduced-transparency or prefers-contrast: more, the panes are opaque, without refraction.

The tokens (tints, blurs, the colors of the light field) are CSS variables in scss/glass/_tokens.scss, for day and night: the rest of the theme is tweb's, with the purple accent of scss/theme.scss.

How it fits together

  • The PHP side builds each page as a view model (src/WebUI: Page, Field, Alert, Action) and renders it with native PHP templates (src/WebUI/templates, see TemplateEngine): that markup is for browsers without JavaScript. The page also embeds the view model as JSON (#madeline-state).
  • This app (built into src/WebUI/templates/assets/tweb/, served by MadelineProto's asset route ?madelineAsset=) renders the page as a tweb card, picked by Page::$view, and submits the same fields with fetch: the server answers with the next page. PROTOCOL.md is the contract.
  • Users customize the pages by overriding single templates from a directory of theirs: $settings->getTemplates()->addDirectory(__DIR__.'/templates') (an assets/tweb/app.js there replaces the app too).

What was ported, what was rewritten

Ported from tweb (src/, same paths as in tweb):

  • the auth flow: pages/authFlow.tsx (router and context), pages/AuthCardsHost.tsx (shell, theme button, card transitions), pages/AuthCard.tsx, pages/AuthCardError.tsx, pages/authFlow.module.scss, pages/sentCode.ts;
  • the cards: SignInCard (country picker and phone), AuthCodeCard (digit boxes or a secret word, the tracking monkey), PasswordCard (the peeking monkey), SignUpCard, SignQRCard (tweb's styled QR code);
  • the components and helpers they use: the input fields (telInputField, countryInputField, passwordInputField, codeInputField), mediaHeader, buttonTsx, ripple, autoHeight, putPreloader, the monkeys, formatPhoneNumber, paintQrCode, the DOM and scheduling helpers, the country list, and the SCSS (variables, mixins, inputs, buttons, ripple, preloader, Roboto).

Rewritten, because tweb's versions are tied to the rest of its app (its MTProto worker, storage, settings):

  • lib/transport.ts instead of tweb's managers: the POSTs and the QR code long poll of PROTOCOL.md;
  • lib/langPack.ts (a lite I18n, with tweb's formatter) and lang.ts (the English strings of the auth flow, out of tweb's lang.ts and langSign.ts, with MadelineProto's own);
  • components/inputField.ts (the same DOM and API, on a plain <input>), helpers/theme.ts and scss/theme.scss (static day and night palettes derived from one accent, instead of the themeController), lib/lottie/lottieLoader.ts (lottie-web instead of tweb's WASM player), components/icon.ts (the few glyphs as SVG instead of the 111 KB icon font), components/logo.tsx (MadelineProto's mark instead of Telegram's logo);
  • MadelineProto's own cards, in tweb's style: SignBotCard (bot token), ApiFormCard (the API ID setup, and any page without a card of its own), StatusCard.

Left out, because MadelineProto doesn't offer them through the web login: resending the code, the login email, editing the phone number, password recovery, account reset, passkeys, the language picker, the avatar upload.

Development

npm ci
npm run dev        # the pages of src/fixtures.ts with a mock server: /?view=login.signIn, /?view=api.auto...
npm test
npm run build      # writes src/WebUI/templates/assets/tweb/app.js and app.css: commit them

The build is committed, because Composer and the phar ship it without running npm; CI (tests/webui.sh) fails if it isn't the build of the committed sources (the build is deterministic).