684 lines
27 KiB
Dart
684 lines
27 KiB
Dart
// ignore_for_file: unused_element_parameter, deprecated_member_use
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:didvan/config/design_config.dart';
|
|
import 'package:didvan/config/theme_data.dart';
|
|
import 'package:didvan/constants/assets.dart';
|
|
import 'package:didvan/models/enums.dart';
|
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
|
import 'package:didvan/routes/routes.dart';
|
|
import 'package:didvan/utils/action_sheet.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/checkbox.dart';
|
|
import 'package:didvan/views/widgets/didvan/scaffold.dart';
|
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
|
import 'package:didvan/views/widgets/date_picker_button.dart';
|
|
import 'package:didvan/views/widgets/item_title.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/divider.dart';
|
|
import 'package:didvan/views/widgets/state_handlers/empty_result.dart';
|
|
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
|
import 'package:didvan/views/widgets/search_field.dart';
|
|
import 'package:didvan/views/widgets/ai_chat_dialog.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();
|
|
});
|
|
}
|
|
|
|
// ignore: unused_element
|
|
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);
|
|
});
|
|
}
|
|
|
|
Future<void> _showFilterBottomSheet() async {
|
|
final state = context.read<BookmarksState>();
|
|
|
|
final categories = [
|
|
{'id': 1, 'label': 'پویش افق'},
|
|
{'id': 2, 'label': 'دنیای فولاد'},
|
|
{'id': 3, 'label': 'استودیو آینده'},
|
|
{'id': 5, 'label': 'رادارهای استراتژیک'},
|
|
{'id': 6, 'label': 'سها'},
|
|
{'id': 7, 'label': 'اینفوگرافی'},
|
|
];
|
|
|
|
await ActionSheetUtils(context).showBottomSheet(
|
|
data: ActionSheetData(
|
|
title: 'فیلتر جستجو',
|
|
titleIconWidget: SvgPicture.asset(
|
|
'lib/assets/icons/document-filter.svg',
|
|
width: 24,
|
|
height: 24,
|
|
),
|
|
dismissTitle: 'حذف فیلتر',
|
|
confrimTitle: 'نمایش نتایج',
|
|
onDismissed: () => state.resetFilters(false),
|
|
onConfirmed: () => state.loadInitialData(),
|
|
content: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
ItemTitle(
|
|
title: 'تاریخ',
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.bodyMedium
|
|
?.copyWith(fontWeight: FontWeight.bold),
|
|
iconWidget: 'lib/assets/icons/calendar.svg',
|
|
color: const Color.fromARGB(255, 27, 60, 89),
|
|
),
|
|
// const SizedBox(height: 8),
|
|
StatefulBuilder(
|
|
builder: (context, setState) => Row(
|
|
children: [
|
|
DatePickerButton(
|
|
initialValue:
|
|
state.startDate?.toIso8601String().split('T').first,
|
|
emptyText: 'از تاریخ',
|
|
onPicked: (date) => setState(() {
|
|
state.startDate =
|
|
date != null ? DateTime.parse(date) : null;
|
|
}),
|
|
lastDate: state.endDate?.toIso8601String().split('T').first,
|
|
),
|
|
const SizedBox(width: 8),
|
|
DatePickerButton(
|
|
initialValue:
|
|
state.endDate?.toIso8601String().split('T').first,
|
|
emptyText: 'تا تاریخ',
|
|
onPicked: (date) => setState(() {
|
|
state.endDate =
|
|
date != null ? DateTime.parse(date) : null;
|
|
}),
|
|
firstDate:
|
|
state.startDate?.toIso8601String().split('T').first,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// const SizedBox(height: 28),
|
|
ItemTitle(
|
|
title: 'دسته بندی',
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.bodyMedium
|
|
?.copyWith(fontWeight: FontWeight.bold),
|
|
iconWidget: 'lib/assets/icons/ion_extension-puzzle-outline.svg',
|
|
color: const Color.fromARGB(255, 27, 60, 89),
|
|
),
|
|
const SizedBox(height: 12),
|
|
Wrap(
|
|
children: [
|
|
for (var category in categories)
|
|
SizedBox(
|
|
width: (MediaQuery.of(context).size.width - 40) / 2,
|
|
child: DidvanCheckbox(
|
|
title: category['label'] as String,
|
|
value: state.selectedTypes.contains(category['id']),
|
|
onChanged: (value) {
|
|
if (value) {
|
|
state.selectedTypes.add(category['id'] as int);
|
|
} else {
|
|
state.selectedTypes.remove(category['id']);
|
|
}
|
|
},
|
|
color: const Color.fromARGB(255, 61, 61, 61),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final state = context.watch<BookmarksState>();
|
|
return DidvanScaffold(
|
|
appBarData: null,
|
|
showSliversFirst: true,
|
|
physics: const BouncingScrollPhysics(),
|
|
padding: const EdgeInsets.all(8.0),
|
|
hidePlayer: true,
|
|
slivers: [
|
|
SliverAppBar(
|
|
pinned: false,
|
|
expandedHeight: 140,
|
|
scrolledUnderElevation: 0,
|
|
surfaceTintColor: Colors.transparent,
|
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
|
automaticallyImplyLeading: false,
|
|
flexibleSpace: FlexibleSpaceBar(
|
|
background: Column(
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
SvgPicture.asset(
|
|
Assets.horizontalLogoWithText,
|
|
height: 60,
|
|
color: Theme.of(context).colorScheme.title,
|
|
),
|
|
Row(
|
|
children: [
|
|
GestureDetector(
|
|
onTap: () {
|
|
Navigator.pushNamed(context, Routes.profile);
|
|
},
|
|
child: SizedBox(
|
|
width: 44,
|
|
height: 44,
|
|
child: Center(
|
|
child: SvgPicture.asset(
|
|
'lib/assets/icons/New_Profile.svg',
|
|
width: 30,
|
|
height: 30,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
GestureDetector(
|
|
onTap: () => Navigator.pop(context),
|
|
child: SizedBox(
|
|
width: 44,
|
|
height: 44,
|
|
child: Center(
|
|
child: SvgPicture.asset(
|
|
'lib/assets/icons/arrow-left.svg',
|
|
width: 25,
|
|
height: 25,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
|
child: SearchField(
|
|
title: 'دیدوان',
|
|
focusNode: _focuseNode,
|
|
onChanged: _onSearchChanged,
|
|
onFilterButtonPressed: _showFilterBottomSheet,
|
|
isFiltered: state.isFiltered,
|
|
extraIconPath: 'lib/assets/icons/live ai.svg',
|
|
onExtraIconPressed: () {
|
|
showDialog(
|
|
context: context,
|
|
barrierDismissible: true,
|
|
builder: (context) => const AiChatDialog(),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
SliverPadding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
sliver: SliverToBoxAdapter(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
AnimatedVisibility(
|
|
duration: DesignConfig.lowAnimationDuration,
|
|
isVisible: !state.searching,
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.surface,
|
|
borderRadius: BorderRadius.circular(16),
|
|
border: Border.all(
|
|
color: Theme.of(context).colorScheme.focused,
|
|
width: 1,
|
|
),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withOpacity(0.03),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 4),
|
|
)
|
|
],
|
|
),
|
|
padding: const EdgeInsets.all(10.0),
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.focused,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: Center(
|
|
child: DidvanText(
|
|
'نشانشدهها',
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.titleMedium
|
|
?.copyWith(
|
|
color: DesignConfig.isDark
|
|
? Colors.white
|
|
: Colors.black,
|
|
fontWeight: FontWeight.normal,
|
|
fontSize: 15),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 15),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 100),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(5),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/Stratzhic Radar.svg",
|
|
width: 20,
|
|
),
|
|
titleWidget: DidvanText('رادارهای استراتژیک',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
),
|
|
),
|
|
const _FadeInSlide(
|
|
delay: Duration(milliseconds: 150),
|
|
child: DidvanDivider(),
|
|
),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 200),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(2),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/Donye_Foolad.svg",
|
|
width: 20,
|
|
),
|
|
titleWidget: DidvanText('دنیای فولاد',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
),
|
|
),
|
|
const _FadeInSlide(
|
|
delay: Duration(milliseconds: 250),
|
|
child: DidvanDivider(),
|
|
),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 300),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(1),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/Pouyesh_Ofogh_New.svg",
|
|
width: 20,
|
|
),
|
|
titleWidget: DidvanText('پویش افق',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
),
|
|
),
|
|
const _FadeInSlide(
|
|
delay: Duration(milliseconds: 350),
|
|
child: DidvanDivider(),
|
|
),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 400),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(3),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/video-play.svg",
|
|
color: const Color.fromARGB(255, 0, 126, 167),
|
|
width: 20,
|
|
),
|
|
titleWidget: DidvanText('ویدیوکست',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
),
|
|
),
|
|
const _FadeInSlide(
|
|
delay: Duration(milliseconds: 450),
|
|
child: DidvanDivider(),
|
|
),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 500),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(4),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/microphone-2.svg",
|
|
color: const Color.fromARGB(255, 0, 126, 167),
|
|
width: 20,
|
|
),
|
|
titleWidget: DidvanText('پادکست',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
),
|
|
),
|
|
const _FadeInSlide(
|
|
delay: Duration(milliseconds: 550),
|
|
child: DidvanDivider(),
|
|
),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 600),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(6),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/Saha.svg",
|
|
width: 20,
|
|
),
|
|
titleWidget: DidvanText('سها',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
),
|
|
),
|
|
const _FadeInSlide(
|
|
delay: Duration(milliseconds: 650),
|
|
child: DidvanDivider(),
|
|
),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 700),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(7),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/hugeicons_chart-02.svg",
|
|
color: const Color.fromARGB(255, 0, 126, 167),
|
|
width: 20,
|
|
),
|
|
titleWidget: DidvanText('اینفوگرافی',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
),
|
|
),
|
|
const _FadeInSlide(
|
|
delay: Duration(milliseconds: 750),
|
|
child: DidvanDivider(),
|
|
),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 800),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(8),
|
|
titleWidget: DidvanText('ماژول بایدها و نبایدها',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/Swot_New.svg",
|
|
width: 24),
|
|
iconSize: 24,
|
|
),
|
|
),
|
|
const _FadeInSlide(
|
|
delay: Duration(milliseconds: 850),
|
|
child: DidvanDivider(),
|
|
),
|
|
_FadeInSlide(
|
|
delay: const Duration(milliseconds: 900),
|
|
child: MenuOption(
|
|
onTap: () => _onCategorySelected(9),
|
|
titleWidget: DidvanText('ماهنامه تحلیلی',
|
|
style: TextStyle(
|
|
color:
|
|
Theme.of(context).colorScheme.caption)),
|
|
iconWidget: SvgPicture.asset(
|
|
"lib/assets/icons/Monthly.svg",
|
|
width: 24),
|
|
iconSize: 24,
|
|
),
|
|
),
|
|
const SizedBox(height: 7),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
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 _FadeInSlide(
|
|
delay: Duration(milliseconds: (index % 10) * 100),
|
|
child: Padding(
|
|
padding: const EdgeInsets.fromLTRB(0, 5, 0, 5),
|
|
child: Container(
|
|
clipBehavior: Clip.antiAlias,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(16),
|
|
border: Border.all(
|
|
color: const Color.fromRGBO(184, 184, 184, 1),
|
|
width: 1,
|
|
),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: MultitypeOverview(
|
|
item: state.bookmarks[index],
|
|
onMarkChanged: state.onMarkChanged,
|
|
hasUnmarkConfirmation: true,
|
|
enableCaption: true,
|
|
enableBookmark: true,
|
|
showDivider: false,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
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 _FadeInSlide(
|
|
delay: Duration(milliseconds: (index % 10) * 100),
|
|
child: Padding(
|
|
padding:
|
|
const EdgeInsets.only(bottom: 8, left: 16, right: 16),
|
|
child: Container(
|
|
clipBehavior: Clip.antiAlias,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(16),
|
|
border: Border.all(
|
|
color: const Color.fromRGBO(184, 184, 184, 1),
|
|
width: 1,
|
|
),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
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);
|
|
// });
|
|
// }
|
|
// }
|
|
|
|
class _FadeInSlide extends StatefulWidget {
|
|
final Widget child;
|
|
final Duration delay;
|
|
final Duration duration;
|
|
final double slideOffset;
|
|
|
|
const _FadeInSlide({
|
|
Key? key,
|
|
required this.child,
|
|
this.delay = Duration.zero,
|
|
// ignore: unused_element_parameter
|
|
this.duration = const Duration(milliseconds: 400),
|
|
this.slideOffset = 50.0,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
State<_FadeInSlide> createState() => _FadeInSlideState();
|
|
}
|
|
|
|
class _FadeInSlideState extends State<_FadeInSlide> {
|
|
bool _isVisible = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
Timer(widget.delay, () {
|
|
if (mounted) {
|
|
setState(() {
|
|
_isVisible = true;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AnimatedOpacity(
|
|
opacity: _isVisible ? 1.0 : 0.0,
|
|
duration: widget.duration,
|
|
curve: Curves.easeOut,
|
|
child: AnimatedContainer(
|
|
duration: widget.duration,
|
|
curve: Curves.easeOut,
|
|
transform: Matrix4.translationValues(
|
|
0, _isVisible ? 0 : widget.slideOffset, 0),
|
|
child: widget.child,
|
|
),
|
|
);
|
|
}
|
|
}
|