mirror of
https://github.com/wanghongenpin/proxypin.git
synced 2026-05-08 00:24:16 +08:00
fix china android secure keyboard (#296)
This commit is contained in:
@@ -99,7 +99,7 @@ class ProxyServer {
|
||||
///检查是否监听端口 没有监听则启动
|
||||
Future<void> startForCheck() async {
|
||||
try {
|
||||
var socket = await Socket.connect('127.0.0.1', port, timeout: const Duration(milliseconds: 100));
|
||||
var socket = await Socket.connect('127.0.0.1', port, timeout: const Duration(milliseconds: 150));
|
||||
socket.close();
|
||||
} catch (e) {
|
||||
await start();
|
||||
|
||||
@@ -80,7 +80,7 @@ class _CertHashPageState extends State<CertHashPage> {
|
||||
FilledButton.icon(
|
||||
onPressed: () {
|
||||
getSubjectName();
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
style: buttonStyle,
|
||||
icon: const Icon(Icons.play_arrow_rounded),
|
||||
|
||||
@@ -2,10 +2,13 @@ import 'dart:io';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_code_editor/flutter_code_editor.dart';
|
||||
import 'package:flutter_js/flutter_js.dart';
|
||||
import 'package:highlight/languages/javascript.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_highlight/themes/monokai-sublime.dart';
|
||||
import 'package:flutter_js/flutter_js.dart';
|
||||
import 'package:flutter_toastr/flutter_toastr.dart';
|
||||
import 'package:highlight/languages/javascript.dart';
|
||||
import 'package:proxypin/network/components/js/file.dart';
|
||||
import 'package:proxypin/network/components/js/md5.dart';
|
||||
|
||||
@@ -19,21 +22,31 @@ class JavaScript extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _JavaScriptState extends State<JavaScript> {
|
||||
static JavascriptRuntime flutterJs = getJavascriptRuntime();
|
||||
//重置环境
|
||||
static bool resetEnvironment = true;
|
||||
|
||||
static JavascriptRuntime? flutterJs;
|
||||
|
||||
late CodeController code;
|
||||
|
||||
List<Text> outLines = [];
|
||||
|
||||
ScrollController inputScrollController = ScrollController();
|
||||
ScrollController outputScrollController = ScrollController();
|
||||
|
||||
AppLocalizations get localizations => AppLocalizations.of(context)!;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (resetEnvironment || flutterJs == null) {
|
||||
flutterJs = getJavascriptRuntime();
|
||||
}
|
||||
// register channel callback
|
||||
final channelCallbacks = JavascriptRuntime.channelFunctionsRegistered[flutterJs.getEngineInstanceId()];
|
||||
final channelCallbacks = JavascriptRuntime.channelFunctionsRegistered[flutterJs!.getEngineInstanceId()];
|
||||
channelCallbacks!["ConsoleLog"] = consoleLog;
|
||||
Md5Bridge.registerMd5(flutterJs);
|
||||
FileBridge.registerFile(flutterJs);
|
||||
Md5Bridge.registerMd5(flutterJs!);
|
||||
FileBridge.registerFile(flutterJs!);
|
||||
|
||||
code = CodeController(language: javascript, text: 'console.log("Hello, World!")');
|
||||
}
|
||||
@@ -41,6 +54,12 @@ class _JavaScriptState extends State<JavaScript> {
|
||||
@override
|
||||
void dispose() {
|
||||
code.dispose();
|
||||
inputScrollController.dispose();
|
||||
outputScrollController.dispose();
|
||||
if (resetEnvironment) {
|
||||
flutterJs?.dispose();
|
||||
flutterJs = null;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -48,17 +67,18 @@ class _JavaScriptState extends State<JavaScript> {
|
||||
var level = args.removeAt(0);
|
||||
String output = args.join(' ');
|
||||
if (level == 'info') level = 'warn';
|
||||
outLines.add(Text(output, style: TextStyle(color: level == 'error' ? Colors.red : Colors.white, fontSize: 13)));
|
||||
setState(() {
|
||||
outLines.add(Text(output, style: TextStyle(color: level == 'error' ? Colors.red : Colors.white, fontSize: 13)));
|
||||
print(outLines);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Color primaryColor = Theme.of(context).colorScheme.primary;
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text("JavaScript", style: TextStyle(fontSize: 16)), centerTitle: true),
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: AppBar(title: const Text("JavaScript", style: TextStyle(fontSize: 16)), centerTitle: true),
|
||||
body: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
@@ -82,15 +102,16 @@ class _JavaScriptState extends State<JavaScript> {
|
||||
onPressed: () async {
|
||||
outLines.clear();
|
||||
//失去焦点
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
var jsResult = await flutterJs.evaluateAsync(code.text);
|
||||
FocusScope.of(context).unfocus();
|
||||
var jsResult = await flutterJs!.evaluateAsync(code.text);
|
||||
if (jsResult.isPromise || jsResult.rawResult is Future) {
|
||||
jsResult = await flutterJs.handlePromise(jsResult);
|
||||
jsResult = await flutterJs!.handlePromise(jsResult);
|
||||
}
|
||||
|
||||
if (jsResult.isError) {
|
||||
outLines.add(Text(jsResult.toString(), style: const TextStyle(color: Colors.red, fontSize: 13)));
|
||||
setState(() {});
|
||||
setState(() {
|
||||
outLines
|
||||
.add(Text(jsResult.toString(), style: const TextStyle(color: Colors.red, fontSize: 13)));
|
||||
});
|
||||
}
|
||||
},
|
||||
icon: const Icon(Icons.play_arrow_rounded),
|
||||
@@ -103,22 +124,85 @@ class _JavaScriptState extends State<JavaScript> {
|
||||
height: 320,
|
||||
child: CodeTheme(
|
||||
data: CodeThemeData(styles: monokaiSublimeTheme),
|
||||
child: SingleChildScrollView(
|
||||
child: CodeField(
|
||||
minLines: 16,
|
||||
textStyle: const TextStyle(fontSize: 12),
|
||||
controller: code,
|
||||
gutterStyle: const GutterStyle(width: 50, margin: 0),
|
||||
)))),
|
||||
child: Scrollbar(
|
||||
controller: inputScrollController,
|
||||
thumbVisibility: true,
|
||||
interactive: true,
|
||||
trackVisibility: true,
|
||||
thickness: 8,
|
||||
child: SingleChildScrollView(
|
||||
controller: inputScrollController,
|
||||
scrollDirection: Axis.vertical,
|
||||
child: CodeField(
|
||||
minLines: 16,
|
||||
background: Colors.grey.shade800,
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
textStyle: const TextStyle(fontSize: 13),
|
||||
controller: code,
|
||||
enableSuggestions: true,
|
||||
onTapOutside: (event) => FocusScope.of(context).unfocus(),
|
||||
gutterStyle: const GutterStyle(width: 50, margin: 0),
|
||||
))))),
|
||||
const SizedBox(height: 10),
|
||||
TextButton(onPressed: () {}, child: const Text("Output:", style: TextStyle(fontSize: 16))),
|
||||
Row(children: [
|
||||
Text("Output:", style: TextStyle(fontSize: 16, color: primaryColor, fontWeight: FontWeight.w500)),
|
||||
const SizedBox(width: 15),
|
||||
//copy
|
||||
IconButton(
|
||||
icon: Icon(Icons.copy, color: primaryColor, size: 18),
|
||||
onPressed: () {
|
||||
Clipboard.setData(ClipboardData(text: outLines.join("\n")));
|
||||
FlutterToastr.show(localizations.copied, context, duration: 3);
|
||||
}),
|
||||
]),
|
||||
Expanded(
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(10),
|
||||
color: Colors.black,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: outLines)))),
|
||||
color: Colors.grey.shade800,
|
||||
child: Scrollbar(
|
||||
controller: outputScrollController,
|
||||
thumbVisibility: true,
|
||||
trackVisibility: true,
|
||||
child: SingleChildScrollView(
|
||||
controller: outputScrollController,
|
||||
child: SelectionArea(
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: outLines)))))),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new widget for the fullscreen CodeField
|
||||
class FullScreenCodeField extends StatelessWidget {
|
||||
final CodeController code;
|
||||
|
||||
FullScreenCodeField({required this.code});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("FullScreen Code Editor"),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Expanded(
|
||||
child: CodeTheme(
|
||||
data: CodeThemeData(styles: monokaiSublimeTheme),
|
||||
child: CodeField(
|
||||
background: Colors.grey.shade800,
|
||||
minLines: 50,
|
||||
textStyle: const TextStyle(fontSize: 12),
|
||||
controller: code,
|
||||
gutterStyle: const GutterStyle(width: 50, margin: 0),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,12 @@ class _SocketLaunchState extends State<SocketLaunch> with WindowListener, Widget
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
if (widget.proxyServer.isRunning) {
|
||||
widget.proxyServer.startForCheck();
|
||||
}
|
||||
}
|
||||
|
||||
if (state == AppLifecycleState.detached) {
|
||||
logger.d('AppLifecycleState.detached');
|
||||
widget.onStop?.call();
|
||||
|
||||
@@ -470,7 +470,11 @@ class _ScriptEditState extends State<ScriptEdit> {
|
||||
CodeTheme(
|
||||
data: CodeThemeData(styles: monokaiSublimeTheme),
|
||||
child: SingleChildScrollView(
|
||||
child: CodeField(textStyle: const TextStyle(fontSize: 14), controller: script)))
|
||||
child: CodeField(
|
||||
textStyle: const TextStyle(fontSize: 13),
|
||||
enableSuggestions: true,
|
||||
onTapOutside: (event) => FocusScope.of(context).unfocus(),
|
||||
controller: script)))
|
||||
],
|
||||
))));
|
||||
}
|
||||
|
||||
@@ -33,7 +33,10 @@ dependencies:
|
||||
share_plus: ^10.1.1
|
||||
brotli: ^0.6.0
|
||||
flutter_js: ^0.8.1
|
||||
flutter_code_editor: ^0.3.2
|
||||
flutter_code_editor:
|
||||
git:
|
||||
url: https://github.com/wanghongenpin/flutter-code-editor.git
|
||||
ref: secure-keyboard
|
||||
flutter_desktop_context_menu: ^0.2.0
|
||||
file_picker: ^8.1.3
|
||||
file_selector: ^1.0.3
|
||||
|
||||
Reference in New Issue
Block a user