Skip to content

Commit 91b7edb

Browse files
recent dms [nfc]: Allow onDmSelect callback, notifying the selected DM
This will be used soon to provide a specific behaviour when selecting a DM, where if specified it will replace the default behaviour of routing to the message list page of the selected DM narrow.
1 parent b5744a0 commit 91b7edb

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

lib/widgets/new_dm_sheet.dart

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import '../model/narrow.dart';
66
import '../model/store.dart';
77
import 'color.dart';
88
import 'icons.dart';
9-
import 'message_list.dart';
109
import 'page.dart';
10+
import 'recent_dm_conversations.dart';
1111
import 'store.dart';
1212
import 'text.dart';
1313
import 'theme.dart';
1414
import 'user.dart';
1515

16-
void showNewDmSheet(BuildContext context) {
16+
void showNewDmSheet(BuildContext context, OnDmSelectCallback onDmSelect) {
1717
final pageContext = PageRoot.contextOf(context);
1818
final store = PerAccountStoreWidget.of(context);
1919
showModalBottomSheet<void>(
@@ -29,12 +29,14 @@ void showNewDmSheet(BuildContext context) {
2929
padding: EdgeInsets.only(bottom: MediaQuery.viewInsetsOf(context).bottom),
3030
child: PerAccountStoreWidget(
3131
accountId: store.accountId,
32-
child: NewDmPicker())));
32+
child: NewDmPicker(onDmSelect: onDmSelect))));
3333
}
3434

3535
@visibleForTesting
3636
class NewDmPicker extends StatefulWidget {
37-
const NewDmPicker({super.key});
37+
const NewDmPicker({super.key, required this.onDmSelect});
38+
39+
final OnDmSelectCallback onDmSelect;
3840

3941
@override
4042
State<NewDmPicker> createState() => _NewDmPickerState();
@@ -132,7 +134,7 @@ class _NewDmPickerState extends State<NewDmPicker> with PerAccountStoreAwareStat
132134
@override
133135
Widget build(BuildContext context) {
134136
return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
135-
_NewDmHeader(selectedUserIds: selectedUserIds),
137+
_NewDmHeader(selectedUserIds: selectedUserIds, onDmSelect: widget.onDmSelect),
136138
_NewDmSearchBar(
137139
controller: searchController,
138140
selectedUserIds: selectedUserIds,
@@ -148,9 +150,10 @@ class _NewDmPickerState extends State<NewDmPicker> with PerAccountStoreAwareStat
148150
}
149151

150152
class _NewDmHeader extends StatelessWidget {
151-
const _NewDmHeader({required this.selectedUserIds});
153+
const _NewDmHeader({required this.selectedUserIds, required this.onDmSelect});
152154

153155
final Set<int> selectedUserIds;
156+
final OnDmSelectCallback onDmSelect;
154157

155158
Widget _buildCancelButton(BuildContext context) {
156159
final designVariables = DesignVariables.of(context);
@@ -178,8 +181,7 @@ class _NewDmHeader extends StatelessWidget {
178181
final narrow = DmNarrow.withUsers(
179182
selectedUserIds.toList(),
180183
selfUserId: store.selfUserId);
181-
Navigator.pushReplacement(context,
182-
MessageListPage.buildRoute(context: context, narrow: narrow));
184+
onDmSelect(narrow);
183185
},
184186
child: Text(zulipLocalizations.newDmSheetComposeButtonLabel,
185187
style: TextStyle(

lib/widgets/recent_dm_conversations.dart

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,22 @@ import 'theme.dart';
1414
import 'unread_count_badge.dart';
1515
import 'user.dart';
1616

17+
typedef OnDmSelectCallback = void Function(DmNarrow narrow);
18+
1719
class RecentDmConversationsPageBody extends StatefulWidget {
1820
const RecentDmConversationsPageBody({
1921
super.key,
2022
this.hideDmsIfUserCantPost = false,
23+
this.onDmSelect,
2124
});
2225

2326
final bool hideDmsIfUserCantPost;
2427

28+
/// Callback to invoke when the user selects a DM conversation from the list.
29+
///
30+
/// If null, the default behavior is to navigate to the DM conversation.
31+
final OnDmSelectCallback? onDmSelect;
32+
2533
@override
2634
State<RecentDmConversationsPageBody> createState() => _RecentDmConversationsPageBodyState();
2735
}
@@ -55,6 +63,18 @@ class _RecentDmConversationsPageBodyState extends State<RecentDmConversationsPag
5563
});
5664
}
5765

66+
void _handleDmSelect(DmNarrow narrow) {
67+
Navigator.push(context,
68+
MessageListPage.buildRoute(context: context,
69+
narrow: narrow));
70+
}
71+
72+
void _handleDmSelectForNewDms(DmNarrow narrow) {
73+
Navigator.pushReplacement(context,
74+
MessageListPage.buildRoute(context: context,
75+
narrow: narrow));
76+
}
77+
5878
@override
5979
Widget build(BuildContext context) {
6080
final store = PerAccountStoreWidget.of(context);
@@ -91,11 +111,20 @@ class _RecentDmConversationsPageBodyState extends State<RecentDmConversationsPag
91111
}
92112
return RecentDmConversationsItem(
93113
narrow: narrow,
94-
unreadCount: unreadsModel!.countInDmNarrow(narrow));
114+
unreadCount: unreadsModel!.countInDmNarrow(narrow),
115+
onDmSelect: widget.onDmSelect ?? _handleDmSelect);
95116
})),
96117
Positioned(
97118
bottom: 21,
98-
child: _NewDmButton()),
119+
child: _NewDmButton(onDmSelect: (narrow) {
120+
if (widget.onDmSelect case final onDmSelect?) {
121+
// Pop the new DMs action sheet.
122+
Navigator.pop(context);
123+
onDmSelect(narrow);
124+
} else {
125+
_handleDmSelectForNewDms(narrow);
126+
}
127+
})),
99128
]);
100129
}
101130
}
@@ -105,10 +134,12 @@ class RecentDmConversationsItem extends StatelessWidget {
105134
super.key,
106135
required this.narrow,
107136
required this.unreadCount,
137+
required this.onDmSelect,
108138
});
109139

110140
final DmNarrow narrow;
111141
final int unreadCount;
142+
final OnDmSelectCallback onDmSelect;
112143

113144
static const double _avatarSize = 32;
114145

@@ -151,10 +182,7 @@ class RecentDmConversationsItem extends StatelessWidget {
151182
return Material(
152183
color: backgroundColor,
153184
child: InkWell(
154-
onTap: () {
155-
Navigator.push(context,
156-
MessageListPage.buildRoute(context: context, narrow: narrow));
157-
},
185+
onTap: () => onDmSelect(narrow),
158186
child: ConstrainedBox(constraints: const BoxConstraints(minHeight: 48),
159187
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
160188
Padding(padding: const EdgeInsetsDirectional.fromSTEB(12, 8, 0, 8),
@@ -188,7 +216,11 @@ class RecentDmConversationsItem extends StatelessWidget {
188216
}
189217

190218
class _NewDmButton extends StatefulWidget {
191-
const _NewDmButton();
219+
const _NewDmButton({
220+
required this.onDmSelect,
221+
});
222+
223+
final OnDmSelectCallback onDmSelect;
192224

193225
@override
194226
State<_NewDmButton> createState() => _NewDmButtonState();
@@ -210,7 +242,7 @@ class _NewDmButtonState extends State<_NewDmButton> {
210242
: designVariables.fabLabel;
211243

212244
return GestureDetector(
213-
onTap: () => showNewDmSheet(context),
245+
onTap: () => showNewDmSheet(context, widget.onDmSelect),
214246
onTapDown: (_) => setState(() => _pressed = true),
215247
onTapUp: (_) => setState(() => _pressed = false),
216248
onTapCancel: () => setState(() => _pressed = false),

0 commit comments

Comments
 (0)