Skip to content

Commit f12b7c5

Browse files
authored
Web Worker を Chrome でも実行可能に (#84)
1 parent 3411256 commit f12b7c5

File tree

6 files changed

+75
-40
lines changed

6 files changed

+75
-40
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "d-anime comments viewer",
44
"description": "Player addon for d-anime",
55
"author": "sopi",
6-
"version": "2024.9.17",
6+
"version": "2024.9.18",
77
"private": true,
88
"license": "GPL-3.0",
99
"type": "module",

src/@types/global.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
/// <reference lib="esnext" />
44
/// <reference types="react" />
55
/// <reference types="react-dom" />
6+
/// <reference types="vite/client" />
67

78
declare module "*.md";

src/content_scripts/comments.ts

+31-15
Original file line numberDiff line numberDiff line change
@@ -15,41 +15,57 @@
1515
along with d-comments. If not, see <https://www.gnu.org/licenses/>.
1616
*/
1717

18-
import { type config_keys, getConfig } from "@/config";
19-
import { threads as getThreads } from "./state";
18+
import { getConfig } from "@/config";
19+
import browser from "webextension-polyfill";
20+
21+
import comments_ngfilter from "./comments_ngfilter?worker&url";
22+
import comments_worker from "./comments_worker?worker&url";
2023

2124
type message = {
2225
comments: nv_comment[];
2326
};
2427

25-
const sort_worker = new Worker(
26-
new URL("./comments_worker.ts", import.meta.url),
27-
{
28-
type: "module",
29-
}
30-
);
28+
async function newWorker(url: string): Promise<Worker> {
29+
const script = await fetch(url).then((r) => r.text());
30+
const blob = new Blob([script], { type: "application/javascript" });
31+
const objURL = URL.createObjectURL(blob);
32+
const worker = new Worker(objURL, { type: "module" });
33+
worker.addEventListener("error", (_e) => {
34+
URL.revokeObjectURL(objURL);
35+
});
36+
return worker;
37+
}
3138

32-
const ngfilter_worker = new Worker(
33-
new URL("./comments_ngfilter.ts", import.meta.url),
34-
{ type: "module" }
39+
const ngfilter_worker = await newWorker(
40+
browser.runtime.getURL(comments_ngfilter)
3541
);
42+
const sort_worker = await newWorker(browser.runtime.getURL(comments_worker));
3643

3744
async function build_ng_filter_message(comments: nv_comment[]) {
3845
const id = Math.random().toString(36).slice(-8);
3946

4047
const ng_words = await getConfig("comment_ng_words");
41-
const enabled_ng_users = ng_words.filter((w) => w.enabled);
42-
const regex = enabled_ng_users.map((w) => w.value).join("|");
48+
const enabled_ng_words = ng_words.filter((w) => w.enabled);
49+
const regex = enabled_ng_words.map((w) => w.value).join("|");
4350

4451
const ng_users = await getConfig("comment_ng_users");
45-
const enabled_ng_words = ng_users
52+
const enabled_ng_users = ng_users
4653
.filter((u) => u.enabled)
4754
.map((u) => u.value);
4855

56+
if (enabled_ng_words.length === 0) {
57+
return {
58+
id: id,
59+
ng_words_regex: "skip-ng-words-filter",
60+
ng_users: enabled_ng_users,
61+
comments: comments,
62+
};
63+
}
64+
4965
const ng_filter_message = {
5066
id: id,
5167
ng_words_regex: new RegExp(regex, "i"),
52-
ng_users: enabled_ng_words,
68+
ng_users: enabled_ng_users,
5369
comments: comments,
5470
};
5571
return ng_filter_message;

src/content_scripts/comments_ngfilter.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,27 @@
1919

2020
type message = {
2121
id: string;
22-
ng_words_regex: RegExp;
22+
ng_words_regex: RegExp | "skip-ng-words-filter";
2323
ng_users: string[];
2424
comments: nv_comment[];
2525
};
2626

2727
self.addEventListener("message", async (e: MessageEvent<message>) => {
2828
const { id, comments } = e.data;
2929
const { ng_words_regex, ng_users } = e.data;
30-
const filtered = comments.filter((comment) => {
31-
if (ng_users.includes(comment.userId)) return false;
32-
if (ng_words_regex.test(comment.body)) return false;
33-
return true;
34-
});
35-
self.postMessage({ id, comments: filtered });
30+
if (ng_words_regex === "skip-ng-words-filter") {
31+
const filtered = comments.filter((comment) => {
32+
return !ng_users.includes(comment.userId);
33+
});
34+
self.postMessage({ id, comments: filtered });
35+
} else {
36+
const filtered = comments.filter((comment) => {
37+
return (
38+
!ng_users.includes(comment.userId) && !ng_words_regex.test(comment.body)
39+
);
40+
});
41+
self.postMessage({ id, comments: filtered });
42+
}
3643
});
3744

3845
export default {};

src/content_scripts/components/canvas.tsx

+2-10
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,13 @@ export class Renderer {
9797
if (this.options.format !== "v1") {
9898
console.error("format should be v1");
9999
}
100-
if (this.threads.length === 0) {
101-
console.error("no threads");
102-
}
103100
}
104101
setThread(threads: V1Thread[]) {
105102
this.threads = threads;
106-
this.canvas.dataset.commentsCount = threads
107-
.map((thread) => thread.commentCount)
108-
.reduce((a, b) => a + b)
109-
.toString();
110103
this.start();
111104
}
112105
setOptions(options: Options) {
113106
this.options = options;
114-
console.log("setOptions", JSON.stringify(options, null, 2));
115107
this.start();
116108
}
117109
getOptions() {
@@ -202,8 +194,8 @@ async function initRenderer() {
202194
});
203195

204196
if (!(await getConfig("show_comments_in_niconico_style"))) return;
205-
const threads = getThreads()?.threads || [];
206-
renderer.setThread(threads);
197+
const threads = getThreads()?.threads;
198+
if (threads) renderer.setThread(threads);
207199
}
208200

209201
export default initRenderer;

src/content_scripts/components/scroll.tsx

+26-7
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ export function Scroll() {
9898
if (new_comments.length !== comments.length) {
9999
setComments(new_comments);
100100
}
101+
102+
if (await getConfig("show_comments_in_list")) {
103+
setVisibility(true);
104+
}
101105
}
102106

103107
on_threads_change(async (_, next) => {
@@ -208,17 +212,32 @@ export function Scroll() {
208212
data={comments}
209213
className="w-full h-full"
210214
components={{
215+
Header: () => {
216+
return (
217+
<div
218+
className={`flex flex-row justify-center items-center gap-4 ${comments.length === 0 ? "p-4 text-center" : "hidden"}`}
219+
>
220+
{comments.length === 0 && (
221+
<>
222+
コメントがありません
223+
<button
224+
type="button"
225+
className="bg-black text-white rounded border border-white px-2 py-1"
226+
onClick={() => setVisibility(false)}
227+
>
228+
閉じる
229+
</button>
230+
</>
231+
)}
232+
</div>
233+
);
234+
},
211235
Footer: () => {
212236
return (
213237
<div
214-
style={{
215-
padding: "1rem",
216-
textAlign: "center",
217-
}}
238+
className={comments.length > 0 ? "p-4 text-center" : "hidden"}
218239
>
219-
{comments.length > 0
220-
? "最後のコメントです"
221-
: "コメントはありません"}
240+
{comments.length > 0 && "最後のコメントです"}
222241
</div>
223242
);
224243
},

0 commit comments

Comments
 (0)