mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
merge branch master into config
This commit is contained in:
commit
850df11f27
351 changed files with 12788 additions and 5249 deletions
|
@ -7,38 +7,70 @@ trigger:
|
||||||
tags:
|
tags:
|
||||||
include:
|
include:
|
||||||
- '*'
|
- '*'
|
||||||
|
pr:
|
||||||
|
branches:
|
||||||
|
include:
|
||||||
|
- '*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- job: main_build
|
- job: build
|
||||||
displayName: 'Main Build'
|
displayName: 'Build'
|
||||||
|
|
||||||
dependsOn: lint
|
|
||||||
condition: succeeded()
|
|
||||||
|
|
||||||
pool:
|
pool:
|
||||||
vmImage: 'ubuntu-latest'
|
vmImage: 'ubuntu-latest'
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
Development:
|
||||||
|
BuildConfiguration: development
|
||||||
|
Production:
|
||||||
|
BuildConfiguration: production
|
||||||
|
Standalone:
|
||||||
|
BuildConfiguration: standalone
|
||||||
|
maxParallel: 3
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- task: NodeTool@0
|
- task: NodeTool@0
|
||||||
displayName: 'Install Node'
|
displayName: 'Install Node'
|
||||||
inputs:
|
inputs:
|
||||||
versionSpec: '10.x'
|
versionSpec: '12.x'
|
||||||
|
|
||||||
- script: 'yarn install'
|
- task: Cache@2
|
||||||
|
displayName: 'Check Cache'
|
||||||
|
inputs:
|
||||||
|
key: 'yarn | yarn.lock'
|
||||||
|
path: 'node_modules'
|
||||||
|
cacheHitVar: CACHE_RESTORED
|
||||||
|
|
||||||
|
- script: 'yarn install --frozen-lockfile'
|
||||||
displayName: 'Install Dependencies'
|
displayName: 'Install Dependencies'
|
||||||
|
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||||
|
|
||||||
|
- script: 'yarn build:development'
|
||||||
|
displayName: 'Build Development'
|
||||||
|
condition: eq(variables['BuildConfiguration'], 'development')
|
||||||
|
|
||||||
|
- script: 'yarn build:production'
|
||||||
|
displayName: 'Build Bundle'
|
||||||
|
condition: eq(variables['BuildConfiguration'], 'production')
|
||||||
|
|
||||||
|
- script: 'yarn build:standalone'
|
||||||
|
displayName: 'Build Standalone'
|
||||||
|
condition: eq(variables['BuildConfiguration'], 'standalone')
|
||||||
|
|
||||||
- script: 'test -d dist'
|
- script: 'test -d dist'
|
||||||
displayName: 'Check Build'
|
displayName: 'Check Build'
|
||||||
|
|
||||||
- script: 'yarn pack --filename jellyfin-web.tgz'
|
- script: 'mv dist jellyfin-web'
|
||||||
displayName: 'Bundle Release'
|
displayName: 'Rename Directory'
|
||||||
|
condition: succeeded()
|
||||||
|
|
||||||
- task: PublishPipelineArtifact@1
|
- task: PublishPipelineArtifact@1
|
||||||
displayName: 'Publish Release'
|
displayName: 'Publish Release'
|
||||||
condition: succeeded()
|
condition: succeeded()
|
||||||
inputs:
|
inputs:
|
||||||
targetPath: '$(Build.SourcesDirectory)/jellyfin-web.tgz'
|
targetPath: '$(Build.SourcesDirectory)/jellyfin-web'
|
||||||
artifactName: 'jellyfin-web'
|
artifactName: 'jellyfin-web-$(BuildConfiguration)'
|
||||||
|
|
||||||
- job: lint
|
- job: lint
|
||||||
displayName: 'Lint'
|
displayName: 'Lint'
|
||||||
|
@ -50,14 +82,21 @@ jobs:
|
||||||
- task: NodeTool@0
|
- task: NodeTool@0
|
||||||
displayName: 'Install Node'
|
displayName: 'Install Node'
|
||||||
inputs:
|
inputs:
|
||||||
versionSpec: '10.x'
|
versionSpec: '12.x'
|
||||||
|
|
||||||
- script: 'yarn install'
|
- task: Cache@2
|
||||||
|
displayName: 'Check Cache'
|
||||||
|
inputs:
|
||||||
|
key: 'yarn | yarn.lock'
|
||||||
|
path: 'node_modules'
|
||||||
|
cacheHitVar: CACHE_RESTORED
|
||||||
|
|
||||||
|
- script: 'yarn install --frozen-lockfile'
|
||||||
displayName: 'Install Dependencies'
|
displayName: 'Install Dependencies'
|
||||||
|
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||||
|
|
||||||
- script: 'yarn run lint'
|
- script: 'yarn run lint'
|
||||||
displayName: 'Run ESLint'
|
displayName: 'Run ESLint'
|
||||||
|
|
||||||
- script: |
|
- script: 'yarn run stylelint'
|
||||||
yarn run stylelint
|
displayName: 'Run Stylelint'
|
||||||
displayName: 'Run stylelint'
|
|
||||||
|
|
|
@ -3,25 +3,75 @@ env:
|
||||||
browser: true
|
browser: true
|
||||||
amd: true
|
amd: true
|
||||||
|
|
||||||
|
parserOptions:
|
||||||
|
ecmaVersion: 6
|
||||||
|
sourceType: module
|
||||||
|
ecmaFeatures:
|
||||||
|
impliedStrict: true
|
||||||
|
|
||||||
|
globals:
|
||||||
|
# New browser globals
|
||||||
|
DataView: readonly
|
||||||
|
MediaMetadata: readonly
|
||||||
|
Promise: readonly
|
||||||
|
# Deprecated browser globals
|
||||||
|
DocumentTouch: readonly
|
||||||
|
# Tizen globals
|
||||||
|
tizen: readonly
|
||||||
|
webapis: readonly
|
||||||
|
# WebOS globals
|
||||||
|
webOS: readonly
|
||||||
|
# Dependency globals
|
||||||
|
$: readonly
|
||||||
|
jQuery: readonly
|
||||||
|
queryString: readonly
|
||||||
|
requirejs: readonly
|
||||||
|
# Jellyfin globals
|
||||||
|
ApiClient: writable
|
||||||
|
AppInfo: writable
|
||||||
|
chrome: writable
|
||||||
|
ConnectionManager: writable
|
||||||
|
DlnaProfilePage: writable
|
||||||
|
Dashboard: writable
|
||||||
|
DashboardPage: writable
|
||||||
|
Emby: readonly
|
||||||
|
Events: writable
|
||||||
|
getParameterByName: writable
|
||||||
|
getWindowLocationSearch: writable
|
||||||
|
Globalize: writable
|
||||||
|
Hls: writable
|
||||||
|
humaneDate: writable
|
||||||
|
humaneElapsed: writable
|
||||||
|
LibraryMenu: writable
|
||||||
|
LinkParser: writable
|
||||||
|
LiveTvHelpers: writable
|
||||||
|
MetadataEditor: writable
|
||||||
|
pageClassOn: writable
|
||||||
|
pageIdOn: writable
|
||||||
|
PlaylistViewer: writable
|
||||||
|
UserParentalControlPage: writable
|
||||||
|
Windows: readonly
|
||||||
|
|
||||||
|
extends:
|
||||||
|
- eslint:recommended
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
block-spacing: ["error"]
|
block-spacing: ["error"]
|
||||||
brace-style: ["error"]
|
brace-style: ["error"]
|
||||||
comma-dangle: ["error", "never"]
|
comma-dangle: ["error", "never"]
|
||||||
comma-spacing: ["error"]
|
comma-spacing: ["error"]
|
||||||
eol-last: ["off"]
|
eol-last: ["error"]
|
||||||
indent: ["error", 4, { "SwitchCase": 1 }]
|
indent: ["error", 4, { "SwitchCase": 1 }]
|
||||||
keyword-spacing: ["error"]
|
keyword-spacing: ["error"]
|
||||||
line-comment-position: ["off"]
|
|
||||||
max-statements-per-line: ["error"]
|
max-statements-per-line: ["error"]
|
||||||
no-empty: ["error"]
|
|
||||||
no-extra-semi: ["error"]
|
|
||||||
no-floating-decimal: ["error"]
|
no-floating-decimal: ["error"]
|
||||||
no-multi-spaces: ["error"]
|
no-multi-spaces: ["error"]
|
||||||
no-multiple-empty-lines: ["error", { "max": 1 }]
|
no-multiple-empty-lines: ["error", { "max": 1 }]
|
||||||
no-trailing-spaces: ["error"]
|
no-trailing-spaces: ["error"]
|
||||||
no-void: ["off"]
|
|
||||||
one-var: ["error", "never"]
|
one-var: ["error", "never"]
|
||||||
padding-line-between-statements: ["off"]
|
semi: ["warn"]
|
||||||
semi: ["off"]
|
|
||||||
space-before-blocks: ["error"]
|
space-before-blocks: ["error"]
|
||||||
yoda: ["off"]
|
# TODO: Fix warnings and remove these rules
|
||||||
|
no-redeclare: ["warn"]
|
||||||
|
no-unused-vars: ["warn"]
|
||||||
|
no-useless-escape: ["warn"]
|
||||||
|
|
|
@ -140,4 +140,4 @@
|
||||||
"value-list-comma-space-before": "never",
|
"value-list-comma-space-before": "never",
|
||||||
"value-list-max-empty-lines": 0,
|
"value-list-max-empty-lines": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
- [Daniel Hartung](https://github.com/dhartung)
|
- [Daniel Hartung](https://github.com/dhartung)
|
||||||
- [Ryan Hartzell](https://github.com/ryan-hartzell)
|
- [Ryan Hartzell](https://github.com/ryan-hartzell)
|
||||||
- [Thibault Nocchi](https://github.com/ThibaultNocchi)
|
- [Thibault Nocchi](https://github.com/ThibaultNocchi)
|
||||||
|
- [MrTimscampi](https://github.com/MrTimscampi)
|
||||||
|
|
||||||
# Emby Contributors
|
# Emby Contributors
|
||||||
|
|
||||||
|
|
17
README.md
17
README.md
|
@ -45,20 +45,37 @@ Jellyfin Web is the frontend used for most of the clients available for end user
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
- Yarn
|
- Yarn
|
||||||
|
- Gulp-cli
|
||||||
|
|
||||||
### Getting Started
|
### Getting Started
|
||||||
|
|
||||||
1. Clone or download this repository.
|
1. Clone or download this repository.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/jellyfin/jellyfin-web.git
|
git clone https://github.com/jellyfin/jellyfin-web.git
|
||||||
cd jellyfin-web
|
cd jellyfin-web
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Install build dependencies in the project directory.
|
2. Install build dependencies in the project directory.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yarn install
|
yarn install
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Run the web client with webpack for local development.
|
3. Run the web client with webpack for local development.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yarn serve
|
yarn serve
|
||||||
```
|
```
|
||||||
|
|
||||||
|
4. Build the client with sourcemaps.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yarn build:development
|
||||||
|
```
|
||||||
|
|
||||||
|
You can build a nginx compatible version as well.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yarn build:standalone
|
||||||
|
```
|
201
gulpfile.js
Normal file
201
gulpfile.js
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { src, dest, series, parallel, watch } = require('gulp');
|
||||||
|
const browserSync = require('browser-sync').create();
|
||||||
|
const del = require('del');
|
||||||
|
const babel = require('gulp-babel');
|
||||||
|
const concat = require('gulp-concat');
|
||||||
|
const terser = require('gulp-terser');
|
||||||
|
const htmlmin = require('gulp-htmlmin');
|
||||||
|
const imagemin = require('gulp-imagemin');
|
||||||
|
const sourcemaps = require('gulp-sourcemaps');
|
||||||
|
const mode = require('gulp-mode')({
|
||||||
|
modes: ["development", "production"],
|
||||||
|
default: "development",
|
||||||
|
verbose: false
|
||||||
|
});
|
||||||
|
const stream = require('webpack-stream');
|
||||||
|
const inject = require('gulp-inject');
|
||||||
|
const postcss = require('gulp-postcss');
|
||||||
|
const sass = require('gulp-sass');
|
||||||
|
const gulpif = require('gulp-if');
|
||||||
|
const lazypipe = require('lazypipe');
|
||||||
|
|
||||||
|
sass.compiler = require('node-sass');
|
||||||
|
|
||||||
|
let config;
|
||||||
|
if (mode.production()) {
|
||||||
|
config = require('./webpack.prod.js');
|
||||||
|
} else {
|
||||||
|
config = require('./webpack.dev.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
javascript: {
|
||||||
|
query: ['src/**/*.js', '!src/bundle.js', '!src/standalone.js', '!src/scripts/apploader.js']
|
||||||
|
},
|
||||||
|
apploader: {
|
||||||
|
query: ['src/standalone.js', 'src/scripts/apploader.js']
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
query: ['src/**/*.css', 'src/**/*.scss']
|
||||||
|
},
|
||||||
|
html: {
|
||||||
|
query: ['src/**/*.html', '!src/index.html']
|
||||||
|
},
|
||||||
|
images: {
|
||||||
|
query: ['src/**/*.png', 'src/**/*.jpg', 'src/**/*.gif', 'src/**/*.svg']
|
||||||
|
},
|
||||||
|
copy: {
|
||||||
|
query: ['src/**/*.json', 'src/**/*.ico']
|
||||||
|
},
|
||||||
|
injectBundle: {
|
||||||
|
query: 'src/index.html'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function serve() {
|
||||||
|
browserSync.init({
|
||||||
|
server: {
|
||||||
|
baseDir: "./dist"
|
||||||
|
},
|
||||||
|
port: 8080
|
||||||
|
});
|
||||||
|
|
||||||
|
let events = ['add', 'change'];
|
||||||
|
|
||||||
|
watch(options.javascript.query).on('all', function (event, path) {
|
||||||
|
if (events.includes(event)) {
|
||||||
|
javascript(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(options.apploader.query, apploader(true));
|
||||||
|
|
||||||
|
watch('src/bundle.js', webpack);
|
||||||
|
|
||||||
|
watch(options.css.query).on('all', function (event, path) {
|
||||||
|
if (events.includes(event)) {
|
||||||
|
css(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(options.html.query).on('all', function (event, path) {
|
||||||
|
if (events.includes(event)) {
|
||||||
|
html(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(options.images.query).on('all', function (event, path) {
|
||||||
|
if (events.includes(event)) {
|
||||||
|
images(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(options.copy.query).on('all', function (event, path) {
|
||||||
|
if (events.includes(event)) {
|
||||||
|
copy(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(options.injectBundle.query, injectBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clean() {
|
||||||
|
return del(['dist/']);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pipelineJavascript = lazypipe()
|
||||||
|
.pipe(function () {
|
||||||
|
return mode.development(sourcemaps.init({ loadMaps: true }));
|
||||||
|
})
|
||||||
|
.pipe(function () {
|
||||||
|
return babel({
|
||||||
|
presets: [
|
||||||
|
['@babel/preset-env']
|
||||||
|
]
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.pipe(function () {
|
||||||
|
return terser({
|
||||||
|
keep_fnames: true,
|
||||||
|
mangle: false
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.pipe(function () {
|
||||||
|
return mode.development(sourcemaps.write('.'));
|
||||||
|
});
|
||||||
|
|
||||||
|
function javascript(query) {
|
||||||
|
return src(typeof query !== 'function' ? query : options.javascript.query, { base: './src/' })
|
||||||
|
.pipe(pipelineJavascript())
|
||||||
|
.pipe(dest('dist/'))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
function apploader(standalone) {
|
||||||
|
function task() {
|
||||||
|
return src(options.apploader.query, { base: './src/' })
|
||||||
|
.pipe(gulpif(standalone, concat('scripts/apploader.js')))
|
||||||
|
.pipe(pipelineJavascript())
|
||||||
|
.pipe(dest('dist/'))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
};
|
||||||
|
|
||||||
|
task.displayName = 'apploader';
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
function webpack() {
|
||||||
|
return stream(config)
|
||||||
|
.pipe(dest('dist/'))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
function css(query) {
|
||||||
|
return src(typeof query !== 'function' ? query : options.css.query, { base: './src/' })
|
||||||
|
.pipe(mode.development(sourcemaps.init({ loadMaps: true })))
|
||||||
|
.pipe(sass().on('error', sass.logError))
|
||||||
|
.pipe(postcss())
|
||||||
|
.pipe(mode.development(sourcemaps.write('.')))
|
||||||
|
.pipe(dest('dist/'))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
function html(query) {
|
||||||
|
return src(typeof query !== 'function' ? query : options.html.query, { base: './src/' })
|
||||||
|
.pipe(mode.production(htmlmin({ collapseWhitespace: true })))
|
||||||
|
.pipe(dest('dist/'))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
function images(query) {
|
||||||
|
return src(typeof query !== 'function' ? query : options.images.query, { base: './src/' })
|
||||||
|
.pipe(mode.production(imagemin()))
|
||||||
|
.pipe(dest('dist/'))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
function copy(query) {
|
||||||
|
return src(typeof query !== 'function' ? query : options.copy.query, { base: './src/' })
|
||||||
|
.pipe(dest('dist/'))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
function injectBundle() {
|
||||||
|
return src(options.injectBundle.query, { base: './src/' })
|
||||||
|
.pipe(inject(
|
||||||
|
src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), { relative: true }
|
||||||
|
))
|
||||||
|
.pipe(dest('dist/'))
|
||||||
|
.pipe(browserSync.stream());
|
||||||
|
}
|
||||||
|
|
||||||
|
function build(standalone) {
|
||||||
|
return series(clean, parallel(javascript, apploader(standalone), webpack, css, html, images, copy), injectBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.default = build(false);
|
||||||
|
exports.standalone = build(true);
|
||||||
|
exports.serve = series(exports.standalone, serve);
|
72
package.json
72
package.json
|
@ -5,12 +5,38 @@
|
||||||
"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.8.6",
|
||||||
|
"@babel/plugin-transform-modules-amd": "^7.8.3",
|
||||||
|
"@babel/polyfill": "^7.8.7",
|
||||||
|
"@babel/preset-env": "^7.8.6",
|
||||||
|
"autoprefixer": "^9.7.4",
|
||||||
|
"babel-loader": "^8.0.6",
|
||||||
|
"browser-sync": "^2.26.7",
|
||||||
"clean-webpack-plugin": "^3.0.0",
|
"clean-webpack-plugin": "^3.0.0",
|
||||||
"copy-webpack-plugin": "^5.1.1",
|
"copy-webpack-plugin": "^5.1.1",
|
||||||
"css-loader": "^3.4.2",
|
"css-loader": "^3.4.2",
|
||||||
|
"cssnano": "^4.1.10",
|
||||||
|
"del": "^5.1.0",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"file-loader": "^5.0.2",
|
"file-loader": "^6.0.0",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"gulp": "^4.0.2",
|
||||||
|
"gulp-babel": "^8.0.0",
|
||||||
|
"gulp-cli": "^2.2.0",
|
||||||
|
"gulp-concat": "^2.6.1",
|
||||||
|
"gulp-htmlmin": "^5.0.1",
|
||||||
|
"gulp-if": "^3.0.0",
|
||||||
|
"gulp-imagemin": "^7.1.0",
|
||||||
|
"gulp-inject": "^5.0.5",
|
||||||
|
"gulp-mode": "^1.0.2",
|
||||||
|
"gulp-postcss": "^8.0.0",
|
||||||
|
"gulp-sass": "^4.0.2",
|
||||||
|
"gulp-sourcemaps": "^2.6.5",
|
||||||
|
"gulp-terser": "^1.2.0",
|
||||||
|
"html-webpack-plugin": "^4.0.2",
|
||||||
|
"lazypipe": "^1.0.2",
|
||||||
|
"node-sass": "^4.13.1",
|
||||||
|
"postcss-loader": "^3.0.0",
|
||||||
|
"postcss-preset-env": "^6.7.0",
|
||||||
"style-loader": "^1.1.3",
|
"style-loader": "^1.1.3",
|
||||||
"stylelint": "^13.1.0",
|
"stylelint": "^13.1.0",
|
||||||
"stylelint-config-rational-order": "^0.1.2",
|
"stylelint-config-rational-order": "^0.1.2",
|
||||||
|
@ -20,10 +46,12 @@
|
||||||
"webpack-cli": "^3.3.10",
|
"webpack-cli": "^3.3.10",
|
||||||
"webpack-concat-plugin": "^3.0.0",
|
"webpack-concat-plugin": "^3.0.0",
|
||||||
"webpack-dev-server": "^3.10.3",
|
"webpack-dev-server": "^3.10.3",
|
||||||
"webpack-merge": "^4.2.2"
|
"webpack-merge": "^4.2.2",
|
||||||
|
"webpack-stream": "^5.2.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"alameda": "^1.4.0",
|
"alameda": "^1.4.0",
|
||||||
|
"core-js": "^3.6.4",
|
||||||
"document-register-element": "^1.14.3",
|
"document-register-element": "^1.14.3",
|
||||||
"flv.js": "^1.5.0",
|
"flv.js": "^1.5.0",
|
||||||
"hls.js": "^0.13.1",
|
"hls.js": "^0.13.1",
|
||||||
|
@ -31,18 +59,37 @@
|
||||||
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
|
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
"jstree": "^3.3.7",
|
"jstree": "^3.3.7",
|
||||||
"libass-wasm": "^2.1.1",
|
"libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf",
|
||||||
"libjass": "^0.11.0",
|
|
||||||
"material-design-icons-iconfont": "^5.0.1",
|
"material-design-icons-iconfont": "^5.0.1",
|
||||||
"native-promise-only": "^0.8.0-a",
|
"native-promise-only": "^0.8.0-a",
|
||||||
"requirejs": "^2.3.5",
|
"page": "^1.11.5",
|
||||||
|
"query-string": "^6.11.1",
|
||||||
"resize-observer-polyfill": "^1.5.1",
|
"resize-observer-polyfill": "^1.5.1",
|
||||||
"shaka-player": "^2.5.9",
|
"shaka-player": "^2.5.10",
|
||||||
"sortablejs": "^1.10.2",
|
"sortablejs": "^1.10.2",
|
||||||
"swiper": "^5.3.1",
|
"swiper": "^5.3.1",
|
||||||
"webcomponents.js": "^0.7.24",
|
"webcomponents.js": "^0.7.24",
|
||||||
"whatwg-fetch": "^3.0.0"
|
"whatwg-fetch": "^3.0.0"
|
||||||
},
|
},
|
||||||
|
"babel": {
|
||||||
|
"presets": [
|
||||||
|
"@babel/preset-env"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"test": [
|
||||||
|
"src/components/cardbuilder/cardBuilder.js",
|
||||||
|
"src/components/filedownloader.js",
|
||||||
|
"src/components/filesystem.js",
|
||||||
|
"src/components/input/keyboardnavigation.js",
|
||||||
|
"src/components/sanatizefilename.js"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@babel/plugin-transform-modules-amd"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"last 2 Firefox versions",
|
"last 2 Firefox versions",
|
||||||
"last 2 Chrome versions",
|
"last 2 Chrome versions",
|
||||||
|
@ -50,6 +97,7 @@
|
||||||
"last 2 Safari versions",
|
"last 2 Safari versions",
|
||||||
"last 2 iOS versions",
|
"last 2 iOS versions",
|
||||||
"last 2 Edge versions",
|
"last 2 Edge versions",
|
||||||
|
"Chrome 27",
|
||||||
"Chrome 38",
|
"Chrome 38",
|
||||||
"Chrome 47",
|
"Chrome 47",
|
||||||
"Chrome 53",
|
"Chrome 53",
|
||||||
|
@ -58,10 +106,12 @@
|
||||||
"Firefox ESR"
|
"Firefox ESR"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "webpack-dev-server --config webpack.dev.js --open",
|
"serve": "gulp serve",
|
||||||
"build": "webpack --config webpack.prod.js",
|
"prepare": "gulp --production",
|
||||||
|
"build:development": "gulp --development",
|
||||||
|
"build:production": "gulp --production",
|
||||||
|
"build:standalone": "gulp standalone --development",
|
||||||
"lint": "eslint \"src\"",
|
"lint": "eslint \"src\"",
|
||||||
"stylelint": "stylelint \"src/**/*.css\"",
|
"stylelint": "stylelint \"src/**/*.css\""
|
||||||
"prepare": "webpack --config webpack.prod.js"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
postcss.config.js
Normal file
11
postcss.config.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
const postcssPresetEnv = require('postcss-preset-env');
|
||||||
|
const cssnano = require('cssnano');
|
||||||
|
|
||||||
|
const config = () => ({
|
||||||
|
plugins: [
|
||||||
|
postcssPresetEnv(),
|
||||||
|
cssnano()
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = config
|
|
@ -63,6 +63,10 @@ progress[aria-valuenow]::before {
|
||||||
}
|
}
|
||||||
|
|
||||||
.adminDrawerLogo {
|
.adminDrawerLogo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-mobile .adminDrawerLogo {
|
||||||
padding: 1.5em 1em 1.2em;
|
padding: 1.5em 1em 1.2em;
|
||||||
border-bottom: 1px solid #e0e0e0;
|
border-bottom: 1px solid #e0e0e0;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
@ -161,7 +165,7 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||||
|
|
||||||
@media all and (min-width: 40em) {
|
@media all and (min-width: 40em) {
|
||||||
.content-primary {
|
.content-primary {
|
||||||
padding-top: 7em;
|
padding-top: 4.6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.withTabs .content-primary {
|
.withTabs .content-primary {
|
||||||
|
|
|
@ -29,7 +29,7 @@ h3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-tv {
|
.layout-tv {
|
||||||
font-size: 2.5vh;
|
font-size: 130%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mobile {
|
.layout-mobile {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.libraryPage {
|
.libraryPage {
|
||||||
padding-top: 7em !important;
|
padding-top: 7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemDetailPage {
|
.itemDetailPage {
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
display: -webkit-inline-box;
|
display: -webkit-inline-box;
|
||||||
display: -webkit-inline-flex;
|
display: -webkit-inline-flex;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
margin: 0.3em 0 0 0.5em;
|
margin: 0 0 0 0.5em;
|
||||||
height: 1.7em;
|
height: 1.7em;
|
||||||
-webkit-box-align: center;
|
-webkit-box-align: center;
|
||||||
-webkit-align-items: center;
|
-webkit-align-items: center;
|
||||||
|
@ -128,6 +128,10 @@
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-mobile .pageTitleWithDefaultLogo {
|
||||||
|
background-image: url(../img/icon-transparent.png);
|
||||||
|
}
|
||||||
|
|
||||||
.headerLeft,
|
.headerLeft,
|
||||||
.skinHeader {
|
.skinHeader {
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
@ -227,6 +231,7 @@
|
||||||
.centerMessage {
|
.centerMessage {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
width: 30%;
|
width: 30%;
|
||||||
|
padding: 5em 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +246,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-width: 40em) {
|
@media all and (min-width: 40em) {
|
||||||
.dashboardDocument .adminDrawerLogo,
|
|
||||||
.dashboardDocument .mainDrawerButton {
|
.dashboardDocument .mainDrawerButton {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
@ -267,12 +271,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (max-width: 60em) {
|
|
||||||
.libraryDocument .mainDrawerButton {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all and (max-width: 84em) {
|
@media all and (max-width: 84em) {
|
||||||
.withSectionTabs .headerTop {
|
.withSectionTabs .headerTop {
|
||||||
padding-bottom: 0.55em;
|
padding-bottom: 0.55em;
|
||||||
|
@ -315,7 +313,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboardDocument .mainDrawer-scrollContainer {
|
.dashboardDocument .mainDrawer-scrollContainer {
|
||||||
margin-top: 6em !important;
|
margin-top: 4.6em !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,10 +436,46 @@
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
background-attachment: fixed;
|
||||||
height: 50vh;
|
height: 50vh;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-mobile .itemBackdrop {
|
||||||
|
background-attachment: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .itemBackdrop::after,
|
||||||
|
.layout-tv .itemBackdrop::after {
|
||||||
|
content: "";
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.65);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .noBackdrop .itemBackdrop,
|
||||||
|
.layout-tv .noBackdrop .itemBackdrop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailPageContent {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-left: 2%;
|
||||||
|
padding-right: 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .noBackdrop .detailPageContent,
|
||||||
|
.layout-tv .noBackdrop .detailPageContent {
|
||||||
|
margin-top: 2.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .noBackdrop .detailImageContainer img,
|
||||||
|
.layout-tv .noBackdrop .detailImageContainer img {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.personBackdrop {
|
.personBackdrop {
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
@ -502,14 +536,13 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailPagePrimaryContainer {
|
.detailPagePrimaryContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
position: sticky;
|
|
||||||
top: 3.85em;
|
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,12 +552,21 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-tv .detailPagePrimaryContainer {
|
.layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer,
|
||||||
|
.layout-desktop #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
padding-left: 32.45vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailSticky {
|
.layout-desktop .detailSticky,
|
||||||
background-color: #101010;
|
.layout-tv .detailSticky {
|
||||||
|
margin-top: -7.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-desktop .noBackdrop .detailSticky,
|
||||||
|
.layout-tv .noBackdrop .detailSticky {
|
||||||
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.infoWrapper {
|
.infoWrapper {
|
||||||
|
@ -546,23 +588,17 @@
|
||||||
margin: 1.25em 0;
|
margin: 1.25em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailPageContent {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding-left: 2%;
|
|
||||||
padding-right: 2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detailImageContainer {
|
.detailImageContainer {
|
||||||
position: sticky;
|
position: relative;
|
||||||
top: 25%;
|
margin-top: -25vh;
|
||||||
float: left;
|
float: left;
|
||||||
width: 22.786458333333332vw;
|
width: 25vw;
|
||||||
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mobile .detailImageContainer,
|
.layout-desktop .noBackdrop .detailImageContainer,
|
||||||
.layout-tv .detailImageContainer {
|
.layout-tv .noBackdrop .detailImageContainer {
|
||||||
position: relative;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailPagePrimaryContent {
|
.detailPagePrimaryContent {
|
||||||
|
@ -570,15 +606,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.detailLogo {
|
.detailLogo {
|
||||||
width: 25em;
|
width: 67.25vw;
|
||||||
height: 9.375em;
|
height: 14.5vh;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 14.5%;
|
top: 15vh;
|
||||||
right: 10.5%;
|
right: 0;
|
||||||
-webkit-background-size: contain;
|
-webkit-background-size: contain;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noBackdrop .detailLogo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
@media all and (max-width: 87.5em) {
|
@media all and (max-width: 87.5em) {
|
||||||
.detailLogo {
|
.detailLogo {
|
||||||
right: 5%;
|
right: 5%;
|
||||||
|
@ -605,8 +645,27 @@
|
||||||
|
|
||||||
.itemDetailImage {
|
.itemDetailImage {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
box-shadow: 0 0.0725em 0.29em 0 rgba(0, 0, 0, 0.37);
|
-webkit-box-shadow: 0 0.1em 0.5em 0 rgba(0, 0, 0, 0.75);
|
||||||
-webkit-box-shadow: 0 0.0725em 0.29em 0 rgba(0, 0, 0, 0.37);
|
box-shadow: 0 0.1em 0.5em 0 rgba(0, 0, 0, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.itemDetailGalleryLink.defaultCardBackground {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemDetailGalleryLink.defaultCardBackground {
|
||||||
|
height: 23vw; /* Dirty hack to get it to look somewhat square. Less than ideal. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnSyncComplete i {
|
||||||
|
-webkit-border-radius: 100em;
|
||||||
|
border-radius: 100em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemDetailGalleryLink.defaultCardBackground > i {
|
||||||
|
font-size: 15vw;
|
||||||
|
margin-top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (max-width: 62.5em) {
|
@media all and (max-width: 62.5em) {
|
||||||
|
@ -614,6 +673,16 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-desktop .detailPageWrapperContainer,
|
||||||
|
.layout-tv .detailPageWrapperContainer {
|
||||||
|
margin-top: 7.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer,
|
||||||
|
.layout-desktop #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer {
|
||||||
|
padding-left: 3.3%;
|
||||||
|
}
|
||||||
|
|
||||||
.btnPlaySimple {
|
.btnPlaySimple {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
@ -629,11 +698,6 @@
|
||||||
background: #673ab7 !important;
|
background: #673ab7 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btnSyncComplete i {
|
|
||||||
-webkit-border-radius: 100em;
|
|
||||||
border-radius: 100em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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) !important;
|
||||||
|
@ -787,7 +851,7 @@
|
||||||
width: auto;
|
width: auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-top: -4.3em;
|
margin-top: -4.2em;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,6 +897,11 @@
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-desktop .noBackdrop .detailPageWrapperContainer,
|
||||||
|
.layout-tv .noBackdrop .detailPageWrapperContainer {
|
||||||
|
margin-top: 3.8em;
|
||||||
|
}
|
||||||
|
|
||||||
.mediaInfoStream {
|
.mediaInfoStream {
|
||||||
margin: 0 3em 0 0;
|
margin: 0 3em 0 0;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -882,12 +951,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (max-width: 75em) {
|
.listViewUserDataButtons {
|
||||||
.listViewUserDataButtons {
|
display: flex;
|
||||||
display: flex;
|
align-items: center;
|
||||||
align-items: center;
|
|
||||||
font-size: 65%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bulletSeparator {
|
.bulletSeparator {
|
||||||
|
@ -1053,3 +1119,50 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||||
.itemsViewSettingsContainer > .button-flat {
|
.itemsViewSettingsContainer > .button-flat {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.layout-mobile #myPreferencesMenuPage {
|
||||||
|
padding-top: 3.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemDetailsGroup {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trackSelections {
|
||||||
|
max-width: 44em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailsGroupItem,
|
||||||
|
.trackSelections .selectContainer {
|
||||||
|
display: flex;
|
||||||
|
max-width: 44em;
|
||||||
|
margin: 0 0 0.5em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trackSelections .selectContainer {
|
||||||
|
margin: 0 0 0.3em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailsGroupItem .label,
|
||||||
|
.trackSelections .selectContainer .selectLabel {
|
||||||
|
cursor: default;
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-basis: 6.25em;
|
||||||
|
margin: 0 0.6em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trackSelections .selectContainer .selectLabel {
|
||||||
|
margin: 0 0.2em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trackSelections .selectContainer .detailTrackSelect {
|
||||||
|
font-size: inherit;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trackSelections .selectContainer .selectArrowContainer .selectArrow {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,11 @@ html {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
/* Fix font ligatures on older WebOS versions */
|
||||||
|
-webkit-font-feature-settings: "liga";
|
||||||
|
}
|
||||||
|
|
||||||
.backgroundContainer {
|
.backgroundContainer {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M24 19H0a13.6 13.6 0 0 1 2.21-6.07A11.2 11.2 0 0 1 5.87 9.4l.41-.23-2.02-3.41a.51.51 0 0 1 .17-.7.5.5 0 0 1 .69.18l2.08 3.5a12.62 12.62 0 0 1 4.84-.9 12.2 12.2 0 0 1 4.75.9l2.07-3.5a.5.5 0 0 1 .7-.17.51.51 0 0 1 .16.7L17.7 9.19l.5.28a11.38 11.38 0 0 1 3.63 3.62A14.48 14.48 0 0 1 24 19zm-7.5-4.48a1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1 1 1 0 0 0-1 1zm-11 0a1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1 1 1 0 0 0-1 1z"/>
|
<path d="M24 19H0a13.6 13.6 0 0 1 2.21-6.07A11.2 11.2 0 0 1 5.87 9.4l.41-.23-2.02-3.41a.51.51 0 0 1 .17-.7.5.5 0 0 1 .69.18l2.08 3.5a12.62 12.62 0 0 1 4.84-.9 12.2 12.2 0 0 1 4.75.9l2.07-3.5a.5.5 0 0 1 .7-.17.51.51 0 0 1 .16.7L17.7 9.19l.5.28a11.38 11.38 0 0 1 3.63 3.62A14.48 14.48 0 0 1 24 19zm-7.5-4.48a1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1 1 1 0 0 0-1 1zm-11 0a1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1 1 1 0 0 0-1 1z" fill="#fff"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 563 B |
20
src/assets/img/fresh.svg
Normal file
20
src/assets/img/fresh.svg
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg id="svg3390" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="141.25" viewBox="0 0 138.75 141.25" width="138.75" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<metadata id="metadata3396">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||||
|
<dc:title/>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g id="layer1" fill="#f93208">
|
||||||
|
<path id="path3412" d="m20.154 40.829c-28.149 27.622-13.657 61.011-5.734 71.931 35.254 41.954 92.792 25.339 111.89-5.9071 4.7608-8.2027 22.554-53.467-23.976-78.009z"/>
|
||||||
|
<path id="path3471" d="m39.613 39.265 4.7778-8.8607 28.406-5.0384 11.119 9.2082z"/>
|
||||||
|
</g>
|
||||||
|
<g id="layer2">
|
||||||
|
<path id="path3437" d="m39.436 8.5696 8.9682-5.2826 6.7569 15.479c3.7925-6.3226 13.79-16.316 24.939-4.6684-4.7281 1.2636-7.5161 3.8553-7.7397 8.4768 15.145-4.1697 31.343 3.2127 33.539 9.0911-10.951-4.314-27.695 10.377-41.771 2.334 0.009 15.045-12.617 16.636-19.902 17.076 2.077-4.996 5.591-9.994 1.474-14.987-7.618 8.171-13.874 10.668-33.17 4.668 4.876-1.679 14.843-11.39 24.448-11.425-6.775-2.467-12.29-2.087-17.814-1.475 2.917-3.961 12.149-15.197 28.625-8.476z" fill="#02902e"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
1
src/assets/img/rotten.svg
Normal file
1
src/assets/img/rotten.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="145" height="140"><path fill="#0fc755" d="M47.4 35.342c-13.607-7.935-12.32-25.203 2.097-31.88 26.124-6.531 29.117 13.78 22.652 30.412-6.542 24.11 18.095 23.662 19.925 10.067 3.605-18.412 19.394-26.695 31.67-16.359 12.598 12.135 7.074 36.581-17.827 34.187-16.03-1.545-19.552 19.585.839 21.183 32.228 1.915 42.49 22.167 31.04 35.865-15.993 15.15-37.691-4.439-45.512-19.505-6.8-9.307-17.321.11-13.423 6.502 12.983 19.465 2.923 31.229-10.906 30.62-13.37-.85-20.96-9.06-13.214-29.15 3.897-12.481-8.595-15.386-16.57-5.45-11.707 19.61-28.865 13.68-33.976 4.19-3.243-7.621-2.921-25.846 24.119-23.696 16.688 4.137 11.776-12.561-.63-13.633-9.245-.443-30.501-7.304-22.86-24.54 7.34-11.056 24.958-11.768 33.348 6.293 3.037 4.232 8.361 11.042 18.037 5.033 3.51-5.197 1.21-13.9-8.809-20.135z"/></svg>
|
After Width: | Height: | Size: 833 B |
|
@ -5,4 +5,4 @@
|
||||||
<div id="pluginTiles" style="text-align:left;"></div>
|
<div id="pluginTiles" style="text-align:left;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,6 +16,12 @@ _define("fetch", function() {
|
||||||
return fetch
|
return fetch
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// query-string
|
||||||
|
var query = require("query-string");
|
||||||
|
_define("queryString", function() {
|
||||||
|
return query;
|
||||||
|
});
|
||||||
|
|
||||||
// flvjs
|
// flvjs
|
||||||
var flvjs = require("flv.js/dist/flv").default;
|
var flvjs = require("flv.js/dist/flv").default;
|
||||||
_define("flvjs", function() {
|
_define("flvjs", function() {
|
||||||
|
@ -47,12 +53,6 @@ _define("howler", function() {
|
||||||
return howler;
|
return howler;
|
||||||
});
|
});
|
||||||
|
|
||||||
// native-promise-only
|
|
||||||
var nativePromise = require("native-promise-only");
|
|
||||||
_define("native-promise-only", function() {
|
|
||||||
return nativePromise;
|
|
||||||
});
|
|
||||||
|
|
||||||
// resize-observer-polyfill
|
// resize-observer-polyfill
|
||||||
var resize = require("resize-observer-polyfill").default;
|
var resize = require("resize-observer-polyfill").default;
|
||||||
_define("resize-observer-polyfill", function() {
|
_define("resize-observer-polyfill", function() {
|
||||||
|
@ -66,7 +66,7 @@ _define("shaka", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// swiper
|
// swiper
|
||||||
var swiper = require("swiper");
|
var swiper = require("swiper/js/swiper");
|
||||||
require("swiper/css/swiper.min.css");
|
require("swiper/css/swiper.min.css");
|
||||||
_define("swiper", function() {
|
_define("swiper", function() {
|
||||||
return swiper;
|
return swiper;
|
||||||
|
@ -81,14 +81,7 @@ _define("sortable", function() {
|
||||||
// webcomponents
|
// webcomponents
|
||||||
var webcomponents = require("webcomponents.js/webcomponents-lite");
|
var webcomponents = require("webcomponents.js/webcomponents-lite");
|
||||||
_define("webcomponents", function() {
|
_define("webcomponents", function() {
|
||||||
return webcomponents
|
return webcomponents;
|
||||||
});
|
|
||||||
|
|
||||||
// libjass
|
|
||||||
var libjass = require("libjass");
|
|
||||||
require("libjass/libjass.css");
|
|
||||||
_define("libjass", function() {
|
|
||||||
return libjass;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// libass-wasm
|
// libass-wasm
|
||||||
|
@ -103,7 +96,19 @@ _define("material-icons", function() {
|
||||||
return material_icons;
|
return material_icons;
|
||||||
});
|
});
|
||||||
|
|
||||||
var jellyfin_noto = require("jellyfin-noto");
|
// noto font
|
||||||
|
var noto = require("jellyfin-noto");
|
||||||
_define("jellyfin-noto", function () {
|
_define("jellyfin-noto", function () {
|
||||||
return jellyfin_noto;
|
return noto;
|
||||||
|
});
|
||||||
|
|
||||||
|
// page.js
|
||||||
|
var page = require("page");
|
||||||
|
_define("page", function() {
|
||||||
|
return page;
|
||||||
|
});
|
||||||
|
|
||||||
|
var polyfill = require("@babel/polyfill/dist/polyfill");
|
||||||
|
_define("polyfill", function () {
|
||||||
|
return polyfill;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
|
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons arrow_back"></i>
|
||||||
</button>
|
</button>
|
||||||
<h3 class="formDialogHeaderTitle">
|
<h3 class="formDialogHeaderTitle">
|
||||||
${HeaderAccessSchedule}
|
${HeaderAccessSchedule}
|
||||||
|
|
|
@ -158,7 +158,7 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layoutManager.tv) {
|
if (layoutManager.tv) {
|
||||||
html += '<button is="paper-icon-button-light" class="btnCloseActionSheet hide-mouse-idle-tv" tabindex="-1"><i class="material-icons">arrow_back</i></button>';
|
html += '<button is="paper-icon-button-light" class="btnCloseActionSheet hide-mouse-idle-tv" tabindex="-1"><i class="material-icons arrow_back"></i></button>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// If any items have an icon, give them all an icon just to make sure they're all lined up evenly
|
// If any items have an icon, give them all an icon just to make sure they're all lined up evenly
|
||||||
|
|
|
@ -42,4 +42,4 @@ define(['browser', 'dialog', 'globalize'], function (browser, dialog, globalize)
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,7 +10,7 @@ define(['dom', 'focusManager'], function (dom, focusManager) {
|
||||||
if (e.ctrlKey) {
|
if (e.ctrlKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!!e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.altKey) {
|
if (e.altKey) {
|
||||||
|
@ -127,4 +127,4 @@ define(['dom', 'focusManager'], function (dom, focusManager) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return AlphaNumericShortcuts;
|
return AlphaNumericShortcuts;
|
||||||
});
|
});
|
||||||
|
|
|
@ -67,7 +67,7 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b
|
||||||
|
|
||||||
html += '<div class="' + rowClassName + '">';
|
html += '<div class="' + rowClassName + '">';
|
||||||
if (options.mode === 'keyboard') {
|
if (options.mode === 'keyboard') {
|
||||||
html += '<button data-value=" " is="paper-icon-button-light" class="' + alphaPickerButtonClassName + '"><i class="material-icons alphaPickerButtonIcon">space_bar</i></button>';
|
html += '<button data-value=" " is="paper-icon-button-light" class="' + alphaPickerButtonClassName + '"><i class="material-icons alphaPickerButtonIcon space_bar"></i></button>';
|
||||||
} else {
|
} else {
|
||||||
letters = ['#'];
|
letters = ['#'];
|
||||||
html += mapLetters(letters, vertical).join('');
|
html += mapLetters(letters, vertical).join('');
|
||||||
|
@ -241,7 +241,7 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b
|
||||||
try {
|
try {
|
||||||
btn = element.querySelector('.alphaPickerButton[data-value=\'' + value + '\']');
|
btn = element.querySelector('.alphaPickerButton[data-value=\'' + value + '\']');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Error in querySelector: ' + err);
|
console.error('error in querySelector: ' + err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btn && btn !== selected) {
|
if (btn && btn !== selected) {
|
||||||
|
|
|
@ -14,6 +14,9 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
},
|
},
|
||||||
showSettings: function () {
|
showSettings: function () {
|
||||||
show('/settings/settings.html');
|
show('/settings/settings.html');
|
||||||
|
},
|
||||||
|
showNowPlaying: function () {
|
||||||
|
show("/nowplaying.html");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -367,7 +370,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableNativeHistory() {
|
function enableNativeHistory() {
|
||||||
return page.enableNativeHistory();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function authenticate(ctx, route, callback) {
|
function authenticate(ctx, route, callback) {
|
||||||
|
@ -387,13 +390,13 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
var apiClient = connectionManager.currentApiClient();
|
var apiClient = connectionManager.currentApiClient();
|
||||||
var pathname = ctx.pathname.toLowerCase();
|
var pathname = ctx.pathname.toLowerCase();
|
||||||
|
|
||||||
console.log('appRouter - processing path request ' + pathname);
|
console.debug('appRouter - processing path request ' + pathname);
|
||||||
|
|
||||||
var isCurrentRouteStartup = currentRouteInfo ? currentRouteInfo.route.startup : true;
|
var isCurrentRouteStartup = currentRouteInfo ? currentRouteInfo.route.startup : true;
|
||||||
var shouldExitApp = ctx.isBack && route.isDefaultRoute && isCurrentRouteStartup;
|
var shouldExitApp = ctx.isBack && route.isDefaultRoute && isCurrentRouteStartup;
|
||||||
|
|
||||||
if (!shouldExitApp && (!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) {
|
if (!shouldExitApp && (!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) {
|
||||||
console.log('appRouter - route does not allow anonymous access, redirecting to login');
|
console.debug('appRouter - route does not allow anonymous access, redirecting to login');
|
||||||
beginConnectionWizard();
|
beginConnectionWizard();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -408,10 +411,10 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
|
|
||||||
if (apiClient && apiClient.isLoggedIn()) {
|
if (apiClient && apiClient.isLoggedIn()) {
|
||||||
|
|
||||||
console.log('appRouter - user is authenticated');
|
console.debug('appRouter - user is authenticated');
|
||||||
|
|
||||||
if (route.isDefaultRoute) {
|
if (route.isDefaultRoute) {
|
||||||
console.log('appRouter - loading skin home page');
|
console.debug('appRouter - loading skin home page');
|
||||||
loadUserSkinWithOptions(ctx);
|
loadUserSkinWithOptions(ctx);
|
||||||
return;
|
return;
|
||||||
} else if (route.roles) {
|
} else if (route.roles) {
|
||||||
|
@ -425,7 +428,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('appRouter - proceeding to ' + pathname);
|
console.debug('appRouter - proceeding to ' + pathname);
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,9 +511,16 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
return baseRoute;
|
return baseRoute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var popstateOccurred = false;
|
||||||
|
window.addEventListener('popstate', function () {
|
||||||
|
popstateOccurred = true;
|
||||||
|
});
|
||||||
|
|
||||||
function getHandler(route) {
|
function getHandler(route) {
|
||||||
return function (ctx, next) {
|
return function (ctx, next) {
|
||||||
|
ctx.isBack = popstateOccurred;
|
||||||
handleRoute(ctx, next, route);
|
handleRoute(ctx, next, route);
|
||||||
|
popstateOccurred = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,7 +569,10 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
if (!document.querySelector('.dialogContainer') && startPages.indexOf(curr.type) !== -1) {
|
if (!document.querySelector('.dialogContainer') && startPages.indexOf(curr.type) !== -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return page.canGoBack();
|
if (enableHistory()) {
|
||||||
|
return history.length > 1;
|
||||||
|
}
|
||||||
|
return (page.len || 0) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showDirect(path) {
|
function showDirect(path) {
|
||||||
|
@ -663,7 +676,8 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
|
|
||||||
function pushState(state, title, url) {
|
function pushState(state, title, url) {
|
||||||
state.navigate = false;
|
state.navigate = false;
|
||||||
page.pushState(state, title, url);
|
history.pushState(state, title, url);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBaseRoute() {
|
function setBaseRoute() {
|
||||||
|
@ -672,7 +686,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
baseRoute = baseRoute.substring(0, baseRoute.length - 1);
|
baseRoute = baseRoute.substring(0, baseRoute.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Setting page base to ' + baseRoute);
|
console.debug('setting page base to ' + baseRoute);
|
||||||
page.base(baseRoute);
|
page.base(baseRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,7 +727,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||||
appRouter.getRoutes = getRoutes;
|
appRouter.getRoutes = getRoutes;
|
||||||
appRouter.pushState = pushState;
|
appRouter.pushState = pushState;
|
||||||
appRouter.enableNativeHistory = enableNativeHistory;
|
appRouter.enableNativeHistory = enableNativeHistory;
|
||||||
appRouter.handleAnchorClick = page.handleAnchorClick;
|
appRouter.handleAnchorClick = page.clickHandler;
|
||||||
appRouter.TransparencyLevel = {
|
appRouter.TransparencyLevel = {
|
||||||
None: 0,
|
None: 0,
|
||||||
Backdrop: 1,
|
Backdrop: 1,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 1;
|
z-index: 10;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
transition: transform 180ms linear;
|
transition: transform 180ms linear;
|
||||||
contain: layout style;
|
contain: layout style;
|
||||||
|
|
|
@ -186,7 +186,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
||||||
|
|
||||||
return !!cue.length;
|
return !!cue.length;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("error detecting cue support: " + err);
|
console.error("error detecting cue support: " + err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
||||||
function onAppVisible() {
|
function onAppVisible() {
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
isHidden = false;
|
isHidden = false;
|
||||||
console.log("triggering app resume event");
|
console.debug("triggering app resume event");
|
||||||
events.trigger(appHost, "resume");
|
events.trigger(appHost, "resume");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
||||||
function onAppHidden() {
|
function onAppHidden() {
|
||||||
if (!isHidden) {
|
if (!isHidden) {
|
||||||
isHidden = true;
|
isHidden = true;
|
||||||
console.log("app is hidden");
|
console.debug("app is hidden");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,11 +282,11 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
||||||
features.push("multiserver")
|
features.push("multiserver")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!browser.orsay && !browser.tizen && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) {
|
if (!browser.orsay && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) {
|
||||||
features.push("subtitleappearancesettings");
|
features.push("subtitleappearancesettings");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!browser.orsay && !browser.tizen) {
|
if (!browser.orsay) {
|
||||||
features.push("subtitleburnsettings");
|
features.push("subtitleburnsettings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("error closing application: " + err);
|
console.error("error closing application: " + err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
||||||
* Ask user for exit
|
* Ask user for exit
|
||||||
*/
|
*/
|
||||||
function askForExit() {
|
function askForExit() {
|
||||||
if (!!exitPromise) {
|
if (exitPromise) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
|
||||||
return -1 !== supportedFeatures.indexOf(command.toLowerCase());
|
return -1 !== supportedFeatures.indexOf(command.toLowerCase());
|
||||||
},
|
},
|
||||||
preferVisualCards: browser.android || browser.chrome,
|
preferVisualCards: browser.android || browser.chrome,
|
||||||
moreIcon: browser.android ? "dots-vert" : "dots-horiz",
|
moreIcon: browser.android ? "more_vert" : "more_horiz",
|
||||||
getSyncProfile: getSyncProfile,
|
getSyncProfile: getSyncProfile,
|
||||||
getDefaultLayout: function () {
|
getDefaultLayout: function () {
|
||||||
if (window.NativeShell) {
|
if (window.NativeShell) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ define(["focusManager", "layoutManager"], function (focusManager, layoutManager)
|
||||||
activeElement = e.target;
|
activeElement = e.target;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("AutoFocuser enabled");
|
console.debug("AutoFocuser enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -182,6 +182,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', "userSettings"
|
||||||
return apiClient.getScaledImageUrl(item.BackdropItemId || item.Id, Object.assign(imageOptions, {
|
return apiClient.getScaledImageUrl(item.BackdropItemId || item.Id, Object.assign(imageOptions, {
|
||||||
type: "Backdrop",
|
type: "Backdrop",
|
||||||
tag: imgTag,
|
tag: imgTag,
|
||||||
|
maxWidth: dom.getScreenWidth(),
|
||||||
index: index
|
index: index
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
@ -192,6 +193,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', "userSettings"
|
||||||
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, Object.assign(imageOptions, {
|
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, Object.assign(imageOptions, {
|
||||||
type: "Backdrop",
|
type: "Backdrop",
|
||||||
tag: imgTag,
|
tag: imgTag,
|
||||||
|
maxWidth: dom.getScreenWidth(),
|
||||||
index: index
|
index: index
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
|
@ -370,13 +370,13 @@ button::-moz-focus-inner {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cardImageIcon {
|
.cardImageContainer .cardImageIcon {
|
||||||
font-size: 5em;
|
font-size: 5em;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cardImageIcon-small {
|
.cardImageIcon-small {
|
||||||
font-size: 3em;
|
font-size: 3em !important;
|
||||||
margin-bottom: 0.1em;
|
margin-bottom: 0.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,6 +429,12 @@ button::-moz-focus-inner {
|
||||||
font-size: 1.66956521739130434em !important;
|
font-size: 1.66956521739130434em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cardOverlayButtonIcon.material-icons {
|
||||||
|
/* material-icons override display, so we need to
|
||||||
|
make a better matching selector to set it to flex */
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.cardOverlayButton-centered {
|
.cardOverlayButton-centered {
|
||||||
bottom: initial;
|
bottom: initial;
|
||||||
right: initial;
|
right: initial;
|
||||||
|
@ -725,7 +731,7 @@ button::-moz-focus-inner {
|
||||||
@media (min-width: 120em) {
|
@media (min-width: 120em) {
|
||||||
.overflowSquareCard,
|
.overflowSquareCard,
|
||||||
.overflowPortraitCard {
|
.overflowPortraitCard {
|
||||||
width: 10.3vw;
|
width: 10.41vw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,7 +790,7 @@ button::-moz-focus-inner {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: 0.2s;
|
transition: 0.2s;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 0.5em;
|
padding: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cardOverlayButtonIcon-hover {
|
.cardOverlayButtonIcon-hover {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -68,7 +68,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
|
||||||
|
|
||||||
return apiClient.getScaledImageUrl(item.Id, {
|
return apiClient.getScaledImageUrl(item.Id, {
|
||||||
|
|
||||||
maxWidth: maxWidth,
|
maxWidth: maxWidth * 2,
|
||||||
tag: chapter.ImageTag,
|
tag: chapter.ImageTag,
|
||||||
type: "Chapter",
|
type: "Chapter",
|
||||||
index: index
|
index: index
|
||||||
|
@ -90,7 +90,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
|
||||||
var cardImageContainer = imgUrl ? ('<div class="' + cardImageContainerClass + ' lazy" data-src="' + imgUrl + '">') : ('<div class="' + cardImageContainerClass + '">');
|
var cardImageContainer = imgUrl ? ('<div class="' + cardImageContainerClass + ' lazy" data-src="' + imgUrl + '">') : ('<div class="' + cardImageContainerClass + '">');
|
||||||
|
|
||||||
if (!imgUrl) {
|
if (!imgUrl) {
|
||||||
cardImageContainer += '<i class="material-icons cardImageIcon">local_movies</i>';
|
cardImageContainer += '<i class="material-icons cardImageIcon local_movies"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
var nameHtml = '';
|
var nameHtml = '';
|
||||||
|
|
34
src/components/castSenderApi.js
Normal file
34
src/components/castSenderApi.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
define([], function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (window.appMode === "cordova" || window.appMode === "android") {
|
||||||
|
return {
|
||||||
|
load: function () {
|
||||||
|
window.chrome = window.chrome || {};
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
var ccLoaded = false;
|
||||||
|
return {
|
||||||
|
load: function () {
|
||||||
|
if (ccLoaded) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
var fileref = document.createElement("script");
|
||||||
|
fileref.setAttribute("type", "text/javascript");
|
||||||
|
|
||||||
|
fileref.onload = function () {
|
||||||
|
ccLoaded = true;
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
fileref.setAttribute("src", "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js");
|
||||||
|
document.querySelector("head").appendChild(fileref);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
|
@ -84,7 +84,7 @@ define(["dialogHelper", "loading", "connectionManager", "globalize", "actionshee
|
||||||
|
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
html += '<button class="btnMap autoSize" is="paper-icon-button-light" type="button" data-id="' + channel.Id + '" data-providerid="' + channel.ProviderChannelId + '"><i class="material-icons">mode_edit</i></button>';
|
html += '<button class="btnMap autoSize" is="paper-icon-button-light" type="button" data-id="' + channel.Id + '" data-providerid="' + channel.ProviderChannelId + '"><i class="material-icons mode_edit"></i></button>';
|
||||||
return html += "</div>";
|
return html += "</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ define(["dialogHelper", "loading", "connectionManager", "globalize", "actionshee
|
||||||
var html = "";
|
var html = "";
|
||||||
var title = globalize.translate("MapChannels");
|
var title = globalize.translate("MapChannels");
|
||||||
html += '<div class="formDialogHeader">';
|
html += '<div class="formDialogHeader">';
|
||||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>';
|
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>';
|
||||||
html += '<h3 class="formDialogHeaderTitle">';
|
html += '<h3 class="formDialogHeaderTitle">';
|
||||||
html += title;
|
html += title;
|
||||||
html += "</h3>";
|
html += "</h3>";
|
||||||
|
|
|
@ -131,8 +131,9 @@ define(['events'], function (events) {
|
||||||
var links = [];
|
var links = [];
|
||||||
var match;
|
var match;
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-cond-assign
|
||||||
while (match = linkRegExp.exec(text)) {
|
while (match = linkRegExp.exec(text)) {
|
||||||
// console.log(matches);
|
console.debug(match);
|
||||||
var txt = match[0];
|
var txt = match[0];
|
||||||
var pos = match.index;
|
var pos = match.index;
|
||||||
var len = txt.length;
|
var len = txt.length;
|
||||||
|
@ -189,7 +190,7 @@ define(['events'], function (events) {
|
||||||
return apiClient.getPublicSystemInfo().then(function (info) {
|
return apiClient.getPublicSystemInfo().then(function (info) {
|
||||||
var localAddress = info.LocalAddress
|
var localAddress = info.LocalAddress
|
||||||
if (!localAddress) {
|
if (!localAddress) {
|
||||||
console.log("No valid local address returned, defaulting to external one")
|
console.debug("No valid local address returned, defaulting to external one")
|
||||||
localAddress = serverAddress;
|
localAddress = serverAddress;
|
||||||
}
|
}
|
||||||
addToCache(serverAddress, localAddress);
|
addToCache(serverAddress, localAddress);
|
||||||
|
@ -230,4 +231,4 @@ define(['events'], function (events) {
|
||||||
return {
|
return {
|
||||||
getServerAddress: getServerAddress
|
getServerAddress: getServerAddress
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -105,7 +105,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
this.sessionListener.bind(this),
|
this.sessionListener.bind(this),
|
||||||
this.receiverListener.bind(this));
|
this.receiverListener.bind(this));
|
||||||
|
|
||||||
console.log('chromecast.initialize');
|
console.debug('chromecast.initialize');
|
||||||
chrome.cast.initialize(apiConfig, this.onInitSuccess.bind(this), this.errorHandler);
|
chrome.cast.initialize(apiConfig, this.onInitSuccess.bind(this), this.errorHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,14 +114,14 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.onInitSuccess = function () {
|
CastPlayer.prototype.onInitSuccess = function () {
|
||||||
this.isInitialized = true;
|
this.isInitialized = true;
|
||||||
console.log("chromecast init success");
|
console.debug("chromecast init success");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic error callback function
|
* Generic error callback function
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.onError = function () {
|
CastPlayer.prototype.onError = function () {
|
||||||
console.log("chromecast error");
|
console.debug("chromecast error");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,10 +177,10 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.receiverListener = function (e) {
|
CastPlayer.prototype.receiverListener = function (e) {
|
||||||
if (e === 'available') {
|
if (e === 'available') {
|
||||||
console.log("chromecast receiver found");
|
console.debug("chromecast receiver found");
|
||||||
this.hasReceivers = true;
|
this.hasReceivers = true;
|
||||||
} else {
|
} else {
|
||||||
console.log("chromecast receiver list empty");
|
console.debug("chromecast receiver list empty");
|
||||||
this.hasReceivers = false;
|
this.hasReceivers = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -190,7 +190,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.sessionUpdateListener = function (isAlive) {
|
CastPlayer.prototype.sessionUpdateListener = function (isAlive) {
|
||||||
if (isAlive) {
|
if (isAlive) {
|
||||||
console.log('sessionUpdateListener: already alive');
|
console.debug('sessionUpdateListener: already alive');
|
||||||
} else {
|
} else {
|
||||||
this.session = null;
|
this.session = null;
|
||||||
this.deviceState = DEVICE_STATE.IDLE;
|
this.deviceState = DEVICE_STATE.IDLE;
|
||||||
|
@ -198,7 +198,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
document.removeEventListener("volumeupbutton", onVolumeUpKeyDown, false);
|
document.removeEventListener("volumeupbutton", onVolumeUpKeyDown, false);
|
||||||
document.removeEventListener("volumedownbutton", onVolumeDownKeyDown, false);
|
document.removeEventListener("volumedownbutton", onVolumeDownKeyDown, false);
|
||||||
|
|
||||||
console.log('sessionUpdateListener: setting currentMediaSession to null');
|
console.debug('sessionUpdateListener: setting currentMediaSession to null');
|
||||||
this.currentMediaSession = null;
|
this.currentMediaSession = null;
|
||||||
|
|
||||||
sendConnectionResult(false);
|
sendConnectionResult(false);
|
||||||
|
@ -211,7 +211,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
* session request in opt_sessionRequest.
|
* session request in opt_sessionRequest.
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.launchApp = function () {
|
CastPlayer.prototype.launchApp = function () {
|
||||||
console.log("chromecast launching app...");
|
console.debug("chromecast launching app...");
|
||||||
chrome.cast.requestSession(this.onRequestSessionSuccess.bind(this), this.onLaunchError.bind(this));
|
chrome.cast.requestSession(this.onRequestSessionSuccess.bind(this), this.onLaunchError.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
* @param {Object} e A chrome.cast.Session object
|
* @param {Object} e A chrome.cast.Session object
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.onRequestSessionSuccess = function (e) {
|
CastPlayer.prototype.onRequestSessionSuccess = function (e) {
|
||||||
console.log("chromecast session success: " + e.sessionId);
|
console.debug("chromecast session success: " + e.sessionId);
|
||||||
this.onSessionConnected(e);
|
this.onSessionConnected(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
* Callback function for launch error
|
* Callback function for launch error
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.onLaunchError = function () {
|
CastPlayer.prototype.onLaunchError = function () {
|
||||||
console.log("chromecast launch error");
|
console.debug("chromecast launch error");
|
||||||
this.deviceState = DEVICE_STATE.ERROR;
|
this.deviceState = DEVICE_STATE.ERROR;
|
||||||
sendConnectionResult(false);
|
sendConnectionResult(false);
|
||||||
};
|
};
|
||||||
|
@ -280,7 +280,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
* Callback function for stop app success
|
* Callback function for stop app success
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.onStopAppSuccess = function (message) {
|
CastPlayer.prototype.onStopAppSuccess = function (message) {
|
||||||
console.log(message);
|
console.debug(message);
|
||||||
|
|
||||||
this.deviceState = DEVICE_STATE.IDLE;
|
this.deviceState = DEVICE_STATE.IDLE;
|
||||||
this.castPlayerState = PLAYER_STATE.IDLE;
|
this.castPlayerState = PLAYER_STATE.IDLE;
|
||||||
|
@ -296,7 +296,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.loadMedia = function (options, command) {
|
CastPlayer.prototype.loadMedia = function (options, command) {
|
||||||
if (!this.session) {
|
if (!this.session) {
|
||||||
console.log("no session");
|
console.debug("no session");
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
};
|
};
|
||||||
|
|
||||||
CastPlayer.prototype.onPlayCommandSuccess = function () {
|
CastPlayer.prototype.onPlayCommandSuccess = function () {
|
||||||
//console.log('Message was sent to receiver ok.');
|
console.debug('Message was sent to receiver ok.');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -386,7 +386,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.onMediaDiscovered = function (how, mediaSession) {
|
CastPlayer.prototype.onMediaDiscovered = function (how, mediaSession) {
|
||||||
|
|
||||||
//console.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
|
console.debug("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
|
||||||
this.currentMediaSession = mediaSession;
|
this.currentMediaSession = mediaSession;
|
||||||
|
|
||||||
if (how === 'loadMedia') {
|
if (how === 'loadMedia') {
|
||||||
|
@ -405,7 +405,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
* @param {!Boolean} e true/false
|
* @param {!Boolean} e true/false
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.onMediaStatusUpdate = function (e) {
|
CastPlayer.prototype.onMediaStatusUpdate = function (e) {
|
||||||
//console.log("chromecast updating media: " + e);
|
console.debug("chromecast updating media: " + e);
|
||||||
if (e === false) {
|
if (e === false) {
|
||||||
this.castPlayerState = PLAYER_STATE.IDLE;
|
this.castPlayerState = PLAYER_STATE.IDLE;
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.setReceiverVolume = function (mute, vol) {
|
CastPlayer.prototype.setReceiverVolume = function (mute, vol) {
|
||||||
if (!this.currentMediaSession) {
|
if (!this.currentMediaSession) {
|
||||||
//console.log('this.currentMediaSession is null');
|
console.debug('this.currentMediaSession is null');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +443,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
* Callback function for media command success
|
* Callback function for media command success
|
||||||
*/
|
*/
|
||||||
CastPlayer.prototype.mediaCommandSuccessCallback = function (info, e) {
|
CastPlayer.prototype.mediaCommandSuccessCallback = function (info, e) {
|
||||||
//console.log(info);
|
console.debug(info);
|
||||||
};
|
};
|
||||||
|
|
||||||
function normalizeImages(state) {
|
function normalizeImages(state) {
|
||||||
|
@ -493,7 +493,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
|
|
||||||
events.on(instance._castPlayer, eventName, function (e, data) {
|
events.on(instance._castPlayer, eventName, function (e, data) {
|
||||||
|
|
||||||
//console.log('cc: ' + eventName);
|
console.debug('cc: ' + eventName);
|
||||||
var state = instance.getPlayerStateInternal(data);
|
var state = instance.getPlayerStateInternal(data);
|
||||||
|
|
||||||
events.trigger(instance, eventName, [state]);
|
events.trigger(instance, eventName, [state]);
|
||||||
|
@ -520,14 +520,14 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
playbackManager.setActivePlayer(PlayerName, instance.getCurrentTargetInfo());
|
playbackManager.setActivePlayer(PlayerName, instance.getCurrentTargetInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('cc: connect');
|
console.debug('cc: connect');
|
||||||
// Reset this so that statechange will fire
|
// Reset this so that statechange will fire
|
||||||
instance.lastPlayerData = null;
|
instance.lastPlayerData = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
events.on(instance._castPlayer, "playbackstart", function (e, data) {
|
events.on(instance._castPlayer, "playbackstart", function (e, data) {
|
||||||
|
|
||||||
console.log('cc: playbackstart');
|
console.debug('cc: playbackstart');
|
||||||
|
|
||||||
instance._castPlayer.initializeCastPlayer();
|
instance._castPlayer.initializeCastPlayer();
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
|
|
||||||
events.on(instance._castPlayer, "playbackstop", function (e, data) {
|
events.on(instance._castPlayer, "playbackstop", function (e, data) {
|
||||||
|
|
||||||
console.log('cc: playbackstop');
|
console.debug('cc: playbackstop');
|
||||||
var state = instance.getPlayerStateInternal(data);
|
var state = instance.getPlayerStateInternal(data);
|
||||||
|
|
||||||
events.trigger(instance, "playbackstop", [state]);
|
events.trigger(instance, "playbackstop", [state]);
|
||||||
|
@ -555,7 +555,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
|
|
||||||
events.on(instance._castPlayer, "playbackprogress", function (e, data) {
|
events.on(instance._castPlayer, "playbackprogress", function (e, data) {
|
||||||
|
|
||||||
//console.log('cc: positionchange');
|
console.debug('cc: positionchange');
|
||||||
var state = instance.getPlayerStateInternal(data);
|
var state = instance.getPlayerStateInternal(data);
|
||||||
|
|
||||||
events.trigger(instance, "timeupdate", [state]);
|
events.trigger(instance, "timeupdate", [state]);
|
||||||
|
@ -569,7 +569,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
|
|
||||||
events.on(instance._castPlayer, "playstatechange", function (e, data) {
|
events.on(instance._castPlayer, "playstatechange", function (e, data) {
|
||||||
|
|
||||||
//console.log('cc: playstatechange');
|
console.debug('cc: playstatechange');
|
||||||
var state = instance.getPlayerStateInternal(data);
|
var state = instance.getPlayerStateInternal(data);
|
||||||
|
|
||||||
events.trigger(instance, "pause", [state]);
|
events.trigger(instance, "pause", [state]);
|
||||||
|
@ -664,7 +664,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||||
|
|
||||||
normalizeImages(data);
|
normalizeImages(data);
|
||||||
|
|
||||||
//console.log(JSON.stringify(data));
|
console.debug(JSON.stringify(data));
|
||||||
|
|
||||||
if (triggerStateChange) {
|
if (triggerStateChange) {
|
||||||
events.trigger(this, "statechange", [data]);
|
events.trigger(this, "statechange", [data]);
|
||||||
|
|
|
@ -243,7 +243,7 @@ define(['dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectionManage
|
||||||
var title = items.length ? globalize.translate('HeaderAddToCollection') : globalize.translate('NewCollection');
|
var title = items.length ? globalize.translate('HeaderAddToCollection') : globalize.translate('NewCollection');
|
||||||
|
|
||||||
html += '<div class="formDialogHeader">';
|
html += '<div class="formDialogHeader">';
|
||||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>';
|
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>';
|
||||||
html += '<h3 class="formDialogHeaderTitle">';
|
html += '<h3 class="formDialogHeaderTitle">';
|
||||||
html += title;
|
html += title;
|
||||||
html += '</h3>';
|
html += '</h3>';
|
||||||
|
|
|
@ -1,40 +1,65 @@
|
||||||
define(['dialog', 'globalize'], function (dialog, globalize) {
|
define(["browser", "dialog", "globalize"], function(browser, dialog, globalize) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (text, title) {
|
function replaceAll(str, find, replace) {
|
||||||
|
return str.split(find).join(replace);
|
||||||
|
}
|
||||||
|
|
||||||
var options;
|
if (browser.tv && window.confirm) {
|
||||||
if (typeof text === 'string') {
|
// Use the native confirm dialog
|
||||||
options = {
|
return function (options) {
|
||||||
title: title,
|
if (typeof options === 'string') {
|
||||||
text: text
|
options = {
|
||||||
};
|
title: '',
|
||||||
} else {
|
text: options
|
||||||
options = text;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
var items = [];
|
|
||||||
|
|
||||||
items.push({
|
|
||||||
name: options.cancelText || globalize.translate('ButtonCancel'),
|
|
||||||
id: 'cancel',
|
|
||||||
type: 'cancel'
|
|
||||||
});
|
|
||||||
|
|
||||||
items.push({
|
|
||||||
name: options.confirmText || globalize.translate('ButtonOk'),
|
|
||||||
id: 'ok',
|
|
||||||
type: options.primary === 'delete' ? 'delete' : 'submit'
|
|
||||||
});
|
|
||||||
|
|
||||||
options.buttons = items;
|
|
||||||
|
|
||||||
return dialog(options).then(function (result) {
|
|
||||||
if (result === 'ok') {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject();
|
var text = replaceAll(options.text || '', '<br/>', '\n');
|
||||||
});
|
var result = confirm(text);
|
||||||
};
|
|
||||||
|
if (result) {
|
||||||
|
return Promise.resolve();
|
||||||
|
} else {
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// Use our own dialog
|
||||||
|
return function (text, title) {
|
||||||
|
var options;
|
||||||
|
if (typeof text === 'string') {
|
||||||
|
options = {
|
||||||
|
title: title,
|
||||||
|
text: text
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
options = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = [];
|
||||||
|
|
||||||
|
items.push({
|
||||||
|
name: options.cancelText || globalize.translate('ButtonCancel'),
|
||||||
|
id: 'cancel',
|
||||||
|
type: 'cancel'
|
||||||
|
});
|
||||||
|
|
||||||
|
items.push({
|
||||||
|
name: options.confirmText || globalize.translate('ButtonOk'),
|
||||||
|
id: 'ok',
|
||||||
|
type: options.primary === 'delete' ? 'delete' : 'submit'
|
||||||
|
});
|
||||||
|
|
||||||
|
options.buttons = items;
|
||||||
|
|
||||||
|
return dialog(options).then(function (result) {
|
||||||
|
if (result === 'ok') {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
define([], function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function replaceAll(str, find, replace) {
|
|
||||||
|
|
||||||
return str.split(find).join(replace);
|
|
||||||
}
|
|
||||||
|
|
||||||
return function (options) {
|
|
||||||
|
|
||||||
if (typeof options === 'string') {
|
|
||||||
options = {
|
|
||||||
title: '',
|
|
||||||
text: options
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var text = replaceAll(options.text || '', '<br/>', '\n');
|
|
||||||
var result = confirm(text);
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
return Promise.resolve();
|
|
||||||
} else {
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -12,4 +12,4 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="formDialogFooter formDialogFooter-clear formDialogFooter-flex" style="padding-bottom: 1.5em;">
|
<div class="formDialogFooter formDialogFooter-clear formDialogFooter-flex" style="padding-bottom: 1.5em;">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -32,7 +32,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager',
|
||||||
try {
|
try {
|
||||||
parentNode.removeChild(elem);
|
parentNode.removeChild(elem);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Error removing dialog element: ' + err);
|
console.error('error removing dialog element: ' + err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,15 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager',
|
||||||
}, {
|
}, {
|
||||||
passive: true
|
passive: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dom.addEventListener((dlg.dialogContainer || backdrop), 'contextmenu', function (e) {
|
||||||
|
if (e.target === dlg.dialogContainer) {
|
||||||
|
// Close the application dialog menu
|
||||||
|
close(dlg);
|
||||||
|
// Prevent the default browser context menu from appearing
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function isHistoryEnabled(dlg) {
|
function isHistoryEnabled(dlg) {
|
||||||
|
@ -242,9 +251,15 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager',
|
||||||
|
|
||||||
var onAnimationFinish = function () {
|
var onAnimationFinish = function () {
|
||||||
focusManager.pushScope(dlg);
|
focusManager.pushScope(dlg);
|
||||||
|
|
||||||
if (dlg.getAttribute('data-autofocus') === 'true') {
|
if (dlg.getAttribute('data-autofocus') === 'true') {
|
||||||
focusManager.autoFocus(dlg);
|
focusManager.autoFocus(dlg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (document.activeElement && !dlg.contains(document.activeElement)) {
|
||||||
|
// Blur foreign element to prevent triggering of an action from the previous scope
|
||||||
|
document.activeElement.blur();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (enableAnimation()) {
|
if (enableAnimation()) {
|
||||||
|
@ -481,4 +496,4 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager',
|
||||||
globalOnOpenCallback = val;
|
globalOnOpenCallback = val;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -76,7 +76,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
||||||
html += name;
|
html += name;
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
html += '<i class="material-icons" style="font-size:inherit;">arrow_forward</i>';
|
html += '<i class="material-icons arrow_forward" style="font-size:inherit;"></i>';
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
||||||
|
|
||||||
var html = "";
|
var html = "";
|
||||||
html += '<div class="formDialogHeader">';
|
html += '<div class="formDialogHeader">';
|
||||||
html += '<button is="paper-icon-button-light" class="btnCloseDialog autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>';
|
html += '<button is="paper-icon-button-light" class="btnCloseDialog autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>';
|
||||||
html += '<h3 class="formDialogHeaderTitle">';
|
html += '<h3 class="formDialogHeaderTitle">';
|
||||||
html += options.header || Globalize.translate("HeaderSelectPath");
|
html += options.header || Globalize.translate("HeaderSelectPath");
|
||||||
html += "</h3>";
|
html += "</h3>";
|
||||||
|
|
|
@ -63,27 +63,28 @@ define([], function () {
|
||||||
var supportsCaptureOption = false;
|
var supportsCaptureOption = false;
|
||||||
try {
|
try {
|
||||||
var opts = Object.defineProperty({}, 'capture', {
|
var opts = Object.defineProperty({}, 'capture', {
|
||||||
|
// eslint-disable-next-line getter-return
|
||||||
get: function () {
|
get: function () {
|
||||||
supportsCaptureOption = true;
|
supportsCaptureOption = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
window.addEventListener("test", null, opts);
|
window.addEventListener("test", null, opts);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('error checking capture support');
|
console.debug('error checking capture support');
|
||||||
}
|
}
|
||||||
|
|
||||||
function addEventListenerWithOptions(target, type, handler, options) {
|
function addEventListenerWithOptions(target, type, handler, options) {
|
||||||
var optionsOrCapture = options;
|
var optionsOrCapture = options || {};
|
||||||
if (!supportsCaptureOption) {
|
if (!supportsCaptureOption) {
|
||||||
optionsOrCapture = options.capture;
|
optionsOrCapture = optionsOrCapture.capture;
|
||||||
}
|
}
|
||||||
target.addEventListener(type, handler, optionsOrCapture);
|
target.addEventListener(type, handler, optionsOrCapture);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeEventListenerWithOptions(target, type, handler, options) {
|
function removeEventListenerWithOptions(target, type, handler, options) {
|
||||||
var optionsOrCapture = options;
|
var optionsOrCapture = options || {};
|
||||||
if (!supportsCaptureOption) {
|
if (!supportsCaptureOption) {
|
||||||
optionsOrCapture = options.capture;
|
optionsOrCapture = optionsOrCapture.capture;
|
||||||
}
|
}
|
||||||
target.removeEventListener(type, handler, optionsOrCapture);
|
target.removeEventListener(type, handler, optionsOrCapture);
|
||||||
}
|
}
|
||||||
|
@ -111,6 +112,22 @@ define([], function () {
|
||||||
return windowSize;
|
return windowSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var standardWidths = [480, 720, 1280, 1440, 1920, 2560, 3840, 5120, 7680];
|
||||||
|
function getScreenWidth() {
|
||||||
|
var width = window.innerWidth;
|
||||||
|
var height = window.innerHeight;
|
||||||
|
|
||||||
|
if (height > width) {
|
||||||
|
width = height * (16.0 / 9.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var closest = standardWidths.sort(function (a, b) {
|
||||||
|
return Math.abs(width - a) - Math.abs(width - b);
|
||||||
|
})[0];
|
||||||
|
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
|
|
||||||
var _animationEvent;
|
var _animationEvent;
|
||||||
function whichAnimationEvent() {
|
function whichAnimationEvent() {
|
||||||
|
|
||||||
|
@ -174,8 +191,9 @@ define([], function () {
|
||||||
addEventListener: addEventListenerWithOptions,
|
addEventListener: addEventListenerWithOptions,
|
||||||
removeEventListener: removeEventListenerWithOptions,
|
removeEventListener: removeEventListenerWithOptions,
|
||||||
getWindowSize: getWindowSize,
|
getWindowSize: getWindowSize,
|
||||||
|
getScreenWidth: getScreenWidth,
|
||||||
whichTransitionEvent: whichTransitionEvent,
|
whichTransitionEvent: whichTransitionEvent,
|
||||||
whichAnimationEvent: whichAnimationEvent,
|
whichAnimationEvent: whichAnimationEvent,
|
||||||
whichAnimationCancelEvent: whichAnimationCancelEvent
|
whichAnimationCancelEvent: whichAnimationCancelEvent
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -74,4 +74,4 @@ define(['emby-progressring', 'dom', 'serverNotifications', 'events', 'registerEl
|
||||||
prototype: EmbyItemRefreshIndicatorPrototype,
|
prototype: EmbyItemRefreshIndicatorPrototype,
|
||||||
extends: 'div'
|
extends: 'div'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -467,7 +467,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
|
||||||
focusManager.focus(newElement);
|
focusManager.focus(newElement);
|
||||||
return;
|
return;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,4 +479,4 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
|
||||||
prototype: ItemsContainerPrototype,
|
prototype: ItemsContainerPrototype,
|
||||||
extends: 'div'
|
extends: 'div'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,7 @@ define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'registerElement', '
|
||||||
|
|
||||||
function getScrollButtonHtml(direction) {
|
function getScrollButtonHtml(direction) {
|
||||||
var html = '';
|
var html = '';
|
||||||
var icon = direction === 'left' ? 'chevron_left' : 'chevron_right';
|
var icon = direction === 'left' ? '' : '';
|
||||||
|
|
||||||
html += '<button type="button" is="paper-icon-button-light" data-ripple="false" data-direction="' + direction + '" class="emby-scrollbuttons-button">';
|
html += '<button type="button" is="paper-icon-button-light" data-ripple="false" data-direction="' + direction + '" class="emby-scrollbuttons-button">';
|
||||||
html += '<i class="material-icons">' + icon + '</i>';
|
html += '<i class="material-icons">' + icon + '</i>';
|
||||||
|
|
|
@ -206,4 +206,4 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro
|
||||||
prototype: ScrollerPrototype,
|
prototype: ScrollerPrototype,
|
||||||
extends: 'div'
|
extends: 'div'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 1.5em;
|
padding: 1.5em 1.5em;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: auto;
|
height: auto;
|
||||||
min-width: initial;
|
min-width: initial;
|
||||||
line-height: initial;
|
line-height: 1.25;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
|
@ -338,4 +338,4 @@ define(['dom', 'scroller', 'browser', 'layoutManager', 'focusManager', 'register
|
||||||
prototype: EmbyTabs,
|
prototype: EmbyTabs,
|
||||||
extends: 'div'
|
extends: 'div'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -136,7 +136,7 @@ define(["loading", "libraryBrowser", "cardBuilder", "dom", "apphost", "imageLoad
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
||||||
html += globalize.translate(section.name);
|
html += globalize.translate(section.name);
|
||||||
html += "</h2>";
|
html += "</h2>";
|
||||||
html += '<i class="material-icons">chevron_right</i>';
|
html += '<i class="material-icons chevron_right"></i>';
|
||||||
html += "</a>";
|
html += "</a>";
|
||||||
} else {
|
} else {
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate(section.name) + "</h2>";
|
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate(section.name) + "</h2>";
|
||||||
|
|
|
@ -51,7 +51,7 @@ define([], function () {
|
||||||
|
|
||||||
function fetchWithTimeout(url, options, timeoutMs) {
|
function fetchWithTimeout(url, options, timeoutMs) {
|
||||||
|
|
||||||
console.log('fetchWithTimeout: timeoutMs: ' + timeoutMs + ', url: ' + url);
|
console.debug('fetchWithTimeout: timeoutMs: ' + timeoutMs + ', url: ' + url);
|
||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
|
||||||
|
@ -63,14 +63,14 @@ define([], function () {
|
||||||
fetch(url, options).then(function (response) {
|
fetch(url, options).then(function (response) {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
|
|
||||||
console.log('fetchWithTimeout: succeeded connecting to url: ' + url);
|
console.debug('fetchWithTimeout: succeeded connecting to url: ' + url);
|
||||||
|
|
||||||
resolve(response);
|
resolve(response);
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
|
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
|
|
||||||
console.log('fetchWithTimeout: timed out connecting to url: ' + url);
|
console.debug('fetchWithTimeout: timed out connecting to url: ' + url);
|
||||||
|
|
||||||
reject();
|
reject();
|
||||||
});
|
});
|
||||||
|
@ -93,21 +93,17 @@ define([], function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ajax(request) {
|
function ajax(request) {
|
||||||
|
|
||||||
if (!request) {
|
if (!request) {
|
||||||
throw new Error("Request cannot be null");
|
throw new Error("Request cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
request.headers = request.headers || {};
|
request.headers = request.headers || {};
|
||||||
|
|
||||||
console.log('requesting url: ' + request.url);
|
console.debug('requesting url: ' + request.url);
|
||||||
|
|
||||||
return getFetchPromise(request).then(function (response) {
|
return getFetchPromise(request).then(function (response) {
|
||||||
|
console.debug('response status: ' + response.status + ', url: ' + request.url);
|
||||||
console.log('response status: ' + response.status + ', url: ' + request.url);
|
|
||||||
|
|
||||||
if (response.status < 400) {
|
if (response.status < 400) {
|
||||||
|
|
||||||
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
|
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
|
||||||
return response.json();
|
return response.json();
|
||||||
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') === 0) {
|
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') === 0) {
|
||||||
|
@ -118,10 +114,8 @@ define([], function () {
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject(response);
|
return Promise.reject(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
|
console.error('request failed to url: ' + request.url);
|
||||||
console.log('request failed to url: ' + request.url);
|
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -129,4 +123,4 @@ define([], function () {
|
||||||
getFetchPromise: getFetchPromise,
|
getFetchPromise: getFetchPromise,
|
||||||
ajax: ajax
|
ajax: ajax
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
define(['multi-download'], function (multiDownload) {
|
import multiDownload from "multi-download"
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return {
|
export function download(items) {
|
||||||
download: function (items) {
|
|
||||||
|
|
||||||
if (window.NativeShell) {
|
if (window.NativeShell) {
|
||||||
items.map(function (item) {
|
items.map(function (item) {
|
||||||
window.NativeShell.downloadFile(item.url);
|
window.NativeShell.downloadFile(item.url);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
multiDownload(items.map(function (item) {
|
multiDownload(items.map(function (item) {
|
||||||
return item.url;
|
return item.url;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
define([], function () {
|
export function fileExists(path) {
|
||||||
'use strict';
|
if (window.NativeShell && window.NativeShell.FileSystem) {
|
||||||
|
return window.NativeShell.FileSystem.fileExists(path);
|
||||||
|
}
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
export function directoryExists(path) {
|
||||||
fileExists: function (path) {
|
if (window.NativeShell && window.NativeShell.FileSystem) {
|
||||||
if (window.NativeShell && window.NativeShell.FileSystem) {
|
return window.NativeShell.FileSystem.directoryExists(path);
|
||||||
return window.NativeShell.FileSystem.fileExists(path);
|
}
|
||||||
}
|
return Promise.reject();
|
||||||
return Promise.reject();
|
}
|
||||||
},
|
|
||||||
directoryExists: function (path) {
|
|
||||||
if (window.NativeShell && window.NativeShell.FileSystem) {
|
|
||||||
return window.NativeShell.FileSystem.directoryExists(path);
|
|
||||||
}
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost',
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
html += '<div class="formDialogHeader">';
|
html += '<div class="formDialogHeader">';
|
||||||
html += '<button is="paper-icon-button-light" class="btnCancel hide-mouse-idle-tv" tabindex="-1"><i class="material-icons">arrow_back</i></button>';
|
html += '<button is="paper-icon-button-light" class="btnCancel hide-mouse-idle-tv" tabindex="-1"><i class="material-icons arrow_back"></i></button>';
|
||||||
html += '<h3 class="formDialogHeaderTitle">${Filters}</h3>';
|
html += '<h3 class="formDialogHeaderTitle">${Filters}</h3>';
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
|
@ -105,4 +105,4 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -43,7 +43,7 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) {
|
||||||
preventScroll: scrollManager.isEnabled()
|
preventScroll: scrollManager.isEnabled()
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Error in focusManager.autoFocus: ' + err);
|
console.error('Error in focusManager.autoFocus: ' + err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,20 +89,6 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSortByChange() {
|
|
||||||
var newValue = this.value;
|
|
||||||
if (this.checked) {
|
|
||||||
var changed = options.query.SortBy !== newValue;
|
|
||||||
|
|
||||||
options.query.SortBy = newValue.replace('_', ',');
|
|
||||||
options.query.StartIndex = 0;
|
|
||||||
|
|
||||||
if (options.callback && changed) {
|
|
||||||
options.callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showEditor(options) {
|
function showEditor(options) {
|
||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
@ -171,4 +157,4 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectio
|
||||||
return {
|
return {
|
||||||
show: showEditor
|
show: showEditor
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>
|
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>
|
||||||
<h3 class="formDialogHeaderTitle">
|
<h3 class="formDialogHeaderTitle">
|
||||||
${Settings}
|
${Settings}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
@ -29,7 +29,6 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
|
||||||
var offset = newPct - left;
|
var offset = newPct - left;
|
||||||
var pctOfWidth = (offset / width) * 100;
|
var pctOfWidth = (offset / width) * 100;
|
||||||
|
|
||||||
//console.log(pctOfWidth);
|
|
||||||
var guideProgramName = cell.guideProgramName;
|
var guideProgramName = cell.guideProgramName;
|
||||||
if (!guideProgramName) {
|
if (!guideProgramName) {
|
||||||
guideProgramName = cell.querySelector('.guideProgramName');
|
guideProgramName = cell.querySelector('.guideProgramName');
|
||||||
|
@ -396,7 +395,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
|
||||||
try {
|
try {
|
||||||
program.StartDateLocal = datetime.parseISO8601Date(program.StartDate, { toLocal: true });
|
program.StartDateLocal = datetime.parseISO8601Date(program.StartDate, { toLocal: true });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('error parsing timestamp for start date');
|
console.error('error parsing timestamp for start date');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +403,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
|
||||||
try {
|
try {
|
||||||
program.EndDateLocal = datetime.parseISO8601Date(program.EndDate, { toLocal: true });
|
program.EndDateLocal = datetime.parseISO8601Date(program.EndDate, { toLocal: true });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('error parsing timestamp for end date');
|
console.error('error parsing timestamp for end date');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +415,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
|
||||||
var status;
|
var status;
|
||||||
|
|
||||||
if (item.Type === 'SeriesTimer') {
|
if (item.Type === 'SeriesTimer') {
|
||||||
return '<i class="material-icons programIcon seriesTimerIcon">fiber_smart_record</i>';
|
return '<i class="material-icons programIcon seriesTimerIcon fiber_smart_record"></i>';
|
||||||
} else if (item.TimerId || item.SeriesTimerId) {
|
} else if (item.TimerId || item.SeriesTimerId) {
|
||||||
|
|
||||||
status = item.Status || 'Cancelled';
|
status = item.Status || 'Cancelled';
|
||||||
|
@ -430,13 +429,13 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
|
||||||
if (item.SeriesTimerId) {
|
if (item.SeriesTimerId) {
|
||||||
|
|
||||||
if (status !== 'Cancelled') {
|
if (status !== 'Cancelled') {
|
||||||
return '<i class="material-icons programIcon seriesTimerIcon">fiber_smart_record</i>';
|
return '<i class="material-icons programIcon seriesTimerIcon fiber_smart_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<i class="material-icons programIcon seriesTimerIcon seriesTimerIcon-inactive">fiber_smart_record</i>';
|
return '<i class="material-icons programIcon seriesTimerIcon seriesTimerIcon-inactive fiber_smart_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<i class="material-icons programIcon timerIcon">fiber_manual_record</i>';
|
return '<i class="material-icons programIcon timerIcon fiber_manual_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannelProgramsHtml(context, date, channel, programs, options, listInfo) {
|
function getChannelProgramsHtml(context, date, channel, programs, options, listInfo) {
|
||||||
|
@ -550,7 +549,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
|
||||||
|
|
||||||
html += '<div class="' + guideProgramNameClass + '">';
|
html += '<div class="' + guideProgramNameClass + '">';
|
||||||
|
|
||||||
html += '<div class="guide-programNameCaret hide"><i class="guideProgramNameCaretIcon material-icons">keyboard_arrow_left</i></div>';
|
html += '<div class="guide-programNameCaret hide"><i class="guideProgramNameCaretIcon material-icons keyboard_arrow_left"></i></div>';
|
||||||
|
|
||||||
html += '<div class="guideProgramNameText">' + program.Name;
|
html += '<div class="guideProgramNameText">' + program.Name;
|
||||||
|
|
||||||
|
@ -1106,7 +1105,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
|
||||||
|
|
||||||
var icon = cell.querySelector('.timerIcon');
|
var icon = cell.querySelector('.timerIcon');
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
cell.querySelector('.guideProgramName').insertAdjacentHTML('beforeend', '<i class="timerIcon material-icons programIcon">fiber_manual_record</i>');
|
cell.querySelector('.guideProgramName').insertAdjacentHTML('beforeend', '<i class="timerIcon material-icons programIcon fiber_manual_record"></i>');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newTimerId) {
|
if (newTimerId) {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<div class="guide-headerTimeslots">
|
<div class="guide-headerTimeslots">
|
||||||
<div class="guide-channelTimeslotHeader">
|
<div class="guide-channelTimeslotHeader">
|
||||||
<button is="paper-icon-button-light" type="button" class="btnGuideViewSettings">
|
<button is="paper-icon-button-light" type="button" class="btnGuideViewSettings">
|
||||||
<i class="material-icons btnGuideViewSettingsIcon">more_horiz</i>
|
<i class="material-icons btnGuideViewSettingsIcon more_horiz"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeslotHeaders scrollX guideScroller"></div>
|
<div class="timeslotHeaders scrollX guideScroller"></div>
|
||||||
|
@ -30,9 +30,9 @@
|
||||||
|
|
||||||
<div class="guideOptions hide">
|
<div class="guideOptions hide">
|
||||||
<button is="paper-icon-button-light" type="button" class="btnPreviousPage">
|
<button is="paper-icon-button-light" type="button" class="btnPreviousPage">
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons arrow_back"></i>
|
||||||
</button>
|
</button>
|
||||||
<button is="paper-icon-button-light" type="button" class="btnNextPage">
|
<button is="paper-icon-button-light" type="button" class="btnNextPage">
|
||||||
<i class="material-icons">arrow_forward</i>
|
<i class="material-icons arrow_forward"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -340,4 +340,4 @@ define(['dom', 'layoutManager', 'browser', 'css!./headroom'], function (dom, lay
|
||||||
};
|
};
|
||||||
|
|
||||||
return Headroom;
|
return Headroom;
|
||||||
});
|
});
|
||||||
|
|
|
@ -149,7 +149,7 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa
|
||||||
|
|
||||||
currentHtml += '<div class="listItem viewItem" data-viewid="' + view.Id + '">';
|
currentHtml += '<div class="listItem viewItem" data-viewid="' + view.Id + '">';
|
||||||
|
|
||||||
currentHtml += '<i class="material-icons listItemIcon">folder_open</i>';
|
currentHtml += '<i class="material-icons listItemIcon folder_open"></i>';
|
||||||
|
|
||||||
currentHtml += '<div class="listItemBody">';
|
currentHtml += '<div class="listItemBody">';
|
||||||
|
|
||||||
|
@ -159,8 +159,8 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa
|
||||||
|
|
||||||
currentHtml += '</div>';
|
currentHtml += '</div>';
|
||||||
|
|
||||||
currentHtml += '<button type="button" is="paper-icon-button-light" class="btnViewItemUp btnViewItemMove autoSize" title="' + globalize.translate('Up') + '"><i class="material-icons">keyboard_arrow_up</i></button>';
|
currentHtml += '<button type="button" is="paper-icon-button-light" class="btnViewItemUp btnViewItemMove autoSize" title="' + globalize.translate('Up') + '"><i class="material-icons keyboard_arrow_up"></i></button>';
|
||||||
currentHtml += '<button type="button" is="paper-icon-button-light" class="btnViewItemDown btnViewItemMove autoSize" title="' + globalize.translate('Down') + '"><i class="material-icons">keyboard_arrow_down</i></button>';
|
currentHtml += '<button type="button" is="paper-icon-button-light" class="btnViewItemDown btnViewItemMove autoSize" title="' + globalize.translate('Down') + '"><i class="material-icons keyboard_arrow_down"></i></button>';
|
||||||
|
|
||||||
currentHtml += '</div>';
|
currentHtml += '</div>';
|
||||||
|
|
||||||
|
|
|
@ -129,4 +129,4 @@
|
||||||
<button is="emby-button" type="submit" class="raised button-submit block btnSave hide">
|
<button is="emby-button" type="submit" class="raised button-submit block btnSave hide">
|
||||||
<span>${Save}</span>
|
<span>${Save}</span>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -40,26 +40,48 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
return getUserViews(apiClient, user.Id).then(function (userViews) {
|
return getUserViews(apiClient, user.Id).then(function (userViews) {
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
var sectionCount = 7;
|
if (userViews.length) {
|
||||||
for (var i = 0; i < sectionCount; i++) {
|
var sectionCount = 7;
|
||||||
html += '<div class="verticalSection section' + i + '"></div>';
|
for (var i = 0; i < sectionCount; i++) {
|
||||||
}
|
html += '<div class="verticalSection section' + i + '"></div>';
|
||||||
|
}
|
||||||
|
|
||||||
elem.innerHTML = html;
|
elem.innerHTML = html;
|
||||||
elem.classList.add('homeSectionsContainer');
|
elem.classList.add('homeSectionsContainer');
|
||||||
|
|
||||||
var promises = [];
|
var promises = [];
|
||||||
var sections = getAllSectionsToShow(userSettings, sectionCount);
|
var sections = getAllSectionsToShow(userSettings, sectionCount);
|
||||||
for (var i = 0; i < sections.length; i++) {
|
for (var i = 0; i < sections.length; i++) {
|
||||||
promises.push(loadSection(elem, apiClient, user, userSettings, userViews, sections, i));
|
promises.push(loadSection(elem, apiClient, user, userSettings, userViews, sections, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises).then(function () {
|
return Promise.all(promises).then(function () {
|
||||||
return resume(elem, {
|
return resume(elem, {
|
||||||
refresh: true,
|
refresh: true,
|
||||||
returnPromise: false
|
returnPromise: false
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
} else {
|
||||||
|
var noLibDescription;
|
||||||
|
if (user['Policy'] && user['Policy']['IsAdministrator']) {
|
||||||
|
noLibDescription = Globalize.translate("NoCreatedLibraries", '<a id="button-createLibrary" class="button-link">', '</a>')
|
||||||
|
} else {
|
||||||
|
noLibDescription = Globalize.translate("AskAdminToCreateLibrary");
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '<div class="centerMessage padded-left padded-right">';
|
||||||
|
html += '<h2>' + Globalize.translate("MessageNothingHere") + '</h2>';
|
||||||
|
html += '<p>' + noLibDescription + '</p>'
|
||||||
|
html += '</div>';
|
||||||
|
elem.innerHTML = html;
|
||||||
|
|
||||||
|
var createNowLink = elem.querySelector("#button-createLibrary")
|
||||||
|
if (createNowLink) {
|
||||||
|
createNowLink.addEventListener("click", function () {
|
||||||
|
Dashboard.navigate("library.html");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +183,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
for (var i = 0, length = items.length; i < length; i++) {
|
for (var i = 0, length = items.length; i < length; i++) {
|
||||||
var item = items[i];
|
var item = items[i];
|
||||||
var icon = imageHelper.getLibraryIcon(item.CollectionType);
|
var icon = imageHelper.getLibraryIcon(item.CollectionType);
|
||||||
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(item) + '" class="raised homeLibraryButton"><i class="material-icons homeLibraryIcon">' + icon + '</i><span class="homeLibraryText">' + item.Name + '</span></a>';
|
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(item) + '" class="raised homeLibraryButton"><i class="material-icons homeLibraryIcon ' + icon + '"></i><span class="homeLibraryText">' + item.Name + '</span></a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
@ -260,7 +282,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
||||||
html += globalize.translate('LatestFromLibrary', parent.Name);
|
html += globalize.translate('LatestFromLibrary', parent.Name);
|
||||||
html += '</h2>';
|
html += '</h2>';
|
||||||
html += '<i class="material-icons">chevron_right</i>';
|
html += '<i class="material-icons chevron_right"></i>';
|
||||||
html += '</a>';
|
html += '</a>';
|
||||||
} else {
|
} else {
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('LatestFromLibrary', parent.Name) + '</h2>';
|
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('LatestFromLibrary', parent.Name) + '</h2>';
|
||||||
|
@ -268,7 +290,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
if (enableScrollX()) {
|
if (enableScrollX()) {
|
||||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
|
||||||
} else {
|
} else {
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer focuscontainer-x padded-left padded-right vertical-wrap">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer focuscontainer-x padded-left padded-right vertical-wrap">';
|
||||||
|
@ -321,7 +343,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
if (userViews.length) {
|
if (userViews.length) {
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderMyMedia') + '</h2>';
|
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderMyMedia') + '</h2>';
|
||||||
if (enableScrollX()) {
|
if (enableScrollX()) {
|
||||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
|
||||||
} else {
|
} else {
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right focuscontainer-x vertical-wrap">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right focuscontainer-x vertical-wrap">';
|
||||||
|
@ -401,7 +423,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
|
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderContinueWatching') + '</h2>';
|
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderContinueWatching') + '</h2>';
|
||||||
if (enableScrollX()) {
|
if (enableScrollX()) {
|
||||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">';
|
||||||
} else {
|
} else {
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">';
|
||||||
|
@ -474,7 +496,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
|
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderContinueWatching') + '</h2>';
|
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderContinueWatching') + '</h2>';
|
||||||
if (enableScrollX()) {
|
if (enableScrollX()) {
|
||||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="audioplayback,markplayed">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="audioplayback,markplayed">';
|
||||||
} else {
|
} else {
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="audioplayback,markplayed">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="audioplayback,markplayed">';
|
||||||
|
@ -560,7 +582,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
if (enableScrollX()) {
|
if (enableScrollX()) {
|
||||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true" data-scrollbuttons="false">';
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true" data-scrollbuttons="false">';
|
||||||
html += '<div class="padded-top padded-bottom scrollSlider focuscontainer-x">';
|
html += '<div class="padded-top padded-bottom scrollSlider focuscontainer-x">';
|
||||||
} else {
|
} else {
|
||||||
html += '<div class="padded-top padded-bottom focuscontainer-x">';
|
html += '<div class="padded-top padded-bottom focuscontainer-x">';
|
||||||
|
@ -608,7 +630,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
||||||
html += globalize.translate('HeaderOnNow');
|
html += globalize.translate('HeaderOnNow');
|
||||||
html += '</h2>';
|
html += '</h2>';
|
||||||
html += '<i class="material-icons">chevron_right</i>';
|
html += '<i class="material-icons chevron_right"></i>';
|
||||||
html += '</a>';
|
html += '</a>';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -617,7 +639,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
if (enableScrollX()) {
|
if (enableScrollX()) {
|
||||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
|
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
|
||||||
} else {
|
} else {
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
|
||||||
|
@ -683,7 +705,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
||||||
html += globalize.translate('HeaderNextUp');
|
html += globalize.translate('HeaderNextUp');
|
||||||
html += '</h2>';
|
html += '</h2>';
|
||||||
html += '<i class="material-icons">chevron_right</i>';
|
html += '<i class="material-icons chevron_right"></i>';
|
||||||
html += '</a>';
|
html += '</a>';
|
||||||
} else {
|
} else {
|
||||||
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('HeaderNextUp') + '</h2>';
|
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('HeaderNextUp') + '</h2>';
|
||||||
|
@ -691,7 +713,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
if (enableScrollX()) {
|
if (enableScrollX()) {
|
||||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">'
|
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">'
|
||||||
} else {
|
} else {
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">';
|
||||||
|
@ -763,7 +785,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
if (enableScrollX()) {
|
if (enableScrollX()) {
|
||||||
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
|
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
|
||||||
} else {
|
} else {
|
||||||
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
|
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
|
||||||
|
|
|
@ -114,12 +114,12 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
|
|
||||||
if (!recoverDecodingErrorDate || (now - recoverDecodingErrorDate) > 3000) {
|
if (!recoverDecodingErrorDate || (now - recoverDecodingErrorDate) > 3000) {
|
||||||
recoverDecodingErrorDate = now;
|
recoverDecodingErrorDate = now;
|
||||||
console.log('try to recover media Error ...');
|
console.debug('try to recover media Error ...');
|
||||||
hlsPlayer.recoverMediaError();
|
hlsPlayer.recoverMediaError();
|
||||||
} else {
|
} else {
|
||||||
if (!recoverSwapAudioCodecDate || (now - recoverSwapAudioCodecDate) > 3000) {
|
if (!recoverSwapAudioCodecDate || (now - recoverSwapAudioCodecDate) > 3000) {
|
||||||
recoverSwapAudioCodecDate = now;
|
recoverSwapAudioCodecDate = now;
|
||||||
console.log('try to swap Audio Codec and recover media Error ...');
|
console.debug('try to swap Audio Codec and recover media Error ...');
|
||||||
hlsPlayer.swapAudioCodec();
|
hlsPlayer.swapAudioCodec();
|
||||||
hlsPlayer.recoverMediaError();
|
hlsPlayer.recoverMediaError();
|
||||||
} else {
|
} else {
|
||||||
|
@ -233,7 +233,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('error calling video.play: ' + err);
|
console.error('error calling video.play: ' + err);
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
try {
|
try {
|
||||||
player.unload();
|
player.unload();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance._castPlayer = null;
|
instance._castPlayer = null;
|
||||||
|
@ -258,7 +258,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
try {
|
try {
|
||||||
player.destroy();
|
player.destroy();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance._shakaPlayer = null;
|
instance._shakaPlayer = null;
|
||||||
|
@ -271,7 +271,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
try {
|
try {
|
||||||
player.destroy();
|
player.destroy();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance._hlsPlayer = null;
|
instance._hlsPlayer = null;
|
||||||
|
@ -286,7 +286,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
player.detachMediaElement();
|
player.detachMediaElement();
|
||||||
player.destroy();
|
player.destroy();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance._flvPlayer = null;
|
instance._flvPlayer = null;
|
||||||
|
@ -307,14 +307,14 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
|
|
||||||
hls.on(Hls.Events.ERROR, function (event, data) {
|
hls.on(Hls.Events.ERROR, function (event, data) {
|
||||||
|
|
||||||
console.log('HLS Error: Type: ' + data.type + ' Details: ' + (data.details || '') + ' Fatal: ' + (data.fatal || false));
|
console.error('HLS Error: Type: ' + data.type + ' Details: ' + (data.details || '') + ' Fatal: ' + (data.fatal || false));
|
||||||
|
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case Hls.ErrorTypes.NETWORK_ERROR:
|
case Hls.ErrorTypes.NETWORK_ERROR:
|
||||||
// try to recover network error
|
// try to recover network error
|
||||||
if (data.response && data.response.code && data.response.code >= 400) {
|
if (data.response && data.response.code && data.response.code >= 400) {
|
||||||
|
|
||||||
console.log('hls.js response error code: ' + data.response.code);
|
console.debug('hls.js response error code: ' + data.response.code);
|
||||||
|
|
||||||
// Trigger failure differently depending on whether this is prior to start of playback, or after
|
// Trigger failure differently depending on whether this is prior to start of playback, or after
|
||||||
hls.destroy();
|
hls.destroy();
|
||||||
|
@ -343,7 +343,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
|
|
||||||
// This could be a CORS error related to access control response headers
|
// This could be a CORS error related to access control response headers
|
||||||
|
|
||||||
console.log('hls.js response error code: ' + data.response.code);
|
console.debug('hls.js response error code: ' + data.response.code);
|
||||||
|
|
||||||
// Trigger failure differently depending on whether this is prior to start of playback, or after
|
// Trigger failure differently depending on whether this is prior to start of playback, or after
|
||||||
hls.destroy();
|
hls.destroy();
|
||||||
|
@ -355,20 +355,20 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
onErrorInternal(instance, 'network');
|
onErrorInternal(instance, 'network');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("fatal network error encountered, try to recover");
|
console.debug("fatal network error encountered, try to recover");
|
||||||
hls.startLoad();
|
hls.startLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Hls.ErrorTypes.MEDIA_ERROR:
|
case Hls.ErrorTypes.MEDIA_ERROR:
|
||||||
console.log("fatal media error encountered, try to recover");
|
console.debug("fatal media error encountered, try to recover");
|
||||||
var currentReject = reject;
|
var currentReject = reject;
|
||||||
reject = null;
|
reject = null;
|
||||||
handleHlsJsMediaError(instance, currentReject);
|
handleHlsJsMediaError(instance, currentReject);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
console.log('Cannot recover from hls error - destroy and trigger error');
|
console.debug('Cannot recover from hls error - destroy and trigger error');
|
||||||
// cannot recover
|
// cannot recover
|
||||||
// Trigger failure differently depending on whether this is prior to start of playback, or after
|
// Trigger failure differently depending on whether this is prior to start of playback, or after
|
||||||
hls.destroy();
|
hls.destroy();
|
||||||
|
@ -463,4 +463,4 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
|
||||||
getCrossOriginValue: getCrossOriginValue,
|
getCrossOriginValue: getCrossOriginValue,
|
||||||
getBufferedRanges: getBufferedRanges
|
getBufferedRanges: getBufferedRanges
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,7 +16,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
|
||||||
// Need to record the starting volume on each pass rather than querying elem.volume
|
// Need to record the starting volume on each pass rather than querying elem.volume
|
||||||
// This is due to iOS safari not allowing volume changes and always returning the system volume value
|
// This is due to iOS safari not allowing volume changes and always returning the system volume value
|
||||||
var newVolume = Math.max(0, startingVolume - 0.15);
|
var newVolume = Math.max(0, startingVolume - 0.15);
|
||||||
console.log('fading volume to ' + newVolume);
|
console.debug('fading volume to ' + newVolume);
|
||||||
elem.volume = newVolume;
|
elem.volume = newVolume;
|
||||||
|
|
||||||
if (newVolume <= 0) {
|
if (newVolume <= 0) {
|
||||||
|
@ -113,7 +113,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
|
||||||
bindEvents(elem);
|
bindEvents(elem);
|
||||||
|
|
||||||
var val = options.url;
|
var val = options.url;
|
||||||
console.log('playing url: ' + val);
|
console.debug('playing url: ' + val);
|
||||||
|
|
||||||
// Convert to seconds
|
// Convert to seconds
|
||||||
var seconds = (options.playerStartPositionTicks || 0) / 10000000;
|
var seconds = (options.playerStartPositionTicks || 0) / 10000000;
|
||||||
|
@ -298,7 +298,7 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
|
||||||
|
|
||||||
var errorCode = this.error ? (this.error.code || 0) : 0;
|
var errorCode = this.error ? (this.error.code || 0) : 0;
|
||||||
var errorMessage = this.error ? (this.error.message || '') : '';
|
var errorMessage = this.error ? (this.error.message || '') : '';
|
||||||
console.log('Media element error: ' + errorCode.toString() + ' ' + errorMessage);
|
console.error('media element error: ' + errorCode.toString() + ' ' + errorMessage);
|
||||||
|
|
||||||
var type;
|
var type;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'fullscreenManager', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, fullscreenManager, globalize) {
|
define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'fullscreenManager', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, fullscreenManager, globalize) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
/* globals cast */
|
||||||
|
|
||||||
var mediaManager;
|
var mediaManager;
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
try {
|
try {
|
||||||
parentNode.removeChild(elem);
|
parentNode.removeChild(elem);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Error removing dialog element: ' + err);
|
console.error('error removing dialog element: ' + err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +80,6 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
if (track) {
|
if (track) {
|
||||||
var format = (track.Codec || '').toLowerCase();
|
var format = (track.Codec || '').toLowerCase();
|
||||||
if (format === 'ssa' || format === 'ass') {
|
if (format === 'ssa' || format === 'ass') {
|
||||||
// libjass is needed here
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
|
|
||||||
loading.show();
|
loading.show();
|
||||||
|
|
||||||
console.log('prefetching hls playlist: ' + hlsPlaylistUrl);
|
console.debug('prefetching hls playlist: ' + hlsPlaylistUrl);
|
||||||
|
|
||||||
return connectionManager.getApiClient(item.ServerId).ajax({
|
return connectionManager.getApiClient(item.ServerId).ajax({
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
|
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
|
|
||||||
console.log('completed prefetching hls playlist: ' + hlsPlaylistUrl);
|
console.debug('completed prefetching hls playlist: ' + hlsPlaylistUrl);
|
||||||
|
|
||||||
loading.hide();
|
loading.hide();
|
||||||
streamInfo.url = hlsPlaylistUrl;
|
streamInfo.url = hlsPlaylistUrl;
|
||||||
|
@ -260,7 +260,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
|
|
||||||
}, function () {
|
}, function () {
|
||||||
|
|
||||||
console.log('error prefetching hls playlist: ' + hlsPlaylistUrl);
|
console.error('error prefetching hls playlist: ' + hlsPlaylistUrl);
|
||||||
|
|
||||||
loading.hide();
|
loading.hide();
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
@ -357,6 +357,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
|
||||||
require(['shaka'], function () {
|
require(['shaka'], function () {
|
||||||
|
/* globals shaka */
|
||||||
|
|
||||||
var player = new shaka.Player(elem);
|
var player = new shaka.Player(elem);
|
||||||
|
|
||||||
|
@ -408,7 +409,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
lrd.media.streamType = cast.receiver.media.StreamType.OTHER;
|
lrd.media.streamType = cast.receiver.media.StreamType.OTHER;
|
||||||
lrd.media.customData = options;
|
lrd.media.customData = options;
|
||||||
|
|
||||||
console.log('loading media url into mediaManager');
|
console.debug('loading media url into media manager');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mediaManager.load(lrd);
|
mediaManager.load(lrd);
|
||||||
|
@ -418,7 +419,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
||||||
console.log('mediaManager error: ' + err);
|
console.debug('media manager error: ' + err);
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,11 +461,11 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
protocol = cast.player.api.CreateSmoothStreamingProtocol(host);
|
protocol = cast.player.api.CreateSmoothStreamingProtocol(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('loading playback url: ' + url);
|
console.debug('loading playback url: ' + url);
|
||||||
console.log('contentType: ' + contentType);
|
console.debug('content type: ' + contentType);
|
||||||
|
|
||||||
host.onError = function (errorCode) {
|
host.onError = function (errorCode) {
|
||||||
console.log("Fatal Error - " + errorCode);
|
console.error("fatal Error - " + errorCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
mediaElement.autoplay = false;
|
mediaElement.autoplay = false;
|
||||||
|
@ -499,7 +500,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
elem.removeEventListener('error', onError);
|
elem.removeEventListener('error', onError);
|
||||||
|
|
||||||
var val = options.url;
|
var val = options.url;
|
||||||
console.log('playing url: ' + val);
|
console.debug('playing url: ' + val);
|
||||||
|
|
||||||
// Convert to seconds
|
// Convert to seconds
|
||||||
var seconds = (options.playerStartPositionTicks || 0) / 10000000;
|
var seconds = (options.playerStartPositionTicks || 0) / 10000000;
|
||||||
|
@ -608,7 +609,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
} else if (currentTrackEvents) {
|
} else if (currentTrackEvents) {
|
||||||
setTrackEventsSubtitleOffset(currentTrackEvents, offsetValue);
|
setTrackEventsSubtitleOffset(currentTrackEvents, offsetValue);
|
||||||
} else {
|
} else {
|
||||||
console.log("No available track, cannot apply offset: ", offsetValue);
|
console.debug("No available track, cannot apply offset: ", offsetValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -727,22 +728,18 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
// https://msdn.microsoft.com/en-us/library/hh772507(v=vs.85).aspx
|
// https://msdn.microsoft.com/en-us/library/hh772507(v=vs.85).aspx
|
||||||
|
|
||||||
var elemAudioTracks = elem.audioTracks || [];
|
var elemAudioTracks = elem.audioTracks || [];
|
||||||
console.log('found ' + elemAudioTracks.length + ' audio tracks');
|
console.debug('found ' + elemAudioTracks.length + ' audio tracks');
|
||||||
|
|
||||||
for (i = 0, length = elemAudioTracks.length; i < length; i++) {
|
for (i = 0, length = elemAudioTracks.length; i < length; i++) {
|
||||||
|
|
||||||
if (audioIndex === i) {
|
if (audioIndex === i) {
|
||||||
console.log('setting audio track ' + i + ' to enabled');
|
console.debug('setting audio track ' + i + ' to enabled');
|
||||||
elemAudioTracks[i].enabled = true;
|
elemAudioTracks[i].enabled = true;
|
||||||
} else {
|
} else {
|
||||||
console.log('setting audio track ' + i + ' to disabled');
|
console.debug('setting audio track ' + i + ' to disabled');
|
||||||
elemAudioTracks[i].enabled = false;
|
elemAudioTracks[i].enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
elem.currentTime = elem.currentTime;
|
|
||||||
}, 100);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.stop = function (destroyPlayer) {
|
self.stop = function (destroyPlayer) {
|
||||||
|
@ -911,7 +908,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
function onError() {
|
function onError() {
|
||||||
var errorCode = this.error ? (this.error.code || 0) : 0;
|
var errorCode = this.error ? (this.error.code || 0) : 0;
|
||||||
var errorMessage = this.error ? (this.error.message || '') : '';
|
var errorMessage = this.error ? (this.error.message || '') : '';
|
||||||
console.log('Media element error: ' + errorCode.toString() + ' ' + errorMessage);
|
console.error('media element error: ' + errorCode.toString() + ' ' + errorMessage);
|
||||||
|
|
||||||
var type;
|
var type;
|
||||||
|
|
||||||
|
@ -1049,7 +1046,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
lastCustomTrackMs = 0;
|
lastCustomTrackMs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderWithSubtitlesOctopus(videoElement, track, item) {
|
function renderSsaAss(videoElement, track, item) {
|
||||||
var attachments = self._currentPlayOptions.mediaSource.MediaAttachments || [];
|
var attachments = self._currentPlayOptions.mediaSource.MediaAttachments || [];
|
||||||
var options = {
|
var options = {
|
||||||
video: videoElement,
|
video: videoElement,
|
||||||
|
@ -1058,90 +1055,28 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
return i.DeliveryUrl;
|
return i.DeliveryUrl;
|
||||||
}),
|
}),
|
||||||
workerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker.js",
|
workerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker.js",
|
||||||
|
legacyWorkerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker-legacy.js",
|
||||||
onError: function() {
|
onError: function() {
|
||||||
htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror')
|
htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror');
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// new octopus options; override all, even defaults
|
||||||
|
renderMode: 'blend',
|
||||||
|
dropAllAnimations: false,
|
||||||
|
libassMemoryLimit: 40,
|
||||||
|
libassGlyphLimit: 40,
|
||||||
|
targetFps: 24,
|
||||||
|
prescaleTradeoff: 0.8,
|
||||||
|
softHeightLimit: 1080,
|
||||||
|
hardHeightLimit: 2160,
|
||||||
|
resizeVariation: 0.2,
|
||||||
|
renderAhead: 90
|
||||||
};
|
};
|
||||||
require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) {
|
require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) {
|
||||||
currentSubtitlesOctopus = new SubtitlesOctopus(options);
|
currentSubtitlesOctopus = new SubtitlesOctopus(options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderWithLibjass(videoElement, track, item) {
|
|
||||||
|
|
||||||
var rendererSettings = {};
|
|
||||||
|
|
||||||
if (browser.ps4) {
|
|
||||||
// Text outlines are not rendering very well
|
|
||||||
rendererSettings.enableSvg = false;
|
|
||||||
} else if (browser.edge || browser.msie) {
|
|
||||||
// svg not rendering at all
|
|
||||||
rendererSettings.enableSvg = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// probably safer to just disable everywhere
|
|
||||||
rendererSettings.enableSvg = false;
|
|
||||||
|
|
||||||
require(['libjass', 'ResizeObserver'], function (libjass, ResizeObserver) {
|
|
||||||
|
|
||||||
libjass.ASS.fromUrl(getTextTrackUrl(track, item)).then(function (ass) {
|
|
||||||
|
|
||||||
var clock = new libjass.renderers.ManualClock();
|
|
||||||
currentClock = clock;
|
|
||||||
|
|
||||||
// Create a DefaultRenderer using the video element and the ASS object
|
|
||||||
var renderer = new libjass.renderers.WebRenderer(ass, clock, videoElement.parentNode, rendererSettings);
|
|
||||||
|
|
||||||
currentAssRenderer = renderer;
|
|
||||||
|
|
||||||
renderer.addEventListener("ready", function () {
|
|
||||||
try {
|
|
||||||
renderer.resize(videoElement.offsetWidth, videoElement.offsetHeight, 0, 0);
|
|
||||||
|
|
||||||
if (!self._resizeObserver) {
|
|
||||||
self._resizeObserver = new ResizeObserver(onVideoResize, {});
|
|
||||||
self._resizeObserver.observe(videoElement);
|
|
||||||
}
|
|
||||||
//clock.pause();
|
|
||||||
} catch (ex) {
|
|
||||||
//alert(ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, function () {
|
|
||||||
htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderSsaAss(videoElement, track, item) {
|
|
||||||
if (supportsCanvas() && supportsWebWorkers()) {
|
|
||||||
renderWithSubtitlesOctopus(videoElement, track, item);
|
|
||||||
} else {
|
|
||||||
console.log('rendering subtitles with libjass');
|
|
||||||
renderWithLibjass(videoElement, track, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onVideoResize() {
|
|
||||||
if (browser.iOS) {
|
|
||||||
// the new sizes will be delayed for about 500ms with wkwebview
|
|
||||||
setTimeout(resetVideoRendererSize, 500);
|
|
||||||
} else {
|
|
||||||
resetVideoRendererSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetVideoRendererSize() {
|
|
||||||
var renderer = currentAssRenderer;
|
|
||||||
if (renderer) {
|
|
||||||
var videoElement = self._mediaElement;
|
|
||||||
var width = videoElement.offsetWidth;
|
|
||||||
var height = videoElement.offsetHeight;
|
|
||||||
console.log('videoElement resized: ' + width + 'x' + height);
|
|
||||||
renderer.resize(width, height, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function requiresCustomSubtitlesElement() {
|
function requiresCustomSubtitlesElement() {
|
||||||
|
|
||||||
// after a system update, ps4 isn't showing anything when creating a track element dynamically
|
// after a system update, ps4 isn't showing anything when creating a track element dynamically
|
||||||
|
@ -1231,7 +1166,6 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
if (!itemHelper.isLocalItem(item) || track.IsExternal) {
|
if (!itemHelper.isLocalItem(item) || track.IsExternal) {
|
||||||
var format = (track.Codec || '').toLowerCase();
|
var format = (track.Codec || '').toLowerCase();
|
||||||
if (format === 'ssa' || format === 'ass') {
|
if (format === 'ssa' || format === 'ass') {
|
||||||
// libjass is needed here
|
|
||||||
renderSsaAss(videoElement, track, item);
|
renderSsaAss(videoElement, track, item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1254,7 +1188,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
trackElement.removeCue(trackElement.cues[0]);
|
trackElement.removeCue(trackElement.cues[0]);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('Error removing cue from textTrack');
|
console.error('error removing cue from textTrack');
|
||||||
}
|
}
|
||||||
|
|
||||||
trackElement.mode = 'disabled';
|
trackElement.mode = 'disabled';
|
||||||
|
@ -1268,7 +1202,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
fetchSubtitles(track, item).then(function (data) {
|
fetchSubtitles(track, item).then(function (data) {
|
||||||
|
|
||||||
// show in ui
|
// show in ui
|
||||||
console.log('downloaded ' + data.TrackEvents.length + ' track events');
|
console.debug('downloaded ' + data.TrackEvents.length + ' track events');
|
||||||
// add some cues to show the text
|
// add some cues to show the text
|
||||||
// in safari, the cues need to be added before setting the track mode to showing
|
// in safari, the cues need to be added before setting the track mode to showing
|
||||||
data.TrackEvents.forEach(function (trackEvent) {
|
data.TrackEvents.forEach(function (trackEvent) {
|
||||||
|
@ -1294,7 +1228,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
try {
|
try {
|
||||||
clock.seek(timeMs / 1000);
|
clock.seek(timeMs / 1000);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Error in libjass: ' + err);
|
console.error('error in libjass: ' + err);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1327,7 +1261,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
|
|
||||||
function setCurrentTrackElement(streamIndex) {
|
function setCurrentTrackElement(streamIndex) {
|
||||||
|
|
||||||
console.log('Setting new text track index to: ' + streamIndex);
|
console.debug('setting new text track index to: ' + streamIndex);
|
||||||
|
|
||||||
var mediaStreamTextTracks = getMediaStreamTextTracks(self._currentPlayOptions.mediaSource);
|
var mediaStreamTextTracks = getMediaStreamTextTracks(self._currentPlayOptions.mediaSource);
|
||||||
|
|
||||||
|
@ -1348,38 +1282,6 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTextStreamUrls(startPositionTicks) {
|
|
||||||
|
|
||||||
if (!supportsTextTracks()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var allTracks = self._mediaElement.textTracks; // get list of tracks
|
|
||||||
var i;
|
|
||||||
var track;
|
|
||||||
|
|
||||||
for (i = 0; i < allTracks.length; i++) {
|
|
||||||
|
|
||||||
track = allTracks[i];
|
|
||||||
|
|
||||||
// This throws an error in IE, but is fine in chrome
|
|
||||||
// In IE it's not necessary anyway because changing the src seems to be enough
|
|
||||||
try {
|
|
||||||
while (track.cues.length) {
|
|
||||||
track.removeCue(track.cues[0]);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Error removing cue from textTrack');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var tracks = self._mediaElement.querySelectorAll('track');
|
|
||||||
for (i = 0; i < tracks.length; i++) {
|
|
||||||
track = tracks[i];
|
|
||||||
track.src = replaceQueryString(track.src, 'startPositionTicks', startPositionTicks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMediaElement(options) {
|
function createMediaElement(options) {
|
||||||
|
|
||||||
if (browser.tv || browser.iOS || browser.mobile) {
|
if (browser.tv || browser.iOS || browser.mobile) {
|
||||||
|
@ -1590,7 +1492,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
};
|
};
|
||||||
|
|
||||||
function onPictureInPictureError(err) {
|
function onPictureInPictureError(err) {
|
||||||
console.log('Picture in picture error: ' + err.toString());
|
console.error('Picture in picture error: ' + err.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlVideoPlayer.prototype.setPictureInPictureEnabled = function (isEnabled) {
|
HtmlVideoPlayer.prototype.setPictureInPictureEnabled = function (isEnabled) {
|
||||||
|
@ -1651,9 +1553,13 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
|
||||||
if (document.AirPlayEnabled) {
|
if (document.AirPlayEnabled) {
|
||||||
if (video) {
|
if (video) {
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
video.requestAirPlay().catch(onAirPlayError);
|
video.requestAirPlay().catch(function(err) {
|
||||||
|
console.error("Error requesting AirPlay", err)
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
document.exitAirPLay().catch(onAirPlayError);
|
document.exitAirPLay().catch(function(err) {
|
||||||
|
console.error("Error exiting AirPlay", err)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,6 +25,7 @@ define(["datetime"], function (datetime) {
|
||||||
if (seconds < 0) {
|
if (seconds < 0) {
|
||||||
seconds = Math.abs(seconds);
|
seconds = Math.abs(seconds);
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line no-cond-assign
|
||||||
for (; format = time_formats[i++];) {
|
for (; format = time_formats[i++];) {
|
||||||
if (seconds < format[0]) {
|
if (seconds < format[0]) {
|
||||||
if (2 == format.length) {
|
if (2 == format.length) {
|
||||||
|
|
|
@ -116,8 +116,8 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
|
||||||
if (showControls) {
|
if (showControls) {
|
||||||
html += '<div data-role="controlgroup" data-type="horizontal" style="display:inline-block;">';
|
html += '<div data-role="controlgroup" data-type="horizontal" style="display:inline-block;">';
|
||||||
|
|
||||||
html += '<button is="paper-icon-button-light" title="' + globalize.translate('Previous') + '" class="btnPreviousPage autoSize" ' + (startIndex ? '' : 'disabled') + '><i class="material-icons">arrow_back</i></button>';
|
html += '<button is="paper-icon-button-light" title="' + globalize.translate('Previous') + '" class="btnPreviousPage autoSize" ' + (startIndex ? '' : 'disabled') + '><i class="material-icons arrow_back"></i></button>';
|
||||||
html += '<button is="paper-icon-button-light" title="' + globalize.translate('Next') + '" class="btnNextPage autoSize" ' + (startIndex + limit >= totalRecordCount ? 'disabled' : '') + '><i class="material-icons">arrow_forward</i></button>';
|
html += '<button is="paper-icon-button-light" title="' + globalize.translate('Next') + '" class="btnNextPage autoSize" ' + (startIndex + limit >= totalRecordCount ? 'disabled' : '') + '><i class="material-icons arrow_forward"></i></button>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
|
||||||
if (enableFooterButtons) {
|
if (enableFooterButtons) {
|
||||||
html += '<div class="cardText cardTextCentered">';
|
html += '<div class="cardText cardTextCentered">';
|
||||||
|
|
||||||
html += '<button is="paper-icon-button-light" class="btnDownloadRemoteImage autoSize" raised" title="' + globalize.translate('Download') + '"><i class="material-icons">cloud_download</i></button>';
|
html += '<button is="paper-icon-button-light" class="btnDownloadRemoteImage autoSize" raised" title="' + globalize.translate('Download') + '"><i class="material-icons cloud_download"></i></button>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>
|
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>
|
||||||
<h3 class="formDialogHeaderTitle">
|
<h3 class="formDialogHeaderTitle">
|
||||||
${Search}
|
${Search}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
@ -155,15 +155,15 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager',
|
||||||
if (image.ImageType === "Backdrop" || image.ImageType === "Screenshot") {
|
if (image.ImageType === "Backdrop" || image.ImageType === "Screenshot") {
|
||||||
|
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex - 1) + '" title="' + globalize.translate('MoveLeft') + '"><i class="material-icons">chevron_left</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex - 1) + '" title="' + globalize.translate('MoveLeft') + '"><i class="material-icons chevron_left"></i></button>';
|
||||||
} else {
|
} else {
|
||||||
html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('MoveLeft') + '"><i class="material-icons">chevron_left</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('MoveLeft') + '"><i class="material-icons chevron_left"></i></button>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < numImages - 1) {
|
if (index < numImages - 1) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex + 1) + '" title="' + globalize.translate('MoveRight') + '"><i class="material-icons">chevron_right</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex + 1) + '" title="' + globalize.translate('MoveRight') + '"><i class="material-icons chevron_right"></i></button>';
|
||||||
} else {
|
} else {
|
||||||
html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('MoveRight') + '"><i class="material-icons">chevron_right</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('MoveRight') + '"><i class="material-icons chevron_right"></i></button>';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (imageProviders.length) {
|
if (imageProviders.length) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>
|
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>
|
||||||
<h3 class="formDialogHeaderTitle">
|
<h3 class="formDialogHeaderTitle">
|
||||||
${HeaderEditImages}
|
${HeaderEditImages}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button type="button" is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>
|
<button type="button" is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>
|
||||||
<h3 class="formDialogHeaderTitle">
|
<h3 class="formDialogHeaderTitle">
|
||||||
${HeaderImageOptions}
|
${HeaderImageOptions}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
@ -35,4 +35,4 @@ define(['dom'], function (dom) {
|
||||||
loadImage: loadImage
|
loadImage: loadImage
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -122,4 +122,4 @@ define(['lazyLoader', 'imageFetcher', 'layoutManager', 'browser', 'appSettings',
|
||||||
self.getPrimaryImageAspectRatio = getPrimaryImageAspectRatio;
|
self.getPrimaryImageAspectRatio = getPrimaryImageAspectRatio;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,7 +47,7 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
|
||||||
};
|
};
|
||||||
reader.onabort = function () {
|
reader.onabort = function () {
|
||||||
loading.hide();
|
loading.hide();
|
||||||
console.log('File read cancelled');
|
console.debug('File read cancelled');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Closure to capture the file information.
|
// Closure to capture the file information.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>
|
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>
|
||||||
<h3 class="formDialogHeaderTitle">
|
<h3 class="formDialogHeaderTitle">
|
||||||
${HeaderUploadImage}
|
${HeaderUploadImage}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
|
@ -62,7 +62,7 @@ define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], fun
|
||||||
startDate = datetime.parseISO8601Date(item.StartDate).getTime();
|
startDate = datetime.parseISO8601Date(item.StartDate).getTime();
|
||||||
endDate = datetime.parseISO8601Date(item.EndDate).getTime();
|
endDate = datetime.parseISO8601Date(item.EndDate).getTime();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var now = new Date().getTime();
|
var now = new Date().getTime();
|
||||||
|
@ -118,7 +118,7 @@ define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], fun
|
||||||
var status;
|
var status;
|
||||||
|
|
||||||
if (item.Type === 'SeriesTimer') {
|
if (item.Type === 'SeriesTimer') {
|
||||||
return '<i class="material-icons timerIndicator indicatorIcon">fiber_smart_record</i>';
|
return '<i class="material-icons timerIndicator indicatorIcon fiber_smart_record"></i>';
|
||||||
} else if (item.TimerId || item.SeriesTimerId) {
|
} else if (item.TimerId || item.SeriesTimerId) {
|
||||||
status = item.Status || 'Cancelled';
|
status = item.Status || 'Cancelled';
|
||||||
} else if (item.Type === 'Timer') {
|
} else if (item.Type === 'Timer') {
|
||||||
|
@ -129,20 +129,20 @@ define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], fun
|
||||||
|
|
||||||
if (item.SeriesTimerId) {
|
if (item.SeriesTimerId) {
|
||||||
if (status !== 'Cancelled') {
|
if (status !== 'Cancelled') {
|
||||||
return '<i class="material-icons timerIndicator indicatorIcon">fiber_smart_record</i>';
|
return '<i class="material-icons timerIndicator indicatorIcon fiber_smart_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<i class="material-icons timerIndicator timerIndicator-inactive indicatorIcon">fiber_smart_record</i>';
|
return '<i class="material-icons timerIndicator timerIndicator-inactive indicatorIcon fiber_smart_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<i class="material-icons timerIndicator indicatorIcon">fiber_manual_record</i>';
|
return '<i class="material-icons timerIndicator indicatorIcon fiber_manual_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSyncIndicator(item) {
|
function getSyncIndicator(item) {
|
||||||
if (item.SyncPercent === 100) {
|
if (item.SyncPercent === 100) {
|
||||||
return '<div class="syncIndicator indicator fullSyncIndicator"><i class="material-icons indicatorIcon">file_download</i></div>';
|
return '<div class="syncIndicator indicator fullSyncIndicator"><i class="material-icons indicatorIcon file_download"></i></div>';
|
||||||
} else if (item.SyncPercent != null) {
|
} else if (item.SyncPercent != null) {
|
||||||
return '<div class="syncIndicator indicator emptySyncIndicator"><i class="material-icons indicatorIcon">file_download</i></div>';
|
return '<div class="syncIndicator indicator emptySyncIndicator"><i class="material-icons indicatorIcon file_download"></i></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
|
@ -152,9 +152,12 @@ define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], fun
|
||||||
if (item.Type === 'Video') {
|
if (item.Type === 'Video') {
|
||||||
return '<div class="indicator videoIndicator"><i class="material-icons indicatorIcon">videocam</i></div>';
|
return '<div class="indicator videoIndicator"><i class="material-icons indicatorIcon">videocam</i></div>';
|
||||||
}
|
}
|
||||||
if (item.Type === 'Folder' || item.Type === 'PhotoAlbum') {
|
if (item.Type === 'Folder') {
|
||||||
return '<div class="indicator videoIndicator"><i class="material-icons indicatorIcon">folder</i></div>';
|
return '<div class="indicator videoIndicator"><i class="material-icons indicatorIcon">folder</i></div>';
|
||||||
}
|
}
|
||||||
|
if (item.Type === 'PhotoAlbum') {
|
||||||
|
return '<div class="indicator videoIndicator"><i class="material-icons indicatorIcon photo_album"></i></div>';
|
||||||
|
}
|
||||||
if (item.Type === 'Photo') {
|
if (item.Type === 'Photo') {
|
||||||
return '<div class="indicator videoIndicator"><i class="material-icons indicatorIcon">photo</i></div>';
|
return '<div class="indicator videoIndicator"><i class="material-icons indicatorIcon">photo</i></div>';
|
||||||
}
|
}
|
||||||
|
@ -171,7 +174,7 @@ define(['datetime', 'itemHelper', 'css!./indicators.css', 'material-icons'], fun
|
||||||
return '<div class="unairedIndicator">Unaired</div>';
|
return '<div class="unairedIndicator">Unaired</div>';
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '<div class="missingIndicator">Missing</div>';
|
return '<div class="missingIndicator">Missing</div>';
|
||||||
|
|
|
@ -251,114 +251,150 @@ require(['apphost'], function (appHost) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var inputLoopTimer;
|
||||||
function runInputLoop() {
|
function runInputLoop() {
|
||||||
// Get the latest gamepad state.
|
// Get the latest gamepad state.
|
||||||
var gamepads;
|
var gamepads = navigator.getGamepads();
|
||||||
if (navigator.getGamepads) {
|
for (var i = 0, len = gamepads.length; i < len; i++) {
|
||||||
gamepads = navigator.getGamepads();
|
|
||||||
} else if (navigator.webkitGetGamepads) {
|
|
||||||
gamepads = navigator.webkitGetGamepads();
|
|
||||||
}
|
|
||||||
gamepads = gamepads || [];
|
|
||||||
var i;
|
|
||||||
var j;
|
|
||||||
var len;
|
|
||||||
for (i = 0, len = gamepads.length; i < len; i++) {
|
|
||||||
var gamepad = gamepads[i];
|
var gamepad = gamepads[i];
|
||||||
if (gamepad) {
|
if (!gamepad) {
|
||||||
// Iterate through the axes
|
continue;
|
||||||
var axes = gamepad.axes;
|
}
|
||||||
var leftStickX = axes[0];
|
// Iterate through the axes
|
||||||
var leftStickY = axes[1];
|
var axes = gamepad.axes;
|
||||||
if (leftStickX > _THUMB_STICK_THRESHOLD) { // Right
|
var leftStickX = axes[0];
|
||||||
_ButtonPressedState.setleftThumbstickRight(true);
|
var leftStickY = axes[1];
|
||||||
} else if (leftStickX < -_THUMB_STICK_THRESHOLD) { // Left
|
if (leftStickX > _THUMB_STICK_THRESHOLD) { // Right
|
||||||
_ButtonPressedState.setleftThumbstickLeft(true);
|
_ButtonPressedState.setleftThumbstickRight(true);
|
||||||
} else if (leftStickY < -_THUMB_STICK_THRESHOLD) { // Up
|
} else if (leftStickX < -_THUMB_STICK_THRESHOLD) { // Left
|
||||||
_ButtonPressedState.setleftThumbstickUp(true);
|
_ButtonPressedState.setleftThumbstickLeft(true);
|
||||||
} else if (leftStickY > _THUMB_STICK_THRESHOLD) { // Down
|
} else if (leftStickY < -_THUMB_STICK_THRESHOLD) { // Up
|
||||||
_ButtonPressedState.setleftThumbstickDown(true);
|
_ButtonPressedState.setleftThumbstickUp(true);
|
||||||
} else {
|
} else if (leftStickY > _THUMB_STICK_THRESHOLD) { // Down
|
||||||
_ButtonPressedState.setleftThumbstickLeft(false);
|
_ButtonPressedState.setleftThumbstickDown(true);
|
||||||
_ButtonPressedState.setleftThumbstickRight(false);
|
} else {
|
||||||
_ButtonPressedState.setleftThumbstickUp(false);
|
_ButtonPressedState.setleftThumbstickLeft(false);
|
||||||
_ButtonPressedState.setleftThumbstickDown(false);
|
_ButtonPressedState.setleftThumbstickRight(false);
|
||||||
}
|
_ButtonPressedState.setleftThumbstickUp(false);
|
||||||
// Iterate through the buttons to see if Left thumbstick, DPad, A and B are pressed.
|
_ButtonPressedState.setleftThumbstickDown(false);
|
||||||
var buttons = gamepad.buttons;
|
}
|
||||||
for (j = 0, len = buttons.length; j < len; j++) {
|
// Iterate through the buttons to see if Left thumbstick, DPad, A and B are pressed.
|
||||||
if (ProcessedButtons.indexOf(j) !== -1) {
|
var buttons = gamepad.buttons;
|
||||||
|
for (var j = 0, len = buttons.length; j < len; j++) {
|
||||||
if (buttons[j].pressed) {
|
if (ProcessedButtons.indexOf(j) !== -1) {
|
||||||
switch (j) {
|
if (buttons[j].pressed) {
|
||||||
case _GAMEPAD_DPAD_UP_BUTTON_INDEX:
|
switch (j) {
|
||||||
_ButtonPressedState.setdPadUp(true);
|
case _GAMEPAD_DPAD_UP_BUTTON_INDEX:
|
||||||
break;
|
_ButtonPressedState.setdPadUp(true);
|
||||||
case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX:
|
break;
|
||||||
_ButtonPressedState.setdPadDown(true);
|
case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX:
|
||||||
break;
|
_ButtonPressedState.setdPadDown(true);
|
||||||
case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX:
|
break;
|
||||||
_ButtonPressedState.setdPadLeft(true);
|
case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX:
|
||||||
break;
|
_ButtonPressedState.setdPadLeft(true);
|
||||||
case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX:
|
break;
|
||||||
_ButtonPressedState.setdPadRight(true);
|
case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX:
|
||||||
break;
|
_ButtonPressedState.setdPadRight(true);
|
||||||
case _GAMEPAD_A_BUTTON_INDEX:
|
break;
|
||||||
_ButtonPressedState.setgamepadA(true);
|
case _GAMEPAD_A_BUTTON_INDEX:
|
||||||
break;
|
_ButtonPressedState.setgamepadA(true);
|
||||||
case _GAMEPAD_B_BUTTON_INDEX:
|
break;
|
||||||
_ButtonPressedState.setgamepadB(true);
|
case _GAMEPAD_B_BUTTON_INDEX:
|
||||||
break;
|
_ButtonPressedState.setgamepadB(true);
|
||||||
default:
|
break;
|
||||||
// No-op
|
default:
|
||||||
break;
|
// No-op
|
||||||
}
|
break;
|
||||||
} else {
|
}
|
||||||
switch (j) {
|
} else {
|
||||||
case _GAMEPAD_DPAD_UP_BUTTON_INDEX:
|
switch (j) {
|
||||||
if (_ButtonPressedState.getdPadUp()) {
|
case _GAMEPAD_DPAD_UP_BUTTON_INDEX:
|
||||||
_ButtonPressedState.setdPadUp(false);
|
if (_ButtonPressedState.getdPadUp()) {
|
||||||
}
|
_ButtonPressedState.setdPadUp(false);
|
||||||
break;
|
}
|
||||||
case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX:
|
break;
|
||||||
if (_ButtonPressedState.getdPadDown()) {
|
case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX:
|
||||||
_ButtonPressedState.setdPadDown(false);
|
if (_ButtonPressedState.getdPadDown()) {
|
||||||
}
|
_ButtonPressedState.setdPadDown(false);
|
||||||
break;
|
}
|
||||||
case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX:
|
break;
|
||||||
if (_ButtonPressedState.getdPadLeft()) {
|
case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX:
|
||||||
_ButtonPressedState.setdPadLeft(false);
|
if (_ButtonPressedState.getdPadLeft()) {
|
||||||
}
|
_ButtonPressedState.setdPadLeft(false);
|
||||||
break;
|
}
|
||||||
case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX:
|
break;
|
||||||
if (_ButtonPressedState.getdPadRight()) {
|
case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX:
|
||||||
_ButtonPressedState.setdPadRight(false);
|
if (_ButtonPressedState.getdPadRight()) {
|
||||||
}
|
_ButtonPressedState.setdPadRight(false);
|
||||||
break;
|
}
|
||||||
case _GAMEPAD_A_BUTTON_INDEX:
|
break;
|
||||||
if (_ButtonPressedState.getgamepadA()) {
|
case _GAMEPAD_A_BUTTON_INDEX:
|
||||||
_ButtonPressedState.setgamepadA(false);
|
if (_ButtonPressedState.getgamepadA()) {
|
||||||
}
|
_ButtonPressedState.setgamepadA(false);
|
||||||
break;
|
}
|
||||||
case _GAMEPAD_B_BUTTON_INDEX:
|
break;
|
||||||
if (_ButtonPressedState.getgamepadB()) {
|
case _GAMEPAD_B_BUTTON_INDEX:
|
||||||
_ButtonPressedState.setgamepadB(false);
|
if (_ButtonPressedState.getgamepadB()) {
|
||||||
}
|
_ButtonPressedState.setgamepadB(false);
|
||||||
break;
|
}
|
||||||
default:
|
break;
|
||||||
// No-op
|
default:
|
||||||
break;
|
// No-op
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Schedule the next one
|
// Schedule the next one
|
||||||
requestAnimationFrame(runInputLoop);
|
inputLoopTimer = requestAnimationFrame(runInputLoop);
|
||||||
}
|
}
|
||||||
|
|
||||||
runInputLoop();
|
function startInputLoop() {
|
||||||
|
if (!inputLoopTimer) {
|
||||||
|
runInputLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopInputLoop() {
|
||||||
|
cancelAnimationFrame(inputLoopTimer);
|
||||||
|
inputLoopTimer = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isGamepadConnected() {
|
||||||
|
var gamepads = navigator.getGamepads();
|
||||||
|
for (var i = 0, len = gamepads.length; i < len; i++) {
|
||||||
|
var gamepad = gamepads[i];
|
||||||
|
if (gamepad && gamepad.connected) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFocusOrGamepadAttach(e) {
|
||||||
|
if (isGamepadConnected() && document.hasFocus()) {
|
||||||
|
console.log("Gamepad connected! Starting input loop");
|
||||||
|
startInputLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFocusOrGamepadDetach(e) {
|
||||||
|
if (!isGamepadConnected() || !document.hasFocus()) {
|
||||||
|
console.log("Gamepad disconnected! No other gamepads are connected, stopping input loop");
|
||||||
|
stopInputLoop();
|
||||||
|
} else {
|
||||||
|
console.log("Gamepad disconnected! There are gamepads still connected.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listeners for any change in gamepads' state.
|
||||||
|
window.addEventListener("gamepaddisconnected", onFocusOrGamepadDetach);
|
||||||
|
window.addEventListener("gamepadconnected", onFocusOrGamepadAttach);
|
||||||
|
window.addEventListener("blur", onFocusOrGamepadDetach);
|
||||||
|
window.addEventListener("focus", onFocusOrGamepadAttach);
|
||||||
|
|
||||||
|
onFocusOrGamepadAttach();
|
||||||
|
|
||||||
// The gamepadInputEmulation is a string property that exists in JavaScript UWAs and in WebViews in UWAs.
|
// The gamepadInputEmulation is a string property that exists in JavaScript UWAs and in WebViews in UWAs.
|
||||||
// It won't exist in Win8.1 style apps or browsers.
|
// It won't exist in Win8.1 style apps or browsers.
|
||||||
|
@ -369,4 +405,4 @@ require(['apphost'], function (appHost) {
|
||||||
window.navigator.gamepadInputEmulation = "gamepad";
|
window.navigator.gamepadInputEmulation = "gamepad";
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
157
src/components/input/keyboardnavigation.js
Normal file
157
src/components/input/keyboardnavigation.js
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
import inputManager from "inputManager";
|
||||||
|
import layoutManager from "layoutManager";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key name mapping.
|
||||||
|
*/
|
||||||
|
const KeyNames = {
|
||||||
|
13: "Enter",
|
||||||
|
19: "Pause",
|
||||||
|
27: "Escape",
|
||||||
|
32: "Space",
|
||||||
|
37: "ArrowLeft",
|
||||||
|
38: "ArrowUp",
|
||||||
|
39: "ArrowRight",
|
||||||
|
40: "ArrowDown",
|
||||||
|
// MediaRewind (Tizen/WebOS)
|
||||||
|
412: "MediaRewind",
|
||||||
|
// MediaStop (Tizen/WebOS)
|
||||||
|
413: "MediaStop",
|
||||||
|
// MediaPlay (Tizen/WebOS)
|
||||||
|
415: "MediaPlay",
|
||||||
|
// MediaFastForward (Tizen/WebOS)
|
||||||
|
417: "MediaFastForward",
|
||||||
|
// Back (WebOS)
|
||||||
|
461: "Back",
|
||||||
|
// Back (Tizen)
|
||||||
|
10009: "Back",
|
||||||
|
// MediaTrackPrevious (Tizen)
|
||||||
|
10232: "MediaTrackPrevious",
|
||||||
|
// MediaTrackNext (Tizen)
|
||||||
|
10233: "MediaTrackNext",
|
||||||
|
// MediaPlayPause (Tizen)
|
||||||
|
10252: "MediaPlayPause"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keys used for keyboard navigation.
|
||||||
|
*/
|
||||||
|
const NavigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"];
|
||||||
|
|
||||||
|
let hasFieldKey = false;
|
||||||
|
try {
|
||||||
|
hasFieldKey = "key" in new KeyboardEvent("keydown");
|
||||||
|
} catch (e) {
|
||||||
|
console.error("error checking 'key' field");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasFieldKey) {
|
||||||
|
// Add [a..z]
|
||||||
|
for (let i = 65; i <= 90; i++) {
|
||||||
|
KeyNames[i] = String.fromCharCode(i).toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns key name from event.
|
||||||
|
*
|
||||||
|
* @param {KeyboardEvent} event keyboard event
|
||||||
|
* @return {string} key name
|
||||||
|
*/
|
||||||
|
export function getKeyName(event) {
|
||||||
|
return KeyNames[event.keyCode] || event.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns _true_ if key is used for navigation.
|
||||||
|
*
|
||||||
|
* @param {string} key name
|
||||||
|
* @return {boolean} _true_ if key is used for navigation
|
||||||
|
*/
|
||||||
|
export function isNavigationKey(key) {
|
||||||
|
return NavigationKeys.indexOf(key) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function enable() {
|
||||||
|
document.addEventListener("keydown", function (e) {
|
||||||
|
const key = getKeyName(e);
|
||||||
|
|
||||||
|
// Ignore navigation keys for non-TV
|
||||||
|
if (!layoutManager.tv && isNavigationKey(key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let capture = true;
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case "ArrowLeft":
|
||||||
|
inputManager.handle("left");
|
||||||
|
break;
|
||||||
|
case "ArrowUp":
|
||||||
|
inputManager.handle("up");
|
||||||
|
break;
|
||||||
|
case "ArrowRight":
|
||||||
|
inputManager.handle("right");
|
||||||
|
break;
|
||||||
|
case "ArrowDown":
|
||||||
|
inputManager.handle("down");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Back":
|
||||||
|
inputManager.handle("back");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Escape":
|
||||||
|
if (layoutManager.tv) {
|
||||||
|
inputManager.handle("back");
|
||||||
|
} else {
|
||||||
|
capture = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "MediaPlay":
|
||||||
|
inputManager.handle("play");
|
||||||
|
break;
|
||||||
|
case "Pause":
|
||||||
|
inputManager.handle("pause");
|
||||||
|
break;
|
||||||
|
case "MediaPlayPause":
|
||||||
|
inputManager.handle("playpause");
|
||||||
|
break;
|
||||||
|
case "MediaRewind":
|
||||||
|
inputManager.handle("rewind");
|
||||||
|
break;
|
||||||
|
case "MediaFastForward":
|
||||||
|
inputManager.handle("fastforward");
|
||||||
|
break;
|
||||||
|
case "MediaStop":
|
||||||
|
inputManager.handle("stop");
|
||||||
|
break;
|
||||||
|
case "MediaTrackPrevious":
|
||||||
|
inputManager.handle("previoustrack");
|
||||||
|
break;
|
||||||
|
case "MediaTrackNext":
|
||||||
|
inputManager.handle("nexttrack");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
capture = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (capture) {
|
||||||
|
console.debug("disabling default event handling");
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gamepad initialisation. No script is required if no gamepads are present at init time, saving a bit of resources.
|
||||||
|
// Whenever the gamepad is connected, we hand all the control of the gamepad to gamepadtokey.js by removing the event handler
|
||||||
|
function attachGamepadScript(e) {
|
||||||
|
console.log("Gamepad connected! Attaching gamepadtokey.js script");
|
||||||
|
window.removeEventListener("gamepadconnected", attachGamepadScript);
|
||||||
|
require(["components/input/gamepadtokey"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No need to check for gamepads manually at load time, the eventhandler will be fired for that
|
||||||
|
window.addEventListener("gamepadconnected", attachGamepadScript);
|
|
@ -166,4 +166,4 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd
|
||||||
events.on(layoutManager, 'modechange', initMouse);
|
events.on(layoutManager, 'modechange', initMouse);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
|
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons arrow_back"></i>
|
||||||
</button>
|
</button>
|
||||||
<h3 class="formDialogHeaderTitle">${HeaderMediaInfo}</h3>
|
<h3 class="formDialogHeaderTitle">${HeaderMediaInfo}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,7 +15,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
|
||||||
commands.push({
|
commands.push({
|
||||||
name: globalize.translate("Play"),
|
name: globalize.translate("Play"),
|
||||||
id: "resume",
|
id: "resume",
|
||||||
icon: "play_arrow"
|
icon: ""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
|
||||||
commands.push({
|
commands.push({
|
||||||
name: globalize.translate("PlayAllFromHere"),
|
name: globalize.translate("PlayAllFromHere"),
|
||||||
id: "playallfromhere",
|
id: "playallfromhere",
|
||||||
icon: "play_arrow"
|
icon: ""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,11 +346,7 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
|
||||||
break;
|
break;
|
||||||
case "copy-stream":
|
case "copy-stream":
|
||||||
var downloadHref = apiClient.getItemDownloadUrl(itemId);
|
var downloadHref = apiClient.getItemDownloadUrl(itemId);
|
||||||
navigator.clipboard.writeText(downloadHref).then(function () {
|
var textAreaCopy = function () {
|
||||||
require(["toast"], function (toast) {
|
|
||||||
toast(globalize.translate("CopyStreamURLSuccess"));
|
|
||||||
});
|
|
||||||
}, function () {
|
|
||||||
var textArea = document.createElement("textarea");
|
var textArea = document.createElement("textarea");
|
||||||
textArea.value = downloadHref;
|
textArea.value = downloadHref;
|
||||||
document.body.appendChild(textArea);
|
document.body.appendChild(textArea);
|
||||||
|
@ -364,7 +360,16 @@ define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter",
|
||||||
prompt(globalize.translate("CopyStreamURL"), downloadHref);
|
prompt(globalize.translate("CopyStreamURL"), downloadHref);
|
||||||
}
|
}
|
||||||
document.body.removeChild(textArea);
|
document.body.removeChild(textArea);
|
||||||
});
|
};
|
||||||
|
if (navigator.clipboard === undefined) {
|
||||||
|
textAreaCopy();
|
||||||
|
} else {
|
||||||
|
navigator.clipboard.writeText(downloadHref).then(function () {
|
||||||
|
require(["toast"], function (toast) {
|
||||||
|
toast(globalize.translate("CopyStreamURLSuccess"));
|
||||||
|
});
|
||||||
|
}, textAreaCopy);
|
||||||
|
}
|
||||||
getResolveFunction(resolve, id)();
|
getResolveFunction(resolve, id)();
|
||||||
break;
|
break;
|
||||||
case "editsubtitles":
|
case "editsubtitles":
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
|
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
|
||||||
<i class="material-icons">arrow_back</i>
|
<i class="material-icons arrow_back"></i>
|
||||||
</button>
|
</button>
|
||||||
<h3 class="formDialogHeaderTitle">${Identify}</h3>
|
<h3 class="formDialogHeaderTitle">${Identify}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -278,4 +278,4 @@ define(['playbackManager', 'serverNotifications', 'events'], function (playbackM
|
||||||
};
|
};
|
||||||
|
|
||||||
return ItemsRefresher;
|
return ItemsRefresher;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
define(["inputManager", "layoutManager"], function (inputManager, layoutManager) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
console.log("keyboardnavigation");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Key name mapping.
|
|
||||||
*/
|
|
||||||
// Add more to support old browsers
|
|
||||||
var KeyNames = {
|
|
||||||
13: "Enter",
|
|
||||||
19: "Pause",
|
|
||||||
27: "Escape",
|
|
||||||
32: "Space",
|
|
||||||
37: "ArrowLeft",
|
|
||||||
38: "ArrowUp",
|
|
||||||
39: "ArrowRight",
|
|
||||||
40: "ArrowDown",
|
|
||||||
// MediaRewind (Tizen/WebOS)
|
|
||||||
412: "MediaRewind",
|
|
||||||
// MediaStop (Tizen/WebOS)
|
|
||||||
413: "MediaStop",
|
|
||||||
// MediaPlay (Tizen/WebOS)
|
|
||||||
415: "MediaPlay",
|
|
||||||
// MediaFastForward (Tizen/WebOS)
|
|
||||||
417: "MediaFastForward",
|
|
||||||
// Back (WebOS)
|
|
||||||
461: "Back",
|
|
||||||
// Back (Tizen)
|
|
||||||
10009: "Back",
|
|
||||||
// MediaTrackPrevious (Tizen)
|
|
||||||
10232: "MediaTrackPrevious",
|
|
||||||
// MediaTrackNext (Tizen)
|
|
||||||
10233: "MediaTrackNext",
|
|
||||||
// MediaPlayPause (Tizen)
|
|
||||||
10252: "MediaPlayPause"
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Keys used for keyboard navigation.
|
|
||||||
*/
|
|
||||||
var NavigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"];
|
|
||||||
|
|
||||||
var hasFieldKey = false;
|
|
||||||
try {
|
|
||||||
hasFieldKey = "key" in new KeyboardEvent("keydown");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("error checking 'key' field");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasFieldKey) {
|
|
||||||
// Add [a..z]
|
|
||||||
for (var i = 65; i <= 90; i++) {
|
|
||||||
KeyNames[i] = String.fromCharCode(i).toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns key name from event.
|
|
||||||
*
|
|
||||||
* @param {KeyboardEvent} keyboard event
|
|
||||||
* @return {string} key name
|
|
||||||
*/
|
|
||||||
function getKeyName(event) {
|
|
||||||
return KeyNames[event.keyCode] || event.key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns _true_ if key is used for navigation.
|
|
||||||
*
|
|
||||||
* @param {string} key name
|
|
||||||
* @return {boolean} _true_ if key is used for navigation
|
|
||||||
*/
|
|
||||||
function isNavigationKey(key) {
|
|
||||||
return NavigationKeys.indexOf(key) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function enable() {
|
|
||||||
document.addEventListener("keydown", function (e) {
|
|
||||||
var key = getKeyName(e);
|
|
||||||
|
|
||||||
// Ignore navigation keys for non-TV
|
|
||||||
if (!layoutManager.tv && isNavigationKey(key)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var capture = true;
|
|
||||||
|
|
||||||
switch (key) {
|
|
||||||
case "ArrowLeft":
|
|
||||||
inputManager.handle("left");
|
|
||||||
break;
|
|
||||||
case "ArrowUp":
|
|
||||||
inputManager.handle("up");
|
|
||||||
break;
|
|
||||||
case "ArrowRight":
|
|
||||||
inputManager.handle("right");
|
|
||||||
break;
|
|
||||||
case "ArrowDown":
|
|
||||||
inputManager.handle("down");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "Back":
|
|
||||||
inputManager.handle("back");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "Escape":
|
|
||||||
if (layoutManager.tv) {
|
|
||||||
inputManager.handle("back");
|
|
||||||
} else {
|
|
||||||
capture = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "MediaPlay":
|
|
||||||
inputManager.handle("play");
|
|
||||||
break;
|
|
||||||
case "Pause":
|
|
||||||
inputManager.handle("pause");
|
|
||||||
break;
|
|
||||||
case "MediaPlayPause":
|
|
||||||
inputManager.handle("playpause");
|
|
||||||
break;
|
|
||||||
case "MediaRewind":
|
|
||||||
inputManager.handle("rewind");
|
|
||||||
break;
|
|
||||||
case "MediaFastForward":
|
|
||||||
inputManager.handle("fastforward");
|
|
||||||
break;
|
|
||||||
case "MediaStop":
|
|
||||||
inputManager.handle("stop");
|
|
||||||
break;
|
|
||||||
case "MediaTrackPrevious":
|
|
||||||
inputManager.handle("previoustrack");
|
|
||||||
break;
|
|
||||||
case "MediaTrackNext":
|
|
||||||
inputManager.handle("nexttrack");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
capture = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (capture) {
|
|
||||||
console.log("Disabling default event handling");
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
enable: enable,
|
|
||||||
getKeyName: getKeyName,
|
|
||||||
isNavigationKey: isNavigationKey
|
|
||||||
};
|
|
||||||
});
|
|
|
@ -100,4 +100,4 @@ define(['require', 'browser'], function (require, browser) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return LazyLoader;
|
return LazyLoader;
|
||||||
});
|
});
|
||||||
|
|
|
@ -186,4 +186,4 @@ define(['visibleinviewport', 'dom', 'browser'], function (visibleinviewport, dom
|
||||||
};
|
};
|
||||||
|
|
||||||
return LazyLoader;
|
return LazyLoader;
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,16 +58,16 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
for (var i = 0; i < plugins.length; i++) {
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
var plugin = plugins[i];
|
var plugin = plugins[i];
|
||||||
html += '<div class="listItem localReaderOption sortableOption" data-pluginname="' + plugin.Name + '">';
|
html += '<div class="listItem localReaderOption sortableOption" data-pluginname="' + plugin.Name + '">';
|
||||||
html += '<i class="listItemIcon material-icons">live_tv</i>';
|
html += '<i class="listItemIcon material-icons live_tv"></i>';
|
||||||
html += '<div class="listItemBody">';
|
html += '<div class="listItemBody">';
|
||||||
html += '<h3 class="listItemBodyText">';
|
html += '<h3 class="listItemBodyText">';
|
||||||
html += plugin.Name;
|
html += plugin.Name;
|
||||||
html += "</h3>";
|
html += "</h3>";
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons">keyboard_arrow_up</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_up"></i></button>';
|
||||||
} else if (plugins.length > 1) {
|
} else if (plugins.length > 1) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons">keyboard_arrow_down</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_down"></i></button>';
|
||||||
}
|
}
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
if (!plugins.length) return html;
|
if (!plugins.length) return html;
|
||||||
|
|
||||||
html += '<div class="metadataFetcher" data-type="' + availableTypeOptions.Type + '">';
|
html += '<div class="metadataFetcher" data-type="' + availableTypeOptions.Type + '">';
|
||||||
html += '<h3 class="checkboxListLabel">' + globalize.translate("LabelTypeMetadataDownloaders", availableTypeOptions.Type) + "</h3>";
|
html += '<h3 class="checkboxListLabel">' + globalize.translate("LabelTypeMetadataDownloaders", globalize.translate(availableTypeOptions.Type)) + "</h3>";
|
||||||
html += '<div class="checkboxList paperList checkboxList-paperList">';
|
html += '<div class="checkboxList paperList checkboxList-paperList">';
|
||||||
for (var i = 0; i < plugins.length; i++) {
|
for (var i = 0; i < plugins.length; i++) {
|
||||||
var plugin = plugins[i];
|
var plugin = plugins[i];
|
||||||
|
@ -120,7 +120,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
html += plugin.Name;
|
html += plugin.Name;
|
||||||
html += "</h3>";
|
html += "</h3>";
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
i > 0 ? html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons">keyboard_arrow_up</i></button>' : plugins.length > 1 && (html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons">keyboard_arrow_down</i></button>'), html += "</div>"
|
i > 0 ? html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_up"></i></button>' : plugins.length > 1 && (html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_down"></i></button>'), html += "</div>"
|
||||||
}
|
}
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
html += '<div class="fieldDescription">' + globalize.translate("LabelMetadataDownloadersHelp") + "</div>";
|
html += '<div class="fieldDescription">' + globalize.translate("LabelMetadataDownloadersHelp") + "</div>";
|
||||||
|
@ -181,9 +181,9 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
html += "</h3>";
|
html += "</h3>";
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons">keyboard_arrow_up</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_up"></i></button>';
|
||||||
} else if (plugins.length > 1) {
|
} else if (plugins.length > 1) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons">keyboard_arrow_down</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_down"></i></button>';
|
||||||
}
|
}
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
}
|
}
|
||||||
|
@ -220,9 +220,9 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
html += "</h3>";
|
html += "</h3>";
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons">keyboard_arrow_up</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_up"></i></button>';
|
||||||
} else if (plugins.length > 1) {
|
} else if (plugins.length > 1) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons">keyboard_arrow_down</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_down"></i></button>';
|
||||||
}
|
}
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
}
|
}
|
||||||
|
@ -273,14 +273,19 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
|
|
||||||
function adjustSortableListElement(elem) {
|
function adjustSortableListElement(elem) {
|
||||||
var btnSortable = elem.querySelector(".btnSortable");
|
var btnSortable = elem.querySelector(".btnSortable");
|
||||||
|
var inner = btnSortable.querySelector("i");
|
||||||
if (elem.previousSibling) {
|
if (elem.previousSibling) {
|
||||||
|
btnSortable.title = globalize.translate("ButtonUp");
|
||||||
btnSortable.classList.add("btnSortableMoveUp");
|
btnSortable.classList.add("btnSortableMoveUp");
|
||||||
btnSortable.classList.remove("btnSortableMoveDown");
|
btnSortable.classList.remove("btnSortableMoveDown");
|
||||||
btnSortable.querySelector("i").innerHTML = "keyboard_arrow_up";
|
inner.classList.remove("keyboard_arrow_down");
|
||||||
|
inner.classList.add("keyboard_arrow_up");
|
||||||
} else {
|
} else {
|
||||||
|
btnSortable.title = globalize.translate("ButtonDown");
|
||||||
btnSortable.classList.remove("btnSortableMoveUp");
|
btnSortable.classList.remove("btnSortableMoveUp");
|
||||||
btnSortable.classList.add("btnSortableMoveDown");
|
btnSortable.classList.add("btnSortableMoveDown");
|
||||||
btnSortable.querySelector("i").innerHTML = "keyboard_arrow_down";
|
inner.classList.remove("keyboard_arrow_up");
|
||||||
|
inner.classList.add("keyboard_arrow_down");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,6 +396,12 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
parent.querySelector(".chkEnableEmbeddedTitlesContainer").classList.remove("hide");
|
parent.querySelector(".chkEnableEmbeddedTitlesContainer").classList.remove("hide");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (contentType === "tvshows") {
|
||||||
|
parent.querySelector(".chkEnableEmbeddedEpisodeInfosContainer").classList.remove("hide");
|
||||||
|
} else {
|
||||||
|
parent.querySelector(".chkEnableEmbeddedEpisodeInfosContainer").classList.add("hide");
|
||||||
|
}
|
||||||
|
|
||||||
return populateMetadataSettings(parent, contentType);
|
return populateMetadataSettings(parent, contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,7 +474,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
|
|
||||||
if (!typeOptions) {
|
if (!typeOptions) {
|
||||||
typeOptions = {
|
typeOptions = {
|
||||||
Type: type
|
Type: originalTypeOption.Type
|
||||||
};
|
};
|
||||||
options.TypeOptions.push(typeOptions);
|
options.TypeOptions.push(typeOptions);
|
||||||
}
|
}
|
||||||
|
@ -488,6 +499,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
SeasonZeroDisplayName: parent.querySelector("#txtSeasonZeroName").value,
|
SeasonZeroDisplayName: parent.querySelector("#txtSeasonZeroName").value,
|
||||||
AutomaticRefreshIntervalDays: parseInt(parent.querySelector("#selectAutoRefreshInterval").value),
|
AutomaticRefreshIntervalDays: parseInt(parent.querySelector("#selectAutoRefreshInterval").value),
|
||||||
EnableEmbeddedTitles: parent.querySelector("#chkEnableEmbeddedTitles").checked,
|
EnableEmbeddedTitles: parent.querySelector("#chkEnableEmbeddedTitles").checked,
|
||||||
|
EnableEmbeddedEpisodeInfos: parent.querySelector("#chkEnableEmbeddedEpisodeInfos").checked,
|
||||||
SkipSubtitlesIfEmbeddedSubtitlesPresent: parent.querySelector("#chkSkipIfGraphicalSubsPresent").checked,
|
SkipSubtitlesIfEmbeddedSubtitlesPresent: parent.querySelector("#chkSkipIfGraphicalSubsPresent").checked,
|
||||||
SkipSubtitlesIfAudioTrackMatches: parent.querySelector("#chkSkipIfAudioTrackPresent").checked,
|
SkipSubtitlesIfAudioTrackMatches: parent.querySelector("#chkSkipIfAudioTrackPresent").checked,
|
||||||
SaveSubtitlesWithMedia: parent.querySelector("#chkSaveSubtitlesLocally").checked,
|
SaveSubtitlesWithMedia: parent.querySelector("#chkSaveSubtitlesLocally").checked,
|
||||||
|
@ -540,6 +552,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
|
||||||
parent.querySelector("#chkImportMissingEpisodes").checked = options.ImportMissingEpisodes;
|
parent.querySelector("#chkImportMissingEpisodes").checked = options.ImportMissingEpisodes;
|
||||||
parent.querySelector(".chkAutomaticallyGroupSeries").checked = options.EnableAutomaticSeriesGrouping;
|
parent.querySelector(".chkAutomaticallyGroupSeries").checked = options.EnableAutomaticSeriesGrouping;
|
||||||
parent.querySelector("#chkEnableEmbeddedTitles").checked = options.EnableEmbeddedTitles;
|
parent.querySelector("#chkEnableEmbeddedTitles").checked = options.EnableEmbeddedTitles;
|
||||||
|
parent.querySelector("#chkEnableEmbeddedEpisodeInfos").checked = options.EnableEmbeddedEpisodeInfos;
|
||||||
parent.querySelector("#chkSkipIfGraphicalSubsPresent").checked = options.SkipSubtitlesIfEmbeddedSubtitlesPresent;
|
parent.querySelector("#chkSkipIfGraphicalSubsPresent").checked = options.SkipSubtitlesIfEmbeddedSubtitlesPresent;
|
||||||
parent.querySelector("#chkSaveSubtitlesLocally").checked = options.SaveSubtitlesWithMedia;
|
parent.querySelector("#chkSaveSubtitlesLocally").checked = options.SaveSubtitlesWithMedia;
|
||||||
parent.querySelector("#chkSkipIfAudioTrackPresent").checked = options.SkipSubtitlesIfAudioTrackMatches;
|
parent.querySelector("#chkSkipIfAudioTrackPresent").checked = options.SkipSubtitlesIfAudioTrackMatches;
|
||||||
|
|
|
@ -28,6 +28,13 @@
|
||||||
</label>
|
</label>
|
||||||
<div class="fieldDescription checkboxFieldDescription">${PreferEmbeddedTitlesOverFileNamesHelp}</div>
|
<div class="fieldDescription checkboxFieldDescription">${PreferEmbeddedTitlesOverFileNamesHelp}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="checkboxContainer checkboxContainer-withDescription chkEnableEmbeddedEpisodeInfosContainer hide advanced">
|
||||||
|
<label>
|
||||||
|
<input is="emby-checkbox" type="checkbox" id="chkEnableEmbeddedEpisodeInfos" />
|
||||||
|
<span>${PreferEmbeddedEpisodeInfosOverFileNames}</span>
|
||||||
|
</label>
|
||||||
|
<div class="fieldDescription checkboxFieldDescription">${PreferEmbeddedEpisodeInfosOverFileNamesHelp}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="checkboxContainer checkboxContainer-withDescription advanced">
|
<div class="checkboxContainer checkboxContainer-withDescription advanced">
|
||||||
<label>
|
<label>
|
||||||
|
@ -147,4 +154,4 @@
|
||||||
</label>
|
</label>
|
||||||
<div class="fieldDescription checkboxFieldDescription">${SaveSubtitlesIntoMediaFoldersHelp}</div>
|
<div class="fieldDescription checkboxFieldDescription">${SaveSubtitlesIntoMediaFoldersHelp}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -238,13 +238,6 @@
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.listItemMediaInfo {
|
|
||||||
/* Don't display if flex not supported */
|
|
||||||
display: none;
|
|
||||||
align-items: center;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.listGroupHeader-first {
|
.listGroupHeader-first {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
||||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
var apiClient = connectionManager.getApiClient(item.ServerId);
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
width: width,
|
maxWidth: width * 2,
|
||||||
type: "Primary"
|
type: "Primary"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
||||||
var apiClient = connectionManager.getApiClient(item.ServerId);
|
var apiClient = connectionManager.getApiClient(item.ServerId);
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
width: width,
|
maxWidth: width * 2,
|
||||||
type: "Primary"
|
type: "Primary"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -262,14 +262,13 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clickEntireItem && options.dragHandle) {
|
if (!clickEntireItem && options.dragHandle) {
|
||||||
//html += '<button is="paper-icon-button-light" class="listViewDragHandle listItemButton"><i class="material-icons">drag_handle</i></button>';
|
//html += '<button is="paper-icon-button-light" class="listViewDragHandle listItemButton"><i class="material-icons drag_handle"></i></button>';
|
||||||
// Firefox and Edge are not allowing the button to be draggable
|
// Firefox and Edge are not allowing the button to be draggable
|
||||||
html += '<i class="listViewDragHandle material-icons listItemIcon listItemIcon-transparent">drag_handle</i>';
|
html += '<i class="listViewDragHandle material-icons listItemIcon listItemIcon-transparent drag_handle"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.image !== false) {
|
if (options.image !== false) {
|
||||||
var imgUrl = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth);
|
var imgUrl = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth);
|
||||||
console.log(imgUrl);
|
|
||||||
var imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage';
|
var imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage';
|
||||||
|
|
||||||
if (isLargeStyle && layoutManager.tv) {
|
if (isLargeStyle && layoutManager.tv) {
|
||||||
|
@ -298,7 +297,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playOnImageClick) {
|
if (playOnImageClick) {
|
||||||
html += '<button is="paper-icon-button-light" class="listItemImageButton itemAction" data-action="resume"><i class="material-icons listItemImageButton-icon">play_arrow</i></button>';
|
html += '<button is="paper-icon-button-light" class="listItemImageButton itemAction" data-action="resume"><i class="material-icons listItemImageButton-icon play_arrow"></i></button>';
|
||||||
}
|
}
|
||||||
|
|
||||||
var progressHtml = indicators.getProgressBarHtml(item, {
|
var progressHtml = indicators.getProgressBarHtml(item, {
|
||||||
|
@ -427,7 +426,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
||||||
|
|
||||||
html += '<div class="' + cssClass + '">';
|
html += '<div class="' + cssClass + '">';
|
||||||
|
|
||||||
var moreIcon = 'more_horiz';
|
var moreIcon = '';
|
||||||
|
|
||||||
html += getTextLinesHtml(textlines, isLargeStyle);
|
html += getTextLinesHtml(textlines, isLargeStyle);
|
||||||
|
|
||||||
|
@ -476,7 +475,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
||||||
if (!clickEntireItem) {
|
if (!clickEntireItem) {
|
||||||
|
|
||||||
if (options.addToListButton) {
|
if (options.addToListButton) {
|
||||||
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="addtoplaylist"><i class="material-icons">playlist_add</i></button>';
|
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="addtoplaylist"><i class="material-icons playlist_add"></i></button>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.moreButton !== false) {
|
if (options.moreButton !== false) {
|
||||||
|
@ -484,7 +483,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.infoButton) {
|
if (options.infoButton) {
|
||||||
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="link"><i class="material-icons">info_outline</i></button>';
|
html += '<button is="paper-icon-button-light" class="listItemButton itemAction" data-action="link"><i class="material-icons info_outline"></i></button>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.rightButtons) {
|
if (options.rightButtons) {
|
||||||
|
|
|
@ -81,4 +81,4 @@ define(['components/loading/loadingLegacy', 'browser', 'css!./loading'], functio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -264,4 +264,4 @@ define(['dom', 'browser', 'events', 'emby-tabs', 'emby-button'], function (dom,
|
||||||
getTabsElement: getTabsElement,
|
getTabsElement: getTabsElement,
|
||||||
selectedTabIndex: selectedTabIndex
|
selectedTabIndex: selectedTabIndex
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
|
@ -54,11 +54,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.mediaInfoCriticRatingFresh {
|
.mediaInfoCriticRatingFresh {
|
||||||
background-image: url(fresh.png);
|
background-image: url(../../assets/img/fresh.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mediaInfoCriticRatingRotten {
|
.mediaInfoCriticRatingRotten {
|
||||||
background-image: url(rotten.png);
|
background-image: url(../../assets/img/rotten.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mediaInfoProgramAttribute {
|
.mediaInfoProgramAttribute {
|
||||||
|
|
|
@ -6,7 +6,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
|
||||||
var status;
|
var status;
|
||||||
|
|
||||||
if (item.Type === 'SeriesTimer') {
|
if (item.Type === 'SeriesTimer') {
|
||||||
return '<i class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon">fiber_smart_record</i>';
|
return '<i class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon fiber_smart_record"></i>';
|
||||||
} else if (item.TimerId || item.SeriesTimerId) {
|
} else if (item.TimerId || item.SeriesTimerId) {
|
||||||
|
|
||||||
status = item.Status || 'Cancelled';
|
status = item.Status || 'Cancelled';
|
||||||
|
@ -20,13 +20,13 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
|
||||||
if (item.SeriesTimerId) {
|
if (item.SeriesTimerId) {
|
||||||
|
|
||||||
if (status !== 'Cancelled') {
|
if (status !== 'Cancelled') {
|
||||||
return '<i class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon">fiber_smart_record</i>';
|
return '<i class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon fiber_smart_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<i class="material-icons mediaInfoItem mediaInfoIconItem">fiber_smart_record</i>';
|
return '<i class="material-icons mediaInfoItem mediaInfoIconItem fiber_smart_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<i class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon">fiber_manual_record</i>';
|
return '<i class="material-icons mediaInfoItem mediaInfoIconItem mediaInfoTimerIcon fiber_manual_record"></i>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProgramInfoHtml(item, options) {
|
function getProgramInfoHtml(item, options) {
|
||||||
|
@ -57,7 +57,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
|
||||||
|
|
||||||
miscInfo.push(text);
|
miscInfo.push(text);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error parsing date: " + item.StartDate);
|
console.error("error parsing date: " + item.StartDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
|
||||||
text = datetime.toLocaleDateString(date);
|
text = datetime.toLocaleDateString(date);
|
||||||
miscInfo.push(text);
|
miscInfo.push(text);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error parsing date: " + item.PremiereDate);
|
console.error("error parsing date: " + item.PremiereDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
|
||||||
miscInfo.push(text);
|
miscInfo.push(text);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error parsing date: " + item.StartDate);
|
console.error("error parsing date: " + item.StartDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error parsing date: " + item.EndDate);
|
console.error("error parsing date: " + item.EndDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
|
||||||
text = globalize.translate('OriginalAirDateValue', datetime.toLocaleDateString(date));
|
text = globalize.translate('OriginalAirDateValue', datetime.toLocaleDateString(date));
|
||||||
miscInfo.push(text);
|
miscInfo.push(text);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error parsing date: " + item.PremiereDate);
|
console.error("error parsing date: " + item.PremiereDate);
|
||||||
}
|
}
|
||||||
} else if (item.ProductionYear) {
|
} else if (item.ProductionYear) {
|
||||||
miscInfo.push(item.ProductionYear);
|
miscInfo.push(item.ProductionYear);
|
||||||
|
@ -267,7 +267,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
|
||||||
text = datetime.parseISO8601Date(item.PremiereDate).getFullYear();
|
text = datetime.parseISO8601Date(item.PremiereDate).getFullYear();
|
||||||
miscInfo.push(text);
|
miscInfo.push(text);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Error parsing date: " + item.PremiereDate);
|
console.error("error parsing date: " + item.PremiereDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 9.8 KiB |
|
@ -1,5 +1,5 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button type="button" is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>
|
<button type="button" is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>
|
||||||
<h3 class="formDialogHeaderTitle">${ButtonAddMediaLibrary}</h3>
|
<h3 class="formDialogHeaderTitle">${ButtonAddMediaLibrary}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button type="button" is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>
|
<button type="button" is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>
|
||||||
<h3 class="formDialogHeaderTitle"></h3>
|
<h3 class="formDialogHeaderTitle"></h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -477,7 +477,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
if (formatString) {
|
if (formatString) {
|
||||||
html += '<button type="button" is="paper-icon-button-light" class="btnOpenExternalId align-self-flex-end" data-fieldid="' + id + '"><i class="material-icons">open_in_browser</i></button>';
|
html += '<button type="button" is="paper-icon-button-light" class="btnOpenExternalId align-self-flex-end" data-fieldid="' + id + '"><i class="material-icons open_in_browser"></i></button>';
|
||||||
}
|
}
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
@ -917,7 +917,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi
|
||||||
for (var i = 0; i < items.length; i++) {
|
for (var i = 0; i < items.length; i++) {
|
||||||
html += '<div class="listItem">';
|
html += '<div class="listItem">';
|
||||||
|
|
||||||
html += '<i class="material-icons listItemIcon" style="background-color:#333;">live_tv</i>';
|
html += '<i class="material-icons listItemIcon live_tv" style="background-color:#333;"></i>';
|
||||||
|
|
||||||
html += '<div class="listItemBody">';
|
html += '<div class="listItemBody">';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="formDialogHeader">
|
<div class="formDialogHeader">
|
||||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons">arrow_back</i></button>
|
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="material-icons arrow_back"></i></button>
|
||||||
<h3 class="formDialogHeaderTitle">
|
<h3 class="formDialogHeaderTitle">
|
||||||
${Edit}
|
${Edit}
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
<span>${Save}</span>
|
<span>${Save}</span>
|
||||||
</button>
|
</button>
|
||||||
<button is="paper-icon-button-light" class="btnMore autoSize" tabindex="-1">
|
<button is="paper-icon-button-light" class="btnMore autoSize" tabindex="-1">
|
||||||
<i class="material-icons">more_horiz</i>
|
<i class="material-icons more_horiz"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
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