mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
add server page
This commit is contained in:
parent
39f7835df1
commit
6ca487e3e0
@ -97,6 +97,15 @@ MediaProjectionManager -> MediaProjection
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
### 3.获取音频输入
|
||||||
|
https://developer.android.google.cn/guide/topics/media/playback-capture?hl=zh-cn
|
||||||
|
|
||||||
|
目前谷歌只开放了Android10系统同步音频内录功能
|
||||||
|
10之前录音的时候会截取原本系统的音频输出
|
||||||
|
即 开启内录时候无法在手机上正常使用耳机扬声器输出
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
### 其他
|
### 其他
|
||||||
- Kotlin 与 compose 版本设置问题
|
- Kotlin 与 compose 版本设置问题
|
||||||
- https://stackoverflow.com/questions/67600344/jetpack-compose-on-kotlin-1-5-0
|
- https://stackoverflow.com/questions/67600344/jetpack-compose-on-kotlin-1-5-0
|
||||||
|
|||||||
@ -22,7 +22,6 @@ class HomePage extends StatefulWidget {
|
|||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
final _idController = TextEditingController();
|
final _idController = TextEditingController();
|
||||||
var _updateUrl = '';
|
var _updateUrl = '';
|
||||||
static const toAndroidChannel = MethodChannel("mChannel");
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -55,15 +54,21 @@ class _HomePageState extends State<HomePage> {
|
|||||||
items: [
|
items: [
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
child: Text(translate('ID Server')),
|
child: Text(translate('ID Server')),
|
||||||
|
value: 'id_server'),
|
||||||
|
PopupMenuItem<String>(
|
||||||
|
child: Text(translate('Share My Screen')),
|
||||||
value: 'server'),
|
value: 'server'),
|
||||||
|
// TODO only android
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
child: Text(translate('About') + ' RustDesk'),
|
child: Text(translate('About') + ' RustDesk'),
|
||||||
value: 'about'),
|
value: 'about'),
|
||||||
],
|
],
|
||||||
elevation: 8,
|
elevation: 8,
|
||||||
);
|
);
|
||||||
if (value == 'server') {
|
if (value == 'id_server') {
|
||||||
showServer(context);
|
showServer(context);
|
||||||
|
} else if (value == 'server') {
|
||||||
|
Navigator.pushNamed(context, "server_page");
|
||||||
} else if (value == 'about') {
|
} else if (value == 'about') {
|
||||||
showAbout(context);
|
showAbout(context);
|
||||||
}
|
}
|
||||||
@ -98,29 +103,9 @@ class _HomePageState extends State<HomePage> {
|
|||||||
fontWeight: FontWeight.bold)))),
|
fontWeight: FontWeight.bold)))),
|
||||||
getSearchBarUI(),
|
getSearchBarUI(),
|
||||||
getPeers(),
|
getPeers(),
|
||||||
ElevatedButton(onPressed:_toAndroidGetPer, child: Text("获取权限事件")),
|
|
||||||
ElevatedButton(onPressed:_toAndroidStartSer, child: Text("开启录屏服务")),
|
|
||||||
ElevatedButton(onPressed:_toAndroidStopSer, child: Text("停止录屏服务")),
|
|
||||||
ElevatedButton(onPressed:_toAndroidCheckInput, child: Text("检查输入权限")),
|
|
||||||
]),
|
]),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Future<Null> _toAndroidGetPer() async{
|
|
||||||
bool res = await toAndroidChannel.invokeMethod("getPer");
|
|
||||||
debugPrint("_toAndroidGetPer:$res");
|
|
||||||
}
|
|
||||||
Future<Null> _toAndroidStartSer() async{
|
|
||||||
bool res = await toAndroidChannel.invokeMethod("startSer");
|
|
||||||
debugPrint("_toAndroidStartSer:$res");
|
|
||||||
}
|
|
||||||
Future<Null> _toAndroidStopSer() async{
|
|
||||||
bool res = await toAndroidChannel.invokeMethod("stopSer");
|
|
||||||
debugPrint("_toAndroidStopSer:$res");
|
|
||||||
}
|
|
||||||
Future<Null> _toAndroidCheckInput() async{
|
|
||||||
bool res = await toAndroidChannel.invokeMethod("checkInput");
|
|
||||||
debugPrint("_toAndroidStopSer:$res");
|
|
||||||
}
|
|
||||||
|
|
||||||
void onConnect() {
|
void onConnect() {
|
||||||
var id = _idController.text.trim();
|
var id = _idController.text.trim();
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/server_page.dart';
|
||||||
import 'package:provider/provider.dart';
|
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';
|
||||||
@ -31,6 +32,9 @@ class App extends StatelessWidget {
|
|||||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||||
),
|
),
|
||||||
home: HomePage(title: 'RustDesk'),
|
home: HomePage(title: 'RustDesk'),
|
||||||
|
routes: {
|
||||||
|
"server_page":(context) => ServerPage(),
|
||||||
|
},
|
||||||
navigatorObservers: [
|
navigatorObservers: [
|
||||||
FirebaseAnalyticsObserver(analytics: analytics),
|
FirebaseAnalyticsObserver(analytics: analytics),
|
||||||
],
|
],
|
||||||
|
|||||||
218
lib/server_page.dart
Normal file
218
lib/server_page.dart
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_hbb/model.dart';
|
||||||
|
|
||||||
|
import 'common.dart';
|
||||||
|
|
||||||
|
class ServerPage extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_ServerPageState createState() => _ServerPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ServerPageState extends State<ServerPage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: MyTheme.grayBg,
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
title: const Text("Share My Screen"),
|
||||||
|
),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
ServerInfo(),
|
||||||
|
PermissionChecker(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServerInfo extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_ServerInfoState createState() => _ServerInfoState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ServerInfoState extends State<ServerInfo> {
|
||||||
|
var _passwdShow = true;
|
||||||
|
|
||||||
|
// TODO set ID / PASSWORD
|
||||||
|
var _serverId = "";
|
||||||
|
var _serverPasswd = "";
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_serverId = FFI.getByName("server_id");
|
||||||
|
_serverPasswd = FFI.getByName("server_password");
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return myCard(Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
readOnly: true,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 25.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: MyTheme.accent),
|
||||||
|
initialValue: _serverId,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
icon: const Icon(Icons.perm_identity),
|
||||||
|
labelText: '服务ID',
|
||||||
|
labelStyle:
|
||||||
|
TextStyle(fontWeight: FontWeight.bold, color: MyTheme.accent50),
|
||||||
|
),
|
||||||
|
onSaved: (String value) {},
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
readOnly: true,
|
||||||
|
obscureText: _passwdShow,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 25.0,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: MyTheme.accent),
|
||||||
|
initialValue: _serverPasswd,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
icon: const Icon(Icons.lock),
|
||||||
|
labelText: '密码',
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold, color: MyTheme.accent50),
|
||||||
|
suffix: IconButton(
|
||||||
|
icon: Icon(Icons.visibility),
|
||||||
|
onPressed: () {
|
||||||
|
debugPrint("icon btn");
|
||||||
|
setState(() {
|
||||||
|
_passwdShow = !_passwdShow;
|
||||||
|
});
|
||||||
|
})),
|
||||||
|
onSaved: (String value) {},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PermissionChecker extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_PermissionCheckerState createState() => _PermissionCheckerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PermissionCheckerState extends State<PermissionChecker> {
|
||||||
|
static const toAndroidChannel = MethodChannel("mChannel");
|
||||||
|
|
||||||
|
var videoOk = false;
|
||||||
|
var inputOk = false;
|
||||||
|
var audioOk = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return myCard(Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
cardTitle("权限列表"),
|
||||||
|
PermissionRow("视频权限", videoOk, _toAndroidGetPer),
|
||||||
|
const Divider(height: 0),
|
||||||
|
PermissionRow("音频权限", videoOk, () => {debugPrint("获取视频权限")}),
|
||||||
|
const Divider(height: 0),
|
||||||
|
PermissionRow("输入权限", inputOk, _toAndroidCheckInput),
|
||||||
|
const Divider(),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
TextButton.icon(
|
||||||
|
icon: Icon(Icons.play_arrow),
|
||||||
|
onPressed: _toAndroidStartSer,
|
||||||
|
label: Text("Start")),
|
||||||
|
TextButton.icon(
|
||||||
|
icon: Icon(Icons.stop),
|
||||||
|
onPressed: _toAndroidStopSer,
|
||||||
|
label: Text("Stop")),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Null> _toAndroidGetPer() async {
|
||||||
|
bool res = await toAndroidChannel.invokeMethod("getPer");
|
||||||
|
debugPrint("_toAndroidGetPer:$res");
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Null> _toAndroidStartSer() async {
|
||||||
|
bool res = await toAndroidChannel.invokeMethod("startSer");
|
||||||
|
debugPrint("_toAndroidStartSer:$res");
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Null> _toAndroidStopSer() async {
|
||||||
|
bool res = await toAndroidChannel.invokeMethod("stopSer");
|
||||||
|
debugPrint("_toAndroidStopSer:$res");
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Null> _toAndroidCheckInput() async {
|
||||||
|
bool res = await toAndroidChannel.invokeMethod("checkInput");
|
||||||
|
debugPrint("_toAndroidStopSer:$res");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PermissionRow extends StatelessWidget {
|
||||||
|
PermissionRow(this.name, this.isOk, this.onPressed);
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
final bool isOk;
|
||||||
|
final VoidCallback onPressed;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text.rich(TextSpan(children: [
|
||||||
|
TextSpan(
|
||||||
|
text: name + ":",
|
||||||
|
style: TextStyle(fontSize: 16.0, color: MyTheme.accent50)),
|
||||||
|
TextSpan(
|
||||||
|
text: isOk ? "已开启" : "未开启",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16.0, color: isOk ? Colors.green : Colors.red)),
|
||||||
|
])),
|
||||||
|
TextButton(
|
||||||
|
onPressed: onPressed,
|
||||||
|
child: const Text(
|
||||||
|
"去开启",
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget cardTitle(String text) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 5.0),
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'WorkSans',
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 25,
|
||||||
|
color: Color(0xFF00B6F0),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget myCard(Widget child) {
|
||||||
|
return Card(
|
||||||
|
margin: EdgeInsets.all(15.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 30.0),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user