fix: Archive

This commit is contained in:
Krille 2023-01-08 12:32:35 +01:00
parent 8632154832
commit a1f60b7ff9
11 changed files with 89 additions and 53 deletions

View File

@ -94,6 +94,13 @@ class AppRoutes {
VWidget(
path: '/archive',
widget: const Archive(),
stackedRoutes: [
VWidget(
path: ':roomid',
widget: const Chat(),
buildTransition: _dynamicTransition,
),
],
),
VWidget(
path: '/newprivatechat',
@ -220,13 +227,25 @@ class AppRoutes {
),
],
),
VWidget(
VNester(
path: '/archive',
widget: const TwoColumnLayout(
mainView: Archive(),
sideView: EmptyPage(),
widgetBuilder: (child) => TwoColumnLayout(
mainView: const Archive(),
sideView: child,
),
buildTransition: _fadeTransition,
nestedRoutes: [
VWidget(
path: '',
widget: const EmptyPage(),
buildTransition: _dynamicTransition,
),
VWidget(
path: ':roomid',
widget: const Chat(),
buildTransition: _dynamicTransition,
),
],
),
],
),

View File

@ -21,11 +21,9 @@ class ArchiveController extends State<Archive> {
Future<List<Room>> getArchive(BuildContext context) async {
final archive = this.archive;
if (archive != null) return archive;
return await Matrix.of(context).client.loadArchive();
return this.archive = await Matrix.of(context).client.loadArchive();
}
void forgetAction(int i) => setState(() => archive?.removeAt(i));
void forgetAllAction() async {
final archive = this.archive;
if (archive == null) return;

View File

@ -21,10 +21,14 @@ class ArchiveView extends StatelessWidget {
leading: const BackButton(),
title: Text(L10n.of(context)!.archive),
actions: [
if (snapshot.hasData && archive != null && archive!.isNotEmpty)
TextButton(
if (snapshot.data?.isNotEmpty ?? false)
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton.icon(
onPressed: controller.forgetAllAction,
child: Text(L10n.of(context)!.clearArchive),
label: Text(L10n.of(context)!.clearArchive),
icon: const Icon(Icons.cleaning_services_outlined),
),
)
],
),
@ -50,7 +54,6 @@ class ArchiveView extends StatelessWidget {
itemCount: archive!.length,
itemBuilder: (BuildContext context, int i) => ChatListItem(
archive![i],
onForget: controller.forgetAction,
),
);
}

View File

@ -630,6 +630,7 @@ class ChatController extends State<Chat> {
}
bool get canRedactSelectedEvents {
if (isArchived) return false;
final clients = matrix!.currentBundle;
for (final event in selectedEvents) {
if (event.canRedact == false &&
@ -639,7 +640,9 @@ class ChatController extends State<Chat> {
}
bool get canEditSelectedEvents {
if (selectedEvents.length != 1 || !selectedEvents.first.status.isSent) {
if (isArchived ||
selectedEvents.length != 1 ||
!selectedEvents.first.status.isSent) {
return false;
}
return currentRoomBundle
@ -757,6 +760,15 @@ class ChatController extends State<Chat> {
return sendEmojiAction(emoji.emoji);
}
void forgetRoom() async {
final result = await showFutureLoadingDialog(
context: context,
future: room!.forget,
);
if (result.error != null) return;
VRouter.of(context).to('/archive');
}
void typeEmoji(Emoji? emoji) {
if (emoji == null) return;
final text = sendController.text;
@ -1008,6 +1020,9 @@ class ChatController extends State<Chat> {
setState(() => inputText = text);
}
bool get isArchived =>
{Membership.leave, Membership.ban}.contains(room?.membership);
void showEventInfo([Event? event]) =>
(event ?? selectedEvents.single).showInfoDialog(context);

View File

@ -37,7 +37,10 @@ class ChatAppBarTitle extends StatelessWidget {
'${room.unsafeGetUserFromMemoryOrFallback(directChatMatrixID).mention} ',
),
)
: () => VRouter.of(context).toSegments(['rooms', room.id, 'details']),
: controller.isArchived
? null
: () =>
VRouter.of(context).toSegments(['rooms', room.id, 'details']),
child: Row(
children: [
Hero(

View File

@ -108,6 +108,20 @@ class ChatView extends StatelessWidget {
],
),
];
} else if (controller.isArchived) {
return [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton.icon(
onPressed: controller.forgetRoom,
style: TextButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.error,
),
icon: const Icon(Icons.delete_forever_outlined),
label: Text(L10n.of(context)!.delete),
),
)
];
} else {
return [
if (Matrix.of(context).voipPlugin != null &&

View File

@ -21,10 +21,11 @@ class PinnedEvents extends StatelessWidget {
BuildContext context, List<Event?> events) async {
final eventId = events.length == 1
? events.single?.eventId
: await showModalActionSheet<String>(
: await showConfirmationDialog<String>(
context: context,
title: L10n.of(context)!.pinMessage,
actions: events
.map((event) => SheetAction(
.map((event) => AlertDialogAction(
key: event?.eventId ?? '',
label: event?.calcLocalizedBodyFallback(
MatrixLocals(L10n.of(context)!),

View File

@ -21,7 +21,6 @@ class ChatListItem extends StatelessWidget {
final Room room;
final bool activeChat;
final bool selected;
final Function? onForget;
final void Function()? onTap;
final void Function()? onLongPress;
@ -31,7 +30,6 @@ class ChatListItem extends StatelessWidget {
this.selected = false,
this.onTap,
this.onLongPress,
this.onForget,
Key? key,
}) : super(key: key);
@ -62,35 +60,7 @@ class ChatListItem extends StatelessWidget {
}
if (room.membership == Membership.leave) {
final action = await showModalActionSheet<ArchivedRoomAction>(
context: context,
title: L10n.of(context)!.archivedRoom,
message: L10n.of(context)!.thisRoomHasBeenArchived,
actions: [
SheetAction(
label: L10n.of(context)!.rejoin,
key: ArchivedRoomAction.rejoin,
),
SheetAction(
label: L10n.of(context)!.delete,
key: ArchivedRoomAction.delete,
isDestructiveAction: true,
),
],
);
if (action != null) {
switch (action) {
case ArchivedRoomAction.delete:
await archiveAction(context);
break;
case ArchivedRoomAction.rejoin:
await showFutureLoadingDialog(
context: context,
future: () => room.join(),
);
break;
}
}
VRouter.of(context).toSegments(['archive', room.id]);
}
if (room.membership == Membership.join) {
@ -122,13 +92,10 @@ class ChatListItem extends StatelessWidget {
Future<void> archiveAction(BuildContext context) async {
{
if ([Membership.leave, Membership.ban].contains(room.membership)) {
final success = await showFutureLoadingDialog(
await showFutureLoadingDialog(
context: context,
future: () => room.forget(),
);
if (success.error == null) {
if (onForget != null) onForget!();
}
return;
}
final confirmed = await showOkCancelAlertDialog(

View File

@ -66,6 +66,16 @@ class ClientChooserButton extends StatelessWidget {
],
),
),
PopupMenuItem(
value: SettingsAction.archive,
child: Row(
children: [
const Icon(Icons.archive_outlined),
const SizedBox(width: 18),
Text(L10n.of(context)!.archive),
],
),
),
PopupMenuItem(
value: SettingsAction.settings,
child: Row(
@ -259,6 +269,9 @@ class ClientChooserButton extends StatelessWidget {
case SettingsAction.settings:
VRouter.of(context).to('/settings');
break;
case SettingsAction.archive:
VRouter.of(context).to('/archive');
break;
}
}
}
@ -336,4 +349,5 @@ enum SettingsAction {
newSpace,
invite,
settings,
archive,
}

View File

@ -8,12 +8,14 @@ Future<T?> showAdaptiveBottomSheet<T>({
required BuildContext context,
required Widget Function(BuildContext) builder,
bool isDismissible = true,
bool isScrollControlled = false,
}) =>
showModalBottomSheet(
context: context,
builder: builder,
useRootNavigator: !PlatformInfos.isMobile,
isDismissible: isDismissible,
isScrollControlled: isScrollControlled,
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height - 128,
maxWidth: FluffyThemes.columnWidth * 1.5,

View File

@ -29,12 +29,12 @@ extension on PermissionLevel {
Future<int?> showPermissionChooser(BuildContext context,
{int currentLevel = 0}) async {
final permissionLevel = await showModalActionSheet(
final permissionLevel = await showConfirmationDialog(
context: context,
title: L10n.of(context)!.setPermissionsLevel,
actions: PermissionLevel.values
.map(
(level) => SheetAction(
(level) => AlertDialogAction(
key: level,
label: level.toLocalizedString(context),
),