|
| 1 | +import 'package:flutter/material.dart'; |
| 2 | +import 'package:flutter_gen/gen_l10n/zulip_localizations.dart'; |
| 3 | + |
| 4 | +import '../api/model/model.dart'; |
| 5 | +import '../model/narrow.dart'; |
| 6 | +import 'app_bar.dart'; |
| 7 | +import 'icons.dart'; |
| 8 | +import 'message_list.dart'; |
| 9 | +import 'page.dart'; |
| 10 | +import 'store.dart'; |
| 11 | +import 'theme.dart'; |
| 12 | + |
| 13 | +class ChannelListPage extends StatelessWidget { |
| 14 | + const ChannelListPage({super.key}); |
| 15 | + |
| 16 | + static Route<void> buildRoute({int? accountId, BuildContext? context}) { |
| 17 | + return MaterialAccountWidgetRoute(accountId: accountId, context: context, |
| 18 | + page: const ChannelListPage()); |
| 19 | + } |
| 20 | + |
| 21 | + @override |
| 22 | + Widget build(BuildContext context) { |
| 23 | + final store = PerAccountStoreWidget.of(context); |
| 24 | + final zulipLocalizations = ZulipLocalizations.of(context); |
| 25 | + final streams = store.streams.values.toList()..sort((a, b) { |
| 26 | + return a.name.toLowerCase().compareTo(b.name.toLowerCase()); |
| 27 | + }); |
| 28 | + return Scaffold( |
| 29 | + appBar: ZulipAppBar(title: Text(zulipLocalizations.channelListPageTitle)), |
| 30 | + body: SafeArea( |
| 31 | + // Don't pad the bottom here; we want the list content to do that. |
| 32 | + bottom: false, |
| 33 | + child: streams.isEmpty ? const _NoChannelsItem() : ListView.builder( |
| 34 | + itemCount: streams.length, |
| 35 | + itemBuilder: (context, index) => ChannelItem(stream: streams[index])))); |
| 36 | + } |
| 37 | +} |
| 38 | + |
| 39 | +class _NoChannelsItem extends StatelessWidget { |
| 40 | + const _NoChannelsItem(); |
| 41 | + |
| 42 | + @override |
| 43 | + Widget build(BuildContext context) { |
| 44 | + final zulipLocalizations = ZulipLocalizations.of(context); |
| 45 | + final designVariables = DesignVariables.of(context); |
| 46 | + |
| 47 | + return Center( |
| 48 | + child: Padding( |
| 49 | + padding: const EdgeInsets.all(10), |
| 50 | + child: Text(zulipLocalizations.noChannelsFound, |
| 51 | + textAlign: TextAlign.center, |
| 52 | + style: TextStyle( |
| 53 | + // TODO(design) check if this is the right variable |
| 54 | + color: designVariables.subscriptionListHeaderText, |
| 55 | + fontSize: 18, |
| 56 | + height: (20 / 18), |
| 57 | + )))); |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +@visibleForTesting |
| 62 | +class ChannelItem extends StatelessWidget { |
| 63 | + const ChannelItem({super.key, required this.stream}); |
| 64 | + |
| 65 | + final ZulipStream stream; |
| 66 | + |
| 67 | + @override |
| 68 | + Widget build(BuildContext context) { |
| 69 | + final designVariables = DesignVariables.of(context); |
| 70 | + return Material( |
| 71 | + color: designVariables.background, |
| 72 | + child: InkWell( |
| 73 | + onTap: () => Navigator.push(context, MessageListPage.buildRoute(context: context, |
| 74 | + narrow: ChannelNarrow(stream.streamId))), |
| 75 | + child: Padding( |
| 76 | + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16), |
| 77 | + child: Row(children: [ |
| 78 | + Icon(size: 16, iconDataForStream(stream)), |
| 79 | + const SizedBox(width: 8), |
| 80 | + Expanded(child: Column( |
| 81 | + crossAxisAlignment: CrossAxisAlignment.start, |
| 82 | + mainAxisAlignment: MainAxisAlignment.spaceBetween, |
| 83 | + children: [ |
| 84 | + Text(stream.name, |
| 85 | + style: TextStyle( |
| 86 | + fontSize: 18, |
| 87 | + height: (20 / 18), |
| 88 | + // TODO(design) check if this is the right variable |
| 89 | + color: designVariables.labelMenuButton), |
| 90 | + maxLines: 1, |
| 91 | + overflow: TextOverflow.ellipsis), |
| 92 | + // TODO(#488) parse and show `stream.renderedDescription` with content widget |
| 93 | + if (stream.description.isNotEmpty) Text( |
| 94 | + stream.description, |
| 95 | + style: TextStyle( |
| 96 | + fontSize: 12, |
| 97 | + // TODO(design) check if this is the right variable |
| 98 | + color: designVariables.labelMenuButton.withOpacity(0.75)), |
| 99 | + maxLines: 1, |
| 100 | + overflow: TextOverflow.ellipsis), |
| 101 | + ])), |
| 102 | + ])))); |
| 103 | + } |
| 104 | +} |
0 commit comments