diff --git a/src/components/tabbedview/tabbedview.js b/src/components/tabbedview/tabbedview.js
deleted file mode 100644
index 46b14ed36e..0000000000
--- a/src/components/tabbedview/tabbedview.js
+++ /dev/null
@@ -1,114 +0,0 @@
-import { clearBackdrop } from '../backdrop/backdrop';
-import * as mainTabsManager from '../maintabsmanager';
-import layoutManager from '../layoutManager';
-import '../../elements/emby-tabs/emby-tabs';
-import LibraryMenu from '../../scripts/libraryMenu';
-
-function onViewDestroy() {
- const tabControllers = this.tabControllers;
-
- if (tabControllers) {
- tabControllers.forEach(function (t) {
- if (t.destroy) {
- t.destroy();
- }
- });
-
- this.tabControllers = null;
- }
-
- this.view = null;
- this.params = null;
- this.currentTabController = null;
- this.initialTabIndex = null;
-}
-
-class TabbedView {
- constructor(view, params) {
- this.tabControllers = [];
- this.view = view;
- this.params = params;
-
- const self = this;
-
- let currentTabIndex = parseInt(params.tab || this.getDefaultTabIndex(params.parentId));
- this.initialTabIndex = currentTabIndex;
-
- function validateTabLoad(index) {
- return self.validateTabLoad ? self.validateTabLoad(index) : Promise.resolve();
- }
-
- function loadTab(index, previousIndex) {
- validateTabLoad(index).then(function () {
- self.getTabController(index).then(function (controller) {
- const refresh = !controller.refreshed;
-
- controller.onResume({
- autoFocus: previousIndex == null && layoutManager.tv,
- refresh: refresh
- });
-
- controller.refreshed = true;
-
- currentTabIndex = index;
- self.currentTabController = controller;
- });
- });
- }
-
- function getTabContainers() {
- return view.querySelectorAll('.tabContent');
- }
-
- function onTabChange(e) {
- const newIndex = parseInt(e.detail.selectedTabIndex);
- const previousIndex = e.detail.previousIndex;
-
- const previousTabController = previousIndex == null ? null : self.tabControllers[previousIndex];
- if (previousTabController && previousTabController.onPause) {
- previousTabController.onPause();
- }
-
- loadTab(newIndex, previousIndex);
- }
-
- view.addEventListener('viewbeforehide', this.onPause.bind(this));
-
- view.addEventListener('viewbeforeshow', function () {
- mainTabsManager.setTabs(view, currentTabIndex, self.getTabs, getTabContainers, null, onTabChange, false);
- });
-
- view.addEventListener('viewshow', function (e) {
- self.onResume(e.detail);
- });
-
- view.addEventListener('viewdestroy', onViewDestroy.bind(this));
- }
-
- onResume() {
- this.setTitle();
- clearBackdrop();
-
- const currentTabController = this.currentTabController;
-
- if (!currentTabController) {
- mainTabsManager.selectedTabIndex(this.initialTabIndex);
- } else if (currentTabController && currentTabController.onResume) {
- currentTabController.onResume({});
- }
- }
-
- onPause() {
- const currentTabController = this.currentTabController;
-
- if (currentTabController && currentTabController.onPause) {
- currentTabController.onPause();
- }
- }
-
- setTitle() {
- LibraryMenu.setTitle('');
- }
-}
-
-export default TabbedView;
diff --git a/src/components/toast/toast.scss b/src/components/toast/toast.scss
index 05a7fda0a1..18a2c6d155 100644
--- a/src/components/toast/toast.scss
+++ b/src/components/toast/toast.scss
@@ -3,7 +3,12 @@
bottom: 0;
pointer-events: none;
z-index: 9999999;
- padding: 1em;
+ padding-left: 1em;
+ padding-left: max(env(safe-area-inset-left), 1em);
+ padding-right: 1em;
+ padding-top: 1em;
+ padding-bottom: 1em;
+ padding-bottom: max(env(safe-area-inset-bottom), 1em);
display: flex;
flex-direction: column;
diff --git a/src/components/viewManager/viewManager.js b/src/components/viewManager/viewManager.js
index 5073cccf8c..48c708d2a0 100644
--- a/src/components/viewManager/viewManager.js
+++ b/src/components/viewManager/viewManager.js
@@ -21,9 +21,9 @@ viewContainer.setOnBeforeChange(function (newView, isRestored, options) {
newView.initComplete = true;
if (typeof options.controllerFactory === 'function') {
- new options.controllerFactory(newView, eventDetail.detail.params, eventDetail);
+ new options.controllerFactory(newView, eventDetail.detail.params);
} else if (options.controllerFactory && typeof options.controllerFactory.default === 'function') {
- new options.controllerFactory.default(newView, eventDetail.detail.params, eventDetail);
+ new options.controllerFactory.default(newView, eventDetail.detail.params);
}
if (!options.controllerFactory || dispatchPageEvents) {
diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js
index a9fd39e9df..5ce2b0f991 100644
--- a/src/controllers/dashboard/general.js
+++ b/src/controllers/dashboard/general.js
@@ -15,7 +15,6 @@ import alert from '../../components/alert';
page.querySelector('#txtServerName').value = systemInfo.ServerName;
page.querySelector('#txtCachePath').value = systemInfo.CachePath || '';
page.querySelector('#chkQuickConnectAvailable').checked = config.QuickConnectAvailable === true;
- page.querySelector('#chkSplashScreenAvailable').checked = config.SplashscreenEnabled === true;
$('#txtMetadataPath', page).val(systemInfo.InternalMetadataPath || '');
$('#txtMetadataNetworkPath', page).val(systemInfo.MetadataNetworkPath || '');
$('#selectLocalizationLanguage', page).html(languageOptions.map(function (language) {
@@ -108,6 +107,7 @@ import alert from '../../components/alert';
ApiClient.getNamedConfiguration(brandingConfigKey).then(function (config) {
view.querySelector('#txtLoginDisclaimer').value = config.LoginDisclaimer || '';
view.querySelector('#txtCustomCss').value = config.CustomCss || '';
+ view.querySelector('#chkSplashScreenAvailable').checked = config.SplashscreenEnabled === true;
});
});
}
diff --git a/src/controllers/dashboard/logs.js b/src/controllers/dashboard/logs.js
index 39c71f432b..aa6436962d 100644
--- a/src/controllers/dashboard/logs.js
+++ b/src/controllers/dashboard/logs.js
@@ -9,7 +9,8 @@ import alert from '../../components/alert';
/* eslint-disable indent */
- function onSubmit() {
+ function onSubmit(event) {
+ event.preventDefault();
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function (config) {
diff --git a/src/controllers/dashboard/users/useredit.html b/src/controllers/dashboard/users/useredit.html
deleted file mode 100644
index e4b6afd33e..0000000000
--- a/src/controllers/dashboard/users/useredit.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/controllers/dashboard/users/userlibraryaccess.html b/src/controllers/dashboard/users/userlibraryaccess.html
deleted file mode 100644
index abcbfaf103..0000000000
--- a/src/controllers/dashboard/users/userlibraryaccess.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/controllers/dashboard/users/usernew.html b/src/controllers/dashboard/users/usernew.html
deleted file mode 100644
index c3f77c5e49..0000000000
--- a/src/controllers/dashboard/users/usernew.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/controllers/dashboard/users/userparentalcontrol.html b/src/controllers/dashboard/users/userparentalcontrol.html
deleted file mode 100644
index 8a93c3f931..0000000000
--- a/src/controllers/dashboard/users/userparentalcontrol.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/controllers/dashboard/users/userpassword.html b/src/controllers/dashboard/users/userpassword.html
deleted file mode 100644
index 984fcc2c9c..0000000000
--- a/src/controllers/dashboard/users/userpassword.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/controllers/dashboard/users/userprofiles.html b/src/controllers/dashboard/users/userprofiles.html
deleted file mode 100644
index 047cdff1fc..0000000000
--- a/src/controllers/dashboard/users/userprofiles.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/src/controllers/home.html b/src/controllers/home.html
deleted file mode 100644
index 240caef6c6..0000000000
--- a/src/controllers/home.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/src/controllers/home.js b/src/controllers/home.js
deleted file mode 100644
index feb29b542c..0000000000
--- a/src/controllers/home.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import TabbedView from '../components/tabbedview/tabbedview';
-import globalize from '../scripts/globalize';
-import '../elements/emby-tabs/emby-tabs';
-import '../elements/emby-button/emby-button';
-import '../elements/emby-scroller/emby-scroller';
-import LibraryMenu from '../scripts/libraryMenu';
-
-class HomeView extends TabbedView {
- constructor(view, params) {
- super(view, params);
- }
-
- setTitle() {
- LibraryMenu.setTitle(null);
- }
-
- onPause() {
- super.onPause(this);
- document.querySelector('.skinHeader').classList.remove('noHomeButtonHeader');
- }
-
- onResume(options) {
- super.onResume(this, options);
- document.querySelector('.skinHeader').classList.add('noHomeButtonHeader');
- }
-
- getDefaultTabIndex() {
- return 0;
- }
-
- getTabs() {
- return [{
- name: globalize.translate('Home')
- }, {
- name: globalize.translate('Favorites')
- }];
- }
-
- getTabController(index) {
- if (index == null) {
- throw new Error('index cannot be null');
- }
-
- let depends = '';
-
- switch (index) {
- case 0:
- depends = 'hometab';
- break;
-
- case 1:
- depends = 'favorites';
- }
-
- const instance = this;
- return import(/* webpackChunkName: "[request]" */ `../controllers/${depends}`).then(({ default: controllerFactory }) => {
- let controller = instance.tabControllers[index];
-
- if (!controller) {
- controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params);
- instance.tabControllers[index] = controller;
- }
-
- return controller;
- });
- }
-}
-
-export default HomeView;
diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js
index e7d06125ce..b0ae20886c 100644
--- a/src/controllers/itemDetails/index.js
+++ b/src/controllers/itemDetails/index.js
@@ -1985,7 +1985,9 @@ export default function (view, params) {
download([{
url: downloadHref,
itemId: currentItem.Id,
- serverId: currentItem.serverId
+ serverId: currentItem.ServerId,
+ title: currentItem.Name,
+ filename: currentItem.Path.replace(/^.*[\\/]/, '')
}]);
}
diff --git a/src/controllers/livetvtuner.html b/src/controllers/livetvtuner.html
index 29940a9141..eca335a2eb 100644
--- a/src/controllers/livetvtuner.html
+++ b/src/controllers/livetvtuner.html
@@ -62,6 +62,14 @@
${EnableStreamLoopingHelp}
diff --git a/src/controllers/livetvtuner.js b/src/controllers/livetvtuner.js
index dde8a10331..6b798c6c4a 100644
--- a/src/controllers/livetvtuner.js
+++ b/src/controllers/livetvtuner.js
@@ -61,6 +61,7 @@ function fillTunerHostInfo(view, info) {
view.querySelector('.chkFavorite').checked = info.ImportFavoritesOnly;
view.querySelector('.chkTranscode').checked = info.AllowHWTranscoding;
view.querySelector('.chkStreamLoop').checked = info.EnableStreamLooping;
+ view.querySelector('.chkIgnoreDts').checked = info.IgnoreDts;
view.querySelector('.txtTunerCount').value = info.TunerCount || '0';
}
@@ -75,7 +76,8 @@ function submitForm(page) {
TunerCount: page.querySelector('.txtTunerCount').value || 0,
ImportFavoritesOnly: page.querySelector('.chkFavorite').checked,
AllowHWTranscoding: page.querySelector('.chkTranscode').checked,
- EnableStreamLooping: page.querySelector('.chkStreamLoop').checked
+ EnableStreamLooping: page.querySelector('.chkStreamLoop').checked,
+ IgnoreDts: page.querySelector('.chkIgnoreDts').checked
};
if (isM3uVariant(info.Type)) {
@@ -120,6 +122,7 @@ function onTypeChange() {
const supportsTunerIpAddress = value === 'hdhomerun';
const supportsTunerFileOrUrl = value === 'm3u';
const supportsStreamLooping = value === 'm3u';
+ const supportsIgnoreDts = value === 'm3u';
const supportsTunerCount = value === 'm3u';
const supportsUserAgent = value === 'm3u';
const suppportsSubmit = value !== 'other';
@@ -168,6 +171,12 @@ function onTypeChange() {
view.querySelector('.fldStreamLoop').classList.add('hide');
}
+ if (supportsIgnoreDts) {
+ view.querySelector('.fldIgnoreDts').classList.remove('hide');
+ } else {
+ view.querySelector('.fldIgnoreDts').classList.add('hide');
+ }
+
if (supportsTunerCount) {
view.querySelector('.fldTunerCount').classList.remove('hide');
view.querySelector('.txtTunerCount').setAttribute('required', 'required');
diff --git a/src/controllers/music/music.html b/src/controllers/music/music.html
index 7096ce96fa..aad1fe545d 100644
--- a/src/controllers/music/music.html
+++ b/src/controllers/music/music.html
@@ -92,6 +92,7 @@
diff --git a/src/controllers/music/songs.js b/src/controllers/music/songs.js
index 2053901b25..721787b75c 100644
--- a/src/controllers/music/songs.js
+++ b/src/controllers/music/songs.js
@@ -8,197 +8,207 @@ import * as userSettings from '../../scripts/settings/userSettings';
import globalize from '../../scripts/globalize';
import '../../elements/emby-itemscontainer/emby-itemscontainer';
import Dashboard from '../../utils/dashboard';
+import {playbackManager} from '../../components/playback/playbackmanager';
-/* eslint-disable indent */
+export default function (view, params, tabContent) {
+ function getPageData(context) {
+ const key = getSavedQueryKey(context);
+ let pageData = data[key];
- export default function (view, params, tabContent) {
- function getPageData(context) {
- const key = getSavedQueryKey(context);
- let pageData = data[key];
-
- if (!pageData) {
- pageData = data[key] = {
- query: {
- SortBy: 'Album,SortName',
- SortOrder: 'Ascending',
- IncludeItemTypes: 'Audio',
- Recursive: true,
- Fields: 'AudioInfo,ParentId',
- StartIndex: 0,
- ImageTypeLimit: 1,
- EnableImageTypes: 'Primary'
- }
- };
-
- if (userSettings.libraryPageSize() > 0) {
- pageData.query['Limit'] = userSettings.libraryPageSize();
+ if (!pageData) {
+ pageData = data[key] = {
+ query: {
+ SortBy: 'Album,SortName',
+ SortOrder: 'Ascending',
+ IncludeItemTypes: 'Audio',
+ Recursive: true,
+ Fields: 'AudioInfo,ParentId',
+ StartIndex: 0,
+ ImageTypeLimit: 1,
+ EnableImageTypes: 'Primary'
}
+ };
- pageData.query.ParentId = params.topParentId;
- libraryBrowser.loadSavedQueryValues(key, pageData.query);
+ if (userSettings.libraryPageSize() > 0) {
+ pageData.query['Limit'] = userSettings.libraryPageSize();
}
- return pageData;
+ pageData.query.ParentId = params.topParentId;
+ libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
- function getQuery(context) {
- return getPageData(context).query;
- }
-
- function getSavedQueryKey(context) {
- if (!context.savedQueryKey) {
- context.savedQueryKey = libraryBrowser.getSavedQueryKey('songs');
- }
-
- return context.savedQueryKey;
- }
-
- function reloadItems(page) {
- loading.show();
- isLoading = true;
- const query = getQuery(page);
- ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
- function onNextPageClick() {
- if (isLoading) {
- return;
- }
-
- if (userSettings.libraryPageSize() > 0) {
- query.StartIndex += query.Limit;
- }
- reloadItems(tabContent);
- }
-
- function onPreviousPageClick() {
- if (isLoading) {
- return;
- }
-
- if (userSettings.libraryPageSize() > 0) {
- query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
- }
- reloadItems(tabContent);
- }
-
- window.scrollTo(0, 0);
- const pagingHtml = libraryBrowser.getQueryPagingHtml({
- startIndex: query.StartIndex,
- limit: query.Limit,
- totalRecordCount: result.TotalRecordCount,
- showLimit: false,
- updatePageSizeSetting: false,
- addLayoutButton: false,
- sortButton: false,
- filterButton: false
- });
- const html = listView.getListViewHtml({
- items: result.Items,
- action: 'playallfromhere',
- smallIcon: true,
- artist: true,
- addToListButton: true
- });
- let elems = tabContent.querySelectorAll('.paging');
-
- for (let i = 0, length = elems.length; i < length; i++) {
- elems[i].innerHTML = pagingHtml;
- }
-
- elems = tabContent.querySelectorAll('.btnNextPage');
- for (let i = 0, length = elems.length; i < length; i++) {
- elems[i].addEventListener('click', onNextPageClick);
- }
-
- elems = tabContent.querySelectorAll('.btnPreviousPage');
- for (let i = 0, length = elems.length; i < length; i++) {
- elems[i].addEventListener('click', onPreviousPageClick);
- }
-
- const itemsContainer = tabContent.querySelector('.itemsContainer');
- itemsContainer.innerHTML = html;
- imageLoader.lazyChildren(itemsContainer);
- libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
- loading.hide();
- isLoading = false;
-
- import('../../components/autoFocuser').then(({default: autoFocuser}) => {
- autoFocuser.autoFocus(page);
- });
- });
- }
-
- const self = this;
- const data = {};
- let isLoading = false;
-
- self.showFilterMenu = function () {
- import('../../components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
- const filterDialog = new filterDialogFactory({
- query: getQuery(tabContent),
- mode: 'songs',
- serverId: ApiClient.serverId()
- });
- Events.on(filterDialog, 'filterchange', function () {
- getQuery(tabContent).StartIndex = 0;
- reloadItems(tabContent);
- });
- filterDialog.show();
- });
- };
-
- self.getCurrentViewStyle = function () {
- return getPageData(tabContent).view;
- };
-
- function initPage(tabContent) {
- tabContent.querySelector('.btnFilter').addEventListener('click', function () {
- self.showFilterMenu();
- });
- tabContent.querySelector('.btnSort').addEventListener('click', function (e) {
- libraryBrowser.showSortMenu({
- items: [{
- name: globalize.translate('OptionTrackName'),
- id: 'Name'
- }, {
- name: globalize.translate('Album'),
- id: 'Album,SortName'
- }, {
- name: globalize.translate('AlbumArtist'),
- id: 'AlbumArtist,Album,SortName'
- }, {
- name: globalize.translate('Artist'),
- id: 'Artist,Album,SortName'
- }, {
- name: globalize.translate('OptionDateAdded'),
- id: 'DateCreated,SortName'
- }, {
- name: globalize.translate('OptionDatePlayed'),
- id: 'DatePlayed,SortName'
- }, {
- name: globalize.translate('OptionPlayCount'),
- id: 'PlayCount,SortName'
- }, {
- name: globalize.translate('OptionReleaseDate'),
- id: 'PremiereDate,AlbumArtist,Album,SortName'
- }, {
- name: globalize.translate('Runtime'),
- id: 'Runtime,AlbumArtist,Album,SortName'
- }],
- callback: function () {
- getQuery(tabContent).StartIndex = 0;
- reloadItems(tabContent);
- },
- query: getQuery(tabContent),
- button: e.target
- });
- });
- }
-
- initPage(tabContent);
-
- self.renderTab = function () {
- reloadItems(tabContent);
- };
+ return pageData;
}
-/* eslint-enable indent */
+ function getQuery(context) {
+ return getPageData(context).query;
+ }
+
+ function getSavedQueryKey(context) {
+ if (!context.savedQueryKey) {
+ context.savedQueryKey = libraryBrowser.getSavedQueryKey('songs');
+ }
+
+ return context.savedQueryKey;
+ }
+
+ function reloadItems(page) {
+ loading.show();
+ isLoading = true;
+ const query = getQuery(page);
+ ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
+ function onNextPageClick() {
+ if (isLoading) {
+ return;
+ }
+
+ if (userSettings.libraryPageSize() > 0) {
+ query.StartIndex += query.Limit;
+ }
+ reloadItems(tabContent);
+ }
+
+ function onPreviousPageClick() {
+ if (isLoading) {
+ return;
+ }
+
+ if (userSettings.libraryPageSize() > 0) {
+ query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
+ }
+ reloadItems(tabContent);
+ }
+
+ window.scrollTo(0, 0);
+ const pagingHtml = libraryBrowser.getQueryPagingHtml({
+ startIndex: query.StartIndex,
+ limit: query.Limit,
+ totalRecordCount: result.TotalRecordCount,
+ showLimit: false,
+ updatePageSizeSetting: false,
+ addLayoutButton: false,
+ sortButton: false,
+ filterButton: false
+ });
+ const html = listView.getListViewHtml({
+ items: result.Items,
+ action: 'playallfromhere',
+ smallIcon: true,
+ artist: true,
+ addToListButton: true
+ });
+ let elems = tabContent.querySelectorAll('.paging');
+
+ for (let i = 0, length = elems.length; i < length; i++) {
+ elems[i].innerHTML = pagingHtml;
+ }
+
+ elems = tabContent.querySelectorAll('.btnNextPage');
+ for (let i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener('click', onNextPageClick);
+ }
+
+ elems = tabContent.querySelectorAll('.btnPreviousPage');
+ for (let i = 0, length = elems.length; i < length; i++) {
+ elems[i].addEventListener('click', onPreviousPageClick);
+ }
+
+ const itemsContainer = tabContent.querySelector('.itemsContainer');
+ itemsContainer.innerHTML = html;
+ imageLoader.lazyChildren(itemsContainer);
+ libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
+
+ tabContent.querySelector('.btnShuffle').classList.toggle('hide', result.TotalRecordCount < 1);
+
+ loading.hide();
+ isLoading = false;
+
+ import('../../components/autoFocuser').then(({default: autoFocuser}) => {
+ autoFocuser.autoFocus(page);
+ });
+ });
+ }
+
+ const self = this;
+ const data = {};
+ let isLoading = false;
+
+ self.showFilterMenu = function () {
+ import('../../components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
+ const filterDialog = new filterDialogFactory({
+ query: getQuery(tabContent),
+ mode: 'songs',
+ serverId: ApiClient.serverId()
+ });
+ Events.on(filterDialog, 'filterchange', function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems(tabContent);
+ });
+ filterDialog.show();
+ });
+ };
+
+ function shuffle() {
+ ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) {
+ playbackManager.shuffle(item);
+ });
+ }
+
+ self.getCurrentViewStyle = function () {
+ return getPageData(tabContent).view;
+ };
+
+ function initPage(tabContent) {
+ tabContent.querySelector('.btnFilter').addEventListener('click', function () {
+ self.showFilterMenu();
+ });
+ tabContent.querySelector('.btnSort').addEventListener('click', function (e) {
+ libraryBrowser.showSortMenu({
+ items: [{
+ name: globalize.translate('OptionTrackName'),
+ id: 'Name'
+ }, {
+ name: globalize.translate('Album'),
+ id: 'Album,SortName'
+ }, {
+ name: globalize.translate('AlbumArtist'),
+ id: 'AlbumArtist,Album,SortName'
+ }, {
+ name: globalize.translate('Artist'),
+ id: 'Artist,Album,SortName'
+ }, {
+ name: globalize.translate('OptionDateAdded'),
+ id: 'DateCreated,SortName'
+ }, {
+ name: globalize.translate('OptionDatePlayed'),
+ id: 'DatePlayed,SortName'
+ }, {
+ name: globalize.translate('OptionPlayCount'),
+ id: 'PlayCount,SortName'
+ }, {
+ name: globalize.translate('OptionReleaseDate'),
+ id: 'PremiereDate,AlbumArtist,Album,SortName'
+ }, {
+ name: globalize.translate('Runtime'),
+ id: 'Runtime,AlbumArtist,Album,SortName'
+ }, {
+ name: globalize.translate('OptionRandom'),
+ id: 'Random,SortName'
+ }],
+ callback: function () {
+ getQuery(tabContent).StartIndex = 0;
+ reloadItems(tabContent);
+ },
+ query: getQuery(tabContent),
+ button: e.target
+ });
+ });
+ tabContent.querySelector('.btnShuffle').addEventListener('click', shuffle);
+ }
+
+ initPage(tabContent);
+
+ self.renderTab = function () {
+ reloadItems(tabContent);
+ };
+}
diff --git a/src/controllers/shows/tvshows.js b/src/controllers/shows/tvshows.js
index ba18ecec7f..6e982f7c9f 100644
--- a/src/controllers/shows/tvshows.js
+++ b/src/controllers/shows/tvshows.js
@@ -259,8 +259,11 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
name: globalize.translate('OptionImdbRating'),
id: 'CommunityRating,SortName'
}, {
- name: globalize.translate('OptionDateAdded'),
+ name: globalize.translate('OptionDateShowAdded'),
id: 'DateCreated,SortName'
+ }, {
+ name: globalize.translate('OptionDateEpisodeAdded'),
+ id: 'DateLastContentAdded,SortName'
}, {
name: globalize.translate('OptionDatePlayed'),
id: 'SeriesDatePlayed,SortName'
diff --git a/src/controllers/user/menu/index.html b/src/controllers/user/menu/index.html
index 185dad7c7d..2741f89282 100644
--- a/src/controllers/user/menu/index.html
+++ b/src/controllers/user/menu/index.html
@@ -3,7 +3,7 @@