mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-04-19 19:01:24 +08:00
use linux_webview_window to support linux geetest (#1889)
* use webview_all to support linux geetest * use desktop_webview_window to support linux geetest * remove previous change in my_application.cc * update --------- Co-authored-by: dom <githubaccount56556@proton.me>
This commit is contained in:
@@ -313,9 +313,6 @@ class LoginPageController extends GetxController
|
|||||||
}
|
}
|
||||||
if (data['status'] == 2) {
|
if (data['status'] == 2) {
|
||||||
SmartDialog.showToast(data['message']);
|
SmartDialog.showToast(data['message']);
|
||||||
if (Platform.isLinux) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// return;
|
// return;
|
||||||
//{"code":0,"message":"0","ttl":1,"data":{"status":2,"message":"本次登录环境存在风险, 需使用手机号进行验证或绑定","url":"https://passport.bilibili.com/h5-app/passport/risk/verify?tmp_token=9e785433940891dfa78f033fb7928181&request_id=e5a6d6480df04097870be56c6e60f7ef&source=risk","token_info":null,"cookie_info":null,"sso":null,"is_new":false,"is_tourist":false}}
|
//{"code":0,"message":"0","ttl":1,"data":{"status":2,"message":"本次登录环境存在风险, 需使用手机号进行验证或绑定","url":"https://passport.bilibili.com/h5-app/passport/risk/verify?tmp_token=9e785433940891dfa78f033fb7928181&request_id=e5a6d6480df04097870be56c6e60f7ef&source=risk","token_info":null,"cookie_info":null,"sso":null,"is_new":false,"is_tourist":false}}
|
||||||
String url = data['url']!;
|
String url = data['url']!;
|
||||||
@@ -520,7 +517,7 @@ class LoginPageController extends GetxController
|
|||||||
case 0:
|
case 0:
|
||||||
// login success
|
// login success
|
||||||
break;
|
break;
|
||||||
case -105 when (!Platform.isLinux):
|
case -105:
|
||||||
String captureUrl = res['data']['url'];
|
String captureUrl = res['data']['url'];
|
||||||
Uri captureUri = Uri.parse(captureUrl);
|
Uri captureUri = Uri.parse(captureUrl);
|
||||||
captchaData.token = captureUri.queryParameters['recaptcha_token']!;
|
captchaData.token = captureUri.queryParameters['recaptcha_token']!;
|
||||||
|
|||||||
@@ -1,24 +1,44 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert' show jsonDecode, jsonEncode;
|
||||||
|
import 'dart:io' show Platform, Directory, File;
|
||||||
|
|
||||||
import 'package:PiliPlus/http/browser_ua.dart';
|
import 'package:PiliPlus/http/browser_ua.dart';
|
||||||
import 'package:PiliPlus/http/init.dart';
|
import 'package:PiliPlus/http/init.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/main.dart';
|
import 'package:PiliPlus/main.dart';
|
||||||
import 'package:PiliPlus/utils/accounts/account.dart';
|
import 'package:PiliPlus/utils/accounts/account.dart';
|
||||||
|
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
class GeetestWebviewDialog extends StatelessWidget {
|
class GeetestWebviewDialog extends StatefulWidget {
|
||||||
const GeetestWebviewDialog(this.gt, this.challenge, {super.key});
|
const GeetestWebviewDialog(this.gt, this.challenge, {super.key});
|
||||||
|
|
||||||
final String gt;
|
final String gt;
|
||||||
final String challenge;
|
final String challenge;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<GeetestWebviewDialog> createState() => _GeetestWebviewDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
|
||||||
static const _geetestJsUri =
|
static const _geetestJsUri =
|
||||||
'https://static.geetest.com/static/js/fullpage.0.0.0.js';
|
'https://static.geetest.com/static/js/fullpage.0.0.0.js';
|
||||||
|
|
||||||
|
late final Future<LoadingState<String>> _future;
|
||||||
|
Webview? _linuxWebview;
|
||||||
|
late bool _linuxWebviewLoading = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_future = _getConfig(widget.gt, widget.challenge);
|
||||||
|
if (Platform.isLinux) {
|
||||||
|
_initLinuxWebview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future<LoadingState<String>> _getConfig(
|
static Future<LoadingState<String>> _getConfig(
|
||||||
String gt,
|
String gt,
|
||||||
String challenge,
|
String challenge,
|
||||||
@@ -62,9 +82,126 @@ class GeetestWebviewDialog extends StatelessWidget {
|
|||||||
return Error(res.data['message']);
|
return Error(res.data['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _initLinuxWebview() async {
|
||||||
|
final config = await _future;
|
||||||
|
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config is Error) {
|
||||||
|
config.toast();
|
||||||
|
Get.back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final response = (config as Success<String>).response;
|
||||||
|
|
||||||
|
_linuxWebview = await WebviewWindow.create(
|
||||||
|
configuration: const CreateConfiguration(
|
||||||
|
windowWidth: 300,
|
||||||
|
windowHeight: 400,
|
||||||
|
title: "验证码",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!mounted) {
|
||||||
|
_closeLinuxWebview();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_linuxWebview!.addOnWebMessageReceivedCallback((msg) {
|
||||||
|
final msgStr = msg.toString();
|
||||||
|
if (msgStr.startsWith("success:")) {
|
||||||
|
final dataStr = msgStr.substring("success:".length);
|
||||||
|
try {
|
||||||
|
final data = jsonDecode(dataStr);
|
||||||
|
Get.back(result: data);
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('geetest decode error: $e');
|
||||||
|
}
|
||||||
|
} else if (msgStr.startsWith("error:")) {
|
||||||
|
debugPrint('geetest error: $msgStr');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_linuxWebview!.onClose.whenComplete(() {
|
||||||
|
if (mounted) {
|
||||||
|
Get.back();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final html =
|
||||||
|
'''
|
||||||
|
<!DOCTYPE html><html><head></head><body>
|
||||||
|
<script src="$_geetestJsUri"></script>
|
||||||
|
<script>
|
||||||
|
function R(n,o){
|
||||||
|
window.webkit.messageHandlers.msgToNative.postMessage(n + ':' + JSON.stringify(o));
|
||||||
|
}
|
||||||
|
let t=Geetest($response).onSuccess(()=>R("success",t.getValidate())).onError((o)=>R("error",o));
|
||||||
|
t.onReady(()=>t.verify());
|
||||||
|
</script>
|
||||||
|
</body></html>
|
||||||
|
''';
|
||||||
|
|
||||||
|
final tempDir = Directory.systemTemp;
|
||||||
|
final file = File(
|
||||||
|
'${tempDir.path}/geetest_${DateTime.now().millisecondsSinceEpoch}.html',
|
||||||
|
);
|
||||||
|
await file.writeAsString(html);
|
||||||
|
|
||||||
|
if (!mounted) {
|
||||||
|
_closeLinuxWebview();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_linuxWebview!.launch('file://${file.path}');
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_linuxWebviewLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _closeLinuxWebview() {
|
||||||
|
_linuxWebview?.close();
|
||||||
|
_linuxWebview = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_closeLinuxWebview();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final future = _getConfig(gt, challenge);
|
if (Platform.isLinux) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('验证码'),
|
||||||
|
content: SizedBox(
|
||||||
|
width: 300,
|
||||||
|
height: 400,
|
||||||
|
child: Center(
|
||||||
|
child: _linuxWebviewLoading
|
||||||
|
? const CircularProgressIndicator()
|
||||||
|
: const Text('请在弹出的新窗口中完成验证'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: Get.back,
|
||||||
|
child: Text(
|
||||||
|
'取消',
|
||||||
|
style: TextStyle(color: ColorScheme.of(context).outline),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: const Text('验证码'),
|
title: const Text('验证码'),
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
@@ -108,7 +245,8 @@ class GeetestWebviewDialog extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
onLoadStop: (ctr, _) async {
|
onLoadStop: (ctr, _) async {
|
||||||
final config = await future;
|
final config = await _future;
|
||||||
|
if (!mounted) return;
|
||||||
if (config case Success(:final response)) {
|
if (config case Success(:final response)) {
|
||||||
ctr.evaluateJavascript(
|
ctr.evaluateJavascript(
|
||||||
source:
|
source:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import 'dart:io';
|
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:PiliPlus/common/constants.dart';
|
import 'package:PiliPlus/common/constants.dart';
|
||||||
@@ -380,7 +379,6 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
Builder(
|
Builder(
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return PopupMenuButton(
|
return PopupMenuButton(
|
||||||
enabled: !Platform.isLinux,
|
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
tooltip:
|
tooltip:
|
||||||
'选择国际冠码,'
|
'选择国际冠码,'
|
||||||
@@ -428,7 +426,6 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
enabled: !Platform.isLinux,
|
|
||||||
controller: _loginPageCtr.telTextController,
|
controller: _loginPageCtr.telTextController,
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
inputFormatters: <TextInputFormatter>[
|
inputFormatters: <TextInputFormatter>[
|
||||||
@@ -460,7 +457,6 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
enabled: !Platform.isLinux,
|
|
||||||
controller: _loginPageCtr.smsCodeTextController,
|
controller: _loginPageCtr.smsCodeTextController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
prefixIcon: Icon(Icons.sms_outlined),
|
prefixIcon: Icon(Icons.sms_outlined),
|
||||||
@@ -475,11 +471,9 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
),
|
),
|
||||||
Obx(
|
Obx(
|
||||||
() => TextButton.icon(
|
() => TextButton.icon(
|
||||||
onPressed: !Platform.isLinux
|
onPressed: _loginPageCtr.smsSendCooldown > 0
|
||||||
? _loginPageCtr.smsSendCooldown > 0
|
? null
|
||||||
? null
|
: _loginPageCtr.sendSmsCode,
|
||||||
: _loginPageCtr.sendSmsCode
|
|
||||||
: null,
|
|
||||||
icon: const Icon(Icons.send),
|
icon: const Icon(Icons.send),
|
||||||
label: Text(
|
label: Text(
|
||||||
_loginPageCtr.smsSendCooldown > 0
|
_loginPageCtr.smsSendCooldown > 0
|
||||||
@@ -494,7 +488,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
OutlinedButton.icon(
|
OutlinedButton.icon(
|
||||||
onPressed: !Platform.isLinux ? _loginPageCtr.loginBySmsCode : null,
|
onPressed: _loginPageCtr.loginBySmsCode,
|
||||||
icon: const Icon(Icons.login),
|
icon: const Icon(Icons.login),
|
||||||
label: const Text('登录'),
|
label: const Text('登录'),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -493,10 +493,6 @@ abstract final class RequestUtils {
|
|||||||
String vVoucher,
|
String vVoucher,
|
||||||
ValueChanged<String> onSuccess,
|
ValueChanged<String> onSuccess,
|
||||||
) async {
|
) async {
|
||||||
if (Platform.isLinux) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final res = await ValidateHttp.gaiaVgateRegister(vVoucher);
|
final res = await ValidateHttp.gaiaVgateRegister(vVoucher);
|
||||||
if (!res.isSuccess) {
|
if (!res.isSuccess) {
|
||||||
res.toast();
|
res.toast();
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ static void my_application_activate(GApplication *application) {
|
|||||||
// if future cases occur).
|
// if future cases occur).
|
||||||
|
|
||||||
const gboolean use_header_bar = [window]() -> gboolean {
|
const gboolean use_header_bar = [window]() -> gboolean {
|
||||||
if (g_file_test(
|
if (g_file_test(g_build_filename(g_get_user_data_dir(),
|
||||||
g_build_filename(g_get_user_data_dir(), "com.example.piliplus", "use_ssd", NULL),
|
"com.example.piliplus", "use_ssd", NULL),
|
||||||
G_FILE_TEST_EXISTS))
|
G_FILE_TEST_EXISTS))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
|
|||||||
@@ -387,6 +387,15 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.12"
|
version: "0.7.12"
|
||||||
|
desktop_webview_window:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "."
|
||||||
|
ref: main
|
||||||
|
resolved-ref: b429f8ba6b8a99cd0f7eb5fe8d1621f325635c3d
|
||||||
|
url: "https://github.com/Predidit/linux_webview_window"
|
||||||
|
source: git
|
||||||
|
version: "0.2.4"
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -79,6 +79,10 @@ dependencies:
|
|||||||
# 浏览器
|
# 浏览器
|
||||||
# webview_flutter: ^4.10.0
|
# webview_flutter: ^4.10.0
|
||||||
flutter_inappwebview: ^6.1.5
|
flutter_inappwebview: ^6.1.5
|
||||||
|
desktop_webview_window:
|
||||||
|
git:
|
||||||
|
url: https://github.com/Predidit/linux_webview_window
|
||||||
|
ref: main
|
||||||
# 解决sliver滑动不同步
|
# 解决sliver滑动不同步
|
||||||
# extended_nested_scroll_view: ^6.2.1
|
# extended_nested_scroll_view: ^6.2.1
|
||||||
extended_nested_scroll_view:
|
extended_nested_scroll_view:
|
||||||
|
|||||||
Reference in New Issue
Block a user