add BottomNavigationBar/change dirs structure
This commit is contained in:
parent
034d825b74
commit
e6b1ff40be
@ -51,6 +51,10 @@ class DialogManager{
|
|||||||
static void register(BuildContext dialogContext){
|
static void register(BuildContext dialogContext){
|
||||||
_dialogContext = dialogContext;
|
_dialogContext = dialogContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drop(){
|
||||||
|
_dialogContext = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef BuildAlertDialog = Tuple3<Widget, Widget, List<Widget>> Function(
|
typedef BuildAlertDialog = Tuple3<Widget, Widget, List<Widget>> Function(
|
||||||
@ -83,7 +87,7 @@ Future<T?> showAlertDialog<T>(BuildAlertDialog build,
|
|||||||
DialogManager.register(context);
|
DialogManager.register(context);
|
||||||
return dialog;
|
return dialog;
|
||||||
});
|
});
|
||||||
DialogManager.reset();
|
DialogManager.drop();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:firebase_analytics/firebase_analytics.dart';
|
import 'package:firebase_analytics/firebase_analytics.dart';
|
||||||
import 'package:firebase_analytics/observer.dart';
|
import 'package:firebase_analytics/observer.dart';
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'model.dart';
|
import 'models/model.dart';
|
||||||
import 'home_page.dart';
|
import 'pages/home_page.dart';
|
||||||
import 'server_page.dart';
|
import 'pages/server_page.dart';
|
||||||
|
|
||||||
Future<Null> main() async {
|
Future<Null> main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
@ -37,7 +37,7 @@ class App extends StatelessWidget {
|
|||||||
primarySwatch: Colors.blue,
|
primarySwatch: Colors.blue,
|
||||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||||
),
|
),
|
||||||
home: HomePage(title: 'RustDesk'),
|
home: HomePage(),
|
||||||
routes: {
|
routes: {
|
||||||
"server_page": (context) => ServerPage(),
|
"server_page": (context) => ServerPage(),
|
||||||
},
|
},
|
||||||
|
@ -8,7 +8,7 @@ import 'dart:ui' as ui;
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'common.dart';
|
import '../common.dart';
|
||||||
import 'native_model.dart' if (dart.library.html) 'web_model.dart';
|
import 'native_model.dart' if (dart.library.html) 'web_model.dart';
|
||||||
|
|
||||||
class FfiModel with ChangeNotifier {
|
class FfiModel with ChangeNotifier {
|
@ -7,7 +7,7 @@ import 'package:device_info/device_info.dart';
|
|||||||
import 'package:package_info/package_info.dart';
|
import 'package:package_info/package_info.dart';
|
||||||
import 'package:external_path/external_path.dart';
|
import 'package:external_path/external_path.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'common.dart';
|
import '../common.dart';
|
||||||
|
|
||||||
class RgbaFrame extends Struct {
|
class RgbaFrame extends Struct {
|
||||||
@Uint32()
|
@Uint32()
|
@ -3,7 +3,7 @@ import 'dart:js' as js;
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'common.dart';
|
import '../common.dart';
|
||||||
import 'dart:html';
|
import 'dart:html';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
@ -1,22 +1,89 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/pages/server_page.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'common.dart';
|
import '../common.dart';
|
||||||
import 'model.dart';
|
import '../models/model.dart';
|
||||||
import 'remote_page.dart';
|
import 'remote_page.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
abstract class PageShape extends Widget {
|
||||||
HomePage({Key? key, required this.title}) : super(key: key);
|
final String title = "";
|
||||||
|
final Icon icon = Icon(null);
|
||||||
|
final List<Widget> appBarActions = [];
|
||||||
|
}
|
||||||
|
|
||||||
final String title;
|
class HomePage extends StatefulWidget {
|
||||||
|
HomePage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_HomePageState createState() => _HomePageState();
|
_HomePageState createState() => _HomePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
|
var _selectedIndex = 0;
|
||||||
|
final List<PageShape> _pages = [ConnectionPage(), ServerPage()];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: MyTheme.grayBg,
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
title: Text("RustDesk"),
|
||||||
|
actions: _pages.elementAt(_selectedIndex).appBarActions,
|
||||||
|
),
|
||||||
|
bottomNavigationBar: BottomNavigationBar(
|
||||||
|
items: _pages
|
||||||
|
.map((page) =>
|
||||||
|
BottomNavigationBarItem(icon: page.icon, label: page.title))
|
||||||
|
.toList(),
|
||||||
|
currentIndex: _selectedIndex,
|
||||||
|
type: BottomNavigationBarType.fixed,
|
||||||
|
selectedItemColor: MyTheme.accent,
|
||||||
|
unselectedItemColor: MyTheme.darkGray,
|
||||||
|
onTap: (index) => setState(() {
|
||||||
|
_selectedIndex = index;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
body: _pages.elementAt(_selectedIndex),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConnectionPage extends StatefulWidget implements PageShape {
|
||||||
|
ConnectionPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final icon = Icon(Icons.connected_tv);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final title = translate("Connection");
|
||||||
|
|
||||||
|
@override
|
||||||
|
final appBarActions = [
|
||||||
|
PopupMenuButton<String>(
|
||||||
|
itemBuilder: (context) => [
|
||||||
|
PopupMenuItem<String>(
|
||||||
|
child: Text(translate('ID Server')), value: 'id_server'),
|
||||||
|
PopupMenuItem<String>(
|
||||||
|
child: Text(translate('About') + ' RustDesk'), value: 'about')
|
||||||
|
],
|
||||||
|
onSelected: (value) {
|
||||||
|
if (value == 'id_server') {
|
||||||
|
showServer();
|
||||||
|
} else if (value == 'about') {
|
||||||
|
showAbout();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ConnectionPageState createState() => _ConnectionPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ConnectionPageState extends State<ConnectionPage> {
|
||||||
final _idController = TextEditingController();
|
final _idController = TextEditingController();
|
||||||
var _updateUrl = '';
|
var _updateUrl = '';
|
||||||
var _menuPos;
|
var _menuPos;
|
||||||
@ -36,83 +103,18 @@ class _HomePageState extends State<HomePage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Provider.of<FfiModel>(context);
|
Provider.of<FfiModel>(context);
|
||||||
if (_idController.text.isEmpty) _idController.text = FFI.getId();
|
if (_idController.text.isEmpty) _idController.text = FFI.getId();
|
||||||
// This method is rerun every time setState is called
|
return SingleChildScrollView(
|
||||||
return Scaffold(
|
child: Column(
|
||||||
backgroundColor: MyTheme.grayBg,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
appBar: AppBar(
|
mainAxisSize: MainAxisSize.max,
|
||||||
centerTitle: true,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
actions: [
|
children: <Widget>[
|
||||||
Ink(
|
getUpdateUI(),
|
||||||
child: InkWell(
|
getSearchBarUI(),
|
||||||
child: Padding(
|
Container(height: 12),
|
||||||
padding: const EdgeInsets.all(12),
|
getPeers(),
|
||||||
child: Icon(Icons.more_vert)),
|
]),
|
||||||
onTapDown: (e) {
|
);
|
||||||
var x = e.globalPosition.dx;
|
|
||||||
var y = e.globalPosition.dy;
|
|
||||||
this._menuPos = RelativeRect.fromLTRB(x, y, x, y);
|
|
||||||
},
|
|
||||||
onTap: () {
|
|
||||||
List<PopupMenuItem<String>> items = [];
|
|
||||||
items.add(PopupMenuItem<String>(
|
|
||||||
child: Text(translate('ID Server')),
|
|
||||||
value: 'id_server'));
|
|
||||||
if (isAndroid) {
|
|
||||||
items.add(PopupMenuItem<String>(
|
|
||||||
child: Text(translate('Share My Screen')),
|
|
||||||
value: 'server'));
|
|
||||||
}
|
|
||||||
items.add(PopupMenuItem<String>(
|
|
||||||
child: Text(translate('About') + ' RustDesk'),
|
|
||||||
value: 'about'));
|
|
||||||
() async {
|
|
||||||
var value = await showMenu<dynamic>(
|
|
||||||
context: context,
|
|
||||||
position: this._menuPos,
|
|
||||||
items: items,
|
|
||||||
elevation: 8,
|
|
||||||
);
|
|
||||||
if (value == 'id_server') {
|
|
||||||
showServer(context);
|
|
||||||
} else if (value == 'server') {
|
|
||||||
Navigator.pushNamed(context, "server_page");
|
|
||||||
} else if (value == 'about') {
|
|
||||||
showAbout(context);
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
}))
|
|
||||||
],
|
|
||||||
title: Text(widget.title),
|
|
||||||
),
|
|
||||||
body: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
_updateUrl.isEmpty
|
|
||||||
? SizedBox(height: 0)
|
|
||||||
: InkWell(
|
|
||||||
onTap: () async {
|
|
||||||
final url = _updateUrl + '.apk';
|
|
||||||
if (await canLaunch(url)) {
|
|
||||||
await launch(url);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
alignment: AlignmentDirectional.center,
|
|
||||||
width: double.infinity,
|
|
||||||
color: Colors.pinkAccent,
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 12),
|
|
||||||
child: Text(translate('Download new version'),
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontWeight: FontWeight.bold)))),
|
|
||||||
getSearchBarUI(),
|
|
||||||
Container(height: 12),
|
|
||||||
getPeers(),
|
|
||||||
]),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onConnect() {
|
void onConnect() {
|
||||||
@ -138,6 +140,26 @@ class _HomePageState extends State<HomePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget getUpdateUI() {
|
||||||
|
return _updateUrl.isEmpty
|
||||||
|
? SizedBox(height: 0)
|
||||||
|
: InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
final url = _updateUrl + '.apk';
|
||||||
|
if (await canLaunch(url)) {
|
||||||
|
await launch(url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
alignment: AlignmentDirectional.center,
|
||||||
|
width: double.infinity,
|
||||||
|
color: Colors.pinkAccent,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 12),
|
||||||
|
child: Text(translate('Download new version'),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white, fontWeight: FontWeight.bold))));
|
||||||
|
}
|
||||||
|
|
||||||
Widget getSearchBarUI() {
|
Widget getSearchBarUI() {
|
||||||
if (!FFI.ffiModel.initialized) {
|
if (!FFI.ffiModel.initialized) {
|
||||||
return Container();
|
return Container();
|
||||||
@ -305,7 +327,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showServer(BuildContext context) {
|
void showServer() {
|
||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
final id0 = FFI.getByName('option', 'custom-rendezvous-server');
|
final id0 = FFI.getByName('option', 'custom-rendezvous-server');
|
||||||
final relay0 = FFI.getByName('option', 'relay-server');
|
final relay0 = FFI.getByName('option', 'relay-server');
|
||||||
@ -355,7 +377,7 @@ void showServer(BuildContext context) {
|
|||||||
TextButton(
|
TextButton(
|
||||||
style: flatButtonStyle,
|
style: flatButtonStyle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
DialogManager.reset();
|
||||||
},
|
},
|
||||||
child: Text(translate('Cancel')),
|
child: Text(translate('Cancel')),
|
||||||
),
|
),
|
||||||
@ -373,7 +395,7 @@ void showServer(BuildContext context) {
|
|||||||
'option', '{"name": "relay-server", "value": "$relay"}');
|
'option', '{"name": "relay-server", "value": "$relay"}');
|
||||||
if (key != key0)
|
if (key != key0)
|
||||||
FFI.setByName('option', '{"name": "key", "value": "$key"}');
|
FFI.setByName('option', '{"name": "key", "value": "$key"}');
|
||||||
Navigator.pop(context);
|
DialogManager.reset();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(translate('OK')),
|
child: Text(translate('OK')),
|
||||||
@ -382,7 +404,7 @@ void showServer(BuildContext context) {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Null> showAbout(BuildContext context) async {
|
Future<Null> showAbout() async {
|
||||||
var version = await FFI.getVersion();
|
var version = await FFI.getVersion();
|
||||||
showAlertDialog(
|
showAlertDialog(
|
||||||
(setState) => Tuple3(
|
(setState) => Tuple3(
|
@ -8,9 +8,9 @@ import 'dart:ui' as ui;
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
import 'common.dart';
|
import '../common.dart';
|
||||||
import 'gestures.dart';
|
import '../gestures.dart';
|
||||||
import 'model.dart';
|
import '../models/model.dart';
|
||||||
|
|
||||||
final initText = '\1' * 1024;
|
final initText = '\1' * 1024;
|
||||||
|
|
@ -1,56 +1,59 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/main.dart';
|
import 'package:flutter_hbb/main.dart';
|
||||||
import 'package:flutter_hbb/model.dart';
|
import 'package:flutter_hbb/models/model.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'common.dart';
|
import '../common.dart';
|
||||||
import 'model.dart';
|
import 'home_page.dart';
|
||||||
|
import '../models/model.dart';
|
||||||
|
|
||||||
|
class ServerPage extends StatelessWidget implements PageShape {
|
||||||
|
@override
|
||||||
|
final title = "Share Screen";
|
||||||
|
|
||||||
|
@override
|
||||||
|
final icon = Icon(Icons.mobile_screen_share);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final appBarActions = [
|
||||||
|
PopupMenuButton<String>(
|
||||||
|
itemBuilder: (context) {
|
||||||
|
return [
|
||||||
|
PopupMenuItem(
|
||||||
|
child: Text(translate("Change ID")),
|
||||||
|
value: "changeID",
|
||||||
|
enabled: false,
|
||||||
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
child: Text("Set your own password"),
|
||||||
|
value: "changePW",
|
||||||
|
enabled: false,
|
||||||
|
)
|
||||||
|
];
|
||||||
|
},
|
||||||
|
onSelected: (value) => debugPrint("PopupMenuItem onSelected:$value"))
|
||||||
|
];
|
||||||
|
|
||||||
class ServerPage extends StatelessWidget {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
checkService();
|
checkService();
|
||||||
return ChangeNotifierProvider.value(
|
return ChangeNotifierProvider.value(
|
||||||
value: FFI.serverModel,
|
value: FFI.serverModel,
|
||||||
child: Scaffold(
|
child: SingleChildScrollView(
|
||||||
backgroundColor: MyTheme.grayBg,
|
child: Center(
|
||||||
appBar: AppBar(
|
child: Column(
|
||||||
centerTitle: true,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
title: const Text("Share My Screen"),
|
children: [
|
||||||
actions: [
|
ServerInfo(),
|
||||||
PopupMenuButton<String>(
|
PermissionChecker(),
|
||||||
itemBuilder: (context) {
|
ConnectionManager(),
|
||||||
return [
|
SizedBox.fromSize(size: Size(0, 15.0)), // Bottom padding
|
||||||
PopupMenuItem(
|
],
|
||||||
child: Text(translate("Change ID")),
|
),
|
||||||
value: "changeID",
|
),
|
||||||
enabled: false,
|
),
|
||||||
),
|
);
|
||||||
PopupMenuItem(
|
|
||||||
child: Text("Set your own password"),
|
|
||||||
value: "changePW",
|
|
||||||
enabled: false,
|
|
||||||
)
|
|
||||||
];
|
|
||||||
},
|
|
||||||
onSelected: (value) =>
|
|
||||||
debugPrint("PopupMenuItem onSelected:$value"))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: SingleChildScrollView(
|
|
||||||
child: Center(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
ServerInfo(),
|
|
||||||
PermissionChecker(),
|
|
||||||
ConnectionManager(),
|
|
||||||
SizedBox.fromSize(size: Size(0, 15.0)), // Bottom padding
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user