mod: use inappwebview

This commit is contained in:
bggRGjQaUbCoE
2024-09-06 17:58:08 +08:00
parent c5e7943c54
commit 365d2bc643
24 changed files with 310 additions and 43 deletions

View File

@@ -114,7 +114,7 @@ class VideoCardV extends StatelessWidget {
default:
SmartDialog.showToast(videoItem.goto);
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': videoItem.uri,
'type': 'url',

View File

@@ -120,7 +120,7 @@ class DynamicsController extends GetxController
});
} else {
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': 'https:$url',
'type': 'note',

View File

@@ -96,7 +96,7 @@ InlineSpan richNode(item, context) {
child: GestureDetector(
onTap: () {
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': i.origText,
'type': 'url',
@@ -122,7 +122,7 @@ InlineSpan richNode(item, context) {
try {
String dynamicId = item.basic['comment_id_str'];
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url':
'https://t.bilibili.com/vote/h5/index/#/result?vote_id=${i.rid}&dynamic_id=$dynamicId&isWeb=1',

View File

@@ -46,7 +46,7 @@ class HistoryItem extends StatelessWidget {
// videoItem.history.oid ??
await SearchHttp.ab2c(aid: aid, bvid: bvid);
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': 'https://www.bilibili.com/read/cv$cid',
'type': 'note',

View File

@@ -148,7 +148,7 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
IconButton(
tooltip: '用内置浏览器打开',
onPressed: () {
Get.toNamed('/webview', parameters: {
Get.toNamed('/webviewnew', parameters: {
'url': url.startsWith('http') ? url : 'https:$url',
'type': 'url',
'pageTitle': title,
@@ -174,7 +174,7 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
),
PopupMenuItem(
onTap: () => {
Get.toNamed('/webview', parameters: {
Get.toNamed('/webviewnew', parameters: {
'url': url.startsWith('http') ? url : 'https:$url',
'type': 'url',
'pageTitle': title,

View File

@@ -4,7 +4,6 @@ import 'package:PiliPalaX/http/live.dart';
import 'package:PiliPalaX/models/live/room_info.dart';
import 'package:PiliPalaX/plugin/pl_player/index.dart';
import '../../models/live/room_info_h5.dart';
import '../../utils/storage.dart';
import '../../utils/video_utils.dart';
class LiveRoomController extends GetxController {

View File

@@ -179,7 +179,7 @@ class _LiveRoomPageState extends State<LiveRoomPage> {
tooltip: '内置浏览器打开',
onPressed: () {
Get.offNamed(
'/webview',
'/webviewnew',
parameters: {
'url':
'https://live.bilibili.com/h5/${_liveRoomController.roomId}',

View File

@@ -202,6 +202,7 @@ class _LoginPageState extends State<LoginPage> {
context: context,
builder: (context) {
return SimpleDialog(
clipBehavior: Clip.hardEdge,
title: const Text('忘记密码?'),
contentPadding:
const EdgeInsets.fromLTRB(0.0, 2.0, 0.0, 16.0),
@@ -220,7 +221,7 @@ class _LoginPageState extends State<LoginPage> {
dense: false,
onTap: () async {
Get.back();
Get.toNamed('/webview', parameters: {
Get.toNamed('/webviewnew', parameters: {
'url':
'https://passport.bilibili.com/h5-app/passport/login/findPassword',
'type': 'url',
@@ -238,7 +239,7 @@ class _LoginPageState extends State<LoginPage> {
dense: false,
onTap: () async {
Get.back();
Get.toNamed('/webview', parameters: {
Get.toNamed('/webviewnew', parameters: {
'url':
'https://passport.bilibili.com/pc/passport/findPassword',
'type': 'url',

View File

@@ -36,11 +36,11 @@ class MediaController extends GetxController {
{
'icon': Icons.create_outlined,
'title': '创作中心(web)',
'onTap': () => Get.toNamed('/webview', parameters: {
'url': 'https://member.bilibili.com/platform/home',
'type': 'url',
'pageTitle': "创作中心(建议浏览器打开)",
}),
'onTap': () => Get.toNamed('/webviewnew', parameters: {
'url': 'https://member.bilibili.com/platform/home',
'type': 'url',
'pageTitle': "创作中心(建议浏览器打开)",
}),
},
];
var userInfo;

View File

@@ -239,7 +239,7 @@ class ProfilePanel extends StatelessWidget {
if (ctr.ownerMid == ctr.mid && ctr.ownerMid != -1) ...[
TextButton(
onPressed: () {
Get.toNamed('/webview', parameters: {
Get.toNamed('/webviewnew', parameters: {
'url': 'https://account.bilibili.com/account/home',
'pageTitle': '个人中心(建议浏览器打开)',
'type': 'url'

View File

@@ -38,7 +38,7 @@ class MineController extends GetxController {
onLogin() async {
if (!userLogin.value) {
// Get.toNamed(
// '/webview',
// '/webviewnew',
// parameters: {
// 'url': 'https://passport.bilibili.com/h5-app/passport/login',
// 'type': 'login',

View File

@@ -144,7 +144,7 @@ class IntroDetail extends StatelessWidget {
// 处理点击事件
try {
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': match.group(0)!,
'type': 'url',

View File

@@ -625,7 +625,7 @@ InlineSpan buildContent(
),
recognizer: TapGestureRecognizer()
..onTap = () => Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': content.vote['url'],
'type': 'vote',
@@ -814,7 +814,7 @@ InlineSpan buildContent(
// );
// } else {
// Get.toNamed(
// '/webview',
// '/webviewnew',
// parameters: {
// 'url': redirectUrl,
// 'type': 'url',
@@ -841,7 +841,7 @@ InlineSpan buildContent(
);
} else {
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': redirectUrl,
'type': 'url',
@@ -851,7 +851,7 @@ InlineSpan buildContent(
}
} else {
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': matchStr,
'type': 'url',
@@ -922,7 +922,7 @@ InlineSpan buildContent(
recognizer: TapGestureRecognizer()
..onTap = () {
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': patternStr,
'type': 'url',
@@ -1074,7 +1074,7 @@ InlineSpan buildContent(
),
recognizer: TapGestureRecognizer()
..onTap = () => Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': content.richText['note']['click_url'],
'type': 'note',
@@ -1100,11 +1100,10 @@ class MorePanel extends StatelessWidget {
case 'report':
Get.back();
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url':
'https://www.bilibili.com/h5/comment/report?mid=${item.mid}&oid=${item.oid}&pageType=1&rpid=${item.rpid}&platform=android',
'type': 'url',
},
);
break;

View File

@@ -6,7 +6,6 @@ import 'package:PiliPalaX/models/video/ai.dart';
import 'package:PiliPalaX/pages/video/detail/index.dart';
import 'package:PiliPalaX/utils/utils.dart';
class AiDetail extends StatelessWidget {
final ModelResult? modelResult;
@@ -185,7 +184,7 @@ class AiDetail extends StatelessWidget {
// 处理点击事件
try {
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': match.group(0)!,
'type': 'url',

View File

@@ -0,0 +1,193 @@
import 'dart:async';
import 'package:PiliPalaX/http/init.dart';
import 'package:PiliPalaX/utils/id_utils.dart';
import 'package:PiliPalaX/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
// ignore: constant_identifier_names
enum WebviewMenuItem { Refresh, Copy, Open_In_Browser, Clear_Cache, Go_Back }
class WebviewPageNew extends StatefulWidget {
const WebviewPageNew({super.key});
@override
State<WebviewPageNew> createState() => _WebviewPageNewState();
}
class _WebviewPageNewState extends State<WebviewPageNew> {
final String _url = Get.parameters['url'] ?? '';
final uaType = Get.parameters['uaType'] ?? 'mob';
final _titleStream = StreamController<String?>();
final _progressStream = StreamController<double>();
InAppWebViewController? _webViewController;
@override
void dispose() {
_titleStream.close();
_progressStream.close();
_webViewController = null;
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
titleSpacing: 0,
title: StreamBuilder(
initialData: null,
stream: _titleStream.stream,
builder: (_, snapshot) => Text(
maxLines: 1,
snapshot.hasData ? snapshot.data! : _url,
overflow: TextOverflow.ellipsis,
),
),
bottom: PreferredSize(
preferredSize: Size.zero,
child: StreamBuilder(
initialData: 0.0,
stream: _progressStream.stream,
builder: (_, snapshot) => snapshot.data as double < 1
? LinearProgressIndicator(
value: snapshot.data as double,
)
: const SizedBox.shrink(),
),
),
actions: [
PopupMenuButton(
onSelected: (item) async {
switch (item) {
case WebviewMenuItem.Refresh:
_webViewController?.reload();
break;
case WebviewMenuItem.Copy:
WebUri? uri = await _webViewController?.getUrl();
if (uri != null) {
Utils.copyText(uri.toString());
}
break;
case WebviewMenuItem.Open_In_Browser:
WebUri? uri = await _webViewController?.getUrl();
if (uri != null) {
Utils.launchURL(uri.toString());
}
break;
case WebviewMenuItem.Clear_Cache:
try {
await InAppWebViewController.clearAllCache();
await _webViewController?.clearHistory();
SmartDialog.showToast('已清理');
} catch (e) {
SmartDialog.showToast(e.toString());
}
break;
case WebviewMenuItem.Go_Back:
if (await _webViewController?.canGoBack() == true) {
_webViewController?.goBack();
}
break;
}
},
itemBuilder: (context) => <PopupMenuEntry<WebviewMenuItem>>[
...WebviewMenuItem.values.sublist(0, 4).map(
(item) => PopupMenuItem(value: item, child: Text(item.name))),
const PopupMenuDivider(),
PopupMenuItem(
value: WebviewMenuItem.Go_Back,
child: Text(
WebviewMenuItem.Go_Back.name,
style:
TextStyle(color: Theme.of(context).colorScheme.error),
)),
],
)
],
),
body: SafeArea(
child: InAppWebView(
initialSettings: InAppWebViewSettings(
clearCache: true,
javaScriptEnabled: true,
forceDark: ForceDark.AUTO,
useHybridComposition: false,
algorithmicDarkeningAllowed: true,
useShouldOverrideUrlLoading: true,
userAgent: Request().headerUa(type: uaType),
mixedContentMode: MixedContentMode.MIXED_CONTENT_ALWAYS_ALLOW,
),
initialUrlRequest: URLRequest(url: WebUri.uri(Uri.parse(_url))),
onWebViewCreated: (InAppWebViewController controller) {
_webViewController = controller;
},
onProgressChanged: (controller, progress) {
_progressStream.add(progress / 100);
},
onTitleChanged: (controller, title) {
_titleStream.add(title);
},
onCloseWindow: (controller) => Get.back(),
onLoadStop: (controller, url) {
_webViewController?.evaluateJavascript(
source: '''
document.styleSheets[0].insertRule('div.open-app-btn.bili-btn-warp {display:none;}', 0);
document.styleSheets[0].insertRule('#app__display-area > div.control-panel {display:none;}', 0);
''',
);
_webViewController?.evaluateJavascript(
source: '''
document.querySelector('#internationalHeader').remove();
document.querySelector('#message-navbar').remove();
''',
);
},
shouldOverrideUrlLoading: (controller, navigationAction) async {
final String str = navigationAction.request.url!.pathSegments[0];
final Map matchRes = IdUtils.matchAvorBv(input: str);
final List matchKeys = matchRes.keys.toList();
if (matchKeys.isNotEmpty) {
if (matchKeys.first == 'BV') {
Get.offAndToNamed(
'/searchResult',
parameters: {'keyword': matchRes['BV']},
);
return NavigationActionPolicy.CANCEL;
}
}
var url = navigationAction.request.url!.toString();
if (!url.startsWith('http')) {
if (url.startsWith('bilibili://video/')) {
String str = Uri.parse(url).pathSegments[0];
Get.offAndToNamed(
'/searchResult',
parameters: {'keyword': str},
);
} else {
var snackBar = SnackBar(
content: const Text('当前网页将要打开外部链接,是否打开'),
showCloseIcon: true,
action: SnackBarAction(
label: '打开',
onPressed: () => Utils.launchURL(url),
),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
return NavigationActionPolicy.CANCEL;
}
return NavigationActionPolicy.ALLOW;
},
),
),
);
}
}

View File

@@ -57,7 +57,7 @@ class _WhisperPageState extends State<WhisperPage> {
color: Theme.of(context).colorScheme.primary),
tooltip: '用浏览器打开',
onPressed: () {
Get.toNamed('/webview', parameters: {
Get.toNamed('/webviewnew', parameters: {
'url': 'https://message.bilibili.com',
'type': 'whisper',
'pageTitle': '消息中心',

View File

@@ -84,8 +84,7 @@ class ChatItem extends StatelessWidget {
final String emojiKey = match[0]!;
print(emojiKey);
if (emojiMap.containsKey(emojiKey)) {
children.add(
WidgetSpan(
children.add(WidgetSpan(
child: NetworkImgLayer(
width: 18,
height: 18,
@@ -315,7 +314,7 @@ class ChatItem extends StatelessWidget {
}
} else {
SmartDialog.showToast('未匹配到 BV 号');
Get.toNamed('/webview',
Get.toNamed('/webviewnew',
arguments: {'url': i['jump_url']});
}
},

View File

@@ -1,5 +1,6 @@
// ignore_for_file: must_be_immutable
import 'package:PiliPalaX/pages/webview/webview_page.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
@@ -80,6 +81,7 @@ class Routes {
// ),
//
CustomGetPage(name: '/webview', page: () => const WebviewPage()),
CustomGetPage(name: '/webviewnew', page: () => const WebviewPageNew()),
// 设置
CustomGetPage(name: '/setting', page: () => const SettingPage()),
//

View File

@@ -103,7 +103,7 @@ class PiliScheme {
if (path.startsWith('/detail')) {
var opusId = path.split('/').last;
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': 'https://www.bilibili.com/opus/$opusId',
'type': 'url',
@@ -170,7 +170,7 @@ class PiliScheme {
void getToOpusWeb() {
var opusId = path.split('/').last;
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': 'https://m.bilibili.com/dynamic/$opusId',
'type': 'url',
@@ -214,7 +214,7 @@ class PiliScheme {
print(value);
SmartDialog.showToast('未知路径:$value,请截图反馈给开发者');
// Get.toNamed(
// '/webview',
// '/webviewnew',
// parameters: {
// 'url': value.dataString ?? "",
// 'type': 'url',
@@ -332,7 +332,7 @@ class PiliScheme {
);
} else {
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {'url': redirectUrl, 'type': 'url', 'pageTitle': ''},
);
}
@@ -396,7 +396,7 @@ class PiliScheme {
} else {
SmartDialog.showToast('未知路径或匹配错误:$value,先采用浏览器打开');
Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': value.toString(),
'type': 'url',

View File

@@ -65,7 +65,7 @@ class CacheManage {
}
// 缓存大小格式转换
String formatSize(double value) {
static String formatSize(double value) {
List<String> unitArr = ['B', 'K', 'M', 'G'];
int index = 0;
while (value > 1024) {

View File

@@ -53,7 +53,7 @@ class UrlUtils {
);
} else {
await Get.toNamed(
'/webview',
'/webviewnew',
parameters: {
'url': redirectUrl,
'type': 'url',

View File

@@ -9,6 +9,7 @@ import 'package:PiliPalaX/utils/storage.dart';
import 'package:crypto/crypto.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart';
@@ -21,6 +22,22 @@ import '../models/github/latest.dart';
class Utils {
static final Random random = Random();
static void copyText(String text) {
Clipboard.setData(ClipboardData(text: text));
SmartDialog.showToast('已复制');
}
static launchURL(String url) async {
try {
final Uri uri = Uri.parse(url);
if (!await launchUrl(uri)) {
SmartDialog.showToast('Could not launch $url');
}
} catch (e) {
SmartDialog.showToast(e.toString());
}
}
static Color get vipColor {
return GStorage.brightness == Brightness.light
? const Color(0xFFFF6699)