restucturing | reusablity
This commit is contained in:
parent
0553cc75ae
commit
711a4ad1d0
|
|
@ -1,4 +1,4 @@
|
|||
class NewsOverview {
|
||||
class NewsOverviewData {
|
||||
final int id;
|
||||
final String title;
|
||||
final String reference;
|
||||
|
|
@ -7,7 +7,7 @@ class NewsOverview {
|
|||
final String createdAt;
|
||||
bool marked;
|
||||
|
||||
NewsOverview({
|
||||
NewsOverviewData({
|
||||
required this.id,
|
||||
required this.title,
|
||||
required this.reference,
|
||||
|
|
@ -17,7 +17,8 @@ class NewsOverview {
|
|||
required this.marked,
|
||||
});
|
||||
|
||||
factory NewsOverview.fromJson(Map<String, dynamic> json) => NewsOverview(
|
||||
factory NewsOverviewData.fromJson(Map<String, dynamic> json) =>
|
||||
NewsOverviewData(
|
||||
id: json['id'],
|
||||
title: json['title'],
|
||||
reference: json['reference'],
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import 'category.dart';
|
||||
|
||||
class RadarOverview {
|
||||
class RadarOverviewData {
|
||||
final int id;
|
||||
final String image;
|
||||
final String title;
|
||||
|
|
@ -12,7 +12,7 @@ class RadarOverview {
|
|||
final List<Category> categories;
|
||||
int comments;
|
||||
|
||||
RadarOverview({
|
||||
RadarOverviewData({
|
||||
required this.id,
|
||||
required this.image,
|
||||
required this.title,
|
||||
|
|
@ -25,7 +25,8 @@ class RadarOverview {
|
|||
required this.comments,
|
||||
});
|
||||
|
||||
factory RadarOverview.fromJson(Map<String, dynamic> json) => RadarOverview(
|
||||
factory RadarOverviewData.fromJson(Map<String, dynamic> json) =>
|
||||
RadarOverviewData(
|
||||
id: json['id'],
|
||||
image: json['image'],
|
||||
title: json['title'],
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import 'package:didvan/constants/app_icons.dart';
|
|||
import 'package:didvan/models/enums.dart';
|
||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||
import 'package:didvan/pages/home/news/news_state.dart';
|
||||
import 'package:didvan/pages/home/news/widgets/news_item.dart';
|
||||
import 'package:didvan/pages/home/widgets/news_overview.dart';
|
||||
import 'package:didvan/utils/action_sheet.dart';
|
||||
import 'package:didvan/widgets/date_picker_button.dart';
|
||||
import 'package:didvan/widgets/item_title.dart';
|
||||
|
|
@ -56,16 +56,20 @@ class _NewsState extends State<News> {
|
|||
SliverStateHandler<NewsState>(
|
||||
onRetry: () => state.getNews(page: state.page),
|
||||
state: state,
|
||||
builder: (context, state, index) => NewsItem(
|
||||
news: state.news[index],
|
||||
),
|
||||
builder: (context, state, index) {
|
||||
final news = state.news[index];
|
||||
return NewsOverview(
|
||||
news: news,
|
||||
onMarkChanged: (value) => state.onMarkChanged(news.id, value),
|
||||
);
|
||||
},
|
||||
enableEmptyState: state.news.isEmpty,
|
||||
emptyState: EmptyResult(
|
||||
onNewSearch: () => _focusNode.requestFocus(),
|
||||
),
|
||||
childCount: state.news.length,
|
||||
itemPadding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
||||
placeholder: const _NewsItemPlaceholder(),
|
||||
placeholder: const _NewsOverviewPlaceholder(),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
@ -131,8 +135,8 @@ class _NewsState extends State<News> {
|
|||
}
|
||||
}
|
||||
|
||||
class _NewsItemPlaceholder extends StatelessWidget {
|
||||
const _NewsItemPlaceholder({Key? key}) : super(key: key);
|
||||
class _NewsOverviewPlaceholder extends StatelessWidget {
|
||||
const _NewsOverviewPlaceholder({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
|||
|
|
@ -49,8 +49,17 @@ class _NewsDetailsState extends State<NewsDetails> {
|
|||
left: 0,
|
||||
right: 0,
|
||||
child: FloatingNavigationBar(
|
||||
news: state.currentNews,
|
||||
scrollController: _scrollController,
|
||||
comments: state.currentNews.comments,
|
||||
id: state.currentNews.id,
|
||||
marked: state.currentNews.marked,
|
||||
title: state.currentNews.title,
|
||||
onCommentsChanged: state.onCommentsChanged,
|
||||
onMarkChanged: (value) => widget.pageData['onMarkChanged'](
|
||||
state.currentNews.id,
|
||||
value,
|
||||
),
|
||||
isRadar: false,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ class NewsDetailsState extends CoreProvier {
|
|||
bool exists(NewsDetailsData? newsItem) =>
|
||||
news.any((n) => newsItem != null && n != null && n.id == newsItem.id);
|
||||
|
||||
void onCommentAdded(int id) {
|
||||
news.firstWhere((item) => item!.id == id)!.comments++;
|
||||
void onCommentsChanged(int count) {
|
||||
news.firstWhere((item) => item!.id == currentNews.id)!.comments = count;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:didvan/models/enums.dart';
|
||||
import 'package:didvan/models/news_overview.dart';
|
||||
import 'package:didvan/models/requests/news.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';
|
||||
|
||||
|
|
@ -13,8 +13,7 @@ class NewsState extends CoreProvier {
|
|||
String? endDate;
|
||||
int page = 1;
|
||||
|
||||
final List<MapEntry> _markQueue = [];
|
||||
final List<NewsOverview> news = [];
|
||||
final List<NewsOverviewData> news = [];
|
||||
|
||||
void init() {
|
||||
search = '';
|
||||
|
|
@ -58,7 +57,7 @@ class NewsState extends CoreProvier {
|
|||
if (service.isSuccess) {
|
||||
final newsList = service.result['news'];
|
||||
for (var i = 0; i < newsList.length; i++) {
|
||||
news.add(NewsOverview.fromJson(newsList[i]));
|
||||
news.add(NewsOverviewData.fromJson(newsList[i]));
|
||||
}
|
||||
appState = AppState.idle;
|
||||
return;
|
||||
|
|
@ -66,36 +65,10 @@ class NewsState extends CoreProvier {
|
|||
appState = AppState.failed;
|
||||
}
|
||||
|
||||
Future<void> mark(int id) async {
|
||||
news.firstWhere((element) => element.id == id).marked = true;
|
||||
Future<void> onMarkChanged(int id, bool value) async {
|
||||
news.firstWhere((element) => element.id == id).marked = value;
|
||||
notifyListeners();
|
||||
_markQueue.add(MapEntry(id, true));
|
||||
Future.delayed(const Duration(milliseconds: 500), () async {
|
||||
final MapEntry? lastChange =
|
||||
_markQueue.lastWhereOrNull((item) => item.key == id);
|
||||
if (lastChange == null) return;
|
||||
if (lastChange.value) {
|
||||
final service = RequestService(RequestHelper.markNews(id));
|
||||
await service.post();
|
||||
_markQueue.removeWhere((element) => element.key == id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> unMark(int id) async {
|
||||
news.firstWhere((element) => element.id == id).marked = false;
|
||||
notifyListeners();
|
||||
_markQueue.add(MapEntry(id, false));
|
||||
Future.delayed(const Duration(milliseconds: 500), () async {
|
||||
final MapEntry? lastChange =
|
||||
_markQueue.lastWhereOrNull((item) => item.key == id);
|
||||
if (lastChange == null) return;
|
||||
if (!lastChange.value) {
|
||||
final service = RequestService(RequestHelper.markNews(id));
|
||||
await service.delete();
|
||||
_markQueue.removeWhere((element) => element.key == id);
|
||||
}
|
||||
});
|
||||
UserProvider.changeNewsMark(id, value);
|
||||
}
|
||||
|
||||
bool get isFiltering => startDate != null || endDate != null;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import 'package:didvan/models/view/action_sheet_data.dart';
|
|||
import 'package:didvan/pages/home/radar/radar_state.dart';
|
||||
import 'package:didvan/pages/home/radar/widgets/categories_gird.dart';
|
||||
import 'package:didvan/pages/home/radar/widgets/categories_list.dart';
|
||||
import 'package:didvan/pages/home/radar/widgets/radar_item.dart';
|
||||
import 'package:didvan/pages/home/widgets/radar_overview.dart';
|
||||
import 'package:didvan/widgets/animated_visibility.dart';
|
||||
import 'package:didvan/widgets/search_field.dart';
|
||||
import 'package:didvan/pages/home/widgets/logo_app_bar.dart';
|
||||
|
|
@ -114,7 +114,7 @@ class _RadarState extends State<Radar> {
|
|||
),
|
||||
),
|
||||
SliverStateHandler<RadarState>(
|
||||
onRetry: () => state.getRadarOverviews(page: state.page),
|
||||
onRetry: () => state.getRadarOverviewDatas(page: state.page),
|
||||
state: state,
|
||||
itemPadding: const EdgeInsets.only(
|
||||
bottom: 20,
|
||||
|
|
@ -122,12 +122,21 @@ class _RadarState extends State<Radar> {
|
|||
right: 16,
|
||||
),
|
||||
enableEmptyState: state.radars.isEmpty,
|
||||
emptyState:
|
||||
emptyState: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 120),
|
||||
child:
|
||||
EmptyResult(onNewSearch: () => _focusNode.requestFocus()),
|
||||
placeholder: const _RadarItemPlaceholder(),
|
||||
builder: (context, state, index) => RadarItem(
|
||||
radar: state.radars[index],
|
||||
),
|
||||
placeholder: const _RadarOverviewPlaceholder(),
|
||||
builder: (context, state, index) {
|
||||
final radar = state.radars[index];
|
||||
return RadarOverview(
|
||||
radar: radar,
|
||||
onMarkChanged: (value) => state.changeMark(radar.id, value),
|
||||
onCommentsChanged: (count) =>
|
||||
state.onCommentsChanged(radar.id, count),
|
||||
);
|
||||
},
|
||||
childCount: state.radars.length,
|
||||
),
|
||||
if (state.radars.length == 1)
|
||||
|
|
@ -136,20 +145,9 @@ class _RadarState extends State<Radar> {
|
|||
),
|
||||
],
|
||||
),
|
||||
if (state.appState != AppState.failed)
|
||||
CategoriesRow1(
|
||||
isColapsed:
|
||||
state.isColapsed || state.searching || state.filtering,
|
||||
),
|
||||
if (state.appState != AppState.failed)
|
||||
CategoriesRow2(
|
||||
isColapsed:
|
||||
state.isColapsed || state.searching || state.filtering,
|
||||
),
|
||||
if (state.appState != AppState.failed)
|
||||
CategoriesList(
|
||||
isColapsed: state.isColapsed && !state.searching,
|
||||
),
|
||||
if (state.appState != AppState.failed) const CategoriesRow1(),
|
||||
if (state.appState != AppState.failed) const CategoriesRow2(),
|
||||
if (state.appState != AppState.failed) const CategoriesList(),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
@ -163,7 +161,7 @@ class _RadarState extends State<Radar> {
|
|||
_timer?.cancel();
|
||||
_timer = Timer(const Duration(seconds: 1), () {
|
||||
state.search = value;
|
||||
state.getRadarOverviews(page: 1);
|
||||
state.getRadarOverviewDatas(page: 1);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +206,7 @@ class _RadarState extends State<Radar> {
|
|||
dismissTitle: 'حذف فیلتر',
|
||||
confrimTitle: 'نمایش نتایج',
|
||||
onDismissed: () => state.resetFilters(false),
|
||||
onConfirmed: () => state.getRadarOverviews(page: 1),
|
||||
onConfirmed: () => state.getRadarOverviewDatas(page: 1),
|
||||
content: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
|
@ -276,8 +274,8 @@ class _RadarState extends State<Radar> {
|
|||
}
|
||||
}
|
||||
|
||||
class _RadarItemPlaceholder extends StatelessWidget {
|
||||
const _RadarItemPlaceholder({
|
||||
class _RadarOverviewPlaceholder extends StatelessWidget {
|
||||
const _RadarOverviewPlaceholder({
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,17 @@ class _RadarDetailsState extends State<RadarDetails> {
|
|||
left: 0,
|
||||
right: 0,
|
||||
child: FloatingNavigationBar(
|
||||
radar: state.currentRadar,
|
||||
comments: state.currentRadar.comments,
|
||||
id: state.currentRadar.id,
|
||||
isRadar: true,
|
||||
marked: state.currentRadar.marked,
|
||||
title: state.currentRadar.title,
|
||||
onMarkChanged: (value) => widget.pageData['onMarkChanged'](
|
||||
state.currentRadar.id,
|
||||
value,
|
||||
),
|
||||
onCommentsChanged: state.onCommentsChanged,
|
||||
categories: state.currentRadar.categories,
|
||||
scrollController: _scrollController,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -15,7 +15,13 @@ class RadarDetailsState extends CoreProvier {
|
|||
int _currentIndex = 0;
|
||||
int get currentIndex => _currentIndex;
|
||||
|
||||
RadarDetailsData get currentRadar => radars[_currentIndex]!;
|
||||
RadarDetailsData get currentRadar {
|
||||
try {
|
||||
return radars[_currentIndex]!;
|
||||
} catch (e) {
|
||||
return radars[_currentIndex + 1]!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getRadarDetails(int id, {bool? isForward}) async {
|
||||
if (isForward == null) {
|
||||
|
|
@ -74,8 +80,9 @@ class RadarDetailsState extends CoreProvier {
|
|||
bool exists(RadarDetailsData? radar) =>
|
||||
radars.any((r) => radar != null && r != null && r.id == radar.id);
|
||||
|
||||
void onCommentAdded(int id) {
|
||||
radars.firstWhere((radar) => radar!.id == id)!.comments++;
|
||||
void onCommentsChanged(int count) {
|
||||
radars.firstWhere((radar) => radar!.id == currentRadar.id)!.comments =
|
||||
count;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/models/enums.dart';
|
||||
import 'package:didvan/models/requests/radar.dart';
|
||||
import 'package:didvan/models/view/radar_category.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';
|
||||
|
||||
|
|
@ -16,10 +16,9 @@ class RadarState extends CoreProvier {
|
|||
int page = 1;
|
||||
bool isScrolled = false;
|
||||
bool shouldColapse = false;
|
||||
final List<MapEntry> _markQueue = [];
|
||||
final List<RadarCategory> selectedCats = [];
|
||||
List<RadarCategory> categories = [];
|
||||
final List<RadarOverview> radars = [];
|
||||
final List<RadarOverviewData> radars = [];
|
||||
|
||||
bool get filtering =>
|
||||
selectedCats.length > 1 || startDate != null || endDate != null;
|
||||
|
|
@ -43,7 +42,7 @@ class RadarState extends CoreProvier {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> getRadarOverviews({
|
||||
Future<void> getRadarOverviewDatas({
|
||||
required int page,
|
||||
}) async {
|
||||
if (this.page == page) {
|
||||
|
|
@ -66,7 +65,7 @@ class RadarState extends CoreProvier {
|
|||
await service.httpGet();
|
||||
if (service.isSuccess) {
|
||||
for (var i = 0; i < service.result['radars'].length; i++) {
|
||||
radars.add(RadarOverview.fromJson(service.result['radars'][i]));
|
||||
radars.add(RadarOverviewData.fromJson(service.result['radars'][i]));
|
||||
}
|
||||
if (searching || filtering || isColapsed || isCategorySelected) {
|
||||
shouldColapse = true;
|
||||
|
|
@ -78,47 +77,21 @@ class RadarState extends CoreProvier {
|
|||
appState = AppState.failed;
|
||||
}
|
||||
|
||||
Future<void> mark(int id) async {
|
||||
radars.firstWhere((element) => element.id == id).marked = true;
|
||||
Future<void> changeMark(int id, bool value) async {
|
||||
radars.firstWhere((element) => element.id == id).marked = value;
|
||||
notifyListeners();
|
||||
_markQueue.add(MapEntry(id, true));
|
||||
Future.delayed(const Duration(milliseconds: 500), () async {
|
||||
final MapEntry? lastChange =
|
||||
_markQueue.lastWhereOrNull((item) => item.key == id);
|
||||
if (lastChange == null) return;
|
||||
if (lastChange.value) {
|
||||
final service = RequestService(RequestHelper.markRadar(id));
|
||||
await service.post();
|
||||
_markQueue.removeWhere((element) => element.key == id);
|
||||
}
|
||||
});
|
||||
UserProvider.changeRadarMark(id, value);
|
||||
}
|
||||
|
||||
Future<void> unMark(int id) async {
|
||||
radars.firstWhere((element) => element.id == id).marked = false;
|
||||
notifyListeners();
|
||||
_markQueue.add(MapEntry(id, false));
|
||||
Future.delayed(const Duration(milliseconds: 500), () async {
|
||||
final MapEntry? lastChange =
|
||||
_markQueue.lastWhereOrNull((item) => item.key == id);
|
||||
if (lastChange == null) return;
|
||||
if (!lastChange.value) {
|
||||
final service = RequestService(RequestHelper.markRadar(id));
|
||||
await service.delete();
|
||||
_markQueue.removeWhere((element) => element.key == id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void onCommentAdded(int id) {
|
||||
radars.firstWhere((radar) => radar.id == id).comments++;
|
||||
void onCommentsChanged(int id, int count) {
|
||||
radars.firstWhere((radar) => radar.id == id).comments = count;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void init() {
|
||||
resetFilters(true);
|
||||
Future.delayed(Duration.zero, () {
|
||||
getRadarOverviews(page: 1);
|
||||
getRadarOverviewDatas(page: 1);
|
||||
});
|
||||
categories = [
|
||||
RadarCategory(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import 'package:didvan/constants/assets.dart';
|
|||
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||
import 'package:didvan/models/view/app_bar_data.dart';
|
||||
import 'package:didvan/pages/home/settings/general_settings/settings_state.dart';
|
||||
import 'package:didvan/pages/home/settings/widgets/menu_item.dart';
|
||||
import 'package:didvan/pages/home/widgets/menu_item.dart';
|
||||
import 'package:didvan/providers/theme_provider.dart';
|
||||
import 'package:didvan/utils/action_sheet.dart';
|
||||
import 'package:didvan/widgets/didvan/card.dart';
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/models/view/app_bar_data.dart';
|
||||
import 'package:didvan/pages/home/settings/profile/widgets/profile_photo.dart';
|
||||
import 'package:didvan/pages/home/settings/widgets/menu_item.dart';
|
||||
import 'package:didvan/pages/home/widgets/menu_item.dart';
|
||||
import 'package:didvan/providers/user_provider.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/widgets/animated_visibility.dart';
|
||||
import 'package:didvan/widgets/didvan/button.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/text.dart';
|
||||
import 'package:didvan/widgets/didvan/text_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
|
@ -26,6 +29,7 @@ class _ProfileState extends State<Profile> {
|
|||
late String fullName;
|
||||
String? username;
|
||||
String? email;
|
||||
bool _usernameIsAvailible = true;
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
|
|
@ -54,6 +58,7 @@ class _ProfileState extends State<Profile> {
|
|||
const SizedBox(height: 16),
|
||||
DidvanCard(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
DidvanTextField(
|
||||
title: 'نام و نام خانوادگی',
|
||||
|
|
@ -76,12 +81,15 @@ class _ProfileState extends State<Profile> {
|
|||
hintText: 'انتخاب نام کاربری (اختیاری)',
|
||||
onChanged: _onUsernameChanged,
|
||||
initialValue: state.user.username,
|
||||
validator: (value) async {
|
||||
final result = await state.checkUsername(value);
|
||||
if (result == false) {
|
||||
return 'نام کاربری در دسترس نمیباشد';
|
||||
}
|
||||
},
|
||||
),
|
||||
AnimatedVisibility(
|
||||
duration: DesignConfig.lowAnimationDuration,
|
||||
isVisible: !_usernameIsAvailible,
|
||||
child: DidvanText(
|
||||
'نام کاربری در دسترس نمیباشد',
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
DidvanTextField(
|
||||
|
|
@ -156,6 +164,7 @@ class _ProfileState extends State<Profile> {
|
|||
}
|
||||
|
||||
void _onUsernameChanged(String value) {
|
||||
_usernameIsAvailible = true;
|
||||
_setButtonState();
|
||||
username = value;
|
||||
_timer?.cancel();
|
||||
|
|
@ -163,7 +172,13 @@ class _ProfileState extends State<Profile> {
|
|||
return;
|
||||
}
|
||||
_timer = Timer(const Duration(seconds: 1), () {
|
||||
_formKey.currentState!.validate();
|
||||
context.read<UserProvider>().checkUsername(value).then((value) {
|
||||
if (value == false) {
|
||||
setState(() {
|
||||
_usernameIsAvailible = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/pages/home/settings/widgets/menu_item.dart';
|
||||
import 'package:didvan/pages/home/widgets/menu_item.dart';
|
||||
import 'package:didvan/pages/home/widgets/logo_app_bar.dart';
|
||||
import 'package:didvan/providers/theme_provider.dart';
|
||||
import 'package:didvan/providers/user_provider.dart';
|
||||
|
|
@ -11,6 +11,7 @@ import 'package:didvan/widgets/didvan/text.dart';
|
|||
import 'package:didvan/widgets/item_title.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class Settings extends StatelessWidget {
|
||||
const Settings({Key? key}) : super(key: key);
|
||||
|
|
@ -86,13 +87,15 @@ class Settings extends StatelessWidget {
|
|||
MenuItem(
|
||||
icon: DidvanIcons.didvan_solid,
|
||||
title: 'معرفی دیدوان',
|
||||
onTap: () => {},
|
||||
onTap: () => Navigator.of(context).pushNamed(Routes.aboutUs),
|
||||
),
|
||||
const DidvanDivider(),
|
||||
MenuItem(
|
||||
icon: DidvanIcons.support_regular,
|
||||
title: 'پیام به پشتیبانی',
|
||||
onTap: () => {},
|
||||
onTap: () {
|
||||
launch('mailto:info@didvan.app');
|
||||
},
|
||||
),
|
||||
const DidvanDivider(),
|
||||
MenuItem(
|
||||
|
|
|
|||
|
|
@ -1,190 +0,0 @@
|
|||
import 'package:day_night_time_picker/lib/constants.dart';
|
||||
import 'package:day_night_time_picker/lib/daynight_timepicker.dart';
|
||||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||
import 'package:didvan/models/view/app_bar_data.dart';
|
||||
import 'package:didvan/pages/home/settings/general_settings/settings_state.dart';
|
||||
import 'package:didvan/pages/home/settings/widgets/menu_item.dart';
|
||||
import 'package:didvan/providers/theme_provider.dart';
|
||||
import 'package:didvan/utils/action_sheet.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/text.dart';
|
||||
import 'package:didvan/widgets/item_title.dart';
|
||||
import 'package:didvan/widgets/state_handler.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GeneralSettings extends StatelessWidget {
|
||||
const GeneralSettings({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<GeneralSettingsState>(
|
||||
builder: (context, state, child) => StateHandler<GeneralSettingsState>(
|
||||
state: context.read<GeneralSettingsState>(),
|
||||
builder: (context, state) => DidvanScaffold(
|
||||
appBarData: AppBarData(hasBack: true, title: 'تنظیمات'),
|
||||
children: [
|
||||
DidvanCard(
|
||||
child: MenuItem(
|
||||
title: 'زمان دریافت اعلان',
|
||||
onTap: () => _pickTimeRange(context),
|
||||
icon: DidvanIcons.notification_regular,
|
||||
suffix: state.notificationTimeRange[0],
|
||||
),
|
||||
),
|
||||
const ItemTitle(
|
||||
title: 'انتخاب قلم',
|
||||
icon: DidvanIcons.font_solid,
|
||||
),
|
||||
DidvanCard(
|
||||
child: Column(
|
||||
children: [
|
||||
MenuItem(
|
||||
suffix: 'نیاز به پیادهسازی',
|
||||
title: 'فونت برنامه',
|
||||
onTap: () {},
|
||||
),
|
||||
const DidvanDivider(),
|
||||
MenuItem(
|
||||
suffix: 'نیاز به پیادهسازی',
|
||||
title: 'اندازه متن',
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const ItemTitle(
|
||||
title: 'ظاهر برنامه',
|
||||
icon: DidvanIcons.theme_solid,
|
||||
),
|
||||
DidvanCard(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_themeItem(context, state, 'light'),
|
||||
_themeItem(context, state, 'dark'),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _pickTimeRange(BuildContext context) async {
|
||||
ActionSheetUtils.showBottomSheet(
|
||||
data: ActionSheetData(
|
||||
content: Row(
|
||||
children: [
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _timeFieldBuilder(context, 0)),
|
||||
const SizedBox(width: 8),
|
||||
const DidvanText('-'),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(child: _timeFieldBuilder(context, 1)),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
),
|
||||
title: 'زمان دریافت اعلان',
|
||||
titleIcon: DidvanIcons.notification_regular,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _timeFieldBuilder(BuildContext context, int index) {
|
||||
final GeneralSettingsState state = context.read<GeneralSettingsState>();
|
||||
return ChangeNotifierProvider.value(
|
||||
value: state,
|
||||
child: StatefulBuilder(
|
||||
builder: (context, setState) => GestureDetector(
|
||||
onTap: () async {
|
||||
await _openTimePicker(context, index);
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.splash,
|
||||
borderRadius: DesignConfig.mediumBorderRadius,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.border,
|
||||
),
|
||||
),
|
||||
child: DidvanText(state.notificationTimeRange[index]),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _openTimePicker(BuildContext context, int index) async {
|
||||
final GeneralSettingsState state = context.read<GeneralSettingsState>();
|
||||
await Navigator.of(context).push(
|
||||
showPicker(
|
||||
okText: 'تایید',
|
||||
cancelText: 'بازگشت',
|
||||
accentColor: Theme.of(context).colorScheme.primary,
|
||||
okStyle: Theme.of(context).textTheme.bodyText2!,
|
||||
cancelStyle: Theme.of(context).textTheme.bodyText2!,
|
||||
unselectedColor: Theme.of(context).colorScheme.text,
|
||||
blurredBackground: true,
|
||||
hourLabel: 'ساعت',
|
||||
minuteLabel: 'دقیقه',
|
||||
is24HrFormat: true,
|
||||
iosStylePicker: true,
|
||||
minuteInterval: MinuteInterval.FIFTEEN,
|
||||
context: context,
|
||||
value: const TimeOfDay(hour: 0, minute: 0),
|
||||
themeData: Theme.of(context),
|
||||
onChange: (time) {
|
||||
state.notificationTimeRange = state.notificationTimeRange
|
||||
..replaceRange(
|
||||
index,
|
||||
index + 1,
|
||||
['${time.hour}:${time.minute}'],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _themeItem(
|
||||
BuildContext context, GeneralSettingsState state, String brightness) {
|
||||
final bool isDarkTheme = brightness == 'dark';
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
state.brightness = brightness;
|
||||
if (isDarkTheme && DesignConfig.isDark) {
|
||||
return;
|
||||
} else if (!isDarkTheme && !DesignConfig.isDark) {
|
||||
return;
|
||||
} else {
|
||||
if (isDarkTheme) {
|
||||
context.read<ThemeProvider>().themeMode = ThemeMode.dark;
|
||||
} else {
|
||||
context.read<ThemeProvider>().themeMode = ThemeMode.light;
|
||||
}
|
||||
DesignConfig.updateSystemUiOverlayStyle();
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
SvgPicture.asset(isDarkTheme ? Assets.darkTheme : Assets.lightTheme),
|
||||
const SizedBox(height: 8),
|
||||
DidvanText(
|
||||
isDarkTheme ? 'تیره' : 'روشن',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,21 +4,29 @@ import 'package:didvan/widgets/didvan/text.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class MenuItem extends StatelessWidget {
|
||||
final String title;
|
||||
final String? title;
|
||||
final Widget? titleWidget;
|
||||
final IconData? icon;
|
||||
final double iconSize;
|
||||
final String? suffix;
|
||||
final VoidCallback onTap;
|
||||
final Widget? trailing;
|
||||
final Color? color;
|
||||
const MenuItem({
|
||||
MenuItem({
|
||||
Key? key,
|
||||
required this.title,
|
||||
required this.onTap,
|
||||
this.title,
|
||||
this.icon,
|
||||
this.suffix,
|
||||
required this.onTap,
|
||||
this.color,
|
||||
this.trailing,
|
||||
}) : super(key: key);
|
||||
this.titleWidget,
|
||||
this.iconSize = 18,
|
||||
}) : super(key: key) {
|
||||
if (title == null && titleWidget == null) {
|
||||
throw Exception;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -31,12 +39,14 @@ class MenuItem extends StatelessWidget {
|
|||
if (icon != null)
|
||||
Icon(
|
||||
icon,
|
||||
size: 18,
|
||||
size: iconSize,
|
||||
color: color ?? Theme.of(context).colorScheme.title,
|
||||
),
|
||||
if (icon != null) const SizedBox(width: 4),
|
||||
if (titleWidget != null) titleWidget!,
|
||||
if (titleWidget == null)
|
||||
DidvanText(
|
||||
title,
|
||||
title!,
|
||||
color: color ?? Theme.of(context).colorScheme.title,
|
||||
),
|
||||
const Spacer(),
|
||||
|
|
@ -11,9 +11,12 @@ import 'package:didvan/widgets/skeleton_image.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class NewsItem extends StatelessWidget {
|
||||
final NewsOverview news;
|
||||
const NewsItem({Key? key, required this.news}) : super(key: key);
|
||||
class NewsOverview extends StatelessWidget {
|
||||
final NewsOverviewData news;
|
||||
final void Function(bool value) onMarkChanged;
|
||||
const NewsOverview(
|
||||
{Key? key, required this.news, required this.onMarkChanged})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -77,8 +80,8 @@ class NewsItem extends StatelessWidget {
|
|||
),
|
||||
BookmarkButton(
|
||||
value: news.marked,
|
||||
onMark: () => state.mark(news.id),
|
||||
onUnmark: () => state.unMark(news.id),
|
||||
onMarkChanged: onMarkChanged,
|
||||
bigGestureSize: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
@ -2,7 +2,6 @@ import 'package:didvan/config/theme_data.dart';
|
|||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/models/radar_overview.dart';
|
||||
import 'package:didvan/models/requests/radar.dart';
|
||||
import 'package:didvan/pages/home/radar/radar_state.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/utils/date_time.dart';
|
||||
import 'package:didvan/widgets/bookmark_button.dart';
|
||||
|
|
@ -12,28 +11,30 @@ import 'package:didvan/widgets/didvan/icon_button.dart';
|
|||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:didvan/widgets/skeleton_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class RadarItem extends StatelessWidget {
|
||||
final RadarOverview radar;
|
||||
const RadarItem({Key? key, required this.radar}) : super(key: key);
|
||||
class RadarOverview extends StatelessWidget {
|
||||
final RadarOverviewData radar;
|
||||
final void Function(int count) onCommentsChanged;
|
||||
final void Function(bool value) onMarkChanged;
|
||||
final RadarRequestArgs? radarRequestArgs;
|
||||
const RadarOverview({
|
||||
Key? key,
|
||||
required this.radar,
|
||||
required this.onCommentsChanged,
|
||||
required this.onMarkChanged,
|
||||
this.radarRequestArgs,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final state = context.read<RadarState>();
|
||||
return DidvanCard(
|
||||
onTap: () => Navigator.of(context).pushNamed(
|
||||
Routes.radarDetails,
|
||||
arguments: {
|
||||
'state': state,
|
||||
'onMarkChanged': onMarkChanged,
|
||||
'onCommentsChanged': onCommentsChanged,
|
||||
'id': radar.id,
|
||||
'args': RadarRequestArgs(
|
||||
page: state.page,
|
||||
categories: state.selectedCats.map((e) => e.id).toList(),
|
||||
endDate: state.endDate,
|
||||
search: state.search,
|
||||
startDate: state.startDate,
|
||||
)
|
||||
'args': radarRequestArgs,
|
||||
},
|
||||
),
|
||||
child: Column(
|
||||
|
|
@ -99,8 +100,7 @@ class RadarItem extends StatelessWidget {
|
|||
children: [
|
||||
BookmarkButton(
|
||||
value: radar.marked,
|
||||
onMark: () => state.mark(radar.id),
|
||||
onUnmark: () => state.unMark(radar.id),
|
||||
onMarkChanged: onMarkChanged,
|
||||
),
|
||||
const Spacer(),
|
||||
if (radar.comments != 0) DidvanText(radar.comments.toString()),
|
||||
|
|
@ -114,7 +114,7 @@ class RadarItem extends StatelessWidget {
|
|||
'isRadar': true,
|
||||
'title': radar.title,
|
||||
'id': radar.id,
|
||||
'onCommentAdded': () => state.onCommentAdded(radar.id)
|
||||
'onCommentsChanged': onCommentsChanged
|
||||
},
|
||||
),
|
||||
),
|
||||
Loading…
Reference in New Issue