feat: mini apps customizados com importacao por arquivo/URL, paleta de cores, avatar autenticado e documentacao
This commit is contained in:
127
lib/config/miniapp_config.dart
Normal file
127
lib/config/miniapp_config.dart
Normal file
@@ -0,0 +1,127 @@
|
||||
// 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),
|
||||
htmlAsset: 'assets/miniapps/tasks.html',
|
||||
),
|
||||
MiniAppConfig(
|
||||
id: miniAppAccountDataId,
|
||||
icon: Icons.storage_rounded,
|
||||
color: Color(0xFF1F8EF1),
|
||||
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? htmlAsset;
|
||||
final String? html;
|
||||
|
||||
const MiniAppConfig({
|
||||
required this.id,
|
||||
required this.icon,
|
||||
required this.color,
|
||||
this.name,
|
||||
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? html,
|
||||
}) : this(
|
||||
id: id,
|
||||
icon: Icons.web_asset_rounded,
|
||||
color: const Color(0xFF9C27B0),
|
||||
name: name,
|
||||
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),
|
||||
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),
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user