mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
New UI.
This commit is contained in:
13
README.md
13
README.md
@@ -9,10 +9,10 @@ A new Flutter project which provide a chart view to display server status data a
|
|||||||
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/server.jpg">
|
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/server.jpg">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/detail.jpg">
|
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/server_detail.jpg">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/ping.jpg">
|
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/server_edit.jpg">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -22,13 +22,20 @@ A new Flutter project which provide a chart view to display server status data a
|
|||||||
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/convert.jpg">
|
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/convert.jpg">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/drawer.jpg">
|
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/ping.jpg">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/setting.jpg">
|
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/setting.jpg">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img width="200px" src="https://raw.githubusercontent.com/LollipopKit/flutter_server_monitor_toolbox/main/screenshots/drawer.jpg">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
# Support
|
# Support
|
||||||
Status|Platform
|
Status|Platform
|
||||||
|
|||||||
8
lib/data/model/app/navigation_item.dart
Normal file
8
lib/data/model/app/navigation_item.dart
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class NavigationItem {
|
||||||
|
final IconData icon;
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
NavigationItem(this.icon, this.title);
|
||||||
|
}
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
class BuildData {
|
class BuildData {
|
||||||
static const String name = "ServerBox";
|
static const String name = "ServerBox";
|
||||||
static const int build = 91;
|
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 engine =
|
||||||
static const String buildAt = "2022-02-08 19:01:55.450937";
|
"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 int modifications = 3;
|
static const String buildAt = "2022-02-08 20:57:54.707031";
|
||||||
|
static const int modifications = 9;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,9 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:toolbox/data/model/app/navigation_item.dart';
|
||||||
|
|
||||||
final List<String> tabs = ['Servers', 'En/Decode', 'Ping'];
|
final List<String> tabs = ['Servers', 'En/Decode', 'Ping'];
|
||||||
|
final List<NavigationItem> tabItems = [
|
||||||
|
NavigationItem(Icons.computer, 'Server'),
|
||||||
|
NavigationItem(Icons.code, 'Convert'),
|
||||||
|
NavigationItem(Icons.network_check, 'Ping'),
|
||||||
|
];
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class _DebugPageState extends State<DebugPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar:
|
appBar:
|
||||||
AppBar(title: const Text('Terminal'), backgroundColor: Colors.black),
|
AppBar(title: const Text('App log'), backgroundColor: Colors.black),
|
||||||
body: _buildTerminal(context),
|
body: _buildTerminal(context),
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
import 'package:after_layout/after_layout.dart';
|
import 'package:after_layout/after_layout.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_advanced_drawer/flutter_advanced_drawer.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:toolbox/core/analysis.dart';
|
import 'package:toolbox/core/analysis.dart';
|
||||||
import 'package:toolbox/core/build_mode.dart';
|
import 'package:toolbox/core/build_mode.dart';
|
||||||
import 'package:toolbox/core/route.dart';
|
import 'package:toolbox/core/route.dart';
|
||||||
import 'package:toolbox/core/update.dart';
|
import 'package:toolbox/core/update.dart';
|
||||||
import 'package:toolbox/core/utils.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/provider/server.dart';
|
||||||
import 'package:toolbox/data/res/build_data.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/icon/common.dart';
|
||||||
import 'package:toolbox/data/res/tab.dart';
|
import 'package:toolbox/data/res/tab.dart';
|
||||||
import 'package:toolbox/data/res/url.dart';
|
import 'package:toolbox/data/res/url.dart';
|
||||||
@@ -36,23 +39,26 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
SingleTickerProviderStateMixin,
|
SingleTickerProviderStateMixin,
|
||||||
AfterLayoutMixin,
|
AfterLayoutMixin,
|
||||||
WidgetsBindingObserver {
|
WidgetsBindingObserver {
|
||||||
late final TabController _tabController;
|
|
||||||
late final ServerProvider _serverProvider;
|
late final ServerProvider _serverProvider;
|
||||||
|
late final PageController _pageController;
|
||||||
|
late final AdvancedDrawerController _advancedDrawerController;
|
||||||
|
late int _selectIndex;
|
||||||
|
late double _width;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_serverProvider = locator<ServerProvider>();
|
_serverProvider = locator<ServerProvider>();
|
||||||
WidgetsBinding.instance?.addObserver(this);
|
WidgetsBinding.instance?.addObserver(this);
|
||||||
_tabController = TabController(
|
_selectIndex = locator<SettingStore>().launchPage.fetch()!;
|
||||||
initialIndex: locator<SettingStore>().launchPage.fetch()!,
|
_pageController = PageController(initialPage: _selectIndex);
|
||||||
length: tabs.length,
|
_advancedDrawerController = AdvancedDrawerController();
|
||||||
vsync: this);
|
}
|
||||||
_tabController.addListener(() {
|
|
||||||
if (_tabController.index == 0) {
|
@override
|
||||||
FocusScope.of(context).unfocus();
|
void didChangeDependencies() {
|
||||||
}
|
super.didChangeDependencies();
|
||||||
});
|
_width = MediaQuery.of(context).size.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -77,37 +83,123 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
setTransparentNavigationBar(context);
|
setTransparentNavigationBar(context);
|
||||||
super.build(context);
|
super.build(context);
|
||||||
return Scaffold(
|
return AdvancedDrawer(
|
||||||
appBar: AppBar(
|
controller: _advancedDrawerController,
|
||||||
title: GestureDetector(
|
animationCurve: Curves.easeInOutCirc,
|
||||||
onLongPress: () =>
|
animationDuration: const Duration(milliseconds: 300),
|
||||||
AppRoute(const DebugPage(), 'Debug Page').go(context),
|
animateChildDecoration: true,
|
||||||
child: const Text(BuildData.name),
|
rtlOpening: false,
|
||||||
),
|
disabledGestures: true,
|
||||||
bottom: TabBar(
|
childDecoration: const BoxDecoration(
|
||||||
indicatorColor: widget.primaryColor,
|
// NOTICE: Uncomment if you want to add shadow behind the page.
|
||||||
tabs: tabs.map((e) => Tab(text: e)).toList(),
|
// Keep in mind that it may cause animation jerks.
|
||||||
controller: _tabController,
|
boxShadow: <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<AdvancedDrawerValue>(
|
||||||
|
valueListenable: _advancedDrawerController,
|
||||||
|
builder: (_, value, __) {
|
||||||
|
return AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 250),
|
||||||
|
child: Icon(
|
||||||
|
value.visible ? Icons.clear : Icons.menu,
|
||||||
|
key: ValueKey<bool>(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() {
|
Widget _buildDrawer() {
|
||||||
return Drawer(
|
return SafeArea(
|
||||||
child: ListView(
|
child: Column(
|
||||||
padding: EdgeInsets.zero,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
UserAccountsDrawerHeader(
|
_buildIcon(),
|
||||||
accountName: const Text(BuildData.name),
|
const Text(BuildData.name),
|
||||||
accountEmail: Text(_buildVersionStr()),
|
Text(_buildVersionStr()),
|
||||||
currentAccountPicture: _buildIcon(),
|
SizedBox(
|
||||||
|
height: MediaQuery.of(context).size.height * 0.07,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.settings),
|
leading: const Icon(Icons.settings),
|
||||||
@@ -149,9 +241,19 @@ class _MyHomePageState extends State<MyHomePage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildIcon() {
|
Widget _buildIcon() {
|
||||||
return ConstrainedBox(
|
return Stack(
|
||||||
constraints: const BoxConstraints(maxHeight: 60, maxWidth: 60),
|
alignment: Alignment.center,
|
||||||
child: appIcon,
|
children: [
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxHeight: 53, maxWidth: 53),
|
||||||
|
child: Container(
|
||||||
|
color: primaryColor,
|
||||||
|
)),
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxHeight: 83, maxWidth: 83),
|
||||||
|
child: appIcon,
|
||||||
|
)
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'package:marquee/marquee.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
import 'package:toolbox/core/route.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.dart';
|
||||||
import 'package:toolbox/data/model/server/server_connection_state.dart';
|
import 'package:toolbox/data/model/server/server_connection_state.dart';
|
||||||
import 'package:toolbox/data/model/server/server_private_info.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';
|
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||||
|
|
||||||
class ServerPage extends StatefulWidget {
|
class ServerPage extends StatefulWidget {
|
||||||
final TabController tabController;
|
const ServerPage({Key? key}) : super(key: key);
|
||||||
const ServerPage(this.tabController, {Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_ServerPageState createState() => _ServerPageState();
|
_ServerPageState createState() => _ServerPageState();
|
||||||
@@ -50,9 +50,6 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
_media = MediaQuery.of(context);
|
_media = MediaQuery.of(context);
|
||||||
_theme = Theme.of(context);
|
_theme = Theme.of(context);
|
||||||
_primaryColor = primaryColor;
|
_primaryColor = primaryColor;
|
||||||
if (widget.tabController.index == 0) {
|
|
||||||
FocusScope.of(context).unfocus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -207,11 +204,10 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
final item = value as MenuItem;
|
final item = value as MenuItem;
|
||||||
switch (item) {
|
switch (item) {
|
||||||
case MenuItems.sftp:
|
|
||||||
//Do something
|
|
||||||
break;
|
|
||||||
case MenuItems.apt:
|
case MenuItems.apt:
|
||||||
//Do something
|
case MenuItems.sftp:
|
||||||
|
showSnackBar(
|
||||||
|
context, const Text('Now is not supported'));
|
||||||
break;
|
break;
|
||||||
case MenuItems.snippet:
|
case MenuItems.snippet:
|
||||||
AppRoute(
|
AppRoute(
|
||||||
@@ -404,7 +400,7 @@ class MenuItems {
|
|||||||
static const List<MenuItem> firstItems = [sftp, snippet, apt];
|
static const List<MenuItem> firstItems = [sftp, snippet, apt];
|
||||||
static const List<MenuItem> secondItems = [edit];
|
static const List<MenuItem> 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 snippet = MenuItem(text: 'Snippet', icon: Icons.label);
|
||||||
static const apt = MenuItem(text: 'Apt', icon: Icons.system_security_update);
|
static const apt = MenuItem(text: 'Apt', icon: Icons.system_security_update);
|
||||||
static const edit = MenuItem(text: 'Edit', icon: Icons.settings);
|
static const edit = MenuItem(text: 'Edit', icon: Icons.settings);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ Future<void> updateBuildData() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dartFormat() {
|
void dartFormat() {
|
||||||
final result = Process.runSync('dart', ['format', './*.dart']);
|
final result = Process.runSync('dart', ['format', '.']);
|
||||||
print(result.stdout);
|
print(result.stdout);
|
||||||
if (result.exitCode != 0) {
|
if (result.exitCode != 0) {
|
||||||
print(result.stderr);
|
print(result.stderr);
|
||||||
|
|||||||
16
pubspec.lock
16
pubspec.lock
@@ -199,6 +199,13 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
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:
|
flutter_icmp_ping:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -328,13 +335,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.11"
|
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:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -521,7 +521,7 @@ packages:
|
|||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.8"
|
version: "0.4.3"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ dependencies:
|
|||||||
dart_ping: ^6.1.1
|
dart_ping: ^6.1.1
|
||||||
dart_ping_ios: ^1.0.0
|
dart_ping_ios: ^1.0.0
|
||||||
dropdown_button2: ^1.1.1
|
dropdown_button2: ^1.1.1
|
||||||
|
flutter_advanced_drawer: ^1.3.0
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user