First separation commit.

Added LICENSE, README.md, CONTRIBUTORS.md
This commit is contained in:
Erwin de Haan 2019-01-09 12:36:54 +01:00
parent 09513af31b
commit 4678528d00
657 changed files with 422 additions and 0 deletions

View file

@ -0,0 +1,198 @@
define(["dialogHelper", "globalize", "connectionManager", "events", "browser", "require", "emby-checkbox", "emby-collapse", "css!./style"], function(dialogHelper, globalize, connectionManager, events, browser, require) {
"use strict";
function renderOptions(context, selector, cssClass, items, isCheckedFn) {
var elem = context.querySelector(selector);
items.length ? elem.classList.remove("hide") : elem.classList.add("hide");
var html = "";
html += '<div class="checkboxList">', html += items.map(function(filter) {
var itemHtml = "",
checkedHtml = isCheckedFn(filter) ? " checked" : "";
return itemHtml += "<label>", itemHtml += '<input is="emby-checkbox" type="checkbox"' + checkedHtml + ' data-filter="' + filter + '" class="' + cssClass + '"/>', itemHtml += "<span>" + filter + "</span>", itemHtml += "</label>"
}).join(""), html += "</div>", elem.querySelector(".filterOptions").innerHTML = html
}
function renderFilters(context, result, query) {
result.Tags && (result.Tags.length = Math.min(result.Tags.length, 50)), renderOptions(context, ".genreFilters", "chkGenreFilter", result.Genres, function(i) {
return -1 != ("|" + (query.Genres || "") + "|").indexOf("|" + i + "|")
}), renderOptions(context, ".officialRatingFilters", "chkOfficialRatingFilter", result.OfficialRatings, function(i) {
return -1 != ("|" + (query.OfficialRatings || "") + "|").indexOf("|" + i + "|")
}), renderOptions(context, ".tagFilters", "chkTagFilter", result.Tags, function(i) {
return -1 != ("|" + (query.Tags || "") + "|").indexOf("|" + i + "|")
}), renderOptions(context, ".yearFilters", "chkYearFilter", result.Years, function(i) {
return -1 != ("," + (query.Years || "") + ",").indexOf("," + i + ",")
})
}
function loadDynamicFilters(context, apiClient, userId, itemQuery) {
return apiClient.getJSON(apiClient.getUrl("Items/Filters", {
UserId: userId,
ParentId: itemQuery.ParentId,
IncludeItemTypes: itemQuery.IncludeItemTypes
})).then(function(result) {
renderFilters(context, result, itemQuery)
})
}
function updateFilterControls(context, options) {
var elems, i, length, query = options.query;
if ("livetvchannels" == options.mode) context.querySelector(".chkFavorite").checked = 1 == query.IsFavorite, context.querySelector(".chkLikes").checked = 1 == query.IsLiked, context.querySelector(".chkDislikes").checked = 1 == query.IsDisliked;
else
for (elems = context.querySelectorAll(".chkStandardFilter"), i = 0, length = elems.length; i < length; i++) {
var chkStandardFilter = elems[i],
filters = "," + (query.Filters || ""),
filterName = chkStandardFilter.getAttribute("data-filter");
chkStandardFilter.checked = -1 != filters.indexOf("," + filterName)
}
for (elems = context.querySelectorAll(".chkVideoTypeFilter"), i = 0, length = elems.length; i < length; i++) {
var chkVideoTypeFilter = elems[i],
filters = "," + (query.VideoTypes || ""),
filterName = chkVideoTypeFilter.getAttribute("data-filter");
chkVideoTypeFilter.checked = -1 != filters.indexOf("," + filterName)
}
for (context.querySelector(".chk3DFilter").checked = 1 == query.Is3D, context.querySelector(".chkHDFilter").checked = 1 == query.IsHD, context.querySelector(".chk4KFilter").checked = 1 == query.Is4K, context.querySelector(".chkSDFilter").checked = 1 == query.IsHD, context.querySelector("#chkSubtitle").checked = 1 == query.HasSubtitles, context.querySelector("#chkTrailer").checked = 1 == query.HasTrailer, context.querySelector("#chkThemeSong").checked = 1 == query.HasThemeSong, context.querySelector("#chkThemeVideo").checked = 1 == query.HasThemeVideo, context.querySelector("#chkSpecialFeature").checked = 1 == query.HasSpecialFeature, context.querySelector("#chkSpecialEpisode").checked = 0 == query.ParentIndexNumber, context.querySelector("#chkMissingEpisode").checked = 1 == query.IsMissing, context.querySelector("#chkFutureEpisode").checked = 1 == query.IsUnaired, i = 0, length = elems.length; i < length; i++) {
var chkStatus = elems[i],
filters = "," + (query.SeriesStatus || ""),
filterName = chkStatus.getAttribute("data-filter");
chkStatus.checked = -1 != filters.indexOf("," + filterName)
}
}
function triggerChange(instance) {
events.trigger(instance, "filterchange")
}
function parentWithClass(elem, className) {
for (; !elem.classList || !elem.classList.contains(className);)
if (!(elem = elem.parentNode)) return null;
return elem
}
function setVisibility(context, options) {
"livetvchannels" != options.mode && "albums" != options.mode && "artists" != options.mode && "albumartists" != options.mode && "songs" != options.mode || hideByClass(context, "videoStandard"), enableDynamicFilters(options.mode) && (context.querySelector(".genreFilters").classList.remove("hide"), context.querySelector(".officialRatingFilters").classList.remove("hide"), context.querySelector(".tagFilters").classList.remove("hide"), context.querySelector(".yearFilters").classList.remove("hide")), "movies" != options.mode && "episodes" != options.mode || context.querySelector(".videoTypeFilters").classList.remove("hide"), options.mode, "movies" != options.mode && "series" != options.mode && "games" != options.mode && "episodes" != options.mode || context.querySelector(".features").classList.remove("hide"), "series" == options.mode && context.querySelector(".seriesStatus").classList.remove("hide"), "episodes" == options.mode && showByClass(context, "episodeFilter")
}
function showByClass(context, className) {
for (var elems = context.querySelectorAll("." + className), i = 0, length = elems.length; i < length; i++) elems[i].classList.remove("hide")
}
function hideByClass(context, className) {
for (var elems = context.querySelectorAll("." + className), i = 0, length = elems.length; i < length; i++) elems[i].classList.add("hide")
}
function enableDynamicFilters(mode) {
return "movies" == mode || "games" == mode || "series" == mode || "albums" == mode || "albumartists" == mode || "artists" == mode || "songs" == mode || "episodes" == mode
}
return function(options) {
function onFavoriteChange() {
var query = options.query;
query.StartIndex = 0, query.IsFavorite = !!this.checked || null, triggerChange(self)
}
function onStandardFilterChange() {
var query = options.query,
filterName = this.getAttribute("data-filter"),
filters = query.Filters || "";
filters = ("," + filters).replace("," + filterName, "").substring(1), this.checked && (filters = filters ? filters + "," + filterName : filterName), query.StartIndex = 0, query.Filters = filters, triggerChange(self)
}
function onVideoTypeFilterChange() {
var query = options.query,
filterName = this.getAttribute("data-filter"),
filters = query.VideoTypes || "";
filters = ("," + filters).replace("," + filterName, "").substring(1), this.checked && (filters = filters ? filters + "," + filterName : filterName), query.StartIndex = 0, query.VideoTypes = filters, triggerChange(self)
}
function onStatusChange() {
var query = options.query,
filterName = this.getAttribute("data-filter"),
filters = query.SeriesStatus || "";
filters = ("," + filters).replace("," + filterName, "").substring(1), this.checked && (filters = filters ? filters + "," + filterName : filterName), query.SeriesStatus = filters, query.StartIndex = 0, triggerChange(self)
}
function bindEvents(context) {
var elems, i, length, query = options.query;
if ("livetvchannels" == options.mode) {
for (elems = context.querySelectorAll(".chkFavorite"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("change", onFavoriteChange);
context.querySelector(".chkLikes").addEventListener("change", function() {
query.StartIndex = 0, query.IsLiked = !!this.checked || null, triggerChange(self)
}), context.querySelector(".chkDislikes").addEventListener("change", function() {
query.StartIndex = 0, query.IsDisliked = !!this.checked || null, triggerChange(self)
})
} else
for (elems = context.querySelectorAll(".chkStandardFilter"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("change", onStandardFilterChange);
for (elems = context.querySelectorAll(".chkVideoTypeFilter"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("change", onVideoTypeFilterChange);
for (context.querySelector(".chk3DFilter").addEventListener("change", function() {
query.StartIndex = 0, query.Is3D = !!this.checked || null, triggerChange(self)
}), context.querySelector(".chk4KFilter").addEventListener("change", function() {
query.StartIndex = 0, query.Is4K = !!this.checked || null, triggerChange(self)
}), context.querySelector(".chkHDFilter").addEventListener("change", function() {
query.StartIndex = 0, query.IsHD = !!this.checked || null, triggerChange(self)
}), context.querySelector(".chkSDFilter").addEventListener("change", function() {
query.StartIndex = 0, query.IsHD = !this.checked && null, triggerChange(self)
}), elems = context.querySelectorAll(".chkStatus"), i = 0, length = elems.length; i < length; i++) elems[i].addEventListener("change", onStatusChange);
context.querySelector("#chkTrailer").addEventListener("change", function() {
query.StartIndex = 0, query.HasTrailer = !!this.checked || null, triggerChange(self)
}), context.querySelector("#chkThemeSong").addEventListener("change", function() {
query.StartIndex = 0, query.HasThemeSong = !!this.checked || null, triggerChange(self)
}), context.querySelector("#chkSpecialFeature").addEventListener("change", function() {
query.StartIndex = 0, query.HasSpecialFeature = !!this.checked || null, triggerChange(self)
}), context.querySelector("#chkThemeVideo").addEventListener("change", function() {
query.StartIndex = 0, query.HasThemeVideo = !!this.checked || null, triggerChange(self)
}), context.querySelector("#chkMissingEpisode").addEventListener("change", function() {
query.StartIndex = 0, this.checked ? (query.IsMissing = !0, query.IsUnaired = !1) : (query.IsMissing = !1, query.IsUnaired = context.querySelector("#chkFutureEpisode").checked || null), triggerChange(self)
}), context.querySelector("#chkSpecialEpisode").addEventListener("change", function() {
query.StartIndex = 0, query.ParentIndexNumber = this.checked ? 0 : null, triggerChange(self)
}), context.querySelector("#chkFutureEpisode").addEventListener("change", function() {
query.StartIndex = 0, this.checked ? (query.IsUnaired = !0, query.IsMissing = null) : (query.IsUnaired = null, query.IsMissing = context.querySelector("#chkMissingEpisode").checked), triggerChange(self)
}), context.querySelector("#chkSubtitle").addEventListener("change", function() {
query.StartIndex = 0, query.HasSubtitles = !!this.checked || null, triggerChange(self)
}), context.addEventListener("change", function(e) {
var chkGenreFilter = parentWithClass(e.target, "chkGenreFilter");
if (chkGenreFilter) {
var filterName = chkGenreFilter.getAttribute("data-filter"),
filters = query.Genres || "",
delimiter = "|";
return filters = (delimiter + filters).replace(delimiter + filterName, "").substring(1), chkGenreFilter.checked && (filters = filters ? filters + delimiter + filterName : filterName), query.StartIndex = 0, query.Genres = filters, void triggerChange(self)
}
var chkTagFilter = parentWithClass(e.target, "chkTagFilter");
if (chkTagFilter) {
var filterName = chkTagFilter.getAttribute("data-filter"),
filters = query.Tags || "",
delimiter = "|";
return filters = (delimiter + filters).replace(delimiter + filterName, "").substring(1), chkTagFilter.checked && (filters = filters ? filters + delimiter + filterName : filterName), query.StartIndex = 0, query.Tags = filters, void triggerChange(self)
}
var chkYearFilter = parentWithClass(e.target, "chkYearFilter");
if (chkYearFilter) {
var filterName = chkYearFilter.getAttribute("data-filter"),
filters = query.Years || "",
delimiter = ",";
return filters = (delimiter + filters).replace(delimiter + filterName, "").substring(1), chkYearFilter.checked && (filters = filters ? filters + delimiter + filterName : filterName), query.StartIndex = 0, query.Years = filters, void triggerChange(self)
}
var chkOfficialRatingFilter = parentWithClass(e.target, "chkOfficialRatingFilter");
if (chkOfficialRatingFilter) {
var filterName = chkOfficialRatingFilter.getAttribute("data-filter"),
filters = query.OfficialRatings || "",
delimiter = "|";
return filters = (delimiter + filters).replace(delimiter + filterName, "").substring(1), chkOfficialRatingFilter.checked && (filters = filters ? filters + delimiter + filterName : filterName), query.StartIndex = 0, query.OfficialRatings = filters, void triggerChange(self)
}
})
}
var self = this;
self.show = function() {
return new Promise(function(resolve, reject) {
require(["text!./filterdialog.template.html"], function(template) {
var dlg = dialogHelper.createDialog({
removeOnClose: !0,
modal: !1
});
if (dlg.classList.add("ui-body-a"), dlg.classList.add("background-theme-a"), dlg.classList.add("formDialog"), dlg.classList.add("filterDialog"), dlg.innerHTML = globalize.translateDocument(template), setVisibility(dlg, options), dialogHelper.open(dlg), dlg.addEventListener("close", resolve), updateFilterControls(dlg, options), bindEvents(dlg), enableDynamicFilters(options.mode)) {
dlg.classList.add("dynamicFilterDialog");
var apiClient = connectionManager.getApiClient(options.serverId);
loadDynamicFilters(dlg, apiClient, apiClient.getCurrentUserId(), options.query)
}
})
})
}
}
});

View file

@ -0,0 +1,154 @@
<div style="margin: 0;padding:1.5em 2em;" class="filterDialogContent">
<h2 style="margin-bottom: .25em;">
${HeaderFilters}
</h2>
<div class="checkboxList">
<label>
<input type="checkbox" is="emby-checkbox" class="chkStandardFilter videoStandard" data-filter="IsPlayed" />
<span>${OptionPlayed}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkStandardFilter videoStandard" data-filter="IsUnPlayed" />
<span>${OptionUnplayed}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkStandardFilter videoStandard" data-filter="IsResumable" />
<span>${OptionResumable}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkStandardFilter chkFavorite" data-filter="IsFavorite" />
<span>${OptionFavorite}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkStandardFilter chkLikes" data-filter="Likes" />
<span>${OptionLikes}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkStandardFilter chkDislikes" data-filter="Dislikes" />
<span>${OptionDislikes}</span>
</label>
<label class="episodeFilter hide">
<input type="checkbox" is="emby-checkbox" id="chkSpecialEpisode" />
<span>${OptionSpecialEpisode}</span>
</label>
<label class="episodeFilter hide">
<input type="checkbox" is="emby-checkbox" id="chkMissingEpisode" />
<span>${OptionMissingEpisode}</span>
</label>
<label class="episodeFilter hide">
<input type="checkbox" is="emby-checkbox" id="chkFutureEpisode" />
<span>${OptionUnairedEpisode}</span>
</label>
</div>
<div class="seriesStatus hide">
<br />
<h2 style="margin-bottom: .25em;">
${HeaderStatus}
</h2>
<div class="checkboxList">
<label>
<input type="checkbox" is="emby-checkbox" class="chkStatus" data-filter="Continuing" />
<span>${OptionContinuing}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkStatus" data-filter="Ended" />
<span>${OptionEnded}</span>
</label>
</div>
</div>
<br />
<div is="emby-collapse" title="${HeaderFeatures}" class="features hide">
<div class="collapseContent">
<div class="checkboxList">
<label>
<input type="checkbox" is="emby-checkbox" class="chkFeatureFilter" id="chkSubtitle" />
<span>${OptionHasSubtitles}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkFeatureFilter" id="chkTrailer" />
<span>${OptionHasTrailer}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkFeatureFilter" id="chkSpecialFeature" />
<span>${OptionHasSpecialFeatures}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkFeatureFilter" id="chkThemeSong" />
<span>${OptionHasThemeSong}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkFeatureFilter" id="chkThemeVideo" />
<span>${OptionHasThemeVideo}</span>
</label>
</div>
</div>
</div>
<!--<div class="players hide">
<h2 style="margin-bottom: .25em;">
${HeaderNumberOfPlayers}
</h2>
<paper-radio-group class="playersRadioGroup" selected="all">
<paper-radio-button class="radioPlayers" name="all">${OptionAnyNumberOfPlayers}</paper-radio-button>
<paper-radio-button class="radioPlayers" name="2">${Option2Player}</paper-radio-button>
<paper-radio-button class="radioPlayers" name="3">${Option3Player}</paper-radio-button>
<paper-radio-button class="radioPlayers" name="4">${Option4Player}</paper-radio-button>
</paper-radio-group>
</div>-->
<div is="emby-collapse" title="${HeaderGenres}" class="genreFilters hide">
<div class="collapseContent filterOptions">
</div>
</div>
<div is="emby-collapse" title="${HeaderParentalRatings}" class="officialRatingFilters hide">
<div class="collapseContent filterOptions">
</div>
</div>
<div is="emby-collapse" title="${HeaderTags}" class="tagFilters hide">
<div class="collapseContent filterOptions">
</div>
</div>
<div is="emby-collapse" title="${HeaderVideoTypes}" class="videoTypeFilters hide">
<div class="collapseContent">
<div class="checkboxList">
<label>
<input type="checkbox" is="emby-checkbox" class="chkVideoTypeFilter chkBluray" data-filter="Bluray" />
<span>${OptionBluray}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkVideoTypeFilter chkDvd" data-filter="Dvd" />
<span>${OptionDvd}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkHDFilter IsHD" />
<span>${OptionIsHD}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chk4KFilter Is4K" />
<span>4K</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chkSDFilter IsHD" />
<span>${OptionIsSD}</span>
</label>
<label>
<input type="checkbox" is="emby-checkbox" class="chk3DFilter chk3D" />
<span>${Option3D}</span>
</label>
</div>
</div>
</div>
<div is="emby-collapse" title="${HeaderYears}" class="yearFilters hide">
<div class="collapseContent filterOptions">
</div>
</div>
</div>

View file

@ -0,0 +1,36 @@
.dynamicFilterDialog {
position: fixed !important;
top: 5% !important;
bottom: 5% !important;
margin-top: 0 !important;
margin-bottom: 0 !important;
margin-right: 0 !important;
-webkit-border-radius: 0 !important;
border-radius: 0 !important;
max-height: none !important;
max-width: none !important
}
@media all and (min-height:600px) {
.dynamicFilterDialog {
top: 10% !important;
bottom: 10% !important
}
}
@media all and (max-width:400px) {
.dynamicFilterDialog {
width: auto;
left: 10vw !important;
right: 10vw !important;
margin-left: 0 !important
}
}
@media all and (min-width:400px) {
.dynamicFilterDialog {
width: 300px;
margin-left: -150px !important;
left: 50% !important
}
}