Skip to content

Commit 96329d3

Browse files
committed
fix: 🐛 修复 nhentai 改版后导致的失效
2 parents 1ebc77e + 3a63511 commit 96329d3

11 files changed

Lines changed: 367 additions & 300 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,11 @@ Cotrans 也有自己的油猴脚本 —— 「[Cotrans 漫画/图片翻译器](h
269269

270270
关联其他站点的漫画源,使用外站源来加载图片,避免消耗配额,同时或许(?)也能用更快的速度加载图片。
271271

272-
结果会以标签的形式显示在标签列表中,鼠标悬停在标签上可以看到外站漫画的具体标题,点击标签后会出现跳至外站或直接加载的选项,也可以直接右键标签点击「在新标签页中打开」来跳至外站。
272+
结果会以标签的形式显示在标签列表中:
273+
274+
- 鼠标悬停在标签上可以看到外站漫画的具体标题
275+
- 点击标签后会出现跳至外站或直接加载的选项,也可以直接右键标签点击「在新标签页中打开」来跳至外站
276+
- 百分百确定就是同一作品的结果标签会是实心边框,无法确定是同一作品的结果标签则是虚线边框
273277

274278
目前支持 nhentai 和 hitomi。
275279

docs/index.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,11 @@ Cotrans 也有自己的油猴脚本 —— 「[Cotrans 漫画/图片翻译器](h
269269

270270
关联其他站点的漫画源,使用外站源来加载图片,避免消耗配额,同时或许(?)也能用更快的速度加载图片。
271271

272-
结果会以标签的形式显示在标签列表中,鼠标悬停在标签上可以看到外站漫画的具体标题,点击标签后会出现跳至外站或直接加载的选项,也可以直接右键标签点击「在新标签页中打开」来跳至外站。
272+
结果会以标签的形式显示在标签列表中:
273+
274+
- 鼠标悬停在标签上可以看到外站漫画的具体标题
275+
- 点击标签后会出现跳至外站或直接加载的选项,也可以直接右键标签点击「在新标签页中打开」来跳至外站
276+
- 百分百确定就是同一作品的结果标签会是实心边框,无法确定是同一作品的结果标签则是虚线边框
273277

274278
目前支持 nhentai 和 hitomi。
275279

src/helper/other.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -651,11 +651,12 @@ export const onUrlChange = (
651651
};
652652

653653
/** wait,但是只在 url 变化时判断 */
654-
export const waitUrlChange = (isValidUrl: () => unknown) =>
655-
new Promise<void>((resolve) => {
654+
export const waitUrlChange = <T = unknown>(isValidUrl: () => T) =>
655+
new Promise<NonNullable<T>>((resolve) => {
656656
const abort = onUrlChange(async () => {
657-
if (!(await isValidUrl())) return;
658-
resolve();
657+
const res = await isValidUrl();
658+
if (!res) return;
659+
resolve(res);
659660
abort();
660661
});
661662
});

src/site/ehentai/crossSiteLink.tsx

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import { For, Show } from 'solid-js';
44
import { createStore } from 'solid-js/store';
55
import { render } from 'solid-js/web';
66

7-
import { fileType, hijackFn, querySelector, querySelectorAll, t } from 'helper';
7+
import { hijackFn, querySelector, querySelectorAll, t } from 'helper';
88
import { request, toast } from 'main';
99

10-
import { searchNhentai } from '../../userscript/nhentaiApi';
10+
import {
11+
getNhentaiData,
12+
searchNhentai,
13+
toImgList,
14+
} from '../../userscript/nhentaiApi';
1115
import { type GalleryContext, isInCategories } from './helper';
1216

1317
type ItemData = {
@@ -23,39 +27,44 @@ type SiteFn = {
2327
errorTip: (context: GalleryContext) => string;
2428
};
2529

26-
const nhentai: SiteFn = async ({ setState, galleryTitle }) => {
27-
const downImg = async (i: number, media_id: string, type: string) => {
28-
const imgRes = await request<Blob>(
29-
`https://i.nhentai.net/galleries/${media_id}/${i + 1}.${fileType[type]}`,
30-
{
31-
headers: { Referer: `https://nhentai.net/g/${media_id}` },
32-
responseType: 'blob',
33-
fetch: false,
34-
},
35-
);
36-
return URL.createObjectURL(imgRes.response);
37-
};
38-
30+
const nhentai: SiteFn = async ({ setState, galleryTitle, galleryId }) => {
3931
const result = await searchNhentai(galleryTitle!);
40-
return result.map(({ id, title, images, num_pages, media_id }) => {
41-
const itemId = `@nh:${id}`;
42-
setState('comicMap', itemId, {
43-
getImgList: ({ dynamicLazyLoad }) =>
44-
dynamicLazyLoad({
45-
loadImg: (i) => downImg(i, media_id, images.pages[i].t),
46-
length: num_pages,
47-
id: itemId,
48-
}),
49-
});
32+
return result
33+
.map(({ id, english_title, japanese_title, media_id }) => {
34+
const itemId = `@nh:${id}`;
5035

51-
return {
52-
id: itemId,
53-
showText: `${id}`,
54-
title: title.english || title.japanese,
55-
href: `https://nhentai.net/g/${id}`,
56-
class: 'gtl',
57-
};
58-
});
36+
setState('comicMap', itemId, {
37+
getImgList: async ({ dynamicLazyLoad }) => {
38+
const galleryData = await getNhentaiData(`${id}`);
39+
const imgList = toImgList(galleryData);
40+
return dynamicLazyLoad({
41+
loadImg: async (i) => {
42+
const imgRes = await request<Blob>(imgList[i].src, {
43+
headers: { Referer: `https://nhentai.net/g/${id}` },
44+
responseType: 'blob',
45+
fetch: false,
46+
});
47+
return URL.createObjectURL(imgRes.response);
48+
},
49+
length: imgList.length,
50+
id: itemId,
51+
});
52+
},
53+
});
54+
55+
return {
56+
id: itemId,
57+
showText: `${id}`,
58+
title: japanese_title || english_title,
59+
href: `https://nhentai.net/g/${id}`,
60+
class: `${galleryId}` === media_id ? 'gt' : 'gtl',
61+
};
62+
})
63+
.sort(
64+
(a, b) =>
65+
(a.class === 'gt' ? 0 : 1) - (b.class === 'gt' ? 0 : 1) ||
66+
Number(b.showText) - Number(a.showText),
67+
);
5968
};
6069
nhentai.errorTip = (context) =>
6170
t('site.ehentai.nhentai_failed', {

src/site/kemono.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,31 @@ universalSPA('kemono', {
3232
/** 加载原图 */
3333
load_original_image: true,
3434
},
35-
isMangaPage: async () => {
36-
if (!location.pathname.includes('/post/')) return false;
35+
getPageType: async () => {
36+
const match = location.pathname.match(/\/post\/(\w+)/);
37+
if (!match) return;
3738
await waitDom('.post__thumbnail');
3839
handlePwa();
39-
return true;
40+
return { type: 'manga', id: match[1] };
4041
},
4142

42-
work: async ({ store, setState, showComic }) => {
43-
// 在切换时重新获取图片
44-
createEffectOn(
45-
() => store.options.load_original_image,
46-
(isOriginal, prev) => {
47-
setState('nowComic', isOriginal ? 'original' : 'thumbnail');
48-
if (prev) showComic();
49-
},
50-
);
43+
handlers: {
44+
manga: async ({ store, setState, showComic }) => {
45+
// 在切换时重新获取图片
46+
createEffectOn(
47+
() => store.options.load_original_image,
48+
(isOriginal, prev) => {
49+
setState('nowComic', isOriginal ? 'original' : 'thumbnail');
50+
if (prev) showComic();
51+
},
52+
);
5153

52-
setState((state) => {
53-
state.comicMap.original = { getImgList: original };
54-
state.comicMap.thumbnail = { getImgList: thumbnail };
55-
state.manga.onNext = querySelectorClick('.post__nav-link.next');
56-
state.manga.onPrev = querySelectorClick('.post__nav-link.prev');
57-
});
54+
setState((state) => {
55+
state.comicMap.original = { getImgList: original };
56+
state.comicMap.thumbnail = { getImgList: thumbnail };
57+
state.manga.onNext = querySelectorClick('.post__nav-link.next');
58+
state.manga.onPrev = querySelectorClick('.post__nav-link.prev');
59+
});
60+
},
5861
},
5962
});

0 commit comments

Comments
 (0)