From b5e99e505d03332a87de30acd9b9740fa7c4e561 Mon Sep 17 00:00:00 2001 From: MateusHBR Date: Mon, 18 Apr 2022 14:27:21 -0300 Subject: [PATCH 1/5] add message localizations --- .../lib/src/localization/translations.dart | 6 ++++++ .../stream_chat_localizations/example/lib/add_new_lang.dart | 3 +++ .../lib/src/stream_chat_localizations_en.dart | 3 +++ .../lib/src/stream_chat_localizations_es.dart | 3 +++ .../lib/src/stream_chat_localizations_fr.dart | 3 +++ .../lib/src/stream_chat_localizations_hi.dart | 3 +++ .../lib/src/stream_chat_localizations_it.dart | 3 +++ .../lib/src/stream_chat_localizations_ja.dart | 3 +++ .../lib/src/stream_chat_localizations_ko.dart | 3 +++ .../lib/src/stream_chat_localizations_pt.dart | 3 +++ 10 files changed, 33 insertions(+) diff --git a/packages/stream_chat_flutter/lib/src/localization/translations.dart b/packages/stream_chat_flutter/lib/src/localization/translations.dart index 8aa8d071..665ddcce 100644 --- a/packages/stream_chat_flutter/lib/src/localization/translations.dart +++ b/packages/stream_chat_flutter/lib/src/localization/translations.dart @@ -311,6 +311,9 @@ abstract class Translations { /// The label for "Reply to message" String get replyToMessageLabel; + /// The label for "View library" + String get viewLibrary; + /// Label for "Attachment limit exceeded: /// it's not possible to add more than $limit attachments" String attachmentLimitExceedError(int limit); @@ -682,6 +685,9 @@ class DefaultTranslations implements Translations { @override String get slowModeOnLabel => 'Slow mode ON'; + @override + String get viewLibrary => 'View library'; + @override String attachmentLimitExceedError(int limit) => """ Attachment limit exceeded: it's not possible to add more than $limit attachments"""; diff --git a/packages/stream_chat_localizations/example/lib/add_new_lang.dart b/packages/stream_chat_localizations/example/lib/add_new_lang.dart index 6fa7689b..be0c446a 100644 --- a/packages/stream_chat_localizations/example/lib/add_new_lang.dart +++ b/packages/stream_chat_localizations/example/lib/add_new_lang.dart @@ -392,6 +392,9 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations { @override String get slowModeOnLabel => 'Slow mode ON'; + + @override + String get viewLibrary => 'View library'; } void main() async { diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart index c1106cab..bc6de244 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart @@ -368,4 +368,7 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations { @override String get slowModeOnLabel => 'Slow mode ON'; + + @override + String get viewLibrary => 'View library'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart index 49e66184..526a11e6 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart @@ -372,6 +372,9 @@ class StreamChatLocalizationsEs extends GlobalStreamChatLocalizations { No es posible añadir más de $limit archivos adjuntos '''; + @override + String get viewLibrary => 'Ver Librería'; + @override String get slowModeOnLabel => 'Modo lento activado'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart index 0057b7cc..8e73e0f9 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart @@ -371,6 +371,9 @@ class StreamChatLocalizationsFr extends GlobalStreamChatLocalizations { Limite de pièces jointes dépassée : il n'est pas possible d'ajouter plus de $limit pièces jointes '''; + @override + String get viewLibrary => 'Voir la bibliothèque'; + @override String get slowModeOnLabel => 'Mode lent activé'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart index 10f1858b..e482aebf 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart @@ -366,6 +366,9 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations { अटैचमेंट लिमिट: $limit अटैचमेंट से अधिक जोड़ना संभव नहीं है '''; + @override + String get viewLibrary => 'पुस्तकालय देखिये'; + @override String get slowModeOnLabel => 'स्लो मोड चालू'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart index 18e961d6..44cf8264 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart @@ -368,6 +368,9 @@ Il file è troppo grande per essere caricato. Il limite è di $limitInMB MB.'''; Attenzione: il limite massimo di $limit file è stato superato. '''; + @override + String get viewLibrary => 'Vedi la biblioteca'; + @override String get slowModeOnLabel => 'Slowmode attiva'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart index 3b28d867..cc94b202 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart @@ -350,6 +350,9 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations { @override String get slowModeOnLabel => 'スローモードオン'; + @override + String get viewLibrary => 'ライブラリを表示'; + @override String attachmentLimitExceedError(int limit) => ''' 添付ファイルの制限を超えました:$limit個のファイル以上を添付することはできません diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart index 3693bc11..f31a1bb5 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart @@ -352,6 +352,9 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations { String get slowModeOnLabel => '슬로모드 켜짐'; @override + @override + String get viewLibrary => '라이브러리 보기'; + String attachmentLimitExceedError(int limit) => '첨부 파일 제한 초과: $limit 이상의 첨부 파일을 추가할 수 없습니다'; } diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart index 44c02081..d00f0818 100644 --- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart +++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart @@ -371,4 +371,7 @@ Não é possível adicionar mais de $limit arquivos de uma vez @override String get slowModeOnLabel => 'Modo lento ativado'; + + @override + String get viewLibrary => 'Ver biblioteca'; } From 852f4b1ec506a417e7e0e824fa1103828c68c35f Mon Sep 17 00:00:00 2001 From: MateusHBR Date: Mon, 18 Apr 2022 14:27:50 -0300 Subject: [PATCH 2/5] create media list view controller to handles media list view --- .../lib/src/media_list_view_controller.dart | 16 ++++++++ .../src/media_list_view_controller_test.dart | 37 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 packages/stream_chat_flutter/lib/src/media_list_view_controller.dart create mode 100644 packages/stream_chat_flutter/test/src/media_list_view_controller_test.dart diff --git a/packages/stream_chat_flutter/lib/src/media_list_view_controller.dart b/packages/stream_chat_flutter/lib/src/media_list_view_controller.dart new file mode 100644 index 00000000..9ec3f594 --- /dev/null +++ b/packages/stream_chat_flutter/lib/src/media_list_view_controller.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; + +/// Controller for MediaListView Widget +class MediaListViewController extends ChangeNotifier { + var _shouldUpdateMedia = false; + + /// Getter that knows if the media should be updated. + bool get shouldUpdateMedia => _shouldUpdateMedia; + + /// Method that update shouldUpdateMedia and notify all listeners + /// about this update. + void updateMedia({required bool newValue}) { + _shouldUpdateMedia = newValue; + notifyListeners(); + } +} diff --git a/packages/stream_chat_flutter/test/src/media_list_view_controller_test.dart b/packages/stream_chat_flutter/test/src/media_list_view_controller_test.dart new file mode 100644 index 00000000..3500d30b --- /dev/null +++ b/packages/stream_chat_flutter/test/src/media_list_view_controller_test.dart @@ -0,0 +1,37 @@ +import 'package:stream_chat_flutter/src/media_list_view_controller.dart'; +import 'package:test/test.dart'; + +void main() { + test('should update media', () { + final controller = MediaListViewController(); + + expect(controller.shouldUpdateMedia, false); + + controller.updateMedia(newValue: true); + expect(controller.shouldUpdateMedia, true); + + controller.dispose(); + }); + + test('should notify listeners on update media', () { + final controller = MediaListViewController(); + + var callCount = 0; + void updateCallsSpy() => callCount++; + + controller.addListener(updateCallsSpy); + + expect(callCount, 0); + controller.updateMedia(newValue: false); + expect(controller.shouldUpdateMedia, false); + expect(callCount, 1); + + controller.updateMedia(newValue: true); + expect(controller.shouldUpdateMedia, true); + expect(callCount, 2); + + controller + ..removeListener(updateCallsSpy) + ..dispose(); + }); +} From 4e82131cf31fad16e485e1d6c85ec119bcf98bb7 Mon Sep 17 00:00:00 2001 From: MateusHBR Date: Mon, 18 Apr 2022 14:28:27 -0300 Subject: [PATCH 3/5] add media list view controller to message input --- .../lib/src/media_list_view.dart | 44 ++++++++++++++++--- .../lib/src/message_input.dart | 27 ++++++++++++ 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/media_list_view.dart b/packages/stream_chat_flutter/lib/src/media_list_view.dart index 62072b0a..81a5fa4e 100644 --- a/packages/stream_chat_flutter/lib/src/media_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/media_list_view.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:photo_manager/photo_manager.dart'; +import 'package:stream_chat_flutter/src/media_list_view_controller.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; extension on Duration { @@ -25,6 +26,7 @@ class MediaListView extends StatefulWidget { Key? key, this.selectedIds = const [], this.onSelect, + this.controller, }) : super(key: key); /// Stores the media selected @@ -33,18 +35,28 @@ class MediaListView extends StatefulWidget { /// Callback for on media selected final void Function(AssetEntity media)? onSelect; + /// Controller that handles MediaListView + final MediaListViewController? controller; + @override _MediaListViewState createState() => _MediaListViewState(); } class _MediaListViewState extends State { - final _media = []; - final ScrollController _scrollController = ScrollController(); - int _currentPage = 0; + var _media = []; + var _currentPage = 0; + final _scrollController = ScrollController(); + + /// Controller necessary to verify limited access to photo gallery in iOS and + /// update the media list when listerners are emitted + late final controller = widget.controller ?? MediaListViewController(); @override Widget build(BuildContext context) => LazyLoadScrollView( - onEndOfPage: () async => _getMedia(), + onEndOfPage: () async { + await _getMedia(); + _updatePage(); + }, child: GridView.builder( itemCount: _media.length, controller: _scrollController, @@ -141,9 +153,29 @@ class _MediaListViewState extends State { @override void initState() { super.initState(); + controller.addListener(_updateMediaList); _getMedia(); } + @override + void dispose() { + super.dispose(); + controller.removeListener(_updateMediaList); + if (widget.controller == null) { + controller.dispose(); + } + } + + void _updateMediaList() { + if (controller.shouldUpdateMedia) { + _getMedia(); + } + } + + void _updatePage() { + ++_currentPage; + } + Future _getMedia() async { final assetList = (await PhotoManager.getAssetPathList( filterOption: FilterOptionGroup( @@ -162,13 +194,11 @@ class _MediaListViewState extends State { page: _currentPage, size: 50, ); - if (media?.isNotEmpty == true) { setState(() { - _media.addAll(media!); + _media = media!; }); } - ++_currentPage; } } diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index bb82386f..43528f73 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -15,6 +15,7 @@ import 'package:stream_chat_flutter/src/emoji/emoji.dart'; import 'package:stream_chat_flutter/src/emoji_overlay.dart'; import 'package:stream_chat_flutter/src/extension.dart'; import 'package:stream_chat_flutter/src/media_list_view.dart'; +import 'package:stream_chat_flutter/src/media_list_view_controller.dart'; import 'package:stream_chat_flutter/src/multi_overlay.dart'; import 'package:stream_chat_flutter/src/quoted_message_widget.dart'; import 'package:stream_chat_flutter/src/user_mentions_overlay.dart'; @@ -343,6 +344,7 @@ class MessageInputState extends State { final List _mentionedUsers = []; final _imagePicker = ImagePicker(); + final _mediaListViewController = MediaListViewController(); late final _focusNode = widget.focusNode ?? FocusNode(); late final _isInternalFocusNode = widget.focusNode == null; bool _inputEnabled = true; @@ -1056,6 +1058,26 @@ class MessageInputState extends State { ); }, ), + const Spacer(), + FutureBuilder( + future: PhotoManager.requestPermissionExtend(), + builder: (context, snapshot) { + if (snapshot.hasData && + snapshot.data == PermissionState.limited) { + return TextButton( + child: Text(context.translations.viewLibrary), + onPressed: () async { + await PhotoManager.presentLimited(); + _mediaListViewController.updateMedia( + newValue: true, + ); + }, + ); + } + + return const SizedBox.shrink(); + }, + ), ], ), DecoratedBox( @@ -1088,6 +1110,7 @@ class MessageInputState extends State { borderRadius: BorderRadius.circular(8), ), child: _PickerWidget( + mediaListViewController: _mediaListViewController, filePickerIndex: _filePickerIndex, streamChatTheme: _streamChatTheme, containsFile: _attachmentContainsFile, @@ -1966,6 +1989,7 @@ class _PickerWidget extends StatefulWidget { required this.onAddMoreFilesClick, required this.onMediaSelected, required this.streamChatTheme, + required this.mediaListViewController, }) : super(key: key); final int filePickerIndex; @@ -1974,6 +1998,7 @@ class _PickerWidget extends StatefulWidget { final void Function(DefaultAttachmentTypes) onAddMoreFilesClick; final void Function(AssetEntity) onMediaSelected; final StreamChatThemeData streamChatTheme; + final MediaListViewController mediaListViewController; @override _PickerWidgetState createState() => _PickerWidgetState(); @@ -2021,7 +2046,9 @@ class _PickerWidgetState extends State<_PickerWidget> { ), ); } + return MediaListView( + controller: widget.mediaListViewController, selectedIds: widget.selectedMedias, onSelect: widget.onMediaSelected, ); From 94139b70f9be46a626d52d100541f5996dc9be40 Mon Sep 17 00:00:00 2001 From: MateusHBR Date: Mon, 18 Apr 2022 14:49:52 -0300 Subject: [PATCH 4/5] added limited access handler --- packages/stream_chat_flutter/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 5d3d1406..b7a90144 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +✅ Added + +- [[#1087]](https://github.com/GetStream/stream-chat-flutter/issues/1087): Handle limited access to camera on iOS. + ## 3.6.1 - Updated `stream_chat_flutter_core` dependency to [`3.6.1`](https://pub.dev/packages/stream_chat_flutter_core/changelog). From b0e93dcb3ac1bf8e8205727bf27e14edc4f7d853 Mon Sep 17 00:00:00 2001 From: MateusHBR Date: Mon, 18 Apr 2022 14:50:08 -0300 Subject: [PATCH 5/5] add translations changelog --- packages/stream_chat_localizations/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/stream_chat_localizations/CHANGELOG.md b/packages/stream_chat_localizations/CHANGELOG.md index 94dc71c3..a79e912e 100644 --- a/packages/stream_chat_localizations/CHANGELOG.md +++ b/packages/stream_chat_localizations/CHANGELOG.md @@ -1,3 +1,7 @@ +## Upcoming + +* Added translations for viewLibrary. + ## 2.1.0 ✅ Added