Skip to content

Commit 0099a66

Browse files
authored
chore: improve edits of replies, more future loading dialogs (#74)
1 parent 17d4986 commit 0099a66

19 files changed

+467
-350
lines changed

lib/chat_master/view/chat_space_filter.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import 'package:flutter/material.dart';
2-
import 'package:matrix/matrix.dart';
32
import 'package:watch_it/watch_it.dart';
43
import 'package:yaru/yaru.dart';
54

6-
import '../../common/view/ui_constants.dart';
75
import '../../common/chat_model.dart';
86
import '../../common/search_model.dart';
97
import '../../common/view/chat_avatar.dart';
8+
import '../../common/view/ui_constants.dart';
109

1110
class ChatSpaceFilter extends StatelessWidget with WatchItMixin {
1211
const ChatSpaceFilter({super.key});
@@ -20,8 +19,9 @@ class ChatSpaceFilter extends StatelessWidget with WatchItMixin {
2019
watchStream(
2120
(ChatModel m) => m.spacesStream,
2221
initialValue: chatModel.spaces,
22+
preserveState: false,
2323
).data ??
24-
<Room>[];
24+
chatModel.spaces;
2525

2626
return Padding(
2727
padding: const EdgeInsets.symmetric(horizontal: kMediumPlusPadding),

lib/chat_room/create_or_edit/chat_create_or_edit_room_dialog.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ class _ChatCreateOrEditRoomDialogState
320320
),
321321
),
322322
),
323-
if (_existingGroup && widget.room!.canChangePowerLevel)
323+
if (_existingGroup)
324324
SliverPadding(
325325
padding: const EdgeInsets.symmetric(
326326
horizontal: kBigPadding,

lib/chat_room/create_or_edit/chat_room_history_visibility_drop_down.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:matrix/matrix.dart';
44
import 'package:watch_it/watch_it.dart';
55
import 'package:yaru/yaru.dart';
66
import '../../common/chat_model.dart';
7+
import '../../common/view/snackbars.dart';
78
import '../../common/view/ui_constants.dart';
89
import '../../l10n/app_localizations.dart';
910
import '../../l10n/l10n.dart';
@@ -46,7 +47,12 @@ class ChatRoomHistoryVisibilityDropDown extends StatelessWidget
4647
onSelected: canChangeHistoryVisibility
4748
? (v) => showFutureLoadingDialog(
4849
context: context,
49-
future: () => room.setHistoryVisibility(v),
50+
future: () =>
51+
di<ChatModel>().setHistoryVisibility(room: room, value: v),
52+
onError: (e) {
53+
showSnackBar(context, content: Text(e.toString()));
54+
return e;
55+
},
5056
)
5157
: null,
5258
itemBuilder: (context) => HistoryVisibility.values

lib/chat_room/create_or_edit/chat_room_join_rules_drop_down.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:watch_it/watch_it.dart';
55
import 'package:yaru/yaru.dart';
66

77
import '../../common/chat_model.dart';
8+
import '../../common/view/snackbars.dart';
89
import '../../common/view/ui_constants.dart';
910
import '../../l10n/app_localizations.dart';
1011
import '../../l10n/l10n.dart';
@@ -47,7 +48,12 @@ class ChatRoomJoinRulesDropDown extends StatelessWidget with WatchItMixin {
4748
onSelected: canChangeJoinRules
4849
? (v) => showFutureLoadingDialog(
4950
context: context,
50-
future: () => room.setJoinRules(v),
51+
onError: (e) {
52+
showErrorSnackBar(context, e);
53+
return e;
54+
},
55+
future: () =>
56+
di<ChatModel>().setJoinRules(room: room, value: v),
5157
)
5258
: null,
5359
itemBuilder: (context) => JoinRules.values

lib/chat_room/create_or_edit/chat_room_permissions.dart

Lines changed: 65 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import 'package:flutter/material.dart';
2+
import 'package:future_loading_dialog/future_loading_dialog.dart';
23
import 'package:matrix/matrix.dart';
34
import 'package:watch_it/watch_it.dart';
45
import 'package:yaru/yaru.dart';
56

67
import '../../common/chat_model.dart';
78
import '../../common/view/build_context_x.dart';
8-
import '../../common/view/confirm.dart';
99
import '../../common/view/snackbars.dart';
1010
import '../../common/view/ui_constants.dart';
1111
import '../../l10n/l10n.dart';
@@ -23,6 +23,16 @@ class ChatPermissionsSettingsView extends StatelessWidget with WatchItMixin {
2323
final l10n = context.l10n;
2424
final chatModel = di<ChatModel>();
2525

26+
final canChangePowerLevel =
27+
watchStream(
28+
(ChatModel m) => m
29+
.getJoinedRoomUpdate(room.id)
30+
.map((_) => room.canChangePowerLevel),
31+
initialValue: room.canChangePowerLevel,
32+
preserveState: false,
33+
).data ??
34+
room.canChangePowerLevel;
35+
2636
final powerLevelsContent =
2737
watchStream(
2838
(ChatModel m) => m.getPermissionsStream(room),
@@ -63,20 +73,21 @@ class ChatPermissionsSettingsView extends StatelessWidget with WatchItMixin {
6373
children: [
6474
for (final entry in powerLevels.entries)
6575
_ChatRoomPermissionTile(
76+
canEdit: canChangePowerLevel,
6677
permissionKey: entry.key,
6778
permission: entry.value,
68-
onChanged: (level) => chatModel.editPowerLevel(
69-
room: room,
70-
key: entry.key,
71-
newLevel: level,
72-
onFail: () =>
73-
showSnackBar(context, content: Text(l10n.noPermission)),
74-
onCustomPermissionsChosen: () => _showPermissionChooser(
75-
context,
76-
currentLevel: entry.value,
79+
onChanged: (level) => showFutureLoadingDialog(
80+
context: context,
81+
onError: (e) {
82+
showSnackBar(context, content: Text(e.toString()));
83+
return e;
84+
},
85+
future: () => chatModel.editPowerLevel(
86+
room: room,
87+
key: entry.key,
88+
newLevel: level,
7789
),
7890
),
79-
canEdit: room.canChangePowerLevel,
8091
),
8192
],
8293
),
@@ -93,19 +104,22 @@ class ChatPermissionsSettingsView extends StatelessWidget with WatchItMixin {
93104
return Padding(
94105
padding: const EdgeInsets.only(bottom: kMediumPadding),
95106
child: _ChatRoomPermissionTile(
107+
canEdit: canChangePowerLevel,
96108
permissionKey: key,
97109
permission: value,
98110
category: 'notifications',
99-
canEdit: room.canChangePowerLevel,
100-
onChanged: (level) => chatModel.editPowerLevel(
101-
room: room,
102-
key: key,
103-
onFail: () =>
104-
showSnackBar(context, content: Text(l10n.noPermission)),
105-
onCustomPermissionsChosen: () =>
106-
_showPermissionChooser(context, currentLevel: value),
107-
newLevel: level,
108-
category: 'notifications',
111+
onChanged: (level) => showFutureLoadingDialog(
112+
context: context,
113+
onError: (e) {
114+
showSnackBar(context, content: Text(e.toString()));
115+
return e;
116+
},
117+
future: () => chatModel.editPowerLevel(
118+
room: room,
119+
key: key,
120+
newLevel: level,
121+
category: 'notifications',
122+
),
109123
),
110124
),
111125
);
@@ -118,21 +132,23 @@ class ChatPermissionsSettingsView extends StatelessWidget with WatchItMixin {
118132
children: [
119133
for (final entry in eventsPowerLevels.entries)
120134
_ChatRoomPermissionTile(
135+
canEdit: canChangePowerLevel,
121136
permissionKey: entry.key,
122137
category: 'events',
123138
permission: entry.value ?? 0,
124-
canEdit: room.canChangePowerLevel,
125-
onChanged: (level) => di<ChatModel>().editPowerLevel(
126-
room: room,
127-
onFail: () =>
128-
showSnackBar(context, content: Text(l10n.noPermission)),
129-
key: entry.key,
130-
onCustomPermissionsChosen: () => _showPermissionChooser(
131-
context,
132-
currentLevel: entry.value ?? 0,
139+
140+
onChanged: (level) => showFutureLoadingDialog(
141+
context: context,
142+
onError: (e) {
143+
showSnackBar(context, content: Text(e.toString()));
144+
return e;
145+
},
146+
future: () => di<ChatModel>().editPowerLevel(
147+
room: room,
148+
key: entry.key,
149+
newLevel: level,
150+
category: 'events',
133151
),
134-
newLevel: level,
135-
category: 'events',
136152
),
137153
),
138154
],
@@ -141,35 +157,9 @@ class ChatPermissionsSettingsView extends StatelessWidget with WatchItMixin {
141157
],
142158
);
143159
}
144-
145-
Future<int?> _showPermissionChooser(
146-
BuildContext context, {
147-
int currentLevel = 0,
148-
}) async {
149-
final l10n = context.l10n;
150-
final customLevel = await showConfirmDialogWithInput(
151-
context: context,
152-
title: l10n.setPermissionsLevel,
153-
initialText: currentLevel.toString(),
154-
keyboardType: TextInputType.number,
155-
autocorrect: false,
156-
validator: (text) {
157-
if (text.isEmpty) {
158-
return l10n.pleaseEnterANumber;
159-
}
160-
final level = int.tryParse(text);
161-
if (level == null) {
162-
return l10n.pleaseEnterANumber;
163-
}
164-
return null;
165-
},
166-
);
167-
if (customLevel == null) return null;
168-
return int.tryParse(customLevel);
169-
}
170160
}
171161

172-
class _ChatRoomPermissionTile extends StatelessWidget {
162+
class _ChatRoomPermissionTile extends StatelessWidget with WatchItMixin {
173163
final String permissionKey;
174164
final int permission;
175165
final String? category;
@@ -238,6 +228,9 @@ class _ChatRoomPermissionTile extends StatelessWidget {
238228
final l10n = context.l10n;
239229
final theme = context.theme;
240230
final colorScheme = theme.colorScheme;
231+
final style = canEdit
232+
? theme.textTheme.bodyMedium
233+
: theme.textTheme.bodyMedium?.copyWith(color: theme.disabledColor);
241234

242235
final color = permission >= 100
243236
? colorScheme.warning
@@ -251,40 +244,48 @@ class _ChatRoomPermissionTile extends StatelessWidget {
251244
style: theme.textTheme.titleSmall,
252245
),
253246
trailing: Material(
254-
color: color.withAlpha(32),
247+
color: canEdit ? color.withAlpha(32) : null,
255248
borderRadius: BorderRadius.circular(kYaruContainerRadius),
256249
child: DropdownButton<int>(
257250
isDense: true,
258-
style: TextStyle(color: colorScheme.onSurface),
251+
style: style,
259252
icon: const SizedBox.shrink(),
260253
padding: const EdgeInsets.symmetric(
261254
horizontal: kMediumPadding,
262255
vertical: kSmallPadding,
263256
),
264257
borderRadius: BorderRadius.circular(kYaruContainerRadius),
265258
underline: const SizedBox.shrink(),
266-
onChanged: canEdit ? onChanged : null,
259+
onChanged: onChanged,
267260
value: permission,
268261
items: [
269262
DropdownMenuItem(
270263
value: permission < 50 ? permission : 0,
271-
child: Text(l10n.userLevel(permission < 50 ? permission : 0)),
264+
child: Text(
265+
l10n.userLevel(permission < 50 ? permission : 0),
266+
style: style,
267+
),
272268
),
273269
DropdownMenuItem(
274270
value: permission < 100 && permission >= 50 ? permission : 50,
275271
child: Text(
276272
l10n.moderatorLevel(
277273
permission < 100 && permission >= 50 ? permission : 50,
278274
),
275+
style: style,
279276
),
280277
),
281278
DropdownMenuItem(
282279
value: permission >= 100 ? permission : 100,
283280
child: Text(
284281
l10n.adminLevel(permission >= 100 ? permission : 100),
282+
style: style,
285283
),
286284
),
287-
DropdownMenuItem(value: null, child: Text(l10n.custom)),
285+
DropdownMenuItem(
286+
value: null,
287+
child: Text(l10n.custom, style: style),
288+
),
288289
],
289290
),
290291
),

lib/chat_room/input/draft_model.dart

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ class DraftModel extends SafeChangeNotifier {
5252
_setSending(true);
5353

5454
try {
55-
room.setTyping(false);
55+
await room.setTyping(false);
5656
} on Exception catch (e, s) {
5757
onFail(e.toString());
5858
printMessageInDebugMode(e, s);
5959
}
6060

61+
final textDraft = '${getTextDraft(room.id)}';
62+
removeTextDraft(room.id);
6163
final matrixFiles = List<MatrixFile>.from(getFilesDraft(room.id));
6264
if (matrixFiles.isNotEmpty) {
6365
for (var matrixFile in matrixFiles) {
@@ -84,6 +86,7 @@ class DraftModel extends SafeChangeNotifier {
8486
thumbnail: matrixFile.mimeType.startsWith('video') && xFile != null
8587
? await getVideoThumbnail(xFile)
8688
: null,
89+
extraContent: textDraft.isNotEmpty ? {'body': textDraft} : null,
8790
);
8891
if (eventId != null) {
8992
_matrixFilesToXFile.remove(matrixFile);
@@ -95,15 +98,11 @@ class DraftModel extends SafeChangeNotifier {
9598
printMessageInDebugMode(e, s);
9699
}
97100
}
98-
}
99-
100-
if (getDraft(room.id)?.isNotEmpty == true) {
101-
final draft = '${getDraft(room.id)}';
102-
removeDraft(room.id);
101+
} else if (textDraft.isNotEmpty == true) {
103102
String? eventId;
104103
try {
105104
eventId = await room.sendTextEvent(
106-
draft.trim(),
105+
textDraft.trim(),
107106
inReplyTo: replyEvent,
108107
editEventId: _editEvents[room.id]?.eventId,
109108
);
@@ -112,7 +111,7 @@ class DraftModel extends SafeChangeNotifier {
112111
printMessageInDebugMode(e, s);
113112
}
114113
if (eventId == null) {
115-
setDraft(roomId: room.id, draft: draft, notify: true);
114+
setTextDraft(roomId: room.id, draft: textDraft, notify: true);
116115
}
117116
}
118117

@@ -123,25 +122,24 @@ class DraftModel extends SafeChangeNotifier {
123122
notifyListeners();
124123
}
125124

126-
final Map<String, String> _drafts = {};
127-
int get draftLength => _drafts.length;
128-
Map<String, String?> get drafts => _drafts;
129-
String? getDraft(String roomId) => _drafts[roomId];
130-
void setDraft({
125+
final Map<String, String> _textDrafts = {};
126+
int get draftLength => _textDrafts.length;
127+
String? getTextDraft(String roomId) => _textDrafts[roomId];
128+
void setTextDraft({
131129
required String roomId,
132130
required String draft,
133131
required bool notify,
134132
}) {
135-
_drafts[roomId] = draft;
133+
_textDrafts[roomId] = draft;
136134
if (notify) {
137135
notifyListeners();
138136
}
139137
}
140138

141-
void removeDraft(String roomId) {
142-
final oldDraft = _drafts[roomId];
139+
void removeTextDraft(String roomId) {
140+
final oldDraft = _textDrafts[roomId];
143141
if (oldDraft == null) return;
144-
_drafts.remove(roomId);
142+
_textDrafts.remove(roomId);
145143
notifyListeners();
146144
}
147145

0 commit comments

Comments
 (0)