mirror of
https://github.com/BTMuli/TeyvatGuide.git
synced 2025-12-12 09:18:14 +08:00
♻️ 重构链接识别处理
This commit is contained in:
@@ -14,9 +14,9 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { toRaw } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
import { isMysPost } from "../../utils/toolFunc";
|
||||
import { parseLink } from "../../utils/linkParser";
|
||||
import showSnackbar from "../func/snackbar";
|
||||
|
||||
interface TpLinkCard {
|
||||
insert: {
|
||||
@@ -41,22 +41,22 @@ interface TpLinkCardProps {
|
||||
}
|
||||
|
||||
const props = defineProps<TpLinkCardProps>();
|
||||
const router = useRouter();
|
||||
|
||||
console.log("tpLinkCard", props.data.insert.link_card.card_id, toRaw(props.data).insert.link_card);
|
||||
|
||||
async function toLink() {
|
||||
const link = props.data.insert.link_card.landing_url;
|
||||
if (isMysPost(link)) {
|
||||
await router.push({
|
||||
name: "帖子详情",
|
||||
params: {
|
||||
post_id: link.split("/").pop(),
|
||||
},
|
||||
const res = await parseLink(link);
|
||||
if (res === true) return;
|
||||
if (res === false) {
|
||||
showSnackbar({
|
||||
text: `未知链接:${link}`,
|
||||
color: "error",
|
||||
timeout: 3000,
|
||||
});
|
||||
} else {
|
||||
window.open(link);
|
||||
return;
|
||||
}
|
||||
window.open(res);
|
||||
}
|
||||
</script>
|
||||
<style lang="css" scoped>
|
||||
|
||||
@@ -22,12 +22,10 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, StyleValue, toRaw } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
import { getEmojis } from "../../plugins/Mys/request/getEmojis";
|
||||
import TGClient from "../../utils/TGClient";
|
||||
import { isColorSimilar, isMysPost } from "../../utils/toolFunc";
|
||||
import showConfirm from "../func/confirm";
|
||||
import { parseLink } from "../../utils/linkParser";
|
||||
import { isColorSimilar } from "../../utils/toolFunc";
|
||||
import showSnackbar from "../func/snackbar";
|
||||
|
||||
interface TpText {
|
||||
@@ -46,7 +44,6 @@ interface TpTextProps {
|
||||
|
||||
const props = defineProps<TpTextProps>();
|
||||
const mode = ref<string>("text");
|
||||
const router = useRouter();
|
||||
const localEmojis = ref(localStorage.getItem("emojis"));
|
||||
const emojis = ref<TpText[]>([]);
|
||||
|
||||
@@ -122,46 +119,17 @@ async function toLink() {
|
||||
if (!props.data.attributes) return;
|
||||
if (!props.data.attributes.link) return;
|
||||
const link = props.data.attributes.link;
|
||||
if (isMysPost(link)) {
|
||||
await router.push({
|
||||
name: "帖子详情",
|
||||
params: {
|
||||
post_id: link.split("/").pop(),
|
||||
},
|
||||
const res = await parseLink(link);
|
||||
if (res === true) return;
|
||||
if (res === false) {
|
||||
showSnackbar({
|
||||
text: `未知链接:${link}`,
|
||||
color: "error",
|
||||
timeout: 3000,
|
||||
});
|
||||
} else if (isMysAct(link)) {
|
||||
const resOpen = await showConfirm({
|
||||
title: "采用内置 JSBridge?",
|
||||
text: "取消则使用外部浏览器打开",
|
||||
});
|
||||
if (resOpen) {
|
||||
const resType = await showConfirm({
|
||||
title: "采用宽屏模式?",
|
||||
text: "取消则使用默认竖屏",
|
||||
});
|
||||
if (resType) {
|
||||
await TGClient.open("web_act", link);
|
||||
} else {
|
||||
await TGClient.open("web_act_thin", link);
|
||||
}
|
||||
} else {
|
||||
window.open(link);
|
||||
}
|
||||
} else {
|
||||
window.open(props.data.attributes.link);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function isMysAct(url: string): boolean {
|
||||
const link = new URL(url);
|
||||
const prefix = ["act.mihoyo.com", "mhyurl.cn", "webstatic.mihoyo.com", "qaa.miyoushe.com"];
|
||||
if (prefix.includes(link.hostname)) {
|
||||
if (link.hostname == "webstatic.mihoyo.com") {
|
||||
return link.pathname.includes("event");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
window.open(res);
|
||||
}
|
||||
|
||||
// 解析表情链接
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
/**
|
||||
* @file utils/TGClient.ts
|
||||
* @desc 负责米游社客户端的 callback 处理
|
||||
* @since Beta v0.3.7
|
||||
* @since Beta v0.3.8
|
||||
*/
|
||||
|
||||
import { event, invoke } from "@tauri-apps/api";
|
||||
import type { Event } from "@tauri-apps/api/event";
|
||||
import { WebviewWindow } from "@tauri-apps/api/window";
|
||||
import { appWindow, WebviewWindow } from "@tauri-apps/api/window";
|
||||
|
||||
import { parseLink } from "./linkParser";
|
||||
import { getDeviceInfo } from "./toolFunc";
|
||||
import showSnackbar from "../components/func/snackbar";
|
||||
import { useAppStore } from "../store/modules/app";
|
||||
import { useUserStore } from "../store/modules/user";
|
||||
import TGConstant from "../web/constant/TGConstant";
|
||||
@@ -29,7 +31,7 @@ interface InvokeArg {
|
||||
|
||||
/**
|
||||
* @class TGClient
|
||||
* @since Beta v0.3.7
|
||||
* @since Beta v0.3.8
|
||||
* @description 米游社客户端
|
||||
*/
|
||||
class TGClient {
|
||||
@@ -457,33 +459,40 @@ class TGClient {
|
||||
|
||||
/**
|
||||
* @func pushPage
|
||||
* @since Beta v0.3.7
|
||||
* @since Beta v0.3.8
|
||||
* @desc 打开米游社客户端的页面
|
||||
* @param {unknown} payload - 请求参数
|
||||
* @returns {void} - 无返回值
|
||||
*/
|
||||
async pushPage(payload: any): Promise<void> {
|
||||
const url: string = payload.page;
|
||||
if (url.startsWith("mihoyobbs://article/")) {
|
||||
const urlBBS = url.replace("mihoyobbs://article/", "https://m.miyoushe.com/ys/#/article/");
|
||||
await this.pushPage({ page: urlBBS });
|
||||
return;
|
||||
} else if (url.startsWith("mihoyobbs://webview?link=")) {
|
||||
const urlWv = url.replace("mihoyobbs://webview?link=", "");
|
||||
// 解析经过编码作为参数的链接
|
||||
const urlReal = decodeURIComponent(urlWv);
|
||||
await this.pushPage({ page: urlReal });
|
||||
const url = payload.page;
|
||||
const res = await parseLink(url, true);
|
||||
if (!res) {
|
||||
await appWindow.setFocus();
|
||||
showSnackbar({
|
||||
text: `未知链接:${url}`,
|
||||
color: "error",
|
||||
timeout: 3000,
|
||||
});
|
||||
await new Promise<void>((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, 3000);
|
||||
});
|
||||
await this.window?.setFocus();
|
||||
return;
|
||||
}
|
||||
this.route.push(url);
|
||||
console.log(`[pushPage] ${url}`);
|
||||
if (typeof res !== "string") return;
|
||||
this.route.push(res);
|
||||
console.log(`[pushPage] ${res}`);
|
||||
const executeJS = `javascript:(function(){
|
||||
window.location.href = '${url}';
|
||||
window.location.href = '${res}';
|
||||
})();`;
|
||||
await invoke("execute_js", { label: "mhy_client", js: executeJS });
|
||||
await this.loadJSBridge();
|
||||
await this.hideSideBar();
|
||||
await this.hideOverlay();
|
||||
await this.window?.setFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
74
src/utils/linkParser.ts
Normal file
74
src/utils/linkParser.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @file src/utils/linkParser.ts
|
||||
* @description 处理链接
|
||||
* @since Beta v0.3.8
|
||||
*/
|
||||
|
||||
import TGClient from "./TGClient";
|
||||
import { createPost } from "./TGWindow";
|
||||
import showConfirm from "../components/func/confirm";
|
||||
|
||||
/**
|
||||
* @function parseLink
|
||||
* @description 处理链接
|
||||
* @param {string} link - 链接
|
||||
* @param {boolean} useInner - 是否采用内置 JSBridge 打开
|
||||
* @returns {Promise<boolean|string>} - 处理情况,或者转换后的链接
|
||||
*/
|
||||
export async function parseLink(
|
||||
link: string,
|
||||
useInner: boolean = false,
|
||||
): Promise<boolean | string> {
|
||||
console.warn("parseLink", link);
|
||||
const url = new URL(link);
|
||||
if (url.protocol !== "https:") {
|
||||
if (url.protocol === "mihoyobbs:") {
|
||||
if (url.pathname.startsWith("//article/")) {
|
||||
const postId = url.pathname.split("/").pop();
|
||||
if (!postId) return false;
|
||||
createPost(postId);
|
||||
return true;
|
||||
}
|
||||
if (url.pathname === "//webview" && url.search.startsWith("?link=")) {
|
||||
return decodeURIComponent(url.search.replace("?link=", ""));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (url.hostname === "bbs.mihoyo.com" || url.hostname === "www.miyoushe.com") {
|
||||
if (url.pathname.includes("/article/")) {
|
||||
const postId = url.pathname.split("/").pop();
|
||||
if (typeof postId !== "string") return false;
|
||||
createPost(postId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const prefix = [
|
||||
"m.miyoushe.com",
|
||||
"act.mihoyo.com",
|
||||
"mhyurl.cn",
|
||||
"webstatic.mihoyo.com",
|
||||
"bbs.mihoyo.com",
|
||||
"qaa.miyoushe.com",
|
||||
];
|
||||
if (prefix.includes(url.hostname)) {
|
||||
if (!useInner) {
|
||||
const openCheck = await showConfirm({
|
||||
title: "采用内置 JSBridge?",
|
||||
text: "取消则使用外部浏览器打开",
|
||||
});
|
||||
if (!openCheck) return url.href;
|
||||
const typeCheck = await showConfirm({
|
||||
title: "采用宽屏模式?",
|
||||
text: "取消则使用默认竖屏",
|
||||
});
|
||||
if (typeCheck) {
|
||||
await TGClient.open("web_act", link);
|
||||
} else {
|
||||
await TGClient.open("web_act_thin", link);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return url.href.toString();
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file utils/toolFunc.ts
|
||||
* @description 一些工具函数
|
||||
* @since Beta v0.3.6
|
||||
* @since Beta v0.3.8
|
||||
*/
|
||||
|
||||
import { os, path } from "@tauri-apps/api";
|
||||
@@ -177,15 +177,3 @@ export function isColorSimilar(colorBg: string, colorText: string): boolean {
|
||||
: colorConvert.keyword.hex(<KEYWORD>colorText);
|
||||
return score(hexText, hexBg) === "Fail";
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 判断是否为 Mys 帖子
|
||||
* @since Beta v0.3.7
|
||||
* @param {string} url - 网址
|
||||
* @returns {boolean} 是否为 Mys 帖子
|
||||
*/
|
||||
export function isMysPost(url: string): boolean {
|
||||
const regBBS = /^https:\/\/bbs\.mihoyo\.com\/\w+\/article\/\d+$/;
|
||||
const regMys = /^https:\/\/www\.miyoushe\.com\/\w+\/article\/\d+$/;
|
||||
return regBBS.test(url) || regMys.test(url);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user