[client] FolderNavigator

This commit is contained in:
Abhishek Shroff
2024-08-12 13:20:51 +05:30
parent c394f03963
commit 9fad2b9de8
3 changed files with 84 additions and 57 deletions

View File

@@ -2,25 +2,17 @@ import 'package:flutter/material.dart';
import 'package:flutter_state_notifier/flutter_state_notifier.dart';
import 'package:go_router/go_router.dart';
import 'package:offtheline/offtheline.dart';
import 'package:phylum/folder_view.dart';
import 'package:phylum/home_page.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:provider/provider.dart';
final _router = GoRouter(
routes: [
ShellRoute(
builder: (context, state, child) => NavScaffold(child: child),
routes: [
GoRoute(name: 'home', path: '/', builder: (context, state) => const HomePage()),
GoRoute(
name: 'dir',
path: '/dir/:id',
builder: (context, state) {
return FolderView(id: state.pathParameters['id']!);
}),
],
)
GoRoute(
name: 'home',
path: '/',
builder: (context, state) => const HomePage(),
),
],
);
@@ -57,20 +49,3 @@ class _AppContent extends StatelessWidget {
);
}
}
class NavScaffold extends StatelessWidget {
final Widget child;
const NavScaffold({super.key, required this.child});
@override
Widget build(BuildContext context) {
final router = GoRouter.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('Phylum'),
leading: router.canPop() ? BackButton(onPressed: router.pop) : null,
),
body: child,
);
}
}

View File

@@ -1,20 +1,78 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter_state_notifier/flutter_state_notifier.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/libphylum/requests/resource_detail_request.dart';
import 'package:provider/provider.dart';
class FolderView extends StatefulWidget {
final String id;
class FolderNavigatorState {
final String root;
final List<String> _stack;
const FolderView({super.key, required this.id});
bool get isRoot => _stack.isEmpty;
@override
State<FolderView> createState() => _FolderViewState();
String get folderId => isRoot ? root : _stack.last;
const FolderNavigatorState({required this.root, required List<String> stack}) : _stack = stack;
}
class _FolderViewState extends State<FolderView> {
class FolderNavigator extends StateNotifier<FolderNavigatorState> {
final String root;
FolderNavigator(this.root) : super(FolderNavigatorState(root: root, stack: const []));
bool pop() {
if (state.isRoot) return false;
state = FolderNavigatorState(root: state.root, stack: state._stack.sublist(0, state._stack.length - 1).toList(growable: false));
return true;
}
void push(String id) {
state = FolderNavigatorState(root: state.root, stack: [...state._stack, id]);
}
}
class FolderNavigatorView extends StatelessWidget {
final String root;
const FolderNavigatorView({super.key, required this.root});
@override
Widget build(BuildContext context) {
return StateNotifierProvider<FolderNavigator, FolderNavigatorState>(
create: (context) => FolderNavigator(root),
builder: (context, child) => const FolderScaffold(),
);
}
}
class FolderScaffold extends StatelessWidget {
const FolderScaffold({super.key});
@override
Widget build(BuildContext context) {
final nav = context.watch<FolderNavigatorState>();
final folderId = nav.folderId;
return Scaffold(
appBar: AppBar(
title: const Text('Phylum'),
leading: nav.isRoot ? null : BackButton(onPressed: context.read<FolderNavigator>().pop),
),
body: FolderContentsView(key: ValueKey(folderId), id: folderId),
);
}
}
class FolderContentsView extends StatefulWidget {
final String id;
const FolderContentsView({super.key, required this.id});
@override
State<FolderContentsView> createState() => _FolderContentsViewState();
}
class _FolderContentsViewState extends State<FolderContentsView> {
@override
void initState() {
super.initState();
@@ -34,20 +92,18 @@ class _FolderViewState extends State<FolderView> {
child: Center(
child: StreamBuilder(
stream: account.datastore.db.managers.resources.filter((f) => f.parent.id.equals(widget.id)).watch(),
builder: (context, snapshot) {
return Column(
children: [
if (snapshot.hasData)
for (final r in snapshot.data!)
ListTile(
leading: r.getIcon(),
title: Text(r.name),
trailing: r.dir ? null : Text(r.getSizeString()),
onTap: () => context.go('/dir/${r.id}'),
),
],
);
}),
builder: (context, snapshot) => ListView(
children: [
if (snapshot.hasData)
for (final r in snapshot.data!)
ListTile(
leading: r.getIcon(),
title: Text(r.name),
trailing: r.dir ? null : Text(r.getSizeString()),
onTap: () => context.read<FolderNavigator>().push('/dir/${r.id}'),
),
],
)),
),
);
}

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:phylum/folder_view.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:provider/provider.dart';
@@ -14,14 +14,10 @@ class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
final account = context.read<PhylumAccount>();
WidgetsBinding.instance.addPostFrameCallback((t) {
context.replace('/dir/${account.userHome}');
});
}
@override
Widget build(BuildContext context) {
return Container();
return FolderNavigatorView(root: context.read<PhylumAccount>().userHome);
}
}