From fe2b391046a43ee65c898007f624d7dd6df2f527 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Sat, 21 Nov 2020 21:53:11 +0100 Subject: [PATCH] feat: add ability to mark a room as unread This also add tooltips to all the room context actions. --- lib/components/list_items/chat_list_item.dart | 28 ++++++----- lib/l10n/intl_en.arb | 15 ++++++ lib/views/chat.dart | 10 ++-- lib/views/chat_list.dart | 16 +++++++ pubspec.lock | 48 +++++++++---------- pubspec.yaml | 2 +- 6 files changed, 74 insertions(+), 45 deletions(-) diff --git a/lib/components/list_items/chat_list_item.dart b/lib/components/list_items/chat_list_item.dart index 3c75dd65..d3b836ca 100644 --- a/lib/components/list_items/chat_list_item.dart +++ b/lib/components/list_items/chat_list_item.dart @@ -1,12 +1,12 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; -import 'package:flushbar/flushbar_helper.dart'; import 'package:circular_check_box/circular_check_box.dart'; import 'package:famedlysdk/famedlysdk.dart'; -import 'package:fluffychat/utils/matrix_locals.dart'; -import 'package:fluffychat/views/chat.dart'; -import 'package:flutter/material.dart'; import 'package:fluffychat/utils/event_extension.dart'; +import 'package:fluffychat/utils/matrix_locals.dart'; import 'package:fluffychat/utils/room_status_extension.dart'; +import 'package:fluffychat/views/chat.dart'; +import 'package:flushbar/flushbar_helper.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:pedantic/pedantic.dart'; @@ -249,23 +249,25 @@ class ChatListItem extends StatelessWidget { color: Theme.of(context).primaryColor, ), ), - if (room.notificationCount > 0) + if (room.isUnread) Container( padding: EdgeInsets.symmetric(horizontal: 7), - height: 20, + height: room.notificationCount > 0 ? 20 : 14, decoration: BoxDecoration( - color: room.highlightCount > 0 + color: room.highlightCount > 0 || room.markedUnread ? Colors.red : Theme.of(context).primaryColor, borderRadius: BorderRadius.circular(20), ), child: Center( - child: Text( - room.notificationCount.toString(), - style: TextStyle( - color: Colors.white, - ), - ), + child: room.notificationCount > 0 + ? Text( + room.notificationCount.toString(), + style: TextStyle( + color: Colors.white, + ), + ) + : Container(), ), ), ], diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 7181c88e..88d694b0 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1665,6 +1665,21 @@ "type": "text", "placeholders": {} }, + "toggleFavorite": "Toggle Favorite", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Toggle Muted", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Mark Read/Unread", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, "tryToSendAgain": "Try to send again", "@tryToSendAgain": { "type": "text", diff --git a/lib/views/chat.dart b/lib/views/chat.dart index c520ee9d..d737a89b 100644 --- a/lib/views/chat.dart +++ b/lib/views/chat.dart @@ -4,7 +4,6 @@ import 'dart:math'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:famedlysdk/famedlysdk.dart'; - import 'package:file_picker_cross/file_picker_cross.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; import 'package:fluffychat/components/avatar.dart'; @@ -34,8 +33,8 @@ import 'package:swipe_to_action/swipe_to_action.dart'; import '../components/dialogs/send_file_dialog.dart'; import '../components/input_bar.dart'; -import '../utils/matrix_file_extension.dart'; import '../config/app_config.dart'; +import '../utils/matrix_file_extension.dart'; import 'chat_details.dart'; import 'chat_list.dart'; @@ -181,9 +180,7 @@ class _ChatState extends State<_Chat> { if (timeline == null) { timeline = await room.getTimeline(onUpdate: updateView); if (timeline.events.isNotEmpty) { - unawaited(room - .sendReadReceipt(timeline.events.first.eventId) - .catchError((err) { + unawaited(room.setUnread(false).catchError((err) { if (err is MatrixException && err.errcode == 'M_FORBIDDEN') { // ignore if the user is not in the room (still joining) return; @@ -484,7 +481,6 @@ class _ChatState extends State<_Chat> { } final typingText = room.getLocalizedTypingText(context); - return Scaffold( appBar: AppBar( leading: selectMode @@ -624,7 +620,7 @@ class _ChatState extends State<_Chat> { timeline != null && timeline.events.isNotEmpty && Matrix.of(context).webHasFocus) { - room.sendReadReceipt(timeline.events.first.eventId); + room.sendReadMarker(timeline.events.first.eventId); } final filteredEvents = getFilteredEvents(); diff --git a/lib/views/chat_list.dart b/lib/views/chat_list.dart index 346dbd14..c90c80f2 100644 --- a/lib/views/chat_list.dart +++ b/lib/views/chat_list.dart @@ -140,6 +140,13 @@ class _ChatListState extends State { super.dispose(); } + Future _toggleUnread(BuildContext context) { + final room = Matrix.of(context).client.getRoomById(_selectedRoomIds.single); + return SimpleDialogs(context).tryRequestWithLoadingDialog( + room.setUnread(!room.isUnread), + ); + } + Future _toggleFavouriteRoom(BuildContext context) { final room = Matrix.of(context).client.getRoomById(_selectedRoomIds.single); return SimpleDialogs(context).tryRequestWithLoadingDialog( @@ -226,16 +233,25 @@ class _ChatListState extends State { : [ if (_selectedRoomIds.length == 1) IconButton( + tooltip: L10n.of(context).toggleUnread, + icon: Icon(Icons.mark_chat_unread_outlined), + onPressed: () => _toggleUnread(context), + ), + if (_selectedRoomIds.length == 1) + IconButton( + tooltip: L10n.of(context).toggleFavorite, icon: Icon(Icons.favorite_border_outlined), onPressed: () => _toggleFavouriteRoom(context), ), if (_selectedRoomIds.length == 1) IconButton( icon: Icon(Icons.notifications_none_outlined), + tooltip: L10n.of(context).toggleMuted, onPressed: () => _toggleMuted(context), ), IconButton( icon: Icon(Icons.archive_outlined), + tooltip: L10n.of(context).archive, onPressed: () => _archiveAction(context), ), ], diff --git a/pubspec.lock b/pubspec.lock index b0e94d8b..021b50a5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -70,7 +70,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0-nullsafety.1" + version: "2.5.0-nullsafety.3" base58check: dependency: transitive description: @@ -84,7 +84,7 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0-nullsafety.3" cached_network_image: dependency: "direct main" description: @@ -105,14 +105,14 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.0-nullsafety.5" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" circular_check_box: dependency: "direct main" description: @@ -133,14 +133,14 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0-nullsafety.3" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0-nullsafety.3" + version: "1.15.0-nullsafety.5" convert: dependency: transitive description: @@ -203,13 +203,13 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" famedlysdk: dependency: "direct main" description: path: "." - ref: "20ae1ae20e51840643988768620cc9900f83231c" - resolved-ref: "20ae1ae20e51840643988768620cc9900f83231c" + ref: "5167e92913784937fb7ec5bd4f64072c50924e19" + resolved-ref: "5167e92913784937fb7ec5bd4f64072c50924e19" url: "https://gitlab.com/famedly/famedlysdk.git" source: git version: "0.0.1" @@ -547,7 +547,7 @@ packages: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.3-nullsafety.2" + version: "0.6.3-nullsafety.3" localstorage: dependency: "direct main" description: @@ -575,7 +575,7 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10-nullsafety.1" + version: "0.12.10-nullsafety.3" matrix_file_e2ee: dependency: transitive description: @@ -596,7 +596,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.6" mime: dependency: transitive description: @@ -710,7 +710,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.1" + version: "1.8.0-nullsafety.3" path_drawing: dependency: transitive description: @@ -946,7 +946,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0-nullsafety.2" + version: "1.8.0-nullsafety.4" sqflite: dependency: "direct main" description: @@ -981,21 +981,21 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0-nullsafety.1" + version: "1.10.0-nullsafety.6" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.1" + version: "2.1.0-nullsafety.3" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0-nullsafety.1" + version: "1.1.0-nullsafety.3" swipe_to_action: dependency: "direct main" description: @@ -1016,28 +1016,28 @@ packages: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0-nullsafety.1" + version: "1.2.0-nullsafety.3" test: dependency: transitive description: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.16.0-nullsafety.5" + version: "1.16.0-nullsafety.12" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19-nullsafety.2" + version: "0.2.19-nullsafety.6" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.3.12-nullsafety.5" + version: "0.3.12-nullsafety.11" timezone: dependency: transitive description: @@ -1058,7 +1058,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0-nullsafety.3" + version: "1.3.0-nullsafety.5" universal_html: dependency: "direct main" description: @@ -1142,7 +1142,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.0-nullsafety.5" vm_service: dependency: transitive description: @@ -1214,5 +1214,5 @@ packages: source: hosted version: "0.1.2" sdks: - dart: ">=2.10.2 <2.11.0" + dart: ">=2.12.0-0.0 <=2.12.0-29.10.beta" flutter: ">=1.22.2 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index c75aec1d..ed879364 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: famedlysdk: git: url: https://gitlab.com/famedly/famedlysdk.git - ref: 20ae1ae20e51840643988768620cc9900f83231c + ref: 5167e92913784937fb7ec5bd4f64072c50924e19 localstorage: ^3.0.3+6 file_picker_cross: 4.2.2