From 642db67709feb927dea2db47108fb279dbef356d Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Sat, 1 May 2021 09:58:09 +0200 Subject: [PATCH] feat: Much better alias managing --- lib/l10n/intl_en.arb | 10 +++ lib/views/chat_details.dart | 134 ++++++++++++++++++++++++------ lib/views/ui/chat_details_ui.dart | 8 +- pubspec.lock | 4 +- 4 files changed, 122 insertions(+), 34 deletions(-) diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index a9552c37..3bf15d2c 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -16,6 +16,16 @@ "type": "text", "placeholders": {} }, + "editRoomAliases": "Edit room aliases", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "setAsCanonicalAlias": "Set as main alias", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, "people": "People", "@people": { "type": "text", diff --git a/lib/views/chat_details.dart b/lib/views/chat_details.dart index ec739176..29d893bb 100644 --- a/lib/views/chat_details.dart +++ b/lib/views/chat_details.dart @@ -6,6 +6,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:file_picker_cross/file_picker_cross.dart'; import 'package:fluffychat/views/ui/chat_details_ui.dart'; import 'package:fluffychat/views/widgets/matrix.dart'; +import 'package:flutter/services.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:fluffychat/utils/matrix_locals.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -13,6 +14,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:image_picker/image_picker.dart'; +enum AliasActions { copy, delete, setCanonical } + class ChatDetails extends StatefulWidget { final String roomId; @@ -61,7 +64,104 @@ class ChatDetailsController extends State { } } - void setCanonicalAliasAction(context) async { + void editAliases() async { + final room = Matrix.of(context).client.getRoomById(widget.roomId); + + // The current endpoint doesnt seem to be implemented in Synapse. This may + // change in the future and then we just need to switch to this api call: + // + // final aliases = await showFutureLoadingDialog( + // context: context, + // future: () => room.client.requestRoomAliases(room.id), + // ); + // + // While this is not working we use the unstable api: + final aliases = await showFutureLoadingDialog( + context: context, + future: () => room.client + .request( + RequestType.GET, + '/client/unstable/org.matrix.msc2432/rooms/${Uri.encodeComponent(room.id)}/aliases', + ) + .then((response) => List.from(response['aliases'])), + ); + // Switch to the stable api once it is implemented. + + if (aliases.error != null) return; + final adminMode = room.canSendEvent('m.room.canonical_alias'); + if (aliases.result.isEmpty && (room.canonicalAlias?.isNotEmpty ?? false)) { + aliases.result.add(room.canonicalAlias); + } + if (aliases.result.isEmpty && adminMode) { + return setAliasAction(); + } + final select = await showConfirmationDialog( + context: context, + title: L10n.of(context).editRoomAliases, + actions: [ + if (adminMode) + AlertDialogAction(label: L10n.of(context).create, key: 'new'), + ...aliases.result + .map((alias) => AlertDialogAction(key: alias, label: alias)) + .toList(), + ], + ); + if (select == null) return; + if (select == 'new') { + return setAliasAction(); + } + final option = await showConfirmationDialog( + context: context, + title: select, + actions: [ + AlertDialogAction( + label: L10n.of(context).copyToClipboard, + key: AliasActions.copy, + isDefaultAction: true, + ), + if (adminMode) ...{ + AlertDialogAction( + label: L10n.of(context).setAsCanonicalAlias, + key: AliasActions.setCanonical, + isDestructiveAction: true, + ), + AlertDialogAction( + label: L10n.of(context).delete, + key: AliasActions.delete, + isDestructiveAction: true, + ), + }, + ], + ); + switch (option) { + case AliasActions.copy: + await Clipboard.setData(ClipboardData(text: select)); + AdaptivePageLayout.of(context).showSnackBar( + SnackBar(content: Text(L10n.of(context).copiedToClipboard)), + ); + break; + case AliasActions.delete: + await showFutureLoadingDialog( + context: context, + future: () => room.client.removeRoomAlias(select), + ); + break; + case AliasActions.setCanonical: + await showFutureLoadingDialog( + context: context, + future: () => + room.client.sendState(room.id, EventTypes.RoomCanonicalAlias, { + 'alias': select, + }), + ); + break; + } + } + + void setAliasAction() async { + final room = Matrix.of(context).client.getRoomById(widget.roomId); + final domain = room.client.userID.domain; + final input = await showTextInputDialog( context: context, title: L10n.of(context).setInvitationLink, @@ -70,38 +170,18 @@ class ChatDetailsController extends State { useRootNavigator: false, textFields: [ DialogTextField( - hintText: '#localpart:domain', - initialText: L10n.of(context).alias.toLowerCase(), + prefixText: '#', + suffixText: domain, + hintText: L10n.of(context).alias, + initialText: room.canonicalAlias?.localpart, ) ], ); if (input == null) return; - final room = Matrix.of(context).client.getRoomById(widget.roomId); - final domain = room.client.userID.domain; - final canonicalAlias = '%23' + input.single + '%3A' + domain; - final aliasEvent = room.getState('m.room.aliases', domain); - final aliases = - aliasEvent != null ? aliasEvent.content['aliases'] ?? [] : []; - if (aliases.indexWhere((s) => s == canonicalAlias) == -1) { - final newAliases = List.from(aliases); - newAliases.add(canonicalAlias); - final response = await showFutureLoadingDialog( - context: context, - future: () => room.client.requestRoomAliasInformation(canonicalAlias), - ); - if (response.error != null) { - final success = await showFutureLoadingDialog( - context: context, - future: () => room.client.createRoomAlias(canonicalAlias, room.id), - ); - if (success.error != null) return; - } - } await showFutureLoadingDialog( context: context, - future: () => room.client.sendState(room.id, 'm.room.canonical_alias', { - 'alias': input.single, - }), + future: () => room.client + .createRoomAlias('#' + input.single + ':' + domain, room.id), ); } diff --git a/lib/views/ui/chat_details_ui.dart b/lib/views/ui/chat_details_ui.dart index 0bdb2b9a..a467195c 100644 --- a/lib/views/ui/chat_details_ui.dart +++ b/lib/views/ui/chat_details_ui.dart @@ -153,8 +153,7 @@ class ChatDetailsUI extends StatelessWidget { MatrixLocals(L10n.of(context)))), onTap: controller.setDisplaynameAction, ), - if (room.canSendEvent('m.room.canonical_alias') && - room.joinRules == JoinRules.public) + if (room.joinRules == JoinRules.public) ListTile( leading: CircleAvatar( backgroundColor: @@ -162,9 +161,8 @@ class ChatDetailsUI extends StatelessWidget { foregroundColor: Colors.grey, child: Icon(Icons.link_outlined), ), - onTap: () => - controller.setCanonicalAliasAction(context), - title: Text(L10n.of(context).setInvitationLink), + onTap: controller.editAliases, + title: Text(L10n.of(context).editRoomAliases), subtitle: Text( (room.canonicalAlias?.isNotEmpty ?? false) ? room.canonicalAlias diff --git a/pubspec.lock b/pubspec.lock index ad38f7e3..4b6d1968 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -216,7 +216,7 @@ packages: description: path: "." ref: main - resolved-ref: "71fdd28a8a644a9ca17c5e2546d51ebb135d31bc" + resolved-ref: "70ee808911f49f34bbc933859dfffd4b804f1b2e" url: "https://gitlab.com/famedly/famedlysdk.git" source: git version: "0.0.1" @@ -591,7 +591,7 @@ packages: name: matrix_api_lite url: "https://pub.dartlang.org" source: hosted - version: "0.2.4" + version: "0.2.6" matrix_link_text: dependency: transitive description: