127 lines
4.0 KiB
Dart
127 lines
4.0 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),
|
|
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;
|
|
}
|
|
} |