${HeaderAdmin}
- +${HeaderContinueWatching}
${HeaderAccessScheduleHelp}
-${HeaderAccessScheduleHelp}
+- ${LabelYoureDone} -
- +${LabelYoureDone}
${WizardCompleted}
--
diff --git a/.gitignore b/.gitignore
index ce35528e1..2e12adf22 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,6 +81,9 @@ build/Release
node_modules/
jspm_packages/
+# Dependency lockfile
+package-lock.json
+
# TypeScript v1 declaration files
typings/
diff --git a/README.md b/README.md
index f9796e617..6a80b0b09 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
-
+
@@ -53,7 +53,7 @@ Jellyfin Web is the frontend used for most of the clients available for end user
git clone https://github.com/jellyfin/jellyfin-web.git
cd jellyfin-web
```
-2. Install build dependencies in the project directory via npm.
+2. Install build dependencies in the project directory.
```sh
yarn install
```
diff --git a/package.json b/package.json
index a7ef3f7e6..76d01b184 100644
--- a/package.json
+++ b/package.json
@@ -5,12 +5,14 @@
"repository": "https://github.com/jellyfin/jellyfin-web",
"license": "GPL-2.0-or-later",
"devDependencies": {
+ "autoprefixer": "^9.7.3",
"clean-webpack-plugin": "^3.0.0",
- "copy-webpack-plugin": "^5.0.3",
+ "copy-webpack-plugin": "^5.1.1",
"css-loader": "^2.1.0",
"eslint": "^5.16.0",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
+ "postcss-loader": "^3.0.0",
"style-loader": "^0.23.1",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9",
@@ -33,9 +35,25 @@
"shaka-player": "^2.5.5",
"sortablejs": "^1.9.0",
"swiper": "^3.4.2",
+ "libass-wasm": "^2.1.1",
"webcomponents.js": "^0.7.24",
"whatwg-fetch": "^1.1.1"
},
+ "browserslist": [
+ "last 2 Firefox versions",
+ "last 2 Chrome versions",
+ "last 2 ChromeAndroid versions",
+ "last 2 Safari versions",
+ "last 2 iOS versions",
+ "last 2 Edge versions",
+ "Chrome 38",
+ "Chrome 47",
+ "Chrome 53",
+ "Chrome 56",
+ "Chrome 63",
+ "Explorer 11",
+ "Firefox ESR"
+ ],
"scripts": {
"serve": "webpack-dev-server --config webpack.dev.js --open",
"build": "webpack --config webpack.prod.js",
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 000000000..a26de7e9f
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ plugins: [
+ require('autoprefixer')
+ ]
+}
diff --git a/src/css/clearbutton.css b/src/assets/css/clearbutton.css
similarity index 100%
rename from src/css/clearbutton.css
rename to src/assets/css/clearbutton.css
diff --git a/src/css/dashboard.css b/src/assets/css/dashboard.css
similarity index 83%
rename from src/css/dashboard.css
rename to src/assets/css/dashboard.css
index 1c69dfccb..d4928db69 100644
--- a/src/css/dashboard.css
+++ b/src/assets/css/dashboard.css
@@ -1,7 +1,6 @@
.dashboardColumn,
.dashboardSections {
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal
+ flex-direction: column;
}
.dashboardFooter {
@@ -15,8 +14,6 @@
progress {
appearance: none;
- -moz-appearance: none;
- -webkit-appearance: none;
margin: 0;
background: #ccc !important
}
@@ -76,23 +73,17 @@ progress[aria-valuenow]:before {
div[data-role=controlgroup] a[data-role=button] {
display: inline-block !important;
margin: 0 !important;
- -webkit-box-shadow: none !important;
box-shadow: none !important;
- -webkit-border-radius: 0;
border-radius: 0
}
div[data-role=controlgroup] a[data-role=button]:first-child {
- -webkit-border-bottom-left-radius: .3125em;
border-bottom-left-radius: .3125em;
- -webkit-border-top-left-radius: .3125em;
border-top-left-radius: .3125em
}
div[data-role=controlgroup] a[data-role=button]:last-child {
- -webkit-border-bottom-right-radius: .3125em;
border-bottom-right-radius: .3125em;
- -webkit-border-top-right-radius: .3125em;
border-top-right-radius: .3125em
}
@@ -146,23 +137,14 @@ div[data-role=controlgroup] a.ui-btn-active {
}
.dashboardSections {
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-flex-direction: column;
flex-direction: column
}
.dashboardColumn {
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-flex-direction: column;
flex-direction: column;
- -webkit-flex-shrink: 0;
flex-shrink: 0;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
flex-grow: 1
}
@@ -171,7 +153,6 @@ div[data-role=controlgroup] a.ui-btn-active {
}
.dashboardSection {
- -webkit-flex-shrink: 0;
flex-shrink: 0;
margin: 0 0 2em
}
@@ -187,11 +168,7 @@ div[data-role=controlgroup] a.ui-btn-active {
@media all and (min-width:70em) {
.dashboardSections {
- -webkit-flex-wrap: wrap;
flex-wrap: wrap;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -webkit-flex-direction: row;
flex-direction: row
}
@@ -296,7 +273,6 @@ div[data-role=controlgroup] a.ui-btn-active {
}
.sessionNowPlayingContent {
- -webkit-background-size: cover;
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
@@ -395,7 +371,6 @@ div[data-role=controlgroup] a.ui-btn-active {
}
.disabledUser {
- -webkit-filter: grayscale(100%);
filter: grayscale(100%)
}
@@ -416,9 +391,7 @@ div[data-role=controlgroup] a.ui-btn-active {
}
a[data-role=button] {
- -webkit-font-smoothing: antialiased;
- -webkit-user-select: none;
- -webkit-background-clip: padding-box;
+ background-clip: padding-box;
cursor: pointer !important;
font-family: inherit !important;
font-weight: 500 !important;
@@ -430,37 +403,21 @@ a[data-role=button] {
background: #292929 !important;
}
-@-webkit-keyframes rotating {
- from {
- -webkit-transform: rotate(0);
- transform: rotate(0)
- }
-
- to {
- -webkit-transform: rotate(360deg);
- transform: rotate(360deg)
- }
-}
-
@keyframes rotating {
from {
- -webkit-transform: rotate(0);
transform: rotate(0)
}
to {
- -webkit-transform: rotate(360deg);
transform: rotate(360deg)
}
}
.rotatingCircle {
- -webkit-animation: rotating 2s linear infinite;
animation: rotating 2s linear infinite
}
.pluginPreviewImg {
- -webkit-box-shadow: 0 .0725em .29em 0 rgba(0, 0, 0, .37);
box-shadow: 0 .0725em .29em 0 rgba(0, 0, 0, .37)
}
diff --git a/src/css/detailtable.css b/src/assets/css/detailtable.css
similarity index 100%
rename from src/css/detailtable.css
rename to src/assets/css/detailtable.css
diff --git a/src/css/flexstyles.css b/src/assets/css/flexstyles.css
similarity index 100%
rename from src/css/flexstyles.css
rename to src/assets/css/flexstyles.css
diff --git a/src/css/fonts.css b/src/assets/css/fonts.css
similarity index 95%
rename from src/css/fonts.css
rename to src/assets/css/fonts.css
index 12f1eaf4b..da5515fc1 100644
--- a/src/css/fonts.css
+++ b/src/assets/css/fonts.css
@@ -4,7 +4,6 @@ html {
html {
font-size: 93%;
- -webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
}
diff --git a/src/css/fonts.sized.css b/src/assets/css/fonts.sized.css
similarity index 100%
rename from src/css/fonts.sized.css
rename to src/assets/css/fonts.sized.css
diff --git a/src/css/ios.css b/src/assets/css/ios.css
similarity index 100%
rename from src/css/ios.css
rename to src/assets/css/ios.css
diff --git a/src/css/librarybrowser.css b/src/assets/css/librarybrowser.css
similarity index 76%
rename from src/css/librarybrowser.css
rename to src/assets/css/librarybrowser.css
index 8982ba88b..af106959e 100644
--- a/src/css/librarybrowser.css
+++ b/src/assets/css/librarybrowser.css
@@ -15,7 +15,6 @@
.headerSelectedPlayer,
.itemMiscInfo,
.navMenuOptionText {
- -o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden
}
@@ -25,7 +24,7 @@
}
.itemDetailPage {
- padding-top: 4em !important
+ padding-top: 0em !important
}
.standalonePage {
@@ -48,8 +47,6 @@
z-index: 1;
margin: 0 !important;
top: 6.9em !important;
- -webkit-transition: -webkit-transform .2s ease-out;
- -o-transition: transform .2s ease-out;
transition: transform .2s ease-out
}
@@ -58,17 +55,14 @@
}
.headerUserImage {
- -webkit-background-size: contain;
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
- -webkit-border-radius: 100em;
border-radius: 100em;
display: inline-block
}
.headerUserButtonRound div {
- -webkit-border-radius: 100em;
border-radius: 100em;
background-size: cover;
background-repeat: no-repeat;
@@ -76,7 +70,6 @@
}
.headerButton {
- -webkit-flex-shrink: 0;
flex-shrink: 0
}
@@ -90,34 +83,25 @@
}
.pageTitle {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
display: inline-flex;
- margin: 0 0 0 .5em;
+ margin: .3em 0 0 .5em;
height: 1.7em;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center;
- -webkit-flex-shrink: 1;
flex-shrink: 1
}
.headerLeft,
.skinHeader {
- display: -webkit-box;
- display: -webkit-flex
+ display: flex;
}
.detailButton-mobile,
.skinHeader {
- -webkit-flex-direction: column;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal
+ flex-direction: column;
}
.pageTitleWithLogo {
background-position: left center;
- -webkit-background-size: contain;
background-size: contain;
background-repeat: no-repeat;
width: 13.2em
@@ -137,7 +121,7 @@
.headerLeft,
.headerRight {
- -webkit-box-align: center
+ justify-content: center;
}
.hiddenViewMenuBar .skinHeader {
@@ -150,12 +134,10 @@
.headerLeft {
display: flex;
- -webkit-align-items: center;
align-items: center;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
flex-grow: 1;
- overflow: hidden
+ overflow: hidden;
+ justify-content: left;
}
.sectionTabs {
@@ -163,13 +145,8 @@
}
.headerRight {
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-align-items: center;
align-items: center;
- -webkit-box-pack: end;
- -webkit-justify-content: flex-end;
justify-content: flex-end
}
@@ -178,27 +155,19 @@
}
.navMenuOption {
- display: -webkit-box !important;
- display: -webkit-flex !important;
display: flex !important;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center;
text-decoration: none;
color: inherit;
padding: .9em 0 .9em 2.4em !important;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
flex-grow: 1;
font-weight: 400 !important;
margin: 0 !important;
- -webkit-border-radius: 0 !important;
border-radius: 0 !important
}
.navMenuOptionIcon {
margin-right: 1.2em;
- -webkit-flex-shrink: 0;
flex-shrink: 0
}
@@ -212,8 +181,6 @@
}
.dashboardDocument .skinBody {
- -webkit-transition: left ease-in-out .3s, padding ease-in-out .3s;
- -o-transition: left ease-in-out .3s, padding ease-in-out .3s;
transition: left ease-in-out .3s, padding ease-in-out .3s;
position: absolute;
top: 0;
@@ -233,6 +200,7 @@
}
@media all and (min-width:40em) {
+
.dashboardDocument .adminDrawerLogo,
.dashboardDocument .mainDrawerButton {
display: none !important
@@ -242,9 +210,7 @@
z-index: inherit !important;
left: 0 !important;
top: 0 !important;
- -webkit-transform: none !important;
transform: none !important;
- -webkit-box-shadow: none !important;
box-shadow: none !important;
width: 20.205em !important;
font-size: 94%
@@ -281,14 +247,9 @@
}
.headerTabs {
- -webkit-align-self: center;
align-self: center;
width: auto;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center;
- -webkit-box-pack: center;
- -webkit-justify-content: center;
justify-content: center;
margin-top: -3.34em;
position: relative;
@@ -346,8 +307,6 @@
}
.flexPageTabContent.is-active {
- display: -webkit-box !important;
- display: -webkit-flex !important;
display: flex !important
}
@@ -363,7 +322,6 @@
margin: 1.5em 0;
background: #222;
padding: .8em .8em .8em 3em;
- -webkit-border-radius: .3em;
border-radius: .3em;
position: relative
}
@@ -422,8 +380,9 @@
}
.itemBackdrop {
- -webkit-background-size: cover;
background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
height: 50vh;
position: relative
}
@@ -435,41 +394,73 @@
right: 0
}
-.itemBackdropFader {
- position: absolute;
- bottom: -1px;
- left: 0;
- right: 0;
- height: 15vh
-}
-
.desktopMiscInfoContainer {
position: absolute;
bottom: .75em
}
+.layout-mobile .detailPagePrimaryContainer {
+ display: block;
+ position: relative;
+}
+
+.layout-tv .detailPagePrimaryContainer {
+ position: relative;
+}
+
+.detailPagePrimaryContainer {
+ display: flex;
+ align-items: center;
+ align-content: center;
+ position: sticky;
+ background-color: #101010;
+ top: 0;
+ z-index: 2;
+}
+
+.infoWrapper {
+ flex: 1 0 0;
+}
+
+.infoText {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ text-align: left;
+}
+
+.detailPageSecondaryContainer {
+ margin: 1.25em 0;
+ display: flex;
+ flex-direction: column;
+ padding-left: 2%;
+ padding-right: 2%;
+}
+
+.layout-mobile .detailImageContainer,
+.layout-tv .detailImageContainer {
+ position: relative;
+}
+
.detailImageContainer {
- margin-right: 2em;
- width: 280px;
- -webkit-flex-shrink: 0;
- flex-shrink: 0;
- margin-left: .6em
+ margin: 1.25em 0;
+ position: sticky;
+ top: 15%;
+ float: left;
+ width: 22.786458333333332vw;
}
.detailPagePrimaryContent {
position: relative;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
flex-grow: 1
}
.detailLogo {
- width: 21.3em;
- height: 5em;
+ width: 25em;
+ height: 9.375em;
position: absolute;
- top: 13.5%;
- right: 19.5%;
- -webkit-background-size: contain;
+ top: 14.5%;
+ right: 10.5%;
background-size: contain
}
@@ -498,13 +489,8 @@
}
.itemDetailImage {
- width: 100%;
- -webkit-box-shadow: 0 .0725em .29em 0 rgba(0, 0, 0, .37);
- box-shadow: 0 .0725em .29em 0 rgba(0, 0, 0, .37)
-}
-
-.thumbDetailImageContainer {
- width: 400px
+ width: 100% !important;
+ box-shadow: 0 .0725em .29em 0 rgba(0, 0, 0, .37);
}
@media all and (max-width:62.5em) {
@@ -512,36 +498,11 @@
position: relative
}
- .detailImageContainer {
- position: absolute;
- top: -90px;
- left: 5%;
- width: auto
- }
-
- .itemDetailImage {
- height: 120px;
- width: auto !important
- }
-
.btnPlaySimple {
display: none !important
}
}
-@media all and (min-width:62.5em) {
- .itemBackdrop {
- display: none
- }
-
- .detailPagePrimaryContainer {
- display: -webkit-box;
- display: -webkit-flex;
- display: flex;
- margin-bottom: 3em
- }
-}
-
@media all and (max-width:75em) {
.lnkSibling {
display: none !important
@@ -597,8 +558,7 @@
.detailButton-mobile,
.mainDetailButtons {
- display: -webkit-box;
- display: -webkit-flex
+ display: flex;
}
.itemName {
@@ -619,18 +579,14 @@
.mainDetailButtons {
display: flex;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center;
- -webkit-flex-wrap: wrap;
flex-wrap: wrap;
- margin: 1em 0
+ margin: 1em 0;
}
.recordingFields button {
margin-left: 0;
margin-right: .5em;
- -webkit-flex-shrink: 0;
flex-shrink: 0
}
@@ -641,11 +597,7 @@
.detailButton-mobile {
display: flex;
flex-direction: column;
- -webkit-box-pack: center;
- -webkit-justify-content: center;
justify-content: center;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center;
margin: 0 !important;
padding: .5em .7em !important
@@ -677,18 +629,9 @@
}
.detailButton-mobile-content {
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -webkit-flex-direction: column;
flex-direction: column;
- -webkit-box-pack: center;
- -webkit-justify-content: center;
justify-content: center;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center
}
@@ -699,11 +642,8 @@
}
.detailImageProgressContainer {
- position: absolute;
- bottom: 4px;
- right: 1px;
- left: 1px;
- text-align: center
+ margin-left: 6px;
+ width: 21.886458333333332vw;
}
.detailButton-mobile-text {
@@ -723,7 +663,7 @@
}
@media all and (min-width:62.5em) {
- .detailButton-mobile {
+ .detailFloatingButton {
display: none !important
}
@@ -745,21 +685,14 @@
}
.itemMiscInfo {
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-flex-wrap: wrap;
flex-wrap: wrap;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center
}
@media all and (max-width:31.25em) {
.mobileDetails .itemMiscInfo {
text-align: center;
- -webkit-box-pack: center;
- -webkit-justify-content: center;
justify-content: center
}
@@ -775,13 +708,11 @@
.detailPageContent {
border-spacing: 0;
border-collapse: collapse;
- padding-top: 3em
}
@media all and (max-width:62.5em) {
.detailPageContent-nodetailimg {
padding-top: 0;
- margin-top: -3em
}
}
@@ -851,7 +782,6 @@
}
.btnSyncComplete i {
- -webkit-border-radius: 100em;
border-radius: 100em
}
@@ -860,14 +790,9 @@
}
.mediaInfoIcons {
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center;
margin: 1em 0;
- -webkit-flex-wrap: wrap;
flex-wrap: wrap
}
@@ -892,17 +817,19 @@
vertical-align: middle;
}
+/* these next two rules are for the scroller element headers */
.sectionTitleContainer-cards {
- margin-bottom: 0;
+ margin: 0;
+ padding-top: 1.25em;
}
-.sectionTitle-cards {
- margin-bottom: 0;
+div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
+ margin: 0;
+ padding-top: 1.25em;
}
.sectionTitleButton {
margin-left: 1.5em !important;
- -webkit-flex-shrink: 0;
flex-shrink: 0
}
@@ -912,22 +839,17 @@
.sectionTitleIconButton {
margin-left: 1.5em !important;
- -webkit-flex-shrink: 0;
flex-shrink: 0;
font-size: 84% !important;
padding: .5em !important
}
.horizontalItemsContainer {
- display: -webkit-box;
- display: -webkit-flex;
display: flex
}
.sectionTitleTextButton {
margin: 0 !important;
- display: -webkit-inline-box !important;
- display: -webkit-inline-flex !important;
display: inline-flex !important;
color: inherit !important
}
@@ -999,8 +921,6 @@
}
.itemsViewSettingsContainer {
- -webkit-box-pack: center;
- -webkit-justify-content: center;
justify-content: center
}
diff --git a/src/css/livetv.css b/src/assets/css/livetv.css
similarity index 100%
rename from src/css/livetv.css
rename to src/assets/css/livetv.css
diff --git a/src/css/material-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.woff b/src/assets/css/material-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.woff
similarity index 100%
rename from src/css/material-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.woff
rename to src/assets/css/material-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNa.woff
diff --git a/src/css/material-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2 b/src/assets/css/material-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2
similarity index 100%
rename from src/css/material-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2
rename to src/assets/css/material-icons/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2
diff --git a/src/css/material-icons/style.css b/src/assets/css/material-icons/style.css
similarity index 100%
rename from src/css/material-icons/style.css
rename to src/assets/css/material-icons/style.css
diff --git a/src/css/metadataeditor.css b/src/assets/css/metadataeditor.css
similarity index 88%
rename from src/css/metadataeditor.css
rename to src/assets/css/metadataeditor.css
index 542c7c8f2..c5de6f3ef 100644
--- a/src/css/metadataeditor.css
+++ b/src/assets/css/metadataeditor.css
@@ -28,17 +28,13 @@
.jstree-wholerow-hovered {
background: #38c !important;
- -webkit-border-radius: 0 !important;
border-radius: 0 !important;
- -webkit-box-shadow: none !important;
box-shadow: none !important
}
.jstree-default .jstree-hovered {
background: 0 0 !important;
- -webkit-border-radius: 0 !important;
border-radius: 0 !important;
- -webkit-box-shadow: none !important;
box-shadow: none !important;
color: #fff !important
}
diff --git a/src/css/scrollstyles.css b/src/assets/css/scrollstyles.css
similarity index 58%
rename from src/css/scrollstyles.css
rename to src/assets/css/scrollstyles.css
index aa2f7dafa..69039ce34 100644
--- a/src/css/scrollstyles.css
+++ b/src/assets/css/scrollstyles.css
@@ -1,6 +1,5 @@
.scrollX {
overflow-x: auto;
- -webkit-overflow-scrolling: touch;
overflow-y: hidden;
white-space: nowrap;
}
@@ -10,13 +9,11 @@
}
.hiddenScrollX, .layout-tv .scrollX {
- -ms-overflow-style: none;
- /* Can't do this because it not only hides the scrollbar, but also prevents scrolling */
- /*overflow: -moz-scrollbars-none;*/
+ scrollbar-width: none;
}
.hiddenScrollX-forced {
- overflow: -moz-scrollbars-none;
+ scrollbar-width: none;
}
.hiddenScrollX::-webkit-scrollbar, .layout-tv .scrollX::-webkit-scrollbar {
@@ -26,28 +23,24 @@
.scrollY {
overflow-y: auto;
- -webkit-overflow-scrolling: touch;
overflow-x: hidden;
}
.smoothScrollY {
overflow-y: auto;
- -webkit-overflow-scrolling: touch;
overflow-x: hidden;
scroll-behavior: smooth;
}
.hiddenScrollY, .layout-tv .smoothScrollY {
- -ms-overflow-style: none;
- /* Can't do this because it not only hides the scrollbar, but also prevents scrolling */
- /*overflow: -moz-scrollbars-none;*/
+ scrollbar-width: none;
}
.hiddenScrollY-forced {
- overflow: -moz-scrollbars-none;
+ scrollbar-width: none;
}
.hiddenScrollY::-webkit-scrollbar, .layout-tv .smoothScrollY::-webkit-scrollbar, .layout-tv .scrollY::-webkit-scrollbar {
width: 0 !important;
display: none;
-}
\ No newline at end of file
+}
diff --git a/src/css/site.css b/src/assets/css/site.css
similarity index 87%
rename from src/css/site.css
rename to src/assets/css/site.css
index 292fc6745..649179911 100644
--- a/src/css/site.css
+++ b/src/assets/css/site.css
@@ -20,18 +20,12 @@ html {
.layout-mobile,
.layout-tv {
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
user-select: none
}
body {
overflow-x: hidden;
background-color: transparent !important;
- -webkit-font-smoothing: antialiased
}
.mainAnimatedPage {
diff --git a/src/css/videoosd.css b/src/assets/css/videoosd.css
similarity index 64%
rename from src/css/videoosd.css
rename to src/assets/css/videoosd.css
index f9c4798e9..f20abf9d0 100644
--- a/src/css/videoosd.css
+++ b/src/assets/css/videoosd.css
@@ -1,8 +1,6 @@
.chapterThumbTextContainer,
.videoOsdBottom {
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none
+ user-select: none;
}
.osdPoster img,
@@ -14,13 +12,10 @@
}
.osdHeader {
- -webkit-transition: opacity .3s ease-out;
- -o-transition: opacity .3s ease-out;
transition: opacity .3s ease-out;
position: relative;
z-index: 1;
background: rgba(0, 0, 0, 0.7) !important;
- -webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
color: #eee !important;
}
@@ -34,17 +29,13 @@
}
.chapterThumbContainer {
- -webkit-box-shadow: 0 0 1.9vh #000;
box-shadow: 0 0 1.9vh #000;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
flex-grow: 1;
position: relative
}
.chapterThumb {
background-position: center center;
- -webkit-background-size: contain;
background-size: contain;
background-repeat: no-repeat;
border: 0;
@@ -90,20 +81,12 @@
position: fixed;
background-color: rgba(0, 0, 0, 0.7);
padding: 1%;
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -webkit-flex-direction: row;
flex-direction: row;
will-change: opacity;
- -webkit-transition: opacity 0.3s ease-out;
- -o-transition: opacity 0.3s ease-out;
transition: opacity 0.3s ease-out;
color: #fff;
- user-select: none;
- -webkit-touch-callout: none
+ user-select: none
}
.videoOsdBottom-hidden {
@@ -111,49 +94,35 @@
}
.osdControls {
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
flex-grow: 1
}
.videoOsdBottom .buttons {
padding: .25em 0 0;
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-flex-wrap: wrap;
flex-wrap: wrap;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center
}
.osdVolumeSliderContainer {
width: 9em;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
flex-grow: 1
}
.osdMediaInfo,
.volumeButtons {
- display: -webkit-box;
- display: -webkit-flex;
- -webkit-box-align: center
+ display: flex;
+ align-items: center;
}
.volumeButtons {
margin: 0 .5em 0 auto;
display: flex;
- -webkit-align-items: center;
align-items: center
}
.osdTimeText {
margin-left: 1em;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
user-select: none
}
@@ -167,15 +136,10 @@
position: absolute;
height: auto;
width: 100%;
- -webkit-box-shadow: 0 0 1.9vh #000;
box-shadow: 0 0 1.9vh #000;
border: .08em solid #222;
user-drag: none;
- user-select: none;
- -moz-user-select: none;
- -webkit-user-drag: none;
- -webkit-user-select: none;
- -ms-user-select: none
+ user-select: none
}
.osdTitle,
@@ -185,7 +149,6 @@
.osdMediaInfo {
display: flex;
- -webkit-align-items: center;
align-items: center
}
@@ -194,23 +157,14 @@
}
.osdTextContainer {
- display: -webkit-box;
- display: -webkit-flex;
display: flex;
- -webkit-box-align: center;
- -webkit-align-items: center;
align-items: center;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
user-select: none;
margin-bottom: .7em;
padding-left: .5em
}
.osdMainTextContainer {
- -webkit-box-align: baseline;
- -webkit-align-items: baseline;
align-items: baseline
}
@@ -218,12 +172,13 @@
margin-left: auto;
}
-@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
-@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
-@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
+@keyframes spin {
+ 100% {
+ transform:rotate(360deg);
+ }
+}
+
.osdMediaStatus .animate {
- -webkit-animation:spin 4s linear infinite;
- -moz-animation:spin 4s linear infinite;
animation:spin 4s linear infinite;
}
diff --git a/src/img/logindefault.png b/src/assets/img/avatar.png
similarity index 100%
rename from src/img/logindefault.png
rename to src/assets/img/avatar.png
diff --git a/src/assets/img/devices/android.svg b/src/assets/img/devices/android.svg
new file mode 100644
index 000000000..c0d377bb7
--- /dev/null
+++ b/src/assets/img/devices/android.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/src/img/devices/chrome.svg b/src/assets/img/devices/chrome.svg
similarity index 100%
rename from src/img/devices/chrome.svg
rename to src/assets/img/devices/chrome.svg
diff --git a/src/img/devices/edge.svg b/src/assets/img/devices/edge.svg
similarity index 100%
rename from src/img/devices/edge.svg
rename to src/assets/img/devices/edge.svg
diff --git a/src/img/devices/firefox.svg b/src/assets/img/devices/firefox.svg
similarity index 100%
rename from src/img/devices/firefox.svg
rename to src/assets/img/devices/firefox.svg
diff --git a/src/img/devices/html5.svg b/src/assets/img/devices/html5.svg
similarity index 100%
rename from src/img/devices/html5.svg
rename to src/assets/img/devices/html5.svg
diff --git a/src/assets/img/devices/kodi.svg b/src/assets/img/devices/kodi.svg
new file mode 100644
index 000000000..3618149b1
--- /dev/null
+++ b/src/assets/img/devices/kodi.svg
@@ -0,0 +1,11 @@
+
+
diff --git a/src/img/devices/msie.svg b/src/assets/img/devices/msie.svg
similarity index 100%
rename from src/img/devices/msie.svg
rename to src/assets/img/devices/msie.svg
diff --git a/src/img/devices/opera.svg b/src/assets/img/devices/opera.svg
similarity index 100%
rename from src/img/devices/opera.svg
rename to src/assets/img/devices/opera.svg
diff --git a/src/img/devices/other.svg b/src/assets/img/devices/other.svg
similarity index 100%
rename from src/img/devices/other.svg
rename to src/assets/img/devices/other.svg
diff --git a/src/img/devices/playstation.svg b/src/assets/img/devices/playstation.svg
similarity index 100%
rename from src/img/devices/playstation.svg
rename to src/assets/img/devices/playstation.svg
diff --git a/src/img/devices/safari.svg b/src/assets/img/devices/safari.svg
similarity index 100%
rename from src/img/devices/safari.svg
rename to src/assets/img/devices/safari.svg
diff --git a/src/img/devices/samsungtv.svg b/src/assets/img/devices/samsungtv.svg
similarity index 100%
rename from src/img/devices/samsungtv.svg
rename to src/assets/img/devices/samsungtv.svg
diff --git a/src/img/devices/windows.svg b/src/assets/img/devices/windows.svg
similarity index 100%
rename from src/img/devices/windows.svg
rename to src/assets/img/devices/windows.svg
diff --git a/src/img/devices/xbox.svg b/src/assets/img/devices/xbox.svg
similarity index 100%
rename from src/img/devices/xbox.svg
rename to src/assets/img/devices/xbox.svg
diff --git a/src/img/equalizer.gif b/src/assets/img/equalizer.gif
similarity index 100%
rename from src/img/equalizer.gif
rename to src/assets/img/equalizer.gif
diff --git a/src/img/logo.png b/src/assets/img/logo.png
similarity index 100%
rename from src/img/logo.png
rename to src/assets/img/logo.png
diff --git a/src/splashscreens/ipad_splash.png b/src/assets/splash/ipad_splash.png
similarity index 100%
rename from src/splashscreens/ipad_splash.png
rename to src/assets/splash/ipad_splash.png
diff --git a/src/splashscreens/ipad_splash_l.png b/src/assets/splash/ipad_splash_l.png
similarity index 100%
rename from src/splashscreens/ipad_splash_l.png
rename to src/assets/splash/ipad_splash_l.png
diff --git a/src/splashscreens/ipadpro1_splash.png b/src/assets/splash/ipadpro1_splash.png
similarity index 100%
rename from src/splashscreens/ipadpro1_splash.png
rename to src/assets/splash/ipadpro1_splash.png
diff --git a/src/splashscreens/ipadpro1_splash_l.png b/src/assets/splash/ipadpro1_splash_l.png
similarity index 100%
rename from src/splashscreens/ipadpro1_splash_l.png
rename to src/assets/splash/ipadpro1_splash_l.png
diff --git a/src/splashscreens/ipadpro2_splash.png b/src/assets/splash/ipadpro2_splash.png
similarity index 100%
rename from src/splashscreens/ipadpro2_splash.png
rename to src/assets/splash/ipadpro2_splash.png
diff --git a/src/splashscreens/ipadpro2_splash_l.png b/src/assets/splash/ipadpro2_splash_l.png
similarity index 100%
rename from src/splashscreens/ipadpro2_splash_l.png
rename to src/assets/splash/ipadpro2_splash_l.png
diff --git a/src/splashscreens/ipadpro3_splash.png b/src/assets/splash/ipadpro3_splash.png
similarity index 100%
rename from src/splashscreens/ipadpro3_splash.png
rename to src/assets/splash/ipadpro3_splash.png
diff --git a/src/splashscreens/ipadpro3_splash_l.png b/src/assets/splash/ipadpro3_splash_l.png
similarity index 100%
rename from src/splashscreens/ipadpro3_splash_l.png
rename to src/assets/splash/ipadpro3_splash_l.png
diff --git a/src/splashscreens/iphone5_splash.png b/src/assets/splash/iphone5_splash.png
similarity index 100%
rename from src/splashscreens/iphone5_splash.png
rename to src/assets/splash/iphone5_splash.png
diff --git a/src/splashscreens/iphone5_splash_l.png b/src/assets/splash/iphone5_splash_l.png
similarity index 100%
rename from src/splashscreens/iphone5_splash_l.png
rename to src/assets/splash/iphone5_splash_l.png
diff --git a/src/splashscreens/iphone6_splash.png b/src/assets/splash/iphone6_splash.png
similarity index 100%
rename from src/splashscreens/iphone6_splash.png
rename to src/assets/splash/iphone6_splash.png
diff --git a/src/splashscreens/iphone6_splash_l.png b/src/assets/splash/iphone6_splash_l.png
similarity index 100%
rename from src/splashscreens/iphone6_splash_l.png
rename to src/assets/splash/iphone6_splash_l.png
diff --git a/src/splashscreens/iphoneplus_splash.png b/src/assets/splash/iphoneplus_splash.png
similarity index 100%
rename from src/splashscreens/iphoneplus_splash.png
rename to src/assets/splash/iphoneplus_splash.png
diff --git a/src/splashscreens/iphoneplus_splash_l.png b/src/assets/splash/iphoneplus_splash_l.png
similarity index 100%
rename from src/splashscreens/iphoneplus_splash_l.png
rename to src/assets/splash/iphoneplus_splash_l.png
diff --git a/src/splashscreens/iphonex_splash.png b/src/assets/splash/iphonex_splash.png
similarity index 100%
rename from src/splashscreens/iphonex_splash.png
rename to src/assets/splash/iphonex_splash.png
diff --git a/src/splashscreens/iphonex_splash_l.png b/src/assets/splash/iphonex_splash_l.png
similarity index 100%
rename from src/splashscreens/iphonex_splash_l.png
rename to src/assets/splash/iphonex_splash_l.png
diff --git a/src/splashscreens/iphonexr_splash.png b/src/assets/splash/iphonexr_splash.png
similarity index 100%
rename from src/splashscreens/iphonexr_splash.png
rename to src/assets/splash/iphonexr_splash.png
diff --git a/src/splashscreens/iphonexr_splash_l.png b/src/assets/splash/iphonexr_splash_l.png
similarity index 100%
rename from src/splashscreens/iphonexr_splash_l.png
rename to src/assets/splash/iphonexr_splash_l.png
diff --git a/src/splashscreens/iphonexsmax_splash.png b/src/assets/splash/iphonexsmax_splash.png
similarity index 100%
rename from src/splashscreens/iphonexsmax_splash.png
rename to src/assets/splash/iphonexsmax_splash.png
diff --git a/src/splashscreens/iphonexsmax_splash_l.png b/src/assets/splash/iphonexsmax_splash_l.png
similarity index 100%
rename from src/splashscreens/iphonexsmax_splash_l.png
rename to src/assets/splash/iphonexsmax_splash_l.png
diff --git a/src/bundle.js b/src/bundle.js
index 508e2c306..54623fab7 100644
--- a/src/bundle.js
+++ b/src/bundle.js
@@ -17,7 +17,7 @@ _define("fetch", function() {
});
// flvjs
-var flvjs = require("flv.js");
+var flvjs = require("flv.js").default;
_define("flvjs", function() {
return flvjs;
});
@@ -54,7 +54,7 @@ _define("native-promise-only", function() {
});
// resize-observer-polyfill
-var resize = require("resize-observer-polyfill");
+var resize = require("resize-observer-polyfill").default;
_define("resize-observer-polyfill", function() {
return resize;
});
@@ -73,7 +73,7 @@ _define("swiper", function() {
});
// sortable
-var sortable = require("sortablejs");
+var sortable = require("sortablejs").default;
_define("sortable", function() {
return sortable;
});
@@ -90,3 +90,9 @@ require("libjass/libjass.css");
_define("libjass", function() {
return libjass;
});
+
+// libass-wasm
+var libass_wasm = require("libass-wasm");
+_define("JavascriptSubtitlesOctopus", function() {
+ return libass_wasm;
+});
diff --git a/src/components/actionsheet/actionsheet.css b/src/components/actionsheet/actionsheet.css
index c1b169889..8e5084038 100644
--- a/src/components/actionsheet/actionsheet.css
+++ b/src/components/actionsheet/actionsheet.css
@@ -37,11 +37,12 @@
box-shadow: none;
flex-shrink: 0;
border-radius: 0;
+ margin: 0;
}
- .actionSheetMenuItem:focus {
- transform: none !important;
- }
+.actionSheetMenuItem:focus {
+ transform: none !important;
+}
.actionsheetListItemBody {
padding: .4em 1em .4em .6em !important;
@@ -104,7 +105,7 @@
}
.actionsheet-xlargeFont {
- font-size: 112%!important;
+ font-size: 112% !important;
}
.btnCloseActionSheet {
diff --git a/src/components/apphost.js b/src/components/apphost.js
index ad3540e21..b1b1c30dc 100644
--- a/src/components/apphost.js
+++ b/src/components/apphost.js
@@ -278,6 +278,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
features.push("targetblank");
// allows users to connect to more than one server
//features.push("multiserver");
+ features.push("screensaver");
if (!browser.orsay && !browser.tizen && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || cueSupported())) {
features.push("subtitleappearancesettings");
diff --git a/src/components/backdropscreensaver/plugin.js b/src/components/backdropscreensaver/plugin.js
new file mode 100644
index 000000000..c0bd31fb8
--- /dev/null
+++ b/src/components/backdropscreensaver/plugin.js
@@ -0,0 +1,56 @@
+define(["connectionManager"], function (connectionManager) {
+
+ return function () {
+
+ var self = this;
+
+ self.name = "Backdrop ScreenSaver";
+ self.type = "screensaver";
+ self.id = "backdropscreensaver";
+ self.supportsAnonymous = false;
+
+ var currentSlideshow;
+
+ self.show = function () {
+
+ var query = {
+ ImageTypes: "Backdrop",
+ EnableImageTypes: "Backdrop",
+ IncludeItemTypes: "Movie,Series,MusicArtist",
+ SortBy: "Random",
+ Recursive: true,
+ Fields: "Taglines",
+ ImageTypeLimit: 1,
+ StartIndex: 0,
+ Limit: 200
+ };
+
+ var apiClient = connectionManager.currentApiClient();
+ apiClient.getItems(apiClient.getCurrentUserId(), query).then(function (result) {
+
+ if (result.Items.length) {
+
+ require(["slideshow"], function (slideshow) {
+
+ var newSlideShow = new slideshow({
+ showTitle: true,
+ cover: true,
+ items: result.Items
+ });
+
+ newSlideShow.show();
+ currentSlideshow = newSlideShow;
+ });
+ }
+ });
+ };
+
+ self.hide = function () {
+
+ if (currentSlideshow) {
+ currentSlideshow.hide();
+ currentSlideshow = null;
+ }
+ };
+ }
+});
diff --git a/src/components/cardbuilder/card.css b/src/components/cardbuilder/card.css
index ec19c83f0..5520ce2c7 100644
--- a/src/components/cardbuilder/card.css
+++ b/src/components/cardbuilder/card.css
@@ -18,7 +18,6 @@ button {
padding: 0;
display: block;
color: inherit !important;
- -webkit-tap-highlight-color: rgba(0,0,0,0);
outline: none !important;
cursor: pointer;
contain: layout style;
@@ -80,10 +79,9 @@ button {
margin: 0.6em;
transition: none;
border: 0 solid transparent;
- /* These both are needed in case cardBox is a button */
- -webkit-tap-highlight-color: rgba(0,0,0,0);
outline: none !important;
- contain: layout style;
+ contain: layout;
+ contain: style;
}
.card.show-focus:not(.show-animation) .cardBox {
@@ -148,7 +146,6 @@ button {
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
- display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
@@ -182,7 +179,6 @@ button {
margin: 0 !important;
/* Needed in safari */
height: 100%;
- -webkit-tap-highlight-color: rgba(0,0,0,0);
outline: none !important;
contain: strict;
}
@@ -247,7 +243,7 @@ button {
}
.coveredImage {
- background-size: 100% 100%;
+ background-size: cover;
background-position: center center;
}
@@ -346,7 +342,6 @@ button {
border: 0 !important;
padding: 0 !important;
cursor: pointer;
- -webkit-tap-highlight-color: rgba(0,0,0,0);
outline: none !important;
color: inherit;
vertical-align: middle;
@@ -627,7 +622,7 @@ button {
@media (min-width: 43.75em) {
.overflowSquareCard, .overflowPortraitCard {
- width: 23.3vw;
+ width: 23.1vw;
}
}
@@ -643,13 +638,13 @@ button {
}
.overflowSquareCard, .overflowPortraitCard {
- width: 23.3vw;
+ width: 23.1vw;
}
}
@media (orientation: landscape) and (min-width: 48.125em) {
.overflowBackdropCard, .overflowSmallBackdropCard {
- width: 23.3vw;
+ width: 23.1vw;
}
}
@@ -661,13 +656,13 @@ button {
@media (min-width: 50em) {
.overflowSquareCard, .overflowPortraitCard {
- width: 18.4vw;
+ width: 18.5vw;
}
}
@media (min-width: 75em) {
.overflowBackdropCard, .overflowSmallBackdropCard {
- width: 23.3vw;
+ width: 23.1vw;
}
.overflowSquareCard, .overflowPortraitCard {
@@ -780,4 +775,4 @@ button {
.cardOverlayFab-primary:hover {
transform: scale(1.4, 1.4);
transition: 0.2s;
-}
\ No newline at end of file
+}
diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js
index 3b7516309..44c5b3b07 100644
--- a/src/components/cardbuilder/cardBuilder.js
+++ b/src/components/cardbuilder/cardBuilder.js
@@ -892,7 +892,8 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
} else {
if (item.EndDate && item.ProductionYear) {
- lines.push(item.ProductionYear + ' - ' + datetime.parseISO8601Date(item.EndDate).getFullYear());
+ var endYear = datetime.parseISO8601Date(item.EndDate).getFullYear();
+ lines.push(item.ProductionYear + ((endYear === item.ProductionYear) ? '' : (' - ' + endYear)));
} else {
lines.push(item.ProductionYear || '');
}
diff --git a/src/components/dialogHelper/dialoghelper.css b/src/components/dialogHelper/dialoghelper.css
index 2cc20b5ff..aa4145e01 100644
--- a/src/components/dialogHelper/dialoghelper.css
+++ b/src/components/dialogHelper/dialoghelper.css
@@ -16,7 +16,6 @@
.dialog {
margin: 0;
border-radius: .2em;
- -webkit-font-smoothing: antialiased;
border: 0;
padding: 0;
will-change: transform, opacity;
diff --git a/src/components/emby-scrollbuttons/emby-scrollbuttons.css b/src/components/emby-scrollbuttons/emby-scrollbuttons.css
index 007557be9..6786824bd 100644
--- a/src/components/emby-scrollbuttons/emby-scrollbuttons.css
+++ b/src/components/emby-scrollbuttons/emby-scrollbuttons.css
@@ -6,6 +6,7 @@
justify-content: center;
min-width:104px;
min-height:24px;
+ padding-top: 1.25em;
z-index: 1;
color: #ffffff;
display: flex;
@@ -15,4 +16,4 @@
min-width: 24px;
min-height: 24px;
display: block;
-}
\ No newline at end of file
+}
diff --git a/src/components/emby-scroller/emby-scroller.css b/src/components/emby-scroller/emby-scroller.css
index 1e0b05b83..11c2c7327 100644
--- a/src/components/emby-scroller/emby-scroller.css
+++ b/src/components/emby-scroller/emby-scroller.css
@@ -8,21 +8,15 @@
}
/* align first card in scroller to heading */
-.emby-scroller .card:first-of-type > .cardBox {
+.itemsContainer > .card > .cardBox {
margin-left: 0;
+ margin-right: 1.2em;
}
-/* align heading for normal item containers */
-/* still not ideal solution but better than the last method */
-.verticalSection > .itemsContainer .cardBox {
+.layout-tv .emby-scroller,
+.layout-mobile .emby-scroller {
+ padding-left: 3.3%;
+ padding-right: 3.3%;
margin-left: 0;
+ margin-right: 0;
}
-
-@media all and (max-width:50em) {
- .emby-scroller {
- padding-left: 3.3%;
- padding-right: 3.3%;
- margin-left: 0;
- margin-right: 0;
- }
-}
\ No newline at end of file
diff --git a/src/components/emby-tabs/emby-tabs.css b/src/components/emby-tabs/emby-tabs.css
index 00abd7efa..b8831b881 100644
--- a/src/components/emby-tabs/emby-tabs.css
+++ b/src/components/emby-tabs/emby-tabs.css
@@ -22,7 +22,7 @@
.emby-tab-button.show-focus:focus {
/* these buttons are small so scale larger than usual */
- transform: scale(1.6) !important;
+ transform: scale(1.3) !important;
background: 0 !important;
}
diff --git a/src/components/filterdialog/style.css b/src/components/filterdialog/style.css
index 5daf6eb38..69a82d240 100644
--- a/src/components/filterdialog/style.css
+++ b/src/components/filterdialog/style.css
@@ -5,7 +5,6 @@
margin-top: 0 !important;
margin-bottom: 0 !important;
margin-right: 0 !important;
- -webkit-border-radius: 0 !important;
border-radius: 0 !important;
max-height: none !important;
max-width: none !important
diff --git a/src/components/homesections/homesections.css b/src/components/homesections/homesections.css
index 45df67c48..5df2440f8 100644
--- a/src/components/homesections/homesections.css
+++ b/src/components/homesections/homesections.css
@@ -13,13 +13,11 @@
.homeLibraryIcon {
margin-left: .5em;
margin-right: .5em;
- -webkit-flex-shrink: 0;
flex-shrink: 0
}
.homeLibraryText {
white-space: nowrap;
- -o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden
}
diff --git a/src/components/htmlaudioplayer/plugin.js b/src/components/htmlaudioplayer/plugin.js
index 1b41cc544..ef64bad04 100644
--- a/src/components/htmlaudioplayer/plugin.js
+++ b/src/components/htmlaudioplayer/plugin.js
@@ -2,11 +2,8 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
"use strict";
function getDefaultProfile() {
-
return new Promise(function (resolve, reject) {
-
require(['browserdeviceprofile'], function (profileBuilder) {
-
resolve(profileBuilder({}));
});
});
@@ -14,28 +11,22 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
var fadeTimeout;
function fade(instance, elem, startingVolume) {
-
instance._isFadingOut = true;
// Need to record the starting volume on each pass rather than querying elem.volume
// This is due to iOS safari not allowing volume changes and always returning the system volume value
-
var newVolume = Math.max(0, startingVolume - 0.15);
console.log('fading volume to ' + newVolume);
elem.volume = newVolume;
if (newVolume <= 0) {
-
instance._isFadingOut = false;
return Promise.resolve();
}
return new Promise(function (resolve, reject) {
-
cancelFadeTimeout();
-
fadeTimeout = setTimeout(function () {
-
fade(instance, elem, newVolume).then(resolve, reject);
}, 100);
});
@@ -50,7 +41,6 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
}
function supportsFade() {
-
if (browser.tv) {
// Not working on tizen.
// We could possibly enable on other tv's, but all smart tv browsers tend to be pretty primitive
@@ -68,9 +58,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
}
function enableHlsPlayer(url, item, mediaSource, mediaType) {
-
if (!htmlMediaHelper.enableHlsJsPlayer(mediaSource.RunTimeTicks, mediaType)) {
-
return Promise.reject();
}
@@ -86,21 +74,18 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
url: url,
type: 'HEAD'
}).then(function (response) {
-
var contentType = (response.headers.get('Content-Type') || '').toLowerCase();
if (contentType === 'application/x-mpegurl') {
resolve();
} else {
reject();
}
-
}, reject);
});
});
}
function HtmlAudioPlayer() {
-
var self = this;
self.name = 'Html Audio Player';
@@ -114,11 +99,9 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
self._started = false;
self._timeUpdated = false;
-
self._currentTime = null;
var elem = createMediaElement(options);
-
return setCurrentSrc(elem, options);
};
@@ -511,4 +494,4 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
};
return HtmlAudioPlayer;
-});
\ No newline at end of file
+});
diff --git a/src/components/htmlvideoplayer/plugin.js b/src/components/htmlvideoplayer/plugin.js
index ac4e8cf6a..b52b86797 100644
--- a/src/components/htmlvideoplayer/plugin.js
+++ b/src/components/htmlvideoplayer/plugin.js
@@ -27,6 +27,14 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
return _supportsTextTracks;
}
+ function supportsCanvas() {
+ return !!document.createElement('canvas').getContext;
+ }
+
+ function supportsWebWorkers() {
+ return !!window.Worker;
+ }
+
function enableNativeTrackSupport(currentSrc, track) {
if (track) {
@@ -185,6 +193,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
var lastCustomTrackMs = 0;
var currentClock;
+ var currentSubtitlesOctopus;
var currentAssRenderer;
var customTrackIndex = -1;
@@ -962,6 +971,12 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
currentClock = null;
self._currentAspectRatio = null;
+ var octopus = currentSubtitlesOctopus;
+ if (octopus) {
+ octopus.dispose();
+ }
+ currentSubtitlesOctopus = null;
+
var renderer = currentAssRenderer;
if (renderer) {
renderer.setEnabled(false);
@@ -1026,6 +1041,22 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
lastCustomTrackMs = 0;
}
+ function renderWithSubtitlesOctopus(videoElement, track, item) {
+ var attachments = self._currentPlayOptions.mediaSource.MediaAttachments || [];
+ var options = {
+ video: videoElement,
+ subUrl: getTextTrackUrl(track, item),
+ fonts: attachments.map(i => i.DeliveryUrl),
+ workerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker.js",
+ onError: function() {
+ htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror')
+ }
+ };
+ require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) {
+ currentSubtitlesOctopus = new SubtitlesOctopus(options);
+ });
+ }
+
function renderWithLibjass(videoElement, track, item) {
var rendererSettings = {};
@@ -1072,6 +1103,15 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
});
}
+ function renderSsaAss(videoElement, track, item) {
+ if (supportsCanvas() && supportsWebWorkers()) {
+ renderWithSubtitlesOctopus(videoElement, track, item);
+ } else {
+ console.log('rendering subtitles with libjass');
+ renderWithLibjass(videoElement, track, item);
+ }
+ }
+
function onVideoResize() {
if (browser.iOS) {
// the new sizes will be delayed for about 500ms with wkwebview
@@ -1182,7 +1222,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
var format = (track.Codec || '').toLowerCase();
if (format === 'ssa' || format === 'ass') {
// libjass is needed here
- renderWithLibjass(videoElement, track, item);
+ renderSsaAss(videoElement, track, item);
return;
}
@@ -1483,6 +1523,10 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
}
}
+ if (browser.safari || browser.iOS || browser.iPad) {
+ list.push('AirPlay')
+ }
+
list.push('SetBrightness');
list.push("SetAspectRatio")
@@ -1591,6 +1635,31 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
return false;
};
+ HtmlVideoPlayer.prototype.isAirPlayEnabled = function () {
+
+ if (document.AirPlayEnabled) {
+ return document.AirplayElement ? true : false;
+ }
+
+ return false;
+ };
+
+ HtmlVideoPlayer.prototype.setAirPlayEnabled = function (isEnabled) {
+ var video = this._mediaElement;
+
+ if (document.AirPlayEnabled) {
+ if (video) {
+ if (isEnabled) {
+ video.requestAirPlay().catch(onAirPlayError);
+ } else {
+ document.exitAirPLay().catch(onAirPlayError);
+ }
+ }
+ } else {
+ video.webkitShowPlaybackTargetPicker();
+ }
+ };
+
HtmlVideoPlayer.prototype.setBrightness = function (val) {
var elem = this._mediaElement;
@@ -1744,6 +1813,10 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
return this.setPictureInPictureEnabled(!this.isPictureInPictureEnabled());
};
+ HtmlVideoPlayer.prototype.toggleAirPlay = function () {
+ return this.setAirPlayEnabled(!this.isAirPlayEnabled());
+ };
+
HtmlVideoPlayer.prototype.getBufferedRanges = function () {
var mediaElement = this._mediaElement;
if (mediaElement) {
diff --git a/src/components/htmlvideoplayer/style.css b/src/components/htmlvideoplayer/style.css
index 9550f2c87..e1875ff33 100644
--- a/src/components/htmlvideoplayer/style.css
+++ b/src/components/htmlvideoplayer/style.css
@@ -24,6 +24,10 @@
z-index: 1000;
}
+.videoPlayerContainer .libassjs-canvas-parent {
+ order: -1;
+}
+
video::-webkit-media-controls {
display: none !important;
}
@@ -38,7 +42,6 @@ video::-webkit-media-controls {
.htmlvideoplayer::cue {
background-color: transparent;
text-shadow: 0.14em 0.14em 0.14em rgba(0, 0, 0, 1);
- -webkit-font-smoothing: antialiased;
font-family: inherit;
}
diff --git a/src/components/images/style.css b/src/components/images/style.css
index 5cf39c1e4..06fbf1f9c 100644
--- a/src/components/images/style.css
+++ b/src/components/images/style.css
@@ -18,21 +18,9 @@
.lazy-image-fadein {
opacity: 0;
- -webkit-animation-duration: .8s;
- -moz-animation-duration: .8s;
- -o-animation-duration: .8s;
animation-duration: .8s;
- -webkit-animation-name: popInAnimation;
- -moz-animation-name: popInAnimation;
- -o-animation-name: popInAnimation;
animation-name: popInAnimation;
- -webkit-animation-fill-mode: forwards;
- -moz-animation-fill-mode: forwards;
- -o-animation-fill-mode: forwards;
animation-fill-mode: forwards;
- -webkit-animation-timing-function: cubic-bezier(0,0,.5,1);
- -moz-animation-timing-function: cubic-bezier(0,0,.5,1);
- -o-animation-timing-function: cubic-bezier(0,0,.5,1);
animation-timing-function: cubic-bezier(0,0,.5,1);
}
diff --git a/src/components/imageuploader/imageuploader.js b/src/components/imageuploader/imageuploader.js
index 98fcf0ebc..198f54080 100644
--- a/src/components/imageuploader/imageuploader.js
+++ b/src/components/imageuploader/imageuploader.js
@@ -74,7 +74,7 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
return false;
}
- if (file.type !== "image/png" && file.type !== "image/x-png" && file.type !== "image/jpeg") {
+ if (!file.type.startsWith("image/")) {
require(['toast'], function (toast) {
toast(globalize.translate('MessageImageFileTypeAllowed'));
});
@@ -185,4 +185,4 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
});
}
};
-});
\ No newline at end of file
+});
diff --git a/src/components/imageuploader/imageuploader.template.html b/src/components/imageuploader/imageuploader.template.html
index b33355945..42d894db6 100644
--- a/src/components/imageuploader/imageuploader.template.html
+++ b/src/components/imageuploader/imageuploader.template.html
@@ -22,7 +22,7 @@
${HeaderAccessScheduleHelp}
-${HeaderAccessScheduleHelp}
+${WizardCompleted}
-