mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge remote-tracking branch 'upstream/master' into es6
With conflicts
This commit is contained in:
commit
3713091382
165 changed files with 4194 additions and 2714 deletions
|
@ -36,6 +36,14 @@ jobs:
|
||||||
targetPath: '$(Build.SourcesDirectory)/deployment/dist'
|
targetPath: '$(Build.SourcesDirectory)/deployment/dist'
|
||||||
artifactName: 'jellyfin-web-$(BuildConfiguration)'
|
artifactName: 'jellyfin-web-$(BuildConfiguration)'
|
||||||
|
|
||||||
|
- task: SSH@0
|
||||||
|
displayName: 'Create target directory on repository server'
|
||||||
|
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))
|
||||||
|
inputs:
|
||||||
|
sshEndpoint: repository
|
||||||
|
runOptions: 'inline'
|
||||||
|
inline: 'mkdir -p /srv/repository/incoming/azure/$(Build.BuildNumber)/$(BuildConfiguration)'
|
||||||
|
|
||||||
- task: CopyFilesOverSSH@0
|
- task: CopyFilesOverSSH@0
|
||||||
displayName: 'Upload artifacts to repository server'
|
displayName: 'Upload artifacts to repository server'
|
||||||
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))
|
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))
|
||||||
|
|
|
@ -2,4 +2,4 @@ version: 1
|
||||||
update_configs:
|
update_configs:
|
||||||
- package_manager: "javascript"
|
- package_manager: "javascript"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
update_schedule: "weekly"
|
update_schedule: "live"
|
||||||
|
|
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
|
@ -1,4 +1,6 @@
|
||||||
.ci @dkanada @EraYaN
|
.ci @dkanada @EraYaN
|
||||||
.github @jellyfin/core
|
.github @jellyfin/core
|
||||||
build.sh @joshuaboniface
|
fedora @joshuaboniface
|
||||||
|
debian @joshuaboniface
|
||||||
|
.copr @joshuaboniface
|
||||||
deployment @joshuaboniface
|
deployment @joshuaboniface
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug Report
|
||||||
about: Create a bug report
|
about: You have noticed a general issue or regression, and would like to report it
|
||||||
title: ''
|
|
||||||
labels: bug
|
labels: bug
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Describe the bug**
|
**Describe The Bug**
|
||||||
<!-- A clear and concise description of what the bug is. -->
|
<!-- A clear and concise description of what the bug is. -->
|
||||||
|
|
||||||
**To Reproduce**
|
**Steps To Reproduce**
|
||||||
<!-- Steps to reproduce the behavior: -->
|
<!-- Steps to reproduce the behavior: -->
|
||||||
1. Go to '...'
|
1. Go to '...'
|
||||||
2. Click on '....'
|
2. Click on '....'
|
||||||
3. Scroll down to '....'
|
3. Scroll down to '....'
|
||||||
4. See error
|
4. See error
|
||||||
|
|
||||||
**Expected behavior**
|
**Expected Behavior**
|
||||||
<!-- A clear and concise description of what you expected to happen. -->
|
<!-- A clear and concise description of what you expected to happen. -->
|
||||||
|
|
||||||
**Logs**
|
**Logs**
|
||||||
|
@ -27,9 +24,9 @@ assignees: ''
|
||||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||||
|
|
||||||
**System (please complete the following information):**
|
**System (please complete the following information):**
|
||||||
- OS: [e.g. Docker, Debian, Windows]
|
- Platform: [e.g. Linux, Windows, iPhone, Tizen]
|
||||||
- Browser: [e.g. Firefox, Chrome, Safari]
|
- Browser: [e.g. Firefox, Chrome, Safari]
|
||||||
- Jellyfin Version: [e.g. 10.0.1]
|
- Jellyfin Version: [e.g. 10.6.0]
|
||||||
|
|
||||||
**Additional context**
|
**Additional Context**
|
||||||
<!-- Add any other context about the problem here. -->
|
<!-- Add any other context about the problem here. -->
|
22
.github/ISSUE_TEMPLATE/2-playback-issue.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/2-playback-issue.md
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
name: Playback Issue
|
||||||
|
about: You have playback issues with some files
|
||||||
|
labels: playback
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe The Bug**
|
||||||
|
<!-- A clear and concise description of what the bug is. -->
|
||||||
|
|
||||||
|
**Media Information**
|
||||||
|
<!-- Please paste any ffprobe or MediaInfo logs. -->
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
<!-- Add screenshots from the Playback Data and Media Info. -->
|
||||||
|
|
||||||
|
**System (please complete the following information):**
|
||||||
|
- Platform: [e.g. Linux, Windows, iPhone, Tizen]
|
||||||
|
- Browser: [e.g. Firefox, Chrome, Safari]
|
||||||
|
- Jellyfin Version: [e.g. 10.6.0]
|
||||||
|
|
||||||
|
**Additional Context**
|
||||||
|
<!-- Add any other context about the problem here. -->
|
13
.github/ISSUE_TEMPLATE/3-technical-discussion.md
vendored
Normal file
13
.github/ISSUE_TEMPLATE/3-technical-discussion.md
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
name: Technical Discussion
|
||||||
|
about: You want to discuss technical aspects of changes you intend to make
|
||||||
|
labels: enhancement
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Explain the change and the motivations behind it.
|
||||||
|
|
||||||
|
For example, if you plan to rely on a new dependency, explain why and what
|
||||||
|
it brings to the project.
|
||||||
|
|
||||||
|
If you plan to make significant changes, go roughly over the steps you intend
|
||||||
|
to take and how you would divide the change in PRs of a manageable size. -->
|
9
.github/ISSUE_TEMPLATE/4-meta-issue.md
vendored
Normal file
9
.github/ISSUE_TEMPLATE/4-meta-issue.md
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
name: Meta Issue
|
||||||
|
about: You want to track a number of other issues as part of a larger project
|
||||||
|
labels: meta
|
||||||
|
---
|
||||||
|
|
||||||
|
* [ ] Issue 1 [#123]
|
||||||
|
* [ ] Issue 2 [#456]
|
||||||
|
* [ ] ...
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Feature Request
|
||||||
|
url: https://features.jellyfin.org/
|
||||||
|
about: Please head over to our feature request hub to vote on or submit a feature.
|
||||||
|
- name: Help Or Question
|
||||||
|
url: https://matrix.to/#/#jellyfin-troubleshooting:matrix.org
|
||||||
|
about: Please join the troubleshooting Matrix channel to get some help.
|
24
.github/SUPPORT.md
vendored
Normal file
24
.github/SUPPORT.md
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Support
|
||||||
|
|
||||||
|
Jellyfin contributors have limited availability to address general support
|
||||||
|
questions. Please make sure you are using the latest version of Jellyfin.
|
||||||
|
|
||||||
|
When looking for support or information, please first search for your
|
||||||
|
question in these venues:
|
||||||
|
|
||||||
|
* [Jellyfin Forum](https://forum.jellyfin.org)
|
||||||
|
* [Jellyfin Documentation](https://docs.jellyfin.org)
|
||||||
|
* [Open or **closed** issues in the organization](https://github.com/issues?q=sort%3Aupdated-desc+org%3Ajellyfin+is%3Aissue+)
|
||||||
|
|
||||||
|
If you didn't find an answer in the resources above, contributors and other
|
||||||
|
users are reachable through the following channels:
|
||||||
|
|
||||||
|
* #jellyfin on [Matrix](https://matrix.to/#/#jellyfin:matrix.org%22) or [IRC](https://webchat.freenode.net/#jellyfin)
|
||||||
|
* #jellyfin-troubleshooting on [Matrix](https://matrix.to/#/#jellyfin-troubleshooting:matrix.org) or [IRC](https://webchat.freenode.net/#jellyfin-troubleshooting)
|
||||||
|
* [/r/jellyfin on Reddit](https://www.reddit.com/r/jellyfin)
|
||||||
|
|
||||||
|
GitHub issues are for tracking enhancements and bugs, not general support.
|
||||||
|
|
||||||
|
The open source license grants you the freedom to use Jellyfin.
|
||||||
|
It does not guarantee commitments of other people's time.
|
||||||
|
Please be respectful and manage your expectations.
|
|
@ -184,7 +184,12 @@ function copy(query) {
|
||||||
function injectBundle() {
|
function injectBundle() {
|
||||||
return src(options.injectBundle.query, { base: './src/' })
|
return src(options.injectBundle.query, { base: './src/' })
|
||||||
.pipe(inject(
|
.pipe(inject(
|
||||||
src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), { relative: true }
|
src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), {
|
||||||
|
relative: true,
|
||||||
|
transform: function (filepath) {
|
||||||
|
return `<script src="${filepath}" defer></script>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
))
|
))
|
||||||
.pipe(dest('dist/'))
|
.pipe(dest('dist/'))
|
||||||
.pipe(browserSync.stream());
|
.pipe(browserSync.stream());
|
||||||
|
|
30
package.json
30
package.json
|
@ -5,16 +5,16 @@
|
||||||
"repository": "https://github.com/jellyfin/jellyfin-web",
|
"repository": "https://github.com/jellyfin/jellyfin-web",
|
||||||
"license": "GPL-2.0-or-later",
|
"license": "GPL-2.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.10.3",
|
"@babel/core": "^7.10.5",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.10.1",
|
"@babel/plugin-proposal-class-properties": "^7.10.1",
|
||||||
"@babel/plugin-proposal-private-methods": "^7.10.1",
|
"@babel/plugin-proposal-private-methods": "^7.10.1",
|
||||||
"@babel/plugin-transform-modules-amd": "^7.9.6",
|
"@babel/plugin-transform-modules-amd": "^7.10.5",
|
||||||
"@babel/polyfill": "^7.8.7",
|
"@babel/polyfill": "^7.8.7",
|
||||||
"@babel/preset-env": "^7.10.3",
|
"@babel/preset-env": "^7.10.3",
|
||||||
"autoprefixer": "^9.8.2",
|
"autoprefixer": "^9.8.5",
|
||||||
"babel-eslint": "^11.0.0-beta.2",
|
"babel-eslint": "^11.0.0-beta.2",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"browser-sync": "^2.26.7",
|
"browser-sync": "^2.26.10",
|
||||||
"copy-webpack-plugin": "^5.1.1",
|
"copy-webpack-plugin": "^5.1.1",
|
||||||
"css-loader": "^3.6.0",
|
"css-loader": "^3.6.0",
|
||||||
"cssnano": "^4.1.10",
|
"cssnano": "^4.1.10",
|
||||||
|
@ -57,16 +57,15 @@
|
||||||
"blurhash": "^1.1.3",
|
"blurhash": "^1.1.3",
|
||||||
"classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz",
|
"classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"date-fns": "^2.14.0",
|
"date-fns": "^2.15.0",
|
||||||
"document-register-element": "^1.14.3",
|
|
||||||
"epubjs": "^0.3.85",
|
"epubjs": "^0.3.85",
|
||||||
"fast-text-encoding": "^1.0.3",
|
"fast-text-encoding": "^1.0.3",
|
||||||
"flv.js": "^1.5.0",
|
"flv.js": "^1.5.0",
|
||||||
"headroom.js": "^0.11.0",
|
"headroom.js": "^0.11.0",
|
||||||
"hls.js": "^0.13.1",
|
"hls.js": "^0.14.3",
|
||||||
"howler": "^2.2.0",
|
"howler": "^2.2.0",
|
||||||
"intersection-observer": "^0.10.0",
|
"intersection-observer": "^0.11.0",
|
||||||
"jellyfin-apiclient": "^1.2.2",
|
"jellyfin-apiclient": "^1.4.1",
|
||||||
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
|
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
|
||||||
"jquery": "^3.5.1",
|
"jquery": "^3.5.1",
|
||||||
"jstree": "^3.3.10",
|
"jstree": "^3.3.10",
|
||||||
|
@ -77,11 +76,11 @@
|
||||||
"query-string": "^6.13.1",
|
"query-string": "^6.13.1",
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"screenfull": "^5.0.2",
|
"screenfull": "^5.0.2",
|
||||||
"shaka-player": "^3.0.1",
|
"shaka-player": "^2.5.13",
|
||||||
"sortablejs": "^1.10.2",
|
"sortablejs": "^1.10.2",
|
||||||
"swiper": "^5.4.5",
|
"swiper": "^5.4.5",
|
||||||
"webcomponents.js": "^0.7.24",
|
"webcomponents.js": "^0.7.24",
|
||||||
"whatwg-fetch": "^3.0.0"
|
"whatwg-fetch": "^3.2.0"
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"presets": [
|
"presets": [
|
||||||
|
@ -174,6 +173,7 @@
|
||||||
"src/controllers/dashboard/metadataImages.js",
|
"src/controllers/dashboard/metadataImages.js",
|
||||||
"src/controllers/dashboard/metadatanfo.js",
|
"src/controllers/dashboard/metadatanfo.js",
|
||||||
"src/controllers/dashboard/plugins/repositories.js",
|
"src/controllers/dashboard/plugins/repositories.js",
|
||||||
|
<<<<<<< HEAD
|
||||||
"src/controllers/dashboard/streaming.js",
|
"src/controllers/dashboard/streaming.js",
|
||||||
"src/controllers/dashboard/mediaLibrary.js",
|
"src/controllers/dashboard/mediaLibrary.js",
|
||||||
"src/controllers/dashboard/networking.js",
|
"src/controllers/dashboard/networking.js",
|
||||||
|
@ -230,6 +230,14 @@
|
||||||
"src/elements/emby-button/paper-icon-button-light.js",
|
"src/elements/emby-button/paper-icon-button-light.js",
|
||||||
"src/elements/emby-collapse/emby-collapse.js",
|
"src/elements/emby-collapse/emby-collapse.js",
|
||||||
"src/elements/emby-input/emby-input.js",
|
"src/elements/emby-input/emby-input.js",
|
||||||
|
=======
|
||||||
|
"src/controllers/playback/nowplaying.js",
|
||||||
|
"src/controllers/playback/videoosd.js",
|
||||||
|
"src/controllers/user/display.js",
|
||||||
|
"src/controllers/user/home.js",
|
||||||
|
"src/controllers/user/playback.js",
|
||||||
|
"src/controllers/user/subtitles.js",
|
||||||
|
>>>>>>> upstream/master
|
||||||
"src/plugins/bookPlayer/plugin.js",
|
"src/plugins/bookPlayer/plugin.js",
|
||||||
"src/plugins/bookPlayer/tableOfContents.js",
|
"src/plugins/bookPlayer/tableOfContents.js",
|
||||||
"src/plugins/photoPlayer/plugin.js",
|
"src/plugins/photoPlayer/plugin.js",
|
||||||
|
|
|
@ -235,6 +235,15 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.localUsers .cardText-secondary {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
height: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customCssContainer textarea {
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media all and (min-width: 70em) {
|
@media all and (min-width: 70em) {
|
||||||
.dashboardSections {
|
.dashboardSections {
|
||||||
-webkit-flex-wrap: wrap;
|
-webkit-flex-wrap: wrap;
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.align-items-flex-end {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
.justify-content-center {
|
.justify-content-center {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +42,10 @@
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.justify-content-space-between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-wrap-wrap {
|
.flex-wrap-wrap {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
html {
|
html {
|
||||||
font-size: 82% !important;
|
font-size: 82% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.formDialogFooter {
|
|
||||||
position: static !important;
|
|
||||||
margin: 0 -1em !important;
|
|
||||||
}
|
|
||||||
|
|
|
@ -24,10 +24,6 @@
|
||||||
padding-top: 7em !important;
|
padding-top: 7em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mobile .libraryPage {
|
|
||||||
padding-top: 4em !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.itemDetailPage {
|
.itemDetailPage {
|
||||||
padding-top: 0 !important;
|
padding-top: 0 !important;
|
||||||
}
|
}
|
||||||
|
@ -164,6 +160,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
contain: layout style paint;
|
contain: layout style paint;
|
||||||
|
transition: background ease-in-out 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hiddenViewMenuBar .skinHeader {
|
.hiddenViewMenuBar .skinHeader {
|
||||||
|
@ -178,6 +175,10 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-tv .sectionTabs {
|
||||||
|
width: 55%;
|
||||||
|
}
|
||||||
|
|
||||||
.selectedMediaFolder {
|
.selectedMediaFolder {
|
||||||
background-color: #f2f2f2 !important;
|
background-color: #f2f2f2 !important;
|
||||||
}
|
}
|
||||||
|
@ -272,7 +273,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (max-width: 84em) {
|
@media all and (max-width: 100em) {
|
||||||
.withSectionTabs .headerTop {
|
.withSectionTabs .headerTop {
|
||||||
padding-bottom: 0.55em;
|
padding-bottom: 0.55em;
|
||||||
}
|
}
|
||||||
|
@ -280,9 +281,13 @@
|
||||||
.sectionTabs {
|
.sectionTabs {
|
||||||
font-size: 83.5%;
|
font-size: 83.5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-tv .sectionTabs {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-width: 84em) {
|
@media all and (min-width: 100em) {
|
||||||
.headerTop {
|
.headerTop {
|
||||||
padding: 0.8em 0.8em;
|
padding: 0.8em 0.8em;
|
||||||
}
|
}
|
||||||
|
@ -438,12 +443,14 @@
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
height: 50vh;
|
height: 40vh;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
animation: backdrop-fadein 800ms ease-in normal both;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mobile .itemBackdrop {
|
.layout-mobile .itemBackdrop {
|
||||||
background-attachment: scroll;
|
background-attachment: scroll;
|
||||||
|
height: 26.5vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-desktop .itemBackdrop::after,
|
.layout-desktop .itemBackdrop::after,
|
||||||
|
@ -463,10 +470,20 @@
|
||||||
.detailPageContent {
|
.detailPageContent {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding-left: 2%;
|
padding-left: 32.45vw;
|
||||||
padding-right: 2%;
|
padding-right: 2%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-mobile .detailPageContent {
|
||||||
|
padding-left: 5%;
|
||||||
|
padding-right: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .detailPageContent .emby-scroller,
|
||||||
|
.layout-tv .detailPageContent .emby-scroller {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.layout-desktop .noBackdrop .detailPageContent,
|
.layout-desktop .noBackdrop .detailPageContent,
|
||||||
.layout-tv .noBackdrop .detailPageContent {
|
.layout-tv .noBackdrop .detailPageContent {
|
||||||
margin-top: 2.5em;
|
margin-top: 2.5em;
|
||||||
|
@ -477,6 +494,10 @@
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detailSectionContent a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.personBackdrop {
|
.personBackdrop {
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
@ -495,7 +516,23 @@
|
||||||
|
|
||||||
.parentName {
|
.parentName {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 0.5em;
|
margin: 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .parentName {
|
||||||
|
margin: 0.6em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.musicParentName {
|
||||||
|
margin: 0.15em 0 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .musicParentName {
|
||||||
|
margin: -0.25em 0 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .itemExternalLinks {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainDetailButtons {
|
.mainDetailButtons {
|
||||||
|
@ -503,8 +540,6 @@
|
||||||
-webkit-box-align: center;
|
-webkit-box-align: center;
|
||||||
-webkit-align-items: center;
|
-webkit-align-items: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
-webkit-flex-wrap: wrap;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,6 +555,35 @@
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.itemName.originalTitle {
|
||||||
|
margin: 0.2em 0 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemName.parentNameLast {
|
||||||
|
margin: 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .itemName.parentNameLast {
|
||||||
|
margin: 0.4em 0 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile h1.itemName,
|
||||||
|
.layout-mobile h1.parentName {
|
||||||
|
font-size: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemName.parentNameLast.withOriginalTitle {
|
||||||
|
margin: 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .itemName.parentNameLast.withOriginalTitle {
|
||||||
|
margin: 0.6em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .itemName.originalTitle {
|
||||||
|
margin: 0.5em 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
.nameContainer {
|
.nameContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -546,6 +610,19 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-mobile .mainDetailButtons {
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
margin: 0.15em 0 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .subtitle {
|
||||||
|
margin: 0.2em 0 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
.detailPagePrimaryContainer {
|
.detailPagePrimaryContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -556,7 +633,7 @@
|
||||||
.layout-mobile .detailPagePrimaryContainer {
|
.layout-mobile .detailPagePrimaryContainer {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0;
|
padding: 0.5em 3.3% 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer,
|
.layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer,
|
||||||
|
@ -566,13 +643,14 @@
|
||||||
padding-left: 32.45vw;
|
padding-left: 32.45vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-desktop .detailSticky,
|
.layout-desktop .detailRibbon,
|
||||||
.layout-tv .detailSticky {
|
.layout-tv .detailRibbon {
|
||||||
margin-top: -7.2em;
|
margin-top: -7.2em;
|
||||||
|
height: 7.18em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-desktop .noBackdrop .detailSticky,
|
.layout-desktop .noBackdrop .detailRibbon,
|
||||||
.layout-tv .noBackdrop .detailSticky {
|
.layout-tv .noBackdrop .detailRibbon {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,6 +662,9 @@
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
min-width: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mobile .infoText {
|
.layout-mobile .infoText {
|
||||||
|
@ -594,13 +675,29 @@
|
||||||
margin: 1.25em 0;
|
margin: 1.25em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailImageContainer {
|
.layout-mobile .detailPageSecondaryContainer {
|
||||||
position: relative;
|
margin: 1em 0;
|
||||||
margin-top: -25vh;
|
}
|
||||||
margin-bottom: 10vh;
|
|
||||||
|
.layout-mobile .detailImageContainer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailImageContainer .card {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
float: left;
|
float: left;
|
||||||
width: 25vw;
|
width: 25vw;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailImageContainer .card.backdropCard {
|
||||||
|
top: 35%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailImageContainer .card.squareCard {
|
||||||
|
top: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-desktop .noBackdrop .detailImageContainer,
|
.layout-desktop .noBackdrop .detailImageContainer,
|
||||||
|
@ -613,11 +710,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailLogo {
|
.detailLogo {
|
||||||
width: 30vw;
|
width: 25vw;
|
||||||
height: 25vh;
|
height: 16vh;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10vh;
|
top: 10vh;
|
||||||
right: 20vw;
|
right: 25vw;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,14 +754,19 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-desktop .detailPageWrapperContainer,
|
.layout-desktop .itemBackdrop,
|
||||||
.layout-tv .detailPageWrapperContainer {
|
.layout-tv .itemBackdrop {
|
||||||
margin-top: 7.2em;
|
height: 40vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer,
|
.layout-desktop .detailPageWrapperContainer,
|
||||||
.layout-desktop #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer {
|
.layout-tv .detailPageWrapperContainer {
|
||||||
padding-left: 3.3%;
|
margin-top: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .detailImageContainer .card,
|
||||||
|
.layout-tv .detailImageContainer .card {
|
||||||
|
top: 10%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btnPlaySimple {
|
.btnPlaySimple {
|
||||||
|
@ -680,12 +782,12 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||||
|
|
||||||
.emby-button.detailFloatingButton {
|
.emby-button.detailFloatingButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: rgba(0, 0, 0, 0.5) !important;
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
z-index: 1;
|
z-index: 3;
|
||||||
top: 50%;
|
top: 100%;
|
||||||
left: 50%;
|
left: 90%;
|
||||||
margin: -2.2em 0 0 -2.2em;
|
margin: -2.2em 0 0 -2.2em;
|
||||||
padding: 0.4em !important;
|
padding: 0.4em;
|
||||||
color: rgba(255, 255, 255, 0.76);
|
color: rgba(255, 255, 255, 0.76);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,16 +797,12 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||||
|
|
||||||
@media all and (max-width: 62.5em) {
|
@media all and (max-width: 62.5em) {
|
||||||
.parentName {
|
.parentName {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemDetailPage {
|
.itemDetailPage {
|
||||||
padding-top: 0 !important;
|
padding-top: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailimg-hidemobile {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-width: 31.25em) {
|
@media all and (min-width: 31.25em) {
|
||||||
|
@ -820,21 +918,7 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-width: 62.5em) {
|
@media all and (min-width: 100em) {
|
||||||
.headerTop {
|
|
||||||
padding-left: 0.8em;
|
|
||||||
padding-right: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.headerTabs {
|
|
||||||
align-self: center;
|
|
||||||
width: auto;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: -4.2em;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detailFloatingButton {
|
.detailFloatingButton {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
@ -868,6 +952,10 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detailVerticalSection .emby-scrollbuttons {
|
||||||
|
padding-top: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
.layout-tv .detailVerticalSection {
|
.layout-tv .detailVerticalSection {
|
||||||
margin-bottom: 3.4em !important;
|
margin-bottom: 3.4em !important;
|
||||||
}
|
}
|
||||||
|
@ -956,6 +1044,10 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||||
margin-bottom: 2.7em;
|
margin-bottom: 2.7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-mobile .verticalSection-extrabottompadding {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.sectionTitleButton,
|
.sectionTitleButton,
|
||||||
.sectionTitleIconButton {
|
.sectionTitleIconButton {
|
||||||
margin-right: 0 !important;
|
margin-right: 0 !important;
|
||||||
|
@ -981,7 +1073,13 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||||
|
|
||||||
div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-top: 1.25em;
|
padding-top: 0.5em;
|
||||||
|
padding-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile :not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||||
|
margin: 0;
|
||||||
|
padding-top: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sectionTitleButton {
|
.sectionTitleButton {
|
||||||
|
@ -1134,6 +1232,12 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||||
|
|
||||||
.trackSelections .selectContainer .selectLabel {
|
.trackSelections .selectContainer .selectLabel {
|
||||||
margin: 0 0.2em 0 0;
|
margin: 0 0.2em 0 0;
|
||||||
|
line-height: 1.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .detailsGroupItem .label,
|
||||||
|
.layout-mobile .trackSelections .selectContainer .selectLabel {
|
||||||
|
flex-basis: 4.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trackSelections .selectContainer .detailTrackSelect {
|
.trackSelections .selectContainer .detailTrackSelect {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
.hiddenScrollX,
|
.hiddenScrollX,
|
||||||
.layout-tv .scrollX {
|
.layout-tv .scrollX {
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hiddenScrollX-forced {
|
.hiddenScrollX-forced {
|
||||||
|
@ -40,6 +41,7 @@
|
||||||
.hiddenScrollY,
|
.hiddenScrollY,
|
||||||
.layout-tv .smoothScrollY {
|
.layout-tv .smoothScrollY {
|
||||||
-ms-overflow-style: none;
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
|
||||||
/* Can't do this because it not only hides the scrollbar, but also prevents scrolling */
|
/* Can't do this because it not only hides the scrollbar, but also prevents scrolling */
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,12 @@ html {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-mobile,
|
||||||
|
.layout-tv {
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
.clipForScreenReader {
|
.clipForScreenReader {
|
||||||
clip: rect(1px, 1px, 1px, 1px);
|
clip: rect(1px, 1px, 1px, 1px);
|
||||||
clip-path: inset(50%);
|
clip-path: inset(50%);
|
||||||
|
@ -18,7 +24,7 @@ html {
|
||||||
|
|
||||||
.material-icons {
|
.material-icons {
|
||||||
/* Fix font ligatures on older WebOS versions */
|
/* Fix font ligatures on older WebOS versions */
|
||||||
-webkit-font-feature-settings: "liga";
|
font-feature-settings: "liga";
|
||||||
}
|
}
|
||||||
|
|
||||||
.backgroundContainer {
|
.backgroundContainer {
|
||||||
|
@ -34,16 +40,6 @@ html {
|
||||||
line-height: 1.35;
|
line-height: 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
.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 {
|
body {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
|
@ -133,3 +129,7 @@ div[data-role=page] {
|
||||||
.hide-scroll {
|
.hide-scroll {
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-100 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
// Use define from require.js not webpack's define
|
// Use define from require.js not webpack's define
|
||||||
var _define = window.define;
|
var _define = window.define;
|
||||||
|
|
||||||
// document-register-element
|
|
||||||
var docRegister = require('document-register-element');
|
|
||||||
_define('document-register-element', function() {
|
|
||||||
return docRegister;
|
|
||||||
});
|
|
||||||
|
|
||||||
// fetch
|
// fetch
|
||||||
var fetch = require('whatwg-fetch');
|
var fetch = require('whatwg-fetch');
|
||||||
_define('fetch', function() {
|
_define('fetch', function() {
|
||||||
|
@ -65,12 +59,6 @@ _define('resize-observer-polyfill', function() {
|
||||||
return resize;
|
return resize;
|
||||||
});
|
});
|
||||||
|
|
||||||
// shaka
|
|
||||||
var shaka = require('shaka-player');
|
|
||||||
_define('shaka', function() {
|
|
||||||
return shaka;
|
|
||||||
});
|
|
||||||
|
|
||||||
// swiper
|
// swiper
|
||||||
var swiper = require('swiper/js/swiper');
|
var swiper = require('swiper/js/swiper');
|
||||||
require('swiper/css/swiper.min.css');
|
require('swiper/css/swiper.min.css');
|
||||||
|
@ -90,6 +78,12 @@ _define('webcomponents', function() {
|
||||||
return webcomponents;
|
return webcomponents;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// shaka
|
||||||
|
var shaka = require('shaka-player');
|
||||||
|
_define('shaka', function() {
|
||||||
|
return shaka;
|
||||||
|
});
|
||||||
|
|
||||||
// libass-wasm
|
// libass-wasm
|
||||||
var libassWasm = require('libass-wasm');
|
var libassWasm = require('libass-wasm');
|
||||||
_define('JavascriptSubtitlesOctopus', function() {
|
_define('JavascriptSubtitlesOctopus', function() {
|
||||||
|
|
|
@ -16,7 +16,7 @@ function getOffsets(elems) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let elem of elems) {
|
for (const elem of elems) {
|
||||||
let box = elem.getBoundingClientRect();
|
let box = elem.getBoundingClientRect();
|
||||||
|
|
||||||
results.push({
|
results.push({
|
||||||
|
@ -135,7 +135,7 @@ export function show(options) {
|
||||||
let renderIcon = false;
|
let renderIcon = false;
|
||||||
let icons = [];
|
let icons = [];
|
||||||
let itemIcon;
|
let itemIcon;
|
||||||
for (let item of options.items) {
|
for (const item of options.items) {
|
||||||
|
|
||||||
itemIcon = item.icon || (item.selected ? 'check' : null);
|
itemIcon = item.icon || (item.selected ? 'check' : null);
|
||||||
|
|
||||||
|
|
|
@ -222,46 +222,13 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeImageOptions(options) {
|
function normalizeImageOptions(options) {
|
||||||
var scaleFactor = browser.tv ? 0.8 : 1;
|
|
||||||
|
|
||||||
var setQuality;
|
var setQuality;
|
||||||
if (options.maxWidth) {
|
if (options.maxWidth || options.width || options.maxHeight || options.height) {
|
||||||
options.maxWidth = Math.round(options.maxWidth * scaleFactor);
|
|
||||||
setQuality = true;
|
setQuality = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.width) {
|
if (setQuality && !options.quality) {
|
||||||
options.width = Math.round(options.width * scaleFactor);
|
options.quality = 90;
|
||||||
setQuality = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.maxHeight) {
|
|
||||||
options.maxHeight = Math.round(options.maxHeight * scaleFactor);
|
|
||||||
setQuality = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.height) {
|
|
||||||
options.height = Math.round(options.height * scaleFactor);
|
|
||||||
setQuality = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setQuality) {
|
|
||||||
var quality;
|
|
||||||
var type = options.type || 'Primary';
|
|
||||||
|
|
||||||
if (browser.tv || browser.slow) {
|
|
||||||
// TODO: wtf
|
|
||||||
if (browser.chrome) {
|
|
||||||
// webp support
|
|
||||||
quality = type === 'Primary' ? 40 : 50;
|
|
||||||
} else {
|
|
||||||
quality = type === 'Backdrop' ? 60 : 50;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quality = type === 'Backdrop' ? 70 : 90;
|
|
||||||
}
|
|
||||||
|
|
||||||
options.quality = quality;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,8 +167,9 @@ button::-moz-focus-inner {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-clip: content-box !important;
|
background-clip: content-box !important;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is only needed for scalable cards */
|
.cardScalable .cardImageContainer {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
contain: strict;
|
contain: strict;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1310,7 +1310,7 @@ import 'programStyles';
|
||||||
}
|
}
|
||||||
|
|
||||||
const mediaSourceCount = item.MediaSourceCount || 1;
|
const mediaSourceCount = item.MediaSourceCount || 1;
|
||||||
if (mediaSourceCount > 1) {
|
if (mediaSourceCount > 1 && options.disableIndicators !== true) {
|
||||||
innerCardFooter += '<div class="mediaSourceIndicator">' + mediaSourceCount + '</div>';
|
innerCardFooter += '<div class="mediaSourceIndicator">' + mediaSourceCount + '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1391,34 +1391,44 @@ import 'programStyles';
|
||||||
cardBoxClose = '</div>';
|
cardBoxClose = '</div>';
|
||||||
cardScalableClose = '</div>';
|
cardScalableClose = '</div>';
|
||||||
|
|
||||||
let indicatorsHtml = '';
|
if (options.disableIndicators !== true) {
|
||||||
|
let indicatorsHtml = '';
|
||||||
|
|
||||||
if (options.missingIndicator !== false) {
|
if (options.missingIndicator !== false) {
|
||||||
indicatorsHtml += indicators.getMissingIndicator(item);
|
indicatorsHtml += indicators.getMissingIndicator(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
indicatorsHtml += indicators.getSyncIndicator(item);
|
indicatorsHtml += indicators.getSyncIndicator(item);
|
||||||
indicatorsHtml += indicators.getTimerIndicator(item);
|
indicatorsHtml += indicators.getTimerIndicator(item);
|
||||||
|
|
||||||
indicatorsHtml += indicators.getTypeIndicator(item);
|
indicatorsHtml += indicators.getTypeIndicator(item);
|
||||||
|
|
||||||
if (options.showGroupCount) {
|
if (options.showGroupCount) {
|
||||||
|
|
||||||
indicatorsHtml += indicators.getChildCountIndicatorHtml(item, {
|
indicatorsHtml += indicators.getChildCountIndicatorHtml(item, {
|
||||||
minCount: 1
|
minCount: 1
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
indicatorsHtml += indicators.getPlayedIndicatorHtml(item);
|
indicatorsHtml += indicators.getPlayedIndicatorHtml(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
if (item.Type === 'CollectionFolder' || item.CollectionType) {
|
if (item.Type === 'CollectionFolder' || item.CollectionType) {
|
||||||
const refreshClass = item.RefreshProgress ? '' : ' class="hide"';
|
const refreshClass = item.RefreshProgress ? '' : ' class="hide"';
|
||||||
indicatorsHtml += '<div is="emby-itemrefreshindicator"' + refreshClass + ' data-progress="' + (item.RefreshProgress || 0) + '" data-status="' + item.RefreshStatus + '"></div>';
|
indicatorsHtml += '<div is="emby-itemrefreshindicator"' + refreshClass + ' data-progress="' + (item.RefreshProgress || 0) + '" data-status="' + item.RefreshStatus + '"></div>';
|
||||||
importRefreshIndicator();
|
importRefreshIndicator();
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
if (item.Type === 'CollectionFolder' || item.CollectionType) {
|
||||||
|
const refreshClass = item.RefreshProgress ? '' : ' class="hide"';
|
||||||
|
indicatorsHtml += '<div is="emby-itemrefreshindicator"' + refreshClass + ' data-progress="' + (item.RefreshProgress || 0) + '" data-status="' + item.RefreshStatus + '"></div>';
|
||||||
|
requireRefreshIndicator();
|
||||||
|
}
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
if (indicatorsHtml) {
|
if (indicatorsHtml) {
|
||||||
cardImageContainerOpen += '<div class="cardIndicators">' + indicatorsHtml + '</div>';
|
cardImageContainerOpen += '<div class="cardIndicators">' + indicatorsHtml + '</div>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!imgUrl) {
|
if (!imgUrl) {
|
||||||
|
@ -1466,8 +1476,8 @@ import 'programStyles';
|
||||||
|
|
||||||
let additionalCardContent = '';
|
let additionalCardContent = '';
|
||||||
|
|
||||||
if (layoutManager.desktop) {
|
if (layoutManager.desktop && !options.disableHoverMenu) {
|
||||||
additionalCardContent += getHoverMenuHtml(item, action);
|
additionalCardContent += getHoverMenuHtml(item, action, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<' + tagName + ' data-index="' + index + '"' + timerAttributes + actionAttribute + ' data-isfolder="' + (item.IsFolder || false) + '" data-serverid="' + (item.ServerId || options.serverId) + '" data-id="' + (item.Id || item.ItemId) + '" data-type="' + item.Type + '"' + mediaTypeData + collectionTypeData + channelIdData + positionTicksData + collectionIdData + playlistIdData + contextData + parentIdData + ' data-prefix="' + prefix + '" class="' + className + '">' + cardImageContainerOpen + innerCardFooter + cardImageContainerClose + overlayButtons + additionalCardContent + cardScalableClose + outerCardFooter + cardBoxClose + '</' + tagName + '>';
|
return '<' + tagName + ' data-index="' + index + '"' + timerAttributes + actionAttribute + ' data-isfolder="' + (item.IsFolder || false) + '" data-serverid="' + (item.ServerId || options.serverId) + '" data-id="' + (item.Id || item.ItemId) + '" data-type="' + item.Type + '"' + mediaTypeData + collectionTypeData + channelIdData + positionTicksData + collectionIdData + playlistIdData + contextData + parentIdData + ' data-prefix="' + prefix + '" class="' + className + '">' + cardImageContainerOpen + innerCardFooter + cardImageContainerClose + overlayButtons + additionalCardContent + cardScalableClose + outerCardFooter + cardBoxClose + '</' + tagName + '>';
|
||||||
|
@ -1477,9 +1487,10 @@ import 'programStyles';
|
||||||
* Generates HTML markup for the card overlay.
|
* Generates HTML markup for the card overlay.
|
||||||
* @param {object} item - Item used to generate the card overlay.
|
* @param {object} item - Item used to generate the card overlay.
|
||||||
* @param {string} action - Action assigned to the overlay.
|
* @param {string} action - Action assigned to the overlay.
|
||||||
|
* @param {Array} options - Card builder options.
|
||||||
* @returns {string} HTML markup of the card overlay.
|
* @returns {string} HTML markup of the card overlay.
|
||||||
*/
|
*/
|
||||||
function getHoverMenuHtml(item, action) {
|
function getHoverMenuHtml(item, action, options) {
|
||||||
let html = '';
|
let html = '';
|
||||||
|
|
||||||
html += '<div class="cardOverlayContainer itemAction" data-action="' + action + '">';
|
html += '<div class="cardOverlayContainer itemAction" data-action="' + action + '">';
|
||||||
|
@ -1508,7 +1519,6 @@ import 'programStyles';
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover more_vert"></span></button>';
|
html += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover more_vert"></span></button>';
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
@ -1532,6 +1542,8 @@ import 'programStyles';
|
||||||
case 'MusicArtist':
|
case 'MusicArtist':
|
||||||
case 'Person':
|
case 'Person':
|
||||||
return '<span class="cardImageIcon material-icons person"></span>';
|
return '<span class="cardImageIcon material-icons person"></span>';
|
||||||
|
case 'Audio':
|
||||||
|
return '<span class="cardImageIcon material-icons audiotrack"></span>';
|
||||||
case 'Movie':
|
case 'Movie':
|
||||||
return '<span class="cardImageIcon material-icons movie"></span>';
|
return '<span class="cardImageIcon material-icons movie"></span>';
|
||||||
case 'Series':
|
case 'Series':
|
||||||
|
@ -1540,6 +1552,12 @@ import 'programStyles';
|
||||||
return '<span class="cardImageIcon material-icons book"></span>';
|
return '<span class="cardImageIcon material-icons book"></span>';
|
||||||
case 'Folder':
|
case 'Folder':
|
||||||
return '<span class="cardImageIcon material-icons folder"></span>';
|
return '<span class="cardImageIcon material-icons folder"></span>';
|
||||||
|
case 'BoxSet':
|
||||||
|
return '<span class="cardImageIcon material-icons collections"></span>';
|
||||||
|
case 'Playlist':
|
||||||
|
return '<span class="cardImageIcon material-icons view_list"></span>';
|
||||||
|
case 'PhotoAlbum':
|
||||||
|
return '<span class="cardImageIcon material-icons photo_album"></span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options && options.defaultCardImageIcon) {
|
if (options && options.defaultCardImageIcon) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ import connectionManager from 'connectionManager';
|
||||||
return void appRouter.showItem(items[0]);
|
return void appRouter.showItem(items[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = 'itemdetails.html?id=' + itemId + '&serverId=' + serverId;
|
var url = 'details?id=' + itemId + '&serverId=' + serverId;
|
||||||
Dashboard.navigate(url);
|
Dashboard.navigate(url);
|
||||||
});
|
});
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'registerElement'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) {
|
define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function showViewSettings(instance) {
|
function showViewSettings(instance) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import 'css!./style';
|
||||||
fillImageElement(elem, source);
|
fillImageElement(elem, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function itemBlurhashing(target, blurhashstr) {
|
function itemBlurhashing(target, blurhashstr) {
|
||||||
if (blurhash.isBlurhashValid(blurhashstr)) {
|
if (blurhash.isBlurhashValid(blurhashstr)) {
|
||||||
// Although the default values recommended by Blurhash developers is 32x32, a size of 18x18 seems to be the sweet spot for us,
|
// Although the default values recommended by Blurhash developers is 32x32, a size of 18x18 seems to be the sweet spot for us,
|
||||||
// improving the performance and reducing the memory usage, while retaining almost full blur quality.
|
// improving the performance and reducing the memory usage, while retaining almost full blur quality.
|
||||||
|
@ -36,24 +36,18 @@ import 'css!./style';
|
||||||
imgData.data.set(pixels);
|
imgData.data.set(pixels);
|
||||||
ctx.putImageData(imgData, 0, 0);
|
ctx.putImageData(imgData, 0, 0);
|
||||||
|
|
||||||
let child = target.appendChild(canvas);
|
requestAnimationFrame(() => {
|
||||||
child.classList.add('blurhash-canvas');
|
canvas.classList.add('blurhash-canvas');
|
||||||
child.style.opacity = 1;
|
if (userSettings.enableFastFadein()) {
|
||||||
if (userSettings.enableFastFadein()) {
|
canvas.classList.add('lazy-blurhash-fadein-fast');
|
||||||
child.classList.add('lazy-blurhash-fadein-fast');
|
} else {
|
||||||
} else {
|
canvas.classList.add('lazy-blurhash-fadein');
|
||||||
child.classList.add('lazy-blurhash-fadein');
|
}
|
||||||
}
|
|
||||||
|
|
||||||
target.classList.add('blurhashed');
|
target.parentNode.insertBefore(canvas, target);
|
||||||
target.removeAttribute('data-blurhash');
|
target.classList.add('blurhashed');
|
||||||
}
|
target.removeAttribute('data-blurhash');
|
||||||
}
|
});
|
||||||
|
|
||||||
function switchCanvas(elem) {
|
|
||||||
let child = elem.getElementsByClassName('blurhash-canvas')[0];
|
|
||||||
if (child) {
|
|
||||||
child.style.opacity = elem.getAttribute('data-src') ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,23 +60,16 @@ import 'css!./style';
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
source = target.getAttribute('data-src');
|
source = target.getAttribute('data-src');
|
||||||
var blurhashstr = target.getAttribute('data-blurhash');
|
|
||||||
} else {
|
} else {
|
||||||
source = entry;
|
source = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userSettings.enableBlurhash()) {
|
|
||||||
if (!target.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) {
|
|
||||||
itemBlurhashing(target, blurhashstr);
|
|
||||||
} else if (!blurhashstr && !target.classList.contains('blurhashed')) {
|
|
||||||
target.classList.add('non-blurhashable');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.intersectionRatio > 0) {
|
if (entry.intersectionRatio > 0) {
|
||||||
if (source) fillImageElement(target, source);
|
if (source) fillImageElement(target, source);
|
||||||
} else if (!source) {
|
} else if (!source) {
|
||||||
emptyImageElement(target);
|
requestAnimationFrame(() => {
|
||||||
|
emptyImageElement(target);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,29 +81,24 @@ import 'css!./style';
|
||||||
let preloaderImg = new Image();
|
let preloaderImg = new Image();
|
||||||
preloaderImg.src = url;
|
preloaderImg.src = url;
|
||||||
|
|
||||||
// This is necessary here, so changing blurhash settings without reloading the page works
|
elem.classList.add('lazy-hidden');
|
||||||
if (!userSettings.enableBlurhash() || elem.classList.contains('non-blurhashable')) {
|
|
||||||
elem.classList.add('lazy-hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
preloaderImg.addEventListener('load', () => {
|
preloaderImg.addEventListener('load', () => {
|
||||||
if (elem.tagName !== 'IMG') {
|
requestAnimationFrame(() => {
|
||||||
elem.style.backgroundImage = "url('" + url + "')";
|
if (elem.tagName !== 'IMG') {
|
||||||
} else {
|
elem.style.backgroundImage = "url('" + url + "')";
|
||||||
elem.setAttribute('src', url);
|
} else {
|
||||||
}
|
elem.setAttribute('src', url);
|
||||||
elem.removeAttribute('data-src');
|
}
|
||||||
|
elem.removeAttribute('data-src');
|
||||||
|
|
||||||
if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) {
|
|
||||||
elem.classList.remove('lazy-hidden');
|
elem.classList.remove('lazy-hidden');
|
||||||
if (userSettings.enableFastFadein()) {
|
if (userSettings.enableFastFadein()) {
|
||||||
elem.classList.add('lazy-image-fadein-fast');
|
elem.classList.add('lazy-image-fadein-fast');
|
||||||
} else {
|
} else {
|
||||||
elem.classList.add('lazy-image-fadein');
|
elem.classList.add('lazy-image-fadein');
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
switchCanvas(elem);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,15 +114,21 @@ import 'css!./style';
|
||||||
}
|
}
|
||||||
elem.setAttribute('data-src', url);
|
elem.setAttribute('data-src', url);
|
||||||
|
|
||||||
if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) {
|
elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein');
|
||||||
elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein');
|
elem.classList.add('lazy-hidden');
|
||||||
elem.classList.add('lazy-hidden');
|
|
||||||
} else {
|
|
||||||
switchCanvas(elem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function lazyChildren(elem) {
|
export function lazyChildren(elem) {
|
||||||
|
if (userSettings.enableBlurhash()) {
|
||||||
|
for (const lazyElem of elem.querySelectorAll('.lazy')) {
|
||||||
|
const blurhashstr = lazyElem.getAttribute('data-blurhash');
|
||||||
|
if (!lazyElem.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) {
|
||||||
|
itemBlurhashing(lazyElem, blurhashstr);
|
||||||
|
} else if (!blurhashstr && !lazyElem.classList.contains('blurhashed')) {
|
||||||
|
lazyElem.classList.add('non-blurhashable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
lazyLoader.lazyChildren(elem, fillImage);
|
lazyLoader.lazyChildren(elem, fillImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,8 +200,15 @@ import 'css!./style';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setLazyImage(element, url) {
|
||||||
|
element.classList.add('lazy');
|
||||||
|
element.setAttribute('data-src', url);
|
||||||
|
lazyImage(element);
|
||||||
|
}
|
||||||
|
|
||||||
/* eslint-enable indent */
|
/* eslint-enable indent */
|
||||||
export default {
|
export default {
|
||||||
|
serLazyImage: setLazyImage,
|
||||||
fillImages: fillImages,
|
fillImages: fillImages,
|
||||||
fillImage: fillImage,
|
fillImage: fillImage,
|
||||||
lazyImage: lazyImage,
|
lazyImage: lazyImage,
|
||||||
|
|
|
@ -12,12 +12,22 @@
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes fadein {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.lazy-blurhash-fadein-fast {
|
.lazy-blurhash-fadein-fast {
|
||||||
transition: opacity 0.2s;
|
animation: fadein 0.1s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lazy-blurhash-fadein {
|
.lazy-blurhash-fadein {
|
||||||
transition: opacity 0.7s;
|
animation: fadein 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blurhash-canvas {
|
.blurhash-canvas {
|
||||||
|
@ -28,6 +38,5 @@
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 100;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,23 @@ import actionsheet from 'actionsheet';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (playbackManager.getCurrentPlayer() !== null) {
|
||||||
|
if (options.stopPlayback) {
|
||||||
|
commands.push({
|
||||||
|
name: globalize.translate('StopPlayback'),
|
||||||
|
id: 'stopPlayback',
|
||||||
|
icon: 'stop'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.clearQueue) {
|
||||||
|
commands.push({
|
||||||
|
name: globalize.translate('ClearQueue'),
|
||||||
|
id: 'clearQueue',
|
||||||
|
icon: 'clear_all'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (playbackManager.canQueue(item)) {
|
if (playbackManager.canQueue(item)) {
|
||||||
if (options.queue !== false) {
|
if (options.queue !== false) {
|
||||||
commands.push({
|
commands.push({
|
||||||
|
@ -54,13 +71,6 @@ import actionsheet from 'actionsheet';
|
||||||
icon: 'playlist_add'
|
icon: 'playlist_add'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (options.queueAllFromHere) {
|
|
||||||
// commands.push({
|
|
||||||
// name: globalize.translate("QueueAllFromHere"),
|
|
||||||
// id: "queueallfromhere"
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.IsFolder || item.Type === 'MusicArtist' || item.Type === 'MusicGenre') {
|
if (item.IsFolder || item.Type === 'MusicArtist' || item.Type === 'MusicGenre') {
|
||||||
|
@ -298,10 +308,11 @@ import actionsheet from 'actionsheet';
|
||||||
icon: 'album'
|
icon: 'album'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Show Album Artist by default, as a song can have multiple artists, which specific one would this option refer to?
|
||||||
if (options.openArtist !== false && item.ArtistItems && item.ArtistItems.length) {
|
// Although some albums can have multiple artists, it's not as common as songs.
|
||||||
|
if (options.openArtist !== false && item.AlbumArtists && item.AlbumArtists.length) {
|
||||||
commands.push({
|
commands.push({
|
||||||
name: globalize.translate('ViewArtist'),
|
name: globalize.translate('ViewAlbumArtist'),
|
||||||
id: 'artist',
|
id: 'artist',
|
||||||
icon: 'person'
|
icon: 'person'
|
||||||
});
|
});
|
||||||
|
@ -441,6 +452,12 @@ import actionsheet from 'actionsheet';
|
||||||
play(item, false, true, true);
|
play(item, false, true, true);
|
||||||
getResolveFunction(resolve, id)();
|
getResolveFunction(resolve, id)();
|
||||||
break;
|
break;
|
||||||
|
case 'stopPlayback':
|
||||||
|
playbackManager.stop();
|
||||||
|
break;
|
||||||
|
case 'clearQueue':
|
||||||
|
playbackManager.clearQueue();
|
||||||
|
break;
|
||||||
case 'record':
|
case 'record':
|
||||||
import('recordingCreator').then(({default: recordingCreator}) => {
|
import('recordingCreator').then(({default: recordingCreator}) => {
|
||||||
recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
|
recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
|
||||||
|
@ -469,7 +486,7 @@ import actionsheet from 'actionsheet';
|
||||||
getResolveFunction(resolve, id)();
|
getResolveFunction(resolve, id)();
|
||||||
break;
|
break;
|
||||||
case 'artist':
|
case 'artist':
|
||||||
appRouter.showItem(item.ArtistItems[0].Id, item.ServerId);
|
appRouter.showItem(item.AlbumArtists[0].Id, item.ServerId);
|
||||||
getResolveFunction(resolve, id)();
|
getResolveFunction(resolve, id)();
|
||||||
break;
|
break;
|
||||||
case 'playallfromhere':
|
case 'playallfromhere':
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
define(['apphost', 'globalize'], function (appHost, globalize) {
|
define(['apphost', 'globalize'], function (appHost, globalize) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function getDisplayName(item, options) {
|
function getDisplayName(item, options = {}) {
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
throw new Error('null item passed into getDisplayName');
|
throw new Error('null item passed into getDisplayName');
|
||||||
}
|
}
|
||||||
|
|
||||||
options = options || {};
|
|
||||||
|
|
||||||
if (item.Type === 'Timer') {
|
if (item.Type === 'Timer') {
|
||||||
item = item.ProgramInfo || item;
|
item = item.ProgramInfo || item;
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,13 +240,19 @@ import 'cardStyle';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
let numLines = 2;
|
let numLines = 2;
|
||||||
|
=======
|
||||||
|
var numLines = 3;
|
||||||
|
>>>>>>> upstream/master
|
||||||
if (currentItemType === 'MusicAlbum') {
|
if (currentItemType === 'MusicAlbum') {
|
||||||
numLines++;
|
numLines++;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lines = [result.Name];
|
const lines = [result.Name];
|
||||||
|
|
||||||
|
lines.push(result.SearchProviderName);
|
||||||
|
|
||||||
if (result.AlbumArtist) {
|
if (result.AlbumArtist) {
|
||||||
lines.push(result.AlbumArtist.Name);
|
lines.push(result.AlbumArtist.Name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +16,10 @@ import datetime from 'datetime';
|
||||||
import 'css!./listview';
|
import 'css!./listview';
|
||||||
import 'emby-ratingbutton';
|
import 'emby-ratingbutton';
|
||||||
import 'emby-playstatebutton';
|
import 'emby-playstatebutton';
|
||||||
|
=======
|
||||||
|
define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutManager', 'globalize', 'datetime', 'cardBuilder', 'css!./listview', 'emby-ratingbutton', 'emby-playstatebutton'], function (itemHelper, mediaInfo, indicators, connectionManager, layoutManager, globalize, datetime, cardBuilder) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
function getIndex(item, options) {
|
function getIndex(item, options) {
|
||||||
|
|
||||||
|
@ -106,11 +111,8 @@ import 'emby-playstatebutton';
|
||||||
itemId = item.ParentPrimaryImageItemId;
|
itemId = item.ParentPrimaryImageItemId;
|
||||||
}
|
}
|
||||||
|
|
||||||
let blurHashes = item.ImageBlurHashes || {};
|
|
||||||
let blurhashstr = (blurHashes[options.type] || {})[options.tag];
|
|
||||||
|
|
||||||
if (itemId) {
|
if (itemId) {
|
||||||
return { url: apiClient.getScaledImageUrl(itemId, options), blurhash: blurhashstr };
|
return apiClient.getScaledImageUrl(itemId, options);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -126,24 +128,30 @@ import 'emby-playstatebutton';
|
||||||
if (item.ChannelId && item.ChannelPrimaryImageTag) {
|
if (item.ChannelId && item.ChannelPrimaryImageTag) {
|
||||||
options.tag = item.ChannelPrimaryImageTag;
|
options.tag = item.ChannelPrimaryImageTag;
|
||||||
}
|
}
|
||||||
let blurHashes = item.ImageBlurHashes || {};
|
|
||||||
let blurhashstr = (blurHashes[options.type])[options.tag];
|
|
||||||
|
|
||||||
if (item.ChannelId) {
|
if (item.ChannelId) {
|
||||||
return { url: apiClient.getScaledImageUrl(item.ChannelId, options), blurhash: blurhashstr };
|
return apiClient.getScaledImageUrl(item.ChannelId, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTextLinesHtml(textlines, isLargeStyle) {
|
function getTextLinesHtml(textlines, isLargeStyle) {
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
let html = '';
|
let html = '';
|
||||||
|
=======
|
||||||
|
var html = '';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
const largeTitleTagName = layoutManager.tv ? 'h2' : 'div';
|
const largeTitleTagName = layoutManager.tv ? 'h2' : 'div';
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
for (let i = 0, length = textlines.length; i < length; i++) {
|
for (let i = 0, length = textlines.length; i < length; i++) {
|
||||||
|
|
||||||
const text = textlines[i];
|
const text = textlines[i];
|
||||||
|
|
||||||
|
=======
|
||||||
|
for (const [i, text] of textlines.entries()) {
|
||||||
|
>>>>>>> upstream/master
|
||||||
if (!text) {
|
if (!text) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -284,10 +292,8 @@ import 'emby-playstatebutton';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.image !== false) {
|
if (options.image !== false) {
|
||||||
let imgData = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth);
|
var imgUrl = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth);
|
||||||
let imgUrl = imgData.url;
|
var imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage';
|
||||||
let blurhash = imgData.blurhash;
|
|
||||||
let imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage';
|
|
||||||
|
|
||||||
if (isLargeStyle && layoutManager.tv) {
|
if (isLargeStyle && layoutManager.tv) {
|
||||||
imageClass += ' listItemImage-large-tv';
|
imageClass += ' listItemImage-large-tv';
|
||||||
|
@ -299,6 +305,7 @@ import 'emby-playstatebutton';
|
||||||
imageClass += ' itemAction';
|
imageClass += ' itemAction';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
const imageAction = playOnImageClick ? 'resume' : action;
|
const imageAction = playOnImageClick ? 'resume' : action;
|
||||||
|
|
||||||
let blurhashAttrib = '';
|
let blurhashAttrib = '';
|
||||||
|
@ -310,6 +317,14 @@ import 'emby-playstatebutton';
|
||||||
html += `<div data-action="${imageAction}" class="${imageClass} lazy" data-src="${imgUrl}" ${blurhashAttrib} item-icon>`;
|
html += `<div data-action="${imageAction}" class="${imageClass} lazy" data-src="${imgUrl}" ${blurhashAttrib} item-icon>`;
|
||||||
} else {
|
} else {
|
||||||
html += `<div class="${imageClass}">`;
|
html += `<div class="${imageClass}">`;
|
||||||
|
=======
|
||||||
|
var imageAction = playOnImageClick ? 'link' : action;
|
||||||
|
|
||||||
|
if (imgUrl) {
|
||||||
|
html += '<div data-action="' + imageAction + '" class="' + imageClass + ' lazy" data-src="' + imgUrl + '" item-icon>';
|
||||||
|
} else {
|
||||||
|
html += '<div class="' + imageClass + ' cardImageContainer ' + cardBuilder.getDefaultBackgroundClass(item.Name) + '">' + cardBuilder.getDefaultText(item, options);
|
||||||
|
>>>>>>> upstream/master
|
||||||
}
|
}
|
||||||
|
|
||||||
let indicatorsHtml = '';
|
let indicatorsHtml = '';
|
||||||
|
@ -449,8 +464,6 @@ import 'emby-playstatebutton';
|
||||||
|
|
||||||
html += `<div class="${cssClass}">`;
|
html += `<div class="${cssClass}">`;
|
||||||
|
|
||||||
const moreIcon = 'more_vert';
|
|
||||||
|
|
||||||
html += getTextLinesHtml(textlines, isLargeStyle);
|
html += getTextLinesHtml(textlines, isLargeStyle);
|
||||||
|
|
||||||
if (options.mediaInfo !== false) {
|
if (options.mediaInfo !== false) {
|
||||||
|
@ -505,10 +518,13 @@ import 'emby-playstatebutton';
|
||||||
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="addtoplaylist"><span class="material-icons playlist_add"></span></button>';
|
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="addtoplaylist"><span class="material-icons playlist_add"></span></button>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
if (options.moreButton !== false) {
|
if (options.moreButton !== false) {
|
||||||
html += `<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="menu"><span class="material-icons ${moreIcon}"></span></button>`;
|
html += `<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="menu"><span class="material-icons ${moreIcon}"></span></button>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> upstream/master
|
||||||
if (options.infoButton) {
|
if (options.infoButton) {
|
||||||
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="link"><span class="material-icons info_outline"></span></button>';
|
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="link"><span class="material-icons info_outline"></span></button>';
|
||||||
}
|
}
|
||||||
|
@ -522,13 +538,26 @@ import 'emby-playstatebutton';
|
||||||
const userData = item.UserData || {};
|
const userData = item.UserData || {};
|
||||||
const likes = userData.Likes == null ? '' : userData.Likes;
|
const likes = userData.Likes == null ? '' : userData.Likes;
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
if (itemHelper.canMarkPlayed(item)) {
|
if (itemHelper.canMarkPlayed(item)) {
|
||||||
html += `<button is="emby-playstatebutton" type="button" class="listItemButton paper-icon-button-light" data-id="${item.Id}" data-serverid="${item.ServerId}" data-itemtype="${item.Type}" data-played="${userData.Played}"><span class="material-icons check"></span></button>`;
|
html += `<button is="emby-playstatebutton" type="button" class="listItemButton paper-icon-button-light" data-id="${item.Id}" data-serverid="${item.ServerId}" data-itemtype="${item.Type}" data-played="${userData.Played}"><span class="material-icons check"></span></button>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemHelper.canRate(item)) {
|
if (itemHelper.canRate(item)) {
|
||||||
html += `<button is="emby-ratingbutton" type="button" class="listItemButton paper-icon-button-light" data-id="${item.Id}" data-serverid="${item.ServerId}" data-itemtype="${item.Type}" data-likes="${likes}" data-isfavorite="${userData.IsFavorite}"><span class="material-icons favorite"></span></button>`;
|
html += `<button is="emby-ratingbutton" type="button" class="listItemButton paper-icon-button-light" data-id="${item.Id}" data-serverid="${item.ServerId}" data-itemtype="${item.Type}" data-likes="${likes}" data-isfavorite="${userData.IsFavorite}"><span class="material-icons favorite"></span></button>`;
|
||||||
|
=======
|
||||||
|
if (itemHelper.canMarkPlayed(item) && options.enablePlayedButton !== false) {
|
||||||
|
html += '<button is="emby-playstatebutton" type="button" class="listItemButton paper-icon-button-light" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-played="' + (userData.Played) + '"><span class="material-icons check"></span></button>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (itemHelper.canRate(item) && options.enableRatingButton !== false) {
|
||||||
|
html += '<button is="emby-ratingbutton" type="button" class="listItemButton paper-icon-button-light" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><span class="material-icons favorite"></span></button>';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.moreButton !== false) {
|
||||||
|
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="menu"><span class="material-icons more_vert"></span></button>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
|
@ -1,10 +1,6 @@
|
||||||
define(['components/loading/loadingLegacy', 'browser', 'css!./loading'], function (loadingLegacy, browser) {
|
define(['css!./loading'], function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
if (browser.tizen || browser.operaTv || browser.chromecast || browser.orsay || browser.web0s || browser.ps4) {
|
|
||||||
return loadingLegacy;
|
|
||||||
}
|
|
||||||
|
|
||||||
var loadingElem;
|
var loadingElem;
|
||||||
var layer1;
|
var layer1;
|
||||||
var layer2;
|
var layer2;
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
.loading-spinner {
|
|
||||||
margin-top: -3em;
|
|
||||||
margin-left: -3em;
|
|
||||||
width: 6em;
|
|
||||||
height: 6em;
|
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
z-index: 9999999;
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
define(['require', 'css!./loadingLegacy'], function (require) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var loadingElem;
|
|
||||||
|
|
||||||
return {
|
|
||||||
show: function () {
|
|
||||||
var elem = loadingElem;
|
|
||||||
if (!elem) {
|
|
||||||
elem = document.createElement('img');
|
|
||||||
elem.src = require.toUrl('.').split('?')[0] + '/loader.gif';
|
|
||||||
|
|
||||||
loadingElem = elem;
|
|
||||||
elem.classList.add('loading-spinner');
|
|
||||||
|
|
||||||
document.body.appendChild(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
elem.classList.remove('hide');
|
|
||||||
},
|
|
||||||
hide: function () {
|
|
||||||
var elem = loadingElem;
|
|
||||||
if (elem) {
|
|
||||||
elem.classList.add('hide');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -41,6 +41,8 @@
|
||||||
width: auto !important;
|
width: auto !important;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
font-size: 1.4em;
|
font-size: 1.4em;
|
||||||
|
margin-right: 0.125em;
|
||||||
|
color: #f2b01e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mediaInfoCriticRating {
|
.mediaInfoCriticRating {
|
||||||
|
|
|
@ -266,6 +266,43 @@ import 'flexStyles';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function afterDeleted(context, item) {
|
||||||
|
var parentId = item.ParentId || item.SeasonId || item.SeriesId;
|
||||||
|
|
||||||
|
if (parentId) {
|
||||||
|
reload(context, parentId, item.ServerId);
|
||||||
|
} else {
|
||||||
|
require(['appRouter'], function (appRouter) {
|
||||||
|
appRouter.goHome();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMoreMenu(context, button, user) {
|
||||||
|
require(['itemContextMenu'], function (itemContextMenu) {
|
||||||
|
var item = currentItem;
|
||||||
|
|
||||||
|
itemContextMenu.show({
|
||||||
|
item: item,
|
||||||
|
positionTo: button,
|
||||||
|
edit: false,
|
||||||
|
editImages: true,
|
||||||
|
editSubtitles: true,
|
||||||
|
sync: false,
|
||||||
|
share: false,
|
||||||
|
play: false,
|
||||||
|
queue: false,
|
||||||
|
user: user
|
||||||
|
}).then(function (result) {
|
||||||
|
if (result.deleted) {
|
||||||
|
afterDeleted(context, item);
|
||||||
|
} else if (result.updated) {
|
||||||
|
reload(context, item.Id, item.ServerId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function onEditorClick(e) {
|
function onEditorClick(e) {
|
||||||
|
|
||||||
const btnRemoveFromEditorList = dom.parentWithClass(e.target, 'btnRemoveFromEditorList');
|
const btnRemoveFromEditorList = dom.parentWithClass(e.target, 'btnRemoveFromEditorList');
|
||||||
|
@ -291,7 +328,6 @@ import 'flexStyles';
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(context, apiClient) {
|
function init(context, apiClient) {
|
||||||
|
|
||||||
context.querySelector('.externalIds').addEventListener('click', function (e) {
|
context.querySelector('.externalIds').addEventListener('click', function (e) {
|
||||||
const btnOpenExternalId = dom.parentWithClass(e.target, 'btnOpenExternalId');
|
const btnOpenExternalId = dom.parentWithClass(e.target, 'btnOpenExternalId');
|
||||||
if (btnOpenExternalId) {
|
if (btnOpenExternalId) {
|
||||||
|
@ -315,13 +351,17 @@ import 'flexStyles';
|
||||||
closeDialog(false);
|
closeDialog(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
context.querySelector('.btnHeaderSave').addEventListener('click', function (e) {
|
context.querySelector('.btnMore').addEventListener('click', function (e) {
|
||||||
|
getApiClient().getCurrentUser().then(function (user) {
|
||||||
|
showMoreMenu(context, e.target, user);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context.querySelector('.btnHeaderSave').addEventListener('click', function (e) {
|
||||||
context.querySelector('.btnSave').click();
|
context.querySelector('.btnSave').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
context.querySelector('#chkLockData').addEventListener('click', function (e) {
|
context.querySelector('#chkLockData').addEventListener('click', function (e) {
|
||||||
|
|
||||||
if (!e.target.checked) {
|
if (!e.target.checked) {
|
||||||
showElement('.providerSettingsContainer');
|
showElement('.providerSettingsContainer');
|
||||||
} else {
|
} else {
|
||||||
|
@ -1107,6 +1147,7 @@ import 'flexStyles';
|
||||||
elem.innerHTML = globalize.translateHtml(template, 'core');
|
elem.innerHTML = globalize.translateHtml(template, 'core');
|
||||||
|
|
||||||
elem.querySelector('.formDialogFooter').classList.remove('formDialogFooter');
|
elem.querySelector('.formDialogFooter').classList.remove('formDialogFooter');
|
||||||
|
elem.querySelector('.btnClose').classList.add('hide');
|
||||||
elem.querySelector('.btnHeaderSave').classList.remove('hide');
|
elem.querySelector('.btnHeaderSave').classList.remove('hide');
|
||||||
elem.querySelector('.btnCancel').classList.add('hide');
|
elem.querySelector('.btnCancel').classList.add('hide');
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
<span class="material-icons check"></span>
|
<span class="material-icons check"></span>
|
||||||
<span>${Save}</span>
|
<span>${Save}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button is="paper-icon-button-light" class="btnMore autoSize" tabindex="-1">
|
||||||
|
<span class="material-icons more_vert"></span>
|
||||||
|
</button>
|
||||||
<button is="paper-icon-button-light" class="btnCancel btnClose autoSize" tabindex="-1">
|
<button is="paper-icon-button-light" class="btnCancel btnClose autoSize" tabindex="-1">
|
||||||
<span class="material-icons close"></span>
|
<span class="material-icons close"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
text-align: left;
|
text-align: left;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 92%;
|
font-size: 92%;
|
||||||
margin-right: 2.4em;
|
margin-right: 1em;
|
||||||
margin-left: 1em;
|
margin-left: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingBarCenter {
|
.nowPlayingBarCenter {
|
||||||
|
@ -114,8 +114,6 @@
|
||||||
|
|
||||||
.nowPlayingBarUserDataButtons {
|
.nowPlayingBarUserDataButtons {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: 1em;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingBarPositionSlider::-webkit-slider-thumb {
|
.nowPlayingBarPositionSlider::-webkit-slider-thumb {
|
||||||
|
@ -133,33 +131,50 @@
|
||||||
.toggleRepeatButton {
|
.toggleRepeatButton {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@media all and (max-width: 62em) {
|
.nowPlayingBar .btnShuffleQueue {
|
||||||
.nowPlayingBarCenter .nowPlayingBarCurrentTime {
|
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media all and (max-width: 80em) {
|
||||||
|
.nowPlayingBarCenter .nowPlayingBarCurrentTime,
|
||||||
|
.nowPlayingBarCenter .stopButton {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nowPlayingBarInfoContainer {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .nowPlayingBarRight button:not(.playPauseButton, .nextTrackButton) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .nowPlayingBarRight .playPauseButton,
|
||||||
|
.layout-tv .nowPlayingBarRight .playPauseButton {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .nowPlayingBarRight input,
|
||||||
|
.layout-mobile .nowPlayingBarRight div {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media all and (max-width: 56em) {
|
@media all and (max-width: 56em) {
|
||||||
.nowPlayingBarCenter {
|
.nowPlayingBarCenter {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-width: 56em) {
|
@media all and (max-width: 60em) {
|
||||||
.nowPlayingBarRight .playPauseButton {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all and (max-width: 36em) {
|
|
||||||
.nowPlayingBarRight .nowPlayingBarVolumeSliderContainer {
|
.nowPlayingBarRight .nowPlayingBarVolumeSliderContainer {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingBarInfoContainer {
|
.nowPlayingBarInfoContainer {
|
||||||
width: 70%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,9 @@ import 'emby-ratingbutton';
|
||||||
html += '<button is="paper-icon-button-light" class="playPauseButton mediaButton"><span class="material-icons pause"></span></button>';
|
html += '<button is="paper-icon-button-light" class="playPauseButton mediaButton"><span class="material-icons pause"></span></button>';
|
||||||
|
|
||||||
html += '<button is="paper-icon-button-light" class="stopButton mediaButton"><span class="material-icons stop"></span></button>';
|
html += '<button is="paper-icon-button-light" class="stopButton mediaButton"><span class="material-icons stop"></span></button>';
|
||||||
html += '<button is="paper-icon-button-light" class="nextTrackButton mediaButton"><span class="material-icons skip_next"></span></button>';
|
if (!layoutManager.mobile) {
|
||||||
|
html += '<button is="paper-icon-button-light" class="nextTrackButton mediaButton"><span class="material-icons skip_next"></span></button>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<div class="nowPlayingBarCurrentTime"></div>';
|
html += '<div class="nowPlayingBarCurrentTime"></div>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
@ -76,12 +78,17 @@ import 'emby-ratingbutton';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
html += '<button is="paper-icon-button-light" class="toggleRepeatButton mediaButton"><span class="material-icons repeat"></span></button>';
|
html += '<button is="paper-icon-button-light" class="toggleRepeatButton mediaButton"><span class="material-icons repeat"></span></button>';
|
||||||
|
html += '<button is="paper-icon-button-light" class="btnShuffleQueue mediaButton"><span class="material-icons shuffle"></span></button>';
|
||||||
|
|
||||||
html += '<div class="nowPlayingBarUserDataButtons">';
|
html += '<div class="nowPlayingBarUserDataButtons">';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
html += '<button is="paper-icon-button-light" class="playPauseButton mediaButton"><span class="material-icons pause"></span></button>';
|
html += '<button is="paper-icon-button-light" class="playPauseButton mediaButton"><span class="material-icons pause"></span></button>';
|
||||||
html += '<button is="paper-icon-button-light" class="btnToggleContextMenu"><span class="material-icons more_vert"></span></button>';
|
if (layoutManager.mobile) {
|
||||||
|
html += '<button is="paper-icon-button-light" class="nextTrackButton mediaButton"><span class="material-icons skip_next"></span></button>';
|
||||||
|
} else {
|
||||||
|
html += '<button is="paper-icon-button-light" class="btnToggleContextMenu mediaButton"><span class="material-icons more_vert"></span></button>';
|
||||||
|
}
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
@ -132,8 +139,13 @@ import 'emby-ratingbutton';
|
||||||
nowPlayingImageElement = elem.querySelector('.nowPlayingImage');
|
nowPlayingImageElement = elem.querySelector('.nowPlayingImage');
|
||||||
nowPlayingTextElement = elem.querySelector('.nowPlayingBarText');
|
nowPlayingTextElement = elem.querySelector('.nowPlayingBarText');
|
||||||
nowPlayingUserData = elem.querySelector('.nowPlayingBarUserDataButtons');
|
nowPlayingUserData = elem.querySelector('.nowPlayingBarUserDataButtons');
|
||||||
|
positionSlider = elem.querySelector('.nowPlayingBarPositionSlider');
|
||||||
muteButton = elem.querySelector('.muteButton');
|
muteButton = elem.querySelector('.muteButton');
|
||||||
|
playPauseButtons = elem.querySelectorAll('.playPauseButton');
|
||||||
|
toggleRepeatButton = elem.querySelector('.toggleRepeatButton');
|
||||||
|
volumeSlider = elem.querySelector('.nowPlayingBarVolumeSlider');
|
||||||
|
volumeSliderContainer = elem.querySelector('.nowPlayingBarVolumeSliderContainer');
|
||||||
|
|
||||||
muteButton.addEventListener('click', function () {
|
muteButton.addEventListener('click', function () {
|
||||||
|
|
||||||
if (currentPlayer) {
|
if (currentPlayer) {
|
||||||
|
@ -149,7 +161,6 @@ import 'emby-ratingbutton';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
playPauseButtons = elem.querySelectorAll('.playPauseButton');
|
|
||||||
playPauseButtons.forEach((button) => {
|
playPauseButtons.forEach((button) => {
|
||||||
button.addEventListener('click', onPlayPauseClick);
|
button.addEventListener('click', onPlayPauseClick);
|
||||||
});
|
});
|
||||||
|
@ -161,54 +172,59 @@ import 'emby-ratingbutton';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
elem.querySelector('.previousTrackButton').addEventListener('click', function () {
|
elem.querySelector('.previousTrackButton').addEventListener('click', function (e) {
|
||||||
|
if (currentPlayer) {
|
||||||
|
if (lastPlayerState.NowPlayingItem.MediaType === 'Audio' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) {
|
||||||
|
// Cancel this event if doubleclick is fired
|
||||||
|
if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
playbackManager.seekPercent(0, currentPlayer);
|
||||||
|
// This is done automatically by playbackManager, however, setting this here gives instant visual feedback.
|
||||||
|
// TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround.
|
||||||
|
positionSlider.value = 0;
|
||||||
|
} else {
|
||||||
|
playbackManager.previousTrack(currentPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
elem.querySelector('.previousTrackButton').addEventListener('dblclick', function () {
|
||||||
if (currentPlayer) {
|
if (currentPlayer) {
|
||||||
playbackManager.previousTrack(currentPlayer);
|
playbackManager.previousTrack(currentPlayer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
elem.querySelector('.btnShuffleQueue').addEventListener('click', function () {
|
||||||
|
if (currentPlayer) {
|
||||||
|
playbackManager.toggleQueueShuffleMode();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
toggleRepeatButton = elem.querySelector('.toggleRepeatButton');
|
toggleRepeatButton = elem.querySelector('.toggleRepeatButton');
|
||||||
toggleRepeatButton.addEventListener('click', function () {
|
toggleRepeatButton.addEventListener('click', function () {
|
||||||
|
switch (playbackManager.getRepeatMode()) {
|
||||||
if (currentPlayer) {
|
case 'RepeatAll':
|
||||||
|
playbackManager.setRepeatMode('RepeatOne');
|
||||||
switch (playbackManager.getRepeatMode(currentPlayer)) {
|
break;
|
||||||
case 'RepeatAll':
|
case 'RepeatOne':
|
||||||
playbackManager.setRepeatMode('RepeatOne', currentPlayer);
|
playbackManager.setRepeatMode('RepeatNone');
|
||||||
break;
|
break;
|
||||||
case 'RepeatOne':
|
case 'RepeatNone':
|
||||||
playbackManager.setRepeatMode('RepeatNone', currentPlayer);
|
playbackManager.setRepeatMode('RepeatAll');
|
||||||
break;
|
|
||||||
default:
|
|
||||||
playbackManager.setRepeatMode('RepeatAll', currentPlayer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
toggleRepeatButtonIcon = toggleRepeatButton.querySelector('.material-icons');
|
toggleRepeatButtonIcon = toggleRepeatButton.querySelector('.material-icons');
|
||||||
|
|
||||||
volumeSlider = elem.querySelector('.nowPlayingBarVolumeSlider');
|
volumeSliderContainer.classList.toggle('hide', appHost.supports('physicalvolumecontrol'));
|
||||||
volumeSliderContainer = elem.querySelector('.nowPlayingBarVolumeSliderContainer');
|
|
||||||
|
|
||||||
if (appHost.supports('physicalvolumecontrol')) {
|
volumeSlider.addEventListener('input', (e) => {
|
||||||
volumeSliderContainer.classList.add('hide');
|
|
||||||
} else {
|
|
||||||
volumeSliderContainer.classList.remove('hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
function setVolume() {
|
|
||||||
if (currentPlayer) {
|
if (currentPlayer) {
|
||||||
currentPlayer.setVolume(this.value);
|
currentPlayer.setVolume(e.target.value);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
volumeSlider.addEventListener('change', setVolume);
|
|
||||||
volumeSlider.addEventListener('mousemove', setVolume);
|
|
||||||
volumeSlider.addEventListener('touchmove', setVolume);
|
|
||||||
|
|
||||||
positionSlider = elem.querySelector('.nowPlayingBarPositionSlider');
|
|
||||||
positionSlider.addEventListener('change', function () {
|
positionSlider.addEventListener('change', function () {
|
||||||
|
|
||||||
if (currentPlayer) {
|
if (currentPlayer) {
|
||||||
|
@ -277,6 +293,11 @@ import 'emby-ratingbutton';
|
||||||
parentContainer.insertAdjacentHTML('afterbegin', getNowPlayingBarHtml());
|
parentContainer.insertAdjacentHTML('afterbegin', getNowPlayingBarHtml());
|
||||||
nowPlayingBarElement = parentContainer.querySelector('.nowPlayingBar');
|
nowPlayingBarElement = parentContainer.querySelector('.nowPlayingBar');
|
||||||
|
|
||||||
|
if (layoutManager.mobile) {
|
||||||
|
hideButton(nowPlayingBarElement.querySelector('.btnShuffleQueue'));
|
||||||
|
hideButton(nowPlayingBarElement.querySelector('.nowPlayingBarCenter'));
|
||||||
|
}
|
||||||
|
|
||||||
if (browser.safari && browser.slow) {
|
if (browser.safari && browser.slow) {
|
||||||
// Not handled well here. The wrong elements receive events, bar doesn't update quickly enough, etc.
|
// Not handled well here. The wrong elements receive events, bar doesn't update quickly enough, etc.
|
||||||
nowPlayingBarElement.classList.add('noMediaProgress');
|
nowPlayingBarElement.classList.add('noMediaProgress');
|
||||||
|
@ -329,7 +350,8 @@ import 'emby-ratingbutton';
|
||||||
toggleRepeatButton.classList.remove('hide');
|
toggleRepeatButton.classList.remove('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRepeatModeDisplay(playState.RepeatMode);
|
updateRepeatModeDisplay(playbackManager.getRepeatMode());
|
||||||
|
onQueueShuffleModeChange();
|
||||||
|
|
||||||
updatePlayerVolumeState(playState.IsMuted, playState.VolumeLevel);
|
updatePlayerVolumeState(playState.IsMuted, playState.VolumeLevel);
|
||||||
|
|
||||||
|
@ -349,32 +371,39 @@ import 'emby-ratingbutton';
|
||||||
|
|
||||||
function updateRepeatModeDisplay(repeatMode) {
|
function updateRepeatModeDisplay(repeatMode) {
|
||||||
toggleRepeatButtonIcon.classList.remove('repeat', 'repeat_one');
|
toggleRepeatButtonIcon.classList.remove('repeat', 'repeat_one');
|
||||||
|
const cssClass = 'buttonActive';
|
||||||
|
|
||||||
if (repeatMode === 'RepeatAll') {
|
switch (repeatMode) {
|
||||||
toggleRepeatButtonIcon.classList.add('repeat');
|
case 'RepeatAll':
|
||||||
toggleRepeatButton.classList.add('repeatButton-active');
|
toggleRepeatButtonIcon.classList.add('repeat');
|
||||||
} else if (repeatMode === 'RepeatOne') {
|
toggleRepeatButton.classList.add(cssClass);
|
||||||
toggleRepeatButtonIcon.classList.add('repeat_one');
|
break;
|
||||||
toggleRepeatButton.classList.add('repeatButton-active');
|
case 'RepeatOne':
|
||||||
} else {
|
toggleRepeatButtonIcon.classList.add('repeat_one');
|
||||||
toggleRepeatButtonIcon.classList.add('repeat');
|
toggleRepeatButton.classList.add(cssClass);
|
||||||
toggleRepeatButton.classList.remove('repeatButton-active');
|
break;
|
||||||
|
case 'RepeatNone':
|
||||||
|
default:
|
||||||
|
toggleRepeatButtonIcon.classList.add('repeat');
|
||||||
|
toggleRepeatButton.classList.remove(cssClass);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimeDisplay(positionTicks, runtimeTicks, bufferedRanges) {
|
function updateTimeDisplay(positionTicks, runtimeTicks, bufferedRanges) {
|
||||||
|
|
||||||
// See bindEvents for why this is necessary
|
// See bindEvents for why this is necessary
|
||||||
if (positionSlider && !positionSlider.dragging) {
|
if (positionSlider && !positionSlider.dragging) {
|
||||||
if (runtimeTicks) {
|
if (runtimeTicks) {
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
let pct = positionTicks / runtimeTicks;
|
let pct = positionTicks / runtimeTicks;
|
||||||
|
=======
|
||||||
|
var pct = positionTicks / runtimeTicks;
|
||||||
|
>>>>>>> upstream/master
|
||||||
pct *= 100;
|
pct *= 100;
|
||||||
|
|
||||||
positionSlider.value = pct;
|
positionSlider.value = pct;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
positionSlider.value = 0;
|
positionSlider.value = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,9 +413,13 @@ import 'emby-ratingbutton';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTimeElement) {
|
if (currentTimeElement) {
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
let timeText = positionTicks == null ? '--:--' : datetime.getDisplayRunningTime(positionTicks);
|
let timeText = positionTicks == null ? '--:--' : datetime.getDisplayRunningTime(positionTicks);
|
||||||
|
|
||||||
|
=======
|
||||||
|
var timeText = positionTicks == null ? '--:--' : datetime.getDisplayRunningTime(positionTicks);
|
||||||
|
>>>>>>> upstream/master
|
||||||
if (runtimeTicks) {
|
if (runtimeTicks) {
|
||||||
timeText += ' / ' + datetime.getDisplayRunningTime(runtimeTicks);
|
timeText += ' / ' + datetime.getDisplayRunningTime(runtimeTicks);
|
||||||
}
|
}
|
||||||
|
@ -428,11 +461,7 @@ import 'emby-ratingbutton';
|
||||||
// See bindEvents for why this is necessary
|
// See bindEvents for why this is necessary
|
||||||
if (volumeSlider) {
|
if (volumeSlider) {
|
||||||
|
|
||||||
if (showVolumeSlider) {
|
volumeSliderContainer.classList.toggle('hide', !showVolumeSlider);
|
||||||
volumeSliderContainer.classList.remove('hide');
|
|
||||||
} else {
|
|
||||||
volumeSliderContainer.classList.add('hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!volumeSlider.dragging) {
|
if (!volumeSlider.dragging) {
|
||||||
volumeSlider.value = volumeLevel || 0;
|
volumeSlider.value = volumeLevel || 0;
|
||||||
|
@ -440,15 +469,6 @@ import 'emby-ratingbutton';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTextActionButton(item, text) {
|
|
||||||
|
|
||||||
if (!text) {
|
|
||||||
text = itemHelper.getDisplayName(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return `<a>${text}</a>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function seriesImageUrl(item, options) {
|
function seriesImageUrl(item, options) {
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
@ -520,6 +540,7 @@ import 'emby-ratingbutton';
|
||||||
|
|
||||||
const nowPlayingItem = state.NowPlayingItem;
|
const nowPlayingItem = state.NowPlayingItem;
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
const textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : [];
|
const textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : [];
|
||||||
if (textLines.length > 1) {
|
if (textLines.length > 1) {
|
||||||
textLines[1].secondary = true;
|
textLines[1].secondary = true;
|
||||||
|
@ -536,6 +557,31 @@ import 'emby-ratingbutton';
|
||||||
return `<div ${cssClass}>${nowPlayingText}</div>`;
|
return `<div ${cssClass}>${nowPlayingText}</div>`;
|
||||||
|
|
||||||
}).join('');
|
}).join('');
|
||||||
|
=======
|
||||||
|
var textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : [];
|
||||||
|
nowPlayingTextElement.innerHTML = '';
|
||||||
|
if (textLines) {
|
||||||
|
let itemText = document.createElement('div');
|
||||||
|
let secondaryText = document.createElement('div');
|
||||||
|
secondaryText.classList.add('nowPlayingBarSecondaryText');
|
||||||
|
if (textLines.length > 1) {
|
||||||
|
textLines[1].secondary = true;
|
||||||
|
if (textLines[1].text) {
|
||||||
|
let text = document.createElement('a');
|
||||||
|
text.innerHTML = textLines[1].text;
|
||||||
|
secondaryText.appendChild(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textLines[0].text) {
|
||||||
|
let text = document.createElement('a');
|
||||||
|
text.innerHTML = textLines[0].text;
|
||||||
|
itemText.appendChild(text);
|
||||||
|
}
|
||||||
|
nowPlayingTextElement.appendChild(itemText);
|
||||||
|
nowPlayingTextElement.appendChild(secondaryText);
|
||||||
|
}
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
const imgHeight = 70;
|
const imgHeight = 70;
|
||||||
|
|
||||||
|
@ -553,8 +599,12 @@ import 'emby-ratingbutton';
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
imageLoader.lazyImage(nowPlayingImageElement, url);
|
imageLoader.lazyImage(nowPlayingImageElement, url);
|
||||||
|
nowPlayingImageElement.style.display = null;
|
||||||
|
nowPlayingTextElement.style.marginLeft = null;
|
||||||
} else {
|
} else {
|
||||||
nowPlayingImageElement.style.backgroundImage = '';
|
nowPlayingImageElement.style.backgroundImage = '';
|
||||||
|
nowPlayingImageElement.style.display = 'none';
|
||||||
|
nowPlayingTextElement.style.marginLeft = '1em';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,6 +613,7 @@ import 'emby-ratingbutton';
|
||||||
|
|
||||||
const apiClient = connectionManager.getApiClient(nowPlayingItem.ServerId);
|
const apiClient = connectionManager.getApiClient(nowPlayingItem.ServerId);
|
||||||
apiClient.getItem(apiClient.getCurrentUserId(), nowPlayingItem.Id).then(function (item) {
|
apiClient.getItem(apiClient.getCurrentUserId(), nowPlayingItem.Id).then(function (item) {
|
||||||
|
<<<<<<< HEAD
|
||||||
const userData = item.UserData || {};
|
const userData = item.UserData || {};
|
||||||
const likes = userData.Likes == null ? '' : userData.Likes;
|
const likes = userData.Likes == null ? '' : userData.Likes;
|
||||||
const contextButton = document.querySelector('.btnToggleContextMenu');
|
const contextButton = document.querySelector('.btnToggleContextMenu');
|
||||||
|
@ -578,8 +629,32 @@ import 'emby-ratingbutton';
|
||||||
item: item,
|
item: item,
|
||||||
user: user
|
user: user
|
||||||
}, options ));
|
}, options ));
|
||||||
|
=======
|
||||||
|
var userData = item.UserData || {};
|
||||||
|
var likes = userData.Likes == null ? '' : userData.Likes;
|
||||||
|
if (!layoutManager.mobile) {
|
||||||
|
let contextButton = nowPlayingBarElement.querySelector('.btnToggleContextMenu');
|
||||||
|
// We remove the previous event listener by replacing the item in each update event
|
||||||
|
let contextButtonClone = contextButton.cloneNode(true);
|
||||||
|
contextButton.parentNode.replaceChild(contextButtonClone, contextButton);
|
||||||
|
contextButton = nowPlayingBarElement.querySelector('.btnToggleContextMenu');
|
||||||
|
let options = {
|
||||||
|
play: false,
|
||||||
|
queue: false,
|
||||||
|
clearQueue: true,
|
||||||
|
positionTo: contextButton
|
||||||
|
};
|
||||||
|
apiClient.getCurrentUser().then(function (user) {
|
||||||
|
contextButton.addEventListener('click', function () {
|
||||||
|
itemContextMenu.show(Object.assign({
|
||||||
|
item: item,
|
||||||
|
user: user
|
||||||
|
}, options));
|
||||||
|
});
|
||||||
|
>>>>>>> upstream/master
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
nowPlayingUserData.innerHTML = '<button is="emby-ratingbutton" type="button" class="listItemButton mediaButton paper-icon-button-light" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><span class="material-icons favorite"></span></button>';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -589,25 +664,49 @@ import 'emby-ratingbutton';
|
||||||
|
|
||||||
function onPlaybackStart(e, state) {
|
function onPlaybackStart(e, state) {
|
||||||
console.debug('nowplaying event: ' + e.type);
|
console.debug('nowplaying event: ' + e.type);
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
const player = this;
|
const player = this;
|
||||||
|
|
||||||
|
=======
|
||||||
|
var player = this;
|
||||||
|
>>>>>>> upstream/master
|
||||||
onStateChanged.call(player, e, state);
|
onStateChanged.call(player, e, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRepeatModeChange(e) {
|
function onRepeatModeChange() {
|
||||||
|
|
||||||
if (!isEnabled) {
|
if (!isEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
const player = this;
|
const player = this;
|
||||||
|
=======
|
||||||
|
updateRepeatModeDisplay(playbackManager.getRepeatMode());
|
||||||
|
}
|
||||||
|
|
||||||
updateRepeatModeDisplay(playbackManager.getRepeatMode(player));
|
function onQueueShuffleModeChange() {
|
||||||
|
if (!isEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
|
let shuffleMode = playbackManager.getQueueShuffleMode();
|
||||||
|
let context = nowPlayingBarElement;
|
||||||
|
const cssClass = 'buttonActive';
|
||||||
|
let toggleShuffleButton = context.querySelector('.btnShuffleQueue');
|
||||||
|
switch (shuffleMode) {
|
||||||
|
case 'Shuffle':
|
||||||
|
toggleShuffleButton.classList.add(cssClass);
|
||||||
|
break;
|
||||||
|
case 'Sorted':
|
||||||
|
default:
|
||||||
|
toggleShuffleButton.classList.remove(cssClass);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showNowPlayingBar() {
|
function showNowPlayingBar() {
|
||||||
|
|
||||||
if (!isVisibilityAllowed) {
|
if (!isVisibilityAllowed) {
|
||||||
hideNowPlayingBar();
|
hideNowPlayingBar();
|
||||||
return;
|
return;
|
||||||
|
@ -711,6 +810,7 @@ import 'emby-ratingbutton';
|
||||||
events.off(player, 'playbackstart', onPlaybackStart);
|
events.off(player, 'playbackstart', onPlaybackStart);
|
||||||
events.off(player, 'statechange', onPlaybackStart);
|
events.off(player, 'statechange', onPlaybackStart);
|
||||||
events.off(player, 'repeatmodechange', onRepeatModeChange);
|
events.off(player, 'repeatmodechange', onRepeatModeChange);
|
||||||
|
events.off(player, 'shufflequeuemodechange', onQueueShuffleModeChange);
|
||||||
events.off(player, 'playbackstop', onPlaybackStopped);
|
events.off(player, 'playbackstop', onPlaybackStopped);
|
||||||
events.off(player, 'volumechange', onVolumeChanged);
|
events.off(player, 'volumechange', onVolumeChanged);
|
||||||
events.off(player, 'pause', onPlayPauseStateChanged);
|
events.off(player, 'pause', onPlayPauseStateChanged);
|
||||||
|
@ -759,6 +859,7 @@ import 'emby-ratingbutton';
|
||||||
events.on(player, 'playbackstart', onPlaybackStart);
|
events.on(player, 'playbackstart', onPlaybackStart);
|
||||||
events.on(player, 'statechange', onPlaybackStart);
|
events.on(player, 'statechange', onPlaybackStart);
|
||||||
events.on(player, 'repeatmodechange', onRepeatModeChange);
|
events.on(player, 'repeatmodechange', onRepeatModeChange);
|
||||||
|
events.on(player, 'shufflequeuemodechange', onQueueShuffleModeChange);
|
||||||
events.on(player, 'playbackstop', onPlaybackStopped);
|
events.on(player, 'playbackstop', onPlaybackStopped);
|
||||||
events.on(player, 'volumechange', onVolumeChanged);
|
events.on(player, 'volumechange', onVolumeChanged);
|
||||||
events.on(player, 'pause', onPlayPauseStateChanged);
|
events.on(player, 'pause', onPlayPauseStateChanged);
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) {
|
define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/** Delay time in ms for reportPlayback logging */
|
|
||||||
const reportPlaybackLogDelay = 1e3;
|
|
||||||
|
|
||||||
function enableLocalPlaylistManagement(player) {
|
function enableLocalPlaylistManagement(player) {
|
||||||
|
|
||||||
if (player.getPlaylist) {
|
if (player.getPlaylist) {
|
||||||
|
@ -43,12 +40,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]);
|
events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Last invoked method */
|
|
||||||
let reportPlaybackLastMethod;
|
|
||||||
|
|
||||||
/** Last invoke time of method */
|
|
||||||
let reportPlaybackLastTime;
|
|
||||||
|
|
||||||
function reportPlayback(playbackManagerInstance, state, player, reportPlaylist, serverId, method, progressEventName) {
|
function reportPlayback(playbackManagerInstance, state, player, reportPlaylist, serverId, method, progressEventName) {
|
||||||
|
|
||||||
if (!serverId) {
|
if (!serverId) {
|
||||||
|
@ -69,14 +60,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId);
|
addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = (new Date).getTime();
|
|
||||||
|
|
||||||
if (method !== reportPlaybackLastMethod || now - (reportPlaybackLastTime || 0) >= reportPlaybackLogDelay) {
|
|
||||||
console.debug(method + '-' + JSON.stringify(info));
|
|
||||||
reportPlaybackLastMethod = method;
|
|
||||||
reportPlaybackLastTime = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
var apiClient = connectionManager.getApiClient(serverId);
|
var apiClient = connectionManager.getApiClient(serverId);
|
||||||
var reportPlaybackPromise = apiClient[method](info);
|
var reportPlaybackPromise = apiClient[method](info);
|
||||||
// Notify that report has been sent
|
// Notify that report has been sent
|
||||||
|
@ -2097,6 +2080,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
state.PlayState.IsMuted = player.isMuted();
|
state.PlayState.IsMuted = player.isMuted();
|
||||||
state.PlayState.IsPaused = player.paused();
|
state.PlayState.IsPaused = player.paused();
|
||||||
state.PlayState.RepeatMode = self.getRepeatMode(player);
|
state.PlayState.RepeatMode = self.getRepeatMode(player);
|
||||||
|
state.PlayState.ShuffleMode = self.getQueueShuffleMode(player);
|
||||||
state.PlayState.MaxStreamingBitrate = self.getMaxStreamingBitrate(player);
|
state.PlayState.MaxStreamingBitrate = self.getMaxStreamingBitrate(player);
|
||||||
|
|
||||||
state.PlayState.PositionTicks = getCurrentTicks(player);
|
state.PlayState.PositionTicks = getCurrentTicks(player);
|
||||||
|
@ -2877,11 +2861,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.queue = function (options, player) {
|
self.queue = function (options, player = this._currentPlayer) {
|
||||||
queue(options, '', player);
|
queue(options, '', player);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.queueNext = function (options, player) {
|
self.queueNext = function (options, player = this._currentPlayer) {
|
||||||
queue(options, 'next', player);
|
queue(options, 'next', player);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2969,6 +2953,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
} else {
|
} else {
|
||||||
self._playQueueManager.queue(items);
|
self._playQueueManager.queue(items);
|
||||||
}
|
}
|
||||||
|
events.trigger(player, 'playlistitemadd');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPlayerProgressInterval() {
|
function onPlayerProgressInterval() {
|
||||||
|
@ -3304,6 +3289,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
sendProgressUpdate(player, 'repeatmodechange');
|
sendProgressUpdate(player, 'repeatmodechange');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onShuffleQueueModeChange() {
|
||||||
|
var player = this;
|
||||||
|
sendProgressUpdate(player, 'shufflequeuemodechange');
|
||||||
|
}
|
||||||
|
|
||||||
function onPlaylistItemMove(e) {
|
function onPlaylistItemMove(e) {
|
||||||
var player = this;
|
var player = this;
|
||||||
sendProgressUpdate(player, 'playlistitemmove', true);
|
sendProgressUpdate(player, 'playlistitemmove', true);
|
||||||
|
@ -3358,6 +3348,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
events.on(player, 'unpause', onPlaybackUnpause);
|
events.on(player, 'unpause', onPlaybackUnpause);
|
||||||
events.on(player, 'volumechange', onPlaybackVolumeChange);
|
events.on(player, 'volumechange', onPlaybackVolumeChange);
|
||||||
events.on(player, 'repeatmodechange', onRepeatModeChange);
|
events.on(player, 'repeatmodechange', onRepeatModeChange);
|
||||||
|
events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange);
|
||||||
events.on(player, 'playlistitemmove', onPlaylistItemMove);
|
events.on(player, 'playlistitemmove', onPlaylistItemMove);
|
||||||
events.on(player, 'playlistitemremove', onPlaylistItemRemove);
|
events.on(player, 'playlistitemremove', onPlaylistItemRemove);
|
||||||
events.on(player, 'playlistitemadd', onPlaylistItemAdd);
|
events.on(player, 'playlistitemadd', onPlaylistItemAdd);
|
||||||
|
@ -3370,6 +3361,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
events.on(player, 'unpause', onPlaybackUnpause);
|
events.on(player, 'unpause', onPlaybackUnpause);
|
||||||
events.on(player, 'volumechange', onPlaybackVolumeChange);
|
events.on(player, 'volumechange', onPlaybackVolumeChange);
|
||||||
events.on(player, 'repeatmodechange', onRepeatModeChange);
|
events.on(player, 'repeatmodechange', onRepeatModeChange);
|
||||||
|
events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange);
|
||||||
events.on(player, 'playlistitemmove', onPlaylistItemMove);
|
events.on(player, 'playlistitemmove', onPlaylistItemMove);
|
||||||
events.on(player, 'playlistitemremove', onPlaylistItemRemove);
|
events.on(player, 'playlistitemremove', onPlaylistItemRemove);
|
||||||
events.on(player, 'playlistitemadd', onPlaylistItemAdd);
|
events.on(player, 'playlistitemadd', onPlaylistItemAdd);
|
||||||
|
@ -3655,6 +3647,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
this.seek(parseInt(ticks), player);
|
this.seek(parseInt(ticks), player);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PlaybackManager.prototype.seekMs = function (ms, player) {
|
||||||
|
|
||||||
|
player = player || this._currentPlayer;
|
||||||
|
|
||||||
|
var ticks = ms * 10000;
|
||||||
|
this.seek(ticks, player);
|
||||||
|
};
|
||||||
|
|
||||||
PlaybackManager.prototype.playTrailers = function (item) {
|
PlaybackManager.prototype.playTrailers = function (item) {
|
||||||
|
|
||||||
var player = this._currentPlayer;
|
var player = this._currentPlayer;
|
||||||
|
@ -3702,7 +3702,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
};
|
};
|
||||||
|
|
||||||
PlaybackManager.prototype.stop = function (player) {
|
PlaybackManager.prototype.stop = function (player) {
|
||||||
|
|
||||||
player = player || this._currentPlayer;
|
player = player || this._currentPlayer;
|
||||||
|
|
||||||
if (player) {
|
if (player) {
|
||||||
|
@ -3811,7 +3810,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
PlaybackManager.prototype.shuffle = function (shuffleItem, player, queryOptions) {
|
PlaybackManager.prototype.shuffle = function (shuffleItem, player) {
|
||||||
|
|
||||||
player = player || this._currentPlayer;
|
player = player || this._currentPlayer;
|
||||||
if (player && player.shuffle) {
|
if (player && player.shuffle) {
|
||||||
|
@ -3878,6 +3877,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
'GoToSearch',
|
'GoToSearch',
|
||||||
'DisplayMessage',
|
'DisplayMessage',
|
||||||
'SetRepeatMode',
|
'SetRepeatMode',
|
||||||
|
'SetShuffleQueue',
|
||||||
'PlayMediaSource',
|
'PlayMediaSource',
|
||||||
'PlayTrailers'
|
'PlayTrailers'
|
||||||
];
|
];
|
||||||
|
@ -3911,9 +3911,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
return info ? info.supportedCommands : [];
|
return info ? info.supportedCommands : [];
|
||||||
};
|
};
|
||||||
|
|
||||||
PlaybackManager.prototype.setRepeatMode = function (value, player) {
|
PlaybackManager.prototype.setRepeatMode = function (value, player = this._currentPlayer) {
|
||||||
|
|
||||||
player = player || this._currentPlayer;
|
|
||||||
if (player && !enableLocalPlaylistManagement(player)) {
|
if (player && !enableLocalPlaylistManagement(player)) {
|
||||||
return player.setRepeatMode(value);
|
return player.setRepeatMode(value);
|
||||||
}
|
}
|
||||||
|
@ -3922,9 +3920,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
events.trigger(player, 'repeatmodechange');
|
events.trigger(player, 'repeatmodechange');
|
||||||
};
|
};
|
||||||
|
|
||||||
PlaybackManager.prototype.getRepeatMode = function (player) {
|
PlaybackManager.prototype.getRepeatMode = function (player = this._currentPlayer) {
|
||||||
|
|
||||||
player = player || this._currentPlayer;
|
|
||||||
if (player && !enableLocalPlaylistManagement(player)) {
|
if (player && !enableLocalPlaylistManagement(player)) {
|
||||||
return player.getRepeatMode();
|
return player.getRepeatMode();
|
||||||
}
|
}
|
||||||
|
@ -3932,6 +3928,52 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
return this._playQueueManager.getRepeatMode();
|
return this._playQueueManager.getRepeatMode();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PlaybackManager.prototype.setQueueShuffleMode = function (value, player = this._currentPlayer) {
|
||||||
|
if (player && !enableLocalPlaylistManagement(player)) {
|
||||||
|
return player.setQueueShuffleMode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._playQueueManager.setShuffleMode(value);
|
||||||
|
events.trigger(player, 'shufflequeuemodechange');
|
||||||
|
};
|
||||||
|
|
||||||
|
PlaybackManager.prototype.getQueueShuffleMode = function (player = this._currentPlayer) {
|
||||||
|
if (player && !enableLocalPlaylistManagement(player)) {
|
||||||
|
return player.getQueueShuffleMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._playQueueManager.getShuffleMode();
|
||||||
|
};
|
||||||
|
|
||||||
|
PlaybackManager.prototype.toggleQueueShuffleMode = function (player = this._currentPlayer) {
|
||||||
|
let currentvalue;
|
||||||
|
if (player && !enableLocalPlaylistManagement(player)) {
|
||||||
|
currentvalue = player.getQueueShuffleMode();
|
||||||
|
switch (currentvalue) {
|
||||||
|
case 'Shuffle':
|
||||||
|
player.setQueueShuffleMode('Sorted');
|
||||||
|
break;
|
||||||
|
case 'Sorted':
|
||||||
|
player.setQueueShuffleMode('Shuffle');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new TypeError('current value for shufflequeue is invalid');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._playQueueManager.toggleShuffleMode();
|
||||||
|
}
|
||||||
|
events.trigger(player, 'shufflequeuemodechange');
|
||||||
|
};
|
||||||
|
|
||||||
|
PlaybackManager.prototype.clearQueue = function (clearCurrentItem = false, player = this._currentPlayer) {
|
||||||
|
if (player && !enableLocalPlaylistManagement(player)) {
|
||||||
|
return player.clearQueue(clearCurrentItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._playQueueManager.clearPlaylist(clearCurrentItem);
|
||||||
|
events.trigger(player, 'playlistitemremove');
|
||||||
|
};
|
||||||
|
|
||||||
PlaybackManager.prototype.trySetActiveDeviceName = function (name) {
|
PlaybackManager.prototype.trySetActiveDeviceName = function (name) {
|
||||||
|
|
||||||
name = normalizeName(name);
|
name = normalizeName(name);
|
||||||
|
@ -4000,6 +4042,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
|
||||||
case 'SetRepeatMode':
|
case 'SetRepeatMode':
|
||||||
this.setRepeatMode(cmd.Arguments.RepeatMode, player);
|
this.setRepeatMode(cmd.Arguments.RepeatMode, player);
|
||||||
break;
|
break;
|
||||||
|
case 'SetShuffleQueue':
|
||||||
|
this.setQueueShuffleMode(cmd.Arguments.ShuffleMode, player);
|
||||||
|
break;
|
||||||
case 'VolumeUp':
|
case 'VolumeUp':
|
||||||
this.volumeUp(player);
|
this.volumeUp(player);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -24,8 +24,10 @@ define([], function () {
|
||||||
|
|
||||||
function PlayQueueManager() {
|
function PlayQueueManager() {
|
||||||
|
|
||||||
|
this._sortedPlaylist = [];
|
||||||
this._playlist = [];
|
this._playlist = [];
|
||||||
this._repeatMode = 'RepeatNone';
|
this._repeatMode = 'RepeatNone';
|
||||||
|
this._shuffleMode = 'Sorted';
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayQueueManager.prototype.getPlaylist = function () {
|
PlayQueueManager.prototype.getPlaylist = function () {
|
||||||
|
@ -56,6 +58,40 @@ define([], function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PlayQueueManager.prototype.shufflePlaylist = function () {
|
||||||
|
this._sortedPlaylist = [];
|
||||||
|
for (const item of this._playlist) {
|
||||||
|
this._sortedPlaylist.push(item);
|
||||||
|
}
|
||||||
|
const currentPlaylistItem = this._playlist.splice(this.getCurrentPlaylistIndex(), 1)[0];
|
||||||
|
|
||||||
|
for (let i = this._playlist.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * i);
|
||||||
|
const temp = this._playlist[i];
|
||||||
|
this._playlist[i] = this._playlist[j];
|
||||||
|
this._playlist[j] = temp;
|
||||||
|
}
|
||||||
|
this._playlist.unshift(currentPlaylistItem);
|
||||||
|
this._shuffleMode = 'Shuffle';
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayQueueManager.prototype.sortShuffledPlaylist = function () {
|
||||||
|
this._playlist = [];
|
||||||
|
for (let item of this._sortedPlaylist) {
|
||||||
|
this._playlist.push(item);
|
||||||
|
}
|
||||||
|
this._sortedPlaylist = [];
|
||||||
|
this._shuffleMode = 'Sorted';
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayQueueManager.prototype.clearPlaylist = function (clearCurrentItem = false) {
|
||||||
|
const currentPlaylistItem = this._playlist.splice(this.getCurrentPlaylistIndex(), 1)[0];
|
||||||
|
this._playlist = [];
|
||||||
|
if (!clearCurrentItem) {
|
||||||
|
this._playlist.push(currentPlaylistItem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function arrayInsertAt(destArray, pos, arrayToInsert) {
|
function arrayInsertAt(destArray, pos, arrayToInsert) {
|
||||||
var args = [];
|
var args = [];
|
||||||
args.push(pos); // where to insert
|
args.push(pos); // where to insert
|
||||||
|
@ -116,9 +152,7 @@ define([], function () {
|
||||||
|
|
||||||
PlayQueueManager.prototype.removeFromPlaylist = function (playlistItemIds) {
|
PlayQueueManager.prototype.removeFromPlaylist = function (playlistItemIds) {
|
||||||
|
|
||||||
var playlist = this.getPlaylist();
|
if (this._playlist.length <= playlistItemIds.length) {
|
||||||
|
|
||||||
if (playlist.length <= playlistItemIds.length) {
|
|
||||||
return {
|
return {
|
||||||
result: 'empty'
|
result: 'empty'
|
||||||
};
|
};
|
||||||
|
@ -127,8 +161,12 @@ define([], function () {
|
||||||
var currentPlaylistItemId = this.getCurrentPlaylistItemId();
|
var currentPlaylistItemId = this.getCurrentPlaylistItemId();
|
||||||
var isCurrentIndex = playlistItemIds.indexOf(currentPlaylistItemId) !== -1;
|
var isCurrentIndex = playlistItemIds.indexOf(currentPlaylistItemId) !== -1;
|
||||||
|
|
||||||
this._playlist = playlist.filter(function (item) {
|
this._sortedPlaylist = this._sortedPlaylist.filter(function (item) {
|
||||||
return playlistItemIds.indexOf(item.PlaylistItemId) === -1;
|
return !playlistItemIds.includes(item.PlaylistItemId);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._playlist = this._playlist.filter(function (item) {
|
||||||
|
return !playlistItemIds.includes(item.PlaylistItemId);
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -176,21 +214,56 @@ define([], function () {
|
||||||
|
|
||||||
PlayQueueManager.prototype.reset = function () {
|
PlayQueueManager.prototype.reset = function () {
|
||||||
|
|
||||||
|
this._sortedPlaylist = [];
|
||||||
this._playlist = [];
|
this._playlist = [];
|
||||||
this._currentPlaylistItemId = null;
|
this._currentPlaylistItemId = null;
|
||||||
this._repeatMode = 'RepeatNone';
|
this._repeatMode = 'RepeatNone';
|
||||||
|
this._shuffleMode = 'Sorted';
|
||||||
};
|
};
|
||||||
|
|
||||||
PlayQueueManager.prototype.setRepeatMode = function (value) {
|
PlayQueueManager.prototype.setRepeatMode = function (value) {
|
||||||
|
const repeatModes = ['RepeatOne', 'RepeatAll', 'RepeatNone'];
|
||||||
this._repeatMode = value;
|
if (repeatModes.includes(value)) {
|
||||||
|
this._repeatMode = value;
|
||||||
|
} else {
|
||||||
|
throw new TypeError('invalid value provided for setRepeatMode');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PlayQueueManager.prototype.getRepeatMode = function () {
|
PlayQueueManager.prototype.getRepeatMode = function () {
|
||||||
|
|
||||||
return this._repeatMode;
|
return this._repeatMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PlayQueueManager.prototype.setShuffleMode = function (value) {
|
||||||
|
switch (value) {
|
||||||
|
case 'Shuffle':
|
||||||
|
this.shufflePlaylist();
|
||||||
|
break;
|
||||||
|
case 'Sorted':
|
||||||
|
this.sortShuffledPlaylist();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new TypeError('invalid value provided to setShuffleMode');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayQueueManager.prototype.toggleShuffleMode = function () {
|
||||||
|
switch (this._shuffleMode) {
|
||||||
|
case 'Shuffle':
|
||||||
|
this.setShuffleMode('Sorted');
|
||||||
|
break;
|
||||||
|
case 'Sorted':
|
||||||
|
this.setShuffleMode('Shuffle');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new TypeError('current value for shufflequeue is invalid');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PlayQueueManager.prototype.getShuffleMode = function () {
|
||||||
|
return this._shuffleMode;
|
||||||
|
};
|
||||||
|
|
||||||
PlayQueueManager.prototype.getNextItemInfo = function () {
|
PlayQueueManager.prototype.getNextItemInfo = function () {
|
||||||
|
|
||||||
var newIndex;
|
var newIndex;
|
||||||
|
|
|
@ -415,7 +415,8 @@ import 'css!./playerstats';
|
||||||
name: 'Original Media Info'
|
name: 'Original Media Info'
|
||||||
});
|
});
|
||||||
|
|
||||||
if (syncPlayManager.isSyncPlayEnabled()) {
|
var apiClient = connectionManager.getApiClient(playbackManager.currentItem(player).ServerId);
|
||||||
|
if (syncPlayManager.isSyncPlayEnabled() && apiClient.isMinServerVersion('10.6.0')) {
|
||||||
categories.push({
|
categories.push({
|
||||||
stats: getSyncPlayStats(),
|
stats: getSyncPlayStats(),
|
||||||
name: 'SyncPlay Info'
|
name: 'SyncPlay Info'
|
||||||
|
|
|
@ -157,43 +157,110 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingSecondaryButtons {
|
.nowPlayingSecondaryButtons {
|
||||||
display: -webkit-box;
|
|
||||||
display: -webkit-flex;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
-webkit-box-align: center;
|
|
||||||
-webkit-align-items: center;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
-webkit-flex-wrap: wrap;
|
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
-webkit-box-pack: end;
|
|
||||||
-webkit-justify-content: flex-end;
|
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-mobile .playlistSectionButtonTransparent {
|
||||||
|
background: rgba(0, 0, 0, 0) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .playlistSection .playlist,
|
||||||
|
.layout-mobile .playlistSection .contextMenu {
|
||||||
|
position: absolute;
|
||||||
|
top: 12.2em;
|
||||||
|
bottom: 4.2em;
|
||||||
|
overflow: scroll;
|
||||||
|
padding: 0 1em;
|
||||||
|
display: inline-block;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .playlistSectionButton {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 4.2em;
|
||||||
|
right: 0;
|
||||||
|
padding-left: 7.3%;
|
||||||
|
padding-right: 7.3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .playlistSectionButton,
|
||||||
|
.layout-tv .playlistSectionButton {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .nowPlayingPlaylist,
|
||||||
|
.layout-tv .nowPlayingPlaylist {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .playlistSectionButton .btnTogglePlaylist {
|
||||||
|
font-size: larger;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .playlistSectionButton .btnSavePlaylist {
|
||||||
|
margin: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .playlistSectionButton .volumecontrol {
|
||||||
|
margin: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .playlistSectionButton .btnToggleContextMenu {
|
||||||
|
font-size: larger;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .nowPlayingSecondaryButtons .btnShuffleQueue {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .nowPlayingSecondaryButtons .volumecontrol {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .nowPlayingSecondaryButtons .btnRepeat {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .nowPlayingInfoButtons .btnRepeat,
|
||||||
|
.layout-tv .nowPlayingInfoButtons .btnRepeat {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .nowPlayingInfoButtons .btnShuffleQueue,
|
||||||
|
.layout-tv .nowPlayingInfoButtons .btnShuffleQueue {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .playlistSectionButton .volumecontrol,
|
||||||
|
.layout-tv .playlistSectionButton .volumecontrol {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .nowPlayingPageUserDataButtons {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media all and (min-width: 63em) {
|
@media all and (min-width: 63em) {
|
||||||
.nowPlayingPage {
|
.nowPlayingPage {
|
||||||
padding: 8em 0 0 0 !important;
|
padding: 8em 0 0 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingSecondaryButtons {
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-webkit-flex-grow: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-webkit-justify-content: flex-end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPageUserDataButtonsTitle {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton,
|
|
||||||
.nowPlayingPlaylist,
|
|
||||||
.nowPlayingContextMenu {
|
|
||||||
background: unset !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-width: 80em) {
|
@media all and (min-width: 80em) {
|
||||||
|
@ -202,7 +269,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (orientation: portrait) and (max-width: 47em) {
|
@media all and (orientation: portrait) and (max-width: 43em) {
|
||||||
.remoteControlContent {
|
.remoteControlContent {
|
||||||
padding-left: 7.3% !important;
|
padding-left: 7.3% !important;
|
||||||
padding-right: 7.3% !important;
|
padding-right: 7.3% !important;
|
||||||
|
@ -211,6 +278,10 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-desktop .nowPlayingPageUserDataButtons {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.nowPlayingInfoContainer {
|
.nowPlayingInfoContainer {
|
||||||
-webkit-box-orient: vertical !important;
|
-webkit-box-orient: vertical !important;
|
||||||
-webkit-box-direction: normal !important;
|
-webkit-box-direction: normal !important;
|
||||||
|
@ -280,6 +351,7 @@
|
||||||
.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle {
|
.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
font-size: large;
|
font-size: large;
|
||||||
|
display: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle button {
|
.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle button {
|
||||||
|
@ -290,7 +362,7 @@
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingInfoButtons .btnRewind {
|
.nowPlayingInfoButtons .btnRepeat {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
@ -298,7 +370,7 @@
|
||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nowPlayingInfoButtons .btnFastForward {
|
.nowPlayingInfoButtons .btnShuffleQueue {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
@ -342,250 +414,6 @@
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nowPlayingPage .playlistSection .playlist,
|
|
||||||
#nowPlayingPage .playlistSection .contextMenu {
|
|
||||||
position: absolute;
|
|
||||||
top: 12.2em;
|
|
||||||
bottom: 4.2em;
|
|
||||||
overflow: scroll;
|
|
||||||
padding: 0 1em;
|
|
||||||
display: inline-block;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 4.2em;
|
|
||||||
right: 0;
|
|
||||||
padding-left: 7.3%;
|
|
||||||
padding-right: 7.3%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton .btnTogglePlaylist {
|
|
||||||
font-size: larger;
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton .btnSavePlaylist {
|
|
||||||
margin: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-webkit-flex-grow: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-webkit-justify-content: flex-end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton .btnToggleContextMenu {
|
|
||||||
font-size: larger;
|
|
||||||
margin: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-webkit-flex-grow: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-webkit-justify-content: flex-end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton .volumecontrol {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remoteControlSection {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 0 4.2em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingButtonsContainer {
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all and (orientation: landscape) and (max-width: 63em) {
|
|
||||||
.remoteControlContent {
|
|
||||||
padding-left: 4.3% !important;
|
|
||||||
padding-right: 4.3% !important;
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingInfoContainer {
|
|
||||||
-webkit-box-orient: horizontal !important;
|
|
||||||
-webkit-box-direction: normal !important;
|
|
||||||
-webkit-flex-direction: row !important;
|
|
||||||
flex-direction: row !important;
|
|
||||||
-webkit-box-align: center;
|
|
||||||
-webkit-align-items: center;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100% - 4.2em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPageTitle {
|
|
||||||
/* text-align: center; */
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingInfoContainerMedia {
|
|
||||||
text-align: left !important;
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPositionSliderContainer {
|
|
||||||
margin: 0.2em 1em 0.2em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingInfoButtons {
|
|
||||||
/* margin: 1.5em 0 0 0; */
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
-webkit-justify-content: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: x-large;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPageImageContainer {
|
|
||||||
width: 30%;
|
|
||||||
margin: auto 1em auto auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPageImageContainerNoAlbum .cardImageContainer .cardImageIcon {
|
|
||||||
font-size: 12em;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingInfoControls {
|
|
||||||
margin: 0.5em 0 1em 0;
|
|
||||||
width: 100%;
|
|
||||||
-webkit-box-pack: start !important;
|
|
||||||
-webkit-justify-content: start !important;
|
|
||||||
justify-content: start !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingSecondaryButtons {
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-webkit-flex-grow: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
-webkit-justify-content: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle {
|
|
||||||
width: 20%;
|
|
||||||
font-size: large;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle button {
|
|
||||||
padding-top: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
float: right;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.paper-icon-button-light:hover {
|
|
||||||
color: #fff !important;
|
|
||||||
background-color: transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btnPlayPause {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1.7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btnPlayPause:hover {
|
|
||||||
background-color: transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPageImage {
|
|
||||||
/* width: inherit; */
|
|
||||||
overflow-y: hidden;
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPageImage.nowPlayingPageImageAudio {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPageImageContainer.nowPlayingPageImagePoster {
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nowPlayingPageImageContainer.nowPlayingPageImagePoster img {
|
|
||||||
height: 100%;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nowPlayingPage .playlistSection .playlist,
|
|
||||||
#nowPlayingPage .playlistSection .contextMenu {
|
|
||||||
position: absolute;
|
|
||||||
top: 7.2em;
|
|
||||||
bottom: 4.2em;
|
|
||||||
overflow: scroll;
|
|
||||||
padding: 0 1em;
|
|
||||||
display: inline-block;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 4.2em;
|
|
||||||
right: 0;
|
|
||||||
padding-left: 4.3%;
|
|
||||||
padding-right: 4.3%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton .btnTogglePlaylist {
|
|
||||||
font-size: larger;
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton .btnSavePlaylist {
|
|
||||||
margin: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-webkit-flex-grow: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-webkit-justify-content: flex-end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton .btnToggleContextMenu {
|
|
||||||
font-size: larger;
|
|
||||||
margin: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
-webkit-box-flex: 1;
|
|
||||||
-webkit-flex-grow: 1;
|
|
||||||
flex-grow: 1;
|
|
||||||
-webkit-box-pack: end;
|
|
||||||
-webkit-justify-content: flex-end;
|
|
||||||
justify-content: flex-end;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playlistSectionButton .volumecontrol {
|
.playlistSectionButton .volumecontrol {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -627,6 +455,10 @@
|
||||||
background-image: url(../../assets/img/equalizer.gif) !important;
|
background-image: url(../../assets/img/equalizer.gif) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.playlistIndexIndicatorImage > * {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.hideVideoButtons .videoButton {
|
.hideVideoButtons .videoButton {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -636,7 +468,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (max-width: 63em) {
|
@media all and (max-width: 63em) {
|
||||||
.nowPlayingSecondaryButtons .nowPlayingPageUserDataButtons,
|
|
||||||
.nowPlayingSecondaryButtons .repeatToggleButton,
|
.nowPlayingSecondaryButtons .repeatToggleButton,
|
||||||
.nowPlayingInfoButtons .playlist .listItemMediaInfo,
|
.nowPlayingInfoButtons .playlist .listItemMediaInfo,
|
||||||
.nowPlayingInfoButtons .btnStop {
|
.nowPlayingInfoButtons .btnStop {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageLoader', 'playbackManager', 'nowPlayingHelper', 'events', 'connectionManager', 'apphost', 'globalize', 'layoutManager', 'userSettings', 'cardBuilder', 'cardStyle', 'emby-itemscontainer', 'css!./remotecontrol.css', 'emby-ratingbutton'], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder) {
|
define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageLoader', 'playbackManager', 'nowPlayingHelper', 'events', 'connectionManager', 'apphost', 'globalize', 'layoutManager', 'userSettings', 'cardBuilder', 'itemContextMenu', 'cardStyle', 'emby-itemscontainer', 'css!./remotecontrol.css', 'emby-ratingbutton'], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder, itemContextMenu) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
var showMuteButton = true;
|
||||||
|
var showVolumeSlider = true;
|
||||||
|
|
||||||
function showAudioMenu(context, player, button, item) {
|
function showAudioMenu(context, player, button, item) {
|
||||||
var currentIndex = playbackManager.getAudioStreamIndex(player);
|
var currentIndex = playbackManager.getAudioStreamIndex(player);
|
||||||
|
@ -118,30 +120,41 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
if (item.Type == 'Audio' || item.MediaStreams[0].Type == 'Audio') {
|
if (item.Type == 'Audio' || item.MediaStreams[0].Type == 'Audio') {
|
||||||
var songName = item.Name;
|
var songName = item.Name;
|
||||||
if (item.Album != null && item.Artists != null) {
|
if (item.Album != null && item.Artists != null) {
|
||||||
|
var artistsSeries = '';
|
||||||
var albumName = item.Album;
|
var albumName = item.Album;
|
||||||
var artistName;
|
|
||||||
if (item.ArtistItems != null) {
|
if (item.ArtistItems != null) {
|
||||||
artistName = item.ArtistItems[0].Name;
|
for (const artist of item.ArtistItems) {
|
||||||
context.querySelector('.nowPlayingAlbum').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="itemdetails.html?id=' + item.AlbumId + `&serverId=${nowPlayingServerId}">${albumName}</a>`;
|
let artistName = artist.Name;
|
||||||
context.querySelector('.nowPlayingArtist').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="itemdetails.html?id=' + item.ArtistItems[0].Id + `&serverId=${nowPlayingServerId}">${artistName}</a>`;
|
let artistId = artist.Id;
|
||||||
context.querySelector('.contextMenuAlbum').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="itemdetails.html?id=' + item.AlbumId + `&serverId=${nowPlayingServerId}"><span class="actionsheetMenuItemIcon listItemIcon listItemIcon-transparent material-icons album"></span> ` + globalize.translate('ViewAlbum') + '</a>';
|
artistsSeries += `<a class="button-link emby-button" is="emby-linkbutton" href="details?id=${artistId}&serverId=${nowPlayingServerId}">${artistName}</a>`;
|
||||||
context.querySelector('.contextMenuArtist').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="itemdetails.html?id=' + item.ArtistItems[0].Id + `&serverId=${nowPlayingServerId}"><span class="actionsheetMenuItemIcon listItemIcon listItemIcon-transparent material-icons person"></span> ` + globalize.translate('ViewArtist') + '</a>';
|
if (artist !== item.ArtistItems.slice(-1)[0]) {
|
||||||
} else {
|
artistsSeries += ', ';
|
||||||
artistName = item.Artists;
|
}
|
||||||
context.querySelector('.nowPlayingAlbum').innerHTML = albumName;
|
}
|
||||||
context.querySelector('.nowPlayingArtist').innerHTML = artistName;
|
} else if (item.Artists) {
|
||||||
|
// For some reason, Chromecast Player doesn't return a item.ArtistItems object, so we need to fallback
|
||||||
|
// to normal item.Artists item.
|
||||||
|
// TODO: Normalise fields returned by all the players
|
||||||
|
for (const artist of item.Artists) {
|
||||||
|
artistsSeries += `<a>${artist}</a>`;
|
||||||
|
if (artist !== item.Artists.slice(-1)[0]) {
|
||||||
|
artistsSeries += ', ';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries;
|
||||||
|
context.querySelector('.nowPlayingAlbum').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="details?id=' + item.AlbumId + `&serverId=${nowPlayingServerId}">${albumName}</a>`;
|
||||||
}
|
}
|
||||||
context.querySelector('.nowPlayingSongName').innerHTML = songName;
|
context.querySelector('.nowPlayingSongName').innerHTML = songName;
|
||||||
} else if (item.Type == 'Episode') {
|
} else if (item.Type == 'Episode') {
|
||||||
if (item.SeasonName != null) {
|
if (item.SeasonName != null) {
|
||||||
var seasonName = item.SeasonName;
|
var seasonName = item.SeasonName;
|
||||||
context.querySelector('.nowPlayingSeason').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="itemdetails.html?id=' + item.SeasonId + `&serverId=${nowPlayingServerId}">${seasonName}</a>`;
|
context.querySelector('.nowPlayingSeason').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="details?id=' + item.SeasonId + `&serverId=${nowPlayingServerId}">${seasonName}</a>`;
|
||||||
}
|
}
|
||||||
if (item.SeriesName != null) {
|
if (item.SeriesName != null) {
|
||||||
var seriesName = item.SeriesName;
|
var seriesName = item.SeriesName;
|
||||||
if (item.SeriesId != null) {
|
if (item.SeriesId != null) {
|
||||||
context.querySelector('.nowPlayingSerie').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="itemdetails.html?id=' + item.SeriesId + `&serverId=${nowPlayingServerId}">${seriesName}</a>`;
|
context.querySelector('.nowPlayingSerie').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="details?id=' + item.SeriesId + `&serverId=${nowPlayingServerId}">${seriesName}</a>`;
|
||||||
} else {
|
} else {
|
||||||
context.querySelector('.nowPlayingSerie').innerHTML = seriesName;
|
context.querySelector('.nowPlayingSerie').innerHTML = seriesName;
|
||||||
}
|
}
|
||||||
|
@ -163,11 +176,38 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
maxHeight: 300 * 2
|
maxHeight: 300 * 2
|
||||||
}) : null;
|
}) : null;
|
||||||
|
|
||||||
console.debug('updateNowPlayingInfo');
|
let contextButton = context.querySelector('.btnToggleContextMenu');
|
||||||
|
// We remove the previous event listener by replacing the item in each update event
|
||||||
|
const autoFocusContextButton = document.activeElement === contextButton;
|
||||||
|
let contextButtonClone = contextButton.cloneNode(true);
|
||||||
|
contextButton.parentNode.replaceChild(contextButtonClone, contextButton);
|
||||||
|
contextButton = context.querySelector('.btnToggleContextMenu');
|
||||||
|
if (autoFocusContextButton) {
|
||||||
|
contextButton.focus();
|
||||||
|
}
|
||||||
|
const stopPlayback = !!layoutManager.mobile;
|
||||||
|
var options = {
|
||||||
|
play: false,
|
||||||
|
queue: false,
|
||||||
|
stopPlayback: stopPlayback,
|
||||||
|
clearQueue: true,
|
||||||
|
openAlbum: false,
|
||||||
|
positionTo: contextButton
|
||||||
|
};
|
||||||
|
var apiClient = connectionManager.getApiClient(item.ServerId);
|
||||||
|
apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) {
|
||||||
|
apiClient.getCurrentUser().then(function (user) {
|
||||||
|
contextButton.addEventListener('click', function () {
|
||||||
|
itemContextMenu.show(Object.assign({
|
||||||
|
item: fullItem,
|
||||||
|
user: user
|
||||||
|
}, options));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
setImageUrl(context, state, url);
|
setImageUrl(context, state, url);
|
||||||
if (item) {
|
if (item) {
|
||||||
backdrop.setBackdrops([item]);
|
backdrop.setBackdrops([item]);
|
||||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
|
||||||
apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) {
|
apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) {
|
||||||
var userData = fullItem.UserData || {};
|
var userData = fullItem.UserData || {};
|
||||||
var likes = null == userData.Likes ? '' : userData.Likes;
|
var likes = null == userData.Likes ? '' : userData.Likes;
|
||||||
|
@ -219,20 +259,16 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
|
|
||||||
var currentImgUrl;
|
var currentImgUrl;
|
||||||
return function () {
|
return function () {
|
||||||
function toggleRepeat(player) {
|
function toggleRepeat() {
|
||||||
if (player) {
|
switch (playbackManager.getRepeatMode()) {
|
||||||
switch (playbackManager.getRepeatMode(player)) {
|
case 'RepeatAll':
|
||||||
case 'RepeatNone':
|
playbackManager.setRepeatMode('RepeatOne');
|
||||||
playbackManager.setRepeatMode('RepeatAll', player);
|
break;
|
||||||
break;
|
case 'RepeatOne':
|
||||||
|
playbackManager.setRepeatMode('RepeatNone');
|
||||||
case 'RepeatAll':
|
break;
|
||||||
playbackManager.setRepeatMode('RepeatOne', player);
|
case 'RepeatNone':
|
||||||
break;
|
playbackManager.setRepeatMode('RepeatAll');
|
||||||
|
|
||||||
case 'RepeatOne':
|
|
||||||
playbackManager.setRepeatMode('RepeatNone', player);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,8 +311,13 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
buttonVisible(context.querySelector('.btnStop'), null != item);
|
buttonVisible(context.querySelector('.btnStop'), null != item);
|
||||||
buttonVisible(context.querySelector('.btnNextTrack'), null != item);
|
buttonVisible(context.querySelector('.btnNextTrack'), null != item);
|
||||||
buttonVisible(context.querySelector('.btnPreviousTrack'), null != item);
|
buttonVisible(context.querySelector('.btnPreviousTrack'), null != item);
|
||||||
buttonVisible(context.querySelector('.btnRewind'), null != item);
|
if (layoutManager.mobile) {
|
||||||
buttonVisible(context.querySelector('.btnFastForward'), null != item);
|
buttonVisible(context.querySelector('.btnRewind'), false);
|
||||||
|
buttonVisible(context.querySelector('.btnFastForward'), false);
|
||||||
|
} else {
|
||||||
|
buttonVisible(context.querySelector('.btnRewind'), null != item);
|
||||||
|
buttonVisible(context.querySelector('.btnFastForward'), null != item);
|
||||||
|
}
|
||||||
var positionSlider = context.querySelector('.nowPlayingPositionSlider');
|
var positionSlider = context.querySelector('.nowPlayingPositionSlider');
|
||||||
|
|
||||||
if (positionSlider && item && item.RunTimeTicks) {
|
if (positionSlider && item && item.RunTimeTicks) {
|
||||||
|
@ -300,7 +341,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
context.classList.add('hideVideoButtons');
|
context.classList.add('hideVideoButtons');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRepeatModeDisplay(playState.RepeatMode);
|
updateRepeatModeDisplay(playbackManager.getRepeatMode());
|
||||||
|
onShuffleQueueModeChange(false);
|
||||||
updateNowPlayingInfo(context, state);
|
updateNowPlayingInfo(context, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,25 +358,32 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
|
|
||||||
function updateRepeatModeDisplay(repeatMode) {
|
function updateRepeatModeDisplay(repeatMode) {
|
||||||
var context = dlg;
|
var context = dlg;
|
||||||
var toggleRepeatButton = context.querySelector('.repeatToggleButton');
|
let toggleRepeatButtons = context.querySelectorAll('.repeatToggleButton');
|
||||||
|
const cssClass = 'buttonActive';
|
||||||
|
let innHtml = '<span class="material-icons repeat"></span>';
|
||||||
|
let repeatOn = true;
|
||||||
|
|
||||||
if ('RepeatAll' == repeatMode) {
|
switch (repeatMode) {
|
||||||
toggleRepeatButton.innerHTML = "<span class='material-icons repeat'></span>";
|
case 'RepeatAll':
|
||||||
toggleRepeatButton.classList.add('repeatButton-active');
|
break;
|
||||||
} else if ('RepeatOne' == repeatMode) {
|
case 'RepeatOne':
|
||||||
toggleRepeatButton.innerHTML = "<span class='material-icons repeat_one'></span>";
|
innHtml = '<span class="material-icons repeat_one"></span>';
|
||||||
toggleRepeatButton.classList.add('repeatButton-active');
|
break;
|
||||||
} else {
|
case 'RepeatNone':
|
||||||
toggleRepeatButton.innerHTML = "<span class='material-icons repeat'></span>";
|
default:
|
||||||
toggleRepeatButton.classList.remove('repeatButton-active');
|
repeatOn = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const toggleRepeatButton of toggleRepeatButtons) {
|
||||||
|
toggleRepeatButton.classList.toggle(cssClass, repeatOn);
|
||||||
|
toggleRepeatButton.innerHTML = innHtml;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePlayerVolumeState(context, isMuted, volumeLevel) {
|
function updatePlayerVolumeState(context, isMuted, volumeLevel) {
|
||||||
var view = context;
|
var view = context;
|
||||||
var supportedCommands = currentPlayerSupportedCommands;
|
var supportedCommands = currentPlayerSupportedCommands;
|
||||||
var showMuteButton = true;
|
|
||||||
var showVolumeSlider = true;
|
|
||||||
|
|
||||||
if (-1 === supportedCommands.indexOf('Mute')) {
|
if (-1 === supportedCommands.indexOf('Mute')) {
|
||||||
showMuteButton = false;
|
showMuteButton = false;
|
||||||
|
@ -362,24 +411,21 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
buttonMuteIcon.classList.add('volume_up');
|
buttonMuteIcon.classList.add('volume_up');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showMuteButton) {
|
if (!showMuteButton && !showVolumeSlider) {
|
||||||
buttonMute.classList.remove('hide');
|
context.querySelector('.volumecontrol').classList.add('hide');
|
||||||
} else {
|
} else {
|
||||||
buttonMute.classList.add('hide');
|
buttonMute.classList.toggle('hide', !showMuteButton);
|
||||||
}
|
|
||||||
|
|
||||||
var nowPlayingVolumeSlider = context.querySelector('.nowPlayingVolumeSlider');
|
var nowPlayingVolumeSlider = context.querySelector('.nowPlayingVolumeSlider');
|
||||||
var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer');
|
var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer');
|
||||||
|
|
||||||
if (nowPlayingVolumeSlider) {
|
if (nowPlayingVolumeSlider) {
|
||||||
if (showVolumeSlider) {
|
|
||||||
nowPlayingVolumeSliderContainer.classList.remove('hide');
|
|
||||||
} else {
|
|
||||||
nowPlayingVolumeSliderContainer.classList.add('hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nowPlayingVolumeSlider.dragging) {
|
nowPlayingVolumeSliderContainer.classList.toggle('hide', !showVolumeSlider);
|
||||||
nowPlayingVolumeSlider.value = volumeLevel || 0;
|
|
||||||
|
if (!nowPlayingVolumeSlider.dragging) {
|
||||||
|
nowPlayingVolumeSlider.value = volumeLevel || 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,11 +466,21 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
function loadPlaylist(context, player) {
|
function loadPlaylist(context, player) {
|
||||||
getPlaylistItems(player).then(function (items) {
|
getPlaylistItems(player).then(function (items) {
|
||||||
var html = '';
|
var html = '';
|
||||||
|
let favoritesEnabled = true;
|
||||||
|
if (layoutManager.mobile) {
|
||||||
|
if (items.length > 0) {
|
||||||
|
context.querySelector('.btnTogglePlaylist').classList.remove('hide');
|
||||||
|
} else {
|
||||||
|
context.querySelector('.btnTogglePlaylist').classList.add('hide');
|
||||||
|
}
|
||||||
|
favoritesEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
html += listView.getListViewHtml({
|
html += listView.getListViewHtml({
|
||||||
items: items,
|
items: items,
|
||||||
smallIcon: true,
|
smallIcon: true,
|
||||||
action: 'setplaylistindex',
|
action: 'setplaylistindex',
|
||||||
enableUserDataButtons: false,
|
enableUserDataButtons: favoritesEnabled,
|
||||||
rightButtons: [{
|
rightButtons: [{
|
||||||
icon: 'remove_circle_outline',
|
icon: 'remove_circle_outline',
|
||||||
title: globalize.translate('ButtonRemove'),
|
title: globalize.translate('ButtonRemove'),
|
||||||
|
@ -433,18 +489,21 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
dragHandle: true
|
dragHandle: true
|
||||||
});
|
});
|
||||||
|
|
||||||
if (items.length) {
|
var itemsContainer = context.querySelector('.playlist');
|
||||||
context.querySelector('.btnTogglePlaylist').classList.remove('hide');
|
let focusedItemPlaylistId = itemsContainer.querySelector('button:focus');
|
||||||
} else {
|
itemsContainer.innerHTML = html;
|
||||||
context.querySelector('.btnTogglePlaylist').classList.add('hide');
|
if (focusedItemPlaylistId !== null) {
|
||||||
|
focusedItemPlaylistId = focusedItemPlaylistId.getAttribute('data-playlistitemid');
|
||||||
|
const newFocusedItem = itemsContainer.querySelector(`button[data-playlistitemid="${focusedItemPlaylistId}"]`);
|
||||||
|
if (newFocusedItem !== null) {
|
||||||
|
newFocusedItem.focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var itemsContainer = context.querySelector('.playlist');
|
|
||||||
itemsContainer.innerHTML = html;
|
|
||||||
var playlistItemId = playbackManager.getCurrentPlaylistItemId(player);
|
var playlistItemId = playbackManager.getCurrentPlaylistItemId(player);
|
||||||
|
|
||||||
if (playlistItemId) {
|
if (playlistItemId) {
|
||||||
var img = itemsContainer.querySelector('.listItem[data-playlistItemId="' + playlistItemId + '"] .listItemImage');
|
var img = itemsContainer.querySelector(`.listItem[data-playlistItemId="${playlistItemId}"] .listItemImage`);
|
||||||
|
|
||||||
if (img) {
|
if (img) {
|
||||||
img.classList.remove('lazy');
|
img.classList.remove('lazy');
|
||||||
|
@ -453,9 +512,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
}
|
}
|
||||||
|
|
||||||
imageLoader.lazyChildren(itemsContainer);
|
imageLoader.lazyChildren(itemsContainer);
|
||||||
context.querySelector('.playlist').classList.add('hide');
|
|
||||||
context.querySelector('.contextMenu').classList.add('hide');
|
|
||||||
context.querySelector('.btnSavePlaylist').classList.add('hide');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,9 +521,31 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
onStateChanged.call(player, e, state);
|
onStateChanged.call(player, e, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRepeatModeChange(e) {
|
function onRepeatModeChange() {
|
||||||
var player = this;
|
updateRepeatModeDisplay(playbackManager.getRepeatMode());
|
||||||
updateRepeatModeDisplay(playbackManager.getRepeatMode(player));
|
}
|
||||||
|
|
||||||
|
function onShuffleQueueModeChange(updateView = true) {
|
||||||
|
let shuffleMode = playbackManager.getQueueShuffleMode(this);
|
||||||
|
let context = dlg;
|
||||||
|
const cssClass = 'buttonActive';
|
||||||
|
let shuffleButtons = context.querySelectorAll('.btnShuffleQueue');
|
||||||
|
|
||||||
|
for (let shuffleButton of shuffleButtons) {
|
||||||
|
switch (shuffleMode) {
|
||||||
|
case 'Shuffle':
|
||||||
|
shuffleButton.classList.add(cssClass);
|
||||||
|
break;
|
||||||
|
case 'Sorted':
|
||||||
|
default:
|
||||||
|
shuffleButton.classList.remove(cssClass);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateView) {
|
||||||
|
onPlaylistUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPlaylistUpdate(e) {
|
function onPlaylistUpdate(e) {
|
||||||
|
@ -476,14 +554,18 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
|
|
||||||
function onPlaylistItemRemoved(e, info) {
|
function onPlaylistItemRemoved(e, info) {
|
||||||
var context = dlg;
|
var context = dlg;
|
||||||
var playlistItemIds = info.playlistItemIds;
|
if (info !== undefined) {
|
||||||
|
var playlistItemIds = info.playlistItemIds;
|
||||||
|
|
||||||
for (var i = 0, length = playlistItemIds.length; i < length; i++) {
|
for (var i = 0, length = playlistItemIds.length; i < length; i++) {
|
||||||
var listItem = context.querySelector('.listItem[data-playlistItemId="' + playlistItemIds[i] + '"]');
|
var listItem = context.querySelector('.listItem[data-playlistItemId="' + playlistItemIds[i] + '"]');
|
||||||
|
|
||||||
if (listItem) {
|
if (listItem) {
|
||||||
listItem.parentNode.removeChild(listItem);
|
listItem.parentNode.removeChild(listItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
onPlaylistUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +575,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
|
|
||||||
if (!state.NextMediaType) {
|
if (!state.NextMediaType) {
|
||||||
updatePlayerState(player, dlg, {});
|
updatePlayerState(player, dlg, {});
|
||||||
loadPlaylist(dlg);
|
|
||||||
Emby.Page.back();
|
Emby.Page.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,7 +586,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
function onStateChanged(event, state) {
|
function onStateChanged(event, state) {
|
||||||
var player = this;
|
var player = this;
|
||||||
updatePlayerState(player, dlg, state);
|
updatePlayerState(player, dlg, state);
|
||||||
loadPlaylist(dlg, player);
|
onPlaylistUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTimeUpdate(e) {
|
function onTimeUpdate(e) {
|
||||||
|
@ -531,8 +612,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
events.off(player, 'playbackstart', onPlaybackStart);
|
events.off(player, 'playbackstart', onPlaybackStart);
|
||||||
events.off(player, 'statechange', onStateChanged);
|
events.off(player, 'statechange', onStateChanged);
|
||||||
events.off(player, 'repeatmodechange', onRepeatModeChange);
|
events.off(player, 'repeatmodechange', onRepeatModeChange);
|
||||||
events.off(player, 'playlistitemremove', onPlaylistUpdate);
|
events.off(player, 'shufflequeuemodechange', onShuffleQueueModeChange);
|
||||||
|
events.off(player, 'playlistitemremove', onPlaylistItemRemoved);
|
||||||
events.off(player, 'playlistitemmove', onPlaylistUpdate);
|
events.off(player, 'playlistitemmove', onPlaylistUpdate);
|
||||||
|
events.off(player, 'playlistitemadd', onPlaylistUpdate);
|
||||||
events.off(player, 'playbackstop', onPlaybackStopped);
|
events.off(player, 'playbackstop', onPlaybackStopped);
|
||||||
events.off(player, 'volumechange', onVolumeChanged);
|
events.off(player, 'volumechange', onVolumeChanged);
|
||||||
events.off(player, 'pause', onPlayPauseStateChanged);
|
events.off(player, 'pause', onPlayPauseStateChanged);
|
||||||
|
@ -551,8 +634,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
events.on(player, 'playbackstart', onPlaybackStart);
|
events.on(player, 'playbackstart', onPlaybackStart);
|
||||||
events.on(player, 'statechange', onStateChanged);
|
events.on(player, 'statechange', onStateChanged);
|
||||||
events.on(player, 'repeatmodechange', onRepeatModeChange);
|
events.on(player, 'repeatmodechange', onRepeatModeChange);
|
||||||
|
events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange);
|
||||||
events.on(player, 'playlistitemremove', onPlaylistItemRemoved);
|
events.on(player, 'playlistitemremove', onPlaylistItemRemoved);
|
||||||
events.on(player, 'playlistitemmove', onPlaylistUpdate);
|
events.on(player, 'playlistitemmove', onPlaylistUpdate);
|
||||||
|
events.on(player, 'playlistitemadd', onPlaylistUpdate);
|
||||||
events.on(player, 'playbackstop', onPlaybackStopped);
|
events.on(player, 'playbackstop', onPlaybackStopped);
|
||||||
events.on(player, 'volumechange', onVolumeChanged);
|
events.on(player, 'volumechange', onVolumeChanged);
|
||||||
events.on(player, 'pause', onPlayPauseStateChanged);
|
events.on(player, 'pause', onPlayPauseStateChanged);
|
||||||
|
@ -568,7 +653,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
function onBtnCommandClick() {
|
function onBtnCommandClick() {
|
||||||
if (currentPlayer) {
|
if (currentPlayer) {
|
||||||
if (this.classList.contains('repeatToggleButton')) {
|
if (this.classList.contains('repeatToggleButton')) {
|
||||||
toggleRepeat(currentPlayer);
|
toggleRepeat();
|
||||||
} else {
|
} else {
|
||||||
playbackManager.sendCommand({
|
playbackManager.sendCommand({
|
||||||
Name: this.getAttribute('data-command')
|
Name: this.getAttribute('data-command')
|
||||||
|
@ -603,6 +688,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
|
|
||||||
function bindEvents(context) {
|
function bindEvents(context) {
|
||||||
var btnCommand = context.querySelectorAll('.btnCommand');
|
var btnCommand = context.querySelectorAll('.btnCommand');
|
||||||
|
var positionSlider = context.querySelector('.nowPlayingPositionSlider');
|
||||||
|
|
||||||
for (var i = 0, length = btnCommand.length; i < length; i++) {
|
for (var i = 0, length = btnCommand.length; i < length; i++) {
|
||||||
btnCommand[i].addEventListener('click', onBtnCommandClick);
|
btnCommand[i].addEventListener('click', onBtnCommandClick);
|
||||||
|
@ -650,12 +736,37 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
playbackManager.fastForward(currentPlayer);
|
playbackManager.fastForward(currentPlayer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
context.querySelector('.btnPreviousTrack').addEventListener('click', function () {
|
for (const shuffleButton of context.querySelectorAll('.btnShuffleQueue')) {
|
||||||
|
shuffleButton.addEventListener('click', function () {
|
||||||
|
if (currentPlayer) {
|
||||||
|
playbackManager.toggleQueueShuffleMode(currentPlayer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
context.querySelector('.btnPreviousTrack').addEventListener('click', function (e) {
|
||||||
|
if (currentPlayer) {
|
||||||
|
if (lastPlayerState.NowPlayingItem.MediaType === 'Audio' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) {
|
||||||
|
// Cancel this event if doubleclick is fired
|
||||||
|
if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
playbackManager.seekPercent(0, currentPlayer);
|
||||||
|
// This is done automatically by playbackManager. However, setting this here gives instant visual feedback.
|
||||||
|
// TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround.
|
||||||
|
positionSlider.value = 0;
|
||||||
|
} else {
|
||||||
|
playbackManager.previousTrack(currentPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
context.querySelector('.btnPreviousTrack').addEventListener('dblclick', function () {
|
||||||
if (currentPlayer) {
|
if (currentPlayer) {
|
||||||
playbackManager.previousTrack(currentPlayer);
|
playbackManager.previousTrack(currentPlayer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
context.querySelector('.nowPlayingPositionSlider').addEventListener('change', function () {
|
positionSlider.addEventListener('change', function () {
|
||||||
var value = this.value;
|
var value = this.value;
|
||||||
|
|
||||||
if (currentPlayer) {
|
if (currentPlayer) {
|
||||||
|
@ -664,7 +775,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
context.querySelector('.nowPlayingPositionSlider').getBubbleText = function (value) {
|
positionSlider.getBubbleText = function (value) {
|
||||||
var state = lastPlayerState;
|
var state = lastPlayerState;
|
||||||
|
|
||||||
if (!state || !state.NowPlayingItem || !currentRuntimeTicks) {
|
if (!state || !state.NowPlayingItem || !currentRuntimeTicks) {
|
||||||
|
@ -677,13 +788,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
return datetime.getDisplayRunningTime(ticks);
|
return datetime.getDisplayRunningTime(ticks);
|
||||||
};
|
};
|
||||||
|
|
||||||
function setVolume() {
|
context.querySelector('.nowPlayingVolumeSlider').addEventListener('input', (e) => {
|
||||||
playbackManager.setVolume(this.value, currentPlayer);
|
playbackManager.setVolume(e.target.value, currentPlayer);
|
||||||
}
|
});
|
||||||
|
|
||||||
context.querySelector('.nowPlayingVolumeSlider').addEventListener('change', setVolume);
|
|
||||||
context.querySelector('.nowPlayingVolumeSlider').addEventListener('mousemove', setVolume);
|
|
||||||
context.querySelector('.nowPlayingVolumeSlider').addEventListener('touchmove', setVolume);
|
|
||||||
context.querySelector('.buttonMute').addEventListener('click', function () {
|
context.querySelector('.buttonMute').addEventListener('click', function () {
|
||||||
playbackManager.toggleMute(currentPlayer);
|
playbackManager.toggleMute(currentPlayer);
|
||||||
});
|
});
|
||||||
|
@ -701,21 +809,19 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
if (context.querySelector('.playlist').classList.contains('hide')) {
|
if (context.querySelector('.playlist').classList.contains('hide')) {
|
||||||
context.querySelector('.playlist').classList.remove('hide');
|
context.querySelector('.playlist').classList.remove('hide');
|
||||||
context.querySelector('.btnSavePlaylist').classList.remove('hide');
|
context.querySelector('.btnSavePlaylist').classList.remove('hide');
|
||||||
context.querySelector('.contextMenu').classList.add('hide');
|
|
||||||
context.querySelector('.volumecontrol').classList.add('hide');
|
context.querySelector('.volumecontrol').classList.add('hide');
|
||||||
|
if (layoutManager.mobile) {
|
||||||
|
context.querySelector('.playlistSectionButton').classList.remove('playlistSectionButtonTransparent');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
context.querySelector('.playlist').classList.add('hide');
|
context.querySelector('.playlist').classList.add('hide');
|
||||||
context.querySelector('.btnSavePlaylist').classList.add('hide');
|
context.querySelector('.btnSavePlaylist').classList.add('hide');
|
||||||
context.querySelector('.volumecontrol').classList.remove('hide');
|
if (showMuteButton || showVolumeSlider) {
|
||||||
}
|
context.querySelector('.volumecontrol').classList.remove('hide');
|
||||||
});
|
}
|
||||||
context.querySelector('.btnToggleContextMenu').addEventListener('click', function () {
|
if (layoutManager.mobile) {
|
||||||
if (context.querySelector('.contextMenu').classList.contains('hide')) {
|
context.querySelector('.playlistSectionButton').classList.add('playlistSectionButtonTransparent');
|
||||||
context.querySelector('.contextMenu').classList.remove('hide');
|
}
|
||||||
context.querySelector('.btnSavePlaylist').classList.add('hide');
|
|
||||||
context.querySelector('.playlist').classList.add('hide');
|
|
||||||
} else {
|
|
||||||
context.querySelector('.contextMenu').classList.add('hide');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -764,16 +870,24 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(ownerView, context) {
|
function init(ownerView, context) {
|
||||||
let contextmenuHtml = `<button id="toggleContextMenu" is="paper-icon-button-light" class="btnToggleContextMenu" title=${globalize.translate('ButtonToggleContextMenu')}><span class="material-icons more_vert"></span></button>`;
|
|
||||||
let volumecontrolHtml = '<div class="volumecontrol flex align-items-center flex-wrap-wrap justify-content-center">';
|
let volumecontrolHtml = '<div class="volumecontrol flex align-items-center flex-wrap-wrap justify-content-center">';
|
||||||
volumecontrolHtml += `<button is="paper-icon-button-light" class="buttonMute autoSize" title=${globalize.translate('Mute')}><span class="xlargePaperIconButton material-icons volume_up"></span></button>`;
|
volumecontrolHtml += `<button is="paper-icon-button-light" class="buttonMute autoSize" title=${globalize.translate('Mute')}><span class="xlargePaperIconButton material-icons volume_up"></span></button>`;
|
||||||
volumecontrolHtml += '<div class="sliderContainer nowPlayingVolumeSliderContainer"><input is="emby-slider" type="range" step="1" min="0" max="100" value="0" class="nowPlayingVolumeSlider"/></div>';
|
volumecontrolHtml += '<div class="sliderContainer nowPlayingVolumeSliderContainer"><input is="emby-slider" type="range" step="1" min="0" max="100" value="0" class="nowPlayingVolumeSlider"/></div>';
|
||||||
volumecontrolHtml += '</div>';
|
volumecontrolHtml += '</div>';
|
||||||
|
let optionsSection = context.querySelector('.playlistSectionButton');
|
||||||
if (!layoutManager.mobile) {
|
if (!layoutManager.mobile) {
|
||||||
context.querySelector('.nowPlayingSecondaryButtons').innerHTML += volumecontrolHtml;
|
context.querySelector('.nowPlayingSecondaryButtons').insertAdjacentHTML('beforeend', volumecontrolHtml);
|
||||||
context.querySelector('.playlistSectionButton').innerHTML += contextmenuHtml;
|
optionsSection.classList.remove('align-items-center', 'justify-content-center');
|
||||||
|
optionsSection.classList.add('align-items-right', 'justify-content-flex-end');
|
||||||
|
context.querySelector('.playlist').classList.remove('hide');
|
||||||
|
context.querySelector('.btnSavePlaylist').classList.remove('hide');
|
||||||
|
context.classList.add('padded-bottom');
|
||||||
} else {
|
} else {
|
||||||
context.querySelector('.playlistSectionButton').innerHTML += volumecontrolHtml + contextmenuHtml;
|
optionsSection.querySelector('.btnTogglePlaylist').insertAdjacentHTML('afterend', volumecontrolHtml);
|
||||||
|
optionsSection.classList.add('playlistSectionButtonTransparent');
|
||||||
|
context.querySelector('.btnTogglePlaylist').classList.remove('hide');
|
||||||
|
context.querySelector('.playlistSectionButton').classList.remove('justify-content-center');
|
||||||
|
context.querySelector('.playlistSectionButton').classList.add('justify-content-space-between');
|
||||||
}
|
}
|
||||||
|
|
||||||
bindEvents(context);
|
bindEvents(context);
|
||||||
|
|
|
@ -474,7 +474,7 @@ import 'emby-button';
|
||||||
showTitle: true,
|
showTitle: true,
|
||||||
overlayText: false,
|
overlayText: false,
|
||||||
centerText: true,
|
centerText: true,
|
||||||
action: 'play'
|
overlayPlayButton: true
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -224,6 +224,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
||||||
});
|
});
|
||||||
|
|
||||||
inputManager.on(window, onInputCommand);
|
inputManager.on(window, onInputCommand);
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
document.addEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
|
document.addEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
|
||||||
|
|
||||||
dialog.addEventListener('close', onDialogClosed);
|
dialog.addEventListener('close', onDialogClosed);
|
||||||
|
@ -489,6 +490,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
|
||||||
}
|
}
|
||||||
|
|
||||||
inputManager.off(window, onInputCommand);
|
inputManager.off(window, onInputCommand);
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
document.removeEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
|
document.removeEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
|
||||||
// Shows page scrollbar
|
// Shows page scrollbar
|
||||||
document.body.classList.remove('hide-scroll');
|
document.body.classList.remove('hide-scroll');
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
|
.subtitleSync {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.subtitleSyncContainer {
|
.subtitleSyncContainer {
|
||||||
width: 40%;
|
width: 40%;
|
||||||
margin-left: 30%;
|
min-width: 18em;
|
||||||
margin-right: 30%;
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
height: 4.2em;
|
height: 4.2em;
|
||||||
background: rgba(28, 28, 28, 0.8);
|
background: rgba(28, 28, 28, 0.8);
|
||||||
border-radius: 0.3em;
|
border-radius: 0.3em;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
position: absolute;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subtitleSync-closeButton {
|
.subtitleSync-closeButton {
|
||||||
|
|
|
@ -65,6 +65,9 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: TV layout will require special handling for navigation keys. But now field is not focusable
|
||||||
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
|
|
||||||
subtitleSyncTextField.blur = function() {
|
subtitleSyncTextField.blur = function() {
|
||||||
|
@ -87,14 +90,6 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
|
||||||
getOffsetFromPercentage(this.value));
|
getOffsetFromPercentage(this.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
subtitleSyncSlider.addEventListener('touchmove', function () {
|
|
||||||
// set new offset
|
|
||||||
playbackManager.setSubtitleOffset(getOffsetFromPercentage(this.value), player);
|
|
||||||
// synchronize with textField value
|
|
||||||
subtitleSyncTextField.updateOffset(
|
|
||||||
getOffsetFromPercentage(this.value));
|
|
||||||
});
|
|
||||||
|
|
||||||
subtitleSyncSlider.getBubbleHtml = function (value) {
|
subtitleSyncSlider.getBubbleHtml = function (value) {
|
||||||
var newOffset = getOffsetFromPercentage(value);
|
var newOffset = getOffsetFromPercentage(value);
|
||||||
return '<h1 class="sliderBubbleText">' +
|
return '<h1 class="sliderBubbleText">' +
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
<div class="subtitleSyncContainer">
|
<div class="subtitleSync">
|
||||||
<button type="button" is="paper-icon-button-light" class="subtitleSync-closeButton"><span class="material-icons close"></span></button>
|
<div class="subtitleSyncContainer">
|
||||||
<div class="subtitleSyncTextField" contenteditable="true" spellcheck="false">0s</div>
|
<button type="button" is="paper-icon-button-light" class="subtitleSync-closeButton"><span class="material-icons close"></span></button>
|
||||||
<div class="sliderContainer subtitleSyncSliderContainer">
|
<div class="subtitleSyncTextField" contenteditable="true" spellcheck="false">0s</div>
|
||||||
<input is="emby-slider" type="range" step="1" min="0" max="100" value="50" class="subtitleSyncSlider" />
|
<div class="sliderContainer subtitleSyncSliderContainer">
|
||||||
|
<input is="emby-slider" type="range" step="1" min="0" max="100" value="50" class="subtitleSyncSlider" data-slider-keep-progress="true" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -37,7 +37,7 @@ function showNewJoinGroupSelection (button, user, apiClient) {
|
||||||
console.debug('No item is currently playing.');
|
console.debug('No item is currently playing.');
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'ListGroups').then(function (response) {
|
apiClient.getSyncPlayGroups().then(function (response) {
|
||||||
response.json().then(function (groups) {
|
response.json().then(function (groups) {
|
||||||
var menuItems = groups.map(function (group) {
|
var menuItems = groups.map(function (group) {
|
||||||
return {
|
return {
|
||||||
|
@ -83,9 +83,9 @@ function showNewJoinGroupSelection (button, user, apiClient) {
|
||||||
|
|
||||||
actionsheet.show(menuOptions).then(function (id) {
|
actionsheet.show(menuOptions).then(function (id) {
|
||||||
if (id == 'new-group') {
|
if (id == 'new-group') {
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'NewGroup');
|
apiClient.createSyncPlayGroup();
|
||||||
} else {
|
} else if (id) {
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'JoinGroup', {
|
apiClient.joinSyncPlayGroup({
|
||||||
GroupId: id,
|
GroupId: id,
|
||||||
PlayingItemId: playingItemId
|
PlayingItemId: playingItemId
|
||||||
});
|
});
|
||||||
|
@ -140,7 +140,7 @@ function showLeaveGroupSelection (button, user, apiClient) {
|
||||||
|
|
||||||
actionsheet.show(menuOptions).then(function (id) {
|
actionsheet.show(menuOptions).then(function (id) {
|
||||||
if (id == 'leave-group') {
|
if (id == 'leave-group') {
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'LeaveGroup');
|
apiClient.leaveSyncPlayGroup();
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('SyncPlay: unexpected error showing group menu:', error);
|
console.error('SyncPlay: unexpected error showing group menu:', error);
|
||||||
|
|
|
@ -139,7 +139,7 @@ class SyncPlayManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'UpdatePing', {
|
apiClient.sendSyncPlayPing({
|
||||||
Ping: ping
|
Ping: ping
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,7 @@ class SyncPlayManager {
|
||||||
if (!this.lastPlaybackWaiting) {
|
if (!this.lastPlaybackWaiting) {
|
||||||
this.lastPlaybackWaiting = new Date();
|
this.lastPlaybackWaiting = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
events.trigger(this, 'waiting');
|
events.trigger(this, 'waiting');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +289,7 @@ class SyncPlayManager {
|
||||||
player.setPlaybackRate(this.localPlayerPlaybackRate);
|
player.setPlaybackRate(this.localPlayerPlaybackRate);
|
||||||
this.localPlayerPlaybackRate = 1.0;
|
this.localPlayerPlaybackRate = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentPlayer = null;
|
this.currentPlayer = null;
|
||||||
this.playbackRateSupported = false;
|
this.playbackRateSupported = false;
|
||||||
}
|
}
|
||||||
|
@ -433,6 +435,7 @@ class SyncPlayManager {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get playing item id
|
// Get playing item id
|
||||||
let playingItemId;
|
let playingItemId;
|
||||||
try {
|
try {
|
||||||
|
@ -447,7 +450,7 @@ class SyncPlayManager {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
console.warning('Error reporting playback state to server. Joining group will fail.');
|
console.warning('Error reporting playback state to server. Joining group will fail.');
|
||||||
}
|
}
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'JoinGroup', {
|
apiClient.joinSyncPlayGroup({
|
||||||
GroupId: groupId,
|
GroupId: groupId,
|
||||||
PlayingItemId: playingItemId
|
PlayingItemId: playingItemId
|
||||||
});
|
});
|
||||||
|
@ -619,6 +622,7 @@ class SyncPlayManager {
|
||||||
if (this.currentPlayer) {
|
if (this.currentPlayer) {
|
||||||
this.currentPlayer.setPlaybackRate(1);
|
this.currentPlayer.setPlaybackRate(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clearSyncIcon();
|
this.clearSyncIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,8 +662,7 @@ class SyncPlayManager {
|
||||||
*/
|
*/
|
||||||
playRequest (player) {
|
playRequest (player) {
|
||||||
var apiClient = connectionManager.currentApiClient();
|
var apiClient = connectionManager.currentApiClient();
|
||||||
var sessionId = getActivePlayerId();
|
apiClient.requestSyncPlayStart();
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'PlayRequest');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -667,8 +670,7 @@ class SyncPlayManager {
|
||||||
*/
|
*/
|
||||||
pauseRequest (player) {
|
pauseRequest (player) {
|
||||||
var apiClient = connectionManager.currentApiClient();
|
var apiClient = connectionManager.currentApiClient();
|
||||||
var sessionId = getActivePlayerId();
|
apiClient.requestSyncPlayPause();
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'PauseRequest');
|
|
||||||
// Pause locally as well, to give the user some little control
|
// Pause locally as well, to give the user some little control
|
||||||
playbackManager._localUnpause(player);
|
playbackManager._localUnpause(player);
|
||||||
}
|
}
|
||||||
|
@ -678,8 +680,7 @@ class SyncPlayManager {
|
||||||
*/
|
*/
|
||||||
seekRequest (PositionTicks, player) {
|
seekRequest (PositionTicks, player) {
|
||||||
var apiClient = connectionManager.currentApiClient();
|
var apiClient = connectionManager.currentApiClient();
|
||||||
var sessionId = getActivePlayerId();
|
apiClient.requestSyncPlaySeek({
|
||||||
apiClient.sendSyncPlayCommand(sessionId, 'SeekRequest', {
|
|
||||||
PositionTicks: PositionTicks
|
PositionTicks: PositionTicks
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import appHost from 'apphost';
|
import appHost from 'apphost';
|
||||||
import appSettings from 'appSettings';
|
import appSettings from 'appSettings';
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
|
@ -8,6 +9,10 @@ import browser from 'browser';
|
||||||
import globalize from 'globalize';
|
import globalize from 'globalize';
|
||||||
import 'cardStyle';
|
import 'cardStyle';
|
||||||
import 'emby-checkbox';
|
import 'emby-checkbox';
|
||||||
|
=======
|
||||||
|
define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layoutManager', 'libraryMenu', 'browser', 'globalize', 'cardStyle', 'emby-checkbox'], function (appHost, appSettings, dom, connectionManager, loading, layoutManager, libraryMenu, browser, globalize) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
@ -16,6 +21,7 @@ import 'emby-checkbox';
|
||||||
function authenticateUserByName(page, apiClient, username, password) {
|
function authenticateUserByName(page, apiClient, username, password) {
|
||||||
loading.show();
|
loading.show();
|
||||||
apiClient.authenticateUserByName(username, password).then(function (result) {
|
apiClient.authenticateUserByName(username, password).then(function (result) {
|
||||||
|
<<<<<<< HEAD
|
||||||
const user = result.User;
|
const user = result.User;
|
||||||
const serverId = getParameterByName('serverid');
|
const serverId = getParameterByName('serverid');
|
||||||
let newUrl;
|
let newUrl;
|
||||||
|
@ -26,9 +32,13 @@ import 'emby-checkbox';
|
||||||
newUrl = 'home.html';
|
newUrl = 'home.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=======
|
||||||
|
var user = result.User;
|
||||||
|
>>>>>>> upstream/master
|
||||||
loading.hide();
|
loading.hide();
|
||||||
|
|
||||||
Dashboard.onServerChanged(user.Id, result.AccessToken, apiClient);
|
Dashboard.onServerChanged(user.Id, result.AccessToken, apiClient);
|
||||||
Dashboard.navigate(newUrl);
|
Dashboard.navigate('home.html');
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
page.querySelector('#txtManualName').value = '';
|
page.querySelector('#txtManualName').value = '';
|
||||||
page.querySelector('#txtManualPassword').value = '';
|
page.querySelector('#txtManualPassword').value = '';
|
||||||
|
@ -204,6 +214,7 @@ import 'emby-checkbox';
|
||||||
});
|
});
|
||||||
view.addEventListener('viewshow', function (e) {
|
view.addEventListener('viewshow', function (e) {
|
||||||
loading.show();
|
loading.show();
|
||||||
|
libraryMenu.setTransparentMenu(true);
|
||||||
|
|
||||||
if (!appHost.supports('multiserver')) {
|
if (!appHost.supports('multiserver')) {
|
||||||
view.querySelector('.btnSelectServer').classList.add('hide');
|
view.querySelector('.btnSelectServer').classList.add('hide');
|
||||||
|
@ -225,6 +236,14 @@ import 'emby-checkbox';
|
||||||
view.querySelector('.disclaimer').textContent = options.LoginDisclaimer || '';
|
view.querySelector('.disclaimer').textContent = options.LoginDisclaimer || '';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
<<<<<<< HEAD
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-enable indent */
|
/* eslint-enable indent */
|
||||||
|
=======
|
||||||
|
view.addEventListener('viewhide', function (e) {
|
||||||
|
libraryMenu.setTransparentMenu(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import loading from 'loading';
|
import loading from 'loading';
|
||||||
import appRouter from 'appRouter';
|
import appRouter from 'appRouter';
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
|
@ -19,6 +20,12 @@ import 'emby-button';
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
const enableFocusTransform = !browser.slow && !browser.edge;
|
const enableFocusTransform = !browser.slow && !browser.edge;
|
||||||
|
=======
|
||||||
|
define(['loading', 'appRouter', 'layoutManager', 'libraryMenu', 'appSettings', 'apphost', 'focusManager', 'connectionManager', 'globalize', 'actionsheet', 'dom', 'browser', 'material-icons', 'flexStyles', 'emby-scroller', 'emby-itemscontainer', 'cardStyle', 'emby-button'], function (loading, appRouter, layoutManager, libraryMenu, appSettings, appHost, focusManager, connectionManager, globalize, actionSheet, dom, browser) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var enableFocusTransform = !browser.slow && !browser.edge;
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
function renderSelectServerItems(view, servers) {
|
function renderSelectServerItems(view, servers) {
|
||||||
const items = servers.map(function (server) {
|
const items = servers.map(function (server) {
|
||||||
|
@ -200,6 +207,7 @@ import 'emby-button';
|
||||||
view.addEventListener('viewshow', function (e) {
|
view.addEventListener('viewshow', function (e) {
|
||||||
const isRestored = e.detail.isRestored;
|
const isRestored = e.detail.isRestored;
|
||||||
appRouter.setTitle(null);
|
appRouter.setTitle(null);
|
||||||
|
libraryMenu.setTransparentMenu(true);
|
||||||
|
|
||||||
if (!isRestored) {
|
if (!isRestored) {
|
||||||
loadServers();
|
loadServers();
|
||||||
|
|
|
@ -189,6 +189,7 @@ import 'emby-itemscontainer';
|
||||||
function reloadSystemInfo(view, apiClient) {
|
function reloadSystemInfo(view, apiClient) {
|
||||||
apiClient.getSystemInfo().then(function (systemInfo) {
|
apiClient.getSystemInfo().then(function (systemInfo) {
|
||||||
view.querySelector('#serverName').innerHTML = globalize.translate('DashboardServerName', systemInfo.ServerName);
|
view.querySelector('#serverName').innerHTML = globalize.translate('DashboardServerName', systemInfo.ServerName);
|
||||||
|
<<<<<<< HEAD
|
||||||
let localizedVersion = globalize.translate('DashboardVersionNumber', systemInfo.Version);
|
let localizedVersion = globalize.translate('DashboardVersionNumber', systemInfo.Version);
|
||||||
|
|
||||||
if (systemInfo.SystemUpdateLevel !== 'Release') {
|
if (systemInfo.SystemUpdateLevel !== 'Release') {
|
||||||
|
@ -196,6 +197,9 @@ import 'emby-itemscontainer';
|
||||||
}
|
}
|
||||||
|
|
||||||
view.querySelector('#versionNumber').innerHTML = localizedVersion;
|
view.querySelector('#versionNumber').innerHTML = localizedVersion;
|
||||||
|
=======
|
||||||
|
view.querySelector('#versionNumber').innerHTML = globalize.translate('DashboardVersionNumber', systemInfo.Version);
|
||||||
|
>>>>>>> upstream/master
|
||||||
view.querySelector('#operatingSystem').innerHTML = globalize.translate('DashboardOperatingSystem', systemInfo.OperatingSystem);
|
view.querySelector('#operatingSystem').innerHTML = globalize.translate('DashboardOperatingSystem', systemInfo.OperatingSystem);
|
||||||
view.querySelector('#architecture').innerHTML = globalize.translate('DashboardArchitecture', systemInfo.SystemArchitecture);
|
view.querySelector('#architecture').innerHTML = globalize.translate('DashboardArchitecture', systemInfo.SystemArchitecture);
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ import 'emby-itemrefreshindicator';
|
||||||
showType: false,
|
showType: false,
|
||||||
showLocations: false,
|
showLocations: false,
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
showNameWithIcon: true
|
showNameWithIcon: false
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let i = 0; i < virtualFolders.length; i++) {
|
for (let i = 0; i < virtualFolders.length; i++) {
|
||||||
|
@ -185,7 +185,7 @@ import 'emby-itemrefreshindicator';
|
||||||
$('.btnCardMenu', divVirtualFolders).on('click', function () {
|
$('.btnCardMenu', divVirtualFolders).on('click', function () {
|
||||||
showCardMenu(page, this, virtualFolders);
|
showCardMenu(page, this, virtualFolders);
|
||||||
});
|
});
|
||||||
divVirtualFolders.querySelector('.addLibrary').addEventListener('click', function () {
|
divVirtualFolders.querySelector('#addLibrary').addEventListener('click', function () {
|
||||||
addVirtualFolder(page);
|
addVirtualFolder(page);
|
||||||
});
|
});
|
||||||
$('.editLibrary', divVirtualFolders).on('click', function () {
|
$('.editLibrary', divVirtualFolders).on('click', function () {
|
||||||
|
@ -256,7 +256,12 @@ import 'emby-itemrefreshindicator';
|
||||||
style += 'min-width:33.3%;';
|
style += 'min-width:33.3%;';
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '<div class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">';
|
if (virtualFolder.Locations.length == 0) {
|
||||||
|
html += '<div id="addLibrary" class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">';
|
||||||
|
} else {
|
||||||
|
html += '<div class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">';
|
||||||
|
}
|
||||||
|
|
||||||
html += '<div class="cardBox visualCardBox">';
|
html += '<div class="cardBox visualCardBox">';
|
||||||
html += '<div class="cardScalable visualCardBox-cardScalable">';
|
html += '<div class="cardScalable visualCardBox-cardScalable">';
|
||||||
html += '<div class="cardPadder cardPadder-backdrop"></div>';
|
html += '<div class="cardPadder cardPadder-backdrop"></div>';
|
||||||
|
|
|
@ -105,7 +105,9 @@ import globalize from 'globalize';
|
||||||
$('#chkEnableSharing', page).prop('checked', user.Policy.EnablePublicSharing);
|
$('#chkEnableSharing', page).prop('checked', user.Policy.EnablePublicSharing);
|
||||||
$('#txtRemoteClientBitrateLimit', page).val(user.Policy.RemoteClientBitrateLimit / 1e6 || '');
|
$('#txtRemoteClientBitrateLimit', page).val(user.Policy.RemoteClientBitrateLimit / 1e6 || '');
|
||||||
$('#txtLoginAttemptsBeforeLockout', page).val(user.Policy.LoginAttemptsBeforeLockout || '0');
|
$('#txtLoginAttemptsBeforeLockout', page).val(user.Policy.LoginAttemptsBeforeLockout || '0');
|
||||||
$('#selectSyncPlayAccess').val(user.Policy.SyncPlayAccess);
|
if (ApiClient.isMinServerVersion('10.6.0')) {
|
||||||
|
$('#selectSyncPlayAccess').val(user.Policy.SyncPlayAccess);
|
||||||
|
}
|
||||||
loading.hide();
|
loading.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +149,9 @@ import globalize from 'globalize';
|
||||||
}).map(function (c) {
|
}).map(function (c) {
|
||||||
return c.getAttribute('data-id');
|
return c.getAttribute('data-id');
|
||||||
});
|
});
|
||||||
user.Policy.SyncPlayAccess = page.querySelector('#selectSyncPlayAccess').value;
|
if (ApiClient.isMinServerVersion('10.6.0')) {
|
||||||
|
user.Policy.SyncPlayAccess = page.querySelector('#selectSyncPlayAccess').value;
|
||||||
|
}
|
||||||
ApiClient.updateUser(user).then(function () {
|
ApiClient.updateUser(user).then(function () {
|
||||||
ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () {
|
ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () {
|
||||||
onSaveComplete(page, user);
|
onSaveComplete(page, user);
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
<div id="itemDetailPage" data-role="page" class="page libraryPage itemDetailPage noSecondaryNavPage selfBackdropPage noBackdrop" data-backbutton="true">
|
<div id="itemDetailPage" data-role="page" class="page libraryPage itemDetailPage noSecondaryNavPage selfBackdropPage" data-backbutton="true">
|
||||||
<div id="itemBackdrop" class="itemBackdrop">
|
<div id="itemBackdrop" class="itemBackdrop">
|
||||||
<button is="emby-button" type="button" class="btnPlay detailFloatingButton hide fab autoSize" title="${ButtonPlay}" data-mode="resume">
|
|
||||||
<span class="material-icons play_arrow"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="detailLogo"></div>
|
<div class="detailLogo"></div>
|
||||||
|
@ -15,94 +12,75 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mainDetailButtons">
|
<div class="mainDetailButtons">
|
||||||
<button is="emby-button" type="button" class="button-flat btnResume hide detailButton detailButtonHideonMobile" data-mode="resume">
|
<button is="emby-button" type="button" class="button-flat btnResume hide detailButton" title="${ButtonResume}" data-mode="resume">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon play_arrow"></span>
|
<span class="material-icons detailButton-icon play_arrow"></span>
|
||||||
<div class="detailButton-text">${ButtonResume}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnPlay hide detailButton detailButtonHideonMobile" data-mode="play">
|
<button is="emby-button" type="button" class="button-flat btnPlay hide detailButton" title="${ButtonPlay}" data-mode="play">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon play_arrow"></span>
|
<span class="material-icons detailButton-icon play_arrow"></span>
|
||||||
<div class="detailButton-text">${ButtonPlay}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnDownload hide detailButton">
|
<button is="emby-button" type="button" class="button-flat btnDownload hide detailButton" title="${ButtonDownload}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon get_app"></span>
|
<span class="material-icons detailButton-icon get_app"></span>
|
||||||
<div class="detailButton-text">${ButtonDownload}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnPlayTrailer hide detailButton">
|
<button is="emby-button" type="button" class="button-flat btnPlayTrailer hide detailButton" title="${ButtonTrailer}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon theaters"></span>
|
<span class="material-icons detailButton-icon theaters"></span>
|
||||||
<div class="detailButton-text">${ButtonTrailer}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnInstantMix hide detailButton">
|
<button is="emby-button" type="button" class="button-flat btnInstantMix hide detailButton" title="${HeaderInstantMix}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon explore"></span>
|
<span class="material-icons detailButton-icon explore"></span>
|
||||||
<div class="detailButton-text">${HeaderInstantMix}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnShuffle hide detailButton">
|
<button is="emby-button" type="button" class="button-flat btnShuffle hide detailButton" title="${ButtonShuffle}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon shuffle"></span>
|
<span class="material-icons detailButton-icon shuffle"></span>
|
||||||
<div class="detailButton-text">${ButtonShuffle}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnCancelSeriesTimer hide detailButton">
|
<button is="emby-button" type="button" class="button-flat btnCancelSeriesTimer hide detailButton" title="${CancelSeries}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon delete"></span>
|
<span class="material-icons detailButton-icon delete"></span>
|
||||||
<div class="detailButton-text">${CancelSeries}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnCancelTimer hide detailButton">
|
<button is="emby-button" type="button" class="button-flat btnCancelTimer hide detailButton" title="${StopRecording}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon stop"></span>
|
<span class="material-icons detailButton-icon stop"></span>
|
||||||
<div class="detailButton-text">${StopRecording}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnDeleteItem hide detailButton">
|
<button is="emby-playstatebutton" type="button" class="button-flat btnPlaystate hide detailButton" title="">
|
||||||
<div class="detailButton-content">
|
|
||||||
<span class="material-icons detailButton-icon delete"></span>
|
|
||||||
<div class="detailButton-text">${Delete}</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button is="emby-playstatebutton" type="button" class="button-flat btnPlaystate hide detailButton">
|
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon check"></span>
|
<span class="material-icons detailButton-icon check"></span>
|
||||||
<div class="detailButton-text button-text"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-ratingbutton" type="button" class="button-flat btnUserRating hide detailButton">
|
<button is="emby-ratingbutton" type="button" class="button-flat btnUserRating hide detailButton" title="${Rate}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon favorite"></span>
|
<span class="material-icons detailButton-icon favorite"></span>
|
||||||
<div class="detailButton-text button-text">${Rate}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnSplitVersions hide detailButton">
|
<button is="emby-button" type="button" class="button-flat btnSplitVersions hide detailButton" title="${ButtonSplit}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon call_split"></span>
|
<span class="material-icons detailButton-icon call_split"></span>
|
||||||
<div class="detailButton-text">${ButtonSplit}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="emby-button" type="button" class="button-flat btnMoreCommands hide detailButton">
|
<button is="emby-button" type="button" class="button-flat btnMoreCommands hide detailButton" title="${ButtonMore}">
|
||||||
<div class="detailButton-content">
|
<div class="detailButton-content">
|
||||||
<span class="material-icons detailButton-icon more_vert"></span>
|
<span class="material-icons detailButton-icon more_vert"></span>
|
||||||
<div class="detailButton-text">${ButtonMore}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -110,7 +88,7 @@
|
||||||
<div class="detailPageSecondaryContainer">
|
<div class="detailPageSecondaryContainer">
|
||||||
<div class="detailImageContainer padded-left"></div>
|
<div class="detailImageContainer padded-left"></div>
|
||||||
<div class="detailPageContent">
|
<div class="detailPageContent">
|
||||||
<div class="detailPagePrimaryContent padded-left padded-right">
|
<div class="detailPagePrimaryContent padded-right">
|
||||||
<div class="detailSection">
|
<div class="detailSection">
|
||||||
<div class="itemMiscInfo nativeName hide"></div>
|
<div class="itemMiscInfo nativeName hide"></div>
|
||||||
|
|
||||||
|
@ -124,6 +102,11 @@
|
||||||
<div class="directorsLabel label"></div>
|
<div class="directorsLabel label"></div>
|
||||||
<div class="directors content"></div>
|
<div class="directors content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="detailsGroupItem writersGroup hide">
|
||||||
|
<div class="writersLabel label"></div>
|
||||||
|
<div class="writers content"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form class="trackSelections hide focuscontainer-x">
|
<form class="trackSelections hide focuscontainer-x">
|
||||||
|
@ -164,15 +147,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="seriesTimerScheduleSection verticalSection detailVerticalSection hide" style="margin-top:-3em;">
|
<div class="seriesTimerScheduleSection verticalSection detailVerticalSection hide" style="margin-top:-3em;">
|
||||||
<h2 class="sectionTitle padded-left">${HeaderSchedule}</h2>
|
<h2 class="sectionTitle">${HeaderSchedule}</h2>
|
||||||
<div class="seriesTimerSchedule padded-left padded-right"></div>
|
<div class="seriesTimerSchedule padded-right"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="collectionItems"></div>
|
<div class="collectionItems hide"></div>
|
||||||
|
|
||||||
<div class="nextUpSection verticalSection detailVerticalSection hide">
|
<div class="nextUpSection verticalSection detailVerticalSection hide">
|
||||||
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderNextUp}</h2>
|
<h2 class="sectionTitle sectionTitle-cards">${HeaderNextUp}</h2>
|
||||||
<div is="emby-itemscontainer" class="nextUpItems vertical-wrap padded-left padded-right"></div>
|
<div is="emby-itemscontainer" class="nextUpItems vertical-wrap padded-right"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="programGuideSection hide verticalSection detailVerticalSection">
|
<div class="programGuideSection hide verticalSection detailVerticalSection">
|
||||||
|
@ -180,64 +163,64 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="childrenCollapsible" class="hide verticalSection detailVerticalSection">
|
<div id="childrenCollapsible" class="hide verticalSection detailVerticalSection">
|
||||||
<h2 class="childrenSectionHeader sectionTitle sectionTitle-cards padded-left">
|
<h2 class="childrenSectionHeader sectionTitle sectionTitle-cards hide">
|
||||||
<span id="childrenTitle"></span>
|
<span id="childrenTitle"></span>
|
||||||
</h2>
|
</h2>
|
||||||
<div id="childrenContent">
|
<div id="childrenContent">
|
||||||
<div is="emby-itemscontainer" class="childrenItemsContainer itemsContainer padded-left padded-right" style="text-align: left;"></div>
|
<div is="emby-itemscontainer" class="childrenItemsContainer itemsContainer padded-right" style="text-align: left;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="additionalPartsCollapsible" class="verticalSection detailVerticalSection hide">
|
<div id="additionalPartsCollapsible" class="verticalSection detailVerticalSection hide">
|
||||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderAdditionalParts}</h2>
|
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderAdditionalParts}</h2>
|
||||||
<div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
|
<div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-right"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="verticalSection itemVerticalSection moreFromSeasonSection hide">
|
<div class="verticalSection detailVerticalSection moreFromSeasonSection hide">
|
||||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right"></h2>
|
<h2 class="sectionTitle sectionTitle-cards padded-right"></h2>
|
||||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||||
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="verticalSection itemVerticalSection moreFromArtistSection hide">
|
<div class="verticalSection detailVerticalSection moreFromArtistSection hide">
|
||||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right"></h2>
|
<h2 class="sectionTitle sectionTitle-cards padded-right"></h2>
|
||||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||||
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="castCollapsible" class="verticalSection detailVerticalSection hide">
|
<div id="castCollapsible" class="verticalSection detailVerticalSection hide">
|
||||||
<h2 id="peopleHeader" class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderCastCrew}</h2>
|
<h2 id="peopleHeader" class="sectionTitle sectionTitle-cards padded-right">${HeaderCastCrew}</h2>
|
||||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||||
<div id="castContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
<div id="castContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="seriesScheduleSection" class="verticalSection detailVerticalSection hide">
|
<div id="seriesScheduleSection" class="verticalSection detailVerticalSection hide">
|
||||||
<h2 class="sectionTitle padded-left padded-right">${HeaderUpcomingOnTV}</h2>
|
<h2 class="sectionTitle padded-right">${HeaderUpcomingOnTV}</h2>
|
||||||
<div id="seriesScheduleList" is="emby-itemscontainer" class="itemsContainer vertical-list padded-left padded-right"></div>
|
<div id="seriesScheduleList" is="emby-itemscontainer" class="itemsContainer vertical-list padded-right"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="specialsCollapsible" class="verticalSection detailVerticalSection hide">
|
<div id="specialsCollapsible" class="verticalSection detailVerticalSection hide">
|
||||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderSpecialFeatures}</h2>
|
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderSpecialFeatures}</h2>
|
||||||
<div id="specialsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
|
<div id="specialsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-right"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="musicVideosCollapsible" class="verticalSection detailVerticalSection hide">
|
<div id="musicVideosCollapsible" class="verticalSection detailVerticalSection hide">
|
||||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderMusicVideos}</h2>
|
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderMusicVideos}</h2>
|
||||||
<div id="musicVideosContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
|
<div id="musicVideosContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-right"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="scenesCollapsible" class="verticalSection itemVerticalSection verticalSection-extrabottompadding hide">
|
<div id="scenesCollapsible" class="verticalSection detailVerticalSection verticalSection-extrabottompadding hide">
|
||||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderScenes}</h2>
|
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderScenes}</h2>
|
||||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||||
<div id="scenesContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
<div id="scenesContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="similarCollapsible" class="verticalSection itemVerticalSection verticalSection-extrabottompadding hide">
|
<div id="similarCollapsible" class="verticalSection detailVerticalSection verticalSection-extrabottompadding hide">
|
||||||
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderMoreLikeThis}</h2>
|
<h2 class="sectionTitle sectionTitle-cards padded-right">${HeaderMoreLikeThis}</h2>
|
||||||
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
|
||||||
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer similarContent"></div>
|
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer similarContent"></div>
|
||||||
</div>
|
</div>
|
|
@ -28,15 +28,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideAll(page, className, show) {
|
function hideAll(page, className, show) {
|
||||||
var i;
|
for (const elem of page.querySelectorAll('.' + className)) {
|
||||||
var length;
|
|
||||||
var elems = page.querySelectorAll('.' + className);
|
|
||||||
|
|
||||||
for (i = 0, length = elems.length; i < length; i++) {
|
|
||||||
if (show) {
|
if (show) {
|
||||||
elems[i].classList.remove('hide');
|
elem.classList.remove('hide');
|
||||||
} else {
|
} else {
|
||||||
elems[i].classList.add('hide');
|
elem.classList.add('hide');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,17 +47,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
positionTo: button,
|
positionTo: button,
|
||||||
cancelTimer: false,
|
cancelTimer: false,
|
||||||
record: false,
|
record: false,
|
||||||
deleteItem: true === item.IsFolder,
|
deleteItem: item.CanDelete === true,
|
||||||
shuffle: false,
|
shuffle: false,
|
||||||
instantMix: false,
|
instantMix: false,
|
||||||
user: user,
|
user: user,
|
||||||
share: true
|
share: true
|
||||||
};
|
};
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProgramScheduleHtml(items) {
|
function getProgramScheduleHtml(items) {
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-list" data-contextmenu="false">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-list" data-contextmenu="false">';
|
||||||
html += listView.getListViewHtml({
|
html += listView.getListViewHtml({
|
||||||
items: items,
|
items: items,
|
||||||
|
@ -75,7 +73,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
moreButton: false,
|
moreButton: false,
|
||||||
recordButton: false
|
recordButton: false
|
||||||
});
|
});
|
||||||
return html += '</div>';
|
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderSeriesTimerSchedule(page, apiClient, seriesTimerId) {
|
function renderSeriesTimerSchedule(page, apiClient, seriesTimerId) {
|
||||||
|
@ -143,9 +144,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
|
|
||||||
var mediaSources = item.MediaSources;
|
var mediaSources = item.MediaSources;
|
||||||
instance._currentPlaybackMediaSources = mediaSources;
|
instance._currentPlaybackMediaSources = mediaSources;
|
||||||
|
|
||||||
page.querySelector('.trackSelections').classList.remove('hide');
|
page.querySelector('.trackSelections').classList.remove('hide');
|
||||||
select.setLabel(globalize.translate('LabelVersion'));
|
select.setLabel(globalize.translate('LabelVersion'));
|
||||||
|
|
||||||
var currentValue = select.value;
|
var currentValue = select.value;
|
||||||
|
|
||||||
var selectedId = mediaSources[0].Id;
|
var selectedId = mediaSources[0].Id;
|
||||||
select.innerHTML = mediaSources.map(function (v) {
|
select.innerHTML = mediaSources.map(function (v) {
|
||||||
var selected = v.Id === selectedId ? ' selected' : '';
|
var selected = v.Id === selectedId ? ' selected' : '';
|
||||||
|
@ -163,7 +167,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
renderAudioSelections(page, mediaSources);
|
renderAudioSelections(page, mediaSources);
|
||||||
renderSubtitleSelections(page, mediaSources);
|
renderSubtitleSelections(page, mediaSources);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderVideoSelections(page, mediaSources) {
|
function renderVideoSelections(page, mediaSources) {
|
||||||
|
@ -171,9 +174,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
var mediaSource = mediaSources.filter(function (m) {
|
var mediaSource = mediaSources.filter(function (m) {
|
||||||
return m.Id === mediaSourceId;
|
return m.Id === mediaSourceId;
|
||||||
})[0];
|
})[0];
|
||||||
|
|
||||||
var tracks = mediaSource.MediaStreams.filter(function (m) {
|
var tracks = mediaSource.MediaStreams.filter(function (m) {
|
||||||
return 'Video' === m.Type;
|
return m.Type === 'Video';
|
||||||
});
|
});
|
||||||
|
|
||||||
var select = page.querySelector('.selectVideo');
|
var select = page.querySelector('.selectVideo');
|
||||||
select.setLabel(globalize.translate('LabelVideo'));
|
select.setLabel(globalize.translate('LabelVideo'));
|
||||||
var selectedId = tracks.length ? tracks[0].Index : -1;
|
var selectedId = tracks.length ? tracks[0].Index : -1;
|
||||||
|
@ -242,12 +247,24 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
select.setLabel(globalize.translate('LabelSubtitles'));
|
select.setLabel(globalize.translate('LabelSubtitles'));
|
||||||
var selectedId = null == mediaSource.DefaultSubtitleStreamIndex ? -1 : mediaSource.DefaultSubtitleStreamIndex;
|
var selectedId = null == mediaSource.DefaultSubtitleStreamIndex ? -1 : mediaSource.DefaultSubtitleStreamIndex;
|
||||||
|
|
||||||
if (tracks.length) {
|
var videoTracks = mediaSource.MediaStreams.filter(function (m) {
|
||||||
|
return 'Video' === m.Type;
|
||||||
|
});
|
||||||
|
|
||||||
|
// This only makes sense on Video items
|
||||||
|
if (videoTracks.length) {
|
||||||
var selected = -1 === selectedId ? ' selected' : '';
|
var selected = -1 === selectedId ? ' selected' : '';
|
||||||
select.innerHTML = '<option value="-1">' + globalize.translate('Off') + '</option>' + tracks.map(function (v) {
|
select.innerHTML = '<option value="-1">' + globalize.translate('Off') + '</option>' + tracks.map(function (v) {
|
||||||
selected = v.Index === selectedId ? ' selected' : '';
|
selected = v.Index === selectedId ? ' selected' : '';
|
||||||
return '<option value="' + v.Index + '" ' + selected + '>' + v.DisplayTitle + '</option>';
|
return '<option value="' + v.Index + '" ' + selected + '>' + v.DisplayTitle + '</option>';
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
|
if (tracks.length > 0) {
|
||||||
|
select.removeAttribute('disabled');
|
||||||
|
} else {
|
||||||
|
select.setAttribute('disabled', 'disabled');
|
||||||
|
}
|
||||||
|
|
||||||
page.querySelector('.selectSubtitlesContainer').classList.remove('hide');
|
page.querySelector('.selectSubtitlesContainer').classList.remove('hide');
|
||||||
} else {
|
} else {
|
||||||
select.innerHTML = '';
|
select.innerHTML = '';
|
||||||
|
@ -278,7 +295,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
var enableShuffle = item.IsFolder || -1 !== ['MusicAlbum', 'MusicGenre', 'MusicArtist'].indexOf(item.Type);
|
var enableShuffle = item.IsFolder || -1 !== ['MusicAlbum', 'MusicGenre', 'MusicArtist'].indexOf(item.Type);
|
||||||
hideAll(page, 'btnShuffle', enableShuffle);
|
hideAll(page, 'btnShuffle', enableShuffle);
|
||||||
canPlay = true;
|
canPlay = true;
|
||||||
hideAll(page, 'btnResume', item.UserData && item.UserData.PlaybackPositionTicks > 0);
|
|
||||||
|
const isResumable = item.UserData && item.UserData.PlaybackPositionTicks > 0;
|
||||||
|
hideAll(page, 'btnResume', isResumable);
|
||||||
|
|
||||||
|
if (isResumable) {
|
||||||
|
for (const elem of page.querySelectorAll('.btnPlay')) {
|
||||||
|
elem.querySelector('.detailButton-icon').classList.replace('play_arrow', 'replay');
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
hideAll(page, 'btnPlay');
|
hideAll(page, 'btnPlay');
|
||||||
hideAll(page, 'btnResume');
|
hideAll(page, 'btnResume');
|
||||||
|
@ -324,8 +349,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
function getArtistLinksHtml(artists, serverId, context) {
|
function getArtistLinksHtml(artists, serverId, context) {
|
||||||
var html = [];
|
var html = [];
|
||||||
|
|
||||||
for (var i = 0, length = artists.length; i < length; i++) {
|
for (const artist of artists) {
|
||||||
var artist = artists[i];
|
|
||||||
var href = appRouter.getRouteUrl(artist, {
|
var href = appRouter.getRouteUrl(artist, {
|
||||||
context: context,
|
context: context,
|
||||||
itemType: 'MusicArtist',
|
itemType: 'MusicArtist',
|
||||||
|
@ -333,10 +357,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
});
|
});
|
||||||
html.push('<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + href + '">' + artist.Name + '</a>');
|
html.push('<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + href + '">' + artist.Name + '</a>');
|
||||||
}
|
}
|
||||||
|
html = html.join(' / ');
|
||||||
|
|
||||||
return html = html.join(' / ');
|
return html;
|
||||||
}
|
}
|
||||||
function renderName(item, container, isStatic, context) {
|
|
||||||
|
/**
|
||||||
|
* Renders the item's name block
|
||||||
|
* @param {Object} item - Item used to render the name.
|
||||||
|
* @param {HTMLDivElement} container - Container to render the information into.
|
||||||
|
* @param {Object} context - Application context.
|
||||||
|
*/
|
||||||
|
function renderName(item, container, context) {
|
||||||
var parentRoute;
|
var parentRoute;
|
||||||
var parentNameHtml = [];
|
var parentNameHtml = [];
|
||||||
var parentNameLast = false;
|
var parentNameLast = false;
|
||||||
|
@ -410,16 +442,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
if (parentNameLast) {
|
if (parentNameLast) {
|
||||||
// Music
|
// Music
|
||||||
if (layoutManager.mobile) {
|
if (layoutManager.mobile) {
|
||||||
html = '<h3 class="parentName" style="margin: .25em 0;">' + parentNameHtml.join('</br>') + '</h3>';
|
html = '<h3 class="parentName musicParentName">' + parentNameHtml.join('</br>') + '</h3>';
|
||||||
} else {
|
} else {
|
||||||
html = '<h3 class="parentName" style="margin: .25em 0;">' + parentNameHtml.join(' - ') + '</h3>';
|
html = '<h3 class="parentName musicParentName">' + parentNameHtml.join(' - ') + '</h3>';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (layoutManager.mobile) {
|
html = '<h1 class="parentName">' + tvShowHtml + '</h1>';
|
||||||
html = '<h1 class="parentName" style="margin: 0.2em 0 0">' + parentNameHtml.join('</br>') + '</h1>';
|
|
||||||
} else {
|
|
||||||
html = '<h1 class="parentName" style="margin: 0.2em 0 0">' + tvShowHtml + '</h1>';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,17 +456,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
});
|
});
|
||||||
|
|
||||||
if (html && !parentNameLast) {
|
if (html && !parentNameLast) {
|
||||||
if (!layoutManager.mobile && tvSeasonHtml) {
|
if (tvSeasonHtml) {
|
||||||
html += '<h3 class="itemName infoText" style="margin: 0.2em 0 0">' + tvSeasonHtml + ' - ' + name + '</h3>';
|
html += '<h3 class="itemName infoText subtitle">' + tvSeasonHtml + ' - ' + name + '</h3>';
|
||||||
} else {
|
} else {
|
||||||
html += '<h3 class="itemName infoText" style="margin: 0.2em 0 0">' + name + '</h3>';
|
html += '<h3 class="itemName infoText subtitle">' + name + '</h3>';
|
||||||
}
|
}
|
||||||
|
} else if (item.OriginalTitle && item.OriginalTitle != item.Name) {
|
||||||
|
html = '<h1 class="itemName infoText parentNameLast withOriginalTitle">' + name + '</h1>' + html;
|
||||||
} else {
|
} else {
|
||||||
html = '<h1 class="itemName infoText" style="margin: 0.4em 0 0">' + name + '</h1>' + html;
|
html = '<h1 class="itemName infoText parentNameLast">' + name + '</h1>' + html;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.OriginalTitle && item.OriginalTitle != item.Name) {
|
if (item.OriginalTitle && item.OriginalTitle != item.Name) {
|
||||||
html += '<h4 class="itemName infoText" style="margin: 0 0 0;">' + item.OriginalTitle + '</h4>';
|
html += '<h4 class="itemName infoText originalTitle">' + item.OriginalTitle + '</h4>';
|
||||||
}
|
}
|
||||||
|
|
||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
|
@ -470,43 +500,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
var imgUrl;
|
var imgUrl;
|
||||||
var hasbackdrop = false;
|
var hasbackdrop = false;
|
||||||
var itemBackdropElement = page.querySelector('#itemBackdrop');
|
var itemBackdropElement = page.querySelector('#itemBackdrop');
|
||||||
var usePrimaryImage = item.MediaType === 'Video' && item.Type !== 'Movie' && item.Type !== 'Trailer' ||
|
|
||||||
item.MediaType && item.MediaType !== 'Video' ||
|
|
||||||
item.Type === 'MusicAlbum' ||
|
|
||||||
item.Type === 'Person';
|
|
||||||
|
|
||||||
if (!layoutManager.mobile && !userSettings.detailsBanner()) {
|
if (!layoutManager.mobile && !userSettings.detailsBanner()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('Program' === item.Type && item.ImageTags && item.ImageTags.Thumb) {
|
if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
||||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
|
||||||
type: 'Thumb',
|
|
||||||
maxWidth: dom.getScreenWidth(),
|
|
||||||
index: 0,
|
|
||||||
tag: item.ImageTags.Thumb
|
|
||||||
});
|
|
||||||
page.classList.remove('noBackdrop');
|
|
||||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
|
||||||
hasbackdrop = true;
|
|
||||||
} else if (usePrimaryImage && item.ImageTags && item.ImageTags.Primary) {
|
|
||||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
|
||||||
type: 'Primary',
|
|
||||||
maxWidth: dom.getScreenWidth(),
|
|
||||||
index: 0,
|
|
||||||
tag: item.ImageTags.Primary
|
|
||||||
});
|
|
||||||
page.classList.remove('noBackdrop');
|
|
||||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
|
||||||
hasbackdrop = true;
|
|
||||||
} else if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
|
||||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||||
type: 'Backdrop',
|
type: 'Backdrop',
|
||||||
maxWidth: dom.getScreenWidth(),
|
maxWidth: dom.getScreenWidth(),
|
||||||
index: 0,
|
index: 0,
|
||||||
tag: item.BackdropImageTags[0]
|
tag: item.BackdropImageTags[0]
|
||||||
});
|
});
|
||||||
page.classList.remove('noBackdrop');
|
|
||||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||||
hasbackdrop = true;
|
hasbackdrop = true;
|
||||||
} else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
|
} else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
|
||||||
|
@ -516,50 +521,35 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
index: 0,
|
index: 0,
|
||||||
tag: item.ParentBackdropImageTags[0]
|
tag: item.ParentBackdropImageTags[0]
|
||||||
});
|
});
|
||||||
page.classList.remove('noBackdrop');
|
|
||||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
|
||||||
hasbackdrop = true;
|
|
||||||
} else if (item.ImageTags && item.ImageTags.Thumb) {
|
|
||||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
|
||||||
type: 'Thumb',
|
|
||||||
maxWidth: dom.getScreenWidth(),
|
|
||||||
index: 0,
|
|
||||||
tag: item.ImageTags.Thumb
|
|
||||||
});
|
|
||||||
page.classList.remove('noBackdrop');
|
|
||||||
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
imageLoader.lazyImage(itemBackdropElement, imgUrl);
|
||||||
hasbackdrop = true;
|
hasbackdrop = true;
|
||||||
} else {
|
} else {
|
||||||
itemBackdropElement.style.backgroundImage = '';
|
itemBackdropElement.style.backgroundImage = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('Person' === item.Type) {
|
|
||||||
// FIXME: This hides the backdrop on all persons to fix a margin issue. Ideally, a proper fix should be made.
|
|
||||||
page.classList.add('noBackdrop');
|
|
||||||
itemBackdropElement.classList.add('personBackdrop');
|
|
||||||
} else {
|
|
||||||
itemBackdropElement.classList.remove('personBackdrop');
|
|
||||||
}
|
|
||||||
|
|
||||||
return hasbackdrop;
|
return hasbackdrop;
|
||||||
}
|
}
|
||||||
|
|
||||||
function reloadFromItem(instance, page, params, item, user) {
|
function reloadFromItem(instance, page, params, item, user) {
|
||||||
var context = params.context;
|
const apiClient = connectionManager.getApiClient(item.ServerId);
|
||||||
page.querySelector('.detailPagePrimaryContainer').classList.add('detailSticky');
|
|
||||||
|
|
||||||
renderName(item, page.querySelector('.nameContainer'), false, context);
|
|
||||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
|
||||||
renderSeriesTimerEditor(page, item, apiClient, user);
|
|
||||||
renderTimerEditor(page, item, apiClient, user);
|
|
||||||
renderImage(page, item, apiClient, user);
|
|
||||||
renderLogo(page, item, apiClient);
|
|
||||||
Emby.Page.setTitle('');
|
Emby.Page.setTitle('');
|
||||||
setInitialCollapsibleState(page, item, apiClient, context, user);
|
|
||||||
renderDetails(page, item, apiClient, context);
|
// Start rendering the artwork first
|
||||||
renderTrackSelections(page, instance, item);
|
renderImage(page, item);
|
||||||
|
renderLogo(page, item, apiClient);
|
||||||
renderBackdrop(item);
|
renderBackdrop(item);
|
||||||
renderDetailPageBackdrop(page, item, apiClient);
|
renderDetailPageBackdrop(page, item, apiClient);
|
||||||
|
|
||||||
|
// Render the main information for the item
|
||||||
|
page.querySelector('.detailPagePrimaryContainer').classList.add('detailRibbon');
|
||||||
|
renderName(item, page.querySelector('.nameContainer'), params.context);
|
||||||
|
renderDetails(page, item, apiClient, params.context);
|
||||||
|
renderTrackSelections(page, instance, item);
|
||||||
|
|
||||||
|
renderSeriesTimerEditor(page, item, apiClient, user);
|
||||||
|
renderTimerEditor(page, item, apiClient, user);
|
||||||
|
setInitialCollapsibleState(page, item, apiClient, params.context, user);
|
||||||
var canPlay = reloadPlayButtons(page, item);
|
var canPlay = reloadPlayButtons(page, item);
|
||||||
|
|
||||||
if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf('PlayTrailers')) {
|
if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf('PlayTrailers')) {
|
||||||
|
@ -570,12 +560,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
|
|
||||||
setTrailerButtonVisibility(page, item);
|
setTrailerButtonVisibility(page, item);
|
||||||
|
|
||||||
if (item.CanDelete && !item.IsFolder) {
|
|
||||||
hideAll(page, 'btnDeleteItem', true);
|
|
||||||
} else {
|
|
||||||
hideAll(page, 'btnDeleteItem');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('Program' !== item.Type || canPlay) {
|
if ('Program' !== item.Type || canPlay) {
|
||||||
hideAll(page, 'mainDetailButtons', true);
|
hideAll(page, 'mainDetailButtons', true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -667,18 +651,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderLogo(page, item, apiClient) {
|
function renderLogo(page, item, apiClient) {
|
||||||
var url = logoImageUrl(item, apiClient, {
|
|
||||||
maxWidth: 400
|
|
||||||
});
|
|
||||||
var detailLogo = page.querySelector('.detailLogo');
|
var detailLogo = page.querySelector('.detailLogo');
|
||||||
|
|
||||||
|
var url = logoImageUrl(item, apiClient, {});
|
||||||
|
|
||||||
if (!layoutManager.mobile && !userSettings.enableBackdrops()) {
|
if (!layoutManager.mobile && !userSettings.enableBackdrops()) {
|
||||||
detailLogo.classList.add('hide');
|
detailLogo.classList.add('hide');
|
||||||
} else if (url) {
|
} else if (url) {
|
||||||
detailLogo.classList.remove('hide');
|
detailLogo.classList.remove('hide');
|
||||||
detailLogo.classList.add('lazy');
|
imageLoader.setLazyImage(detailLogo, url);
|
||||||
detailLogo.setAttribute('data-src', url);
|
|
||||||
imageLoader.lazyImage(detailLogo);
|
|
||||||
} else {
|
} else {
|
||||||
detailLogo.classList.add('hide');
|
detailLogo.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
@ -704,172 +685,59 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderLinks(linksElem, item) {
|
function renderLinks(page, item) {
|
||||||
var html = [];
|
var externalLinksElem = page.querySelector('.itemExternalLinks');
|
||||||
|
|
||||||
var links = [];
|
var links = [];
|
||||||
|
|
||||||
if (!layoutManager.tv && item.HomePageUrl) {
|
if (!layoutManager.tv && item.HomePageUrl) {
|
||||||
links.push('<a style="color:inherit;" is="emby-linkbutton" class="button-link" href="' + item.HomePageUrl + '" target="_blank">' + globalize.translate('ButtonWebsite') + '</a>');
|
links.push(`<a is="emby-linkbutton" class="button-link" href="${item.HomePageUrl}" target="_blank">${globalize.translate('ButtonWebsite')}</a>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.ExternalUrls) {
|
if (item.ExternalUrls) {
|
||||||
for (var i = 0, length = item.ExternalUrls.length; i < length; i++) {
|
for (const url of item.ExternalUrls) {
|
||||||
var url = item.ExternalUrls[i];
|
links.push(`<a is="emby-linkbutton" class="button-link" href="${url.Url}" target="_blank">${url.Name}</a>`);
|
||||||
links.push('<a style="color:inherit;" is="emby-linkbutton" class="button-link" href="' + url.Url + '" target="_blank">' + url.Name + '</a>');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var html = [];
|
||||||
if (links.length) {
|
if (links.length) {
|
||||||
html.push(links.join(', '));
|
html.push(links.join(', '));
|
||||||
}
|
}
|
||||||
|
|
||||||
linksElem.innerHTML = html.join(', ');
|
externalLinksElem.innerHTML = html.join(', ');
|
||||||
|
|
||||||
if (html.length) {
|
if (html.length) {
|
||||||
linksElem.classList.remove('hide');
|
externalLinksElem.classList.remove('hide');
|
||||||
} else {
|
} else {
|
||||||
linksElem.classList.add('hide');
|
externalLinksElem.classList.add('hide');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderDetailImage(page, elem, item, apiClient, editable, imageLoader, indicators) {
|
function renderDetailImage(elem, item, imageLoader) {
|
||||||
if ('SeriesTimer' === item.Type || 'Program' === item.Type) {
|
const itemArray = [];
|
||||||
editable = false;
|
itemArray.push(item);
|
||||||
}
|
const cardHtml = cardBuilder.getCardsHtml(itemArray, {
|
||||||
|
shape: 'auto',
|
||||||
|
showTitle: false,
|
||||||
|
centerText: true,
|
||||||
|
overlayText: false,
|
||||||
|
transition: false,
|
||||||
|
disableIndicators: true,
|
||||||
|
disableHoverMenu: true,
|
||||||
|
overlayPlayButton: true,
|
||||||
|
width: dom.getWindowSize().innerWidth * 0.5
|
||||||
|
});
|
||||||
|
|
||||||
elem.classList.add('detailimg-hidemobile');
|
elem.innerHTML = cardHtml;
|
||||||
|
imageLoader.lazyChildren(elem);
|
||||||
var imageTags = item.ImageTags || {};
|
|
||||||
|
|
||||||
if (item.PrimaryImageTag) {
|
|
||||||
imageTags.Primary = item.PrimaryImageTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
var url;
|
|
||||||
var html = '';
|
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (editable && url === undefined) {
|
|
||||||
html += "<a class='itemDetailGalleryLink itemDetailImage defaultCardBackground defaultCardBackground" + cardBuilder.getDefaultBackgroundClass(item.Name) + "' is='emby-linkbutton' style='display:block;margin:0;padding:0;' href='#'>";
|
|
||||||
} else if (!editable && url === undefined) {
|
|
||||||
html += "<div class='itemDetailGalleryLink itemDetailImage defaultCardBackground defaultCardBackground" + cardBuilder.getDefaultBackgroundClass(item.Name) + "' is='emby-linkbutton' style='display:block;margin:0;padding:0;' href='#'>";
|
|
||||||
} else if (editable) {
|
|
||||||
html += "<a class='itemDetailGalleryLink' is='emby-linkbutton' style='display:block;margin:0;padding:0;' href='#'>";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
html += "<img class='itemDetailImage lazy' src='data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' />";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url === undefined) {
|
|
||||||
html += cardBuilder.getDefaultText(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (editable) {
|
|
||||||
html += '</a>';
|
|
||||||
} else if (!editable && url === undefined) {
|
|
||||||
html += '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
var progressHtml = item.IsFolder || !item.UserData ? '' : indicators.getProgressBarHtml(item);
|
|
||||||
html += '<div class="detailImageProgressContainer">';
|
|
||||||
|
|
||||||
if (progressHtml) {
|
|
||||||
html += progressHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '</div>';
|
|
||||||
elem.innerHTML = html;
|
|
||||||
|
|
||||||
if (detectRatio && item.PrimaryImageAspectRatio) {
|
|
||||||
if (item.PrimaryImageAspectRatio >= 1.48) {
|
|
||||||
shape = 'thumb';
|
|
||||||
} else if (item.PrimaryImageAspectRatio >= 0.85 && item.PrimaryImageAspectRatio <= 1.34) {
|
|
||||||
shape = 'square';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('thumb' == shape) {
|
|
||||||
elem.classList.add('thumbDetailImageContainer');
|
|
||||||
elem.classList.remove('portraitDetailImageContainer');
|
|
||||||
elem.classList.remove('squareDetailImageContainer');
|
|
||||||
} else if ('square' == shape) {
|
|
||||||
elem.classList.remove('thumbDetailImageContainer');
|
|
||||||
elem.classList.remove('portraitDetailImageContainer');
|
|
||||||
elem.classList.add('squareDetailImageContainer');
|
|
||||||
} else {
|
|
||||||
elem.classList.remove('thumbDetailImageContainer');
|
|
||||||
elem.classList.add('portraitDetailImageContainer');
|
|
||||||
elem.classList.remove('squareDetailImageContainer');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
imageLoader.lazyImage(elem.querySelector('img'), url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderImage(page, item, apiClient, user) {
|
function renderImage(page, item) {
|
||||||
renderDetailImage(
|
renderDetailImage(
|
||||||
page,
|
|
||||||
page.querySelector('.detailImageContainer'),
|
page.querySelector('.detailImageContainer'),
|
||||||
item,
|
item,
|
||||||
apiClient,
|
imageLoader
|
||||||
user.Policy.IsAdministrator && 'Photo' != item.MediaType,
|
|
||||||
imageLoader,
|
|
||||||
indicators
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,54 +853,41 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderOverview(elems, item) {
|
function renderOverview(page, item) {
|
||||||
for (var i = 0, length = elems.length; i < length; i++) {
|
for (const overviewElemnt of page.querySelectorAll('.overview')) {
|
||||||
var elem = elems[i];
|
|
||||||
var overview = item.Overview || '';
|
var overview = item.Overview || '';
|
||||||
|
|
||||||
if (overview) {
|
if (overview) {
|
||||||
elem.innerHTML = overview;
|
overviewElemnt.innerHTML = overview;
|
||||||
elem.classList.remove('hide');
|
overviewElemnt.classList.remove('hide');
|
||||||
elem.classList.add('detail-clamp-text');
|
overviewElemnt.classList.add('detail-clamp-text');
|
||||||
|
|
||||||
// Grab the sibling element to control the expand state
|
// Grab the sibling element to control the expand state
|
||||||
var expandButton = elem.parentElement.querySelector('.overview-expand');
|
var expandButton = overviewElemnt.parentElement.querySelector('.overview-expand');
|
||||||
|
|
||||||
// Detect if we have overflow of text. Based on this StackOverflow answer
|
// Detect if we have overflow of text. Based on this StackOverflow answer
|
||||||
// https://stackoverflow.com/a/35157976
|
// https://stackoverflow.com/a/35157976
|
||||||
if (Math.abs(elem.scrollHeight - elem.offsetHeight) > 2) {
|
if (Math.abs(overviewElemnt.scrollHeight - overviewElemnt.offsetHeight) > 2) {
|
||||||
expandButton.classList.remove('hide');
|
expandButton.classList.remove('hide');
|
||||||
} else {
|
} else {
|
||||||
expandButton.classList.add('hide');
|
expandButton.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
expandButton.addEventListener('click', toggleLineClamp.bind(null, elem));
|
expandButton.addEventListener('click', toggleLineClamp.bind(null, overviewElemnt));
|
||||||
|
|
||||||
var anchors = elem.querySelectorAll('a');
|
for (const anchor of overviewElemnt.querySelectorAll('a')) {
|
||||||
|
anchor.setAttribute('target', '_blank');
|
||||||
for (var j = 0, length2 = anchors.length; j < length2; j++) {
|
|
||||||
anchors[j].setAttribute('target', '_blank');
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
elem.innerHTML = '';
|
overviewElemnt.innerHTML = '';
|
||||||
elem.classList.add('hide');
|
overviewElemnt.classList.add('hide');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderGenres(page, item, context) {
|
function renderGenres(page, item, context = inferContext(item)) {
|
||||||
context = context || inferContext(item);
|
|
||||||
var type;
|
|
||||||
var genres = item.GenreItems || [];
|
var genres = item.GenreItems || [];
|
||||||
|
var type = context === 'music' ? 'MusicGenre' : 'Genre';
|
||||||
switch (context) {
|
|
||||||
case 'music':
|
|
||||||
type = 'MusicGenre';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
type = 'Genre';
|
|
||||||
}
|
|
||||||
|
|
||||||
var html = genres.map(function (p) {
|
var html = genres.map(function (p) {
|
||||||
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
|
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
|
||||||
|
@ -1058,19 +913,49 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderDirector(page, item, context) {
|
function renderWriter(page, item, context) {
|
||||||
var directors = (item.People || []).filter(function (p) {
|
var writers = (item.People || []).filter(function (person) {
|
||||||
return 'Director' === p.Type;
|
return person.Type === 'Writer';
|
||||||
});
|
});
|
||||||
var html = directors.map(function (p) {
|
|
||||||
|
var html = writers.map(function (person) {
|
||||||
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
|
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
|
||||||
Name: p.Name,
|
Name: person.Name,
|
||||||
Type: 'Person',
|
Type: 'Person',
|
||||||
ServerId: item.ServerId,
|
ServerId: item.ServerId,
|
||||||
Id: p.Id
|
Id: person.Id
|
||||||
}, {
|
}, {
|
||||||
context: context
|
context: context
|
||||||
}) + '">' + p.Name + '</a>';
|
}) + '">' + person.Name + '</a>';
|
||||||
|
}).join(', ');
|
||||||
|
|
||||||
|
var writersLabel = page.querySelector('.writersLabel');
|
||||||
|
writersLabel.innerHTML = globalize.translate(writers.length > 1 ? 'Writers' : 'Writer');
|
||||||
|
var writersValue = page.querySelector('.writers');
|
||||||
|
writersValue.innerHTML = html;
|
||||||
|
|
||||||
|
var writersGroup = page.querySelector('.writersGroup');
|
||||||
|
if (writers.length) {
|
||||||
|
writersGroup.classList.remove('hide');
|
||||||
|
} else {
|
||||||
|
writersGroup.classList.add('hide');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDirector(page, item, context) {
|
||||||
|
var directors = (item.People || []).filter(function (person) {
|
||||||
|
return person.Type === 'Director';
|
||||||
|
});
|
||||||
|
|
||||||
|
var html = directors.map(function (person) {
|
||||||
|
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
|
||||||
|
Name: person.Name,
|
||||||
|
Type: 'Person',
|
||||||
|
ServerId: item.ServerId,
|
||||||
|
Id: person.Id
|
||||||
|
}, {
|
||||||
|
context: context
|
||||||
|
}) + '">' + person.Name + '</a>';
|
||||||
}).join(', ');
|
}).join(', ');
|
||||||
|
|
||||||
var directorsLabel = page.querySelector('.directorsLabel');
|
var directorsLabel = page.querySelector('.directorsLabel');
|
||||||
|
@ -1086,13 +971,39 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderDetails(page, item, apiClient, context, isStatic) {
|
function renderMiscInfo(page, item) {
|
||||||
renderSimilarItems(page, item, context);
|
const primaryItemMiscInfo = page.querySelectorAll('.itemMiscInfo-primary');
|
||||||
renderMoreFromSeason(page, item, apiClient);
|
|
||||||
renderMoreFromArtist(page, item, apiClient);
|
for (const miscInfo of primaryItemMiscInfo) {
|
||||||
renderDirector(page, item, context);
|
mediaInfo.fillPrimaryMediaInfo(miscInfo, item, {
|
||||||
renderGenres(page, item, context);
|
interactive: true,
|
||||||
renderChannelGuide(page, apiClient, item);
|
episodeTitle: false,
|
||||||
|
subtitles: false
|
||||||
|
});
|
||||||
|
|
||||||
|
if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) {
|
||||||
|
miscInfo.classList.remove('hide');
|
||||||
|
} else {
|
||||||
|
miscInfo.classList.add('hide');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const secondaryItemMiscInfo = page.querySelectorAll('.itemMiscInfo-secondary');
|
||||||
|
|
||||||
|
for (const miscInfo of secondaryItemMiscInfo) {
|
||||||
|
mediaInfo.fillSecondaryMediaInfo(miscInfo, item, {
|
||||||
|
interactive: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) {
|
||||||
|
miscInfo.classList.remove('hide');
|
||||||
|
} else {
|
||||||
|
miscInfo.classList.add('hide');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTagline(page, item) {
|
||||||
var taglineElement = page.querySelector('.tagline');
|
var taglineElement = page.querySelector('.tagline');
|
||||||
|
|
||||||
if (item.Taglines && item.Taglines.length) {
|
if (item.Taglines && item.Taglines.length) {
|
||||||
|
@ -1101,44 +1012,21 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
} else {
|
} else {
|
||||||
taglineElement.classList.add('hide');
|
taglineElement.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var overview = page.querySelector('.overview');
|
function renderDetails(page, item, apiClient, context, isStatic) {
|
||||||
var externalLinksElem = page.querySelector('.itemExternalLinks');
|
renderSimilarItems(page, item, context);
|
||||||
|
renderMoreFromSeason(page, item, apiClient);
|
||||||
renderOverview([overview], item);
|
renderMoreFromArtist(page, item, apiClient);
|
||||||
|
renderDirector(page, item, context);
|
||||||
var i;
|
renderWriter(page, item, context);
|
||||||
var itemMiscInfo;
|
renderGenres(page, item, context);
|
||||||
itemMiscInfo = page.querySelectorAll('.itemMiscInfo-primary');
|
renderChannelGuide(page, apiClient, item);
|
||||||
for (i = 0; i < itemMiscInfo.length; i++) {
|
renderTagline(page, item);
|
||||||
mediaInfo.fillPrimaryMediaInfo(itemMiscInfo[i], item, {
|
renderOverview(page, item);
|
||||||
interactive: true,
|
renderMiscInfo(page, item);
|
||||||
episodeTitle: false,
|
|
||||||
subtitles: false
|
|
||||||
});
|
|
||||||
|
|
||||||
if (itemMiscInfo[i].innerHTML && 'SeriesTimer' !== item.Type) {
|
|
||||||
itemMiscInfo[i].classList.remove('hide');
|
|
||||||
} else {
|
|
||||||
itemMiscInfo[i].classList.add('hide');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
itemMiscInfo = page.querySelectorAll('.itemMiscInfo-secondary');
|
|
||||||
for (i = 0; i < itemMiscInfo.length; i++) {
|
|
||||||
mediaInfo.fillSecondaryMediaInfo(itemMiscInfo[i], item, {
|
|
||||||
interactive: true
|
|
||||||
});
|
|
||||||
|
|
||||||
if (itemMiscInfo[i].innerHTML && 'SeriesTimer' !== item.Type) {
|
|
||||||
itemMiscInfo[i].classList.remove('hide');
|
|
||||||
} else {
|
|
||||||
itemMiscInfo[i].classList.add('hide');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadUserDataButtons(page, item);
|
reloadUserDataButtons(page, item);
|
||||||
renderLinks(externalLinksElem, item);
|
renderLinks(page, item);
|
||||||
renderTags(page, item);
|
renderTags(page, item);
|
||||||
renderSeriesAirTime(page, item, isStatic);
|
renderSeriesAirTime(page, item, isStatic);
|
||||||
}
|
}
|
||||||
|
@ -1426,8 +1314,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
action: 'playallfromhere',
|
action: 'playallfromhere',
|
||||||
image: false,
|
image: false,
|
||||||
artist: 'auto',
|
artist: 'auto',
|
||||||
containerAlbumArtists: item.AlbumArtists,
|
containerAlbumArtists: item.AlbumArtists
|
||||||
addToListButton: true
|
|
||||||
});
|
});
|
||||||
isList = true;
|
isList = true;
|
||||||
} else if ('Series' == item.Type) {
|
} else if ('Series' == item.Type) {
|
||||||
|
@ -1469,11 +1356,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
items: result.Items,
|
items: result.Items,
|
||||||
showIndexNumber: false,
|
showIndexNumber: false,
|
||||||
enableOverview: true,
|
enableOverview: true,
|
||||||
|
enablePlayedButton: layoutManager.mobile ? false : true,
|
||||||
|
infoButton: layoutManager.mobile ? false : true,
|
||||||
imageSize: 'large',
|
imageSize: 'large',
|
||||||
enableSideMediaInfo: false,
|
enableSideMediaInfo: false,
|
||||||
highlight: false,
|
highlight: false,
|
||||||
action: layoutManager.tv ? 'resume' : 'none',
|
action: !layoutManager.desktop ? 'link' : 'none',
|
||||||
infoButton: true,
|
|
||||||
imagePlayButton: true,
|
imagePlayButton: true,
|
||||||
includeParentInfoInTitle: false
|
includeParentInfoInTitle: false
|
||||||
});
|
});
|
||||||
|
@ -1500,6 +1388,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
childrenItemsContainer.classList.remove('vertical-list');
|
childrenItemsContainer.classList.remove('vertical-list');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (layoutManager.mobile) {
|
||||||
|
childrenItemsContainer.classList.remove('padded-right');
|
||||||
|
}
|
||||||
childrenItemsContainer.innerHTML = html;
|
childrenItemsContainer.innerHTML = html;
|
||||||
imageLoader.lazyChildren(childrenItemsContainer);
|
imageLoader.lazyChildren(childrenItemsContainer);
|
||||||
if ('BoxSet' == item.Type) {
|
if ('BoxSet' == item.Type) {
|
||||||
|
@ -1701,12 +1592,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCollectionItems(page, parentItem, types, items) {
|
function renderCollectionItems(page, parentItem, types, items) {
|
||||||
|
page.querySelector('.collectionItems').classList.remove('hide');
|
||||||
page.querySelector('.collectionItems').innerHTML = '';
|
page.querySelector('.collectionItems').innerHTML = '';
|
||||||
var i;
|
|
||||||
var length;
|
|
||||||
|
|
||||||
for (i = 0, length = types.length; i < length; i++) {
|
for (const type of types) {
|
||||||
var type = types[i];
|
|
||||||
var typeItems = filterItemsByCollectionItemType(items, type);
|
var typeItems = filterItemsByCollectionItemType(items, type);
|
||||||
|
|
||||||
if (typeItems.length) {
|
if (typeItems.length) {
|
||||||
|
@ -1739,8 +1628,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
renderChildren(page, parentItem);
|
renderChildren(page, parentItem);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i = 0, length = containers.length; i < length; i++) {
|
for (const container of containers) {
|
||||||
containers[i].notifyRefreshNeeded = notifyRefreshNeeded;
|
container.notifyRefreshNeeded = notifyRefreshNeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if nothing in the collection can be played hide play and shuffle buttons
|
// if nothing in the collection can be played hide play and shuffle buttons
|
||||||
|
@ -1876,7 +1765,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
|
|
||||||
function renderCast(page, item) {
|
function renderCast(page, item) {
|
||||||
var people = (item.People || []).filter(function (p) {
|
var people = (item.People || []).filter(function (p) {
|
||||||
return 'Director' !== p.Type;
|
return p.Type === 'Actor';
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!people.length) {
|
if (!people.length) {
|
||||||
|
@ -1905,12 +1794,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindAll(view, selector, eventName, fn) {
|
function bindAll(view, selector, eventName, fn) {
|
||||||
var i;
|
|
||||||
var length;
|
|
||||||
var elems = view.querySelectorAll(selector);
|
var elems = view.querySelectorAll(selector);
|
||||||
|
|
||||||
for (i = 0, length = elems.length; i < length; i++) {
|
for (const elem of elems) {
|
||||||
elems[i].addEventListener(eventName, fn);
|
elem.addEventListener(eventName, fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1923,13 +1810,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
return function (view, params) {
|
return function (view, params) {
|
||||||
function reload(instance, page, params) {
|
function reload(instance, page, params) {
|
||||||
loading.show();
|
loading.show();
|
||||||
|
|
||||||
var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient;
|
var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient;
|
||||||
var promises = [getPromise(apiClient, params), apiClient.getCurrentUser()];
|
|
||||||
Promise.all(promises).then(function (responses) {
|
Promise.all([getPromise(apiClient, params), apiClient.getCurrentUser()]).then(([item, user]) => {
|
||||||
var item = responses[0];
|
|
||||||
var user = responses[1];
|
|
||||||
currentItem = item;
|
currentItem = item;
|
||||||
reloadFromItem(instance, page, params, item, user);
|
reloadFromItem(instance, page, params, item, user);
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error('failed to get item or current user: ', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1980,7 +1868,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
playItem(item, item.UserData && 'resume' === mode ? item.UserData.PlaybackPositionTicks : 0);
|
playItem(item, item.UserData && mode === 'resume' ? item.UserData.PlaybackPositionTicks : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPlayClick() {
|
function onPlayClick() {
|
||||||
|
@ -1995,15 +1883,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
playbackManager.shuffle(currentItem);
|
playbackManager.shuffle(currentItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDeleteClick() {
|
|
||||||
require(['deleteHelper'], function (deleteHelper) {
|
|
||||||
deleteHelper.deleteItem({
|
|
||||||
item: currentItem,
|
|
||||||
navigate: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCancelSeriesTimerClick() {
|
function onCancelSeriesTimerClick() {
|
||||||
require(['recordingHelper'], function (recordingHelper) {
|
require(['recordingHelper'], function (recordingHelper) {
|
||||||
recordingHelper.cancelSeriesTimerWithConfirmation(currentItem.Id, currentItem.ServerId).then(function () {
|
recordingHelper.cancelSeriesTimerWithConfirmation(currentItem.Id, currentItem.ServerId).then(function () {
|
||||||
|
@ -2092,7 +1971,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
bindAll(view, '.btnPlayTrailer', 'click', onPlayTrailerClick);
|
bindAll(view, '.btnPlayTrailer', 'click', onPlayTrailerClick);
|
||||||
bindAll(view, '.btnCancelSeriesTimer', 'click', onCancelSeriesTimerClick);
|
bindAll(view, '.btnCancelSeriesTimer', 'click', onCancelSeriesTimerClick);
|
||||||
bindAll(view, '.btnCancelTimer', 'click', onCancelTimerClick);
|
bindAll(view, '.btnCancelTimer', 'click', onCancelTimerClick);
|
||||||
bindAll(view, '.btnDeleteItem', 'click', onDeleteClick);
|
|
||||||
bindAll(view, '.btnDownload', 'click', onDownloadClick);
|
bindAll(view, '.btnDownload', 'click', onDownloadClick);
|
||||||
view.querySelector('.trackSelections').addEventListener('submit', onTrackSelectionsSubmit);
|
view.querySelector('.trackSelections').addEventListener('submit', onTrackSelectionsSubmit);
|
||||||
view.querySelector('.btnSplitVersions').addEventListener('click', function () {
|
view.querySelector('.btnSplitVersions').addEventListener('click', function () {
|
||||||
|
@ -2125,9 +2003,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
|
||||||
view.addEventListener('viewshow', function (e) {
|
view.addEventListener('viewshow', function (e) {
|
||||||
var page = this;
|
var page = this;
|
||||||
|
|
||||||
if (layoutManager.mobile) {
|
libraryMenu.setTransparentMenu(true);
|
||||||
libraryMenu.setTransparentMenu(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.detail.isRestored) {
|
if (e.detail.isRestored) {
|
||||||
if (currentItem) {
|
if (currentItem) {
|
|
@ -1,22 +1,22 @@
|
||||||
define(['components/remotecontrol/remotecontrol', 'libraryMenu', 'emby-button'], function (remotecontrolFactory, libraryMenu) {
|
import remotecontrolFactory from 'components/remotecontrol/remotecontrol';
|
||||||
'use strict';
|
import libraryMenu from 'libraryMenu';
|
||||||
|
import 'emby-button';
|
||||||
|
|
||||||
return function (view, params) {
|
export default function (view, params) {
|
||||||
var remoteControl = new remotecontrolFactory();
|
const remoteControl = new remotecontrolFactory();
|
||||||
remoteControl.init(view, view.querySelector('.remoteControlContent'));
|
remoteControl.init(view, view.querySelector('.remoteControlContent'));
|
||||||
view.addEventListener('viewshow', function (e) {
|
view.addEventListener('viewshow', function (e) {
|
||||||
libraryMenu.setTransparentMenu(true);
|
libraryMenu.setTransparentMenu(true);
|
||||||
|
|
||||||
if (remoteControl) {
|
if (remoteControl) {
|
||||||
remoteControl.onShow();
|
remoteControl.onShow();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
view.addEventListener('viewbeforehide', function (e) {
|
view.addEventListener('viewbeforehide', function (e) {
|
||||||
libraryMenu.setTransparentMenu(false);
|
libraryMenu.setTransparentMenu(false);
|
||||||
|
|
||||||
if (remoteControl) {
|
if (remoteControl) {
|
||||||
remoteControl.destroy();
|
remoteControl.destroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
});
|
|
||||||
|
|
|
@ -1,5 +1,26 @@
|
||||||
define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'mediaInfo', 'focusManager', 'imageLoader', 'scrollHelper', 'events', 'connectionManager', 'browser', 'globalize', 'apphost', 'layoutManager', 'userSettings', 'keyboardnavigation', 'scrollStyles', 'emby-slider', 'paper-icon-button-light', 'css!assets/css/videoosd'], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings, keyboardnavigation) {
|
import playbackManager from 'playbackManager';
|
||||||
'use strict';
|
import dom from 'dom';
|
||||||
|
import inputManager from 'inputManager';
|
||||||
|
import datetime from 'datetime';
|
||||||
|
import itemHelper from 'itemHelper';
|
||||||
|
import mediaInfo from 'mediaInfo';
|
||||||
|
import focusManager from 'focusManager';
|
||||||
|
import imageLoader from 'imageLoader';
|
||||||
|
import scrollHelper from 'scrollHelper';
|
||||||
|
import events from 'events';
|
||||||
|
import connectionManager from 'connectionManager';
|
||||||
|
import browser from 'browser';
|
||||||
|
import globalize from 'globalize';
|
||||||
|
import appHost from 'apphost';
|
||||||
|
import layoutManager from 'layoutManager';
|
||||||
|
import * as userSettings from 'userSettings';
|
||||||
|
import keyboardnavigation from 'keyboardnavigation';
|
||||||
|
import 'scrollStyles';
|
||||||
|
import 'emby-slider';
|
||||||
|
import 'paper-icon-button-light';
|
||||||
|
import 'css!assets/css/videoosd';
|
||||||
|
|
||||||
|
/* eslint-disable indent */
|
||||||
|
|
||||||
function seriesImageUrl(item, options) {
|
function seriesImageUrl(item, options) {
|
||||||
if ('Episode' !== item.Type) {
|
if ('Episode' !== item.Type) {
|
||||||
|
@ -45,13 +66,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return function (view, params) {
|
export default function (view, params) {
|
||||||
function onVerticalSwipe(e, elem, data) {
|
function onVerticalSwipe(e, elem, data) {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
|
|
||||||
if (player) {
|
if (player) {
|
||||||
var deltaY = data.currentDeltaY;
|
const deltaY = data.currentDeltaY;
|
||||||
var windowSize = dom.getWindowSize();
|
const windowSize = dom.getWindowSize();
|
||||||
|
|
||||||
if (supportsBrightnessChange && data.clientX < windowSize.innerWidth / 2) {
|
if (supportsBrightnessChange && data.clientX < windowSize.innerWidth / 2) {
|
||||||
return void doBrightnessTouch(deltaY, player, windowSize.innerHeight);
|
return void doBrightnessTouch(deltaY, player, windowSize.innerHeight);
|
||||||
|
@ -62,23 +83,23 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function doBrightnessTouch(deltaY, player, viewHeight) {
|
function doBrightnessTouch(deltaY, player, viewHeight) {
|
||||||
var delta = -deltaY / viewHeight * 100;
|
const delta = -deltaY / viewHeight * 100;
|
||||||
var newValue = playbackManager.getBrightness(player) + delta;
|
let newValue = playbackManager.getBrightness(player) + delta;
|
||||||
newValue = Math.min(newValue, 100);
|
newValue = Math.min(newValue, 100);
|
||||||
newValue = Math.max(newValue, 0);
|
newValue = Math.max(newValue, 0);
|
||||||
playbackManager.setBrightness(newValue, player);
|
playbackManager.setBrightness(newValue, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
function doVolumeTouch(deltaY, player, viewHeight) {
|
function doVolumeTouch(deltaY, player, viewHeight) {
|
||||||
var delta = -deltaY / viewHeight * 100;
|
const delta = -deltaY / viewHeight * 100;
|
||||||
var newValue = playbackManager.getVolume(player) + delta;
|
let newValue = playbackManager.getVolume(player) + delta;
|
||||||
newValue = Math.min(newValue, 100);
|
newValue = Math.min(newValue, 100);
|
||||||
newValue = Math.max(newValue, 0);
|
newValue = Math.max(newValue, 0);
|
||||||
playbackManager.setVolume(newValue, player);
|
playbackManager.setVolume(newValue, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDoubleClick(e) {
|
function onDoubleClick(e) {
|
||||||
var clientX = e.clientX;
|
const clientX = e.clientX;
|
||||||
|
|
||||||
if (null != clientX) {
|
if (null != clientX) {
|
||||||
if (clientX < dom.getWindowSize().innerWidth / 2) {
|
if (clientX < dom.getWindowSize().innerWidth / 2) {
|
||||||
|
@ -94,7 +115,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
function getDisplayItem(item) {
|
function getDisplayItem(item) {
|
||||||
if ('TvChannel' === item.Type) {
|
if ('TvChannel' === item.Type) {
|
||||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
const apiClient = connectionManager.getApiClient(item.ServerId);
|
||||||
return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (refreshedItem) {
|
return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (refreshedItem) {
|
||||||
return {
|
return {
|
||||||
originalItem: refreshedItem,
|
originalItem: refreshedItem,
|
||||||
|
@ -120,7 +141,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function (user) {
|
connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function (user) {
|
||||||
if (user.Policy.EnableLiveTvManagement) {
|
if (user.Policy.EnableLiveTvManagement) {
|
||||||
require(['recordingButton'], function (RecordingButton) {
|
import('recordingButton').then(({default: RecordingButton}) => {
|
||||||
if (recordingButtonManager) {
|
if (recordingButtonManager) {
|
||||||
return void recordingButtonManager.refreshItem(item);
|
return void recordingButtonManager.refreshItem(item);
|
||||||
}
|
}
|
||||||
|
@ -136,22 +157,22 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDisplayItem(itemInfo) {
|
function updateDisplayItem(itemInfo) {
|
||||||
var item = itemInfo.originalItem;
|
const item = itemInfo.originalItem;
|
||||||
currentItem = item;
|
currentItem = item;
|
||||||
var displayItem = itemInfo.displayItem || item;
|
const displayItem = itemInfo.displayItem || item;
|
||||||
updateRecordingButton(displayItem);
|
updateRecordingButton(displayItem);
|
||||||
setPoster(displayItem, item);
|
setPoster(displayItem, item);
|
||||||
var parentName = displayItem.SeriesName || displayItem.Album;
|
let parentName = displayItem.SeriesName || displayItem.Album;
|
||||||
|
|
||||||
if (displayItem.EpisodeTitle || displayItem.IsSeries) {
|
if (displayItem.EpisodeTitle || displayItem.IsSeries) {
|
||||||
parentName = displayItem.Name;
|
parentName = displayItem.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTitle(displayItem, parentName);
|
setTitle(displayItem, parentName);
|
||||||
var titleElement;
|
let titleElement;
|
||||||
var osdTitle = view.querySelector('.osdTitle');
|
const osdTitle = view.querySelector('.osdTitle');
|
||||||
titleElement = osdTitle;
|
titleElement = osdTitle;
|
||||||
var displayName = itemHelper.getDisplayName(displayItem, {
|
let displayName = itemHelper.getDisplayName(displayItem, {
|
||||||
includeParentInfo: 'Program' !== displayItem.Type,
|
includeParentInfo: 'Program' !== displayItem.Type,
|
||||||
includeIndexNumber: 'Program' !== displayItem.Type
|
includeIndexNumber: 'Program' !== displayItem.Type
|
||||||
});
|
});
|
||||||
|
@ -168,7 +189,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
titleElement.classList.add('hide');
|
titleElement.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, {
|
const mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, {
|
||||||
runtime: false,
|
runtime: false,
|
||||||
subtitles: false,
|
subtitles: false,
|
||||||
tomatoes: false,
|
tomatoes: false,
|
||||||
|
@ -178,7 +199,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
episodeTitleIndexNumber: 'Program' !== displayItem.Type,
|
episodeTitleIndexNumber: 'Program' !== displayItem.Type,
|
||||||
programIndicator: false
|
programIndicator: false
|
||||||
});
|
});
|
||||||
var osdMediaInfo = view.querySelector('.osdMediaInfo');
|
const osdMediaInfo = view.querySelector('.osdMediaInfo');
|
||||||
osdMediaInfo.innerHTML = mediaInfoHtml;
|
osdMediaInfo.innerHTML = mediaInfoHtml;
|
||||||
|
|
||||||
if (mediaInfoHtml) {
|
if (mediaInfoHtml) {
|
||||||
|
@ -187,8 +208,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
osdMediaInfo.classList.add('hide');
|
osdMediaInfo.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
var secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo');
|
const secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo');
|
||||||
var secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, {
|
const secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, {
|
||||||
startDate: false,
|
startDate: false,
|
||||||
programTime: false
|
programTime: false
|
||||||
});
|
});
|
||||||
|
@ -236,7 +257,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDisplayTime(elem, date) {
|
function setDisplayTime(elem, date) {
|
||||||
var html;
|
let html;
|
||||||
|
|
||||||
if (date) {
|
if (date) {
|
||||||
date = datetime.parseISO8601Date(date);
|
date = datetime.parseISO8601Date(date);
|
||||||
|
@ -251,7 +272,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNowPlayingInfo(player, state) {
|
function updateNowPlayingInfo(player, state) {
|
||||||
var item = state.NowPlayingItem;
|
const item = state.NowPlayingItem;
|
||||||
|
|
||||||
currentItem = item;
|
currentItem = item;
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
@ -294,7 +315,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
function setTitle(item, parentName) {
|
function setTitle(item, parentName) {
|
||||||
Emby.Page.setTitle(parentName || '');
|
Emby.Page.setTitle(parentName || '');
|
||||||
|
|
||||||
var documentTitle = parentName || (item ? item.Name : null);
|
const documentTitle = parentName || (item ? item.Name : null);
|
||||||
|
|
||||||
if (documentTitle) {
|
if (documentTitle) {
|
||||||
document.title = documentTitle;
|
document.title = documentTitle;
|
||||||
|
@ -302,10 +323,10 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPoster(item, secondaryItem) {
|
function setPoster(item, secondaryItem) {
|
||||||
var osdPoster = view.querySelector('.osdPoster');
|
const osdPoster = view.querySelector('.osdPoster');
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
var imgUrl = seriesImageUrl(item, {
|
let imgUrl = seriesImageUrl(item, {
|
||||||
maxWidth: osdPoster.clientWidth * 2,
|
maxWidth: osdPoster.clientWidth * 2,
|
||||||
type: 'Primary'
|
type: 'Primary'
|
||||||
}) || seriesImageUrl(item, {
|
}) || seriesImageUrl(item, {
|
||||||
|
@ -333,13 +354,21 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
osdPoster.innerHTML = '';
|
osdPoster.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let osdLockCount = 0;
|
||||||
|
|
||||||
function showOsd() {
|
function showOsd() {
|
||||||
slideDownToShow(headerElement);
|
slideDownToShow(headerElement);
|
||||||
showMainOsdControls();
|
showMainOsdControls();
|
||||||
startOsdHideTimer();
|
if (!osdLockCount) {
|
||||||
|
startOsdHideTimer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideOsd() {
|
function hideOsd() {
|
||||||
|
if (osdLockCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
slideUpToHide(headerElement);
|
slideUpToHide(headerElement);
|
||||||
hideMainOsdControls();
|
hideMainOsdControls();
|
||||||
}
|
}
|
||||||
|
@ -352,6 +381,19 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function lockOsd() {
|
||||||
|
osdLockCount++;
|
||||||
|
stopOsdHideTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
function unlockOsd() {
|
||||||
|
osdLockCount--;
|
||||||
|
// Restart hide timer if OSD is currently visible
|
||||||
|
if (currentVisibleMenu && !osdLockCount) {
|
||||||
|
startOsdHideTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function startOsdHideTimer() {
|
function startOsdHideTimer() {
|
||||||
stopOsdHideTimer();
|
stopOsdHideTimer();
|
||||||
osdHideTimeout = setTimeout(hideOsd, 3e3);
|
osdHideTimeout = setTimeout(hideOsd, 3e3);
|
||||||
|
@ -379,7 +421,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function onHideAnimationComplete(e) {
|
function onHideAnimationComplete(e) {
|
||||||
var elem = e.target;
|
const elem = e.target;
|
||||||
if (elem != osdBottomElement)
|
if (elem != osdBottomElement)
|
||||||
return;
|
return;
|
||||||
elem.classList.add('hide');
|
elem.classList.add('hide');
|
||||||
|
@ -390,7 +432,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
function showMainOsdControls() {
|
function showMainOsdControls() {
|
||||||
if (!currentVisibleMenu) {
|
if (!currentVisibleMenu) {
|
||||||
var elem = osdBottomElement;
|
const elem = osdBottomElement;
|
||||||
currentVisibleMenu = 'osd';
|
currentVisibleMenu = 'osd';
|
||||||
clearHideAnimationEventListeners(elem);
|
clearHideAnimationEventListeners(elem);
|
||||||
elem.classList.remove('hide');
|
elem.classList.remove('hide');
|
||||||
|
@ -407,7 +449,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
function hideMainOsdControls() {
|
function hideMainOsdControls() {
|
||||||
if ('osd' === currentVisibleMenu) {
|
if ('osd' === currentVisibleMenu) {
|
||||||
var elem = osdBottomElement;
|
const elem = osdBottomElement;
|
||||||
clearHideAnimationEventListeners(elem);
|
clearHideAnimationEventListeners(elem);
|
||||||
elem.classList.add('videoOsdBottom-hidden');
|
elem.classList.add('videoOsdBottom-hidden');
|
||||||
dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, {
|
||||||
|
@ -425,9 +467,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
function onPointerMove(e) {
|
function onPointerMove(e) {
|
||||||
if ('mouse' === (e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'))) {
|
if ('mouse' === (e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'))) {
|
||||||
var eventX = e.screenX || 0;
|
const eventX = e.screenX || 0;
|
||||||
var eventY = e.screenY || 0;
|
const eventY = e.screenY || 0;
|
||||||
var obj = lastPointerMoveData;
|
const obj = lastPointerMoveData;
|
||||||
|
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
lastPointerMoveData = {
|
lastPointerMoveData = {
|
||||||
|
@ -448,7 +490,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInputCommand(e) {
|
function onInputCommand(e) {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
|
|
||||||
switch (e.detail.command) {
|
switch (e.detail.command) {
|
||||||
case 'left':
|
case 'left':
|
||||||
|
@ -507,7 +549,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRecordingCommand() {
|
function onRecordingCommand() {
|
||||||
var btnRecord = view.querySelector('.btnRecord');
|
const btnRecord = view.querySelector('.btnRecord');
|
||||||
|
|
||||||
if (!btnRecord.classList.contains('hide')) {
|
if (!btnRecord.classList.contains('hide')) {
|
||||||
btnRecord.click();
|
btnRecord.click();
|
||||||
|
@ -534,7 +576,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStateChanged(event, state) {
|
function onStateChanged(event, state) {
|
||||||
var player = this;
|
const player = this;
|
||||||
|
|
||||||
if (state.NowPlayingItem) {
|
if (state.NowPlayingItem) {
|
||||||
isEnabled = true;
|
isEnabled = true;
|
||||||
|
@ -552,21 +594,21 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
function onVolumeChanged(e) {
|
function onVolumeChanged(e) {
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
var player = this;
|
const player = this;
|
||||||
updatePlayerVolumeState(player, player.isMuted(), player.getVolume());
|
updatePlayerVolumeState(player, player.isMuted(), player.getVolume());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPlaybackStart(e, state) {
|
function onPlaybackStart(e, state) {
|
||||||
console.debug('nowplaying event: ' + e.type);
|
console.debug('nowplaying event: ' + e.type);
|
||||||
var player = this;
|
const player = this;
|
||||||
onStateChanged.call(player, e, state);
|
onStateChanged.call(player, e, state);
|
||||||
resetUpNextDialog();
|
resetUpNextDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetUpNextDialog() {
|
function resetUpNextDialog() {
|
||||||
comingUpNextDisplayed = false;
|
comingUpNextDisplayed = false;
|
||||||
var dlg = currentUpNextDialog;
|
const dlg = currentUpNextDialog;
|
||||||
|
|
||||||
if (dlg) {
|
if (dlg) {
|
||||||
dlg.destroy();
|
dlg.destroy();
|
||||||
|
@ -586,8 +628,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMediaStreamsChanged(e) {
|
function onMediaStreamsChanged(e) {
|
||||||
var player = this;
|
const player = this;
|
||||||
var state = playbackManager.getPlayerState(player);
|
const state = playbackManager.getPlayerState(player);
|
||||||
onStateChanged.call(player, {
|
onStateChanged.call(player, {
|
||||||
type: 'init'
|
type: 'init'
|
||||||
}, state);
|
}, state);
|
||||||
|
@ -607,7 +649,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
currentPlayer = player;
|
currentPlayer = player;
|
||||||
if (!player) return;
|
if (!player) return;
|
||||||
}
|
}
|
||||||
var state = playbackManager.getPlayerState(player);
|
const state = playbackManager.getPlayerState(player);
|
||||||
onStateChanged.call(player, {
|
onStateChanged.call(player, {
|
||||||
type: 'init'
|
type: 'init'
|
||||||
}, state);
|
}, state);
|
||||||
|
@ -632,7 +674,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
destroyStats();
|
destroyStats();
|
||||||
destroySubtitleSync();
|
destroySubtitleSync();
|
||||||
resetUpNextDialog();
|
resetUpNextDialog();
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
|
|
||||||
if (player) {
|
if (player) {
|
||||||
events.off(player, 'playbackstart', onPlaybackStart);
|
events.off(player, 'playbackstart', onPlaybackStart);
|
||||||
|
@ -650,15 +692,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
function onTimeUpdate(e) {
|
function onTimeUpdate(e) {
|
||||||
// Test for 'currentItem' is required for Firefox since its player spams 'timeupdate' events even being at breakpoint
|
// Test for 'currentItem' is required for Firefox since its player spams 'timeupdate' events even being at breakpoint
|
||||||
if (isEnabled && currentItem) {
|
if (isEnabled && currentItem) {
|
||||||
var now = new Date().getTime();
|
const now = new Date().getTime();
|
||||||
|
|
||||||
if (!(now - lastUpdateTime < 700)) {
|
if (!(now - lastUpdateTime < 700)) {
|
||||||
lastUpdateTime = now;
|
lastUpdateTime = now;
|
||||||
var player = this;
|
const player = this;
|
||||||
currentRuntimeTicks = playbackManager.duration(player);
|
currentRuntimeTicks = playbackManager.duration(player);
|
||||||
var currentTime = playbackManager.currentTime(player);
|
const currentTime = playbackManager.currentTime(player);
|
||||||
updateTimeDisplay(currentTime, currentRuntimeTicks, playbackManager.playbackStartTime(player), playbackManager.getBufferedRanges(player));
|
updateTimeDisplay(currentTime, currentRuntimeTicks, playbackManager.playbackStartTime(player), playbackManager.getBufferedRanges(player));
|
||||||
var item = currentItem;
|
const item = currentItem;
|
||||||
refreshProgramInfoIfNeeded(player, item);
|
refreshProgramInfoIfNeeded(player, item);
|
||||||
showComingUpNextIfNeeded(player, item, currentTime, currentRuntimeTicks);
|
showComingUpNextIfNeeded(player, item, currentTime, currentRuntimeTicks);
|
||||||
}
|
}
|
||||||
|
@ -667,9 +709,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) {
|
function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) {
|
||||||
if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && 'Episode' === currentItem.Type && userSettings.enableNextVideoInfoOverlay()) {
|
if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && 'Episode' === currentItem.Type && userSettings.enableNextVideoInfoOverlay()) {
|
||||||
var showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30;
|
const showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30;
|
||||||
var showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4;
|
const showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4;
|
||||||
var timeRemainingTicks = runtimeTicks - currentTimeTicks;
|
const timeRemainingTicks = runtimeTicks - currentTimeTicks;
|
||||||
|
|
||||||
if (currentTimeTicks >= showAtTicks && runtimeTicks >= 6e9 && timeRemainingTicks >= 2e8) {
|
if (currentTimeTicks >= showAtTicks && runtimeTicks >= 6e9 && timeRemainingTicks >= 2e8) {
|
||||||
showComingUpNext(player);
|
showComingUpNext(player);
|
||||||
|
@ -684,7 +726,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function showComingUpNext(player) {
|
function showComingUpNext(player) {
|
||||||
require(['upNextDialog'], function (UpNextDialog) {
|
import('upNextDialog').then(({default: UpNextDialog}) => {
|
||||||
if (!(currentVisibleMenu || currentUpNextDialog)) {
|
if (!(currentVisibleMenu || currentUpNextDialog)) {
|
||||||
currentVisibleMenu = 'upnext';
|
currentVisibleMenu = 'upnext';
|
||||||
comingUpNextDisplayed = true;
|
comingUpNextDisplayed = true;
|
||||||
|
@ -702,15 +744,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
function refreshProgramInfoIfNeeded(player, item) {
|
function refreshProgramInfoIfNeeded(player, item) {
|
||||||
if ('TvChannel' === item.Type) {
|
if ('TvChannel' === item.Type) {
|
||||||
var program = item.CurrentProgram;
|
const program = item.CurrentProgram;
|
||||||
|
|
||||||
if (program && program.EndDate) {
|
if (program && program.EndDate) {
|
||||||
try {
|
try {
|
||||||
var endDate = datetime.parseISO8601Date(program.EndDate);
|
const endDate = datetime.parseISO8601Date(program.EndDate);
|
||||||
|
|
||||||
if (new Date().getTime() >= endDate.getTime()) {
|
if (new Date().getTime() >= endDate.getTime()) {
|
||||||
console.debug('program info needs to be refreshed');
|
console.debug('program info needs to be refreshed');
|
||||||
var state = playbackManager.getPlayerState(player);
|
const state = playbackManager.getPlayerState(player);
|
||||||
onStateChanged.call(player, {
|
onStateChanged.call(player, {
|
||||||
type: 'init'
|
type: 'init'
|
||||||
}, state);
|
}, state);
|
||||||
|
@ -738,9 +780,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePlayerStateInternal(event, player, state) {
|
function updatePlayerStateInternal(event, player, state) {
|
||||||
var playState = state.PlayState || {};
|
const playState = state.PlayState || {};
|
||||||
updatePlayPauseState(playState.IsPaused);
|
updatePlayPauseState(playState.IsPaused);
|
||||||
var supportedCommands = playbackManager.getSupportedCommands(player);
|
const supportedCommands = playbackManager.getSupportedCommands(player);
|
||||||
currentPlayerSupportedCommands = supportedCommands;
|
currentPlayerSupportedCommands = supportedCommands;
|
||||||
supportsBrightnessChange = -1 !== supportedCommands.indexOf('SetBrightness');
|
supportsBrightnessChange = -1 !== supportedCommands.indexOf('SetBrightness');
|
||||||
updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel);
|
updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel);
|
||||||
|
@ -751,7 +793,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
btnFastForward.disabled = !playState.CanSeek;
|
btnFastForward.disabled = !playState.CanSeek;
|
||||||
btnRewind.disabled = !playState.CanSeek;
|
btnRewind.disabled = !playState.CanSeek;
|
||||||
var nowPlayingItem = state.NowPlayingItem || {};
|
const nowPlayingItem = state.NowPlayingItem || {};
|
||||||
playbackStartTimeTicks = playState.PlaybackStartTimeTicks;
|
playbackStartTimeTicks = playState.PlaybackStartTimeTicks;
|
||||||
updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []);
|
updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []);
|
||||||
updateNowPlayingInfo(player, state);
|
updateNowPlayingInfo(player, state);
|
||||||
|
@ -762,7 +804,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
view.querySelector('.btnVideoOsdSettings').classList.add('hide');
|
view.querySelector('.btnVideoOsdSettings').classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
|
const isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
|
||||||
nowPlayingPositionSlider.setIsClear(isProgressClear);
|
nowPlayingPositionSlider.setIsClear(isProgressClear);
|
||||||
|
|
||||||
if (nowPlayingItem.RunTimeTicks) {
|
if (nowPlayingItem.RunTimeTicks) {
|
||||||
|
@ -799,12 +841,12 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
if (enableProgressByTimeOfDay) {
|
if (enableProgressByTimeOfDay) {
|
||||||
if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) {
|
if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) {
|
||||||
if (programStartDateMs && programEndDateMs) {
|
if (programStartDateMs && programEndDateMs) {
|
||||||
var currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4;
|
const currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4;
|
||||||
var programRuntimeMs = programEndDateMs - programStartDateMs;
|
const programRuntimeMs = programEndDateMs - programStartDateMs;
|
||||||
|
|
||||||
if (nowPlayingPositionSlider.value = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs), bufferedRanges.length) {
|
if (nowPlayingPositionSlider.value = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs), bufferedRanges.length) {
|
||||||
var rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4);
|
const rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4);
|
||||||
var rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4);
|
const rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4);
|
||||||
nowPlayingPositionSlider.setBufferedRanges([{
|
nowPlayingPositionSlider.setBufferedRanges([{
|
||||||
start: rangeStart,
|
start: rangeStart,
|
||||||
end: rangeEnd
|
end: rangeEnd
|
||||||
|
@ -823,7 +865,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
} else {
|
} else {
|
||||||
if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) {
|
if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) {
|
||||||
if (runtimeTicks) {
|
if (runtimeTicks) {
|
||||||
var pct = positionTicks / runtimeTicks;
|
let pct = positionTicks / runtimeTicks;
|
||||||
pct *= 100;
|
pct *= 100;
|
||||||
nowPlayingPositionSlider.value = pct;
|
nowPlayingPositionSlider.value = pct;
|
||||||
} else {
|
} else {
|
||||||
|
@ -847,9 +889,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePlayerVolumeState(player, isMuted, volumeLevel) {
|
function updatePlayerVolumeState(player, isMuted, volumeLevel) {
|
||||||
var supportedCommands = currentPlayerSupportedCommands;
|
const supportedCommands = currentPlayerSupportedCommands;
|
||||||
var showMuteButton = true;
|
let showMuteButton = true;
|
||||||
var showVolumeSlider = true;
|
let showVolumeSlider = true;
|
||||||
|
|
||||||
if (-1 === supportedCommands.indexOf('Mute')) {
|
if (-1 === supportedCommands.indexOf('Mute')) {
|
||||||
showMuteButton = false;
|
showMuteButton = false;
|
||||||
|
@ -897,8 +939,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePlaylist(player) {
|
function updatePlaylist(player) {
|
||||||
var btnPreviousTrack = view.querySelector('.btnPreviousTrack');
|
const btnPreviousTrack = view.querySelector('.btnPreviousTrack');
|
||||||
var btnNextTrack = view.querySelector('.btnNextTrack');
|
const btnNextTrack = view.querySelector('.btnNextTrack');
|
||||||
btnPreviousTrack.classList.remove('hide');
|
btnPreviousTrack.classList.remove('hide');
|
||||||
btnNextTrack.classList.remove('hide');
|
btnNextTrack.classList.remove('hide');
|
||||||
btnNextTrack.disabled = false;
|
btnNextTrack.disabled = false;
|
||||||
|
@ -911,7 +953,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var html = datetime.getDisplayRunningTime(ticks);
|
let html = datetime.getDisplayRunningTime(ticks);
|
||||||
|
|
||||||
if (divider) {
|
if (divider) {
|
||||||
html = ' / ' + html;
|
html = ' / ' + html;
|
||||||
|
@ -921,15 +963,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSettingsButtonClick(e) {
|
function onSettingsButtonClick(e) {
|
||||||
var btn = this;
|
const btn = this;
|
||||||
|
|
||||||
require(['playerSettingsMenu'], function (playerSettingsMenu) {
|
import('playerSettingsMenu').then(({default: playerSettingsMenu}) => {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
|
|
||||||
if (player) {
|
if (player) {
|
||||||
|
|
||||||
// show subtitle offset feature only if player and media support it
|
// show subtitle offset feature only if player and media support it
|
||||||
var showSubOffset = playbackManager.supportSubtitleOffset(player) &&
|
const showSubOffset = playbackManager.supportSubtitleOffset(player) &&
|
||||||
playbackManager.canHandleOffsetOnCurrentSubtitle(player);
|
playbackManager.canHandleOffsetOnCurrentSubtitle(player);
|
||||||
|
|
||||||
playerSettingsMenu.show({
|
playerSettingsMenu.show({
|
||||||
|
@ -948,7 +990,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
if ('stats' === selectedOption) {
|
if ('stats' === selectedOption) {
|
||||||
toggleStats();
|
toggleStats();
|
||||||
} else if ('suboffset' === selectedOption) {
|
} else if ('suboffset' === selectedOption) {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
if (player) {
|
if (player) {
|
||||||
playbackManager.enableShowingSubtitleOffset(player);
|
playbackManager.enableShowingSubtitleOffset(player);
|
||||||
toggleSubtitleSync();
|
toggleSubtitleSync();
|
||||||
|
@ -957,8 +999,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleStats() {
|
function toggleStats() {
|
||||||
require(['playerStats'], function (PlayerStats) {
|
import('playerStats').then(({default: PlayerStats}) => {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
|
|
||||||
if (player) {
|
if (player) {
|
||||||
if (statsOverlay) {
|
if (statsOverlay) {
|
||||||
|
@ -980,11 +1022,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAudioTrackSelection() {
|
function showAudioTrackSelection() {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
var audioTracks = playbackManager.audioTracks(player);
|
const audioTracks = playbackManager.audioTracks(player);
|
||||||
var currentIndex = playbackManager.getAudioStreamIndex(player);
|
const currentIndex = playbackManager.getAudioStreamIndex(player);
|
||||||
var menuItems = audioTracks.map(function (stream) {
|
const menuItems = audioTracks.map(function (stream) {
|
||||||
var opt = {
|
const opt = {
|
||||||
name: stream.DisplayTitle,
|
name: stream.DisplayTitle,
|
||||||
id: stream.Index
|
id: stream.Index
|
||||||
};
|
};
|
||||||
|
@ -995,15 +1037,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
return opt;
|
return opt;
|
||||||
});
|
});
|
||||||
var positionTo = this;
|
const positionTo = this;
|
||||||
|
|
||||||
require(['actionsheet'], function (actionsheet) {
|
import('actionsheet').then(({default: actionsheet}) => {
|
||||||
actionsheet.show({
|
actionsheet.show({
|
||||||
items: menuItems,
|
items: menuItems,
|
||||||
title: globalize.translate('Audio'),
|
title: globalize.translate('Audio'),
|
||||||
positionTo: positionTo
|
positionTo: positionTo
|
||||||
}).then(function (id) {
|
}).then(function (id) {
|
||||||
var index = parseInt(id);
|
const index = parseInt(id);
|
||||||
|
|
||||||
if (index !== currentIndex) {
|
if (index !== currentIndex) {
|
||||||
playbackManager.setAudioStreamIndex(index, player);
|
playbackManager.setAudioStreamIndex(index, player);
|
||||||
|
@ -1013,9 +1055,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSubtitleTrackSelection() {
|
function showSubtitleTrackSelection() {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
var streams = playbackManager.subtitleTracks(player);
|
const streams = playbackManager.subtitleTracks(player);
|
||||||
var currentIndex = playbackManager.getSubtitleStreamIndex(player);
|
let currentIndex = playbackManager.getSubtitleStreamIndex(player);
|
||||||
|
|
||||||
if (null == currentIndex) {
|
if (null == currentIndex) {
|
||||||
currentIndex = -1;
|
currentIndex = -1;
|
||||||
|
@ -1025,8 +1067,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
Index: -1,
|
Index: -1,
|
||||||
DisplayTitle: globalize.translate('Off')
|
DisplayTitle: globalize.translate('Off')
|
||||||
});
|
});
|
||||||
var menuItems = streams.map(function (stream) {
|
const menuItems = streams.map(function (stream) {
|
||||||
var opt = {
|
const opt = {
|
||||||
name: stream.DisplayTitle,
|
name: stream.DisplayTitle,
|
||||||
id: stream.Index
|
id: stream.Index
|
||||||
};
|
};
|
||||||
|
@ -1037,15 +1079,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
return opt;
|
return opt;
|
||||||
});
|
});
|
||||||
var positionTo = this;
|
const positionTo = this;
|
||||||
|
|
||||||
require(['actionsheet'], function (actionsheet) {
|
import('actionsheet').then(({default: actionsheet}) => {
|
||||||
actionsheet.show({
|
actionsheet.show({
|
||||||
title: globalize.translate('Subtitles'),
|
title: globalize.translate('Subtitles'),
|
||||||
items: menuItems,
|
items: menuItems,
|
||||||
positionTo: positionTo
|
positionTo: positionTo
|
||||||
}).then(function (id) {
|
}).then(function (id) {
|
||||||
var index = parseInt(id);
|
const index = parseInt(id);
|
||||||
|
|
||||||
if (index !== currentIndex) {
|
if (index !== currentIndex) {
|
||||||
playbackManager.setSubtitleStreamIndex(index, player);
|
playbackManager.setSubtitleStreamIndex(index, player);
|
||||||
|
@ -1057,8 +1099,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleSubtitleSync(action) {
|
function toggleSubtitleSync(action) {
|
||||||
require(['subtitleSync'], function (SubtitleSync) {
|
import('subtitleSync').then(({default: SubtitleSync}) => {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
if (subtitleSyncOverlay) {
|
if (subtitleSyncOverlay) {
|
||||||
subtitleSyncOverlay.toggle(action);
|
subtitleSyncOverlay.toggle(action);
|
||||||
} else if (player) {
|
} else if (player) {
|
||||||
|
@ -1078,12 +1120,12 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
* Clicked element.
|
* Clicked element.
|
||||||
* To skip 'click' handling on Firefox/Edge.
|
* To skip 'click' handling on Firefox/Edge.
|
||||||
*/
|
*/
|
||||||
var clickedElement;
|
let clickedElement;
|
||||||
|
|
||||||
function onWindowKeyDown(e) {
|
function onKeyDown(e) {
|
||||||
clickedElement = e.srcElement;
|
clickedElement = e.srcElement;
|
||||||
|
|
||||||
var key = keyboardnavigation.getKeyName(e);
|
const key = keyboardnavigation.getKeyName(e);
|
||||||
|
|
||||||
if (!currentVisibleMenu && 32 === e.keyCode) {
|
if (!currentVisibleMenu && 32 === e.keyCode) {
|
||||||
playbackManager.playPause(currentPlayer);
|
playbackManager.playPause(currentPlayer);
|
||||||
|
@ -1187,19 +1229,37 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
case '6':
|
case '6':
|
||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9': {
|
||||||
var percent = parseInt(key, 10) * 10;
|
const percent = parseInt(key, 10) * 10;
|
||||||
playbackManager.seekPercent(percent, currentPlayer);
|
playbackManager.seekPercent(percent, currentPlayer);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onKeyDownCapture() {
|
||||||
|
// Restart hide timer if OSD is currently visible
|
||||||
|
if (currentVisibleMenu) {
|
||||||
|
showOsd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWindowMouseDown(e) {
|
function onWindowMouseDown(e) {
|
||||||
clickedElement = e.srcElement;
|
clickedElement = e.srcElement;
|
||||||
|
lockOsd();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWindowMouseUp() {
|
||||||
|
unlockOsd();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWindowTouchStart(e) {
|
function onWindowTouchStart(e) {
|
||||||
clickedElement = e.srcElement;
|
clickedElement = e.srcElement;
|
||||||
|
lockOsd();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWindowTouchEnd() {
|
||||||
|
unlockOsd();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImgUrl(item, chapter, index, maxWidth, apiClient) {
|
function getImgUrl(item, chapter, index, maxWidth, apiClient) {
|
||||||
|
@ -1216,11 +1276,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChapterBubbleHtml(apiClient, item, chapters, positionTicks) {
|
function getChapterBubbleHtml(apiClient, item, chapters, positionTicks) {
|
||||||
var chapter;
|
let chapter;
|
||||||
var index = -1;
|
let index = -1;
|
||||||
|
|
||||||
for (var i = 0, length = chapters.length; i < length; i++) {
|
for (let i = 0, length = chapters.length; i < length; i++) {
|
||||||
var currentChapter = chapters[i];
|
const currentChapter = chapters[i];
|
||||||
|
|
||||||
if (positionTicks >= currentChapter.StartPositionTicks) {
|
if (positionTicks >= currentChapter.StartPositionTicks) {
|
||||||
chapter = currentChapter;
|
chapter = currentChapter;
|
||||||
|
@ -1232,10 +1292,10 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var src = getImgUrl(item, chapter, index, 400, apiClient);
|
const src = getImgUrl(item, chapter, index, 400, apiClient);
|
||||||
|
|
||||||
if (src) {
|
if (src) {
|
||||||
var html = '<div class="chapterThumbContainer">';
|
let html = '<div class="chapterThumbContainer">';
|
||||||
html += '<img class="chapterThumb" src="' + src + '" />';
|
html += '<img class="chapterThumb" src="' + src + '" />';
|
||||||
html += '<div class="chapterThumbTextContainer">';
|
html += '<div class="chapterThumbTextContainer">';
|
||||||
html += '<div class="chapterThumbText chapterThumbText-dim">';
|
html += '<div class="chapterThumbText chapterThumbText-dim">';
|
||||||
|
@ -1251,15 +1311,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var playPauseClickTimeout;
|
let playPauseClickTimeout;
|
||||||
function onViewHideStopPlayback() {
|
function onViewHideStopPlayback() {
|
||||||
if (playbackManager.isPlayingVideo()) {
|
if (playbackManager.isPlayingVideo()) {
|
||||||
require(['shell'], function (shell) {
|
import('shell').then(({default: shell}) => {
|
||||||
shell.disableFullscreen();
|
shell.disableFullscreen();
|
||||||
});
|
});
|
||||||
|
|
||||||
clearTimeout(playPauseClickTimeout);
|
clearTimeout(playPauseClickTimeout);
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
view.removeEventListener('viewbeforehide', onViewHideStopPlayback);
|
view.removeEventListener('viewbeforehide', onViewHideStopPlayback);
|
||||||
releaseCurrentPlayer();
|
releaseCurrentPlayer();
|
||||||
playbackManager.stop(player);
|
playbackManager.stop(player);
|
||||||
|
@ -1274,47 +1334,49 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
require(['shell'], function (shell) {
|
import('shell').then(({default: shell}) => {
|
||||||
shell.enableFullscreen();
|
shell.enableFullscreen();
|
||||||
});
|
});
|
||||||
|
|
||||||
var currentPlayer;
|
let currentPlayer;
|
||||||
var comingUpNextDisplayed;
|
let comingUpNextDisplayed;
|
||||||
var currentUpNextDialog;
|
let currentUpNextDialog;
|
||||||
var isEnabled;
|
let isEnabled;
|
||||||
var currentItem;
|
let currentItem;
|
||||||
var recordingButtonManager;
|
let recordingButtonManager;
|
||||||
var enableProgressByTimeOfDay;
|
let enableProgressByTimeOfDay;
|
||||||
var supportsBrightnessChange;
|
let supportsBrightnessChange;
|
||||||
var currentVisibleMenu;
|
let currentVisibleMenu;
|
||||||
var statsOverlay;
|
let statsOverlay;
|
||||||
var osdHideTimeout;
|
let osdHideTimeout;
|
||||||
var lastPointerMoveData;
|
let lastPointerMoveData;
|
||||||
var self = this;
|
const self = this;
|
||||||
var currentPlayerSupportedCommands = [];
|
let currentPlayerSupportedCommands = [];
|
||||||
var currentRuntimeTicks = 0;
|
let currentRuntimeTicks = 0;
|
||||||
var lastUpdateTime = 0;
|
let lastUpdateTime = 0;
|
||||||
var programStartDateMs = 0;
|
let programStartDateMs = 0;
|
||||||
var programEndDateMs = 0;
|
let programEndDateMs = 0;
|
||||||
var playbackStartTimeTicks = 0;
|
let playbackStartTimeTicks = 0;
|
||||||
var subtitleSyncOverlay;
|
let subtitleSyncOverlay;
|
||||||
var nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider');
|
const nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider');
|
||||||
var nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer');
|
const nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer');
|
||||||
var nowPlayingPositionSlider = view.querySelector('.osdPositionSlider');
|
const nowPlayingPositionSlider = view.querySelector('.osdPositionSlider');
|
||||||
var nowPlayingPositionText = view.querySelector('.osdPositionText');
|
const nowPlayingPositionText = view.querySelector('.osdPositionText');
|
||||||
var nowPlayingDurationText = view.querySelector('.osdDurationText');
|
const nowPlayingDurationText = view.querySelector('.osdDurationText');
|
||||||
var startTimeText = view.querySelector('.startTimeText');
|
const startTimeText = view.querySelector('.startTimeText');
|
||||||
var endTimeText = view.querySelector('.endTimeText');
|
const endTimeText = view.querySelector('.endTimeText');
|
||||||
var endsAtText = view.querySelector('.endsAtText');
|
const endsAtText = view.querySelector('.endsAtText');
|
||||||
var btnRewind = view.querySelector('.btnRewind');
|
const btnRewind = view.querySelector('.btnRewind');
|
||||||
var btnFastForward = view.querySelector('.btnFastForward');
|
const btnFastForward = view.querySelector('.btnFastForward');
|
||||||
var transitionEndEventName = dom.whichTransitionEvent();
|
const transitionEndEventName = dom.whichTransitionEvent();
|
||||||
var headerElement = document.querySelector('.skinHeader');
|
const headerElement = document.querySelector('.skinHeader');
|
||||||
var osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols');
|
const osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols');
|
||||||
|
|
||||||
|
nowPlayingPositionSlider.enableKeyboardDragging();
|
||||||
|
nowPlayingVolumeSlider.enableKeyboardDragging();
|
||||||
|
|
||||||
if (layoutManager.tv) {
|
if (layoutManager.tv) {
|
||||||
nowPlayingPositionSlider.classList.add('focusable');
|
nowPlayingPositionSlider.classList.add('focusable');
|
||||||
nowPlayingPositionSlider.enableKeyboardDragging();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
view.addEventListener('viewbeforeshow', function (e) {
|
view.addEventListener('viewbeforeshow', function (e) {
|
||||||
|
@ -1325,23 +1387,35 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
try {
|
try {
|
||||||
events.on(playbackManager, 'playerchange', onPlayerChange);
|
events.on(playbackManager, 'playerchange', onPlayerChange);
|
||||||
bindToPlayer(playbackManager.getCurrentPlayer());
|
bindToPlayer(playbackManager.getCurrentPlayer());
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
dom.addEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, {
|
dom.addEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
showOsd();
|
showOsd();
|
||||||
inputManager.on(window, onInputCommand);
|
inputManager.on(window, onInputCommand);
|
||||||
dom.addEventListener(window, 'keydown', onWindowKeyDown, {
|
document.addEventListener('keydown', onKeyDown);
|
||||||
|
dom.addEventListener(document, 'keydown', onKeyDownCapture, {
|
||||||
capture: true
|
capture: true
|
||||||
});
|
});
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
dom.addEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, {
|
dom.addEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
|
dom.addEventListener(window, window.PointerEvent ? 'pointerup' : 'mouseup', onWindowMouseUp, {
|
||||||
|
passive: true
|
||||||
|
});
|
||||||
dom.addEventListener(window, 'touchstart', onWindowTouchStart, {
|
dom.addEventListener(window, 'touchstart', onWindowTouchStart, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
['touchend', 'touchcancel'].forEach((event) => {
|
||||||
|
dom.addEventListener(window, event, onWindowTouchEnd, {
|
||||||
|
passive: true
|
||||||
|
});
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
require(['appRouter'], function(appRouter) {
|
import('appRouter').then(({default: appRouter}) => {
|
||||||
appRouter.showDirect('/');
|
appRouter.goHome();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1350,18 +1424,30 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
statsOverlay.enabled(false);
|
statsOverlay.enabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
dom.removeEventListener(window, 'keydown', onWindowKeyDown, {
|
document.removeEventListener('keydown', onKeyDown);
|
||||||
|
dom.removeEventListener(document, 'keydown', onKeyDownCapture, {
|
||||||
capture: true
|
capture: true
|
||||||
});
|
});
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
dom.removeEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, {
|
dom.removeEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
|
dom.removeEventListener(window, window.PointerEvent ? 'pointerup' : 'mouseup', onWindowMouseUp, {
|
||||||
|
passive: true
|
||||||
|
});
|
||||||
dom.removeEventListener(window, 'touchstart', onWindowTouchStart, {
|
dom.removeEventListener(window, 'touchstart', onWindowTouchStart, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
['touchend', 'touchcancel'].forEach((event) => {
|
||||||
|
dom.removeEventListener(window, event, onWindowTouchEnd, {
|
||||||
|
passive: true
|
||||||
|
});
|
||||||
|
});
|
||||||
stopOsdHideTimer();
|
stopOsdHideTimer();
|
||||||
headerElement.classList.remove('osdHeader');
|
headerElement.classList.remove('osdHeader');
|
||||||
headerElement.classList.remove('osdHeader-hidden');
|
headerElement.classList.remove('osdHeader-hidden');
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
dom.removeEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, {
|
dom.removeEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
@ -1396,14 +1482,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
destroyStats();
|
destroyStats();
|
||||||
destroySubtitleSync();
|
destroySubtitleSync();
|
||||||
});
|
});
|
||||||
var lastPointerDown = 0;
|
let lastPointerDown = 0;
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
dom.addEventListener(view, window.PointerEvent ? 'pointerdown' : 'click', function (e) {
|
dom.addEventListener(view, window.PointerEvent ? 'pointerdown' : 'click', function (e) {
|
||||||
if (dom.parentWithClass(e.target, ['videoOsdBottom', 'upNextContainer'])) {
|
if (dom.parentWithClass(e.target, ['videoOsdBottom', 'upNextContainer'])) {
|
||||||
return void showOsd();
|
return void showOsd();
|
||||||
}
|
}
|
||||||
|
|
||||||
var pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
|
const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
|
||||||
var now = new Date().getTime();
|
const now = new Date().getTime();
|
||||||
|
|
||||||
switch (pointerType) {
|
switch (pointerType) {
|
||||||
case 'touch':
|
case 'touch':
|
||||||
|
@ -1441,31 +1528,28 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
if (browser.touch) {
|
if (browser.touch) {
|
||||||
dom.addEventListener(view, 'dblclick', onDoubleClick, {});
|
dom.addEventListener(view, 'dblclick', onDoubleClick, {});
|
||||||
} else {
|
} else {
|
||||||
var options = { passive: true };
|
const options = { passive: true };
|
||||||
dom.addEventListener(view, 'dblclick', function () {
|
dom.addEventListener(view, 'dblclick', function () {
|
||||||
playbackManager.toggleFullscreen(currentPlayer);
|
playbackManager.toggleFullscreen(currentPlayer);
|
||||||
}, options);
|
}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setVolume() {
|
|
||||||
playbackManager.setVolume(this.value, currentPlayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.querySelector('.buttonMute').addEventListener('click', function () {
|
view.querySelector('.buttonMute').addEventListener('click', function () {
|
||||||
playbackManager.toggleMute(currentPlayer);
|
playbackManager.toggleMute(currentPlayer);
|
||||||
});
|
});
|
||||||
nowPlayingVolumeSlider.addEventListener('change', setVolume);
|
|
||||||
nowPlayingVolumeSlider.addEventListener('mousemove', setVolume);
|
nowPlayingVolumeSlider.addEventListener('input', (e) => {
|
||||||
nowPlayingVolumeSlider.addEventListener('touchmove', setVolume);
|
playbackManager.setVolume(e.target.value, currentPlayer);
|
||||||
|
});
|
||||||
|
|
||||||
nowPlayingPositionSlider.addEventListener('change', function () {
|
nowPlayingPositionSlider.addEventListener('change', function () {
|
||||||
var player = currentPlayer;
|
const player = currentPlayer;
|
||||||
|
|
||||||
if (player) {
|
if (player) {
|
||||||
var newPercent = parseFloat(this.value);
|
const newPercent = parseFloat(this.value);
|
||||||
|
|
||||||
if (enableProgressByTimeOfDay) {
|
if (enableProgressByTimeOfDay) {
|
||||||
var seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4;
|
let seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4;
|
||||||
seekAirTimeTicks += 1e4 * programStartDateMs;
|
seekAirTimeTicks += 1e4 * programStartDateMs;
|
||||||
seekAirTimeTicks -= playbackStartTimeTicks;
|
seekAirTimeTicks -= playbackStartTimeTicks;
|
||||||
playbackManager.seek(seekAirTimeTicks, player);
|
playbackManager.seek(seekAirTimeTicks, player);
|
||||||
|
@ -1479,7 +1563,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
showOsd();
|
showOsd();
|
||||||
if (enableProgressByTimeOfDay) {
|
if (enableProgressByTimeOfDay) {
|
||||||
if (programStartDateMs && programEndDateMs) {
|
if (programStartDateMs && programEndDateMs) {
|
||||||
var ms = programEndDateMs - programStartDateMs;
|
let ms = programEndDateMs - programStartDateMs;
|
||||||
ms /= 100;
|
ms /= 100;
|
||||||
ms *= value;
|
ms *= value;
|
||||||
ms += programStartDateMs;
|
ms += programStartDateMs;
|
||||||
|
@ -1493,13 +1577,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
return '--:--';
|
return '--:--';
|
||||||
}
|
}
|
||||||
|
|
||||||
var ticks = currentRuntimeTicks;
|
let ticks = currentRuntimeTicks;
|
||||||
ticks /= 100;
|
ticks /= 100;
|
||||||
ticks *= value;
|
ticks *= value;
|
||||||
var item = currentItem;
|
const item = currentItem;
|
||||||
|
|
||||||
if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) {
|
if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) {
|
||||||
var html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks);
|
let html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks);
|
||||||
|
|
||||||
if (html) {
|
if (html) {
|
||||||
return html;
|
return html;
|
||||||
|
@ -1532,8 +1616,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
|
|
||||||
if (browser.touch) {
|
if (browser.touch) {
|
||||||
(function () {
|
(function () {
|
||||||
|
<<<<<<< HEAD
|
||||||
require(['touchHelper'], function (TouchHelper) {
|
require(['touchHelper'], function (TouchHelper) {
|
||||||
self.touchHelper = new TouchHelper.default(view, {
|
self.touchHelper = new TouchHelper.default(view, {
|
||||||
|
=======
|
||||||
|
import('touchHelper').then(({default: TouchHelper}) => {
|
||||||
|
self.touchHelper = new TouchHelper(view, {
|
||||||
|
>>>>>>> upstream/master
|
||||||
swipeYThreshold: 30,
|
swipeYThreshold: 30,
|
||||||
triggerOnMove: true,
|
triggerOnMove: true,
|
||||||
preventDefaultOnMove: true,
|
preventDefaultOnMove: true,
|
||||||
|
@ -1544,5 +1633,6 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
});
|
|
||||||
|
/* eslint-enable indent */
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySettings, userSettings, autoFocuser) {
|
import DisplaySettings from 'displaySettings';
|
||||||
'use strict';
|
import * as userSettings from 'userSettings';
|
||||||
|
import autoFocuser from 'autoFocuser';
|
||||||
|
|
||||||
|
/* eslint-disable indent */
|
||||||
|
|
||||||
// Shortcuts
|
// Shortcuts
|
||||||
const UserSettings = userSettings.UserSettings;
|
const UserSettings = userSettings.UserSettings;
|
||||||
|
|
||||||
return function (view, params) {
|
export default function (view, params) {
|
||||||
function onBeforeUnload(e) {
|
function onBeforeUnload(e) {
|
||||||
if (hasChanges) {
|
if (hasChanges) {
|
||||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var settingsInstance;
|
let settingsInstance;
|
||||||
var hasChanges;
|
let hasChanges;
|
||||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
const userId = params.userId || ApiClient.getCurrentUserId();
|
||||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||||
view.addEventListener('viewshow', function () {
|
view.addEventListener('viewshow', function () {
|
||||||
window.addEventListener('beforeunload', onBeforeUnload);
|
window.addEventListener('beforeunload', onBeforeUnload);
|
||||||
|
|
||||||
|
@ -26,28 +29,23 @@ define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySett
|
||||||
userId: userId,
|
userId: userId,
|
||||||
element: view.querySelector('.settingsContainer'),
|
element: view.querySelector('.settingsContainer'),
|
||||||
userSettings: currentSettings,
|
userSettings: currentSettings,
|
||||||
enableSaveButton: false,
|
enableSaveButton: true,
|
||||||
enableSaveConfirmation: false,
|
enableSaveConfirmation: true,
|
||||||
autoFocus: autoFocuser.isEnabled()
|
autoFocus: autoFocuser.isEnabled()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
view.addEventListener('change', function () {
|
view.addEventListener('change', function () {
|
||||||
hasChanges = true;
|
hasChanges = true;
|
||||||
});
|
});
|
||||||
view.addEventListener('viewbeforehide', function () {
|
|
||||||
window.removeEventListener('beforeunload', onBeforeUnload);
|
|
||||||
hasChanges = false;
|
|
||||||
|
|
||||||
if (settingsInstance) {
|
|
||||||
settingsInstance.submit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
view.addEventListener('viewdestroy', function () {
|
view.addEventListener('viewdestroy', function () {
|
||||||
if (settingsInstance) {
|
if (settingsInstance) {
|
||||||
settingsInstance.destroy();
|
settingsInstance.destroy();
|
||||||
settingsInstance = null;
|
settingsInstance = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
});
|
|
||||||
|
/* eslint-enable indent */
|
||||||
|
|
|
@ -1,20 +1,27 @@
|
||||||
define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (HomescreenSettings, dom, globalize, loading, userSettings, autoFocuser) {
|
import HomescreenSettings from 'homescreenSettings';
|
||||||
'use strict';
|
import dom from 'dom';
|
||||||
|
import globalize from 'globalize';
|
||||||
|
import loading from 'loading';
|
||||||
|
import * as userSettings from 'userSettings';
|
||||||
|
import autoFocuser from 'autoFocuser';
|
||||||
|
import 'listViewStyle';
|
||||||
|
|
||||||
|
/* eslint-disable indent */
|
||||||
|
|
||||||
// Shortcuts
|
// Shortcuts
|
||||||
const UserSettings = userSettings.UserSettings;
|
const UserSettings = userSettings.UserSettings;
|
||||||
|
|
||||||
return function (view, params) {
|
export default function (view, params) {
|
||||||
function onBeforeUnload(e) {
|
function onBeforeUnload(e) {
|
||||||
if (hasChanges) {
|
if (hasChanges) {
|
||||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var homescreenSettingsInstance;
|
let homescreenSettingsInstance;
|
||||||
var hasChanges;
|
let hasChanges;
|
||||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
const userId = params.userId || ApiClient.getCurrentUserId();
|
||||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||||
view.addEventListener('viewshow', function () {
|
view.addEventListener('viewshow', function () {
|
||||||
window.addEventListener('beforeunload', onBeforeUnload);
|
window.addEventListener('beforeunload', onBeforeUnload);
|
||||||
|
|
||||||
|
@ -26,27 +33,23 @@ define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'au
|
||||||
userId: userId,
|
userId: userId,
|
||||||
element: view.querySelector('.homeScreenSettingsContainer'),
|
element: view.querySelector('.homeScreenSettingsContainer'),
|
||||||
userSettings: currentSettings,
|
userSettings: currentSettings,
|
||||||
enableSaveButton: false,
|
enableSaveButton: true,
|
||||||
enableSaveConfirmation: false,
|
enableSaveConfirmation: true,
|
||||||
autoFocus: autoFocuser.isEnabled()
|
autoFocus: autoFocuser.isEnabled()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
view.addEventListener('change', function () {
|
view.addEventListener('change', function () {
|
||||||
hasChanges = true;
|
hasChanges = true;
|
||||||
});
|
});
|
||||||
view.addEventListener('viewbeforehide', function () {
|
|
||||||
hasChanges = false;
|
|
||||||
|
|
||||||
if (homescreenSettingsInstance) {
|
|
||||||
homescreenSettingsInstance.submit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
view.addEventListener('viewdestroy', function () {
|
view.addEventListener('viewdestroy', function () {
|
||||||
if (homescreenSettingsInstance) {
|
if (homescreenSettingsInstance) {
|
||||||
homescreenSettingsInstance.destroy();
|
homescreenSettingsInstance.destroy();
|
||||||
homescreenSettingsInstance = null;
|
homescreenSettingsInstance = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
});
|
|
||||||
|
/* eslint-enable indent */
|
||||||
|
|
|
@ -1,20 +1,27 @@
|
||||||
define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (PlaybackSettings, dom, globalize, loading, userSettings, autoFocuser) {
|
import PlaybackSettings from 'playbackSettings';
|
||||||
'use strict';
|
import dom from 'dom';
|
||||||
|
import globalize from 'globalize';
|
||||||
|
import loading from 'loading';
|
||||||
|
import * as userSettings from 'userSettings';
|
||||||
|
import autoFocuser from 'autoFocuser';
|
||||||
|
import 'listViewStyle';
|
||||||
|
|
||||||
|
/* eslint-disable indent */
|
||||||
|
|
||||||
// Shortcuts
|
// Shortcuts
|
||||||
const UserSettings = userSettings.UserSettings;
|
const UserSettings = userSettings.UserSettings;
|
||||||
|
|
||||||
return function (view, params) {
|
export default function (view, params) {
|
||||||
function onBeforeUnload(e) {
|
function onBeforeUnload(e) {
|
||||||
if (hasChanges) {
|
if (hasChanges) {
|
||||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var settingsInstance;
|
let settingsInstance;
|
||||||
var hasChanges;
|
let hasChanges;
|
||||||
var userId = params.userId || ApiClient.getCurrentUserId();
|
const userId = params.userId || ApiClient.getCurrentUserId();
|
||||||
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||||
view.addEventListener('viewshow', function () {
|
view.addEventListener('viewshow', function () {
|
||||||
window.addEventListener('beforeunload', onBeforeUnload);
|
window.addEventListener('beforeunload', onBeforeUnload);
|
||||||
|
|
||||||
|
@ -26,27 +33,23 @@ define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'auto
|
||||||
userId: userId,
|
userId: userId,
|
||||||
element: view.querySelector('.settingsContainer'),
|
element: view.querySelector('.settingsContainer'),
|
||||||
userSettings: currentSettings,
|
userSettings: currentSettings,
|
||||||
enableSaveButton: false,
|
enableSaveButton: true,
|
||||||
enableSaveConfirmation: false,
|
enableSaveConfirmation: true,
|
||||||
autoFocus: autoFocuser.isEnabled()
|
autoFocus: autoFocuser.isEnabled()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
view.addEventListener('change', function () {
|
view.addEventListener('change', function () {
|
||||||
hasChanges = true;
|
hasChanges = true;
|
||||||
});
|
});
|
||||||
view.addEventListener('viewbeforehide', function () {
|
|
||||||
hasChanges = false;
|
|
||||||
|
|
||||||
if (settingsInstance) {
|
|
||||||
settingsInstance.submit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
view.addEventListener('viewdestroy', function () {
|
view.addEventListener('viewdestroy', function () {
|
||||||
if (settingsInstance) {
|
if (settingsInstance) {
|
||||||
settingsInstance.destroy();
|
settingsInstance.destroy();
|
||||||
settingsInstance = null;
|
settingsInstance = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
});
|
|
||||||
|
/* eslint-enable indent */
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import subtitleSettings from 'subtitleSettings';
|
import subtitleSettings from 'subtitleSettings';
|
||||||
import {UserSettings, currentSettings as userSettings} from 'userSettings';
|
import {UserSettings, currentSettings as userSettings} from 'userSettings';
|
||||||
import autoFocuser from 'autoFocuser';
|
import autoFocuser from 'autoFocuser';
|
||||||
|
=======
|
||||||
|
import SubtitleSettings from 'subtitleSettings';
|
||||||
|
import * as userSettings from 'userSettings';
|
||||||
|
import autoFocuser from 'autoFocuser';
|
||||||
|
|
||||||
|
/* eslint-disable indent */
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
export class SubtitleController {
|
export class SubtitleController {
|
||||||
constructor(view, params) {
|
constructor(view, params) {
|
||||||
|
@ -10,6 +18,7 @@ export class SubtitleController {
|
||||||
this.subtitleSettingsInstance = null;
|
this.subtitleSettingsInstance = null;
|
||||||
this.view = view;
|
this.view = view;
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
view.addEventListener('viewshow', this.viewShow.bind(this));
|
view.addEventListener('viewshow', this.viewShow.bind(this));
|
||||||
view.addEventListener('change', this.change.bind(this));
|
view.addEventListener('change', this.change.bind(this));
|
||||||
view.addEventListener('viewbeforehide', this.viewBeforeHide.bind(this));
|
view.addEventListener('viewbeforehide', this.viewBeforeHide.bind(this));
|
||||||
|
@ -56,8 +65,53 @@ export class SubtitleController {
|
||||||
beforeUnload(e) {
|
beforeUnload(e) {
|
||||||
if (this.hasChanges) {
|
if (this.hasChanges) {
|
||||||
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||||
|
=======
|
||||||
|
export default function (view, params) {
|
||||||
|
function onBeforeUnload(e) {
|
||||||
|
if (hasChanges) {
|
||||||
|
e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?';
|
||||||
|
}
|
||||||
|
>>>>>>> upstream/master
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
export default SubtitleController;
|
export default SubtitleController;
|
||||||
|
=======
|
||||||
|
let subtitleSettingsInstance;
|
||||||
|
let hasChanges;
|
||||||
|
const userId = params.userId || ApiClient.getCurrentUserId();
|
||||||
|
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
|
||||||
|
view.addEventListener('viewshow', function () {
|
||||||
|
window.addEventListener('beforeunload', onBeforeUnload);
|
||||||
|
|
||||||
|
if (subtitleSettingsInstance) {
|
||||||
|
subtitleSettingsInstance.loadData();
|
||||||
|
} else {
|
||||||
|
subtitleSettingsInstance = new SubtitleSettings({
|
||||||
|
serverId: ApiClient.serverId(),
|
||||||
|
userId: userId,
|
||||||
|
element: view.querySelector('.settingsContainer'),
|
||||||
|
userSettings: currentSettings,
|
||||||
|
enableSaveButton: true,
|
||||||
|
enableSaveConfirmation: true,
|
||||||
|
autoFocus: autoFocuser.isEnabled()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
view.addEventListener('change', function () {
|
||||||
|
hasChanges = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
view.addEventListener('viewdestroy', function () {
|
||||||
|
if (subtitleSettingsInstance) {
|
||||||
|
subtitleSettingsInstance.destroy();
|
||||||
|
subtitleSettingsInstance = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-enable indent */
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
|
@ -6,6 +7,10 @@ import appRouter from 'appRouter';
|
||||||
import appHost from 'apphost';
|
import appHost from 'apphost';
|
||||||
import 'css!./emby-button';
|
import 'css!./emby-button';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
|
=======
|
||||||
|
define(['browser', 'dom', 'layoutManager', 'shell', 'appRouter', 'apphost', 'css!./emby-button', 'webcomponents'], function (browser, dom, layoutManager, shell, appRouter, appHost) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
|
const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
|
||||||
const EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype);
|
const EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype);
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
import 'css!./emby-button';
|
import 'css!./emby-button';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
|
=======
|
||||||
|
define(['layoutManager', 'css!./emby-button', 'webcomponents'], function (layoutManager) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
|
const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
import 'css!./emby-checkbox';
|
import 'css!./emby-checkbox';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
|
=======
|
||||||
|
define(['browser', 'dom', 'css!./emby-checkbox', 'webcomponents'], function (browser, dom) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
import 'css!./emby-collapse';
|
import 'css!./emby-collapse';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
import 'emby-button';
|
import 'emby-button';
|
||||||
|
=======
|
||||||
|
define(['browser', 'css!./emby-collapse', 'webcomponents', 'emby-button'], function (browser) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
import 'css!./emby-input';
|
import 'css!./emby-input';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
|
=======
|
||||||
|
define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'webcomponents'], function (layoutManager, browser, dom) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import EmbyProgressRing from 'emby-progressring';
|
import EmbyProgressRing from 'emby-progressring';
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
import serverNotifications from 'serverNotifications';
|
import serverNotifications from 'serverNotifications';
|
||||||
|
@ -5,6 +6,10 @@ import events from 'events';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
=======
|
||||||
|
define(['emby-progressring', 'dom', 'serverNotifications', 'events', 'webcomponents'], function (EmbyProgressRing, dom, serverNotifications, events) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
function addNotificationEvent(instance, name, handler) {
|
function addNotificationEvent(instance, name, handler) {
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import itemShortcuts from 'itemShortcuts';
|
import itemShortcuts from 'itemShortcuts';
|
||||||
import inputManager from 'inputManager';
|
import inputManager from 'inputManager';
|
||||||
import connectionManager from 'connectionManager';
|
import connectionManager from 'connectionManager';
|
||||||
|
@ -15,6 +16,12 @@ import 'registerElement';
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
const ItemsContainerPrototype = Object.create(HTMLDivElement.prototype);
|
const ItemsContainerPrototype = Object.create(HTMLDivElement.prototype);
|
||||||
|
=======
|
||||||
|
define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager', 'imageLoader', 'layoutManager', 'browser', 'dom', 'loading', 'focusManager', 'serverNotifications', 'events', 'webcomponents'], function (itemShortcuts, inputManager, connectionManager, playbackManager, imageLoader, layoutManager, browser, dom, loading, focusManager, serverNotifications, events) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var ItemsContainerPrototype = Object.create(HTMLDivElement.prototype);
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
function onClick(e) {
|
function onClick(e) {
|
||||||
const itemsContainer = this;
|
const itemsContainer = this;
|
||||||
|
@ -42,7 +49,7 @@ import 'registerElement';
|
||||||
|
|
||||||
// check for serverId, it won't be present on selectserver
|
// check for serverId, it won't be present on selectserver
|
||||||
if (card && card.getAttribute('data-serverid')) {
|
if (card && card.getAttribute('data-serverid')) {
|
||||||
inputManager.trigger('menu', {
|
inputManager.handleCommand('menu', {
|
||||||
sourceElement: card
|
sourceElement: card
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import require from 'require';
|
import require from 'require';
|
||||||
import 'css!./emby-progressring';
|
import 'css!./emby-progressring';
|
||||||
import 'webcomponents';
|
import 'webcomponents';
|
||||||
|
=======
|
||||||
|
define(['require', 'css!./emby-progressring', 'webcomponents'], function (require) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
import 'css!./emby-radio';
|
import 'css!./emby-radio';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
|
=======
|
||||||
|
define(['layoutManager', 'css!./emby-radio', 'webcomponents'], function (layoutManager) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
min-width: 104px;
|
min-width: 104px;
|
||||||
min-height: 24px;
|
min-height: 24px;
|
||||||
padding-top: 1.25em;
|
padding-top: 0.85em;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
import 'css!./emby-scrollbuttons';
|
import 'css!./emby-scrollbuttons';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
import 'paper-icon-button-light';
|
import 'paper-icon-button-light';
|
||||||
|
=======
|
||||||
|
define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'webcomponents', 'paper-icon-button-light'], function (layoutManager, dom) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import scroller from 'scroller';
|
import scroller from 'scroller';
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
|
@ -6,6 +7,10 @@ import focusManager from 'focusManager';
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
import 'css!./emby-scroller';
|
import 'css!./emby-scroller';
|
||||||
|
=======
|
||||||
|
define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'browser', 'webcomponents', 'css!./emby-scroller'], function (scroller, dom, layoutManager, inputManager, focusManager, browser) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
import actionsheet from 'actionsheet';
|
import actionsheet from 'actionsheet';
|
||||||
import 'css!./emby-select';
|
import 'css!./emby-select';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
|
=======
|
||||||
|
define(['layoutManager', 'browser', 'actionsheet', 'css!./emby-select', 'webcomponents'], function (layoutManager, browser, actionsheet) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
|
@ -5,6 +6,10 @@ import keyboardnavigation from 'keyboardnavigation';
|
||||||
import 'css!./emby-slider';
|
import 'css!./emby-slider';
|
||||||
import 'webcomponents';
|
import 'webcomponents';
|
||||||
import 'emby-input';
|
import 'emby-input';
|
||||||
|
=======
|
||||||
|
define(['browser', 'dom', 'layoutManager', 'keyboardnavigation', 'css!./emby-slider', 'webcomponents', 'emby-input'], function (browser, dom, layoutManager, keyboardnavigation) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,6 @@
|
||||||
|
|
||||||
.emby-tabs-slider {
|
.emby-tabs-slider {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-mobile .emby-tabs-slider {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabContent:not(.is-active) {
|
.tabContent:not(.is-active) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import dom from 'dom';
|
import dom from 'dom';
|
||||||
import scroller from 'scroller';
|
import scroller from 'scroller';
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
|
@ -6,6 +7,10 @@ import focusManager from 'focusManager';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
import 'css!./emby-tabs';
|
import 'css!./emby-tabs';
|
||||||
import 'scrollStyles';
|
import 'scrollStyles';
|
||||||
|
=======
|
||||||
|
define(['dom', 'scroller', 'browser', 'layoutManager', 'focusManager', 'webcomponents', 'css!./emby-tabs', 'scrollStyles'], function (dom, scroller, browser, layoutManager, focusManager) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import layoutManager from 'layoutManager';
|
import layoutManager from 'layoutManager';
|
||||||
import browser from 'browser';
|
import browser from 'browser';
|
||||||
import 'css!./emby-textarea';
|
import 'css!./emby-textarea';
|
||||||
|
@ -5,6 +6,10 @@ import 'registerElement';
|
||||||
import 'emby-input';
|
import 'emby-input';
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
=======
|
||||||
|
define(['layoutManager', 'browser', 'css!./emby-textarea', 'webcomponents', 'emby-input'], function (layoutManager, browser) {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
function autoGrow(textarea, maxLines) {
|
function autoGrow(textarea, maxLines) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
|
<<<<<<< HEAD
|
||||||
import 'css!./emby-toggle';
|
import 'css!./emby-toggle';
|
||||||
import 'registerElement';
|
import 'registerElement';
|
||||||
|
=======
|
||||||
|
define(['css!./emby-toggle', 'webcomponents'], function () {
|
||||||
|
'use strict';
|
||||||
|
>>>>>>> upstream/master
|
||||||
|
|
||||||
/* eslint-disable indent */
|
/* eslint-disable indent */
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
<!-- iPad Pro 1 -->
|
<!-- iPad Pro 1 -->
|
||||||
<link href="assets/splash/ipadpro1_splash.png" media="screen and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" rel="apple-touch-startup-image" />
|
<link href="assets/splash/ipadpro1_splash.png" media="screen and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" rel="apple-touch-startup-image" />
|
||||||
<link href="assets/splash/ipadpro1_splash_l.png" media="screen and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" rel="apple-touch-startup-image" />
|
<link href="assets/splash/ipadpro1_splash_l.png" media="screen and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" rel="apple-touch-startup-image" />
|
||||||
|
|
||||||
<!-- iPad Pro 3 -->
|
<!-- iPad Pro 3 -->
|
||||||
<link href="assets/splash/ipadpro3_splash.png" media="screen and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" rel="apple-touch-startup-image" />
|
<link href="assets/splash/ipadpro3_splash.png" media="screen and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" rel="apple-touch-startup-image" />
|
||||||
<link href="assets/splash/ipadpro3_splash_l.png" media="screen and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" rel="apple-touch-startup-image" />
|
<link href="assets/splash/ipadpro3_splash_l.png" media="screen and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" rel="apple-touch-startup-image" />
|
||||||
|
@ -69,12 +69,19 @@
|
||||||
<title>Jellyfin</title>
|
<title>Jellyfin</title>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.transparentDocument, .backgroundContainer-transparent:not(.withBackdrop) {
|
.transparentDocument,
|
||||||
|
.backgroundContainer-transparent:not(.withBackdrop) {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mouseIdle, .mouseIdle button, .mouseIdle select, .mouseIdle input, .mouseIdle textarea, .mouseIdle a, .mouseIdle label {
|
.mouseIdle,
|
||||||
|
.mouseIdle button,
|
||||||
|
.mouseIdle select,
|
||||||
|
.mouseIdle input,
|
||||||
|
.mouseIdle textarea,
|
||||||
|
.mouseIdle a,
|
||||||
|
.mouseIdle label {
|
||||||
cursor: none !important;
|
cursor: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +89,9 @@
|
||||||
background-color: #101010;
|
background-color: #101010;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hide, .mouseIdle .hide-mouse-idle, .mouseIdle-tv .hide-mouse-idle-tv {
|
.hide,
|
||||||
|
.mouseIdle .hide-mouse-idle,
|
||||||
|
.mouseIdle-tv .hide-mouse-idle-tv {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +103,42 @@
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
width: 0.8em;
|
width: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes fadein {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadein {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.splashLogo {
|
||||||
|
-webkit-animation: fadein 0.5s;
|
||||||
|
animation: fadein 0.5s;
|
||||||
|
width: 30%;
|
||||||
|
height: 30%;
|
||||||
|
background-image: url(assets/img/banner-light.png);
|
||||||
|
background-position: center center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
-webkit-transform: translate(-50%, -50%);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -103,7 +148,9 @@
|
||||||
<div class="mainDrawer-scrollContainer scrollContainer focuscontainer-y"></div>
|
<div class="mainDrawer-scrollContainer scrollContainer focuscontainer-y"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="skinHeader focuscontainer-x"></div>
|
<div class="skinHeader focuscontainer-x"></div>
|
||||||
<div class="mainAnimatedPages skinBody"></div>
|
<div class="mainAnimatedPages skinBody">
|
||||||
|
<div class="splashLogo"></div>
|
||||||
|
</div>
|
||||||
<div class="mainDrawerHandle"></div>
|
<div class="mainDrawerHandle"></div>
|
||||||
|
|
||||||
<!-- inject:js -->
|
<!-- inject:js -->
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
<div id="loginPage" data-role="page" class="page standalonePage" data-backbutton="false">
|
<div id="loginPage" data-role="page" class="page standalonePage flex flex-direction-column align-items-center justify-content-center" data-backbutton="false">
|
||||||
<div class="padded-left padded-right padded-bottom-page">
|
<div class="padded-left padded-right padded-bottom-page">
|
||||||
<form class="manualLoginForm hide" style="margin: 0 auto;">
|
<form class="manualLoginForm hide">
|
||||||
<h1 style="margin-top:1em;text-align: left;">${HeaderPleaseSignIn}</h1>
|
<div class="padded-left padded-right flex align-items-center justify-content-center">
|
||||||
|
<h1 class="sectionTitle">${HeaderPleaseSignIn}</h1>
|
||||||
|
</div>
|
||||||
<div style="height:0; overflow: hidden;">
|
<div style="height:0; overflow: hidden;">
|
||||||
<input type="text" name="fakeusernameremembered" tabindex="-1" />
|
<input type="text" name="fakeusernameremembered" tabindex="-1" />
|
||||||
<input type="password" name="fakepasswordremembered" tabindex="-1" />
|
<input type="password" name="fakepasswordremembered" tabindex="-1" />
|
||||||
|
@ -29,8 +31,6 @@
|
||||||
<span>${ButtonCancel}</span>
|
<span>${ButtonCancel}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
|
||||||
<br/>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="visualLoginForm" style="text-align: center;">
|
<div class="visualLoginForm" style="text-align: center;">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="nowPlayingInfoContainer">
|
<div class="nowPlayingInfoContainer">
|
||||||
<div class="nowPlayingPageImageContainer"></div>
|
<div class="nowPlayingPageImageContainer"></div>
|
||||||
<div class="nowPlayingInfoControls">
|
<div class="nowPlayingInfoControls">
|
||||||
|
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
|
|
||||||
<div class="nowPlayingInfoContainerMedia">
|
<div class="nowPlayingInfoContainerMedia">
|
||||||
|
@ -15,9 +15,9 @@
|
||||||
<div class="nowPlayingArtist nowPlayingSerie"></div>
|
<div class="nowPlayingArtist nowPlayingSerie"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="nowPlayingPageUserDataButtonsTitle"></div>
|
<div class="nowPlayingPageUserDataButtonsTitle"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sliderContainer flex">
|
<div class="sliderContainer flex">
|
||||||
<div class="positionTime"></div>
|
<div class="positionTime"></div>
|
||||||
<div class="nowPlayingPositionSliderContainer">
|
<div class="nowPlayingPositionSliderContainer">
|
||||||
|
@ -25,15 +25,20 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="runtime"></div>
|
<div class="runtime"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nowPlayingButtonsContainer focuscontainer-x">
|
<div class="nowPlayingButtonsContainer focuscontainer-x justify-content-space-between">
|
||||||
|
|
||||||
<div class="nowPlayingInfoButtons">
|
<div class="nowPlayingInfoButtons">
|
||||||
|
|
||||||
|
<button is="paper-icon-button-light" class="btnCommand btnRepeat repeatToggleButton autoSize" title="${ButtonRepeat}"
|
||||||
|
data-command="SetRepeatMode">
|
||||||
|
<span class="material-icons repeat"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button is="paper-icon-button-light" class="btnRewind btnNowPlayingRewind btnPlayStateCommand autoSize" title="${Rewind}">
|
<button is="paper-icon-button-light" class="btnRewind btnNowPlayingRewind btnPlayStateCommand autoSize" title="${Rewind}">
|
||||||
<span class="material-icons replay_10"></span>
|
<span class="material-icons replay_10"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="paper-icon-button-light" class="btnPreviousTrack btnPlayStateCommand autoSize" title="${ButtonPreviousTrack}">
|
<button is="paper-icon-button-light" class="btnPreviousTrack btnPlayStateCommand autoSize" title="${ButtonPreviousTrack}">
|
||||||
<span class="material-icons skip_previous"></span>
|
<span class="material-icons skip_previous"></span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -49,15 +54,19 @@
|
||||||
<button is="paper-icon-button-light" class="btnPlayStateCommand btnNextTrack autoSize" title="${ButtonNextTrack}">
|
<button is="paper-icon-button-light" class="btnPlayStateCommand btnNextTrack autoSize" title="${ButtonNextTrack}">
|
||||||
<span class="material-icons skip_next"></span>
|
<span class="material-icons skip_next"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="paper-icon-button-light" class="btnPlayStateCommand btnFastForward btnNowPlayingFastForward autoSize" title="${FastForward}">
|
<button is="paper-icon-button-light" class="btnPlayStateCommand btnFastForward btnNowPlayingFastForward autoSize" title="${FastForward}">
|
||||||
<span class="material-icons forward_30"></span>
|
<span class="material-icons forward_30"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button is="paper-icon-button-light" class="btnShuffleQueue autoSize" title="${ButtonShuffle}">
|
||||||
|
<span class="material-icons shuffle"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nowPlayingSecondaryButtons">
|
<div class="nowPlayingSecondaryButtons">
|
||||||
|
|
||||||
<button is="paper-icon-button-light" class="btnAudioTracks videoButton btnPlayStateCommand autoSize" title="${ButtonAudioTracks}" data-command="GoToSearch">
|
<button is="paper-icon-button-light" class="btnAudioTracks videoButton btnPlayStateCommand autoSize" title="${ButtonAudioTracks}" data-command="GoToSearch">
|
||||||
<span class="material-icons audiotrack"></span>
|
<span class="material-icons audiotrack"></span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -65,14 +74,19 @@
|
||||||
<button is="paper-icon-button-light" class="btnSubtitles videoButton btnPlayStateCommand autoSize" title="${ButtonSubtitles}" data-command="GoToSearch">
|
<button is="paper-icon-button-light" class="btnSubtitles videoButton btnPlayStateCommand autoSize" title="${ButtonSubtitles}" data-command="GoToSearch">
|
||||||
<span class="material-icons closed_caption"></span>
|
<span class="material-icons closed_caption"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="nowPlayingPageUserDataButtons"></div>
|
<div class="nowPlayingPageUserDataButtons"></div>
|
||||||
|
|
||||||
<button is="paper-icon-button-light" class="btnToggleFullscreen videoButton btnPlayStateCommand autoSize" title="${ButtonFullscreen}" data-command="ToggleFullscreen">
|
<button is="paper-icon-button-light" class="btnToggleFullscreen videoButton btnPlayStateCommand autoSize" title="${ButtonFullscreen}" data-command="ToggleFullscreen">
|
||||||
<span class="material-icons fullscreen"></span>
|
<span class="material-icons fullscreen"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button is="paper-icon-button-light" class="btnCommand repeatToggleButton autoSize" title="${ButtonRepeat}" data-command="SetRepeatMode">
|
<button is="paper-icon-button-light" class="btnShuffleQueue autoSize" title="${ButtonShuffle}">
|
||||||
|
<span class="material-icons shuffle"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button is="paper-icon-button-light" class="btnCommand btnRepeat repeatToggleButton autoSize" title="${ButtonRepeat}"
|
||||||
|
data-command="SetRepeatMode">
|
||||||
<span class="material-icons repeat"></span>
|
<span class="material-icons repeat"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
@ -162,21 +176,18 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="playlistSection">
|
<div class="playlistSection">
|
||||||
<div class="playlistSectionButton flex align-items-center justify-content-center">
|
<div class="playlistSectionButton flex align-items-center justify-content-center focuscontainer-x">
|
||||||
<button id="togglePlaylist" is="paper-icon-button-light" class="btnTogglePlaylist" title="${ButtonTogglePlaylist}">
|
<button id="togglePlaylist" is="paper-icon-button-light" class="btnTogglePlaylist hide" title="${ButtonTogglePlaylist}">
|
||||||
<span class="material-icons queue_music"></span>
|
<span class="material-icons queue_music"></span>
|
||||||
</button>
|
</button>
|
||||||
<button is="paper-icon-button-light" class="btnSavePlaylist" title="${ButtonSave}">
|
<button is="paper-icon-button-light" class="btnSavePlaylist hide" title="${ButtonSave}">
|
||||||
<span class="material-icons save"></span>
|
<span class="material-icons save"></span>
|
||||||
</button>
|
</button>
|
||||||
|
<button id="toggleContextMenu" is="paper-icon-button-light" class="btnToggleContextMenu" title="${ButtonToggleContextMenu}">
|
||||||
|
<span class="material-icons more_vert"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="playlist" class="playlist itemsContainer vertical-list nowPlayingPlaylist hide" is="emby-itemscontainer" data-dragreorder="true"></div>
|
<div id="playlist" class="playlist itemsContainer vertical-list nowPlayingPlaylist hide" is="emby-itemscontainer" data-dragreorder="true"></div>
|
||||||
<div id="contextMenu" class="contextMenu itemsContainer vertical-list nowPlayingContextMenu hide" is="emby-itemscontainer">
|
|
||||||
<div class="listItem listItem-border contextMenuList contextMenuArtist">
|
|
||||||
</div>
|
|
||||||
<div class="listItem listItem-border contextMenuList contextMenuAlbum">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -548,7 +548,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
|
|
||||||
events.trigger(instance, 'playbackstop', [state]);
|
events.trigger(instance, 'playbackstop', [state]);
|
||||||
|
|
||||||
var state = instance.lastPlayerData.PlayState || {};
|
state = instance.lastPlayerData.PlayState || {};
|
||||||
var volume = state.VolumeLevel || 0.5;
|
var volume = state.VolumeLevel || 0.5;
|
||||||
var mute = state.IsMuted || false;
|
var mute = state.IsMuted || false;
|
||||||
|
|
||||||
|
@ -572,6 +572,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
bindEventForRelay(instance, 'unpause');
|
bindEventForRelay(instance, 'unpause');
|
||||||
bindEventForRelay(instance, 'volumechange');
|
bindEventForRelay(instance, 'volumechange');
|
||||||
bindEventForRelay(instance, 'repeatmodechange');
|
bindEventForRelay(instance, 'repeatmodechange');
|
||||||
|
bindEventForRelay(instance, 'shufflequeuemodechange');
|
||||||
|
|
||||||
events.on(instance._castPlayer, 'playstatechange', function (e, data) {
|
events.on(instance._castPlayer, 'playstatechange', function (e, data) {
|
||||||
|
|
||||||
|
@ -651,6 +652,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
'SetSubtitleStreamIndex',
|
'SetSubtitleStreamIndex',
|
||||||
'DisplayContent',
|
'DisplayContent',
|
||||||
'SetRepeatMode',
|
'SetRepeatMode',
|
||||||
|
'SetShuffleQueue',
|
||||||
'EndSession',
|
'EndSession',
|
||||||
'PlayMediaSource',
|
'PlayMediaSource',
|
||||||
'PlayTrailers'
|
'PlayTrailers'
|
||||||
|
@ -864,6 +866,12 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
return state.RepeatMode;
|
return state.RepeatMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ChromecastPlayer.prototype.getQueueShuffleMode = function () {
|
||||||
|
var state = this.lastPlayerData || {};
|
||||||
|
state = state.PlayState || {};
|
||||||
|
return state.ShuffleMode;
|
||||||
|
};
|
||||||
|
|
||||||
ChromecastPlayer.prototype.playTrailers = function (item) {
|
ChromecastPlayer.prototype.playTrailers = function (item) {
|
||||||
|
|
||||||
this._castPlayer.sendMessage({
|
this._castPlayer.sendMessage({
|
||||||
|
@ -884,6 +892,15 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ChromecastPlayer.prototype.setQueueShuffleMode = function (value) {
|
||||||
|
this._castPlayer.sendMessage({
|
||||||
|
options: {
|
||||||
|
ShuffleMode: value
|
||||||
|
},
|
||||||
|
command: 'SetShuffleQueue'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
ChromecastPlayer.prototype.toggleMute = function () {
|
ChromecastPlayer.prototype.toggleMute = function () {
|
||||||
|
|
||||||
this._castPlayer.sendMessage({
|
this._castPlayer.sendMessage({
|
||||||
|
|
|
@ -649,7 +649,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
function setTrackEventsSubtitleOffset(trackEvents, offsetValue) {
|
function setTrackEventsSubtitleOffset(trackEvents, offsetValue) {
|
||||||
|
|
||||||
if (Array.isArray(trackEvents)) {
|
if (Array.isArray(trackEvents)) {
|
||||||
offsetValue = updateCurrentTrackOffset(offsetValue);
|
offsetValue = updateCurrentTrackOffset(offsetValue) * 1e7; // ticks
|
||||||
trackEvents.forEach(function(trackEvent) {
|
trackEvents.forEach(function(trackEvent) {
|
||||||
trackEvent.StartPositionTicks -= offsetValue;
|
trackEvent.StartPositionTicks -= offsetValue;
|
||||||
trackEvent.EndPositionTicks -= offsetValue;
|
trackEvent.EndPositionTicks -= offsetValue;
|
||||||
|
|
|
@ -263,7 +263,7 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
|
||||||
appName: s.Client,
|
appName: s.Client,
|
||||||
playableMediaTypes: s.PlayableMediaTypes,
|
playableMediaTypes: s.PlayableMediaTypes,
|
||||||
isLocalPlayer: false,
|
isLocalPlayer: false,
|
||||||
supportedCommands: s.SupportedCommands,
|
supportedCommands: s.Capabilities.SupportedCommands,
|
||||||
user: s.UserId ? {
|
user: s.UserId ? {
|
||||||
|
|
||||||
Id: s.UserId,
|
Id: s.UserId,
|
||||||
|
@ -506,6 +506,17 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SessionPlayer.prototype.setQueueShuffleMode = function (mode) {
|
||||||
|
|
||||||
|
sendCommandByName(this, 'SetShuffleQueue', {
|
||||||
|
ShuffleMode: mode
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
SessionPlayer.prototype.getQueueShuffleMode = function () {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
SessionPlayer.prototype.displayContent = function (options) {
|
SessionPlayer.prototype.displayContent = function (options) {
|
||||||
|
|
||||||
sendCommandByName(this, 'DisplayContent', options);
|
sendCommandByName(this, 'DisplayContent', options);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
src += `?v=${self.dashboardVersion}`;
|
src += `?v=${self.dashboardVersion}`;
|
||||||
}
|
}
|
||||||
script.src = src;
|
script.src = src;
|
||||||
|
script.setAttribute('async', '');
|
||||||
|
|
||||||
if (onload) {
|
if (onload) {
|
||||||
script.onload = onload;
|
script.onload = onload;
|
||||||
|
|
|
@ -60,7 +60,7 @@ define(['browser'], function (browser) {
|
||||||
|
|
||||||
function canPlayHlsWithMSE() {
|
function canPlayHlsWithMSE() {
|
||||||
// text tracks don’t work with this in firefox
|
// text tracks don’t work with this in firefox
|
||||||
return window.MediaSource != null;
|
return window.MediaSource != null; /* eslint-disable-line compat/compat */
|
||||||
}
|
}
|
||||||
|
|
||||||
function supportsAc3(videoTestElement) {
|
function supportsAc3(videoTestElement) {
|
||||||
|
|
|
@ -211,7 +211,7 @@
|
||||||
'MozAnimation': 'animationend',
|
'MozAnimation': 'animationend',
|
||||||
'WebkitAnimation': 'webkitAnimationEnd'
|
'WebkitAnimation': 'webkitAnimationEnd'
|
||||||
};
|
};
|
||||||
for (let t in animations) {
|
for (const t in animations) {
|
||||||
if (el.style[t] !== undefined) {
|
if (el.style[t] !== undefined) {
|
||||||
_animationEvent = animations[t];
|
_animationEvent = animations[t];
|
||||||
return animations[t];
|
return animations[t];
|
||||||
|
@ -251,7 +251,7 @@
|
||||||
'MozTransition': 'transitionend',
|
'MozTransition': 'transitionend',
|
||||||
'WebkitTransition': 'webkitTransitionEnd'
|
'WebkitTransition': 'webkitTransitionEnd'
|
||||||
};
|
};
|
||||||
for (let t in transitions) {
|
for (const t in transitions) {
|
||||||
if (el.style[t] !== undefined) {
|
if (el.style[t] !== undefined) {
|
||||||
_transitionEvent = transitions[t];
|
_transitionEvent = transitions[t];
|
||||||
return transitions[t];
|
return transitions[t];
|
||||||
|
|
|
@ -201,6 +201,9 @@ import appHost from 'apphost';
|
||||||
'rewind': () => {
|
'rewind': () => {
|
||||||
playbackManager.rewind();
|
playbackManager.rewind();
|
||||||
},
|
},
|
||||||
|
'seek': () => {
|
||||||
|
playbackManager.seekMs(options);
|
||||||
|
},
|
||||||
'togglefullscreen': () => {
|
'togglefullscreen': () => {
|
||||||
playbackManager.toggleFullscreen();
|
playbackManager.toggleFullscreen();
|
||||||
},
|
},
|
||||||
|
@ -235,9 +238,6 @@ import appHost from 'apphost';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alias for backward compatibility
|
|
||||||
export const trigger = handleCommand;
|
|
||||||
|
|
||||||
dom.addEventListener(document, 'click', notify, {
|
dom.addEventListener(document, 'click', notify, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
@ -245,8 +245,7 @@ import appHost from 'apphost';
|
||||||
/* eslint-enable indent */
|
/* eslint-enable indent */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
trigger: handleCommand,
|
handleCommand: handleCommand,
|
||||||
handle: handleCommand,
|
|
||||||
notify: notify,
|
notify: notify,
|
||||||
notifyMouseMove: notifyMouseMove,
|
notifyMouseMove: notifyMouseMove,
|
||||||
idleTime: idleTime,
|
idleTime: idleTime,
|
||||||
|
|
|
@ -71,12 +71,12 @@ define(['connectionManager', 'listView', 'cardBuilder', 'imageLoader', 'libraryB
|
||||||
|
|
||||||
html += '<div class="' + sectionClass + '" data-type="' + section.type + '">';
|
html += '<div class="' + sectionClass + '" data-type="' + section.type + '">';
|
||||||
html += '<div class="sectionTitleContainer sectionTitleContainer-cards">';
|
html += '<div class="sectionTitleContainer sectionTitleContainer-cards">';
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">';
|
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
||||||
html += section.name;
|
html += section.name;
|
||||||
html += '</h2>';
|
html += '</h2>';
|
||||||
html += '<a is="emby-linkbutton" href="#" class="clearLink hide" style="margin-left:1em;vertical-align:middle;"><button is="emby-button" type="button" class="raised more raised-mini noIcon">' + globalize.translate('ButtonMore') + '</button></a>';
|
html += '<a is="emby-linkbutton" href="#" class="clearLink hide" style="margin-left:1em;vertical-align:middle;"><button is="emby-button" type="button" class="raised more raised-mini noIcon">' + globalize.translate('ButtonMore') + '</button></a>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer padded-right">';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
return html += '</div>';
|
return html += '</div>';
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
|
@ -78,7 +78,7 @@ export function isNavigationKey(key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function enable() {
|
export function enable() {
|
||||||
document.addEventListener('keydown', function (e) {
|
window.addEventListener('keydown', function (e) {
|
||||||
const key = getKeyName(e);
|
const key = getKeyName(e);
|
||||||
|
|
||||||
// Ignore navigation keys for non-TV
|
// Ignore navigation keys for non-TV
|
||||||
|
@ -90,53 +90,53 @@ export function enable() {
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'ArrowLeft':
|
case 'ArrowLeft':
|
||||||
inputManager.handle('left');
|
inputManager.handleCommand('left');
|
||||||
break;
|
break;
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
inputManager.handle('up');
|
inputManager.handleCommand('up');
|
||||||
break;
|
break;
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
inputManager.handle('right');
|
inputManager.handleCommand('right');
|
||||||
break;
|
break;
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
inputManager.handle('down');
|
inputManager.handleCommand('down');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Back':
|
case 'Back':
|
||||||
inputManager.handle('back');
|
inputManager.handleCommand('back');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
if (layoutManager.tv) {
|
if (layoutManager.tv) {
|
||||||
inputManager.handle('back');
|
inputManager.handleCommand('back');
|
||||||
} else {
|
} else {
|
||||||
capture = false;
|
capture = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'MediaPlay':
|
case 'MediaPlay':
|
||||||
inputManager.handle('play');
|
inputManager.handleCommand('play');
|
||||||
break;
|
break;
|
||||||
case 'Pause':
|
case 'Pause':
|
||||||
inputManager.handle('pause');
|
inputManager.handleCommand('pause');
|
||||||
break;
|
break;
|
||||||
case 'MediaPlayPause':
|
case 'MediaPlayPause':
|
||||||
inputManager.handle('playpause');
|
inputManager.handleCommand('playpause');
|
||||||
break;
|
break;
|
||||||
case 'MediaRewind':
|
case 'MediaRewind':
|
||||||
inputManager.handle('rewind');
|
inputManager.handleCommand('rewind');
|
||||||
break;
|
break;
|
||||||
case 'MediaFastForward':
|
case 'MediaFastForward':
|
||||||
inputManager.handle('fastforward');
|
inputManager.handleCommand('fastforward');
|
||||||
break;
|
break;
|
||||||
case 'MediaStop':
|
case 'MediaStop':
|
||||||
inputManager.handle('stop');
|
inputManager.handleCommand('stop');
|
||||||
break;
|
break;
|
||||||
case 'MediaTrackPrevious':
|
case 'MediaTrackPrevious':
|
||||||
inputManager.handle('previoustrack');
|
inputManager.handleCommand('previoustrack');
|
||||||
break;
|
break;
|
||||||
case 'MediaTrackNext':
|
case 'MediaTrackNext':
|
||||||
inputManager.handle('nexttrack');
|
inputManager.handleCommand('nexttrack');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -13,7 +13,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', '
|
||||||
html += '<div class="headerRight">';
|
html += '<div class="headerRight">';
|
||||||
html += '<span class="headerSelectedPlayer"></span>';
|
html += '<span class="headerSelectedPlayer"></span>';
|
||||||
html += `<button is="paper-icon-button-light" class="headerSyncButton syncButton headerButton headerButtonRight hide" title="${globalize.translate('ButtonSyncPlay')}"><span class="material-icons sync_disabled"></span></button>`;
|
html += `<button is="paper-icon-button-light" class="headerSyncButton syncButton headerButton headerButtonRight hide" title="${globalize.translate('ButtonSyncPlay')}"><span class="material-icons sync_disabled"></span></button>`;
|
||||||
html += '<button is="paper-icon-button-light" class="headerAudioPlayerButton audioPlayerButton headerButton headerButtonRight hide"><span class="material-icons music_note"></span></button>';
|
html += `<button is="paper-icon-button-light" class="headerAudioPlayerButton audioPlayerButton headerButton headerButtonRight hide" title="${globalize.translate('ButtonPlayer')}"><span class="material-icons music_note"></span></button>`;
|
||||||
html += `<button is="paper-icon-button-light" class="headerCastButton castButton headerButton headerButtonRight hide" title="${globalize.translate('ButtonCast')}"><span class="material-icons cast"></span></button>`;
|
html += `<button is="paper-icon-button-light" class="headerCastButton castButton headerButton headerButtonRight hide" title="${globalize.translate('ButtonCast')}"><span class="material-icons cast"></span></button>`;
|
||||||
html += `<button type="button" is="paper-icon-button-light" class="headerButton headerButtonRight headerSearchButton hide" title="${globalize.translate('ButtonSearch')}"><span class="material-icons search"></span></button>`;
|
html += `<button type="button" is="paper-icon-button-light" class="headerButton headerButtonRight headerSearchButton hide" title="${globalize.translate('ButtonSearch')}"><span class="material-icons search"></span></button>`;
|
||||||
html += '<button is="paper-icon-button-light" class="headerButton headerButtonRight headerUserButton hide"><span class="material-icons person"></span></button>';
|
html += '<button is="paper-icon-button-light" class="headerButton headerButtonRight headerUserButton hide"><span class="material-icons person"></span></button>';
|
||||||
|
@ -89,7 +89,8 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', '
|
||||||
|
|
||||||
var policy = user.Policy ? user.Policy : user.localUser.Policy;
|
var policy = user.Policy ? user.Policy : user.localUser.Policy;
|
||||||
|
|
||||||
if (headerSyncButton && policy && policy.SyncPlayAccess !== 'None') {
|
var apiClient = getCurrentApiClient();
|
||||||
|
if (headerSyncButton && policy && policy.SyncPlayAccess !== 'None' && apiClient.isMinServerVersion('10.6.0')) {
|
||||||
headerSyncButton.classList.remove('hide');
|
headerSyncButton.classList.remove('hide');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -116,7 +117,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', '
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSearch() {
|
function showSearch() {
|
||||||
inputManager.trigger('search');
|
inputManager.handleCommand('search');
|
||||||
}
|
}
|
||||||
|
|
||||||
function onHeaderUserButtonClick(e) {
|
function onHeaderUserButtonClick(e) {
|
||||||
|
@ -967,8 +968,10 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', '
|
||||||
updateUserInHeader();
|
updateUserInHeader();
|
||||||
});
|
});
|
||||||
events.on(playbackManager, 'playerchange', updateCastIcon);
|
events.on(playbackManager, 'playerchange', updateCastIcon);
|
||||||
|
|
||||||
events.on(syncPlayManager, 'enabled', onSyncPlayEnabled);
|
events.on(syncPlayManager, 'enabled', onSyncPlayEnabled);
|
||||||
events.on(syncPlayManager, 'syncing', onSyncPlaySyncing);
|
events.on(syncPlayManager, 'syncing', onSyncPlaySyncing);
|
||||||
|
|
||||||
loadNavDrawer();
|
loadNavDrawer();
|
||||||
return LibraryMenu;
|
return LibraryMenu;
|
||||||
});
|
});
|
||||||
|
|
|
@ -136,6 +136,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd
|
||||||
|
|
||||||
stopMouseInterval();
|
stopMouseInterval();
|
||||||
|
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
dom.removeEventListener(document, (window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove, {
|
dom.removeEventListener(document, (window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
@ -148,6 +149,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eslint-disable-next-line compat/compat */
|
||||||
dom.removeEventListener(document, (window.PointerEvent ? 'pointerenter' : 'mouseenter'), onPointerEnter, {
|
dom.removeEventListener(document, (window.PointerEvent ? 'pointerenter' : 'mouseenter'), onPointerEnter, {
|
||||||
capture: true,
|
capture: true,
|
||||||
passive: true
|
passive: true
|
||||||
|
|
|
@ -15,7 +15,7 @@ define([
|
||||||
'detailtablecss'], function () {
|
'detailtablecss'], function () {
|
||||||
|
|
||||||
function defineRoute(newRoute) {
|
function defineRoute(newRoute) {
|
||||||
var path = newRoute.path;
|
var path = newRoute.alias ? newRoute.alias : newRoute.path;
|
||||||
console.debug('defining route: ' + path);
|
console.debug('defining route: ' + path);
|
||||||
newRoute.dictionary = 'core';
|
newRoute.dictionary = 'core';
|
||||||
Emby.Page.addRoute(path, newRoute);
|
Emby.Page.addRoute(path, newRoute);
|
||||||
|
@ -240,8 +240,9 @@ define([
|
||||||
transition: 'fade'
|
transition: 'fade'
|
||||||
});
|
});
|
||||||
defineRoute({
|
defineRoute({
|
||||||
path: '/itemdetails.html',
|
alias: '/details',
|
||||||
controller: 'itemDetails',
|
path: '/controllers/itemDetails/index.html',
|
||||||
|
controller: 'itemDetails/index',
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
transition: 'fade'
|
transition: 'fade'
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,28 +36,28 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in
|
||||||
console.debug('Received command: ' + cmd.Name);
|
console.debug('Received command: ' + cmd.Name);
|
||||||
switch (cmd.Name) {
|
switch (cmd.Name) {
|
||||||
case 'Select':
|
case 'Select':
|
||||||
inputManager.trigger('select');
|
inputManager.handleCommand('select');
|
||||||
return;
|
return;
|
||||||
case 'Back':
|
case 'Back':
|
||||||
inputManager.trigger('back');
|
inputManager.handleCommand('back');
|
||||||
return;
|
return;
|
||||||
case 'MoveUp':
|
case 'MoveUp':
|
||||||
inputManager.trigger('up');
|
inputManager.handleCommand('up');
|
||||||
return;
|
return;
|
||||||
case 'MoveDown':
|
case 'MoveDown':
|
||||||
inputManager.trigger('down');
|
inputManager.handleCommand('down');
|
||||||
return;
|
return;
|
||||||
case 'MoveLeft':
|
case 'MoveLeft':
|
||||||
inputManager.trigger('left');
|
inputManager.handleCommand('left');
|
||||||
return;
|
return;
|
||||||
case 'MoveRight':
|
case 'MoveRight':
|
||||||
inputManager.trigger('right');
|
inputManager.handleCommand('right');
|
||||||
return;
|
return;
|
||||||
case 'PageUp':
|
case 'PageUp':
|
||||||
inputManager.trigger('pageup');
|
inputManager.handleCommand('pageup');
|
||||||
return;
|
return;
|
||||||
case 'PageDown':
|
case 'PageDown':
|
||||||
inputManager.trigger('pagedown');
|
inputManager.handleCommand('pagedown');
|
||||||
return;
|
return;
|
||||||
case 'PlayTrailers':
|
case 'PlayTrailers':
|
||||||
playTrailers(apiClient, cmd.Arguments.ItemId);
|
playTrailers(apiClient, cmd.Arguments.ItemId);
|
||||||
|
@ -65,26 +65,29 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in
|
||||||
case 'SetRepeatMode':
|
case 'SetRepeatMode':
|
||||||
playbackManager.setRepeatMode(cmd.Arguments.RepeatMode);
|
playbackManager.setRepeatMode(cmd.Arguments.RepeatMode);
|
||||||
break;
|
break;
|
||||||
|
case 'SetShuffleQueue':
|
||||||
|
playbackManager.setQueueShuffleMode(cmd.Arguments.ShuffleMode);
|
||||||
|
break;
|
||||||
case 'VolumeUp':
|
case 'VolumeUp':
|
||||||
inputManager.trigger('volumeup');
|
inputManager.handleCommand('volumeup');
|
||||||
return;
|
return;
|
||||||
case 'VolumeDown':
|
case 'VolumeDown':
|
||||||
inputManager.trigger('volumedown');
|
inputManager.handleCommand('volumedown');
|
||||||
return;
|
return;
|
||||||
case 'ChannelUp':
|
case 'ChannelUp':
|
||||||
inputManager.trigger('channelup');
|
inputManager.handleCommand('channelup');
|
||||||
return;
|
return;
|
||||||
case 'ChannelDown':
|
case 'ChannelDown':
|
||||||
inputManager.trigger('channeldown');
|
inputManager.handleCommand('channeldown');
|
||||||
return;
|
return;
|
||||||
case 'Mute':
|
case 'Mute':
|
||||||
inputManager.trigger('mute');
|
inputManager.handleCommand('mute');
|
||||||
return;
|
return;
|
||||||
case 'Unmute':
|
case 'Unmute':
|
||||||
inputManager.trigger('unmute');
|
inputManager.handleCommand('unmute');
|
||||||
return;
|
return;
|
||||||
case 'ToggleMute':
|
case 'ToggleMute':
|
||||||
inputManager.trigger('togglemute');
|
inputManager.handleCommand('togglemute');
|
||||||
return;
|
return;
|
||||||
case 'SetVolume':
|
case 'SetVolume':
|
||||||
notifyApp();
|
notifyApp();
|
||||||
|
@ -99,19 +102,19 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in
|
||||||
playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index));
|
playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index));
|
||||||
break;
|
break;
|
||||||
case 'ToggleFullscreen':
|
case 'ToggleFullscreen':
|
||||||
inputManager.trigger('togglefullscreen');
|
inputManager.handleCommand('togglefullscreen');
|
||||||
return;
|
return;
|
||||||
case 'GoHome':
|
case 'GoHome':
|
||||||
inputManager.trigger('home');
|
inputManager.handleCommand('home');
|
||||||
return;
|
return;
|
||||||
case 'GoToSettings':
|
case 'GoToSettings':
|
||||||
inputManager.trigger('settings');
|
inputManager.handleCommand('settings');
|
||||||
return;
|
return;
|
||||||
case 'DisplayContent':
|
case 'DisplayContent':
|
||||||
displayContent(cmd, apiClient);
|
displayContent(cmd, apiClient);
|
||||||
break;
|
break;
|
||||||
case 'GoToSearch':
|
case 'GoToSearch':
|
||||||
inputManager.trigger('search');
|
inputManager.handleCommand('search');
|
||||||
return;
|
return;
|
||||||
case 'DisplayMessage':
|
case 'DisplayMessage':
|
||||||
displayMessage(cmd);
|
displayMessage(cmd);
|
||||||
|
@ -162,19 +165,19 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in
|
||||||
}
|
}
|
||||||
} else if (msg.MessageType === 'Playstate') {
|
} else if (msg.MessageType === 'Playstate') {
|
||||||
if (msg.Data.Command === 'Stop') {
|
if (msg.Data.Command === 'Stop') {
|
||||||
inputManager.trigger('stop');
|
inputManager.handleCommand('stop');
|
||||||
} else if (msg.Data.Command === 'Pause') {
|
} else if (msg.Data.Command === 'Pause') {
|
||||||
inputManager.trigger('pause');
|
inputManager.handleCommand('pause');
|
||||||
} else if (msg.Data.Command === 'Unpause') {
|
} else if (msg.Data.Command === 'Unpause') {
|
||||||
inputManager.trigger('play');
|
inputManager.handleCommand('play');
|
||||||
} else if (msg.Data.Command === 'PlayPause') {
|
} else if (msg.Data.Command === 'PlayPause') {
|
||||||
inputManager.trigger('playpause');
|
inputManager.handleCommand('playpause');
|
||||||
} else if (msg.Data.Command === 'Seek') {
|
} else if (msg.Data.Command === 'Seek') {
|
||||||
playbackManager.seek(msg.Data.SeekPositionTicks);
|
playbackManager.seek(msg.Data.SeekPositionTicks);
|
||||||
} else if (msg.Data.Command === 'NextTrack') {
|
} else if (msg.Data.Command === 'NextTrack') {
|
||||||
inputManager.trigger('next');
|
inputManager.handleCommand('next');
|
||||||
} else if (msg.Data.Command === 'PreviousTrack') {
|
} else if (msg.Data.Command === 'PreviousTrack') {
|
||||||
inputManager.trigger('previous');
|
inputManager.handleCommand('previous');
|
||||||
} else {
|
} else {
|
||||||
notifyApp();
|
notifyApp();
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ var Dashboard = {
|
||||||
capabilities: function (appHost) {
|
capabilities: function (appHost) {
|
||||||
var capabilities = {
|
var capabilities = {
|
||||||
PlayableMediaTypes: ['Audio', 'Video'],
|
PlayableMediaTypes: ['Audio', 'Video'],
|
||||||
SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'],
|
SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'SetShuffleQueue', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'],
|
||||||
SupportsPersistentIdentifier: 'cordova' === self.appMode || 'android' === self.appMode,
|
SupportsPersistentIdentifier: 'cordova' === self.appMode || 'android' === self.appMode,
|
||||||
SupportsMediaControl: true
|
SupportsMediaControl: true
|
||||||
};
|
};
|
||||||
|
@ -387,8 +387,6 @@ var AppInfo = {};
|
||||||
define('lazyLoader', [componentsPath + '/lazyLoader/lazyLoaderIntersectionObserver'], returnFirstDependency);
|
define('lazyLoader', [componentsPath + '/lazyLoader/lazyLoaderIntersectionObserver'], returnFirstDependency);
|
||||||
define('shell', [scriptsPath + '/shell'], returnFirstDependency);
|
define('shell', [scriptsPath + '/shell'], returnFirstDependency);
|
||||||
|
|
||||||
define('registerElement', ['document-register-element'], returnFirstDependency);
|
|
||||||
|
|
||||||
define('alert', [componentsPath + '/alert'], returnFirstDependency);
|
define('alert', [componentsPath + '/alert'], returnFirstDependency);
|
||||||
|
|
||||||
defineResizeObserver();
|
defineResizeObserver();
|
||||||
|
@ -672,7 +670,6 @@ var AppInfo = {};
|
||||||
},
|
},
|
||||||
bundles: {
|
bundles: {
|
||||||
bundle: [
|
bundle: [
|
||||||
'document-register-element',
|
|
||||||
'fetch',
|
'fetch',
|
||||||
'flvjs',
|
'flvjs',
|
||||||
'jstree',
|
'jstree',
|
||||||
|
@ -1039,7 +1036,7 @@ var AppInfo = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('SeriesTimer' == itemType) {
|
if ('SeriesTimer' == itemType) {
|
||||||
return 'itemdetails.html?seriesTimerId=' + id + '&serverId=' + serverId;
|
return 'details?seriesTimerId=' + id + '&serverId=' + serverId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('livetv' == item.CollectionType) {
|
if ('livetv' == item.CollectionType) {
|
||||||
|
@ -1109,13 +1106,13 @@ var AppInfo = {};
|
||||||
var itemTypes = ['Playlist', 'TvChannel', 'Program', 'BoxSet', 'MusicAlbum', 'MusicGenre', 'Person', 'Recording', 'MusicArtist'];
|
var itemTypes = ['Playlist', 'TvChannel', 'Program', 'BoxSet', 'MusicAlbum', 'MusicGenre', 'Person', 'Recording', 'MusicArtist'];
|
||||||
|
|
||||||
if (itemTypes.indexOf(itemType) >= 0) {
|
if (itemTypes.indexOf(itemType) >= 0) {
|
||||||
return 'itemdetails.html?id=' + id + '&serverId=' + serverId;
|
return 'details?id=' + id + '&serverId=' + serverId;
|
||||||
}
|
}
|
||||||
|
|
||||||
var contextSuffix = context ? '&context=' + context : '';
|
var contextSuffix = context ? '&context=' + context : '';
|
||||||
|
|
||||||
if ('Series' == itemType || 'Season' == itemType || 'Episode' == itemType) {
|
if ('Series' == itemType || 'Season' == itemType || 'Episode' == itemType) {
|
||||||
return 'itemdetails.html?id=' + id + contextSuffix + '&serverId=' + serverId;
|
return 'details?id=' + id + contextSuffix + '&serverId=' + serverId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.IsFolder) {
|
if (item.IsFolder) {
|
||||||
|
@ -1126,7 +1123,7 @@ var AppInfo = {};
|
||||||
return '#';
|
return '#';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'itemdetails.html?id=' + id + '&serverId=' + serverId;
|
return 'details?id=' + id + '&serverId=' + serverId;
|
||||||
};
|
};
|
||||||
|
|
||||||
appRouter.showItem = showItem;
|
appRouter.showItem = showItem;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<div id="selectServerPage" data-role="page" class="page noSecondaryNavPage standalonePage pageContainer fullWidth vertical flex flex-direction-column">
|
<div id="selectServerPage" data-role="page" class="page noSecondaryNavPage standalonePage pageContainer fullWidthContent vertical flex flex-direction-column align-items-center justify-content-center">
|
||||||
<div class="verticalSection flex-shrink-zero flex flex-direction-column" style="margin: 2em 0 1em;">
|
<div class="verticalSection flex-shrink-zero w-100 flex flex-direction-column">
|
||||||
<div class="padded-left padded-right flex align-items-center justify-content-center" style="margin-bottom:2em;">
|
<div class="padded-left padded-right flex align-items-center justify-content-center">
|
||||||
<h1 class="sectionTitle sectionTitle-cards">${HeaderSelectServer}</h1>
|
<h1 class="sectionTitle sectionTitle-cards">${HeaderSelectServer}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="padded-top padded-bottom-focusscale flex-grow flex" data-horizontal="true" data-centerfocus="card">
|
<div class="padded-top padded-bottom-focusscale flex-grow flex" data-horizontal="true" data-centerfocus="card">
|
||||||
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x padded-left padded-right servers flex-grow" style="display: block; text-align: center;" data-hovermenu="false" data-multiselect="false"></div>
|
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x servers flex-grow" style="display: block; text-align: center;" data-hovermenu="false" data-multiselect="false"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="padded-top padded-left padded-right flex flex-shrink-zero justify-content-center verticalSection flex-wrap-wrap" style="margin-left:auto;margin-right:auto;">
|
<div class="padded-top padded-left padded-right flex flex-shrink-zero justify-content-center verticalSection flex-wrap-wrap" style="margin-left:auto;margin-right:auto;">
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue