11import 'package:flutter/material.dart' ;
22
33import '../api/model/model.dart' ;
4+ import 'package:flutter_svg/flutter_svg.dart' ;
45import '../api/route/channels.dart' ;
56import '../generated/l10n/zulip_localizations.dart' ;
67import '../log.dart' ;
@@ -32,20 +33,21 @@ class AllChannelsPage extends StatelessWidget {
3233
3334 static AccountRoute <void > buildRoute ({required BuildContext context}) {
3435 return MaterialAccountWidgetRoute (
35- context: context, page: const AllChannelsPage ());
36+ context: context,
37+ page: const AllChannelsPage (),
38+ );
3639 }
3740
3841 @override
3942 Widget build (BuildContext context) {
4043 final zulipLocalizations = ZulipLocalizations .of (context);
4144 return Scaffold (
42- appBar: ZulipAppBar (
43- title : Text (zulipLocalizations.allChannelsPageTitle) ),
44- body : AllChannelsPageBody () );
45+ appBar: ZulipAppBar (title : Text (zulipLocalizations.allChannelsPageTitle)),
46+ body : AllChannelsPageBody ( ),
47+ );
4548 }
4649}
4750
48-
4951class AllChannelsPageBody extends StatelessWidget {
5052 const AllChannelsPageBody ({super .key});
5153
@@ -56,7 +58,8 @@ class AllChannelsPageBody extends StatelessWidget {
5658
5759 if (channels.isEmpty) {
5860 return PageBodyEmptyContentPlaceholder (
59- header: zulipLocalizations.allChannelsEmptyPlaceholderHeader);
61+ header: zulipLocalizations.allChannelsEmptyPlaceholderHeader,
62+ );
6063 }
6164
6265 final items = channels.values.toList ();
@@ -69,18 +72,27 @@ class AllChannelsPageBody extends StatelessWidget {
6972 // the bottom inset will be consumed by a different sliver after this one
7073 removeBottom: true ,
7174 child: SliverSafeArea (
72- minimum: EdgeInsetsDirectional .only (start: 8 ).resolve (Directionality .of (context)),
75+ minimum: EdgeInsetsDirectional .only (
76+ start: 8 ,
77+ ).resolve (Directionality .of (context)),
7378 sliver: SliverList .builder (
7479 itemCount: items.length,
7580 itemBuilder: (context, i) =>
76- AllChannelsListEntry (channel: items[i])))));
77-
78- return CustomScrollView (slivers: [
79- sliverList,
80- SliverSafeArea (
81- // TODO(#1572) "New channel" button
82- sliver: SliverPadding (padding: EdgeInsets .zero)),
83- ]);
81+ AllChannelsListEntry (channel: items[i]),
82+ ),
83+ ),
84+ ),
85+ );
86+
87+ return CustomScrollView (
88+ slivers: [
89+ sliverList,
90+ SliverSafeArea (
91+ // TODO(#1572) "New channel" button
92+ sliver: SliverPadding (padding: EdgeInsets .zero),
93+ ),
94+ ],
95+ );
8496 }
8597}
8698
@@ -97,31 +109,57 @@ class AllChannelsListEntry extends StatelessWidget {
97109 final channel = this .channel;
98110 final Subscription ? subscription = channel is Subscription ? channel : null ;
99111 final hasContentAccess = store.selfHasContentAccess (channel);
100-
112+ final Color iconColor = colorSwatchFor (
113+ context,
114+ subscription,
115+ ).iconOnPlainBackground;
116+
117+ final Widget channelIcon = channel.isArchived
118+ ? SvgPicture .asset (
119+ 'assets/icons/archive.svg' ,
120+ width: 20 ,
121+ height: 20 ,
122+ colorFilter: ColorFilter .mode (iconColor, BlendMode .srcIn),
123+ )
124+ : Icon (iconDataForStream (channel), size: 20 , color: iconColor);
101125 return InkWell (
102- onTap: ! hasContentAccess ? null : () => Navigator .push (context,
103- MessageListPage .buildRoute (context: context,
104- narrow: ChannelNarrow (channel.streamId))),
105- onLongPress: () => showChannelActionSheet (context, channelId: channel.streamId),
106- child: ConstrainedBox (constraints: const BoxConstraints (minHeight: 44 ),
107- child: Padding (padding: const EdgeInsetsDirectional .only (start: 8 , end: 12 ),
108- child: Row (spacing: 6 , children: [
109- Icon (
110- size: 20 ,
111- color: colorSwatchFor (context, subscription).iconOnPlainBackground,
112- iconDataForStream (channel)),
113- Expanded (
114- child: Text (
115- maxLines: 1 ,
116- overflow: TextOverflow .ellipsis,
117- style: TextStyle (
118- color: designVariables.textMessage,
119- fontSize: 17 ,
120- height: 20 / 17 ,
121- ).merge (weightVariableTextStyle (context, wght: 600 )),
122- channel.name)),
123- if (hasContentAccess) _SubscribeToggle (channel: channel),
124- ]))));
126+ onTap: ! hasContentAccess
127+ ? null
128+ : () => Navigator .push (
129+ context,
130+ MessageListPage .buildRoute (
131+ context: context,
132+ narrow: ChannelNarrow (channel.streamId),
133+ ),
134+ ),
135+ onLongPress: () =>
136+ showChannelActionSheet (context, channelId: channel.streamId),
137+ child: ConstrainedBox (
138+ constraints: const BoxConstraints (minHeight: 44 ),
139+ child: Padding (
140+ padding: const EdgeInsetsDirectional .only (start: 8 , end: 12 ),
141+ child: Row (
142+ children: [
143+ channelIcon,
144+ const SizedBox (width: 6 ),
145+ Expanded (
146+ child: Text (
147+ channel.name,
148+ maxLines: 1 ,
149+ overflow: TextOverflow .ellipsis,
150+ style: TextStyle (
151+ color: designVariables.textMessage,
152+ fontSize: 17 ,
153+ height: 20 / 17 ,
154+ ).merge (weightVariableTextStyle (context, wght: 600 )),
155+ ),
156+ ),
157+ if (hasContentAccess) _SubscribeToggle (channel: channel),
158+ ],
159+ ),
160+ ),
161+ ),
162+ );
125163 }
126164}
127165
@@ -136,24 +174,30 @@ class _SubscribeToggle extends StatelessWidget {
136174 final store = PerAccountStoreWidget .of (context);
137175
138176 return RemoteSettingBuilder <bool >(
139- findValueInStore: (store) => store.subscriptions.containsKey (channel.streamId),
177+ findValueInStore: (store) =>
178+ store.subscriptions.containsKey (channel.streamId),
140179 sendValueToServer: (value) async {
141180 if (value) {
142- await subscribeToChannel (store.connection,
143- subscriptions: [channel.name]);
181+ await subscribeToChannel (
182+ store.connection,
183+ subscriptions: [channel.name],
184+ );
144185 } else {
145- await ZulipAction .unsubscribeFromChannel (context,
186+ await ZulipAction .unsubscribeFromChannel (
187+ context,
146188 channelId: channel.streamId,
147- alwaysAsk: false );
189+ alwaysAsk: false ,
190+ );
148191 }
149192 },
150193 // TODO(#741) interpret API errors for user
151194 onError: (e, requestedValue) => reportErrorToUserBriefly (
152195 requestedValue
153- ? zulipLocalizations.subscribeFailedTitle
154- : zulipLocalizations.unsubscribeFailedTitle),
155- builder: (value, handleRequestNewValue) => Toggle (
156- value: value,
157- onChanged: handleRequestNewValue));
196+ ? zulipLocalizations.subscribeFailedTitle
197+ : zulipLocalizations.unsubscribeFailedTitle,
198+ ),
199+ builder: (value, handleRequestNewValue) =>
200+ Toggle (value: value, onChanged: handleRequestNewValue),
201+ );
158202 }
159203}
0 commit comments