Files
tatuchat/lib/config/miniapp_config.dart
Welton Moura 6c689d1f34
Some checks failed
Main Deploy Workflow / deploy_web (push) Has been cancelled
Main Deploy Workflow / deploy_playstore_internal (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
feat: tela de apps com logos/menu de exclusao, correcao de tema nas mini apps e sidebar de navegacao
2026-09-19 00:08:35 -03:00

162 lines
5.1 KiB
Dart

// SPDX-FileCopyrightText: 2019-Present Christian Kußowski
// SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat
//
// SPDX-License-Identifier: AGPL-3.0-or-later
import 'package:material_ui/material_ui.dart';
import 'package:matrix/matrix.dart';
import 'package:tatchat/l10n/l10n.dart';
import 'package:tatchat/utils/miniapp_store.dart';
/// ID of the built-in tasks example app.
const String miniAppTasksId = 'tasks';
/// ID of the built-in account data explorer app.
const String miniAppAccountDataId = 'accountdata';
/// Static registry of all built-in mini apps that ship with this build. A mini
/// app only shows up in the "Apps" page once the user installs it (see
/// [installedMiniApps]). Additionally to this list, users can import their own
/// single-file HTML apps which are resolved through [resolveMiniAppConfig].
const List<MiniAppConfig> availableMiniApps = [
MiniAppConfig(
id: miniAppTasksId,
icon: Icons.checklist_rounded,
color: Color(0xFF00D084),
category: 'productivity',
description:
'A simple task checklist that lives in your Matrix account data.',
inChat: false,
htmlAsset: 'assets/miniapps/tasks.html',
),
MiniAppConfig(
id: miniAppAccountDataId,
icon: Icons.storage_rounded,
color: Color(0xFF1F8EF1),
category: 'developer',
description: 'Read and edit the account data of your Matrix account.',
inChat: false,
htmlAsset: 'assets/miniapps/accountdata.html',
),
];
/// Declarative description of a mini app. The rendering is either a
/// self-contained HTML document loaded from [htmlAsset] (built-in apps) or
/// from [html] which is stored in the user's account data (imported apps).
class MiniAppConfig {
final String id;
final IconData icon;
final Color color;
final String? name;
final String? category;
final String? description;
/// Logo of the app: either an http(s) URL or a `data:` URI.
final String? logo;
/// Whether the mini app can run inside a chat room.
final bool inChat;
final String? htmlAsset;
final String? html;
const MiniAppConfig({
required this.id,
required this.icon,
required this.color,
this.name,
this.category,
this.description,
this.logo,
this.inChat = false,
this.htmlAsset,
this.html,
});
/// Config for a user-imported app whose HTML source is persisted in the
/// account data store.
MiniAppConfig.custom({
required String id,
String? name,
String? category,
String? description,
String? logo,
bool inChat = false,
String? html,
}) : this(
id: id,
icon: Icons.web_asset_rounded,
color: const Color(0xFF9C27B0),
name: name,
category: category,
description: description,
logo: logo,
inChat: inChat,
html: html,
);
bool get isCustom => html != null || htmlAsset == null;
/// Resolves the HTML source that should be rendered for this app. Returns a
/// bundled asset path for built-in apps or the raw HTML for imported apps.
String? get htmlSource => html ?? htmlAsset;
}
/// Resolves the config of a single installed app, whether it is built-in or
/// user-imported. Returns null if the app is not installed or not available.
MiniAppConfig? resolveMiniAppConfig(Client client, String appId) {
for (final app in availableMiniApps) {
if (app.id == appId) return app;
}
if (client.isMiniAppInstalled(appId)) {
final html = client.getMiniAppSource(appId);
if (html != null) {
return MiniAppConfig.custom(
id: appId,
name: client.getMiniAppName(appId),
category: client.getMiniAppCategory(appId),
description: client.getMiniAppDescription(appId),
logo: client.getMiniAppLogo(appId),
inChat: client.getMiniAppInChat(appId),
html: html,
);
}
}
return null;
}
/// Returns the configs of all installed apps: built-in ones plus the
/// user-imported ones. The visual order is: installed built-in apps first,
/// then imported apps.
List<MiniAppConfig> installedMiniAppConfigs(Client client) {
final installed = client.installedMiniApps;
return [
for (final app in availableMiniApps)
if (installed.contains(app.id)) app,
for (final id in installed)
if (!availableMiniApps.any((app) => app.id == id))
if (client.getMiniAppSource(id) != null)
MiniAppConfig.custom(
id: id,
name: client.getMiniAppName(id),
category: client.getMiniAppCategory(id),
description: client.getMiniAppDescription(id),
logo: client.getMiniAppLogo(id),
inChat: client.getMiniAppInChat(id),
html: client.getMiniAppSource(id),
),
];
}
/// Resolves the localized display name of a mini app configuration.
String miniAppName(BuildContext context, MiniAppConfig app) {
final customName = app.name;
if (customName != null && customName.isNotEmpty) return customName;
switch (app.id) {
case miniAppTasksId:
return L10n.of(context).tasks;
case miniAppAccountDataId:
return L10n.of(context).accountDataEditor;
default:
return app.id;
}
}