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
139 changes: 138 additions & 1 deletion Emby/Emby.Plugins.Moonfin/Pages/configPage.html
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ <h3 class="sectionTitle">Default User Settings</h3>
<button type="button" class="defaultsSubtabBtn" data-subtab="home-screen">Home Screen</button>
<button type="button" class="defaultsSubtabBtn" data-subtab="home-sections">Home Sections</button>
<button type="button" class="defaultsSubtabBtn" data-subtab="libraries">Libraries</button>
<button type="button" class="defaultsSubtabBtn" data-subtab="playback">Playback</button>
<button type="button" class="defaultsSubtabBtn" data-subtab="extras">Extras</button>
<button type="button" class="defaultsSubtabBtn" data-subtab="integrations">Integrations</button>
</div>
Expand Down Expand Up @@ -1385,7 +1386,143 @@ <h4 style="margin: 1.5em 0 0.5em; font-size: 0.95em; color: #00a4dc;">Library Vi
</div>
</div>

<!-- 7. Extras -->
<!-- 7. Playback -->
<div class="defaultsSubtabPanel" data-subtab="playback">
<h4 style="margin: 1em 0 0.5em; font-size: 0.95em; color: #00a4dc;">Video Playback</h4>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultResumeSubtractDuration">Resume Rewind</label>
<select id="DefaultResumeSubtractDuration" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="0">Disabled</option>
<option value="5">5 seconds</option>
<option value="10">10 seconds</option>
<option value="15">15 seconds</option>
<option value="30">30 seconds</option>
</select>
<div class="fieldDescription">Automatically rewinds slightly when resuming an in-progress video.</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultUnpauseRewindDuration">Unpause Rewind</label>
<select id="DefaultUnpauseRewindDuration" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="0">Disabled</option>
<option value="5000">5 seconds</option>
<option value="10000">10 seconds</option>
<option value="15000">15 seconds</option>
<option value="30000">30 seconds</option>
</select>
<div class="fieldDescription">Rewinds slightly when unpausing playback.</div>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultSkipBackLength">Skip Back Length</label>
<select id="DefaultSkipBackLength" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="5000">5 seconds</option>
<option value="10000">10 seconds</option>
<option value="15000">15 seconds</option>
<option value="30000">30 seconds</option>
</select>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultSkipForwardLength">Skip Forward Length</label>
<select id="DefaultSkipForwardLength" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="5000">5 seconds</option>
<option value="10000">10 seconds</option>
<option value="15000">15 seconds</option>
<option value="30000">30 seconds</option>
</select>
</div>

<h4 style="margin: 1.5em 0 0.5em; font-size: 0.95em; color: #00a4dc;">Audio Playback</h4>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultDefaultAudioLanguage">Default Audio Language</label>
<select id="DefaultDefaultAudioLanguage" is="emby-select"></select>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultPreferDefaultAudioTrack">Prefer Default Audio Track</label>
<select id="DefaultPreferDefaultAudioTrack" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultPreferAudioDescription">Prefer Audio Description</label>
<select id="DefaultPreferAudioDescription" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>

<h4 style="margin: 1.5em 0 0.5em; font-size: 0.95em; color: #00a4dc;">Subtitle Preferences</h4>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultSubtitleMode">Subtitle Mode</label>
<select id="DefaultSubtitleMode" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="flagged">Flagged</option>
<option value="always">Always</option>
<option value="foreign">Foreign</option>
<option value="forced">Forced</option>
<option value="none">None</option>
</select>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultDefaultSubtitleLanguage">Default Subtitle Language</label>
<select id="DefaultDefaultSubtitleLanguage" is="emby-select"></select>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultPreferSdhSubtitles">Prefer SDH Subtitles</label>
<select id="DefaultPreferSdhSubtitles" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>

<h4 style="margin: 1.5em 0 0.5em; font-size: 0.95em; color: #00a4dc;">Automation &amp; Queue</h4>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultCinemaModeEnabled">Cinema Mode</label>
<select id="DefaultCinemaModeEnabled" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultAutoplayNextEpisode">Autoplay Next Episode</label>
<select id="DefaultAutoplayNextEpisode" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultNextUpTimeout">Next Up Timeout</label>
<select id="DefaultNextUpTimeout" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="5000">5 seconds</option>
<option value="7000">7 seconds</option>
<option value="10000">10 seconds</option>
<option value="15000">15 seconds</option>
<option value="30000">30 seconds</option>
</select>
</div>
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="DefaultStillWatchingBehavior">Still Watching Prompt</label>
<select id="DefaultStillWatchingBehavior" is="emby-select">
<option value="">Not set (user decides)</option>
<option value="disabled">Off</option>
<option value="short_">After 2 episodes</option>
<option value="medium">After 3 episodes</option>
<option value="long_">After 5 episodes</option>
<option value="veryLong">After 8 episodes</option>
</select>
</div>
</div>

<!-- 8. Extras -->
<div class="defaultsSubtabPanel" data-subtab="extras">
<h4 style="margin: 1em 0 0.5em; font-size: 0.95em; color: #00a4dc;">Media Bar</h4>
<div class="inputContainer">
Expand Down
68 changes: 68 additions & 0 deletions Emby/Emby.Plugins.Moonfin/Pages/moonfin.js
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,35 @@ define(['baseView', 'loading', 'emby-input', 'emby-button', 'emby-checkbox', 'em
return result.length > 0 ? result : null;
}

// ISO 639-2 codes, matching the table Core resolves track languages against.
// The audio and subtitle pickers share the list so the two stay in sync.
var LANGUAGE_OPTIONS = [
['auto', 'Server Default'], ['eng', 'English'], ['spa', 'Spanish'],
['fra', 'French'], ['deu', 'German'], ['ita', 'Italian'],
['jpn', 'Japanese'], ['kor', 'Korean'], ['zho', 'Chinese'],
['rus', 'Russian'], ['por', 'Portuguese'], ['ara', 'Arabic'],
['hin', 'Hindi'], ['nld', 'Dutch'], ['pol', 'Polish'],
['swe', 'Swedish'], ['nor', 'Norwegian'], ['dan', 'Danish'],
['fin', 'Finnish'], ['tha', 'Thai'], ['tur', 'Turkish'],
['heb', 'Hebrew'], ['ces', 'Czech'], ['ell', 'Greek'],
['ron', 'Romanian'], ['hun', 'Hungarian'], ['ukr', 'Ukrainian'],
['ind', 'Indonesian'], ['vie', 'Vietnamese']
];

function fillLanguageSelect(view, selector) {
var select = view.querySelector(selector);
if (!select || select.dataset.filled) return;
select.dataset.filled = 'true';
var html = '<option value="">Not set (user decides)</option>';
for (var i = 0; i < LANGUAGE_OPTIONS.length; i++) {
var code = LANGUAGE_OPTIONS[i][0];
var label = LANGUAGE_OPTIONS[i][1];
html += '<option value="' + esc(code) + '">'
+ esc(code === 'auto' ? label : label + ' (' + code + ')') + '</option>';
}
select.innerHTML = html;
}

// Same ids and declaration order as DetailButton in Core, so an untouched
// arrangement here matches what a fresh client shows.
var DETAIL_BUTTONS = [
Expand Down Expand Up @@ -1744,6 +1773,26 @@ define(['baseView', 'loading', 'emby-input', 'emby-button', 'emby-checkbox', 'em
setNullableBoolSelect(view, '#DefaultPreviewAudioEnabled', defaults.previewAudioEnabled);
setSelectValue(view, '#DefaultSeasonalSurprise', defaults.seasonalSurprise, 'Configured surprise');

setSelectValue(view, '#DefaultResumeSubtractDuration', defaults.resumeSubtractDuration != null ? String(defaults.resumeSubtractDuration) : '', 'Configured rewind');
setSelectValue(view, '#DefaultUnpauseRewindDuration', defaults.unpauseRewindDuration != null ? String(defaults.unpauseRewindDuration) : '', 'Configured rewind');
setSelectValue(view, '#DefaultSkipBackLength', defaults.skipBackLength != null ? String(defaults.skipBackLength) : '', 'Configured skip');
setSelectValue(view, '#DefaultSkipForwardLength', defaults.skipForwardLength != null ? String(defaults.skipForwardLength) : '', 'Configured skip');

fillLanguageSelect(view, '#DefaultDefaultAudioLanguage');
fillLanguageSelect(view, '#DefaultDefaultSubtitleLanguage');
setSelectValue(view, '#DefaultDefaultAudioLanguage', defaults.defaultAudioLanguage, 'Configured language');
setNullableBoolSelect(view, '#DefaultPreferDefaultAudioTrack', defaults.preferDefaultAudioTrack);
setNullableBoolSelect(view, '#DefaultPreferAudioDescription', defaults.preferAudioDescription);

setSelectValue(view, '#DefaultSubtitleMode', defaults.subtitleMode, 'Configured mode');
setSelectValue(view, '#DefaultDefaultSubtitleLanguage', defaults.defaultSubtitleLanguage, 'Configured language');
setNullableBoolSelect(view, '#DefaultPreferSdhSubtitles', defaults.preferSdhSubtitles);

setNullableBoolSelect(view, '#DefaultCinemaModeEnabled', defaults.cinemaModeEnabled);
setNullableBoolSelect(view, '#DefaultAutoplayNextEpisode', defaults.autoplayNextEpisode);
setSelectValue(view, '#DefaultNextUpTimeout', defaults.nextUpTimeout != null ? String(defaults.nextUpTimeout) : '', 'Configured timeout');
setSelectValue(view, '#DefaultStillWatchingBehavior', defaults.stillWatchingBehavior, 'Configured behavior');

setSelectValue(view, '#DefaultHomeRowsStyle', defaults.homeRowsStyle, 'Configured style');
setNullableBoolSelect(view, '#DefaultFullScreenRows', defaults.fullScreenRows);
setNullableBoolSelect(view, '#DefaultHomeRowInfoOverlay', defaults.homeRowInfoOverlay);
Expand Down Expand Up @@ -1887,6 +1936,25 @@ define(['baseView', 'loading', 'emby-input', 'emby-button', 'emby-checkbox', 'em
d.previewAudioEnabled = getNullableBoolSelect(view, '#DefaultPreviewAudioEnabled');
d.seasonalSurprise = view.querySelector('#DefaultSeasonalSurprise').value || null;

// Clients store this one as text, unlike the millisecond fields below.
d.resumeSubtractDuration = view.querySelector('#DefaultResumeSubtractDuration').value || null;
d.unpauseRewindDuration = getNullableIntInput(view, '#DefaultUnpauseRewindDuration');
d.skipBackLength = getNullableIntInput(view, '#DefaultSkipBackLength');
d.skipForwardLength = getNullableIntInput(view, '#DefaultSkipForwardLength');

d.defaultAudioLanguage = view.querySelector('#DefaultDefaultAudioLanguage').value.trim() || null;
d.preferDefaultAudioTrack = getNullableBoolSelect(view, '#DefaultPreferDefaultAudioTrack');
d.preferAudioDescription = getNullableBoolSelect(view, '#DefaultPreferAudioDescription');

d.subtitleMode = view.querySelector('#DefaultSubtitleMode').value || null;
d.defaultSubtitleLanguage = view.querySelector('#DefaultDefaultSubtitleLanguage').value.trim() || null;
d.preferSdhSubtitles = getNullableBoolSelect(view, '#DefaultPreferSdhSubtitles');

d.cinemaModeEnabled = getNullableBoolSelect(view, '#DefaultCinemaModeEnabled');
d.autoplayNextEpisode = getNullableBoolSelect(view, '#DefaultAutoplayNextEpisode');
d.nextUpTimeout = getNullableIntInput(view, '#DefaultNextUpTimeout');
d.stillWatchingBehavior = view.querySelector('#DefaultStillWatchingBehavior').value || null;

var collectionIds = Array.prototype.slice.call(view.querySelectorAll('.adminCollectionCb:checked')).map(function (cb) { return cb.dataset.id; });
d.mediaBarCollectionIds = collectionIds.length > 0 ? collectionIds : null;
var libraryIds = Array.prototype.slice.call(view.querySelectorAll('.adminLibraryCb:checked')).map(function (cb) { return cb.dataset.id; });
Expand Down
Loading
Loading