Compare commits

...

2 Commits

Author SHA1 Message Date
Origuchi
2232bc009d 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>
2026-04-16 18:05:25 +08:00
dom
e778f2b463 correct reply field names
Signed-off-by: dom <githubaccount56556@proton.me>
2026-04-16 17:56:57 +08:00
12 changed files with 259 additions and 70 deletions

View File

@@ -8159,7 +8159,7 @@ class ReplyControl extends $pb.GeneratedMessage {
ReplyControl_EasterEggLabel? easterEggLabel,
$core.String? contextFeature,
ReplyControl_InsertEffect? insertEffect,
$core.int? translationSwitch,
TranslationSwitch? translationSwitch,
$core.bool? showTranslation,
}) {
final result = create();
@@ -8261,7 +8261,8 @@ class ReplyControl extends $pb.GeneratedMessage {
..aOS(35, _omitFieldNames ? '' : 'contextFeature')
..aOM<ReplyControl_InsertEffect>(36, _omitFieldNames ? '' : 'insertEffect',
subBuilder: ReplyControl_InsertEffect.create)
..aI(37, _omitFieldNames ? '' : 'translationSwitch')
..aE<TranslationSwitch>(37, _omitFieldNames ? '' : 'translationSwitch',
enumValues: TranslationSwitch.values)
..aOB(100, _omitFieldNames ? '' : 'showTranslation')
..hasRequiredFields = false;
@@ -8612,9 +8613,9 @@ class ReplyControl extends $pb.GeneratedMessage {
ReplyControl_InsertEffect ensureInsertEffect() => $_ensure(35);
@$pb.TagNumber(37)
$core.int get translationSwitch => $_getIZ(36);
TranslationSwitch get translationSwitch => $_getN(36);
@$pb.TagNumber(37)
set translationSwitch($core.int value) => $_setSignedInt32(36, value);
set translationSwitch(TranslationSwitch value) => $_setField(37, value);
@$pb.TagNumber(37)
$core.bool hasTranslationSwitch() => $_has(36);
@$pb.TagNumber(37)
@@ -14020,12 +14021,12 @@ class TranslateReplyReq extends $pb.GeneratedMessage {
factory TranslateReplyReq({
$fixnum.Int64? type,
$fixnum.Int64? oid,
$core.Iterable<$fixnum.Int64>? rpid,
$core.Iterable<$fixnum.Int64>? rpids,
}) {
final result = create();
if (type != null) result.type = type;
if (oid != null) result.oid = oid;
if (rpid != null) result.rpid.addAll(rpid);
if (rpids != null) result.rpids.addAll(rpids);
return result;
}
@@ -14045,7 +14046,7 @@ class TranslateReplyReq extends $pb.GeneratedMessage {
createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'type')
..aInt64(2, _omitFieldNames ? '' : 'oid')
..p<$fixnum.Int64>(3, _omitFieldNames ? '' : 'rpid', $pb.PbFieldType.K6)
..p<$fixnum.Int64>(3, _omitFieldNames ? '' : 'rpids', $pb.PbFieldType.K6)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
@@ -14086,16 +14087,16 @@ class TranslateReplyReq extends $pb.GeneratedMessage {
void clearOid() => $_clearField(2);
@$pb.TagNumber(3)
$pb.PbList<$fixnum.Int64> get rpid => $_getList(2);
$pb.PbList<$fixnum.Int64> get rpids => $_getList(2);
}
class TranslateReplyResp extends $pb.GeneratedMessage {
factory TranslateReplyResp({
$core.Iterable<$core.MapEntry<$fixnum.Int64, ReplyInfo>>? translatedReply,
$core.Iterable<$core.MapEntry<$fixnum.Int64, ReplyInfo>>? translatedReplies,
}) {
final result = create();
if (translatedReply != null)
result.translatedReply.addEntries(translatedReply);
if (translatedReplies != null)
result.translatedReplies.addEntries(translatedReplies);
return result;
}
@@ -14113,8 +14114,8 @@ class TranslateReplyResp extends $pb.GeneratedMessage {
package: const $pb.PackageName(
_omitMessageNames ? '' : 'bilibili.main.community.reply.v1'),
createEmptyInstance: create)
..m<$fixnum.Int64, ReplyInfo>(1, _omitFieldNames ? '' : 'translatedReply',
entryClassName: 'TranslateReplyResp.TranslatedReplyEntry',
..m<$fixnum.Int64, ReplyInfo>(1, _omitFieldNames ? '' : 'translatedReplies',
entryClassName: 'TranslateReplyResp.TranslatedRepliesEntry',
keyFieldType: $pb.PbFieldType.O6,
valueFieldType: $pb.PbFieldType.OM,
valueCreator: ReplyInfo.create,
@@ -14142,7 +14143,7 @@ class TranslateReplyResp extends $pb.GeneratedMessage {
static TranslateReplyResp? _defaultInstance;
@$pb.TagNumber(1)
$pb.PbMap<$fixnum.Int64, ReplyInfo> get translatedReply => $_getMap(0);
$pb.PbMap<$fixnum.Int64, ReplyInfo> get translatedReplies => $_getMap(0);
}
const $core.bool _omitFieldNames =

View File

@@ -194,6 +194,35 @@ class UserCallbackScene extends $pb.ProtobufEnum {
const UserCallbackScene._(super.value, super.name);
}
class TranslationSwitch extends $pb.ProtobufEnum {
static const TranslationSwitch TRANSLATION_SWITCH_UNSPECIFIED =
TranslationSwitch._(
0, _omitEnumNames ? '' : 'TRANSLATION_SWITCH_UNSPECIFIED');
static const TranslationSwitch TRANSLATION_SWITCH_UNSUPPORTED =
TranslationSwitch._(
1, _omitEnumNames ? '' : 'TRANSLATION_SWITCH_UNSUPPORTED');
static const TranslationSwitch TRANSLATION_SWITCH_SHOW_TRANSLATION =
TranslationSwitch._(
2, _omitEnumNames ? '' : 'TRANSLATION_SWITCH_SHOW_TRANSLATION');
static const TranslationSwitch TRANSLATION_SWITCH_SHOW_ORIGIN =
TranslationSwitch._(
3, _omitEnumNames ? '' : 'TRANSLATION_SWITCH_SHOW_ORIGIN');
static const $core.List<TranslationSwitch> values = <TranslationSwitch>[
TRANSLATION_SWITCH_UNSPECIFIED,
TRANSLATION_SWITCH_UNSUPPORTED,
TRANSLATION_SWITCH_SHOW_TRANSLATION,
TRANSLATION_SWITCH_SHOW_ORIGIN,
];
static final $core.List<TranslationSwitch?> _byValue =
$pb.ProtobufEnum.$_initByValueList(values, 3);
static TranslationSwitch? valueOf($core.int value) =>
value < 0 || value >= _byValue.length ? null : _byValue[value];
const TranslationSwitch._(super.value, super.name);
}
class AtGroup_Type extends $pb.ProtobufEnum {
static const AtGroup_Type AT_GROUP_TYPE_DEFAULT =
AtGroup_Type._(0, _omitEnumNames ? '' : 'AT_GROUP_TYPE_DEFAULT');

View File

@@ -133,6 +133,24 @@ final $typed_data.Uint8List userCallbackSceneDescriptor = $convert.base64Decode(
'ChFVc2VyQ2FsbGJhY2tTY2VuZRIcChhJbnNlcnRfVXNlckNhbGxiYWNrU2NlbmUQABIYChRSZW'
'NvbW1lbmRTdXBlcmJSZXBseRAB');
@$core.Deprecated('Use translationSwitchDescriptor instead')
const TranslationSwitch$json = {
'1': 'TranslationSwitch',
'2': [
{'1': 'TRANSLATION_SWITCH_UNSPECIFIED', '2': 0},
{'1': 'TRANSLATION_SWITCH_UNSUPPORTED', '2': 1},
{'1': 'TRANSLATION_SWITCH_SHOW_TRANSLATION', '2': 2},
{'1': 'TRANSLATION_SWITCH_SHOW_ORIGIN', '2': 3},
],
};
/// Descriptor for `TranslationSwitch`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List translationSwitchDescriptor = $convert.base64Decode(
'ChFUcmFuc2xhdGlvblN3aXRjaBIiCh5UUkFOU0xBVElPTl9TV0lUQ0hfVU5TUEVDSUZJRUQQAB'
'IiCh5UUkFOU0xBVElPTl9TV0lUQ0hfVU5TVVBQT1JURUQQARInCiNUUkFOU0xBVElPTl9TV0lU'
'Q0hfU0hPV19UUkFOU0xBVElPThACEiIKHlRSQU5TTEFUSU9OX1NXSVRDSF9TSE9XX09SSUdJTh'
'AD');
@$core.Deprecated('Use activityDescriptor instead')
const Activity$json = {
'1': 'Activity',
@@ -2861,7 +2879,8 @@ const ReplyControl$json = {
'1': 'translation_switch',
'3': 37,
'4': 1,
'5': 5,
'5': 14,
'6': '.bilibili.main.community.reply.v1.TranslationSwitch',
'10': 'translationSwitch'
},
{
@@ -2991,20 +3010,21 @@ final $typed_data.Uint8List replyControlDescriptor = $convert.base64Decode(
'aWxpLm1haW4uY29tbXVuaXR5LnJlcGx5LnYxLlJlcGx5Q29udHJvbC5FYXN0ZXJFZ2dMYWJlbF'
'IOZWFzdGVyRWdnTGFiZWwSJwoPY29udGV4dF9mZWF0dXJlGCMgASgJUg5jb250ZXh0RmVhdHVy'
'ZRJgCg1pbnNlcnRfZWZmZWN0GCQgASgLMjsuYmlsaWJpbGkubWFpbi5jb21tdW5pdHkucmVwbH'
'kudjEuUmVwbHlDb250cm9sLkluc2VydEVmZmVjdFIMaW5zZXJ0RWZmZWN0Ei0KEnRyYW5zbGF0'
'aW9uX3N3aXRjaBglIAEoBVIRdHJhbnNsYXRpb25Td2l0Y2gSKQoQc2hvd190cmFuc2xhdGlvbh'
'hkIAEoCFIPc2hvd1RyYW5zbGF0aW9uGkEKDkVhc3RlckVnZ0xhYmVsEhQKBWltYWdlGAEgASgJ'
'UgVpbWFnZRIZCghqdW1wX3VybBgCIAEoCVIHanVtcFVybBrXAQoLR3JhZGVSZWNvcmQSFAoFc2'
'NvcmUYASABKAVSBXNjb3JlElUKBXRleHRzGAIgAygLMj8uYmlsaWJpbGkubWFpbi5jb21tdW5p'
'dHkucmVwbHkudjEuUmVwbHlDb250cm9sLkdyYWRlUmVjb3JkLlRleHRSBXRleHRzGlsKBFRleH'
'QSEAoDcmF3GAEgASgJUgNyYXcSQQoFc3R5bGUYAiABKAsyKy5iaWxpYmlsaS5tYWluLmNvbW11'
'bml0eS5yZXBseS52MS5UZXh0U3R5bGVSBXN0eWxlGjwKDEluc2VydEVmZmVjdBIYCgdjb250ZW'
'50GAEgASgJUgdjb250ZW50EhIKBGljb24YAiABKAlSBGljb24a8QEKClZvdGVPcHRpb24SYgoK'
'bGFiZWxfa2luZBgBIAEoDjJDLmJpbGliaWxpLm1haW4uY29tbXVuaXR5LnJlcGx5LnYxLlJlcG'
'x5Q29udHJvbC5Wb3RlT3B0aW9uLkxhYmVsS2luZFIJbGFiZWxLaW5kEhIKBGRlc2MYAiABKAlS'
'BGRlc2MSEAoDaWR4GAMgASgDUgNpZHgSFwoHdm90ZV9pZBgEIAEoA1IGdm90ZUlkIkAKCUxhYm'
'VsS2luZBIVChFERUZBVUxUX0xhYmVsS2luZBAAEgcKA1JFRBABEggKBEJMVUUQAhIJCgVQTEFJ'
'ThAD');
'kudjEuUmVwbHlDb250cm9sLkluc2VydEVmZmVjdFIMaW5zZXJ0RWZmZWN0EmIKEnRyYW5zbGF0'
'aW9uX3N3aXRjaBglIAEoDjIzLmJpbGliaWxpLm1haW4uY29tbXVuaXR5LnJlcGx5LnYxLlRyYW'
'5zbGF0aW9uU3dpdGNoUhF0cmFuc2xhdGlvblN3aXRjaBIpChBzaG93X3RyYW5zbGF0aW9uGGQg'
'ASgIUg9zaG93VHJhbnNsYXRpb24aQQoORWFzdGVyRWdnTGFiZWwSFAoFaW1hZ2UYASABKAlSBW'
'ltYWdlEhkKCGp1bXBfdXJsGAIgASgJUgdqdW1wVXJsGtcBCgtHcmFkZVJlY29yZBIUCgVzY29y'
'ZRgBIAEoBVIFc2NvcmUSVQoFdGV4dHMYAiADKAsyPy5iaWxpYmlsaS5tYWluLmNvbW11bml0eS'
'5yZXBseS52MS5SZXBseUNvbnRyb2wuR3JhZGVSZWNvcmQuVGV4dFIFdGV4dHMaWwoEVGV4dBIQ'
'CgNyYXcYASABKAlSA3JhdxJBCgVzdHlsZRgCIAEoCzIrLmJpbGliaWxpLm1haW4uY29tbXVuaX'
'R5LnJlcGx5LnYxLlRleHRTdHlsZVIFc3R5bGUaPAoMSW5zZXJ0RWZmZWN0EhgKB2NvbnRlbnQY'
'ASABKAlSB2NvbnRlbnQSEgoEaWNvbhgCIAEoCVIEaWNvbhrxAQoKVm90ZU9wdGlvbhJiCgpsYW'
'JlbF9raW5kGAEgASgOMkMuYmlsaWJpbGkubWFpbi5jb21tdW5pdHkucmVwbHkudjEuUmVwbHlD'
'b250cm9sLlZvdGVPcHRpb24uTGFiZWxLaW5kUglsYWJlbEtpbmQSEgoEZGVzYxgCIAEoCVIEZG'
'VzYxIQCgNpZHgYAyABKANSA2lkeBIXCgd2b3RlX2lkGAQgASgDUgZ2b3RlSWQiQAoJTGFiZWxL'
'aW5kEhUKEURFRkFVTFRfTGFiZWxLaW5kEAASBwoDUkVEEAESCAoEQkxVRRACEgkKBVBMQUlOEA'
'M=');
@$core.Deprecated('Use replyExtraDescriptor instead')
const ReplyExtra$json = {
@@ -4593,35 +4613,35 @@ const TranslateReplyReq$json = {
'2': [
{'1': 'type', '3': 1, '4': 1, '5': 3, '10': 'type'},
{'1': 'oid', '3': 2, '4': 1, '5': 3, '10': 'oid'},
{'1': 'rpid', '3': 3, '4': 3, '5': 3, '10': 'rpid'},
{'1': 'rpids', '3': 3, '4': 3, '5': 3, '10': 'rpids'},
],
};
/// Descriptor for `TranslateReplyReq`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List translateReplyReqDescriptor = $convert.base64Decode(
'ChFUcmFuc2xhdGVSZXBseVJlcRISCgR0eXBlGAEgASgDUgR0eXBlEhAKA29pZBgCIAEoA1IDb2'
'lkEhIKBHJwaWQYAyADKANSBHJwaWQ=');
'lkEhQKBXJwaWRzGAMgAygDUgVycGlkcw==');
@$core.Deprecated('Use translateReplyRespDescriptor instead')
const TranslateReplyResp$json = {
'1': 'TranslateReplyResp',
'2': [
{
'1': 'translated_reply',
'1': 'translated_replies',
'3': 1,
'4': 3,
'5': 11,
'6':
'.bilibili.main.community.reply.v1.TranslateReplyResp.TranslatedReplyEntry',
'10': 'translatedReply'
'.bilibili.main.community.reply.v1.TranslateReplyResp.TranslatedRepliesEntry',
'10': 'translatedReplies'
},
],
'3': [TranslateReplyResp_TranslatedReplyEntry$json],
'3': [TranslateReplyResp_TranslatedRepliesEntry$json],
};
@$core.Deprecated('Use translateReplyRespDescriptor instead')
const TranslateReplyResp_TranslatedReplyEntry$json = {
'1': 'TranslatedReplyEntry',
const TranslateReplyResp_TranslatedRepliesEntry$json = {
'1': 'TranslatedRepliesEntry',
'2': [
{'1': 'key', '3': 1, '4': 1, '5': 3, '10': 'key'},
{
@@ -4638,8 +4658,8 @@ const TranslateReplyResp_TranslatedReplyEntry$json = {
/// Descriptor for `TranslateReplyResp`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List translateReplyRespDescriptor = $convert.base64Decode(
'ChJUcmFuc2xhdGVSZXBseVJlc3ASdAoQdHJhbnNsYXRlZF9yZXBseRgBIAMoCzJJLmJpbGliaW'
'xpLm1haW4uY29tbXVuaXR5LnJlcGx5LnYxLlRyYW5zbGF0ZVJlcGx5UmVzcC5UcmFuc2xhdGVk'
'UmVwbHlFbnRyeVIPdHJhbnNsYXRlZFJlcGx5Gm8KFFRyYW5zbGF0ZWRSZXBseUVudHJ5EhAKA2'
'tleRgBIAEoA1IDa2V5EkEKBXZhbHVlGAIgASgLMisuYmlsaWJpbGkubWFpbi5jb21tdW5pdHku'
'cmVwbHkudjEuUmVwbHlJbmZvUgV2YWx1ZToCOAE=');
'ChJUcmFuc2xhdGVSZXBseVJlc3ASegoSdHJhbnNsYXRlZF9yZXBsaWVzGAEgAygLMksuYmlsaW'
'JpbGkubWFpbi5jb21tdW5pdHkucmVwbHkudjEuVHJhbnNsYXRlUmVwbHlSZXNwLlRyYW5zbGF0'
'ZWRSZXBsaWVzRW50cnlSEXRyYW5zbGF0ZWRSZXBsaWVzGnEKFlRyYW5zbGF0ZWRSZXBsaWVzRW'
'50cnkSEAoDa2V5GAEgASgDUgNrZXkSQQoFdmFsdWUYAiABKAsyKy5iaWxpYmlsaS5tYWluLmNv'
'bW11bml0eS5yZXBseS52MS5SZXBseUluZm9SBXZhbHVlOgI4AQ==');

View File

@@ -159,7 +159,7 @@ abstract final class ReplyGrpc {
TranslateReplyReq(
type: type,
oid: oid,
rpid: [rpid],
rpids: [rpid],
),
TranslateReplyResp.fromBuffer,
);

View File

@@ -313,9 +313,6 @@ class LoginPageController extends GetxController
}
if (data['status'] == 2) {
SmartDialog.showToast(data['message']);
if (Platform.isLinux) {
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}}
String url = data['url']!;
@@ -520,7 +517,7 @@ class LoginPageController extends GetxController
case 0:
// login success
break;
case -105 when (!Platform.isLinux):
case -105:
String captureUrl = res['data']['url'];
Uri captureUri = Uri.parse(captureUrl);
captchaData.token = captureUri.queryParameters['recaptcha_token']!;

View File

@@ -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/init.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/utils/accounts/account.dart';
import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:get/get.dart';
class GeetestWebviewDialog extends StatelessWidget {
class GeetestWebviewDialog extends StatefulWidget {
const GeetestWebviewDialog(this.gt, this.challenge, {super.key});
final String gt;
final String challenge;
@override
State<GeetestWebviewDialog> createState() => _GeetestWebviewDialogState();
}
class _GeetestWebviewDialogState extends State<GeetestWebviewDialog> {
static const _geetestJsUri =
'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(
String gt,
String challenge,
@@ -62,9 +82,126 @@ class GeetestWebviewDialog extends StatelessWidget {
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
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(
title: const Text('验证码'),
content: SizedBox(
@@ -108,7 +245,8 @@ class GeetestWebviewDialog extends StatelessWidget {
);
},
onLoadStop: (ctr, _) async {
final config = await future;
final config = await _future;
if (!mounted) return;
if (config case Success(:final response)) {
ctr.evaluateJavascript(
source:

View File

@@ -1,4 +1,3 @@
import 'dart:io';
import 'dart:ui';
import 'package:PiliPlus/common/constants.dart';
@@ -380,7 +379,6 @@ class _LoginPageState extends State<LoginPage> {
Builder(
builder: (context) {
return PopupMenuButton(
enabled: !Platform.isLinux,
padding: EdgeInsets.zero,
tooltip:
'选择国际冠码,'
@@ -428,7 +426,6 @@ class _LoginPageState extends State<LoginPage> {
const SizedBox(width: 6),
Expanded(
child: TextField(
enabled: !Platform.isLinux,
controller: _loginPageCtr.telTextController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
@@ -460,7 +457,6 @@ class _LoginPageState extends State<LoginPage> {
children: [
Expanded(
child: TextField(
enabled: !Platform.isLinux,
controller: _loginPageCtr.smsCodeTextController,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.sms_outlined),
@@ -475,11 +471,9 @@ class _LoginPageState extends State<LoginPage> {
),
Obx(
() => TextButton.icon(
onPressed: !Platform.isLinux
? _loginPageCtr.smsSendCooldown > 0
? null
: _loginPageCtr.sendSmsCode
: null,
onPressed: _loginPageCtr.smsSendCooldown > 0
? null
: _loginPageCtr.sendSmsCode,
icon: const Icon(Icons.send),
label: Text(
_loginPageCtr.smsSendCooldown > 0
@@ -494,7 +488,7 @@ class _LoginPageState extends State<LoginPage> {
),
const SizedBox(height: 20),
OutlinedButton.icon(
onPressed: !Platform.isLinux ? _loginPageCtr.loginBySmsCode : null,
onPressed: _loginPageCtr.loginBySmsCode,
icon: const Icon(Icons.login),
label: const Text('登录'),
),

View File

@@ -404,7 +404,7 @@ class ReplyItemGrpc extends StatelessWidget {
rpid: replyItem.id,
);
if (res case Success(:final response)) {
final item = response.translatedReply[replyItem.id];
final item = response.translatedReplies[replyItem.id];
if (item != null && item.hasTranslatedContent()) {
replyControl.showTranslation = true;
replyItem.translatedContent = item.translatedContent;
@@ -477,7 +477,8 @@ class ReplyItemGrpc extends StatelessWidget {
),
),
const SizedBox(width: 2),
if (replyControl.translationSwitch == 2) ...[
if (replyControl.translationSwitch ==
.TRANSLATION_SWITCH_SHOW_TRANSLATION) ...[
_buildTranslateBtn(
context,
theme,

View File

@@ -493,10 +493,6 @@ abstract final class RequestUtils {
String vVoucher,
ValueChanged<String> onSuccess,
) async {
if (Platform.isLinux) {
return;
}
final res = await ValidateHttp.gaiaVgateRegister(vVoucher);
if (!res.isSuccess) {
res.toast();

View File

@@ -46,9 +46,9 @@ static void my_application_activate(GApplication *application) {
// if future cases occur).
const gboolean use_header_bar = [window]() -> gboolean {
if (g_file_test(
g_build_filename(g_get_user_data_dir(), "com.example.piliplus", "use_ssd", NULL),
G_FILE_TEST_EXISTS))
if (g_file_test(g_build_filename(g_get_user_data_dir(),
"com.example.piliplus", "use_ssd", NULL),
G_FILE_TEST_EXISTS))
return FALSE;
#ifdef GDK_WINDOWING_X11

View File

@@ -387,6 +387,15 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: "direct main"
description:

View File

@@ -79,6 +79,10 @@ dependencies:
# 浏览器
# webview_flutter: ^4.10.0
flutter_inappwebview: ^6.1.5
desktop_webview_window:
git:
url: https://github.com/Predidit/linux_webview_window
ref: main
# 解决sliver滑动不同步
# extended_nested_scroll_view: ^6.2.1
extended_nested_scroll_view: