-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.ts
More file actions
143 lines (126 loc) · 4.82 KB
/
Copy pathmain.ts
File metadata and controls
143 lines (126 loc) · 4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import { Plugin, WorkspaceLeaf } from "obsidian";
import { NoteBoardSettingTab, DEFAULT_SETTINGS } from "./src/settings";
import type { NoteBoardSettings } from "./src/settings";
import { NOTEBOARD_VIEW_TYPE, NoteBoardView } from "./src/mainView";
import { AITaskQueue } from "./src/noteOps";
export default class NoteBoardPlugin extends Plugin {
settings: NoteBoardSettings = DEFAULT_SETTINGS;
taskQueue!: AITaskQueue;
/**
* 全局白噪音 iframe 容器(挂在 document.body),插件生命周期内只创建一次。
* 这样在 Tab 切换、面板重渲染时 iframe 不会被卸载,播放状态可保持。
*/
ambientHost: HTMLElement | null = null;
private ambientHostListeners: Array<() => void> = [];
/** 确保全局白噪音宿主已创建(懒创建),返回宿主节点。 */
ensureAmbientHost(): HTMLElement {
if (this.ambientHost && document.body.contains(this.ambientHost)) {
return this.ambientHost;
}
const host = document.body.createDiv({ cls: "nb-ambient-host" });
// 默认隐藏但不卸载:用 visibility + 缩小到 0x0,iframe 仍保持 DOM 与播放状态
host.style.visibility = "hidden";
host.style.position = "fixed";
host.style.right = "16px";
host.style.bottom = "16px";
host.style.zIndex = "9999";
host.style.pointerEvents = "none"; // 隐藏时不拦截点击
host.style.transformOrigin = "bottom right";
host.style.transform = "scale(0.001)";
host.style.opacity = "0";
host.style.transition =
"opacity 0.12s ease, transform 0.12s ease";
const iframe = host.createEl("iframe");
iframe.setAttribute("src", "https://www.ppbzy.com/embed");
iframe.setAttribute("width", "420");
iframe.setAttribute("height", "200");
iframe.setAttribute("frameborder", "0");
iframe.setAttribute("allow", "autoplay");
iframe.style.borderRadius = "16px";
iframe.style.border = "none";
iframe.style.display = "block";
this.ambientHost = host;
this.register(() => {
this.setAmbientVisible(false);
// 插件卸载时彻底移除 iframe
host.remove();
if (this.ambientHost === host) this.ambientHost = null;
});
return host;
}
/** 切换白噪音宿主的可见性(显隐不卸载 iframe,播放状态保留)。 */
setAmbientVisible(visible: boolean) {
const host = this.ensureAmbientHost();
if (visible) {
host.style.visibility = "visible";
host.style.pointerEvents = "auto";
host.style.transform = "scale(1)";
host.style.opacity = "1";
} else {
host.style.visibility = "hidden";
host.style.pointerEvents = "none";
host.style.transform = "scale(0.001)";
host.style.opacity = "0";
}
// 同步通知订阅者(多个 Dashboard 开关按钮要跟这个状态一致)
this.ambientHostListeners.forEach((fn) => {
try { fn(); } catch {}
});
}
/** 订阅宿主显隐状态变化,返回取消订阅函数。 */
onAmbientHostChange(fn: () => void): () => void {
this.ambientHostListeners.push(fn);
return () => {
const i = this.ambientHostListeners.indexOf(fn);
if (i >= 0) this.ambientHostListeners.splice(i, 1);
};
}
/** 返回当前宿主是否可见(白噪音面板处于展开状态)。 */
isAmbientVisible(): boolean {
if (!this.ambientHost) return false;
return this.ambientHost.style.visibility === "visible";
}
async onload() {
await this.loadSettings();
this.taskQueue = new AITaskQueue(this);
this.registerView(NOTEBOARD_VIEW_TYPE, (leaf) => new NoteBoardView(leaf, this));
// 单个插件图标,默认打开「数据面板」
this.addRibbonIcon("layout-dashboard", "NoteBoard", () => {
this.activateView("dashboard");
});
this.addCommand({
id: "open-dashboard",
name: "打开数据面板",
callback: () => this.activateView("dashboard"),
});
this.addCommand({
id: "open-note-ops",
name: "打开笔记操作页面",
callback: () => this.activateView("noteops"),
});
this.addSettingTab(new NoteBoardSettingTab(this.app, this));
}
/** 打开主视图并切换到指定 Tab。 */
async activateView(tab: "dashboard" | "noteops") {
const { workspace } = this.app;
let leaf: WorkspaceLeaf | null = null;
const leaves = workspace.getLeavesOfType(NOTEBOARD_VIEW_TYPE);
if (leaves.length > 0) {
leaf = leaves[0];
} else {
leaf = workspace.getLeaf("tab");
await leaf.setViewState({ type: NOTEBOARD_VIEW_TYPE, active: true });
}
workspace.revealLeaf(leaf);
const view = leaf.view;
if (view instanceof NoteBoardView) {
await view.activateTab(tab);
}
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
}