stremiok 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +8 -6
- package/config.xml +1 -1
- package/css/style.css +11 -8
- package/index.html +33 -33
- package/js/app.js +24 -22
- package/js/focus.js +5 -5
- package/js/iptv.js +15 -2
- package/js/player-core.js +71 -9
- package/js/player-lang.js +66 -5
- package/js/player-store.js +4 -3
- package/js/player-subs.js +67 -13
- package/js/stremio.js +154 -23
- package/js/util.js +55 -13
- package/js/view-core.js +43 -13
- package/js/view-detail.js +36 -8
- package/js/view-discover.js +1 -1
- package/js/view-guide.js +41 -2
- package/js/view-home.js +33 -8
- package/js/view-settings.js +208 -57
- package/js/views.js +2 -2
- package/js/ytplay.js +4 -3
- package/package.json +2 -1
- package/service/index.js +33 -9
package/js/player-lang.js
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
fre: ['fre', 'fra', 'fr', 'french', 'français', 'francais'],
|
|
35
35
|
ger: ['ger', 'deu', 'de', 'german', 'deutsch'],
|
|
36
36
|
ita: ['ita', 'it', 'italian', 'italiano'],
|
|
37
|
-
por: ['por', 'pob', 'pt', 'portuguese', 'português', 'portugues'],
|
|
37
|
+
por: ['por', 'pob', 'pom', 'pt', 'portuguese', 'português', 'portugues'],
|
|
38
38
|
dut: ['dut', 'nld', 'nl', 'dutch', 'nederlands'],
|
|
39
39
|
rus: ['rus', 'ru', 'russian'],
|
|
40
40
|
ara: ['ara', 'ar', 'arabic'],
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
pol: ['pol', 'pl', 'polish', 'polski'],
|
|
43
43
|
jpn: ['jpn', 'ja', 'japanese', '日本語'],
|
|
44
44
|
kor: ['kor', 'ko', 'korean', '한국어'],
|
|
45
|
-
chi: ['chi', 'zho', 'zh', 'cmn', 'chinese', 'mandarin', '中文'],
|
|
45
|
+
chi: ['chi', 'zho', 'zh', 'cmn', 'zht', 'zhe', 'chinese', 'mandarin', '中文'], // (zht / zhe: OpenSubtitles' traditional and bilingual)
|
|
46
46
|
hin: ['hin', 'hi', 'hindi'],
|
|
47
47
|
swe: ['swe', 'sv', 'swedish', 'svenska'],
|
|
48
48
|
nor: ['nor', 'nob', 'nno', 'nb', 'nn', 'norwegian', 'norsk'],
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
ukr: ['ukr', 'uk', 'ukrainian'],
|
|
59
59
|
tha: ['tha', 'th', 'thai'],
|
|
60
60
|
vie: ['vie', 'vi', 'vietnamese'],
|
|
61
|
-
ind: ['ind', 'id', 'indonesian'],
|
|
61
|
+
ind: ['ind', 'id', 'indonesian', 'indonesia'], // ("Bahasa Indonesia": its last word)
|
|
62
62
|
may: ['may', 'msa', 'ms', 'malay'],
|
|
63
63
|
fil: ['fil', 'tgl', 'tl', 'filipino', 'tagalog'],
|
|
64
64
|
cat: ['cat', 'ca', 'catalan', 'català'],
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
glg: ['glg', 'gl', 'galician', 'galego'],
|
|
67
67
|
bul: ['bul', 'bg', 'bulgarian'],
|
|
68
68
|
hrv: ['hrv', 'hr', 'croatian', 'hrvatski'],
|
|
69
|
-
srp: ['srp', 'sr', 'serbian'],
|
|
69
|
+
srp: ['srp', 'scc', 'sr', 'serbian'],
|
|
70
70
|
per: ['per', 'fas', 'fa', 'persian', 'farsi'],
|
|
71
71
|
est: ['est', 'et', 'estonian'],
|
|
72
72
|
lav: ['lav', 'lv', 'latvian'],
|
|
@@ -74,7 +74,57 @@
|
|
|
74
74
|
ice: ['ice', 'isl', 'is', 'icelandic'],
|
|
75
75
|
tam: ['tam', 'ta', 'tamil'],
|
|
76
76
|
tel: ['tel', 'te', 'telugu'],
|
|
77
|
-
ben: ['ben', 'bn', 'bengali']
|
|
77
|
+
ben: ['ben', 'bn', 'bengali'],
|
|
78
|
+
// (2.2.0.2) the rest of OpenSubtitles' languages; two-letter codes that are also everyday
|
|
79
|
+
// words or labels (my, be, or, so, an, se, si, ne, mr, SD, BR…) left out
|
|
80
|
+
afr: ['afr', 'af', 'afrikaans'],
|
|
81
|
+
alb: ['alb', 'sqi', 'sq', 'albanian', 'shqip'],
|
|
82
|
+
arg: ['arg', 'aragonese'],
|
|
83
|
+
arm: ['arm', 'hye', 'hy', 'armenian'],
|
|
84
|
+
ast: ['ast', 'asturian'],
|
|
85
|
+
aze: ['aze', 'az', 'azerbaijani'],
|
|
86
|
+
bel: ['bel', 'belarusian'],
|
|
87
|
+
bos: ['bos', 'bs', 'bosnian'],
|
|
88
|
+
bre: ['bre', 'breton'],
|
|
89
|
+
bur: ['bur', 'mya', 'burmese'],
|
|
90
|
+
prs: ['prs', 'dari'],
|
|
91
|
+
epo: ['epo', 'eo', 'esperanto'],
|
|
92
|
+
ext: ['ext', 'extremaduran'],
|
|
93
|
+
gla: ['gla', 'gd', 'gaelic'],
|
|
94
|
+
geo: ['geo', 'kat', 'ka', 'georgian'],
|
|
95
|
+
ibo: ['ibo', 'ig', 'igbo'],
|
|
96
|
+
ina: ['ina', 'interlingua'],
|
|
97
|
+
gle: ['gle', 'ga', 'irish'],
|
|
98
|
+
kan: ['kan', 'kn', 'kannada'],
|
|
99
|
+
kaz: ['kaz', 'kk', 'kazakh'],
|
|
100
|
+
khm: ['khm', 'km', 'khmer'],
|
|
101
|
+
kur: ['kur', 'ku', 'kurdish'],
|
|
102
|
+
ltz: ['ltz', 'lb', 'luxembourgish'],
|
|
103
|
+
mac: ['mac', 'mkd', 'mk', 'macedonian'],
|
|
104
|
+
mal: ['mal', 'ml', 'malayalam'],
|
|
105
|
+
mni: ['mni', 'manipuri'],
|
|
106
|
+
mar: ['mar', 'marathi'],
|
|
107
|
+
mon: ['mon', 'mn', 'mongolian'],
|
|
108
|
+
mne: ['mne', 'montenegrin'],
|
|
109
|
+
nav: ['nav', 'nv', 'navajo'],
|
|
110
|
+
nep: ['nep', 'nepali'],
|
|
111
|
+
sme: ['sme', 'sami'],
|
|
112
|
+
oci: ['oci', 'oc', 'occitan'],
|
|
113
|
+
ori: ['ori', 'odia', 'oriya'],
|
|
114
|
+
pan: ['pan', 'pa', 'punjabi', 'panjabi'],
|
|
115
|
+
pus: ['pus', 'pashto'],
|
|
116
|
+
sat: ['sat', 'santali'],
|
|
117
|
+
snd: ['snd', 'sindhi'],
|
|
118
|
+
sin: ['sin', 'sinhala', 'sinhalese'],
|
|
119
|
+
som: ['som', 'somali'],
|
|
120
|
+
swa: ['swa', 'sw', 'swahili'],
|
|
121
|
+
syr: ['syr', 'syriac'],
|
|
122
|
+
tat: ['tat', 'tt', 'tatar'],
|
|
123
|
+
tok: ['tok', 'toki'],
|
|
124
|
+
tuk: ['tuk', 'tk', 'turkmen'],
|
|
125
|
+
urd: ['urd', 'ur', 'urdu'],
|
|
126
|
+
uzb: ['uzb', 'uz', 'uzbek'],
|
|
127
|
+
wel: ['wel', 'cym', 'cy', 'welsh']
|
|
78
128
|
};
|
|
79
129
|
function langMatches(pref, lang) {
|
|
80
130
|
var names = LANG_ALIASES[pref] || [pref];
|
|
@@ -97,6 +147,14 @@
|
|
|
97
147
|
per: 'Persian', fas: 'Persian', fa: 'Persian', slo: 'Slovak', slv: 'Slovenian', may: 'Malay', fil: 'Filipino',
|
|
98
148
|
baq: 'Basque', glg: 'Galician', est: 'Estonian', lav: 'Latvian', lit: 'Lithuanian', ice: 'Icelandic',
|
|
99
149
|
tam: 'Tamil', tel: 'Telugu', ben: 'Bengali', mul: 'Multiple languages', zxx: 'No language',
|
|
150
|
+
afr: 'Afrikaans', alb: 'Albanian', arg: 'Aragonese', arm: 'Armenian', ast: 'Asturian', aze: 'Azerbaijani',
|
|
151
|
+
bel: 'Belarusian', bos: 'Bosnian', bre: 'Breton', bur: 'Burmese', prs: 'Dari', epo: 'Esperanto', ext:
|
|
152
|
+
'Extremaduran', gla: 'Scottish Gaelic', geo: 'Georgian', ibo: 'Igbo', ina: 'Interlingua', gle: 'Irish', kan:
|
|
153
|
+
'Kannada', kaz: 'Kazakh', khm: 'Khmer', kur: 'Kurdish', ltz: 'Luxembourgish', mac: 'Macedonian', mal:
|
|
154
|
+
'Malayalam', mni: 'Manipuri', mar: 'Marathi', mon: 'Mongolian', mne: 'Montenegrin', nav: 'Navajo', nep:
|
|
155
|
+
'Nepali', sme: 'Northern Sami', oci: 'Occitan', ori: 'Odia', pan: 'Punjabi', pus: 'Pashto', sat: 'Santali',
|
|
156
|
+
snd: 'Sindhi', sin: 'Sinhala', som: 'Somali', swa: 'Swahili', syr: 'Syriac', tat: 'Tatar', tok: 'Toki Pona',
|
|
157
|
+
tuk: 'Turkmen', urd: 'Urdu', uzb: 'Uzbek', wel: 'Welsh',
|
|
100
158
|
und: 'Unknown language', '': 'Unknown language' };
|
|
101
159
|
function langName(lang) {
|
|
102
160
|
var k = langKey(lang);
|
|
@@ -122,6 +180,9 @@
|
|
|
122
180
|
// ----- for the other parts (and js/player.js) -----
|
|
123
181
|
P.trackInfo = trackInfo; P.infoLang = infoLang; P.trackLang = trackLang; P.langMatches = langMatches;
|
|
124
182
|
P.langName = langName; P.langRank = langRank; P.langKey = langKey;
|
|
183
|
+
// A track that doesn't say its language (by its key): none, "und", "unknown"…, or no letters.
|
|
184
|
+
// (A language StremioK has no name for is still a language.)
|
|
185
|
+
P.langUnstated = function (k) { k = ('' + (k || '')).trim(); return !/[a-zà-ÿ]/i.test(k) || /^(und|unk|unknown|unknown language|mul|zxx|n\/a|none)$/i.test(k); };
|
|
125
186
|
// A language code's two-letter form (ISO 639-1: "spa" -> "es"), or '' (TMDB asks by it).
|
|
126
187
|
P.lang2 = function (key) { var a = LANG_ALIASES[key] || []; for (var i = 0; i < a.length; i++) { if (/^[a-z]{2}$/.test(a[i])) { return a[i]; } } return ''; };
|
|
127
188
|
})(PlayerParts);
|
package/js/player-store.js
CHANGED
|
@@ -85,7 +85,8 @@
|
|
|
85
85
|
edge: pick3(SUB_EDGES, d.edge)[0], pos: pick3(SUB_POSITIONS, d.pos || 'bottom')[0], // (Bottom unless chosen: Lower comes first in the list)
|
|
86
86
|
font: subFontFamily(d.font) ? d.font : 'default', // an unknown font -> TV default
|
|
87
87
|
skip: skipWords(d.skip), // lines with one of these aren't shown (none by default: see player-subs' skipLines)
|
|
88
|
-
second: typeof d.second === 'string' && /^[a-z]{2,3}$/.test(d.second) ? d.second : 'off'
|
|
88
|
+
second: typeof d.second === 'string' && /^[a-z]{2,3}$/.test(d.second) ? d.second : 'off', // a second subtitle at the top (player-subs; Off by default)
|
|
89
|
+
only: d.only === 'on' ? 'on' : 'off' }; // the subtitle menu: only your languages (player-subs' langMenu; Off by default)
|
|
89
90
|
}
|
|
90
91
|
// Settings › Subtitles › Skip lines with: words (or bits, ".srt"), capitals or not; at most 20.
|
|
91
92
|
function skipWords(x) {
|
|
@@ -129,14 +130,14 @@
|
|
|
129
130
|
var SIZE_PX = { small: 28, medium: 36, large: 46, xlarge: 58 };
|
|
130
131
|
function styleSpan(span) {
|
|
131
132
|
var cfg = getSubCfg();
|
|
132
|
-
span.style.fontSize = (SIZE_PX[cfg.size] || 36) + 'px';
|
|
133
|
+
span.style.fontSize = (SIZE_PX[cfg.size] || 36) / U.zoom() + 'px'; // (their own size, whatever the zoom)
|
|
133
134
|
span.style.fontFamily = subFontFamily(cfg.font);
|
|
134
135
|
span.style.color = pick3(SUB_COLORS, cfg.color)[2];
|
|
135
136
|
span.style.background = pick3(SUB_BGS, cfg.bg)[2];
|
|
136
137
|
span.style.textShadow = pick3(SUB_EDGES, cfg.edge)[2];
|
|
137
138
|
if (span.parentNode) { span.parentNode.style.bottom = Math.max(subsPosPx(), (P.S && P.S.subsLift) || 0) + 'px'; } // (raised over the progress bar: core's liftSubs)
|
|
138
139
|
}
|
|
139
|
-
function subsPosPx() { return pick3(SUB_POSITIONS, getSubCfg().pos)[2]; }
|
|
140
|
+
function subsPosPx() { return pick3(SUB_POSITIONS, getSubCfg().pos)[2] / U.zoom(); }
|
|
140
141
|
|
|
141
142
|
// ---------- progress (Continue Watching) ----------
|
|
142
143
|
function progressAll() { return U.store.get(PROGRESS_KEY, {}); }
|
package/js/player-subs.js
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
|
|
49
49
|
// A new playback: no subtitles yet.
|
|
50
50
|
function resetSubs() {
|
|
51
|
-
_subGen++;
|
|
51
|
+
_subGen++; stopSubLoad();
|
|
52
52
|
_subTracks = []; _cues = null; _subOn = false; _subLabel = ''; _subTrackUrl = '';
|
|
53
53
|
_subDelay = 0; _subTrackId = null; _embSub = null; _embLang = ''; _embWant = null;
|
|
54
54
|
_embDelay = 0; _embQueue = []; _embNudge = null;
|
|
@@ -285,12 +285,52 @@
|
|
|
285
285
|
// Each choice (a track, Off, a built-in one) is a new one: a download still on its way
|
|
286
286
|
// for an earlier choice is dropped when it comes, without a word (_subGen).
|
|
287
287
|
var _subGen = 0;
|
|
288
|
+
// A subtitle file's time to arrive: some servers build it when asked (12 s, seen from an
|
|
289
|
+
// OpenSubtitles proxy); the video plays on meanwhile.
|
|
290
|
+
var SUB_FILE_MS = 20000;
|
|
291
|
+
// The download under way (_subLoad: { url, ctx, cancel, timer, done }): the same track picked
|
|
292
|
+
// again while it comes waits for it (it used to be asked for again, what was on its way
|
|
293
|
+
// dropped: slow servers took several picks); another choice stops it, its connection freed.
|
|
294
|
+
// The files downloaded (the last SUB_FILES_MAX, while StremioK runs) come back at once.
|
|
295
|
+
var _subLoad = null, SUB_FILES_MAX = 8, _subFiles = []; // ([{ url, text }], newest last)
|
|
296
|
+
function subFile(url) { for (var i = 0; i < _subFiles.length; i++) { if (_subFiles[i].url === url) { return _subFiles[i].text; } } return null; }
|
|
297
|
+
function keepSubFile(url, text) {
|
|
298
|
+
_subFiles = _subFiles.filter(function (f) { return f.url !== url; });
|
|
299
|
+
_subFiles.push({ url: url, text: text });
|
|
300
|
+
if (_subFiles.length > SUB_FILES_MAX) { _subFiles.shift(); }
|
|
301
|
+
}
|
|
302
|
+
function stopSubLoad() {
|
|
303
|
+
var l = _subLoad;
|
|
304
|
+
_subLoad = null;
|
|
305
|
+
if (l) { clearInterval(l.timer); l.cancel.cancel(); }
|
|
306
|
+
}
|
|
307
|
+
// A subtitle file: from those kept, else downloaded (the same one shared by whoever asks).
|
|
308
|
+
function subText(track, cancel) {
|
|
309
|
+
var kept = subFile(track.url);
|
|
310
|
+
if (kept !== null) { return Promise.resolve(kept); }
|
|
311
|
+
return U.getText(track.url, SUB_FILE_MS, undefined, cancel || null, false, track.headers || null).then(function (text) { keepSubFile(track.url, text); return text; }); // (a USB file's: the service's header where there's no token)
|
|
312
|
+
}
|
|
288
313
|
function loadTrack(track, onDone) {
|
|
289
314
|
if (!U.parseUrl(track.url)) { U.toast('That subtitle track has no usable link'); return; } // (http(s) only)
|
|
290
|
-
|
|
315
|
+
var l = _subLoad;
|
|
316
|
+
if (l && l.url === track.url && l.ctx === S.ctx) { // (still coming: waited for, not asked for again)
|
|
317
|
+
if (onDone) { l.done.push(onDone); }
|
|
318
|
+
U.toast('Still loading subtitles… ' + l.secs + ' s', 1500);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
stopSubLoad();
|
|
291
322
|
var forCtx = S.ctx, gen = ++_subGen;
|
|
292
323
|
function stale() { return !S.active || S.ctx !== forCtx || gen !== _subGen; } // (another playback, or another choice, meanwhile)
|
|
293
|
-
U.
|
|
324
|
+
var cancel = U.cancelToken(), mine = { url: track.url, ctx: forCtx, cancel: cancel, secs: 0, done: onDone ? [onDone] : [], timer: null };
|
|
325
|
+
if (subFile(track.url) === null) { // (a download: how long it's been, every second, till it's in)
|
|
326
|
+
_subLoad = mine;
|
|
327
|
+
U.toast('Loading subtitles…', 1500);
|
|
328
|
+
mine.timer = setInterval(function () { mine.secs++; if (_subLoad === mine) { U.toast('Loading subtitles… ' + mine.secs + ' s', 1500); } }, 1000);
|
|
329
|
+
}
|
|
330
|
+
function finished() { clearInterval(mine.timer); if (_subLoad === mine) { _subLoad = null; } }
|
|
331
|
+
onDone = function () { mine.done.forEach(function (f) { try { f(); } catch (e) {} }); };
|
|
332
|
+
subText(track, cancel).then(function (text) {
|
|
333
|
+
finished();
|
|
294
334
|
if (stale()) { return; }
|
|
295
335
|
var cues = parseCues(text);
|
|
296
336
|
if (!cues.length) { U.toast('Could not parse subtitles'); return; }
|
|
@@ -299,8 +339,8 @@
|
|
|
299
339
|
_subTrackId = (track.id != null) ? track.id : null; _subDelay = 0;
|
|
300
340
|
renderSubs();
|
|
301
341
|
U.toast('Subtitles: ' + (track.lang || 'on'));
|
|
302
|
-
|
|
303
|
-
}, function () { if (!stale()) { U.toast('Failed to download subtitles'); } });
|
|
342
|
+
onDone();
|
|
343
|
+
}, function () { finished(); if (!stale()) { U.toast('Failed to download subtitles'); } });
|
|
304
344
|
}
|
|
305
345
|
|
|
306
346
|
// ---------- the second subtitle ----------
|
|
@@ -323,7 +363,7 @@
|
|
|
323
363
|
var track = _subTracks.filter(function (t) { return t.url && langMatches(want, t.lang); })[0];
|
|
324
364
|
if (!track || (_cues2 && _sub2Label === track.url)) { if (!track) { secondOff(); } return; }
|
|
325
365
|
var forCtx = S.ctx, gen = ++_sub2Gen;
|
|
326
|
-
|
|
366
|
+
subText(track).then(function (text) {
|
|
327
367
|
if (!S.active || S.ctx !== forCtx || gen !== _sub2Gen) { return; }
|
|
328
368
|
var cues = parseCues(text);
|
|
329
369
|
if (!cues.length) { return; }
|
|
@@ -374,7 +414,7 @@
|
|
|
374
414
|
}
|
|
375
415
|
|
|
376
416
|
function subsOff() {
|
|
377
|
-
_subGen++;
|
|
417
|
+
_subGen++; stopSubLoad(); // (a download under way for a track: stopped)
|
|
378
418
|
_subOn = false; _cues = null; _subLabel = ''; _subTrackUrl = ''; _subTrackId = null; _subDelay = 0;
|
|
379
419
|
embOff();
|
|
380
420
|
S.subsEl.className = 'hidden'; U.clear(S.subsEl);
|
|
@@ -583,19 +623,32 @@
|
|
|
583
623
|
// Level 1: one entry per language, spellings merged ("en", "eng" and "English" are one
|
|
584
624
|
// group), named in full, with the file's own tracks in the same groups as the addons'.
|
|
585
625
|
// Order: the language showing now, the preferred language, then by name.
|
|
586
|
-
|
|
626
|
+
// Only my languages (Settings, Off by default): just your default, second-choice and
|
|
627
|
+
// second-subtitle languages, the one showing, and tracks that don't say their language;
|
|
628
|
+
// Other languages, after them, lists the rest (all: that list).
|
|
629
|
+
function langMenu(all) {
|
|
587
630
|
var groups = Object.create(null), order = []; // (no inherited names: a language an addon calls "__proto__" is just a key)
|
|
631
|
+
function key(l) { var k = langKey(l); return P.langUnstated(k) ? '' : k; } // (no language, "und"…: one Unknown language)
|
|
588
632
|
function add(k, item) {
|
|
589
633
|
if (!groups[k]) { groups[k] = []; order.push(k); }
|
|
590
634
|
groups[k].push(item);
|
|
591
635
|
}
|
|
592
|
-
getTextTracks().forEach(function (tr, i) { add(
|
|
636
|
+
getTextTracks().forEach(function (tr, i) { add(key(textLang(tr)), { emb: tr, n: i }); });
|
|
593
637
|
var offer = S.ctx && !S.ctx._relayCc ? S.ctx._ccOffer : null; // (a live channel's closed captions, not on yet)
|
|
594
|
-
(offer || []).forEach(function (c, i) { add(
|
|
595
|
-
_subTracks.forEach(function (tr) { add(
|
|
596
|
-
var curKey = _subOn ?
|
|
638
|
+
(offer || []).forEach(function (c, i) { add(key(c.lang || ''), { cc: c, n: i, emb: true }); });
|
|
639
|
+
_subTracks.forEach(function (tr) { add(key(tr.lang), { track: tr }); });
|
|
640
|
+
var curKey = _subOn ? key(_subLabel) : (_embSub != null ? key(_embLang) : null);
|
|
597
641
|
var pref = getSubCfg().lang;
|
|
598
642
|
var prefs = [curKey, pref].filter(function (x) { return x && x !== 'off'; });
|
|
643
|
+
var cfg = getSubCfg(), hidden = 0;
|
|
644
|
+
var mine = [cfg.lang, cfg.lang2, cfg.second].filter(function (l) { return l && l !== 'off' && l !== 'none'; });
|
|
645
|
+
if (cfg.only === 'on' && !all && mine.length) {
|
|
646
|
+
order = order.filter(function (k) {
|
|
647
|
+
var keep = k === curKey || k === '' || mine.some(function (l) { return langKey(l) === k || langMatches(l, k); });
|
|
648
|
+
if (!keep) { hidden++; }
|
|
649
|
+
return keep;
|
|
650
|
+
});
|
|
651
|
+
}
|
|
599
652
|
order.sort(function (a, b) {
|
|
600
653
|
var ra = langRank(a, prefs), rb = langRank(b, prefs);
|
|
601
654
|
if (ra !== rb) { return ra - rb; }
|
|
@@ -610,11 +663,12 @@
|
|
|
610
663
|
sel: (k === curKey),
|
|
611
664
|
run: function () { pushMenu(langTracksMenu(k, list)); } });
|
|
612
665
|
});
|
|
666
|
+
if (hidden) { items.push({ label: 'Other languages', detail: hidden + ' more', run: function () { pushMenu(langMenu(true)); } }); }
|
|
613
667
|
var sec = getSubCfg().second;
|
|
614
668
|
if (_subTracks.length) { items.push({ label: 'Second subtitle: ' + (sec === 'off' ? 'Off' : langName(sec)), detail: 'At the top, at the same time', run: function () { pushMenu(secondMenu()); } }); }
|
|
615
669
|
var idx = 0;
|
|
616
670
|
for (var i = 0; i < items.length; i++) { if (items[i].sel) { idx = i; break; } }
|
|
617
|
-
return { title: 'Subtitle language', items: items, idx: idx, rebuild: langMenu };
|
|
671
|
+
return { title: all ? 'All subtitle languages' : 'Subtitle language', items: items, idx: idx, rebuild: function () { return langMenu(all); } };
|
|
618
672
|
}
|
|
619
673
|
|
|
620
674
|
function inFile() { return S.ctx && (S.ctx._relayCc || S.ctx._ccOffer) ? 'closed captions' : 'in the file'; }
|