Skip to content

Commit

Permalink
TW-1955: Create permission dialogs for contacts and images (#1956)
Browse files Browse the repository at this point in the history
* TW-1955: Implement permission dialog for contact and media

TW-1955: new chat and group chat updated with contact permission dialog

TW-1955: permission dialog for media added

TW-1955: add autoDisplayPermissionDialog notifier

TW-1955: remove permission dialog before displaying native one

TW-1955: remove data refresh when back to screen

* TW-1955: Implement permission dialog for contact and media - part II

* TW-1955: Implement permission dialog for contact and media - part III

---------

Co-authored-by: HuyNguyen <[email protected]>
  • Loading branch information
Te-Z and nqhhdev authored Jul 19, 2024
1 parent 517091f commit aaf6a12
Show file tree
Hide file tree
Showing 20 changed files with 348 additions and 66 deletions.
4 changes: 4 additions & 0 deletions assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -3041,6 +3041,10 @@
}
}
},
"explainPermissionToAccessContacts": "Twake chat needs access to your contacts to find out whether your friends are on the matrix server. This is done locally, and your contacts are not synchronized with our server.",
"explainPermissionToAccessMedias": "Twake chat needs access to storage so you can send and save photos, videos, music and other documents. Press Settings > Authorizations, then activate Storage authorization: Photos and videos.",
"explainPermissionToAccessPhotos": "Twake chat needs access to your photos so you can send and save images. Press Settings > Permissions, then enable Storage permission: Photos.",
"explainPermissionToAccessVideos": "Twake chat needs access to your videos so you can send and save videos. Press Settings > Permissions, then enable Storage permission: Videos.",
"downloading": "Downloading",
"settingUpYourTwake": "Setting up your Twake\nIt could take a while",
"performingAutomaticalLogin": "Performing automatical login via SSO",
Expand Down
4 changes: 4 additions & 0 deletions assets/l10n/intl_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2714,6 +2714,10 @@
"count": {}
}
},
"explainPermissionToAccessContacts": "Twake chat doit accéder à vos contacts pour savoir si vos amis sont sur le serveur matrix. Cela se fait localement et vos contacts ne sont pas synchronisés avec notre serveur.",
"explainPermissionToAccessMedias": "Twake chat a besoin d'accéder au stockage pour que vous puissiez envoyer et enregistrer des photos, vidéos, musiques et autres documents. Appuyez sur Paramètres > Autorisations puis activez l'autorisation de stockage: Photos et vidéos.",
"explainPermissionToAccessPhotos": "Twake chat a besoin d'accéder à vos photos pour que vous puissiez envoyer et de enregistrer des images. Allez dans Paramètres > Autorisations, puis activez l'autorisation de stockage : Photos.",
"explainPermissionToAccessVideos": "Twake chat a besoin d'accéder à vos vidéos pour que vous puissiez envoyer et de sauvegarder des vidéos. Allez dans Paramètres > Autorisations, puis activez l'autorisation de stockage : Vidéos.",
"recentChat": "DISCUSSION RÉCENTE",
"@recentChat": {},
"muteThisMessage": "Couper le son de ce salon",
Expand Down
12 changes: 12 additions & 0 deletions lib/domain/contact_manager/contacts_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class ContactsManager {

bool _doNotShowWarningContactsBannerAgain = false;

bool _doNotShowWarningContactsDialogAgain = false;

final ValueNotifierCustom<Either<Failure, Success>> _contactsNotifier =
ValueNotifierCustom(const Right(ContactsInitial()));

Expand All @@ -41,10 +43,17 @@ class ContactsManager {
bool get isDoNotShowWarningContactsBannerAgain =>
_doNotShowWarningContactsBannerAgain;

bool get isDoNotShowWarningContactsDialogAgain =>
_doNotShowWarningContactsDialogAgain;

set updateNotShowWarningContactsBannerAgain(bool value) {
_doNotShowWarningContactsBannerAgain = value;
}

set updateNotShowWarningContactsDialogAgain(bool value) {
_doNotShowWarningContactsDialogAgain = value;
}

Future<void> reSyncContacts() async {
_contactsNotifier.value = const Right(ContactsInitial());
_phonebookContactsNotifier.value =
Expand Down Expand Up @@ -92,4 +101,7 @@ class ContactsManager {
},
);
}

void refreshPhonebookContacts() =>
_fetchPhonebookContacts(isAvailableSupportPhonebookContacts: true);
}
2 changes: 1 addition & 1 deletion lib/pages/chat_details/chat_details_edit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class ChatDetailsEditController extends State<ChatDetailsEdit>
_getImageOnWeb(context);
return;
}
final currentPermissionPhotos = await getCurrentMediaPermission();
final currentPermissionPhotos = await getCurrentMediaPermission(context);
if (currentPermissionPhotos != null) {
final imagePickerController = createImagePickerController();
showImagePickerBottomSheet(
Expand Down
16 changes: 14 additions & 2 deletions lib/pages/contacts_tab/contacts_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import 'package:fluffychat/presentation/model/contact/presentation_contact_const
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/responsive/responsive_utils.dart';
import 'package:fluffychat/utils/string_extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';

class ContactsTab extends StatefulWidget {
Expand All @@ -27,16 +28,21 @@ class ContactsTab extends StatefulWidget {
}

class ContactsTabController extends State<ContactsTab>
with ComparablePresentationContactMixin, ContactsViewControllerMixin {
with
ComparablePresentationContactMixin,
ContactsViewControllerMixin,
WidgetsBindingObserver {
final responsive = getIt.get<ResponsiveUtils>();

Client get client => Matrix.of(context).client;

@override
void initState() {
SchedulerBinding.instance.addPostFrameCallback((_) async {
WidgetsBinding.instance.addObserver(this);
if (mounted) {
initialFetchContacts(
context: context,
client: Matrix.of(context).client,
matrixLocalizations: MatrixLocals(L10n.of(context)!),
);
Expand Down Expand Up @@ -100,9 +106,15 @@ class ContactsTabController extends State<ContactsTab>
}
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
await handleDidChangeAppLifecycleState(state);
}

@override
void dispose() {
disposeContactsMixin();
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}

Expand Down
4 changes: 2 additions & 2 deletions lib/pages/contacts_tab/contacts_tab_body_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,8 @@ class _SliverWarningBanner extends StatelessWidget {
child: ContactsWarningBannerView(
warningBannerNotifier: controller.warningBannerNotifier,
closeContactsWarningBanner: controller.closeContactsWarningBanner,
goToSettingsForPermissionActions:
controller.goToSettingsForPermissionActions,
goToSettingsForPermissionActions: () =>
controller.displayContactPermissionDialog(context),
),
);
}
Expand Down
16 changes: 14 additions & 2 deletions lib/pages/new_group/contacts_selection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import 'package:fluffychat/pages/new_group/selected_contacts_map_change_notifier
import 'package:fluffychat/presentation/model/contact/presentation_contact.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter/cupertino.dart';
import 'package:matrix/matrix.dart';

abstract class ContactsSelectionController<T extends StatefulWidget>
extends State<T>
with InviteExternalContactMixin, ContactsViewControllerMixin {
with
InviteExternalContactMixin,
ContactsViewControllerMixin,
WidgetsBindingObserver {
final selectedContactsMapNotifier = SelectedContactsMapChangeNotifier();

String getTitle(BuildContext context);
Expand All @@ -37,8 +40,10 @@ abstract class ContactsSelectionController<T extends StatefulWidget>
@override
void initState() {
SchedulerBinding.instance.addPostFrameCallback((_) async {
WidgetsBinding.instance.addObserver(this);
if (mounted) {
initialFetchContacts(
context: context,
client: client,
matrixLocalizations: MatrixLocals(L10n.of(context)!),
);
Expand All @@ -47,9 +52,16 @@ abstract class ContactsSelectionController<T extends StatefulWidget>
super.initState();
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
await handleDidChangeAppLifecycleState(state);
}

@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
disposeContactsMixin();
selectedContactsMapNotifier.dispose();
super.dispose();
}

Expand Down
4 changes: 2 additions & 2 deletions lib/pages/new_group/contacts_selection_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class ContactsSelectionView extends StatelessWidget {
warningBannerNotifier: controller.warningBannerNotifier,
closeContactsWarningBanner:
controller.closeContactsWarningBanner,
goToSettingsForPermissionActions:
controller.goToSettingsForPermissionActions,
goToSettingsForPermissionActions: () =>
controller.displayContactPermissionDialog(context),
),
),
SliverToBoxAdapter(
Expand Down
2 changes: 1 addition & 1 deletion lib/pages/new_group/new_group_chat_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ class NewGroupChatInfoController extends State<NewGroupChatInfo>
_getImageOnWeb(context);
return;
}
final currentPermissionPhotos = await getCurrentMediaPermission();
final currentPermissionPhotos = await getCurrentMediaPermission(context);
if (currentPermissionPhotos != null) {
final imagePickerController = createImagePickerController();
groupNameFocusNode.unfocus();
Expand Down
10 changes: 10 additions & 0 deletions lib/pages/new_private_chat/new_private_chat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class NewPrivateChatController extends State<NewPrivateChat>
ComparablePresentationContactMixin,
ContactsViewControllerMixin,
GoToDraftChatMixin,
WidgetsBindingObserver,
InviteExternalContactMixin,
GoToGroupChatMixin {
final isShowContactsNotifier = ValueNotifier(true);
Expand All @@ -34,8 +35,10 @@ class NewPrivateChatController extends State<NewPrivateChat>
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) async {
WidgetsBinding.instance.addObserver(this);
if (mounted) {
initialFetchContacts(
context: context,
client: Matrix.of(context).client,
matrixLocalizations: MatrixLocals(L10n.of(context)!),
);
Expand Down Expand Up @@ -84,9 +87,16 @@ class NewPrivateChatController extends State<NewPrivateChat>
});
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
await handleDidChangeAppLifecycleState(state);
}

@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);
isShowContactsNotifier.dispose();
disposeContactsMixin();
scrollController.dispose();
}
Expand Down
7 changes: 7 additions & 0 deletions lib/pages/new_private_chat/new_private_chat_style.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'package:flutter/material.dart';

class NewPrivateChatStyle {
static const EdgeInsets paddingBody = EdgeInsets.only(left: 8.0, right: 10.0);

static const EdgeInsets paddingWarningBanner = EdgeInsets.only(top: 16.0);
}
44 changes: 31 additions & 13 deletions lib/pages/new_private_chat/new_private_chat_view.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:fluffychat/pages/new_private_chat/new_private_chat.dart';
import 'package:fluffychat/pages/new_private_chat/new_private_chat_style.dart';
import 'package:fluffychat/pages/new_private_chat/widget/expansion_list.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/app_bars/searchable_app_bar.dart';
import 'package:fluffychat/widgets/app_bars/searchable_app_bar_style.dart';
import 'package:fluffychat/widgets/contacts_warning_banner/contacts_warning_banner_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:linagora_design_flutter/colors/linagora_sys_colors.dart';
Expand Down Expand Up @@ -31,20 +33,36 @@ class NewPrivateChatView extends StatelessWidget {
keyboardDismissBehavior: PlatformInfos.isMobile
? ScrollViewKeyboardDismissBehavior.manual
: ScrollViewKeyboardDismissBehavior.onDrag,
padding: const EdgeInsets.only(left: 8.0, right: 10.0),
padding: NewPrivateChatStyle.paddingBody,
controller: controller.scrollController,
child: ExpansionList(
presentationContactsNotifier: controller.presentationContactNotifier,
goToNewGroupChat: () => controller.goToNewGroupChat(context),
isShowContactsNotifier: controller.isShowContactsNotifier,
onContactTap: controller.onContactAction,
onExternalContactTap: controller.onExternalContactAction,
toggleContactsList: controller.toggleContactsList,
textEditingController: controller.textEditingController,
warningBannerNotifier: controller.warningBannerNotifier,
closeContactsWarningBanner: controller.closeContactsWarningBanner,
goToSettingsForPermissionActions:
controller.goToSettingsForPermissionActions,
child: Column(
children: [
Padding(
padding: NewPrivateChatStyle.paddingWarningBanner,
child: ContactsWarningBannerView(
warningBannerNotifier: controller.warningBannerNotifier,
closeContactsWarningBanner:
controller.closeContactsWarningBanner,
goToSettingsForPermissionActions: () =>
controller.displayContactPermissionDialog(context),
isShowMargin: false,
),
),
ExpansionList(
presentationContactsNotifier:
controller.presentationContactNotifier,
goToNewGroupChat: () => controller.goToNewGroupChat(context),
isShowContactsNotifier: controller.isShowContactsNotifier,
onContactTap: controller.onContactAction,
onExternalContactTap: controller.onExternalContactAction,
toggleContactsList: controller.toggleContactsList,
textEditingController: controller.textEditingController,
warningBannerNotifier: controller.warningBannerNotifier,
closeContactsWarningBanner: controller.closeContactsWarningBanner,
goToSettingsForPermissionActions: () =>
controller.displayContactPermissionDialog(context),
),
],
),
),
);
Expand Down
11 changes: 0 additions & 11 deletions lib/pages/new_private_chat/widget/expansion_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'package:fluffychat/presentation/model/contact/get_presentation_contacts_
import 'package:fluffychat/presentation/model/contact/presentation_contact.dart';
import 'package:fluffychat/presentation/model/contact/presentation_contact_success.dart';
import 'package:fluffychat/utils/responsive/responsive_utils.dart';
import 'package:fluffychat/widgets/contacts_warning_banner/contacts_warning_banner_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:linagora_design_flutter/colors/linagora_ref_colors.dart';
Expand Down Expand Up @@ -164,7 +163,6 @@ class ExpansionList extends StatelessWidget {
const SizedBox(
height: 12,
),
_contactsWarningBannerViewBuilder(),
..._buildResponsiveButtons(context),
for (final child in expansionList) ...[child],
] else ...[
Expand All @@ -188,15 +186,6 @@ class ExpansionList extends StatelessWidget {
);
}

Widget _contactsWarningBannerViewBuilder() {
return ContactsWarningBannerView(
warningBannerNotifier: warningBannerNotifier,
isShowMargin: false,
closeContactsWarningBanner: closeContactsWarningBanner,
goToSettingsForPermissionActions: goToSettingsForPermissionActions,
);
}

Widget _buildTitle(BuildContext context, int countContacts) {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class SettingsProfileController extends State<SettingsProfile>
_getImageOnWeb(context);
return;
}
final currentPermissionPhotos = await getCurrentMediaPermission();
final currentPermissionPhotos = await getCurrentMediaPermission(context);
if (currentPermissionPhotos != null) {
final imagePickerController = createImagePickerController();
showImagePickerBottomSheet(
Expand Down
6 changes: 3 additions & 3 deletions lib/presentation/mixins/common_media_picker_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ mixin CommonMediaPickerMixin {
final PermissionHandlerService _permissionHandlerService =
PermissionHandlerService();

Future<PermissionStatus?>? getCurrentMediaPermission() {
return _permissionHandlerService.requestPermissionForMediaActions();
Future<PermissionStatus?>? getCurrentMediaPermission(BuildContext context) {
return _permissionHandlerService.requestPermissionForMediaActions(context);
}

Future<PermissionStatus>? getCurrentCameraPermission() {
return _permissionHandlerService.requestPermissionForCameraActions();
}

Future<PermissionStatus>? getCurrentMicroPermission() {
return _permissionHandlerService.requestPermissionForMircoActions();
return _permissionHandlerService.requestPermissionForMicroActions();
}

void goToSettings(
Expand Down
Loading

0 comments on commit aaf6a12

Please sign in to comment.