feat: add chapter transition toast and smart title & episode badge parsing
parent
7a755f684f
commit
338ab8a16c
@ -0,0 +1,49 @@
|
|||||||
|
export interface ParsedTitle {
|
||||||
|
title: string;
|
||||||
|
episode: string | null;
|
||||||
|
fullCleanTitle: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseTitleAndEpisode(rawTitle: string | null): ParsedTitle {
|
||||||
|
if (!rawTitle) return { title: '', episode: null, fullCleanTitle: '' };
|
||||||
|
|
||||||
|
// Remove site name suffixes like "- 마나토키 330", "- 뉴토끼", "- newtoki"
|
||||||
|
let clean = rawTitle
|
||||||
|
.replace(/\s*[-|_]\s*(마나토키|뉴토끼|newtoki|manatoki|웹툰|만화).*$/i, '')
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
// 1. Match explicit episode format like "150화", "150.5화", "EP.15"
|
||||||
|
const epMatch = clean.match(/(\d+(?:\.\d+)?\s*화|ep\.?\s*\d+)/i);
|
||||||
|
if (epMatch) {
|
||||||
|
let episode = epMatch[1].replace(/\s+/g, '');
|
||||||
|
if (!episode.endsWith('화') && !episode.toLowerCase().startsWith('ep')) {
|
||||||
|
episode += '화';
|
||||||
|
}
|
||||||
|
// Remove the matched episode part from the title
|
||||||
|
let title = clean.replace(epMatch[0], '').trim();
|
||||||
|
// Clean up trailing dashes/colons/dots left over
|
||||||
|
title = title.replace(/[-|_:]\s*$/, '').trim();
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: title || clean,
|
||||||
|
episode,
|
||||||
|
fullCleanTitle: clean,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Match trailing numbers like "제목 150"
|
||||||
|
const numMatch = clean.match(/(\d+(?:\.\d+)?)\s*$/);
|
||||||
|
if (numMatch) {
|
||||||
|
const episode = `${numMatch[1]}화`;
|
||||||
|
let title = clean.slice(0, numMatch.index).trim();
|
||||||
|
title = title.replace(/[-|_:]\s*$/, '').trim();
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: title || clean,
|
||||||
|
episode,
|
||||||
|
fullCleanTitle: clean,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { title: clean, episode: null, fullCleanTitle: clean };
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue