Skip to content

Commit 40d5a7d

Browse files
recent dms [nfc]: Allow onDmSelect callback
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 87d4762 commit 40d5a7d

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);
@@ -92,11 +122,12 @@ class _RecentDmConversationsPageBodyState extends State<RecentDmConversationsPag
92122
}
93123
return RecentDmConversationsItem(
94124
narrow: narrow,
95-
unreadCount: unreadsModel!.countInDmNarrow(narrow));
125+
unreadCount: unreadsModel!.countInDmNarrow(narrow),
126+
onDmSelect: _handleDmSelect);
96127
})),
97128
Positioned(
98129
bottom: 21,
99-
child: _NewDmButton()),
130+
child: _NewDmButton(onDmSelect: _handleDmSelectForNewDms)),
100131
]);
101132
}
102133
}
@@ -106,10 +137,12 @@ class RecentDmConversationsItem extends StatelessWidget {
106137
super.key,
107138
required this.narrow,
108139
required this.unreadCount,
140+
required this.onDmSelect,
109141
});
110142

111143
final DmNarrow narrow;
112144
final int unreadCount;
145+
final OnDmSelectCallback onDmSelect;
113146

114147
static const double _avatarSize = 32;
115148

@@ -152,10 +185,7 @@ class RecentDmConversationsItem extends StatelessWidget {
152185
return Material(
153186
color: backgroundColor,
154187
child: InkWell(
155-
onTap: () {
156-
Navigator.push(context,
157-
MessageListPage.buildRoute(context: context, narrow: narrow));
158-
},
188+
onTap: () => onDmSelect(narrow),
159189
child: ConstrainedBox(constraints: const BoxConstraints(minHeight: 48),
160190
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
161191
Padding(padding: const EdgeInsetsDirectional.fromSTEB(12, 8, 0, 8),
@@ -189,7 +219,11 @@ class RecentDmConversationsItem extends StatelessWidget {
189219
}
190220

191221
class _NewDmButton extends StatefulWidget {
192-
const _NewDmButton();
222+
const _NewDmButton({
223+
required this.onDmSelect,
224+
});
225+
226+
final OnDmSelectCallback onDmSelect;
193227

194228
@override
195229
State<_NewDmButton> createState() => _NewDmButtonState();
@@ -211,7 +245,7 @@ class _NewDmButtonState extends State<_NewDmButton> {
211245
: designVariables.fabLabel;
212246

213247
return GestureDetector(
214-
onTap: () => showNewDmSheet(context),
248+
onTap: () => showNewDmSheet(context, widget.onDmSelect),
215249
onTapDown: (_) => setState(() => _pressed = true),
216250
onTapUp: (_) => setState(() => _pressed = false),
217251
onTapCancel: () => setState(() => _pressed = false),

0 commit comments

Comments
 (0)