From 85a3e6a524fe2b63111598edde30637bf3fff398 Mon Sep 17 00:00:00 2001 From: Sun Date: Thu, 14 Oct 2021 14:20:13 +0800 Subject: [PATCH] DC: update file type UI --- lib/apps/file/editor.dart | 53 ++++++++++++++-- lib/apps/file/list.dart | 130 +++++++++++++++++--------------------- lib/apps/file/models.dart | 108 +++++++++++++++++++++++++++++++ lib/utils/file_image.dart | 52 --------------- 4 files changed, 215 insertions(+), 128 deletions(-) delete mode 100644 lib/utils/file_image.dart diff --git a/lib/apps/file/editor.dart b/lib/apps/file/editor.dart index 4a948e5..09919e2 100644 --- a/lib/apps/file/editor.dart +++ b/lib/apps/file/editor.dart @@ -19,11 +19,14 @@ class EditorPage extends StatefulWidget { class _EditorPageState extends State { QuillController _controller = QuillController.basic(); + TextEditingController _nameController = TextEditingController(); + bool _nameEdit = false; @override initState() { print("File editor initState..."); super.initState(); + _nameController.text = widget.path.name(); } @override @@ -32,19 +35,61 @@ class _EditorPageState extends State { final lang = AppLocalizations.of(context); final isDesktop = isDisplayDesktop(context); - return Scaffold( appBar: AppBar( leading: isDesktop ? IconButton( icon: Icon(Icons.arrow_back), onPressed: () { - final w = FilesList(path: widget.path); + final w = FilesList(path: FilePath.prev(widget.path)); context.read().updateActivedWidget(w); } ) : null, centerTitle: true, - title: TextButton(child: Text('New Document 0'), - onPressed: () {} + title: _nameEdit + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + width: 200.0, + child: TextField( + autofocus: true, + style: TextStyle(fontSize: 16.0), + textAlign: TextAlign.center, + controller: _nameController, + decoration: InputDecoration( + hintStyle: TextStyle( + color: Color(0xFF1C1939).withOpacity(0.25)), + filled: false, + isDense: true, + ), + ), + ), + const SizedBox(width: 10.0), + GestureDetector( + onTap: () { + if (_nameController.text.length > 0) { + // TODO update file name. + } + setState(() { + this._nameEdit = false; + }); + }, + child: Container( + width: 20.0, + child: Icon(Icons.done_rounded, color: color.primary)), + ), + const SizedBox(width: 8.0), + GestureDetector( + onTap: () => setState(() { + _nameController.text = widget.path.name(); + this._nameEdit = false; + }), + child: Container( + width: 20.0, child: Icon(Icons.clear_rounded)), + ), + ]) + : TextButton(child: Text(widget.path.name()), + onPressed: () => setState(() { this._nameEdit = true; }), ), ), body: Column( diff --git a/lib/apps/file/list.dart b/lib/apps/file/list.dart index cee5ba7..a961c42 100644 --- a/lib/apps/file/list.dart +++ b/lib/apps/file/list.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:esse/utils/adaptive.dart'; -import 'package:esse/utils/file_image.dart'; import 'package:esse/l10n/localizations.dart'; import 'package:esse/provider.dart'; @@ -18,6 +17,8 @@ class FilesList extends StatefulWidget { } class _FilesListState extends State { + bool _isDesktop = false; + @override void initState() { super.initState(); @@ -28,6 +29,14 @@ class _FilesListState extends State { // } + _navigator(Widget w) { + if (_isDesktop) { + context.read().updateActivedWidget(w); + } else { + Navigator.push(context, MaterialPageRoute(builder: (_) => w)); + } + } + _nextDirectory(FilePath path) { setState(() { widget.path = path; @@ -58,11 +67,42 @@ class _FilesListState extends State { return widgets; } + Widget _item(FilePath file) { + final trueName = file.name(); + final params = file.fileType().params(); + return InkWell( + onTap: () { + if (file.isDirectory()) { + _nextDirectory(file); + } else if (file.isPost()) { + _navigator(EditorPage(path: file)); + } + }, + child: Container( + padding: const EdgeInsets.all(4.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + height: 55.0, + width: 60.0, + child: Icon(params[0], color: params[1], size: 48.0), + ), + Tooltip( + message: trueName, + child: Text(trueName, + style: TextStyle(fontSize: 14.0), maxLines: 1, overflow: TextOverflow.ellipsis), + ) + ] + ))); + } + @override Widget build(BuildContext context) { final color = Theme.of(context).colorScheme; final lang = AppLocalizations.of(context); - final isDesktop = isDisplayDesktop(context); + this._isDesktop = isDisplayDesktop(context); return Scaffold( appBar: AppBar( @@ -101,12 +141,8 @@ class _FilesListState extends State { child: SizedBox(width: 40.0, child: Icon(Icons.add_rounded, color: color.primary)), onSelected: (int value) { if (value == 0) { - final editor = EditorPage(path: widget.path); - if (!isDesktop) { - Navigator.push(context, MaterialPageRoute(builder: (_) => editor)); - } else { - context.read().updateActivedWidget(editor); - } + final path = FilePath.next(widget.path, "new document 0.quill.json"); + _navigator(EditorPage(path: path)); } else if (value == 1) { // new folder } else if (value == 2) { @@ -142,35 +178,20 @@ class _FilesListState extends State { maxCrossAxisExtent: 75.0, childAspectRatio: 0.8, children: [ - FileItem( - path: FilePath.next(widget.path, 'myworks.dir'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'ESSE-infos-public.dir'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'personal.dir'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'others.dir'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'logo.jpg'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'cat.png'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'what-is-esse_en.doc'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, '20210101-customers.xls'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'product.pdf'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'deck.ppt'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'coder.md'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'how-to-live-in-happy.mp4'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'something_important'), - directory: this._nextDirectory), - FileItem(path: FilePath.next(widget.path, 'car.json'), - directory: this._nextDirectory), + _item(FilePath.next(widget.path, 'myworks.dir')), + _item(FilePath.next(widget.path, 'ESSE-infos-public.dir')), + _item(FilePath.next(widget.path, 'personal.dir')), + _item(FilePath.next(widget.path, 'others.dir')), + _item(FilePath.next(widget.path, 'logo.jpg')), + _item(FilePath.next(widget.path, 'cat.png')), + _item(FilePath.next(widget.path, 'what-is-esse_en.doc')), + _item(FilePath.next(widget.path, '20210101-customers.xls')), + _item(FilePath.next(widget.path, 'product.pdf')), + _item(FilePath.next(widget.path, 'deck.ppt')), + _item(FilePath.next(widget.path, 'coder.md')), + _item(FilePath.next(widget.path, 'how-to-live-in-happy.mp4')), + _item(FilePath.next(widget.path, 'something_important')), + _item(FilePath.next(widget.path, 'car.quill.json')), ], ), ) @@ -180,38 +201,3 @@ class _FilesListState extends State { ); } } - -class FileItem extends StatelessWidget { - final FilePath path; - final Function directory; - const FileItem({Key? key, required this.path, required this.directory}) : super(key: key); - - @override - Widget build(BuildContext context) { - final trueName = this.path.name(); - return InkWell( - onTap: () { - if (this.path.isDirectory()) { - this.directory(this.path); - } - }, - child: Container( - padding: const EdgeInsets.all(4.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - height: 55.0, - width: 60.0, - child: fileIcon(this.path.fullName, 48.0), - ), - Tooltip( - message: trueName, - child: Text(trueName, - style: TextStyle(fontSize: 14.0), maxLines: 1, overflow: TextOverflow.ellipsis), - ) - ] - ))); - } -} diff --git a/lib/apps/file/models.dart b/lib/apps/file/models.dart index 84fa4e0..af824ef 100644 --- a/lib/apps/file/models.dart +++ b/lib/apps/file/models.dart @@ -38,6 +38,77 @@ extension InnerServiceExtension on RootDirectory { } } +const Map FILE_TYPES = { + 'dir': FileType.Folder, + 'quill.json': FileType.Post, + 'jpg': FileType.Image, + 'jpeg': FileType.Image, + 'png': FileType.Image, + 'svg': FileType.Image, + 'pdf': FileType.Pdf, + 'doc': FileType.Word, + 'docx': FileType.Word, + 'xls': FileType.Sheet, + 'xlsx': FileType.Sheet, + 'ppt': FileType.Slide, + 'pptx': FileType.Slide, + 'md': FileType.Markdown, + 'mp4': FileType.Video, + 'mp3': FileType.Music, +}; + +enum FileType { + Folder, + Post, + Image, + Music, + Video, + Pdf, + Slide, + Sheet, + Word, + Markdown, + Other, +} + +// AssetImage('assets/images/file_default.png'), +// AssetImage('assets/images/file_image.png'), +// AssetImage('assets/images/file_pdf.png'), +// AssetImage('assets/images/file_word.png'), +// AssetImage('assets/images/file_sheet.png'), +// AssetImage('assets/images/file_markdown.png'), +// AssetImage('assets/images/file_video.png'), +// AssetImage('assets/images/dir_folder.svg'), + +extension FileTypeExtension on FileType { + List params() { + switch (this) { + case FileType.Folder: + return [Icons.folder_rounded, Colors.blue]; + case FileType.Post: + return [Icons.article_rounded, Color(0xFF6174FF)]; + case FileType.Image: + return [Icons.image_rounded, Colors.green]; + case FileType.Music: + return [Icons.music_note_rounded, Colors.red]; + case FileType.Video: + return [Icons.play_circle_fill_rounded, Colors.red]; + case FileType.Pdf: + return [Icons.chrome_reader_mode_rounded, Color(0xFFFF5722)]; + case FileType.Slide: + return [Icons.slideshow_rounded, Color(0xFFFF6D00)]; + case FileType.Sheet: + return [Icons.table_chart_rounded, Color(0xFF4CAF50)]; + case FileType.Word: + return [Icons.description_rounded, Color(0xFF1976d2)]; + case FileType.Markdown: + return [Icons.description_rounded, Color(0xFF455A64)]; + case FileType.Other: + return [Icons.insert_drive_file_rounded, Colors.grey]; + } + } +} + class FilePath { RootDirectory root; List path = []; @@ -54,6 +125,17 @@ class FilePath { return FilePath(root, path); } + static FilePath prev(FilePath file) { + final root = file.root; + List path = List.from(file.path); + if (path.length == 0) { + return FilePath.root(root); + } else { + path.removeLast(); + return FilePath(root, path); + } + } + static directoryName(String name) { final i = name.lastIndexOf('.'); return name.substring(0, i); @@ -67,11 +149,37 @@ class FilePath { if (isDirectory()) { final i = this.path.last.lastIndexOf('.'); return this.path.last.substring(0, i); + } else if (isPost()){ + final i = this.path.last.lastIndexOf('.quill'); + return this.path.last.substring(0, i); } else { return this.path.last; } } + FileType fileType() { + if (isDirectory()) { + return FileType.Folder; + } + + if (isPost()) { + return FileType.Post; + } + + final i = this.path.last.lastIndexOf('.'); + if (i > 0) { + final suffix = this.path.last.substring(i + 1); + if (FILE_TYPES.containsKey(suffix)) { + return FILE_TYPES[suffix]!; + } + } + return FileType.Other; + } + + bool isPost() { + return this.path.last.endsWith('.quill.json'); + } + bool isDirectory() { return this.path.last.endsWith('.dir'); } diff --git a/lib/utils/file_image.dart b/lib/utils/file_image.dart deleted file mode 100644 index 4db6d7e..0000000 --- a/lib/utils/file_image.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; - -// AssetImage('assets/images/file_default.png'), -// AssetImage('assets/images/file_image.png'), -// AssetImage('assets/images/file_pdf.png'), -// AssetImage('assets/images/file_word.png'), -// AssetImage('assets/images/file_sheet.png'), -// AssetImage('assets/images/file_markdown.png'), -// AssetImage('assets/images/file_video.png'), -// AssetImage('assets/images/dir_folder.svg'), - -const List FILE_IMAGES = [ - [Icons.insert_drive_file_rounded, Colors.grey], // default file - [Icons.image_rounded, Colors.green], // image - [Icons.chrome_reader_mode_rounded, Color(0xFFFF5722)], // pdf - [Icons.text_snippet_rounded, Color(0xFF1976d2)], // word - [Icons.table_chart_rounded, Color(0xFF4CAF50)], // sheet - [Icons.slideshow_rounded, Color(0xFFFF6D00)], // slide - [Icons.article_rounded, Color(0xFF455A64)], // markdown - [Icons.play_circle_fill_rounded, Colors.red], // video - [Icons.folder_rounded, Colors.blue], // folder -]; - -const Map FILE_TYPES = { - 'jpg': 1, - 'jpeg': 1, - 'png': 1, - 'svg': 1, - 'pdf': 2, - 'doc': 3, - 'docx': 3, - 'xls': 4, - 'xlsx': 4, - 'ppt': 5, - 'pptx': 5, - 'md': 6, - 'mp4': 7, - 'dir': 8, -}; - -Widget fileIcon(String name, double size) { - final i = name.lastIndexOf('.'); - if (i > 0) { - final suffix = name.substring(i + 1); - if (FILE_TYPES.containsKey(suffix)) { - final index = FILE_TYPES[suffix]!; - return Icon(FILE_IMAGES[index][0], color: FILE_IMAGES[index][1], size: size); - } - } - - return Icon(FILE_IMAGES[0][0], color: FILE_IMAGES[0][1], size: size); -}