Skip to content

Commit 412f911

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 ef6dcf6 commit 412f911

File tree

2 files changed

+52
-16
lines changed

2 files changed

+52
-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: 42 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,28 @@ class _RecentDmConversationsPageBodyState extends State<RecentDmConversationsPag
5563
});
5664
}
5765

66+
void _handleDmSelect(DmNarrow narrow) {
67+
if (widget.onDmSelect case final onDmSelect?) {
68+
onDmSelect(narrow);
69+
} else {
70+
Navigator.push(context,
71+
MessageListPage.buildRoute(context: context,
72+
narrow: narrow));
73+
}
74+
}
75+
76+
void _handleDmSelectForNewDms(DmNarrow narrow) {
77+
if (widget.onDmSelect case final onDmSelect?) {
78+
// Pop the new DMs action sheet.
79+
Navigator.pop(context);
80+
onDmSelect(narrow);
81+
} else {
82+
Navigator.pushReplacement(context,
83+
MessageListPage.buildRoute(context: context,
84+
narrow: narrow));
85+
}
86+
}
87+
5888
@override
5989
Widget build(BuildContext context) {
6090
final store = PerAccountStoreWidget.of(context);
@@ -91,11 +121,12 @@ class _RecentDmConversationsPageBodyState extends State<RecentDmConversationsPag
91121
}
92122
return RecentDmConversationsItem(
93123
narrow: narrow,
94-
unreadCount: unreadsModel!.countInDmNarrow(narrow));
124+
unreadCount: unreadsModel!.countInDmNarrow(narrow),
125+
onDmSelect: _handleDmSelect);
95126
})),
96127
Positioned(
97128
bottom: 21,
98-
child: _NewDmButton()),
129+
child: _NewDmButton(onDmSelect: _handleDmSelectForNewDms)),
99130
]);
100131
}
101132
}
@@ -105,10 +136,12 @@ class RecentDmConversationsItem extends StatelessWidget {
105136
super.key,
106137
required this.narrow,
107138
required this.unreadCount,
139+
required this.onDmSelect,
108140
});
109141

110142
final DmNarrow narrow;
111143
final int unreadCount;
144+
final OnDmSelectCallback onDmSelect;
112145

113146
static const double _avatarSize = 32;
114147

@@ -151,10 +184,7 @@ class RecentDmConversationsItem extends StatelessWidget {
151184
return Material(
152185
color: backgroundColor,
153186
child: InkWell(
154-
onTap: () {
155-
Navigator.push(context,
156-
MessageListPage.buildRoute(context: context, narrow: narrow));
157-
},
187+
onTap: () => onDmSelect(narrow),
158188
child: ConstrainedBox(constraints: const BoxConstraints(minHeight: 48),
159189
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
160190
Padding(padding: const EdgeInsetsDirectional.fromSTEB(12, 8, 0, 8),
@@ -188,7 +218,11 @@ class RecentDmConversationsItem extends StatelessWidget {
188218
}
189219

190220
class _NewDmButton extends StatefulWidget {
191-
const _NewDmButton();
221+
const _NewDmButton({
222+
required this.onDmSelect,
223+
});
224+
225+
final OnDmSelectCallback onDmSelect;
192226

193227
@override
194228
State<_NewDmButton> createState() => _NewDmButtonState();
@@ -210,7 +244,7 @@ class _NewDmButtonState extends State<_NewDmButton> {
210244
: designVariables.fabLabel;
211245

212246
return GestureDetector(
213-
onTap: () => showNewDmSheet(context),
247+
onTap: () => showNewDmSheet(context, widget.onDmSelect),
214248
onTapDown: (_) => setState(() => _pressed = true),
215249
onTapUp: (_) => setState(() => _pressed = false),
216250
onTapCancel: () => setState(() => _pressed = false),

0 commit comments

Comments
 (0)