|
|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter/rendering.dart';
|
|
|
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
|
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
|
|
|
import 'package:immich_mobile/modules/home/ui/immich_sliver_appbar.dart';
|
|
|
|
|
@ -8,6 +9,7 @@ import 'package:immich_mobile/modules/home/models/get_all_asset_respose.model.da
|
|
|
|
|
import 'package:immich_mobile/modules/home/ui/image_grid.dart';
|
|
|
|
|
import 'package:immich_mobile/modules/home/providers/asset.provider.dart';
|
|
|
|
|
import 'package:immich_mobile/shared/providers/backup.provider.dart';
|
|
|
|
|
import 'package:visibility_detector/visibility_detector.dart';
|
|
|
|
|
import 'package:intl/intl.dart';
|
|
|
|
|
|
|
|
|
|
class HomePage extends HookConsumerWidget {
|
|
|
|
|
@ -18,10 +20,9 @@ class HomePage extends HookConsumerWidget {
|
|
|
|
|
final ValueNotifier<bool> _showBackToTopBtn = useState(false);
|
|
|
|
|
ScrollController _scrollController = useScrollController();
|
|
|
|
|
List<ImmichAssetGroupByDate> assetGroup = ref.watch(assetProvider);
|
|
|
|
|
BackUpState _backupState = ref.watch(backupProvider);
|
|
|
|
|
List<Widget> imageGridGroup = [];
|
|
|
|
|
List<GlobalKey> monthGroupKey = [];
|
|
|
|
|
|
|
|
|
|
final monthInView = useState<String>("");
|
|
|
|
|
_scrollControllerCallback() {
|
|
|
|
|
var endOfPage = _scrollController.position.maxScrollExtent;
|
|
|
|
|
|
|
|
|
|
@ -34,6 +35,13 @@ class HomePage extends HookConsumerWidget {
|
|
|
|
|
} else {
|
|
|
|
|
_showBackToTopBtn.value = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Quick Scroll For Jumping to Month
|
|
|
|
|
if (_scrollController.position.userScrollDirection == ScrollDirection.forward) {
|
|
|
|
|
// Scroll UP
|
|
|
|
|
} else if (_scrollController.position.userScrollDirection == ScrollDirection.reverse) {
|
|
|
|
|
// SCroll Down
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
useEffect(() {
|
|
|
|
|
@ -41,8 +49,63 @@ class HomePage extends HookConsumerWidget {
|
|
|
|
|
|
|
|
|
|
_scrollController.addListener(_scrollControllerCallback);
|
|
|
|
|
|
|
|
|
|
return () => _scrollController.removeListener(_scrollControllerCallback);
|
|
|
|
|
}, [_scrollController, key]);
|
|
|
|
|
return () {
|
|
|
|
|
debugPrint("Remove scroll listener");
|
|
|
|
|
_scrollController.removeListener(_scrollControllerCallback);
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
SliverToBoxAdapter _buildMonthGroupTitle(String dateTitle, BuildContext context) {
|
|
|
|
|
return SliverToBoxAdapter(
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.only(left: 10.0, top: 32),
|
|
|
|
|
child: Text(
|
|
|
|
|
DateFormat('MMMM, y').format(
|
|
|
|
|
DateTime.parse(dateTitle),
|
|
|
|
|
),
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
fontSize: 24,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Theme.of(context).primaryColor,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SliverToBoxAdapter _buildDateGroupTitle(String dateTitle) {
|
|
|
|
|
var currentYear = DateTime.now().year;
|
|
|
|
|
var groupYear = DateTime.parse(dateTitle).year;
|
|
|
|
|
var formatDateTemplate = currentYear == groupYear ? 'E, MMM dd' : 'E, MMM dd, yyyy';
|
|
|
|
|
var dateText = DateFormat(formatDateTemplate).format(DateTime.parse(dateTitle));
|
|
|
|
|
var monthText = DateFormat('MMMM, y').format(DateTime.parse(dateTitle));
|
|
|
|
|
return SliverToBoxAdapter(
|
|
|
|
|
child: VisibilityDetector(
|
|
|
|
|
key: Key(dateText),
|
|
|
|
|
onVisibilityChanged: (visibilityInfo) {
|
|
|
|
|
monthInView.value = monthText;
|
|
|
|
|
},
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.only(top: 24.0, bottom: 24.0, left: 3.0),
|
|
|
|
|
child: Row(
|
|
|
|
|
children: [
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.only(left: 8.0, bottom: 5.0, top: 5.0),
|
|
|
|
|
child: Text(
|
|
|
|
|
dateText,
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Colors.black87,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildBody() {
|
|
|
|
|
if (assetGroup.isNotEmpty) {
|
|
|
|
|
@ -56,28 +119,9 @@ class HomePage extends HookConsumerWidget {
|
|
|
|
|
int? previousMonth = DateTime.tryParse(lastGroupDate)?.month;
|
|
|
|
|
|
|
|
|
|
if ((currentMonth! - previousMonth!) != 0) {
|
|
|
|
|
var myKey = GlobalKey();
|
|
|
|
|
monthGroupKey.add(myKey);
|
|
|
|
|
// debugPrint("Group Key $myKey");
|
|
|
|
|
|
|
|
|
|
imageGridGroup.add(
|
|
|
|
|
SliverToBoxAdapter(
|
|
|
|
|
key: myKey,
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.only(left: 10.0, top: 32),
|
|
|
|
|
child: Text(
|
|
|
|
|
DateFormat('MMMM, y').format(
|
|
|
|
|
DateTime.parse(dateTitle),
|
|
|
|
|
),
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
fontSize: 24,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Theme.of(context).primaryColor,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
var monthTitleText = DateFormat('MMMM, y').format(DateTime.parse(dateTitle));
|
|
|
|
|
|
|
|
|
|
imageGridGroup.add(_buildMonthGroupTitle(monthTitleText, context));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
imageGridGroup.add(
|
|
|
|
|
@ -88,39 +132,36 @@ class HomePage extends HookConsumerWidget {
|
|
|
|
|
|
|
|
|
|
lastGroupDate = dateTitle;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SafeArea(
|
|
|
|
|
child: CustomScrollView(
|
|
|
|
|
return SafeArea(
|
|
|
|
|
child: Stack(children: [
|
|
|
|
|
RawScrollbar(
|
|
|
|
|
minThumbLength: 50,
|
|
|
|
|
isAlwaysShown: false,
|
|
|
|
|
interactive: true,
|
|
|
|
|
controller: _scrollController,
|
|
|
|
|
slivers: [
|
|
|
|
|
ImmichSliverAppBar(imageGridGroup: imageGridGroup),
|
|
|
|
|
...imageGridGroup,
|
|
|
|
|
],
|
|
|
|
|
thickness: 50,
|
|
|
|
|
crossAxisMargin: -20,
|
|
|
|
|
mainAxisMargin: 70,
|
|
|
|
|
timeToFade: const Duration(seconds: 2),
|
|
|
|
|
thumbColor: Colors.blueGrey,
|
|
|
|
|
radius: const Radius.circular(30),
|
|
|
|
|
child: CustomScrollView(
|
|
|
|
|
controller: _scrollController,
|
|
|
|
|
slivers: [
|
|
|
|
|
ImmichSliverAppBar(imageGridGroup: imageGridGroup),
|
|
|
|
|
...imageGridGroup,
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
]),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Scaffold(
|
|
|
|
|
drawer: const ProfileDrawer(),
|
|
|
|
|
body: _buildBody(),
|
|
|
|
|
bottomNavigationBar: BottomAppBar(
|
|
|
|
|
child: IconButton(
|
|
|
|
|
onPressed: () {
|
|
|
|
|
if (monthGroupKey.isNotEmpty) {
|
|
|
|
|
var targetContext = monthGroupKey.last.currentContext;
|
|
|
|
|
if (targetContext != null) {
|
|
|
|
|
Scrollable.ensureVisible(
|
|
|
|
|
targetContext,
|
|
|
|
|
duration: const Duration(milliseconds: 400),
|
|
|
|
|
curve: Curves.easeInOut,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
icon: const Icon(Icons.ac_unit_outlined),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
floatingActionButton: _showBackToTopBtn.value
|
|
|
|
|
? FloatingActionButton.small(
|
|
|
|
|
enableFeedback: true,
|
|
|
|
|
@ -134,30 +175,4 @@ class HomePage extends HookConsumerWidget {
|
|
|
|
|
: null,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SliverToBoxAdapter _buildDateGroupTitle(String dateTitle) {
|
|
|
|
|
var currentYear = DateTime.now().year;
|
|
|
|
|
var groupYear = DateTime.parse(dateTitle).year;
|
|
|
|
|
var formatDateTemplate = currentYear == groupYear ? 'E, MMM dd' : 'E, MMM dd, yyyy';
|
|
|
|
|
return SliverToBoxAdapter(
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.only(top: 24.0, bottom: 24.0, left: 3.0),
|
|
|
|
|
child: Row(
|
|
|
|
|
children: [
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.only(left: 8.0, bottom: 5.0, top: 5.0),
|
|
|
|
|
child: Text(
|
|
|
|
|
DateFormat(formatDateTemplate).format(DateTime.parse(dateTitle)),
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Colors.black87,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|