261 lines
10 KiB
Dart
261 lines
10 KiB
Dart
import 'dart:async';
|
|
|
|
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/enums.dart';
|
|
import 'package:didvan/models/view/app_bar_data.dart';
|
|
import 'package:didvan/routes/routes.dart';
|
|
import 'package:didvan/views/home/bookmarks/bookmark_state.dart';
|
|
import 'package:didvan/views/home/main/widgets/swot_bookmark.dart';
|
|
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
|
import 'package:didvan/views/widgets/menu_item.dart';
|
|
import 'package:didvan/views/widgets/overview/multitype.dart';
|
|
import 'package:didvan/views/widgets/animated_visibility.dart';
|
|
import 'package:didvan/views/widgets/didvan/card.dart';
|
|
import 'package:didvan/views/widgets/didvan/divider.dart';
|
|
import 'package:didvan/views/widgets/item_title.dart';
|
|
import 'package:didvan/views/widgets/state_handlers/empty_result.dart';
|
|
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/svg.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
class Bookmarks extends StatefulWidget {
|
|
const Bookmarks({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<Bookmarks> createState() => _BookmarksState();
|
|
}
|
|
|
|
|
|
class _BookmarksState extends State<Bookmarks> {
|
|
final _focuseNode = FocusNode();
|
|
Timer? _timer;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
context.read<BookmarksState>().loadInitialData();
|
|
});
|
|
}
|
|
|
|
|
|
void _onSearchChanged(String value) {
|
|
final state = context.read<BookmarksState>();
|
|
if (value.length < 3 && value.isNotEmpty) {
|
|
if (state.search.isNotEmpty && value.isEmpty) {
|
|
state.search = value;
|
|
state.loadInitialData();
|
|
}
|
|
return;
|
|
}
|
|
if (state.lastSearch == value && value.isNotEmpty) return;
|
|
|
|
_timer?.cancel();
|
|
_timer = Timer(const Duration(milliseconds: 700), () {
|
|
state.search = value;
|
|
state.searchAndLoadData(page: 1);
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final state = context.watch<BookmarksState>();
|
|
return DidvanScaffold(
|
|
appBarData: AppBarData(title: 'رصدخانه من', hasBack: true, isSmall: true),
|
|
physics: const BouncingScrollPhysics(),
|
|
padding: const EdgeInsets.all(8.0),
|
|
hidePlayer: true,
|
|
slivers: [
|
|
SliverPadding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
sliver: SliverToBoxAdapter(
|
|
child: Column(
|
|
children: [
|
|
AnimatedVisibility(
|
|
duration: DesignConfig.lowAnimationDuration,
|
|
isVisible: !state.searching,
|
|
child: DidvanCard(
|
|
child: Column(
|
|
children: [
|
|
MenuOption(
|
|
onTap: () => _onCategorySelected(5),
|
|
title: 'رادارهای استراتژیک',
|
|
icon: DidvanIcons.radar_regular,
|
|
iconSize: 24,
|
|
),
|
|
const DidvanDivider(),
|
|
MenuOption(
|
|
onTap: () => _onCategorySelected(2),
|
|
title: 'دنیای فولاد',
|
|
icon: DidvanIcons.foolad_regular,
|
|
iconSize: 24,
|
|
),
|
|
const DidvanDivider(),
|
|
MenuOption(
|
|
onTap: () => _onCategorySelected(1),
|
|
title: 'پویش افق',
|
|
icon: DidvanIcons.scanning_regular,
|
|
iconSize: 24,
|
|
),
|
|
const DidvanDivider(),
|
|
MenuOption(
|
|
onTap: () => _onCategorySelected(3),
|
|
title: 'ویدیوکست',
|
|
icon: DidvanIcons.video_regular,
|
|
iconSize: 24,
|
|
),
|
|
const DidvanDivider(),
|
|
MenuOption(
|
|
onTap: () => _onCategorySelected(4),
|
|
title: 'پادکست',
|
|
icon: DidvanIcons.podcast_regular,
|
|
iconSize: 24,
|
|
),
|
|
const DidvanDivider(),
|
|
MenuOption(
|
|
onTap: () => _onCategorySelected(6),
|
|
title: 'سها',
|
|
icon: DidvanIcons.saha_regular,
|
|
iconSize: 24,
|
|
),
|
|
const DidvanDivider(),
|
|
MenuOption(
|
|
onTap: () => _onCategorySelected(7),
|
|
title: 'اینفوگرافی',
|
|
icon: DidvanIcons.infography_regular,
|
|
iconSize: 24,
|
|
),
|
|
const DidvanDivider(),
|
|
MenuOption(
|
|
onTap: () => _onCategorySelected(8),
|
|
title: 'فرصت و تهدید',
|
|
iconWidget: SvgPicture.asset("lib/assets/images/features/Saha Solid.svg",width: 24,),
|
|
iconSize: 24,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
if (!state.searching || (state.bookmarks.isNotEmpty || state.bookmarkedSwotItems.isNotEmpty))
|
|
Align(
|
|
alignment: Alignment.centerRight,
|
|
child: AnimatedVisibility(
|
|
duration: DesignConfig.lowAnimationDuration,
|
|
isVisible: !state.searching,
|
|
child: const ItemTitle(title: 'نشان شدهها'),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
|
|
SliverStateHandler<BookmarksState>(
|
|
state: state,
|
|
enableEmptyState: state.bookmarks.isEmpty && state.bookmarkedSwotItems.isEmpty && !state.searching && !state.swotItemsLoading,
|
|
emptyState: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
DidvanText(
|
|
'در قسمت رصدخانه من، تمامی مطالبی که در قسمتهای مختلف سوپراپلیکیشن دیدوان، بوکمارک (نشاندار) کردهاید، به تفکیک نمایش داده میشوند. همچنین امکان درج یادداشت شخصی بصورت ضمیمه برای هر محتوا وجود دارد.',
|
|
fontSize: 14,
|
|
color: Theme.of(context).colorScheme.title,
|
|
textAlign: TextAlign.justify,
|
|
),
|
|
Image.asset(
|
|
Assets.bookmarkAnimation,
|
|
width: MediaQuery.sizeOf(context).width,
|
|
height: 180,
|
|
),
|
|
],
|
|
),
|
|
placeholder: state.searching && state.bookmarks.isEmpty && state.bookmarkedSwotItems.isEmpty && !state.swotItemsLoading
|
|
? EmptyResult(onNewSearch: _focuseNode.requestFocus)
|
|
: MultitypeOverview.placeholder,
|
|
builder: (context, state, index) {
|
|
|
|
if (index >= state.bookmarks.length) {
|
|
return const Center(child: CircularProgressIndicator());
|
|
}
|
|
return MultitypeOverview(
|
|
item: state.bookmarks[index],
|
|
onMarkChanged: state.onMarkChanged,
|
|
hasUnmarkConfirmation: true,
|
|
enableCaption: true,
|
|
enableBookmark: true,
|
|
);
|
|
},
|
|
itemPadding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
|
|
childCount: state.bookmarks.length + (state.page != state.lastPage && state.bookmarks.isNotEmpty ? 1 : 0),
|
|
onRetry: () => state.loadInitialData(),
|
|
),
|
|
|
|
if (state.appState == AppState.idle && state.bookmarkedSwotItems.isNotEmpty)
|
|
SliverList(
|
|
delegate: SliverChildBuilderDelegate(
|
|
(context, index) {
|
|
final item = state.bookmarkedSwotItems[index];
|
|
return Padding(
|
|
padding: const EdgeInsets.only(bottom: 8, left: 16, right: 16),
|
|
child: SwotBookmark(
|
|
item: item,
|
|
onSwotUnbookmarked: (postId) {
|
|
state.onSwotMarkChanged(postId);
|
|
},
|
|
),
|
|
);
|
|
},
|
|
childCount: state.bookmarkedSwotItems.length,
|
|
),
|
|
)
|
|
else if (state.swotItemsLoading)
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Center(child: MultitypeOverview.placeholder),
|
|
),
|
|
)
|
|
],
|
|
);
|
|
}
|
|
|
|
void _onCategorySelected(int type) {
|
|
FocusScope.of(context).unfocus();
|
|
final state = context.read<BookmarksState>();
|
|
|
|
Navigator.of(context).pushNamed(Routes.filteredBookmarks, arguments: {
|
|
'type': type,
|
|
'onDeleted': (int id) {
|
|
state.bookmarks.removeWhere(
|
|
(element) => element.id == id && element.typeInteger == type);
|
|
|
|
if (type == 8) {
|
|
state.bookmarkedSwotItems.removeWhere((element) => element.id == id);
|
|
}
|
|
state.update();
|
|
},
|
|
}).then((_) {
|
|
state.loadInitialData();
|
|
});
|
|
}
|
|
}
|
|
|
|
// void _onChanged(String value) {
|
|
// final state = context.read<BookmarksState>();
|
|
// if (value.length < 3 && value.isNotEmpty || state.lastSearch == value) {
|
|
// return;
|
|
// }
|
|
// _timer?.cancel();
|
|
// _timer = Timer(const Duration(seconds: 1), () {
|
|
// state.search = value;
|
|
// state.getBookmarks(page: 1);
|
|
// });
|
|
// }
|
|
|