diff --git a/lib/components/content_banner.dart b/lib/components/content_banner.dart index 102575d6..a441857d 100644 --- a/lib/components/content_banner.dart +++ b/lib/components/content_banner.dart @@ -12,6 +12,7 @@ class ContentBanner extends StatelessWidget { final bool loading; final Function onEdit; final Client client; + final double opacity; const ContentBanner(this.mxContent, {this.height = 400, @@ -19,6 +20,7 @@ class ContentBanner extends StatelessWidget { this.loading = false, this.onEdit, this.client, + this.opacity = 0.75, Key key}) : super(key: key); @@ -35,7 +37,7 @@ class ContentBanner extends StatelessWidget { animated: true, ); return Container( - height: 300, + height: height, alignment: Alignment.center, decoration: BoxDecoration( color: Theme.of(context).secondaryHeaderColor, @@ -48,7 +50,7 @@ class ContentBanner extends StatelessWidget { top: 0, bottom: 0, child: Opacity( - opacity: 0.75, + opacity: opacity, child: !loading ? mxContent != null ? CachedNetworkImage( diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 6d12fc71..545a4ee5 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -16,7 +16,6 @@ import 'package:fluffychat/views/login.dart'; import 'package:fluffychat/views/new_group.dart'; import 'package:fluffychat/views/new_private_chat.dart'; import 'package:fluffychat/views/set_status_view.dart'; -import 'package:fluffychat/views/settings.dart'; import 'package:fluffychat/views/settings_3pid.dart'; import 'package:fluffychat/views/settings_devices.dart'; import 'package:fluffychat/views/settings_emotes.dart'; @@ -149,17 +148,17 @@ class FluffyRoutes { switch (action) { case '3pid': return ViewData( - leftView: (_) => Settings(), + leftView: (_) => HomeView(), mainView: (_) => Settings3Pid(), ); case 'devices': return ViewData( - leftView: (_) => Settings(), + leftView: (_) => HomeView(), mainView: (_) => DevicesSettings(), ); case 'emotes': return ViewData( - leftView: (_) => Settings(), + leftView: (_) => HomeView(), mainView: (_) => EmotesSettings( room: ((settings.arguments ?? {}) as Map)['room'], stateKey: ((settings.arguments ?? {}) as Map)['stateKey'], @@ -167,25 +166,25 @@ class FluffyRoutes { ); case 'ignore': return ViewData( - leftView: (_) => Settings(), + leftView: (_) => HomeView(), mainView: (_) => SettingsIgnoreList( initialUserId: settings.arguments, ), ); case 'notifications': return ViewData( - leftView: (_) => Settings(), + leftView: (_) => HomeView(), mainView: (_) => SettingsNotifications(), ); case 'style': return ViewData( - leftView: (_) => Settings(), + leftView: (_) => HomeView(), mainView: (_) => SettingsStyle(), ); } } return ViewData( - mainView: (_) => Settings(), + mainView: (_) => HomeView(), emptyView: (_) => EmptyPage(), ); } diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index f8fdd11a..6b4f4d7c 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1025,8 +1025,13 @@ "type": "text", "placeholders": {} }, - "newPrivateChat": "New private chat", - "@newPrivateChat": { + "noStatusesFound": "No statuses found so far.", + "@noStatusesFound": { + "type": "text", + "placeholders": {} + }, + "newChat": "New chat", + "@newChat": { "type": "text", "placeholders": {} }, @@ -1352,6 +1357,16 @@ "type": "text", "placeholders": {} }, + "contacts": "Contacts", + "@contacts": { + "type": "text", + "placeholders": {} + }, + "all": "All", + "@all": { + "type": "text", + "placeholders": {} + }, "discover": "Discover", "@discover": { "type": "text", diff --git a/lib/views/chat.dart b/lib/views/chat.dart index c00e6e65..4ee15e35 100644 --- a/lib/views/chat.dart +++ b/lib/views/chat.dart @@ -571,14 +571,14 @@ class _ChatState extends State { : Row( children: [ Icon(Icons.edit_outlined, - color: Theme.of(context).primaryColor, + color: Theme.of(context).accentColor, size: 13), SizedBox(width: 4), Text( room.getLocalizedTypingText(context), maxLines: 1, style: TextStyle( - color: Theme.of(context).primaryColor, + color: Theme.of(context).accentColor, fontStyle: FontStyle.italic, fontSize: 16, ), diff --git a/lib/views/home_view.dart b/lib/views/home_view.dart index b333672b..40383952 100644 --- a/lib/views/home_view.dart +++ b/lib/views/home_view.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:adaptive_page_layout/adaptive_page_layout.dart'; import 'package:famedlysdk/famedlysdk.dart'; +import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/views/home_view_parts/discover.dart'; import 'package:fluffychat/views/share_view.dart'; import 'package:flutter/cupertino.dart'; @@ -11,12 +12,12 @@ import 'package:fluffychat/app_config.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:preload_page_view/preload_page_view.dart'; import 'package:receive_sharing_intent/receive_sharing_intent.dart'; import '../components/matrix.dart'; import '../utils/matrix_file_extension.dart'; import '../utils/url_launcher.dart'; import 'home_view_parts/chat_list.dart'; +import 'home_view_parts/settings.dart'; import 'home_view_parts/status_list.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -31,13 +32,18 @@ class HomeView extends StatefulWidget { _HomeViewState createState() => _HomeViewState(); } -class _HomeViewState extends State { +class _HomeViewState extends State with TickerProviderStateMixin { @override void initState() { _initReceiveSharingIntent(); + _pageController = TabController(length: 4, vsync: this, initialIndex: 1); + _pageController.addListener(_updateCurrentIndex); super.initState(); } + void _updateCurrentIndex() => + setState(() => currentIndex = _pageController.index); + int currentIndex = 1; StreamSubscription _intentDataStreamSubscription; @@ -48,8 +54,7 @@ class _HomeViewState extends State { AppBar appBar; - final PreloadPageController _pageController = - PreloadPageController(initialPage: 1); + TabController _pageController; void _onShare(Map content) { if (content != null) { @@ -114,6 +119,7 @@ class _HomeViewState extends State { void dispose() { _intentDataStreamSubscription?.cancel(); _intentFileStreamSubscription?.cancel(); + _pageController.removeListener(_updateCurrentIndex); super.dispose(); } @@ -170,9 +176,6 @@ class _HomeViewState extends State { fabIcon = Icons.add_outlined; break; case 2: - fabIcon = Icons.group_add_outlined; - break; - case 3: fabIcon = Icons.domain_outlined; break; } @@ -182,33 +185,56 @@ class _HomeViewState extends State { AppBar( centerTitle: false, actions: [ - IconButton( - icon: Icon(Icons.account_circle_outlined), - onPressed: () => - AdaptivePageLayout.of(context).pushNamed('/settings'), + PopupMenuButton( + onSelected: (action) { + switch (action) { + case 'invite': + FluffyShare.share( + L10n.of(context).inviteText( + Matrix.of(context).client.userID, + 'https://matrix.to/#/${Matrix.of(context).client.userID}'), + context); + break; + case 'archive': + AdaptivePageLayout.of(context).pushNamed('/archive'); + break; + } + }, + itemBuilder: (_) => [ + PopupMenuItem( + value: 'invite', + child: Text(L10n.of(context).inviteContact), + ), + PopupMenuItem( + value: 'archive', + child: Text(L10n.of(context).archive), + ), + ], ), ], title: Text(AppConfig.applicationName)), - body: PreloadPageView( + body: TabBarView( controller: _pageController, - onPageChanged: (i) => setState(() => currentIndex = i), children: [ StatusList(key: Key('StatusList')), ChatList( - type: ChatListType.messages, - onCustomAppBar: (appBar) => setState(() => this.appBar = appBar), - ), - ChatList( - type: ChatListType.groups, onCustomAppBar: (appBar) => setState(() => this.appBar = appBar), ), Discover(server: _server), + Settings(), ], ), - floatingActionButton: FloatingActionButton( - child: Icon(fabIcon), - onPressed: _onFabTab, - ), + floatingActionButton: fabIcon == null + ? null + : FloatingActionButton( + child: Icon(fabIcon), + onPressed: _onFabTab, + foregroundColor: + currentIndex == 2 ? Theme.of(context).accentColor : null, + backgroundColor: currentIndex == 2 + ? Theme.of(context).scaffoldBackgroundColor + : null, + ), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, bottomNavigationBar: BottomNavigationBar( unselectedItemColor: Theme.of(context).textTheme.bodyText1.color, @@ -219,11 +245,7 @@ class _HomeViewState extends State { elevation: 20, backgroundColor: Theme.of(context).appBarTheme.color, onTap: (i) { - _pageController.animateToPage( - i, - duration: Duration(milliseconds: 200), - curve: Curves.bounceOut, - ); + _pageController.animateTo(i); setState(() => currentIndex = i); }, items: [ @@ -235,14 +257,14 @@ class _HomeViewState extends State { label: L10n.of(context).messages, icon: Icon(CupertinoIcons.chat_bubble_2), ), - BottomNavigationBarItem( - label: L10n.of(context).groups, - icon: Icon(Icons.people_outline), - ), BottomNavigationBarItem( label: L10n.of(context).discover, icon: Icon(CupertinoIcons.search_circle), ), + BottomNavigationBarItem( + label: L10n.of(context).settings, + icon: Icon(Icons.settings_outlined), + ), ], ), ); diff --git a/lib/views/home_view_parts/chat_list.dart b/lib/views/home_view_parts/chat_list.dart index 545ad3dd..446485f8 100644 --- a/lib/views/home_view_parts/chat_list.dart +++ b/lib/views/home_view_parts/chat_list.dart @@ -8,19 +8,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; -enum ChatListType { messages, groups, all } - enum SelectMode { normal, select } class ChatList extends StatefulWidget { final String activeChat; - final ChatListType type; final void Function(AppBar appBar) onCustomAppBar; const ChatList({ Key key, this.activeChat, - @required this.type, this.onCustomAppBar, }) : super(key: key); @override @@ -175,11 +171,6 @@ class _ChatListState extends State { (searchMode && !room.displayname.toLowerCase().contains( searchController.text.toLowerCase() ?? ''))); - if (widget.type == ChatListType.messages) { - rooms.removeWhere((room) => !room.isDirectChat); - } else if (widget.type == ChatListType.groups) { - rooms.removeWhere((room) => room.isDirectChat); - } if (rooms.isEmpty && (!searchMode)) { return Column( mainAxisAlignment: MainAxisAlignment.center, @@ -196,6 +187,7 @@ class _ChatListState extends State { searchMode ? L10n.of(context).noRoomsFound : L10n.of(context).startYourFirstChat, + textAlign: TextAlign.center, style: TextStyle( color: Colors.grey, fontSize: 16, diff --git a/lib/views/settings.dart b/lib/views/home_view_parts/settings.dart similarity index 54% rename from lib/views/settings.dart rename to lib/views/home_view_parts/settings.dart index 7e1fc9d2..2b7d9743 100644 --- a/lib/views/settings.dart +++ b/lib/views/home_view_parts/settings.dart @@ -19,11 +19,11 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:image_picker/image_picker.dart'; import 'package:url_launcher/url_launcher.dart'; -import '../components/content_banner.dart'; +import '../../components/content_banner.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; -import '../components/matrix.dart'; -import '../app_config.dart'; -import '../config/setting_keys.dart'; +import '../../components/matrix.dart'; +import '../../app_config.dart'; +import '../../config/setting_keys.dart'; class Settings extends StatefulWidget { @override @@ -320,221 +320,197 @@ class _SettingsState extends State { return c; }); } - return Scaffold( - body: NestedScrollView( - headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => - [ - SliverAppBar( - leading: BackButton(), - expandedHeight: 300.0, - floating: true, - pinned: true, - backgroundColor: Theme.of(context).appBarTheme.color, - flexibleSpace: FlexibleSpaceBar( - title: Text( - L10n.of(context).settings, - style: TextStyle( - color: Theme.of(context) - .appBarTheme - .textTheme - .headline6 - .color), - ), - background: ContentBanner( - profile?.avatarUrl, - height: 300, - defaultIcon: Icons.account_circle_outlined, - loading: profile == null, - onEdit: () => setAvatarAction(context), + return ListView( + children: [ + ContentBanner( + profile?.avatarUrl, + height: 200, + opacity: 1, + defaultIcon: Icons.account_circle_outlined, + loading: profile == null, + onEdit: () => setAvatarAction(context), + ), + ListTile( + title: Text( + L10n.of(context).notifications, + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ListTile( + trailing: Icon(Icons.notifications_outlined), + title: Text(L10n.of(context).notifications), + onTap: () => AdaptivePageLayout.of(context) + .pushNamed('/settings/notifications'), + ), + Divider(thickness: 1), + ListTile( + title: Text( + L10n.of(context).chat, + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ListTile( + title: Text(L10n.of(context).changeTheme), + onTap: () => + AdaptivePageLayout.of(context).pushNamed('/settings/style'), + trailing: Icon(Icons.style_outlined), + ), + SettingsSwitchListTile( + title: L10n.of(context).renderRichContent, + onChanged: (b) => AppConfig.renderHtml = b, + storeKey: SettingKeys.renderHtml, + defaultValue: AppConfig.renderHtml, + ), + SettingsSwitchListTile( + title: L10n.of(context).hideRedactedEvents, + onChanged: (b) => AppConfig.hideRedactedEvents = b, + storeKey: SettingKeys.hideRedactedEvents, + defaultValue: AppConfig.hideRedactedEvents, + ), + SettingsSwitchListTile( + title: L10n.of(context).hideUnknownEvents, + onChanged: (b) => AppConfig.hideUnknownEvents = b, + storeKey: SettingKeys.hideUnknownEvents, + defaultValue: AppConfig.hideUnknownEvents, + ), + ListTile( + title: Text(L10n.of(context).emoteSettings), + onTap: () => + AdaptivePageLayout.of(context).pushNamed('/settings/emotes'), + trailing: Icon(Icons.insert_emoticon_outlined), + ), + Divider(thickness: 1), + ListTile( + title: Text( + L10n.of(context).account, + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ListTile( + trailing: Icon(Icons.edit_outlined), + title: Text(L10n.of(context).editDisplayname), + subtitle: Text(profile?.displayname ?? client.userID.localpart), + onTap: () => setDisplaynameAction(context), + ), + ListTile( + trailing: Icon(Icons.phone_outlined), + title: Text(L10n.of(context).editJitsiInstance), + subtitle: Text(AppConfig.jitsiInstance), + onTap: () => setJitsiInstanceAction(context), + ), + ListTile( + trailing: Icon(Icons.devices_other_outlined), + title: Text(L10n.of(context).devices), + onTap: () => + AdaptivePageLayout.of(context).pushNamed('/settings/devices'), + ), + ListTile( + trailing: Icon(Icons.block_outlined), + title: Text(L10n.of(context).ignoredUsers), + onTap: () => + AdaptivePageLayout.of(context).pushNamed('/settings/ignore'), + ), + SentrySwitchListTile(), + Divider(thickness: 1), + ListTile( + trailing: Icon(Icons.security_outlined), + title: Text( + L10n.of(context).changePassword, + ), + onTap: () => _changePasswordAccountAction(context), + ), + ListTile( + trailing: Icon(Icons.email_outlined), + title: Text(L10n.of(context).passwordRecovery), + onTap: () => + AdaptivePageLayout.of(context).pushNamed('/settings/3pid'), + ), + ListTile( + trailing: Icon(Icons.exit_to_app_outlined), + title: Text(L10n.of(context).logout), + onTap: () => logoutAction(context), + ), + ListTile( + trailing: Icon(Icons.delete_forever_outlined), + title: Text( + L10n.of(context).deleteAccount, + style: TextStyle(color: Colors.red), + ), + onTap: () => _deleteAccountAction(context), + ), + if (client.encryption != null) ...{ + Divider(thickness: 1), + ListTile( + title: Text( + L10n.of(context).security, + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, ), ), ), - ], - body: ListView( - children: [ + if (PlatformInfos.isMobile) ListTile( - title: Text( - L10n.of(context).notifications, - style: TextStyle( - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.bold, - ), - ), + trailing: Icon(Icons.lock_outlined), + title: Text(L10n.of(context).appLock), + onTap: () => _setAppLockAction(context), ), - ListTile( - trailing: Icon(Icons.notifications_outlined), - title: Text(L10n.of(context).notifications), - onTap: () => AdaptivePageLayout.of(context) - .pushNamed('/settings/notifications'), + ListTile( + title: Text(L10n.of(context).yourPublicKey), + onTap: () => showOkAlertDialog( + context: context, + title: L10n.of(context).yourPublicKey, + message: client.fingerprintKey.beautified, ), - Divider(thickness: 1), - ListTile( - title: Text( - L10n.of(context).chat, - style: TextStyle( - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.bold, - ), - ), + trailing: Icon(Icons.vpn_key_outlined), + ), + ListTile( + title: Text(L10n.of(context).cachedKeys), + trailing: Icon(Icons.wb_cloudy_outlined), + subtitle: Text( + '${client.encryption.keyManager.enabled ? L10n.of(context).onlineKeyBackupEnabled : L10n.of(context).onlineKeyBackupDisabled}\n${client.encryption.crossSigning.enabled ? L10n.of(context).crossSigningEnabled : L10n.of(context).crossSigningDisabled}'), + onTap: () => BootstrapDialog( + l10n: L10n.of(context), + client: Matrix.of(context).client, + ).show(context), + ), + }, + Divider(thickness: 1), + ListTile( + title: Text( + L10n.of(context).about, + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.bold, ), - ListTile( - title: Text(L10n.of(context).changeTheme), - onTap: () => - AdaptivePageLayout.of(context).pushNamed('/settings/style'), - trailing: Icon(Icons.style_outlined), - ), - SettingsSwitchListTile( - title: L10n.of(context).renderRichContent, - onChanged: (b) => AppConfig.renderHtml = b, - storeKey: SettingKeys.renderHtml, - defaultValue: AppConfig.renderHtml, - ), - SettingsSwitchListTile( - title: L10n.of(context).hideRedactedEvents, - onChanged: (b) => AppConfig.hideRedactedEvents = b, - storeKey: SettingKeys.hideRedactedEvents, - defaultValue: AppConfig.hideRedactedEvents, - ), - SettingsSwitchListTile( - title: L10n.of(context).hideUnknownEvents, - onChanged: (b) => AppConfig.hideUnknownEvents = b, - storeKey: SettingKeys.hideUnknownEvents, - defaultValue: AppConfig.hideUnknownEvents, - ), - ListTile( - title: Text(L10n.of(context).emoteSettings), - onTap: () => - AdaptivePageLayout.of(context).pushNamed('/settings/emotes'), - trailing: Icon(Icons.insert_emoticon_outlined), - ), - Divider(thickness: 1), - ListTile( - title: Text( - L10n.of(context).account, - style: TextStyle( - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.bold, - ), - ), - ), - ListTile( - trailing: Icon(Icons.edit_outlined), - title: Text(L10n.of(context).editDisplayname), - subtitle: Text(profile?.displayname ?? client.userID.localpart), - onTap: () => setDisplaynameAction(context), - ), - ListTile( - trailing: Icon(Icons.phone_outlined), - title: Text(L10n.of(context).editJitsiInstance), - subtitle: Text(AppConfig.jitsiInstance), - onTap: () => setJitsiInstanceAction(context), - ), - ListTile( - trailing: Icon(Icons.devices_other_outlined), - title: Text(L10n.of(context).devices), - onTap: () => - AdaptivePageLayout.of(context).pushNamed('/settings/devices'), - ), - ListTile( - trailing: Icon(Icons.block_outlined), - title: Text(L10n.of(context).ignoredUsers), - onTap: () => - AdaptivePageLayout.of(context).pushNamed('/settings/ignore'), - ), - SentrySwitchListTile(), - Divider(thickness: 1), - ListTile( - trailing: Icon(Icons.security_outlined), - title: Text( - L10n.of(context).changePassword, - ), - onTap: () => _changePasswordAccountAction(context), - ), - ListTile( - trailing: Icon(Icons.email_outlined), - title: Text(L10n.of(context).passwordRecovery), - onTap: () => - AdaptivePageLayout.of(context).pushNamed('/settings/3pid'), - ), - ListTile( - trailing: Icon(Icons.exit_to_app_outlined), - title: Text(L10n.of(context).logout), - onTap: () => logoutAction(context), - ), - ListTile( - trailing: Icon(Icons.delete_forever_outlined), - title: Text( - L10n.of(context).deleteAccount, - style: TextStyle(color: Colors.red), - ), - onTap: () => _deleteAccountAction(context), - ), - if (client.encryption != null) ...{ - Divider(thickness: 1), - ListTile( - title: Text( - L10n.of(context).security, - style: TextStyle( - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.bold, - ), - ), - ), - if (PlatformInfos.isMobile) - ListTile( - trailing: Icon(Icons.lock_outlined), - title: Text(L10n.of(context).appLock), - onTap: () => _setAppLockAction(context), - ), - ListTile( - title: Text(L10n.of(context).yourPublicKey), - onTap: () => showOkAlertDialog( - context: context, - title: L10n.of(context).yourPublicKey, - message: client.fingerprintKey.beautified, - ), - trailing: Icon(Icons.vpn_key_outlined), - ), - ListTile( - title: Text(L10n.of(context).cachedKeys), - trailing: Icon(Icons.wb_cloudy_outlined), - subtitle: Text( - '${client.encryption.keyManager.enabled ? L10n.of(context).onlineKeyBackupEnabled : L10n.of(context).onlineKeyBackupDisabled}\n${client.encryption.crossSigning.enabled ? L10n.of(context).crossSigningEnabled : L10n.of(context).crossSigningDisabled}'), - onTap: () => BootstrapDialog( - l10n: L10n.of(context), - client: Matrix.of(context).client, - ).show(context), - ), - }, - Divider(thickness: 1), - ListTile( - title: Text( - L10n.of(context).about, - style: TextStyle( - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.bold, - ), - ), - onTap: () => AdaptivePageLayout.of(context).pushNamed('/logs'), - ), - ListTile( - trailing: Icon(Icons.help_outlined), - title: Text(L10n.of(context).help), - onTap: () => launch(AppConfig.supportUrl), - ), - ListTile( - trailing: Icon(Icons.privacy_tip_outlined), - title: Text(L10n.of(context).privacy), - onTap: () => launch(AppConfig.privacyUrl), - ), - ListTile( - trailing: Icon(Icons.link_outlined), - title: Text(L10n.of(context).about), - onTap: () => PlatformInfos.showDialog(context), - ), - ], + ), + onTap: () => AdaptivePageLayout.of(context).pushNamed('/logs'), ), - ), + ListTile( + trailing: Icon(Icons.help_outlined), + title: Text(L10n.of(context).help), + onTap: () => launch(AppConfig.supportUrl), + ), + ListTile( + trailing: Icon(Icons.privacy_tip_outlined), + title: Text(L10n.of(context).privacy), + onTap: () => launch(AppConfig.privacyUrl), + ), + ListTile( + trailing: Icon(Icons.link_outlined), + title: Text(L10n.of(context).about), + onTap: () => PlatformInfos.showDialog(context), + ), + ], ); } } diff --git a/lib/views/home_view_parts/status_list.dart b/lib/views/home_view_parts/status_list.dart index f56338b5..17c725ab 100644 --- a/lib/views/home_view_parts/status_list.dart +++ b/lib/views/home_view_parts/status_list.dart @@ -2,6 +2,7 @@ import 'package:fluffychat/components/list_items/status_list_tile.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/utils/status.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; class StatusList extends StatefulWidget { const StatusList({Key key}) : super(key: key); @@ -22,7 +23,7 @@ class _StatusListState extends State { elevation: _onlyContacts ? 7 : null, color: !_onlyContacts ? null : Theme.of(context).primaryColor, child: Text( - 'Contacts', + L10n.of(context).contacts, style: TextStyle(color: _onlyContacts ? Colors.white : null), ), onPressed: () => setState(() => _onlyContacts = true), @@ -31,7 +32,7 @@ class _StatusListState extends State { elevation: !_onlyContacts ? 7 : null, color: _onlyContacts ? null : Theme.of(context).primaryColor, child: Text( - 'All', + L10n.of(context).all, style: TextStyle(color: !_onlyContacts ? Colors.white : null), ), onPressed: () => setState(() => _onlyContacts = false), @@ -53,6 +54,16 @@ class _StatusListState extends State { statuses.removeWhere( (p) => client.getDirectChatFromUserId(p.senderId) == null); } + if (statuses.isEmpty) { + return Container( + padding: EdgeInsets.all(16), + alignment: Alignment.center, + child: Text( + L10n.of(context).noStatusesFound, + textAlign: TextAlign.center, + ), + ); + } return ListView.separated( physics: NeverScrollableScrollPhysics(), shrinkWrap: true, diff --git a/lib/views/new_private_chat.dart b/lib/views/new_private_chat.dart index f5888184..78f57ebe 100644 --- a/lib/views/new_private_chat.dart +++ b/lib/views/new_private_chat.dart @@ -87,8 +87,18 @@ class _NewPrivateChatState extends State { return Scaffold( appBar: AppBar( leading: BackButton(), - title: Text(L10n.of(context).newPrivateChat), + title: Text(L10n.of(context).newChat), elevation: 0, + actions: [ + FlatButton( + child: Text( + L10n.of(context).createNewGroup, + style: TextStyle(color: Theme.of(context).accentColor), + ), + onPressed: () => AdaptivePageLayout.of(context) + .pushNamedAndRemoveUntilIsFirst('/newgroup'), + ) + ], ), body: Column( children: [ diff --git a/lib/views/share_view.dart b/lib/views/share_view.dart index 40ad4ec8..ed8369eb 100644 --- a/lib/views/share_view.dart +++ b/lib/views/share_view.dart @@ -19,9 +19,7 @@ class ShareView extends StatelessWidget { ), title: Text(L10n.of(context).share), ), - body: ChatList( - type: ChatListType.all, - ), + body: ChatList(), ); } } diff --git a/pubspec.lock b/pubspec.lock index 73a21ee2..8b8b7f71 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -872,13 +872,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.0-nullsafety.2" - preload_page_view: - dependency: "direct main" - description: - name: preload_page_view - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4" process: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7057ae91..9d7396da 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,7 +31,6 @@ dependencies: adaptive_page_layout: ^0.1.6 provider: ^4.3.3 adaptive_theme: ^1.1.0 - preload_page_view: ^0.1.4 # desktop_notifications: ^0.0.0-dev.4 // Currently blocked by: https://github.com/canonical/desktop_notifications.dart/issues/5 matrix_link_text: ^0.3.2 path_provider: ^1.6.27