Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/mangaplus/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mangaplus",
"version": "1.2.1",
"version": "1.3.0",
"publoader_api": "^2.0.0",
"runtime": "node",
"entrypoint": "index.mjs",
Expand Down
2 changes: 1 addition & 1 deletion src/mangaplus/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "publoader-ext-mangaplus",
"version": "1.2.1",
"version": "1.3.0",
"private": true,
"type": "module",
"description": "publoader extension for MangaPlus by Shueisha (extension API v2)",
Expand Down
11 changes: 11 additions & 0 deletions src/mangaplus/src/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ export interface ChapterInput {
mdMangaId: string | null;
mangaName: string | null;
mangaUrl: string | null;
/**
* Why an ordinary reader cannot open this chapter, when they cannot.
*
* Null (or omitted) means freely readable and the chapter is published
* normally. Anything else means the publisher still lists it but will not
* serve it to a logged-out reader, and the platform publishes it already
* carded with wording that says so.
*/
unavailableReason?: "subscriber-only" | "region-locked" | "removed" | null;
/** The tier a `subscriber-only` chapter needs, e.g. "MANGA Plus MAX". */
subscriptionName?: string | null;
images?: Uint8Array[];
}

Expand Down
22 changes: 19 additions & 3 deletions src/mangaplus/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ const CHAPTER_URL = (chapterId: string) =>
`https://mangaplus.shueisha.co.jp/viewer/${chapterId}`;
const MANGA_URL = (mangaId: string) => `https://mangaplus.shueisha.co.jp/titles/${mangaId}`;

/** What MangaPlus calls the tier that unlocks a subscriber-only chapter. */
const SUBSCRIPTION_NAME = "MANGA Plus MAX";

/** Stand-in for a missing timestamp, matching the Python DEFAULT_TIMESTAMP. */
const DEFAULT_TIMESTAMP = 1;
/** An update is only "new" if it went up within this window. */
Expand Down Expand Up @@ -189,6 +192,10 @@ function toChapterInput(chapter: RawChapter): ChapterInput {
return {
chapterTimestamp: isoFromEpoch(chapter.chapterTimestamp),
chapterExpire: chapter.chapterExpire === null ? null : isoFromEpoch(chapter.chapterExpire),
// Null for a readable chapter; set, the platform publishes it already
// carded and names the subscription that unlocks it.
unavailableReason: chapter.unavailableReason ?? null,
subscriptionName: chapter.subscriptionName ?? null,
chapterLanguage: chapter.chapterLanguage,
chapterNumber: chapter.chapterNumber,
chapterTitle: chapter.chapterTitle,
Expand Down Expand Up @@ -339,10 +346,19 @@ class MangaPlus implements ExtensionRuntime {
});
}

// A dead chapter is LABELLED, not dropped. MangaPlus still lists it and a
// MANGA Plus MAX subscriber can still open it -- what the viewer refuses is
// the logged-out request this extension makes. Dropping it is
// indistinguishable, from the platform's side, from MangaPlus deleting the
// chapter, so the removal pass cards it "removed" and tells a reader a
// chapter they could subscribe to read no longer exists.
const dead = await this.findDeadChapters(input, allChapters, updatedChapters);
const isDead = (chapter: RawChapter): boolean => dead.has(chapter.chapterId);
const liveUpdated = updatedChapters.filter((chapter) => !isDead(chapter));
const liveAll = allChapters.filter((chapter) => !isDead(chapter));
const label = (chapter: RawChapter): RawChapter =>
dead.has(chapter.chapterId)
? { ...chapter, unavailableReason: "subscriber-only", subscriptionName: SUBSCRIPTION_NAME }
: chapter;
const liveUpdated = updatedChapters.map(label);
const liveAll = allChapters.map(label);

// Every fetched series failing is the API refusing us, not a catalogue that
// emptied itself. Publishing that as a clean run's catalogue would claim
Expand Down
8 changes: 8 additions & 0 deletions src/mangaplus/src/normalise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ export interface RawChapter {
mangaId: string;
mangaName: string | null;
mangaUrl: string;
/**
* Why a reader cannot open this chapter, when they cannot. Null for a normal
* chapter; `subscriber-only` for one the viewer refuses a logged-out request
* for but a MANGA Plus MAX subscriber can still read.
*/
unavailableReason?: "subscriber-only" | null;
/** The tier that unlocks it, carried onto the card. */
subscriptionName?: string | null;
}

export interface OverrideOptions {
Expand Down
Loading