diff --git a/apps/flutter/components/lib/widgets/menu/index.dart b/apps/flutter/components/lib/widgets/menu/index.dart index b060f7e82..ff9f64846 100644 --- a/apps/flutter/components/lib/widgets/menu/index.dart +++ b/apps/flutter/components/lib/widgets/menu/index.dart @@ -21,11 +21,7 @@ class Navigation extends StatefulWidget { class _NavigationState extends State { @override Widget build(BuildContext context) { - return SingleChildScrollView( - child: Container( - child: _renderNavigations(widget.menus), - ), - ); + return _renderNavigations(widget.menus); } Widget _renderNavigations(List menus) { @@ -59,7 +55,8 @@ class _NavigationState extends State { return SizedBox( height: 30, child: ListTile( - title: Text(menu.displayName.padLeft(menu.level * 4)), + title: Text( + (menu.meta?['displayName']?.toString().tr ?? menu.displayName).padLeft(menu.level * 4)), ), ); }, @@ -81,7 +78,7 @@ class _NavigationState extends State { height: 30, margin: const EdgeInsets.only(top: 10), child: Text( - menu.displayName.padLeft(menu.level * 8), + (menu.meta?['displayName']?.toString().tr ?? menu.displayName).padLeft(menu.level * 8), ), ), ), diff --git a/apps/flutter/core/lib/models/environment.dart b/apps/flutter/core/lib/models/environment.dart index 0ac766486..f99127ebd 100644 --- a/apps/flutter/core/lib/models/environment.dart +++ b/apps/flutter/core/lib/models/environment.dart @@ -177,10 +177,12 @@ class LocalizationConfig { this.defaultLanguage, this.useLocalResources = true, this.supportedLocales = const [], + this.translationFiles = const {}, }); String? defaultLanguage; bool? useLocalResources; List? supportedLocales; + Map>? translationFiles; factory LocalizationConfig.fromJson(Map json) => _$LocalizationConfigFromJson(json); Map toJson() => _$LocalizationConfigToJson(this); diff --git a/apps/flutter/core/lib/models/environment.g.dart b/apps/flutter/core/lib/models/environment.g.dart index 07efcf04e..45c7cf6fc 100644 --- a/apps/flutter/core/lib/models/environment.g.dart +++ b/apps/flutter/core/lib/models/environment.g.dart @@ -102,6 +102,11 @@ LocalizationConfig _$LocalizationConfigFromJson(Map json) => supportedLocales: json['supportedLocales'] != null ? (json['supportedLocales'] as List).map((e) => LanguageInfo.fromJson(e)).toList() : null, + translationFiles: json['translationFiles'] != null + ? (json['translationFiles'] as Map) + .map((key, value) => MapEntry(key, (value as List) + .map((e) => e as String).toList())) + : null, ); Map _$LocalizationConfigToJson(LocalizationConfig instance) => @@ -109,6 +114,7 @@ Map _$LocalizationConfigToJson(LocalizationConfig instance) => 'defaultLanguage': instance.defaultLanguage, 'useLocalResources': instance.useLocalResources, 'supportedLocales': instance.supportedLocales, + 'translationFiles': instance.translationFiles, }; RemoteService _$RemoteServiceFromJson(Map json) => diff --git a/apps/flutter/dev_app/.gitignore b/apps/flutter/dev_app/.gitignore index bceef1d48..0333a3f0e 100644 --- a/apps/flutter/dev_app/.gitignore +++ b/apps/flutter/dev_app/.gitignore @@ -44,4 +44,8 @@ app.*.map.json /android/app/release # Environment config -/res/config/development.json \ No newline at end of file +/res/config/development.json + +# Ignored translations +/res/translations/merge-en.json +/res/translations/merge-zh-Hans.json \ No newline at end of file diff --git a/apps/flutter/dev_app/lib/pages/main/controller.dart b/apps/flutter/dev_app/lib/pages/main/controller.dart index ccfccf474..7cd35ca98 100644 --- a/apps/flutter/dev_app/lib/pages/main/controller.dart +++ b/apps/flutter/dev_app/lib/pages/main/controller.dart @@ -1,13 +1,13 @@ import 'package:core/dependency/index.dart'; import 'package:core/abstracts/signalr.service.dart'; import 'package:core/services/environment.service.dart'; -import 'package:core/services/notification.send.service.dart'; import 'package:dev_app/handlers/index.dart'; import 'package:get/get.dart'; import 'package:core/services/session.service.dart'; import 'package:core/services/subscription.service.dart'; import 'package:core/utils/index.dart'; import 'package:notifications/models/index.dart'; +import 'package:notifications/services/notification.state.service.dart'; import 'package:notifications/tokens/index.dart'; class MainController extends GetxController { @@ -17,7 +17,7 @@ class MainController extends GetxController { SessionService get _sessionService => injector.get(); SubscriptionService get _subscriptionService => injector.get(tag: NotificationTokens.consumer); SignalrService get _signalrService => injector.get(tag: NotificationTokens.producer); - NotificationSendService get _notificationSendService => injector.get(); + NotificationStateService get _notificationStateService => injector.get(); EnvironmentService get _environmentService => injector.get(); ErrorHandler get _errorHandler => injector.get(); @@ -37,14 +37,7 @@ class MainController extends GetxController { if (data == null) continue; // 解析通知数据 var notification = NotificationInfo.fromJson(data as dynamic); - // 格式化为移动端可识别通知数据 - var payload = NotificationPaylod.fromNotification(notification); - // 发布本地通知 - await _notificationSendService.send( - payload.title, - payload.body, - payload.payload, - ); + _notificationStateService.addNotification(notification); } }, ); diff --git a/apps/flutter/dev_app/lib/pages/public/home/controller.dart b/apps/flutter/dev_app/lib/pages/public/home/controller.dart index b6884ba1c..9b272b415 100644 --- a/apps/flutter/dev_app/lib/pages/public/home/controller.dart +++ b/apps/flutter/dev_app/lib/pages/public/home/controller.dart @@ -1,6 +1,7 @@ import 'package:core/models/common.dart'; import 'package:get/get.dart'; import 'package:core/dependency/index.dart'; +import 'package:notifications/services/notification.state.service.dart'; import 'package:platforms/services/index.dart'; import 'state.dart'; @@ -8,6 +9,7 @@ import 'state.dart'; class HomeController extends GetxController { MenuStateService get _menuStateService => injector.get(); FavoriteMenuStateService get _favoriteMenuStateService => injector.get(); + NotificationStateService get _notificationStateService => injector.get(); final Rx _state = Rx(HomeState()); HomeState get state => _state.value; @@ -27,6 +29,18 @@ class HomeController extends GetxController { val?.favoriteMenus = menus; }); }); + _notificationStateService.getNotifications$() + .listen((payload) { + var notifications = state.notifications.reversed.take(5).toList(); + notifications.add(payload); + _state.update((val) { + val?.notifications = notifications; + }); + }); + } + + Future refreshMenus() async { + await _menuStateService.refreshState(); } void redirectToRoute(String route) { diff --git a/apps/flutter/dev_app/lib/pages/public/home/state.dart b/apps/flutter/dev_app/lib/pages/public/home/state.dart index cafd45fd6..4ddaa2a60 100644 --- a/apps/flutter/dev_app/lib/pages/public/home/state.dart +++ b/apps/flutter/dev_app/lib/pages/public/home/state.dart @@ -1,4 +1,5 @@ import 'package:core/models/common.dart'; +import 'package:notifications/models/common.dart'; import 'package:platforms/modes/menu.dto.dart'; class HomeState { @@ -6,10 +7,12 @@ class HomeState { this.activedMenu, this.menus = const [], this.favoriteMenus = const [], + this.notifications = const [], }); String? activedMenu; List menus; List favoriteMenus; + List notifications; List getMenus() => _buildTreeRecursive(menus, null, 0); diff --git a/apps/flutter/dev_app/lib/pages/public/home/view.dart b/apps/flutter/dev_app/lib/pages/public/home/view.dart index b6a77950c..b55edaa17 100644 --- a/apps/flutter/dev_app/lib/pages/public/home/view.dart +++ b/apps/flutter/dev_app/lib/pages/public/home/view.dart @@ -1,13 +1,13 @@ import 'package:account/pages/route.name.dart'; import 'package:components/index.dart'; import 'package:core/utils/index.dart'; -import 'package:dev_app/pages/public/home/widget/search.dart'; import 'package:dev_app/pages/system/route.name.dart'; import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'controller.dart'; +import './widget/index.dart'; class HomePage extends BasePage { const HomePage({super.key}); @@ -35,114 +35,47 @@ class HomePage extends BasePage { ), body: ListView( children: [ - ExpansionTile( - initiallyExpanded: true, - title: Text('Label:QuickNavigation'.tr, - style: Theme.of(context).textTheme.titleMedium, - ), - children: [ - SizedBox( - height: 120, - child: GridView.count( - shrinkWrap: true, - crossAxisCount: 4, - crossAxisSpacing: 5, - physics: const NeverScrollableScrollPhysics(), - children: [ - _buildMenu( - SystemRoutes.settings, - SystemRoutes.settings, - icon: 'res/images/setting.png', - displayName: "Label:SystemSettings".tr, - color: Colors.red.hex), - _buildMenu( - AccountRoutes.profile, - AccountRoutes.profile, - icon: 'res/images/profile.png', - displayName: "Page:UserProfile".tr, - color: const Color.fromARGB(255, 68, 160, 206).hex), - ], - ), - ), - ], - ), - ExpansionTile( - initiallyExpanded: true, - title: Text('Label:MyFavorite'.tr, - style: Theme.of(context).textTheme.titleMedium, - ), - children: [ - GridView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: bloc.state.favoriteMenus.length, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 4, - crossAxisSpacing: 5, - ), - itemBuilder: (BuildContext context, int index) { - if (index >= bloc.state.favoriteMenus.length) { - return Empty.none; - } - var favoriteMenu = bloc.state.favoriteMenus[index]; - return _buildMenu( - favoriteMenu.name, - favoriteMenu.path, - aliasName: favoriteMenu.aliasName, - //icon: favoriteMenu.icon, - // TODO: 需要各个模块自行提供本地图标 - icon: 'res/images/setting.png', - color: favoriteMenu.color, - displayName: favoriteMenu.displayName, - ); - }, - ), - ], + Obx(() => NotificationBar(notifications: bloc.state.notifications)), + QuickNavigation( + menus: [ + _buildMenu( + SystemRoutes.settings, + SystemRoutes.settings, + icon: 'res/images/setting.png', + displayName: "Label:SystemSettings".tr, + color: Colors.red.hex), + _buildMenu( + AccountRoutes.profile, + AccountRoutes.profile, + icon: 'res/images/profile.png', + displayName: "Page:UserProfile".tr, + color: const Color.fromARGB(255, 68, 160, 206).hex), + ], ), + Obx(() => MyFavorite( + favoriteMenus: bloc.state.favoriteMenus, + favoriteMenuBuilder: (favoriteMenu) { + return _buildMenu( + favoriteMenu.name, + favoriteMenu.path, + aliasName: favoriteMenu.aliasName, + //icon: favoriteMenu.icon, + // TODO: 需要各个模块自行提供本地图标 + icon: 'res/images/setting.png', + color: favoriteMenu.color, + displayName: favoriteMenu.displayName, + ); + }, + )), ], ), drawer: SafeArea( - child: Container( - width: 260, - color: const Color.fromARGB(255, 44, 115, 141), - child: Column( - children: [ - Container( - height: 24, - margin: const EdgeInsets.all(10), - child: Row( - children: [ - Padding( - padding: const EdgeInsets.only(left: 10), - child: Image.asset( - 'res/images/logo.png', - height: 20, - width: 20, - ), - ), - const Padding( - padding: EdgeInsets.only(left: 10), - child: Text( - 'abp flutter', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w400, - ), - ), - ), - ], - ), - ), - Expanded( - child: Obx(() => Navigation( - activedMenu: bloc.state.activedMenu, - menus: bloc.state.getMenus(), - onMenuExpanded: bloc.onMenuExpanded, - )), - ), - ], - ), - ) + child: Obx(() => MenuDrawer( + activedMenu: bloc.state.activedMenu, + menus: bloc.state.getMenus(), + onMenuExpanded: bloc.onMenuExpanded, + onMenuRefresh: bloc.refreshMenus, + )), ), ); } diff --git a/apps/flutter/dev_app/lib/pages/public/home/widget/index.dart b/apps/flutter/dev_app/lib/pages/public/home/widget/index.dart new file mode 100644 index 000000000..769be9109 --- /dev/null +++ b/apps/flutter/dev_app/lib/pages/public/home/widget/index.dart @@ -0,0 +1,5 @@ +export 'search.dart'; +export 'menu_drawer.dart'; +export 'my_favorite.dart'; +export 'notification_bar.dart'; +export 'quick_navigation.dart'; \ No newline at end of file diff --git a/apps/flutter/dev_app/lib/pages/public/home/widget/menu_drawer.dart b/apps/flutter/dev_app/lib/pages/public/home/widget/menu_drawer.dart new file mode 100644 index 000000000..2fd2a49f4 --- /dev/null +++ b/apps/flutter/dev_app/lib/pages/public/home/widget/menu_drawer.dart @@ -0,0 +1,76 @@ +import 'package:components/widgets/menu/index.dart'; +import 'package:core/models/common.dart'; +import 'package:flutter/material.dart'; + +class MenuDrawer extends StatelessWidget { + const MenuDrawer({ + super.key, + this.activedMenu, + this.menus = const [], + required this.onMenuRefresh, + this.onMenuExpanded, + }); + + final String? activedMenu; + final List menus; + final void Function(Menu menu)? onMenuExpanded; + final Future Function() onMenuRefresh; + + @override + Widget build(BuildContext context) { + return RefreshIndicator( + onRefresh: onMenuRefresh, + child: Drawer( + width: 260, + child: Column( + children: [ + _buildLogo(), + Expanded( + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: Column( + children: [ + Navigation( + activedMenu: activedMenu, + menus: menus, + onMenuExpanded: onMenuExpanded, + ), + ], + ), + ) + ), + ], + ), + ), + ); + } + + Widget _buildLogo() { + return Container( + height: 24, + margin: const EdgeInsets.all(10), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 10), + child: Image.asset( + 'res/images/logo.png', + height: 20, + width: 20, + ), + ), + const Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + 'abp flutter', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w400, + ), + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/apps/flutter/dev_app/lib/pages/public/home/widget/my_favorite.dart b/apps/flutter/dev_app/lib/pages/public/home/widget/my_favorite.dart new file mode 100644 index 000000000..ef2c0984d --- /dev/null +++ b/apps/flutter/dev_app/lib/pages/public/home/widget/my_favorite.dart @@ -0,0 +1,42 @@ +import 'package:components/widgets/empty/index.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:platforms/modes/menu.dto.dart'; + +class MyFavorite extends StatelessWidget { + const MyFavorite({ + super.key, + required this.favoriteMenus, + required this.favoriteMenuBuilder, + }); + + final List favoriteMenus; + final Widget Function(UserFavoriteMenuDto favoriteMenu) favoriteMenuBuilder; + + @override + Widget build(BuildContext context) { + return ExpansionTile( + initiallyExpanded: true, + title: Text('Label:MyFavorite'.tr, + style: Theme.of(context).textTheme.titleMedium, + ), + children: [ + GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: favoriteMenus.length, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + crossAxisSpacing: 5, + ), + itemBuilder: (BuildContext context, int index) { + if (index >= favoriteMenus.length) { + return Empty.none; + } + return favoriteMenuBuilder(favoriteMenus[index]); + }, + ), + ], + ); + } +} \ No newline at end of file diff --git a/apps/flutter/dev_app/lib/pages/public/home/widget/notification_bar.dart b/apps/flutter/dev_app/lib/pages/public/home/widget/notification_bar.dart new file mode 100644 index 000000000..b7272fc64 --- /dev/null +++ b/apps/flutter/dev_app/lib/pages/public/home/widget/notification_bar.dart @@ -0,0 +1,55 @@ +import 'package:bruno/bruno.dart'; +import 'package:components/widgets/empty/index.dart'; +import 'package:flutter/material.dart'; +import 'package:notifications/models/common.dart'; +import 'package:notifications/models/notification.dart'; + +class NotificationBar extends StatelessWidget { + const NotificationBar({ + super.key, + required this.notifications + }); + + final List notifications; + + @override + Widget build(BuildContext context) { + if (notifications.isEmpty) { + return Empty.none; + } + return SizedBox( + height: 40, + child: SingleChildScrollView( + child: Column( + children: notifications.map((payload) { + return BrnNoticeBar( + padding: const EdgeInsets.only(left: 5, right: 5, top: 3), + leftWidget: Image.asset( + 'res/images/notification.png', + height: 30, + width: 30, + ), + content: payload.title, + marquee: true, + noticeStyle: _mapNoticeStyles(payload.severity), + ); + }).toList(), + ), + ), + ); + } + + NoticeStyle _mapNoticeStyles(NotificationSeverity? severity) { + if (severity == null) return NoticeStyles.normalNoticeWithArrow; + switch (severity) { + case NotificationSeverity.info: + case NotificationSeverity.success: + return NoticeStyles.succeedWithArrow; + case NotificationSeverity.fatal: + case NotificationSeverity.error: + return NoticeStyles.failWithArrow; + case NotificationSeverity.warn: + return NoticeStyles.warningWithArrow; + } + } +} \ No newline at end of file diff --git a/apps/flutter/dev_app/lib/pages/public/home/widget/quick_navigation.dart b/apps/flutter/dev_app/lib/pages/public/home/widget/quick_navigation.dart new file mode 100644 index 000000000..929bb3c10 --- /dev/null +++ b/apps/flutter/dev_app/lib/pages/public/home/widget/quick_navigation.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +class QuickNavigation extends StatelessWidget { + const QuickNavigation({ + super.key, + this.menus = const [], + }); + + final List menus; + + @override + Widget build(BuildContext context) { + return ExpansionTile( + initiallyExpanded: true, + title: Text('Label:QuickNavigation'.tr, + style: Theme.of(context).textTheme.titleMedium, + ), + children: [ + SizedBox( + height: 120, + child: GridView.count( + shrinkWrap: true, + crossAxisCount: 4, + crossAxisSpacing: 5, + physics: const NeverScrollableScrollPhysics(), + children: menus, + ), + ), + ], + ); + } +} \ No newline at end of file diff --git a/apps/flutter/dev_app/lib/services/notification.send.local.service.dart b/apps/flutter/dev_app/lib/services/notification.send.local.service.dart index beddf7184..de9191cc8 100644 --- a/apps/flutter/dev_app/lib/services/notification.send.local.service.dart +++ b/apps/flutter/dev_app/lib/services/notification.send.local.service.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:core/index.dart'; import 'package:get/get.dart'; +import 'package:notifications/services/notification.state.service.dart'; import 'package:rxdart/rxdart.dart' hide Notification; import 'package:core/models/notifications.dart'; @@ -14,6 +15,22 @@ class FlutterLocalNotificationsSendService extends NotificationSendService { final Subject _selectedNotifications$ = BehaviorSubject(); EnvironmentService get _environmentService => resolve(); + NotificationStateService get _notificationStateService => resolve(); + + @override + void onInit() { + super.onInit(); + _notificationStateService + .getNotifications$() + .listen((payload) async { + // 发布本地通知 + await send( + payload.title, + payload.body, + payload.payload, + ); + }); + } Future initAsync() async { var environment = _environmentService.getEnvironment(); diff --git a/apps/flutter/dev_app/lib/services/translation.service.res.service.dart b/apps/flutter/dev_app/lib/services/translation.service.res.service.dart index 82a9dfe84..28ef8e23f 100644 --- a/apps/flutter/dev_app/lib/services/translation.service.res.service.dart +++ b/apps/flutter/dev_app/lib/services/translation.service.res.service.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:core/services/environment.service.dart'; import 'package:core/services/localization.service.dart'; import 'package:core/services/service.base.dart'; import 'package:core/services/session.service.dart'; @@ -17,6 +18,7 @@ class TranslationResService extends ServiceBase implements TranslationService { final InternalStore _store = InternalStore(state: TranslationState()); SessionService get _sessionService => resolve(); + EnvironmentService get _environmentService => resolve(); LocalizationService get _localizationService => resolve(); @override @@ -44,13 +46,21 @@ class TranslationResService extends ServiceBase implements TranslationService { Future _mapTranslationsMap(String language) async { Map> translationsMap = {}; - var filePath = 'res/translations/$language.json'; - var content = await rootBundle.loadString(filePath); - var translationsObject = jsonDecode(content) as Map; - translationsMap.putIfAbsent( - language, - () => translationsObject.map((key, value) => MapEntry(key, value)) - ); + var environment = _environmentService.getEnvironment(); + var translationFiles = environment.localization.translationFiles?[language] ?? ['$language.json']; + + for (var translationFile in translationFiles) { + try { + var filePath = 'res/translations/$translationFile'; + var content = await rootBundle.loadString(filePath); + var translationsObject = jsonDecode(content) as Map; + var translations = translationsMap[language] ?? {}; + translations.addAll(translationsObject.map((key, value) => MapEntry(key, value))); + translationsMap.putIfAbsent(language, () => translations); + } catch (e) { + logger.error(e); + } + } return TranslationState( language: language, translations: translationsMap, diff --git a/apps/flutter/dev_app/res/config/demo.json b/apps/flutter/dev_app/res/config/demo.json index 49b54960f..840abdf4e 100644 --- a/apps/flutter/dev_app/res/config/demo.json +++ b/apps/flutter/dev_app/res/config/demo.json @@ -13,6 +13,20 @@ "localization": { "useLocalResources": true, "defaultLanguage": "zh-Hans", + "translationFiles": { + "zh-Hans": [ + "zh-Hans.json" + ], + "zh_CN": [ + "zh-Hans.json" + ], + "en": [ + "en.json" + ], + "en_US": [ + "en.json" + ] + }, "supportedLocales": [ { "cultureName": "en", diff --git a/apps/flutter/dev_app/res/images/notification.png b/apps/flutter/dev_app/res/images/notification.png new file mode 100644 index 000000000..bf3be84b1 Binary files /dev/null and b/apps/flutter/dev_app/res/images/notification.png differ diff --git a/apps/flutter/notifications/lib/models/notification.state.dart b/apps/flutter/notifications/lib/models/notification.state.dart index 2b7882188..a45bfc9ac 100644 --- a/apps/flutter/notifications/lib/models/notification.state.dart +++ b/apps/flutter/notifications/lib/models/notification.state.dart @@ -14,6 +14,7 @@ class NotificationState { }); bool isEnabled; List groups; + NotificationGroup? findGroup(String name) { return groups.firstWhereOrNull((item) => item.name == name); diff --git a/apps/flutter/notifications/lib/services/notification.state.service.dart b/apps/flutter/notifications/lib/services/notification.state.service.dart index 037a588d5..3cfa8eb73 100644 --- a/apps/flutter/notifications/lib/services/notification.state.service.dart +++ b/apps/flutter/notifications/lib/services/notification.state.service.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:notifications/models/common.dart'; import 'package:rxdart/rxdart.dart' hide Notification; import 'package:notifications/models/notification.dart'; import 'package:core/services/session.service.dart'; @@ -20,6 +21,8 @@ class NotificationStateService extends ServiceBase { NotificationService get _notificationService => resolve(); SignalrService get _signalrService => resolve(tag: NotificationTokens.producer); + final BehaviorSubject _notifications = BehaviorSubject(); + final InternalStore _store = InternalStore( state: _initState() ); @@ -41,6 +44,10 @@ class NotificationStateService extends ServiceBase { return _store.sliceUpdate((state) => state); } + Stream getNotifications$() { + return _notifications; + } + NotificationGroup? findGroup(String name) { return _store.state.findGroup(name); } @@ -75,6 +82,10 @@ class NotificationStateService extends ServiceBase { return configState ?? NotificationState(isEnabled: true, groups: []); } + void addNotification(NotificationInfo notification) { + _notifications.add(NotificationPaylod.fromNotification(notification)); + } + Future> getGroupAndCombineWithNotification(List groupItems) { return _notificationService.getMySubscribedListAsync() .then((subscres) { diff --git a/apps/flutter/platform/lib/services/favorite.menu.state.service.dart b/apps/flutter/platform/lib/services/favorite.menu.state.service.dart index eb9e6b272..c29255709 100644 --- a/apps/flutter/platform/lib/services/favorite.menu.state.service.dart +++ b/apps/flutter/platform/lib/services/favorite.menu.state.service.dart @@ -33,7 +33,7 @@ class FavoriteMenuStateService extends ServiceBase { Future refreshState() async { var environment = _environmentService.getEnvironment(); - var framework = environment.application.framework ?? 'flutter'; + var framework = environment.application.framework ?? 'abp-flutter'; var result = await _favoriteMenuService.getMyFavoriteMenuList(framework); _state.patch((state) => state.menus = result.items); } diff --git a/apps/flutter/platform/lib/services/menu.state.service.dart b/apps/flutter/platform/lib/services/menu.state.service.dart index ac302d6d8..8729a72e8 100644 --- a/apps/flutter/platform/lib/services/menu.state.service.dart +++ b/apps/flutter/platform/lib/services/menu.state.service.dart @@ -33,7 +33,7 @@ class MenuStateService extends ServiceBase { Future refreshState() async { var environment = _environmentService.getEnvironment(); - var framework = environment.application.framework ?? 'flutter'; + var framework = environment.application.framework ?? 'abp-flutter'; var result = await _menuService.getCurrentUserMenuList(framework); _state.patch((state) => state.menus = result.items); }