D1APP-67 bookmarks

This commit is contained in:
MohammadTaha Basiri 2022-02-05 12:56:08 +03:30
parent 3b3cdd20d0
commit afc9c7bafe
23 changed files with 535 additions and 476 deletions

View File

@ -1,62 +1,26 @@
import 'package:didvan/models/category.dart'; class OverviewData {
class ItemOverview {
final int id; final int id;
final String title; final String title;
final String image; final String image;
final String description; final String description;
final int? timeToRead;
final String? reference;
final bool? forManagers;
final String createdAt; final String createdAt;
final String? type; final String? type;
final List<Category>? categories;
int? comments;
ItemOverview({ const OverviewData({
required this.id, required this.id,
required this.title, required this.title,
required this.image, required this.image,
required this.description, required this.description,
required this.timeToRead,
required this.reference,
required this.forManagers,
required this.createdAt, required this.createdAt,
required this.type, required this.type,
required this.categories,
required this.comments,
}); });
factory ItemOverview.fromJson(Map<String, dynamic> json) => ItemOverview( factory OverviewData.fromJson(Map<String, dynamic> json) => OverviewData(
id: json['id'], id: json['id'],
title: json['title'], title: json['title'],
image: json['image'], image: json['image'],
description: json['description'], description: json['description'],
timeToRead: json['timeToRead'],
reference: json['reference'],
forManagers: json['forManagers'],
createdAt: json['createdAt'], createdAt: json['createdAt'],
type: json['type'], type: json['type'],
comments: json['comments'],
categories: json['categories'] == null
? null
: List<Category>.from(
json['categories'].map(
(cat) => Category.fromJson(cat),
),
),
); );
Map<String, dynamic> toJson() => {
'id': id,
'title': title,
'image': image,
'description': description,
'timeToRead': timeToRead,
'reference': reference,
'forManagers': forManagers,
'createdAt': createdAt,
'type': type,
'categories': categories?.map((e) => e.toJson()).toList(),
};
} }

View File

@ -1,21 +1,25 @@
class NewsOverviewData { import 'package:didvan/models/item_overview.dart';
final int id;
final String title; class NewsOverviewData extends OverviewData {
final String reference; final String reference;
final String description;
final String image;
final String createdAt;
bool marked; bool marked;
NewsOverviewData({ NewsOverviewData({
required this.id,
required this.title,
required this.reference, required this.reference,
required this.description,
required this.image,
required this.createdAt,
required this.marked, required this.marked,
}); required id,
required createdAt,
required description,
required title,
required image,
}) : super(
createdAt: createdAt,
description: description,
id: id,
image: image,
title: title,
type: 'news',
);
factory NewsOverviewData.fromJson(Map<String, dynamic> json) => factory NewsOverviewData.fromJson(Map<String, dynamic> json) =>
NewsOverviewData( NewsOverviewData(
@ -25,16 +29,6 @@ class NewsOverviewData {
description: json['description'], description: json['description'],
image: json['image'], image: json['image'],
createdAt: json['createdAt'], createdAt: json['createdAt'],
marked: json['marked'], marked: json['marked'] ?? true,
); );
Map<String, dynamic> toJson() => {
'id': id,
'title': title,
'reference': reference,
'description': description,
'image': image,
'createdAt': createdAt,
'marked': marked,
};
} }

View File

@ -1,29 +1,33 @@
import 'package:didvan/models/item_overview.dart';
import 'category.dart'; import 'category.dart';
class RadarOverviewData { class RadarOverviewData extends OverviewData {
final int id;
final String image;
final String title;
final String description;
final int timeToRead;
final String createdAt;
final bool forManagers; final bool forManagers;
bool marked;
final List<Category> categories; final List<Category> categories;
final int timeToRead;
int comments; int comments;
bool marked;
RadarOverviewData({ RadarOverviewData({
required this.id,
required this.image,
required this.title,
required this.description,
required this.timeToRead,
required this.createdAt,
required this.forManagers, required this.forManagers,
required this.marked,
required this.categories, required this.categories,
required this.comments, required this.comments,
}); required this.timeToRead,
required this.marked,
required createdAt,
required description,
required id,
required image,
required title,
}) : super(
createdAt: createdAt,
description: description,
id: id,
image: image,
title: title,
type: 'radar',
);
factory RadarOverviewData.fromJson(Map<String, dynamic> json) => factory RadarOverviewData.fromJson(Map<String, dynamic> json) =>
RadarOverviewData( RadarOverviewData(
@ -42,17 +46,4 @@ class RadarOverviewData {
), ),
), ),
); );
Map<String, dynamic> toJson() => {
'id': id,
'image': image,
'title': title,
'description': description,
'timeToRead': timeToRead,
'createdAt': createdAt,
'forManagers': forManagers,
'marked': marked,
'comment': comments,
'categories': categories.map((e) => e.toJson()).toList(),
};
} }

View File

@ -13,7 +13,7 @@ class ActionSheetData {
final bool withoutButtonMode; final bool withoutButtonMode;
final bool smallDismissButton; final bool smallDismissButton;
ActionSheetData({ const ActionSheetData({
required this.content, required this.content,
required this.title, required this.title,
this.confrimTitle, this.confrimTitle,

View File

@ -11,9 +11,6 @@ import 'package:didvan/pages/home/widgets/date_picker_button.dart';
import 'package:didvan/widgets/item_title.dart'; import 'package:didvan/widgets/item_title.dart';
import 'package:didvan/pages/home/widgets/search_field.dart'; import 'package:didvan/pages/home/widgets/search_field.dart';
import 'package:didvan/pages/home/widgets/logo_app_bar.dart'; import 'package:didvan/pages/home/widgets/logo_app_bar.dart';
import 'package:didvan/widgets/didvan/card.dart';
import 'package:didvan/widgets/didvan/divider.dart';
import 'package:didvan/widgets/shimmer_placeholder.dart';
import 'package:didvan/widgets/state_handlers/empty_result.dart'; import 'package:didvan/widgets/state_handlers/empty_result.dart';
import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart'; import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -76,7 +73,7 @@ class _NewsState extends State<News> {
), ),
childCount: state.news.length, childCount: state.news.length,
itemPadding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), itemPadding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
placeholder: const _NewsOverviewPlaceholder(), placeholder: NewsOverview.placeholder,
), ),
], ],
); );
@ -141,56 +138,3 @@ class _NewsState extends State<News> {
); );
} }
} }
class _NewsOverviewPlaceholder extends StatelessWidget {
const _NewsOverviewPlaceholder({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DidvanCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ShimmerPlaceholder(height: 64, width: 64),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
ShimmerPlaceholder(height: 18, width: 200),
SizedBox(height: 8),
ShimmerPlaceholder(height: 18, width: 100),
],
),
],
),
const SizedBox(height: 12),
const ShimmerPlaceholder(
height: 16,
width: double.infinity,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
width: double.infinity,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
width: 100,
),
const DidvanDivider(verticalPadding: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
ShimmerPlaceholder(height: 12, width: 150),
ShimmerPlaceholder(height: 24, width: 24),
],
),
],
),
);
}
}

View File

@ -1,3 +1,4 @@
import 'package:didvan/models/requests/news.dart';
import 'package:didvan/pages/home/news/news_details/news_details_state.dart'; import 'package:didvan/pages/home/news/news_details/news_details_state.dart';
import 'package:didvan/widgets/didvan/page_view.dart'; import 'package:didvan/widgets/didvan/page_view.dart';
import 'package:didvan/pages/home/widgets/floating_navigation_bar.dart'; import 'package:didvan/pages/home/widgets/floating_navigation_bar.dart';
@ -19,7 +20,7 @@ class _NewsDetailsState extends State<NewsDetails> {
@override @override
void initState() { void initState() {
final state = context.read<NewsDetailsState>(); final state = context.read<NewsDetailsState>();
state.args = widget.pageData['args']; state.args = widget.pageData['args'] ?? const NewsRequestArgs(page: 0);
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () {
state.getNewsDetails(widget.pageData['id']); state.getNewsDetails(widget.pageData['id']);
}); });
@ -49,6 +50,8 @@ class _NewsDetailsState extends State<NewsDetails> {
left: 0, left: 0,
right: 0, right: 0,
child: FloatingNavigationBar( child: FloatingNavigationBar(
hasUnmarkConfirmation:
widget.pageData['hasUnmarkConfirmation'],
scrollController: _scrollController, scrollController: _scrollController,
comments: state.currentNews.comments, comments: state.currentNews.comments,
id: state.currentNews.id, id: state.currentNews.id,

View File

@ -29,11 +29,17 @@ class NewsDetailsState extends CoreProvier {
_handleTracking(sendRequest: isForward != null); _handleTracking(sendRequest: isForward != null);
if (service.isSuccess) { if (service.isSuccess) {
final result = service.result; final result = service.result;
final newsItem = NewsDetailsData.fromJson(result['news']);
if (args.page == 0) {
news.add(newsItem);
initialIndex = 0;
appState = AppState.idle;
return;
}
NewsDetailsData? prevNews; NewsDetailsData? prevNews;
if (result['prevNews'].isNotEmpty) { if (result['prevNews'].isNotEmpty) {
prevNews = NewsDetailsData.fromJson(result['prevNews']); prevNews = NewsDetailsData.fromJson(result['prevNews']);
} }
final newsItem = NewsDetailsData.fromJson(result['news']);
NewsDetailsData? nextNews; NewsDetailsData? nextNews;
if (result['nextNews'].isNotEmpty) { if (result['nextNews'].isNotEmpty) {
nextNews = NewsDetailsData.fromJson(result['nextNews']); nextNews = NewsDetailsData.fromJson(result['nextNews']);

View File

@ -18,12 +18,9 @@ import 'package:didvan/pages/home/widgets/search_field.dart';
import 'package:didvan/pages/home/widgets/logo_app_bar.dart'; import 'package:didvan/pages/home/widgets/logo_app_bar.dart';
import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/pages/home/widgets/date_picker_button.dart'; import 'package:didvan/pages/home/widgets/date_picker_button.dart';
import 'package:didvan/widgets/didvan/card.dart';
import 'package:didvan/widgets/didvan/checkbox.dart'; import 'package:didvan/widgets/didvan/checkbox.dart';
import 'package:didvan/widgets/didvan/divider.dart';
import 'package:didvan/widgets/didvan/text.dart'; import 'package:didvan/widgets/didvan/text.dart';
import 'package:didvan/widgets/item_title.dart'; import 'package:didvan/widgets/item_title.dart';
import 'package:didvan/widgets/shimmer_placeholder.dart';
import 'package:didvan/widgets/state_handlers/empty_result.dart'; import 'package:didvan/widgets/state_handlers/empty_result.dart';
import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart'; import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -129,7 +126,7 @@ class _RadarState extends State<Radar> {
child: child:
EmptyResult(onNewSearch: () => _focusNode.requestFocus()), EmptyResult(onNewSearch: () => _focusNode.requestFocus()),
), ),
placeholder: const _RadarOverviewPlaceholder(), placeholder: RadarOverview.placeholder,
builder: (context, state, index) { builder: (context, state, index) {
final radar = state.radars[index]; final radar = state.radars[index];
return RadarOverview( return RadarOverview(
@ -286,71 +283,3 @@ class _RadarState extends State<Radar> {
super.dispose(); super.dispose();
} }
} }
class _RadarOverviewPlaceholder extends StatelessWidget {
const _RadarOverviewPlaceholder({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return DidvanCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ShimmerPlaceholder(
width: 200,
height: 16,
),
const SizedBox(height: 8),
const AspectRatio(aspectRatio: 16 / 9, child: ShimmerPlaceholder()),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
ShimmerPlaceholder(
height: 12,
width: 70,
),
ShimmerPlaceholder(
height: 12,
width: 70,
),
],
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const DidvanDivider(),
Row(
children: const [
ShimmerPlaceholder(
height: 32,
width: 32,
),
Spacer(),
ShimmerPlaceholder(
height: 32,
width: 32,
),
SizedBox(width: 16),
ShimmerPlaceholder(
height: 32,
width: 32,
),
],
),
],
),
);
}
}

View File

@ -32,7 +32,7 @@ class _RadarDetailsState extends State<RadarDetails> {
return Scaffold( return Scaffold(
body: Consumer<RadarDetailsState>( body: Consumer<RadarDetailsState>(
builder: (context, state, child) => StateHandler<RadarDetailsState>( builder: (context, state, child) => StateHandler<RadarDetailsState>(
onRetry: () => state.getRadarDetails(state.currentRadar.id), onRetry: () => state.getRadarDetails(widget.pageData['id']),
state: state, state: state,
builder: (context, state) => Stack( builder: (context, state) => Stack(
children: [ children: [
@ -50,12 +50,15 @@ class _RadarDetailsState extends State<RadarDetails> {
left: 0, left: 0,
right: 0, right: 0,
child: FloatingNavigationBar( child: FloatingNavigationBar(
hasUnmarkConfirmation:
widget.pageData['hasUnmarkConfirmation'],
comments: state.currentRadar.comments, comments: state.currentRadar.comments,
id: state.currentRadar.id, id: state.currentRadar.id,
isRadar: true, isRadar: true,
marked: state.currentRadar.marked, marked: state.currentRadar.marked,
title: state.currentRadar.title, title: state.currentRadar.title,
onMarkChanged: (value) => widget.pageData['onMarkChanged']( onMarkChanged: (value) =>
widget.pageData['onMarkChanged']?.call(
state.currentRadar.id, state.currentRadar.id,
value, value,
), ),
@ -63,7 +66,7 @@ class _RadarDetailsState extends State<RadarDetails> {
scrollController: _scrollController, scrollController: _scrollController,
onCommentsChanged: (count) { onCommentsChanged: (count) {
state.onCommentsChanged(count); state.onCommentsChanged(count);
widget.pageData['onCommentsChanged']( widget.pageData['onCommentsChanged']?.call(
state.currentRadar.id, state.currentRadar.id,
count, count,
); );

View File

@ -35,7 +35,6 @@ class RadarDetailsState extends CoreProvier {
_handleTracking(sendRequest: isForward != null); _handleTracking(sendRequest: isForward != null);
if (service.isSuccess) { if (service.isSuccess) {
final result = service.result; final result = service.result;
RadarDetailsData? prevRadar;
final radar = RadarDetailsData.fromJson(result['radar']); final radar = RadarDetailsData.fromJson(result['radar']);
if (args.page == 0) { if (args.page == 0) {
radars.add(radar); radars.add(radar);
@ -44,6 +43,7 @@ class RadarDetailsState extends CoreProvier {
return; return;
} }
RadarDetailsData? prevRadar;
if (result['prevRadar'].isNotEmpty) { if (result['prevRadar'].isNotEmpty) {
prevRadar = RadarDetailsData.fromJson(result['prevRadar']); prevRadar = RadarDetailsData.fromJson(result['prevRadar']);
} }

View File

@ -1,17 +1,15 @@
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
import 'package:didvan/models/item_overview.dart'; import 'package:didvan/models/item_overview.dart';
import 'package:didvan/providers/core_provider.dart'; import 'package:didvan/providers/core_provider.dart';
import 'package:didvan/providers/user_provider.dart';
import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart'; import 'package:didvan/services/network/request_helper.dart';
class BookmarksState extends CoreProvier { class BookmarksState extends CoreProvier {
final List<ItemOverview> bookmarks = []; final List<OverviewData> bookmarks = [];
final List<dynamic> filterdBookmarks = [];
String search = ''; String search = '';
String lastSearch = ''; String lastSearch = '';
String? groupName;
bool get searching => search != ''; bool get searching => search != '';
Future<void> getBookmarks() async { Future<void> getBookmarks() async {
@ -19,50 +17,34 @@ class BookmarksState extends CoreProvier {
lastSearch = search; lastSearch = search;
} }
appState = AppState.busy; appState = AppState.busy;
final service = RequestService(RequestHelper.bookmarks(groupName)); final service = RequestService(RequestHelper.bookmarks());
await service.httpGet(); await service.httpGet();
String resultKey;
switch (groupName) {
case 'radar':
resultKey = 'radars';
break;
case 'news':
resultKey = groupName!;
break;
default:
resultKey = 'contents';
}
if (service.isSuccess) {
final marks = service.result[resultKey];
if (groupName == null) {
bookmarks.clear();
for (var i = 0; i < marks.length; i++) {
bookmarks.add(ItemOverview.fromJson(marks[i]));
}
} else {
filterdBookmarks.clear();
for (var i = 0; i < marks.length; i++) {
filterdBookmarks.add(ItemOverview.fromJson(marks[i]));
}
}
if (service.isSuccess) {
final marks = service.result['contents'];
bookmarks.clear();
for (var i = 0; i < marks.length; i++) {
bookmarks.add(OverviewData.fromJson(marks[i]));
}
appState = AppState.idle; appState = AppState.idle;
return; return;
} }
appState = AppState.failed; appState = AppState.failed;
} }
void unMark(int id) { void onMarkChanged(int id, bool value) {
if (value) return;
final type = bookmarks.firstWhere((element) => element.id == id).type;
switch (type) {
case 'radars':
UserProvider.changeRadarMark(id, value);
break;
case 'news':
UserProvider.changeNewsMark(id, value);
break;
default:
}
bookmarks.removeWhere((element) => element.id == id); bookmarks.removeWhere((element) => element.id == id);
filterdBookmarks.removeWhere((element) => element.id == id);
notifyListeners();
final service = RequestService(RequestHelper.markRadar(id));
service.delete();
}
void onCommentsChanged(int id, int value) {
bookmarks.firstWhere((radar) => radar.id == id).comments = value;
filterdBookmarks.firstWhere((radar) => radar.id == id).comments = value;
notifyListeners(); notifyListeners();
} }
} }

View File

@ -1,13 +1,18 @@
import 'dart:async'; import 'dart:async';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/pages/home/settings/bookmarks/bookmark_state.dart'; import 'package:didvan/pages/home/settings/bookmarks/bookmark_state.dart';
import 'package:didvan/pages/home/widgets/menu_item.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/widgets/animated_visibility.dart';
import 'package:didvan/widgets/didvan/card.dart'; import 'package:didvan/widgets/didvan/card.dart';
import 'package:didvan/widgets/didvan/divider.dart'; import 'package:didvan/widgets/didvan/divider.dart';
import 'package:didvan/widgets/didvan/scaffold.dart'; import 'package:didvan/widgets/didvan/scaffold.dart';
import 'package:didvan/pages/home/widgets/multitype_item.dart'; import 'package:didvan/pages/home/widgets/multitype_overview.dart';
import 'package:didvan/pages/home/widgets/search_field.dart'; import 'package:didvan/pages/home/widgets/search_field.dart';
import 'package:didvan/widgets/shimmer_placeholder.dart'; import 'package:didvan/widgets/item_title.dart';
import 'package:didvan/widgets/state_handlers/empty_list.dart'; import 'package:didvan/widgets/state_handlers/empty_list.dart';
import 'package:didvan/widgets/state_handlers/empty_result.dart'; import 'package:didvan/widgets/state_handlers/empty_result.dart';
import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart'; import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart';
@ -48,60 +53,62 @@ class _BookmarksState extends State<Bookmarks> {
focusNode: _focuseNode, focusNode: _focuseNode,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
// AnimatedVisibility( AnimatedVisibility(
// duration: DesignConfig.lowAnimationDuration, duration: DesignConfig.lowAnimationDuration,
// isVisible: !state.searching, isVisible: !state.searching,
// child: DidvanCard( child: DidvanCard(
// child: Column( child: Column(
// children: [ children: [
// MenuItem( MenuItem(
// onTap: () => _onCategorySelected('radar'), onTap: () => _onCategorySelected('radars'),
// title: 'تحلیل‌های رادار', title: 'تحلیل‌های رادار',
// icon: DidvanIcons.radar_regular, icon: DidvanIcons.radar_regular,
// iconSize: 24, iconSize: 24,
// ), ),
// const DidvanDivider(), const DidvanDivider(),
// MenuItem( MenuItem(
// onTap: () => _onCategorySelected('news'), onTap: () => _onCategorySelected('news'),
// title: 'اخبار', title: 'اخبار',
// icon: DidvanIcons.news_regular, icon: DidvanIcons.news_regular,
// iconSize: 24, iconSize: 24,
// ), ),
// const DidvanDivider(), const DidvanDivider(),
// MenuItem( MenuItem(
// onTap: () => _onCategorySelected('video'), onTap: () => _onCategorySelected('videos'),
// title: 'ویدئو‌ها', title: 'ویدئو‌ها',
// icon: DidvanIcons.video_regular, icon: DidvanIcons.video_regular,
// iconSize: 24, iconSize: 24,
// ), ),
// const DidvanDivider(), const DidvanDivider(),
// MenuItem( MenuItem(
// onTap: () => _onCategorySelected('podcast'), onTap: () => _onCategorySelected('podcasts'),
// title: 'پادکست‌ها', title: 'پادکست‌ها',
// icon: DidvanIcons.podcast_regular, icon: DidvanIcons.podcast_regular,
// iconSize: 24, iconSize: 24,
// ), ),
// ], ],
// ), ),
// ), ),
// ), ),
// Align( Align(
// alignment: Alignment.centerRight, alignment: Alignment.centerRight,
// child: AnimatedVisibility( child: AnimatedVisibility(
// duration: DesignConfig.lowAnimationDuration, duration: DesignConfig.lowAnimationDuration,
// isVisible: !state.searching, isVisible: !state.searching,
// child: const ItemTitle(title: 'آخرین نشان نشده‌ها'), child: const ItemTitle(title: 'آخرین نشان شده‌ها'),
// ), ),
// ), ),
], ],
slivers: [ slivers: [
SliverStateHandler<BookmarksState>( SliverStateHandler<BookmarksState>(
state: state, state: state,
// centerEmptyState: state.searching, centerEmptyState: state.searching,
builder: (context, state, index) => MultitypeItem( builder: (context, state, index) => MultitypeOverview(
item: state.bookmarks[index], item: state.bookmarks[index],
onMarkChanged: state.onMarkChanged,
hasUnmarkConfirmation: true,
), ),
placeholder: const _NewsOverviewPlaceholder(), placeholder: MultitypeOverview.placeholder,
itemPadding: const EdgeInsets.only(bottom: 8), itemPadding: const EdgeInsets.only(bottom: 8),
emptyState: state.searching emptyState: state.searching
? EmptyResult(onNewSearch: _focuseNode.requestFocus) ? EmptyResult(onNewSearch: _focuseNode.requestFocus)
@ -114,12 +121,11 @@ class _BookmarksState extends State<Bookmarks> {
); );
} }
// void _onCategorySelected(String? type) { void _onCategorySelected(String type) {
// FocusScope.of(context).unfocus(); if (type != 'radars' && type != 'news') return;
// final state = context.read<BookmarksState>(); FocusScope.of(context).unfocus();
// state.groupName = type; Navigator.of(context).pushNamed(Routes.filteredBookmarks, arguments: type);
// Navigator.of(context).pushNamed(Routes.filteredBookmarks, arguments: state); }
// }
void _onChanged(String value) { void _onChanged(String value) {
final state = context.read<BookmarksState>(); final state = context.read<BookmarksState>();
@ -133,56 +139,3 @@ class _BookmarksState extends State<Bookmarks> {
}); });
} }
} }
class _NewsOverviewPlaceholder extends StatelessWidget {
const _NewsOverviewPlaceholder({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DidvanCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ShimmerPlaceholder(height: 64, width: 64),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
ShimmerPlaceholder(height: 18, width: 200),
SizedBox(height: 8),
ShimmerPlaceholder(height: 18, width: 100),
],
),
],
),
const SizedBox(height: 12),
const ShimmerPlaceholder(
height: 16,
width: double.infinity,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
width: double.infinity,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
width: 100,
),
const DidvanDivider(verticalPadding: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
ShimmerPlaceholder(height: 12, width: 150),
ShimmerPlaceholder(height: 24, width: 24),
],
),
],
),
);
}
}

View File

@ -1,10 +1,10 @@
import 'package:didvan/models/news_overview.dart';
import 'package:didvan/models/radar_overview.dart';
import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/models/view/app_bar_data.dart';
import 'package:didvan/pages/home/settings/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart';
import 'package:didvan/pages/home/widgets/news_overview.dart';
import 'package:didvan/pages/home/widgets/radar_overview.dart'; import 'package:didvan/pages/home/widgets/radar_overview.dart';
import 'package:didvan/pages/home/settings/bookmarks/bookmark_state.dart';
import 'package:didvan/widgets/didvan/card.dart';
import 'package:didvan/widgets/didvan/divider.dart';
import 'package:didvan/widgets/didvan/scaffold.dart'; import 'package:didvan/widgets/didvan/scaffold.dart';
import 'package:didvan/widgets/shimmer_placeholder.dart';
import 'package:didvan/widgets/state_handlers/empty_list.dart'; import 'package:didvan/widgets/state_handlers/empty_list.dart';
import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart'; import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -20,19 +20,22 @@ class FilteredBookmarks extends StatefulWidget {
class _FilteredBookmarksState extends State<FilteredBookmarks> { class _FilteredBookmarksState extends State<FilteredBookmarks> {
@override @override
void initState() { void initState() {
Future.delayed(Duration.zero, context.read<BookmarksState>().getBookmarks); Future.delayed(
Duration.zero,
context.read<FilteredBookmarksState>().getBookmarks,
);
super.initState(); super.initState();
} }
String get _appBarTitle { String get _appBarTitle {
switch (context.read<BookmarksState>().groupName) { switch (context.read<FilteredBookmarksState>().type) {
case 'radar': case 'radars':
return 'تحلیل‌های رادار'; return 'تحلیل‌های رادار';
case 'news': case 'news':
return 'اخبار'; return 'اخبار';
case 'video': case 'videos':
return 'ویدئو‌ها'; return 'ویدئو‌ها';
case 'podcast': case 'podcasts':
return 'پادکست‌ها'; return 'پادکست‌ها';
default: default:
return 'پادکست‌ها'; return 'پادکست‌ها';
@ -44,93 +47,40 @@ class _FilteredBookmarksState extends State<FilteredBookmarks> {
return DidvanScaffold( return DidvanScaffold(
appBarData: AppBarData(title: _appBarTitle), appBarData: AppBarData(title: _appBarTitle),
slivers: [ slivers: [
Consumer<BookmarksState>( Consumer<FilteredBookmarksState>(
builder: (context, state, child) => builder: (context, state, child) =>
SliverStateHandler<BookmarksState>( SliverStateHandler<FilteredBookmarksState>(
state: state, state: state,
enableEmptyState: state.filterdBookmarks.isEmpty, enableEmptyState: state.bookmarks.isEmpty,
itemPadding: const EdgeInsets.only(bottom: 8), itemPadding: const EdgeInsets.only(bottom: 8),
placeholder: const _RadarOverviewPlaceholder(), placeholder: RadarOverview.placeholder,
emptyState: const EmptyList(), emptyState: const EmptyList(),
builder: (context, state, index) => RadarOverview( builder: (context, state, index) {
radar: state.filterdBookmarks[index], if (state.type == 'radars') {
onMarkChanged: (id, value) {}, return RadarOverview(
onCommentsChanged: (id, count) => radar: state.bookmarks[index] as RadarOverviewData,
state.onCommentsChanged(id, count), onMarkChanged: _onBookmarkChanged,
), onCommentsChanged: state.onCommentsChanged,
childCount: state.filterdBookmarks.length, hasUnmarkConfirmation: true,
onRetry: state.getBookmarks, );
}
return NewsOverview(
news: state.bookmarks[index] as NewsOverviewData,
onMarkChanged: _onBookmarkChanged,
hasUnmarkConfirmation: true,
);
},
childCount: state.bookmarks.length,
onRetry: () => state.getBookmarks(),
), ),
), ),
], ],
); );
} }
}
class _RadarOverviewPlaceholder extends StatelessWidget { Future<void> _onBookmarkChanged(int id, bool value) async {
const _RadarOverviewPlaceholder({ if (value) return;
Key? key, final state = context.read<FilteredBookmarksState>();
}) : super(key: key); state.onMarkChanged(id, false);
@override
Widget build(BuildContext context) {
return DidvanCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ShimmerPlaceholder(
width: 200,
height: 16,
),
const SizedBox(height: 8),
const AspectRatio(aspectRatio: 16 / 9, child: ShimmerPlaceholder()),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
ShimmerPlaceholder(
height: 12,
width: 70,
),
ShimmerPlaceholder(
height: 12,
width: 70,
),
],
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const DidvanDivider(),
Row(
children: const [
ShimmerPlaceholder(
height: 32,
width: 32,
),
Spacer(),
ShimmerPlaceholder(
height: 32,
width: 32,
),
SizedBox(width: 16),
ShimmerPlaceholder(
height: 32,
width: 32,
),
],
),
],
),
);
} }
} }

View File

@ -0,0 +1,65 @@
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/item_overview.dart';
import 'package:didvan/models/news_overview.dart';
import 'package:didvan/models/radar_overview.dart';
import 'package:didvan/providers/core_provider.dart';
import 'package:didvan/providers/user_provider.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
class FilteredBookmarksState extends CoreProvier {
String search = '';
String lastSearch = '';
final List<OverviewData> bookmarks = [];
final String type;
FilteredBookmarksState(this.type);
bool get searching => search != '';
Future<void> getBookmarks() async {
if (search != '') {
lastSearch = search;
}
appState = AppState.busy;
final service = RequestService(
RequestHelper.bookmarks(type: type == 'radars' ? 'radar' : type));
await service.httpGet();
if (service.isSuccess) {
final marks = service.result[type];
bookmarks.clear();
for (var i = 0; i < marks.length; i++) {
if (type == 'radars') {
bookmarks.add(RadarOverviewData.fromJson(marks[i]));
}
if (type == 'news') {
bookmarks.add(NewsOverviewData.fromJson(marks[i]));
}
}
appState = AppState.idle;
return;
}
appState = AppState.failed;
}
void onMarkChanged(int id, bool value) {
switch (type) {
case 'radars':
UserProvider.changeRadarMark(id, value);
break;
case 'news':
UserProvider.changeNewsMark(id, value);
break;
default:
}
bookmarks.removeWhere((element) => element.id == id);
notifyListeners();
}
void onCommentsChanged(int id, int value) {
(bookmarks.firstWhere((radar) => radar.id == id) as RadarOverviewData)
.comments = value;
notifyListeners();
}
}

View File

@ -1,16 +1,21 @@
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/widgets/didvan/icon_button.dart'; import 'package:didvan/widgets/didvan/icon_button.dart';
import 'package:didvan/widgets/didvan/text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class BookmarkButton extends StatefulWidget { class BookmarkButton extends StatefulWidget {
final bool value; final bool value;
final void Function(bool value) onMarkChanged; final void Function(bool value) onMarkChanged;
final bool bigGestureSize; final bool bigGestureSize;
final bool askForConfirmation;
const BookmarkButton({ const BookmarkButton({
Key? key, Key? key,
required this.value, required this.value,
this.bigGestureSize = false, this.bigGestureSize = false,
required this.onMarkChanged, required this.onMarkChanged,
this.askForConfirmation = false,
}) : super(key: key); }) : super(key: key);
@override @override
@ -37,11 +42,27 @@ class _BookmarkButtonState extends State<BookmarkButton> {
return DidvanIconButton( return DidvanIconButton(
gestureSize: widget.bigGestureSize ? 32 : 24, gestureSize: widget.bigGestureSize ? 32 : 24,
icon: _value ? DidvanIcons.bookmark_solid : DidvanIcons.bookmark_regular, icon: _value ? DidvanIcons.bookmark_solid : DidvanIcons.bookmark_regular,
onPressed: () { onPressed: () async {
setState(() { bool confirm = false;
_value = !_value; if (widget.askForConfirmation) {
}); await ActionSheetUtils.openDialog(
widget.onMarkChanged(_value); data: ActionSheetData(
content: const DidvanText(
'آیا می‌خواهید این محتوا از نشان‌ شده‌ها حذف شود؟',
),
titleIcon: DidvanIcons.bookmark_regular,
titleColor: Theme.of(context).colorScheme.secondary,
title: 'تایید عملیات',
onConfirmed: () => confirm = true,
),
);
}
if (!widget.askForConfirmation || confirm) {
setState(() {
_value = !_value;
});
widget.onMarkChanged(_value);
}
}, },
); );
} }

View File

@ -16,6 +16,7 @@ import 'package:flutter/material.dart';
class FloatingNavigationBar extends StatefulWidget { class FloatingNavigationBar extends StatefulWidget {
final ScrollController scrollController; final ScrollController scrollController;
final bool hasUnmarkConfirmation;
final void Function(int count) onCommentsChanged; final void Function(int count) onCommentsChanged;
final bool isRadar; final bool isRadar;
final bool marked; final bool marked;
@ -36,6 +37,7 @@ class FloatingNavigationBar extends StatefulWidget {
required this.id, required this.id,
required this.title, required this.title,
this.categories, this.categories,
this.hasUnmarkConfirmation = false,
}) : super(key: key); }) : super(key: key);
@override @override
@ -107,8 +109,14 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
const Spacer(), const Spacer(),
if (widget.isRadar) if (widget.isRadar)
BookmarkButton( BookmarkButton(
askForConfirmation: widget.hasUnmarkConfirmation,
value: widget.marked, value: widget.marked,
onMarkChanged: widget.onMarkChanged, onMarkChanged: (value) {
widget.onMarkChanged(value);
if (widget.hasUnmarkConfirmation && !value) {
Navigator.of(context).pop();
}
},
bigGestureSize: true, bigGestureSize: true,
), ),
SizedBox( SizedBox(
@ -140,8 +148,14 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
if (!widget.isRadar) const SizedBox(width: 12), if (!widget.isRadar) const SizedBox(width: 12),
if (!widget.isRadar) if (!widget.isRadar)
BookmarkButton( BookmarkButton(
askForConfirmation: widget.hasUnmarkConfirmation,
value: widget.marked, value: widget.marked,
onMarkChanged: widget.onMarkChanged, onMarkChanged: (value) {
widget.onMarkChanged(value);
if (widget.hasUnmarkConfirmation && !value) {
Navigator.of(context).pop();
}
},
bigGestureSize: true, bigGestureSize: true,
), ),
if (widget.isRadar) if (widget.isRadar)

View File

@ -1,19 +1,42 @@
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/item_overview.dart'; import 'package:didvan/models/item_overview.dart';
import 'package:didvan/models/requests/news.dart';
import 'package:didvan/models/requests/radar.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/widgets/didvan/card.dart'; import 'package:didvan/widgets/didvan/card.dart';
import 'package:didvan/widgets/didvan/text.dart'; import 'package:didvan/widgets/didvan/text.dart';
import 'package:didvan/widgets/shimmer_placeholder.dart';
import 'package:didvan/widgets/skeleton_image.dart'; import 'package:didvan/widgets/skeleton_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:persian_number_utility/persian_number_utility.dart'; import 'package:persian_number_utility/persian_number_utility.dart';
class MultitypeItem extends StatelessWidget { class MultitypeOverview extends StatelessWidget {
final ItemOverview item; final OverviewData item;
const MultitypeItem({Key? key, required this.item}) : super(key: key); final bool hasUnmarkConfirmation;
final void Function(int id, bool value) onMarkChanged;
const MultitypeOverview({
Key? key,
required this.item,
required this.onMarkChanged,
this.hasUnmarkConfirmation = false,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DidvanCard( return DidvanCard(
onTap: () => Navigator.of(context).pushNamed(
item.type == 'radar' ? Routes.radarDetails : Routes.newsDetails,
arguments: {
'onMarkChanged': onMarkChanged,
'id': item.id,
'args': item.type == 'radar'
? const RadarRequestArgs(page: 0)
: const NewsRequestArgs(page: 0),
'hasUnmarkConfirmation': hasUnmarkConfirmation,
},
),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -72,4 +95,27 @@ class MultitypeItem extends StatelessWidget {
), ),
); );
} }
static Widget get placeholder => DidvanCard(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ShimmerPlaceholder(height: 80, width: 80),
const SizedBox(width: 8),
SizedBox(
height: 80,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
ShimmerPlaceholder(height: 18, width: 200),
SizedBox(height: 8),
ShimmerPlaceholder(height: 18, width: 100),
Spacer(),
ShimmerPlaceholder(height: 14, width: 80),
],
),
),
],
),
);
} }

View File

@ -6,6 +6,7 @@ import 'package:didvan/pages/home/widgets/bookmark_button.dart';
import 'package:didvan/widgets/didvan/card.dart'; import 'package:didvan/widgets/didvan/card.dart';
import 'package:didvan/widgets/didvan/divider.dart'; import 'package:didvan/widgets/didvan/divider.dart';
import 'package:didvan/widgets/didvan/text.dart'; import 'package:didvan/widgets/didvan/text.dart';
import 'package:didvan/widgets/shimmer_placeholder.dart';
import 'package:didvan/widgets/skeleton_image.dart'; import 'package:didvan/widgets/skeleton_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -13,11 +14,13 @@ class NewsOverview extends StatelessWidget {
final NewsOverviewData news; final NewsOverviewData news;
final NewsRequestArgs? newsRequestArgs; final NewsRequestArgs? newsRequestArgs;
final void Function(int id, bool value) onMarkChanged; final void Function(int id, bool value) onMarkChanged;
final bool hasUnmarkConfirmation;
const NewsOverview({ const NewsOverview({
Key? key, Key? key,
required this.news, required this.news,
required this.onMarkChanged, required this.onMarkChanged,
this.newsRequestArgs, this.newsRequestArgs,
this.hasUnmarkConfirmation = false,
}) : super(key: key); }) : super(key: key);
@override @override
@ -29,6 +32,7 @@ class NewsOverview extends StatelessWidget {
'onMarkChanged': onMarkChanged, 'onMarkChanged': onMarkChanged,
'id': news.id, 'id': news.id,
'args': newsRequestArgs, 'args': newsRequestArgs,
'hasUnmarkConfirmation': hasUnmarkConfirmation,
}, },
), ),
child: Column( child: Column(
@ -77,6 +81,7 @@ class NewsOverview extends StatelessWidget {
BookmarkButton( BookmarkButton(
value: news.marked, value: news.marked,
onMarkChanged: (value) => onMarkChanged(news.id, value), onMarkChanged: (value) => onMarkChanged(news.id, value),
askForConfirmation: hasUnmarkConfirmation,
), ),
], ],
), ),
@ -84,4 +89,50 @@ class NewsOverview extends StatelessWidget {
), ),
); );
} }
static Widget get placeholder => DidvanCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ShimmerPlaceholder(height: 64, width: 64),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
ShimmerPlaceholder(height: 18, width: 200),
SizedBox(height: 8),
ShimmerPlaceholder(height: 18, width: 100),
],
),
],
),
const SizedBox(height: 12),
const ShimmerPlaceholder(
height: 16,
width: double.infinity,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
width: double.infinity,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
width: 100,
),
const DidvanDivider(verticalPadding: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
ShimmerPlaceholder(height: 12, width: 150),
ShimmerPlaceholder(height: 24, width: 24),
],
),
],
),
);
} }

View File

@ -9,6 +9,7 @@ import 'package:didvan/widgets/didvan/card.dart';
import 'package:didvan/widgets/didvan/divider.dart'; import 'package:didvan/widgets/didvan/divider.dart';
import 'package:didvan/widgets/didvan/icon_button.dart'; import 'package:didvan/widgets/didvan/icon_button.dart';
import 'package:didvan/widgets/didvan/text.dart'; import 'package:didvan/widgets/didvan/text.dart';
import 'package:didvan/widgets/shimmer_placeholder.dart';
import 'package:didvan/widgets/skeleton_image.dart'; import 'package:didvan/widgets/skeleton_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -16,6 +17,7 @@ class RadarOverview extends StatelessWidget {
final RadarOverviewData radar; final RadarOverviewData radar;
final void Function(int id, int count) onCommentsChanged; final void Function(int id, int count) onCommentsChanged;
final void Function(int id, bool value) onMarkChanged; final void Function(int id, bool value) onMarkChanged;
final bool hasUnmarkConfirmation;
final RadarRequestArgs? radarRequestArgs; final RadarRequestArgs? radarRequestArgs;
const RadarOverview({ const RadarOverview({
Key? key, Key? key,
@ -23,6 +25,7 @@ class RadarOverview extends StatelessWidget {
required this.onCommentsChanged, required this.onCommentsChanged,
required this.onMarkChanged, required this.onMarkChanged,
this.radarRequestArgs, this.radarRequestArgs,
this.hasUnmarkConfirmation = false,
}) : super(key: key); }) : super(key: key);
@override @override
@ -35,6 +38,7 @@ class RadarOverview extends StatelessWidget {
'onCommentsChanged': onCommentsChanged, 'onCommentsChanged': onCommentsChanged,
'id': radar.id, 'id': radar.id,
'args': radarRequestArgs, 'args': radarRequestArgs,
'hasUnmarkConfirmation': hasUnmarkConfirmation,
}, },
), ),
child: Column( child: Column(
@ -101,6 +105,7 @@ class RadarOverview extends StatelessWidget {
BookmarkButton( BookmarkButton(
value: radar.marked, value: radar.marked,
onMarkChanged: (value) => onMarkChanged(radar.id, value), onMarkChanged: (value) => onMarkChanged(radar.id, value),
askForConfirmation: hasUnmarkConfirmation,
), ),
const Spacer(), const Spacer(),
if (radar.comments != 0) DidvanText(radar.comments.toString()), if (radar.comments != 0) DidvanText(radar.comments.toString()),
@ -129,4 +134,63 @@ class RadarOverview extends StatelessWidget {
), ),
); );
} }
static Widget get placeholder => DidvanCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const ShimmerPlaceholder(
width: 200,
height: 16,
),
const SizedBox(height: 8),
const AspectRatio(aspectRatio: 16 / 9, child: ShimmerPlaceholder()),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
ShimmerPlaceholder(
height: 12,
width: 70,
),
ShimmerPlaceholder(
height: 12,
width: 70,
),
],
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const SizedBox(height: 8),
const ShimmerPlaceholder(
height: 16,
),
const DidvanDivider(),
Row(
children: const [
ShimmerPlaceholder(
height: 32,
width: 32,
),
Spacer(),
ShimmerPlaceholder(
height: 32,
width: 32,
),
SizedBox(width: 16),
ShimmerPlaceholder(
height: 32,
width: 32,
),
],
),
],
),
);
} }

View File

@ -16,6 +16,7 @@ import 'package:didvan/pages/home/settings/about_us/about_us.dart';
import 'package:didvan/pages/home/settings/bookmarks/bookmarks.dart'; import 'package:didvan/pages/home/settings/bookmarks/bookmarks.dart';
import 'package:didvan/pages/home/settings/bookmarks/bookmark_state.dart'; import 'package:didvan/pages/home/settings/bookmarks/bookmark_state.dart';
import 'package:didvan/pages/home/settings/bookmarks/filtered_bookmark/filtered_bookmark.dart'; import 'package:didvan/pages/home/settings/bookmarks/filtered_bookmark/filtered_bookmark.dart';
import 'package:didvan/pages/home/settings/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart';
import 'package:didvan/pages/home/settings/direct_list/direct_list.dart'; import 'package:didvan/pages/home/settings/direct_list/direct_list.dart';
import 'package:didvan/pages/home/settings/direct_list/direct_list_state.dart'; import 'package:didvan/pages/home/settings/direct_list/direct_list_state.dart';
import 'package:didvan/pages/home/settings/general_settings/settings.dart'; import 'package:didvan/pages/home/settings/general_settings/settings.dart';
@ -129,8 +130,10 @@ class RouteGenerator {
); );
case Routes.filteredBookmarks: case Routes.filteredBookmarks:
return _createRoute( return _createRoute(
ChangeNotifierProvider<BookmarksState>.value( ChangeNotifierProvider<FilteredBookmarksState>(
value: settings.arguments as BookmarksState, create: (context) => FilteredBookmarksState(
settings.arguments as String,
),
child: const FilteredBookmarks(), child: const FilteredBookmarks(),
), ),
); );

View File

@ -14,7 +14,7 @@ class RequestHelper {
static const String updateUserProfile = _baseUserUrl + '/profile/photo'; static const String updateUserProfile = _baseUserUrl + '/profile/photo';
static const String checkUsername = _baseUserUrl + '/CheckUsername'; static const String checkUsername = _baseUserUrl + '/CheckUsername';
static const String updateProfile = _baseUserUrl + '/profile/edit'; static const String updateProfile = _baseUserUrl + '/profile/edit';
static String bookmarks(String? type) => static String bookmarks({String? type}) =>
_baseUserUrl + '/marked/${type ?? ''}'; _baseUserUrl + '/marked/${type ?? ''}';
static const String directTypes = baseUrl + '/direct/types'; static const String directTypes = baseUrl + '/direct/types';

View File

@ -156,6 +156,82 @@ class ActionSheetUtils {
); );
} }
static Future<void> openDialog({required ActionSheetData data}) async {
await showDialog(
context: context,
builder: (context) => Dialog(
shape: const RoundedRectangleBorder(
borderRadius: DesignConfig.mediumBorderRadius,
),
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: Icon(
data.titleIcon,
size: 20,
color: data.titleColor,
),
),
const SizedBox(
width: 8,
),
Expanded(
child: DidvanText(
data.title,
style: Theme.of(context).textTheme.headline3,
color: data.titleColor,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(
height: 12,
),
data.content,
const SizedBox(
height: 12,
),
Row(
children: [
if (data.hasDismissButton)
Expanded(
child: DidvanButton(
onPressed: data.onDismissed ?? () => pop(),
title: data.dismissTitle ?? 'بازگشت',
style: ButtonStyleMode.flat,
),
),
if (data.hasDismissButton)
const SizedBox(
width: 20,
),
Expanded(
child: DidvanButton(
onPressed: () {
pop();
data.onConfirmed?.call();
},
title: data.confrimTitle ?? 'تایید',
),
),
],
),
],
),
),
),
);
}
static void pop() { static void pop() {
DesignConfig.updateSystemUiOverlayStyle(); DesignConfig.updateSystemUiOverlayStyle();
Navigator.of(context).pop(); Navigator.of(context).pop();

View File

@ -43,7 +43,7 @@ class StateHandler<T extends CoreProvier> extends StatelessWidget {
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
); );
case AppState.failed: case AppState.failed:
return EmptyConnection(onRetry: onRetry); return Center(child: EmptyConnection(onRetry: onRetry));
default: default:
return Container(); return Container();
} }