diff --git a/config.sample.json b/config.sample.json index ef40014e0d..d77beb7f60 100644 --- a/config.sample.json +++ b/config.sample.json @@ -15,5 +15,6 @@ "default_max_upload_avatar_size_in_bytes": 1000000, "dev_mode": false, "qr_code_download_url": "https://sign-up.twake.app/download/chat", - "enable_logs": false + "enable_logs": false, + "support_url": "https://twake.app/support" } diff --git a/configurations/icons/ic_twake_support.svg b/configurations/icons/ic_twake_support.svg new file mode 100644 index 0000000000..bc6f129a09 --- /dev/null +++ b/configurations/icons/ic_twake_support.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/configurations/config_web_app_for_public_platform.md b/docs/configurations/config_web_app_for_public_platform.md index 8c1dbb6e1a..c9203758d3 100644 --- a/docs/configurations/config_web_app_for_public_platform.md +++ b/docs/configurations/config_web_app_for_public_platform.md @@ -30,7 +30,8 @@ in [config.sample.json](https://github.com/linagora/twake-on-matrix/blob/main/co "default_max_upload_avatar_size_in_bytes": 1000000, "dev_mode": false, "qr_code_download_url": "https://example.com/", - "enable_logs": true + "enable_logs": true, + "support_url": "https://example.com/" } ``` @@ -51,5 +52,6 @@ in [config.sample.json](https://github.com/linagora/twake-on-matrix/blob/main/co - `dev_mode`: Enable to run app in IDE, - `qr_code_download_url`: URL generate QR code to download app - `enable_logs`: Enable logs +- `support_url`: Enable/Disable if you want to show support button with the URL. Default is `https://twake.app/support` If you want to disable it, please change the value or remove this from `config.sample.json` \ No newline at end of file diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart index 075f2b8272..d4d1ba0068 100644 --- a/lib/config/app_config.dart +++ b/lib/config/app_config.dart @@ -82,8 +82,7 @@ abstract class AppConfig { static String get webBaseUrl => _webBaseUrl; static const String sourceCodeUrl = 'https://github.com/linagora/twake-on-matrix'; - static const String supportUrl = - 'https://github.com/linagora/twake-on-matrix/issues'; + static String supportUrl = 'https://twake.app/support'; static bool renderHtml = true; static bool hideRedactedEvents = false; static bool hideUnknownEvents = true; @@ -271,5 +270,8 @@ abstract class AppConfig { if (json['enable_logs'] is bool) { DebugUtils.enableLogs = json['enable_logs']; } + if (json['support_url'] is String) { + supportUrl = json['support_url']; + } } } diff --git a/lib/pages/app_grid/app_grid_dashboard_controller.dart b/lib/pages/app_grid/app_grid_dashboard_controller.dart index 9fc3bfcae6..6812c7b3a1 100644 --- a/lib/pages/app_grid/app_grid_dashboard_controller.dart +++ b/lib/pages/app_grid/app_grid_dashboard_controller.dart @@ -22,7 +22,9 @@ class AppGridDashboardController extends State { final linagoraApplications = ValueNotifier(null); - final hoverColor = ValueNotifier(Colors.transparent); + final hoverColorAppGrid = ValueNotifier(Colors.transparent); + + final hoverColorAppHelp = ValueNotifier(Colors.transparent); void _getAppGridConfiguration() { _getAppGridConfigurationInteractor @@ -81,7 +83,8 @@ class AppGridDashboardController extends State { void dispose() { isOpenAppGridDashboardNotifier.dispose(); linagoraApplications.dispose(); - hoverColor.dispose(); + hoverColorAppGrid.dispose(); + hoverColorAppHelp.dispose(); super.dispose(); } diff --git a/lib/pages/app_grid/app_grid_dashboard_view.dart b/lib/pages/app_grid/app_grid_dashboard_view.dart index 906a5849d5..58f6efd1b6 100644 --- a/lib/pages/app_grid/app_grid_dashboard_view.dart +++ b/lib/pages/app_grid/app_grid_dashboard_view.dart @@ -1,11 +1,14 @@ +import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/app_grid/app_grid_dashboard_controller.dart'; import 'package:fluffychat/pages/app_grid/app_grid_dashboard_overlay.dart'; import 'package:fluffychat/pages/app_grid/app_grid_dashboard_view_style.dart'; import 'package:fluffychat/resource/image_paths.dart'; import 'package:fluffychat/utils/extension/value_notifier_extension.dart'; +import 'package:fluffychat/utils/url_launcher.dart'; import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; class AppGridDashboardView extends StatelessWidget { final AppGridDashboardController controller; @@ -19,71 +22,126 @@ class AppGridDashboardView extends StatelessWidget { Widget build(BuildContext context) { return Align( alignment: Alignment.centerRight, - child: ValueListenableBuilder( - valueListenable: controller.isOpenAppGridDashboardNotifier, - builder: (context, isOpenAppGridDashboard, _) { - return TapRegion( - behavior: HitTestBehavior.opaque, - onTapInside: (_) { - controller.isOpenAppGridDashboardNotifier.toggle(); - }, - onTapOutside: (_) { - controller.hideAppGridDashboard(); - controller.hoverColor.value = Colors.transparent; - }, - child: MouseRegion( - cursor: SystemMouseCursors.click, - onEnter: (_) => controller.hoverColor.value = - AppGridDashboardViewStyle.hoverColor, - onExit: (_) { - if (!isOpenAppGridDashboard) { - controller.hoverColor.value = Colors.transparent; - } + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (AppConfig.supportUrl.isNotEmpty) + TapRegion( + behavior: HitTestBehavior.opaque, + onTapInside: (_) { + UrlLauncher( + context, + url: AppConfig.supportUrl, + ).openUrlInAppBrowser(); }, - child: ValueListenableBuilder( - valueListenable: controller.hoverColor, - builder: (context, color, child) { - return PortalTarget( - portalFollower: const SizedBox( - width: AppGridDashboardViewStyle.sizIcAppGrid, - ), - visible: isOpenAppGridDashboard, - child: PortalTarget( - anchor: const Aligned( - follower: Alignment.topRight, - target: Alignment.bottomRight, - ), - portalFollower: ValueListenableBuilder( - valueListenable: controller.linagoraApplications, - builder: (context, linagoraApplications, child) { - if (linagoraApplications == null) return child!; - return AppGridDashboardOverlay( - linagoraApplications, - ); - }, - child: const SizedBox.shrink(), - ), - visible: isOpenAppGridDashboard, - child: Container( - decoration: BoxDecoration( - color: color, - borderRadius: - AppGridDashboardViewStyle.appGridIconBorderRadius, - ), - padding: AppGridDashboardViewStyle.appGridIconPadding, - child: SvgPicture.asset( - ImagePaths.icApplicationGrid, - width: AppGridDashboardViewStyle.sizIcAppGrid, - height: AppGridDashboardViewStyle.sizIcAppGrid, + onTapOutside: (_) { + controller.hoverColorAppHelp.value = Colors.transparent; + }, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (_) => controller.hoverColorAppHelp.value = + AppGridDashboardViewStyle.hoverColor, + onExit: (_) { + controller.hoverColorAppHelp.value = Colors.transparent; + }, + child: ValueListenableBuilder( + valueListenable: controller.hoverColorAppHelp, + builder: (context, color, _) { + return TooltipVisibility( + visible: true, + child: Tooltip( + message: L10n.of(context)!.help, + showDuration: const Duration(seconds: 1), + waitDuration: const Duration(seconds: 1), + child: Container( + decoration: BoxDecoration( + color: color, + borderRadius: AppGridDashboardViewStyle + .appGridIconBorderRadius, + ), + padding: AppGridDashboardViewStyle.appGridIconPadding, + child: SvgPicture.asset( + ImagePaths.icTwakeSupport, + width: + AppGridDashboardViewStyle.sizeIcSupportButton, + height: + AppGridDashboardViewStyle.sizeIcSupportButton, + ), ), ), - ), - ); - }, + ); + }, + ), ), ), - ); - }, + ValueListenableBuilder( + valueListenable: controller.isOpenAppGridDashboardNotifier, + builder: (context, isOpenAppGridDashboard, _) { + return TapRegion( + behavior: HitTestBehavior.opaque, + onTapInside: (_) { + controller.isOpenAppGridDashboardNotifier.toggle(); + }, + onTapOutside: (_) { + controller.hideAppGridDashboard(); + controller.hoverColorAppGrid.value = Colors.transparent; + }, + child: MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (_) => controller.hoverColorAppGrid.value = + AppGridDashboardViewStyle.hoverColor, + onExit: (_) { + if (!isOpenAppGridDashboard) { + controller.hoverColorAppGrid.value = Colors.transparent; + } + }, + child: ValueListenableBuilder( + valueListenable: controller.hoverColorAppGrid, + builder: (context, color, child) { + return PortalTarget( + portalFollower: const SizedBox( + width: AppGridDashboardViewStyle.sizIcAppGrid, + ), + visible: isOpenAppGridDashboard, + child: PortalTarget( + anchor: const Aligned( + follower: Alignment.topRight, + target: Alignment.bottomRight, + ), + portalFollower: ValueListenableBuilder( + valueListenable: controller.linagoraApplications, + builder: (context, linagoraApplications, child) { + if (linagoraApplications == null) return child!; + return AppGridDashboardOverlay( + linagoraApplications, + ); + }, + child: const SizedBox.shrink(), + ), + visible: isOpenAppGridDashboard, + child: Container( + decoration: BoxDecoration( + color: color, + borderRadius: AppGridDashboardViewStyle + .appGridIconBorderRadius, + ), + padding: + AppGridDashboardViewStyle.appGridIconPadding, + child: SvgPicture.asset( + ImagePaths.icApplicationGrid, + width: AppGridDashboardViewStyle.sizIcAppGrid, + height: AppGridDashboardViewStyle.sizIcAppGrid, + ), + ), + ), + ); + }, + ), + ), + ); + }, + ), + ], ), ); } diff --git a/lib/pages/app_grid/app_grid_dashboard_view_style.dart b/lib/pages/app_grid/app_grid_dashboard_view_style.dart index 30084fffd9..5c002f8376 100644 --- a/lib/pages/app_grid/app_grid_dashboard_view_style.dart +++ b/lib/pages/app_grid/app_grid_dashboard_view_style.dart @@ -3,6 +3,10 @@ import 'package:flutter/material.dart'; class AppGridDashboardViewStyle { static const double sizIcAppGrid = 23.0; + static const double sizeSupportButton = 36.0; + + static const double sizeIcSupportButton = 24.0; + static const Color hoverColor = Color(0xFFF2F8FB); static const BorderRadius appGridIconBorderRadius = diff --git a/lib/resource/image_paths.dart b/lib/resource/image_paths.dart index c6d62de316..bc31d45890 100644 --- a/lib/resource/image_paths.dart +++ b/lib/resource/image_paths.dart @@ -56,6 +56,8 @@ class ImagePaths { static String get logoPng => _getAssetPath('logo.png'); static String get appStore => _getImagePath('app_store.svg'); static String get googlePlay => _getImagePath('google_play.svg'); + static String get icTwakeSupport => + getConfigurationImagePath('ic_twake_support.svg'); static String _getImagePath(String imageName) { return AssetsPaths.images + imageName;