some changes
This commit is contained in:
parent
694529cf07
commit
b5ee5887c6
|
|
@ -0,0 +1,27 @@
|
||||||
|
class MainPageResultType {
|
||||||
|
final int id;
|
||||||
|
final String title;
|
||||||
|
final String image;
|
||||||
|
final String link;
|
||||||
|
final String createdAt;
|
||||||
|
final String type;
|
||||||
|
|
||||||
|
MainPageResultType({
|
||||||
|
required this.id,
|
||||||
|
required this.title,
|
||||||
|
required this.image,
|
||||||
|
required this.link,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.type,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory MainPageResultType.fromJson(Map<String, dynamic> json) =>
|
||||||
|
MainPageResultType(
|
||||||
|
id: json['id'],
|
||||||
|
title: json['title'],
|
||||||
|
image: json['image'] ?? 'https://wallpapercave.com/fwp/wp12977378.jpg',
|
||||||
|
link: json['link'],
|
||||||
|
createdAt: json['createdAt'],
|
||||||
|
type: json['type'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ class AppBarData {
|
||||||
final bool hasBack;
|
final bool hasBack;
|
||||||
final Widget? trailing;
|
final Widget? trailing;
|
||||||
final bool isSmall;
|
final bool isSmall;
|
||||||
|
final bool? hasElevation;
|
||||||
|
|
||||||
AppBarData({
|
AppBarData({
|
||||||
this.title,
|
this.title,
|
||||||
|
|
@ -13,5 +14,6 @@ class AppBarData {
|
||||||
this.hasBack = false,
|
this.hasBack = false,
|
||||||
this.trailing,
|
this.trailing,
|
||||||
this.isSmall = false,
|
this.isSmall = false,
|
||||||
|
this.hasElevation = true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,21 +161,28 @@ class UserProvider extends CoreProvier {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> changeItemMark(String type, int id, bool value) async {
|
static Future<void> changeItemMark(String type, int id, bool? value,
|
||||||
|
{String? description}) async {
|
||||||
_itemMarkQueue.add({
|
_itemMarkQueue.add({
|
||||||
'type': type,
|
'type': type,
|
||||||
'id': id,
|
'id': id,
|
||||||
'value': value,
|
'value': value,
|
||||||
|
'description': description,
|
||||||
});
|
});
|
||||||
Future.delayed(const Duration(milliseconds: 500), () async {
|
Future.delayed(const Duration(milliseconds: 500), () async {
|
||||||
final lastChange =
|
final lastChange =
|
||||||
_itemMarkQueue.lastWhereOrNull((item) => item['id'] == id);
|
_itemMarkQueue.lastWhereOrNull((item) => item['id'] == id);
|
||||||
if (lastChange == null) return;
|
if (lastChange == null) return;
|
||||||
final service = RequestService(RequestHelper.editItemBookmark(type, id));
|
final service = RequestService(
|
||||||
if (lastChange['value']) {
|
RequestHelper.editItemBookmark(type, id),
|
||||||
|
body: {'description': lastChange['description']},
|
||||||
|
);
|
||||||
|
if (lastChange['value'] == true) {
|
||||||
await service.post();
|
await service.post();
|
||||||
} else {
|
} else if (lastChange['value'] == false) {
|
||||||
await service.delete();
|
await service.delete();
|
||||||
|
} else {
|
||||||
|
service.put();
|
||||||
}
|
}
|
||||||
_itemMarkQueue.removeWhere((element) => element['id'] == id);
|
_itemMarkQueue.removeWhere((element) => element['id'] == id);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class RequestHelper {
|
||||||
String? startDate,
|
String? startDate,
|
||||||
String? endDate,
|
String? endDate,
|
||||||
String? search,
|
String? search,
|
||||||
List<String>? types,
|
List<int>? types,
|
||||||
}) =>
|
}) =>
|
||||||
'$_baseHomeUrl/search${_urlConcatGenerator([
|
'$_baseHomeUrl/search${_urlConcatGenerator([
|
||||||
MapEntry('page', page),
|
MapEntry('page', page),
|
||||||
|
|
@ -27,6 +27,16 @@ class RequestHelper {
|
||||||
MapEntry('q', search),
|
MapEntry('q', search),
|
||||||
MapEntry('type', _urlListConcatGenerator(types)),
|
MapEntry('type', _urlListConcatGenerator(types)),
|
||||||
])}';
|
])}';
|
||||||
|
static String searchMarks({
|
||||||
|
required int page,
|
||||||
|
String? search,
|
||||||
|
List<int>? types,
|
||||||
|
}) =>
|
||||||
|
'$_baseHomeUrl/mark${_urlConcatGenerator([
|
||||||
|
MapEntry('page', page),
|
||||||
|
MapEntry('q', search),
|
||||||
|
MapEntry('type', _urlListConcatGenerator(types)),
|
||||||
|
])}';
|
||||||
|
|
||||||
static const String confirmUsername = '$_baseUserUrl/confirmUsername';
|
static const String confirmUsername = '$_baseUserUrl/confirmUsername';
|
||||||
static const String changePassword = '$_baseUserUrl/changePassword';
|
static const String changePassword = '$_baseUserUrl/changePassword';
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
import 'package:didvan/models/requests/studio.dart';
|
|
||||||
import 'package:didvan/models/view/app_bar_data.dart';
|
import 'package:didvan/models/view/app_bar_data.dart';
|
||||||
import 'package:didvan/views/home/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart';
|
import 'package:didvan/views/home/bookmarks/filtered_bookmark/filtered_bookmarks_state.dart';
|
||||||
import 'package:didvan/views/widgets/overview/news.dart';
|
import 'package:didvan/views/widgets/overview/multitype.dart';
|
||||||
import 'package:didvan/views/widgets/overview/podcast.dart';
|
|
||||||
import 'package:didvan/views/widgets/overview/radar.dart';
|
import 'package:didvan/views/widgets/overview/radar.dart';
|
||||||
import 'package:didvan/views/widgets/overview/video.dart';
|
|
||||||
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
||||||
import 'package:didvan/views/widgets/state_handlers/empty_list.dart';
|
import 'package:didvan/views/widgets/state_handlers/empty_list.dart';
|
||||||
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
||||||
|
|
@ -32,13 +29,15 @@ class _FilteredBookmarksState extends State<FilteredBookmarks> {
|
||||||
String get _appBarTitle {
|
String get _appBarTitle {
|
||||||
switch (context.read<FilteredBookmarksState>().type) {
|
switch (context.read<FilteredBookmarksState>().type) {
|
||||||
case 'radar':
|
case 'radar':
|
||||||
return 'تحلیلهای رادار';
|
return 'پویش افق';
|
||||||
case 'news':
|
case 'news':
|
||||||
return 'اخبار';
|
return 'دنیای فولاد';
|
||||||
case 'video':
|
case 'video':
|
||||||
return 'ویدئوها';
|
return 'ویدئوکستها';
|
||||||
case 'podcast':
|
case 'podcast':
|
||||||
return 'پادکستها';
|
return 'پادکستها';
|
||||||
|
case 'new-radar':
|
||||||
|
return 'تحلیلهای رادار';
|
||||||
default:
|
default:
|
||||||
return 'پادکستها';
|
return 'پادکستها';
|
||||||
}
|
}
|
||||||
|
|
@ -63,37 +62,46 @@ class _FilteredBookmarksState extends State<FilteredBookmarks> {
|
||||||
state.getBookmarks(page: state.page + 1);
|
state.getBookmarks(page: state.page + 1);
|
||||||
}
|
}
|
||||||
index--;
|
index--;
|
||||||
if (state.type == 'radar') {
|
return MultitypeOverview(
|
||||||
return RadarOverview(
|
item: state.bookmarks[index],
|
||||||
radar: state.bookmarks[index],
|
enableCaption: true,
|
||||||
onMarkChanged: _onBookmarkChanged,
|
onMarkChanged: (id, value) => _onBookmarkChanged(
|
||||||
onCommentsChanged: state.onCommentsChanged,
|
id,
|
||||||
hasUnmarkConfirmation: true,
|
value,
|
||||||
);
|
true,
|
||||||
}
|
),
|
||||||
if (state.type == 'news') {
|
|
||||||
return NewsOverview(
|
|
||||||
news: state.bookmarks[index],
|
|
||||||
onMarkChanged: _onBookmarkChanged,
|
|
||||||
hasUnmarkConfirmation: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (state.type == 'podcast') {
|
|
||||||
return PodcastOverview(
|
|
||||||
studioRequestArgs:
|
|
||||||
const StudioRequestArgs(page: 0, type: 'podcast'),
|
|
||||||
podcast: state.bookmarks[index],
|
|
||||||
onMarkChanged: _onBookmarkChanged,
|
|
||||||
hasUnmarkConfirmation: true,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return VideoOverview(
|
|
||||||
studioRequestArgs:
|
|
||||||
const StudioRequestArgs(page: 0, type: 'video'),
|
|
||||||
video: state.bookmarks[index],
|
|
||||||
onMarkChanged: _onBookmarkChanged,
|
|
||||||
hasUnmarkConfirmation: true,
|
|
||||||
);
|
);
|
||||||
|
// if (state.type == 'radar') {
|
||||||
|
// return RadarOverview(
|
||||||
|
// radar: state.bookmarks[index],
|
||||||
|
// onMarkChanged: _onBookmarkChanged,
|
||||||
|
// onCommentsChanged: state.onCommentsChanged,
|
||||||
|
// hasUnmarkConfirmation: true,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// if (state.type == 'news') {
|
||||||
|
// return NewsOverview(
|
||||||
|
// news: state.bookmarks[index],
|
||||||
|
// onMarkChanged: _onBookmarkChanged,
|
||||||
|
// hasUnmarkConfirmation: true,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// if (state.type == 'podcast') {
|
||||||
|
// return PodcastOverview(
|
||||||
|
// studioRequestArgs:
|
||||||
|
// const StudioRequestArgs(page: 0, type: 'podcast'),
|
||||||
|
// podcast: state.bookmarks[index],
|
||||||
|
// onMarkChanged: _onBookmarkChanged,
|
||||||
|
// hasUnmarkConfirmation: true,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// return VideoOverview(
|
||||||
|
// studioRequestArgs:
|
||||||
|
// const StudioRequestArgs(page: 0, type: 'video'),
|
||||||
|
// video: state.bookmarks[index],
|
||||||
|
// onMarkChanged: _onBookmarkChanged,
|
||||||
|
// hasUnmarkConfirmation: true,
|
||||||
|
// );
|
||||||
},
|
},
|
||||||
childCount: state.bookmarks.length,
|
childCount: state.bookmarks.length,
|
||||||
onRetry: () => state.getBookmarks(page: state.page),
|
onRetry: () => state.getBookmarks(page: state.page),
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
|
||||||
final state = context.read<HomeState>();
|
final state = context.read<HomeState>();
|
||||||
DesignConfig.updateSystemUiOverlayStyle();
|
DesignConfig.updateSystemUiOverlayStyle();
|
||||||
_tabController = TabController(length: 4, vsync: this, initialIndex: 0);
|
_tabController = TabController(length: 4, vsync: this, initialIndex: 0);
|
||||||
|
state.tabController = _tabController;
|
||||||
_tabController.addListener(() {
|
_tabController.addListener(() {
|
||||||
state.currentPageIndex = _tabController.index;
|
state.currentPageIndex = _tabController.index;
|
||||||
});
|
});
|
||||||
|
|
@ -43,14 +44,17 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: const LogoAppBar(),
|
appBar: LogoAppBar(),
|
||||||
body: Consumer<HomeState>(
|
body: Consumer<HomeState>(
|
||||||
builder: (context, state, child) => AnimatedCrossFade(
|
builder: (context, state, child) => AnimatedCrossFade(
|
||||||
duration: DesignConfig.lowAnimationDuration,
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
crossFadeState: state.showSearchPage
|
crossFadeState: state.filtering
|
||||||
? CrossFadeState.showSecond
|
? CrossFadeState.showSecond
|
||||||
: CrossFadeState.showFirst,
|
: CrossFadeState.showFirst,
|
||||||
firstChild: TabBarView(
|
firstChild: SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
child: TabBarView(
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
children: const [
|
children: const [
|
||||||
|
|
@ -60,6 +64,7 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
|
||||||
Bookmarks(),
|
Bookmarks(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
secondChild: const SearchPage(),
|
secondChild: const SearchPage(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,13 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:didvan/constants/assets.dart';
|
import 'package:didvan/constants/assets.dart';
|
||||||
import 'package:didvan/models/category.dart';
|
import 'package:didvan/models/category.dart';
|
||||||
|
import 'package:didvan/models/enums.dart';
|
||||||
|
import 'package:didvan/models/overview_data.dart';
|
||||||
import 'package:didvan/providers/core.dart';
|
import 'package:didvan/providers/core.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.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';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class MenuItemType {
|
class MenuItemType {
|
||||||
final String label;
|
final String label;
|
||||||
|
|
@ -25,6 +28,24 @@ class HomeState extends CoreProvier {
|
||||||
String lastSearch = '';
|
String lastSearch = '';
|
||||||
bool _showSearchPage = false;
|
bool _showSearchPage = false;
|
||||||
Timer? timer;
|
Timer? timer;
|
||||||
|
String? startDate;
|
||||||
|
String? endDate;
|
||||||
|
int page = 1;
|
||||||
|
int lastPage = 1;
|
||||||
|
final List<CategoryData> selectedCats = [];
|
||||||
|
final List<OverviewData> results = [];
|
||||||
|
late TabController tabController;
|
||||||
|
|
||||||
|
void resetFilters(bool isInit) {
|
||||||
|
startDate = null;
|
||||||
|
endDate = null;
|
||||||
|
selectedCats.clear();
|
||||||
|
search = '';
|
||||||
|
lastSearch = '';
|
||||||
|
if (!isInit) {
|
||||||
|
searchAll(page: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set showSearchPage(bool value) {
|
set showSearchPage(bool value) {
|
||||||
_showSearchPage = value;
|
_showSearchPage = value;
|
||||||
|
|
@ -43,12 +64,76 @@ class HomeState extends CoreProvier {
|
||||||
List<MenuItemType> menuItems = [];
|
List<MenuItemType> menuItems = [];
|
||||||
List<CategoryData> categories = [];
|
List<CategoryData> categories = [];
|
||||||
|
|
||||||
Future<void> searchAll({required int page}) async {
|
bool get filtering =>
|
||||||
|
selectedCats.isNotEmpty ||
|
||||||
|
startDate != null ||
|
||||||
|
endDate != null ||
|
||||||
|
search.isNotEmpty;
|
||||||
|
|
||||||
|
Future<void> searchMarks({required int page}) async {
|
||||||
|
this.page = page;
|
||||||
|
if (page == 1) {
|
||||||
|
results.clear();
|
||||||
|
appState = AppState.busy;
|
||||||
|
}
|
||||||
lastSearch = search;
|
lastSearch = search;
|
||||||
final service = RequestService(
|
final service = RequestService(
|
||||||
RequestHelper.searchAll(page: page, search: search),
|
RequestHelper.searchAll(
|
||||||
|
page: page,
|
||||||
|
search: search,
|
||||||
|
endDate: endDate,
|
||||||
|
types: selectedCats.map((e) => e.id).toList(),
|
||||||
|
startDate: startDate,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
|
if (service.isSuccess) {
|
||||||
|
lastPage = service.result['lastPage'];
|
||||||
|
results.addAll(
|
||||||
|
List<OverviewData>.from(
|
||||||
|
service.result['contents'].map(
|
||||||
|
(e) => OverviewData.fromJson(e),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
lastPage = service.result['lastPage'];
|
||||||
|
appState = AppState.idle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
appState = AppState.failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> searchAll({required int page}) async {
|
||||||
|
this.page = page;
|
||||||
|
if (page == 1) {
|
||||||
|
results.clear();
|
||||||
|
appState = AppState.busy;
|
||||||
|
}
|
||||||
|
lastSearch = search;
|
||||||
|
final service = RequestService(
|
||||||
|
RequestHelper.searchAll(
|
||||||
|
page: page,
|
||||||
|
search: search,
|
||||||
|
endDate: endDate,
|
||||||
|
types: selectedCats.map((e) => e.id).toList(),
|
||||||
|
startDate: startDate,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await service.httpGet();
|
||||||
|
if (service.isSuccess) {
|
||||||
|
lastPage = service.result['lastPage'];
|
||||||
|
results.addAll(
|
||||||
|
List<OverviewData>.from(
|
||||||
|
service.result['contents'].map(
|
||||||
|
(e) => OverviewData.fromJson(e),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
lastPage = service.result['lastPage'];
|
||||||
|
appState = AppState.idle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
appState = AppState.failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh() {
|
void refresh() {
|
||||||
|
|
@ -62,7 +147,7 @@ class HomeState extends CoreProvier {
|
||||||
),
|
),
|
||||||
MenuItemType(
|
MenuItemType(
|
||||||
label: 'پویش افق',
|
label: 'پویش افق',
|
||||||
asset: Assets.fooladWorld,
|
asset: Assets.ofogh,
|
||||||
link: Routes.radars,
|
link: Routes.radars,
|
||||||
),
|
),
|
||||||
MenuItemType(
|
MenuItemType(
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,7 @@ class _MainPageSection extends StatelessWidget {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (list.type != 'podcast')
|
||||||
DidvanSlider(
|
DidvanSlider(
|
||||||
height: 260,
|
height: 260,
|
||||||
itemCount: list.contents.length,
|
itemCount: list.contents.length,
|
||||||
|
|
@ -171,7 +172,9 @@ class _MainPageSection extends StatelessWidget {
|
||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
if (list.type == 'podcast')
|
if (list.type == 'podcast')
|
||||||
Column(
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 28),
|
||||||
|
child: Column(
|
||||||
children: list.contents
|
children: list.contents
|
||||||
.map(
|
.map(
|
||||||
(e) => Padding(
|
(e) => Padding(
|
||||||
|
|
@ -187,6 +190,7 @@ class _MainPageSection extends StatelessWidget {
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
// if (list.type != 'news' &&
|
// if (list.type != 'news' &&
|
||||||
// list.type != 'radar' &&
|
// list.type != 'radar' &&
|
||||||
// list.type != 'video' &&
|
// list.type != 'video' &&
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
import 'package:didvan/models/home_page_content/home_page_content.dart';
|
import 'package:didvan/models/home_page_content/home_page_content.dart';
|
||||||
|
import 'package:didvan/models/requests/news.dart';
|
||||||
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
import 'package:didvan/providers/core.dart';
|
import 'package:didvan/providers/core.dart';
|
||||||
|
import 'package:didvan/routes/routes.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';
|
||||||
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
class MainPageState extends CoreProvier {
|
class MainPageState extends CoreProvier {
|
||||||
late MainPageContent content;
|
late MainPageContent content;
|
||||||
|
|
@ -22,4 +28,63 @@ class MainPageState extends CoreProvier {
|
||||||
_getMainPageContent();
|
_getMainPageContent();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void markChangeHandler(String type, int id, bool value) {
|
||||||
|
content.lists
|
||||||
|
.firstWhere((element) => element.type == type)
|
||||||
|
.contents
|
||||||
|
.firstWhere((element) => element.id == id)
|
||||||
|
.marked = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void navigationHandler(
|
||||||
|
String type,
|
||||||
|
int id,
|
||||||
|
String? link,
|
||||||
|
) {
|
||||||
|
link = link ?? '';
|
||||||
|
dynamic args;
|
||||||
|
switch (type) {
|
||||||
|
case 'news':
|
||||||
|
{
|
||||||
|
link = Routes.newsDetails;
|
||||||
|
args = {
|
||||||
|
'onMarkChanged': (id, value) => markChangeHandler(type, id, value),
|
||||||
|
'id': id,
|
||||||
|
'args': const NewsRequestArgs(page: 0),
|
||||||
|
'hasUnmarkConfirmation': false,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'radar':
|
||||||
|
{
|
||||||
|
link = Routes.radarDetails;
|
||||||
|
args = {
|
||||||
|
'onMarkChanged': (id, value) => markChangeHandler(type, id, value),
|
||||||
|
'id': id,
|
||||||
|
'args': const RadarRequestArgs(page: 0),
|
||||||
|
'hasUnmarkConfirmation': false,
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'video':
|
||||||
|
{
|
||||||
|
link = Routes.studioDetails;
|
||||||
|
args = {
|
||||||
|
type: 'podcast',
|
||||||
|
id: 'id',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (link == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (link.startsWith('http')) {
|
||||||
|
launchUrlString('$link?accessToken=${RequestService.token}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Navigator.of(ActionSheetUtils.context).pushNamed(link, arguments: args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,15 @@ import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/models/home_page_content/content.dart';
|
import 'package:didvan/models/home_page_content/content.dart';
|
||||||
import 'package:didvan/providers/user.dart';
|
import 'package:didvan/providers/user.dart';
|
||||||
import 'package:didvan/utils/date_time.dart';
|
import 'package:didvan/utils/date_time.dart';
|
||||||
|
import 'package:didvan/views/home/home_state.dart';
|
||||||
|
import 'package:didvan/views/home/main/main_page_state.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/card.dart';
|
import 'package:didvan/views/widgets/didvan/card.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:didvan/views/widgets/skeleton_image.dart';
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:persian_number_utility/persian_number_utility.dart';
|
import 'package:persian_number_utility/persian_number_utility.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class MainPageGeneralItem extends StatefulWidget {
|
class MainPageGeneralItem extends StatefulWidget {
|
||||||
final MainPageContentType content;
|
final MainPageContentType content;
|
||||||
|
|
@ -74,19 +78,79 @@ class _MainPageGeneralItemState extends State<MainPageGeneralItem> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DidvanCard(
|
return GestureDetector(
|
||||||
|
onTap: () => context.read<MainPageState>().navigationHandler(
|
||||||
|
widget.type,
|
||||||
|
widget.content.id,
|
||||||
|
widget.content.link,
|
||||||
|
),
|
||||||
|
child: DidvanCard(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
children: [
|
children: [
|
||||||
SkeletonImage(
|
SkeletonImage(
|
||||||
imageUrl: widget.content.image,
|
imageUrl: widget.content.image,
|
||||||
height: 140,
|
height: 140,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(10)),
|
borderRadius:
|
||||||
|
const BorderRadius.vertical(top: Radius.circular(10)),
|
||||||
|
),
|
||||||
|
if (widget.type == 'video')
|
||||||
|
Positioned.fill(
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
height: 36,
|
||||||
|
width: 36,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondary
|
||||||
|
.withOpacity(0.7),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
DidvanIcons.play_solid,
|
||||||
|
color: Theme.of(context).colorScheme.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.type == 'radar')
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
bottom: 0,
|
||||||
|
child: Container(
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topRight: Radius.circular(10),
|
||||||
|
),
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
context
|
||||||
|
.read<HomeState>()
|
||||||
|
.categories
|
||||||
|
.firstWhere(
|
||||||
|
(element) =>
|
||||||
|
element.id.toString() ==
|
||||||
|
widget.content.subtitles[2],
|
||||||
|
)
|
||||||
|
.asset ??
|
||||||
|
'',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -148,6 +212,7 @@ class _MainPageGeneralItemState extends State<MainPageGeneralItem> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,37 @@
|
||||||
|
import 'package:didvan/models/enums.dart';
|
||||||
|
import 'package:didvan/views/home/home_state.dart';
|
||||||
|
import 'package:didvan/views/home/search/widgets/search_result_item.dart';
|
||||||
|
import 'package:didvan/views/widgets/state_handlers/empty_list.dart';
|
||||||
|
import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class SearchPage extends StatelessWidget {
|
class SearchPage extends StatelessWidget {
|
||||||
const SearchPage({super.key});
|
const SearchPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const Placeholder();
|
final state = context.watch<HomeState>();
|
||||||
|
return SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
child: StateHandler<HomeState>(
|
||||||
|
state: state,
|
||||||
|
enableEmptyState:
|
||||||
|
state.appState == AppState.idle && state.results.isEmpty,
|
||||||
|
emptyState: const EmptyList(),
|
||||||
|
onRetry: () => state.searchAll(page: state.page),
|
||||||
|
builder: (context, state) => ListView.builder(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
itemBuilder: (context, index) => Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
|
child: SearchResultItem(
|
||||||
|
item: state.results[index],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
itemCount: state.results.length,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
import 'package:didvan/config/theme_data.dart';
|
||||||
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/models/overview_data.dart';
|
||||||
|
import 'package:didvan/models/requests/news.dart';
|
||||||
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
|
import 'package:didvan/models/requests/studio.dart';
|
||||||
|
import 'package:didvan/routes/routes.dart';
|
||||||
|
import 'package:didvan/services/media/media.dart';
|
||||||
|
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/card.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
||||||
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:persian_number_utility/persian_number_utility.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class SearchResultItem extends StatelessWidget {
|
||||||
|
final OverviewData item;
|
||||||
|
|
||||||
|
const SearchResultItem({
|
||||||
|
Key? key,
|
||||||
|
required this.item,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
get _targetPageArgs {
|
||||||
|
if (item.type == 'radar') {
|
||||||
|
return const RadarRequestArgs(page: 0);
|
||||||
|
}
|
||||||
|
if (item.type == 'news') {
|
||||||
|
return const NewsRequestArgs(page: 0);
|
||||||
|
}
|
||||||
|
return StudioRequestArgs(page: 0, type: item.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get _targetPageRouteName {
|
||||||
|
if (item.type == 'radar') {
|
||||||
|
return Routes.radarDetails;
|
||||||
|
}
|
||||||
|
if (item.type == 'news') {
|
||||||
|
return Routes.newsDetails;
|
||||||
|
}
|
||||||
|
return Routes.studioDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
IconData get _icon {
|
||||||
|
if (item.type == 'radar') {
|
||||||
|
return DidvanIcons.radar_light;
|
||||||
|
}
|
||||||
|
if (item.type == 'news') {
|
||||||
|
return DidvanIcons.news_light;
|
||||||
|
}
|
||||||
|
if (item.type == 'video') {
|
||||||
|
return DidvanIcons.video_light;
|
||||||
|
}
|
||||||
|
return DidvanIcons.podcast_light;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DidvanCard(
|
||||||
|
onTap: () async {
|
||||||
|
if (item.type == 'podcast') {
|
||||||
|
final state = context.read<StudioDetailsState>();
|
||||||
|
await state.getStudioDetails(
|
||||||
|
item.id,
|
||||||
|
args: const StudioRequestArgs(page: 0, type: 'podcast'),
|
||||||
|
);
|
||||||
|
MediaService.handleAudioPlayback(
|
||||||
|
audioSource: item.link,
|
||||||
|
id: item.id,
|
||||||
|
isNetworkAudio: true,
|
||||||
|
isVoiceMessage: false,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Navigator.of(context).pushNamed(
|
||||||
|
_targetPageRouteName,
|
||||||
|
arguments: {
|
||||||
|
'id': item.id,
|
||||||
|
'args': _targetPageArgs,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
SkeletonImage(imageUrl: item.image, height: 80, width: 80),
|
||||||
|
Container(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
borderRadius: const BorderRadius.horizontal(
|
||||||
|
left: Radius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
_icon,
|
||||||
|
color: Theme.of(context).colorScheme.white,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Expanded(
|
||||||
|
child: SizedBox(
|
||||||
|
height: 80,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
DidvanText(
|
||||||
|
item.title,
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
DidvanIcons.calendar_day_light,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
DidvanText(
|
||||||
|
DateTime.parse(item.createdAt).toPersianDateStr(),
|
||||||
|
style: Theme.of(context).textTheme.labelSmall,
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Widget get placeholder => const DidvanCard(
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ShimmerPlaceholder(height: 80, width: 80),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
SizedBox(
|
||||||
|
height: 80,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ShimmerPlaceholder(height: 18, width: 150),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
ShimmerPlaceholder(height: 18, width: 100),
|
||||||
|
Spacer(),
|
||||||
|
ShimmerPlaceholder(height: 14, width: 80),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -138,6 +138,7 @@ class _StatisticState extends State<Statistic> {
|
||||||
),
|
),
|
||||||
if (state.appState != AppState.failed)
|
if (state.appState != AppState.failed)
|
||||||
CategoriesList(
|
CategoriesList(
|
||||||
|
top: 0,
|
||||||
categories: state.categories,
|
categories: state.categories,
|
||||||
isColapsed: state.isColapsed,
|
isColapsed: state.isColapsed,
|
||||||
onSelected: (id) {
|
onSelected: (id) {
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,7 @@ class _StatisticDetailsState extends State<StatisticDetails> {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
CategoriesList(
|
CategoriesList(
|
||||||
|
top: 0,
|
||||||
isColapsed: false,
|
isColapsed: false,
|
||||||
isAppBar: false,
|
isAppBar: false,
|
||||||
selectedCats: [state.currentDateRange],
|
selectedCats: [state.currentDateRange],
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@ class MainCategories extends StatelessWidget {
|
||||||
if (link.startsWith('http')) {
|
if (link.startsWith('http')) {
|
||||||
launchUrlString(link);
|
launchUrlString(link);
|
||||||
} else if (link.startsWith('tab-')) {
|
} else if (link.startsWith('tab-')) {
|
||||||
context.read<HomeState>().currentPageIndex = 1;
|
final state = context.read<HomeState>();
|
||||||
|
state.currentPageIndex = 1;
|
||||||
|
state.tabController.animateTo(1);
|
||||||
} else {
|
} else {
|
||||||
Navigator.of(context).pushNamed(
|
Navigator.of(context).pushNamed(
|
||||||
link.contains('audio') ? link.replaceAll('/audio', '') : link,
|
link.contains('audio') ? link.replaceAll('/audio', '') : link,
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,12 @@ class _NewsState extends State<News> {
|
||||||
appBarData: AppBarData(
|
appBarData: AppBarData(
|
||||||
title: 'دنیای فولاد',
|
title: 'دنیای فولاد',
|
||||||
hasBack: true,
|
hasBack: true,
|
||||||
|
hasElevation: false,
|
||||||
),
|
),
|
||||||
slivers: [
|
slivers: [
|
||||||
if (state.appState != AppState.failed)
|
if (state.appState != AppState.failed)
|
||||||
SliverAppBar(
|
SliverAppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
pinned: true,
|
pinned: true,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import 'package:didvan/providers/core.dart';
|
||||||
import 'package:didvan/services/app_initalizer.dart';
|
import 'package:didvan/services/app_initalizer.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';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
class PodcastsState extends CoreProvier {
|
class PodcastsState extends CoreProvier {
|
||||||
final List<OverviewData> studios = [];
|
final List<OverviewData> studios = [];
|
||||||
|
|
@ -129,7 +130,7 @@ class PodcastsState extends CoreProvier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changeMark(int id, bool value, bool shouldUpdate) async {
|
Future<void> changeMark(int id, bool value, bool shouldUpdate) async {
|
||||||
studios.firstWhere((element) => element.id == id).marked = value;
|
studios.firstWhereOrNull((element) => element.id == id)?.marked = value;
|
||||||
if (shouldUpdate) {
|
if (shouldUpdate) {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,12 @@ import 'package:didvan/models/category.dart';
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
import 'package:didvan/models/requests/radar.dart';
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
|
import 'package:didvan/models/view/app_bar_data.dart';
|
||||||
import 'package:didvan/views/radar/radar_state.dart';
|
import 'package:didvan/views/radar/radar_state.dart';
|
||||||
import 'package:didvan/views/widgets/categories_gird.dart';
|
import 'package:didvan/views/widgets/categories_gird.dart';
|
||||||
import 'package:didvan/views/widgets/categories_list.dart';
|
import 'package:didvan/views/widgets/categories_list.dart';
|
||||||
import 'package:didvan/views/widgets/date_picker_button.dart';
|
import 'package:didvan/views/widgets/date_picker_button.dart';
|
||||||
import 'package:didvan/views/widgets/logo_app_bar.dart';
|
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
import 'package:didvan/views/widgets/overview/radar.dart';
|
import 'package:didvan/views/widgets/overview/radar.dart';
|
||||||
import 'package:didvan/views/widgets/search_field.dart';
|
import 'package:didvan/views/widgets/search_field.dart';
|
||||||
|
|
@ -59,7 +60,17 @@ class _RadarState extends State<Radar> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Consumer<RadarState>(
|
return Consumer<RadarState>(
|
||||||
builder: (context, state, child) => Stack(
|
builder: (context, state, child) => DidvanScaffold(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
appBarData: AppBarData(
|
||||||
|
hasBack: true,
|
||||||
|
hasElevation: false,
|
||||||
|
title: 'پویشهای افق',
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
CustomScrollView(
|
CustomScrollView(
|
||||||
physics: _isAnimating
|
physics: _isAnimating
|
||||||
|
|
@ -67,29 +78,11 @@ class _RadarState extends State<Radar> {
|
||||||
: const ClampingScrollPhysics(),
|
: const ClampingScrollPhysics(),
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
slivers: [
|
slivers: [
|
||||||
const SliverToBoxAdapter(child: LogoAppBar()),
|
|
||||||
if (state.appState != AppState.failed)
|
|
||||||
SliverPadding(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
left: 16,
|
|
||||||
right: 16,
|
|
||||||
bottom: 16,
|
|
||||||
),
|
|
||||||
sliver: SliverToBoxAdapter(
|
|
||||||
child: SearchField(
|
|
||||||
focusNode: _focusNode,
|
|
||||||
isFiltered: state.filtering,
|
|
||||||
title: 'رادار',
|
|
||||||
onChanged: _onChanged,
|
|
||||||
onFilterButtonPressed: _showFilterBottomSheet,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!state.filtering &&
|
if (!state.filtering &&
|
||||||
!state.searching &&
|
!state.searching &&
|
||||||
state.appState != AppState.failed)
|
state.appState != AppState.failed)
|
||||||
const SliverToBoxAdapter(
|
const SliverToBoxAdapter(
|
||||||
child: SizedBox(height: 276),
|
child: SizedBox(height: 320),
|
||||||
),
|
),
|
||||||
if (state.appState != AppState.failed)
|
if (state.appState != AppState.failed)
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
|
|
@ -122,8 +115,8 @@ class _RadarState extends State<Radar> {
|
||||||
enableEmptyState: state.radars.isEmpty,
|
enableEmptyState: state.radars.isEmpty,
|
||||||
emptyState: Padding(
|
emptyState: Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 120),
|
padding: const EdgeInsets.only(bottom: 120),
|
||||||
child:
|
child: EmptyResult(
|
||||||
EmptyResult(onNewSearch: () => _focusNode.requestFocus()),
|
onNewSearch: () => _focusNode.requestFocus()),
|
||||||
),
|
),
|
||||||
placeholder: RadarOverview.placeholder,
|
placeholder: RadarOverview.placeholder,
|
||||||
builder: (context, state, index) {
|
builder: (context, state, index) {
|
||||||
|
|
@ -143,8 +136,8 @@ class _RadarState extends State<Radar> {
|
||||||
state.onCommentsChanged(id, count),
|
state.onCommentsChanged(id, count),
|
||||||
radarRequestArgs: RadarRequestArgs(
|
radarRequestArgs: RadarRequestArgs(
|
||||||
page: state.page,
|
page: state.page,
|
||||||
categories:
|
categories: List.from(
|
||||||
List.from(state.selectedCats.map((cat) => cat.id)),
|
state.selectedCats.map((cat) => cat.id)),
|
||||||
endDate: state.endDate,
|
endDate: state.endDate,
|
||||||
isSingleItem: false,
|
isSingleItem: false,
|
||||||
search: state.search,
|
search: state.search,
|
||||||
|
|
@ -163,7 +156,7 @@ class _RadarState extends State<Radar> {
|
||||||
),
|
),
|
||||||
if (state.appState != AppState.failed)
|
if (state.appState != AppState.failed)
|
||||||
CategoriesRow1(
|
CategoriesRow1(
|
||||||
topPadding: 300,
|
topPadding: 212,
|
||||||
rightPadding: 124,
|
rightPadding: 124,
|
||||||
onSelected: _onCategorySelected,
|
onSelected: _onCategorySelected,
|
||||||
categories: state.categories,
|
categories: state.categories,
|
||||||
|
|
@ -181,12 +174,33 @@ class _RadarState extends State<Radar> {
|
||||||
!state.searching &&
|
!state.searching &&
|
||||||
!state.filtering)
|
!state.filtering)
|
||||||
CategoriesList(
|
CategoriesList(
|
||||||
|
top: 60,
|
||||||
categories: state.categories,
|
categories: state.categories,
|
||||||
isColapsed:
|
isColapsed:
|
||||||
state.isColapsed || state.searching || state.filtering,
|
state.isColapsed || state.searching || state.filtering,
|
||||||
onSelected: (_) => state.getRadars(page: 1),
|
onSelected: (_) => state.getRadars(page: 1),
|
||||||
selectedCats: state.selectedCats,
|
selectedCats: state.selectedCats,
|
||||||
),
|
),
|
||||||
|
if (state.appState != AppState.failed)
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).colorScheme.surface,
|
||||||
|
borderRadius: const BorderRadius.vertical(
|
||||||
|
bottom: Radius.circular(12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SearchField(
|
||||||
|
focusNode: _focusNode,
|
||||||
|
isFiltered: state.filtering,
|
||||||
|
title: 'رادار',
|
||||||
|
onChanged: _onChanged,
|
||||||
|
onFilterButtonPressed: _showFilterBottomSheet,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class CategoriesRow2 extends StatelessWidget {
|
||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
curve: Curves.easeIn,
|
curve: Curves.easeIn,
|
||||||
duration: DesignConfig.mediumAnimationDuration,
|
duration: DesignConfig.mediumAnimationDuration,
|
||||||
top: isColapsed ? 12 : 176 + d.padding.top,
|
top: isColapsed ? 12 : 92 + d.padding.top,
|
||||||
left: isColapsed ? -d.size.width : 0,
|
left: isColapsed ? -d.size.width : 0,
|
||||||
right: isColapsed ? d.size.width : 0,
|
right: isColapsed ? d.size.width : 0,
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ class CategoriesList extends StatefulWidget {
|
||||||
final List<CategoryData> selectedCats;
|
final List<CategoryData> selectedCats;
|
||||||
final List<CategoryData> categories;
|
final List<CategoryData> categories;
|
||||||
final void Function(int id) onSelected;
|
final void Function(int id) onSelected;
|
||||||
|
final double top;
|
||||||
const CategoriesList({
|
const CategoriesList({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.isColapsed,
|
required this.isColapsed,
|
||||||
|
|
@ -18,6 +19,7 @@ class CategoriesList extends StatefulWidget {
|
||||||
required this.categories,
|
required this.categories,
|
||||||
required this.onSelected,
|
required this.onSelected,
|
||||||
this.isAppBar = true,
|
this.isAppBar = true,
|
||||||
|
required this.top,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -73,7 +75,7 @@ class _CategoriesListState extends State<CategoriesList> {
|
||||||
);
|
);
|
||||||
if (widget.isAppBar) {
|
if (widget.isAppBar) {
|
||||||
return Positioned(
|
return Positioned(
|
||||||
top: 0,
|
top: widget.top,
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: AnimatedCrossFade(
|
child: AnimatedCrossFade(
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,8 @@ class _DidvanScaffoldState extends State<DidvanScaffold> {
|
||||||
pinned: true,
|
pinned: true,
|
||||||
backgroundColor: widget.backgroundColor ??
|
backgroundColor: widget.backgroundColor ??
|
||||||
Theme.of(context).colorScheme.surface,
|
Theme.of(context).colorScheme.surface,
|
||||||
|
elevation:
|
||||||
|
widget.appBarData?.hasElevation == false ? 0 : null,
|
||||||
flexibleSpace: DidvanAppBar(
|
flexibleSpace: DidvanAppBar(
|
||||||
appBarData: widget.appBarData!,
|
appBarData: widget.appBarData!,
|
||||||
backgroundColor: widget.backgroundColor ??
|
backgroundColor: widget.backgroundColor ??
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,14 @@ import 'dart:async';
|
||||||
|
|
||||||
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/constants/assets.dart';
|
import 'package:didvan/models/category.dart';
|
||||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
import 'package:didvan/views/home/home_state.dart';
|
import 'package:didvan/views/home/home_state.dart';
|
||||||
|
import 'package:didvan/views/widgets/date_picker_button.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/checkbox.dart';
|
||||||
|
import 'package:didvan/views/widgets/item_title.dart';
|
||||||
import 'package:didvan/views/widgets/search_field.dart';
|
import 'package:didvan/views/widgets/search_field.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
|
|
@ -14,10 +17,9 @@ import 'package:didvan/views/widgets/logos/didvan_vertical_logo.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:url_launcher/url_launcher_string.dart';
|
|
||||||
|
|
||||||
class LogoAppBar extends StatelessWidget implements PreferredSizeWidget {
|
class LogoAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
const LogoAppBar({Key? key}) : super(key: key);
|
LogoAppBar({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Size get preferredSize => const Size(double.infinity, 144);
|
Size get preferredSize => const Size(double.infinity, 144);
|
||||||
|
|
@ -64,19 +66,21 @@ class LogoAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
DidvanIconButton(
|
DidvanIconButton(
|
||||||
icon: DidvanIcons.notification_light,
|
icon: DidvanIcons.notification_light,
|
||||||
size: 32,
|
size: 32,
|
||||||
onPressed: () => _handleMenuOpen(context),
|
onPressed: () => {},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
SearchField(
|
Consumer<HomeState>(
|
||||||
title: 'دیدوان',
|
builder: (context, state, child) => SearchField(
|
||||||
|
title: state.currentPageIndex == 3 ? 'رصدهای من' : 'دیدوان',
|
||||||
onChanged: (value) => _onChanged(value, context),
|
onChanged: (value) => _onChanged(value, context),
|
||||||
focusNode: FocusNode(),
|
focusNode: FocusNode(),
|
||||||
onFilterButtonPressed: () => _handleMenuOpen(context),
|
onFilterButtonPressed: () => _showFilterBottomSheet(context),
|
||||||
isFiltered: false,
|
isFiltered: state.filtering && state.search == '',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -85,82 +89,167 @@ class LogoAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
|
|
||||||
void _onChanged(String value, BuildContext context) {
|
void _onChanged(String value, BuildContext context) {
|
||||||
final state = context.read<HomeState>();
|
final state = context.read<HomeState>();
|
||||||
if (state.currentPageIndex == 3) {
|
|
||||||
//search bookmarks
|
|
||||||
}
|
|
||||||
if (value.length < 3 && value.isNotEmpty || state.lastSearch == value) {
|
if (value.length < 3 && value.isNotEmpty || state.lastSearch == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.timer?.cancel();
|
state.timer?.cancel();
|
||||||
state.timer = Timer(const Duration(seconds: 1), () {
|
state.timer = Timer(const Duration(seconds: 1), () {
|
||||||
state.search = value;
|
state.search = value;
|
||||||
|
if (state.currentPageIndex == 3) {
|
||||||
|
state.searchMarks(page: 1);
|
||||||
|
} else {
|
||||||
state.searchAll(page: 1);
|
state.searchAll(page: 1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleMenuOpen(BuildContext context) {
|
final categoryFilters = [
|
||||||
ActionSheetUtils.showBottomSheet(
|
CategoryData(id: 1, label: 'پویش افق'),
|
||||||
|
CategoryData(id: 2, label: 'دنیای فولاد'),
|
||||||
|
CategoryData(id: 3, label: 'ویدئوکست'),
|
||||||
|
CategoryData(id: 4, label: 'پادکست'),
|
||||||
|
CategoryData(id: 1, label: 'تحلیلهای راداری'),
|
||||||
|
CategoryData(id: 1, label: 'سها'),
|
||||||
|
];
|
||||||
|
|
||||||
|
Future<void> _showFilterBottomSheet(BuildContext context) async {
|
||||||
|
final state = context.read<HomeState>();
|
||||||
|
await ActionSheetUtils.showBottomSheet(
|
||||||
data: ActionSheetData(
|
data: ActionSheetData(
|
||||||
|
title: 'فیلتر جستجو',
|
||||||
|
smallDismissButton: true,
|
||||||
|
titleIcon: DidvanIcons.filter_regular,
|
||||||
|
dismissTitle: 'حذف فیلتر',
|
||||||
|
confrimTitle: 'نمایش نتایج',
|
||||||
|
onDismissed: () => state.resetFilters(false),
|
||||||
|
onConfirmed: () => state.searchAll(page: 1),
|
||||||
content: Column(
|
content: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
if (state.currentPageIndex != 3) ...[
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
ItemTitle(
|
||||||
children: [
|
title: 'تاریخ ایجاد',
|
||||||
SvgPicture.asset(
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
Assets.strategicRadarIcon,
|
icon: DidvanIcons.calendar_range_regular,
|
||||||
width: 48,
|
|
||||||
height: 48,
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(height: 8),
|
||||||
DidvanText(
|
StatefulBuilder(
|
||||||
'سامانه رادارهای استراتژیک',
|
builder: (context, setState) => Row(
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
children: [
|
||||||
|
DatePickerButton(
|
||||||
|
initialValue: state.startDate,
|
||||||
|
emptyText: 'از تاریخ',
|
||||||
|
onPicked: (date) =>
|
||||||
|
setState(() => state.startDate = date),
|
||||||
|
lastDate: state.endDate,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
DatePickerButton(
|
||||||
|
initialValue: state.endDate,
|
||||||
|
emptyText: 'تا تاریخ',
|
||||||
|
onPicked: (date) => setState(() => state.endDate = date),
|
||||||
|
firstDate: state.startDate,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
),
|
||||||
_BottomSheetItem(
|
const SizedBox(height: 28),
|
||||||
icon: Assets.progressRadarIcon,
|
],
|
||||||
title: 'رادار روند',
|
ItemTitle(
|
||||||
enabled: true,
|
title: 'دسته بندی',
|
||||||
onTap: () {
|
icon: DidvanIcons.radar_regular,
|
||||||
launchUrlString(
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
'https://trend.didvan.app/',
|
),
|
||||||
mode: LaunchMode.inAppWebView,
|
const SizedBox(height: 12),
|
||||||
);
|
Wrap(
|
||||||
|
children: [
|
||||||
|
for (var i = 0; i < categoryFilters.length; i++)
|
||||||
|
SizedBox(
|
||||||
|
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||||
|
child: DidvanCheckbox(
|
||||||
|
title: categoryFilters[i].label,
|
||||||
|
value: state.selectedCats.contains(state.categories[i]),
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value) {
|
||||||
|
state.selectedCats.add(state.categories[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.selectedCats.remove(state.categories[i]);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
|
||||||
_BottomSheetItem(
|
|
||||||
icon: Assets.techRadarIcon,
|
|
||||||
title: 'رادار تکنولوژی',
|
|
||||||
onTap: () {},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
_BottomSheetItem(
|
|
||||||
icon: Assets.riskRadarIcon,
|
|
||||||
title: 'رادار ریسک',
|
|
||||||
enabled: true,
|
|
||||||
onTap: () {
|
|
||||||
launchUrlString(
|
|
||||||
'https://risk.didvan.app/',
|
|
||||||
mode: LaunchMode.inAppWebView,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
_BottomSheetItem(
|
|
||||||
icon: Assets.startupRadarIcon,
|
|
||||||
title: 'رادار استارتآپ',
|
|
||||||
onTap: () {},
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
hasConfirmButton: false,
|
],
|
||||||
hasDismissButton: false,
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void _handleMenuOpen(BuildContext context) {
|
||||||
|
// ActionSheetUtils.showBottomSheet(
|
||||||
|
// data: ActionSheetData(
|
||||||
|
// content: Column(
|
||||||
|
// children: [
|
||||||
|
// Row(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// SvgPicture.asset(
|
||||||
|
// Assets.strategicRadarIcon,
|
||||||
|
// width: 48,
|
||||||
|
// height: 48,
|
||||||
|
// ),
|
||||||
|
// const SizedBox(width: 4),
|
||||||
|
// DidvanText(
|
||||||
|
// 'سامانه رادارهای استراتژیک',
|
||||||
|
// style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 16),
|
||||||
|
// _BottomSheetItem(
|
||||||
|
// icon: Assets.progressRadarIcon,
|
||||||
|
// title: 'رادار روند',
|
||||||
|
// enabled: true,
|
||||||
|
// onTap: () {
|
||||||
|
// launchUrlString(
|
||||||
|
// 'https://trend.didvan.app/',
|
||||||
|
// mode: LaunchMode.inAppWebView,
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 16),
|
||||||
|
// _BottomSheetItem(
|
||||||
|
// icon: Assets.techRadarIcon,
|
||||||
|
// title: 'رادار تکنولوژی',
|
||||||
|
// onTap: () {},
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 16),
|
||||||
|
// _BottomSheetItem(
|
||||||
|
// icon: Assets.riskRadarIcon,
|
||||||
|
// title: 'رادار ریسک',
|
||||||
|
// enabled: true,
|
||||||
|
// onTap: () {
|
||||||
|
// launchUrlString(
|
||||||
|
// 'https://risk.didvan.app/',
|
||||||
|
// mode: LaunchMode.inAppWebView,
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 16),
|
||||||
|
// _BottomSheetItem(
|
||||||
|
// icon: Assets.startupRadarIcon,
|
||||||
|
// title: 'رادار استارتآپ',
|
||||||
|
// onTap: () {},
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// hasConfirmButton: false,
|
||||||
|
// hasDismissButton: false,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BottomSheetItem extends StatelessWidget {
|
class _BottomSheetItem extends StatelessWidget {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import 'package:didvan/models/overview_data.dart';
|
||||||
import 'package:didvan/models/requests/news.dart';
|
import 'package:didvan/models/requests/news.dart';
|
||||||
import 'package:didvan/models/requests/radar.dart';
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
import 'package:didvan/models/requests/studio.dart';
|
import 'package:didvan/models/requests/studio.dart';
|
||||||
|
import 'package:didvan/providers/user.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
|
import 'package:didvan/services/media/media.dart';
|
||||||
import 'package:didvan/utils/date_time.dart';
|
import 'package:didvan/utils/date_time.dart';
|
||||||
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
|
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/card.dart';
|
import 'package:didvan/views/widgets/didvan/card.dart';
|
||||||
|
|
@ -66,11 +68,18 @@ class MultitypeOverview extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DidvanCard(
|
return DidvanCard(
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
if (item.type == 'podcast') {
|
if (item.type == 'podcast') {
|
||||||
context.read<StudioDetailsState>().getStudioDetails(
|
final state = context.read<StudioDetailsState>();
|
||||||
|
await state.getStudioDetails(
|
||||||
item.id,
|
item.id,
|
||||||
args: StudioRequestArgs(page: 0, type: item.type),
|
args: const StudioRequestArgs(page: 0, type: 'podcast'),
|
||||||
|
);
|
||||||
|
MediaService.handleAudioPlayback(
|
||||||
|
audioSource: item.link,
|
||||||
|
id: item.id,
|
||||||
|
isNetworkAudio: true,
|
||||||
|
isVoiceMessage: false,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -196,8 +205,14 @@ class MultitypeOverview extends StatelessWidget {
|
||||||
),
|
),
|
||||||
DidvanTextField(
|
DidvanTextField(
|
||||||
disableBorders: true,
|
disableBorders: true,
|
||||||
|
initialValue: item.description,
|
||||||
hintText: 'برای اضافه کردن یادداشت لمس کنید.',
|
hintText: 'برای اضافه کردن یادداشت لمس کنید.',
|
||||||
onChanged: (value) {},
|
onChanged: (value) => UserProvider.changeItemMark(
|
||||||
|
item.type,
|
||||||
|
item.id,
|
||||||
|
null,
|
||||||
|
description: value,
|
||||||
|
),
|
||||||
isSmall: true,
|
isSmall: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ dependencies:
|
||||||
url: https://github.com/tintran-dev/betterplayer.git
|
url: https://github.com/tintran-dev/betterplayer.git
|
||||||
assets_audio_player: ^3.1.1
|
assets_audio_player: ^3.1.1
|
||||||
fl_chart: ^0.63.0
|
fl_chart: ^0.63.0
|
||||||
|
collection: ^1.17.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue