diff --git a/lib/models/overview_data.dart b/lib/models/overview_data.dart index 4fc6be9..f3a7639 100644 --- a/lib/models/overview_data.dart +++ b/lib/models/overview_data.dart @@ -15,6 +15,7 @@ class OverviewData { final bool forManagers; final String createdAt; final String type; + int typeInteger; int comments; bool marked; final List? categories; @@ -35,17 +36,41 @@ class OverviewData { this.timeToRead, this.reference, this.categories, - }); + this.typeInteger = 0, + }) { + switch (type) { + case 'radar': + typeInteger = 1; + break; + case 'news': + typeInteger = 2; + break; + case 'video': + typeInteger = 3; + break; + case 'podcast': + typeInteger = 4; + break; + case 'saha': + typeInteger = 6; + break; + default: + typeInteger = 5; + } + typeInteger = 2; + } factory OverviewData.fromJson(Map json) { - final document = parse(json['description']); - final String parsedString = - parse(document.body!.text).documentElement!.text; + String? description; + if (json['description'] != null) { + final document = parse(json['description']); + description = parse(document.body!.text).documentElement!.text; + } return OverviewData( id: json['id'], title: json['title'], - image: json['image'], - description: parsedString, + image: json['image'] ?? 'https://wallpapercave.com/fwp/wp12977378.jpg', + description: description ?? '', timeToRead: json['timeToRead'], reference: json['reference'], forManagers: json['forManagers'] ?? false, diff --git a/lib/providers/user.dart b/lib/providers/user.dart index a253a3b..cf3d984 100644 --- a/lib/providers/user.dart +++ b/lib/providers/user.dart @@ -25,9 +25,9 @@ class UserProvider extends CoreProvier { int get unreadMessageCount => _unreadMessageCount; - static final List _radarMarkQueue = []; - static final List _newsMarkQueue = []; - static final List _studioMarkQueue = []; + // static final List _radarMarkQueue = []; + // static final List _newsMarkQueue = []; + // static final List _studioMarkQueue = []; static final List _statisticMarkQueue = []; static final List _itemMarkQueue = []; @@ -188,53 +188,53 @@ class UserProvider extends CoreProvier { }); } - static Future changeRadarMark(int id, bool value) async { - _radarMarkQueue.add(MapEntry(id, value)); - Future.delayed(const Duration(milliseconds: 500), () async { - final MapEntry? lastChange = - _radarMarkQueue.lastWhereOrNull((item) => item.key == id); - if (lastChange == null) return; - final service = RequestService(RequestHelper.mark(id, 'radar')); - if (lastChange.value) { - await service.post(); - } else { - await service.delete(); - } - _radarMarkQueue.removeWhere((element) => element.key == id); - }); - } + // static Future changeRadarMark(int id, bool value) async { + // _radarMarkQueue.add(MapEntry(id, value)); + // Future.delayed(const Duration(milliseconds: 500), () async { + // final MapEntry? lastChange = + // _radarMarkQueue.lastWhereOrNull((item) => item.key == id); + // if (lastChange == null) return; + // final service = RequestService(RequestHelper.mark(id, 'radar')); + // if (lastChange.value) { + // await service.post(); + // } else { + // await service.delete(); + // } + // _radarMarkQueue.removeWhere((element) => element.key == id); + // }); + // } - static Future changeStudioMark(int id, bool value) async { - _studioMarkQueue.add(MapEntry(id, value)); - Future.delayed(const Duration(milliseconds: 500), () async { - final MapEntry? lastChange = - _studioMarkQueue.lastWhereOrNull((item) => item.key == id); - if (lastChange == null) return; - final service = RequestService(RequestHelper.mark(id, 'studio')); - if (lastChange.value) { - await service.post(); - } else { - await service.delete(); - } - _studioMarkQueue.removeWhere((element) => element.key == id); - }); - } + // static Future changeStudioMark(int id, bool value) async { + // _studioMarkQueue.add(MapEntry(id, value)); + // Future.delayed(const Duration(milliseconds: 500), () async { + // final MapEntry? lastChange = + // _studioMarkQueue.lastWhereOrNull((item) => item.key == id); + // if (lastChange == null) return; + // final service = RequestService(RequestHelper.mark(id, 'studio')); + // if (lastChange.value) { + // await service.post(); + // } else { + // await service.delete(); + // } + // _studioMarkQueue.removeWhere((element) => element.key == id); + // }); + // } - static Future changeNewsMark(int id, bool value) async { - _newsMarkQueue.add(MapEntry(id, value)); - Future.delayed(const Duration(milliseconds: 500), () async { - final MapEntry? lastChange = - _newsMarkQueue.lastWhereOrNull((item) => item.key == id); - if (lastChange == null) return; - final service = RequestService(RequestHelper.mark(id, 'news')); - if (lastChange.value) { - await service.post(); - } else { - await service.delete(); - } - _newsMarkQueue.removeWhere((element) => element.key == id); - }); - } + // static Future changeNewsMark(int id, bool value) async { + // _newsMarkQueue.add(MapEntry(id, value)); + // Future.delayed(const Duration(milliseconds: 500), () async { + // final MapEntry? lastChange = + // _newsMarkQueue.lastWhereOrNull((item) => item.key == id); + // if (lastChange == null) return; + // final service = RequestService(RequestHelper.mark(id, 'news')); + // if (lastChange.value) { + // await service.post(); + // } else { + // await service.delete(); + // } + // _newsMarkQueue.removeWhere((element) => element.key == id); + // }); + // } static Future changeStatisticMark(int id, bool value) async { _statisticMarkQueue.add(MapEntry(id, value)); @@ -252,11 +252,11 @@ class UserProvider extends CoreProvier { }); } - Future getUnreadMessageCount() async { - final RequestService service = RequestService(RequestHelper.directs); - await service.httpGet(); - if (service.isSuccess) { - _unreadMessageCount = service.result['unread'] ?? 0; - } - } + // Future getUnreadMessageCount() async { + // final RequestService service = RequestService(RequestHelper.directs); + // await service.httpGet(); + // if (service.isSuccess) { + // _unreadMessageCount = service.result['unread'] ?? 0; + // } + // } } diff --git a/lib/services/network/request_helper.dart b/lib/services/network/request_helper.dart index 2214268..b656f99 100644 --- a/lib/services/network/request_helper.dart +++ b/lib/services/network/request_helper.dart @@ -51,17 +51,6 @@ class RequestHelper { static const String otp = '$_baseUserUrl/otp'; static String editItemBookmark(String type, int id) => '$_baseHomeUrl/$type/$id/mark'; - static String bookmarks({ - required int page, - String? search, - String? type, - String? studioType, - }) => - '$_baseUserUrl/marked/${type ?? ''}${_urlConcatGenerator([ - MapEntry('page', page), - MapEntry('type', studioType), - MapEntry('search', search), - ])}'; static const String directTypes = '$baseUrl/direct/types'; static String direct(int id) => '$_baseDirectUrl/$id'; diff --git a/lib/views/home/bookmarks/bookmark_state.dart b/lib/views/home/bookmarks/bookmark_state.dart index 85d5a44..67f0a8d 100644 --- a/lib/views/home/bookmarks/bookmark_state.dart +++ b/lib/views/home/bookmarks/bookmark_state.dart @@ -22,10 +22,10 @@ class BookmarksState extends CoreProvier { } this.page = page; appState = AppState.busy; - final service = - RequestService(RequestHelper.bookmarks(page: page, search: search)); + final service = RequestService( + RequestHelper.searchMarks(page: page, search: search), + ); await service.httpGet(); - if (service.isSuccess) { lastPage = service.result['lastPage']; final marks = service.result['contents']; diff --git a/lib/views/home/bookmarks/bookmarks.dart b/lib/views/home/bookmarks/bookmarks.dart index 1b7b61d..3795c7b 100644 --- a/lib/views/home/bookmarks/bookmarks.dart +++ b/lib/views/home/bookmarks/bookmarks.dart @@ -10,7 +10,6 @@ import 'package:didvan/views/widgets/overview/multitype.dart'; import 'package:didvan/views/widgets/animated_visibility.dart'; import 'package:didvan/views/widgets/didvan/card.dart'; import 'package:didvan/views/widgets/didvan/divider.dart'; -import 'package:didvan/views/widgets/didvan/scaffold.dart'; import 'package:didvan/views/widgets/item_title.dart'; import 'package:didvan/views/widgets/state_handlers/empty_list.dart'; import 'package:didvan/views/widgets/state_handlers/empty_result.dart'; @@ -40,111 +39,118 @@ class _BookmarksState extends State { @override Widget build(BuildContext context) { final state = context.watch(); - return DidvanScaffold( - appBarData: null, - // appBarData: AppBarData( - // title: 'نشان شده‌ها', - // hasBack: true, - // ), + return CustomScrollView( slivers: [ - SliverStateHandler( - state: state, - centerEmptyState: state.searching, - builder: (context, state, index) { - index++; - if (index % 15 == 0 && state.lastPage != state.page) { - state.getBookmarks(page: state.page + 1); - } - index--; - return MultitypeOverview( - item: state.bookmarks[index], - onMarkChanged: state.onMarkChanged, - hasUnmarkConfirmation: true, - enableCaption: true, - ); - }, - placeholder: MultitypeOverview.placeholder, - itemPadding: const EdgeInsets.only(bottom: 8), - emptyState: state.searching - ? EmptyResult(onNewSearch: _focuseNode.requestFocus) - : const EmptyList(), - enableEmptyState: state.bookmarks.isEmpty, - childCount: - state.bookmarks.length + (state.page != state.lastPage ? 1 : 0), - onRetry: () => state.getBookmarks(page: state.page), - ), - ], - children: [ - // SearchField( - // title: 'نشان شده‌ها', - // onChanged: _onChanged, - // focusNode: _focuseNode, - // ), - const SizedBox(height: 16), - AnimatedVisibility( - duration: DesignConfig.lowAnimationDuration, - isVisible: !state.searching, - child: DidvanCard( + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 16), + sliver: SliverToBoxAdapter( child: Column( children: [ - MenuOption( - onTap: () => _onCategorySelected('radar'), - title: 'تحلیل‌های رادار', - icon: DidvanIcons.radar_solid, - iconSize: 24, + const SizedBox(height: 16), + AnimatedVisibility( + duration: DesignConfig.lowAnimationDuration, + isVisible: !state.searching, + child: DidvanCard( + child: Column( + children: [ + MenuOption( + onTap: () => _onCategorySelected(5), + title: 'تحلیل‌های رادار', + icon: DidvanIcons.radar_solid, + iconSize: 24, + ), + const DidvanDivider(), + MenuOption( + onTap: () => _onCategorySelected(2), + title: 'دنیای فولاد', + icon: DidvanIcons.news_solid, + iconSize: 24, + ), + const DidvanDivider(), + MenuOption( + onTap: () => _onCategorySelected(1), + title: 'پویش افق', + icon: DidvanIcons.radar_solid, + iconSize: 24, + ), + const DidvanDivider(), + MenuOption( + onTap: () => _onCategorySelected(3), + title: 'ویدئو‌کست', + icon: DidvanIcons.video_solid, + iconSize: 24, + ), + const DidvanDivider(), + MenuOption( + onTap: () => _onCategorySelected(4), + title: 'پادکست‌ها', + icon: DidvanIcons.podcast_solid, + iconSize: 24, + ), + const DidvanDivider(), + MenuOption( + onTap: () => _onCategorySelected(6), + title: 'سها', + icon: DidvanIcons.podcast_solid, + iconSize: 24, + ), + ], + ), + ), ), - const DidvanDivider(), - MenuOption( - onTap: () => _onCategorySelected('news'), - title: 'دنیای فولاد', - icon: DidvanIcons.news_solid, - iconSize: 24, - ), - const DidvanDivider(), - MenuOption( - onTap: () => _onCategorySelected('radar'), - title: 'پویش افق', - icon: DidvanIcons.radar_solid, - iconSize: 24, - ), - const DidvanDivider(), - MenuOption( - onTap: () => _onCategorySelected('video'), - title: 'ویدئو‌کست', - icon: DidvanIcons.video_solid, - iconSize: 24, - ), - const DidvanDivider(), - MenuOption( - onTap: () => _onCategorySelected('podcast'), - title: 'پادکست‌ها', - icon: DidvanIcons.podcast_solid, - iconSize: 24, + Align( + alignment: Alignment.centerRight, + child: AnimatedVisibility( + duration: DesignConfig.lowAnimationDuration, + isVisible: !state.searching, + child: const ItemTitle(title: 'آخرین نشان شده‌ها'), + ), ), ], ), ), ), - Align( - alignment: Alignment.centerRight, - child: AnimatedVisibility( - duration: DesignConfig.lowAnimationDuration, - isVisible: !state.searching, - child: const ItemTitle(title: 'آخرین نشان شده‌ها'), + SliverPadding( + padding: const EdgeInsets.symmetric(horizontal: 16), + sliver: SliverStateHandler( + state: state, + centerEmptyState: state.searching, + builder: (context, state, index) { + index++; + if (index % 15 == 0 && state.lastPage != state.page) { + state.getBookmarks(page: state.page + 1); + } + index--; + return MultitypeOverview( + item: state.bookmarks[index], + onMarkChanged: state.onMarkChanged, + hasUnmarkConfirmation: true, + enableCaption: true, + ); + }, + placeholder: MultitypeOverview.placeholder, + itemPadding: const EdgeInsets.only(bottom: 8), + emptyState: state.searching + ? EmptyResult(onNewSearch: _focuseNode.requestFocus) + : const EmptyList(), + enableEmptyState: state.bookmarks.isEmpty, + childCount: + state.bookmarks.length + (state.page != state.lastPage ? 1 : 0), + onRetry: () => state.getBookmarks(page: state.page), ), ), ], ); } - void _onCategorySelected(String type) { + void _onCategorySelected(int type) { FocusScope.of(context).unfocus(); Navigator.of(context).pushNamed(Routes.filteredBookmarks, arguments: { 'type': type, 'onDeleted': (int id) { final state = context.read(); - state.bookmarks - .removeWhere((element) => element.id == id && element.type == type); + state.bookmarks.removeWhere( + (element) => element.id == id && element.typeInteger == type); state.update(); }, }); diff --git a/lib/views/home/bookmarks/filtered_bookmark/filtered_bookmark.dart b/lib/views/home/bookmarks/filtered_bookmark/filtered_bookmark.dart index e07da8f..319d92f 100644 --- a/lib/views/home/bookmarks/filtered_bookmark/filtered_bookmark.dart +++ b/lib/views/home/bookmarks/filtered_bookmark/filtered_bookmark.dart @@ -28,18 +28,20 @@ class _FilteredBookmarksState extends State { String get _appBarTitle { switch (context.read().type) { - case 'radar': + case 1: return 'پویش افق'; - case 'news': + case 2: return 'دنیای فولاد'; - case 'video': + case 3: return 'ویدئوکست‌ها'; - case 'podcast': + case 4: return 'پادکست‌ها'; - case 'new-radar': + case 5: return 'تحلیل‌های رادار'; + case 6: + return 'سها'; default: - return 'پادکست‌ها'; + return 'پویش'; } } diff --git a/lib/views/home/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart b/lib/views/home/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart index 555c953..a35c44e 100644 --- a/lib/views/home/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart +++ b/lib/views/home/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart @@ -6,7 +6,7 @@ import 'package:didvan/services/network/request_helper.dart'; class FilteredBookmarksState extends CoreProvier { final List bookmarks = []; - final String type; + final int type; int page = 1; int lastPage = 1; @@ -14,26 +14,17 @@ class FilteredBookmarksState extends CoreProvier { Future getBookmarks({required int page}) async { this.page = page; - String typeString = ''; - if (type == 'video' || type == 'podcast') { - typeString = 'studios'; - } else if (type == 'news') { - typeString = type; - } else { - typeString = '${type}s'; - } final service = RequestService( - RequestHelper.bookmarks( - type: typeString, + RequestHelper.searchMarks( + types: [type], page: page, - studioType: type == 'podcast' || type == 'video' ? type : null, ), ); await service.httpGet(); if (service.isSuccess) { lastPage = service.result['lastPage']; - final marks = service.result[typeString]; + final marks = service.result['contents']; for (var i = 0; i < marks.length; i++) { bookmarks.add(OverviewData.fromJson(marks[i])); } diff --git a/lib/views/home/home_state.dart b/lib/views/home/home_state.dart index 422127d..b8e4e91 100644 --- a/lib/views/home/home_state.dart +++ b/lib/views/home/home_state.dart @@ -35,6 +35,7 @@ class HomeState extends CoreProvier { final List selectedCats = []; final List results = []; late TabController tabController; + int unreadCount = 0; void resetFilters(bool isInit) { startDate = null; @@ -122,6 +123,7 @@ class HomeState extends CoreProvier { await service.httpGet(); if (service.isSuccess) { lastPage = service.result['lastPage']; + unreadCount = service.result['unread']; results.addAll( List.from( service.result['contents'].map( diff --git a/lib/views/splash/splash.dart b/lib/views/splash/splash.dart index b06a3a8..61c3d18 100644 --- a/lib/views/splash/splash.dart +++ b/lib/views/splash/splash.dart @@ -128,7 +128,6 @@ class _SplashState extends State { } RequestService.token = token; final result = await userProvider.getUserInfo(); - await userProvider.getUnreadMessageCount(); if (!result && mounted) { StorageService.delete(key: 'token'); Navigator.of(context).pushNamedAndRemoveUntil( diff --git a/lib/views/widgets/bookmark_button.dart b/lib/views/widgets/bookmark_button.dart index 79939d5..4740007 100644 --- a/lib/views/widgets/bookmark_button.dart +++ b/lib/views/widgets/bookmark_button.dart @@ -74,21 +74,7 @@ class _BookmarkButtonState extends State { _value = !_value; }); widget.onMarkChanged(_value); - switch (widget.type) { - case 'radar': - UserProvider.changeRadarMark(widget.itemId, _value); - break; - case 'news': - UserProvider.changeNewsMark(widget.itemId, _value); - break; - case 'podcast': - UserProvider.changeStudioMark(widget.itemId, _value); - break; - case 'video': - UserProvider.changeStudioMark(widget.itemId, _value); - break; - default: - } + UserProvider.changeItemMark(widget.type, widget.itemId, _value); } }, ); diff --git a/lib/views/widgets/didvan/bnb.dart b/lib/views/widgets/didvan/bnb.dart index c22799e..891cbea 100644 --- a/lib/views/widgets/didvan/bnb.dart +++ b/lib/views/widgets/didvan/bnb.dart @@ -368,7 +368,6 @@ class _NavBarItem extends StatelessWidget { final String title; final IconData selectedIcon; final IconData unselectedIcon; - final bool hasBadge; const _NavBarItem({ Key? key, required this.isSelected, @@ -376,7 +375,6 @@ class _NavBarItem extends StatelessWidget { required this.selectedIcon, required this.unselectedIcon, required this.onTap, - this.hasBadge = false, }) : super(key: key); @override @@ -407,25 +405,12 @@ class _NavBarItem extends StatelessWidget { ? Theme.of(context).colorScheme.focused : Theme.of(context).colorScheme.surface, ), - child: Stack( - children: [ - Icon( - isSelected ? selectedIcon : unselectedIcon, - size: 32, - color: DesignConfig.isDark - ? Theme.of(context).colorScheme.text - : Theme.of(context).colorScheme.title, - ), - if (hasBadge) - Container( - height: 12, - width: 12, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Theme.of(context).colorScheme.secondary, - ), - ), - ], + child: Icon( + isSelected ? selectedIcon : unselectedIcon, + size: 32, + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.text + : Theme.of(context).colorScheme.title, ), ), DidvanText( diff --git a/lib/views/widgets/logo_app_bar.dart b/lib/views/widgets/logo_app_bar.dart index 6203b91..cdfa3af 100644 --- a/lib/views/widgets/logo_app_bar.dart +++ b/lib/views/widgets/logo_app_bar.dart @@ -26,6 +26,7 @@ class LogoAppBar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { + final state = context.read(); final MediaQueryData d = MediaQuery.of(context); return Container( height: 144, @@ -63,10 +64,30 @@ class LogoAppBar extends StatelessWidget implements PreferredSizeWidget { width: 1, color: Theme.of(context).colorScheme.border, ), - DidvanIconButton( - icon: DidvanIcons.notification_light, - size: 32, - onPressed: () => {}, + Stack( + children: [ + DidvanIconButton( + icon: state.unreadCount == 0 + ? DidvanIcons.message_light + : DidvanIcons.message_solid, + size: 32, + onPressed: () => + Navigator.of(context).pushNamed(Routes.direct), + ), + if (state.unreadCount != 0) + Positioned( + top: 8, + right: 4, + child: Container( + height: 12, + width: 12, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Theme.of(context).colorScheme.secondary, + ), + ), + ), + ], ), ], ),