├── css ├── images │ ├── fresh.png │ ├── rotten.png │ ├── equalizer_black.gif │ └── equalizer_white.gif ├── noflex.css ├── operatv.css └── colors.dark.css ├── search ├── search.css ├── search.html └── search.js ├── skininfo.js ├── livetv ├── guide.html ├── livetvitems.html ├── guide.css ├── series.js ├── channels.js └── guide.js ├── home_horiz ├── views.generic.html ├── views.playlists.html ├── views.collections.html ├── views.channels.html ├── home.html ├── views.collections.js ├── views.playlists.js ├── views.generic.js ├── home.css ├── views.channels.js ├── views.movies.html ├── views.livetv.html ├── views.tv.html ├── views.music.html └── spotlight.js ├── package.json ├── settings ├── settings.html └── settings.js ├── nowplaying ├── playlist.html ├── nowplaying.css ├── nowplaying.html ├── videoosd.html ├── videoosd.css └── playlist.js ├── home ├── home.html ├── hometab.js └── home.js ├── header.html ├── list └── list.html ├── README.md ├── music ├── genres.js ├── folders.js ├── songs.js ├── series.js ├── playlists.js ├── albums.js ├── artists.js └── music.html ├── tv ├── series.js ├── studios.js ├── latest.js ├── tv.html └── favorites.js ├── movies ├── collections.js ├── movies.html ├── moviestab.js └── years.js ├── components └── itemslist.js ├── strings ├── en-US.json ├── en.json ├── en-GB.json ├── sv.json ├── hr.json ├── nl.json ├── it.json ├── de.json ├── pt-PT.json ├── es-419.json ├── pl.json ├── pt-BR.json ├── fr.json ├── lt-LT.json ├── zh-CN.json └── cs.json └── item └── item.css /css/images/fresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaBrowser/emby-web-defaultskin/HEAD/css/images/fresh.png -------------------------------------------------------------------------------- /css/images/rotten.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaBrowser/emby-web-defaultskin/HEAD/css/images/rotten.png -------------------------------------------------------------------------------- /css/images/equalizer_black.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaBrowser/emby-web-defaultskin/HEAD/css/images/equalizer_black.gif -------------------------------------------------------------------------------- /css/images/equalizer_white.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MediaBrowser/emby-web-defaultskin/HEAD/css/images/equalizer_white.gif -------------------------------------------------------------------------------- /search/search.css: -------------------------------------------------------------------------------- 1 | .searchHeader .headerRight { 2 | display: none; 3 | } 4 | 5 | .searchfields-icon { 6 | color: #aaa; 7 | } 8 | -------------------------------------------------------------------------------- /skininfo.js: -------------------------------------------------------------------------------- 1 | define([], function () { 2 | 'use strict'; 3 | 4 | return { 5 | id: 'defaultskin', 6 | name: 'Default Skin' 7 | }; 8 | }); -------------------------------------------------------------------------------- /css/noflex.css: -------------------------------------------------------------------------------- 1 | .actionSheetScroller-tv { 2 | /* Prevent list items from overlapping title 3 | TODO: This belongs in the core, not here in the skin 4 | */ 5 | margin: 2em 0; 6 | } -------------------------------------------------------------------------------- /livetv/guide.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 |
-------------------------------------------------------------------------------- /home_horiz/views.generic.html: -------------------------------------------------------------------------------- 1 |
2 |
 
3 |
4 | 5 |
6 |
7 | -------------------------------------------------------------------------------- /home_horiz/views.playlists.html: -------------------------------------------------------------------------------- 1 |
2 |
 
3 |
4 | 5 |
6 |
7 | -------------------------------------------------------------------------------- /home_horiz/views.collections.html: -------------------------------------------------------------------------------- 1 |
2 |
 
3 |
4 | 5 |
6 |
7 | -------------------------------------------------------------------------------- /home_horiz/views.channels.html: -------------------------------------------------------------------------------- 1 |
2 |
${Channels}
3 |
4 | 5 |
6 |
7 |
8 | 9 |
-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "emby.defaultskin", 3 | "displayName": "Default Skin", 4 | "version": "1.0.0", 5 | "description": "The default Emby skin.", 6 | "plugin": "plugin.js", 7 | "homepage": "https://github.com/MediaBrowser/emby-web-defaultskin", 8 | "thumb": "", 9 | "backdrop": "" 10 | } 11 | -------------------------------------------------------------------------------- /css/operatv.css: -------------------------------------------------------------------------------- 1 | .selectedItemInfo { 2 | display: none !important; 3 | } 4 | 5 | .detailImage { 6 | min-width: 200px; 7 | max-width: 260px; 8 | min-height: initial !important; 9 | max-height: 400px; 10 | } 11 | 12 | .osdMediaInfo { 13 | display: none !important; 14 | } 15 | 16 | .btnVideoOsdSettings { 17 | display: none !important; 18 | } 19 | -------------------------------------------------------------------------------- /search/search.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 |
7 | 8 |
9 | 10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /settings/settings.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 8 |
${EnableEpisodeSpoilerProtectionHelp}
9 |
10 |
11 | -------------------------------------------------------------------------------- /nowplaying/playlist.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
-------------------------------------------------------------------------------- /home_horiz/home.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 14 |
-------------------------------------------------------------------------------- /livetv/livetvitems.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 | 7 |
8 |
9 |
10 |
11 | 12 |
-------------------------------------------------------------------------------- /home/home.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 | 7 |
8 | 9 |
10 | 11 |
12 | 13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 21 |
-------------------------------------------------------------------------------- /livetv/guide.css: -------------------------------------------------------------------------------- 1 | .guidePageContainer { 2 | bottom: 22%; 3 | left: 3%; 4 | padding-top: 9vh; 5 | } 6 | 7 | .guideSelectedInfo { 8 | top: 81%; 9 | left: 7%; 10 | position: absolute; 11 | max-width: 80%; 12 | display: flex; 13 | align-items: center; 14 | } 15 | 16 | .guideSelectedInfo h2 { 17 | margin: 0; 18 | } 19 | 20 | .guideItemDetails { 21 | max-width: 90%; 22 | } 23 | 24 | .guideOverview { 25 | white-space: nowrap; 26 | overflow: hidden; 27 | text-overflow: ellipsis; 28 | } 29 | 30 | .guideImage { 31 | margin-right: 1em; 32 | background-position: right center; 33 | background-size: contain; 34 | background-repeat: no-repeat; 35 | height: 15vh; 36 | width: 22vh; 37 | flex-shrink: 0; 38 | } 39 | 40 | .guideSelectedItemPrimaryInfo { 41 | display: flex; 42 | align-items: center; 43 | } 44 | 45 | .guideSelectedItemMediaInfo { 46 | margin-top: .15em; 47 | display: flex; 48 | align-items: center; 49 | } 50 | -------------------------------------------------------------------------------- /settings/settings.js: -------------------------------------------------------------------------------- 1 | define(['loading', './../skinsettings', './../skininfo', 'focusManager', 'globalize'], function (loading, skinSettings, skinInfo, focusManager, globalize) { 2 | 'use strict'; 3 | 4 | return function (view, params) { 5 | 6 | var self = this; 7 | 8 | view.addEventListener('viewshow', function (e) { 9 | 10 | var isRestored = e.detail.isRestored; 11 | 12 | Emby.Page.setTitle(skinInfo.name); 13 | 14 | loading.hide(); 15 | 16 | if (!isRestored) { 17 | 18 | renderSettings(); 19 | } 20 | }); 21 | 22 | view.addEventListener('viewbeforehide', function (e) { 23 | 24 | skinSettings.enableAntiSpoliers(view.querySelector('.chkEnableEpisodeAntiSpoliers').checked); 25 | 26 | skinSettings.apply(); 27 | }); 28 | 29 | function renderSettings() { 30 | 31 | focusManager.autoFocus(view); 32 | 33 | view.querySelector('.chkEnableEpisodeAntiSpoliers').checked = skinSettings.enableAntiSpoliers(); 34 | } 35 | }; 36 | 37 | }); -------------------------------------------------------------------------------- /nowplaying/nowplaying.css: -------------------------------------------------------------------------------- 1 | .nowPlayingPageContainer { 2 | text-align: center; 3 | display: flex; 4 | align-items: center; 5 | justify-content: center; 6 | } 7 | 8 | .nowPlayingCardContainer { 9 | width: 25%; 10 | margin-right: 1em; 11 | } 12 | 13 | .nowPlayingCardContainer .card { 14 | width: 100% !important; 15 | } 16 | 17 | .nowPlayingInfoContainer { 18 | width: 35%; 19 | } 20 | 21 | .nowPlayingButtonsContainer .userDataIcons { 22 | display: inline-block; 23 | margin-right: 1em; 24 | margin-left: .35em; 25 | } 26 | 27 | .nowPlayingMetadata { 28 | padding-left: .25em; 29 | margin: 0 0 .5em; 30 | } 31 | 32 | .nowPlayingTime { 33 | display: inline-block; 34 | vertical-align: middle; 35 | margin-left: 1em; 36 | } 37 | 38 | .nowPlayingProgressContainer { 39 | display: flex; 40 | align-items: center; 41 | } 42 | 43 | .nowPlayingProgressContainer { 44 | margin: 1em 0; 45 | } 46 | 47 | .nowPlayingProgressSliderContainer { 48 | flex-grow: 1; 49 | margin-left: .5em; 50 | } 51 | 52 | .nowPlayingHeader .headerAudioPlayerButton { 53 | display: none; 54 | } 55 | 56 | .nowPlayingSecondaryButtons { 57 | display: flex; 58 | align-items: center; 59 | margin-top: .5em; 60 | } 61 | -------------------------------------------------------------------------------- /header.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 6 |

 

7 |
8 |
9 | 12 | 13 |
14 | 15 |
16 | 19 | 22 | 25 |
26 |
27 |
28 |
29 |
-------------------------------------------------------------------------------- /css/colors.dark.css: -------------------------------------------------------------------------------- 1 | .emby-button:focus:not(.btnUserViewHeader):not(.emby-tab-button) { 2 | background: #52B54B; 3 | color: #fff !important; 4 | } 5 | 6 | .card[data-cardtype='embyconnect'] .cardImageContainer { 7 | background-color: #52B54B !important; 8 | } 9 | 10 | .userViewButtonText { 11 | border-bottom: 2px solid transparent; 12 | } 13 | 14 | .albumsCard .cardImageContainer, .recordingsCard .cardImageContainer { 15 | background: #38c !important; 16 | } 17 | 18 | .allGenericCard .cardImageContainer, .artistsCard .cardImageContainer { 19 | background: #4CAF50 !important; 20 | } 21 | 22 | .genresCard .cardImageContainer, .channelsLiveTvCard .cardImageContainer { 23 | background: #F44336 !important; 24 | } 25 | 26 | .movieCollectionsCard .cardImageContainer { 27 | background-color: #009688 !important; 28 | } 29 | 30 | .movieGenresCard .cardImageContainer { 31 | background-color: #009688 !important; 32 | } 33 | 34 | .tvUpcomingCard .cardImageContainer { 35 | background-color: #009688 !important; 36 | } 37 | 38 | .btnUserViewHeader.selected { 39 | opacity: 1 !important; 40 | color: inherit; 41 | } 42 | 43 | .btnUserViewHeader:focus { 44 | color: #52B54B; 45 | opacity: 1 !important; 46 | } 47 | 48 | .btnUserViewHeader:focus .userViewButtonText { 49 | border-bottom-color: #52B54B; 50 | } 51 | -------------------------------------------------------------------------------- /list/list.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 | 7 |
8 | 9 |
10 | 11 |
12 | 15 | 18 | 21 | 24 |
25 | 26 |
27 |
28 |
29 |
30 |
-------------------------------------------------------------------------------- /home_horiz/views.collections.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'emby-itemscontainer'], function (cardBuilder) { 2 | 'use strict'; 3 | 4 | function loadAll(element, parentId, autoFocus) { 5 | 6 | return Emby.Models.collections({ 7 | 8 | ParentId: parentId, 9 | EnableImageTypes: "Primary,Backdrop,Thumb", 10 | SortBy: 'SortName' 11 | 12 | }).then(function (result) { 13 | 14 | var section = element.querySelector('.allSection'); 15 | 16 | // Needed in case the view has been destroyed 17 | if (!section) { 18 | return; 19 | } 20 | 21 | cardBuilder.buildCards(result.Items, { 22 | parentContainer: section, 23 | itemsContainer: section.querySelector('.itemsContainer'), 24 | shape: 'auto', 25 | autoFocus: autoFocus, 26 | rows: { 27 | portrait: 2, 28 | square: 3, 29 | backdrop: 3 30 | }, 31 | scalable: false 32 | }); 33 | }); 34 | } 35 | 36 | function view(element, apiClient, parentId, autoFocus) { 37 | var self = this; 38 | 39 | self.loadData = function (isRefresh) { 40 | 41 | if (isRefresh) { 42 | return Promise.resolve(); 43 | } 44 | 45 | return loadAll(element, parentId, autoFocus); 46 | }; 47 | 48 | self.destroy = function () { 49 | 50 | }; 51 | } 52 | 53 | return view; 54 | }); -------------------------------------------------------------------------------- /home_horiz/views.playlists.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'emby-itemscontainer'], function (cardBuilder) { 2 | 'use strict'; 3 | 4 | function loadAll(element, parentId, autoFocus) { 5 | 6 | var options = { 7 | 8 | ParentId: parentId, 9 | EnableImageTypes: "Primary,Backdrop,Thumb", 10 | SortBy: 'SortName' 11 | }; 12 | 13 | return Emby.Models.playlists(options).then(function (result) { 14 | 15 | var section = element.querySelector('.allSection'); 16 | 17 | // Needed in case the view has been destroyed 18 | if (!section) { 19 | return; 20 | } 21 | 22 | cardBuilder.buildCards(result.Items, { 23 | parentContainer: section, 24 | itemsContainer: section.querySelector('.itemsContainer'), 25 | shape: 'auto', 26 | autoFocus: autoFocus, 27 | showTitle: true, 28 | overlayText: true, 29 | rows: { 30 | portrait: 2, 31 | square: 3, 32 | backdrop: 3 33 | }, 34 | scalable: false 35 | }); 36 | }); 37 | } 38 | 39 | function view(element, apiClient, parentId, autoFocus) { 40 | var self = this; 41 | 42 | self.loadData = function (isRefresh) { 43 | 44 | if (isRefresh) { 45 | return Promise.resolve(); 46 | } 47 | 48 | return loadAll(element, parentId, autoFocus); 49 | }; 50 | 51 | self.destroy = function () { 52 | 53 | }; 54 | } 55 | 56 | return view; 57 | }); -------------------------------------------------------------------------------- /home_horiz/views.generic.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'emby-itemscontainer'], function (cardBuilder) { 2 | 'use strict'; 3 | 4 | function loadAll(element, parentId, autoFocus) { 5 | 6 | var options = { 7 | 8 | ParentId: parentId, 9 | EnableImageTypes: "Primary,Backdrop,Thumb", 10 | SortBy: 'SortName' 11 | }; 12 | 13 | return Emby.Models.items(options).then(function (result) { 14 | 15 | var section = element.querySelector('.allSection'); 16 | 17 | // Needed in case the view has been destroyed 18 | if (!section) { 19 | return; 20 | } 21 | 22 | // If showTitle: true is ever specified, make sure to have an exception for photos 23 | cardBuilder.buildCards(result.Items, { 24 | parentContainer: section, 25 | itemsContainer: section.querySelector('.itemsContainer'), 26 | shape: 'auto', 27 | autoFocus: autoFocus, 28 | coverImage: true, 29 | rows: { 30 | portrait: 2, 31 | square: 3, 32 | backdrop: 3 33 | }, 34 | scalable: false, 35 | overlayText: true, 36 | context: 'folders' 37 | }); 38 | }); 39 | } 40 | 41 | function view(element, apiClient, parentId, autoFocus) { 42 | var self = this; 43 | 44 | self.loadData = function (isRefresh) { 45 | 46 | if (isRefresh) { 47 | return Promise.resolve(); 48 | } 49 | 50 | return loadAll(element, parentId, autoFocus); 51 | }; 52 | 53 | self.destroy = function () { 54 | 55 | }; 56 | } 57 | 58 | return view; 59 | }); -------------------------------------------------------------------------------- /search/search.js: -------------------------------------------------------------------------------- 1 | define(['loading', 'searchFields', 'searchResults', 'scroller', './../components/focushandler', 'cardBuilder', 'events', 'connectionManager', 'emby-itemscontainer', 'emby-scroller'], function (loading, SearchFields, SearchResults, scroller, focusHandler, cardBuilder, events, connectionManager) { 2 | 'use strict'; 3 | 4 | return function (view, params) { 5 | 6 | var self = this; 7 | 8 | function getHeaderElement() { 9 | return document.querySelector('.skinHeader'); 10 | } 11 | 12 | self.searchFields = new SearchFields({ 13 | element: view.querySelector('.searchFields') 14 | }); 15 | 16 | self.searchResults = new SearchResults({ 17 | element: view.querySelector('.searchResults'), 18 | serverId: connectionManager.currentApiClient().serverId() 19 | }); 20 | 21 | events.on(self.searchFields, 'search', function (e, value) { 22 | self.searchResults.search(value); 23 | }); 24 | 25 | view.addEventListener('viewshow', function (e) { 26 | 27 | getHeaderElement().classList.add('searchHeader'); 28 | 29 | Emby.Page.setTitle(''); 30 | document.querySelector('.headerSearchButton').classList.add('hide'); 31 | }); 32 | 33 | view.addEventListener('viewhide', function () { 34 | 35 | getHeaderElement().classList.remove('searchHeader'); 36 | 37 | document.querySelector('.headerSearchButton').classList.remove('hide'); 38 | }); 39 | 40 | view.addEventListener('viewdestroy', function () { 41 | 42 | if (self.searchFields) { 43 | self.searchFields.destroy(); 44 | self.searchFields = null; 45 | } 46 | if (self.searchResults) { 47 | self.searchResults.destroy(); 48 | self.searchResults = null; 49 | } 50 | }); 51 | }; 52 | 53 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # emby-web-defaultskin 2 | 3 | This default skin for Emby Theater. To create your own skin, follow these steps: 4 | 5 | * Fork this repository. After forking, you'll probably want to rename it. 6 | * Update package.json (see below). 7 | * Update skininfo.js with your unique names. 8 | * Update plugin.js to change the skin name and id, matching the values from skininfo.js 9 | * Update the installation url below. 10 | 11 | # package.json 12 | 13 | This file is used to display information about your add-on in places such as the installation screen, installed packages list, and catalog. 14 | 15 | * name is your package name, and should have no spaces or special characters. This is a package name and is intended to be unique. Changing the name will cause the application to view it as a completely new package. 16 | * update displayName as desired. 17 | * update thumb to supply an image for display. this should be 16*9. It can be a relative or full url. 18 | * if desired, update backdrop to supply a background image. this should be 16*9. It can be a relative or full url. 19 | 20 | # Installation 21 | 22 | Install into the app by installing a plugin from a url. The url is: http://mediabrowser.github.io/emby-web-defaultskin/package.json 23 | 24 | # Local Testing 25 | 26 | To test locally, install NodeJS, then install the http server module using: 27 | 28 | npm install http-server -g 29 | 30 | To start the server, enter 31 | 32 | http-server -p 8088 --cors 33 | 34 | Now you can install into Emby Theater using the http://localhost:8088/package.json 35 | 36 | To do this: type http://localhost:8088 into your browser bar. (This will confirm that 1. The server is running and 2 you can access your repository. 37 | Next, find your folder for your theme and locate the package.json file. 38 | Click this and you should see what's written in the the package.json in your browser 39 | Copy this address (CTRL+C) 40 | Go into tv.emby.media. Go to settings and Select "Installed Plugins" 41 | Select Install plugin, then select from URL and then paste your copied address in. 42 | You should have your theme loaded. 43 | Now load it from the Display Settings Menu and your done. 44 | 45 | 46 | # Develop with Chrome 47 | 48 | For rapid development, use the hosted version of Emby Theater: 49 | 50 | http://tv.emby.media 51 | 52 | This will allow you to perform all development activities using Chrome and it's excellent debugging tools. 53 | -------------------------------------------------------------------------------- /music/genres.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function MusicGenresTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderItems(view, items, parentId) { 11 | 12 | var container = view.querySelector('.itemsContainer'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "auto", 18 | centerText: true, 19 | showTitle: true, 20 | coverImage: true, 21 | parentId: parentId 22 | }); 23 | } 24 | 25 | MusicGenresTab.prototype.onBeforeShow = function (options) { 26 | 27 | var apiClient = this.apiClient; 28 | 29 | if (!options.refresh) { 30 | this.promises = null; 31 | return; 32 | } 33 | 34 | var promises = []; 35 | var parentId = this.params.parentId; 36 | 37 | promises.push(apiClient.getGenres(apiClient.getCurrentUserId(), { 38 | 39 | SortBy: "SortName", 40 | SortOrder: "Ascending", 41 | Recursive: true, 42 | Fields: "PrimaryImageAspectRatio,ItemCounts", 43 | parentId: parentId 44 | })); 45 | 46 | this.promises = promises; 47 | }; 48 | 49 | MusicGenresTab.prototype.onShow = function (options) { 50 | 51 | var promises = this.promises; 52 | if (!promises) { 53 | return; 54 | } 55 | 56 | this.promises = []; 57 | 58 | var view = this.view; 59 | var parentId = this.params.parentId; 60 | 61 | promises[0].then(function (result) { 62 | renderItems(view, result.Items, parentId); 63 | return Promise.resolve(); 64 | }); 65 | 66 | Promise.all(promises).then(function () { 67 | if (options.autoFocus) { 68 | focusManager.autoFocus(view); 69 | } 70 | }); 71 | }; 72 | 73 | MusicGenresTab.prototype.onHide = function () { 74 | 75 | }; 76 | 77 | MusicGenresTab.prototype.destroy = function () { 78 | 79 | this.view = null; 80 | this.params = null; 81 | this.apiClient = null; 82 | this.promises = null; 83 | }; 84 | 85 | return MusicGenresTab; 86 | }); -------------------------------------------------------------------------------- /music/folders.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function AlbumsTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderAlbums(view, items) { 11 | 12 | var container = view.querySelector('.itemsContainer'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "square", 18 | centerText: true, 19 | overlayMoreButton: !layoutManager.tv 20 | }); 21 | } 22 | 23 | AlbumsTab.prototype.onBeforeShow = function (options) { 24 | 25 | var apiClient = this.apiClient; 26 | 27 | if (!options.refresh) { 28 | this.promises = null; 29 | return; 30 | } 31 | 32 | var promises = []; 33 | var parentId = this.params.parentid; 34 | 35 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), { 36 | 37 | SortBy: "SortName", 38 | SortOrder: "Ascending", 39 | IncludeItemTypes: "MusicAlbum", 40 | Recursive: true, 41 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo", 42 | ImageTypeLimit: 1, 43 | EnableImageTypes: "Primary", 44 | StartIndex: 0, 45 | parentId: parentId 46 | })); 47 | 48 | this.promises = promises; 49 | }; 50 | 51 | AlbumsTab.prototype.onShow = function (options) { 52 | 53 | var promises = this.promises; 54 | if (!promises) { 55 | return; 56 | } 57 | 58 | this.promises = []; 59 | 60 | var view = this.view; 61 | 62 | promises[0].then(function (result) { 63 | renderAlbums(view, result.Items); 64 | return Promise.resolve(); 65 | }); 66 | 67 | Promise.all(promises).then(function () { 68 | if (options.autoFocus) { 69 | focusManager.autoFocus(view); 70 | } 71 | }); 72 | }; 73 | 74 | AlbumsTab.prototype.onHide = function () { 75 | 76 | }; 77 | 78 | AlbumsTab.prototype.destroy = function () { 79 | 80 | this.view = null; 81 | this.params = null; 82 | this.apiClient = null; 83 | this.promises = null; 84 | }; 85 | 86 | return AlbumsTab; 87 | }); -------------------------------------------------------------------------------- /music/songs.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function AlbumsTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderAlbums(view, items) { 11 | 12 | var container = view.querySelector('.itemsContainer'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "square", 18 | centerText: true, 19 | overlayMoreButton: !layoutManager.tv 20 | }); 21 | } 22 | 23 | AlbumsTab.prototype.onBeforeShow = function (options) { 24 | 25 | var apiClient = this.apiClient; 26 | 27 | if (!options.refresh) { 28 | this.promises = null; 29 | return; 30 | } 31 | 32 | var promises = []; 33 | var parentId = this.params.parentId; 34 | 35 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), { 36 | 37 | SortBy: "SortName", 38 | SortOrder: "Ascending", 39 | IncludeItemTypes: "MusicAlbum", 40 | Recursive: true, 41 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo", 42 | ImageTypeLimit: 1, 43 | EnableImageTypes: "Primary", 44 | StartIndex: 0, 45 | parentId: parentId 46 | })); 47 | 48 | this.promises = promises; 49 | }; 50 | 51 | AlbumsTab.prototype.onShow = function (options) { 52 | 53 | var promises = this.promises; 54 | if (!promises) { 55 | return; 56 | } 57 | 58 | this.promises = []; 59 | 60 | var view = this.view; 61 | 62 | promises[0].then(function (result) { 63 | renderAlbums(view, result.Items); 64 | return Promise.resolve(); 65 | }); 66 | 67 | Promise.all(promises).then(function () { 68 | if (options.autoFocus) { 69 | focusManager.autoFocus(view); 70 | } 71 | }); 72 | }; 73 | 74 | AlbumsTab.prototype.onHide = function () { 75 | 76 | }; 77 | 78 | AlbumsTab.prototype.destroy = function () { 79 | 80 | this.view = null; 81 | this.params = null; 82 | this.apiClient = null; 83 | this.promises = null; 84 | }; 85 | 86 | return AlbumsTab; 87 | }); -------------------------------------------------------------------------------- /nowplaying/nowplaying.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 |
7 | 8 |
9 |
10 | 11 |
12 |
13 |
14 |
15 |
16 | 19 | 22 | 25 | 28 | 31 | 34 |
35 |
36 | 37 |
38 |
39 | 42 | 43 |
44 | 45 |
46 |
47 |
48 |
49 |
-------------------------------------------------------------------------------- /music/series.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function SeriesTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderSeries(view, items) { 11 | 12 | var container = view.querySelector('.seriesItems'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "portrait", 18 | centerText: true, 19 | overlayMoreButton: !layoutManager.tv 20 | }); 21 | } 22 | 23 | SeriesTab.prototype.onBeforeShow = function (options) { 24 | 25 | var apiClient = this.apiClient; 26 | 27 | if (!options.refresh) { 28 | this.promises = null; 29 | return; 30 | } 31 | 32 | var promises = []; 33 | var parentId = this.params.parentId; 34 | 35 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), { 36 | 37 | SortBy: "SortName", 38 | SortOrder: "Ascending", 39 | IncludeItemTypes: "Series", 40 | Recursive: true, 41 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo", 42 | ImageTypeLimit: 1, 43 | EnableImageTypes: "Primary,Backdrop,Banner,Thumb", 44 | StartIndex: 0, 45 | parentId: parentId 46 | })); 47 | 48 | this.promises = promises; 49 | }; 50 | 51 | SeriesTab.prototype.onShow = function (options) { 52 | 53 | var promises = this.promises; 54 | if (!promises) { 55 | return; 56 | } 57 | 58 | this.promises = []; 59 | 60 | var view = this.view; 61 | 62 | promises[0].then(function (result) { 63 | renderSeries(view, result.Items); 64 | return Promise.resolve(); 65 | }); 66 | 67 | Promise.all(promises).then(function () { 68 | if (options.autoFocus) { 69 | focusManager.autoFocus(view); 70 | } 71 | }); 72 | }; 73 | 74 | SeriesTab.prototype.onHide = function () { 75 | 76 | }; 77 | 78 | SeriesTab.prototype.destroy = function () { 79 | 80 | this.view = null; 81 | this.params = null; 82 | this.apiClient = null; 83 | this.promises = null; 84 | }; 85 | 86 | return SeriesTab; 87 | }); -------------------------------------------------------------------------------- /music/playlists.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function MusicPlaylistsTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderItems(view, items) { 11 | 12 | var container = view.querySelector('.itemsContainer'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "auto", 18 | context: 'music', 19 | centerText: true, 20 | showTitle: true, 21 | coverImage: true 22 | }); 23 | } 24 | 25 | MusicPlaylistsTab.prototype.onBeforeShow = function (options) { 26 | 27 | var apiClient = this.apiClient; 28 | 29 | if (!options.refresh) { 30 | this.promises = null; 31 | return; 32 | } 33 | 34 | var promises = []; 35 | var parentId = this.params.parentId; 36 | 37 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), { 38 | 39 | SortBy: "SortName", 40 | SortOrder: "Ascending", 41 | IncludeItemTypes: "Playlist", 42 | Recursive: true, 43 | Fields: "PrimaryImageAspectRatio,CanDelete", 44 | StartIndex: 0, 45 | EnableTotalRecordCount: false 46 | })); 47 | 48 | this.promises = promises; 49 | }; 50 | 51 | MusicPlaylistsTab.prototype.onShow = function (options) { 52 | 53 | var promises = this.promises; 54 | if (!promises) { 55 | return; 56 | } 57 | 58 | this.promises = []; 59 | 60 | var view = this.view; 61 | 62 | promises[0].then(function (result) { 63 | renderItems(view, result.Items); 64 | return Promise.resolve(); 65 | }); 66 | 67 | Promise.all(promises).then(function () { 68 | if (options.autoFocus) { 69 | focusManager.autoFocus(view); 70 | } 71 | }); 72 | }; 73 | 74 | MusicPlaylistsTab.prototype.onHide = function () { 75 | 76 | }; 77 | 78 | MusicPlaylistsTab.prototype.destroy = function () { 79 | 80 | this.view = null; 81 | this.params = null; 82 | this.apiClient = null; 83 | this.promises = null; 84 | }; 85 | 86 | return MusicPlaylistsTab; 87 | }); -------------------------------------------------------------------------------- /tv/series.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, focusManager) { 2 | 'use strict'; 3 | 4 | function SeriesTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderSeries(view, items) { 11 | 12 | var container = view.querySelector('.seriesItems'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "portrait", 18 | centerText: true, 19 | overlayMoreButton: !layoutManager.tv, 20 | showTitle: true 21 | }); 22 | } 23 | 24 | SeriesTab.prototype.onBeforeShow = function (options) { 25 | 26 | var apiClient = this.apiClient; 27 | 28 | if (!options.refresh) { 29 | this.promises = null; 30 | return; 31 | } 32 | 33 | var promises = []; 34 | var parentId = this.params.parentId; 35 | 36 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), { 37 | 38 | SortBy: "SortName", 39 | SortOrder: "Ascending", 40 | IncludeItemTypes: "Series", 41 | Recursive: true, 42 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo,SortName", 43 | ImageTypeLimit: 1, 44 | EnableImageTypes: "Primary,Backdrop,Banner,Thumb", 45 | StartIndex: 0, 46 | parentId: parentId 47 | })); 48 | 49 | this.promises = promises; 50 | }; 51 | 52 | SeriesTab.prototype.onShow = function (options) { 53 | 54 | var promises = this.promises; 55 | if (!promises) { 56 | return; 57 | } 58 | 59 | this.promises = []; 60 | 61 | var view = this.view; 62 | 63 | promises[0].then(function (result) { 64 | renderSeries(view, result.Items); 65 | return Promise.resolve(); 66 | }); 67 | 68 | Promise.all(promises).then(function () { 69 | if (options.autoFocus) { 70 | focusManager.autoFocus(view); 71 | } 72 | }); 73 | }; 74 | 75 | SeriesTab.prototype.onHide = function () { 76 | 77 | }; 78 | 79 | SeriesTab.prototype.destroy = function () { 80 | 81 | this.view = null; 82 | this.params = null; 83 | this.apiClient = null; 84 | this.promises = null; 85 | }; 86 | 87 | return SeriesTab; 88 | }); -------------------------------------------------------------------------------- /movies/collections.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function MoviesTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderMovies(view, items) { 11 | 12 | var container = view.querySelector('.movieItems'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "portrait", 18 | centerText: true, 19 | overlayMoreButton: !layoutManager.tv, 20 | showTitle: true 21 | }); 22 | } 23 | 24 | MoviesTab.prototype.onBeforeShow = function (options) { 25 | 26 | var apiClient = this.apiClient; 27 | 28 | if (!options.refresh) { 29 | this.promises = null; 30 | return; 31 | } 32 | 33 | var promises = []; 34 | var parentId = this.params.parentId; 35 | 36 | var query = { 37 | SortBy: "SortName", 38 | SortOrder: "Ascending", 39 | IncludeItemTypes: "BoxSet", 40 | Recursive: true, 41 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo", 42 | ImageTypeLimit: 1, 43 | EnableImageTypes: "Primary,Backdrop,Banner,Thumb", 44 | StartIndex: 0 45 | }; 46 | 47 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), query)); 48 | 49 | this.promises = promises; 50 | }; 51 | 52 | MoviesTab.prototype.onShow = function (options) { 53 | 54 | var promises = this.promises; 55 | if (!promises) { 56 | return; 57 | } 58 | 59 | this.promises = []; 60 | 61 | var view = this.view; 62 | 63 | promises[0].then(function (result) { 64 | renderMovies(view, result.Items); 65 | return Promise.resolve(); 66 | }); 67 | 68 | Promise.all(promises).then(function () { 69 | if (options.autoFocus) { 70 | focusManager.autoFocus(view); 71 | } 72 | }); 73 | }; 74 | 75 | MoviesTab.prototype.onHide = function () { 76 | 77 | }; 78 | 79 | MoviesTab.prototype.destroy = function () { 80 | 81 | this.view = null; 82 | this.params = null; 83 | this.apiClient = null; 84 | this.promises = null; 85 | }; 86 | 87 | return MoviesTab; 88 | }); -------------------------------------------------------------------------------- /movies/movies.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 | 7 |
8 | 9 |
10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |

${ContinueWatching}

18 |
19 |
20 |
21 |
22 |

${LatestMovies}

23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | 42 |
-------------------------------------------------------------------------------- /music/albums.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function AlbumsTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderAlbums(view, items) { 11 | 12 | var container = view.querySelector('.itemsContainer'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "square", 18 | context: 'music', 19 | showTitle: true, 20 | coverImage: true, 21 | showParentTitle: true, 22 | centerText: true 23 | }); 24 | } 25 | 26 | AlbumsTab.prototype.onBeforeShow = function (options) { 27 | 28 | var apiClient = this.apiClient; 29 | 30 | if (!options.refresh) { 31 | this.promises = null; 32 | return; 33 | } 34 | 35 | var promises = []; 36 | var parentId = this.params.parentId; 37 | 38 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), { 39 | 40 | SortBy: "SortName", 41 | SortOrder: "Ascending", 42 | IncludeItemTypes: "MusicAlbum", 43 | Recursive: true, 44 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo,SortName", 45 | ImageTypeLimit: 1, 46 | EnableImageTypes: "Primary", 47 | StartIndex: 0, 48 | parentId: parentId 49 | })); 50 | 51 | this.promises = promises; 52 | }; 53 | 54 | AlbumsTab.prototype.onShow = function (options) { 55 | 56 | var promises = this.promises; 57 | if (!promises) { 58 | return; 59 | } 60 | 61 | this.promises = []; 62 | 63 | var view = this.view; 64 | 65 | promises[0].then(function (result) { 66 | renderAlbums(view, result.Items); 67 | return Promise.resolve(); 68 | }); 69 | 70 | Promise.all(promises).then(function () { 71 | if (options.autoFocus) { 72 | focusManager.autoFocus(view); 73 | } 74 | }); 75 | }; 76 | 77 | AlbumsTab.prototype.onHide = function () { 78 | 79 | }; 80 | 81 | AlbumsTab.prototype.destroy = function () { 82 | 83 | this.view = null; 84 | this.params = null; 85 | this.apiClient = null; 86 | this.promises = null; 87 | }; 88 | 89 | return AlbumsTab; 90 | }); -------------------------------------------------------------------------------- /livetv/series.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper) { 2 | 'use strict'; 3 | 4 | function LiveTvSeriesTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderItems(view, items, sectionClass, overlayButton, cardOptions) { 11 | 12 | var supportsImageAnalysis = appHost.supports('imageanalysis'); 13 | var cardLayout = appHost.preferVisualCards || supportsImageAnalysis; 14 | cardLayout = false; 15 | 16 | cardOptions = cardOptions || {}; 17 | 18 | var html = cardBuilder.getCardsHtml(Object.assign({ 19 | items: items, 20 | shape: 'auto', 21 | defaultShape: 'portrait', 22 | showTitle: true, 23 | cardLayout: cardLayout, 24 | preferThumb: 'auto', 25 | coverImage: true, 26 | overlayText: false, 27 | showSeriesTimerTime: true, 28 | showSeriesTimerChannel: true, 29 | centerText: !cardLayout, 30 | overlayMoreButton: !cardLayout, 31 | lines: 3 32 | 33 | }, cardOptions)); 34 | 35 | var elem = view.querySelector('.' + sectionClass); 36 | 37 | elem.innerHTML = html; 38 | imageLoader.lazyChildren(elem); 39 | } 40 | 41 | LiveTvSeriesTab.prototype.onBeforeShow = function (options) { 42 | 43 | var apiClient = this.apiClient; 44 | 45 | if (!options.refresh) { 46 | this.promises = null; 47 | return; 48 | } 49 | 50 | var promises = []; 51 | 52 | promises.push(apiClient.getLiveTvSeriesTimers({ 53 | 54 | SortBy: "SortName", 55 | SortOrder: "Ascending" 56 | })); 57 | 58 | this.promises = promises; 59 | }; 60 | 61 | LiveTvSeriesTab.prototype.onShow = function () { 62 | 63 | var promises = this.promises; 64 | if (!promises) { 65 | return; 66 | } 67 | 68 | this.promises = []; 69 | 70 | var view = this.view; 71 | 72 | promises[0].then(function (result) { 73 | renderItems(view, result.Items, 'itemsContainer'); 74 | }); 75 | 76 | }; 77 | 78 | LiveTvSeriesTab.prototype.onHide = function () { 79 | 80 | }; 81 | 82 | LiveTvSeriesTab.prototype.destroy = function () { 83 | 84 | this.view = null; 85 | this.params = null; 86 | this.apiClient = null; 87 | this.promises = null; 88 | }; 89 | 90 | return LiveTvSeriesTab; 91 | }); -------------------------------------------------------------------------------- /tv/studios.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function StudiosTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderSeries(view, items, parentId) { 11 | 12 | var container = view.querySelector('.studioItems'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "backdrop", 18 | preferThumb: true, 19 | showTitle: true, 20 | scalable: true, 21 | centerText: true, 22 | overlayMoreButton: true, 23 | parentId: parentId 24 | }); 25 | } 26 | 27 | StudiosTab.prototype.onBeforeShow = function (options) { 28 | 29 | var apiClient = this.apiClient; 30 | 31 | if (!options.refresh) { 32 | this.promises = null; 33 | return; 34 | } 35 | 36 | var promises = []; 37 | var parentId = this.params.parentId; 38 | 39 | promises.push(apiClient.getStudios(apiClient.getCurrentUserId(), { 40 | 41 | SortBy: "SortName", 42 | SortOrder: "Ascending", 43 | IncludeItemTypes: "Series", 44 | Recursive: true, 45 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo,SortName", 46 | ImageTypeLimit: 1, 47 | EnableImageTypes: "Primary,Thumb", 48 | ParentId: parentId 49 | })); 50 | 51 | this.promises = promises; 52 | }; 53 | 54 | StudiosTab.prototype.onShow = function (options) { 55 | 56 | var promises = this.promises; 57 | if (!promises) { 58 | return; 59 | } 60 | 61 | this.promises = []; 62 | 63 | var view = this.view; 64 | 65 | var parentId = this.params.parentId; 66 | 67 | promises[0].then(function (result) { 68 | renderSeries(view, result.Items, parentId); 69 | return Promise.resolve(); 70 | }); 71 | 72 | Promise.all(promises).then(function () { 73 | if (options.autoFocus) { 74 | focusManager.autoFocus(view); 75 | } 76 | }); 77 | }; 78 | 79 | StudiosTab.prototype.onHide = function () { 80 | 81 | }; 82 | 83 | StudiosTab.prototype.destroy = function () { 84 | 85 | this.view = null; 86 | this.params = null; 87 | this.apiClient = null; 88 | this.promises = null; 89 | }; 90 | 91 | return StudiosTab; 92 | }); -------------------------------------------------------------------------------- /home_horiz/home.css: -------------------------------------------------------------------------------- 1 | .itemScrollFrame.scrollFrameX .scrollSlider { 2 | padding-left: 4.5%; 3 | } 4 | 5 | .itemScrollFrame.scrollFrameX .scrollSlider { 6 | padding-bottom: 1.2em; 7 | padding-top: .5em; 8 | } 9 | 10 | .horizontalSectionsContainer { 11 | display: flex; 12 | /* Needed to prevent images from flickering in tizen and orsay */ 13 | transform-style: preserve-3d; 14 | } 15 | 16 | .scrollFrameX .scrollSlider { 17 | white-space: nowrap !important; 18 | } 19 | 20 | .cardColumn { 21 | display: inline-block; 22 | vertical-align: top; 23 | flex-shrink: 0; 24 | } 25 | 26 | .listNumbers { 27 | position: fixed; 28 | bottom: 2.5%; 29 | right: 1.5%; 30 | } 31 | 32 | .horizontalSection { 33 | margin-right: 1.25em; 34 | flex-shrink: 0; 35 | } 36 | 37 | .horizontalSection .sectionTitle { 38 | font-size: 90%; 39 | padding-left: .1em; 40 | margin-bottom: 0; 41 | } 42 | 43 | .userViewNames { 44 | padding-left: 3.75%; 45 | } 46 | 47 | .userViewButtonText { 48 | font-weight: normal; 49 | } 50 | 51 | .userViewNames h3 { 52 | margin-top: 0; 53 | margin-bottom: 0; 54 | font-weight: 300; 55 | } 56 | 57 | .userViewNames .btnUserViewHeader { 58 | min-width: initial; 59 | text-transform: none !important; 60 | margin-top: 0; 61 | background: transparent; 62 | box-shadow: none; 63 | cursor: pointer; 64 | outline: none !important; 65 | width: auto; 66 | font-family: inherit; 67 | font-size: inherit; 68 | display: inline-block; 69 | vertical-align: middle; 70 | flex-shrink: 0; 71 | margin: 0; 72 | padding: 1em .9em; 73 | position: relative; 74 | height: auto; 75 | min-width: initial; 76 | line-height: initial; 77 | border-radius: 0 !important; 78 | overflow: hidden; 79 | opacity: .3; 80 | } 81 | 82 | .homePageContainer .cardImageContainer { 83 | animation: none !important; 84 | opacity: 1 !important; 85 | } 86 | 87 | .homePageContainer .selectedItemInfo { 88 | right: 2%; 89 | bottom: 2.5%; 90 | } 91 | 92 | .homePageContent .squareCard { 93 | width: 9.08em; 94 | } 95 | 96 | .homePageContent .backdropCard { 97 | width: 15.7em; 98 | } 99 | 100 | .homePageContent .portraitCard { 101 | width: 9.3em; 102 | } 103 | 104 | .wideSpotlightCard { 105 | width: 100%; 106 | } 107 | 108 | .wideSpotlightCard .cardImageContainer { 109 | height: 17.59em; 110 | } 111 | 112 | .wideSpotlightCard.card-focusscale:focus > .cardBox { 113 | transform: scale(1.04, 1.04); 114 | } 115 | 116 | .homePageContainer .cardBox { 117 | margin: 4px !important; 118 | } 119 | 120 | .homePageContainer .cardContent { 121 | border-radius: 0 !important; 122 | } 123 | -------------------------------------------------------------------------------- /components/itemslist.js: -------------------------------------------------------------------------------- 1 | define(['loading', './focushandler', 'focusManager', 'cardBuilder'], function (loading, focusHandler, focusManager, cardbuilder) { 2 | 'use strict'; 3 | 4 | function itemsList(options) { 5 | 6 | var self = this; 7 | self.options = options; 8 | } 9 | 10 | itemsList.prototype.render = function () { 11 | 12 | var self = this; 13 | var options = self.options; 14 | 15 | if (options.itemsContainer) { 16 | 17 | self.focusHandler = new focusHandler({ 18 | parent: options.itemsContainer, 19 | selectedItemInfoElement: options.selectedItemInfoElement, 20 | selectedIndexElement: options.selectedIndexElement, 21 | scroller: options.scroller, 22 | selectedItemMode: options.selectedItemMode, 23 | enableBackdrops: true 24 | }); 25 | } 26 | 27 | loading.show(); 28 | 29 | options.getItemsMethod(0, 4000).then(self.onItemsResult.bind(self)); 30 | }; 31 | 32 | itemsList.prototype.onItemsResult = function (result) { 33 | 34 | var self = this; 35 | var options = self.options; 36 | 37 | // Normalize between the different response types 38 | if (result.Items == null && result.TotalRecordCount == null) { 39 | 40 | result = { 41 | Items: result, 42 | TotalRecordCount: result.length 43 | }; 44 | } 45 | 46 | self.items = result.Items; 47 | 48 | if (options.listCountElement) { 49 | options.listCountElement.innerHTML = result.TotalRecordCount; 50 | options.listNumbersElement.classList.remove('hide'); 51 | } 52 | 53 | var cardOptions = options.cardOptions || {}; 54 | cardOptions.itemsContainer = options.itemsContainer; 55 | 56 | cardbuilder.buildCards(result.Items, cardOptions); 57 | 58 | loading.hide(); 59 | 60 | if (options.onRender) { 61 | options.onRender(); 62 | } 63 | 64 | if (options.autoFocus !== false) { 65 | setTimeout(self.onAutoFocusTimeout.bind(self), 400); 66 | } 67 | }; 68 | 69 | itemsList.prototype.onAutoFocusTimeout = function () { 70 | 71 | var self = this; 72 | var options = self.options; 73 | 74 | var firstCard = options.itemsContainer.querySelector('.card'); 75 | if (firstCard) { 76 | focusManager.focus(firstCard); 77 | } 78 | }; 79 | 80 | itemsList.prototype.destroy = function () { 81 | 82 | var self = this; 83 | 84 | if (self.focusHandler) { 85 | self.focusHandler.destroy(); 86 | self.focusHandler = null; 87 | } 88 | 89 | self.options = null; 90 | }; 91 | 92 | return itemsList; 93 | }); -------------------------------------------------------------------------------- /music/artists.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function AlbumsTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderAlbums(view, items) { 11 | 12 | var container = view.querySelector('.itemsContainer'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "square", 18 | showTitle: true, 19 | overlayText: true, 20 | overlayMoreButton: !layoutManager.tv 21 | }); 22 | } 23 | 24 | AlbumsTab.prototype.onBeforeShow = function (options) { 25 | 26 | var apiClient = this.apiClient; 27 | 28 | if (!options.refresh) { 29 | this.promises = null; 30 | return; 31 | } 32 | 33 | var promises = []; 34 | var parentId = this.params.parentId; 35 | 36 | var query = { 37 | SortBy: "SortName", 38 | SortOrder: "Ascending", 39 | Recursive: true, 40 | Fields: "PrimaryImageAspectRatio,SortName,ItemCounts,BasicSyncInfo", 41 | StartIndex: 0, 42 | ImageTypeLimit: 1, 43 | EnableImageTypes: "Primary,Backdrop,Banner,Thumb", 44 | ParentId: parentId 45 | }; 46 | 47 | var promise = this.mode === 'albumartists' ? 48 | apiClient.getAlbumArtists(apiClient.getCurrentUserId(), query) : 49 | apiClient.getArtists(apiClient.getCurrentUserId(), query); 50 | 51 | promises.push(promise); 52 | 53 | this.promises = promises; 54 | }; 55 | 56 | AlbumsTab.prototype.onShow = function (options) { 57 | 58 | var promises = this.promises; 59 | if (!promises) { 60 | return; 61 | } 62 | 63 | this.promises = []; 64 | 65 | var view = this.view; 66 | 67 | promises[0].then(function (result) { 68 | renderAlbums(view, result.Items); 69 | return Promise.resolve(); 70 | }); 71 | 72 | Promise.all(promises).then(function () { 73 | if (options.autoFocus) { 74 | focusManager.autoFocus(view); 75 | } 76 | }); 77 | }; 78 | 79 | AlbumsTab.prototype.onHide = function () { 80 | 81 | }; 82 | 83 | AlbumsTab.prototype.destroy = function () { 84 | 85 | this.view = null; 86 | this.params = null; 87 | this.apiClient = null; 88 | this.promises = null; 89 | }; 90 | 91 | return AlbumsTab; 92 | }); -------------------------------------------------------------------------------- /livetv/channels.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function LiveTvChannelsTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderItems(view, items, sectionClass, overlayButton, cardOptions) { 11 | 12 | var supportsImageAnalysis = appHost.supports('imageanalysis'); 13 | var cardLayout = supportsImageAnalysis; 14 | 15 | cardOptions = cardOptions || {}; 16 | 17 | var html = cardBuilder.getCardsHtml(Object.assign({ 18 | items: items, 19 | shape: "square", 20 | showTitle: true, 21 | lazy: true, 22 | cardLayout: true, 23 | showDetailsMenu: true, 24 | showCurrentProgram: true, 25 | showCurrentProgramTime: true 26 | 27 | }, cardOptions)); 28 | 29 | var elem = view.querySelector('.' + sectionClass); 30 | 31 | elem.innerHTML = html; 32 | imageLoader.lazyChildren(elem); 33 | } 34 | 35 | LiveTvChannelsTab.prototype.onBeforeShow = function (options) { 36 | 37 | var apiClient = this.apiClient; 38 | 39 | if (!options.refresh) { 40 | this.promises = null; 41 | return; 42 | } 43 | 44 | var promises = []; 45 | 46 | promises.push(apiClient.getLiveTvChannels({ 47 | 48 | UserId: apiClient.getCurrentUserId(), 49 | ImageTypeLimit: 1, 50 | EnableImageTypes: "Primary", 51 | EnableTotalRecordCount: false, 52 | Fields: "ChannelInfo,PrimaryImageAspectRatio" 53 | })); 54 | 55 | this.promises = promises; 56 | }; 57 | 58 | LiveTvChannelsTab.prototype.onShow = function (options) { 59 | 60 | var promises = this.promises; 61 | if (!promises) { 62 | return; 63 | } 64 | 65 | this.promises = []; 66 | 67 | var view = this.view; 68 | 69 | promises[0].then(function (result) { 70 | renderItems(view, result.Items, 'itemsContainer'); 71 | return Promise.resolve(); 72 | }); 73 | 74 | Promise.all(promises).then(function () { 75 | if (options.autoFocus) { 76 | focusManager.autoFocus(view); 77 | } 78 | }); 79 | }; 80 | 81 | LiveTvChannelsTab.prototype.onHide = function () { 82 | 83 | }; 84 | 85 | LiveTvChannelsTab.prototype.destroy = function () { 86 | 87 | this.view = null; 88 | this.params = null; 89 | this.apiClient = null; 90 | this.promises = null; 91 | }; 92 | 93 | return LiveTvChannelsTab; 94 | }); -------------------------------------------------------------------------------- /movies/moviestab.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function MoviesTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderMovies(view, items, mode) { 11 | 12 | var container = view.querySelector('.movieItems'); 13 | 14 | cardBuilder.buildCards(items, { 15 | itemsContainer: container, 16 | items: items, 17 | shape: "portrait", 18 | centerText: true, 19 | overlayMoreButton: !layoutManager.tv, 20 | showTitle: true, 21 | showYear: mode === 'unwatched' || mode === 'favorites' 22 | }); 23 | } 24 | 25 | MoviesTab.prototype.onBeforeShow = function (options) { 26 | 27 | var apiClient = this.apiClient; 28 | 29 | if (!options.refresh) { 30 | this.promises = null; 31 | return; 32 | } 33 | 34 | var promises = []; 35 | var parentId = this.params.parentId; 36 | 37 | var query = { 38 | SortBy: "SortName", 39 | SortOrder: "Ascending", 40 | IncludeItemTypes: "Movie", 41 | Recursive: true, 42 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo,SortName", 43 | ImageTypeLimit: 1, 44 | EnableImageTypes: "Primary,Backdrop,Banner,Thumb", 45 | StartIndex: 0, 46 | parentId: parentId 47 | }; 48 | 49 | if (this.mode === 'unwatched') { 50 | query.Filters = "IsUnplayed"; 51 | } 52 | else if (this.mode === 'favorites') { 53 | query.Filters = "IsFavorite"; 54 | } 55 | 56 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), query)); 57 | 58 | this.promises = promises; 59 | }; 60 | 61 | MoviesTab.prototype.onShow = function (options) { 62 | 63 | var promises = this.promises; 64 | if (!promises) { 65 | return; 66 | } 67 | 68 | this.promises = []; 69 | 70 | var view = this.view; 71 | var mode = this.mode; 72 | 73 | promises[0].then(function (result) { 74 | renderMovies(view, result.Items, mode); 75 | return Promise.resolve(); 76 | }); 77 | 78 | Promise.all(promises).then(function () { 79 | if (options.autoFocus) { 80 | focusManager.autoFocus(view); 81 | } 82 | }); 83 | }; 84 | 85 | MoviesTab.prototype.onHide = function () { 86 | 87 | }; 88 | 89 | MoviesTab.prototype.destroy = function () { 90 | 91 | this.view = null; 92 | this.params = null; 93 | this.apiClient = null; 94 | this.promises = null; 95 | }; 96 | 97 | return MoviesTab; 98 | }); -------------------------------------------------------------------------------- /home_horiz/views.channels.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'globalize', 'emby-itemscontainer'], function (cardBuilder, globalize) { 2 | 'use strict'; 3 | 4 | function loadChannels(element, parentId, apiClient, autoFocus) { 5 | 6 | return apiClient.getChannels({ 7 | 8 | UserId: apiClient.getCurrentUserId(), 9 | Fields: "PrimaryImageAspectRatio", 10 | ImageTypeLimit: 1 11 | 12 | }).then(function (result) { 13 | 14 | var section = element.querySelector('.channelsSection'); 15 | 16 | // Needed in case the view has been destroyed 17 | if (!section) { 18 | return; 19 | } 20 | 21 | cardBuilder.buildCards(result.Items, { 22 | parentContainer: section, 23 | itemsContainer: section.querySelector('.itemsContainer'), 24 | shape: 'backdrop', 25 | rows: 3, 26 | preferThumb: true, 27 | autoFocus: autoFocus, 28 | scalable: false 29 | }); 30 | 31 | var latestContainer = element.querySelector('.latestContainer'); 32 | 33 | latestContainer.innerHTML = ''; 34 | 35 | return Promise.all(result.Items.map(function (i) { 36 | return loadLatest(latestContainer, i, apiClient); 37 | })); 38 | }); 39 | } 40 | 41 | function loadLatest(element, channel, apiClient) { 42 | 43 | var html = '
'+ globalize.translate('LatestFromValue', channel.Name) + '
'; 44 | 45 | var section = document.createElement('div'); 46 | section.classList.add('hide'); 47 | section.classList.add('horizontalSection'); 48 | 49 | section.innerHTML = html; 50 | element.appendChild(section); 51 | 52 | var options = { 53 | Limit: 6, 54 | ChannelIds: channel.Id, 55 | UserId: apiClient.getCurrentUserId(), 56 | Filters: "IsUnplayed", 57 | Fields: "PrimaryImageAspectRatio", 58 | ImageTypeLimit: 1 59 | }; 60 | 61 | return apiClient.getLatestChannelItems(options).then(function (result) { 62 | 63 | cardBuilder.buildCards(result.Items, { 64 | parentContainer: section, 65 | itemsContainer: section.querySelector('.itemsContainer'), 66 | shape: 'auto', 67 | showTitle: false, 68 | rows: { 69 | portrait: 2, 70 | square: 3, 71 | backdrop: 3 72 | }, 73 | scalable: false 74 | }); 75 | }); 76 | } 77 | 78 | function view(element, apiClient, parentId, autoFocus) { 79 | 80 | var self = this; 81 | 82 | self.loadData = function () { 83 | return loadChannels(element, parentId, apiClient, autoFocus); 84 | }; 85 | 86 | self.destroy = function () { 87 | 88 | }; 89 | } 90 | 91 | return view; 92 | }); -------------------------------------------------------------------------------- /tv/latest.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function LatestTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderLatest(view, items) { 11 | 12 | var container = view.querySelector('.latestItems'); 13 | var supportsImageAnalysis = appHost.supports('imageanalysis'); 14 | var cardLayout = false; 15 | 16 | cardBuilder.buildCards(items, { 17 | itemsContainer: container, 18 | items: items, 19 | shape: 'backdrop', 20 | preferThumb: true, 21 | showTitle: true, 22 | showSeriesYear: true, 23 | showParentTitle: true, 24 | overlayText: false, 25 | cardLayout: cardLayout, 26 | showUnplayedIndicator: false, 27 | showChildCountIndicator: true, 28 | centerText: !cardLayout, 29 | lazy: true, 30 | overlayPlayButton: true, 31 | vibrant: cardLayout && supportsImageAnalysis, 32 | lines: 2 33 | }); 34 | } 35 | 36 | LatestTab.prototype.onBeforeShow = function (options) { 37 | 38 | var apiClient = this.apiClient; 39 | 40 | if (!options.refresh) { 41 | this.promises = null; 42 | return; 43 | } 44 | 45 | var promises = []; 46 | var parentId = this.params.parentId; 47 | 48 | promises.push(apiClient.getLatestItems({ 49 | 50 | IncludeItemTypes: "Episode", 51 | Limit: 30, 52 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo", 53 | ParentId: parentId, 54 | ImageTypeLimit: 1, 55 | EnableImageTypes: "Primary,Backdrop,Thumb" 56 | 57 | })); 58 | 59 | this.promises = promises; 60 | }; 61 | 62 | LatestTab.prototype.onShow = function (options) { 63 | 64 | var promises = this.promises; 65 | if (!promises) { 66 | return; 67 | } 68 | 69 | this.promises = []; 70 | 71 | var view = this.view; 72 | 73 | var parentId = this.params.parentId; 74 | 75 | promises[0].then(function (result) { 76 | renderLatest(view, result); 77 | return Promise.resolve(); 78 | }); 79 | 80 | Promise.all(promises).then(function () { 81 | if (options.autoFocus) { 82 | focusManager.autoFocus(view); 83 | } 84 | }); 85 | }; 86 | 87 | LatestTab.prototype.onHide = function () { 88 | 89 | }; 90 | 91 | LatestTab.prototype.destroy = function () { 92 | 93 | this.view = null; 94 | this.params = null; 95 | this.apiClient = null; 96 | this.promises = null; 97 | }; 98 | 99 | return LatestTab; 100 | }); -------------------------------------------------------------------------------- /home/hometab.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'homeSections', 'emby-itemscontainer', 'emby-scroller'], function (cardBuilder, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager, homeSections) { 2 | 'use strict'; 3 | 4 | function enableScrollX(section) { 5 | 6 | return !layoutManager.desktop; 7 | } 8 | 9 | function HomeTab(view, params) { 10 | this.view = view; 11 | this.params = params; 12 | this.apiClient = connectionManager.currentApiClient(); 13 | } 14 | 15 | function initLayout(view) { 16 | 17 | var containers = view.querySelectorAll('.autoScrollSection'); 18 | 19 | for (var i = 0, length = containers.length; i < length; i++) { 20 | 21 | var section = containers[i]; 22 | 23 | var html; 24 | 25 | if (enableScrollX(section.getAttribute('data-section'))) { 26 | html = '
'; 27 | } else { 28 | html = '
'; 29 | } 30 | 31 | section.insertAdjacentHTML('beforeend', html); 32 | } 33 | } 34 | 35 | function getThumbShape(section) { 36 | return enableScrollX(section) ? 'overflowBackdrop' : 'backdrop'; 37 | } 38 | 39 | function getRequirePromise(deps) { 40 | 41 | return new Promise(function (resolve, reject) { 42 | 43 | require(deps, resolve); 44 | }); 45 | } 46 | 47 | HomeTab.prototype.onBeforeShow = function (options) { 48 | 49 | this.refreshOnShow = options.refresh; 50 | }; 51 | 52 | HomeTab.prototype.onShow = function (options) { 53 | 54 | if (!this.refreshOnShow) { 55 | return; 56 | } 57 | 58 | var view = this.view; 59 | 60 | if (!this.initComplete) { 61 | this.initComplete = true; 62 | initLayout(view); 63 | } 64 | 65 | var apiClient = this.apiClient; 66 | 67 | var promises = [ 68 | apiClient.getCurrentUser(), 69 | getRequirePromise(['userSettings']) 70 | ]; 71 | 72 | Promise.all(promises).then(function (responses) { 73 | 74 | var user = responses[0]; 75 | var userSettings = responses[1]; 76 | 77 | homeSections.loadSections(view.querySelector('.sections'), apiClient, user, userSettings).then(function () { 78 | 79 | if (options.autoFocus) { 80 | focusManager.autoFocus(view); 81 | } 82 | 83 | loading.hide(); 84 | }); 85 | }); 86 | }; 87 | 88 | HomeTab.prototype.onHide = function () { 89 | 90 | }; 91 | 92 | HomeTab.prototype.destroy = function () { 93 | 94 | this.view = null; 95 | this.params = null; 96 | this.apiClient = null; 97 | this.promises = null; 98 | }; 99 | 100 | return HomeTab; 101 | }); -------------------------------------------------------------------------------- /tv/tv.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 | 7 |
8 | 9 |
10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |

${ContinueWatching}

18 |
19 |
20 |
21 |
22 |

${NextUp}

23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 |

${FavoriteShows}

36 |
37 |
38 |
39 |
40 |
41 |

${FavoriteEpisodes}

42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | 54 |
-------------------------------------------------------------------------------- /home_horiz/views.movies.html: -------------------------------------------------------------------------------- 1 |
2 |
 
3 |
4 | 15 |
16 | 32 | 33 | 49 | 50 | 66 |
67 |
68 |
69 | 70 |
71 |
${ContinueWatching}
72 |
73 | 74 |
75 |
76 | 77 |
78 |
${LatestMovies}
79 |
80 | 81 |
82 |
83 | 84 |
85 | 86 |
-------------------------------------------------------------------------------- /home_horiz/views.livetv.html: -------------------------------------------------------------------------------- 1 |
2 |
 
3 |
4 | 20 | 21 | 37 | 38 | 54 |
55 |
56 | 57 |
58 |
${LatestRecordings}
59 |
60 | 61 |
62 |
63 | 64 |
65 |
${HeaderOnNow}
66 |
67 | 68 |
69 |
70 | 71 |
72 |
${Shows}
73 |
74 | 75 |
76 |
77 | 78 |
79 |
${Movies}
80 |
81 | 82 |
83 |
84 | 85 |
86 |
${Sports}
87 |
88 | 89 |
90 |
91 | 92 |
93 |
${HeaderForKids}
94 |
95 | 96 |
97 |
-------------------------------------------------------------------------------- /home_horiz/views.tv.html: -------------------------------------------------------------------------------- 1 |
2 |
 
3 |
4 | 15 |
16 | 17 | 33 | 34 | 50 | 51 | 67 | 68 |
69 |
70 |
71 | 72 |
73 |
${ContinueWatching}
74 |
75 | 76 |
77 |
78 | 79 |
80 |
${NextUp}
81 |
82 | 83 |
84 |
85 | 86 |
87 |
${LatestEpisodes}
88 |
89 | 90 |
91 |
92 | -------------------------------------------------------------------------------- /strings/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "ButtonEditRecording": "Edit Recording", 3 | "Episodes": "Episodes", 4 | "OtherVideos": "Other videos", 5 | "ShowScenesOnDetailScreensFor": "Show scenes on detail screens for", 6 | "Play": "Play", 7 | "Resume": "Resume", 8 | "Books": "Books", 9 | "HeaderAudioBooks": "Audio Books", 10 | "Queue": "Queue", 11 | "Shuffle": "Shuffle", 12 | "InsstantMix": "Instant Mix", 13 | "ButtonCancel": "Cancel", 14 | "ButtonCancelSeries": "Cancel Series", 15 | "AllShows": "All Shows", 16 | "Genres": "Genres", 17 | "Extras": "Extras", 18 | "NextUp": "Next Up", 19 | "LatestEpisodes": "Latest Episodes", 20 | "ContinueWatching": "Continue Watching", 21 | "AllMovies": "All Movies", 22 | "LatestMovies": "Latest Movies", 23 | "Channels": "Channels", 24 | "LatestFromValue": "Latest from {0}", 25 | "All": "All", 26 | "Latest": "Latest", 27 | "Artists": "Artists", 28 | "Albums": "Albums", 29 | "RecentlyPlayed": "Recently Played", 30 | "FrequentlyPlayed": "Frequently Played", 31 | "Library": "Library", 32 | "Guide": "Guide", 33 | "Overview": "Overview", 34 | "People": "People", 35 | "Specials": "Specials", 36 | "SpecialFeatures": "Special Features", 37 | "Recordings": "Recordings", 38 | "Scheduled": "Scheduled", 39 | "LatestMusic": "Latest Music", 40 | "LatestRecordings": "Latest Recordings", 41 | "NowPlaying": "Now Playing", 42 | "Programs": "Programs", 43 | "RecommendationBecauseYouLike": "Because you like {0}", 44 | "RecommendationBecauseYouWatched": "Because you watched {0}", 45 | "RecommendationDirectedBy": "Directed by {0}", 46 | "RecommendationStarring": "Starring {0}", 47 | "HeaderMoreLikeThis": "More Like This", 48 | "MoreFrom": "More from {0}", 49 | "AlbumArtists": "Album Artists", 50 | "LiveTV": "Live TV", 51 | "TrackCount": "{0} tracks", 52 | "Search": "Search", 53 | "Trailer": "Trailer", 54 | "PlayAll": "Play All", 55 | "Suggestions": "Suggestions", 56 | "Schedule": "Schedule", 57 | "Shows": "Shows", 58 | "Sports": "Sports", 59 | "News": "News", 60 | "HeaderForKids": "For Kids", 61 | "HeaderOnNow": "On Now", 62 | "OptionSunday": "Sunday", 63 | "OptionMonday": "Monday", 64 | "OptionTuesday": "Tuesday", 65 | "OptionWednesday": "Wednesday", 66 | "OptionThursday": "Thursday", 67 | "OptionFriday": "Friday", 68 | "OptionSaturday": "Saturday", 69 | "OptionEveryday": "Every day", 70 | "OptionWeekend": "Weekends", 71 | "OptionWeekday": "Weekdays", 72 | "InstantMix": "Instant Mix", 73 | "SelectServer": "Select server", 74 | "SignOut": "Sign out", 75 | "TopRated": "Top Rated", 76 | "BornValue": "Born: {0}", 77 | "BirthPlaceValue": "Birth place: {0}", 78 | "FavoriteAlbums": "Favorite Albums", 79 | "FavoriteSongs": "Favorite Songs", 80 | "FavoriteArtists": "Favorite Artists", 81 | "FavoriteShows": "Favorite Shows", 82 | "FavoriteEpisodes": "Favorite Episodes", 83 | "FavoriteMovies": "Favorite Movies", 84 | "CastAndCrew": "Cast & Crew", 85 | "Unwatched": "Unwatched", 86 | "Movies": "Movies", 87 | "Collections": "Collections", 88 | "Years": "Years", 89 | "Favorites": "Favorites", 90 | "More": "More", 91 | "Playlists": "Playlists", 92 | "EnableEpisodeSpoilerProtection": "Enable anti-spoiler features", 93 | "EnableEpisodeSpoilerProtectionHelp": "Hide details for episodes beyond the first unwatched", 94 | "DimUnselectedPosters": "Dim unselected posters", 95 | "Songs": "Songs", 96 | "Record": "Record", 97 | "Settings": "Settings", 98 | "Mute": "Mute", 99 | "Unmute": "Unmute", 100 | "Subtitles": "Subtitles", 101 | "Audio": "Audio", 102 | "Rewind": "Rewind", 103 | "Fullscreen": "Full screen", 104 | "ExitFullscreen": "Exit full screen", 105 | "PlayOnAnotherDevice": "Play on another device", 106 | "FastForward": "Fast-forward", 107 | "Items": "Items", 108 | "PictureInPicture": "Picture in picture", 109 | "HeaderActiveRecordings": "Active Recordings", 110 | "Yesterday": "Yesterday", 111 | "HeaderUpcomingEpisodes": "Upcoming Episodes" 112 | } -------------------------------------------------------------------------------- /nowplaying/videoosd.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 |
7 | 8 |
9 | 10 |
11 |
12 | 13 |
14 |

15 |
16 |
17 | 18 |
19 |
20 | 21 |
22 |
23 |
24 | 25 |
26 |
27 |
28 | 29 |
30 | 33 | 34 | 37 | 38 | 41 | 42 | 45 | 46 | 49 | 50 | 53 | 54 | 57 | 60 | 63 | 66 | 69 | 72 | 73 |
74 | 75 |
76 | 79 |
80 | 81 |
82 |
83 |
84 |
85 |
-------------------------------------------------------------------------------- /tv/favorites.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function TvFavoritesTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function renderSeries(view, items) { 11 | 12 | cardBuilder.buildCards(items, { 13 | parentContainer: view.querySelector('.favoriteSeriesSection'), 14 | itemsContainer: view.querySelector('.seriesItems'), 15 | items: items, 16 | shape: "portrait", 17 | centerText: true, 18 | overlayMoreButton: !layoutManager.tv, 19 | showTitle: true 20 | }); 21 | } 22 | 23 | function renderEpisodes(view, items) { 24 | 25 | cardBuilder.buildCards(items, { 26 | parentContainer: view.querySelector('.favoriteEpisodesSection'), 27 | itemsContainer: view.querySelector('.episodeItems'), 28 | items: items, 29 | shape: "backdrop", 30 | showTitle: true, 31 | showParentTitle: true, 32 | overlayText: false, 33 | centerText: true, 34 | coverImage: true, 35 | overlayMoreButton: !layoutManager.tv 36 | }); 37 | } 38 | 39 | TvFavoritesTab.prototype.onBeforeShow = function (options) { 40 | 41 | var apiClient = this.apiClient; 42 | 43 | if (!options.refresh) { 44 | this.promises = null; 45 | return; 46 | } 47 | 48 | var promises = []; 49 | var parentId = this.params.parentId; 50 | 51 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), { 52 | 53 | SortBy: "SortName", 54 | SortOrder: "Ascending", 55 | IncludeItemTypes: "Series", 56 | Recursive: true, 57 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo", 58 | ImageTypeLimit: 1, 59 | EnableImageTypes: "Primary,Backdrop,Thumb", 60 | StartIndex: 0, 61 | parentId: parentId, 62 | IsFavorite: true 63 | })); 64 | 65 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), { 66 | 67 | SortBy: "SortName", 68 | SortOrder: "Ascending", 69 | IncludeItemTypes: "Episode", 70 | Recursive: true, 71 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo", 72 | ImageTypeLimit: 1, 73 | EnableImageTypes: "Primary,Backdrop,Thumb", 74 | StartIndex: 0, 75 | parentId: parentId, 76 | IsFavorite: true 77 | })); 78 | 79 | this.promises = promises; 80 | }; 81 | 82 | TvFavoritesTab.prototype.onShow = function (options) { 83 | 84 | var promises = this.promises; 85 | if (!promises) { 86 | return; 87 | } 88 | 89 | this.promises = []; 90 | 91 | var view = this.view; 92 | 93 | promises[0].then(function (result) { 94 | renderSeries(view, result.Items); 95 | return Promise.resolve(); 96 | }); 97 | 98 | promises[1].then(function (result) { 99 | renderEpisodes(view, result.Items); 100 | return Promise.resolve(); 101 | }); 102 | 103 | Promise.all(promises).then(function () { 104 | if (options.autoFocus) { 105 | focusManager.autoFocus(view); 106 | } 107 | }); 108 | }; 109 | 110 | TvFavoritesTab.prototype.onHide = function () { 111 | 112 | }; 113 | 114 | TvFavoritesTab.prototype.destroy = function () { 115 | 116 | this.view = null; 117 | this.params = null; 118 | this.apiClient = null; 119 | this.promises = null; 120 | }; 121 | 122 | return TvFavoritesTab; 123 | }); -------------------------------------------------------------------------------- /home_horiz/views.music.html: -------------------------------------------------------------------------------- 1 |
2 |
 
3 |
4 | 20 | 21 | 37 | 38 | 54 |
55 |
56 | 57 |
58 |
${LatestMusic}
59 |
60 | 61 |
62 |
63 | 64 |
65 |
${Playlists}
66 |
67 | 68 |
69 |
70 | 71 |
72 |
${RecentlyPlayed}
73 |
74 | 75 |
76 |
77 | 78 |
79 |
${FrequentlyPlayed}
80 |
81 | 82 |
83 |
84 | 85 |
86 |
${FavoriteArtists}
87 |
88 | 89 |
90 |
91 | 92 |
93 |
${FavoriteAlbums}
94 |
95 | 96 |
97 |
98 | 99 |
100 |
${FavoriteSongs}
101 |
102 | 103 |
104 |
-------------------------------------------------------------------------------- /home_horiz/spotlight.js: -------------------------------------------------------------------------------- 1 | define(['visibleinviewport', 'itemShortcuts', 'browser'], function (visibleinviewport, itemShortcuts, browser) { 2 | 'use strict'; 3 | 4 | function loadItemIntoSpotlight(card, item, width) { 5 | 6 | if (!item.BackdropImageTags || !item.BackdropImageTags.length) { 7 | return; 8 | } 9 | 10 | if (document.activeElement === card) { 11 | card.dispatchEvent(new CustomEvent("focus")); 12 | } 13 | 14 | var imgUrl = Emby.Models.backdropImageUrl(item, { 15 | maxWidth: width 16 | }); 17 | 18 | var cardImageContainer = card.querySelector('.cardImage'); 19 | 20 | var newCardImageContainer = document.createElement('div'); 21 | newCardImageContainer.className = cardImageContainer.className; 22 | 23 | newCardImageContainer.style.backgroundImage = "url('" + imgUrl + "')"; 24 | 25 | card.querySelector('.cardText').innerHTML = item.Name; 26 | card.setAttribute('data-id', item.Id); 27 | card.setAttribute('data-serverid', item.ServerId); 28 | card.setAttribute('data-type', item.Type); 29 | card.setAttribute('data-isfolder', item.IsFolder.toString()); 30 | card.setAttribute('data-action', 'link'); 31 | card.classList.add('itemAction'); 32 | 33 | cardImageContainer.parentNode.appendChild(newCardImageContainer); 34 | 35 | var onAnimationFinished = function () { 36 | 37 | var parentNode = cardImageContainer.parentNode; 38 | if (parentNode) { 39 | parentNode.removeChild(cardImageContainer); 40 | } 41 | }; 42 | 43 | // Only use the fade animation if native support for WebAnimations is present 44 | if (browser.animate /*&& cardImageContainer.style.backgroundImage*/) { 45 | var keyframes = [ 46 | { opacity: '0', offset: 0 }, 47 | { opacity: '1', offset: 1 }]; 48 | var timing = { duration: 900, iterations: 1 }; 49 | newCardImageContainer.animate(keyframes, timing).onfinish = onAnimationFinished; 50 | } else { 51 | onAnimationFinished(); 52 | } 53 | } 54 | 55 | function spotlight(card, items, width) { 56 | 57 | var self = this; 58 | 59 | itemShortcuts.on(card); 60 | 61 | self.items = items; 62 | self.card = card; 63 | self.width = width; 64 | 65 | self.start(); 66 | } 67 | 68 | spotlight.prototype.start = function() { 69 | 70 | var self = this; 71 | var items = self.items; 72 | var card = self.card; 73 | var width = self.width; 74 | 75 | if (!items.length) { 76 | return; 77 | } 78 | 79 | loadItemIntoSpotlight(card, items[0], width); 80 | 81 | if (items.length === 1) { 82 | return; 83 | } 84 | 85 | if (browser.slow) { 86 | return; 87 | } 88 | 89 | self.index = 1; 90 | // Use a higher interval for browsers that don't perform as well 91 | var intervalMs = browser.animate ? 10000 : 30000; 92 | 93 | self.interval = setInterval(self.onInterval.bind(self), intervalMs); 94 | }; 95 | 96 | spotlight.prototype.onInterval = function () { 97 | 98 | var self = this; 99 | var items = self.items; 100 | var card = self.card; 101 | var width = self.width; 102 | 103 | if (!document.body.contains(card)) { 104 | clearInterval(self.interval); 105 | return; 106 | } 107 | 108 | if (!visibleinviewport(card, false, 0)) { 109 | // If it's not visible on screen, skip it 110 | return; 111 | } 112 | 113 | if (self.index >= items.length) { 114 | self.index = 0; 115 | } 116 | 117 | loadItemIntoSpotlight(card, items[self.index], width); 118 | self.index++; 119 | }; 120 | 121 | spotlight.prototype.destroy = function () { 122 | 123 | var self = this; 124 | 125 | itemShortcuts.off(self.card); 126 | 127 | if (self.interval) { 128 | clearInterval(self.interval); 129 | } 130 | 131 | self.interval = null; 132 | self.items = null; 133 | self.card = null; 134 | }; 135 | 136 | return spotlight; 137 | }); -------------------------------------------------------------------------------- /strings/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Edit Recording", 5 | "Episodes": "Episodes", 6 | "OtherVideos": "Other videos", 7 | "ShowScenesOnDetailScreensFor": "Show scenes on detail screens for", 8 | "Play": "Play", 9 | "Resume": "Resume", 10 | "Books": "Books", 11 | "HeaderAudioBooks": "Audio Books", 12 | "Queue": "Queue", 13 | "Shuffle": "Shuffle", 14 | "InsstantMix": "Instant Mix", 15 | "ButtonCancel": "Cancel", 16 | "ButtonCancelSeries": "Cancel Series", 17 | "AllShows": "All Shows", 18 | "Genres": "Genres", 19 | "Extras": "Extras", 20 | "NextUp": "Next Up", 21 | "LatestEpisodes": "Latest Episodes", 22 | "ContinueWatching": "Continue Watching", 23 | "AllMovies": "All Movies", 24 | "LatestMovies": "Latest Movies", 25 | "Channels": "Channels", 26 | "LatestFromValue": "Latest from {0}", 27 | "All": "All", 28 | "Latest": "Latest", 29 | "Artists": "Artists", 30 | "Albums": "Albums", 31 | "RecentlyPlayed": "Recently Played", 32 | "FrequentlyPlayed": "Frequently Played", 33 | "Library": "Library", 34 | "Guide": "Guide", 35 | "Overview": "Overview", 36 | "People": "People", 37 | "Specials": "Specials", 38 | "SpecialFeatures": "Special Features", 39 | "Recordings": "Recordings", 40 | "Scheduled": "Scheduled", 41 | "LatestMusic": "Latest Music", 42 | "LatestRecordings": "Latest Recordings", 43 | "NowPlaying": "Now Playing", 44 | "Programs": "Programs", 45 | "RecommendationBecauseYouLike": "Because you like {0}", 46 | "RecommendationBecauseYouWatched": "Because you watched {0}", 47 | "RecommendationDirectedBy": "Directed by {0}", 48 | "RecommendationStarring": "Starring {0}", 49 | "HeaderMoreLikeThis": "More Like This", 50 | "MoreFrom": "More from {0}", 51 | "AlbumArtists": "Album Artists", 52 | "LiveTV": "Live TV", 53 | "TrackCount": "{0} tracks", 54 | "Search": "Search", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Play All", 57 | "Suggestions": "Suggestions", 58 | "Schedule": "Schedule", 59 | "Shows": "Shows", 60 | "HeaderUpcomingPrograms": "Upcoming Programs", 61 | "HeaderUpcomingMovies": "Upcoming Movies", 62 | "HeaderUpcomingSports": "Upcoming Sports", 63 | "HeaderUpcomingForKids": "Upcoming for Kids", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "For Kids", 66 | "HeaderOnNow": "On Now", 67 | "OptionSunday": "Sunday", 68 | "OptionMonday": "Monday", 69 | "OptionTuesday": "Tuesday", 70 | "OptionWednesday": "Wednesday", 71 | "OptionThursday": "Thursday", 72 | "OptionFriday": "Friday", 73 | "OptionSaturday": "Saturday", 74 | "OptionEveryday": "Every day", 75 | "OptionWeekend": "Weekends", 76 | "OptionWeekday": "Weekdays", 77 | "InstantMix": "Instant Mix", 78 | "SelectServer": "Select server", 79 | "SignOut": "Sign out", 80 | "TopRated": "Top Rated", 81 | "BornValue": "Born: {0}", 82 | "BirthPlaceValue": "Birth place: {0}", 83 | "FavoriteAlbums": "Favourite Albums", 84 | "FavoriteSongs": "Favourite Songs", 85 | "FavoriteArtists": "Favourite Artists", 86 | "FavoriteShows": "Favorite Shows", 87 | "FavoriteEpisodes": "Favourite Episodes", 88 | "FavoriteMovies": "Favorite Movies", 89 | "CastAndCrew": "Cast & Crew", 90 | "Unwatched": "Unwatched", 91 | "Movies": "Movies", 92 | "Collections": "Collections", 93 | "Years": "Years", 94 | "Favorites": "Favorites", 95 | "More": "More", 96 | "Playlists": "Playlists", 97 | "EnableEpisodeSpoilerProtection": "Enable anti-spoiler features", 98 | "EnableEpisodeSpoilerProtectionHelp": "Hide details for episodes beyond the first unwatched", 99 | "DimUnselectedPosters": "Dim unselected posters", 100 | "Songs": "Songs", 101 | "Record": "Record", 102 | "Settings": "Settings", 103 | "Mute": "Mute", 104 | "Unmute": "Unmute", 105 | "Subtitles": "Subtitles", 106 | "Audio": "Audio", 107 | "Rewind": "Rewind", 108 | "Fullscreen": "Full screen", 109 | "ExitFullscreen": "Exit full screen", 110 | "PlayOnAnotherDevice": "Play on another device", 111 | "FastForward": "Fast-forward", 112 | "Items": "Items", 113 | "PictureInPicture": "Picture in picture", 114 | "HeaderActiveRecordings": "Active Recordings", 115 | "Yesterday": "Yesterday", 116 | "HeaderUpcomingEpisodes": "Upcoming Episodes" 117 | } -------------------------------------------------------------------------------- /strings/en-GB.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Edit Recording", 5 | "Episodes": "Episodes", 6 | "OtherVideos": "Other videos", 7 | "ShowScenesOnDetailScreensFor": "Show scenes on detail screens for", 8 | "Play": "Play", 9 | "Resume": "Resume", 10 | "Books": "Books", 11 | "HeaderAudioBooks": "Audio Books", 12 | "Queue": "Queue", 13 | "Shuffle": "Shuffle", 14 | "InsstantMix": "Instant Mix", 15 | "ButtonCancel": "Cancel", 16 | "ButtonCancelSeries": "Cancel Series", 17 | "AllShows": "All Shows", 18 | "Genres": "Genres", 19 | "Extras": "Extras", 20 | "NextUp": "Next Up", 21 | "LatestEpisodes": "Latest Episodes", 22 | "ContinueWatching": "Continue Watching", 23 | "AllMovies": "All Movies", 24 | "LatestMovies": "Latest Movies", 25 | "Channels": "Channels", 26 | "LatestFromValue": "Latest from {0}", 27 | "All": "All", 28 | "Latest": "Latest", 29 | "Artists": "Artists", 30 | "Albums": "Albums", 31 | "RecentlyPlayed": "Recently Played", 32 | "FrequentlyPlayed": "Frequently Played", 33 | "Library": "Library", 34 | "Guide": "Guide", 35 | "Overview": "Overview", 36 | "People": "People", 37 | "Specials": "Specials", 38 | "SpecialFeatures": "Special Features", 39 | "Recordings": "Recordings", 40 | "Scheduled": "Scheduled", 41 | "LatestMusic": "Latest Music", 42 | "LatestRecordings": "Latest Recordings", 43 | "NowPlaying": "Now Playing", 44 | "Programs": "Programmes", 45 | "RecommendationBecauseYouLike": "Because you like {0}", 46 | "RecommendationBecauseYouWatched": "Because you watched {0}", 47 | "RecommendationDirectedBy": "Directed by {0}", 48 | "RecommendationStarring": "Starring {0}", 49 | "HeaderMoreLikeThis": "More Like This", 50 | "MoreFrom": "More from {0}", 51 | "AlbumArtists": "Album Artists", 52 | "LiveTV": "Live TV", 53 | "TrackCount": "{0} tracks", 54 | "Search": "Search", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Play All", 57 | "Suggestions": "Suggestions", 58 | "Schedule": "Schedule", 59 | "Shows": "Shows", 60 | "HeaderUpcomingPrograms": "Upcoming Programmes", 61 | "HeaderUpcomingMovies": "Upcoming Movies", 62 | "HeaderUpcomingSports": "Upcoming Sports", 63 | "HeaderUpcomingForKids": "Upcoming for Kids", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "For Kids", 66 | "HeaderOnNow": "On Now", 67 | "OptionSunday": "Sunday", 68 | "OptionMonday": "Monday", 69 | "OptionTuesday": "Tuesday", 70 | "OptionWednesday": "Wednesday", 71 | "OptionThursday": "Thursday", 72 | "OptionFriday": "Friday", 73 | "OptionSaturday": "Saturday", 74 | "OptionEveryday": "Every day", 75 | "OptionWeekend": "Weekends", 76 | "OptionWeekday": "Weekdays", 77 | "InstantMix": "Instant Mix", 78 | "SelectServer": "Select server", 79 | "SignOut": "Sign out", 80 | "TopRated": "Top Rated", 81 | "BornValue": "Born: {0}", 82 | "BirthPlaceValue": "Birth place: {0}", 83 | "FavoriteAlbums": "Favourite Albums", 84 | "FavoriteSongs": "Favourite Songs", 85 | "FavoriteArtists": "Favourite Artists", 86 | "FavoriteShows": "Favourite Shows", 87 | "FavoriteEpisodes": "Favourite Episodes", 88 | "FavoriteMovies": "Favourite Movies", 89 | "CastAndCrew": "Cast & Crew", 90 | "Unwatched": "Unwatched", 91 | "Movies": "Movies", 92 | "Collections": "Collections", 93 | "Years": "Years", 94 | "Favorites": "Favourites", 95 | "More": "More", 96 | "Playlists": "Playlists", 97 | "EnableEpisodeSpoilerProtection": "Enable anti-spoiler features", 98 | "EnableEpisodeSpoilerProtectionHelp": "Hide details for episodes beyond the first unwatched", 99 | "DimUnselectedPosters": "Dim unselected posters", 100 | "Songs": "Songs", 101 | "Record": "Record", 102 | "Settings": "Settings", 103 | "Mute": "Mute", 104 | "Unmute": "Unmute", 105 | "Subtitles": "Subtitles", 106 | "Audio": "Audio", 107 | "Rewind": "Rewind", 108 | "Fullscreen": "Full screen", 109 | "ExitFullscreen": "Exit full screen", 110 | "PlayOnAnotherDevice": "Play on another device", 111 | "FastForward": "Fast-forward", 112 | "Items": "Items", 113 | "PictureInPicture": "Picture in Picture", 114 | "HeaderActiveRecordings": "Active Recordings", 115 | "Yesterday": "Yesterday", 116 | "HeaderUpcomingEpisodes": "Upcoming Episodes" 117 | } -------------------------------------------------------------------------------- /strings/sv.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Edit Recording", 5 | "Episodes": "Episodes", 6 | "OtherVideos": "Other videos", 7 | "ShowScenesOnDetailScreensFor": "Show scenes on detail screens for", 8 | "Play": "Play", 9 | "Resume": "Resume", 10 | "Books": "Books", 11 | "HeaderAudioBooks": "Audio Books", 12 | "Queue": "Queue", 13 | "Shuffle": "Shuffle", 14 | "InsstantMix": "Instant Mix", 15 | "ButtonCancel": "Avbryt", 16 | "ButtonCancelSeries": "Cancel Series", 17 | "AllShows": "All Shows", 18 | "Genres": "Genrer", 19 | "Extras": "Extras", 20 | "NextUp": "N\u00e4sta p\u00e5 tur", 21 | "LatestEpisodes": "Nytillkomna avsnitt", 22 | "ContinueWatching": "Forts\u00e4tt titta", 23 | "AllMovies": "Alla filmer", 24 | "LatestMovies": "Nytillkomna filmer", 25 | "Channels": "Kanaler", 26 | "LatestFromValue": "Nytillkommet fr\u00e5n {0}", 27 | "All": "Alla", 28 | "Latest": "Nytillkommet", 29 | "Artists": "Artister", 30 | "Albums": "Album", 31 | "RecentlyPlayed": "Nyligen spelade", 32 | "FrequentlyPlayed": "Ofta spelade", 33 | "Library": "Bibliotek", 34 | "Guide": "Guide", 35 | "Overview": "Synopsis", 36 | "People": "Personer", 37 | "Specials": "Specialavsnitt", 38 | "SpecialFeatures": "Extramaterial", 39 | "Recordings": "Inspelningar", 40 | "Scheduled": "Schemalagd", 41 | "LatestMusic": "Nytillkommen musik", 42 | "LatestRecordings": "Senaste inspelningarna", 43 | "NowPlaying": "Nu spelas", 44 | "Programs": "Programs", 45 | "RecommendationBecauseYouLike": "Eftersom du gillar {0}", 46 | "RecommendationBecauseYouWatched": "Eftersom du tittade p\u00e5 {0}", 47 | "RecommendationDirectedBy": "Regisserad av {0}", 48 | "RecommendationStarring": "I rollerna: {0}", 49 | "HeaderMoreLikeThis": "More Like This", 50 | "MoreFrom": "More from {0}", 51 | "AlbumArtists": "Albumartister", 52 | "LiveTV": "Live-TV", 53 | "TrackCount": "{0} sp\u00e5r", 54 | "Search": "S\u00f6k", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Spela upp alla", 57 | "Suggestions": "Suggestions", 58 | "Schedule": "Schedule", 59 | "Shows": "Shows", 60 | "HeaderUpcomingPrograms": "Upcoming Programs", 61 | "HeaderUpcomingMovies": "Upcoming Movies", 62 | "HeaderUpcomingSports": "Upcoming Sports", 63 | "HeaderUpcomingForKids": "Upcoming for Kids", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "For Kids", 66 | "HeaderOnNow": "On Now", 67 | "OptionSunday": "S\u00f6ndag", 68 | "OptionMonday": "M\u00e5ndag", 69 | "OptionTuesday": "Tisdag", 70 | "OptionWednesday": "Onsdag", 71 | "OptionThursday": "Torsdag", 72 | "OptionFriday": "Fredag", 73 | "OptionSaturday": "L\u00f6rdag", 74 | "OptionEveryday": "Varje dag", 75 | "OptionWeekend": "Helger", 76 | "OptionWeekday": "Veckodagar", 77 | "InstantMix": "Direktmix", 78 | "SelectServer": "V\u00e4lj server", 79 | "SignOut": "Logga ut", 80 | "TopRated": "H\u00f6gt rankade", 81 | "BornValue": "F\u00f6dd: {0}", 82 | "BirthPlaceValue": "F\u00f6delseort: {0}", 83 | "FavoriteAlbums": "Favoritalbum", 84 | "FavoriteSongs": "Favoritl\u00e5tar", 85 | "FavoriteArtists": "Favoritartister", 86 | "FavoriteShows": "Favorite Shows", 87 | "FavoriteEpisodes": "Favoritavsnitt", 88 | "FavoriteMovies": "Favorite Movies", 89 | "CastAndCrew": "Cast & Crew", 90 | "Unwatched": "Unwatched", 91 | "Movies": "Movies", 92 | "Collections": "Collections", 93 | "Years": "Years", 94 | "Favorites": "Favorites", 95 | "More": "More", 96 | "Playlists": "Playlists", 97 | "EnableEpisodeSpoilerProtection": "Enable anti-spoiler features", 98 | "EnableEpisodeSpoilerProtectionHelp": "Hide details for episodes beyond the first unwatched", 99 | "DimUnselectedPosters": "Dim unselected posters", 100 | "Songs": "Songs", 101 | "Record": "Record", 102 | "Settings": "Settings", 103 | "Mute": "Mute", 104 | "Unmute": "Unmute", 105 | "Subtitles": "Subtitles", 106 | "Audio": "Audio", 107 | "Rewind": "Rewind", 108 | "Fullscreen": "Full screen", 109 | "ExitFullscreen": "Exit full screen", 110 | "PlayOnAnotherDevice": "Play on another device", 111 | "FastForward": "Fast-forward", 112 | "Items": "Items", 113 | "PictureInPicture": "Picture in picture", 114 | "HeaderActiveRecordings": "Active Recordings", 115 | "Yesterday": "Yesterday", 116 | "HeaderUpcomingEpisodes": "Upcoming Episodes" 117 | } -------------------------------------------------------------------------------- /nowplaying/videoosd.css: -------------------------------------------------------------------------------- 1 | .osdHeader { 2 | padding-bottom: 3vh; 3 | background-color: rgba(0, 0, 0, .3); 4 | background: linear-gradient(rgba(0, 0, 0, .6), rgba(0, 0, 0, 0)); 5 | transition: opacity 300ms ease-out; 6 | -webkit-backdrop-filter: none !important; 7 | backdrop-filter: none !important; 8 | color: #eee; 9 | } 10 | 11 | .osdHeader-hidden { 12 | opacity: 0; 13 | } 14 | 15 | .osdHeader .headerButton { 16 | display: none; 17 | } 18 | 19 | .chapterThumbContainer { 20 | -moz-box-shadow: 0 0 1.9vh #000; 21 | -webkit-box-shadow: 0 0 1.9vh #000; 22 | box-shadow: 0 0 1.9vh #000; 23 | flex-grow: 1; 24 | position: relative; 25 | } 26 | 27 | .chapterThumb { 28 | background-position: center center; 29 | background-size: contain; 30 | background-repeat: no-repeat; 31 | border: 0; 32 | height: 20vh; 33 | min-width: 20vh; 34 | } 35 | 36 | @media all and (orientation: portrait) { 37 | 38 | .chapterThumb { 39 | height: 30vw; 40 | min-width: 30vw; 41 | } 42 | } 43 | 44 | @media all and (max-height: 50em) and (orientation: landscape) { 45 | 46 | .chapterThumb { 47 | height: 30vh; 48 | min-width: 30vh; 49 | } 50 | } 51 | 52 | .chapterThumbTextContainer { 53 | position: absolute; 54 | bottom: 0; 55 | left: 0; 56 | right: 0; 57 | background: rgba(0, 0, 0, 0.7); 58 | padding: .25em .5em; 59 | user-select: none; 60 | } 61 | 62 | .chapterThumbText { 63 | padding: .25em 0; 64 | margin: 0; 65 | opacity: 1; 66 | } 67 | 68 | .chapterThumbText-dim { 69 | opacity: .6; 70 | } 71 | 72 | .videoOsdBottom { 73 | position: fixed; 74 | left: 0; 75 | bottom: 0; 76 | right: 0; 77 | background-color: rgba(0, 0, 0, .7); 78 | padding: 1%; 79 | display: flex; 80 | flex-direction: row; 81 | will-change: transform; 82 | transition: opacity 300ms ease-out; 83 | background: linear-gradient(rgba(0, 0, 0, .5), rgba(0, 0, 0, .8)); 84 | color: #fff; 85 | } 86 | 87 | .videoOsdBottom-hidden { 88 | opacity: 0; 89 | } 90 | 91 | .osdControls { 92 | flex-grow: 1; 93 | } 94 | 95 | .videoOsdBottom .buttons { 96 | padding: .25em 0 0; 97 | display: flex; 98 | flex-wrap: wrap; 99 | align-items: center; 100 | } 101 | 102 | .osdVolumeSliderContainer { 103 | width: 6.5em; 104 | flex-grow: 1; 105 | } 106 | 107 | .volumeButtons { 108 | margin: 0 .5em 0 auto; 109 | display: flex; 110 | align-items: center; 111 | } 112 | 113 | .osdTimeText { 114 | margin-left: 1em; 115 | user-select: none; 116 | } 117 | 118 | .mouseIdle .videoOsdBottom .volumeButtons { 119 | display: none; 120 | } 121 | 122 | .osdPoster { 123 | width: 10%; 124 | position: relative; 125 | margin-right: .5em; 126 | } 127 | 128 | .osdPoster img { 129 | position: absolute; 130 | bottom: 0; 131 | left: 0; 132 | right: 0; 133 | height: auto; 134 | width: 100%; 135 | -moz-box-shadow: 0 0 1.9vh #000; 136 | -webkit-box-shadow: 0 0 1.9vh #000; 137 | box-shadow: 0 0 1.9vh #000; 138 | border: solid 1px #222; 139 | user-drag: none; 140 | user-select: none; 141 | -moz-user-select: none; 142 | -webkit-user-drag: none; 143 | -webkit-user-select: none; 144 | -ms-user-select: none; 145 | } 146 | 147 | .osdTitle { 148 | margin: 0; 149 | margin-right: 1em; 150 | } 151 | 152 | .osdTitleSmall { 153 | margin: 0; 154 | margin-right: 1em; 155 | } 156 | 157 | .osdMediaInfo { 158 | color: #eee; 159 | display: flex; 160 | align-items: center; 161 | } 162 | 163 | .osdSecondaryMediaInfo { 164 | padding-left: .6em; 165 | } 166 | 167 | .osdTextContainer { 168 | display: flex; 169 | align-items: center; 170 | user-select: none; 171 | margin-bottom: .7em; 172 | padding-left: .5em; 173 | } 174 | 175 | .osdMainTextContainer { 176 | align-items: baseline; 177 | } 178 | 179 | @media all and (max-width:30em) { 180 | .osdPoster, .btnRewind, .btnFastForward, .osdMediaInfo { 181 | display: none !important; 182 | } 183 | } 184 | 185 | @media all and (max-width:33.75em) { 186 | .videoOsdBottom .paper-icon-button-light { 187 | margin: 0; 188 | } 189 | } 190 | 191 | @media all and (max-width:37.5em) { 192 | .videoOsdBottom .volumeButtons { 193 | display: none !important; 194 | } 195 | } 196 | 197 | @media all and (max-width: 75em) { 198 | .videoOsdBottom .endsAtText { 199 | display: none !important; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /strings/hr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Uredi snimanje", 5 | "Episodes": "Epizode", 6 | "OtherVideos": "Ostali video", 7 | "ShowScenesOnDetailScreensFor": "Prika\u017ei scene na detaljnom ekranu za", 8 | "Play": "Pokreni", 9 | "Resume": "Resume", 10 | "Books": "Books", 11 | "HeaderAudioBooks": "Audio Books", 12 | "Queue": "Red", 13 | "Shuffle": "Mije\u0161aj", 14 | "InsstantMix": "Trenutno mije\u0161anje", 15 | "ButtonCancel": "Odustani", 16 | "ButtonCancelSeries": "Cancel Series", 17 | "AllShows": "All Shows", 18 | "Genres": "\u017danrovi", 19 | "Extras": "Dodaci", 20 | "NextUp": "Sljede\u0107e je", 21 | "LatestEpisodes": "Zadnje epizode", 22 | "ContinueWatching": "Nastavi gledati", 23 | "AllMovies": "Svi filmovi", 24 | "LatestMovies": "Zadnji Filmovi", 25 | "Channels": "Kanali", 26 | "LatestFromValue": "Zadnje od {0}", 27 | "All": "Sve", 28 | "Latest": "Zadnje", 29 | "Artists": "Izvo\u0111a\u010di", 30 | "Albums": "Albumi", 31 | "RecentlyPlayed": "Zadnje izvo\u0111eno", 32 | "FrequentlyPlayed": "\u010cesto izvo\u0111eno", 33 | "Library": "Biblioteka", 34 | "Guide": "Vodi\u010d", 35 | "Overview": "Pregled", 36 | "People": "Ljudi", 37 | "Specials": "Specijali", 38 | "SpecialFeatures": "Specijalne zna\u010dajke", 39 | "Recordings": "Snimke", 40 | "Scheduled": "Zakazano", 41 | "LatestMusic": "Zadnja glazba", 42 | "LatestRecordings": "Zadnje snimke", 43 | "NowPlaying": "Sad se izvodi", 44 | "Programs": "Programs", 45 | "RecommendationBecauseYouLike": "Zato \u0161to volite {0}", 46 | "RecommendationBecauseYouWatched": "Zato \u0161to ste gledali {0}", 47 | "RecommendationDirectedBy": "Re\u017eisirao {0}", 48 | "RecommendationStarring": "Glumi {0}", 49 | "HeaderMoreLikeThis": "Vi\u0161e ovakvih", 50 | "MoreFrom": "Vi\u0161e od {0}", 51 | "AlbumArtists": "Albumi izvo\u0111a\u010da", 52 | "LiveTV": "TV u\u017eivo", 53 | "TrackCount": "{0} pjesme", 54 | "Search": "Tra\u017ei", 55 | "Trailer": "Kratki video", 56 | "PlayAll": "Pokreni sve", 57 | "Suggestions": "Suggestions", 58 | "Schedule": "Schedule", 59 | "Shows": "Shows", 60 | "HeaderUpcomingPrograms": "Upcoming Programs", 61 | "HeaderUpcomingMovies": "Upcoming Movies", 62 | "HeaderUpcomingSports": "Upcoming Sports", 63 | "HeaderUpcomingForKids": "Upcoming for Kids", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "For Kids", 66 | "HeaderOnNow": "On Now", 67 | "OptionSunday": "Nedjelja", 68 | "OptionMonday": "Ponedjeljak", 69 | "OptionTuesday": "Utorak", 70 | "OptionWednesday": "Srijeda", 71 | "OptionThursday": "\u010cetvrtak", 72 | "OptionFriday": "Petak", 73 | "OptionSaturday": "Subota", 74 | "OptionEveryday": "Svaki dan", 75 | "OptionWeekend": "Vikendi", 76 | "OptionWeekday": "Radni dani", 77 | "InstantMix": "Trenutno mije\u0161anje", 78 | "SelectServer": "Odaberi Server", 79 | "SignOut": "Odjava", 80 | "TopRated": "Najbolje ocijenjeno", 81 | "BornValue": "Ro\u0111en: {0}", 82 | "BirthPlaceValue": "Mjesto ro\u0111enja: {0}", 83 | "FavoriteAlbums": "Omiljeni albumi", 84 | "FavoriteSongs": "Omiljene pjesme", 85 | "FavoriteArtists": "Omiljeni izvo\u0111a\u010di", 86 | "FavoriteShows": "Favorite Shows", 87 | "FavoriteEpisodes": "Omiljene epizode", 88 | "FavoriteMovies": "Omiljeni filmovi", 89 | "CastAndCrew": "Glumci i ekipa", 90 | "Unwatched": "Nepogledano", 91 | "Movies": "Filmovi", 92 | "Collections": "Kolekcije", 93 | "Years": "Godine", 94 | "Favorites": "Omiljeni", 95 | "More": "Vi\u0161e", 96 | "Playlists": "Popisi", 97 | "EnableEpisodeSpoilerProtection": "Omogu\u0107i anti-spojler zna\u010dajke", 98 | "EnableEpisodeSpoilerProtectionHelp": "Sakrij detalje za epizode poslije prve nepogledane", 99 | "DimUnselectedPosters": "Zamagli neodabrane postere", 100 | "Songs": "Pjesme", 101 | "Record": "Snimi", 102 | "Settings": "Settings", 103 | "Mute": "Mute", 104 | "Unmute": "Unmute", 105 | "Subtitles": "Subtitles", 106 | "Audio": "Audio", 107 | "Rewind": "Rewind", 108 | "Fullscreen": "Full screen", 109 | "ExitFullscreen": "Exit full screen", 110 | "PlayOnAnotherDevice": "Play on another device", 111 | "FastForward": "Fast-forward", 112 | "Items": "Stavke", 113 | "PictureInPicture": "Picture in picture", 114 | "HeaderActiveRecordings": "Active Recordings", 115 | "Yesterday": "Yesterday", 116 | "HeaderUpcomingEpisodes": "Upcoming Episodes" 117 | } -------------------------------------------------------------------------------- /strings/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Opname Bewerken", 5 | "Episodes": "Afleveringen", 6 | "OtherVideos": "Andere video's", 7 | "ShowScenesOnDetailScreensFor": "Laat een paneel met detail informatie op schermen zien voor", 8 | "Play": "Afspelen", 9 | "Resume": "Hervatten", 10 | "Books": "Boeken", 11 | "HeaderAudioBooks": "Luisterboeken", 12 | "Queue": "Wachtrij", 13 | "Shuffle": "Willekeurig", 14 | "InsstantMix": "Instant Mix", 15 | "ButtonCancel": "Annuleren", 16 | "ButtonCancelSeries": "Annuleren Series", 17 | "AllShows": "Alle shows", 18 | "Genres": "Genres", 19 | "Extras": "Extra's", 20 | "NextUp": "Eerstvolgende", 21 | "LatestEpisodes": "Nieuwste Afleveringen", 22 | "ContinueWatching": "Kijken hervatten", 23 | "AllMovies": "Alle Films", 24 | "LatestMovies": "Nieuwste Films", 25 | "Channels": "Kanalen", 26 | "LatestFromValue": "Nieuwste van {0}", 27 | "All": "Alles", 28 | "Latest": "Nieuwste", 29 | "Artists": "Artiesten", 30 | "Albums": "Albums", 31 | "RecentlyPlayed": "Onlangs Afgespeeld", 32 | "FrequentlyPlayed": "Vaak Afgespeeld", 33 | "Library": "Bibliotheek", 34 | "Guide": "Gids", 35 | "Overview": "Overzicht", 36 | "People": "Personen", 37 | "Specials": "Specials", 38 | "SpecialFeatures": "Extra's", 39 | "Recordings": "Opnames", 40 | "Scheduled": "Gepland", 41 | "LatestMusic": "Nieuwste Muziek", 42 | "LatestRecordings": "Nieuwste Opnames", 43 | "NowPlaying": "Wordt nu afgespeeld", 44 | "Programs": "Programma's", 45 | "RecommendationBecauseYouLike": "Omdat u {0} leuk vond", 46 | "RecommendationBecauseYouWatched": "Omdat u keek naar {0}", 47 | "RecommendationDirectedBy": "Geregisseerd door {0}", 48 | "RecommendationStarring": "In de hoofdrol {0}", 49 | "HeaderMoreLikeThis": "Meer als deze", 50 | "MoreFrom": "Meer van {0}", 51 | "AlbumArtists": "Album Artiesten", 52 | "LiveTV": "Live TV", 53 | "TrackCount": "{0} nummers", 54 | "Search": "Zoeken", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Alles Afspelen", 57 | "Suggestions": "Suggesties", 58 | "Schedule": "Schema", 59 | "Shows": "Shows", 60 | "HeaderUpcomingPrograms": "Programma's Binnenkort", 61 | "HeaderUpcomingMovies": "Films Binnenkort", 62 | "HeaderUpcomingSports": "Sport Binnenkort", 63 | "HeaderUpcomingForKids": "Binnenkort voor Kinderen", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "Voor Kinderen", 66 | "HeaderOnNow": "Aan het spelen", 67 | "OptionSunday": "Zondag", 68 | "OptionMonday": "Maandag", 69 | "OptionTuesday": "Dinsdag", 70 | "OptionWednesday": "Woensdag", 71 | "OptionThursday": "Donderdag", 72 | "OptionFriday": "Vrijdag", 73 | "OptionSaturday": "Zaterdag", 74 | "OptionEveryday": "Elke Dag", 75 | "OptionWeekend": "Weekenden", 76 | "OptionWeekday": "Weekdagen", 77 | "InstantMix": "Instant Mix", 78 | "SelectServer": "Server Selecteren", 79 | "SignOut": "Afmelden", 80 | "TopRated": "Hoogst Gewaardeerd", 81 | "BornValue": "Geboren: {0}", 82 | "BirthPlaceValue": "Geboorteplaats: {0}", 83 | "FavoriteAlbums": "Favoriete Albums", 84 | "FavoriteSongs": "Favoriete Songs", 85 | "FavoriteArtists": "Favoriete Artiesten", 86 | "FavoriteShows": "Favoriete Shows", 87 | "FavoriteEpisodes": "Favoriete Afleveringen", 88 | "FavoriteMovies": "Favoriete Films", 89 | "CastAndCrew": "Cast & Crew", 90 | "Unwatched": "Ongezien", 91 | "Movies": "Films", 92 | "Collections": "Verzamelingen", 93 | "Years": "Jaren", 94 | "Favorites": "Favorieten", 95 | "More": "Meer", 96 | "Playlists": "Afspeellijsten", 97 | "EnableEpisodeSpoilerProtection": "Anti-spoiler functies inschakelen", 98 | "EnableEpisodeSpoilerProtectionHelp": "Verberg details van niet bekeken hoofdstukken", 99 | "DimUnselectedPosters": "Niet geselecteerde posters donkerder maken", 100 | "Songs": "Liedjes", 101 | "Record": "Opnemen", 102 | "Settings": "Instellingen", 103 | "Mute": "Dempen", 104 | "Unmute": "Dempen uitzetten", 105 | "Subtitles": "Ondertitels", 106 | "Audio": "Audio", 107 | "Rewind": "Terugspoelen", 108 | "Fullscreen": "Volledig scherm", 109 | "ExitFullscreen": "Volledig scherm verlaten", 110 | "PlayOnAnotherDevice": "Op ander apparaat afspelen", 111 | "FastForward": "Vooruitspoelen", 112 | "Items": "Items", 113 | "PictureInPicture": "Beeld in beeld", 114 | "HeaderActiveRecordings": "Actieve Opnames", 115 | "Yesterday": "Gisteren", 116 | "HeaderUpcomingEpisodes": "Komende afleveringen" 117 | } -------------------------------------------------------------------------------- /home/home.js: -------------------------------------------------------------------------------- 1 | define(['loading', 'backdrop', 'mainTabsManager', 'connectionManager', 'scroller', 'globalize', 'require', 'emby-itemscontainer', 'emby-tabs', 'emby-button', 'emby-scroller'], function (loading, backdrop, mainTabsManager, connectionManager, scroller, globalize, require) { 2 | 'use strict'; 3 | 4 | function getTabs() { 5 | return [ 6 | { 7 | name: globalize.translate('Home') 8 | }]; 9 | } 10 | 11 | return function (view, params) { 12 | 13 | var self = this; 14 | 15 | var tabControllers = []; 16 | var currentTabController; 17 | 18 | function getTabController(index, callback) { 19 | 20 | if (index == null) { 21 | throw new Error('index cannot be null'); 22 | } 23 | 24 | var depends = []; 25 | 26 | switch (index) { 27 | 28 | case 0: 29 | depends.push('./hometab'); 30 | break; 31 | case 1: 32 | depends.push('./hometab'); 33 | break; 34 | default: 35 | break; 36 | } 37 | 38 | require(depends, function (controllerFactory) { 39 | 40 | var controller = tabControllers[index]; 41 | if (!controller) { 42 | 43 | var tabContent = view.querySelector('.tabContent[data-index=\'' + index + '\']'); 44 | controller = new controllerFactory(tabContent, params, view); 45 | tabControllers[index] = controller; 46 | } 47 | 48 | callback(controller); 49 | }); 50 | } 51 | 52 | 53 | self.scroller = view.querySelector('.scrollFrameY'); 54 | 55 | var currentTabIndex = parseInt(params.tab || '0'); 56 | var initialTabIndex = currentTabIndex; 57 | var isViewRestored; 58 | 59 | function preLoadTab(index) { 60 | 61 | getTabController(index, function (controller) { 62 | if (controller.onBeforeShow) { 63 | 64 | var refresh = isViewRestored !== true || !controller.refreshed; 65 | 66 | controller.onBeforeShow({ 67 | refresh: refresh 68 | }); 69 | 70 | controller.refreshed = true; 71 | } 72 | }); 73 | } 74 | 75 | function loadTab(index) { 76 | 77 | getTabController(index, function (controller) { 78 | 79 | controller.onShow({ 80 | autoFocus: initialTabIndex != null 81 | }); 82 | initialTabIndex = null; 83 | currentTabController = controller; 84 | }); 85 | } 86 | 87 | function getTabContainers() { 88 | return view.querySelectorAll('.tabContent'); 89 | } 90 | 91 | function onBeforeTabChange(e) { 92 | 93 | preLoadTab(parseInt(e.detail.selectedTabIndex)); 94 | } 95 | 96 | function onTabChange(e) { 97 | var newIndex = parseInt(e.detail.selectedTabIndex); 98 | var previousTabController = tabControllers[newIndex]; 99 | if (previousTabController && previousTabController.onHide) { 100 | previousTabController.onHide(); 101 | } 102 | 103 | loadTab(newIndex); 104 | } 105 | 106 | view.addEventListener('viewbeforehide', function (e) { 107 | 108 | if (currentTabController && currentTabController.onHide) { 109 | currentTabController.onHide(); 110 | } 111 | }); 112 | 113 | view.addEventListener('viewbeforeshow', function (e) { 114 | 115 | Emby.Page.setTitle(null); 116 | isViewRestored = e.detail.isRestored; 117 | 118 | mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange); 119 | }); 120 | 121 | view.addEventListener('viewshow', function (e) { 122 | 123 | isViewRestored = e.detail.isRestored; 124 | 125 | backdrop.clear(); 126 | 127 | if (!isViewRestored) { 128 | mainTabsManager.selectedTabIndex(initialTabIndex); 129 | } 130 | }); 131 | 132 | view.addEventListener('viewdestroy', function (e) { 133 | 134 | tabControllers.forEach(function (t) { 135 | if (t.destroy) { 136 | t.destroy(); 137 | } 138 | }); 139 | 140 | self.scroller = null; 141 | }); 142 | }; 143 | 144 | }); -------------------------------------------------------------------------------- /strings/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Modifica Registrazioni", 5 | "Episodes": "Episodi", 6 | "OtherVideos": "Altri Video", 7 | "ShowScenesOnDetailScreensFor": "Mostra scene nella schermata dettagli di", 8 | "Play": "Riproduci", 9 | "Resume": "Riprendi", 10 | "Books": "Libri", 11 | "HeaderAudioBooks": "Audiolibri", 12 | "Queue": "In coda", 13 | "Shuffle": "Riproduzione casuale", 14 | "InsstantMix": "Mix Istantaneo", 15 | "ButtonCancel": "Annulla", 16 | "ButtonCancelSeries": "Cancella Serie", 17 | "AllShows": "Tutti gli spettacoli", 18 | "Genres": "Generi", 19 | "Extras": "Extra", 20 | "NextUp": "Prossimo", 21 | "LatestEpisodes": "Ultimi Episodi Aggiunti", 22 | "ContinueWatching": "Continua a guardare", 23 | "AllMovies": "Tutti i film", 24 | "LatestMovies": "Ultimi Film Aggiunti", 25 | "Channels": "Canali", 26 | "LatestFromValue": "Pi\u00f9 recenti da {0}", 27 | "All": "Tutti", 28 | "Latest": "Pi\u00f9 recenti", 29 | "Artists": "Artisti", 30 | "Albums": "Album", 31 | "RecentlyPlayed": "Visti di recente", 32 | "FrequentlyPlayed": "Visti di frequente", 33 | "Library": "Libreria", 34 | "Guide": "Guida", 35 | "Overview": "Trama", 36 | "People": "Attori", 37 | "Specials": "Speciali", 38 | "SpecialFeatures": "Contenuti speciali", 39 | "Recordings": "Registrazioni", 40 | "Scheduled": "Pianificati", 41 | "LatestMusic": "Musica Recente", 42 | "LatestRecordings": "Ultime Registrazioni", 43 | "NowPlaying": "In Riproduzione", 44 | "Programs": "Programmi", 45 | "RecommendationBecauseYouLike": "Siccome ti piace {0}", 46 | "RecommendationBecauseYouWatched": "Siccome hai visto {0}", 47 | "RecommendationDirectedBy": "Diretto da {0}", 48 | "RecommendationStarring": "Con {0}", 49 | "HeaderMoreLikeThis": "Altri come questo", 50 | "MoreFrom": "Altro di {0}", 51 | "AlbumArtists": "Artisti Album", 52 | "LiveTV": "TV in diretta", 53 | "TrackCount": "{0} tracce", 54 | "Search": "Cerca", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Riproduci tutto", 57 | "Suggestions": "Suggerimenti", 58 | "Schedule": "Programmazione", 59 | "Shows": "Spettacoli", 60 | "HeaderUpcomingPrograms": "Programmi in arrivo", 61 | "HeaderUpcomingMovies": "Film in arrivo", 62 | "HeaderUpcomingSports": "Sport in arrivo", 63 | "HeaderUpcomingForKids": "In arrivo per i bambini", 64 | "HeaderUpcomingNews": "Notizie in Arrivo", 65 | "HeaderForKids": "Per Bambini", 66 | "HeaderOnNow": "In onda ora", 67 | "OptionSunday": "Domenica", 68 | "OptionMonday": "Luned\u00ec", 69 | "OptionTuesday": "Marted\u00ec", 70 | "OptionWednesday": "Mercoled\u00ec", 71 | "OptionThursday": "Gioved\u00ec", 72 | "OptionFriday": "Venerd\u00ec", 73 | "OptionSaturday": "Sabato", 74 | "OptionEveryday": "Tutti i giorni", 75 | "OptionWeekend": "Fine settimana", 76 | "OptionWeekday": "Giorni feriali", 77 | "InstantMix": "Mix Istantaneo", 78 | "SelectServer": "Scegli Server", 79 | "SignOut": "Esci", 80 | "TopRated": "Popolari", 81 | "BornValue": "Data di nascita: {0}", 82 | "BirthPlaceValue": "Luogo di nascita: {0}", 83 | "FavoriteAlbums": "Album Preferiti", 84 | "FavoriteSongs": "Brani Preferiti", 85 | "FavoriteArtists": "Artisti Preferiti", 86 | "FavoriteShows": "Spettacoli Preferiti", 87 | "FavoriteEpisodes": "Episodi Preferiti", 88 | "FavoriteMovies": "Film Preferiti", 89 | "CastAndCrew": "Cast & Crew", 90 | "Unwatched": "Non visto", 91 | "Movies": "Film", 92 | "Collections": "Collezioni", 93 | "Years": "Anni", 94 | "Favorites": "Preferiti", 95 | "More": "Dettagli", 96 | "Playlists": "Playlist", 97 | "EnableEpisodeSpoilerProtection": "Abilita funzionalit\u00e0 anti-spoiler", 98 | "EnableEpisodeSpoilerProtectionHelp": "Nascondi i dettagli degli episodi dopo il primo non visto", 99 | "DimUnselectedPosters": "Attenua i poster non selezionati", 100 | "Songs": "Brani", 101 | "Record": "Registra", 102 | "Settings": "Impostazioni", 103 | "Mute": "Muto", 104 | "Unmute": "Togli muto", 105 | "Subtitles": "Sottotitoli", 106 | "Audio": "Audio", 107 | "Rewind": "Riavvolgi", 108 | "Fullscreen": "Schermo Intero", 109 | "ExitFullscreen": "Esci da Schermo Intero", 110 | "PlayOnAnotherDevice": "Riproduci su un altro dispositivo", 111 | "FastForward": "Avanti veloce", 112 | "Items": "Elementi", 113 | "PictureInPicture": "Picture in picture", 114 | "HeaderActiveRecordings": "Registrazioni attive", 115 | "Yesterday": "Ieri", 116 | "HeaderUpcomingEpisodes": "Episodi in arrivo" 117 | } -------------------------------------------------------------------------------- /strings/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Bearbeite Aufnahme", 5 | "Episodes": "Episoden", 6 | "OtherVideos": "Andere Videos", 7 | "ShowScenesOnDetailScreensFor": "Zeige Kapitel auf den Detailseiten von", 8 | "Play": "Abspielen", 9 | "Resume": "Fortsetzen", 10 | "Books": "B\u00fccher", 11 | "HeaderAudioBooks": "H\u00f6rb\u00fccher", 12 | "Queue": "Warteschlange", 13 | "Shuffle": "Zufallswiedergabe", 14 | "InsstantMix": "Schnellmix", 15 | "ButtonCancel": "Abbrechen", 16 | "ButtonCancelSeries": "Serienaufnahme beenden", 17 | "AllShows": "Alle Serien", 18 | "Genres": "Genres", 19 | "Extras": "Extras", 20 | "NextUp": "Als N\u00e4chstes", 21 | "LatestEpisodes": "Neueste Episoden", 22 | "ContinueWatching": "Weiter anschauen", 23 | "AllMovies": "Alle Filme", 24 | "LatestMovies": "Neueste Filme", 25 | "Channels": "Kan\u00e4le", 26 | "LatestFromValue": "Neuestes von {0}", 27 | "All": "Alle", 28 | "Latest": "Neueste", 29 | "Artists": "K\u00fcnstler", 30 | "Albums": "Alben", 31 | "RecentlyPlayed": "Zuletzt gespielt", 32 | "FrequentlyPlayed": "Oft gespielt", 33 | "Library": "Bibliothek", 34 | "Guide": "Programm", 35 | "Overview": "\u00dcbersicht", 36 | "People": "Personen", 37 | "Specials": "Specials", 38 | "SpecialFeatures": "Special Features", 39 | "Recordings": "Aufnahmen", 40 | "Scheduled": "Geplant", 41 | "LatestMusic": "Neueste Musik", 42 | "LatestRecordings": "Neueste Aufnahmen", 43 | "NowPlaying": "Aktuelle Wiedergabe", 44 | "Programs": "Programme", 45 | "RecommendationBecauseYouLike": "Weil du {0} magst", 46 | "RecommendationBecauseYouWatched": "Weil du {0} gesehen hast", 47 | "RecommendationDirectedBy": "Unter der Regie von {0}", 48 | "RecommendationStarring": "In der Hauptrolle {0}", 49 | "HeaderMoreLikeThis": "Mehr wie dieses", 50 | "MoreFrom": "Mehr von {0}", 51 | "AlbumArtists": "Album-Interpreten", 52 | "LiveTV": "Live TV", 53 | "TrackCount": "{0} Tracks", 54 | "Search": "Suche", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Alle abspielen", 57 | "Suggestions": "Empfehlungen", 58 | "Schedule": "Zeitplan", 59 | "Shows": "Serien", 60 | "HeaderUpcomingPrograms": "Bevorstehende Sendungen", 61 | "HeaderUpcomingMovies": "Bevorstehende Filme", 62 | "HeaderUpcomingSports": "Bevorstehende Sportveranstaltungen", 63 | "HeaderUpcomingForKids": "Bevorstehende Kindersendungen", 64 | "HeaderUpcomingNews": "Bevorstehende Nachrichtensendung", 65 | "HeaderForKids": "F\u00fcr Kinder", 66 | "HeaderOnNow": "Gerade l\u00e4uft", 67 | "OptionSunday": "Sonntag", 68 | "OptionMonday": "Montag", 69 | "OptionTuesday": "Dienstag", 70 | "OptionWednesday": "Mittwoch", 71 | "OptionThursday": "Donnerstag", 72 | "OptionFriday": "Freitag", 73 | "OptionSaturday": "Samstag", 74 | "OptionEveryday": "T\u00e4glich", 75 | "OptionWeekend": "Wochenenden", 76 | "OptionWeekday": "Wochentage", 77 | "InstantMix": "Schnellmix", 78 | "SelectServer": "W\u00e4hle Server", 79 | "SignOut": "Abmelden", 80 | "TopRated": "Am besten bewertet", 81 | "BornValue": "Geboren: {0}", 82 | "BirthPlaceValue": "Geburtsort: {0}", 83 | "FavoriteAlbums": "Lieblingsalben", 84 | "FavoriteSongs": "Lieblingssongs", 85 | "FavoriteArtists": "Lieblingsk\u00fcnstler", 86 | "FavoriteShows": "Lieblingsserien", 87 | "FavoriteEpisodes": "Lieblingsepisoden", 88 | "FavoriteMovies": "Lieblingsfilme", 89 | "CastAndCrew": "Cast & Crew", 90 | "Unwatched": "Ungesehen", 91 | "Movies": "Filme", 92 | "Collections": "Sammlungen", 93 | "Years": "Jahre", 94 | "Favorites": "Favoriten", 95 | "More": "Mehr", 96 | "Playlists": "Wiedergabelisten", 97 | "EnableEpisodeSpoilerProtection": "Aktiviere Anti-Spoiler Features", 98 | "EnableEpisodeSpoilerProtectionHelp": "Verstecke Details f\u00fcr Episoden nach der ersten Ungesehenen", 99 | "DimUnselectedPosters": "Dimme nicht ausgew\u00e4lte Kacheln", 100 | "Songs": "Titel", 101 | "Record": "Aufnahme", 102 | "Settings": "Einstellungen", 103 | "Mute": "Ton aus", 104 | "Unmute": "Ton ein", 105 | "Subtitles": "Untertitel", 106 | "Audio": "Audio", 107 | "Rewind": "Zur\u00fcckspulen", 108 | "Fullscreen": "Vollbild", 109 | "ExitFullscreen": "Vollbild verlassen", 110 | "PlayOnAnotherDevice": "Auf einem anderen Ger\u00e4t wiedergeben", 111 | "FastForward": "Vorw\u00e4rts spulen", 112 | "Items": "Eintr\u00e4ge", 113 | "PictureInPicture": "Bild in Bild", 114 | "HeaderActiveRecordings": "Aktive Aufnahmen", 115 | "Yesterday": "Gestern", 116 | "HeaderUpcomingEpisodes": "Bevorstehende Episoden" 117 | } -------------------------------------------------------------------------------- /nowplaying/playlist.js: -------------------------------------------------------------------------------- 1 | define(['playbackManager', 'scroller', 'loading', 'imageLoader', 'backdrop', 'listView', 'focusManager', 'itemShortcuts', 'globalize', 'emby-itemscontainer'], function (playbackManager, scroller, loading, imageLoader, backdrop, listview, focusManager, itemShortcuts, globalize) { 2 | 'use strict'; 3 | 4 | function createVerticalScroller(view, pageInstance) { 5 | 6 | var scrollFrame = view.querySelector('.scrollFrame'); 7 | 8 | var options = { 9 | horizontal: 0, 10 | itemNav: 0, 11 | mouseDragging: 1, 12 | touchDragging: 1, 13 | slidee: view.querySelector('.scrollSlider'), 14 | itemSelector: '.card', 15 | smart: true, 16 | easing: 'easeOutQuart', 17 | releaseSwing: true, 18 | scrollBar: view.querySelector('.scrollbar'), 19 | scrollBy: 200, 20 | speed: 300, 21 | dragHandle: 1, 22 | dynamicHandle: 1, 23 | clickBar: 1 24 | }; 25 | 26 | pageInstance.verticalScroller = new scroller(scrollFrame, options); 27 | pageInstance.verticalScroller.init(); 28 | initFocusHandler(view, pageInstance.verticalScroller); 29 | } 30 | 31 | function initFocusHandler(view, verticalScroller) { 32 | 33 | var scrollSlider = view.querySelector('.scrollSlider'); 34 | scrollSlider.addEventListener('focus', function (e) { 35 | 36 | var focused = focusManager.focusableParent(e.target); 37 | 38 | if (focused) { 39 | verticalScroller.toCenter(focused); 40 | } 41 | 42 | }, true); 43 | } 44 | 45 | return function (view, params) { 46 | 47 | var self = this; 48 | 49 | function setCurrentItem(item) { 50 | 51 | if (item) { 52 | backdrop.setBackdrops([item]); 53 | 54 | } else { 55 | backdrop.setBackdrops([]); 56 | } 57 | updateCurrentPlaylistItem(); 58 | } 59 | 60 | function onPlaybackStart(e, player) { 61 | 62 | setCurrentItem(playbackManager.currentItem(player)); 63 | } 64 | 65 | function onPlaybackStop(e) { 66 | setCurrentItem(null); 67 | } 68 | 69 | function renderPlaylist() { 70 | 71 | var section = view.querySelector('.trackList'); 72 | 73 | playbackManager.getPlaylist().then(function(items) { 74 | section.innerHTML = listview.getListViewHtml({ 75 | items: items, 76 | action: 'setplaylistindex', 77 | showParentTitle: true, 78 | enableSideMediaInfo: true 79 | }); 80 | 81 | imageLoader.lazyChildren(section); 82 | 83 | focusManager.autoFocus(section); 84 | updateCurrentPlaylistItem(); 85 | }); 86 | } 87 | 88 | function updateCurrentPlaylistItem() { 89 | 90 | var index = playbackManager.getCurrentPlaylistIndex(); 91 | 92 | var current = view.querySelector('.playlistIndexIndicatorImage'); 93 | if (current) { 94 | current.classList.remove('playlistIndexIndicatorImage'); 95 | } 96 | 97 | if (index !== -1) { 98 | 99 | var item = view.querySelectorAll('.trackList .listItem')[index]; 100 | if (item) { 101 | var img = item.querySelector('.listItemImage'); 102 | 103 | img.classList.add('playlistIndexIndicatorImage'); 104 | } 105 | } 106 | } 107 | 108 | view.addEventListener('viewshow', function (e) { 109 | 110 | var isRestored = e.detail.isRestored; 111 | 112 | Emby.Page.setTitle(globalize.translate('NowPlaying')); 113 | 114 | Events.on(playbackManager, 'playbackstart', onPlaybackStart); 115 | Events.on(playbackManager, 'playbackstop', onPlaybackStop); 116 | 117 | renderPlaylist(); 118 | 119 | onPlaybackStart(e, playbackManager.getCurrentPlayer()); 120 | 121 | if (!isRestored) { 122 | createVerticalScroller(view, self); 123 | } 124 | }); 125 | 126 | view.addEventListener('viewhide', function () { 127 | 128 | Events.off(playbackManager, 'playbackstart', onPlaybackStart); 129 | Events.off(playbackManager, 'playbackstop', onPlaybackStop); 130 | 131 | }); 132 | 133 | view.addEventListener('viewdestroy', function () { 134 | 135 | if (self.verticalScroller) { 136 | self.verticalScroller.destroy(); 137 | } 138 | }); 139 | }; 140 | 141 | }); -------------------------------------------------------------------------------- /item/item.css: -------------------------------------------------------------------------------- 1 | .mainSection .raised { 2 | padding: .7em 1.3em; 3 | text-transform: none; 4 | margin: 0 .35em 0 0; 5 | } 6 | 7 | .layout-tv .personCard { 8 | width: 14.285714285714285714285714285714%; 9 | } 10 | 11 | .itemFloatClear { 12 | clear: both; 13 | } 14 | 15 | .itemScrollFrame.clippedLeft { 16 | margin-left: 28%; 17 | } 18 | 19 | .mainSection { 20 | display: flex; 21 | margin-top: 2.5em; 22 | } 23 | 24 | .smallBottomMargin { 25 | margin-bottom: 1em; 26 | } 27 | 28 | .itemPageLeft { 29 | padding-right: 1.7em; 30 | } 31 | 32 | .itemPageMain { 33 | flex: 1; 34 | } 35 | 36 | .itemTitle { 37 | margin: .5em 0; 38 | } 39 | 40 | .albumTitle { 41 | text-align: left; 42 | margin: .5em 0 0; 43 | } 44 | 45 | .albumMainSection { 46 | margin-top: 2em; 47 | } 48 | 49 | .seasonMainSection { 50 | margin-top: 0; 51 | } 52 | 53 | .albumMainSection .itemPageLeft { 54 | display: none; 55 | } 56 | 57 | .seasonMainSection .itemPageLeft { 58 | display: none; 59 | } 60 | 61 | .seasonMainSection .itemPageMain { 62 | text-align: center; 63 | } 64 | 65 | .bulletSeparator { 66 | color: #52B54B; 67 | margin: 0 .35em; 68 | } 69 | 70 | .mediaInfo { 71 | margin: 1em 0; 72 | display: flex; 73 | align-items: center; 74 | } 75 | 76 | .albumMainSection .mediaInfo { 77 | margin: 0; 78 | } 79 | 80 | .itemPageButtonsContainer { 81 | display: flex; 82 | align-items: center; 83 | margin: 1.5em 0; 84 | } 85 | 86 | .mainSection .itemPageButtons { 87 | margin-right: 1em; 88 | } 89 | 90 | .itemPageUserDataIcons button { 91 | margin-left: .25em !important; 92 | } 93 | 94 | .itemPageFixedLeft .itemPageUserDataIcons { 95 | margin-top: 1em; 96 | text-align: center; 97 | } 98 | 99 | .albumMainSection .itemPageUserDataIcons { 100 | display: none !important; 101 | } 102 | 103 | .itemPageFixedLeft .itemPageButtons button { 104 | padding-top: .3em; 105 | padding-bottom: .45em; 106 | margin: .35em 0; 107 | text-transform: none; 108 | } 109 | 110 | .detailImageContainer { 111 | /* Eliminates the gap of space between the image and progress bar*/ 112 | line-height: 1; 113 | } 114 | 115 | .detailImageContainer .itemProgressBar { 116 | position: relative; 117 | /* Slightly higher than it's height' */ 118 | top: -.4em; 119 | } 120 | 121 | .detailImage { 122 | min-width: 20vw; 123 | max-width: 35vw; 124 | min-height: 30vh; 125 | max-height: 67vh; 126 | box-shadow: 0 0 .8em #000; 127 | border: 1px solid #222; 128 | user-drag: none; 129 | user-select: none; 130 | -moz-user-select: none; 131 | -webkit-user-drag: none; 132 | -webkit-user-select: none; 133 | -ms-user-select: none; 134 | } 135 | 136 | .itemPageFixedLeft { 137 | position: absolute; 138 | top: 12%; 139 | left: 0; 140 | width: 25%; 141 | padding: 1.25em 2em 0; 142 | } 143 | 144 | .leftFixedDetailImageContainer .detailImage { 145 | min-width: 0 !important; 146 | max-height: none !important; 147 | max-width: none !important; 148 | width: 100%; 149 | margin-bottom: 1em; 150 | } 151 | 152 | .trackList { 153 | margin: 1em 0 0 -.5em; 154 | } 155 | 156 | .episodes { 157 | margin: 1em 0 0 -.5em; 158 | text-align: left; 159 | } 160 | 161 | .mediaInfoIcons { 162 | margin: 1.25em 0; 163 | display: flex; 164 | align-items: center; 165 | flex-wrap: wrap; 166 | } 167 | 168 | .mediaInfoIcons > .mediaInfoText { 169 | margin-right: .5em; 170 | } 171 | 172 | .mediaInfoText-upper { 173 | text-transform: uppercase; 174 | } 175 | 176 | .itemNextUpSection .backdropCard { 177 | width: 30% !important; 178 | } 179 | 180 | .mediaInfoImageIcon img { 181 | max-height: 100%; 182 | } 183 | 184 | .squareCard.chapterCard { 185 | width: 20%; 186 | } 187 | 188 | .parentName { 189 | display: flex; 190 | align-items: center; 191 | } 192 | 193 | .parentNameDivider { 194 | margin: 0 .25em; 195 | } 196 | 197 | .itemVerticalScrollSlider { 198 | /* Needed to position the logo */ 199 | position: relative; 200 | } 201 | 202 | .detailLogo { 203 | width: 13vw; 204 | height: 3vw; 205 | position: absolute; 206 | top: 8.5%; 207 | right: 7%; 208 | background-repeat: no-repeat; 209 | background-position: center center; 210 | background-size: contain; 211 | } 212 | 213 | @media all and (max-width: 87.5em) { 214 | 215 | .detailLogo { 216 | right: 5%; 217 | } 218 | } 219 | 220 | @media all and (max-width: 75em) { 221 | 222 | .detailLogo { 223 | right: 2%; 224 | } 225 | } 226 | 227 | @media all and (max-width: 68.75em) { 228 | 229 | .detailLogo { 230 | display: none; 231 | } 232 | } 233 | 234 | .layout-tv .itemVerticalSection { 235 | margin-bottom: 3.4em !important; 236 | } -------------------------------------------------------------------------------- /strings/pt-PT.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Editar grava\u00e7\u00e3o", 5 | "Episodes": "Epis\u00f3dios", 6 | "OtherVideos": "Outros v\u00eddeos", 7 | "ShowScenesOnDetailScreensFor": "Exibir as cenas nos ecr\u00e3s de detalhe para", 8 | "Play": "Reproduzir", 9 | "Resume": "Resume", 10 | "Books": "Books", 11 | "HeaderAudioBooks": "Audio Books", 12 | "Queue": "Fila", 13 | "Shuffle": "Misturar", 14 | "InsstantMix": "Mix instant\u00e2neo", 15 | "ButtonCancel": "Cancelar", 16 | "ButtonCancelSeries": "Cancel Series", 17 | "AllShows": "All Shows", 18 | "Genres": "G\u00e9neros", 19 | "Extras": "Extras", 20 | "NextUp": "A Seguir", 21 | "LatestEpisodes": "\u00daltimos Epis\u00f3dios", 22 | "ContinueWatching": "Continuar a Ver", 23 | "AllMovies": "Todos os Filmes", 24 | "LatestMovies": "\u00daltimos Filmes", 25 | "Channels": "Canais", 26 | "LatestFromValue": "Mais recentes de {0}", 27 | "All": "Todos", 28 | "Latest": "\u00daltimas", 29 | "Artists": "Artistas", 30 | "Albums": "\u00c1lbuns", 31 | "RecentlyPlayed": "Reproduzido Recentemente", 32 | "FrequentlyPlayed": "Reproduzido Frequentemente", 33 | "Library": "Biblioteca", 34 | "Guide": "Guia", 35 | "Overview": "Vis\u00e3o Geral", 36 | "People": "Pessoas", 37 | "Specials": "Extras", 38 | "SpecialFeatures": "Extras", 39 | "Recordings": "Grava\u00e7\u00f5es", 40 | "Scheduled": "Agendado", 41 | "LatestMusic": "\u00daltimas M\u00fasicas", 42 | "LatestRecordings": "\u00daltimas Grava\u00e7\u00f5es", 43 | "NowPlaying": "A Reproduzir", 44 | "Programs": "Programs", 45 | "RecommendationBecauseYouLike": "Porque gosta de {0}", 46 | "RecommendationBecauseYouWatched": "Porque viu {0}", 47 | "RecommendationDirectedBy": "Realizado por {0}", 48 | "RecommendationStarring": "{0} como protagonista", 49 | "HeaderMoreLikeThis": "Mais Como Este", 50 | "MoreFrom": "Mais de {0}", 51 | "AlbumArtists": "Artistas do \u00c1lbum", 52 | "LiveTV": "TV ao Vivo", 53 | "TrackCount": "{0} faixas", 54 | "Search": "Procurar", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Reproduzir Tudo", 57 | "Suggestions": "Suggestions", 58 | "Schedule": "Schedule", 59 | "Shows": "Shows", 60 | "HeaderUpcomingPrograms": "Upcoming Programs", 61 | "HeaderUpcomingMovies": "Upcoming Movies", 62 | "HeaderUpcomingSports": "Upcoming Sports", 63 | "HeaderUpcomingForKids": "Upcoming for Kids", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "For Kids", 66 | "HeaderOnNow": "On Now", 67 | "OptionSunday": "Domingo", 68 | "OptionMonday": "Segunda", 69 | "OptionTuesday": "Ter\u00e7a", 70 | "OptionWednesday": "Quarta", 71 | "OptionThursday": "Quinta", 72 | "OptionFriday": "Sexta", 73 | "OptionSaturday": "S\u00e1bado", 74 | "OptionEveryday": "Todos os dias", 75 | "OptionWeekend": "Fins de semana", 76 | "OptionWeekday": "dias de semana", 77 | "InstantMix": "Mix instant\u00e2neo", 78 | "SelectServer": "Selecionar servidor", 79 | "SignOut": "Sair", 80 | "TopRated": "Mais bem classificados", 81 | "BornValue": "Nasceu: {0}", 82 | "BirthPlaceValue": "Local de nascimento: {0}", 83 | "FavoriteAlbums": "\u00c1lbuns Favoritos", 84 | "FavoriteSongs": "M\u00fasicas Favoritas", 85 | "FavoriteArtists": "Artistas Favoritos", 86 | "FavoriteShows": "Favorite Shows", 87 | "FavoriteEpisodes": "Epis\u00f3dios Favoritos", 88 | "FavoriteMovies": "Filmes Favoritos", 89 | "CastAndCrew": "Elenco e Equipa", 90 | "Unwatched": "Por ver", 91 | "Movies": "Filmes", 92 | "Collections": "Cole\u00e7\u00f5es", 93 | "Years": "Anos", 94 | "Favorites": "Favoritos", 95 | "More": "Mais", 96 | "Playlists": "Listas de Reprodu\u00e7\u00e3o", 97 | "EnableEpisodeSpoilerProtection": "Ativar fun\u00e7\u00e3o anti-spolier", 98 | "EnableEpisodeSpoilerProtectionHelp": "Ocultar detalhes dos epis\u00f3dios a partir do primeiro n\u00e3o assistido", 99 | "DimUnselectedPosters": "Escurecer capas n\u00e3o selecionadas", 100 | "Songs": "M\u00fasicas", 101 | "Record": "Gravar", 102 | "Settings": "Defini\u00e7\u00f5es", 103 | "Mute": "Desativar Som", 104 | "Unmute": "Ativar Som", 105 | "Subtitles": "Legendas", 106 | "Audio": "\u00c1udio", 107 | "Rewind": "Retroceder", 108 | "Fullscreen": "Ecr\u00e3 completo", 109 | "ExitFullscreen": "Sair do ecr\u00e3 completo", 110 | "PlayOnAnotherDevice": "Reproduzir noutro dispositivo", 111 | "FastForward": "Avan\u00e7o r\u00e1pido", 112 | "Items": "Itens", 113 | "PictureInPicture": "Picture in picture", 114 | "HeaderActiveRecordings": "Active Recordings", 115 | "Yesterday": "Yesterday", 116 | "HeaderUpcomingEpisodes": "Upcoming Episodes" 117 | } -------------------------------------------------------------------------------- /strings/es-419.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Deportes", 3 | "News": "Noticias", 4 | "ButtonEditRecording": "Editar Grabaciones", 5 | "Episodes": "Episodios", 6 | "OtherVideos": "Otros videos", 7 | "ShowScenesOnDetailScreensFor": "Mostrar escenas en pantalla de detalles para", 8 | "Play": "Reproducir", 9 | "Resume": "Continuar", 10 | "Books": "Libros", 11 | "HeaderAudioBooks": "Audio Libros", 12 | "Queue": "Cola", 13 | "Shuffle": "Aleatorio", 14 | "InsstantMix": "Mezcla Instantanea", 15 | "ButtonCancel": "Cancelar", 16 | "ButtonCancelSeries": "Cancelar Serie", 17 | "AllShows": "Todos los Programas", 18 | "Genres": "G\u00e9neros", 19 | "Extras": "Extras", 20 | "NextUp": "Siguiente", 21 | "LatestEpisodes": "\u00daltimos Episodios", 22 | "ContinueWatching": "Continuar Viendo", 23 | "AllMovies": "Todas las Pel\u00edculas", 24 | "LatestMovies": "Ultimas Pel\u00edculas", 25 | "Channels": "Canales", 26 | "LatestFromValue": "Lo ultimo de {0}", 27 | "All": "Todo", 28 | "Latest": "Lo ultimo", 29 | "Artists": "Artistas", 30 | "Albums": "Albumes", 31 | "RecentlyPlayed": "Reproducido Recientemente", 32 | "FrequentlyPlayed": "Reproducido Frecuentemente", 33 | "Library": "Biblioteca", 34 | "Guide": "Guia", 35 | "Overview": "Resumen", 36 | "People": "Personas", 37 | "Specials": "Especiales", 38 | "SpecialFeatures": "Caracter\u00edsticas Especiales", 39 | "Recordings": "Grabaciones", 40 | "Scheduled": "Programado", 41 | "LatestMusic": "Ultima M\u00fasica", 42 | "LatestRecordings": "Ultimas Grabaciones", 43 | "NowPlaying": "Reproduciendo Ahora", 44 | "Programs": "Programas", 45 | "RecommendationBecauseYouLike": "Porque te gust\u00f3 {0}", 46 | "RecommendationBecauseYouWatched": "Porque viste {0}", 47 | "RecommendationDirectedBy": "Dirigido por {0}", 48 | "RecommendationStarring": "Protagonizada por {0}", 49 | "HeaderMoreLikeThis": "Mas como esto", 50 | "MoreFrom": "Mas de {0}", 51 | "AlbumArtists": "Artista del \u00c1lbum", 52 | "LiveTV": "TV en vivo", 53 | "TrackCount": "{0} pistas", 54 | "Search": "Buscar", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Reproducir Todo", 57 | "Suggestions": "Sugerencias", 58 | "Schedule": "Programaci\u00f3n", 59 | "Shows": "Programas", 60 | "HeaderUpcomingPrograms": "Programas por Estrenarse", 61 | "HeaderUpcomingMovies": "Pel\u00edculas por Estrenarse", 62 | "HeaderUpcomingSports": "Deportes por Estrenarse", 63 | "HeaderUpcomingForKids": "Pr\u00f3ximos Estrenos para Ni\u00f1os", 64 | "HeaderUpcomingNews": "Novedades por Estrenarse", 65 | "HeaderForKids": "Para Ni\u00f1os", 66 | "HeaderOnNow": "Disponible Ahora", 67 | "OptionSunday": "Domingo", 68 | "OptionMonday": "Lunes", 69 | "OptionTuesday": "Martes", 70 | "OptionWednesday": "Mi\u00e9rcoles", 71 | "OptionThursday": "Jueves", 72 | "OptionFriday": "Viernes", 73 | "OptionSaturday": "S\u00e1bado", 74 | "OptionEveryday": "Todos los d\u00edas", 75 | "OptionWeekend": "Fines de Semana", 76 | "OptionWeekday": "Entre Semana", 77 | "InstantMix": "Mezcla Instant\u00e1nea", 78 | "SelectServer": "Seleccionar Servidor", 79 | "SignOut": "Cerrar Sesi\u00f3n", 80 | "TopRated": "Mas Valorados", 81 | "BornValue": "Nacido en: {0}", 82 | "BirthPlaceValue": "Lugar de nacimiento: {0}", 83 | "FavoriteAlbums": "\u00c1lbumes Favoritos", 84 | "FavoriteSongs": "Canciones Favoritas", 85 | "FavoriteArtists": "Artistas Favoritos", 86 | "FavoriteShows": "Programas Favoritos", 87 | "FavoriteEpisodes": "Episodios Favoritos", 88 | "FavoriteMovies": "Pel\u00edculas Favoritas", 89 | "CastAndCrew": "Reparto y Equipo T\u00e9cnico", 90 | "Unwatched": "No Visto", 91 | "Movies": "Pel\u00edculas", 92 | "Collections": "Colecciones", 93 | "Years": "A\u00f1os", 94 | "Favorites": "Favoritos", 95 | "More": "Mas", 96 | "Playlists": "Listas de Reproducci\u00f3n", 97 | "EnableEpisodeSpoilerProtection": "Habilitar opciones anti-spoilers", 98 | "EnableEpisodeSpoilerProtectionHelp": "Ocultar detalles para episodios mas all\u00e1 del primero que ha sido visto.", 99 | "DimUnselectedPosters": "Opacar posters no seleccionados", 100 | "Songs": "Canciones", 101 | "Record": "Grabar", 102 | "Settings": "Configuraciones", 103 | "Mute": "Silenciar", 104 | "Unmute": "Activar Sonido", 105 | "Subtitles": "Subtitulos", 106 | "Audio": "Audio", 107 | "Rewind": "Regresar", 108 | "Fullscreen": "Pantalla completa", 109 | "ExitFullscreen": "Salir de pantalla completa", 110 | "PlayOnAnotherDevice": "Reproducir en otro dispositivo", 111 | "FastForward": "Avance R\u00e1pido", 112 | "Items": "\u00cdtems", 113 | "PictureInPicture": "Pantalla en pantalla", 114 | "HeaderActiveRecordings": "Grabaciones Activas", 115 | "Yesterday": "Ayer", 116 | "HeaderUpcomingEpisodes": "Episodios por Estrenarse" 117 | } -------------------------------------------------------------------------------- /strings/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Wydarzenia sportowe", 3 | "News": "Wiadomo\u015bci", 4 | "ButtonEditRecording": "Edytuj nagranie", 5 | "Episodes": "Odcinki", 6 | "OtherVideos": "Inne wideo", 7 | "ShowScenesOnDetailScreensFor": "Pokazuj sceny w widoku szczeg\u00f3\u0142owym dla", 8 | "Play": "Odtwarzaj", 9 | "Resume": "Wzn\u00f3w", 10 | "Books": "Ksi\u0105\u017cki", 11 | "HeaderAudioBooks": "Ksi\u0105\u017cki audio", 12 | "Queue": "Kolejka", 13 | "Shuffle": "Losowo", 14 | "InsstantMix": "Szybki remiks", 15 | "ButtonCancel": "Anuluj", 16 | "ButtonCancelSeries": "Anuluj nagrywanie seryjne", 17 | "AllShows": "Wszystkie", 18 | "Genres": "Gatunki", 19 | "Extras": "Materia\u0142y dodatkowe", 20 | "NextUp": "Do obejrzenia", 21 | "LatestEpisodes": "Odcinki ostatnio dodane", 22 | "ContinueWatching": "Kontynuuj odtwarzanie", 23 | "AllMovies": "Wszystkie", 24 | "LatestMovies": "Filmy ostatnio dodane", 25 | "Channels": "Kana\u0142y", 26 | "LatestFromValue": "Ostatnio dodane do {0}", 27 | "All": "Wszystko", 28 | "Latest": "Ostatnio dodane", 29 | "Artists": "Wykonawcy", 30 | "Albums": "Albumy", 31 | "RecentlyPlayed": "Ostatnio odtwarzane", 32 | "FrequentlyPlayed": "Cz\u0119sto odtwarzane", 33 | "Library": "Biblioteka", 34 | "Guide": "Przewodnik", 35 | "Overview": "Opis", 36 | "People": "Osoby", 37 | "Specials": "Odcinki specjalne", 38 | "SpecialFeatures": "Funkcje specjalne", 39 | "Recordings": "Nagrania", 40 | "Scheduled": "Zaplanowane", 41 | "LatestMusic": "Muzyka ostatnio dodana", 42 | "LatestRecordings": "Nagrania ostatnio dodane", 43 | "NowPlaying": "Teraz odtwarzane", 44 | "Programs": "Programy", 45 | "RecommendationBecauseYouLike": "Propozycje po polubieniu {0}", 46 | "RecommendationBecauseYouWatched": "Propozycje po obejrzeniu {0}", 47 | "RecommendationDirectedBy": "Wyre\u017cyserowane przez {0}", 48 | "RecommendationStarring": "Wyst\u0119puj\u0105 {0}", 49 | "HeaderMoreLikeThis": "Wi\u0119cej podobnych", 50 | "MoreFrom": "Wi\u0119cej z {0}", 51 | "AlbumArtists": "Wykonawcy album\u00f3w", 52 | "LiveTV": "Telewizja", 53 | "TrackCount": "{0} utwor\u00f3w", 54 | "Search": "Szukaj", 55 | "Trailer": "Zwiastun", 56 | "PlayAll": "Odtwarzaj wszystko", 57 | "Suggestions": "Polecane", 58 | "Schedule": "Zaplanuj", 59 | "Shows": "Seriale", 60 | "HeaderUpcomingPrograms": "Wkr\u00f3tce na antenie", 61 | "HeaderUpcomingMovies": "Wkr\u00f3tce w kinach", 62 | "HeaderUpcomingSports": "Wkr\u00f3tce na arenach sportowych", 63 | "HeaderUpcomingForKids": "Wkr\u00f3tce dla dzieci", 64 | "HeaderUpcomingNews": "Wkr\u00f3tce", 65 | "HeaderForKids": "Dla dzieci", 66 | "HeaderOnNow": "Teraz", 67 | "OptionSunday": "Niedziela", 68 | "OptionMonday": "Poniedzia\u0142ek", 69 | "OptionTuesday": "Wtorek", 70 | "OptionWednesday": "\u015aroda", 71 | "OptionThursday": "Czwartek", 72 | "OptionFriday": "Pi\u0105tek", 73 | "OptionSaturday": "Sobota", 74 | "OptionEveryday": "Codziennie", 75 | "OptionWeekend": "Weekendy", 76 | "OptionWeekday": "Dni tygodnia", 77 | "InstantMix": "Szybki remiks", 78 | "SelectServer": "Wybierz serwer", 79 | "SignOut": "Wyloguj si\u0119", 80 | "TopRated": "Najwy\u017cej oceniane", 81 | "BornValue": "Data urodzenia: {0}", 82 | "BirthPlaceValue": "Miejsce urodzenia: {0}", 83 | "FavoriteAlbums": "Albumy ulubione", 84 | "FavoriteSongs": "Utwory ulubione", 85 | "FavoriteArtists": "Wykonawcy ulubieni", 86 | "FavoriteShows": "Seriale ulubione", 87 | "FavoriteEpisodes": "Odcinki ulubione", 88 | "FavoriteMovies": "Filmy ulubione", 89 | "CastAndCrew": "Obsada i ekipa", 90 | "Unwatched": "Nieobejrzane", 91 | "Movies": "Filmy", 92 | "Collections": "Kolekcje", 93 | "Years": "Lata", 94 | "Favorites": "Ulubione", 95 | "More": "Wi\u0119cej", 96 | "Playlists": "Listy", 97 | "EnableEpisodeSpoilerProtection": "Aktywuj funkcje zapobiegaj\u0105ce poznaniu fabu\u0142y", 98 | "EnableEpisodeSpoilerProtectionHelp": "Umo\u017cliwia ukrywanie opis\u00f3w odcink\u00f3w poza pierwszym nieobejrzanym", 99 | "DimUnselectedPosters": "Wygaszaj nieaktywne plakaty", 100 | "Songs": "Utwory", 101 | "Record": "Nagraj", 102 | "Settings": "Ustawienia", 103 | "Mute": "Wycisz", 104 | "Unmute": "Przywr\u00f3\u0107 g\u0142o\u015bno\u015b\u0107", 105 | "Subtitles": "Napisy", 106 | "Audio": "D\u017awi\u0119k", 107 | "Rewind": "Wstecz", 108 | "Fullscreen": "Pe\u0142ny ekran", 109 | "ExitFullscreen": "Opu\u015b\u0107 pe\u0142ny ekran", 110 | "PlayOnAnotherDevice": "Odtwarzaj na innym urz\u0105dzeniu", 111 | "FastForward": "Wprz\u00f3d", 112 | "Items": "Pozycje", 113 | "PictureInPicture": "Obraz w obrazie", 114 | "HeaderActiveRecordings": "Nagrania aktywne", 115 | "Yesterday": "Wczoraj", 116 | "HeaderUpcomingEpisodes": "Odcinki wkr\u00f3tce na antenie" 117 | } -------------------------------------------------------------------------------- /strings/pt-BR.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Esportes", 3 | "News": "Not\u00edcias", 4 | "ButtonEditRecording": "Editar Grava\u00e7\u00e3o", 5 | "Episodes": "Epis\u00f3dios", 6 | "OtherVideos": "Outros v\u00eddeos", 7 | "ShowScenesOnDetailScreensFor": "Exibir as cenas nas telas de detalhes para", 8 | "Play": "Reproduzir", 9 | "Resume": "Retomar", 10 | "Books": "Livros", 11 | "HeaderAudioBooks": "Livros de \u00c1udio", 12 | "Queue": "Fila", 13 | "Shuffle": "Aleat\u00f3rio", 14 | "InsstantMix": "Mix Instant\u00e2neo", 15 | "ButtonCancel": "Cancelar", 16 | "ButtonCancelSeries": "Cancelar S\u00e9ries", 17 | "AllShows": "Todas as S\u00e9ries", 18 | "Genres": "G\u00eaneros", 19 | "Extras": "Extras", 20 | "NextUp": "Pr\u00f3ximos", 21 | "LatestEpisodes": "Epis\u00f3dios Recentes", 22 | "ContinueWatching": "Continuar Assistindo", 23 | "AllMovies": "Todos os Filmes", 24 | "LatestMovies": "Filmes Recentes", 25 | "Channels": "Canais", 26 | "LatestFromValue": "Recentes de {0}", 27 | "All": "Todos", 28 | "Latest": "Recentes", 29 | "Artists": "Artistas", 30 | "Albums": "\u00c1lbuns", 31 | "RecentlyPlayed": "Reproduzido Recentemente", 32 | "FrequentlyPlayed": "Reproduzido Frequentemente", 33 | "Library": "Biblioteca", 34 | "Guide": "Guia", 35 | "Overview": "Sinopse", 36 | "People": "Pessoas", 37 | "Specials": "Especiais", 38 | "SpecialFeatures": "Conte\u00fado Especial", 39 | "Recordings": "Grava\u00e7\u00f5es", 40 | "Scheduled": "Agendada", 41 | "LatestMusic": "M\u00fasicas Recentes", 42 | "LatestRecordings": "Grava\u00e7\u00f5es Recentes", 43 | "NowPlaying": "Reproduzindo Agora", 44 | "Programs": "Programas", 45 | "RecommendationBecauseYouLike": "Porque voc\u00ea gosta de {0}", 46 | "RecommendationBecauseYouWatched": "Porque voc\u00ea assistiu {0}", 47 | "RecommendationDirectedBy": "Dirigido por {0}", 48 | "RecommendationStarring": "Estrelando {0}", 49 | "HeaderMoreLikeThis": "Mais Como Este", 50 | "MoreFrom": "Mais de {0}", 51 | "AlbumArtists": "Artistas do \u00c1lbum", 52 | "LiveTV": "TV ao Vivo", 53 | "TrackCount": "{0} faixas", 54 | "Search": "Busca", 55 | "Trailer": "Trailer", 56 | "PlayAll": "Reproduzir Tudo", 57 | "Suggestions": "Sugest\u00f5es", 58 | "Schedule": "Agendar", 59 | "Shows": "S\u00e9ries", 60 | "HeaderUpcomingPrograms": "Programas Por Estrear", 61 | "HeaderUpcomingMovies": "Filmes Por Estrear", 62 | "HeaderUpcomingSports": "Esportes Por Estrear", 63 | "HeaderUpcomingForKids": "Infantis Por Estrear", 64 | "HeaderUpcomingNews": "Pr\u00f3ximas Not\u00edcias", 65 | "HeaderForKids": "Para Crian\u00e7as", 66 | "HeaderOnNow": "Em Exibi\u00e7\u00e3o", 67 | "OptionSunday": "Domingo", 68 | "OptionMonday": "Segunda-feira", 69 | "OptionTuesday": "Ter\u00e7a-feira", 70 | "OptionWednesday": "Quarta-feira", 71 | "OptionThursday": "Quinta-feira", 72 | "OptionFriday": "Sexta-feira", 73 | "OptionSaturday": "S\u00e1bado", 74 | "OptionEveryday": "Todos os dias", 75 | "OptionWeekend": "Fins-de-semana", 76 | "OptionWeekday": "Dias-de-semana", 77 | "InstantMix": "Mix Instant\u00e2neo", 78 | "SelectServer": "Selecionar servidor", 79 | "SignOut": "Sair", 80 | "TopRated": "Melhor Avaliados", 81 | "BornValue": "Nascimento: {0}", 82 | "BirthPlaceValue": "Local de nascimento: {0}", 83 | "FavoriteAlbums": "\u00c1lbuns Favoritos", 84 | "FavoriteSongs": "M\u00fasicas Favoritas", 85 | "FavoriteArtists": "Artistas Favoritos", 86 | "FavoriteShows": "S\u00e9ries Favoritas", 87 | "FavoriteEpisodes": "Epis\u00f3dios Favoritos", 88 | "FavoriteMovies": "Filmes Favoritos", 89 | "CastAndCrew": "Elenco & Equipe", 90 | "Unwatched": "N\u00e3o-assistido", 91 | "Movies": "Filmes", 92 | "Collections": "Cole\u00e7\u00f5es", 93 | "Years": "Anos", 94 | "Favorites": "Favoritos", 95 | "More": "Mais", 96 | "Playlists": "Listas de Reprodu\u00e7\u00e3o", 97 | "EnableEpisodeSpoilerProtection": "Ativar recursos anti-spoiler", 98 | "EnableEpisodeSpoilerProtectionHelp": "Ocultar detalhes dos epis\u00f3dios a partir do primeiro n\u00e3o assistido", 99 | "DimUnselectedPosters": "Escurecer capas n\u00e3o selecionadas", 100 | "Songs": "M\u00fasicas", 101 | "Record": "Gravar", 102 | "Settings": "Ajustes", 103 | "Mute": "Mudo", 104 | "Unmute": "Sair do Mudo", 105 | "Subtitles": "Legendas", 106 | "Audio": "\u00c1udio", 107 | "Rewind": "Retroceder", 108 | "Fullscreen": "Tela cheia", 109 | "ExitFullscreen": "Sair da tela cheia", 110 | "PlayOnAnotherDevice": "Reproduzir em outro dispositivo", 111 | "FastForward": "Avan\u00e7o-r\u00e1pido", 112 | "Items": "Itens", 113 | "PictureInPicture": "Picture in picture", 114 | "HeaderActiveRecordings": "Grava\u00e7\u00f5es Ativas", 115 | "Yesterday": "Ontem", 116 | "HeaderUpcomingEpisodes": "Pr\u00f3ximos Epis\u00f3dios" 117 | } -------------------------------------------------------------------------------- /strings/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "Actualit\u00e9s", 4 | "ButtonEditRecording": "Modifier l'enregistrement", 5 | "Episodes": "\u00c9pisodes", 6 | "OtherVideos": "Autres vid\u00e9os", 7 | "ShowScenesOnDetailScreensFor": "Afficher les sc\u00e8nes sur l'\u00e9cran des d\u00e9tails pour", 8 | "Play": "Lire", 9 | "Resume": "Reprendre", 10 | "Books": "Livres", 11 | "HeaderAudioBooks": "Livres audios", 12 | "Queue": "File d'attente", 13 | "Shuffle": "Lecture al\u00e9atoire", 14 | "InsstantMix": "Mix instantan\u00e9", 15 | "ButtonCancel": "Annuler", 16 | "ButtonCancelSeries": "Annuler la s\u00e9rie", 17 | "AllShows": "Toutes les \u00e9missions", 18 | "Genres": "Genres", 19 | "Extras": "Bonus", 20 | "NextUp": "\u00c0 suivre", 21 | "LatestEpisodes": "Derniers \u00e9pisodes", 22 | "ContinueWatching": "Continuer la lecture", 23 | "AllMovies": "Tous les films", 24 | "LatestMovies": "Derniers films", 25 | "Channels": "Cha\u00eenes", 26 | "LatestFromValue": "Derniers dans {0}", 27 | "All": "Tout", 28 | "Latest": "Derniers", 29 | "Artists": "Artistes", 30 | "Albums": "Albums", 31 | "RecentlyPlayed": "Lu r\u00e9cemment", 32 | "FrequentlyPlayed": "Lu fr\u00e9quemment", 33 | "Library": "M\u00e9diath\u00e8que", 34 | "Guide": "Guide", 35 | "Overview": "Synopsis", 36 | "People": "Personnes", 37 | "Specials": "\u00c9pisodes sp\u00e9ciaux", 38 | "SpecialFeatures": "Bonus", 39 | "Recordings": "Enregistrements", 40 | "Scheduled": "Planifi\u00e9", 41 | "LatestMusic": "Derni\u00e8re musique", 42 | "LatestRecordings": "Derniers enregistrements", 43 | "NowPlaying": "Lecture en cours", 44 | "Programs": "Programmes", 45 | "RecommendationBecauseYouLike": "Parce que vous aimez {0}", 46 | "RecommendationBecauseYouWatched": "Parce que vous avez regard\u00e9 {0}", 47 | "RecommendationDirectedBy": "R\u00e9alis\u00e9 par {0}", 48 | "RecommendationStarring": "Avec {0}", 49 | "HeaderMoreLikeThis": "Similaire", 50 | "MoreFrom": "Plus de {0}", 51 | "AlbumArtists": "Artistes de l'album", 52 | "LiveTV": "TV en direct", 53 | "TrackCount": "{0} pistes", 54 | "Search": "Rechercher", 55 | "Trailer": "Bande-annonce", 56 | "PlayAll": "Tout lire", 57 | "Suggestions": "Suggestions", 58 | "Schedule": "Programme", 59 | "Shows": "\u00c9missions", 60 | "HeaderUpcomingPrograms": "Programmes \u00e0 venir", 61 | "HeaderUpcomingMovies": "Films \u00e0 venir", 62 | "HeaderUpcomingSports": "Sport \u00e0 venir", 63 | "HeaderUpcomingForKids": "Programmes jeunesse \u00e0 venir", 64 | "HeaderUpcomingNews": "Actualit\u00e9s \u00e0 venir", 65 | "HeaderForKids": "Jeunesse", 66 | "HeaderOnNow": "En ce moment", 67 | "OptionSunday": "Dimanche", 68 | "OptionMonday": "Lundi", 69 | "OptionTuesday": "Mardi", 70 | "OptionWednesday": "Mercredi", 71 | "OptionThursday": "Jeudi", 72 | "OptionFriday": "Vendredi", 73 | "OptionSaturday": "Samedi", 74 | "OptionEveryday": "Tous les jours", 75 | "OptionWeekend": "Les week-ends", 76 | "OptionWeekday": "En semaine", 77 | "InstantMix": "Mix instantan\u00e9", 78 | "SelectServer": "S\u00e9lectionner le serveur", 79 | "SignOut": "D\u00e9connexion", 80 | "TopRated": "Meilleurs notes", 81 | "BornValue": "N\u00e9(e) le : {0}", 82 | "BirthPlaceValue": "Lieu de naissance : {0}", 83 | "FavoriteAlbums": "Albums favoris", 84 | "FavoriteSongs": "Chansons favorites", 85 | "FavoriteArtists": "Artistes favoris", 86 | "FavoriteShows": "\u00c9missions favorites", 87 | "FavoriteEpisodes": "\u00c9pisodes favoris", 88 | "FavoriteMovies": "Films favoris", 89 | "CastAndCrew": "Casting", 90 | "Unwatched": "Non lu", 91 | "Movies": "Films", 92 | "Collections": "Collections", 93 | "Years": "Ann\u00e9es", 94 | "Favorites": "Favoris", 95 | "More": "Plus", 96 | "Playlists": "Listes de lecture", 97 | "EnableEpisodeSpoilerProtection": "Activer les fonctionnalit\u00e9s anti-spoiler", 98 | "EnableEpisodeSpoilerProtectionHelp": "Cacher les d\u00e9tails pour les \u00e9pisodes au-del\u00e0 du premier non lu", 99 | "DimUnselectedPosters": "Assombrir les affiches non s\u00e9lectionn\u00e9es", 100 | "Songs": "Chansons", 101 | "Record": "Enregistrer", 102 | "Settings": "Param\u00e8tres", 103 | "Mute": "Couper le son", 104 | "Unmute": "R\u00e9tablir le son", 105 | "Subtitles": "Sous-titres", 106 | "Audio": "Audio", 107 | "Rewind": "Rembobiner", 108 | "Fullscreen": "Plein \u00e9cran", 109 | "ExitFullscreen": "Sortir du plein \u00e9cran", 110 | "PlayOnAnotherDevice": "Lire sur un autre appareil", 111 | "FastForward": "Avance rapide", 112 | "Items": "\u00c9l\u00e9ments", 113 | "PictureInPicture": "Picture in Picture", 114 | "HeaderActiveRecordings": "Enregistrements actifs", 115 | "Yesterday": "Hier", 116 | "HeaderUpcomingEpisodes": "\u00c9pisodes \u00e0 venir" 117 | } -------------------------------------------------------------------------------- /strings/lt-LT.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Redaguoti \u012fra\u0161\u0105", 5 | "Episodes": "Serijos", 6 | "OtherVideos": "Kiti video", 7 | "ShowScenesOnDetailScreensFor": "Rodyti i\u0161traukas info ekrane", 8 | "Play": "Rodyti", 9 | "Resume": "Prat\u0119sti", 10 | "Books": "Knygos", 11 | "HeaderAudioBooks": "Audio knygos", 12 | "Queue": "Eil\u0117", 13 | "Shuffle": "Atsitiktinai", 14 | "InsstantMix": "Leisti miks\u0105", 15 | "ButtonCancel": "At\u0161aukti", 16 | "ButtonCancelSeries": "Cancel Series", 17 | "AllShows": "Visos laidos", 18 | "Genres": "\u017danrai", 19 | "Extras": "Priedai", 20 | "NextUp": "Toliau eil\u0117je", 21 | "LatestEpisodes": "V\u0117liausios serijos", 22 | "ContinueWatching": "\u017di\u016br\u0117ti toliau", 23 | "AllMovies": "Visi filmai", 24 | "LatestMovies": "V\u0117liausi filmai", 25 | "Channels": "Kanalai", 26 | "LatestFromValue": "V\u0117liausi nuo {0}", 27 | "All": "Visi", 28 | "Latest": "V\u0117liausi", 29 | "Artists": "Atlik\u0117jai", 30 | "Albums": "Albumai", 31 | "RecentlyPlayed": "Nesenai paleisti", 32 | "FrequentlyPlayed": "Da\u017enai leid\u017eiami", 33 | "Library": "Biblioteka", 34 | "Guide": "Gidas", 35 | "Overview": "Ap\u017evalga", 36 | "People": "\u017dmon\u0117s", 37 | "Specials": "Ypatingi", 38 | "SpecialFeatures": "Ypatingos laidos", 39 | "Recordings": "\u012era\u0161ai", 40 | "Scheduled": "Numatyti", 41 | "LatestMusic": "V\u0117liausia muzika", 42 | "LatestRecordings": "V\u0117liausi \u012fra\u0161ai", 43 | "NowPlaying": "Dabar rodoma", 44 | "Programs": "Programs", 45 | "RecommendationBecauseYouLike": "Nes Jums patinka {0}", 46 | "RecommendationBecauseYouWatched": "Nes \u017ei\u016br\u0117jote {0}", 47 | "RecommendationDirectedBy": "Re\u017eisierius {0}", 48 | "RecommendationStarring": "Vaidina {0}", 49 | "HeaderMoreLikeThis": "Daugiau pana\u0161i\u0173", 50 | "MoreFrom": "Daugiau i\u0161 {0}", 51 | "AlbumArtists": "Albumo atlik\u0117jai", 52 | "LiveTV": "Tiesiogin\u0117 TV", 53 | "TrackCount": "{0} dain\u0173", 54 | "Search": "Ie\u0161koti", 55 | "Trailer": "Anonsai", 56 | "PlayAll": "Leisti visk\u0105", 57 | "Suggestions": "Pasi\u016blymai", 58 | "Schedule": "Schedule", 59 | "Shows": "Laidos", 60 | "HeaderUpcomingPrograms": "Upcoming Programs", 61 | "HeaderUpcomingMovies": "Upcoming Movies", 62 | "HeaderUpcomingSports": "Upcoming Sports", 63 | "HeaderUpcomingForKids": "Upcoming for Kids", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "For Kids", 66 | "HeaderOnNow": "Dabar rodoma", 67 | "OptionSunday": "Sekmadienis", 68 | "OptionMonday": "Pirmadienis", 69 | "OptionTuesday": "Antradienis", 70 | "OptionWednesday": "Tre\u010diadienis", 71 | "OptionThursday": "Ketvirtadienis", 72 | "OptionFriday": "Penktadienis", 73 | "OptionSaturday": "\u0160e\u0161tadienis", 74 | "OptionEveryday": "Kasdien", 75 | "OptionWeekend": "Savaitgaliais", 76 | "OptionWeekday": "Darbo dienomis", 77 | "InstantMix": "Leisti miks\u0105", 78 | "SelectServer": "Rinktis server\u012f", 79 | "SignOut": "Atsijungti", 80 | "TopRated": "Geriausiai vertinama", 81 | "BornValue": "Gim\u0117: {0}", 82 | "BirthPlaceValue": "Gimimo vieta: {0}", 83 | "FavoriteAlbums": "M\u0117gstamiausi albumai", 84 | "FavoriteSongs": "M\u0117gstamiausios dainos", 85 | "FavoriteArtists": "M\u0117gstamiausi atlik\u0117jai", 86 | "FavoriteShows": "M\u0117gstamos laidos", 87 | "FavoriteEpisodes": "M\u0117gstamiausios serijos", 88 | "FavoriteMovies": "M\u0117gstamiausi filmai", 89 | "CastAndCrew": "K\u016br\u0117jai", 90 | "Unwatched": "Ne\u017ei\u016br\u0117ta", 91 | "Movies": "Filmai", 92 | "Collections": "Kolekcijos", 93 | "Years": "Metai", 94 | "Favorites": "M\u0117gstamiausi", 95 | "More": "Daugiau", 96 | "Playlists": "Grojara\u0161\u010diai", 97 | "EnableEpisodeSpoilerProtection": "Leisti anti-spoileri\u0173 funkcijas", 98 | "EnableEpisodeSpoilerProtectionHelp": "Sl\u0117pti info apie sekan\u010dias ne\u017ei\u016br\u0117tas serijas", 99 | "DimUnselectedPosters": "Tamsinti nepasirinktus plakatus", 100 | "Songs": "Dainos", 101 | "Record": "\u012era\u0161yti", 102 | "Settings": "Nustatymai", 103 | "Mute": "I\u0161jungti gars\u0105", 104 | "Unmute": "\u012ejungto gars\u0105", 105 | "Subtitles": "Subtitrai", 106 | "Audio": "Audio", 107 | "Rewind": "Rewind", 108 | "Fullscreen": "Per vis\u0105 ekran\u0105", 109 | "ExitFullscreen": "I\u0161eiti i\u0161 pilno ekrano", 110 | "PlayOnAnotherDevice": "Paleisti kitame \u012frenginyje", 111 | "FastForward": "Fast-forward", 112 | "Items": "Elementai", 113 | "PictureInPicture": "Picture in picture", 114 | "HeaderActiveRecordings": "Aktyv\u016bs \u012fra\u0161ai", 115 | "Yesterday": "Vakar", 116 | "HeaderUpcomingEpisodes": "B\u016bsimos serijos" 117 | } -------------------------------------------------------------------------------- /strings/zh-CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "\u4fee\u6539\u5f55\u5236", 5 | "Episodes": "Episodes", 6 | "OtherVideos": "\u5176\u4ed6\u89c6\u9891", 7 | "ShowScenesOnDetailScreensFor": "Show scenes on detail screens for", 8 | "Play": "\u64ad\u653e", 9 | "Resume": "Resume", 10 | "Books": "Books", 11 | "HeaderAudioBooks": "Audio Books", 12 | "Queue": "\u961f\u5217", 13 | "Shuffle": "\u968f\u673a\u64ad\u653e", 14 | "InsstantMix": "Instant Mix", 15 | "ButtonCancel": "\u53d6\u6d88", 16 | "ButtonCancelSeries": "Cancel Series", 17 | "AllShows": "All Shows", 18 | "Genres": "\u98ce\u683c", 19 | "Extras": "Extras", 20 | "NextUp": "\u63a5\u4e0b\u6765", 21 | "LatestEpisodes": "\u6700\u65b0\u5267\u96c6", 22 | "ContinueWatching": "\u7ee7\u7eed\u89c2\u770b", 23 | "AllMovies": "\u6240\u6709\u7535\u5f71", 24 | "LatestMovies": "\u6700\u65b0\u7535\u5f71", 25 | "Channels": "\u9891\u9053", 26 | "LatestFromValue": "Latest from {0}", 27 | "All": "\u6240\u6709", 28 | "Latest": "\u6700\u65b0", 29 | "Artists": "\u827a\u672f\u5bb6", 30 | "Albums": "Albums", 31 | "RecentlyPlayed": "\u6700\u8fd1\u64ad\u653e", 32 | "FrequentlyPlayed": "Frequently Played", 33 | "Library": "\u5a92\u4f53\u5e93", 34 | "Guide": "\u6307\u5357", 35 | "Overview": "\u6982\u8ff0", 36 | "People": "\u4eba\u7269", 37 | "Specials": "\u7279\u5178", 38 | "SpecialFeatures": "Special Features", 39 | "Recordings": "\u5f55\u5236", 40 | "Scheduled": "Scheduled", 41 | "LatestMusic": "\u6700\u65b0\u97f3\u4e50", 42 | "LatestRecordings": "\u6700\u65b0\u5f55\u5236", 43 | "NowPlaying": "\u6b63\u5728\u64ad\u653e", 44 | "Programs": "Programs", 45 | "RecommendationBecauseYouLike": "\u56e0\u4e3a\u60a8\u559c\u6b22 {0}", 46 | "RecommendationBecauseYouWatched": "\u56e0\u4e3a\u60a8\u770b\u8fc7 {0}", 47 | "RecommendationDirectedBy": "\u5bfc\u6f14 {0}", 48 | "RecommendationStarring": "\u4e3b\u6f14 {0}", 49 | "HeaderMoreLikeThis": "\u66f4\u591a\u7c7b\u4f3c\u7684", 50 | "MoreFrom": "\u66f4\u591a\u6765\u81ea {0}", 51 | "AlbumArtists": "\u4e13\u8f91\u4f5c\u5bb6", 52 | "LiveTV": "\u7535\u89c6\u76f4\u64ad", 53 | "TrackCount": "{0} \u4e2a\u97f3\u8f68", 54 | "Search": "\u641c\u7d22", 55 | "Trailer": "\u9884\u544a\u7247", 56 | "PlayAll": "\u5168\u90e8\u64ad\u653e", 57 | "Suggestions": "Suggestions", 58 | "Schedule": "Schedule", 59 | "Shows": "Shows", 60 | "HeaderUpcomingPrograms": "Upcoming Programs", 61 | "HeaderUpcomingMovies": "Upcoming Movies", 62 | "HeaderUpcomingSports": "Upcoming Sports", 63 | "HeaderUpcomingForKids": "Upcoming for Kids", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "For Kids", 66 | "HeaderOnNow": "On Now", 67 | "OptionSunday": "\u661f\u671f\u65e5", 68 | "OptionMonday": "\u661f\u671f\u4e00", 69 | "OptionTuesday": "\u661f\u671f\u4e8c", 70 | "OptionWednesday": "\u661f\u671f\u4e09", 71 | "OptionThursday": "\u661f\u671f\u56db", 72 | "OptionFriday": "\u661f\u671f\u4e94", 73 | "OptionSaturday": "\u661f\u671f\u516d", 74 | "OptionEveryday": "\u6bcf\u5929", 75 | "OptionWeekend": "\u5468\u672b", 76 | "OptionWeekday": "\u5de5\u4f5c\u65e5", 77 | "InstantMix": "Instant Mix", 78 | "SelectServer": "\u9009\u62e9\u670d\u52a1\u5668", 79 | "SignOut": "\u767b\u51fa", 80 | "TopRated": "Top Rated", 81 | "BornValue": "\u51fa\u751f\uff1a {0}", 82 | "BirthPlaceValue": "\u51fa\u751f\u5730\uff1a{0}", 83 | "FavoriteAlbums": "\u6700\u7231\u7684\u4e13\u8f91", 84 | "FavoriteSongs": "\u6700\u7231\u7684\u6b4c\u66f2", 85 | "FavoriteArtists": "\u6700\u7231\u7684\u827a\u672f\u5bb6", 86 | "FavoriteShows": "Favorite Shows", 87 | "FavoriteEpisodes": "\u6700\u7231\u7684\u5267\u96c6", 88 | "FavoriteMovies": "\u6700\u7231\u7684\u7535\u5f71", 89 | "CastAndCrew": "Cast & Crew", 90 | "Unwatched": "\u672a\u89c2\u770b", 91 | "Movies": "\u7535\u5f71", 92 | "Collections": "\u5408\u96c6", 93 | "Years": "\u5e74\u4efd", 94 | "Favorites": "\u6700\u7231", 95 | "More": "\u66f4\u591a", 96 | "Playlists": "Playlists", 97 | "EnableEpisodeSpoilerProtection": "Enable anti-spoiler features", 98 | "EnableEpisodeSpoilerProtectionHelp": "Hide details for episodes beyond the first unwatched", 99 | "DimUnselectedPosters": "Dim unselected posters", 100 | "Songs": "\u6b4c\u66f2", 101 | "Record": "\u5f55\u5236", 102 | "Settings": "Settings", 103 | "Mute": "Mute", 104 | "Unmute": "Unmute", 105 | "Subtitles": "Subtitles", 106 | "Audio": "Audio", 107 | "Rewind": "Rewind", 108 | "Fullscreen": "Full screen", 109 | "ExitFullscreen": "Exit full screen", 110 | "PlayOnAnotherDevice": "Play on another device", 111 | "FastForward": "Fast-forward", 112 | "Items": "\u9879\u76ee", 113 | "PictureInPicture": "Picture in picture", 114 | "HeaderActiveRecordings": "Active Recordings", 115 | "Yesterday": "Yesterday", 116 | "HeaderUpcomingEpisodes": "Upcoming Episodes" 117 | } -------------------------------------------------------------------------------- /movies/years.js: -------------------------------------------------------------------------------- 1 | define(['cardBuilder', 'imageLoader', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'scrollHelper', 'focusManager', 'emby-itemscontainer'], function (cardBuilder, imageLoader, loading, connectionManager, appHost, layoutManager, scrollHelper, focusManager) { 2 | 'use strict'; 3 | 4 | function MoviesTab(view, params) { 5 | this.view = view; 6 | this.params = params; 7 | this.apiClient = connectionManager.getApiClient(params.serverId); 8 | } 9 | 10 | function enableScrollX() { 11 | return !layoutManager.desktop; 12 | } 13 | 14 | function getPortraitShape() { 15 | return enableScrollX() ? 'overflowPortrait' : 'portrait'; 16 | } 17 | 18 | function renderMovies(view, items) { 19 | 20 | var groups = []; 21 | 22 | var currentGroupName = ''; 23 | var currentGroup = []; 24 | 25 | var i, length; 26 | 27 | for (i = 0, length = items.length; i < length; i++) { 28 | 29 | var item = items[i]; 30 | 31 | var dateText = item.ProductionYear; 32 | 33 | if (dateText !== currentGroupName) { 34 | 35 | if (currentGroup.length) { 36 | groups.push({ 37 | name: currentGroupName, 38 | items: currentGroup 39 | }); 40 | } 41 | 42 | currentGroupName = dateText; 43 | currentGroup = [item]; 44 | } else { 45 | currentGroup.push(item); 46 | } 47 | } 48 | 49 | var html = ''; 50 | 51 | for (i = 0, length = groups.length; i < length; i++) { 52 | 53 | var group = groups[i]; 54 | 55 | html += '
'; 56 | html += '

' + group.name + '

'; 57 | 58 | var allowBottomPadding = true; 59 | 60 | if (enableScrollX()) { 61 | allowBottomPadding = false; 62 | html += '
'; 63 | html += '
'; 64 | } else { 65 | html += '
'; 66 | } 67 | 68 | var supportsImageAnalysis = appHost.supports('imageanalysis'); 69 | 70 | html += cardBuilder.getCardsHtml({ 71 | items: group.items, 72 | shape: getPortraitShape(), 73 | overlayText: true, 74 | allowBottomPadding: allowBottomPadding, 75 | //showTitle: true, 76 | //showParentTitle: true, 77 | centerText: true 78 | 79 | }); 80 | 81 | if (enableScrollX()) { 82 | html += '
'; 83 | } 84 | 85 | html += '
'; 86 | 87 | html += '
'; 88 | } 89 | 90 | view.innerHTML = html; 91 | imageLoader.lazyChildren(view); 92 | } 93 | 94 | MoviesTab.prototype.onBeforeShow = function (options) { 95 | 96 | var apiClient = this.apiClient; 97 | 98 | if (!options.refresh) { 99 | this.promises = null; 100 | return; 101 | } 102 | 103 | var promises = []; 104 | var parentId = this.params.parentId; 105 | 106 | var query = { 107 | SortBy: "ProductionYear,SortName", 108 | SortOrder: "Descending", 109 | IncludeItemTypes: "Movie", 110 | Recursive: true, 111 | Fields: "PrimaryImageAspectRatio,BasicSyncInfo,SortName", 112 | ImageTypeLimit: 1, 113 | EnableImageTypes: "Primary,Backdrop,Banner,Thumb", 114 | StartIndex: 0, 115 | parentId: parentId 116 | }; 117 | 118 | promises.push(apiClient.getItems(apiClient.getCurrentUserId(), query)); 119 | 120 | this.promises = promises; 121 | }; 122 | 123 | MoviesTab.prototype.onShow = function (options) { 124 | 125 | var promises = this.promises; 126 | if (!promises) { 127 | return; 128 | } 129 | 130 | this.promises = []; 131 | 132 | var view = this.view; 133 | 134 | promises[0].then(function (result) { 135 | renderMovies(view, result.Items); 136 | return Promise.resolve(); 137 | }); 138 | 139 | Promise.all(promises).then(function () { 140 | if (options.autoFocus) { 141 | focusManager.autoFocus(view); 142 | } 143 | }); 144 | }; 145 | 146 | MoviesTab.prototype.onHide = function () { 147 | 148 | }; 149 | 150 | MoviesTab.prototype.destroy = function () { 151 | 152 | this.view = null; 153 | this.params = null; 154 | this.apiClient = null; 155 | this.promises = null; 156 | }; 157 | 158 | return MoviesTab; 159 | }); -------------------------------------------------------------------------------- /strings/cs.json: -------------------------------------------------------------------------------- 1 | { 2 | "Sports": "Sports", 3 | "News": "News", 4 | "ButtonEditRecording": "Upravit nahr\u00e1vku", 5 | "Episodes": "Epizody", 6 | "OtherVideos": "Ostatn\u00ed videa", 7 | "ShowScenesOnDetailScreensFor": "Uk\u00e1zat sc\u00e9ny na detailn\u00edch obrazovk\u00e1ch pro", 8 | "Play": "P\u0159ehr\u00e1t", 9 | "Resume": "Pokra\u010dovat", 10 | "Books": "Knihy", 11 | "HeaderAudioBooks": "Audio knihy", 12 | "Queue": "Fronta", 13 | "Shuffle": "Zam\u00edchat", 14 | "InsstantMix": "N\u00e1hodn\u00fd Mix", 15 | "ButtonCancel": "Zru\u0161it", 16 | "ButtonCancelSeries": "Zru\u0161it s\u00e9rii", 17 | "AllShows": "V\u0161echny seri\u00e1ly", 18 | "Genres": "\u017d\u00e1nry", 19 | "Extras": "Extra", 20 | "NextUp": "Nadch\u00e1zej\u00edc\u00ed", 21 | "LatestEpisodes": "Posledn\u00ed epizody", 22 | "ContinueWatching": "Pokra\u010dovat ve sledov\u00e1n\u00ed", 23 | "AllMovies": "V\u0161echny filmy", 24 | "LatestMovies": "Posledn\u00ed filmy", 25 | "Channels": "Kan\u00e1ly", 26 | "LatestFromValue": "Posledn\u00ed od {0}", 27 | "All": "V\u0161e", 28 | "Latest": "Posledn\u00ed", 29 | "Artists": "Um\u011blci", 30 | "Albums": "Alba", 31 | "RecentlyPlayed": "Pr\u00e1v\u011b p\u0159ehran\u00e9", 32 | "FrequentlyPlayed": "\u010casto hran\u00e9", 33 | "Library": "Knihovna", 34 | "Guide": "Pr\u016fvodce", 35 | "Overview": "P\u0159ehled", 36 | "People": "Lid\u00e9", 37 | "Specials": "Speci\u00e1ly", 38 | "SpecialFeatures": "Speci\u00e1ln\u00ed funkce", 39 | "Recordings": "Nahr\u00e1vky", 40 | "Scheduled": "Napl\u00e1novan\u00e9", 41 | "LatestMusic": "Posledn\u00ed hudba", 42 | "LatestRecordings": "Posledn\u00ed nahr\u00e1vky", 43 | "NowPlaying": "Pr\u00e1v\u011b hraje", 44 | "Programs": "Programy", 45 | "RecommendationBecauseYouLike": "Proto\u017ee se v\u00e1m l\u00edb\u00ed {0}", 46 | "RecommendationBecauseYouWatched": "Proto\u017ee jste sledovali {0}", 47 | "RecommendationDirectedBy": "Re\u017eie {0}", 48 | "RecommendationStarring": "Role {0}", 49 | "HeaderMoreLikeThis": "V\u00edce podobn\u00fdch", 50 | "MoreFrom": "V\u00edce od {0}", 51 | "AlbumArtists": "Um\u011blec alba", 52 | "LiveTV": "TV", 53 | "TrackCount": "{0} stop", 54 | "Search": "Hledat", 55 | "Trailer": "Uk\u00e1zka", 56 | "PlayAll": "P\u0159ehr\u00e1t v\u0161e", 57 | "Suggestions": "Doporu\u010den\u00e9", 58 | "Schedule": "Pl\u00e1n", 59 | "Shows": "Po\u0159ady", 60 | "HeaderUpcomingPrograms": "Nadch\u00e1zej\u00edc\u00ed programy", 61 | "HeaderUpcomingMovies": "Nadch\u00e1zej\u00edc\u00ed filmy", 62 | "HeaderUpcomingSports": "Nadch\u00e1zej\u00edc\u00ed sport", 63 | "HeaderUpcomingForKids": "Nadch\u00e1zej\u00edc\u00ed pro d\u011bti", 64 | "HeaderUpcomingNews": "Upcoming News", 65 | "HeaderForKids": "Pro d\u011bti", 66 | "HeaderOnNow": "Pr\u00e1v\u011b te\u010f", 67 | "OptionSunday": "Ned\u011ble", 68 | "OptionMonday": "Pond\u011bl\u00ed", 69 | "OptionTuesday": "\u00dater\u00fd", 70 | "OptionWednesday": "St\u0159eda", 71 | "OptionThursday": "\u010ctvrtek", 72 | "OptionFriday": "P\u00e1tek", 73 | "OptionSaturday": "Sobota", 74 | "OptionEveryday": "Ka\u017ed\u00fd den", 75 | "OptionWeekend": "V\u00edkendy", 76 | "OptionWeekday": "Dny v t\u00fddnu", 77 | "InstantMix": "N\u00e1hodn\u00fd Mix", 78 | "SelectServer": "Vybrat server", 79 | "SignOut": "Odhl\u00e1sit", 80 | "TopRated": "Nejl\u00e9pe hodnocen\u00e9", 81 | "BornValue": "Narozen: {0}", 82 | "BirthPlaceValue": "M\u00edsto narozen\u00ed: {0}", 83 | "FavoriteAlbums": "Obl\u00edben\u00e1 alba", 84 | "FavoriteSongs": "Obl\u00edben\u00e9 p\u00edsni\u010dky", 85 | "FavoriteArtists": "Obl\u00edben\u00ed um\u011blci", 86 | "FavoriteShows": "Obl\u00edben\u00e9 po\u0159ady", 87 | "FavoriteEpisodes": "Obl\u00edben\u00e9 epizody", 88 | "FavoriteMovies": "Obl\u00edben\u00e9 filmy", 89 | "CastAndCrew": "Obsazen\u00ed", 90 | "Unwatched": "Neshl\u00e9dnut\u00e9", 91 | "Movies": "Filmy", 92 | "Collections": "Sb\u00edrky", 93 | "Years": "Roky", 94 | "Favorites": "Obl\u00edben\u00e9", 95 | "More": "V\u00edce", 96 | "Playlists": "Seznam skladeb", 97 | "EnableEpisodeSpoilerProtection": "Funkce proti spoiler\u016fm", 98 | "EnableEpisodeSpoilerProtectionHelp": "Skr\u00fdt detaily pro epizody krom\u011b prvn\u00ed neshl\u00e9dnut\u00e9", 99 | "DimUnselectedPosters": "Ztmavit neshl\u00e9dnut\u00e9 plak\u00e1ty", 100 | "Songs": "Skladby", 101 | "Record": "Z\u00e1znam", 102 | "Settings": "Nastaven\u00ed", 103 | "Mute": "Ztlumit", 104 | "Unmute": "Zes\u00edlit", 105 | "Subtitles": "Titulky", 106 | "Audio": "Zvuk", 107 | "Rewind": "P\u0159eto\u010dit zp\u011bt", 108 | "Fullscreen": "Cel\u00e1 obrazovka", 109 | "ExitFullscreen": "Opustit celou obrazovku", 110 | "PlayOnAnotherDevice": "P\u0159ehr\u00e1t na jin\u00e9m za\u0159\u00edzen\u00ed", 111 | "FastForward": "Rychle vp\u0159ed", 112 | "Items": "Polo\u017eky", 113 | "PictureInPicture": "Obraz v obraze", 114 | "HeaderActiveRecordings": "Aktivn\u00ed nahr\u00e1v\u00e1n\u00ed", 115 | "Yesterday": "V\u010dera", 116 | "HeaderUpcomingEpisodes": "Nadch\u00e1zej\u00edc\u00ed epizody" 117 | } -------------------------------------------------------------------------------- /livetv/guide.js: -------------------------------------------------------------------------------- 1 | define(['globalize', 'tvguide', 'events', 'datetime', 'imageLoader', 'backdrop', 'mediaInfo'], function (globalize, tvguide, events, datetime, imageLoader, backdrop, mediaInfo) { 2 | 'use strict'; 3 | 4 | return function (view, params) { 5 | 6 | var self = this; 7 | var guideInstance; 8 | 9 | var guideItemDetailsElement = view.querySelector('.guideItemDetails'); 10 | var guideImageElement = view.querySelector('.guideImage'); 11 | 12 | var hideTime = 0; 13 | 14 | view.addEventListener('viewshow', function (e) { 15 | 16 | Emby.Page.setTitle(globalize.translate('Guide')); 17 | backdrop.clear(); 18 | 19 | if (e.detail.isRestored) { 20 | if (guideInstance) { 21 | var refreshGuideData = false; 22 | if ((new Date().getTime() - hideTime) > 60000) { 23 | refreshGuideData = true; 24 | } 25 | guideInstance.resume(refreshGuideData); 26 | } 27 | } else { 28 | initGuide(); 29 | } 30 | }); 31 | 32 | view.addEventListener('viewhide', function () { 33 | hideTime = new Date().getTime(); 34 | if (guideInstance) { 35 | guideInstance.pause(); 36 | } 37 | }); 38 | 39 | view.addEventListener('viewdestroy', function () { 40 | if (guideInstance) { 41 | guideInstance.destroy(); 42 | guideInstance = null; 43 | } 44 | }); 45 | 46 | var focusTimeout; 47 | var currentItemId; 48 | 49 | function clearFocusTimeout() { 50 | if (focusTimeout) { 51 | clearTimeout(focusTimeout); 52 | } 53 | } 54 | 55 | function onFocusTimeout() { 56 | 57 | Emby.Models.item(currentItemId).then(function (item) { 58 | 59 | setSelectedInfo(item); 60 | //backdrop.setBackdrop(item); 61 | }); 62 | } 63 | 64 | function onGuideFocus(e, detail) { 65 | 66 | clearFocusTimeout(); 67 | currentItemId = detail.item.Id; 68 | focusTimeout = setTimeout(onFocusTimeout, 500); 69 | } 70 | 71 | function getTime(date) { 72 | 73 | return datetime.getDisplayTime(date).toLowerCase(); 74 | } 75 | 76 | function setSelectedInfo(item) { 77 | 78 | var html = ''; 79 | 80 | html += '
'; 81 | html += '

' + item.Name + '

'; 82 | 83 | if (item.IsHD) { 84 | html += 'hd'; 85 | } 86 | 87 | if (item.SeriesTimerId) { 88 | html += 'fiber_smart_record'; 89 | } else if (item.TimerId) { 90 | html += 'fiber_manual_record'; 91 | } 92 | 93 | html += '
'; 94 | 95 | var secondaryMediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(item); 96 | if (secondaryMediaInfoHtml) { 97 | html += '
'; 98 | html += secondaryMediaInfoHtml; 99 | html += '
'; 100 | } 101 | 102 | var overview = item.ShortOverview || item.Overview; 103 | 104 | if (overview) { 105 | html += '
'; 106 | html += overview; 107 | html += '
'; 108 | } 109 | 110 | var date = ''; 111 | if (item.StartDate) { 112 | 113 | try { 114 | date += getTime(datetime.parseISO8601Date(item.StartDate)); 115 | } catch (e) { 116 | console.log("Error parsing date: " + item.PremiereDate); 117 | } 118 | } 119 | if (item.EndDate) { 120 | 121 | try { 122 | date += ' - ' + getTime(datetime.parseISO8601Date(item.EndDate)); 123 | } catch (e) { 124 | console.log("Error parsing date: " + item.EndDate); 125 | } 126 | } 127 | 128 | if (date) { 129 | html += '
'; 130 | html += date; 131 | html += '
'; 132 | } 133 | 134 | guideItemDetailsElement.innerHTML = html; 135 | 136 | var imgUrl = Emby.Models.imageUrl(item); 137 | if (imgUrl) { 138 | imageLoader.lazyImage(guideImageElement, imgUrl); 139 | } else { 140 | guideImageElement.style.backgroundImage = ''; 141 | } 142 | } 143 | 144 | function initGuide() { 145 | 146 | guideInstance = new tvguide({ 147 | element: view.querySelector('.guidePageContainer'), 148 | serverId: params.serverId 149 | }); 150 | 151 | events.on(guideInstance, 'focus', onGuideFocus); 152 | } 153 | }; 154 | 155 | }); -------------------------------------------------------------------------------- /music/music.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 | 7 |
8 |
9 |
10 | 11 |
12 |
13 |
14 | 15 |
16 | 17 |
18 | 19 |
20 | 21 |
22 |
23 |

${LatestMusic}

24 |
25 |
26 | 27 |
28 |
29 |

${Playlists}

30 |
31 |
32 | 33 |
34 |
35 |

${RecentlyPlayed}

36 |
37 |
38 | 39 |
40 |
41 |

${FrequentlyPlayed}

42 |
43 |
44 | 45 |
46 |
47 |

${FavoriteArtists}

48 |
49 |
50 | 51 |
52 |
53 |

${FavoriteAlbums}

54 |
55 |
56 | 57 |
58 |
59 |

${FavoriteSongs}

60 |
61 |
62 | 63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | 74 |
75 |
76 |
77 | 78 |
79 |
80 |
81 | 82 |
83 |
84 |
85 |
86 |
87 | 88 |
--------------------------------------------------------------------------------