Compare commits

...

49 Commits

Author SHA1 Message Date
Joshua M. Boniface
c25db80cbd Bump version to 10.5.5 2020-04-26 15:26:31 -04:00
dkanada
e33ffbe9aa Merge pull request #1113 from MrTimscampi/tv-genres-title
Add title and year to posters in TV genres view

(cherry picked from commit ddc094dbfa)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:22 -04:00
dkanada
f68bdaa276 Merge pull request #1109 from jellyfin/change-to-google-cast
Change Chromecast player name to Google Cast

(cherry picked from commit f78bcd556d)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:21 -04:00
dkanada
e804227d6d Merge pull request #1108 from nielsvanvelzen/androidtv-exists
Add Android icon for Android TV in devices page

(cherry picked from commit 14fcf7e3a5)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:20 -04:00
dkanada
9092d7fc06 Merge pull request #1105 from thornbill/restore-user-menu
Restore user menu on mobile

(cherry picked from commit 511fe3b61c)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:19 -04:00
dkanada
148920f2f9 Merge pull request #1104 from dmitrylyzo/fix-undefined-variable
Fix reference to undefined variable

(cherry picked from commit 7646c17688)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:19 -04:00
Vasily
482fa20364 Merge pull request #1095 from JustAMan/fix-subs-on-mobile
Fix .ass subtitles not starting on mobile

(cherry picked from commit a4324665f0)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:18 -04:00
dkanada
b102201607 Merge pull request #1093 from MrTimscampi/mobile-fixes-2
Fix some mobile navigation issues

(cherry picked from commit 542a738926)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:17 -04:00
dkanada
7909c0874b Merge pull request #1074 from dmitrylyzo/playback_delayed_update
Move delayed volume update to playbackManager

(cherry picked from commit 5063c4f050)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:16 -04:00
dkanada
d691f4c38f Merge pull request #1022 from ferferga/fix-mobile-layout
Fix mobile layout for itemdetails

(cherry picked from commit d4427e8a37)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:14 -04:00
dkanada
b4adc677fd Merge pull request #872 from Artiume/patch-10
Update ISO playback warning

(cherry picked from commit 9f6ec50715)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-26 14:39:10 -04:00
dkanada
fd66c5a3fb Merge pull request #1111 from dmitrylyzo/fix-old-browser-template-string
Change template string to generic one to support older browsers
2020-04-21 13:15:24 +09:00
Dmitry Lyzo
364bbc988d Change template string to generic one to support older browsers 2020-04-20 19:04:49 +03:00
Joshua M. Boniface
51722fd225 Bump version to 10.5.4 2020-04-12 19:31:34 -04:00
Joshua M. Boniface
a158b1f85a Merge pull request #1072 from ferferga/fix-recent
Move "hide watched media" checkbox

(cherry picked from commit 6246dce320)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:31:07 -04:00
dkanada
0bb732c60a Merge pull request #1070 from redSpoutnik/subtitle-sync-subtitleOctopus
Set subtitle-sync for SubtitlesOctopus

(cherry picked from commit b311ad120e)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:31:01 -04:00
Vasily
2782127ba8 Merge pull request #1068 from jellyfin/download
Pass title and filename to native shell

(cherry picked from commit ed3b140379)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:30:59 -04:00
dkanada
6a80b4caeb Merge pull request #1049 from JustAMan/fix-ff-newline-subs
Fix newline breaks in SRT subtitles shown in Firefox

(cherry picked from commit b44c8c0c52)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:29:07 -04:00
dkanada
b2e95b0ee6 Merge pull request #1048 from JustAMan/bump-octopus
Use patched octopus that works on Cordova

(cherry picked from commit ce84ead81f)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:29:05 -04:00
Vasily
b262b98e83 Merge pull request #1047 from ZadenRB/date-added-dropdown-fix
Fix inconsistent value in drop down list on library page

(cherry picked from commit 14df43c6cb)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:27:26 -04:00
Vasily
b52cb34319 Merge pull request #1040 from JustAMan/fix-native-hls-resume
Fix native hls resume

(cherry picked from commit 2223a16813)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:26:28 -04:00
Anthony Lavado
914ef1e566 Merge pull request #963 from MrTimscampi/fix-logo-size
Don't scale logo on details page

(cherry picked from commit 64a61201d6)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-12 19:26:25 -04:00
Joshua M. Boniface
f832206145 Merge pull request #1018 from MrTimscampi/backport-octopus
Backport changes to Octopus
2020-04-05 13:01:49 -04:00
Joshua M. Boniface
46fcdf91b8 Merge pull request #1028 from ZadenRB/itemdetails-alignment
Fixed alignment of subsections on item details page

(cherry picked from commit 7215e14c39)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:58:40 -04:00
Vasily
3c953d5ffd Merge pull request #1020 from JustAMan/fix-attachment-urls
Fix attachment delivery urls

(cherry picked from commit 50122d0253)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:58:16 -04:00
Vasily
6c28570e82 Merge pull request #1005 from JustAMan/update-octopus
Switch to new version of JavascriptSubtitlesOctopus, enable new options

(cherry picked from commit b782688505)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:57:38 -04:00
Vasily
acf632e77e Merge pull request #1003 from MrTimscampi/admin-logo
Fix admin drawer logo showing up everywhere

(cherry picked from commit 9a65e0351a)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:55:32 -04:00
dkanada
44c273f531 Merge pull request #1000 from Nazar78/tizen5.0-h264-level-52
Support H264 Level 52 (Tizen 5.0)

(cherry picked from commit 4c72a8381c)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:55:02 -04:00
dkanada
ef09b24f0c Merge pull request #970 from MrTimscampi/mobile-menu
Clean up the menus on mobile

(cherry picked from commit 601b75a1a8)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:54:41 -04:00
dkanada
87bcf40e81 Merge pull request #937 from dmitrylyzo/fix_radio_style
Fix radio style

(cherry picked from commit 8a1262eedd)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-04-05 12:54:21 -04:00
Joshua M. Boniface
3cae48be23 Bump version for 10.5.3 2020-04-05 12:53:18 -04:00
MrTimscampi
ecc65dfa3b Backport changes to Octopus 2020-04-04 12:49:15 +02:00
Joshua M. Boniface
9be3f2e731 Merge pull request #969 from dmitrylyzo/tizen_xvid
Fix XviD playback on Tizen

(cherry picked from commit 31d9b35615)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 15:26:45 -04:00
dkanada
44c7b75dbb Merge pull request #932 from MrTimscampi/mobile-fixes
Show hamburger menu on mobile and fix title padding

(cherry picked from commit c49c45ee53)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 15:26:25 -04:00
dkanada
253b0d96d6 Merge pull request #904 from dmitrylyzo/fix_player_data
Clear player data after stop

(cherry picked from commit d5779e115d)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 15:25:53 -04:00
Joshua M. Boniface
7fb75c6d82 Bump version to 10.5.2 2020-03-22 12:09:05 -04:00
dkanada
98816bcce0 Merge pull request #958 from MrTimscampi/listview-missing
Show missing indicator in ListView

(cherry picked from commit 1688a3999c)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 11:52:13 -04:00
Vasily
067e43c0d3 Merge pull request #955 from thornbill/fix-schedules-direct
Fix schedules direct buttons being hidden by default

(cherry picked from commit 298e36388f)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 11:51:27 -04:00
dkanada
a956d602f9 Merge pull request #951 from dtparr/fixUrl
Correct the url in the wizardstart.html to remove the administrator folder

(cherry picked from commit 857ed5401e)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 11:50:48 -04:00
dkanada
9cf6ccc73c Merge pull request #931 from dmitrylyzo/fix_radio
Fix radiobutton and checkbox

(cherry picked from commit 9b54dec5e8)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 11:50:17 -04:00
dkanada
b3b9f355c3 Merge pull request #919 from dmitrylyzo/fix_icons-2
Fix icons doubling and WebOS support

(cherry picked from commit c5171a2fa0)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 11:49:43 -04:00
dkanada
b2d2b1360c Merge pull request #907 from MrTimscampi/artwork-optimal-size
Improve image loading speed and sizes

(cherry picked from commit bdfa8b0121)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-22 11:49:15 -04:00
dkanada
af7f626a43 Merge pull request #948 from MrTimscampi/fix-artist-backdrop
Fix artist details ribbon

(cherry picked from commit 6b22a1113e)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:11:48 -04:00
Joshua M. Boniface
5568d945a7 Merge pull request #943 from jellyfin/dependabot/npm_and_yarn/acorn-6.4.1
Bump acorn from 6.2.1 to 6.4.1

(cherry picked from commit 08919544e4)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:11:17 -04:00
dkanada
4dc5535a02 Merge pull request #936 from macr/master
Fix "Copy Stream URL" for iOS.

(cherry picked from commit 0b107b3770)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:08:49 -04:00
dkanada
b6f5435750 Merge pull request #929 from mark-monteiro/fix-networking-config
Fix Network Settings Page

(cherry picked from commit 00c01d2a4b)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:08:21 -04:00
dkanada
8db63ab520 Merge pull request #926 from ThibaultNocchi/fix_925
Fixed broken links described by #925

(cherry picked from commit 5de205e44d)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:07:57 -04:00
dkanada
527c5fb43e Merge pull request #920 from dmitrylyzo/fix_slideshow-2
Fix slideshow 2

(cherry picked from commit 95f379021e)
Signed-off-by: Joshua M. Boniface <joshua@boniface.me>
2020-03-15 23:07:25 -04:00
Joshua M. Boniface
9ef4e95467 Bump version to 10.5.1 2020-03-15 23:04:37 -04:00
57 changed files with 1338 additions and 1144 deletions

View File

@@ -31,7 +31,7 @@
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
"jquery": "^3.4.1",
"jstree": "^3.3.7",
"libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus",
"libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf-cordova",
"libjass": "^0.11.0",
"material-design-icons-iconfont": "^5.0.1",
"native-promise-only": "^0.8.0-a",

View File

@@ -63,6 +63,10 @@ progress[aria-valuenow]::before {
}
.adminDrawerLogo {
display: none;
}
.layout-mobile .adminDrawerLogo {
padding: 1.5em 1em 1.2em;
border-bottom: 1px solid #e0e0e0;
margin-bottom: 1em;
@@ -161,7 +165,7 @@ div[data-role=controlgroup] a.ui-btn-active {
@media all and (min-width: 40em) {
.content-primary {
padding-top: 7em;
padding-top: 4.6em;
}
.withTabs .content-primary {

View File

@@ -24,6 +24,10 @@
padding-top: 7em !important;
}
.layout-mobile .libraryPage {
padding-top: 4em !important;
}
.itemDetailPage {
padding-top: 0 !important;
}
@@ -115,7 +119,7 @@
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: inline-flex;
margin: 0.3em 0 0 0.5em;
margin: 0 0 0 0.5em;
height: 1.7em;
-webkit-box-align: center;
-webkit-align-items: center;
@@ -268,12 +272,6 @@
}
}
@media all and (max-width: 60em) {
.libraryDocument .mainDrawerButton {
display: none;
}
}
@media all and (max-width: 84em) {
.withSectionTabs .headerTop {
padding-bottom: 0.55em;
@@ -316,7 +314,7 @@
}
.dashboardDocument .mainDrawer-scrollContainer {
margin-top: 6em !important;
margin-top: 4.65em !important;
}
}
@@ -519,6 +517,13 @@
.itemName {
margin: 0.5em 0;
font-weight: 600;
}
.nameContainer {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.itemMiscInfo {
@@ -536,7 +541,6 @@
.layout-mobile .itemName,
.layout-mobile .itemMiscInfo,
.layout-mobile .mainDetailButtons {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
@@ -578,7 +582,6 @@
.infoText {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}
@@ -609,12 +612,11 @@
}
.detailLogo {
width: 67.25vw;
height: 14.5vh;
width: 30vw;
height: 25vh;
position: absolute;
top: 15vh;
right: 0;
-webkit-background-size: contain;
top: 10vh;
right: 20vw;
background-size: contain;
}
@@ -622,26 +624,8 @@
display: none;
}
@media all and (max-width: 87.5em) {
.detailLogo {
right: 5%;
}
}
@media all and (max-width: 75em) {
.detailLogo {
right: 2%;
}
}
@media all and (max-width: 68.75em) {
.detailLogo {
width: 14.91em;
height: 3.5em;
right: 5%;
bottom: 5%;
top: auto;
background-position: center right;
display: none;
}
}

View File

@@ -348,7 +348,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
var deviceId;
var deviceName;
var appName = "Jellyfin Web";
var appVersion = "10.5.0";
var appVersion = "10.5.5";
var visibilityChange;
var visibilityState;

View File

@@ -182,6 +182,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', "userSettings"
return apiClient.getScaledImageUrl(item.BackdropItemId || item.Id, Object.assign(imageOptions, {
type: "Backdrop",
tag: imgTag,
maxWidth: dom.getScreenWidth(),
index: index
}));
});
@@ -192,6 +193,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', "userSettings"
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, Object.assign(imageOptions, {
type: "Backdrop",
tag: imgTag,
maxWidth: dom.getScreenWidth(),
index: index
}));
});

View File

@@ -2,7 +2,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
function (datetime, imageLoader, connectionManager, itemHelper, focusManager, indicators, globalize, layoutManager, appHost, dom, browser, playbackManager, itemShortcuts, imageHelper) {
'use strict';
var devicePixelRatio = window.devicePixelRatio || 1;
var enableFocusTransform = !browser.slow && !browser.edge;
function getCardsHtml(items, options) {
@@ -233,9 +232,9 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
function getImageWidth(shape, screenWidth, isOrientationLandscape) {
var imagesPerRow = getPostersPerRow(shape, screenWidth, isOrientationLandscape);
var shapeWidth = screenWidth / imagesPerRow;
var shapeWidth = Math.round(screenWidth / imagesPerRow) * 2;
return Math.round(shapeWidth);
return shapeWidth;
}
function setCardData(items, options) {
@@ -463,6 +462,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: width,
tag: item.ImageTags.Thumb
});
@@ -470,6 +470,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Banner",
maxWidth: width,
tag: item.ImageTags.Banner
});
@@ -477,6 +478,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Disc",
maxWidth: width,
tag: item.ImageTags.Disc
});
@@ -484,6 +486,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Logo",
maxWidth: width,
tag: item.ImageTags.Logo
});
@@ -491,6 +494,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentLogoItemId, {
type: "Logo",
maxWidth: width,
tag: item.ParentLogoImageTag
});
@@ -498,6 +502,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: "Thumb",
maxWidth: width,
tag: item.SeriesThumbImageTag
});
@@ -505,6 +510,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, {
type: "Thumb",
maxWidth: width,
tag: item.ParentThumbImageTag
});
@@ -512,6 +518,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
maxWidth: width,
tag: item.BackdropImageTags[0]
});
@@ -521,6 +528,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: "Backdrop",
maxWidth: width,
tag: item.ParentBackdropImageTags[0]
});
@@ -530,6 +538,8 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.ImageTags.Primary
});
@@ -550,6 +560,8 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.PrimaryImageItemId || item.Id || item.ItemId, {
type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.PrimaryImageTag
});
@@ -567,20 +579,24 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, {
type: "Primary",
maxWidth: width,
tag: item.ParentPrimaryImageTag
});
} else if (item.SeriesPrimaryImageTag) {
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: "Primary",
maxWidth: width,
tag: item.SeriesPrimaryImageTag
});
} else if (item.AlbumId && item.AlbumPrimaryImageTag) {
width = primaryImageAspectRatio ? Math.round(height * primaryImageAspectRatio) : null;
height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null;
imgUrl = apiClient.getScaledImageUrl(item.AlbumId, {
type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.AlbumPrimaryImageTag
});
@@ -594,6 +610,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: width,
tag: item.ImageTags.Thumb
});
@@ -601,6 +618,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
maxWidth: width,
tag: item.BackdropImageTags[0]
});
@@ -608,6 +626,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: width,
tag: item.ImageTags.Thumb
});
@@ -615,6 +634,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: "Thumb",
maxWidth: width,
tag: item.SeriesThumbImageTag
});
@@ -622,6 +642,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, {
type: "Thumb",
maxWidth: width,
tag: item.ParentThumbImageTag
});
@@ -629,6 +650,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: "Backdrop",
maxWidth: width,
tag: item.ParentBackdropImageTags[0]
});
@@ -1484,7 +1506,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
function getDefaultText(item, options) {
if (item.CollectionType) {
return '<i class="cardImageIcon material-icons">' + imageHelper.getLibraryIcon(item.CollectionType) + '</i>'
return '<i class="cardImageIcon material-icons ' + imageHelper.getLibraryIcon(item.CollectionType) + '"></i>'
}
switch (item.Type) {

View File

@@ -68,7 +68,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
return apiClient.getScaledImageUrl(item.Id, {
maxWidth: maxWidth,
maxWidth: maxWidth * 2,
tag: chapter.ImageTag,
type: "Chapter",
index: index

View File

@@ -5,7 +5,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
var currentResolve;
var currentReject;
var PlayerName = 'Chromecast';
var PlayerName = 'Google Cast';
function sendConnectionResult(isOk) {

View File

@@ -242,9 +242,15 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager',
var onAnimationFinish = function () {
focusManager.pushScope(dlg);
if (dlg.getAttribute('data-autofocus') === 'true') {
focusManager.autoFocus(dlg);
}
if (document.activeElement && !dlg.contains(document.activeElement)) {
// Blur foreign element to prevent triggering of an action from the previous scope
document.activeElement.blur();
}
};
if (enableAnimation()) {

View File

@@ -112,6 +112,22 @@ define([], function () {
return windowSize;
}
var standardWidths = [480, 720, 1280, 1440, 1920, 2560, 3840, 5120, 7680];
function getScreenWidth() {
var width = window.innerWidth;
var height = window.innerHeight;
if (height > width) {
width = height * (16.0 / 9.0);
}
var closest = standardWidths.sort(function (a, b) {
return Math.abs(width - a) - Math.abs(width - b);
})[0];
return closest;
}
var _animationEvent;
function whichAnimationEvent() {
@@ -175,6 +191,7 @@ define([], function () {
addEventListener: addEventListenerWithOptions,
removeEventListener: removeEventListenerWithOptions,
getWindowSize: getWindowSize,
getScreenWidth: getScreenWidth,
whichTransitionEvent: whichTransitionEvent,
whichAnimationEvent: whichAnimationEvent,
whichAnimationCancelEvent: whichAnimationCancelEvent

View File

@@ -6,7 +6,7 @@ define(['multi-download'], function (multiDownload) {
if (window.NativeShell) {
items.map(function (item) {
window.NativeShell.downloadFile(item.url);
window.NativeShell.downloadFile(item);
});
} else {
multiDownload(items.map(function (item) {

View File

@@ -10,6 +10,13 @@
<div class="fieldDescription">${LabelPleaseRestart}</div>
</div>
<div class="verticalSection verticalSection-extrabottompadding">
<label class="checkboxContainer">
<input class="chkHidePlayedFromLatest" type="checkbox" is="emby-checkbox" />
<span>${HideWatchedContentFromLatestMedia}</span>
</label>
</div>
<div class="selectContainer">
<select is="emby-select" id="selectHomeSection1" label="{section1label}">
<option value="smalllibrarytiles">${HeaderMyMedia}</option>
@@ -110,13 +117,6 @@
<div class="perLibrarySettings"></div>
<div class="verticalSection verticalSection-extrabottompadding">
<label class="checkboxContainer">
<input class="chkHidePlayedFromLatest" type="checkbox" is="emby-checkbox" />
<span>${HideWatchedContentFromLatestMedia}</span>
</label>
</div>
<div class="verticalSection verticalSection-extrabottompadding">
<h2 class="sectionTitle">${HeaderLibraryFolders}</h2>
<div>

View File

@@ -183,7 +183,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
for (var i = 0, length = items.length; i < length; i++) {
var item = items[i];
var icon = imageHelper.getLibraryIcon(item.CollectionType);
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(item) + '" class="raised homeLibraryButton"><i class="material-icons homeLibraryIcon">' + icon + '</i><span class="homeLibraryText">' + item.Name + '</span></a>';
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(item) + '" class="raised homeLibraryButton"><i class="material-icons homeLibraryIcon ' + icon + '"></i><span class="homeLibraryText">' + item.Name + '</span></a>';
}
html += '</div>';

View File

@@ -162,7 +162,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
}
}
function seekOnPlaybackStart(instance, element, ticks) {
function seekOnPlaybackStart(instance, element, ticks, onMediaReady) {
var seconds = (ticks || 0) / 10000000;
@@ -171,13 +171,31 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
// Appending #t=xxx to the query string doesn't seem to work with HLS
// For plain video files, not all browsers support it either
var delay = browser.safari ? 2500 : 0;
if (delay) {
setTimeout(function () {
setCurrentTimeIfNeeded(element, seconds);
}, delay);
} else {
if (element.duration >= seconds) {
// media is ready, seek immediately
setCurrentTimeIfNeeded(element, seconds);
if (onMediaReady) onMediaReady();
} else {
// update video player position when media is ready to be sought
var events = ["durationchange", "loadeddata", "play", "loadedmetadata"];
var onMediaChange = function(e) {
if (element.currentTime === 0 && element.duration >= seconds) {
// seek only when video position is exactly zero,
// as this is true only if video hasn't started yet or
// user rewound to the very beginning
// (but rewinding cannot happen as the first event with media of non-empty duration)
console.debug('seeking to ' + seconds + ' on ' + e.type + ' event');
setCurrentTimeIfNeeded(element, seconds);
events.map(function(name) {
element.removeEventListener(name, onMediaChange);
});
if (onMediaReady) onMediaReady();
}
};
events.map(function (name) {
element.addEventListener(name, onMediaChange);
});
}
}
}

View File

@@ -117,8 +117,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
});
}
function normalizeTrackEventText(text) {
return text.replace(/\\N/gi, '\n');
function normalizeTrackEventText(text, useHtml) {
var result = text.replace(/\\N/gi, '\n').replace(/\r/gi, '');
return useHtml ? result.replace(/\n/gi, '<br>') : result;
}
function setTracks(elem, tracks, item, mediaSource) {
@@ -600,8 +601,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
var offsetValue = parseFloat(offset);
// if .ass currently rendering
if (currentAssRenderer) {
if (currentSubtitlesOctopus) {
updateCurrentTrackOffset(offsetValue);
currentSubtitlesOctopus.timeOffset = offsetValue;
} else {
var trackElement = getTextTrack();
// if .vtt currently rendering
@@ -856,7 +858,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
loading.hide();
htmlMediaHelper.seekOnPlaybackStart(self, e.target, self._currentPlayOptions.playerStartPositionTicks);
htmlMediaHelper.seekOnPlaybackStart(self, e.target, self._currentPlayOptions.playerStartPositionTicks, function () {
if (currentSubtitlesOctopus) currentSubtitlesOctopus.resize();
});
if (self._currentPlayOptions.fullscreen) {
@@ -1049,17 +1053,30 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
function renderWithSubtitlesOctopus(videoElement, track, item) {
var attachments = self._currentPlayOptions.mediaSource.MediaAttachments || [];
var apiClient = connectionManager.getApiClient(item);
var options = {
video: videoElement,
subUrl: getTextTrackUrl(track, item),
fonts: attachments.map(function (i) {
return i.DeliveryUrl;
return apiClient.getUrl(i.DeliveryUrl);
}),
workerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker.js",
legacyWorkerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker-legacy.js",
onError: function() {
htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror');
}
},
// new octopus options; override all, even defaults
renderMode: 'blend',
dropAllAnimations: false,
libassMemoryLimit: 40,
libassGlyphLimit: 40,
targetFps: 24,
prescaleTradeoff: 0.8,
softHeightLimit: 1080,
hardHeightLimit: 2160,
resizeVariation: 0.2,
renderAhead: 90
};
require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) {
currentSubtitlesOctopus = new SubtitlesOctopus(options);
@@ -1274,7 +1291,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
data.TrackEvents.forEach(function (trackEvent) {
var trackCueObject = window.VTTCue || window.TextTrackCue;
var cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text));
var cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false));
trackElement.addCue(cue);
});
@@ -1284,11 +1301,6 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
function updateSubtitleText(timeMs) {
// handle offset for ass tracks
if (currentTrackOffset) {
timeMs += (currentTrackOffset * 1000);
}
var clock = currentClock;
if (clock) {
try {
@@ -1315,8 +1327,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
}
if (selectedTrackEvent && selectedTrackEvent.Text) {
subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text);
subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text, true);
subtitleTextElement.classList.remove('hide');
} else {

View File

@@ -339,18 +339,16 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
fileDownloader.download([{
url: downloadHref,
itemId: itemId,
serverId: serverId
serverId: serverId,
title: item.Name,
filename: item.Path.replace(/^.*[\\\/]/, '')
}]);
getResolveFunction(getResolveFunction(resolve, id), id)();
});
break;
case "copy-stream":
var downloadHref = apiClient.getItemDownloadUrl(itemId);
navigator.clipboard.writeText(downloadHref).then(function () {
require(["toast"], function (toast) {
toast(globalize.translate("CopyStreamURLSuccess"));
});
}, function () {
var textAreaCopy = function () {
var textArea = document.createElement("textarea");
textArea.value = downloadHref;
document.body.appendChild(textArea);
@@ -364,7 +362,16 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
prompt(globalize.translate("CopyStreamURL"), downloadHref);
}
document.body.removeChild(textArea);
});
};
if (navigator.clipboard === undefined) {
textAreaCopy();
} else {
navigator.clipboard.writeText(downloadHref).then(function () {
require(["toast"], function (toast) {
toast(globalize.translate("CopyStreamURLSuccess"));
});
}, textAreaCopy);
}
getResolveFunction(resolve, id)();
break;
case "editsubtitles":

View File

@@ -238,13 +238,6 @@
background-color: transparent !important;
}
.listItemMediaInfo {
/* Don't display if flex not supported */
display: none;
align-items: center;
margin-right: 1em;
}
.listGroupHeader-first {
margin-top: 0;
}

View File

@@ -72,7 +72,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
var apiClient = connectionManager.getApiClient(item.ServerId);
var options = {
width: width,
maxWidth: width * 2,
type: "Primary"
};
@@ -105,7 +105,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
var apiClient = connectionManager.getApiClient(item.ServerId);
var options = {
width: width,
maxWidth: width * 2,
type: "Primary"
};

View File

@@ -187,29 +187,15 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader',
volumeSliderContainer.classList.remove('hide');
}
var volumeSliderTimer;
function setVolume() {
clearTimeout(volumeSliderTimer);
volumeSliderTimer = null;
if (currentPlayer) {
currentPlayer.setVolume(this.value);
}
}
function setVolumeDelayed() {
if (!volumeSliderTimer) {
var that = this;
volumeSliderTimer = setTimeout(function () {
setVolume.call(that);
}, 700);
}
}
volumeSlider.addEventListener('change', setVolume);
volumeSlider.addEventListener('mousemove', setVolumeDelayed);
volumeSlider.addEventListener('touchmove', setVolumeDelayed);
volumeSlider.addEventListener('mousemove', setVolume);
volumeSlider.addEventListener('touchmove', setVolume);
positionSlider = elem.querySelector('.nowPlayingBarPositionSlider');
positionSlider.addEventListener('change', function () {

View File

@@ -44,24 +44,15 @@ define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function (
}
function showBlurayMessage() {
var message =
'Playback of Bluray folders in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native Bluray folder support.';
return showMessage(message, 'blurayexpirementalinfo', 'nativeblurayplayback');
return showMessage(globalize.translate("UnsupportedPlayback"), 'blurayexpirementalinfo', 'nativeblurayplayback');
}
function showDvdMessage() {
var message =
'Playback of Dvd folders in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native Dvd folder support.';
return showMessage(message, 'dvdexpirementalinfo', 'nativedvdplayback');
return showMessage(globalize.translate("UnsupportedPlayback"), 'dvdexpirementalinfo', 'nativedvdplayback');
}
function showIsoMessage() {
var message =
'Playback of ISO files in this app is experimental. Some titles may not work at all. For a better experience, consider converting to mkv video files, or use an Jellyfin app with native ISO support.';
return showMessage(message, 'isoexpirementalinfo', 'nativeisoplayback');
return showMessage(globalize.translate("UnsupportedPlayback"), 'isoexpirementalinfo', 'nativeisoplayback');
}
function ExpirementalPlaybackWarnings() {

View File

@@ -3162,7 +3162,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
// User clicked stop or content ended
var state = self.getPlayerState(player);
var streamInfo = getPlayerData(player).streamInfo;
var data = getPlayerData(player);
var streamInfo = data.streamInfo;
var nextItem = self._playNextAfterEnded ? self._playQueueManager.getNextItemInfo() : null;
@@ -3210,6 +3211,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
showPlaybackInfoErrorMessage(self, displayErrorCode, nextItem);
} else if (nextItem) {
self.nextTrack();
} else {
// Nothing more to play - clear data
data.streamInfo = null;
}
}
@@ -3278,7 +3282,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
function onPlaybackVolumeChange(e) {
var player = this;
sendProgressUpdate(player, 'volumechange');
sendProgressUpdateDelayed(player, 'volumechange');
}
function onRepeatModeChange(e) {
@@ -3373,7 +3377,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
pluginManager.ofType('mediaplayer').map(initMediaPlayer);
/** Delay timer for sendProgressUpdate */
var sendProgressUpdateTimer;
/** Delay time in ms for sendProgressUpdate */
var sendProgressUpdateDelay = 700;
function sendProgressUpdate(player, progressEventName, reportPlaylist) {
clearTimeout(sendProgressUpdateTimer);
sendProgressUpdateTimer = null;
if (!player) {
throw new Error('player cannot be null');
@@ -3399,6 +3411,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
}
}
function sendProgressUpdateDelayed(player, progressEventName, reportPlaylist) {
if (!sendProgressUpdateTimer) {
sendProgressUpdateTimer = setTimeout(function () {
sendProgressUpdate(player, progressEventName, reportPlaylist);
}, sendProgressUpdateDelay);
}
}
function getLiveStreamMediaInfo(player, streamInfo, mediaSource, liveStreamId, serverId) {
console.debug('getLiveStreamMediaInfo');

View File

@@ -122,9 +122,9 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL
}
var url = item ? seriesImageUrl(item, {
maxHeight: 300
maxHeight: 300 * 2
}) || imageUrl(item, {
maxHeight: 300
maxHeight: 300 * 2
}) : null;
console.debug("updateNowPlayingInfo");
@@ -614,27 +614,13 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL
return datetime.getDisplayRunningTime(ticks);
};
var volumeSliderTimer;
function setVolume() {
clearTimeout(volumeSliderTimer);
volumeSliderTimer = null;
playbackManager.setVolume(this.value, currentPlayer);
}
function setVolumeDelayed() {
if (!volumeSliderTimer) {
var that = this;
volumeSliderTimer = setTimeout(function () {
setVolume.call(that);
}, 700);
}
}
context.querySelector(".nowPlayingVolumeSlider").addEventListener("change", setVolume);
context.querySelector(".nowPlayingVolumeSlider").addEventListener("mousemove", setVolumeDelayed);
context.querySelector(".nowPlayingVolumeSlider").addEventListener("touchmove", setVolumeDelayed);
context.querySelector(".nowPlayingVolumeSlider").addEventListener("mousemove", setVolume);
context.querySelector(".nowPlayingVolumeSlider").addEventListener("touchmove", setVolume);
context.querySelector(".buttonMute").addEventListener("click", function () {
playbackManager.toggleMute(currentPlayer);
});

View File

@@ -70,7 +70,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
var tabIndex = canFocus ? '' : ' tabindex="-1"';
autoFocus = autoFocus ? ' autofocus' : '';
return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><i class="material-icons slideshowButtonIcon">' + icon + '</i></button>';
return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><i class="material-icons slideshowButtonIcon ' + icon + '"></i></button>';
}
function setUserScalable(scalable) {
@@ -201,14 +201,16 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
function onAutoplayStart() {
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i');
if (btnSlideshowPause) {
btnSlideshowPause.innerHTML = "pause";
btnSlideshowPause.classList.remove("play_arrow");
btnSlideshowPause.classList.add("pause");
}
}
function onAutoplayStop() {
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i');
if (btnSlideshowPause) {
btnSlideshowPause.innerHTML = "&#xE037;";
btnSlideshowPause.classList.remove("pause");
btnSlideshowPause.classList.add("play_arrow");
}
}
@@ -365,8 +367,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
function playPause() {
var paused = dlg.querySelector('.btnSlideshowPause i').innerHTML !== "pause";
var paused = !dlg.querySelector('.btnSlideshowPause i').classList.contains("pause");
if (paused) {
play();
} else {

View File

@@ -264,17 +264,13 @@ define(["jQuery", "loading", "emby-checkbox", "listViewStyle", "emby-input", "em
self.init = function () {
options = options || {};
if (options.showCancelButton) {
page.querySelector(".btnCancel").classList.remove("hide");
} else {
page.querySelector(".btnCancel").classList.add("hide");
}
// Only hide the buttons if explicitly set to false; default to showing if undefined or null
// FIXME: rename this option to clarify logic
var hideCancelButton = options.showCancelButton === false;
page.querySelector(".btnCancel").classList.toggle("hide", hideCancelButton);
if (options.showSubmitButton) {
page.querySelector(".btnSubmitListings").classList.remove("hide");
} else {
page.querySelector(".btnSubmitListings").classList.add("hide");
}
var hideSubmitButton = options.showSubmitButton === false;
page.querySelector(".btnSubmitListings").classList.toggle("hide", hideSubmitButton);
$(".formLogin", page).on("submit", function () {
submitLoginForm();

View File

@@ -163,17 +163,13 @@ define(["jQuery", "loading", "emby-checkbox", "emby-input", "listViewStyle", "pa
self.init = function () {
options = options || {};
if (false !== options.showCancelButton) {
page.querySelector(".btnCancel").classList.remove("hide");
} else {
page.querySelector(".btnCancel").classList.add("hide");
}
// Only hide the buttons if explicitly set to false; default to showing if undefined or null
// FIXME: rename this option to clarify logic
var hideCancelButton = options.showCancelButton === false;
page.querySelector(".btnCancel").classList.toggle("hide", hideCancelButton);
if (false !== options.showSubmitButton) {
page.querySelector(".btnSubmitListings").classList.remove("hide");
} else {
page.querySelector(".btnSubmitListings").classList.add("hide");
}
var hideSubmitButton = options.showSubmitButton === false;
page.querySelector(".btnSubmitListings").classList.toggle("hide", hideSubmitButton);
$("form", page).on("submit", function () {
submitListingsForm();

View File

@@ -634,8 +634,11 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
return "<img src='" + iconUrl + "' />";
},
getNowPlayingImageUrl: function (item) {
/* Screen width is multiplied by 0.2, as the there is currently no way to get the width of
elements that aren't created yet. */
if (item && item.BackdropImageTags && item.BackdropImageTags.length) {
return ApiClient.getScaledImageUrl(item.Id, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Backdrop",
tag: item.BackdropImageTags[0]
});
@@ -643,6 +646,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
if (item && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
return ApiClient.getScaledImageUrl(item.ParentBackdropItemId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Backdrop",
tag: item.ParentBackdropImageTags[0]
});
@@ -650,6 +654,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
if (item && item.BackdropImageTag) {
return ApiClient.getScaledImageUrl(item.BackdropItemId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Backdrop",
tag: item.BackdropImageTag
});
@@ -659,6 +664,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
if (item && imageTags.Thumb) {
return ApiClient.getScaledImageUrl(item.Id, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Thumb",
tag: imageTags.Thumb
});
@@ -666,6 +672,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
if (item && item.ParentThumbImageTag) {
return ApiClient.getScaledImageUrl(item.ParentThumbItemId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Thumb",
tag: item.ParentThumbImageTag
});
@@ -673,6 +680,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
if (item && item.ThumbImageTag) {
return ApiClient.getScaledImageUrl(item.ThumbItemId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Thumb",
tag: item.ThumbImageTag
});
@@ -680,6 +688,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
if (item && imageTags.Primary) {
return ApiClient.getScaledImageUrl(item.Id, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Primary",
tag: imageTags.Primary
});
@@ -687,6 +696,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
if (item && item.PrimaryImageTag) {
return ApiClient.getScaledImageUrl(item.PrimaryImageItemId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Primary",
tag: item.PrimaryImageTag
});
@@ -694,6 +704,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
if (item && item.AlbumPrimaryImageTag) {
return ApiClient.getScaledImageUrl(item.AlbumId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.20),
type: "Primary",
tag: item.AlbumPrimaryImageTag
});

View File

@@ -90,10 +90,11 @@ define(["loading", "libraryMenu", "globalize", "emby-checkbox", "emby-select"],
}
function validateHttps(form) {
var remoteAccess = form.querySelector("#chkRemoteAccess").checked;
var certPath = form.querySelector("#txtCertificatePath").value || null;
var httpsMode = form.querySelector("#selectHttpsMode").value;
if ("enabled" !== httpsMode && "required" !== httpsMode || certPath) {
if (!remoteAccess || ("enabled" !== httpsMode && "required" !== httpsMode || certPath)) {
return Promise.resolve();
}

View File

@@ -49,7 +49,7 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "huma
html += "</a>";
html += "</div>";
if (task.State === "Running") {
html += '<button type="button" is="paper-icon-button-light" id="btnTask' + task.Id + '" class="btnStopTask" data-taskid="' + task.Id + '" title="' + globalize.translate("ButtonStop") + '"><i class="material-icons">stop</i></button>';
html += '<button type="button" is="paper-icon-button-light" id="btnTask' + task.Id + '" class="btnStopTask" data-taskid="' + task.Id + '" title="' + globalize.translate("ButtonStop") + '"><i class="material-icons stop"></i></button>';
} else if (task.State === "Idle") {
html += '<button type="button" is="paper-icon-button-light" id="btnTask' + task.Id + '" class="btnStartTask" data-taskid="' + task.Id + '" title="' + globalize.translate("ButtonStart") + '"><i class="material-icons play_arrow"></i></button>';
}
@@ -90,16 +90,22 @@ define(["jQuery", "loading", "events", "globalize", "serverNotifications", "huma
return html;
}
function setTaskButtonIcon(button, icon) {
var inner = button.querySelector("i");
inner.classList.remove("stop", "play_arrow");
inner.classList.add(icon);
}
function updateTaskButton(elem, state) {
if (state === "Running") {
elem.classList.remove("btnStartTask");
elem.classList.add("btnStopTask");
elem.querySelector("i").innerHTML = "stop";
setTaskButtonIcon(elem, "stop");
elem.title = globalize.translate("ButtonStop");
} else if (state === "Idle") {
elem.classList.add("btnStartTask");
elem.classList.remove("btnStopTask");
elem.querySelector("i").innerHTML = "&#xE037;";
setTaskButtonIcon(elem, "play_arrow");
elem.title = globalize.translate("ButtonStart");
}
$(elem).parents(".listItem")[0].setAttribute("data-status", state);

View File

@@ -336,7 +336,6 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
return html = html.join(" / ");
}
function renderName(item, container, isStatic, context) {
var parentRoute;
var parentNameHtml = [];
@@ -401,14 +400,25 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
} else if (item.Album) {
parentNameHtml.push(item.Album);
}
// FIXME: This whole section needs some refactoring, so it becames easier to scale across all form factors. See GH #1022
var html = "";
var tvShowHtml = parentNameHtml[0];
var tvSeasonHtml = parentNameHtml[1];
if (parentNameHtml.length) {
if (parentNameLast) {
html = '<h3 class="parentName" style="margin: .25em 0;">' + parentNameHtml.join(" - ") + "</h3>";
// Music
if (layoutManager.mobile) {
html = '<h3 class="parentName" style="margin: .25em 0;">' + parentNameHtml.join("</br>") + "</h3>";
} else {
html = '<h3 class="parentName" style="margin: .25em 0;">' + parentNameHtml.join(" - ") + "</h3>";
}
} else {
html = '<h1 class="parentName" style="margin: .1em 0 .25em;">' + parentNameHtml.join(" - ") + "</h1>";
if (layoutManager.mobile) {
html = '<h1 class="parentName" style="margin: .1em 0 .25em;">' + parentNameHtml.join("</br>") + "</h1>";
} else {
html = '<h1 class="parentName" style="margin: .1em 0 .25em;">' + tvShowHtml + "</h1>";
}
}
}
@@ -418,13 +428,17 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
var offset = parentNameLast ? ".25em" : ".5em";
if (html && !parentNameLast) {
html += '<h3 class="itemName infoText" style="margin: .25em 0 .5em;">' + name + '</h3>';
if (!layoutManager.mobile && tvSeasonHtml) {
html += '<h3 class="itemName infoText" style="margin: .25em 0 .5em;">' + tvSeasonHtml + ' - ' + name + '</h3>';
} else {
html += '<h3 class="itemName infoText" style="margin: .25em 0 .5em;">' + name + '</h3>';
}
} else {
html = '<h1 class="itemName infoText" style="margin: .1em 0 ' + offset + ';">' + name + "</h1>" + html;
}
if (item.OriginalTitle && item.OriginalTitle != item.Name) {
html += '<h4 class="itemName infoText" style="margin: -' + offset + ' 0 0">' + item.OriginalTitle + '</h4>';
html += '<h4 class="itemName infoText" style="margin: -' + offset + ' 0 0;">' + item.OriginalTitle + '</h4>';
}
container.innerHTML = html;
@@ -459,7 +473,6 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
var usePrimaryImage = item.MediaType === "Video" && item.Type !== "Movie" && item.Type !== "Trailer" ||
item.MediaType && item.MediaType !== "Video" ||
item.Type === "MusicAlbum" ||
item.Type === "MusicArtist" ||
item.Type === "Person";
if (!layoutManager.mobile && !userSettings.enableBackdrops()) {
@@ -469,6 +482,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
if ("Program" === item.Type && item.ImageTags && item.ImageTags.Thumb) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: dom.getScreenWidth(),
index: 0,
tag: item.ImageTags.Thumb
});
@@ -478,6 +492,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
} else if (usePrimaryImage && item.ImageTags && item.ImageTags.Primary) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Primary",
maxWidth: dom.getScreenWidth(),
index: 0,
tag: item.ImageTags.Primary
});
@@ -487,6 +502,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
} else if (item.BackdropImageTags && item.BackdropImageTags.length) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
maxWidth: dom.getScreenWidth(),
index: 0,
tag: item.BackdropImageTags[0]
});
@@ -496,6 +512,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
} else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: "Backdrop",
maxWidth: dom.getScreenWidth(),
index: 0,
tag: item.ParentBackdropImageTags[0]
});
@@ -505,6 +522,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
} else if (item.ImageTags && item.ImageTags.Thumb) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: dom.getScreenWidth(),
index: 0,
tag: item.ImageTags.Thumb
});
@@ -762,44 +780,54 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
var shape = "portrait";
var detectRatio = false;
/* In the following section, getScreenWidth() is multiplied by 0.5 as the posters
are 25vw and we need double the resolution to counter Skia's scaling. */
// TODO: Find a reliable way to get the poster width
if (imageTags.Primary) {
url = apiClient.getScaledImageUrl(item.Id, {
type: "Primary",
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
tag: item.ImageTags.Primary
});
detectRatio = true;
} else if (item.BackdropImageTags && item.BackdropImageTags.length) {
url = apiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
tag: item.BackdropImageTags[0]
});
shape = "thumb";
} else if (imageTags.Thumb) {
url = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
tag: item.ImageTags.Thumb
});
shape = "thumb";
} else if (imageTags.Disc) {
url = apiClient.getScaledImageUrl(item.Id, {
type: "Disc",
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
tag: item.ImageTags.Disc
});
shape = "square";
} else if (item.AlbumId && item.AlbumPrimaryImageTag) {
url = apiClient.getScaledImageUrl(item.AlbumId, {
type: "Primary",
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
tag: item.AlbumPrimaryImageTag
});
shape = "square";
} else if (item.SeriesId && item.SeriesPrimaryImageTag) {
url = apiClient.getScaledImageUrl(item.SeriesId, {
type: "Primary",
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
tag: item.SeriesPrimaryImageTag
});
} else if (item.ParentPrimaryImageItemId && item.ParentPrimaryImageTag) {
url = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, {
type: "Primary",
maxWidth: Math.round(dom.getScreenWidth() * 0.5),
tag: item.ParentPrimaryImageTag
});
}
@@ -1806,7 +1834,6 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
require(["chaptercardbuilder"], function (chaptercardbuilder) {
chaptercardbuilder.buildChapterCards(item, chapters, {
itemsContainer: scenesContent,
width: 400,
backdropShape: "overflowBackdrop",
squareShape: "overflowSquare"
});
@@ -1859,7 +1886,6 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "userSetti
itemsContainer: castContent,
coverImage: true,
serverId: item.ServerId,
width: 160,
shape: "overflowPortrait"
});
});

View File

@@ -27,14 +27,10 @@ define(["globalize", "loading", "libraryMenu", "emby-checkbox", "emby-button", "
view.querySelector("#chkSaveMetadataHidden").checked = config.SaveMetadataHidden;
});
ApiClient.getNamedConfiguration("metadata").then(function(metadata) {
loadMetadataConfig(this, metadata)
view.querySelector("#selectDateAdded").selectedIndex = metadata.UseFileCreationTimeForDateAdded ? 1 : 0;
});
}
function loadMetadataConfig(page, config) {
$("#selectDateAdded", page).val(config.UseFileCreationTimeForDateAdded ? "1" : "0");
}
view.querySelector("form").addEventListener("submit", function(e) {
loading.show();
var form = this;

View File

@@ -256,6 +256,7 @@ define(["jQuery", "apphost", "scripts/taskbutton", "loading", "libraryMenu", "gl
if (virtualFolder.PrimaryImageItemId) {
imgUrl = ApiClient.getScaledImageUrl(virtualFolder.PrimaryImageItemId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.40),
type: "Primary"
});
}

View File

@@ -334,18 +334,24 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
if (item) {
var imgUrl = seriesImageUrl(item, {
maxWidth: osdPoster.clientWidth * 2,
type: "Primary"
}) || seriesImageUrl(item, {
maxWidth: osdPoster.clientWidth * 2,
type: "Thumb"
}) || imageUrl(item, {
maxWidth: osdPoster.clientWidth * 2,
type: "Primary"
});
if (!imgUrl && secondaryItem && (imgUrl = seriesImageUrl(secondaryItem, {
maxWidth: osdPoster.clientWidth * 2,
type: "Primary"
}) || seriesImageUrl(secondaryItem, {
maxWidth: osdPoster.clientWidth * 2,
type: "Thumb"
}) || imageUrl(secondaryItem, {
maxWidth: osdPoster.clientWidth * 2,
type: "Primary"
})), imgUrl) {
return void (osdPoster.innerHTML = '<img src="' + imgUrl + '" />');
@@ -665,7 +671,8 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
}
function onTimeUpdate(e) {
if (isEnabled) {
// Test for 'currentItem' is required for Firefox since its player spams 'timeupdate' events even being at breakpoint
if (isEnabled && currentItem) {
var now = new Date().getTime();
if (!(now - lastUpdateTime < 700)) {
@@ -1265,7 +1272,6 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
var programEndDateMs = 0;
var playbackStartTimeTicks = 0;
var subtitleSyncOverlay;
var volumeSliderTimer;
var nowPlayingVolumeSlider = view.querySelector(".osdVolumeSlider");
var nowPlayingVolumeSliderContainer = view.querySelector(".osdVolumeSliderContainer");
var nowPlayingPositionSlider = view.querySelector(".osdPositionSlider");
@@ -1416,27 +1422,15 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
}
function setVolume() {
clearTimeout(volumeSliderTimer);
volumeSliderTimer = null;
playbackManager.setVolume(this.value, currentPlayer);
}
function setVolumeDelayed() {
if (!volumeSliderTimer) {
var that = this;
volumeSliderTimer = setTimeout(function () {
setVolume.call(that);
}, 700);
}
}
view.querySelector(".buttonMute").addEventListener("click", function () {
playbackManager.toggleMute(currentPlayer);
});
nowPlayingVolumeSlider.addEventListener("change", setVolume);
nowPlayingVolumeSlider.addEventListener("mousemove", setVolumeDelayed);
nowPlayingVolumeSlider.addEventListener("touchmove", setVolumeDelayed);
nowPlayingVolumeSlider.addEventListener("mousemove", setVolume);
nowPlayingVolumeSlider.addEventListener("touchmove", setVolume);
nowPlayingPositionSlider.addEventListener("change", function () {
var player = currentPlayer;

View File

@@ -113,6 +113,9 @@ define(["layoutManager", "loading", "libraryBrowser", "cardBuilder", "lazyLoader
itemsContainer: elem,
shape: getPortraitShape(),
scalable: true,
showTitle: true,
centerText: true,
showYear: true,
overlayMoreButton: true,
allowBottomPadding: false
});

View File

@@ -1,4 +1,4 @@
define(["apphost", "connectionManager", "listViewStyle", "emby-button"], function(appHost, connectionManager) {
define(["apphost", "connectionManager", "layoutManager", "listViewStyle", "emby-button"], function(appHost, connectionManager, layoutManager) {
"use strict";
return function(view, params) {
@@ -33,6 +33,12 @@ define(["apphost", "connectionManager", "listViewStyle", "emby-button"], functio
page.querySelector(".adminSection").classList.add("hide");
}
if (layoutManager.mobile) {
page.querySelector(".headerUsername").classList.add("hide");
page.querySelector(".adminSection").classList.add("hide");
page.querySelector(".userSection").classList.add("hide");
}
ApiClient.getUser(userId).then(function(user) {
page.querySelector(".headerUsername").innerHTML = user.Name;
if (!user.Policy.IsAdministrator) {

View File

@@ -8,7 +8,7 @@
<div class="verticalSection">
<div class="sectionTitleContainer flex align-items-center">
<h2 class="sectionTitle">${TabSettings}</h2>
<a is="emby-linkbutton" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/administration/connectivity.html#DLNA">${Help}</a>
<a is="emby-linkbutton" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/networking/dlna.html">${Help}</a>
</div>
</div>

View File

@@ -55,7 +55,7 @@
height: 1.83em;
margin: 0;
overflow: hidden;
border: 2px solid currentcolor;
border: 0.14em solid currentcolor;
border-radius: 0.14em;
z-index: 2;
display: flex;

View File

@@ -5,7 +5,8 @@ define(['browser', 'dom', 'css!./emby-checkbox', 'registerElement'], function (b
function onKeyDown(e) {
// Don't submit form on enter
if (e.keyCode === 13) {
// Real (non-emulator) Tizen does nothing on Space
if (e.keyCode === 13 || e.keyCode === 32) {
e.preventDefault();
this.checked = !this.checked;

View File

@@ -80,7 +80,7 @@ define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], fun
var title = this.getAttribute('title');
var html = '<button is="emby-button" type="button" on-click="toggleExpand" id="expandButton" class="emby-collapsible-button iconRight"><h3 class="emby-collapsible-title" title="' + title + '">' + title + '</h3><i class="material-icons emby-collapse-expandIcon">expand_more</i></button>';
var html = '<button is="emby-button" type="button" on-click="toggleExpand" id="expandButton" class="emby-collapsible-button iconRight"><h3 class="emby-collapsible-title" title="' + title + '">' + title + '</h3><i class="material-icons emby-collapse-expandIcon expand_more"></i></button>';
this.insertAdjacentHTML('afterbegin', html);

View File

@@ -4,7 +4,6 @@
display: inline-block;
box-sizing: border-box;
margin: 0;
padding-left: 24px;
}
.radio-label-block {
@@ -31,67 +30,82 @@
border: none;
}
.mdl-radio__outer-circle {
position: absolute;
top: 4px;
left: 0;
display: inline-block;
box-sizing: border-box;
width: 16px;
height: 16px;
margin: 0;
cursor: pointer;
border: 2px solid currentcolor;
.mdl-radio__circles {
position: relative;
margin-right: 0.54em;
width: 1.08em;
height: 1.08em;
border-radius: 50%;
z-index: 2;
cursor: pointer;
}
.mdl-radio__button:checked + .mdl-radio__label + .mdl-radio__outer-circle {
border: 2px solid #00a4dc;
.mdl-radio__circles svg {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
overflow: visible;
}
.mdl-radio__button:disabled + .mdl-radio__label + .mdl-radio__outer-circle {
border: 2px solid rgba(0, 0, 0, 0.26);
.mdl-radio__button:disabled + .mdl-radio__circles {
cursor: auto;
}
.mdl-radio__button:disabled + .mdl-radio__circles .mdl-radio__outer-circle {
color: rgba(0, 0, 0, 0.26);
}
.mdl-radio.show-focus .mdl-radio__button:focus + .mdl-radio__circles .mdl-radio__outer-circle {
color: #00a4dc;
}
.mdl-radio__inner-circle {
position: absolute;
z-index: 1;
margin: 0;
top: 8px;
left: 4px;
box-sizing: border-box;
width: 8px;
height: 8px;
cursor: pointer;
transition-duration: 0.28s;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 0.2s;
transition-property: -webkit-transform;
transition-property: transform;
transition-property: transform, -webkit-transform;
-webkit-transform: scale3d(0, 0, 0);
transform: scale3d(0, 0, 0);
-webkit-transform: scale(0);
transform: scale(0);
transform-origin: 50% 50%;
}
.mdl-radio__button:checked + .mdl-radio__circles .mdl-radio__inner-circle {
-webkit-transform: scale(1);
transform: scale(1);
}
.mdl-radio__button:disabled + .mdl-radio__circles .mdl-radio__inner-circle {
color: rgba(0, 0, 0, 0.26);
}
.mdl-radio.show-focus .mdl-radio__button:focus + .mdl-radio__circles .mdl-radio__inner-circle {
color: #00a4dc;
}
.mdl-radio__focus-circle {
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
width: 100%;
height: 100%;
margin: 0;
border-radius: 50%;
background: #00a4dc;
opacity: 0.26;
transition-duration: 0.2s;
transition-property: -webkit-transform;
transition-property: transform;
transition-property: transform, -webkit-transform;
-webkit-transform: scale(0);
transform: scale(0);
}
.mdl-radio__button:checked + .mdl-radio__label + .mdl-radio__outer-circle + .mdl-radio__inner-circle {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
.mdl-radio__button:disabled + .mdl-radio__label + .mdl-radio__outer-circle + .mdl-radio__inner-circle {
background: rgba(0, 0, 0, 0.26);
cursor: auto;
}
.mdl-radio__button:focus + .mdl-radio__label + .mdl-radio__outer-circle + .mdl-radio__inner-circle {
box-shadow: 0 0 0 10px rgba(255, 255, 255, 0.76);
}
.mdl-radio__button:checked:focus + .mdl-radio__label + .mdl-radio__outer-circle + .mdl-radio__inner-circle {
box-shadow: 0 0 0 10px rgba(0, 164, 220, 0.26);
.mdl-radio.show-focus .mdl-radio__button:focus + .mdl-radio__circles .mdl-radio__focus-circle {
-webkit-transform: scale(1.75);
transform: scale(1.75);
}
.mdl-radio__label {

View File

@@ -1,4 +1,4 @@
define(['css!./emby-radio', 'registerElement'], function () {
define(['layoutManager', 'css!./emby-radio', 'registerElement'], function (layoutManager) {
'use strict';
var EmbyRadioPrototype = Object.create(HTMLInputElement.prototype);
@@ -6,16 +6,24 @@ define(['css!./emby-radio', 'registerElement'], function () {
function onKeyDown(e) {
// Don't submit form on enter
if (e.keyCode === 13) {
// Real (non-emulator) Tizen does nothing on Space
if (e.keyCode === 13 || e.keyCode === 32) {
e.preventDefault();
this.checked = true;
if (!this.checked) {
this.checked = true;
this.dispatchEvent(new CustomEvent('change', {
bubbles: true
}));
}
return false;
}
}
EmbyRadioPrototype.attachedCallback = function () {
var showFocus = !layoutManager.mobile;
if (this.getAttribute('data-radio') === 'true') {
return;
@@ -30,13 +38,36 @@ define(['css!./emby-radio', 'registerElement'], function () {
labelElement.classList.add('mdl-radio');
labelElement.classList.add('mdl-js-radio');
labelElement.classList.add('mdl-js-ripple-effect');
if (showFocus) {
labelElement.classList.add('show-focus');
}
var labelTextElement = labelElement.querySelector('span');
labelTextElement.classList.add('radioButtonLabel');
labelTextElement.classList.add('mdl-radio__label');
labelElement.insertAdjacentHTML('beforeend', '<span class="mdl-radio__outer-circle"></span><span class="mdl-radio__inner-circle"></span>');
var html = '';
html += '<div class="mdl-radio__circles">';
html += '<svg>';
html += '<defs>';
html += '<clipPath id="cutoff">';
html += '<circle cx="50%" cy="50%" r="50%" />';
html += '</clipPath>';
html += '</defs>';
html += '<circle class="mdl-radio__outer-circle" cx="50%" cy="50%" r="50%" fill="none" stroke="currentcolor" stroke-width="0.26em" clip-path="url(#cutoff)" />';
html += '<circle class="mdl-radio__inner-circle" cx="50%" cy="50%" r="25%" fill="currentcolor" />';
html += '</svg>';
if (showFocus) {
html += '<div class="mdl-radio__focus-circle"></div>';
}
html += '</div>';
this.insertAdjacentHTML('afterend', html);
this.addEventListener('keydown', onKeyDown);
};

View File

@@ -92,7 +92,7 @@
left: 0;
bottom: 0;
z-index: 1;
width: 10px;
width: 0.8em;
}
</style>
</head>

View File

@@ -176,8 +176,8 @@
</div>
<div id="additionalPartsCollapsible" class="verticalSection detailVerticalSection hide">
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderAdditionalParts}</h2>
<div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap"></div>
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderAdditionalParts}</h2>
<div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
</div>
<div class="verticalSection itemVerticalSection moreFromSeasonSection hide">
@@ -203,17 +203,17 @@
<div id="seriesScheduleSection" class="verticalSection detailVerticalSection hide">
<h2 class="sectionTitle padded-left padded-right">${HeaderUpcomingOnTV}</h2>
<div id="seriesScheduleList" is="emby-itemscontainer" class="itemsContainer vertical-list"></div>
<div id="seriesScheduleList" is="emby-itemscontainer" class="itemsContainer vertical-list padded-left padded-right"></div>
</div>
<div id="specialsCollapsible" class="verticalSection detailVerticalSection hide">
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderSpecialFeatures}</h2>
<div id="specialsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap"></div>
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderSpecialFeatures}</h2>
<div id="specialsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
</div>
<div id="musicVideosCollapsible" class="verticalSection detailVerticalSection hide">
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderMusicVideos}</h2>
<div id="musicVideosContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap"></div>
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderMusicVideos}</h2>
<div id="musicVideosContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
</div>
<div id="scenesCollapsible" class="verticalSection itemVerticalSection verticalSection-extrabottompadding hide">

View File

@@ -59,8 +59,8 @@ define(["libraries/apiclient/apiclientcore", "localassetmanager"], function(ApiC
})
}
function ApiClientEx(serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio) {
ApiClient.call(this, serverAddress, clientName, applicationVersion, deviceName, deviceId, devicePixelRatio)
function ApiClientEx(serverAddress, clientName, applicationVersion, deviceName, deviceId) {
ApiClient.call(this, serverAddress, clientName, applicationVersion, deviceName, deviceId)
}
var localPrefix = "local:",
localViewPrefix = "localview:";

View File

@@ -58,7 +58,7 @@ define(["events", "appStorage"], function(events, appStorage) {
return request.data && ("string" == typeof request.data ? fetchRequest.body = request.data : (fetchRequest.body = paramsToString(request.data), contentType = contentType || "application/x-www-form-urlencoded; charset=UTF-8")), contentType && (headers["Content-Type"] = contentType), request.timeout ? fetchWithTimeout(request.url, fetchRequest, request.timeout) : fetch(request.url, fetchRequest)
}
function ApiClient(serverAddress, appName, appVersion, deviceName, deviceId, devicePixelRatio) {
function ApiClient(serverAddress, appName, appVersion, deviceName, deviceId) {
if (!serverAddress) {
throw new Error("Must supply a serverAddress");
}
@@ -75,7 +75,6 @@ define(["events", "appStorage"], function(events, appStorage) {
this._deviceName = deviceName;
this._appName = appName;
this._appVersion = appVersion;
this._devicePixelRatio = devicePixelRatio;
}
function setSavedEndpointInfo(instance, info) {
@@ -218,7 +217,7 @@ define(["events", "appStorage"], function(events, appStorage) {
}
function normalizeImageOptions(instance, options) {
var ratio = instance._devicePixelRatio || 1;
var ratio = window.devicePixelRatio;
ratio && (options.minScale && (ratio = Math.max(options.minScale, ratio)), options.width && (options.width = Math.round(options.width * ratio)), options.height && (options.height = Math.round(options.height * ratio)), options.maxWidth && (options.maxWidth = Math.round(options.maxWidth * ratio)), options.maxHeight && (options.maxHeight = Math.round(options.maxHeight * ratio))), options.quality = options.quality || instance.getDefaultImageQuality(options.type), instance.normalizeImageOptions && instance.normalizeImageOptions(options)
}

View File

@@ -186,7 +186,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory
Manual: 2
};
var ConnectionManager = function (credentialProvider, appName, appVersion, deviceName, deviceId, capabilities, devicePixelRatio) {
var ConnectionManager = function (credentialProvider, appName, appVersion, deviceName, deviceId, capabilities) {
function onAuthenticated(apiClient, result, options, saveCredentials) {
var credentials = credentialProvider.credentials();
@@ -540,7 +540,7 @@ define(["events", "apiclient", "appStorage"], function (events, apiClientFactory
var apiClient = self.getApiClient(server.Id);
if (!apiClient) {
apiClient = new apiClientFactory(serverUrl, appName, appVersion, deviceName, deviceId, devicePixelRatio);
apiClient = new apiClientFactory(serverUrl, appName, appVersion, deviceName, deviceId);
self._apiClients.push(apiClient);
apiClient.serverInfo(server);
apiClient.onAuthenticated = function (instance, result) {

View File

@@ -5,7 +5,7 @@
<div class="verticalSection verticalSection-extrabottompadding">
<div class="sectionTitleContainer flex align-items-center">
<h2 class="sectionTitle">${TabNetworking}</h2>
<a is="emby-linkbutton" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/administration/networking.html">${Help}</a>
<a is="emby-linkbutton" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/networking/index.html">${Help}</a>
</div>
<div class="inputContainer">

View File

@@ -77,10 +77,10 @@ define([], function () {
var camel = prop.replace(/-([a-z]|[0-9])/ig, function (all, letter) {
return (letter + '').toUpperCase();
});
// Check if the property is supported
var support = (camel in el.style);
// Create test element
var el = document.createElement('div');
// Check if the property is supported
var support = (camel in el.style);
// Assign the property and value to invoke
// the CSS interpreter
el.style.cssText = prop + ':' + value;
@@ -271,6 +271,9 @@ define([], function () {
if (!browser.tizen) {
browser.orsay = userAgent.toLowerCase().indexOf('smarthub') !== -1;
} else {
var v = (navigator.appVersion).match(/Tizen (\d+).(\d+)/);
browser.tizenVersion = parseInt(v[1]);
}
if (browser.edgeUwp) {

View File

@@ -214,6 +214,15 @@ define(['browser'], function (browser) {
break;
case 'avi':
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
// New Samsung TV don't support XviD/DivX
// Explicitly add supported codecs to make other codecs be transcoded
if (browser.tizenVersion >= 4) {
videoCodecs.push('h264');
if (canPlayH265(videoTestElement, options)) {
videoCodecs.push('h265');
videoCodecs.push('hevc');
}
}
break;
case 'mpg':
case 'mpeg':
@@ -424,13 +433,9 @@ define(['browser'], function (browser) {
var supportsDts = browser.tizen || browser.orsay || browser.web0s || options.supportsDts;
if (self.tizen && self.tizen.systeminfo) {
var v = tizen.systeminfo.getCapability('http://tizen.org/feature/platform.version');
// DTS audio not supported in 2018 models (Tizen 4.0)
if (v && parseFloat(v) >= parseFloat('4.0')) {
supportsDts = false;
}
// DTS audio not supported in 2018 models (Tizen 4.0)
if (browser.tizenVersion >= 4) {
supportsDts = false;
}
if (supportsDts) {
@@ -757,6 +762,11 @@ define(['browser'], function (browser) {
maxH264Level = 51;
}
// Support H264 Level 52 (Tizen 5.0) - app only
if (browser.tizenVersion >= 5 && window.NativeShell) {
maxH264Level = 52;
}
if (browser.tizen || browser.orsay ||
videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, '')) {

View File

@@ -13,6 +13,7 @@ define(["browser"], function (browser) {
case "Kodi":
return baseUrl + "kodi.svg";
case "Jellyfin Android":
case "Android TV":
return baseUrl + "android.svg";
case "Jellyfin Web":
switch (device.Name || device.DeviceName) {

View File

@@ -58,7 +58,15 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], funct
sourceElement = focusManager.focusableParent(sourceElement);
}
sourceElement = sourceElement || document.activeElement || window;
if (!sourceElement) {
sourceElement = document.activeElement || window;
var dlg = document.querySelector('.dialogContainer .dialog.opened');
if (dlg && (!sourceElement || !dlg.contains(sourceElement))) {
sourceElement = dlg;
}
}
if (eventListenerCount) {
var customEvent = new CustomEvent("command", {

View File

@@ -243,15 +243,20 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder" data-itemid="selectserver" href="selectserver.html?showuser=1"><i class="material-icons navMenuOptionIcon">wifi</i><span class="navMenuOptionText">' + globalize.translate("ButtonSelectServer") + "</span></a>";
}
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder btnSettings" data-itemid="settings" href="#"><i class="material-icons navMenuOptionIcon settings"></i><span class="navMenuOptionText">' + globalize.translate("ButtonSettings") + "</span></a>";
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder btnLogout" data-itemid="logout" href="#"><i class="material-icons navMenuOptionIcon exit_to_app"></i><span class="navMenuOptionText">' + globalize.translate("ButtonSignOut") + "</span></a>";
html += "</div>";
}
// add buttons to navigation drawer
navDrawerScrollContainer.innerHTML = html;
// bind logout button click to method
var btnLogout = navDrawerScrollContainer.querySelector(".btnLogout");
var btnSettings = navDrawerScrollContainer.querySelector(".btnSettings");
if (btnSettings) {
btnSettings.addEventListener("click", onSettingsClick);
}
var btnLogout = navDrawerScrollContainer.querySelector(".btnLogout");
if (btnLogout) {
btnLogout.addEventListener("click", onLogoutClick);
}
@@ -598,6 +603,10 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
}
}
function onSettingsClick() {
Dashboard.navigate("mypreferencesmenu.html");
}
function onLogoutClick() {
Dashboard.logout();
}
@@ -788,7 +797,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
var headerCastButton;
var headerSearchButton;
var headerAudioPlayerButton;
var enableLibraryNavDrawer = !layoutManager.tv;
var enableLibraryNavDrawer = layoutManager.desktop;
var skinHeader = document.querySelector(".skinHeader");
var requiresUserRefresh = true;
var lastOpenTime = new Date().getTime();
@@ -863,6 +872,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
pageClassOn("pageshow", "page", function (e) {
var page = this;
var isDashboardPage = page.classList.contains("type-interior");
var isHomePage = page.classList.contains("homePage");
var isLibraryPage = !isDashboardPage && page.classList.contains("libraryPage");
var apiClient = getCurrentApiClient();
@@ -874,7 +884,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
refreshDashboardInfoInDrawer(apiClient);
} else {
if (mainDrawerButton) {
if (enableLibraryNavDrawer) {
if (enableLibraryNavDrawer || isHomePage) {
mainDrawerButton.classList.remove("hide");
} else {
mainDrawerButton.classList.add("hide");

View File

@@ -280,7 +280,7 @@ var AppInfo = {};
capabilities.DeviceProfile = deviceProfile;
var connectionManager = new ConnectionManager(credentialProviderInstance, apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId(), capabilities, window.devicePixelRatio);
var connectionManager = new ConnectionManager(credentialProviderInstance, apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId(), capabilities);
defineConnectionManager(connectionManager);
bindConnectionManagerEvents(connectionManager, events, userSettings);
@@ -291,7 +291,7 @@ var AppInfo = {};
return require(["apiclient"], function (apiClientFactory) {
console.debug("creating ApiClient singleton");
var apiClient = new apiClientFactory(Dashboard.serverAddress(), apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId(), window.devicePixelRatio);
var apiClient = new apiClientFactory(Dashboard.serverAddress(), apphost.appName(), apphost.appVersion(), apphost.deviceName(), apphost.deviceId());
apiClient.enableAutomaticNetworking = false;
apiClient.manualAddressOnly = true;

View File

@@ -1468,5 +1468,6 @@
"XmlTvPathHelp": "A path to a XMLTV file. Jellyfin will read this file and periodically check it for updates. You are responsible for creating and updating the file.",
"XmlTvSportsCategoriesHelp": "Programs with these categories will be displayed as sports programs. Separate multiple with '|'.",
"Yes": "Yes",
"Yesterday": "Yesterday"
"Yesterday": "Yesterday",
"UnsupportedPlayback": "Jellyfin cannot decrypt content protected by DRM but all content will be attempted regardless, including protected titles. Some files may appear completely black due to encryption or other unsupported features, such as interactive titles."
}

View File

@@ -382,7 +382,7 @@ a[data-role=button] {
.emby-checkbox:checked + span + .checkboxOutline {
background-color: #030322;
border: 2px solid rgb(72, 195, 200);
border: 0.14em solid rgb(72, 195, 200);
}
.emby-checkbox:checked + span + .checkboxOutline > .checkboxIcon-checked {
@@ -394,7 +394,7 @@ a[data-role=button] {
}
.emby-checkbox:focus:not(:checked) + span + .checkboxOutline {
border: 2px solid #ff77f1;
border: 0.14em solid #ff77f1;
}
.itemProgressBarForeground {
@@ -438,6 +438,15 @@ a[data-role=button] {
color: #f8f8fe;
}
.mdl-radio.show-focus .mdl-radio__button:focus + .mdl-radio__circles svg .mdl-radio__outer-circle,
.mdl-radio.show-focus .mdl-radio__button:focus + .mdl-radio__circles svg .mdl-radio__inner-circle {
color: #ff77f1;
}
.mdl-radio.show-focus .mdl-radio__button:focus + .mdl-radio__circles .mdl-radio__focus-circle {
background: #00a4dc;
}
.emby-tab-button {
color: #999;
}

View File

@@ -4,7 +4,7 @@
<form class="wizardStartForm">
<div>
<h1 style="float:left;">${WelcomeToProject}</h1>
<a is="emby-linkbutton" href="https://docs.jellyfin.org/general/administration/quick-start.html" target="_blank" class="raised raised-alt" style="float:right;margin-top:20px;">
<a is="emby-linkbutton" href="https://docs.jellyfin.org/general/quick-start.html" target="_blank" class="raised raised-alt" style="float:right;margin-top:20px;">
<span>${ButtonQuickStartGuide}</span>
</a>
</div>

View File

@@ -6,12 +6,12 @@ const CopyPlugin = require("copy-webpack-plugin");
const Assets = [
"alameda/alameda.js",
"native-promise-only/npo.js",
"libass-wasm/dist/subtitles-octopus-worker.js",
"libass-wasm/dist/subtitles-octopus-worker.data",
"libass-wasm/dist/subtitles-octopus-worker.wasm",
"libass-wasm/dist/subtitles-octopus-worker-legacy.js",
"libass-wasm/dist/subtitles-octopus-worker-legacy.data",
"libass-wasm/dist/subtitles-octopus-worker-legacy.js.mem"
"libass-wasm/dist/js/subtitles-octopus-worker.js",
"libass-wasm/dist/js/subtitles-octopus-worker.data",
"libass-wasm/dist/js/subtitles-octopus-worker.wasm",
"libass-wasm/dist/js/subtitles-octopus-worker-legacy.js",
"libass-wasm/dist/js/subtitles-octopus-worker-legacy.data",
"libass-wasm/dist/js/subtitles-octopus-worker-legacy.js.mem"
];
module.exports = {

1725
yarn.lock

File diff suppressed because it is too large Load Diff