From 5ff5d89ed4900873fcf3b91069329ca079f74a13 Mon Sep 17 00:00:00 2001 From: CodeDoctorDE Date: Sun, 19 May 2024 15:56:08 +0200 Subject: [PATCH] Improve responsiveness --- app/lib/dialogs/background/dialog.dart | 135 ++++---- app/lib/dialogs/export/general.dart | 5 +- app/lib/dialogs/import/add.dart | 402 ++++++++++++------------ app/lib/dialogs/packs/pack.dart | 91 +++--- app/lib/dialogs/packs/styles/style.dart | 74 ++--- app/lib/dialogs/search.dart | 3 +- app/lib/dialogs/template.dart | 149 +++++---- app/lib/main.dart | 3 - app/lib/views/app_bar.dart | 10 +- app/lib/views/files/list.dart | 5 +- app/lib/views/home.dart | 2 +- app/lib/views/main.dart | 8 +- app/lib/widgets/responsive_dialog.dart | 23 -- app/pubspec.lock | 12 +- app/pubspec.yaml | 2 +- metadata/en-US/changelogs/106.txt | 1 + 16 files changed, 440 insertions(+), 485 deletions(-) delete mode 100644 app/lib/widgets/responsive_dialog.dart diff --git a/app/lib/dialogs/background/dialog.dart b/app/lib/dialogs/background/dialog.dart index 4e9b510b4b48..2488b6a53982 100644 --- a/app/lib/dialogs/background/dialog.dart +++ b/app/lib/dialogs/background/dialog.dart @@ -30,77 +30,70 @@ class BackgroundDialog extends StatelessWidget { if (state is! DocumentLoadSuccess) return Container(); var background = state.page.backgrounds.firstOrNull; - return AlertDialog( - content: SizedBox( - width: 600, - height: 600, - child: DefaultTabController( - length: 2, - child: Column( - children: [ - Header( - title: Text(AppLocalizations.of(context).background), - leading: const PhosphorIcon(PhosphorIconsLight.image), - actions: [ - IconButton( - tooltip: AppLocalizations.of(context).help, - icon: const PhosphorIcon( - PhosphorIconsLight.sealQuestion), - onPressed: () => openHelp(['background']), - ), - ], - ), - TabBar( - tabAlignment: TabAlignment.fill, - tabs: [ - ( - PhosphorIconsLight.globe, - AppLocalizations.of(context).general, - ), - ( - PhosphorIconsLight.gear, - AppLocalizations.of(context).properties, - ), - ] - .map((e) => HorizontalTab( - icon: PhosphorIcon(e.$1), - label: Text(e.$2), - )) - .toList(), - ), - const SizedBox(height: 8), - Expanded( - child: StatefulBuilder(builder: (context, setState) { - return TabBarView( - children: [ - _GeneralBackgroundPropertiesView( - value: background, - onChanged: (value) => - setState(() => background = value)), - if (background != null) ...[ - background!.map( - texture: (e) => - _TextureBackgroundPropertiesView( - value: e, - onChanged: (value) => - setState(() => background = value)), - image: (e) => _ImageBackgroundPropertiesView( - value: e, - onChanged: (value) => - setState(() => background = value)), - svg: (e) => _SvgBackgroundPropertiesView( - value: e, - onChanged: (value) => - setState(() => background = value)), - ), - ] else - const SizedBox(), - ], - ); - }), - ), - ], - ), + return ResponsiveAlertDialog( + constraints: const BoxConstraints(maxWidth: 600, maxHeight: 800), + title: Text(AppLocalizations.of(context).background), + leading: const PhosphorIcon(PhosphorIconsLight.image), + headerActions: [ + IconButton( + tooltip: AppLocalizations.of(context).help, + icon: const PhosphorIcon(PhosphorIconsLight.sealQuestion), + onPressed: () => openHelp(['background']), + ), + ], + content: DefaultTabController( + length: 2, + child: Column( + children: [ + TabBar( + tabAlignment: TabAlignment.fill, + tabs: [ + ( + PhosphorIconsLight.globe, + AppLocalizations.of(context).general, + ), + ( + PhosphorIconsLight.gear, + AppLocalizations.of(context).properties, + ), + ] + .map((e) => HorizontalTab( + icon: PhosphorIcon(e.$1), + label: Text(e.$2), + )) + .toList(), + ), + const SizedBox(height: 8), + Expanded( + child: StatefulBuilder(builder: (context, setState) { + return TabBarView( + children: [ + _GeneralBackgroundPropertiesView( + value: background, + onChanged: (value) => + setState(() => background = value)), + if (background != null) ...[ + background!.map( + texture: (e) => _TextureBackgroundPropertiesView( + value: e, + onChanged: (value) => + setState(() => background = value)), + image: (e) => _ImageBackgroundPropertiesView( + value: e, + onChanged: (value) => + setState(() => background = value)), + svg: (e) => _SvgBackgroundPropertiesView( + value: e, + onChanged: (value) => + setState(() => background = value)), + ), + ] else + const SizedBox(), + ], + ); + }), + ), + ], ), ), actions: [ diff --git a/app/lib/dialogs/export/general.dart b/app/lib/dialogs/export/general.dart index 9b5d914d6e8c..10cc31f3c4e2 100644 --- a/app/lib/dialogs/export/general.dart +++ b/app/lib/dialogs/export/general.dart @@ -139,7 +139,7 @@ class _GeneralExportDialogState extends State { Widget build(BuildContext context) { return Builder(builder: (context) { return Dialog( - child: Container( + child: ConstrainedBox( constraints: const BoxConstraints(maxHeight: 600, maxWidth: 1000), child: Column( children: [ @@ -166,7 +166,8 @@ class _GeneralExportDialogState extends State { children: [ Expanded( child: LayoutBuilder(builder: (context, constraints) { - var isMobile = constraints.maxWidth < 600; + var isMobile = + constraints.maxWidth < LeapBreakpoints.compact; if (isMobile) { return ListView( children: [ diff --git a/app/lib/dialogs/import/add.dart b/app/lib/dialogs/import/add.dart index 75734a5795d9..f2bf7be20a8f 100644 --- a/app/lib/dialogs/import/add.dart +++ b/app/lib/dialogs/import/add.dart @@ -1,12 +1,10 @@ import 'package:butterfly/cubits/current_index.dart'; import 'package:butterfly/handlers/handler.dart'; import 'package:butterfly/helpers/color.dart'; -import 'package:butterfly/main.dart'; import 'package:butterfly/services/import.dart'; import 'package:butterfly/visualizer/element.dart'; import 'package:butterfly/visualizer/tool.dart'; import 'package:butterfly/visualizer/property.dart'; -import 'package:butterfly/widgets/responsive_dialog.dart'; import 'package:butterfly_api/butterfly_api.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -75,214 +73,210 @@ class AddDialog extends StatelessWidget { return LayoutBuilder( builder: (context, constraints) => ResponsiveDialog( - child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 950, - maxHeight: 800, - ), - child: Column(children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton.outlined( - onPressed: () => Navigator.of(context).pop(), - icon: const PhosphorIcon(PhosphorIconsLight.x), - tooltip: AppLocalizations.of(context).close, - ), - const SizedBox(width: 16), - Text( - AppLocalizations.of(context).add, - style: Theme.of(context).textTheme.headlineSmall, - ), - const SizedBox(width: 8), - Expanded( - child: Align( - child: SearchBar( - constraints: - const BoxConstraints(maxWidth: 200, minHeight: 50), - leading: const PhosphorIcon( - PhosphorIconsLight.magnifyingGlass), - hintText: AppLocalizations.of(context).search, - controller: _searchController, - ), - )), - const SizedBox(width: 8), - IconButton( - onPressed: () => openHelp(['add']), - icon: const PhosphorIcon(PhosphorIconsLight.sealQuestion), - tooltip: AppLocalizations.of(context).help, + constraints: const BoxConstraints( + maxWidth: 950, + maxHeight: 800, + ), + child: Column(children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + IconButton.outlined( + onPressed: () => Navigator.of(context).pop(), + icon: const PhosphorIcon(PhosphorIconsLight.x), + tooltip: AppLocalizations.of(context).close, + ), + const SizedBox(width: 16), + Text( + AppLocalizations.of(context).add, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(width: 8), + Expanded( + child: Align( + child: SearchBar( + constraints: + const BoxConstraints(maxWidth: 200, minHeight: 50), + leading: + const PhosphorIcon(PhosphorIconsLight.magnifyingGlass), + hintText: AppLocalizations.of(context).search, + controller: _searchController, ), - ], - ), + )), + const SizedBox(width: 8), + IconButton( + onPressed: () => openHelp(['add']), + icon: const PhosphorIcon(PhosphorIconsLight.sealQuestion), + tooltip: AppLocalizations.of(context).help, + ), + ], ), - const SizedBox(height: 8), - Expanded( - child: Material( - type: MaterialType.transparency, - child: ValueListenableBuilder( - valueListenable: _searchController, - builder: (context, value, _) => FutureBuilder< - List>( - future: Future.wait(ImportType.values - .map((e) async => (e, await e.isAvailable()))) - .then((value) => value - .where((e) => e.$2) - .map((e) => e.$1) - .toList()), - builder: (context, snapshot) { - final isMobile = constraints.maxWidth <= kMobileWidth; - final search = value.text; - final imports = (snapshot.data ?? []) - .where((e) => e - .getLocalizedName(context) - .toLowerCase() - .contains(search.toLowerCase())) - .toList(); - final tools = [ - Tool.hand, - () => Tool.select(mode: SelectMode.lasso), - () => Tool.select(mode: SelectMode.rectangle), - Tool.pen, - Tool.stamp, - Tool.laser, - Tool.pathEraser, - Tool.label, - Tool.eraser, - Tool.layer, - Tool.area, - Tool.presentation, - () => Tool.spacer(axis: Axis2D.vertical), - () => Tool.spacer(axis: Axis2D.horizontal), - Tool.eyeDropper, - ] - .map((e) => e()) - .where((e) => e - .getLocalizedName(context) - .toLowerCase() - .contains(search.toLowerCase())) - .toList(); - final shapes = [ - PathShape.circle, - PathShape.rectangle, - PathShape.line, - PathShape.triangle, - ] - .map((e) => e()) - .where((e) => e - .getLocalizedName(context) - .toLowerCase() - .contains(search.toLowerCase())) - .toList(); - final textures = [SurfaceTexture.pattern] - .map((e) => e()) - .where((e) => e - .getLocalizedName(context) - .toLowerCase() - .contains(search.toLowerCase())) - .toList(); - final actions = [ - Tool.undo, - Tool.redo, - Tool.fullSceen, - ] - .map((e) => e()) - .where((e) => e - .getLocalizedName(context) - .toLowerCase() - .contains(search.toLowerCase())) - .toList(); - return ListView( - children: [ - if (imports.isNotEmpty) ...[ - _ToolsListView( - isMobile: isMobile, - title: AppLocalizations.of(context).import, - children: imports - .map( - (e) => BoxTile( - title: Text( - e.getLocalizedName(context), - textAlign: TextAlign.center, - ), - trailing: IconButton( - onPressed: () => addTool( - Tool.asset(importType: e)), - tooltip: - AppLocalizations.of(context).pin, - icon: const PhosphorIcon( - PhosphorIconsLight.pushPin), - ), - icon: PhosphorIcon( - e.icon(PhosphorIconsStyle.light)), - onTap: () async { - final bloc = - context.read(); - final importService = - context.read(); - Navigator.of(context).pop(); - await showImportAssetWizard( - e, context, bloc, importService); - }, + ), + const SizedBox(height: 8), + Expanded( + child: Material( + type: MaterialType.transparency, + child: ValueListenableBuilder( + valueListenable: _searchController, + builder: (context, value, _) => FutureBuilder>( + future: Future.wait(ImportType.values + .map((e) async => (e, await e.isAvailable()))) + .then((value) => + value.where((e) => e.$2).map((e) => e.$1).toList()), + builder: (context, snapshot) { + final isMobile = + constraints.maxWidth < LeapBreakpoints.compact; + final search = value.text; + final imports = (snapshot.data ?? []) + .where((e) => e + .getLocalizedName(context) + .toLowerCase() + .contains(search.toLowerCase())) + .toList(); + final tools = [ + Tool.hand, + () => Tool.select(mode: SelectMode.lasso), + () => Tool.select(mode: SelectMode.rectangle), + Tool.pen, + Tool.stamp, + Tool.laser, + Tool.pathEraser, + Tool.label, + Tool.eraser, + Tool.layer, + Tool.area, + Tool.presentation, + () => Tool.spacer(axis: Axis2D.vertical), + () => Tool.spacer(axis: Axis2D.horizontal), + Tool.eyeDropper, + ] + .map((e) => e()) + .where((e) => e + .getLocalizedName(context) + .toLowerCase() + .contains(search.toLowerCase())) + .toList(); + final shapes = [ + PathShape.circle, + PathShape.rectangle, + PathShape.line, + PathShape.triangle, + ] + .map((e) => e()) + .where((e) => e + .getLocalizedName(context) + .toLowerCase() + .contains(search.toLowerCase())) + .toList(); + final textures = [SurfaceTexture.pattern] + .map((e) => e()) + .where((e) => e + .getLocalizedName(context) + .toLowerCase() + .contains(search.toLowerCase())) + .toList(); + final actions = [ + Tool.undo, + Tool.redo, + Tool.fullSceen, + ] + .map((e) => e()) + .where((e) => e + .getLocalizedName(context) + .toLowerCase() + .contains(search.toLowerCase())) + .toList(); + return ListView( + children: [ + if (imports.isNotEmpty) ...[ + _ToolsListView( + isMobile: isMobile, + title: AppLocalizations.of(context).import, + children: imports + .map( + (e) => BoxTile( + title: Text( + e.getLocalizedName(context), + textAlign: TextAlign.center, ), - ) - .toList(), - ), - const SizedBox(height: 16), - ], - if (tools.isNotEmpty) ...[ - _ToolsListView( - isMobile: isMobile, - title: AppLocalizations.of(context).tools, - children: tools.map(buildTool).toList(), - ), - const SizedBox(height: 16), - ], - if (shapes.isNotEmpty || textures.isNotEmpty) ...[ - _ToolsListView( - isMobile: isMobile, - title: AppLocalizations.of(context).surface, - children: [ - ...shapes.map((e) => BoxTile( - title: Text( - e.getLocalizedName(context), - textAlign: TextAlign.center, - ), - icon: Icon( - e.icon(PhosphorIconsStyle.light)), - onTap: () => addTool(ShapeTool( - property: ShapeProperty(shape: e))), - )), - ...textures.map((e) => BoxTile( - title: Text( - e.getLocalizedName(context), - textAlign: TextAlign.center, - ), - icon: Icon( - e.icon(PhosphorIconsStyle.light)), - onTap: () => - addTool(TextureTool(texture: e)), - )), - ], - ), - const SizedBox(height: 16), - ], - if (actions.isNotEmpty) ...[ - _ToolsListView( - isMobile: isMobile, - title: AppLocalizations.of(context).actions, - children: actions.map(buildTool).toList(), - ), - ], + trailing: IconButton( + onPressed: () => + addTool(Tool.asset(importType: e)), + tooltip: + AppLocalizations.of(context).pin, + icon: const PhosphorIcon( + PhosphorIconsLight.pushPin), + ), + icon: PhosphorIcon( + e.icon(PhosphorIconsStyle.light)), + onTap: () async { + final bloc = + context.read(); + final importService = + context.read(); + Navigator.of(context).pop(); + await showImportAssetWizard( + e, context, bloc, importService); + }, + ), + ) + .toList(), + ), + const SizedBox(height: 16), ], - ); - }), - ), + if (tools.isNotEmpty) ...[ + _ToolsListView( + isMobile: isMobile, + title: AppLocalizations.of(context).tools, + children: tools.map(buildTool).toList(), + ), + const SizedBox(height: 16), + ], + if (shapes.isNotEmpty || textures.isNotEmpty) ...[ + _ToolsListView( + isMobile: isMobile, + title: AppLocalizations.of(context).surface, + children: [ + ...shapes.map((e) => BoxTile( + title: Text( + e.getLocalizedName(context), + textAlign: TextAlign.center, + ), + icon: Icon( + e.icon(PhosphorIconsStyle.light)), + onTap: () => addTool(ShapeTool( + property: ShapeProperty(shape: e))), + )), + ...textures.map((e) => BoxTile( + title: Text( + e.getLocalizedName(context), + textAlign: TextAlign.center, + ), + icon: Icon( + e.icon(PhosphorIconsStyle.light)), + onTap: () => + addTool(TextureTool(texture: e)), + )), + ], + ), + const SizedBox(height: 16), + ], + if (actions.isNotEmpty) ...[ + _ToolsListView( + isMobile: isMobile, + title: AppLocalizations.of(context).actions, + children: actions.map(buildTool).toList(), + ), + ], + ], + ); + }), ), ), - ]), - ), + ), + ]), ), ); } diff --git a/app/lib/dialogs/packs/pack.dart b/app/lib/dialogs/packs/pack.dart index 322d7ee22ab1..4e8b6542e7f0 100644 --- a/app/lib/dialogs/packs/pack.dart +++ b/app/lib/dialogs/packs/pack.dart @@ -39,58 +39,55 @@ class _PackDialogState extends State { @override Widget build(BuildContext context) { - return AlertDialog( + return ResponsiveAlertDialog( title: Text(widget.pack == null ? AppLocalizations.of(context).createPack : AppLocalizations.of(context).editPack), - content: SizedBox( - width: 600, - height: 600, - child: DefaultTabController( - length: widget.pack == null ? 1 : 4, - child: Column( - children: [ - if (widget.pack != null) - TabBar( - isScrollable: true, - tabs: [ - ( - PhosphorIconsLight.gear, - AppLocalizations.of(context).general - ), - ( - PhosphorIconsLight.puzzlePiece, - AppLocalizations.of(context).components - ), - ( - PhosphorIconsLight.pencilCircle, - AppLocalizations.of(context).styles - ), - ( - PhosphorIconsLight.palette, - AppLocalizations.of(context).palettes - ) - ] - .map((e) => HorizontalTab( - icon: PhosphorIcon(e.$1), - label: Text(e.$2), - )) - .toList()), - const SizedBox(height: 8), - Expanded( - child: TabBarView( - children: [ - GeneralPackView(value: pack, onChanged: _onChanged), - if (widget.pack != null) ...[ - ComponentsPackView(value: pack, onChanged: _onChanged), - StylesPackView(value: pack, onChanged: _onChanged), - PalettesPackView(value: pack, onChanged: _onChanged), - ], + constraints: const BoxConstraints(maxWidth: 700, maxHeight: 800), + content: DefaultTabController( + length: widget.pack == null ? 1 : 4, + child: Column( + children: [ + if (widget.pack != null) + TabBar( + isScrollable: true, + tabs: [ + ( + PhosphorIconsLight.gear, + AppLocalizations.of(context).general + ), + ( + PhosphorIconsLight.puzzlePiece, + AppLocalizations.of(context).components + ), + ( + PhosphorIconsLight.pencilCircle, + AppLocalizations.of(context).styles + ), + ( + PhosphorIconsLight.palette, + AppLocalizations.of(context).palettes + ) + ] + .map((e) => HorizontalTab( + icon: PhosphorIcon(e.$1), + label: Text(e.$2), + )) + .toList()), + const SizedBox(height: 8), + Expanded( + child: TabBarView( + children: [ + GeneralPackView(value: pack, onChanged: _onChanged), + if (widget.pack != null) ...[ + ComponentsPackView(value: pack, onChanged: _onChanged), + StylesPackView(value: pack, onChanged: _onChanged), + PalettesPackView(value: pack, onChanged: _onChanged), ], - ), + ], ), - ], - ), + ), + ], ), ), actions: [ diff --git a/app/lib/dialogs/packs/styles/style.dart b/app/lib/dialogs/packs/styles/style.dart index 234e1870eec9..ed267676b532 100644 --- a/app/lib/dialogs/packs/styles/style.dart +++ b/app/lib/dialogs/packs/styles/style.dart @@ -44,48 +44,42 @@ class _StyleDialogState extends State { @override Widget build(BuildContext context) { - return AlertDialog( + return ResponsiveAlertDialog( title: Text(AppLocalizations.of(context).style), - content: SizedBox( - height: 600, - width: 700, - child: DefaultTabController( - length: 3, - child: Column( - children: [ - TabBar( - isScrollable: true, - tabs: [ - ( - PhosphorIconsLight.gear, - AppLocalizations.of(context).general - ), - ( - PhosphorIconsLight.article, - AppLocalizations.of(context).paragraph - ), - ( - PhosphorIconsLight.textT, - AppLocalizations.of(context).text - ) - ] - .map((e) => HorizontalTab( - icon: PhosphorIcon(e.$1), - label: Text(e.$2), - )) - .toList()), - const SizedBox(height: 8), - Expanded( - child: TabBarView( - children: [ - GeneralStyleView(value: _style, onChanged: _onChanged), - ParagraphsStyleView(value: _style, onChanged: _onChanged), - TextsStyleView(value: _style, onChanged: _onChanged), - ], - ), + constraints: const BoxConstraints(maxWidth: 700, maxHeight: 800), + content: DefaultTabController( + length: 3, + child: Column( + children: [ + TabBar( + isScrollable: true, + tabs: [ + ( + PhosphorIconsLight.gear, + AppLocalizations.of(context).general + ), + ( + PhosphorIconsLight.article, + AppLocalizations.of(context).paragraph + ), + (PhosphorIconsLight.textT, AppLocalizations.of(context).text) + ] + .map((e) => HorizontalTab( + icon: PhosphorIcon(e.$1), + label: Text(e.$2), + )) + .toList()), + const SizedBox(height: 8), + Expanded( + child: TabBarView( + children: [ + GeneralStyleView(value: _style, onChanged: _onChanged), + ParagraphsStyleView(value: _style, onChanged: _onChanged), + TextsStyleView(value: _style, onChanged: _onChanged), + ], ), - ], - ), + ), + ], ), ), actions: [ diff --git a/app/lib/dialogs/search.dart b/app/lib/dialogs/search.dart index ec0c38eb80a2..a8340ce1981d 100644 --- a/app/lib/dialogs/search.dart +++ b/app/lib/dialogs/search.dart @@ -80,7 +80,8 @@ class _SearchDialogState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( - width: min(constraints.maxWidth, 600), + width: + min(constraints.maxWidth, LeapBreakpoints.compact.toDouble()), child: Material( borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(12), diff --git a/app/lib/dialogs/template.dart b/app/lib/dialogs/template.dart index a3d71a420340..e9d81ee7be38 100644 --- a/app/lib/dialogs/template.dart +++ b/app/lib/dialogs/template.dart @@ -1,7 +1,6 @@ import 'package:butterfly/actions/new.dart'; import 'package:butterfly/cubits/settings.dart'; import 'package:butterfly/widgets/connection_button.dart'; -import 'package:butterfly/widgets/responsive_dialog.dart'; import 'package:butterfly_api/butterfly_api.dart'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; @@ -56,85 +55,81 @@ class _TemplateDialogState extends State { @override Widget build(BuildContext context) { return ResponsiveDialog( - child: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 600, maxHeight: 800), - child: Column( - children: [ - Header( - title: Text(AppLocalizations.of(context).templates), - leading: IconButton.outlined( - icon: const PhosphorIcon(PhosphorIconsLight.x), - onPressed: () => Navigator.of(context).pop(), - tooltip: AppLocalizations.of(context).close, - ), - actions: [ - ConnectionButton( - currentRemote: _fileSystem.remote?.identifier ?? '', - onChanged: (value) { - _fileSystem = - TemplateFileSystem.fromPlatform(remote: value); - load(); - }, - ), - IconButton( - icon: const PhosphorIcon( - PhosphorIconsLight.clockCounterClockwise), - tooltip: AppLocalizations.of(context).defaultTemplate, - onPressed: () { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text( - AppLocalizations.of(context).defaultTemplate), - content: - Text(AppLocalizations.of(context).reallyReset), - actions: [ - TextButton( - child: - Text(AppLocalizations.of(context).cancel), - onPressed: () => Navigator.of(context).pop(), - ), - ElevatedButton( - child: Text(AppLocalizations.of(context).ok), - onPressed: () async { - for (final template - in await _fileSystem.getTemplates()) { - _fileSystem.deleteTemplate(template.name!); - } - if (context.mounted) { - await _fileSystem.createDefault( - this.context, - force: true); - } - if (context.mounted) { - Navigator.of(context).pop(); - load(); - setState(() {}); - } - }, - ), - ], - ), - ); - }, - ), - ...widget.bloc == null - ? [] - : [ - IconButton( - onPressed: () => _showCreateDialog(widget.bloc!), - tooltip: AppLocalizations.of(context).create, - icon: const PhosphorIcon(PhosphorIconsLight.plus), - ) - ], - ], + constraints: const BoxConstraints(maxWidth: 600, maxHeight: 800), + child: Column( + children: [ + Header( + title: Text(AppLocalizations.of(context).templates), + leading: IconButton.outlined( + icon: const PhosphorIcon(PhosphorIconsLight.x), + onPressed: () => Navigator.of(context).pop(), + tooltip: AppLocalizations.of(context).close, + ), + actions: [ + ConnectionButton( + currentRemote: _fileSystem.remote?.identifier ?? '', + onChanged: (value) { + _fileSystem = + TemplateFileSystem.fromPlatform(remote: value); + load(); + }, ), - Flexible( - child: FutureBuilder>( - future: _templatesFuture, builder: _buildBody), + IconButton( + icon: const PhosphorIcon( + PhosphorIconsLight.clockCounterClockwise), + tooltip: AppLocalizations.of(context).defaultTemplate, + onPressed: () { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: + Text(AppLocalizations.of(context).defaultTemplate), + content: Text(AppLocalizations.of(context).reallyReset), + actions: [ + TextButton( + child: Text(AppLocalizations.of(context).cancel), + onPressed: () => Navigator.of(context).pop(), + ), + ElevatedButton( + child: Text(AppLocalizations.of(context).ok), + onPressed: () async { + for (final template + in await _fileSystem.getTemplates()) { + _fileSystem.deleteTemplate(template.name!); + } + if (context.mounted) { + await _fileSystem.createDefault(this.context, + force: true); + } + if (context.mounted) { + Navigator.of(context).pop(); + load(); + setState(() {}); + } + }, + ), + ], + ), + ); + }, ), + ...widget.bloc == null + ? [] + : [ + IconButton( + onPressed: () => _showCreateDialog(widget.bloc!), + tooltip: AppLocalizations.of(context).create, + icon: const PhosphorIcon(PhosphorIconsLight.plus), + ) + ], ], - ))); + ), + Flexible( + child: FutureBuilder>( + future: _templatesFuture, builder: _buildBody), + ), + ], + )); } Widget _buildBody( diff --git a/app/lib/main.dart b/app/lib/main.dart index 077f337e6cce..e60b9e31aeeb 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -41,9 +41,6 @@ import 'views/home.dart'; import 'views/main.dart'; import 'widgets/window.dart'; -const kMobileWidth = 600.0; -const kLargeWidth = 1200.0; - const platform = MethodChannel('linwood.dev/butterfly'); Future main([List args = const []]) async { diff --git a/app/lib/views/app_bar.dart b/app/lib/views/app_bar.dart index 533e82e01a7b..687a02df554f 100644 --- a/app/lib/views/app_bar.dart +++ b/app/lib/views/app_bar.dart @@ -32,7 +32,6 @@ import '../actions/save.dart'; import '../bloc/document_bloc.dart'; import '../cubits/settings.dart'; import '../embed/action.dart'; -import '../main.dart'; import '../widgets/window.dart'; import 'navigator/view.dart'; @@ -55,7 +54,8 @@ class PadAppBar extends StatelessWidget implements PreferredSizeWidget { leading: Padding( padding: const EdgeInsets.only(left: 8.0), child: LayoutBuilder(builder: (context, constraints) { - final isLarge = MediaQuery.of(context).size.width < kLargeWidth; + final isLarge = + MediaQuery.of(context).size.width < LeapBreakpoints.expanded; return _MainPopupMenu( viewportKey: viewportKey, isLarge: isLarge, @@ -63,7 +63,8 @@ class PadAppBar extends StatelessWidget implements PreferredSizeWidget { }), ), title: LayoutBuilder(builder: (context, constraints) { - final isMobile = MediaQuery.of(context).size.width < kMobileWidth; + final isMobile = + MediaQuery.of(context).size.width < LeapBreakpoints.compact; return _AppBarTitle( isMobile: isMobile, ); @@ -343,7 +344,8 @@ class _MainPopupMenu extends StatelessWidget { } }, ), - if (MediaQuery.of(context).size.width < kLargeWidth || + if (MediaQuery.of(context).size.width < + LeapBreakpoints.expanded || !settings.navigationRail) ...NavigatorPage.values.map( (e) => MenuItemButton( diff --git a/app/lib/views/files/list.dart b/app/lib/views/files/list.dart index 7a1041c9996a..c381fd04a08e 100644 --- a/app/lib/views/files/list.dart +++ b/app/lib/views/files/list.dart @@ -13,6 +13,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:material_leap/material_leap.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; class FileEntityListTile extends StatelessWidget { @@ -50,8 +51,8 @@ class FileEntityListTile extends StatelessWidget { final remote = settingsCubit.getRemote(entity.location.remote); final fileSystem = DocumentFileSystem.fromPlatform(remote: remote); return LayoutBuilder(builder: (context, constraints) { - final isDesktop = constraints.maxWidth > 600; - final isTablet = constraints.maxWidth > 500; + final isDesktop = constraints.maxWidth >= LeapBreakpoints.medium; + final isTablet = constraints.maxWidth >= LeapBreakpoints.compact; return Row( children: [ Expanded( diff --git a/app/lib/views/home.dart b/app/lib/views/home.dart index f6f9d8d77357..c1bb6af33c87 100644 --- a/app/lib/views/home.dart +++ b/app/lib/views/home.dart @@ -342,7 +342,7 @@ class _HeaderHomeViewState extends State<_HeaderHomeView> ], ); final innerCard = LayoutBuilder(builder: (context, constraints) { - final isMobile = constraints.maxWidth <= kMobileWidth; + final isMobile = constraints.maxWidth < LeapBreakpoints.compact; if (isMobile) { return Column( children: [logo, const SizedBox(height: 16), whatsNew], diff --git a/app/lib/views/main.dart b/app/lib/views/main.dart index 8406e845a35f..d8094e4eeeac 100644 --- a/app/lib/views/main.dart +++ b/app/lib/views/main.dart @@ -25,6 +25,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:material_leap/material_leap.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -50,7 +51,6 @@ import '../actions/settings.dart'; import '../actions/svg_export.dart'; import '../actions/undo.dart'; import '../actions/zoom.dart'; -import '../main.dart'; import '../models/viewport.dart'; import '../services/asset.dart'; import '../api/changes.dart'; @@ -496,8 +496,10 @@ class _MainBody extends StatelessWidget { builder: (context, settings) { final pos = settings.toolbarPosition; return LayoutBuilder(builder: (context, constraints) { - final isMobile = constraints.maxWidth < kMobileWidth; - final isLarge = constraints.maxWidth > kLargeWidth; + final isMobile = + constraints.maxWidth < LeapBreakpoints.compact; + final isLarge = + constraints.maxWidth >= LeapBreakpoints.expanded; final toolbar = EditToolbar( isMobile: false, centered: true, diff --git a/app/lib/widgets/responsive_dialog.dart b/app/lib/widgets/responsive_dialog.dart deleted file mode 100644 index d3021d0ffff2..000000000000 --- a/app/lib/widgets/responsive_dialog.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:butterfly/main.dart'; -import 'package:flutter/material.dart'; - -class ResponsiveDialog extends StatelessWidget { - final Widget child; - - const ResponsiveDialog({super.key, required this.child}); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, constraints) { - if (constraints.maxWidth < kMobileWidth) { - return Dialog.fullscreen( - child: child, - ); - } else { - return Dialog( - child: child, - ); - } - }); - } -} diff --git a/app/pubspec.lock b/app/pubspec.lock index 60bfd1845c23..95fe143d9f1e 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -308,8 +308,8 @@ packages: dependency: transitive description: path: "packages/dart_leap" - ref: "805e87db09d83b20209645e2ae130597863ecd51" - resolved-ref: "805e87db09d83b20209645e2ae130597863ecd51" + ref: d45bd54f2efd6a861d6f44a8b833575b0482dc4c + resolved-ref: d45bd54f2efd6a861d6f44a8b833575b0482dc4c url: "https://github.com/LinwoodDev/dart_pkgs" source: git version: "1.0.0" @@ -841,8 +841,8 @@ packages: dependency: "direct main" description: path: "packages/material_leap" - ref: fa2fa0e74c8d749e77b7f085a4c7656043bdca92 - resolved-ref: fa2fa0e74c8d749e77b7f085a4c7656043bdca92 + ref: ff93bce26d1f8d5160cbfe66b548cf9286d0576d + resolved-ref: ff93bce26d1f8d5160cbfe66b548cf9286d0576d url: "https://github.com/LinwoodDev/dart_pkgs.git" source: git version: "0.0.1" @@ -1069,10 +1069,10 @@ packages: dependency: "direct main" description: name: popover - sha256: ca3bef9d88ebf5c5c3823946a5de3ce8360018fbb6a3e25819586a7d5a203db2 + sha256: "5cba40e04115cbbf15c35e00767b91e8bf3f769763a34beb2f8a1b9e8b5fc876" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.3.0+1" printing: dependency: "direct main" description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 90e353739553..bf45c2b25a87 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -69,7 +69,7 @@ dependencies: material_leap: git: url: https://github.com/LinwoodDev/dart_pkgs.git - ref: fa2fa0e74c8d749e77b7f085a4c7656043bdca92 + ref: ff93bce26d1f8d5160cbfe66b548cf9286d0576d path: packages/material_leap lw_sysapi: git: diff --git a/metadata/en-US/changelogs/106.txt b/metadata/en-US/changelogs/106.txt index 0edaaeb18f32..2ac6b03ebf9f 100644 --- a/metadata/en-US/changelogs/106.txt +++ b/metadata/en-US/changelogs/106.txt @@ -4,6 +4,7 @@ * Center grid items in home page * Improve webdav requests ([#703](https://github.com/LinwoodDev/Butterfly/pull/703)) * Improve image quality ([#704](https://github.com/LinwoodDev/Butterfly/issues/704)) +* Improve responsiveness * Fix launching url does nothing * Fix settings on mobile fill full height * Fix grid switch on file view will be shown in navigator