feat: tela de apps com logos/menu de exclusao, correcao de tema nas mini apps e sidebar de navegacao
This commit is contained in:
@@ -21,6 +21,36 @@ The available apps page (`/rooms/apps`) lists the built-in apps (`tasks`,
|
||||
`accountdata`) under *Installed* once you install them, plus every app you
|
||||
import.
|
||||
|
||||
## Manifest (meta tags)
|
||||
|
||||
Before installing an app, TatuChat reads the `<meta>` tags of the document and
|
||||
uses them as the app's manifest. **Every tag listed below must be present** in
|
||||
the `<head>` of your document, even if the value is empty — except `id` and
|
||||
`name`, which must also be non-empty. An app that is missing any of these tags
|
||||
**cannot be installed**.
|
||||
|
||||
```html
|
||||
<meta name="mini-app-id" content="myapp">
|
||||
<meta name="mini-app-name" content="My App">
|
||||
<meta name="mini-app-category" content="productivity">
|
||||
<meta name="mini-app-description" content="What my app does">
|
||||
<meta name="mini-app-logo" content=""> <!-- empty is allowed -->
|
||||
<meta name="mini-app-in-chat" content="false"> <!-- true|false -->
|
||||
```
|
||||
|
||||
`mini-app-in-chat` must be `true` or `false` (empty defaults to `false`).
|
||||
Values are trimmed and read case-insensitively.
|
||||
|
||||
The `mini-app-id` is used **as the key in the account data store**: the app's
|
||||
store is persisted under `im.tatuchat.miniapps.data.<id>` and its HTML source
|
||||
under `im.tatuchat.miniapps.source.<id>`. It must be unique: ids of built-in
|
||||
apps (`tasks`, `accountdata`) are reserved and an already installed id cannot
|
||||
be reused. This id is also the `widgetId` your app must send in the bridge
|
||||
protocol.
|
||||
|
||||
The remaining fields are stored as metadata (`category`, `description`, `logo`,
|
||||
`inChat`) and shown in the *Apps* page.
|
||||
|
||||
## Talking to TatuChat
|
||||
|
||||
The host listens for `message` events. A channel app sends a request with
|
||||
@@ -64,10 +94,11 @@ function bridgeRequest(action, data) {
|
||||
window.addEventListener('message', function (event) {
|
||||
const msg = event.data;
|
||||
if (!msg || msg.api !== 'fromMiniApp' || !msg.requestId) return;
|
||||
if (msg.response === undefined) return;
|
||||
if (!_pending.has(msg.requestId)) return;
|
||||
const pending = _pending.get(msg.requestId);
|
||||
_pending.delete(msg.requestId);
|
||||
const response = msg.response || {};
|
||||
const response = msg.response;
|
||||
if (response.error) pending.reject(new Error(response.error));
|
||||
else pending.resolve(response.data);
|
||||
});
|
||||
@@ -121,18 +152,18 @@ only if `avatarDataUri` is absent.
|
||||
### `io.tatuchat.theme.get`
|
||||
|
||||
Resolves with the color palette currently used by TatuChat, so your app can
|
||||
match the ecosystem (light/dark aware). Colors are `#AARRGGBB` hex strings
|
||||
suitable for CSS.
|
||||
match the ecosystem (light/dark aware). Colors are `#RRGGBBAA` hex strings
|
||||
(CSS 8-digit order: red, green, blue, alpha) suitable for CSS.
|
||||
|
||||
```js
|
||||
const { palette } = await bridgeRequest('io.tatuchat.theme.get');
|
||||
// => {
|
||||
// brightness: 'light' | 'dark',
|
||||
// primary: '#FF00D084',
|
||||
// onPrimary: '#FF000000',
|
||||
// primaryContainer: '#FF...',
|
||||
// surface: '#FF...',
|
||||
// surfaceContainerLowest/Low/Container/High/Highest: '#FF...',
|
||||
// primary: '#00D084FF',
|
||||
// onPrimary: '#000000FF',
|
||||
// primaryContainer: '#00D08433',
|
||||
// surface: '#FEF7FF00',
|
||||
// surfaceContainerLowest/Low/Container/High/Highest: '#…',
|
||||
// secondary..., tertiary..., error...,
|
||||
// outline, outlineVariant, background, onBackground, onSurface, ...
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user