@ -7,41 +7,70 @@ trigger:
|
||||
tags:
|
||||
include:
|
||||
- '*'
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
- job: main_build
|
||||
displayName: 'Main Build'
|
||||
|
||||
dependsOn: lint
|
||||
condition: succeeded()
|
||||
- job: build
|
||||
displayName: 'Build'
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
Development:
|
||||
BuildConfiguration: development
|
||||
Production:
|
||||
BuildConfiguration: production
|
||||
Standalone:
|
||||
BuildConfiguration: standalone
|
||||
maxParallel: 3
|
||||
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
displayName: 'Install Node.js'
|
||||
displayName: 'Install Node'
|
||||
inputs:
|
||||
versionSpec: '10.x'
|
||||
|
||||
- script: |
|
||||
yarn install
|
||||
displayName: 'Install dependencies'
|
||||
- task: Cache@2
|
||||
displayName: 'Check Cache'
|
||||
inputs:
|
||||
key: 'yarn | yarn.lock'
|
||||
path: 'node_modules'
|
||||
cacheHitVar: CACHE_RESTORED
|
||||
|
||||
- script: |
|
||||
test -d dist
|
||||
displayName: 'Check dist directory'
|
||||
- script: 'yarn install --frozen-lockfile'
|
||||
displayName: 'Install Dependencies'
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
|
||||
- script: |
|
||||
yarn pack --filename jellyfin-web.tgz
|
||||
displayName: 'Build package'
|
||||
- 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'
|
||||
displayName: 'Check Build'
|
||||
|
||||
- script: 'mv dist jellyfin-web'
|
||||
displayName: 'Rename Directory'
|
||||
condition: succeeded()
|
||||
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Publish package'
|
||||
displayName: 'Publish Release'
|
||||
condition: succeeded()
|
||||
inputs:
|
||||
targetPath: '$(Build.SourcesDirectory)/jellyfin-web.tgz'
|
||||
artifactName: 'jellyfin-web'
|
||||
targetPath: '$(Build.SourcesDirectory)/jellyfin-web'
|
||||
artifactName: 'jellyfin-web-$(BuildConfiguration)'
|
||||
|
||||
- job: lint
|
||||
displayName: 'Lint'
|
||||
@ -51,14 +80,23 @@ jobs:
|
||||
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
displayName: 'Install Node.js'
|
||||
displayName: 'Install Node'
|
||||
inputs:
|
||||
versionSpec: '10.x'
|
||||
|
||||
- script: |
|
||||
yarn install
|
||||
displayName: 'Install dependencies'
|
||||
- task: Cache@2
|
||||
displayName: 'Check Cache'
|
||||
inputs:
|
||||
key: 'yarn | yarn.lock'
|
||||
path: 'node_modules'
|
||||
cacheHitVar: CACHE_RESTORED
|
||||
|
||||
- script: |
|
||||
yarn run lint
|
||||
- script: 'yarn install --frozen-lockfile'
|
||||
displayName: 'Install Dependencies'
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
|
||||
- script: 'yarn run lint'
|
||||
displayName: 'Run ESLint'
|
||||
|
||||
- script: 'yarn run stylelint'
|
||||
displayName: 'Run Stylelint'
|
||||
|
@ -3,25 +3,69 @@ env:
|
||||
browser: true
|
||||
amd: 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:
|
||||
block-spacing: ["error"]
|
||||
brace-style: ["error"]
|
||||
comma-dangle: ["error", "never"]
|
||||
comma-spacing: ["error"]
|
||||
eol-last: ["off"]
|
||||
eol-last: ["error"]
|
||||
indent: ["error", 4, { "SwitchCase": 1 }]
|
||||
keyword-spacing: ["error"]
|
||||
line-comment-position: ["off"]
|
||||
max-statements-per-line: ["error"]
|
||||
no-empty: ["error"]
|
||||
no-extra-semi: ["error"]
|
||||
no-floating-decimal: ["error"]
|
||||
no-multi-spaces: ["error"]
|
||||
no-multiple-empty-lines: ["error", { "max": 1 }]
|
||||
no-trailing-spaces: ["error"]
|
||||
no-void: ["off"]
|
||||
one-var: ["error", "never"]
|
||||
padding-line-between-statements: ["off"]
|
||||
semi: ["off"]
|
||||
semi: ["warn"]
|
||||
space-before-blocks: ["error"]
|
||||
yoda: ["off"]
|
||||
# TODO: Fix warnings and remove these rules
|
||||
no-redeclare: ["warn"]
|
||||
no-unused-vars: ["warn"]
|
||||
no-useless-escape: ["warn"]
|
||||
|
2
.gitignore
vendored
@ -575,4 +575,4 @@ healthchecksdb
|
||||
# End of https://www.gitignore.io/api/node,rider,macos,linux,windows,visualstudio,visualstudiocode
|
||||
|
||||
# dist for webpack output
|
||||
dist
|
||||
dist
|
||||
|
143
.stylelintrc
Normal file
@ -0,0 +1,143 @@
|
||||
{
|
||||
"plugins": [
|
||||
"stylelint-no-browser-hacks/lib",
|
||||
],
|
||||
"rules": {
|
||||
"at-rule-empty-line-before": [ "always", {
|
||||
except: [
|
||||
"blockless-after-same-name-blockless",
|
||||
"first-nested",
|
||||
],
|
||||
ignore: ["after-comment"],
|
||||
} ],
|
||||
"at-rule-name-case": "lower",
|
||||
"at-rule-name-space-after": "always-single-line",
|
||||
"at-rule-no-unknown": true,
|
||||
"at-rule-semicolon-newline-after": "always",
|
||||
"block-closing-brace-empty-line-before": "never",
|
||||
"block-closing-brace-newline-after": "always",
|
||||
"block-closing-brace-newline-before": "always-multi-line",
|
||||
"block-closing-brace-space-before": "always-single-line",
|
||||
"block-no-empty": true,
|
||||
"block-opening-brace-newline-after": "always-multi-line",
|
||||
"block-opening-brace-space-after": "always-single-line",
|
||||
"block-opening-brace-space-before": "always",
|
||||
"color-hex-case": "lower",
|
||||
"color-hex-length": "short",
|
||||
"color-no-invalid-hex": true,
|
||||
"comment-empty-line-before": [ "always", {
|
||||
except: ["first-nested"],
|
||||
ignore: ["stylelint-commands"],
|
||||
} ],
|
||||
"comment-no-empty": true,
|
||||
"comment-whitespace-inside": "always",
|
||||
"custom-property-empty-line-before": [ "always", {
|
||||
except: [
|
||||
"after-custom-property",
|
||||
"first-nested",
|
||||
],
|
||||
ignore: [
|
||||
"after-comment",
|
||||
"inside-single-line-block",
|
||||
],
|
||||
} ],
|
||||
"declaration-bang-space-after": "never",
|
||||
"declaration-bang-space-before": "always",
|
||||
"declaration-block-no-duplicate-properties": [
|
||||
true,
|
||||
{
|
||||
ignore: ["consecutive-duplicates-with-different-values"]
|
||||
}
|
||||
],
|
||||
"declaration-block-no-shorthand-property-overrides": true,
|
||||
"declaration-block-semicolon-newline-after": "always-multi-line",
|
||||
"declaration-block-semicolon-space-after": "always-single-line",
|
||||
"declaration-block-semicolon-space-before": "never",
|
||||
"declaration-block-single-line-max-declarations": 1,
|
||||
"declaration-block-trailing-semicolon": "always",
|
||||
"declaration-colon-newline-after": "always-multi-line",
|
||||
"declaration-colon-space-after": "always-single-line",
|
||||
"declaration-colon-space-before": "never",
|
||||
"font-family-no-duplicate-names": true,
|
||||
"function-calc-no-invalid": true,
|
||||
"function-calc-no-unspaced-operator": true,
|
||||
"function-comma-newline-after": "always-multi-line",
|
||||
"function-comma-space-after": "always-single-line",
|
||||
"function-comma-space-before": "never",
|
||||
"function-linear-gradient-no-nonstandard-direction": true,
|
||||
"function-max-empty-lines": 0,
|
||||
"function-name-case": "lower",
|
||||
"function-parentheses-newline-inside": "always-multi-line",
|
||||
"function-parentheses-space-inside": "never-single-line",
|
||||
"function-whitespace-after": "always",
|
||||
"indentation": 4,
|
||||
"keyframe-declaration-no-important": true,
|
||||
"length-zero-no-unit": true,
|
||||
"max-empty-lines": 1,
|
||||
"media-feature-colon-space-after": "always",
|
||||
"media-feature-colon-space-before": "never",
|
||||
"media-feature-name-case": "lower",
|
||||
"media-feature-name-no-unknown": true,
|
||||
"media-feature-parentheses-space-inside": "never",
|
||||
"media-feature-range-operator-space-after": "always",
|
||||
"media-feature-range-operator-space-before": "always",
|
||||
"media-query-list-comma-newline-after": "always-multi-line",
|
||||
"media-query-list-comma-space-after": "always-single-line",
|
||||
"media-query-list-comma-space-before": "never",
|
||||
"no-descending-specificity": true,
|
||||
"no-duplicate-at-import-rules": true,
|
||||
"no-duplicate-selectors": true,
|
||||
"no-empty-source": true,
|
||||
"no-eol-whitespace": true,
|
||||
"no-extra-semicolons": true,
|
||||
"no-invalid-double-slash-comments": true,
|
||||
"no-missing-end-of-source-newline": true,
|
||||
"number-leading-zero": "always",
|
||||
"number-no-trailing-zeros": true,
|
||||
"plugin/no-browser-hacks": true,
|
||||
"property-case": "lower",
|
||||
"property-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"ignoreProperties": [
|
||||
"user-drag"
|
||||
]
|
||||
}
|
||||
],
|
||||
"rule-empty-line-before": [ "always-multi-line", {
|
||||
except: ["first-nested"],
|
||||
ignore: ["after-comment"],
|
||||
} ],
|
||||
"selector-attribute-brackets-space-inside": "never",
|
||||
"selector-attribute-operator-space-after": "never",
|
||||
"selector-attribute-operator-space-before": "never",
|
||||
"selector-combinator-space-after": "always",
|
||||
"selector-combinator-space-before": "always",
|
||||
"selector-descendant-combinator-no-non-space": true,
|
||||
"selector-list-comma-newline-after": "always",
|
||||
"selector-list-comma-space-before": "never",
|
||||
"selector-max-empty-lines": 0,
|
||||
"selector-pseudo-class-case": "lower",
|
||||
"selector-pseudo-class-no-unknown": true,
|
||||
"selector-pseudo-class-parentheses-space-inside": "never",
|
||||
"selector-pseudo-element-case": "lower",
|
||||
"selector-pseudo-element-colon-notation": "double",
|
||||
"selector-pseudo-element-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"ignorePseudoElements": [
|
||||
"cue"
|
||||
]
|
||||
}
|
||||
],
|
||||
"selector-type-case": "lower",
|
||||
"selector-type-no-unknown": true,
|
||||
"string-no-newline": true,
|
||||
"unit-case": "lower",
|
||||
"unit-no-unknown": true,
|
||||
"value-list-comma-newline-after": "always-multi-line",
|
||||
"value-list-comma-space-after": "always-single-line",
|
||||
"value-list-comma-space-before": "never",
|
||||
"value-list-max-empty-lines": 0,
|
||||
}
|
||||
}
|
@ -32,6 +32,8 @@
|
||||
- [bilde2910](https://github.com/bilde2910)
|
||||
- [Daniel Hartung](https://github.com/dhartung)
|
||||
- [Ryan Hartzell](https://github.com/ryan-hartzell)
|
||||
- [Thibault Nocchi](https://github.com/ThibaultNocchi)
|
||||
- [MrTimscampi](https://github.com/MrTimscampi)
|
||||
|
||||
# Emby Contributors
|
||||
|
||||
|
17
README.md
@ -45,20 +45,37 @@ Jellyfin Web is the frontend used for most of the clients available for end user
|
||||
### Dependencies
|
||||
|
||||
- Yarn
|
||||
- Gulp-cli
|
||||
|
||||
### Getting Started
|
||||
|
||||
1. Clone or download this repository.
|
||||
|
||||
```sh
|
||||
git clone https://github.com/jellyfin/jellyfin-web.git
|
||||
cd jellyfin-web
|
||||
```
|
||||
|
||||
2. Install build dependencies in the project directory.
|
||||
|
||||
```sh
|
||||
yarn install
|
||||
```
|
||||
|
||||
3. Run the web client with webpack for local development.
|
||||
|
||||
```sh
|
||||
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
|
||||
```
|
123
gulpfile.js
Normal file
@ -0,0 +1,123 @@
|
||||
'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');
|
||||
|
||||
sass.compiler = require('node-sass')
|
||||
|
||||
|
||||
if (mode.production()) {
|
||||
var config = require('./webpack.prod.js');
|
||||
} else {
|
||||
var config = require('./webpack.dev.js');
|
||||
}
|
||||
|
||||
function serve() {
|
||||
browserSync.init({
|
||||
server: {
|
||||
baseDir: "./dist"
|
||||
},
|
||||
port: 8080
|
||||
});
|
||||
|
||||
watch(['src/**/*.js', '!src/bundle.js'], javascript);
|
||||
watch('src/bundle.js', webpack);
|
||||
watch('src/**/*.css', css);
|
||||
watch(['src/**/*.html', '!src/index.html'], html);
|
||||
watch(['src/**/*.png', 'src/**/*.jpg', 'src/**/*.gif', 'src/**/*.svg'], images);
|
||||
watch(['src/**/*.json', 'src/**/*.ico'], copy);
|
||||
watch('src/index.html', injectBundle);
|
||||
watch(['src/standalone.js', 'src/scripts/apploader.js'], standalone);
|
||||
}
|
||||
|
||||
function standalone() {
|
||||
return src(['src/standalone.js', 'src/scripts/apploader.js'], { base: './src/' })
|
||||
.pipe(concat('scripts/apploader.js'))
|
||||
.pipe(dest('dist/'));
|
||||
}
|
||||
|
||||
function clean() {
|
||||
return del(['dist/']);
|
||||
}
|
||||
|
||||
function javascript() {
|
||||
return src(['src/**/*.js', '!src/bundle.js'], { base: './src/' })
|
||||
.pipe(mode.development(sourcemaps.init({ loadMaps: true })))
|
||||
.pipe(babel({
|
||||
presets: [
|
||||
['@babel/preset-env']
|
||||
]
|
||||
}))
|
||||
.pipe(terser({
|
||||
keep_fnames: true,
|
||||
mangle: false
|
||||
}))
|
||||
.pipe(mode.development(sourcemaps.write('.')))
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function webpack() {
|
||||
return stream(config)
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function css() {
|
||||
return src(['src/**/*.css', 'src/**/*.scss'], { 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() {
|
||||
return src(['src/**/*.html', '!src/index.html'], { base: './src/' })
|
||||
.pipe(mode.production(htmlmin({ collapseWhitespace: true })))
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function images() {
|
||||
return src(['src/**/*.png', 'src/**/*.jpg', 'src/**/*.gif', 'src/**/*.svg'], { base: './src/' })
|
||||
.pipe(mode.production(imagemin()))
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function copy() {
|
||||
return src(['src/**/*.json', 'src/**/*.ico'], { base: './src/' })
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function injectBundle() {
|
||||
return src('src/index.html', { base: './src/' })
|
||||
.pipe(inject(
|
||||
src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), { relative: true }
|
||||
))
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
exports.default = series(clean, parallel(javascript, webpack, css, html, images, copy), injectBundle)
|
||||
exports.standalone = series(exports.default, standalone)
|
||||
exports.serve = series(exports.standalone, serve)
|
83
package.json
@ -5,38 +5,74 @@
|
||||
"repository": "https://github.com/jellyfin/jellyfin-web",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^9.7.3",
|
||||
"@babel/core": "^7.8.6",
|
||||
"@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",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"css-loader": "^2.1.0",
|
||||
"eslint": "^5.16.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"css-loader": "^3.4.2",
|
||||
"cssnano": "^4.1.10",
|
||||
"del": "^5.1.0",
|
||||
"eslint": "^6.8.0",
|
||||
"file-loader": "^5.0.2",
|
||||
"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-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": "^3.2.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"webpack": "^4.41.0",
|
||||
"webpack-cli": "^3.3.9",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"style-loader": "^1.1.3",
|
||||
"stylelint": "^13.1.0",
|
||||
"stylelint-config-rational-order": "^0.1.2",
|
||||
"stylelint-no-browser-hacks": "^1.2.1",
|
||||
"stylelint-order": "^4.0.0",
|
||||
"webpack": "^4.41.5",
|
||||
"webpack-cli": "^3.3.10",
|
||||
"webpack-concat-plugin": "^3.0.0",
|
||||
"webpack-dev-server": "^3.8.1",
|
||||
"webpack-merge": "^4.2.2"
|
||||
"webpack-dev-server": "^3.10.3",
|
||||
"webpack-merge": "^4.2.2",
|
||||
"webpack-stream": "^5.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"alameda": "^1.3.0",
|
||||
"document-register-element": "^0.5.4",
|
||||
"alameda": "^1.4.0",
|
||||
"core-js": "^3.6.4",
|
||||
"document-register-element": "^1.14.3",
|
||||
"flv.js": "^1.5.0",
|
||||
"hls.js": "^0.12.4",
|
||||
"howler": "^2.1.2",
|
||||
"hls.js": "^0.13.1",
|
||||
"howler": "^2.1.3",
|
||||
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
|
||||
"jquery": "^3.4.1",
|
||||
"jstree": "^3.3.7",
|
||||
"libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus",
|
||||
"libjass": "^0.11.0",
|
||||
"material-design-icons-iconfont": "^5.0.1",
|
||||
"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",
|
||||
"shaka-player": "^2.5.5",
|
||||
"sortablejs": "^1.9.0",
|
||||
"swiper": "^3.4.2",
|
||||
"shaka-player": "^2.5.9",
|
||||
"sortablejs": "^1.10.2",
|
||||
"swiper": "^5.3.1",
|
||||
"webcomponents.js": "^0.7.24",
|
||||
"whatwg-fetch": "^1.1.1"
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"@babel/preset-env"
|
||||
]
|
||||
},
|
||||
"browserslist": [
|
||||
"last 2 Firefox versions",
|
||||
@ -45,18 +81,21 @@
|
||||
"last 2 Safari versions",
|
||||
"last 2 iOS versions",
|
||||
"last 2 Edge versions",
|
||||
"Chrome 27",
|
||||
"Chrome 38",
|
||||
"Chrome 47",
|
||||
"Chrome 53",
|
||||
"Chrome 56",
|
||||
"Chrome 63",
|
||||
"Explorer 11",
|
||||
"Firefox ESR"
|
||||
],
|
||||
"scripts": {
|
||||
"serve": "webpack-dev-server --config webpack.dev.js --open",
|
||||
"build": "webpack --config webpack.prod.js",
|
||||
"serve": "gulp serve",
|
||||
"prepare": "gulp --production",
|
||||
"build:development": "gulp --development",
|
||||
"build:production": "gulp --production",
|
||||
"build:standalone": "gulp standalone --development",
|
||||
"lint": "eslint \"src\"",
|
||||
"prepare": "webpack --config webpack.prod.js"
|
||||
"stylelint": "stylelint \"src/**/*.css\""
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,11 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('autoprefixer')
|
||||
]
|
||||
}
|
||||
const postcssPresetEnv = require('postcss-preset-env');
|
||||
const cssnano = require('cssnano');
|
||||
|
||||
const config = () => ({
|
||||
plugins: [
|
||||
postcssPresetEnv(),
|
||||
cssnano()
|
||||
]
|
||||
});
|
||||
|
||||
module.exports = config
|
||||
|
41
scripts/scdup.py
Normal file
@ -0,0 +1,41 @@
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
# load every key in the source language
|
||||
# check the keys in all translations
|
||||
# remove keys that only exist in translations
|
||||
|
||||
cwd = os.getcwd()
|
||||
langdir = cwd + '/../src/strings'
|
||||
langlst = os.listdir(langdir)
|
||||
|
||||
langlst.remove('en-us.json')
|
||||
print(langlst)
|
||||
input('press enter to continue')
|
||||
|
||||
keysus = []
|
||||
with open(langdir + '/' + 'en-us.json') as en:
|
||||
langus = json.load(en)
|
||||
for key in langus:
|
||||
keysus.append(key)
|
||||
|
||||
for lang in langlst:
|
||||
with open(langdir + '/' + lang, 'r') as f:
|
||||
inde = 2
|
||||
if '\n \"' in f.read():
|
||||
inde = 4
|
||||
f.close()
|
||||
with open(langdir + '/' + lang, 'r+') as f:
|
||||
langjson = json.load(f)
|
||||
langjnew = {}
|
||||
for key in langjson:
|
||||
if key in keysus:
|
||||
langjnew[key] = langjson[key]
|
||||
f.seek(0)
|
||||
f.write(json.dumps(langjnew, indent=inde, sort_keys=False, ensure_ascii=False))
|
||||
f.write('\n')
|
||||
f.truncate()
|
||||
f.close()
|
||||
|
||||
print('DONE')
|
40
scripts/scgen.py
Normal file
@ -0,0 +1,40 @@
|
||||
import os
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
# load all keys in the source language
|
||||
# check entire codebase for usages
|
||||
# print unused keys to a text file
|
||||
# TODO: dynamic string usages cause false positives
|
||||
|
||||
cwd = os.getcwd()
|
||||
langdir = cwd + '/../src/strings'
|
||||
langlst = []
|
||||
langlst.append('en-us.json')
|
||||
|
||||
# unused keys
|
||||
dep = []
|
||||
|
||||
def grep(key):
|
||||
command = 'grep -r -E "(\(\\\"|\(\'|\{)%s(\\\"|\'|\})" --include=\*.{js,html} --exclude-dir=../src/strings ../src' % key
|
||||
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
output = p.stdout.readlines()
|
||||
if output:
|
||||
print('DONE: ' + key)
|
||||
return True
|
||||
print('UNUSED: ' + key)
|
||||
dep.append(key)
|
||||
return False
|
||||
|
||||
for lang in langlst:
|
||||
with open(langdir + '/' + lang) as f:
|
||||
langjson = json.load(f)
|
||||
for key in langjson:
|
||||
grep(key)
|
||||
|
||||
print(dep)
|
||||
print('LENGTH: ' + str(len(dep)))
|
||||
with open('scout.txt', 'w') as out:
|
||||
for item in dep:
|
||||
out.write(item + '\n')
|
||||
out.close()
|
34
scripts/scrm.py
Normal file
@ -0,0 +1,34 @@
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
# load text file containing unused keys
|
||||
# remove the keys from all string files
|
||||
|
||||
cwd = os.getcwd()
|
||||
langdir = cwd + '/../src/strings'
|
||||
langlst = os.listdir(langdir)
|
||||
|
||||
keys = []
|
||||
|
||||
with open('scout.txt', 'r') as f:
|
||||
for line in f:
|
||||
keys.append(line.strip('\n'))
|
||||
|
||||
for lang in langlst:
|
||||
with open(langdir + '/' + lang, 'r') as f:
|
||||
inde = 2
|
||||
if '\n \"' in f.read():
|
||||
inde = 4
|
||||
f.close()
|
||||
with open(langdir + '/' + lang, 'r+') as f:
|
||||
langjson = json.load(f)
|
||||
for key in keys:
|
||||
langjson.pop(key, None)
|
||||
f.seek(0)
|
||||
f.write(json.dumps(langjson, indent=inde, sort_keys=False, ensure_ascii=False))
|
||||
f.write('\n')
|
||||
f.truncate()
|
||||
f.close()
|
||||
|
||||
print('DONE')
|
@ -1,10 +1,7 @@
|
||||
<div id="addPluginPage" data-role="page" class="page type-interior pluginConfigurationPage" data-backbutton="true">
|
||||
|
||||
<div>
|
||||
<div class="content-primary">
|
||||
|
||||
<div class="readOnlyContent">
|
||||
|
||||
<div class="verticalSection">
|
||||
<div class="sectionTitleContainer flex align-items-center">
|
||||
<h1 class="sectionTitle pluginName"></h1>
|
||||
@ -13,9 +10,7 @@
|
||||
|
||||
<p id="tagline" style="font-style: italic;"></p>
|
||||
<p id="pPreviewImage"></p>
|
||||
|
||||
<p id="overview"></p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="verticalSection">
|
||||
@ -27,12 +22,12 @@
|
||||
<select id="selectVersion" name="selectVersion" is="emby-select" label="${LabelSelectVersionToInstall}"></select>
|
||||
</div>
|
||||
|
||||
<p id="btnInstallDiv" class="hide">
|
||||
<div id="btnInstallDiv" class="hide">
|
||||
<button is="emby-button" type="submit" id="btnInstall" class="raised button-submit block">
|
||||
<span>${Install}</span>
|
||||
</button>
|
||||
<div class="fieldDescription">${ServerRestartNeededAfterPluginInstall}</div>
|
||||
</p>
|
||||
</div>
|
||||
<p id="nonServerMsg"></p>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -2,11 +2,9 @@
|
||||
<div>
|
||||
<div class="content-primary">
|
||||
<div class="detailSectionHeader">
|
||||
<h2 style="margin:.6em 0;vertical-align:middle;display:inline-block;">
|
||||
${HeaderApiKeys}
|
||||
</h2>
|
||||
<h2 style="margin:.6em 0;vertical-align:middle;display:inline-block;">${HeaderApiKeys}</h2>
|
||||
<button is="emby-button" type="button" class="fab btnNewKey submit" style="margin-left:1em;" title="${ButtonAdd}">
|
||||
<i class="md-icon">add</i>
|
||||
<i class="material-icons">add</i>
|
||||
</button>
|
||||
</div>
|
||||
<p>${HeaderApiKeysHelp}</p>
|
||||
@ -24,4 +22,4 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,4 +9,4 @@
|
||||
vertical-align: middle;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
462
src/assets/css/dashboard.css
Normal file
@ -0,0 +1,462 @@
|
||||
.dashboardColumn,
|
||||
.dashboardSections {
|
||||
flex-direction: column;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
}
|
||||
|
||||
.dashboardFooter {
|
||||
margin-top: 3.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dashboardFooter a {
|
||||
margin: 0 0.7em;
|
||||
}
|
||||
|
||||
progress {
|
||||
appearance: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
background: #ccc !important;
|
||||
}
|
||||
|
||||
progress[role]::after {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
progress::-webkit-progress-bar {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
progress::-moz-progress-bar {
|
||||
background-color: #00a4dc;
|
||||
}
|
||||
|
||||
progress::-webkit-progress-value {
|
||||
background-color: #00a4dc;
|
||||
}
|
||||
|
||||
progress[aria-valuenow]::before {
|
||||
border-radius: 0.4em;
|
||||
background-color: #00a4dc;
|
||||
}
|
||||
|
||||
.localnav {
|
||||
margin-bottom: 2.2em !important;
|
||||
}
|
||||
|
||||
@media all and (min-width: 50em) {
|
||||
.type-interior > div[data-role=content],
|
||||
.type-interior > .ui-panel-content-wrap > div[data-role=content] {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
padding-top: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboardDocument .dashboardEntryHeaderButton,
|
||||
.dashboardDocument .lnkManageServer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.adminDrawerLogo {
|
||||
padding: 1.5em 1em 1.2em;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
margin-bottom: 1em;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.adminDrawerLogo img {
|
||||
height: 4em;
|
||||
}
|
||||
|
||||
a[data-role=button] {
|
||||
background: #292929 !important;
|
||||
background-clip: padding-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-user-select: none;
|
||||
-webkit-background-clip: padding-box;
|
||||
cursor: pointer !important;
|
||||
font-family: inherit !important;
|
||||
font-weight: 500 !important;
|
||||
margin: 0 0.25em !important;
|
||||
display: inline-block;
|
||||
padding: 0.8em 1em;
|
||||
text-align: center;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
div[data-role=controlgroup] a[data-role=button] {
|
||||
display: inline-block !important;
|
||||
margin: 0 !important;
|
||||
-webkit-box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
div[data-role=controlgroup] a[data-role=button]:first-child {
|
||||
-webkit-border-bottom-left-radius: 0.3125em;
|
||||
border-bottom-left-radius: 0.3125em;
|
||||
-webkit-border-top-left-radius: 0.3125em;
|
||||
border-top-left-radius: 0.3125em;
|
||||
}
|
||||
|
||||
div[data-role=controlgroup] a[data-role=button]:last-child {
|
||||
-webkit-border-bottom-right-radius: 0.3125em;
|
||||
border-bottom-right-radius: 0.3125em;
|
||||
-webkit-border-top-right-radius: 0.3125em;
|
||||
border-top-right-radius: 0.3125em;
|
||||
}
|
||||
|
||||
div[data-role=controlgroup] a[data-role=button] + a[data-role=button] {
|
||||
border-left-width: 0 !important;
|
||||
margin: 0 0 0 -0.4em !important;
|
||||
}
|
||||
|
||||
div[data-role=controlgroup] a.ui-btn-active {
|
||||
background: #00a4dc !important;
|
||||
color: #292929 !important;
|
||||
}
|
||||
|
||||
.sessionAppInfo img {
|
||||
max-width: 40px;
|
||||
max-height: 40px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.appLinks img {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.wizardContent h2 img {
|
||||
height: 2.5em;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.5em;
|
||||
position: relative;
|
||||
top: -0.3em;
|
||||
}
|
||||
|
||||
.header .imageLink {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header .imageLink img {
|
||||
height: 2.1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.content-primary {
|
||||
padding-top: 6em;
|
||||
padding-right: 1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.withTabs .content-primary {
|
||||
padding-top: 9em !important;
|
||||
}
|
||||
|
||||
@media all and (min-width: 40em) {
|
||||
.content-primary {
|
||||
padding-top: 7em;
|
||||
}
|
||||
|
||||
.withTabs .content-primary {
|
||||
padding-top: 10em !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 84em) {
|
||||
.withTabs .content-primary {
|
||||
padding-top: 7em !important;
|
||||
}
|
||||
}
|
||||
|
||||
.content-primary ul:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.dashboardSections {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dashboardColumn {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.sessionNowPlayingContent {
|
||||
-webkit-background-size: cover;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.activeSession:not(.playingSession) .sessionNowPlayingContent {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dashboardSection {
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
margin: 0 0 2em;
|
||||
}
|
||||
|
||||
.dashboardSection h3 {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.activeRecordingItems > .card {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 70em) {
|
||||
.dashboardSections {
|
||||
-webkit-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.dashboardColumn-2-60 {
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.dashboardColumn-2-40 {
|
||||
width: 27%;
|
||||
}
|
||||
|
||||
.dashboardSection {
|
||||
padding: 0 1.5em;
|
||||
}
|
||||
|
||||
.activeRecordingItems > .card {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.wizardContent {
|
||||
max-width: 62em;
|
||||
padding: 0.5em 2em 1em;
|
||||
margin: 0 auto;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.wizardNavigation {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.wizardContent form {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.scheduledTaskPaperIconItem {
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
.activeSession {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.activitylogUserPhoto {
|
||||
height: 1.71em;
|
||||
width: 1.71em;
|
||||
border-radius: 100%;
|
||||
margin-right: 0.5em;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
@media all and (min-width: 40em) {
|
||||
.activeSession {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 50em) {
|
||||
.activeSession {
|
||||
width: 50% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sessionCardFooter {
|
||||
padding-top: 0.5em !important;
|
||||
padding-bottom: 1em !important;
|
||||
border-top: 1px solid #eee;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sessionAppInfo {
|
||||
padding: 0.5em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sessionCardButtons {
|
||||
min-height: 2.7em;
|
||||
}
|
||||
|
||||
.sessionCardButton {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sessionNowPlayingInnerContent {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.sessionNowPlayingContent-withbackground + .sessionNowPlayingInnerContent {
|
||||
color: #fff !important;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.sessionAppName {
|
||||
vertical-align: top;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.sessionNowPlayingDetails {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sessionNowPlayingInfo {
|
||||
flex-grow: 1;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0.8em 0.5em;
|
||||
}
|
||||
|
||||
.sessionNowPlayingTime {
|
||||
flex-shrink: 0;
|
||||
align-self: flex-end;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0.8em 0.5em;
|
||||
}
|
||||
|
||||
.sessionNowPlayingStreamInfo {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.playbackProgress,
|
||||
.transcodingProgress {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.activeSession .playbackProgress,
|
||||
.activeSession .transcodingProgress {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 6px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.playbackProgress > div {
|
||||
z-index: 1000;
|
||||
background-color: #00a4dc;
|
||||
}
|
||||
|
||||
.transcodingProgress > div {
|
||||
background-color: #dd4919;
|
||||
}
|
||||
|
||||
@media all and (max-width: 34.375em) {
|
||||
.sessionAppName {
|
||||
max-width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 31.25em) {
|
||||
.sessionAppName {
|
||||
max-width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
.disabledUser {
|
||||
-webkit-filter: grayscale(100%);
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.disabledUserBanner {
|
||||
margin: 0 0 2em;
|
||||
}
|
||||
|
||||
.appLinks a {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.appLinks a + a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
@-webkit-keyframes rotating {
|
||||
from {
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
-webkit-transform: rotate(0);
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.rotatingCircle {
|
||||
-webkit-animation: rotating 2s linear infinite;
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
.pluginPreviewImg {
|
||||
-webkit-box-shadow: 0 0.0725em 0.29em 0 rgba(0, 0, 0, 0.37);
|
||||
box-shadow: 0 0.0725em 0.29em 0 rgba(0, 0, 0, 0.37);
|
||||
}
|
||||
|
||||
.ui-bar-a {
|
||||
text-align: center;
|
||||
padding: 0 20px;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
.detailTableBodyCell,
|
||||
.detailTableHeaderCell {
|
||||
border-spacing: 0;
|
||||
padding: .4em
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
.detailTable {
|
||||
@ -9,11 +9,11 @@
|
||||
border-spacing: 0;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
margin: 0 auto
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.detailTableHeaderCell {
|
||||
font-weight: 700;
|
||||
text-align: left;
|
||||
vertical-align: top
|
||||
}
|
||||
vertical-align: top;
|
||||
}
|
@ -44,4 +44,4 @@
|
||||
|
||||
.align-self-flex-end {
|
||||
align-self: flex-end;
|
||||
}
|
||||
}
|
37
src/assets/css/fonts.css
Normal file
@ -0,0 +1,37 @@
|
||||
html {
|
||||
font-family: "Noto Sans", sans-serif;
|
||||
font-size: 93%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
text-size-adjust: 100%;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
font-family: "Noto Sans", sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 400;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 400;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
font-size: 1.17em;
|
||||
}
|
||||
|
||||
.layout-tv {
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
.layout-mobile {
|
||||
font-size: 90%;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
h1 {
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
@ -8,12 +8,12 @@ h1 {
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
font-size: 1.17em;
|
||||
}
|
||||
|
8
src/assets/css/ios.css
Normal file
@ -0,0 +1,8 @@
|
||||
html {
|
||||
font-size: 82% !important;
|
||||
}
|
||||
|
||||
.formDialogFooter {
|
||||
position: static !important;
|
||||
margin: 0 -1em !important;
|
||||
}
|
1124
src/assets/css/librarybrowser.css
Normal file
9
src/assets/css/livetv.css
Normal file
@ -0,0 +1,9 @@
|
||||
.guideVerticalScroller {
|
||||
padding-bottom: 15em;
|
||||
}
|
||||
|
||||
@media all and (min-width: 62.5em) {
|
||||
#guideTab {
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
}
|
@ -1,53 +1,57 @@
|
||||
.editPageSidebar {
|
||||
display: block
|
||||
display: block;
|
||||
}
|
||||
|
||||
.editPageSidebar-withcontent {
|
||||
display: none
|
||||
display: none;
|
||||
}
|
||||
|
||||
.libraryTree {
|
||||
margin-left: .25em
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
|
||||
.offlineEditorNode {
|
||||
color: #c33
|
||||
color: #c33;
|
||||
}
|
||||
|
||||
.editorNode img {
|
||||
height: 18px;
|
||||
margin: 0 .35em;
|
||||
margin: 0 0.35em;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
top: -2px
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.jstree-anchor {
|
||||
font-weight: 400 !important
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.jstree-wholerow-hovered {
|
||||
background: #38c !important;
|
||||
-webkit-border-radius: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important
|
||||
-webkit-box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.jstree-default .jstree-hovered {
|
||||
background: 0 0 !important;
|
||||
-webkit-border-radius: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
-webkit-box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
color: #fff !important
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.jstree-default .jstree-wholerow-clicked {
|
||||
background: #00a4dc !important
|
||||
background: #00a4dc !important;
|
||||
}
|
||||
|
||||
.metadataSidebarIcon {
|
||||
margin-right: .4em
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
|
||||
@media all and (min-width:50em) {
|
||||
@media all and (min-width: 50em) {
|
||||
.editPageSidebar {
|
||||
position: fixed;
|
||||
top: 5.2em;
|
||||
@ -55,21 +59,21 @@
|
||||
left: 0;
|
||||
width: 30%;
|
||||
border-right: 1px solid #555;
|
||||
display: block
|
||||
display: block;
|
||||
}
|
||||
|
||||
.editPageInnerContent {
|
||||
float: right;
|
||||
width: 68.5%
|
||||
width: 68.5%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width:112.5em) {
|
||||
@media all and (min-width: 112.5em) {
|
||||
.editPageSidebar {
|
||||
width: 25%
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.editPageInnerContent {
|
||||
width: 73.5%
|
||||
width: 73.5%;
|
||||
}
|
||||
}
|
58
src/assets/css/scrollstyles.css
Normal file
@ -0,0 +1,58 @@
|
||||
.scrollX {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-y: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.smoothScrollX {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.hiddenScrollX,
|
||||
.layout-tv .scrollX {
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.hiddenScrollX-forced {
|
||||
overflow: -moz-scrollbars-none;
|
||||
}
|
||||
|
||||
.hiddenScrollX::-webkit-scrollbar,
|
||||
.layout-tv .scrollX::-webkit-scrollbar {
|
||||
height: 0 !important;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scrollY {
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.smoothScrollY {
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow-x: hidden;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.hiddenScrollY,
|
||||
.layout-tv .smoothScrollY {
|
||||
-ms-overflow-style: none;
|
||||
|
||||
/* Can't do this because it not only hides the scrollbar, but also prevents scrolling */
|
||||
|
||||
/* overflow: -moz-scrollbars-none; */
|
||||
}
|
||||
|
||||
.hiddenScrollY-forced {
|
||||
overflow: -moz-scrollbars-none;
|
||||
}
|
||||
|
||||
.hiddenScrollY::-webkit-scrollbar,
|
||||
.layout-tv .smoothScrollY::-webkit-scrollbar,
|
||||
.layout-tv .scrollY::-webkit-scrollbar {
|
||||
width: 0 !important;
|
||||
display: none;
|
||||
}
|
98
src/assets/css/site.css
Normal file
@ -0,0 +1,98 @@
|
||||
body,
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
/* Fix font ligatures on older WebOS versions */
|
||||
-webkit-font-feature-settings: "liga";
|
||||
}
|
||||
|
||||
.backgroundContainer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
html {
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.layout-mobile,
|
||||
.layout-tv {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
background-color: transparent !important;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.mainAnimatedPage {
|
||||
contain: style size !important;
|
||||
}
|
||||
|
||||
.pageContainer {
|
||||
overflow-x: visible !important;
|
||||
}
|
||||
|
||||
.bodyWithPopupOpen {
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
|
||||
div[data-role=page] {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.pageTitle {
|
||||
margin-top: 0;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.fieldDescription {
|
||||
padding-left: 0.15em;
|
||||
font-weight: 400;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
.fieldDescription + .fieldDescription {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
|
||||
.content-primary,
|
||||
.padded-bottom-page,
|
||||
.page,
|
||||
.pageWithAbsoluteTabs .pageTabContent {
|
||||
/* provides room for the music controls */
|
||||
padding-bottom: 5em !important;
|
||||
}
|
||||
|
||||
@media all and (min-width: 50em) {
|
||||
.readOnlyContent,
|
||||
form {
|
||||
max-width: 54em;
|
||||
}
|
||||
}
|
||||
|
||||
.headerHelpButton {
|
||||
margin-left: 1.25em !important;
|
||||
padding-bottom: 0.4em !important;
|
||||
padding-top: 0.4em !important;
|
||||
}
|
||||
|
||||
.mediaInfoContent {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 85%;
|
||||
}
|
289
src/assets/css/videoosd.css
Normal file
@ -0,0 +1,289 @@
|
||||
.chapterThumbTextContainer,
|
||||
.videoOsdBottom {
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.osdPoster img,
|
||||
.pageContainer,
|
||||
.videoOsdBottom {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.osdHeader {
|
||||
-webkit-transition: opacity 0.3s ease-out;
|
||||
-o-transition: opacity 0.3s ease-out;
|
||||
transition: opacity 0.3s ease-out;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
background: rgba(0, 0, 0, 0.7) !important;
|
||||
-webkit-backdrop-filter: none !important;
|
||||
backdrop-filter: none !important;
|
||||
color: #eee !important;
|
||||
}
|
||||
|
||||
.osdHeader-hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.osdHeader .headerButton:not(.headerBackButton):not(.headerCastButton) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chapterThumbContainer {
|
||||
-webkit-box-shadow: 0 0 1.9vh #000;
|
||||
box-shadow: 0 0 1.9vh #000;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chapterThumb {
|
||||
background-position: center center;
|
||||
-webkit-background-size: contain;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
border: 0;
|
||||
height: 20vh;
|
||||
min-width: 20vh;
|
||||
}
|
||||
|
||||
@media all and (orientation: portrait) {
|
||||
.chapterThumb {
|
||||
height: 30vw;
|
||||
min-width: 30vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-height: 50em) and (orientation: landscape) {
|
||||
.chapterThumb {
|
||||
height: 30vh;
|
||||
min-width: 30vh;
|
||||
}
|
||||
}
|
||||
|
||||
.chapterThumbTextContainer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
padding: 0.25em 0.5em;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.chapterThumbText {
|
||||
padding: 0.25em 0;
|
||||
margin: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.chapterThumbText-dim {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.videoOsdBottom {
|
||||
position: fixed;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
padding: 1%;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
will-change: opacity;
|
||||
-webkit-transition: opacity 0.3s ease-out;
|
||||
-o-transition: opacity 0.3s ease-out;
|
||||
transition: opacity 0.3s ease-out;
|
||||
color: #fff;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
}
|
||||
|
||||
.videoOsdBottom-hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.osdControls {
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.videoOsdBottom .buttons {
|
||||
padding: 0.25em 0 0;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.osdVolumeSliderContainer {
|
||||
width: 9em;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.osdMediaInfo,
|
||||
.volumeButtons {
|
||||
display: flex;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
align-items: center;
|
||||
-webkit-box-align: center;
|
||||
}
|
||||
|
||||
.volumeButtons {
|
||||
margin: 0 0.5em 0 auto;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.osdTimeText {
|
||||
margin-left: 1em;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.osdPoster {
|
||||
width: 10%;
|
||||
position: relative;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.osdPoster img {
|
||||
position: absolute;
|
||||
height: auto;
|
||||
width: 100%;
|
||||
-webkit-box-shadow: 0 0 1.9vh #000;
|
||||
box-shadow: 0 0 1.9vh #000;
|
||||
border: 0.08em solid #222;
|
||||
user-drag: none;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.osdTitle,
|
||||
.osdTitleSmall {
|
||||
margin: 0 1em 0 0;
|
||||
}
|
||||
|
||||
.osdMediaInfo {
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.osdSecondaryMediaInfo {
|
||||
padding-left: 0.6em !important;
|
||||
}
|
||||
|
||||
.osdTextContainer {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
margin-bottom: 0.7em;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.osdMainTextContainer {
|
||||
-webkit-box-align: baseline;
|
||||
-webkit-align-items: baseline;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.osdMediaStatus {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@-moz-keyframes spin {
|
||||
100% {
|
||||
-moz-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes spin {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.osdMediaStatus .animate {
|
||||
-webkit-animation: spin 4s linear infinite;
|
||||
-moz-animation: spin 4s linear infinite;
|
||||
animation: spin 4s linear infinite;
|
||||
}
|
||||
|
||||
.pageContainer {
|
||||
top: 0;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
@media all and (max-width: 30em) {
|
||||
.btnFastForward,
|
||||
.btnRewind,
|
||||
.osdMediaInfo,
|
||||
.osdPoster {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 33.75em) {
|
||||
.videoOsdBottom .paper-icon-button-light {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 43em) {
|
||||
.videoOsdBottom .volumeButtons,
|
||||
.osdMediaStatus span {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 50em) {
|
||||
.videoOsdBottom .btnFastForward,
|
||||
.videoOsdBottom .btnRewind {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 75em) {
|
||||
.videoOsdBottom .endsAtText {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
4
src/assets/img/devices/android.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 863 B After Width: | Height: | Size: 863 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 345 B After Width: | Height: | Size: 345 B |
11
src/assets/img/devices/kodi.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(-36.173 -93.796)">
|
||||
<g transform="matrix(.08 0 0 .08 40.527 88.485)">
|
||||
<path d="m53.295 119.35v-39.688h79.375v79.375h-79.375z" fill="#fcfdfd" stroke-width=".26458"/>
|
||||
</g>
|
||||
<g transform="matrix(1.3761 0 0 1.3825 -26.63 -38.456)" fill="#fff">
|
||||
<path transform="matrix(.08 0 0 .08 40.527 88.485)" d="m86.822 141.89c-4.738-4.7596-5.2168-5.3235-5.2168-6.1442 0-0.82158 0.47505-1.3787 5.2329-6.1365 4.7552-4.7552 5.3153-5.2329 6.1353-5.2329 0.81617 0 1.3676 0.46161 5.7678 4.8286 4.8692 4.8324 5.6182 5.7452 5.6182 6.8466 0 0.41218-1.5697 2.1641-5.2274 5.834-4.8206 4.8367-5.3 5.2449-6.1603 5.2449-0.86046 0-1.3378-0.40681-6.1497-5.2406zm22.168-12.455c-0.43656-0.27248-2.9071-2.6371-5.4901-5.2547-4.1957-4.2519-4.6964-4.8534-4.6964-5.6418 0-0.7938 0.52954-1.414 5.2644-6.1655 4.6582-4.6746 5.362-5.2829 6.1127-5.2829 0.75071 0 1.4546 0.60829 6.1127 5.2829 4.7729 4.7898 5.2644 5.3668 5.2644 6.1818 0 0.81542-0.48628 1.3851-5.2394 6.1382-5.6104 5.6104-5.7707 5.7142-7.3283 4.742zm-40.16-5.2731c-3.5636-3.5816-4.9518-5.1483-4.9518-5.5886 0-0.75745 9.3384-10.601 10.057-10.601 0.2584 0 0.54208 0.18833 0.63041 0.41851s0.1606 4.7624 0.1606 10.072c0 9.1098-0.10948 10.677-0.74606 10.677-0.10905 0-2.4266-2.2396-5.1501-4.9768zm13.2-1.5272c-0.08833-0.23018-0.1606-5.3558-0.1606-11.39 0-8.9734 0.06852-11.102 0.37621-11.686 0.20691-0.39296 2.447-2.7683 4.9781-5.2785 4.3226-4.2871 4.6624-4.5641 5.5987-4.5641 0.94583 0 1.2591 0.26717 6.1277 5.2255 4.658 4.7439 5.1315 5.3102 5.1376 6.1439 6e-3 0.85888-0.67407 1.6-10.506 11.443-5.782 5.7887-10.71 10.525-10.952 10.525s-0.51144-0.18833-0.59977-0.41852z" fill="#fff" stroke-width=".26458"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1015 B After Width: | Height: | Size: 1015 B |
Before Width: | Height: | Size: 683 B After Width: | Height: | Size: 683 B |
Before Width: | Height: | Size: 453 B After Width: | Height: | Size: 453 B |
Before Width: | Height: | Size: 833 B After Width: | Height: | Size: 833 B |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 241 B After Width: | Height: | Size: 241 B |
Before Width: | Height: | Size: 861 B After Width: | Height: | Size: 861 B |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
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 |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
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 |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
@ -5,4 +5,4 @@
|
||||
<div id="pluginTiles" style="text-align:left;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -16,8 +16,14 @@ _define("fetch", function() {
|
||||
return fetch
|
||||
});
|
||||
|
||||
// query-string
|
||||
var query = require("query-string");
|
||||
_define("queryString", function() {
|
||||
return query;
|
||||
});
|
||||
|
||||
// flvjs
|
||||
var flvjs = require("flv.js").default;
|
||||
var flvjs = require("flv.js/dist/flv").default;
|
||||
_define("flvjs", function() {
|
||||
return flvjs;
|
||||
});
|
||||
@ -47,12 +53,6 @@ _define("howler", function() {
|
||||
return howler;
|
||||
});
|
||||
|
||||
// native-promise-only
|
||||
var nativePromise = require("native-promise-only");
|
||||
_define("native-promise-only", function() {
|
||||
return nativePromise;
|
||||
});
|
||||
|
||||
// resize-observer-polyfill
|
||||
var resize = require("resize-observer-polyfill").default;
|
||||
_define("resize-observer-polyfill", function() {
|
||||
@ -66,8 +66,8 @@ _define("shaka", function() {
|
||||
});
|
||||
|
||||
// swiper
|
||||
var swiper = require("swiper");
|
||||
require("swiper/dist/css/swiper.min.css");
|
||||
var swiper = require("swiper/js/swiper");
|
||||
require("swiper/css/swiper.min.css");
|
||||
_define("swiper", function() {
|
||||
return swiper;
|
||||
});
|
||||
@ -81,7 +81,7 @@ _define("sortable", function() {
|
||||
// webcomponents
|
||||
var webcomponents = require("webcomponents.js/webcomponents-lite");
|
||||
_define("webcomponents", function() {
|
||||
return webcomponents
|
||||
return webcomponents;
|
||||
});
|
||||
|
||||
// libjass
|
||||
@ -90,3 +90,32 @@ require("libjass/libjass.css");
|
||||
_define("libjass", function() {
|
||||
return libjass;
|
||||
});
|
||||
|
||||
// libass-wasm
|
||||
var libass_wasm = require("libass-wasm");
|
||||
_define("JavascriptSubtitlesOctopus", function() {
|
||||
return libass_wasm;
|
||||
});
|
||||
|
||||
// material-icons
|
||||
var material_icons = require("material-design-icons-iconfont/dist/material-design-icons.css");
|
||||
_define("material-icons", function() {
|
||||
return material_icons;
|
||||
});
|
||||
|
||||
// noto font
|
||||
var noto = require("jellyfin-noto");
|
||||
_define("jellyfin-noto", function () {
|
||||
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">
|
||||
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
|
||||
<i class="md-icon">arrow_back</i>
|
||||
<i class="material-icons arrow_back"></i>
|
||||
</button>
|
||||
<h3 class="formDialogHeaderTitle">
|
||||
${HeaderAccessSchedule}
|
||||
|
@ -4,7 +4,7 @@
|
||||
padding: 0;
|
||||
border: none;
|
||||
max-height: 84%;
|
||||
border-radius: .1em !important;
|
||||
border-radius: 0.1em !important;
|
||||
}
|
||||
|
||||
.actionsheet-not-fullscreen {
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
.actionSheetContent {
|
||||
margin: 0 !important;
|
||||
padding: .4em 0 !important;
|
||||
padding: 0.4em 0 !important;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@ -45,7 +45,7 @@
|
||||
}
|
||||
|
||||
.actionsheetListItemBody {
|
||||
padding: .4em 1em .4em .6em !important;
|
||||
padding: 0.4em 1em 0.4em 0.6em !important;
|
||||
}
|
||||
|
||||
.actionSheetItemText {
|
||||
@ -59,13 +59,13 @@
|
||||
}
|
||||
|
||||
.actionSheetItemAsideText {
|
||||
opacity: .7;
|
||||
opacity: 0.7;
|
||||
font-size: 90%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex-shrink: 0;
|
||||
margin-left: 5em;
|
||||
margin-right: .5em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.actionSheetScroller {
|
||||
@ -83,14 +83,14 @@
|
||||
}
|
||||
|
||||
.actionsheetDivider {
|
||||
height: .07em;
|
||||
margin: .25em 0;
|
||||
height: 0.07em;
|
||||
margin: 0.25em 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.actionSheetTitle {
|
||||
margin: .6em 0 .7em !important;
|
||||
padding: 0 .9em;
|
||||
margin: 0.6em 0 0.7em !important;
|
||||
padding: 0 0.9em;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@
|
||||
}
|
||||
|
||||
.actionsheetMenuItemIcon {
|
||||
margin: 0 .85em 0 .45em !important;
|
||||
margin: 0 0.85em 0 0.45em !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
@ -110,6 +110,6 @@
|
||||
|
||||
.btnCloseActionSheet {
|
||||
position: fixed;
|
||||
top: .75em;
|
||||
left: .5em;
|
||||
top: 0.75em;
|
||||
left: 0.5em;
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
|
||||
}
|
||||
|
||||
if (layoutManager.tv) {
|
||||
html += '<button is="paper-icon-button-light" class="btnCloseActionSheet hide-mouse-idle-tv" tabindex="-1"><i class="md-icon">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
|
||||
@ -226,9 +226,9 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
|
||||
|
||||
if (itemIcon) {
|
||||
|
||||
html += '<i class="actionsheetMenuItemIcon listItemIcon listItemIcon-transparent md-icon">' + itemIcon + '</i>';
|
||||
html += '<i class="actionsheetMenuItemIcon listItemIcon listItemIcon-transparent material-icons">' + itemIcon + '</i>';
|
||||
} else if (renderIcon && !center) {
|
||||
html += '<i class="actionsheetMenuItemIcon listItemIcon listItemIcon-transparent md-icon" style="visibility:hidden;">check</i>';
|
||||
html += '<i class="actionsheetMenuItemIcon listItemIcon listItemIcon-transparent material-icons" style="visibility:hidden;">check</i>';
|
||||
}
|
||||
|
||||
html += '<div class="listItemBody actionsheetListItemBody">';
|
||||
|
@ -13,12 +13,12 @@ define(["events", "globalize", "dom", "datetime", "userSettings", "serverNotific
|
||||
}
|
||||
|
||||
if (entry.UserId && entry.UserPrimaryImageTag) {
|
||||
html += '<i class="listItemIcon md-icon" style="width:2em!important;height:2em!important;padding:0;color:transparent;background-color:' + color + ";background-image:url('" + apiClient.getUserImageUrl(entry.UserId, {
|
||||
html += '<i class="listItemIcon material-icons" style="width:2em!important;height:2em!important;padding:0;color:transparent;background-color:' + color + ";background-image:url('" + apiClient.getUserImageUrl(entry.UserId, {
|
||||
type: "Primary",
|
||||
tag: entry.UserPrimaryImageTag
|
||||
}) + "');background-repeat:no-repeat;background-position:center center;background-size: cover;\">dvr</i>"
|
||||
} else {
|
||||
html += '<i class="listItemIcon md-icon" style="background-color:' + color + '">' + icon + '</i>';
|
||||
html += '<i class="listItemIcon material-icons" style="background-color:' + color + '">' + icon + '</i>';
|
||||
}
|
||||
|
||||
html += '<div class="listItemBody three-line">';
|
||||
@ -35,7 +35,7 @@ define(["events", "globalize", "dom", "datetime", "userSettings", "serverNotific
|
||||
html += "</div>";
|
||||
|
||||
if (entry.Overview) {
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnEntryInfo" data-id="' + entry.Id + '" title="' + globalize.translate("Info") + '"><i class="md-icon">info</i></button>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnEntryInfo" data-id="' + entry.Id + '" title="' + globalize.translate("Info") + '"><i class="material-icons">info</i></button>';
|
||||
}
|
||||
|
||||
return html += "</div>";
|
||||
|
@ -42,4 +42,4 @@ define(['browser', 'dialog', 'globalize'], function (browser, dialog, globalize)
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ define(['dom', 'focusManager'], function (dom, focusManager) {
|
||||
if (e.ctrlKey) {
|
||||
return;
|
||||
}
|
||||
if (!!e.shiftKey) {
|
||||
if (e.shiftKey) {
|
||||
return;
|
||||
}
|
||||
if (e.altKey) {
|
||||
@ -127,4 +127,4 @@ define(['dom', 'focusManager'], function (dom, focusManager) {
|
||||
};
|
||||
|
||||
return AlphaNumericShortcuts;
|
||||
});
|
||||
});
|
||||
|
@ -67,7 +67,7 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b
|
||||
|
||||
html += '<div class="' + rowClassName + '">';
|
||||
if (options.mode === 'keyboard') {
|
||||
html += '<button data-value=" " is="paper-icon-button-light" class="' + alphaPickerButtonClassName + '"><i class="md-icon 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 {
|
||||
letters = ['#'];
|
||||
html += mapLetters(letters, vertical).join('');
|
||||
@ -77,7 +77,7 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b
|
||||
html += mapLetters(letters, vertical).join('');
|
||||
|
||||
if (options.mode === 'keyboard') {
|
||||
html += '<button data-value="backspace" is="paper-icon-button-light" class="' + alphaPickerButtonClassName + '"><i class="md-icon alphaPickerButtonIcon">backspace</i></button>';
|
||||
html += '<button data-value="backspace" is="paper-icon-button-light" class="' + alphaPickerButtonClassName + '"><i class="material-icons alphaPickerButtonIcon">backspace</i></button>';
|
||||
html += '</div>';
|
||||
|
||||
letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
@ -241,7 +241,7 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b
|
||||
try {
|
||||
btn = element.querySelector('.alphaPickerButton[data-value=\'' + value + '\']');
|
||||
} catch (err) {
|
||||
console.log('Error in querySelector: ' + err);
|
||||
console.error('error in querySelector: ' + err);
|
||||
}
|
||||
|
||||
if (btn && btn !== selected) {
|
||||
|
@ -35,16 +35,15 @@
|
||||
font-size: inherit;
|
||||
min-width: initial;
|
||||
margin: 0;
|
||||
padding: .1em .4em;
|
||||
padding: 0.1em 0.4em;
|
||||
width: auto;
|
||||
border-radius: .1em;
|
||||
border-radius: 0.1em;
|
||||
font-weight: normal;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@media all and (max-height: 50em) {
|
||||
|
||||
.alphaPicker-fixed {
|
||||
bottom: 5em;
|
||||
}
|
||||
@ -56,14 +55,12 @@
|
||||
}
|
||||
|
||||
@media all and (max-height: 49em) {
|
||||
|
||||
.alphaPicker-vertical {
|
||||
font-size: 94%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-height: 44em) {
|
||||
|
||||
.alphaPicker-vertical {
|
||||
font-size: 90%;
|
||||
}
|
||||
@ -75,14 +72,12 @@
|
||||
}
|
||||
|
||||
@media all and (max-height: 37em) {
|
||||
|
||||
.alphaPicker-vertical {
|
||||
font-size: 82%;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-height: 32em) {
|
||||
|
||||
.alphaPicker-vertical {
|
||||
font-size: 74%;
|
||||
}
|
||||
@ -112,27 +107,17 @@
|
||||
bottom: 1%;
|
||||
}
|
||||
|
||||
.alphaPicker-fixed-left {
|
||||
left: .4em;
|
||||
}
|
||||
|
||||
.alphaPicker-fixed-right {
|
||||
right: .4em;
|
||||
right: 0.4em;
|
||||
}
|
||||
|
||||
@media all and (min-width: 62.5em) {
|
||||
|
||||
.alphaPicker-fixed-left {
|
||||
left: 1em;
|
||||
}
|
||||
|
||||
.alphaPicker-fixed-right {
|
||||
right: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-height: 31.25em) {
|
||||
|
||||
.alphaPicker-fixed {
|
||||
display: none !important;
|
||||
}
|
||||
|
@ -14,6 +14,9 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||
},
|
||||
showSettings: function () {
|
||||
show('/settings/settings.html');
|
||||
},
|
||||
showNowPlaying: function () {
|
||||
show("/nowplaying.html");
|
||||
}
|
||||
};
|
||||
|
||||
@ -367,7 +370,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||
}
|
||||
|
||||
function enableNativeHistory() {
|
||||
return page.enableNativeHistory();
|
||||
return false;
|
||||
}
|
||||
|
||||
function authenticate(ctx, route, callback) {
|
||||
@ -387,13 +390,13 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||
var apiClient = connectionManager.currentApiClient();
|
||||
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 shouldExitApp = ctx.isBack && route.isDefaultRoute && isCurrentRouteStartup;
|
||||
|
||||
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();
|
||||
return;
|
||||
}
|
||||
@ -408,10 +411,10 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||
|
||||
if (apiClient && apiClient.isLoggedIn()) {
|
||||
|
||||
console.log('appRouter - user is authenticated');
|
||||
console.debug('appRouter - user is authenticated');
|
||||
|
||||
if (route.isDefaultRoute) {
|
||||
console.log('appRouter - loading skin home page');
|
||||
console.debug('appRouter - loading skin home page');
|
||||
loadUserSkinWithOptions(ctx);
|
||||
return;
|
||||
} 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();
|
||||
}
|
||||
|
||||
@ -545,16 +548,24 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||
page.back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pages of "no return" (when "Go back" should behave differently, probably quitting the application).
|
||||
*/
|
||||
var startPages = ['home', 'login', 'selectserver'];
|
||||
|
||||
function canGoBack() {
|
||||
var curr = current();
|
||||
if (!curr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curr.type === 'home') {
|
||||
if (!document.querySelector('.dialogContainer') && startPages.indexOf(curr.type) !== -1) {
|
||||
return false;
|
||||
}
|
||||
return page.canGoBack();
|
||||
if (enableHistory()) {
|
||||
return history.length > 1;
|
||||
}
|
||||
return (page.len || 0) > 0;
|
||||
}
|
||||
|
||||
function showDirect(path) {
|
||||
@ -658,7 +669,8 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||
|
||||
function pushState(state, title, url) {
|
||||
state.navigate = false;
|
||||
page.pushState(state, title, url);
|
||||
history.pushState(state, title, url);
|
||||
|
||||
}
|
||||
|
||||
function setBaseRoute() {
|
||||
@ -667,7 +679,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||
baseRoute = baseRoute.substring(0, baseRoute.length - 1);
|
||||
}
|
||||
|
||||
console.log('Setting page base to ' + baseRoute);
|
||||
console.debug('setting page base to ' + baseRoute);
|
||||
page.base(baseRoute);
|
||||
}
|
||||
|
||||
@ -708,7 +720,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
|
||||
appRouter.getRoutes = getRoutes;
|
||||
appRouter.pushState = pushState;
|
||||
appRouter.enableNativeHistory = enableNativeHistory;
|
||||
appRouter.handleAnchorClick = page.handleAnchorClick;
|
||||
appRouter.handleAnchorClick = page.clickHandler;
|
||||
appRouter.TransparencyLevel = {
|
||||
None: 0,
|
||||
Backdrop: 1,
|
||||
|
@ -2,12 +2,12 @@
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
z-index: 10;
|
||||
bottom: 0;
|
||||
transition: transform 180ms linear;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.appfooter.headroom--unpinned {
|
||||
transform: translateY(100%)!important;
|
||||
}
|
||||
.appfooter.headroom--unpinned {
|
||||
transform: translateY(100%) !important;
|
||||
}
|
||||
|
@ -2,24 +2,18 @@ define(['browser', 'css!./appfooter'], function (browser) {
|
||||
'use strict';
|
||||
|
||||
function render(options) {
|
||||
|
||||
var elem = document.createElement('div');
|
||||
|
||||
elem.classList.add('appfooter');
|
||||
|
||||
elem.classList.add('appfooter-blurred');
|
||||
|
||||
document.body.appendChild(elem);
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function appFooter(options) {
|
||||
|
||||
var self = this;
|
||||
|
||||
self.element = render(options);
|
||||
|
||||
self.add = function (elem) {
|
||||
self.element.appendChild(elem);
|
||||
};
|
||||
|
@ -104,7 +104,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
|
||||
function getDeviceName() {
|
||||
var deviceName;
|
||||
deviceName = browser.tizen ? "Samsung Smart TV" : browser.web0s ? "LG Smart TV" : browser.operaTv ? "Opera TV" : browser.xboxOne ? "Xbox One" : browser.ps4 ? "Sony PS4" : browser.chrome ? "Chrome" : browser.edge ? "Edge" : browser.firefox ? "Firefox" : browser.msie ? "Internet Explorer" : browser.opera ? "Opera" : "Web Browser";
|
||||
deviceName = browser.tizen ? "Samsung Smart TV" : browser.web0s ? "LG Smart TV" : browser.operaTv ? "Opera TV" : browser.xboxOne ? "Xbox One" : browser.ps4 ? "Sony PS4" : browser.chrome ? "Chrome" : browser.edge ? "Edge" : browser.firefox ? "Firefox" : browser.msie ? "Internet Explorer" : browser.opera ? "Opera" : browser.safari ? "Safari" : "Web Browser";
|
||||
|
||||
if (browser.ipad) {
|
||||
deviceName += " iPad";
|
||||
@ -168,23 +168,25 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
return false;
|
||||
}
|
||||
|
||||
var savedResult = appSettings.get(htmlMediaAutoplayAppStorageKey);
|
||||
return "true" === savedResult || "false" !== savedResult && null;
|
||||
return true;
|
||||
}
|
||||
|
||||
function cueSupported() {
|
||||
function supportsCue() {
|
||||
try {
|
||||
var video = document.createElement("video");
|
||||
var style = document.createElement("style");
|
||||
|
||||
style.textContent = "video::cue {background: inherit}";
|
||||
document.body.appendChild(style);
|
||||
document.body.appendChild(video);
|
||||
|
||||
var cue = window.getComputedStyle(video, "::cue").background;
|
||||
document.body.removeChild(style);
|
||||
document.body.removeChild(video);
|
||||
|
||||
return !!cue.length;
|
||||
} catch (err) {
|
||||
console.log("Error detecting cue support:" + err);
|
||||
console.error("error detecting cue support: " + err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -192,7 +194,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
function onAppVisible() {
|
||||
if (isHidden) {
|
||||
isHidden = false;
|
||||
console.log("triggering app resume event");
|
||||
console.debug("triggering app resume event");
|
||||
events.trigger(appHost, "resume");
|
||||
}
|
||||
}
|
||||
@ -200,12 +202,10 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
function onAppHidden() {
|
||||
if (!isHidden) {
|
||||
isHidden = true;
|
||||
console.log("app is hidden");
|
||||
console.debug("app is hidden");
|
||||
}
|
||||
}
|
||||
|
||||
var htmlMediaAutoplayAppStorageKey = "supportshtmlmediaautoplay0";
|
||||
|
||||
var supportedFeatures = function () {
|
||||
var features = [];
|
||||
|
||||
@ -280,7 +280,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
//features.push("multiserver");
|
||||
features.push("screensaver");
|
||||
|
||||
if (!browser.orsay && !browser.tizen && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || cueSupported())) {
|
||||
if (!browser.orsay && !browser.tizen && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) {
|
||||
features.push("subtitleappearancesettings");
|
||||
}
|
||||
|
||||
@ -299,14 +299,48 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
return features;
|
||||
}();
|
||||
|
||||
if (supportedFeatures.indexOf("htmlvideoautoplay") === -1 && supportsHtmlMediaAutoplay() !== false) {
|
||||
require(["autoPlayDetect"], function (autoPlayDetect) {
|
||||
autoPlayDetect.supportsHtmlMediaAutoplay().then(function () {
|
||||
appSettings.set(htmlMediaAutoplayAppStorageKey, "true");
|
||||
supportedFeatures.push("htmlvideoautoplay");
|
||||
supportedFeatures.push("htmlaudioautoplay");
|
||||
}, function () {
|
||||
appSettings.set(htmlMediaAutoplayAppStorageKey, "false");
|
||||
/**
|
||||
* Do exit according to platform
|
||||
*/
|
||||
function doExit() {
|
||||
try {
|
||||
if (window.NativeShell) {
|
||||
window.NativeShell.AppHost.exit();
|
||||
} else if (browser.tizen) {
|
||||
tizen.application.getCurrentApplication().exit();
|
||||
} else if (browser.web0s) {
|
||||
webOS.platformBack();
|
||||
} else {
|
||||
window.close();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("error closing application: " + err);
|
||||
}
|
||||
}
|
||||
|
||||
var exitPromise;
|
||||
|
||||
/**
|
||||
* Ask user for exit
|
||||
*/
|
||||
function askForExit() {
|
||||
if (exitPromise) {
|
||||
return;
|
||||
}
|
||||
|
||||
require(["actionsheet"], function (actionsheet) {
|
||||
exitPromise = actionsheet.show({
|
||||
title: Globalize.translate("MessageConfirmAppExit"),
|
||||
items: [
|
||||
{id: "yes", name: Globalize.translate("Yes")},
|
||||
{id: "no", name: Globalize.translate("No")}
|
||||
]
|
||||
}).then(function (value) {
|
||||
if (value === "yes") {
|
||||
doExit();
|
||||
}
|
||||
}).finally(function () {
|
||||
exitPromise = null;
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -326,16 +360,10 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
alert("setWindowState is not supported and should not be called");
|
||||
},
|
||||
exit: function () {
|
||||
if (window.NativeShell) {
|
||||
window.NativeShell.AppHost.exit();
|
||||
} else if (browser.tizen) {
|
||||
try {
|
||||
tizen.application.getCurrentApplication().exit();
|
||||
} catch (err) {
|
||||
console.log("error closing application: " + err);
|
||||
}
|
||||
if (!!window.appMode && browser.tizen) {
|
||||
askForExit();
|
||||
} else {
|
||||
window.close();
|
||||
doExit();
|
||||
}
|
||||
},
|
||||
supports: function (command) {
|
||||
@ -346,7 +374,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
return -1 !== supportedFeatures.indexOf(command.toLowerCase());
|
||||
},
|
||||
preferVisualCards: browser.android || browser.chrome,
|
||||
moreIcon: browser.android ? "dots-vert" : "dots-horiz",
|
||||
moreIcon: browser.android ? "more_vert" : "more_horiz",
|
||||
getSyncProfile: getSyncProfile,
|
||||
getDefaultLayout: function () {
|
||||
if (window.NativeShell) {
|
||||
@ -395,7 +423,9 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var doc = self.document;
|
||||
var isHidden = false;
|
||||
|
||||
if (doc) {
|
||||
if (void 0 !== doc.visibilityState) {
|
||||
@ -419,8 +449,6 @@ define(["appSettings", "browser", "events", "htmlMediaHelper"], function (appSet
|
||||
}
|
||||
}
|
||||
|
||||
var isHidden = false;
|
||||
|
||||
if (doc) {
|
||||
doc.addEventListener(visibilityChange, function () {
|
||||
if (document[visibilityState]) {
|
||||
|
@ -25,7 +25,7 @@ define(["focusManager", "layoutManager"], function (focusManager, layoutManager)
|
||||
activeElement = e.target;
|
||||
});
|
||||
|
||||
console.log("AutoFocuser enabled");
|
||||
console.debug("AutoFocuser enabled");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,4 @@
|
||||
define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./backdrop'], function (browser, connectionManager, playbackManager, dom) {
|
||||
define(['browser', 'connectionManager', 'playbackManager', 'dom', "userSettings", 'css!./backdrop'], function (browser, connectionManager, playbackManager, dom, userSettings) {
|
||||
'use strict';
|
||||
|
||||
function enableAnimation(elem) {
|
||||
@ -182,6 +182,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./backdro
|
||||
return apiClient.getScaledImageUrl(item.BackdropItemId || item.Id, Object.assign(imageOptions, {
|
||||
type: "Backdrop",
|
||||
tag: imgTag,
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
index: index
|
||||
}));
|
||||
});
|
||||
@ -192,6 +193,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./backdro
|
||||
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, Object.assign(imageOptions, {
|
||||
type: "Backdrop",
|
||||
tag: imgTag,
|
||||
maxWidth: dom.getScreenWidth(),
|
||||
index: index
|
||||
}));
|
||||
});
|
||||
@ -236,16 +238,22 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./backdro
|
||||
return true;
|
||||
}
|
||||
|
||||
function enabled() {
|
||||
return userSettings.enableBackdrops();
|
||||
}
|
||||
|
||||
var rotationInterval;
|
||||
var currentRotatingImages = [];
|
||||
var currentRotationIndex = -1;
|
||||
function setBackdrops(items, imageOptions, enableImageRotation) {
|
||||
var images = getImageUrls(items, imageOptions);
|
||||
if (enabled()) {
|
||||
var images = getImageUrls(items, imageOptions);
|
||||
|
||||
if (images.length) {
|
||||
startRotation(images, enableImageRotation);
|
||||
} else {
|
||||
clearBackdrop();
|
||||
if (images.length) {
|
||||
startRotation(images, enableImageRotation);
|
||||
} else {
|
||||
clearBackdrop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,4 +318,4 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./backdro
|
||||
clear: clearBackdrop,
|
||||
externalBackdrop: externalBackdrop
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -1,23 +1,24 @@
|
||||
button {
|
||||
-webkit-border-fit: border !important;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
-webkit-border-fit: border !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 0;
|
||||
font-size: inherit !important;
|
||||
font-family: inherit !important;
|
||||
text-transform: none;
|
||||
background-color: transparent !important;
|
||||
background: none !important;
|
||||
background-color: transparent !important;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
color: inherit !important;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
outline: none !important;
|
||||
cursor: pointer;
|
||||
contain: layout style;
|
||||
@ -54,17 +55,27 @@ button {
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.cardPadder-backdrop, .cardPadder-mixedBackdrop, .cardPadder-smallBackdrop, .cardPadder-overflowBackdrop, .cardPadder-overflowSmallBackdrop {
|
||||
.cardPadder-backdrop,
|
||||
.cardPadder-mixedBackdrop,
|
||||
.cardPadder-smallBackdrop,
|
||||
.cardPadder-overflowBackdrop,
|
||||
.cardPadder-overflowSmallBackdrop {
|
||||
padding-bottom: 56.25%;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.cardPadder-square, .cardPadder-mixedSquare, .cardPadder-overflowSquare, .overflowSquareCard-textCardPadder {
|
||||
.cardPadder-square,
|
||||
.cardPadder-mixedSquare,
|
||||
.cardPadder-overflowSquare,
|
||||
.overflowSquareCard-textCardPadder {
|
||||
padding-bottom: 100%;
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.cardPadder-portrait, .cardPadder-mixedPortrait, .cardPadder-overflowPortrait, .overflowPortraitCard-textCardPadder {
|
||||
.cardPadder-portrait,
|
||||
.cardPadder-mixedPortrait,
|
||||
.cardPadder-overflowPortrait,
|
||||
.overflowPortraitCard-textCardPadder {
|
||||
padding-bottom: 150%;
|
||||
contain: strict;
|
||||
}
|
||||
@ -79,23 +90,26 @@ button {
|
||||
margin: 0.6em;
|
||||
transition: none;
|
||||
border: 0 solid transparent;
|
||||
|
||||
/* These both are needed in case cardBox is a button */
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
outline: none !important;
|
||||
contain: layout;
|
||||
contain: style;
|
||||
}
|
||||
|
||||
.card.show-animation .cardBox {
|
||||
will-change: transform;
|
||||
transition: transform 200ms ease-out;
|
||||
}
|
||||
|
||||
.card.show-focus:not(.show-animation) .cardBox {
|
||||
margin: .4em;
|
||||
margin: 0.4em;
|
||||
}
|
||||
|
||||
.card.show-focus:not(.show-animation) .cardBox.visualCardBox,
|
||||
.card.show-focus:not(.show-animation) .cardBox:not(.visualCardBox) .cardScalable {
|
||||
border: .5em solid transparent;
|
||||
}
|
||||
|
||||
.card.show-animation .cardBox {
|
||||
will-change: transform;
|
||||
transition: transform 200ms ease-out;
|
||||
border: 0.5em solid transparent;
|
||||
}
|
||||
|
||||
.card.show-animation:focus > .cardBox {
|
||||
@ -120,7 +134,7 @@ button {
|
||||
|
||||
.btnCardOptions {
|
||||
position: absolute;
|
||||
bottom: .25em;
|
||||
bottom: 0.25em;
|
||||
right: 0;
|
||||
margin: 0 !important;
|
||||
z-index: 1;
|
||||
@ -131,8 +145,8 @@ button {
|
||||
position: absolute;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
top: .3em;
|
||||
left: .3em;
|
||||
top: 0.3em;
|
||||
left: 0.3em;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
width: 1.6em;
|
||||
@ -146,12 +160,14 @@ button {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
background-clip: content-box !important;
|
||||
color: inherit;
|
||||
|
||||
/* This is only needed for scalable cards */
|
||||
height: 100%;
|
||||
contain: strict;
|
||||
@ -173,12 +189,16 @@ button {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
/* Needed in case this is a button */
|
||||
display: block;
|
||||
|
||||
/* Needed in case this is a button */
|
||||
margin: 0 !important;
|
||||
|
||||
/* Needed in safari */
|
||||
height: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
outline: none !important;
|
||||
contain: strict;
|
||||
}
|
||||
@ -207,10 +227,6 @@ button {
|
||||
box-shadow: 0 0.0725em 0.29em 0 rgba(0, 0, 0, 0.37);
|
||||
}
|
||||
|
||||
.cardImageContainer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.cardImage {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -226,6 +242,7 @@ button {
|
||||
.cardImage-img {
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
|
||||
/* This is simply for lazy image purposes, to ensure the image is visible sooner when scrolling */
|
||||
min-height: 70%;
|
||||
min-width: 70%;
|
||||
@ -252,17 +269,17 @@ button {
|
||||
}
|
||||
|
||||
.cardFooter {
|
||||
padding: .3em .3em .5em .3em;
|
||||
padding: 0.3em 0.3em 0.5em 0.3em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.visualCardBox {
|
||||
box-shadow: 0 0.0725em 0.29em 0 rgba(0, 0, 0, 0.37);
|
||||
border-radius: .145em;
|
||||
border-radius: 0.145em;
|
||||
}
|
||||
|
||||
.innerCardFooter {
|
||||
background: rgba(0,0,0,.7);
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
@ -282,7 +299,7 @@ button {
|
||||
}
|
||||
|
||||
.cardText {
|
||||
padding: .06em .5em;
|
||||
padding: 0.06em 0.5em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@ -294,7 +311,24 @@ button {
|
||||
}
|
||||
|
||||
.cardText-first {
|
||||
padding-top: .24em;
|
||||
padding-top: 0.24em;
|
||||
}
|
||||
|
||||
.textActionButton {
|
||||
border: 0 !important;
|
||||
background: transparent;
|
||||
padding: 0 !important;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
outline: none !important;
|
||||
color: inherit;
|
||||
vertical-align: middle;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.textActionButton:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.cardText > .textActionButton {
|
||||
@ -304,7 +338,7 @@ button {
|
||||
}
|
||||
|
||||
.innerCardFooter > .cardText {
|
||||
padding: .3em .5em;
|
||||
padding: 0.3em 0.5em;
|
||||
}
|
||||
|
||||
.cardFooter-withlogo {
|
||||
@ -336,36 +370,19 @@ button {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.textActionButton {
|
||||
border: 0 !important;
|
||||
background: transparent;
|
||||
border: 0 !important;
|
||||
padding: 0 !important;
|
||||
cursor: pointer;
|
||||
outline: none !important;
|
||||
color: inherit;
|
||||
vertical-align: middle;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.textActionButton:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.cardImageIcon {
|
||||
.cardImageContainer .cardImageIcon {
|
||||
font-size: 5em;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.cardImageIcon-small {
|
||||
font-size: 3em;
|
||||
margin-bottom: .1em;
|
||||
font-size: 3em !important;
|
||||
margin-bottom: 0.1em;
|
||||
}
|
||||
|
||||
.cardIndicators {
|
||||
right: .225em;
|
||||
top: .225em;
|
||||
right: 0.225em;
|
||||
top: 0.225em;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -382,16 +399,16 @@ button {
|
||||
}
|
||||
|
||||
.programAttributeIndicator {
|
||||
padding: .18em .5em;
|
||||
padding: 0.18em 0.5em;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.cardOverlayButton {
|
||||
color: rgba(255, 255, 255, .76);
|
||||
color: rgba(255, 255, 255, 0.76);
|
||||
margin: 0;
|
||||
z-index: 1;
|
||||
padding: .75em;
|
||||
padding: 0.75em;
|
||||
font-size: 88%;
|
||||
}
|
||||
|
||||
@ -402,7 +419,7 @@ button {
|
||||
}
|
||||
|
||||
.cardOverlayButtonIcon {
|
||||
background-color: rgba(0,0,0,.7) !important;
|
||||
background-color: rgba(0, 0, 0, 0.7) !important;
|
||||
border-radius: 100em;
|
||||
width: 1.5em !important;
|
||||
height: 1.5em !important;
|
||||
@ -412,6 +429,12 @@ button {
|
||||
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 {
|
||||
bottom: initial;
|
||||
right: initial;
|
||||
@ -424,10 +447,10 @@ button {
|
||||
height: 2.6em;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
background-color: rgba(0,0,0,.5) !important;
|
||||
border: .06em solid rgba(255,255,255,.6);
|
||||
padding: .38em !important;
|
||||
color: rgba(255, 255, 255, .76);
|
||||
background-color: rgba(0, 0, 0, 0.5) !important;
|
||||
border: 0.06em solid rgba(255, 255, 255, 0.6);
|
||||
padding: 0.38em !important;
|
||||
color: rgba(255, 255, 255, 0.76);
|
||||
transition: transform 200ms ease-out;
|
||||
}
|
||||
|
||||
@ -474,13 +497,15 @@ button {
|
||||
width: 33.333333333333333333333333333333%;
|
||||
}
|
||||
|
||||
.squareCard, .portraitCard {
|
||||
.squareCard,
|
||||
.portraitCard {
|
||||
width: 33.333333333333333333333333333333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 43.75em) {
|
||||
.squareCard, .portraitCard {
|
||||
.squareCard,
|
||||
.portraitCard {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
@ -496,7 +521,8 @@ button {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.squareCard, .portraitCard {
|
||||
.squareCard,
|
||||
.portraitCard {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
@ -516,7 +542,8 @@ button {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.squareCard, .portraitCard {
|
||||
.squareCard,
|
||||
.portraitCard {
|
||||
width: 16.666666666666666666666666666667%;
|
||||
}
|
||||
|
||||
@ -529,9 +556,9 @@ button {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 87.5em) {
|
||||
.squareCard, .portraitCard {
|
||||
.squareCard,
|
||||
.portraitCard {
|
||||
width: 14.285714285714285714285714285714%;
|
||||
}
|
||||
|
||||
@ -549,13 +576,15 @@ button {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.squareCard, .portraitCard {
|
||||
.squareCard,
|
||||
.portraitCard {
|
||||
width: 12.5%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 120em) {
|
||||
.squareCard, .portraitCard {
|
||||
.squareCard,
|
||||
.portraitCard {
|
||||
width: 11.111111111111111111111111111111%;
|
||||
}
|
||||
}
|
||||
@ -565,7 +594,8 @@ button {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.squareCard, .portraitCard {
|
||||
.squareCard,
|
||||
.portraitCard {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
@ -596,7 +626,8 @@ button {
|
||||
width: 72vw;
|
||||
}
|
||||
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 40vw;
|
||||
}
|
||||
|
||||
@ -621,29 +652,34 @@ button {
|
||||
}
|
||||
|
||||
@media (min-width: 43.75em) {
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 23.1vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 48.125em) {
|
||||
.overflowBackdropCard, .overflowSmallBackdropCard {
|
||||
.overflowBackdropCard,
|
||||
.overflowSmallBackdropCard {
|
||||
width: 30vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (orientation: landscape) {
|
||||
.overflowBackdropCard, .overflowSmallBackdropCard {
|
||||
.overflowBackdropCard,
|
||||
.overflowSmallBackdropCard {
|
||||
width: 30vw;
|
||||
}
|
||||
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 23.1vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (orientation: landscape) and (min-width: 48.125em) {
|
||||
.overflowBackdropCard, .overflowSmallBackdropCard {
|
||||
.overflowBackdropCard,
|
||||
.overflowSmallBackdropCard {
|
||||
width: 23.1vw;
|
||||
}
|
||||
}
|
||||
@ -655,55 +691,60 @@ button {
|
||||
}
|
||||
|
||||
@media (min-width: 50em) {
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 18.5vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 75em) {
|
||||
.overflowBackdropCard, .overflowSmallBackdropCard {
|
||||
.overflowBackdropCard,
|
||||
.overflowSmallBackdropCard {
|
||||
width: 23.1vw;
|
||||
}
|
||||
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 15.5vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 87.5em) {
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 13.3vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 100em) {
|
||||
|
||||
.overflowBackdropCard, .overflowSmallBackdropCard {
|
||||
.overflowBackdropCard,
|
||||
.overflowSmallBackdropCard {
|
||||
width: 18.7vw;
|
||||
}
|
||||
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 11.6vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 120em) {
|
||||
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
width: 10.3vw;
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 10.41vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 131.25em) {
|
||||
|
||||
.overflowSquareCard, .overflowPortraitCard {
|
||||
.overflowSquareCard,
|
||||
.overflowPortraitCard {
|
||||
width: 9.3vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 156.25em) {
|
||||
|
||||
.overflowBackdropCard, .overflowSmallBackdropCard {
|
||||
.overflowBackdropCard,
|
||||
.overflowSmallBackdropCard {
|
||||
width: 15.6vw;
|
||||
}
|
||||
}
|
||||
@ -720,7 +761,8 @@ button {
|
||||
padding-bottom: 87.75%;
|
||||
}
|
||||
|
||||
.itemsContainer-tv > .overflowSquareCard, .itemsContainer-tv > .overflowPortraitCard {
|
||||
.itemsContainer-tv > .overflowSquareCard,
|
||||
.itemsContainer-tv > .overflowPortraitCard {
|
||||
width: 15.6vw;
|
||||
}
|
||||
|
||||
@ -729,9 +771,9 @@ button {
|
||||
}
|
||||
|
||||
.cardOverlayContainer {
|
||||
background: rgba(0,0,0,0.5);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
opacity: 0;
|
||||
transition: opacity .2s;
|
||||
transition: opacity 0.2s;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@ -748,7 +790,7 @@ button {
|
||||
opacity: 0;
|
||||
transition: 0.2s;
|
||||
background: transparent;
|
||||
padding: 0.5em;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.cardOverlayButtonIcon-hover {
|
||||
@ -760,7 +802,7 @@ button {
|
||||
}
|
||||
|
||||
.cardOverlayFab-primary {
|
||||
background-color: rgba(0,0,0,0.7);
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
font-size: 130%;
|
||||
padding: 0;
|
||||
width: 3em;
|
||||
|
@ -2,7 +2,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
function (datetime, imageLoader, connectionManager, itemHelper, focusManager, indicators, globalize, layoutManager, appHost, dom, browser, playbackManager, itemShortcuts, imageHelper) {
|
||||
'use strict';
|
||||
|
||||
var devicePixelRatio = window.devicePixelRatio || 1;
|
||||
var enableFocusTransform = !browser.slow && !browser.edge;
|
||||
|
||||
function getCardsHtml(items, options) {
|
||||
@ -140,7 +139,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
}
|
||||
return 100 / 72;
|
||||
}
|
||||
break;
|
||||
case 'overflowPortrait':
|
||||
|
||||
if (layoutManager.tv) {
|
||||
@ -166,7 +164,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
}
|
||||
return 100 / 42;
|
||||
}
|
||||
break;
|
||||
case 'overflowSquare':
|
||||
if (layoutManager.tv) {
|
||||
return 100 / 15.5;
|
||||
@ -191,7 +188,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
}
|
||||
return 100 / 42;
|
||||
}
|
||||
break;
|
||||
case 'overflowBackdrop':
|
||||
if (layoutManager.tv) {
|
||||
return 100 / 23.3;
|
||||
@ -216,7 +212,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
}
|
||||
return 100 / 72;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 4;
|
||||
}
|
||||
@ -237,9 +232,9 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
function getImageWidth(shape, screenWidth, isOrientationLandscape) {
|
||||
var imagesPerRow = getPostersPerRow(shape, screenWidth, isOrientationLandscape);
|
||||
var shapeWidth = screenWidth / imagesPerRow;
|
||||
var shapeWidth = Math.round(screenWidth / imagesPerRow) * 2;
|
||||
|
||||
return Math.round(shapeWidth);
|
||||
return shapeWidth;
|
||||
}
|
||||
|
||||
function setCardData(items, options) {
|
||||
@ -342,7 +337,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
try {
|
||||
newIndexValue = datetime.toLocaleDateString(datetime.parseISO8601Date(item.PremiereDate), { weekday: 'long', month: 'long', day: 'numeric' });
|
||||
} catch (err) {
|
||||
console.log('error parsing timestamp for premiere date');
|
||||
console.error('error parsing timestamp for premiere date');
|
||||
}
|
||||
}
|
||||
} else if (options.indexBy === 'ProductionYear') {
|
||||
@ -467,6 +462,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Thumb",
|
||||
maxWidth: width,
|
||||
tag: item.ImageTags.Thumb
|
||||
});
|
||||
|
||||
@ -474,6 +470,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Banner",
|
||||
maxWidth: width,
|
||||
tag: item.ImageTags.Banner
|
||||
});
|
||||
|
||||
@ -481,6 +478,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Disc",
|
||||
maxWidth: width,
|
||||
tag: item.ImageTags.Disc
|
||||
});
|
||||
|
||||
@ -488,6 +486,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Logo",
|
||||
maxWidth: width,
|
||||
tag: item.ImageTags.Logo
|
||||
});
|
||||
|
||||
@ -495,6 +494,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.ParentLogoItemId, {
|
||||
type: "Logo",
|
||||
maxWidth: width,
|
||||
tag: item.ParentLogoImageTag
|
||||
});
|
||||
|
||||
@ -502,6 +502,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
|
||||
type: "Thumb",
|
||||
maxWidth: width,
|
||||
tag: item.SeriesThumbImageTag
|
||||
});
|
||||
|
||||
@ -509,6 +510,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, {
|
||||
type: "Thumb",
|
||||
maxWidth: width,
|
||||
tag: item.ParentThumbImageTag
|
||||
});
|
||||
|
||||
@ -516,6 +518,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Backdrop",
|
||||
maxWidth: width,
|
||||
tag: item.BackdropImageTags[0]
|
||||
});
|
||||
|
||||
@ -525,6 +528,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
|
||||
type: "Backdrop",
|
||||
maxWidth: width,
|
||||
tag: item.ParentBackdropImageTags[0]
|
||||
});
|
||||
|
||||
@ -534,6 +538,8 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Primary",
|
||||
maxHeight: height,
|
||||
maxWidth: width,
|
||||
tag: item.ImageTags.Primary
|
||||
});
|
||||
|
||||
@ -554,6 +560,8 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.PrimaryImageItemId || item.Id || item.ItemId, {
|
||||
type: "Primary",
|
||||
maxHeight: height,
|
||||
maxWidth: width,
|
||||
tag: item.PrimaryImageTag
|
||||
});
|
||||
|
||||
@ -571,20 +579,24 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, {
|
||||
type: "Primary",
|
||||
maxWidth: width,
|
||||
tag: item.ParentPrimaryImageTag
|
||||
});
|
||||
} else if (item.SeriesPrimaryImageTag) {
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
|
||||
type: "Primary",
|
||||
maxWidth: width,
|
||||
tag: item.SeriesPrimaryImageTag
|
||||
});
|
||||
} else if (item.AlbumId && item.AlbumPrimaryImageTag) {
|
||||
|
||||
width = primaryImageAspectRatio ? Math.round(height * primaryImageAspectRatio) : null;
|
||||
height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null;
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.AlbumId, {
|
||||
type: "Primary",
|
||||
maxHeight: height,
|
||||
maxWidth: width,
|
||||
tag: item.AlbumPrimaryImageTag
|
||||
});
|
||||
|
||||
@ -598,6 +610,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Thumb",
|
||||
maxWidth: width,
|
||||
tag: item.ImageTags.Thumb
|
||||
});
|
||||
|
||||
@ -605,6 +618,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Backdrop",
|
||||
maxWidth: width,
|
||||
tag: item.BackdropImageTags[0]
|
||||
});
|
||||
|
||||
@ -612,6 +626,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.Id, {
|
||||
type: "Thumb",
|
||||
maxWidth: width,
|
||||
tag: item.ImageTags.Thumb
|
||||
});
|
||||
|
||||
@ -619,6 +634,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
|
||||
type: "Thumb",
|
||||
maxWidth: width,
|
||||
tag: item.SeriesThumbImageTag
|
||||
});
|
||||
|
||||
@ -626,6 +642,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, {
|
||||
type: "Thumb",
|
||||
maxWidth: width,
|
||||
tag: item.ParentThumbImageTag
|
||||
});
|
||||
|
||||
@ -633,6 +650,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
|
||||
type: "Backdrop",
|
||||
maxWidth: width,
|
||||
tag: item.ParentBackdropImageTags[0]
|
||||
});
|
||||
|
||||
@ -738,7 +756,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
airTimeText += ' - ' + datetime.getDisplayTime(date);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error parsing date: " + item.StartDate);
|
||||
console.error("error parsing date: " + item.StartDate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -758,7 +776,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
if (isOuterFooter && options.cardLayout && layoutManager.mobile) {
|
||||
|
||||
if (options.cardFooterAside !== 'none') {
|
||||
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions cardText-secondary" data-action="menu"><i class="md-icon">more_horiz</i></button>';
|
||||
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions cardText-secondary" data-action="menu"><i class="material-icons more_horiz"></i></button>';
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,9 +888,10 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
if (item.PremiereDate) {
|
||||
try {
|
||||
|
||||
lines.push(getPremiereDateText(item));
|
||||
|
||||
lines.push(datetime.toLocaleDateString(
|
||||
datetime.parseISO8601Date(item.PremiereDate),
|
||||
{ weekday: 'long', month: 'long', day: 'numeric' }
|
||||
));
|
||||
} catch (err) {
|
||||
lines.push('');
|
||||
|
||||
@ -1018,7 +1037,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
return text;
|
||||
}
|
||||
|
||||
var html = '<button ' + itemShortcuts.getShortcutAttributesHtml(item, serverId) + ' type="button" class="itemAction textActionButton" data-action="link">';
|
||||
var html = '<button ' + itemShortcuts.getShortcutAttributesHtml(item, serverId) + ' type="button" class="itemAction textActionButton" title="' + text + '" data-action="link">';
|
||||
html += text;
|
||||
html += '</button>';
|
||||
|
||||
@ -1316,15 +1335,15 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
var btnCssClass = 'cardOverlayButton cardOverlayButton-br itemAction';
|
||||
|
||||
if (options.centerPlayButton) {
|
||||
overlayButtons += '<button is="paper-icon-button-light" class="' + btnCssClass + ' cardOverlayButton-centered" data-action="play"><i class="md-icon cardOverlayButtonIcon">play_arrow</i></button>';
|
||||
overlayButtons += '<button is="paper-icon-button-light" class="' + btnCssClass + ' cardOverlayButton-centered" data-action="play"><i class="material-icons cardOverlayButtonIcon play_arrow"></i></button>';
|
||||
}
|
||||
|
||||
if (overlayPlayButton && !item.IsPlaceHolder && (item.LocationType !== 'Virtual' || !item.MediaType || item.Type === 'Program') && item.Type !== 'Person') {
|
||||
overlayButtons += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="play"><i class="md-icon cardOverlayButtonIcon">play_arrow</i></button>';
|
||||
overlayButtons += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="play"><i class="material-icons cardOverlayButtonIcon play_arrow"></i></button>';
|
||||
}
|
||||
|
||||
if (options.overlayMoreButton) {
|
||||
overlayButtons += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><i class="md-icon cardOverlayButtonIcon">more_horiz</i></button>';
|
||||
overlayButtons += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><i class="material-icons cardOverlayButtonIcon more_horiz"></i></button>';
|
||||
}
|
||||
}
|
||||
|
||||
@ -1383,7 +1402,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
}
|
||||
|
||||
if (item.Type === 'CollectionFolder' || item.CollectionType) {
|
||||
var refreshClass = item.RefreshProgress || (item.RefreshStatus && virtualFolder.item !== 'Idle') ? '' : ' class="hide"';
|
||||
var refreshClass = item.RefreshProgress ? '' : ' class="hide"';
|
||||
indicatorsHtml += '<div is="emby-itemrefreshindicator"' + refreshClass + ' data-progress="' + (item.RefreshProgress || 0) + '" data-status="' + item.RefreshStatus + '"></div>';
|
||||
requireRefreshIndicator();
|
||||
}
|
||||
@ -1397,7 +1416,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
//}
|
||||
|
||||
if (!imgUrl) {
|
||||
cardImageContainerOpen += getCardDefaultText(item, options);
|
||||
cardImageContainerOpen += getDefaultText(item, options);
|
||||
}
|
||||
|
||||
var tagName = (layoutManager.tv) && !overlayButtons ? 'button' : 'div';
|
||||
@ -1457,16 +1476,16 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
var btnCssClass = 'cardOverlayButton cardOverlayButton-hover itemAction paper-icon-button-light';
|
||||
|
||||
if (playbackManager.canPlay(item)) {
|
||||
html += '<button is="paper-icon-button-light" class="' + btnCssClass + ' cardOverlayFab-primary" data-action="resume"><i class="md-icon cardOverlayButtonIcon cardOverlayButtonIcon-hover">play_arrow</i></button>';
|
||||
html += '<button is="paper-icon-button-light" class="' + btnCssClass + ' cardOverlayFab-primary" data-action="resume"><i class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover play_arrow"></i></button>';
|
||||
}
|
||||
|
||||
html += '<div class="cardOverlayButton-br">';
|
||||
html += '<div class="cardOverlayButton-br flex">';
|
||||
|
||||
var userData = item.UserData || {};
|
||||
|
||||
if (itemHelper.canMarkPlayed(item)) {
|
||||
require(['emby-playstatebutton']);
|
||||
html += '<button is="emby-playstatebutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-played="' + (userData.Played) + '"><i class="md-icon cardOverlayButtonIcon cardOverlayButtonIcon-hover">check</i></button>';
|
||||
html += '<button is="emby-playstatebutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-played="' + (userData.Played) + '"><i class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover">check</i></button>';
|
||||
}
|
||||
|
||||
if (itemHelper.canRate(item)) {
|
||||
@ -1474,10 +1493,10 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
var likes = userData.Likes == null ? '' : userData.Likes;
|
||||
|
||||
require(['emby-ratingbutton']);
|
||||
html += '<button is="emby-ratingbutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><i class="md-icon cardOverlayButtonIcon cardOverlayButtonIcon-hover">favorite</i></button>';
|
||||
html += '<button is="emby-ratingbutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><i class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover">favorite</i></button>';
|
||||
}
|
||||
|
||||
html += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><i class="md-icon cardOverlayButtonIcon cardOverlayButtonIcon-hover">more_horiz</i></button>';
|
||||
html += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><i class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover more_horiz"></i></button>';
|
||||
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
@ -1485,18 +1504,29 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
return html;
|
||||
}
|
||||
|
||||
function getCardDefaultText(item, options) {
|
||||
function getDefaultText(item, options) {
|
||||
if (item.CollectionType) {
|
||||
return '<i class="cardImageIcon md-icon">' + imageHelper.getLibraryIcon(item.CollectionType) + '</i>'
|
||||
return '<i class="cardImageIcon material-icons ' + imageHelper.getLibraryIcon(item.CollectionType) + '"></i>'
|
||||
}
|
||||
if (item.Type === 'MusicAlbum') {
|
||||
return '<i class="cardImageIcon md-icon">album</i>';
|
||||
|
||||
switch (item.Type) {
|
||||
case 'MusicAlbum':
|
||||
return '<i class="cardImageIcon material-icons">album</i>';
|
||||
case 'MusicArtist':
|
||||
case 'Person':
|
||||
return '<i class="cardImageIcon material-icons">person</i>';
|
||||
case 'Movie':
|
||||
return '<i class="cardImageIcon material-icons">movie</i>';
|
||||
case 'Series':
|
||||
return '<i class="cardImageIcon material-icons">tv</i>';
|
||||
case 'Book':
|
||||
return '<i class="cardImageIcon material-icons">book</i>';
|
||||
case 'Folder':
|
||||
return '<i class="cardImageIcon material-icons">folder</i>';
|
||||
}
|
||||
if (item.Type === 'MusicArtist' || item.Type === 'Person') {
|
||||
return '<i class="cardImageIcon md-icon">person</i>';
|
||||
}
|
||||
if (options.defaultCardImageIcon) {
|
||||
return '<i class="cardImageIcon md-icon">' + options.defaultCardImageIcon + '</i>';
|
||||
|
||||
if (options && options.defaultCardImageIcon) {
|
||||
return '<i class="cardImageIcon material-icons">' + options.defaultCardImageIcon + '</i>';
|
||||
}
|
||||
|
||||
var defaultName = isUsingLiveTvNaming(item) ? item.Name : itemHelper.getDisplayName(item);
|
||||
@ -1585,7 +1615,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
indicatorsElem = ensureIndicators(card, indicatorsElem);
|
||||
indicatorsElem.appendChild(playedIndicator);
|
||||
}
|
||||
playedIndicator.innerHTML = '<i class="md-icon indicatorIcon">check</i>';
|
||||
playedIndicator.innerHTML = '<i class="material-icons indicatorIcon">check</i>';
|
||||
} else {
|
||||
|
||||
playedIndicator = card.querySelector('.playedIndicator');
|
||||
@ -1666,7 +1696,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
var icon = cell.querySelector('.timerIndicator');
|
||||
if (!icon) {
|
||||
var indicatorsElem = ensureIndicators(cell);
|
||||
indicatorsElem.insertAdjacentHTML('beforeend', '<i class="md-icon timerIndicator indicatorIcon">fiber_manual_record</i>');
|
||||
indicatorsElem.insertAdjacentHTML('beforeend', '<i class="material-icons timerIndicator indicatorIcon fiber_manual_record"></i>');
|
||||
}
|
||||
cell.setAttribute('data-timerid', newTimerId);
|
||||
}
|
||||
@ -1702,6 +1732,8 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
|
||||
|
||||
return {
|
||||
getCardsHtml: getCardsHtml,
|
||||
getDefaultBackgroundClass: getDefaultBackgroundClass,
|
||||
getDefaultText: getDefaultText,
|
||||
buildCards: buildCards,
|
||||
onUserDataChanged: onUserDataChanged,
|
||||
onTimerCreated: onTimerCreated,
|
||||
|
@ -68,7 +68,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
|
||||
|
||||
return apiClient.getScaledImageUrl(item.Id, {
|
||||
|
||||
maxWidth: maxWidth,
|
||||
maxWidth: maxWidth * 2,
|
||||
tag: chapter.ImageTag,
|
||||
type: "Chapter",
|
||||
index: index
|
||||
@ -90,7 +90,7 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
|
||||
var cardImageContainer = imgUrl ? ('<div class="' + cardImageContainerClass + ' lazy" data-src="' + imgUrl + '">') : ('<div class="' + cardImageContainerClass + '">');
|
||||
|
||||
if (!imgUrl) {
|
||||
cardImageContainer += '<i class="md-icon cardImageIcon">local_movies</i>';
|
||||
cardImageContainer += '<i class="material-icons cardImageIcon local_movies"></i>';
|
||||
}
|
||||
|
||||
var nameHtml = '';
|
||||
|
@ -71,7 +71,7 @@ define(["dialogHelper", "loading", "connectionManager", "globalize", "actionshee
|
||||
function getTunerChannelHtml(channel, providerName) {
|
||||
var html = "";
|
||||
html += '<div class="listItem">';
|
||||
html += '<i class="md-icon listItemIcon">dvr</i>';
|
||||
html += '<i class="material-icons listItemIcon">dvr</i>';
|
||||
html += '<div class="listItemBody two-line">';
|
||||
html += '<h3 class="listItemBodyText">';
|
||||
html += channel.Name;
|
||||
@ -84,7 +84,7 @@ define(["dialogHelper", "loading", "connectionManager", "globalize", "actionshee
|
||||
|
||||
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="md-icon">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>";
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ define(["dialogHelper", "loading", "connectionManager", "globalize", "actionshee
|
||||
var html = "";
|
||||
var title = globalize.translate("MapChannels");
|
||||
html += '<div class="formDialogHeader">';
|
||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">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 += title;
|
||||
html += "</h3>";
|
||||
|
@ -131,8 +131,9 @@ define(['events'], function (events) {
|
||||
var links = [];
|
||||
var match;
|
||||
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
while (match = linkRegExp.exec(text)) {
|
||||
// console.log(matches);
|
||||
console.debug(match);
|
||||
var txt = match[0];
|
||||
var pos = match.index;
|
||||
var len = txt.length;
|
||||
@ -189,7 +190,7 @@ define(['events'], function (events) {
|
||||
return apiClient.getPublicSystemInfo().then(function (info) {
|
||||
var localAddress = info.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;
|
||||
}
|
||||
addToCache(serverAddress, localAddress);
|
||||
@ -230,4 +231,4 @@ define(['events'], function (events) {
|
||||
return {
|
||||
getServerAddress: getServerAddress
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -105,7 +105,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
this.sessionListener.bind(this),
|
||||
this.receiverListener.bind(this));
|
||||
|
||||
console.log('chromecast.initialize');
|
||||
console.debug('chromecast.initialize');
|
||||
chrome.cast.initialize(apiConfig, this.onInitSuccess.bind(this), this.errorHandler);
|
||||
};
|
||||
|
||||
@ -114,14 +114,14 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
*/
|
||||
CastPlayer.prototype.onInitSuccess = function () {
|
||||
this.isInitialized = true;
|
||||
console.log("chromecast init success");
|
||||
console.debug("chromecast init success");
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic error callback 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) {
|
||||
if (e === 'available') {
|
||||
console.log("chromecast receiver found");
|
||||
console.debug("chromecast receiver found");
|
||||
this.hasReceivers = true;
|
||||
} else {
|
||||
console.log("chromecast receiver list empty");
|
||||
console.debug("chromecast receiver list empty");
|
||||
this.hasReceivers = false;
|
||||
}
|
||||
};
|
||||
@ -190,7 +190,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
*/
|
||||
CastPlayer.prototype.sessionUpdateListener = function (isAlive) {
|
||||
if (isAlive) {
|
||||
console.log('sessionUpdateListener: already alive');
|
||||
console.debug('sessionUpdateListener: already alive');
|
||||
} else {
|
||||
this.session = null;
|
||||
this.deviceState = DEVICE_STATE.IDLE;
|
||||
@ -198,7 +198,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
document.removeEventListener("volumeupbutton", onVolumeUpKeyDown, false);
|
||||
document.removeEventListener("volumedownbutton", onVolumeDownKeyDown, false);
|
||||
|
||||
console.log('sessionUpdateListener: setting currentMediaSession to null');
|
||||
console.debug('sessionUpdateListener: setting currentMediaSession to null');
|
||||
this.currentMediaSession = null;
|
||||
|
||||
sendConnectionResult(false);
|
||||
@ -211,7 +211,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
* session request in opt_sessionRequest.
|
||||
*/
|
||||
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));
|
||||
};
|
||||
|
||||
@ -220,7 +220,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
* @param {Object} e A chrome.cast.Session object
|
||||
*/
|
||||
CastPlayer.prototype.onRequestSessionSuccess = function (e) {
|
||||
console.log("chromecast session success: " + e.sessionId);
|
||||
console.debug("chromecast session success: " + e.sessionId);
|
||||
this.onSessionConnected(e);
|
||||
};
|
||||
|
||||
@ -262,7 +262,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
* Callback function for launch error
|
||||
*/
|
||||
CastPlayer.prototype.onLaunchError = function () {
|
||||
console.log("chromecast launch error");
|
||||
console.debug("chromecast launch error");
|
||||
this.deviceState = DEVICE_STATE.ERROR;
|
||||
sendConnectionResult(false);
|
||||
};
|
||||
@ -280,7 +280,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
* Callback function for stop app success
|
||||
*/
|
||||
CastPlayer.prototype.onStopAppSuccess = function (message) {
|
||||
console.log(message);
|
||||
console.debug(message);
|
||||
|
||||
this.deviceState = DEVICE_STATE.IDLE;
|
||||
this.castPlayerState = PLAYER_STATE.IDLE;
|
||||
@ -296,7 +296,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
*/
|
||||
CastPlayer.prototype.loadMedia = function (options, command) {
|
||||
if (!this.session) {
|
||||
console.log("no session");
|
||||
console.debug("no session");
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
@ -377,7 +377,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
};
|
||||
|
||||
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) {
|
||||
|
||||
//console.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
|
||||
console.debug("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
|
||||
this.currentMediaSession = mediaSession;
|
||||
|
||||
if (how === 'loadMedia') {
|
||||
@ -405,7 +405,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
* @param {!Boolean} e true/false
|
||||
*/
|
||||
CastPlayer.prototype.onMediaStatusUpdate = function (e) {
|
||||
//console.log("chromecast updating media: " + e);
|
||||
console.debug("chromecast updating media: " + e);
|
||||
if (e === false) {
|
||||
this.castPlayerState = PLAYER_STATE.IDLE;
|
||||
}
|
||||
@ -417,7 +417,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
*/
|
||||
CastPlayer.prototype.setReceiverVolume = function (mute, vol) {
|
||||
if (!this.currentMediaSession) {
|
||||
//console.log('this.currentMediaSession is null');
|
||||
console.debug('this.currentMediaSession is null');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -443,7 +443,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
* Callback function for media command success
|
||||
*/
|
||||
CastPlayer.prototype.mediaCommandSuccessCallback = function (info, e) {
|
||||
//console.log(info);
|
||||
console.debug(info);
|
||||
};
|
||||
|
||||
function normalizeImages(state) {
|
||||
@ -493,7 +493,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
|
||||
events.on(instance._castPlayer, eventName, function (e, data) {
|
||||
|
||||
//console.log('cc: ' + eventName);
|
||||
console.debug('cc: ' + eventName);
|
||||
var state = instance.getPlayerStateInternal(data);
|
||||
|
||||
events.trigger(instance, eventName, [state]);
|
||||
@ -520,14 +520,14 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
playbackManager.setActivePlayer(PlayerName, instance.getCurrentTargetInfo());
|
||||
}
|
||||
|
||||
console.log('cc: connect');
|
||||
console.debug('cc: connect');
|
||||
// Reset this so that statechange will fire
|
||||
instance.lastPlayerData = null;
|
||||
});
|
||||
|
||||
events.on(instance._castPlayer, "playbackstart", function (e, data) {
|
||||
|
||||
console.log('cc: playbackstart');
|
||||
console.debug('cc: playbackstart');
|
||||
|
||||
instance._castPlayer.initializeCastPlayer();
|
||||
|
||||
@ -537,7 +537,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
|
||||
events.on(instance._castPlayer, "playbackstop", function (e, data) {
|
||||
|
||||
console.log('cc: playbackstop');
|
||||
console.debug('cc: playbackstop');
|
||||
var state = instance.getPlayerStateInternal(data);
|
||||
|
||||
events.trigger(instance, "playbackstop", [state]);
|
||||
@ -555,7 +555,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
|
||||
events.on(instance._castPlayer, "playbackprogress", function (e, data) {
|
||||
|
||||
//console.log('cc: positionchange');
|
||||
console.debug('cc: positionchange');
|
||||
var state = instance.getPlayerStateInternal(data);
|
||||
|
||||
events.trigger(instance, "timeupdate", [state]);
|
||||
@ -569,7 +569,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
|
||||
events.on(instance._castPlayer, "playstatechange", function (e, data) {
|
||||
|
||||
//console.log('cc: playstatechange');
|
||||
console.debug('cc: playstatechange');
|
||||
var state = instance.getPlayerStateInternal(data);
|
||||
|
||||
events.trigger(instance, "pause", [state]);
|
||||
@ -664,7 +664,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
|
||||
normalizeImages(data);
|
||||
|
||||
//console.log(JSON.stringify(data));
|
||||
console.debug(JSON.stringify(data));
|
||||
|
||||
if (triggerStateChange) {
|
||||
events.trigger(this, "statechange", [data]);
|
||||
@ -686,6 +686,13 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
|
||||
});
|
||||
}
|
||||
|
||||
if (options.items.length > 1 && options && options.ids) {
|
||||
// Use the original request id array for sorting the result in the proper order
|
||||
options.items.sort(function (a, b) {
|
||||
return options.ids.indexOf(a.Id) - options.ids.indexOf(b.Id);
|
||||
});
|
||||
}
|
||||
|
||||
return this._castPlayer.loadMedia(options, command);
|
||||
};
|
||||
|
||||
|
@ -243,13 +243,13 @@ define(['dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectionManage
|
||||
var title = items.length ? globalize.translate('HeaderAddToCollection') : globalize.translate('NewCollection');
|
||||
|
||||
html += '<div class="formDialogHeader">';
|
||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">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 += title;
|
||||
html += '</h3>';
|
||||
|
||||
if (appHost.supports('externallinks')) {
|
||||
html += '<a is="emby-linkbutton" class="button-link btnHelp flex align-items-center" href="https://web.archive.org/web/20181216120305/https://github.com/MediaBrowser/Wiki/wiki/Collections" target="_blank" style="margin-left:auto;margin-right:.5em;padding:.25em;" title="' + globalize.translate('Help') + '"><i class="md-icon">info</i><span style="margin-left:.25em;">' + globalize.translate('Help') + '</span></a>';
|
||||
html += '<a is="emby-linkbutton" class="button-link btnHelp flex align-items-center" href="https://web.archive.org/web/20181216120305/https://github.com/MediaBrowser/Wiki/wiki/Collections" target="_blank" style="margin-left:auto;margin-right:.5em;padding:.25em;" title="' + globalize.translate('Help') + '"><i class="material-icons">info</i><span style="margin-left:.25em;">' + globalize.translate('Help') + '</span></a>';
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
|
@ -24,4 +24,4 @@ define([], function () {
|
||||
return Promise.reject();
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -12,4 +12,4 @@
|
||||
</div>
|
||||
|
||||
<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 {
|
||||
parentNode.removeChild(elem);
|
||||
} catch (err) {
|
||||
console.log('Error removing dialog element: ' + err);
|
||||
console.error('error removing dialog element: ' + err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -242,9 +242,15 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager',
|
||||
|
||||
var onAnimationFinish = function () {
|
||||
focusManager.pushScope(dlg);
|
||||
|
||||
if (dlg.getAttribute('data-autofocus') === 'true') {
|
||||
focusManager.autoFocus(dlg);
|
||||
}
|
||||
|
||||
if (document.activeElement && !dlg.contains(document.activeElement)) {
|
||||
// Blur foreign element to prevent triggering of an action from the previous scope
|
||||
document.activeElement.blur();
|
||||
}
|
||||
};
|
||||
|
||||
if (enableAnimation()) {
|
||||
@ -481,4 +487,4 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager',
|
||||
globalOnOpenCallback = val;
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
@ -15,10 +15,12 @@
|
||||
|
||||
.dialog {
|
||||
margin: 0;
|
||||
border-radius: .2em;
|
||||
border-radius: 0.2em;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
will-change: transform, opacity;
|
||||
|
||||
/* Strict does not work well with actionsheet */
|
||||
contain: style paint;
|
||||
box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.4);
|
||||
@ -50,13 +52,13 @@
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: scale(.5);
|
||||
transform: scale(0.5);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleup {
|
||||
from {
|
||||
transform: scale(.5);
|
||||
transform: scale(0.5);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@ -77,7 +79,6 @@
|
||||
}
|
||||
|
||||
@keyframes fadeout {
|
||||
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
@ -100,7 +101,6 @@
|
||||
}
|
||||
|
||||
@keyframes slidedown {
|
||||
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
@ -113,8 +113,8 @@
|
||||
}
|
||||
|
||||
@media all and (max-width: 80em), all and (max-height: 45em) {
|
||||
|
||||
.dialog-fixedSize, .dialog-fullscreen-lowres {
|
||||
.dialog-fixedSize,
|
||||
.dialog-fullscreen-lowres {
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
bottom: 0 !important;
|
||||
@ -126,7 +126,6 @@
|
||||
}
|
||||
|
||||
@media all and (min-width: 80em) and (min-height: 45em) {
|
||||
|
||||
.dialog-medium {
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
@ -168,5 +167,5 @@
|
||||
}
|
||||
|
||||
.dialogBackdropOpened {
|
||||
opacity: .5;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ulDirectoryPickerList a {
|
||||
padding-top: .4em;
|
||||
padding-bottom: .4em
|
||||
padding-top: 0.4em;
|
||||
padding-bottom: 0.4em;
|
||||
}
|
||||
|
||||
.lblDirectoryPickerPath {
|
||||
white-space: nowrap
|
||||
}
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
||||
html += name;
|
||||
html += "</div>";
|
||||
html += "</div>";
|
||||
html += '<i class="md-icon" style="font-size:inherit;">arrow_forward</i>';
|
||||
html += '<i class="material-icons arrow_forward" style="font-size:inherit;"></i>';
|
||||
html += "</div>";
|
||||
return html;
|
||||
}
|
||||
@ -116,7 +116,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
||||
html += '<input is="emby-input" id="txtDirectoryPickerPath" type="text" required="required" ' + readOnlyAttribute + ' label="' + Globalize.translate(labelKey) + '"/>';
|
||||
html += "</div>";
|
||||
if (!readOnlyAttribute) {
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnRefreshDirectories emby-input-iconbutton" title="' + Globalize.translate("ButtonRefresh") + '"><i class="md-icon">search</i></button>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnRefreshDirectories emby-input-iconbutton" title="' + Globalize.translate("ButtonRefresh") + '"><i class="material-icons">search</i></button>';
|
||||
}
|
||||
html += "</div>";
|
||||
if (!readOnlyAttribute) {
|
||||
@ -265,7 +265,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
|
||||
|
||||
var html = "";
|
||||
html += '<div class="formDialogHeader">';
|
||||
html += '<button is="paper-icon-button-light" class="btnCloseDialog autoSize" tabindex="-1"><i class="md-icon">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 += options.header || Globalize.translate("HeaderSelectPath");
|
||||
html += "</h3>";
|
||||
|
@ -180,6 +180,7 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', '
|
||||
|
||||
context.querySelector('#chkThemeSong').checked = userSettings.enableThemeSongs();
|
||||
context.querySelector('#chkThemeVideo').checked = userSettings.enableThemeVideos();
|
||||
context.querySelector('#chkFadein').checked = userSettings.enableFastFadein();
|
||||
context.querySelector('#chkBackdrops').checked = userSettings.enableBackdrops();
|
||||
|
||||
context.querySelector('#selectLanguage').value = userSettings.language() || '';
|
||||
@ -216,6 +217,7 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', '
|
||||
|
||||
userSettingsInstance.skin(context.querySelector('.selectSkin').value);
|
||||
|
||||
userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked);
|
||||
userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked);
|
||||
|
||||
if (user.Id === apiClient.getCurrentUserId()) {
|
||||
|
@ -3,6 +3,7 @@
|
||||
<h2 class="sectionTitle">
|
||||
${Display}
|
||||
</h2>
|
||||
|
||||
<div class="selectContainer languageSection hide">
|
||||
<select id="selectLanguage" is="emby-select" label="${LabelDisplayLanguage}">
|
||||
<option value="">${Auto}</option>
|
||||
@ -133,6 +134,7 @@
|
||||
<div class="selectContainer selectDashboardThemeContainer hide">
|
||||
<select id="selectDashboardTheme" is="emby-select" label="${LabelDashboardTheme}"></select>
|
||||
</div>
|
||||
|
||||
<div class="selectContainer hide selectScreensaverContainer">
|
||||
<select is="emby-select" class="selectScreensaver" label="${LabelScreensaver}"></select>
|
||||
</div>
|
||||
@ -141,6 +143,14 @@
|
||||
<select is="emby-select" class="selectSoundEffects" label="${LabelSoundEffects}"></select>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription fldFadein">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkFadein" />
|
||||
<span>${EnableFastImageFadeIn}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${EnableFastImageFadeInHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription fldBackdrops hide">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkBackdrops" />
|
||||
@ -148,6 +158,7 @@
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${EnableBackdropsHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription fldThemeSong hide">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkThemeSong" />
|
||||
@ -155,6 +166,7 @@
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${EnableThemeSongsHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription fldThemeVideo hide">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkThemeVideo" />
|
||||
|
@ -63,13 +63,14 @@ define([], function () {
|
||||
var supportsCaptureOption = false;
|
||||
try {
|
||||
var opts = Object.defineProperty({}, 'capture', {
|
||||
// eslint-disable-next-line getter-return
|
||||
get: function () {
|
||||
supportsCaptureOption = true;
|
||||
}
|
||||
});
|
||||
window.addEventListener("test", null, opts);
|
||||
} catch (e) {
|
||||
console.log('error checking capture support');
|
||||
console.debug('error checking capture support');
|
||||
}
|
||||
|
||||
function addEventListenerWithOptions(target, type, handler, options) {
|
||||
@ -111,6 +112,22 @@ define([], function () {
|
||||
return windowSize;
|
||||
}
|
||||
|
||||
var standardWidths = [480, 720, 1280, 1440, 1920, 2560, 3840, 5120, 7680];
|
||||
function getScreenWidth() {
|
||||
var width = window.innerWidth;
|
||||
var height = window.innerHeight;
|
||||
|
||||
if (height > width) {
|
||||
width = height * (16.0 / 9.0);
|
||||
}
|
||||
|
||||
var closest = standardWidths.sort(function (a, b) {
|
||||
return Math.abs(width - a) - Math.abs(width - b);
|
||||
})[0];
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
var _animationEvent;
|
||||
function whichAnimationEvent() {
|
||||
|
||||
@ -174,8 +191,9 @@ define([], function () {
|
||||
addEventListener: addEventListenerWithOptions,
|
||||
removeEventListener: removeEventListenerWithOptions,
|
||||
getWindowSize: getWindowSize,
|
||||
getScreenWidth: getScreenWidth,
|
||||
whichTransitionEvent: whichTransitionEvent,
|
||||
whichAnimationEvent: whichAnimationEvent,
|
||||
whichAnimationCancelEvent: whichAnimationCancelEvent
|
||||
};
|
||||
});
|
||||
});
|
||||
|