256 lines
7.8 KiB
Dart
256 lines
7.8 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:async/async.dart';
|
|
import 'package:tatchat/l10n/l10n.dart';
|
|
import 'package:tatchat/widgets/avatar.dart';
|
|
import 'package:tatchat/widgets/matrix.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:material_ui/material_ui.dart';
|
|
import 'package:matrix/matrix.dart' hide Result;
|
|
import 'package:url_launcher/url_launcher_string.dart';
|
|
|
|
import 'package:tatchat/utils/tatu_share.dart';
|
|
import 'chat_list.dart';
|
|
|
|
class ClientChooserButton extends StatelessWidget {
|
|
final ChatListController controller;
|
|
|
|
const ClientChooserButton(this.controller, {super.key});
|
|
|
|
List<PopupMenuEntry<Object>> _bundleMenuItems(BuildContext context) {
|
|
final matrix = Matrix.of(context);
|
|
final bundles = matrix.accountBundles.keys.toList()
|
|
..sort(
|
|
(a, b) => a!.isValidMatrixIdStrict() == b!.isValidMatrixIdStrict()
|
|
? 0
|
|
: a.isValidMatrixIdStrict() && !b.isValidMatrixIdStrict()
|
|
? -1
|
|
: 1,
|
|
);
|
|
return <PopupMenuEntry<Object>>[
|
|
PopupMenuItem(
|
|
value: SettingsAction.newGroup,
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.group_add_outlined),
|
|
const SizedBox(width: 18),
|
|
Text(L10n.of(context).createGroup),
|
|
],
|
|
),
|
|
),
|
|
PopupMenuItem(
|
|
value: SettingsAction.setStatus,
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.edit_outlined),
|
|
const SizedBox(width: 18),
|
|
Text(L10n.of(context).setStatus),
|
|
],
|
|
),
|
|
),
|
|
PopupMenuItem(
|
|
value: SettingsAction.invite,
|
|
child: Row(
|
|
children: [
|
|
Icon(Icons.adaptive.share_outlined),
|
|
const SizedBox(width: 18),
|
|
Text(L10n.of(context).inviteContact),
|
|
],
|
|
),
|
|
),
|
|
PopupMenuItem(
|
|
value: SettingsAction.archive,
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.archive_outlined),
|
|
const SizedBox(width: 18),
|
|
Text(L10n.of(context).archive),
|
|
],
|
|
),
|
|
),
|
|
PopupMenuItem(
|
|
value: SettingsAction.apps,
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.apps_outlined),
|
|
const SizedBox(width: 18),
|
|
Text(L10n.of(context).apps),
|
|
],
|
|
),
|
|
),
|
|
PopupMenuItem(
|
|
value: SettingsAction.settings,
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.settings_outlined),
|
|
const SizedBox(width: 18),
|
|
Text(L10n.of(context).settings),
|
|
],
|
|
),
|
|
),
|
|
PopupMenuItem(
|
|
value: SettingsAction.support,
|
|
child: Row(
|
|
children: [
|
|
Icon(Icons.favorite, color: Colors.red),
|
|
const SizedBox(width: 18),
|
|
Text(L10n.of(context).supportFluffyChat),
|
|
],
|
|
),
|
|
),
|
|
const PopupMenuDivider(),
|
|
for (final bundle in bundles) ...[
|
|
if (matrix.accountBundles[bundle]!.length != 1 ||
|
|
matrix.accountBundles[bundle]!.single!.userID != bundle)
|
|
PopupMenuItem(
|
|
value: null,
|
|
child: Column(
|
|
crossAxisAlignment: .start,
|
|
mainAxisSize: .min,
|
|
children: [
|
|
Text(
|
|
bundle!,
|
|
style: TextStyle(
|
|
color: Theme.of(context).textTheme.titleMedium!.color,
|
|
fontSize: 14,
|
|
),
|
|
),
|
|
const Divider(height: 1),
|
|
],
|
|
),
|
|
),
|
|
...matrix.accountBundles[bundle]!
|
|
.whereType<Client>()
|
|
.where((client) => client.isLogged())
|
|
.map(
|
|
(client) => PopupMenuItem(
|
|
value: client,
|
|
child: FutureBuilder<Profile?>(
|
|
future: client.fetchOwnProfile(),
|
|
builder: (context, snapshot) {
|
|
final displayname =
|
|
snapshot.data?.displayName ?? client.userID!.localpart!;
|
|
return Row(
|
|
key: ValueKey('switch_account_$displayname'),
|
|
children: [
|
|
Avatar(
|
|
mxContent: snapshot.data?.avatarUrl,
|
|
name: displayname,
|
|
size: 32,
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Text(
|
|
displayname,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
IconButton(
|
|
icon: const Icon(Icons.edit_outlined),
|
|
onPressed: () => controller.editBundlesForAccount(
|
|
client.userID,
|
|
bundle,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
],
|
|
PopupMenuItem(
|
|
value: SettingsAction.addAccount,
|
|
child: Row(
|
|
children: [
|
|
const Icon(Icons.person_add_outlined),
|
|
const SizedBox(width: 18),
|
|
Text(L10n.of(context).addAccount),
|
|
],
|
|
),
|
|
),
|
|
];
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final matrix = Matrix.of(context);
|
|
final client = Result(() => matrix.client).asValue?.value;
|
|
|
|
var clientCount = 0;
|
|
matrix.accountBundles.forEach((key, value) => clientCount += value.length);
|
|
return FutureBuilder<Profile>(
|
|
future: client?.isLogged() == true ? client?.fetchOwnProfile() : null,
|
|
builder: (context, snapshot) => Material(
|
|
clipBehavior: Clip.hardEdge,
|
|
borderRadius: BorderRadius.circular(99),
|
|
color: Colors.transparent,
|
|
child: PopupMenuButton<Object>(
|
|
key: Key('accounts_and_settings_buttons'),
|
|
tooltip: L10n.of(context).accountsAndSettings,
|
|
onSelected: (o) => _clientSelected(o, context),
|
|
itemBuilder: _bundleMenuItems,
|
|
icon: Avatar(
|
|
mxContent: snapshot.data?.avatarUrl,
|
|
name: snapshot.data?.displayName ?? client?.userID?.localpart,
|
|
size: 32,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> _clientSelected(Object object, BuildContext context) async {
|
|
if (object is Client) {
|
|
controller.setActiveClient(object);
|
|
} else if (object is String) {
|
|
controller.setActiveBundle(object);
|
|
} else if (object is SettingsAction) {
|
|
switch (object) {
|
|
case SettingsAction.addAccount:
|
|
if (!context.mounted) return;
|
|
context.go('/rooms/settings/addaccount');
|
|
break;
|
|
case SettingsAction.newGroup:
|
|
context.go('/rooms/newgroup');
|
|
break;
|
|
case SettingsAction.invite:
|
|
TatuShare.shareInviteLink(context);
|
|
break;
|
|
case SettingsAction.support:
|
|
launchUrlString(
|
|
'https://ko-fi.com/post/How-can-I-support-FluffyChat-J2G325WE6I',
|
|
);
|
|
break;
|
|
case SettingsAction.settings:
|
|
context.go('/rooms/settings');
|
|
break;
|
|
case SettingsAction.archive:
|
|
context.go('/rooms/archive');
|
|
break;
|
|
case SettingsAction.apps:
|
|
context.go('/rooms/apps');
|
|
break;
|
|
case SettingsAction.setStatus:
|
|
controller.setStatus();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
enum SettingsAction {
|
|
addAccount,
|
|
newGroup,
|
|
setStatus,
|
|
invite,
|
|
support,
|
|
settings,
|
|
archive,
|
|
apps,
|
|
}
|