Spaces:
Sleeping
Sleeping
Update static/index.html
Browse files- static/index.html +39 -23
static/index.html
CHANGED
|
@@ -71,28 +71,44 @@
|
|
| 71 |
parseSRT: (data) => {
|
| 72 |
if (!data) return [];
|
| 73 |
const normalized = data.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
const parsed = [];
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
startTimeMs: Helpers.timeStringToMs(startTimeStr),
|
| 92 |
-
text: text
|
| 93 |
-
});
|
| 94 |
-
}
|
| 95 |
});
|
|
|
|
| 96 |
return parsed;
|
| 97 |
}
|
| 98 |
};
|
|
@@ -299,7 +315,7 @@
|
|
| 299 |
</div>
|
| 300 |
<div className="col-span-9 flex flex-col justify-center">
|
| 301 |
<div className="flex items-center justify-between mb-1">
|
| 302 |
-
<span className="text-xs font-bold text-slate-400 uppercase">Line #{parseInt(item.id)
|
| 303 |
<span className="text-xs font-mono text-slate-500 bg-slate-100 px-2 py-0.5 rounded">{item.srt.time.split('-->')[0].trim()}</span>
|
| 304 |
</div>
|
| 305 |
<div className="text-sm font-medium text-slate-800 p-2 bg-slate-50 rounded border border-slate-100 group-hover:bg-white">{item.srt.text}</div>
|
|
@@ -400,7 +416,7 @@
|
|
| 400 |
|
| 401 |
if (hasArchive) {
|
| 402 |
displayItems = parsedSrt.map((srt, idx) => ({
|
| 403 |
-
id:
|
| 404 |
srt: srt,
|
| 405 |
imgName: "Inside Archive",
|
| 406 |
imgUrl: null,
|
|
@@ -416,7 +432,7 @@
|
|
| 416 |
displayItems = parsedSrt.map((srt, idx) => {
|
| 417 |
const matchedImg = images[idx];
|
| 418 |
return {
|
| 419 |
-
id:
|
| 420 |
srt: srt,
|
| 421 |
imgName: matchedImg ? matchedImg.file.name : "Missing Image",
|
| 422 |
imgUrl: matchedImg ? URL.createObjectURL(matchedImg.file) : null,
|
|
@@ -425,7 +441,7 @@
|
|
| 425 |
});
|
| 426 |
} else {
|
| 427 |
displayItems = parsedSrt.map((srt, idx) => ({
|
| 428 |
-
id:
|
| 429 |
srt: srt,
|
| 430 |
imgName: "Waiting for media...",
|
| 431 |
imgUrl: null,
|
|
|
|
| 71 |
parseSRT: (data) => {
|
| 72 |
if (!data) return [];
|
| 73 |
const normalized = data.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
| 74 |
+
|
| 75 |
+
// Robust Regex-based parsing to handle inconsistent spacing/newlines
|
| 76 |
+
// Looks for: Line with Digits (ID) -> Newline -> Timestamp Line
|
| 77 |
+
const regex = /(\d+)\n(\d{2}:\d{2}:\d{2}[,.]\d{3}\s*-->\s*\d{2}:\d{2}:\d{2}[,.]\d{3})/g;
|
| 78 |
+
|
| 79 |
const parsed = [];
|
| 80 |
+
let match;
|
| 81 |
+
const matches = [];
|
| 82 |
+
|
| 83 |
+
// 1. Scan for all headers first
|
| 84 |
+
while ((match = regex.exec(normalized)) !== null) {
|
| 85 |
+
matches.push({
|
| 86 |
+
id: match[1],
|
| 87 |
+
time: match[2],
|
| 88 |
+
index: match.index,
|
| 89 |
+
endHeader: match.index + match[0].length
|
| 90 |
+
});
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// 2. Extract content between headers
|
| 94 |
+
matches.forEach((m, i) => {
|
| 95 |
+
const nextMatch = matches[i + 1];
|
| 96 |
+
const startText = m.endHeader;
|
| 97 |
+
const endText = nextMatch ? nextMatch.index : normalized.length;
|
| 98 |
|
| 99 |
+
const textRaw = normalized.substring(startText, endText).trim();
|
| 100 |
+
const text = textRaw || "[BLANK SUBTITLE]";
|
| 101 |
+
|
| 102 |
+
const startTimeStr = m.time.split('-->')[0].trim();
|
| 103 |
+
|
| 104 |
+
parsed.push({
|
| 105 |
+
id: m.id,
|
| 106 |
+
time: m.time,
|
| 107 |
+
startTimeMs: Helpers.timeStringToMs(startTimeStr),
|
| 108 |
+
text: text
|
| 109 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
});
|
| 111 |
+
|
| 112 |
return parsed;
|
| 113 |
}
|
| 114 |
};
|
|
|
|
| 315 |
</div>
|
| 316 |
<div className="col-span-9 flex flex-col justify-center">
|
| 317 |
<div className="flex items-center justify-between mb-1">
|
| 318 |
+
<span className="text-xs font-bold text-slate-400 uppercase">Line #{parseInt(item.id)}</span>
|
| 319 |
<span className="text-xs font-mono text-slate-500 bg-slate-100 px-2 py-0.5 rounded">{item.srt.time.split('-->')[0].trim()}</span>
|
| 320 |
</div>
|
| 321 |
<div className="text-sm font-medium text-slate-800 p-2 bg-slate-50 rounded border border-slate-100 group-hover:bg-white">{item.srt.text}</div>
|
|
|
|
| 416 |
|
| 417 |
if (hasArchive) {
|
| 418 |
displayItems = parsedSrt.map((srt, idx) => ({
|
| 419 |
+
id: srt.id,
|
| 420 |
srt: srt,
|
| 421 |
imgName: "Inside Archive",
|
| 422 |
imgUrl: null,
|
|
|
|
| 432 |
displayItems = parsedSrt.map((srt, idx) => {
|
| 433 |
const matchedImg = images[idx];
|
| 434 |
return {
|
| 435 |
+
id: srt.id,
|
| 436 |
srt: srt,
|
| 437 |
imgName: matchedImg ? matchedImg.file.name : "Missing Image",
|
| 438 |
imgUrl: matchedImg ? URL.createObjectURL(matchedImg.file) : null,
|
|
|
|
| 441 |
});
|
| 442 |
} else {
|
| 443 |
displayItems = parsedSrt.map((srt, idx) => ({
|
| 444 |
+
id: srt.id,
|
| 445 |
srt: srt,
|
| 446 |
imgName: "Waiting for media...",
|
| 447 |
imgUrl: null,
|