Skip to content

Commit a6d81bd

Browse files
committed
✨ feat(protocol): 将协议数据传输至前端
1 parent 0f0aae3 commit a6d81bd

5 files changed

Lines changed: 72 additions & 31 deletions

File tree

electron/main/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import initAppServer from "../server";
1111
import loadWindow from "./windows/load-window";
1212
import mainWindow from "./windows/main-window";
1313
import initIpc from "./ipc";
14-
import { openCustomProtocol, registerCustomProtocol } from "./utils/protocol";
14+
import { trySendCustomProtocol, registerCustomProtocol } from "./utils/protocol";
1515

1616
// 屏蔽报错
1717
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = "true";
@@ -80,8 +80,8 @@ class MainProcess {
8080

8181
// 自定义协议
8282
app.on("open-url", (_, url) => {
83-
processLog.log("Received custom protocol URL:", url);
84-
openCustomProtocol(url)
83+
processLog.log("🔗 Received custom protocol URL:", url);
84+
trySendCustomProtocol(url)
8585
});
8686

8787
// 将要退出

electron/main/utils/protocol.ts

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,30 @@
11
import { app } from "electron";
22
import { processLog } from "../logger";
3+
import mainWindow from "../windows/main-window";
34

45
export const registerCustomProtocol = () => {
56
app.setAsDefaultProtocolClient("orpheus");
67
processLog.info("🔗 Registered custom protocol");
78
};
89

9-
export const openCustomProtocol = (str: string): boolean => {
10-
switch (true) {
11-
case str.startsWith("orpheus://"):
12-
handleOpenOrpheus(str);
10+
export const trySendCustomProtocol = (str: string): boolean => {
11+
try {
12+
if (str.startsWith("orpheus://")) {
13+
mainWindow.getWin()!.webContents.send("protocol-url", str);
1314
return true;
14-
default:
15-
return false;
15+
}
16+
return false;
17+
} catch (e) {
18+
processLog.error("❌ Failed to send protocol url", e);
19+
return false;
1620
}
1721
}
1822

1923
export const processProtocolFromCommand = (command: string[]): boolean => {
2024
// 这里第一个参数是程序名称 忽略此 仅遍历参数
2125
for (let i = 1; i < command.length; i++) {
2226
const arg = command[i];
23-
if (openCustomProtocol(arg)) return true;
27+
if (trySendCustomProtocol(arg)) return true;
2428
}
2529
return false;
2630
}
27-
28-
export const handleOpenOrpheus = (url: string) => {
29-
// 这里的协议是从网页端打开官方客户端的协议
30-
// 形如 `orpheus://eyJ0eXBlIjoic29uZyIsImlkIjoiMTgyNjM2MTcxMiIsImNtZCI6InBsYXkifQ==`
31-
// URI 的 Path 部分是 Base64 编码过的,解码后得到 Json
32-
// 形如 `{"type":"song","id":"1826361712","cmd":"play"}`
33-
34-
if (!url.startsWith("orpheus://")) return;
35-
const path = url.replace("orpheus://", "");
36-
const data = atob(path);
37-
let json: any;
38-
try {
39-
json = JSON.parse(data);
40-
} catch (e) {
41-
processLog.error("❌ Invalid JSON:", e);
42-
return;
43-
}
44-
processLog.info("🚀 Open Orpheus:", json);
45-
// TODO 处理
46-
};

electron/main/utils/single-lock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const initSingleLock = (): boolean => {
2121
if (!processProtocolFromCommand(commandLine)) {
2222
systemLog.warn("❌ 第二个实例将要启动");
2323
} else {
24-
systemLog.info("🚀 第二个实例将要启动,因打开了 Custom Protocol");
24+
systemLog.info("🚀 第二个实例将要启动,通过 Custom Protocol");
2525
}
2626
mainWindow.getWin()?.show();
2727
});

src/utils/initIpc.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { usePlayer } from "./player";
66
import { cloneDeep } from "lodash-es";
77
import { getPlayerInfo } from "./player-utils/song";
88
import { SettingType } from "@/types/main";
9+
import { handleProtocolUrl } from "@/utils/protocal";
910

1011
// 关闭更新状态
1112
const closeUpdateStatus = () => {
@@ -82,6 +83,11 @@ const initIpc = () => {
8283
closeUpdateStatus();
8384
window.$message.error("更新过程出现错误");
8485
});
86+
// 协议数据
87+
window.electron.ipcRenderer.on("protocol-url", (_, url) => {
88+
console.log("📡 Received protocol url:", url);
89+
handleProtocolUrl(url)
90+
});
8591
} catch (error) {
8692
console.log(error);
8793
}

src/utils/protocal.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
class OrpheusData {
2+
constructor(type: string, id: string, cmd: string) {
3+
this.type = type;
4+
this.id = id;
5+
this.cmd = cmd;
6+
}
7+
8+
type: string = "";
9+
id: string = "";
10+
cmd: string = "";
11+
}
12+
13+
export const handleProtocolUrl = (url: string) => {
14+
switch (true) {
15+
case url.startsWith("orpheus://"):
16+
handleOpenOrpheus(url);
17+
break;
18+
default:
19+
break;
20+
}
21+
}
22+
23+
24+
25+
export const handleOpenOrpheus = (url: string) => {
26+
const data = parseOrpheus(url);
27+
if (!data) return;
28+
console.log("🚀 Open Orpheus:", data);
29+
30+
// TODO 处理
31+
};
32+
33+
const parseOrpheus = (url: string): OrpheusData | undefined => {
34+
// 这里的协议是从网页端打开官方客户端的协议
35+
// 形如 `orpheus://eyJ0eXBlIjoic29uZyIsImlkIjoiMTgyNjM2MTcxMiIsImNtZCI6InBsYXkifQ==`
36+
// URI 的 Path 部分是 Base64 编码过的,解码后得到 Json
37+
// 形如 `{"type":"song","id":"1826361712","cmd":"play"}`
38+
39+
if (!url.startsWith("orpheus://")) return;
40+
const path = url.replace("orpheus://", "");
41+
const jsonString = atob(path);
42+
let data: OrpheusData;
43+
try {
44+
const json = JSON.parse(jsonString);
45+
data = new OrpheusData(json.type, json.id, json.cmd);
46+
} catch (e) {
47+
console.error("❌ Invalid Data:", e);
48+
return;
49+
}
50+
return data;
51+
}

0 commit comments

Comments
 (0)