add BottomNavigationBar/change dirs structure

This commit is contained in:
csf 2022-02-28 18:29:25 +08:00
parent 034d825b74
commit e6b1ff40be
8 changed files with 169 additions and 140 deletions

View File

@ -51,6 +51,10 @@ class DialogManager{
static void register(BuildContext dialogContext){
_dialogContext = dialogContext;
}
static void drop(){
_dialogContext = null;
}
}
typedef BuildAlertDialog = Tuple3<Widget, Widget, List<Widget>> Function(
@ -83,7 +87,7 @@ Future<T?> showAlertDialog<T>(BuildAlertDialog build,
DialogManager.register(context);
return dialog;
});
DialogManager.reset();
DialogManager.drop();
return res;
}

View File

@ -4,9 +4,9 @@ import 'package:provider/provider.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart';
import 'package:firebase_core/firebase_core.dart';
import 'model.dart';
import 'home_page.dart';
import 'server_page.dart';
import 'models/model.dart';
import 'pages/home_page.dart';
import 'pages/server_page.dart';
Future<Null> main() async {
WidgetsFlutterBinding.ensureInitialized();
@ -37,7 +37,7 @@ class App extends StatelessWidget {
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(title: 'RustDesk'),
home: HomePage(),
routes: {
"server_page": (context) => ServerPage(),
},

View File

@ -8,7 +8,7 @@ import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:tuple/tuple.dart';
import 'dart:async';
import 'common.dart';
import '../common.dart';
import 'native_model.dart' if (dart.library.html) 'web_model.dart';
class FfiModel with ChangeNotifier {

View File

@ -7,7 +7,7 @@ import 'package:device_info/device_info.dart';
import 'package:package_info/package_info.dart';
import 'package:external_path/external_path.dart';
import 'package:flutter/services.dart';
import 'common.dart';
import '../common.dart';
class RgbaFrame extends Struct {
@Uint32()

View File

@ -3,7 +3,7 @@ import 'dart:js' as js;
import 'package:flutter/cupertino.dart';
import 'dart:convert';
import 'common.dart';
import '../common.dart';
import 'dart:html';
import 'dart:async';

View File

@ -1,22 +1,89 @@
import 'package:flutter/material.dart';
import 'package:flutter_hbb/pages/server_page.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:async';
import 'common.dart';
import 'model.dart';
import '../common.dart';
import '../models/model.dart';
import 'remote_page.dart';
class HomePage extends StatefulWidget {
HomePage({Key? key, required this.title}) : super(key: key);
abstract class PageShape extends Widget {
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
_HomePageState createState() => _HomePageState();
}
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();
var _updateUrl = '';
var _menuPos;
@ -36,83 +103,18 @@ class _HomePageState extends State<HomePage> {
Widget build(BuildContext context) {
Provider.of<FfiModel>(context);
if (_idController.text.isEmpty) _idController.text = FFI.getId();
// This method is rerun every time setState is called
return Scaffold(
backgroundColor: MyTheme.grayBg,
appBar: AppBar(
centerTitle: true,
actions: [
Ink(
child: InkWell(
child: Padding(
padding: const EdgeInsets.all(12),
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(),
]),
));
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
getUpdateUI(),
getSearchBarUI(),
Container(height: 12),
getPeers(),
]),
);
}
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() {
if (!FFI.ffiModel.initialized) {
return Container();
@ -305,7 +327,7 @@ class _HomePageState extends State<HomePage> {
}
}
void showServer(BuildContext context) {
void showServer() {
final formKey = GlobalKey<FormState>();
final id0 = FFI.getByName('option', 'custom-rendezvous-server');
final relay0 = FFI.getByName('option', 'relay-server');
@ -355,7 +377,7 @@ void showServer(BuildContext context) {
TextButton(
style: flatButtonStyle,
onPressed: () {
Navigator.pop(context);
DialogManager.reset();
},
child: Text(translate('Cancel')),
),
@ -373,7 +395,7 @@ void showServer(BuildContext context) {
'option', '{"name": "relay-server", "value": "$relay"}');
if (key != key0)
FFI.setByName('option', '{"name": "key", "value": "$key"}');
Navigator.pop(context);
DialogManager.reset();
}
},
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();
showAlertDialog(
(setState) => Tuple3(

View File

@ -8,9 +8,9 @@ import 'dart:ui' as ui;
import 'dart:async';
import 'package:tuple/tuple.dart';
import 'package:wakelock/wakelock.dart';
import 'common.dart';
import 'gestures.dart';
import 'model.dart';
import '../common.dart';
import '../gestures.dart';
import '../models/model.dart';
final initText = '\1' * 1024;

View File

@ -1,56 +1,59 @@
import 'dart:async';
import 'package:flutter/material.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 'common.dart';
import 'model.dart';
import '../common.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
Widget build(BuildContext context) {
checkService();
return ChangeNotifierProvider.value(
value: FFI.serverModel,
child: Scaffold(
backgroundColor: MyTheme.grayBg,
appBar: AppBar(
centerTitle: true,
title: const Text("Share My Screen"),
actions: [
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"))
],
),
body: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
ServerInfo(),
PermissionChecker(),
ConnectionManager(),
SizedBox.fromSize(size: Size(0, 15.0)), // Bottom padding
],
),
),
)));
value: FFI.serverModel,
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
ServerInfo(),
PermissionChecker(),
ConnectionManager(),
SizedBox.fromSize(size: Size(0, 15.0)), // Bottom padding
],
),
),
),
);
}
}