mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-01-03 18:20:53 -06:00
[client] streamline layouts
This commit is contained in:
@@ -3,41 +3,31 @@ import 'package:flutter_state_notifier/flutter_state_notifier.dart';
|
||||
import 'package:phylum/libphylum/phylum_account.dart';
|
||||
import 'package:phylum/ui/app/app_actions.dart';
|
||||
import 'package:phylum/ui/app/fab_action.dart';
|
||||
import 'package:phylum/ui/app/app_layout_manager.dart';
|
||||
import 'package:phylum/ui/app/nav_list.dart';
|
||||
import 'package:phylum/ui/explorer/explorer_view.dart';
|
||||
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
|
||||
import 'package:phylum/ui/explorer/path_view.dart';
|
||||
import 'package:phylum/ui/explorer/resource_info_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class AppLayout extends StatelessWidget {
|
||||
const AppLayout({super.key});
|
||||
class AppLayout {
|
||||
const AppLayout();
|
||||
|
||||
static Widget create(String folderId) {
|
||||
return MultiProvider(
|
||||
providers: [
|
||||
StateNotifierProvider<AppLayoutManager, AppLayoutState>(create: (context) => AppLayoutManager()),
|
||||
StateNotifierProvider<ExplorerViewController, ExplorerViewState>(
|
||||
create: (context) => ExplorerViewController(account: context.read<PhylumAccount>(), folderId: folderId),
|
||||
),
|
||||
],
|
||||
builder: (context, child) {
|
||||
final manager = context.read<AppLayoutManager>();
|
||||
final platform = Theme.of(context).platform;
|
||||
// final platform = Theme.of(context).platform;
|
||||
final size = MediaQuery.sizeOf(context);
|
||||
Future.microtask(() => manager.update(platform, size));
|
||||
return child!;
|
||||
},
|
||||
child: AppActions(child: AppLayout()),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Builder(builder: (context) {
|
||||
final layout = context.watch<AppLayoutState>();
|
||||
return layout.type.isExpanded ? ExpandedAppLayout() : CollapsedAppLayout();
|
||||
});
|
||||
final layout = size.width <= 600 ? CollapsedAppLayout() : ExpandedAppLayout(large: size.width > 1200);
|
||||
return AppActions(child: layout);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,12 +72,13 @@ class CollapsedAppLayout extends StatelessWidget {
|
||||
}
|
||||
|
||||
class ExpandedAppLayout extends StatelessWidget {
|
||||
const ExpandedAppLayout({super.key});
|
||||
final bool large;
|
||||
const ExpandedAppLayout({super.key, required this.large});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final layout = context.watch<AppLayoutState>();
|
||||
final sidebarWidth = layout.type == LayoutType.expandedLarge ? 300.0 : 240.0;
|
||||
final sidebarWidth = large ? 288.0 : 216.0;
|
||||
final infoWidth = large ? 360.0 : 264.0;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
@@ -100,13 +91,29 @@ class ExpandedAppLayout extends StatelessWidget {
|
||||
),
|
||||
body: Row(
|
||||
children: [
|
||||
SizedBox(width: sidebarWidth, child: NavList(showFab: true)),
|
||||
SizedBox(
|
||||
width: sidebarWidth,
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
margin: const EdgeInsets.only(left: 16, bottom: 16),
|
||||
child: NavList(showFab: true),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
||||
child: const ExplorerView(),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: infoWidth,
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
margin: const EdgeInsets.only(right: 16, bottom: 16),
|
||||
child: ResourceInfoView(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:state_notifier/state_notifier.dart';
|
||||
|
||||
enum LayoutType {
|
||||
collapsed,
|
||||
expandedSmall,
|
||||
expandedLarge;
|
||||
|
||||
bool get isExpanded => this == LayoutType.expandedSmall || this == LayoutType.expandedLarge;
|
||||
}
|
||||
|
||||
class AppLayoutState {
|
||||
final LayoutType type;
|
||||
final bool touchUi;
|
||||
|
||||
AppLayoutState({required this.type, required this.touchUi});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is AppLayoutState && other.type == type && other.touchUi == touchUi;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => type.hashCode ^ touchUi.hashCode;
|
||||
}
|
||||
|
||||
class AppLayoutManager extends StateNotifier<AppLayoutState> {
|
||||
AppLayoutManager() : super(AppLayoutState(type: LayoutType.collapsed, touchUi: true));
|
||||
|
||||
void update(TargetPlatform platform, Size size) {
|
||||
final type = size.width < 600
|
||||
? LayoutType.collapsed
|
||||
: size.width <= 1200
|
||||
? LayoutType.expandedSmall
|
||||
: LayoutType.expandedLarge;
|
||||
final touchUi = platform == TargetPlatform.android || platform == TargetPlatform.iOS;
|
||||
state = AppLayoutState(type: type, touchUi: touchUi);
|
||||
}
|
||||
}
|
||||
@@ -11,46 +11,39 @@ class NavList extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ExcludeFocusTraversal(
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
margin: const EdgeInsets.only(left: 16, bottom: 16),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: ListView(
|
||||
children: [
|
||||
if (showFab)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 16),
|
||||
child: PopupMenuButton(
|
||||
tooltip: 'Create',
|
||||
position: PopupMenuPosition.under,
|
||||
itemBuilder: (context) => [
|
||||
for (final action in popupMenuActions)
|
||||
if (action == null)
|
||||
const PopupMenuItem(enabled: false, height: 16, child: Divider())
|
||||
else
|
||||
PopupMenuItem(child: Text(action.descripiton), onTap: () => Actions.maybeInvoke(context, action.intent)),
|
||||
],
|
||||
child: FloatingActionButton.extended(
|
||||
icon: const Icon(Icons.add), label: const Text('New'), elevation: 0, enableFeedback: false, onPressed: null),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.home),
|
||||
title: const Text('Home'),
|
||||
onTap: () => Actions.maybeInvoke(context, const NavHomeIntent()),
|
||||
child: ListView(
|
||||
children: [
|
||||
if (showFab)
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: PopupMenuButton(
|
||||
tooltip: 'Create',
|
||||
position: PopupMenuPosition.under,
|
||||
itemBuilder: (context) => [
|
||||
for (final action in popupMenuActions)
|
||||
if (action == null)
|
||||
const PopupMenuItem(enabled: false, height: 16, child: Divider())
|
||||
else
|
||||
PopupMenuItem(child: Text(action.descripiton), onTap: () => Actions.maybeInvoke(context, action.intent)),
|
||||
],
|
||||
child: FloatingActionButton.extended(
|
||||
icon: const Icon(Icons.add), label: const Text('New'), elevation: 0, enableFeedback: false, onPressed: null),
|
||||
),
|
||||
const Divider(),
|
||||
const DownloadButton(),
|
||||
const ServerStatusButton(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.settings),
|
||||
title: const Text('Settings'),
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.home),
|
||||
title: const Text('Home'),
|
||||
onTap: () => Actions.maybeInvoke(context, const NavHomeIntent()),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
const DownloadButton(),
|
||||
const ServerStatusButton(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.settings),
|
||||
title: const Text('Settings'),
|
||||
onTap: () {},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:phylum/app_shortcuts.dart';
|
||||
import 'package:phylum/ui/app/app_layout_manager.dart';
|
||||
import 'package:phylum/ui/explorer/paste_action_handler.dart';
|
||||
import 'package:phylum/ui/explorer/resource_info_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'explorer_view_controller.dart';
|
||||
@@ -14,28 +12,13 @@ class ExplorerView extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final layout = context.watch<AppLayoutState>();
|
||||
return Actions(
|
||||
actions: {
|
||||
NextFocusIntent: CallbackAction<NextFocusIntent>(onInvoke: (i) => null),
|
||||
PreviousFocusIntent: CallbackAction<PreviousFocusIntent>(onInvoke: (i) => null),
|
||||
PasteFromClipboardIntent: CallbackAction<PasteFromClipboardIntent>(onInvoke: (PasteFromClipboardIntent i) => handlePasteAction(i, context)),
|
||||
},
|
||||
child: layout.type.isExpanded
|
||||
? Row(
|
||||
children: [
|
||||
Expanded(child: Card(elevation: 0, child: buildPage(context))),
|
||||
SizedBox(
|
||||
width: layout.type == LayoutType.expandedLarge ? 360 : 300,
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
margin: EdgeInsets.only(left: 16),
|
||||
child: ResourceInfoView(),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
: buildPage(context),
|
||||
child: buildPage(context),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user