diff --git a/app/lib/views/files/list.dart b/app/lib/views/files/list.dart index d212ec1a8e72..461e4d3abadb 100644 --- a/app/lib/views/files/list.dart +++ b/app/lib/views/files/list.dart @@ -88,87 +88,148 @@ class FileEntityListTile extends StatelessWidget { horizontal: 16, ), child: Builder(builder: (context) { + final info = [ + if (modifiedText != null) + Tooltip( + message: AppLocalizations.of(context).modified, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + PhosphorIcon( + PhosphorIconsLight.clockCounterClockwise, + size: 12, + color: colorScheme.outline, + ), + const SizedBox(width: 2), + Text( + modifiedText!, + style: + TextTheme.of(context).bodySmall?.copyWith( + color: colorScheme.outline, + ), + ), + ], + ), + ), + if (createdText != null) + Tooltip( + message: AppLocalizations.of(context).created, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + PhosphorIcon( + PhosphorIconsLight.plus, + size: 12, + color: colorScheme.outline, + ), + const SizedBox(width: 2), + Text( + createdText!, + style: + TextTheme.of(context).bodySmall?.copyWith( + color: colorScheme.outline, + ), + ), + ], + ), + ), + ]; final leading = PhosphorIcon( icon, color: colorScheme.outline, ); - final fileName = SizedBox( - height: 42, - child: Row( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - width: 64, - child: thumbnail != null - ? AspectRatio( - aspectRatio: kThumbnailRatio, - child: ClipRRect( - borderRadius: - BorderRadius.circular(8), - child: Image.memory( - thumbnail!, - fit: BoxFit.cover, - cacheHeight: kThumbnailHeight, - cacheWidth: kThumbnailWidth, - )), - ) - : leading, - ), - const SizedBox(width: 8), - Flexible( - child: editable - ? TextField( - controller: nameController, - autofocus: true, - style: TextTheme.of(context).labelLarge, - onSubmitted: (value) async { - await documentSystem.renameAsset( - entity.location.path, value); - onEdit(false); - onReload(); - }, - textAlignVertical: - TextAlignVertical.center, - decoration: InputDecoration( - filled: true, - constraints: BoxConstraints( - maxWidth: constraints.maxWidth, - minWidth: 100, - maxHeight: 40, - ), - hintText: AppLocalizations.of(context) - .enterText, - suffix: IconButton( - onPressed: () async { - await documentSystem.renameAsset( - entity.location.path, - nameController.text); - onEdit(false); - onReload(); - }, - icon: const PhosphorIcon( - PhosphorIconsLight.check), - tooltip: - AppLocalizations.of(context).save, - ), + final fileName = Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: 64, + child: thumbnail != null + ? AspectRatio( + aspectRatio: kThumbnailRatio, + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.memory( + thumbnail!, + fit: BoxFit.cover, + cacheHeight: kThumbnailHeight, + cacheWidth: kThumbnailWidth, + )), + ) + : leading, + ), + const SizedBox(width: 8), + Flexible( + child: editable + ? TextField( + controller: nameController, + autofocus: true, + style: TextTheme.of(context).labelLarge, + onSubmitted: (value) async { + await documentSystem.renameAsset( + entity.location.path, value); + onEdit(false); + onReload(); + }, + textAlignVertical: TextAlignVertical.center, + decoration: InputDecoration( + filled: true, + constraints: BoxConstraints( + maxWidth: constraints.maxWidth, + minWidth: 100, + maxHeight: 40, ), - ) - : GestureDetector( - child: Text( - entity.fileName, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextTheme.of(context).labelLarge, + hintText: AppLocalizations.of(context) + .enterText, + suffix: IconButton( + onPressed: () async { + if (nameController.text == + entity.fileName) { + onEdit(false); + return; + } + await documentSystem.renameAsset( + entity.location.path, + nameController.text); + onEdit(false); + onReload(); + }, + icon: const PhosphorIcon( + PhosphorIconsLight.check), + tooltip: + AppLocalizations.of(context).save, ), - onDoubleTap: () { - onEdit(true); - nameController.text = entity.fileName; - }, ), - ), - ], - ), + ) + : GestureDetector( + onDoubleTap: () { + onEdit(true); + nameController.text = entity.fileName; + }, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + entity.fileName, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: + TextTheme.of(context).labelLarge, + ), + if (!isDesktop && !collapsed) ...[ + const SizedBox(height: 6), + Wrap( + spacing: 4, + children: info, + ), + ], + ], + ), + ), + ), + ], ); final edit = editable ? Container() @@ -248,56 +309,6 @@ class FileEntityListTile extends StatelessWidget { ), ], ); - final info = Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - if (modifiedText != null) - Tooltip( - message: AppLocalizations.of(context).modified, - child: Row( - children: [ - PhosphorIcon( - PhosphorIconsLight.clockCounterClockwise, - size: 12, - color: colorScheme.outline, - ), - const SizedBox(width: 8), - Text( - modifiedText!, - style: TextTheme.of(context) - .bodySmall - ?.copyWith( - color: colorScheme.outline, - ), - ), - ], - ), - ), - if (createdText != null) - Tooltip( - message: AppLocalizations.of(context).created, - child: Row( - children: [ - PhosphorIcon( - PhosphorIconsLight.plus, - size: 12, - color: colorScheme.outline, - ), - const SizedBox(width: 8), - Text( - createdText!, - style: TextTheme.of(context) - .bodySmall - ?.copyWith( - color: colorScheme.outline, - ), - ), - ], - ), - ), - ], - ); final selectionCheckbox = Checkbox( value: selected ?? false, onChanged: (value) => onSelectedChanged(value ?? false), @@ -321,7 +332,11 @@ class FileEntityListTile extends StatelessWidget { ), if (!collapsed) ...[ const SizedBox(width: 32), - info, + Column( + crossAxisAlignment: CrossAxisAlignment.end, + spacing: 4, + children: info, + ), const SizedBox(width: 32), actions, ] else if (collapsed) @@ -337,15 +352,7 @@ class FileEntityListTile extends StatelessWidget { const SizedBox(width: 8), Expanded( child: Row(children: [ - Flexible( - child: Wrap( - spacing: 2, - children: [ - fileName, - if (!collapsed) info, - ], - ), - ), + Flexible(child: fileName), const SizedBox(width: 8), edit, ])), @@ -359,16 +366,7 @@ class FileEntityListTile extends StatelessWidget { selectionCheckbox, const SizedBox(width: 8), ], - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - fileName, - const SizedBox(height: 8), - info, - ], - ), - ), + Expanded(child: fileName), actionButton, ], ); diff --git a/app/lib/views/files/view.dart b/app/lib/views/files/view.dart index b1f3ece6e14e..636749505399 100644 --- a/app/lib/views/files/view.dart +++ b/app/lib/views/files/view.dart @@ -12,6 +12,7 @@ import 'package:go_router/go_router.dart'; import 'package:lw_file_system/lw_file_system.dart'; import 'package:material_leap/material_leap.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; +import 'package:rxdart/rxdart.dart'; import '../../api/open.dart'; import '../../cubits/settings.dart'; @@ -42,6 +43,7 @@ class FilesView extends StatefulWidget { class FilesViewState extends State { final TextEditingController _locationController = TextEditingController(); late final ButterflyFileSystem _fileSystem; + late final Future>> _templatesFuture; late DocumentFileSystem _documentSystem; late TemplateFileSystem _templateSystem; @@ -94,9 +96,11 @@ class FilesViewState extends State { void _setFilesStream() { _templateSystem = _fileSystem.buildTemplateSystem(_remote); _documentSystem = _fileSystem.buildDocumentSystem(_remote); - _filesStream = _documentSystem - .fetchAsset(_locationController.text) - .asBroadcastStream(); + _filesStream = ValueConnectableStream( + _documentSystem.fetchAsset(_locationController.text)) + .autoConnect(); + _templatesFuture = + _templateSystem.initialize().then((_) => _templateSystem.getFiles()); } void reloadFileSystem() { @@ -366,9 +370,7 @@ class FilesViewState extends State { Text(AppLocalizations.of(context).newNote), ), FutureBuilder>>( - future: _templateSystem - .initialize() - .then((_) => _templateSystem.getFiles()), + future: _templatesFuture, builder: (context, snapshot) => SubmenuButton( leadingIcon: const PhosphorIcon( PhosphorIconsLight.file), diff --git a/metadata/en-US/changelogs/130.txt b/metadata/en-US/changelogs/130.txt index e28c2968ef88..f67e880d2e7b 100644 --- a/metadata/en-US/changelogs/130.txt +++ b/metadata/en-US/changelogs/130.txt @@ -5,6 +5,7 @@ * Grid and ruler will now influence shape, stamp and texture tool * Improve ruler rotation handling * Improve selection change animation +* Improve responsiveness of file list view * Improve grid tool * Add stroke width * Add option for position and zoom dependent