2023-05-10 18:42:56 +02:00
|
|
|
import 'dart:async';
|
|
|
|
|
2023-01-09 17:58:28 +01:00
|
|
|
import 'package:event_bus/event_bus.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
import 'package:flutter/material.dart';
|
2023-05-10 18:42:56 +02:00
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
2021-12-07 19:42:25 +01:00
|
|
|
import 'package:kiwi/kiwi.dart';
|
2021-08-08 14:09:21 +02:00
|
|
|
import 'package:logging/logging.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
import 'package:nc_photos/account.dart';
|
2021-07-25 07:00:38 +02:00
|
|
|
import 'package:nc_photos/app_localizations.dart';
|
2023-05-10 18:42:56 +02:00
|
|
|
import 'package:nc_photos/controller/account_controller.dart';
|
2024-02-25 05:09:57 +01:00
|
|
|
import 'package:nc_photos/controller/account_pref_controller.dart';
|
2021-12-07 19:42:25 +01:00
|
|
|
import 'package:nc_photos/di_container.dart';
|
2021-08-08 14:09:21 +02:00
|
|
|
import 'package:nc_photos/entity/album.dart';
|
2022-07-05 22:20:24 +02:00
|
|
|
import 'package:nc_photos/entity/album/data_source.dart';
|
2021-08-08 14:09:21 +02:00
|
|
|
import 'package:nc_photos/entity/file.dart';
|
|
|
|
import 'package:nc_photos/entity/file/data_source.dart';
|
2023-07-17 09:35:45 +02:00
|
|
|
import 'package:nc_photos/entity/pref.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
import 'package:nc_photos/k.dart' as k;
|
|
|
|
import 'package:nc_photos/theme.dart';
|
2023-08-12 17:24:29 +02:00
|
|
|
import 'package:nc_photos/theme/dimension.dart';
|
2021-08-08 14:09:21 +02:00
|
|
|
import 'package:nc_photos/use_case/import_potential_shared_album.dart';
|
2023-04-13 17:32:31 +02:00
|
|
|
import 'package:nc_photos/widget/home_collections.dart';
|
2024-01-12 19:53:14 +01:00
|
|
|
import 'package:nc_photos/widget/home_photos2.dart';
|
2022-08-06 06:21:11 +02:00
|
|
|
import 'package:nc_photos/widget/home_search.dart';
|
2024-07-20 10:17:09 +02:00
|
|
|
import 'package:nc_photos/widget/map_browser.dart';
|
2022-12-16 16:01:04 +01:00
|
|
|
import 'package:np_codegen/np_codegen.dart';
|
2023-08-24 17:31:52 +02:00
|
|
|
import 'package:np_common/or_null.dart';
|
2022-12-16 16:01:04 +01:00
|
|
|
|
|
|
|
part 'home.g.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
|
|
|
|
class HomeArguments {
|
|
|
|
HomeArguments(this.account);
|
|
|
|
|
|
|
|
final Account account;
|
|
|
|
}
|
|
|
|
|
|
|
|
class Home extends StatefulWidget {
|
|
|
|
static const routeName = "/home";
|
|
|
|
|
2021-07-23 22:05:57 +02:00
|
|
|
static Route buildRoute(HomeArguments args) => MaterialPageRoute(
|
|
|
|
builder: (context) => Home.fromArgs(args),
|
|
|
|
);
|
|
|
|
|
2021-09-15 08:58:06 +02:00
|
|
|
const Home({
|
2024-05-28 17:10:33 +02:00
|
|
|
super.key,
|
2021-07-23 22:05:57 +02:00
|
|
|
required this.account,
|
2024-05-28 17:10:33 +02:00
|
|
|
});
|
2021-04-10 06:28:12 +02:00
|
|
|
|
2021-07-23 22:05:57 +02:00
|
|
|
Home.fromArgs(HomeArguments args, {Key? key})
|
2021-04-10 06:28:12 +02:00
|
|
|
: this(
|
2021-09-15 08:58:06 +02:00
|
|
|
key: key,
|
2021-04-10 06:28:12 +02:00
|
|
|
account: args.account,
|
|
|
|
);
|
|
|
|
|
|
|
|
@override
|
|
|
|
createState() => _HomeState();
|
|
|
|
|
|
|
|
final Account account;
|
|
|
|
}
|
|
|
|
|
2022-12-16 16:01:04 +01:00
|
|
|
@npLog
|
2022-01-01 22:01:23 +01:00
|
|
|
class _HomeState extends State<Home> with TickerProviderStateMixin {
|
2021-08-08 14:09:21 +02:00
|
|
|
@override
|
|
|
|
initState() {
|
|
|
|
super.initState();
|
2023-05-17 19:42:08 +02:00
|
|
|
_importPotentialSharedAlbum().then((value) {
|
|
|
|
if (value.isNotEmpty) {
|
|
|
|
AccountPref.of(widget.account).setNewSharedAlbum(true);
|
|
|
|
}
|
|
|
|
});
|
2022-01-01 22:01:23 +01:00
|
|
|
_animationController.value = 1;
|
2023-05-10 18:42:56 +02:00
|
|
|
|
|
|
|
// call once to pre-cache the value
|
|
|
|
unawaited(context
|
|
|
|
.read<AccountController>()
|
|
|
|
.serverController
|
|
|
|
.status
|
|
|
|
.first
|
|
|
|
.then((value) {
|
|
|
|
_log.info("Server status: $value");
|
|
|
|
}));
|
2022-01-01 22:01:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
dispose() {
|
|
|
|
_animationController.dispose();
|
|
|
|
super.dispose();
|
2021-08-08 14:09:21 +02:00
|
|
|
}
|
|
|
|
|
2021-04-10 06:28:12 +02:00
|
|
|
@override
|
2024-07-20 10:17:09 +02:00
|
|
|
Widget build(BuildContext context) {
|
2022-11-12 10:55:33 +01:00
|
|
|
return Scaffold(
|
|
|
|
bottomNavigationBar: _buildBottomNavigationBar(context),
|
|
|
|
body: Builder(builder: (context) => _buildContent(context)),
|
|
|
|
extendBody: true,
|
|
|
|
resizeToAvoidBottomInset: false,
|
2021-04-10 06:28:12 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildBottomNavigationBar(BuildContext context) {
|
2022-11-12 10:55:33 +01:00
|
|
|
return NavigationBar(
|
2023-08-12 17:24:29 +02:00
|
|
|
height: AppDimension.of(context).homeBottomAppBarHeight,
|
2022-11-12 10:55:33 +01:00
|
|
|
destinations: [
|
|
|
|
NavigationDestination(
|
2021-04-10 06:28:12 +02:00
|
|
|
icon: const Icon(Icons.photo_outlined),
|
2022-11-12 10:55:33 +01:00
|
|
|
selectedIcon: const Icon(Icons.photo),
|
2021-08-29 13:51:43 +02:00
|
|
|
label: L10n.global().photosTabLabel,
|
2021-04-10 06:28:12 +02:00
|
|
|
),
|
2022-11-12 10:55:33 +01:00
|
|
|
NavigationDestination(
|
2022-08-06 06:21:11 +02:00
|
|
|
icon: const Icon(Icons.search),
|
|
|
|
label: L10n.global().searchTooltip,
|
|
|
|
),
|
2022-11-12 10:55:33 +01:00
|
|
|
NavigationDestination(
|
2021-08-29 16:16:42 +02:00
|
|
|
icon: const Icon(Icons.grid_view_outlined),
|
2022-11-12 10:55:33 +01:00
|
|
|
selectedIcon: const Icon(Icons.grid_view_sharp),
|
2021-08-29 16:16:42 +02:00
|
|
|
label: L10n.global().collectionsTooltip,
|
2021-04-10 06:28:12 +02:00
|
|
|
),
|
2024-07-20 10:17:09 +02:00
|
|
|
NavigationDestination(
|
|
|
|
icon: const Icon(Icons.map_outlined),
|
|
|
|
selectedIcon: const Icon(Icons.map),
|
|
|
|
label: L10n.global().homeTabMapBrowser,
|
|
|
|
),
|
2021-04-10 06:28:12 +02:00
|
|
|
],
|
2022-11-12 10:55:33 +01:00
|
|
|
selectedIndex: _nextPage,
|
|
|
|
onDestinationSelected: _onTapNavItem,
|
|
|
|
backgroundColor: Theme.of(context).homeNavigationBarBackgroundColor,
|
2021-04-10 06:28:12 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildContent(BuildContext context) {
|
|
|
|
return PageView.builder(
|
|
|
|
controller: _pageController,
|
|
|
|
physics: const NeverScrollableScrollPhysics(),
|
2024-07-20 10:17:09 +02:00
|
|
|
itemCount: 4,
|
2022-01-01 22:01:23 +01:00
|
|
|
itemBuilder: (context, index) => SlideTransition(
|
|
|
|
position: Tween(
|
|
|
|
begin: const Offset(0, .05),
|
|
|
|
end: Offset.zero,
|
|
|
|
).animate(_animation),
|
|
|
|
child: FadeTransition(
|
|
|
|
opacity: _animation,
|
|
|
|
child: _buildPage(context, index),
|
|
|
|
),
|
|
|
|
),
|
2021-04-10 06:28:12 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildPage(BuildContext context, int index) {
|
|
|
|
switch (index) {
|
|
|
|
case 0:
|
2024-01-12 19:53:14 +01:00
|
|
|
return const HomePhotos2();
|
2021-04-10 06:28:12 +02:00
|
|
|
|
|
|
|
case 1:
|
2023-01-09 17:58:28 +01:00
|
|
|
return HomeSearch(
|
|
|
|
account: widget.account,
|
|
|
|
);
|
2022-08-06 06:21:11 +02:00
|
|
|
|
|
|
|
case 2:
|
2023-04-13 17:32:31 +02:00
|
|
|
return const HomeCollections();
|
2021-04-10 06:28:12 +02:00
|
|
|
|
2024-07-20 10:17:09 +02:00
|
|
|
case 3:
|
|
|
|
return const MapBrowser();
|
|
|
|
|
2021-04-10 06:28:12 +02:00
|
|
|
default:
|
|
|
|
throw ArgumentError("Invalid page index: $index");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void _onTapNavItem(int index) {
|
2023-01-09 17:30:39 +01:00
|
|
|
if (index == _nextPage) {
|
2023-01-09 17:58:28 +01:00
|
|
|
if (index == 0) {
|
|
|
|
KiwiContainer()
|
|
|
|
.resolve<EventBus>()
|
2024-01-13 17:33:12 +01:00
|
|
|
.fire(const HomePhotos2BackToTopEvent());
|
2023-01-09 17:58:28 +01:00
|
|
|
}
|
2023-01-09 17:30:39 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-01 22:01:23 +01:00
|
|
|
_pageController.jumpToPage(index);
|
2021-04-10 06:28:12 +02:00
|
|
|
setState(() {
|
|
|
|
_nextPage = index;
|
|
|
|
});
|
2022-01-01 22:01:23 +01:00
|
|
|
_animationController
|
|
|
|
..reset()
|
|
|
|
..forward();
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|
|
|
|
|
2021-08-08 14:09:21 +02:00
|
|
|
Future<List<Album>> _importPotentialSharedAlbum() async {
|
2021-12-07 19:42:25 +01:00
|
|
|
final c = KiwiContainer().resolve<DiContainer>().copyWith(
|
|
|
|
// don't want the potential albums to be cached at this moment
|
2023-08-24 17:31:52 +02:00
|
|
|
fileRepo: const OrNull(FileRepo(FileWebdavDataSource())),
|
2021-12-07 19:42:25 +01:00
|
|
|
albumRepo: OrNull(AlbumRepo(AlbumRemoteDataSource())),
|
|
|
|
);
|
2021-08-08 14:09:21 +02:00
|
|
|
try {
|
2021-12-07 19:42:25 +01:00
|
|
|
return await ImportPotentialSharedAlbum(c)(
|
2023-12-13 17:49:12 +01:00
|
|
|
widget.account,
|
|
|
|
context
|
|
|
|
.read<AccountController>()
|
|
|
|
.accountPrefController
|
2024-02-25 05:09:57 +01:00
|
|
|
.shareFolderValue,
|
2023-12-13 17:49:12 +01:00
|
|
|
);
|
2021-08-08 14:09:21 +02:00
|
|
|
} catch (e, stacktrace) {
|
|
|
|
_log.shout(
|
|
|
|
"[_importPotentialSharedAlbum] Failed while ImportPotentialSharedAlbum",
|
|
|
|
e,
|
|
|
|
stacktrace);
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-23 22:05:57 +02:00
|
|
|
final _pageController = PageController(initialPage: 0, keepPage: false);
|
2021-04-10 06:28:12 +02:00
|
|
|
int _nextPage = 0;
|
2021-08-08 14:09:21 +02:00
|
|
|
|
2022-01-01 22:01:23 +01:00
|
|
|
late final _animationController = AnimationController(
|
2022-01-24 11:05:35 +01:00
|
|
|
duration: k.animationDurationTabTransition,
|
2022-01-01 22:01:23 +01:00
|
|
|
vsync: this,
|
|
|
|
);
|
|
|
|
late final _animation = CurvedAnimation(
|
|
|
|
parent: _animationController,
|
|
|
|
curve: Curves.easeIn,
|
|
|
|
);
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|