mirror of
https://github.com/krille-chan/fluffychat
synced 2024-09-10 03:05:14 +00:00
chore: Follow up manage room aliases
This commit is contained in:
parent
0684bb63ac
commit
4dbe85b278
3 changed files with 234 additions and 130 deletions
|
@ -2509,6 +2509,8 @@
|
|||
"@passwordIsWrong": {},
|
||||
"publicLink": "Public link",
|
||||
"@publicLink": {},
|
||||
"publicLinks": "Public links",
|
||||
"createNewLink": "Create new link",
|
||||
"joinSpace": "Join space",
|
||||
"@joinSpace": {},
|
||||
"publicSpaces": "Public spaces",
|
||||
|
|
|
@ -152,31 +152,76 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
|
|||
);
|
||||
}
|
||||
|
||||
void setCanonicalAlias() async {
|
||||
Future<void> addAlias() async {
|
||||
final domain = room.client.userID?.domain;
|
||||
if (domain == null) {
|
||||
throw Exception('userID or domain is null! This should never happen.');
|
||||
}
|
||||
|
||||
final input = await showTextInputDialog(
|
||||
context: context,
|
||||
title: L10n.of(context)!.editRoomAliases,
|
||||
cancelLabel: L10n.of(context)!.cancel,
|
||||
okLabel: L10n.of(context)!.ok,
|
||||
textFields: [
|
||||
DialogTextField(
|
||||
prefixText: '#',
|
||||
suffixText: room.client.userID!.domain!,
|
||||
initialText: room.canonicalAlias.localpart,
|
||||
suffixText: domain,
|
||||
hintText: L10n.of(context)!.alias,
|
||||
),
|
||||
],
|
||||
);
|
||||
final newAliasLocalpart = input?.singleOrNull?.trim();
|
||||
if (newAliasLocalpart == null || newAliasLocalpart.isEmpty) return;
|
||||
final aliasLocalpart = input?.singleOrNull?.trim();
|
||||
if (aliasLocalpart == null || aliasLocalpart.isEmpty) return;
|
||||
final alias = '#$aliasLocalpart:$domain';
|
||||
|
||||
final result = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => room.client.setRoomAlias(alias, room.id),
|
||||
);
|
||||
if (result.error != null) return;
|
||||
|
||||
final canonicalAliasConsent = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context)!.setAsCanonicalAlias,
|
||||
message: alias,
|
||||
okLabel: L10n.of(context)!.yes,
|
||||
cancelLabel: L10n.of(context)!.no,
|
||||
);
|
||||
|
||||
final altAliases = room
|
||||
.getState(EventTypes.RoomCanonicalAlias)
|
||||
?.content
|
||||
.tryGetList<String>('alt_aliases')
|
||||
?.toSet() ??
|
||||
{};
|
||||
if (room.canonicalAlias.isNotEmpty) altAliases.add(room.canonicalAlias);
|
||||
altAliases.add(alias);
|
||||
if (canonicalAliasConsent == OkCancelResult.ok) {
|
||||
altAliases.remove(alias);
|
||||
} else {
|
||||
altAliases.remove(room.canonicalAlias);
|
||||
}
|
||||
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => room.setCanonicalAlias(
|
||||
'#$newAliasLocalpart:${room.client.userID!.domain!}',
|
||||
future: () => room.client.setRoomStateWithKey(
|
||||
room.id,
|
||||
EventTypes.RoomCanonicalAlias,
|
||||
'',
|
||||
{
|
||||
'alias': canonicalAliasConsent == OkCancelResult.ok
|
||||
? alias
|
||||
: room.canonicalAlias,
|
||||
if (altAliases.isNotEmpty) 'alt_aliases': altAliases.toList(),
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void deleteAlias(String alias) => showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => room.client.deleteRoomAlias(alias),
|
||||
);
|
||||
|
||||
void setChatVisibilityOnDirectory(bool? visibility) async {
|
||||
if (visibility == null) return;
|
||||
setState(() {
|
||||
|
|
|
@ -23,157 +23,214 @@ class ChatAccessSettingsPageView extends StatelessWidget {
|
|||
body: MaxWidthBody(
|
||||
child: StreamBuilder<Object>(
|
||||
stream: room.onUpdate.stream,
|
||||
builder: (context, snapshot) => Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context)!.visibilityOfTheChatHistory,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
for (final historyVisibility in HistoryVisibility.values)
|
||||
RadioListTile<HistoryVisibility>.adaptive(
|
||||
title: Text(
|
||||
historyVisibility
|
||||
.getLocalizedString(MatrixLocals(L10n.of(context)!)),
|
||||
),
|
||||
value: historyVisibility,
|
||||
groupValue: room.historyVisibility,
|
||||
onChanged: controller.historyVisibilityLoading ||
|
||||
!room.canChangeHistoryVisibility
|
||||
? null
|
||||
: controller.setHistoryVisibility,
|
||||
),
|
||||
Divider(color: Theme.of(context).dividerColor),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context)!.whoIsAllowedToJoinThisGroup,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
for (final joinRule
|
||||
in JoinRules.values..remove(JoinRules.private))
|
||||
RadioListTile<JoinRules>.adaptive(
|
||||
title: Text(
|
||||
joinRule.localizedString(L10n.of(context)!),
|
||||
),
|
||||
value: joinRule,
|
||||
groupValue: room.joinRules,
|
||||
onChanged:
|
||||
controller.joinRulesLoading || !room.canChangeJoinRules
|
||||
? null
|
||||
: controller.setJoinRule,
|
||||
),
|
||||
Divider(color: Theme.of(context).dividerColor),
|
||||
if ({JoinRules.public, JoinRules.knock}
|
||||
.contains(room.joinRules)) ...[
|
||||
builder: (context, snapshot) {
|
||||
final canonicalAlias = room.canonicalAlias;
|
||||
final altAliases = room
|
||||
.getState(EventTypes.RoomCanonicalAlias)
|
||||
?.content
|
||||
.tryGetList<String>('alt_aliases') ??
|
||||
[];
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context)!.areGuestsAllowedToJoin,
|
||||
L10n.of(context)!.visibilityOfTheChatHistory,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
for (final guestAccess in GuestAccess.values)
|
||||
RadioListTile<GuestAccess>.adaptive(
|
||||
for (final historyVisibility in HistoryVisibility.values)
|
||||
RadioListTile<HistoryVisibility>.adaptive(
|
||||
title: Text(
|
||||
guestAccess
|
||||
historyVisibility
|
||||
.getLocalizedString(MatrixLocals(L10n.of(context)!)),
|
||||
),
|
||||
value: guestAccess,
|
||||
groupValue: room.guestAccess,
|
||||
onChanged: controller.guestAccessLoading ||
|
||||
!room.canChangeGuestAccess
|
||||
value: historyVisibility,
|
||||
groupValue: room.historyVisibility,
|
||||
onChanged: controller.historyVisibilityLoading ||
|
||||
!room.canChangeHistoryVisibility
|
||||
? null
|
||||
: controller.setGuestAccess,
|
||||
: controller.setHistoryVisibility,
|
||||
),
|
||||
Divider(color: Theme.of(context).dividerColor),
|
||||
FutureBuilder(
|
||||
future: room.client.getRoomVisibilityOnDirectory(room.id),
|
||||
builder: (context, snapshot) => SwitchListTile.adaptive(
|
||||
value: snapshot.data == Visibility.public,
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context)!.whoIsAllowedToJoinThisGroup,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
for (final joinRule in JoinRules.values)
|
||||
if (joinRule != JoinRules.private)
|
||||
RadioListTile<JoinRules>.adaptive(
|
||||
title: Text(
|
||||
joinRule.localizedString(L10n.of(context)!),
|
||||
),
|
||||
value: joinRule,
|
||||
groupValue: room.joinRules,
|
||||
onChanged: controller.joinRulesLoading ||
|
||||
!room.canChangeJoinRules
|
||||
? null
|
||||
: controller.setJoinRule,
|
||||
),
|
||||
Divider(color: Theme.of(context).dividerColor),
|
||||
if ({JoinRules.public, JoinRules.knock}
|
||||
.contains(room.joinRules)) ...[
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context)!.chatCanBeDiscoveredViaSearchOnServer(
|
||||
room.client.userID!.domain!,
|
||||
L10n.of(context)!.areGuestsAllowedToJoin,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
onChanged: controller.setChatVisibilityOnDirectory,
|
||||
),
|
||||
for (final guestAccess in GuestAccess.values)
|
||||
RadioListTile<GuestAccess>.adaptive(
|
||||
title: Text(
|
||||
guestAccess.getLocalizedString(
|
||||
MatrixLocals(L10n.of(context)!),
|
||||
),
|
||||
),
|
||||
value: guestAccess,
|
||||
groupValue: room.guestAccess,
|
||||
onChanged: controller.guestAccessLoading ||
|
||||
!room.canChangeGuestAccess
|
||||
? null
|
||||
: controller.setGuestAccess,
|
||||
),
|
||||
Divider(color: Theme.of(context).dividerColor),
|
||||
ListTile(
|
||||
title: Text(
|
||||
L10n.of(context)!.publicLinks,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.add_outlined),
|
||||
tooltip: L10n.of(context)!.createNewLink,
|
||||
onPressed: controller.addAlias,
|
||||
),
|
||||
),
|
||||
if (canonicalAlias.isNotEmpty)
|
||||
_AliasListTile(
|
||||
alias: canonicalAlias,
|
||||
onDelete: room.canChangeStateEvent(
|
||||
EventTypes.RoomCanonicalAlias,
|
||||
)
|
||||
? () => controller.deleteAlias(canonicalAlias)
|
||||
: null,
|
||||
isCanonicalAlias: true,
|
||||
),
|
||||
for (final alias in altAliases)
|
||||
_AliasListTile(
|
||||
alias: alias,
|
||||
onDelete: room.canChangeStateEvent(
|
||||
EventTypes.RoomCanonicalAlias,
|
||||
)
|
||||
? () => controller.deleteAlias(alias)
|
||||
: null,
|
||||
),
|
||||
Divider(color: Theme.of(context).dividerColor),
|
||||
FutureBuilder(
|
||||
future: room.client.getRoomVisibilityOnDirectory(room.id),
|
||||
builder: (context, snapshot) => SwitchListTile.adaptive(
|
||||
value: snapshot.data == Visibility.public,
|
||||
title: Text(
|
||||
L10n.of(context)!.chatCanBeDiscoveredViaSearchOnServer(
|
||||
room.client.userID!.domain!,
|
||||
),
|
||||
),
|
||||
onChanged: controller.setChatVisibilityOnDirectory,
|
||||
),
|
||||
),
|
||||
],
|
||||
ListTile(
|
||||
title: Text(L10n.of(context)!.globalChatId),
|
||||
subtitle: SelectableText(room.id),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.copy_outlined),
|
||||
onPressed: () => FluffyShare.share(room.id, context),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10n.of(context)!.publicLink),
|
||||
subtitle: room.canonicalAlias.isEmpty
|
||||
? Text(
|
||||
L10n.of(context)!.noPublicLinkHasBeenCreatedYet,
|
||||
style: const TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
),
|
||||
title: Text(L10n.of(context)!.roomVersion),
|
||||
subtitle: SelectableText(
|
||||
room
|
||||
.getState(EventTypes.RoomCreate)!
|
||||
.content
|
||||
.tryGet<String>('room_version') ??
|
||||
'Unknown',
|
||||
),
|
||||
trailing: room.canSendEvent(EventTypes.RoomTombstone)
|
||||
? IconButton(
|
||||
icon: const Icon(Icons.upgrade_outlined),
|
||||
onPressed: controller.updateRoomAction,
|
||||
)
|
||||
: Text(
|
||||
'https://matrix.to/#/${room.canonicalAlias}',
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
onTap: room.canChangeStateEvent(EventTypes.RoomCanonicalAlias)
|
||||
? controller.setCanonicalAlias
|
||||
: null,
|
||||
trailing: room.canonicalAlias.isEmpty
|
||||
? const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Icon(Icons.add),
|
||||
)
|
||||
: IconButton(
|
||||
icon: Icon(Icons.adaptive.share_outlined),
|
||||
onPressed: () => FluffyShare.share(
|
||||
'https://matrix.to/#/${room.canonicalAlias}',
|
||||
context,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
ListTile(
|
||||
title: Text(L10n.of(context)!.globalChatId),
|
||||
subtitle: SelectableText(room.id),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.copy_outlined),
|
||||
onPressed: () => FluffyShare.share(room.id, context),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(L10n.of(context)!.roomVersion),
|
||||
subtitle: SelectableText(
|
||||
room
|
||||
.getState(EventTypes.RoomCreate)!
|
||||
.content
|
||||
.tryGet<String>('room_version') ??
|
||||
'Unknown',
|
||||
),
|
||||
trailing: room.canSendEvent(EventTypes.RoomTombstone)
|
||||
? IconButton(
|
||||
icon: const Icon(Icons.upgrade_outlined),
|
||||
onPressed: controller.updateRoomAction,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _AliasListTile extends StatelessWidget {
|
||||
const _AliasListTile({
|
||||
required this.alias,
|
||||
required this.onDelete,
|
||||
this.isCanonicalAlias = false,
|
||||
});
|
||||
|
||||
final String alias;
|
||||
final void Function()? onDelete;
|
||||
final bool isCanonicalAlias;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
title: Row(
|
||||
children: [
|
||||
TextButton.icon(
|
||||
onPressed: () => FluffyShare.share(
|
||||
'https://matrix.to/#/$alias',
|
||||
context,
|
||||
),
|
||||
icon: isCanonicalAlias
|
||||
? const Icon(Icons.star)
|
||||
: const Icon(Icons.link_outlined),
|
||||
label: SelectableText(
|
||||
'https://matrix.to/#/$alias',
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: Theme.of(context).colorScheme.primary,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
],
|
||||
),
|
||||
trailing: onDelete != null
|
||||
? IconButton(
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
onPressed: onDelete,
|
||||
)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension JoinRulesDisplayString on JoinRules {
|
||||
String localizedString(L10n l10n) {
|
||||
switch (this) {
|
||||
|
|
Loading…
Reference in a new issue