From d70cbb66d29da75c80d75879e3a2bf4a40e2b7b7 Mon Sep 17 00:00:00 2001 From: Junyuan Feng Date: Tue, 8 Feb 2022 21:12:38 +0800 Subject: [PATCH] New UI. --- README.md | 13 +- lib/data/model/app/navigation_item.dart | 8 ++ lib/data/res/build_data.dart | 9 +- lib/data/res/tab.dart | 8 ++ lib/view/page/debug.dart | 2 +- lib/view/page/home.dart | 176 +++++++++++++++++++----- lib/view/page/server/tab.dart | 16 +-- make.dart | 2 +- pubspec.lock | 16 +-- pubspec.yaml | 1 + 10 files changed, 187 insertions(+), 64 deletions(-) create mode 100644 lib/data/model/app/navigation_item.dart diff --git a/README.md b/README.md index 44db3754..21e89d51 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ A new Flutter project which provide a chart view to display server status data a - + - + @@ -22,13 +22,20 @@ A new Flutter project which provide a chart view to display server status data a - + + + + + +
+ +
# Support Status|Platform diff --git a/lib/data/model/app/navigation_item.dart b/lib/data/model/app/navigation_item.dart new file mode 100644 index 00000000..d59683ec --- /dev/null +++ b/lib/data/model/app/navigation_item.dart @@ -0,0 +1,8 @@ +import 'package:flutter/material.dart'; + +class NavigationItem { + final IconData icon; + final String title; + + NavigationItem(this.icon, this.title); +} diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 1edce1e3..e7c8a8b8 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,8 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 91; - static const String engine = "Flutter 2.10.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 5f105a6ca7 (7 days ago) • 2022-02-01 14:15:42 -0800\nEngine • revision 776efd2034\nTools • Dart 2.16.0 • DevTools 2.9.2\n"; - static const String buildAt = "2022-02-08 19:01:55.450937"; - static const int modifications = 3; + static const int build = 93; + static const String engine = + "Flutter 2.10.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 5f105a6ca7 (7 days ago) • 2022-02-01 14:15:42 -0800\nEngine • revision 776efd2034\nTools • Dart 2.16.0 • DevTools 2.9.2\n"; + static const String buildAt = "2022-02-08 20:57:54.707031"; + static const int modifications = 9; } diff --git a/lib/data/res/tab.dart b/lib/data/res/tab.dart index fb289c39..fa7dc7fc 100644 --- a/lib/data/res/tab.dart +++ b/lib/data/res/tab.dart @@ -1 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:toolbox/data/model/app/navigation_item.dart'; + final List tabs = ['Servers', 'En/Decode', 'Ping']; +final List tabItems = [ + NavigationItem(Icons.computer, 'Server'), + NavigationItem(Icons.code, 'Convert'), + NavigationItem(Icons.network_check, 'Ping'), + ]; diff --git a/lib/view/page/debug.dart b/lib/view/page/debug.dart index 0f8396b3..0f357782 100644 --- a/lib/view/page/debug.dart +++ b/lib/view/page/debug.dart @@ -14,7 +14,7 @@ class _DebugPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: - AppBar(title: const Text('Terminal'), backgroundColor: Colors.black), + AppBar(title: const Text('App log'), backgroundColor: Colors.black), body: _buildTerminal(context), backgroundColor: Colors.black, ); diff --git a/lib/view/page/home.dart b/lib/view/page/home.dart index 4ccc194b..11bdcec7 100644 --- a/lib/view/page/home.dart +++ b/lib/view/page/home.dart @@ -1,13 +1,16 @@ import 'package:after_layout/after_layout.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_advanced_drawer/flutter_advanced_drawer.dart'; import 'package:get_it/get_it.dart'; import 'package:toolbox/core/analysis.dart'; import 'package:toolbox/core/build_mode.dart'; import 'package:toolbox/core/route.dart'; import 'package:toolbox/core/update.dart'; import 'package:toolbox/core/utils.dart'; +import 'package:toolbox/data/model/app/navigation_item.dart'; import 'package:toolbox/data/provider/server.dart'; import 'package:toolbox/data/res/build_data.dart'; +import 'package:toolbox/data/res/color.dart'; import 'package:toolbox/data/res/icon/common.dart'; import 'package:toolbox/data/res/tab.dart'; import 'package:toolbox/data/res/url.dart'; @@ -36,23 +39,26 @@ class _MyHomePageState extends State SingleTickerProviderStateMixin, AfterLayoutMixin, WidgetsBindingObserver { - late final TabController _tabController; late final ServerProvider _serverProvider; + late final PageController _pageController; + late final AdvancedDrawerController _advancedDrawerController; + late int _selectIndex; + late double _width; @override void initState() { super.initState(); _serverProvider = locator(); WidgetsBinding.instance?.addObserver(this); - _tabController = TabController( - initialIndex: locator().launchPage.fetch()!, - length: tabs.length, - vsync: this); - _tabController.addListener(() { - if (_tabController.index == 0) { - FocusScope.of(context).unfocus(); - } - }); + _selectIndex = locator().launchPage.fetch()!; + _pageController = PageController(initialPage: _selectIndex); + _advancedDrawerController = AdvancedDrawerController(); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _width = MediaQuery.of(context).size.width; } @override @@ -77,37 +83,123 @@ class _MyHomePageState extends State Widget build(BuildContext context) { setTransparentNavigationBar(context); super.build(context); - return Scaffold( - appBar: AppBar( - title: GestureDetector( - onLongPress: () => - AppRoute(const DebugPage(), 'Debug Page').go(context), - child: const Text(BuildData.name), - ), - bottom: TabBar( - indicatorColor: widget.primaryColor, - tabs: tabs.map((e) => Tab(text: e)).toList(), - controller: _tabController, + return AdvancedDrawer( + controller: _advancedDrawerController, + animationCurve: Curves.easeInOutCirc, + animationDuration: const Duration(milliseconds: 300), + animateChildDecoration: true, + rtlOpening: false, + disabledGestures: true, + childDecoration: const BoxDecoration( + // NOTICE: Uncomment if you want to add shadow behind the page. + // Keep in mind that it may cause animation jerks. + boxShadow: [ + BoxShadow( + color: Colors.black12, + blurRadius: 0.0, + ), + ], + borderRadius: BorderRadius.all(Radius.circular(16)), ), + drawer: _buildDrawer(), + child: Scaffold( + appBar: AppBar( + title: Text(tabItems[_selectIndex].title), + actions: [ + IconButton( + icon: const Icon(Icons.developer_mode, size: 23), + tooltip: 'Debug', + onPressed: () => + AppRoute(const DebugPage(), 'Debug Page').go(context), + ), + ], + leading: IconButton( + onPressed: () => _advancedDrawerController.showDrawer(), + icon: ValueListenableBuilder( + valueListenable: _advancedDrawerController, + builder: (_, value, __) { + return AnimatedSwitcher( + duration: const Duration(milliseconds: 250), + child: Icon( + value.visible ? Icons.clear : Icons.menu, + key: ValueKey(value.visible), + ), + ); + }, + ), + ), + ), + body: PageView( + physics: const ClampingScrollPhysics(), + controller: _pageController, + onPageChanged: (i) { + FocusScope.of(context).unfocus(); + _selectIndex = i; + setState(() {}); + }, + children: const [ServerPage(), ConvertPage(), PingPage()], + ), + bottomNavigationBar: _buildBottom(context), + )); + } + + Widget _buildItem(int idx, NavigationItem item, bool isSelected) { + bool isDarkMode = Theme.of(context).brightness == Brightness.dark; + final width = _width / tabItems.length; + return AnimatedContainer( + duration: const Duration(milliseconds: 377), + curve: Curves.fastOutSlowIn, + height: 50, + width: isSelected ? width : width - 17, + decoration: BoxDecoration( + color: isSelected + ? isDarkMode + ? Colors.white12 + : Colors.black.withOpacity(0.07) + : Colors.transparent, + borderRadius: const BorderRadius.all(Radius.circular(50))), + child: IconButton( + icon: Icon(item.icon), + tooltip: item.title, + splashRadius: width / 3.3, + padding: const EdgeInsets.only(left: 17, right: 17), + onPressed: () { + setState(() { + _pageController.animateToPage(idx, + duration: const Duration(milliseconds: 677), + curve: Curves.fastLinearToSlowEaseIn); + }); + }, ), - drawer: _buildDrawer(), - body: TabBarView(controller: _tabController, children: [ - ServerPage(_tabController), - const ConvertPage(), - const PingPage() - ]), ); } + Widget _buildBottom(BuildContext context) { + return SafeArea( + child: Container( + height: 56, + padding: const EdgeInsets.only(left: 8, top: 4, bottom: 4, right: 8), + width: _width, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: tabItems.map((item) { + int itemIndex = tabItems.indexOf(item); + return _buildItem(itemIndex, item, _selectIndex == itemIndex); + }).toList(), + ), + )); + } + Widget _buildDrawer() { - return Drawer( - child: ListView( - padding: EdgeInsets.zero, + return SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - UserAccountsDrawerHeader( - accountName: const Text(BuildData.name), - accountEmail: Text(_buildVersionStr()), - currentAccountPicture: _buildIcon(), + _buildIcon(), + const Text(BuildData.name), + Text(_buildVersionStr()), + SizedBox( + height: MediaQuery.of(context).size.height * 0.07, ), ListTile( leading: const Icon(Icons.settings), @@ -149,9 +241,19 @@ class _MyHomePageState extends State } Widget _buildIcon() { - return ConstrainedBox( - constraints: const BoxConstraints(maxHeight: 60, maxWidth: 60), - child: appIcon, + return Stack( + alignment: Alignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 53, maxWidth: 53), + child: Container( + color: primaryColor, + )), + ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 83, maxWidth: 83), + child: appIcon, + ) + ], ); } diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 6a8f1fa1..5e598423 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -7,6 +7,7 @@ import 'package:marquee/marquee.dart'; import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:toolbox/core/route.dart'; +import 'package:toolbox/core/utils.dart'; import 'package:toolbox/data/model/server/server.dart'; import 'package:toolbox/data/model/server/server_connection_state.dart'; import 'package:toolbox/data/model/server/server_private_info.dart'; @@ -21,8 +22,7 @@ import 'package:toolbox/view/page/snippet/list.dart'; import 'package:toolbox/view/widget/round_rect_card.dart'; class ServerPage extends StatefulWidget { - final TabController tabController; - const ServerPage(this.tabController, {Key? key}) : super(key: key); + const ServerPage({Key? key}) : super(key: key); @override _ServerPageState createState() => _ServerPageState(); @@ -50,9 +50,6 @@ class _ServerPageState extends State _media = MediaQuery.of(context); _theme = Theme.of(context); _primaryColor = primaryColor; - if (widget.tabController.index == 0) { - FocusScope.of(context).unfocus(); - } } @override @@ -207,11 +204,10 @@ class _ServerPageState extends State onChanged: (value) { final item = value as MenuItem; switch (item) { - case MenuItems.sftp: - //Do something - break; case MenuItems.apt: - //Do something + case MenuItems.sftp: + showSnackBar( + context, const Text('Now is not supported')); break; case MenuItems.snippet: AppRoute( @@ -404,7 +400,7 @@ class MenuItems { static const List firstItems = [sftp, snippet, apt]; static const List secondItems = [edit]; - static const sftp = MenuItem(text: 'SFTP', icon: Icons.hardware); + static const sftp = MenuItem(text: 'SFTP', icon: Icons.file_present); static const snippet = MenuItem(text: 'Snippet', icon: Icons.label); static const apt = MenuItem(text: 'Apt', icon: Icons.system_security_update); static const edit = MenuItem(text: 'Edit', icon: Icons.settings); diff --git a/make.dart b/make.dart index 25a6c02f..91ba4143 100755 --- a/make.dart +++ b/make.dart @@ -68,7 +68,7 @@ Future updateBuildData() async { } void dartFormat() { - final result = Process.runSync('dart', ['format', './*.dart']); + final result = Process.runSync('dart', ['format', '.']); print(result.stdout); if (result.exitCode != 0) { print(result.stderr); diff --git a/pubspec.lock b/pubspec.lock index 42b9cb5f..7875b243 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -199,6 +199,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_advanced_drawer: + dependency: "direct main" + description: + name: flutter_advanced_drawer + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" flutter_icmp_ping: dependency: transitive description: @@ -328,13 +335,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" meta: dependency: transitive description: @@ -521,7 +521,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.3" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 11855c92..616eac6b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -57,6 +57,7 @@ dependencies: dart_ping: ^6.1.1 dart_ping_ios: ^1.0.0 dropdown_button2: ^1.1.1 + flutter_advanced_drawer: ^1.3.0 dev_dependencies: