Compare commits
38 Commits
release-10
...
release-10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc461a830d | ||
|
|
e6e5f38a0d | ||
|
|
756e322e1c | ||
|
|
c9ed8c750e | ||
|
|
5f1af65c2e | ||
|
|
ff88922f19 | ||
|
|
47700dc29c | ||
|
|
c2ebc35080 | ||
|
|
d040177525 | ||
|
|
cac6b42dab | ||
|
|
15e9b645f2 | ||
|
|
1833b348e9 | ||
|
|
ccb74610aa | ||
|
|
5c37ee6276 | ||
|
|
e25721cb34 | ||
|
|
f11b27fc14 | ||
|
|
26d29dc2cb | ||
|
|
537b3a3351 | ||
|
|
ab58d3c3a1 | ||
|
|
e7be594b8f | ||
|
|
229294aecc | ||
|
|
e41c1854d0 | ||
|
|
e355fcdac0 | ||
|
|
453d225c84 | ||
|
|
ec9ab39d26 | ||
|
|
c2d9ca2af9 | ||
|
|
eba30bda75 | ||
|
|
5c9847468f | ||
|
|
027cb4f744 | ||
|
|
37cde45d12 | ||
|
|
875c4e0882 | ||
|
|
ee9d651246 | ||
|
|
7f133ff8cd | ||
|
|
76f9b2c741 | ||
|
|
51768eb119 | ||
|
|
cdaf03a769 | ||
|
|
f1acfda7d2 | ||
|
|
fef30a0be3 |
@@ -8,6 +8,8 @@ jobs:
|
||||
BuildConfiguration: development
|
||||
Production:
|
||||
BuildConfiguration: production
|
||||
Standalone:
|
||||
BuildConfiguration: standalone
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
@@ -19,24 +21,28 @@ jobs:
|
||||
versionSpec: '12.x'
|
||||
|
||||
- task: Cache@2
|
||||
displayName: 'Cache node_modules'
|
||||
displayName: 'Check Cache'
|
||||
inputs:
|
||||
key: 'npm | package-lock.json'
|
||||
key: 'yarn | yarn.lock'
|
||||
path: 'node_modules'
|
||||
cacheHitVar: CACHE_RESTORED
|
||||
|
||||
- script: 'npm ci --no-audit'
|
||||
- script: 'yarn install --frozen-lockfile'
|
||||
displayName: 'Install Dependencies'
|
||||
env:
|
||||
SKIP_PREPARE: 'true'
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
|
||||
- script: 'npm run build:development'
|
||||
- script: 'yarn build:development'
|
||||
displayName: 'Build Development'
|
||||
condition: eq(variables['BuildConfiguration'], 'development')
|
||||
|
||||
- script: 'npm run build:production'
|
||||
- script: 'yarn build:production'
|
||||
displayName: 'Build Production'
|
||||
condition: eq(variables['BuildConfiguration'], 'production')
|
||||
|
||||
- script: 'yarn build:standalone'
|
||||
displayName: 'Build Standalone'
|
||||
condition: eq(variables['BuildConfiguration'], 'standalone')
|
||||
|
||||
- script: 'test -d dist'
|
||||
displayName: 'Check Build'
|
||||
|
||||
|
||||
29
.ci/azure-pipelines-lint.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
jobs:
|
||||
- job: Lint
|
||||
displayName: 'Lint'
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
displayName: 'Install Node'
|
||||
inputs:
|
||||
versionSpec: '12.x'
|
||||
|
||||
- task: Cache@2
|
||||
displayName: 'Check Cache'
|
||||
inputs:
|
||||
key: 'yarn | yarn.lock'
|
||||
path: 'node_modules'
|
||||
cacheHitVar: CACHE_RESTORED
|
||||
|
||||
- script: 'yarn install --frozen-lockfile'
|
||||
displayName: 'Install Dependencies'
|
||||
condition: ne(variables.CACHE_RESTORED, 'true')
|
||||
|
||||
- script: 'yarn run lint --quiet'
|
||||
displayName: 'Run ESLint'
|
||||
|
||||
- script: 'yarn run stylelint'
|
||||
displayName: 'Run Stylelint'
|
||||
@@ -17,10 +17,6 @@ jobs:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- script: echo "##vso[task.setvariable variable=JellyfinVersion]$( awk -F '/' '{ print $NF }' <<<'$(Build.SourceBranch)' | sed 's/^v//' )"
|
||||
displayName: Set release version (stable)
|
||||
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v')
|
||||
|
||||
- script: 'docker build -f deployment/Dockerfile.$(BuildConfiguration) -t jellyfin-web-$(BuildConfiguration) deployment'
|
||||
displayName: 'Build Dockerfile'
|
||||
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))
|
||||
@@ -123,4 +119,4 @@ jobs:
|
||||
inputs:
|
||||
sshEndpoint: repository
|
||||
runOptions: 'inline'
|
||||
inline: 'sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber) $(Build.SourceBranch)'
|
||||
inline: 'sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber)'
|
||||
|
||||
@@ -13,4 +13,5 @@ pr:
|
||||
|
||||
jobs:
|
||||
- template: azure-pipelines-build.yml
|
||||
- template: azure-pipelines-lint.yml
|
||||
- template: azure-pipelines-package.yml
|
||||
|
||||
1
.copr/Makefile
Symbolic link
@@ -0,0 +1 @@
|
||||
../fedora/Makefile
|
||||
5
.dependabot/config.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
version: 1
|
||||
update_configs:
|
||||
- package_manager: "javascript"
|
||||
directory: "/"
|
||||
update_schedule: "weekly"
|
||||
@@ -8,5 +8,5 @@ trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
|
||||
[*.json]
|
||||
[json]
|
||||
indent_size = 2
|
||||
|
||||
@@ -2,3 +2,4 @@ node_modules
|
||||
dist
|
||||
.idea
|
||||
.vscode
|
||||
src/libraries
|
||||
|
||||
252
.eslintrc.js
@@ -1,10 +1,6 @@
|
||||
const restrictedGlobals = require('confusing-browser-globals');
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
plugins: [
|
||||
'@babel',
|
||||
'react',
|
||||
'promise',
|
||||
'import',
|
||||
'eslint-comments'
|
||||
@@ -19,153 +15,42 @@ module.exports = {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
impliedStrict: true,
|
||||
jsx: true
|
||||
impliedStrict: true
|
||||
}
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
// 'plugin:promise/recommended',
|
||||
'plugin:import/errors',
|
||||
'plugin:import/warnings',
|
||||
'plugin:eslint-comments/recommended',
|
||||
'plugin:compat/recommended'
|
||||
],
|
||||
rules: {
|
||||
'array-callback-return': ['error'],
|
||||
'block-spacing': ['error'],
|
||||
'brace-style': ['error', '1tbs', { 'allowSingleLine': true }],
|
||||
'brace-style': ['error'],
|
||||
'comma-dangle': ['error', 'never'],
|
||||
'comma-spacing': ['error'],
|
||||
'default-case-last': ['error'],
|
||||
'eol-last': ['error'],
|
||||
'indent': ['error', 4, { 'SwitchCase': 1 }],
|
||||
'jsx-quotes': ['error', 'prefer-single'],
|
||||
'keyword-spacing': ['error'],
|
||||
'max-statements-per-line': ['error'],
|
||||
'no-empty-function': ['error'],
|
||||
'no-floating-decimal': ['error'],
|
||||
'no-multi-spaces': ['error'],
|
||||
'no-multiple-empty-lines': ['error', { 'max': 1 }],
|
||||
'no-restricted-globals': ['error'].concat(restrictedGlobals),
|
||||
'no-trailing-spaces': ['error'],
|
||||
'@babel/no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }],
|
||||
'one-var': ['error', 'never'],
|
||||
'padded-blocks': ['error', 'never'],
|
||||
'prefer-const': ['error', {'destructuring': 'all'}],
|
||||
'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }],
|
||||
'@babel/semi': ['error'],
|
||||
'no-var': ['error'],
|
||||
'semi': ['error'],
|
||||
'space-before-blocks': ['error'],
|
||||
'space-infix-ops': 'error',
|
||||
'yoda': 'error'
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
},
|
||||
'import/extensions': [
|
||||
'.js',
|
||||
'.ts',
|
||||
'.jsx',
|
||||
'.tsx'
|
||||
],
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': [ '.ts', '.tsx' ]
|
||||
},
|
||||
polyfills: [
|
||||
// Native Promises Only
|
||||
'Promise',
|
||||
// whatwg-fetch
|
||||
'fetch',
|
||||
// document-register-element
|
||||
'document.registerElement',
|
||||
// resize-observer-polyfill
|
||||
'ResizeObserver',
|
||||
// fast-text-encoding
|
||||
'TextEncoder',
|
||||
// intersection-observer
|
||||
'IntersectionObserver',
|
||||
// Core-js
|
||||
'Object.assign',
|
||||
'Object.is',
|
||||
'Object.setPrototypeOf',
|
||||
'Object.toString',
|
||||
'Object.freeze',
|
||||
'Object.seal',
|
||||
'Object.preventExtensions',
|
||||
'Object.isFrozen',
|
||||
'Object.isSealed',
|
||||
'Object.isExtensible',
|
||||
'Object.getOwnPropertyDescriptor',
|
||||
'Object.getPrototypeOf',
|
||||
'Object.keys',
|
||||
'Object.entries',
|
||||
'Object.getOwnPropertyNames',
|
||||
'Function.name',
|
||||
'Function.hasInstance',
|
||||
'Array.from',
|
||||
'Array.arrayOf',
|
||||
'Array.copyWithin',
|
||||
'Array.fill',
|
||||
'Array.find',
|
||||
'Array.findIndex',
|
||||
'Array.iterator',
|
||||
'String.fromCodePoint',
|
||||
'String.raw',
|
||||
'String.iterator',
|
||||
'String.codePointAt',
|
||||
'String.endsWith',
|
||||
'String.includes',
|
||||
'String.repeat',
|
||||
'String.startsWith',
|
||||
'String.trim',
|
||||
'String.anchor',
|
||||
'String.big',
|
||||
'String.blink',
|
||||
'String.bold',
|
||||
'String.fixed',
|
||||
'String.fontcolor',
|
||||
'String.fontsize',
|
||||
'String.italics',
|
||||
'String.link',
|
||||
'String.small',
|
||||
'String.strike',
|
||||
'String.sub',
|
||||
'String.sup',
|
||||
'RegExp',
|
||||
'Number',
|
||||
'Math',
|
||||
'Date',
|
||||
'async',
|
||||
'Symbol',
|
||||
'Map',
|
||||
'Set',
|
||||
'WeakMap',
|
||||
'WeakSet',
|
||||
'ArrayBuffer',
|
||||
'DataView',
|
||||
'Int8Array',
|
||||
'Uint8Array',
|
||||
'Uint8ClampedArray',
|
||||
'Int16Array',
|
||||
'Uint16Array',
|
||||
'Int32Array',
|
||||
'Uint32Array',
|
||||
'Float32Array',
|
||||
'Float64Array',
|
||||
'Reflect',
|
||||
// Temporary while eslint-compat-plugin is buggy
|
||||
'document.querySelector'
|
||||
]
|
||||
'space-infix-ops': 'error'
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
'./src/**/*.js',
|
||||
'./src/**/*.ts'
|
||||
'./src/**/*.js'
|
||||
],
|
||||
parser: '@babel/eslint-parser',
|
||||
parser: 'babel-eslint',
|
||||
env: {
|
||||
node: false,
|
||||
amd: true,
|
||||
@@ -185,13 +70,17 @@ module.exports = {
|
||||
// Dependency globals
|
||||
'$': 'readonly',
|
||||
'jQuery': 'readonly',
|
||||
'requirejs': 'readonly',
|
||||
// Jellyfin globals
|
||||
'ApiClient': 'writable',
|
||||
'Events': 'writable',
|
||||
'AppInfo': 'writable',
|
||||
'chrome': 'writable',
|
||||
'ConnectionManager': 'writable',
|
||||
'DlnaProfilePage': 'writable',
|
||||
'Dashboard': 'writable',
|
||||
'DashboardPage': 'writable',
|
||||
'Emby': 'readonly',
|
||||
'Events': 'writable',
|
||||
'getParameterByName': 'writable',
|
||||
'getWindowLocationSearch': 'writable',
|
||||
'Globalize': 'writable',
|
||||
@@ -200,33 +89,108 @@ module.exports = {
|
||||
'LibraryMenu': 'writable',
|
||||
'LinkParser': 'writable',
|
||||
'LiveTvHelpers': 'writable',
|
||||
'Loading': 'writable',
|
||||
'MetadataEditor': 'writable',
|
||||
'pageClassOn': 'writable',
|
||||
'pageIdOn': 'writable',
|
||||
'PlaylistViewer': 'writable',
|
||||
'ServerNotifications': 'writable',
|
||||
'TaskButton': 'writable',
|
||||
'UserParentalControlPage': 'writable',
|
||||
'Windows': 'readonly'
|
||||
},
|
||||
rules: {
|
||||
// TODO: Fix warnings and remove these rules
|
||||
'no-redeclare': ['warn'],
|
||||
'no-unused-vars': ['warn'],
|
||||
'no-useless-escape': ['warn'],
|
||||
// TODO: Remove after ES6 migration is complete
|
||||
'import/no-unresolved': ['off']
|
||||
},
|
||||
settings: {
|
||||
polyfills: [
|
||||
// Native Promises Only
|
||||
'Promise',
|
||||
// whatwg-fetch
|
||||
'fetch',
|
||||
// document-register-element
|
||||
'document.registerElement',
|
||||
// resize-observer-polyfill
|
||||
'ResizeObserver',
|
||||
// fast-text-encoding
|
||||
'TextEncoder',
|
||||
// intersection-observer
|
||||
'IntersectionObserver',
|
||||
// Core-js
|
||||
'Object.assign',
|
||||
'Object.is',
|
||||
'Object.setPrototypeOf',
|
||||
'Object.toString',
|
||||
'Object.freeze',
|
||||
'Object.seal',
|
||||
'Object.preventExtensions',
|
||||
'Object.isFrozen',
|
||||
'Object.isSealed',
|
||||
'Object.isExtensible',
|
||||
'Object.getOwnPropertyDescriptor',
|
||||
'Object.getPrototypeOf',
|
||||
'Object.keys',
|
||||
'Object.entries',
|
||||
'Object.getOwnPropertyNames',
|
||||
'Function.name',
|
||||
'Function.hasInstance',
|
||||
'Array.from',
|
||||
'Array.arrayOf',
|
||||
'Array.copyWithin',
|
||||
'Array.fill',
|
||||
'Array.find',
|
||||
'Array.findIndex',
|
||||
'Array.iterator',
|
||||
'String.fromCodePoint',
|
||||
'String.raw',
|
||||
'String.iterator',
|
||||
'String.codePointAt',
|
||||
'String.endsWith',
|
||||
'String.includes',
|
||||
'String.repeat',
|
||||
'String.startsWith',
|
||||
'String.trim',
|
||||
'String.anchor',
|
||||
'String.big',
|
||||
'String.blink',
|
||||
'String.bold',
|
||||
'String.fixed',
|
||||
'String.fontcolor',
|
||||
'String.fontsize',
|
||||
'String.italics',
|
||||
'String.link',
|
||||
'String.small',
|
||||
'String.strike',
|
||||
'String.sub',
|
||||
'String.sup',
|
||||
'RegExp',
|
||||
'Number',
|
||||
'Math',
|
||||
'Date',
|
||||
'async',
|
||||
'Symbol',
|
||||
'Map',
|
||||
'Set',
|
||||
'WeakMap',
|
||||
'WeakSet',
|
||||
'ArrayBuffer',
|
||||
'DataView',
|
||||
'Int8Array',
|
||||
'Uint8Array',
|
||||
'Uint8ClampedArray',
|
||||
'Int16Array',
|
||||
'Uint16Array',
|
||||
'Int32Array',
|
||||
'Uint32Array',
|
||||
'Float32Array',
|
||||
'Float64Array',
|
||||
'Reflect',
|
||||
// Temporary while eslint-compat-plugin is buggy
|
||||
'document.querySelector'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
files: [
|
||||
'./src/**/*.ts',
|
||||
'./src/**/*.tsx'
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:eslint-comments/recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:jsx-a11y/recommended'
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
4
.github/CODEOWNERS
vendored
@@ -1,6 +1,4 @@
|
||||
.ci @dkanada @EraYaN
|
||||
.github @jellyfin/core
|
||||
fedora @joshuaboniface
|
||||
debian @joshuaboniface
|
||||
.copr @joshuaboniface
|
||||
build.sh @joshuaboniface
|
||||
deployment @joshuaboniface
|
||||
|
||||
22
.github/ISSUE_TEMPLATE/2-playback-issue.md
vendored
@@ -1,22 +0,0 @@
|
||||
---
|
||||
name: Playback Issue
|
||||
about: You have playback issues with some files
|
||||
labels: playback
|
||||
---
|
||||
|
||||
**Describe The Bug**
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**Media Information**
|
||||
<!-- Please paste any ffprobe or MediaInfo logs. -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- Add screenshots from the Playback Data and Media Info. -->
|
||||
|
||||
**System (please complete the following information):**
|
||||
- Platform: [e.g. Linux, Windows, iPhone, Tizen]
|
||||
- Browser: [e.g. Firefox, Chrome, Safari]
|
||||
- Jellyfin Version: [e.g. 10.6.0]
|
||||
|
||||
**Additional Context**
|
||||
<!-- Add any other context about the problem here. -->
|
||||
13
.github/ISSUE_TEMPLATE/3-technical-discussion.md
vendored
@@ -1,13 +0,0 @@
|
||||
---
|
||||
name: Technical Discussion
|
||||
about: You want to discuss technical aspects of changes you intend to make
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
<!-- Explain the change and the motivations behind it.
|
||||
|
||||
For example, if you plan to rely on a new dependency, explain why and what
|
||||
it brings to the project.
|
||||
|
||||
If you plan to make significant changes, go roughly over the steps you intend
|
||||
to take and how you would divide the change in PRs of a manageable size. -->
|
||||
9
.github/ISSUE_TEMPLATE/4-meta-issue.md
vendored
@@ -1,9 +0,0 @@
|
||||
---
|
||||
name: Meta Issue
|
||||
about: You want to track a number of other issues as part of a larger project
|
||||
labels: meta
|
||||
---
|
||||
|
||||
* [ ] Issue 1 [#123]
|
||||
* [ ] Issue 2 [#456]
|
||||
* [ ] ...
|
||||
@@ -1,20 +1,23 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: You have noticed a general issue or regression, and would like to report it
|
||||
name: Bug report
|
||||
about: Create a bug report
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe The Bug**
|
||||
**Describe the bug**
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**Steps To Reproduce**
|
||||
**To Reproduce**
|
||||
<!-- Steps to reproduce the behavior: -->
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected Behavior**
|
||||
**Expected behavior**
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
**Logs**
|
||||
@@ -24,9 +27,9 @@ labels: bug
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
|
||||
**System (please complete the following information):**
|
||||
- Platform: [e.g. Linux, Windows, iPhone, Tizen]
|
||||
- OS: [e.g. Docker, Debian, Windows]
|
||||
- Browser: [e.g. Firefox, Chrome, Safari]
|
||||
- Jellyfin Version: [e.g. 10.6.0]
|
||||
- Jellyfin Version: [e.g. 10.0.1]
|
||||
|
||||
**Additional Context**
|
||||
**Additional context**
|
||||
<!-- Add any other context about the problem here. -->
|
||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Feature Request
|
||||
url: https://features.jellyfin.org/
|
||||
about: Please head over to our feature request hub to vote on or submit a feature.
|
||||
- name: Help Or Question
|
||||
url: https://matrix.to/#/#jellyfin-troubleshooting:matrix.org
|
||||
about: Please join the troubleshooting Matrix channel to get some help.
|
||||
24
.github/SUPPORT.md
vendored
@@ -1,24 +0,0 @@
|
||||
# Support
|
||||
|
||||
Jellyfin contributors have limited availability to address general support
|
||||
questions. Please make sure you are using the latest version of Jellyfin.
|
||||
|
||||
When looking for support or information, please first search for your
|
||||
question in these venues:
|
||||
|
||||
* [Jellyfin Forum](https://forum.jellyfin.org)
|
||||
* [Jellyfin Documentation](https://docs.jellyfin.org)
|
||||
* [Open or **closed** issues in the organization](https://github.com/issues?q=sort%3Aupdated-desc+org%3Ajellyfin+is%3Aissue+)
|
||||
|
||||
If you didn't find an answer in the resources above, contributors and other
|
||||
users are reachable through the following channels:
|
||||
|
||||
* #jellyfin on [Matrix](https://matrix.to/#/#jellyfin:matrix.org%22) or [IRC](ircs://irc.libera.chat:6697/#jellyfin)
|
||||
* #jellyfin-troubleshooting on [Matrix](https://matrix.to/#/#jellyfin-troubleshooting:matrix.org) or [IRC](ircs://irc.libera.chat:6697/#jellyfin-troubleshooting)
|
||||
* [/r/jellyfin on Reddit](https://www.reddit.com/r/jellyfin)
|
||||
|
||||
GitHub issues are for tracking enhancements and bugs, not general support.
|
||||
|
||||
The open source license grants you the freedom to use Jellyfin.
|
||||
It does not guarantee commitments of other people's time.
|
||||
Please be respectful and manage your expectations.
|
||||
51
.github/renovate.json
vendored
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"packageRules": [
|
||||
{
|
||||
"matchManagers": ["npm"],
|
||||
"addLabels": ["javascript"]
|
||||
},
|
||||
{
|
||||
"description": "Adds label to dev dependency updates",
|
||||
"matchDepTypes": ["devDependencies"],
|
||||
"addLabels": ["dev-deps"]
|
||||
},
|
||||
{
|
||||
"description": "Collects and groups dev dependency updates",
|
||||
"matchDepTypes": ["devDependencies"],
|
||||
"groupName": "development dependencies",
|
||||
"groupSlug": "dev-deps"
|
||||
},
|
||||
{
|
||||
"description": "Collects and groups npm dependency updates",
|
||||
"matchDepTypes": ["dependencies"],
|
||||
"groupName": "dependencies",
|
||||
"groupSlug": "deps"
|
||||
},
|
||||
{
|
||||
"description": "Collects and groups GitHub Action dependency updates",
|
||||
"matchDepTypes": ["action"],
|
||||
"addLabels": ["github_actions"],
|
||||
"groupName": "CI dependencies",
|
||||
"groupSlug": "ci-deps"
|
||||
},
|
||||
{
|
||||
"description": "Disables HLS.js major updates",
|
||||
"matchPackageNames": ["hls.js"],
|
||||
"matchUpdateTypes": "major",
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"vulnerabilityAlerts": {
|
||||
"addLabels": ["security"]
|
||||
},
|
||||
"dependencyDashboard": false,
|
||||
"ignoreDeps": ["npm", "node"],
|
||||
"lockFileMaintenance": {
|
||||
"enabled": false
|
||||
},
|
||||
"enabledManagers": ["npm", "github-actions"],
|
||||
"labels": ["dependencies"],
|
||||
"prHourlyLimit": 2,
|
||||
"rebaseWhen": "conflicted",
|
||||
"rangeStrategy": "pin"
|
||||
}
|
||||
20
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 90
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 14
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- regression
|
||||
- future
|
||||
- feature
|
||||
- enhancement
|
||||
- confirmed
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
Issues go stale after 90d of inactivity. Mark the issue as fresh by adding a comment or commit. Stale issues close after an additional 14d of inactivity.
|
||||
If this issue is safe to close now please do so.
|
||||
If you have any questions you can reach us on [Matrix or Social Media](https://docs.jellyfin.org/general/getting-help.html).
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
20
.github/workflows/automation.yml
vendored
@@ -1,20 +0,0 @@
|
||||
name: 'Automation'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request_target:
|
||||
types:
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
name: 'Merge conflict labeling'
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'jellyfin/jellyfin-web' }}
|
||||
steps:
|
||||
- uses: eps1lon/actions-label-merge-conflict@v2.0.1
|
||||
with:
|
||||
dirtyLabel: 'merge conflict'
|
||||
repoToken: ${{ secrets.JF_BOT_TOKEN }}
|
||||
31
.github/workflows/codeql-analysis.yml
vendored
@@ -1,31 +0,0 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '30 7 * * 6'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-extended
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
28
.github/workflows/commands.yml
vendored
@@ -1,28 +0,0 @@
|
||||
name: Commands
|
||||
on:
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
- edited
|
||||
|
||||
jobs:
|
||||
rebase:
|
||||
name: Rebase
|
||||
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '@jellyfin-bot rebase') && github.event.comment.author_association == 'MEMBER'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Notify as seen
|
||||
uses: peter-evans/create-or-update-comment@v1.4.5
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
comment-id: ${{ github.event.comment.id }}
|
||||
reactions: '+1'
|
||||
- name: Checkout the latest code
|
||||
uses: actions/checkout@v3.0.0
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
- name: Automatic Rebase
|
||||
uses: cirrus-actions/rebase@1.5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
|
||||
119
.github/workflows/lint.yml
vendored
@@ -1,119 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, release* ]
|
||||
pull_request:
|
||||
branches: [ master, release* ]
|
||||
|
||||
jobs:
|
||||
run-eslint:
|
||||
name: Run eslint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node environment
|
||||
uses: actions/setup-node@v3.0.0
|
||||
with:
|
||||
node-version: 12
|
||||
check-latest: true
|
||||
|
||||
- name: Get npm cache directory path
|
||||
id: npm-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3.0.0
|
||||
id: npm-cache
|
||||
with:
|
||||
path: ${{ steps.npm-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-npm-
|
||||
|
||||
- name: Install Node.js dependencies
|
||||
run: npm ci --no-audit
|
||||
env:
|
||||
SKIP_PREPARE: true
|
||||
|
||||
- name: Run eslint
|
||||
run: npm run lint
|
||||
|
||||
run-stylelint-css:
|
||||
name: Run stylelint (css)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node environment
|
||||
uses: actions/setup-node@v3.0.0
|
||||
with:
|
||||
node-version: 12
|
||||
check-latest: true
|
||||
|
||||
- name: Get npm cache directory path
|
||||
id: npm-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3.0.0
|
||||
id: npm-cache
|
||||
with:
|
||||
path: ${{ steps.npm-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-npm-
|
||||
|
||||
- name: Set up stylelint matcher
|
||||
uses: xt0rted/stylelint-problem-matcher@v1
|
||||
|
||||
- name: Install Node.js dependencies
|
||||
run: npm ci --no-audit
|
||||
env:
|
||||
SKIP_PREPARE: true
|
||||
|
||||
- name: Run stylelint
|
||||
run: npm run stylelint:css
|
||||
|
||||
run-stylelint-scss:
|
||||
name: Run stylelint (scss)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup node environment
|
||||
uses: actions/setup-node@v3.0.0
|
||||
with:
|
||||
node-version: 12
|
||||
check-latest: true
|
||||
|
||||
- name: Get npm cache directory path
|
||||
id: npm-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v3.0.0
|
||||
id: npm-cache
|
||||
with:
|
||||
path: ${{ steps.npm-cache-dir-path.outputs.dir }}
|
||||
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-npm-
|
||||
|
||||
- name: Set up stylelint matcher
|
||||
uses: xt0rted/stylelint-problem-matcher@v1
|
||||
|
||||
- name: Install Node.js dependencies
|
||||
run: npm ci --no-audit
|
||||
env:
|
||||
SKIP_PREPARE: true
|
||||
|
||||
- name: Run stylelint
|
||||
run: npm run stylelint:scss
|
||||
27
.github/workflows/repo-stale.yaml
vendored
@@ -1,27 +0,0 @@
|
||||
name: Issue Stale Check
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ contains(github.repository, 'jellyfin/') }}
|
||||
steps:
|
||||
- uses: actions/stale@v5.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
days-before-stale: 120
|
||||
days-before-pr-stale: -1
|
||||
days-before-close: 21
|
||||
days-before-pr-close: -1
|
||||
exempt-issue-labels: regression,security,roadmap,future,feature,enhancement,confirmed
|
||||
stale-issue-label: stale
|
||||
stale-issue-message: |-
|
||||
This issue has gone 120 days without comment. To avoid abandoned issues, it will be closed in 21 days if there are no new comments.
|
||||
|
||||
If you're the original submitter of this issue, please comment confirming if this issue still affects you in the latest release or master branch, or close the issue if it has been fixed. If you're another user also affected by this bug, please comment confirming so. Either action will remove the stale label.
|
||||
|
||||
This bot exists to prevent issues from becoming stale and forgotten. Jellyfin is always moving forward, and bugs are often fixed as side effects of other changes. We therefore ask that bug report authors remain vigilant about their issues to ensure they are closed if fixed, or re-confirmed - perhaps with fresh logs or reproduction examples - regularly. If you have any questions you can reach us on [Matrix or Social Media](https://docs.jellyfin.org/general/getting-help.html).
|
||||
10
.gitignore
vendored
@@ -3,19 +3,9 @@ dist
|
||||
web
|
||||
node_modules
|
||||
|
||||
# config
|
||||
config.json
|
||||
|
||||
# ide
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# log
|
||||
yarn-error.log
|
||||
|
||||
# vim
|
||||
*.sw?
|
||||
|
||||
# build artifacts
|
||||
fedora/jellyfin-web-*.src.rpm
|
||||
fedora/jellyfin-web-*.tar.gz
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"plugins": [
|
||||
"stylelint-no-browser-hacks/lib"
|
||||
"stylelint-no-browser-hacks/lib",
|
||||
],
|
||||
"rules": {
|
||||
"at-rule-empty-line-before": [ "always", {
|
||||
"except": [
|
||||
except: [
|
||||
"blockless-after-same-name-blockless",
|
||||
"first-nested"
|
||||
"first-nested",
|
||||
],
|
||||
"ignore": ["after-comment"]
|
||||
ignore: ["after-comment"],
|
||||
} ],
|
||||
"at-rule-name-case": "lower",
|
||||
"at-rule-name-space-after": "always-single-line",
|
||||
@@ -26,27 +26,27 @@
|
||||
"color-hex-length": "short",
|
||||
"color-no-invalid-hex": true,
|
||||
"comment-empty-line-before": [ "always", {
|
||||
"except": ["first-nested"],
|
||||
"ignore": ["stylelint-commands"]
|
||||
except: ["first-nested"],
|
||||
ignore: ["stylelint-commands"],
|
||||
} ],
|
||||
"comment-no-empty": true,
|
||||
"comment-whitespace-inside": "always",
|
||||
"custom-property-empty-line-before": [ "always", {
|
||||
"except": [
|
||||
except: [
|
||||
"after-custom-property",
|
||||
"first-nested"
|
||||
"first-nested",
|
||||
],
|
||||
"ignore": [
|
||||
ignore: [
|
||||
"after-comment",
|
||||
"inside-single-line-block"
|
||||
]
|
||||
"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"]
|
||||
ignore: ["consecutive-duplicates-with-different-values"]
|
||||
}
|
||||
],
|
||||
"declaration-block-no-shorthand-property-overrides": true,
|
||||
@@ -59,6 +59,7 @@
|
||||
"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",
|
||||
@@ -104,8 +105,8 @@
|
||||
}
|
||||
],
|
||||
"rule-empty-line-before": [ "always-multi-line", {
|
||||
"except": ["first-nested"],
|
||||
"ignore": ["after-comment"]
|
||||
except: ["first-nested"],
|
||||
ignore: ["after-comment"],
|
||||
} ],
|
||||
"selector-attribute-brackets-space-inside": "never",
|
||||
"selector-attribute-operator-space-after": "never",
|
||||
@@ -137,6 +138,6 @@
|
||||
"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
|
||||
"value-list-max-empty-lines": 0,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"extends": [ "./.stylelintrc.json" ],
|
||||
"customSyntax": "postcss-scss",
|
||||
"plugins": [ "stylelint-scss" ],
|
||||
"rules": {
|
||||
"at-rule-no-unknown": null,
|
||||
"scss/at-rule-no-unknown": true,
|
||||
"plugin/no-browser-hacks": null
|
||||
}
|
||||
}
|
||||
@@ -34,25 +34,8 @@
|
||||
- [Ryan Hartzell](https://github.com/ryan-hartzell)
|
||||
- [Thibault Nocchi](https://github.com/ThibaultNocchi)
|
||||
- [MrTimscampi](https://github.com/MrTimscampi)
|
||||
- [artiume](https://github.com/Artiume)
|
||||
- [ConfusedPolarBear](https://github.com/ConfusedPolarBear)
|
||||
- [Sarab Singh](https://github.com/sarab97)
|
||||
- [DesertCookie](https://github.com/desertcookie)
|
||||
- [GuilhermeHideki](https://github.com/GuilhermeHideki)
|
||||
- [Andrei Oanca](https://github.com/OancaAndrei)
|
||||
- [Cromefire_](https://github.com/cromefire)
|
||||
- [Orry Verducci](https://github.com/orryverducci)
|
||||
- [Camc314](https://github.com/camc314)
|
||||
- [danieladov](https://github.com/danieladov)
|
||||
- [Stephane Senart](https://github.com/ssenart)
|
||||
- [imchasingshadows](https://github.com/imchasingshadows)
|
||||
- [Ömer Erdinç Yağmurlu](https://github.com/omeryagmurlu)
|
||||
- [Keegan Dahm](https://github.com/keegandahm)
|
||||
- [GodTamIt](https://github.com/GodTamIt)
|
||||
- [MinecraftPlaye](https://github.com/MinecraftPlaye)
|
||||
- [Matthew Jones](https://github.com/matthew-jones-uk)
|
||||
- [taku0](https://github.com/taku0)
|
||||
- [Peter Spenler](https://github.com/peterspenler)
|
||||
|
||||
# Emby Contributors
|
||||
|
||||
@@ -116,6 +99,3 @@
|
||||
- [tikuf](https://github.com/tikuf/)
|
||||
- [Tim Hobbs](https://github.com/timhobbs)
|
||||
- [SvenVandenbrande](https://github.com/SvenVandenbrande)
|
||||
- [jomp16](https://github.com/jomp16)
|
||||
- [Leon de Klerk](https://github.com/leondeklerk)
|
||||
- [CrispyBaguette](https://github.com/CrispyBaguette)
|
||||
21
README.md
@@ -23,6 +23,9 @@
|
||||
<a href="https://features.jellyfin.org">
|
||||
<img alt="Feature Requests" src="https://img.shields.io/badge/fider-vote%20on%20features-success.svg"/>
|
||||
</a>
|
||||
<a href="https://forum.jellyfin.org">
|
||||
<img alt="Discuss on our Forum" src="https://img.shields.io/discourse/https/forum.jellyfin.org/users.svg"/>
|
||||
</a>
|
||||
<a href="https://matrix.to/#/+jellyfin:matrix.org">
|
||||
<img alt="Chat on Matrix" src="https://img.shields.io/matrix/jellyfin:matrix.org.svg?logo=matrix"/>
|
||||
</a>
|
||||
@@ -41,8 +44,8 @@ Jellyfin Web is the frontend used for most of the clients available for end user
|
||||
|
||||
### Dependencies
|
||||
|
||||
- [Node.js](https://nodejs.org/en/download)
|
||||
- npm (included in Node.js)
|
||||
- [Yarn 1.22.4](https://classic.yarnpkg.com/en/docs/install)
|
||||
- Gulp-cli
|
||||
|
||||
### Getting Started
|
||||
|
||||
@@ -56,17 +59,23 @@ Jellyfin Web is the frontend used for most of the clients available for end user
|
||||
2. Install build dependencies in the project directory.
|
||||
|
||||
```sh
|
||||
npm install
|
||||
yarn install
|
||||
```
|
||||
|
||||
3. Run the web client with webpack for local development.
|
||||
|
||||
```sh
|
||||
npm start
|
||||
yarn serve
|
||||
```
|
||||
|
||||
4. Build the client with sourcemaps available.
|
||||
4. Build the client with sourcemaps.
|
||||
|
||||
```sh
|
||||
npm run build:development
|
||||
yarn build:development
|
||||
```
|
||||
|
||||
You can build a nginx compatible version as well.
|
||||
|
||||
```sh
|
||||
yarn build:standalone
|
||||
```
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
module.exports = {
|
||||
babelrcRoots: [
|
||||
// Keep the root as a root
|
||||
'.'
|
||||
],
|
||||
sourceType: 'unambiguous',
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
useBuiltIns: 'usage',
|
||||
corejs: 3
|
||||
}
|
||||
],
|
||||
'@babel/preset-react',
|
||||
[
|
||||
'@babel/preset-typescript',
|
||||
{
|
||||
isTSX: true,
|
||||
allExtensions: true
|
||||
}
|
||||
]
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
'@babel/plugin-proposal-private-methods',
|
||||
'babel-plugin-dynamic-import-polyfill'
|
||||
]
|
||||
};
|
||||
2
build.sh
@@ -39,7 +39,7 @@ do_build_native() {
|
||||
}
|
||||
|
||||
do_build_docker() {
|
||||
if ! [ $(uname -m) = "x86_64" ]; then
|
||||
if ! dpkg --print-architecture | grep -q 'amd64'; then
|
||||
echo "Docker-based builds only support amd64-based cross-building; use a 'native' build instead."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
# We just wrap `build` so this is really it
|
||||
name: "jellyfin-web"
|
||||
version: "10.8.13"
|
||||
version: "10.6.4"
|
||||
packages:
|
||||
- debian.all
|
||||
- fedora.all
|
||||
|
||||
37
bump_version
@@ -18,39 +18,38 @@ if [[ -z $1 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shared_version_file="src/components/apphost.js"
|
||||
build_file="./build.yaml"
|
||||
package_file="./package*.json"
|
||||
|
||||
new_version="$1"
|
||||
|
||||
old_version="$(
|
||||
grep "version:" ${build_file} \
|
||||
| sed -E 's/version: "([0-9\.]+[-a-z0-9]*)"/\1/'
|
||||
)"
|
||||
echo "Old version: ${old_version}"
|
||||
# Parse the version from shared version file
|
||||
old_version="$( grep "appVersion" ${shared_version_file} | head -1 | sed -E "s/var appVersion = '([0-9\.]+)';/\1/" | tr -d '[:space:]' )"
|
||||
echo "Old version in appHost is: $old_version"
|
||||
|
||||
# Bump the NPM version
|
||||
# Set the shared version to the specified new_version
|
||||
old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars
|
||||
new_version_sed="$( cut -f1 -d'-' <<<"${new_version}" )"
|
||||
npm --no-git-tag-version --allow-same-version version v${new_version_sed}
|
||||
sed -i "s/${old_version_sed}/${new_version_sed}/g" ${shared_version_file}
|
||||
|
||||
old_version="$( grep "version:" ${build_file} | sed -E 's/version: "([0-9\.]+[-a-z0-9]*)"/\1/' )"
|
||||
echo "Old version in ${build_file}: ${old_version}"
|
||||
|
||||
# Set the build.yaml version to the specified new_version
|
||||
old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars
|
||||
sed -i "s/${old_version_sed}/${new_version_sed}/g" ${build_file}
|
||||
|
||||
sed -i "s/${old_version_sed}/${new_version}/g" ${build_file}
|
||||
|
||||
if [[ ${new_version} == *"-"* ]]; then
|
||||
new_version_pkg="$( sed 's/-/~/g' <<<"${new_version}" )"
|
||||
new_version_deb_sup=""
|
||||
new_version_deb="$( sed 's/-/~/g' <<<"${new_version}" )"
|
||||
else
|
||||
new_version_pkg="${new_version}"
|
||||
new_version_deb_sup="-1"
|
||||
new_version_deb="${new_version}-1"
|
||||
fi
|
||||
|
||||
# Write out a temporary Debian changelog with our new stuff appended and some templated formatting
|
||||
debian_changelog_file="debian/changelog"
|
||||
debian_changelog_temp="$( mktemp )"
|
||||
# Create new temp file with our changelog
|
||||
echo -e "jellyfin-web (${new_version_pkg}${new_version_deb_sup}) unstable; urgency=medium
|
||||
echo -e "jellyfin-web (${new_version_deb}) unstable; urgency=medium
|
||||
|
||||
* New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v${new_version}
|
||||
|
||||
@@ -71,7 +70,7 @@ pushd ${fedora_spec_temp_dir}
|
||||
# Split out the stuff before and after changelog
|
||||
csplit jellyfin-web.spec "/^%changelog/" # produces xx00 xx01
|
||||
# Update the version in xx00
|
||||
sed -i "s/${old_version_sed}/${new_version_pkg}/g" xx00
|
||||
sed -i "s/${old_version_sed}/${new_version_sed}/g" xx00
|
||||
# Remove the header from xx01
|
||||
sed -i '/^%changelog/d' xx01
|
||||
# Create new temp file with our changelog
|
||||
@@ -85,8 +84,8 @@ popd
|
||||
# Move into place
|
||||
mv ${fedora_spec_temp} ${fedora_spec_file}
|
||||
# Clean up
|
||||
rm -rf ${fedora_spec_temp_dir}
|
||||
rm -rf ${fedora_changelog_temp} ${fedora_spec_temp_dir}
|
||||
|
||||
# Stage the changed files for commit
|
||||
git add .
|
||||
git status -v
|
||||
git add ${shared_version_file} ${build_file} ${debian_changelog_file} ${fedora_spec_file}
|
||||
git status
|
||||
|
||||
90
debian/changelog
vendored
@@ -1,92 +1,26 @@
|
||||
jellyfin-web (10.8.13-1) unstable; urgency=medium
|
||||
jellyfin-web (10.6.4-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.13; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.13
|
||||
* New upstream version 10.6.4; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.4
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Tue, 28 Nov 2023 22:21:29 -0500
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 30 Aug 2020 16:45:08 -0400
|
||||
|
||||
jellyfin-web (10.8.12-1) unstable; urgency=medium
|
||||
jellyfin-web (10.6.3-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.12; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.12
|
||||
* New upstream version 10.6.3; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.3
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 04 Nov 2023 14:42:41 -0400
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 16 Aug 2020 19:48:03 -0400
|
||||
|
||||
jellyfin-web (10.8.11-1) unstable; urgency=medium
|
||||
jellyfin-web (10.6.2-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.11; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.11
|
||||
* New upstream version 10.6.2; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.2
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 23 Sep 2023 21:41:40 -0400
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 02 Aug 2020 20:25:58 -0400
|
||||
|
||||
jellyfin-web (10.8.10-1) unstable; urgency=medium
|
||||
jellyfin-web (10.6.1-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.10; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.10
|
||||
* New upstream version 10.6.1; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.1
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 23 Apr 2023 11:01:33 -0400
|
||||
|
||||
jellyfin-web (10.8.9-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.9; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.9
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 22 Jan 2023 14:09:13 -0500
|
||||
|
||||
jellyfin-web (10.8.8-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.8; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.8
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Tue, 29 Nov 2022 13:42:54 -0500
|
||||
|
||||
jellyfin-web (10.8.7-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.7; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.7
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Mon, 31 Oct 2022 23:06:34 -0400
|
||||
|
||||
jellyfin-web (10.8.6-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.6; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.6
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Fri, 28 Oct 2022 22:44:15 -0400
|
||||
|
||||
jellyfin-web (10.8.5-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.5; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.5
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 24 Sep 2022 22:02:26 -0400
|
||||
|
||||
jellyfin-web (10.8.4-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.4; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.4
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 13 Aug 2022 21:52:04 -0400
|
||||
|
||||
jellyfin-web (10.8.3-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.3; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.3
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Mon, 01 Aug 2022 20:22:00 -0400
|
||||
|
||||
jellyfin-web (10.8.2-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.2; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.2
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Mon, 01 Aug 2022 14:27:56 -0400
|
||||
|
||||
jellyfin-web (10.8.1-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.1; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.1
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sun, 26 Jun 2022 20:59:39 -0400
|
||||
|
||||
jellyfin-web (10.8.0-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.8.0; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.0
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Fri, 10 Jun 2022 22:16:40 -0400
|
||||
|
||||
jellyfin-web (10.7.0-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.7.0; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.7.0
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Mon, 27 Jul 2020 19:13:31 -0400
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Mon, 27 Jul 2020 18:29:54 -0400
|
||||
|
||||
jellyfin-web (10.6.0-1) unstable; urgency=medium
|
||||
|
||||
|
||||
1
debian/conffiles
vendored
@@ -1 +0,0 @@
|
||||
/usr/share/jellyfin/web/config.json
|
||||
2
debian/rules
vendored
@@ -11,7 +11,7 @@ override_dh_auto_test:
|
||||
override_dh_clistrip:
|
||||
|
||||
override_dh_auto_build:
|
||||
npm ci --no-audit --unsafe-perm
|
||||
npx yarn install
|
||||
mv $(CURDIR)/dist $(CURDIR)/web
|
||||
|
||||
override_dh_auto_clean:
|
||||
|
||||
@@ -12,9 +12,12 @@ ENV IS_DOCKER=YES
|
||||
# Prepare CentOS environment
|
||||
RUN yum update -y \
|
||||
&& yum install -y epel-release \
|
||||
&& yum install -y @buildsys-build rpmdevtools git yum-plugins-core autoconf automake glibc-devel gcc-c++ make \
|
||||
&& curl -fsSL https://rpm.nodesource.com/setup_12.x | bash - \
|
||||
&& yum install -y nodejs
|
||||
&& yum install -y @buildsys-build rpmdevtools git yum-plugins-core nodejs-yarn autoconf automake glibc-devel
|
||||
|
||||
# Install recent NodeJS and Yarn
|
||||
RUN curl -fSsLo /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo \
|
||||
&& rpm -i https://rpm.nodesource.com/pub_10.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm \
|
||||
&& yum install -y yarn
|
||||
|
||||
# Link to build script
|
||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.centos /build.sh
|
||||
|
||||
@@ -12,10 +12,10 @@ ENV IS_DOCKER=YES
|
||||
|
||||
# Prepare Debian build environment
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y debhelper mmv git curl \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_12.x | bash - \
|
||||
&& apt-get install -y nodejs
|
||||
&& apt-get install -y debhelper mmv npm git
|
||||
|
||||
# Prepare Yarn
|
||||
RUN npm install -g yarn
|
||||
|
||||
# Link to build script
|
||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian /build.sh
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FROM node:lts-alpine
|
||||
FROM node:alpine
|
||||
|
||||
ARG SOURCE_DIR=/src
|
||||
ARG ARTIFACT_DIR=/jellyfin-web
|
||||
|
||||
RUN apk add autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3
|
||||
RUN apk add autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python
|
||||
|
||||
WORKDIR ${SOURCE_DIR}
|
||||
COPY . .
|
||||
|
||||
RUN npm ci --no-audit --unsafe-perm && mv dist ${ARTIFACT_DIR}
|
||||
RUN yarn install && mv dist ${ARTIFACT_DIR}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM fedora:36
|
||||
FROM fedora:31
|
||||
|
||||
# Docker build arguments
|
||||
ARG SOURCE_DIR=/jellyfin
|
||||
@@ -11,7 +11,7 @@ ENV IS_DOCKER=YES
|
||||
|
||||
# Prepare Fedora environment
|
||||
RUN dnf update -y \
|
||||
&& dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core nodejs autoconf automake glibc-devel make
|
||||
&& dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core nodejs-yarn autoconf automake glibc-devel
|
||||
|
||||
# Link to build script
|
||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.fedora /build.sh
|
||||
|
||||
@@ -11,9 +11,10 @@ ENV IS_DOCKER=YES
|
||||
|
||||
# Prepare Debian build environment
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y mmv curl git \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_12.x | bash - \
|
||||
&& apt-get install -y nodejs
|
||||
&& apt-get install -y mmv npm git
|
||||
|
||||
# Prepare Yarn
|
||||
RUN npm install -g yarn
|
||||
|
||||
# Link to build script
|
||||
RUN ln -sf ${SOURCE_DIR}/deployment/build.portable /build.sh
|
||||
|
||||
@@ -6,7 +6,7 @@ set -o xtrace
|
||||
# move to source directory
|
||||
pushd ${SOURCE_DIR}
|
||||
|
||||
cp -a package-lock.json /tmp/package-lock.json
|
||||
cp -a yarn.lock /tmp/yarn.lock
|
||||
|
||||
# modify changelog to unstable configuration if IS_UNSTABLE
|
||||
if [[ ${IS_UNSTABLE} == 'yes' ]]; then
|
||||
@@ -36,6 +36,6 @@ if [[ ${IS_DOCKER} == YES ]]; then
|
||||
fi
|
||||
|
||||
rm -f fedora/jellyfin*.tar.gz
|
||||
cp -a /tmp/package-lock.json package-lock.json
|
||||
cp -a /tmp/yarn.lock yarn.lock
|
||||
|
||||
popd
|
||||
|
||||
@@ -6,7 +6,7 @@ set -o xtrace
|
||||
# move to source directory
|
||||
pushd ${SOURCE_DIR}
|
||||
|
||||
cp -a package-lock.json /tmp/package-lock.json
|
||||
cp -a yarn.lock /tmp/yarn.lock
|
||||
|
||||
# modify changelog to unstable configuration if IS_UNSTABLE
|
||||
if [[ ${IS_UNSTABLE} == 'yes' ]]; then
|
||||
@@ -30,7 +30,7 @@ dpkg-buildpackage -us -uc --pre-clean --post-clean
|
||||
mkdir -p ${ARTIFACT_DIR}
|
||||
mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} ${ARTIFACT_DIR}
|
||||
|
||||
cp -a /tmp/package-lock.json package-lock.json
|
||||
cp -a /tmp/yarn.lock yarn.lock
|
||||
|
||||
if [[ ${IS_DOCKER} == YES ]]; then
|
||||
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}
|
||||
|
||||
@@ -6,7 +6,7 @@ set -o xtrace
|
||||
# move to source directory
|
||||
pushd ${SOURCE_DIR}
|
||||
|
||||
cp -a package-lock.json /tmp/package-lock.json
|
||||
cp -a yarn.lock /tmp/yarn.lock
|
||||
|
||||
# modify changelog to unstable configuration if IS_UNSTABLE
|
||||
if [[ ${IS_UNSTABLE} == 'yes' ]]; then
|
||||
@@ -36,6 +36,6 @@ if [[ ${IS_DOCKER} == YES ]]; then
|
||||
fi
|
||||
|
||||
rm -f fedora/jellyfin*.tar.gz
|
||||
cp -a /tmp/package-lock.json package-lock.json
|
||||
cp -a /tmp/yarn.lock yarn.lock
|
||||
|
||||
popd
|
||||
|
||||
@@ -14,7 +14,7 @@ else
|
||||
fi
|
||||
|
||||
# build archives
|
||||
npm ci --no-audit --unsafe-perm
|
||||
npx yarn install
|
||||
mv dist jellyfin-web_${version}
|
||||
tar -czf jellyfin-web_${version}_portable.tar.gz jellyfin-web_${version}
|
||||
rm -rf dist
|
||||
|
||||
@@ -1,48 +1,21 @@
|
||||
DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
# install git and npm
|
||||
$(info $(shell set -x; if [ "$$(id -u)" = "0" ]; then echo "Installing git"; dnf -y install git npm; fi))
|
||||
NAME := jellyfin-web
|
||||
VERSION := $(shell set -x; sed -ne '/^Version:/s/.* *//p' $(DIR)/$(NAME).spec)
|
||||
RELEASE := $(shell set -x; sed -ne '/^Release:/s/.* *\(.*\)%{.*}.*/\1/p' $(DIR)/$(NAME).spec)
|
||||
SRPM := jellyfin-web-$(subst -,~,$(VERSION))-$(RELEASE)$(shell rpm --eval %dist).src.rpm
|
||||
TARBALL :=$(NAME)-$(subst -,~,$(VERSION)).tar.gz
|
||||
VERSION := $(shell sed -ne '/^Version:/s/.* *//p' fedora/jellyfin-web.spec)
|
||||
|
||||
epel-7-x86_64_repos := https://rpm.nodesource.com/pub_16.x/el/\$$releasever/\$$basearch/
|
||||
|
||||
fed_ver := $(shell rpm -E %fedora)
|
||||
# fallback when not running on Fedora
|
||||
fed_ver ?= 36
|
||||
TARGET ?= fedora-$(fed_ver)-x86_64
|
||||
|
||||
outdir ?= $(PWD)/$(DIR)/
|
||||
|
||||
srpm: $(DIR)/$(SRPM)
|
||||
tarball: $(DIR)/$(TARBALL)
|
||||
|
||||
$(DIR)/$(TARBALL):
|
||||
cd $(DIR)/; \
|
||||
SOURCE_DIR=.. \
|
||||
WORKDIR="$${PWD}"; \
|
||||
version=$(VERSION); \
|
||||
tar \
|
||||
--transform "s,^\.,$(NAME)-$(subst -,~,$(VERSION))," \
|
||||
--exclude='.git*' \
|
||||
--exclude='**/.git' \
|
||||
--exclude='**/.hg' \
|
||||
--exclude=deployment \
|
||||
--exclude='*.deb' \
|
||||
--exclude='*.rpm' \
|
||||
--exclude=$(notdir $@) \
|
||||
-czf $(notdir $@) \
|
||||
srpm:
|
||||
cd fedora/; \
|
||||
SOURCE_DIR=.. \
|
||||
WORKDIR="$${PWD}"; \
|
||||
tar \
|
||||
--transform "s,^\.,jellyfin-web-$(VERSION)," \
|
||||
--exclude='.git*' \
|
||||
--exclude='**/.git' \
|
||||
--exclude='**/.hg' \
|
||||
--exclude='deployment' \
|
||||
--exclude='*.deb' \
|
||||
--exclude='*.rpm' \
|
||||
--exclude='jellyfin-web-$(VERSION).tar.gz' \
|
||||
-czf "jellyfin-web-$(VERSION).tar.gz" \
|
||||
-C $${SOURCE_DIR} ./
|
||||
|
||||
$(DIR)/$(SRPM): $(DIR)/$(TARBALL) $(DIR)/jellyfin-web.spec
|
||||
cd $(DIR)/; \
|
||||
rpmbuild -bs $(NAME).spec \
|
||||
--define "_sourcedir $$PWD/" \
|
||||
cd fedora/; \
|
||||
rpmbuild -bs jellyfin-web.spec \
|
||||
--define "_sourcedir $$PWD/" \
|
||||
--define "_srcrpmdir $(outdir)"
|
||||
|
||||
rpms: $(DIR)/$(SRPM)
|
||||
mock $(addprefix --addrepo=, $($(TARGET)_repos)) \
|
||||
--enable-network \
|
||||
-r $(TARGET) $<
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
%global debug_package %{nil}
|
||||
|
||||
Name: jellyfin-web
|
||||
Version: 10.8.13
|
||||
Version: 10.6.4
|
||||
Release: 1%{?dist}
|
||||
Summary: The Free Software Media System web client
|
||||
License: GPLv2
|
||||
License: GPLv3
|
||||
URL: https://jellyfin.org
|
||||
# Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%%{version}.tar.gz`
|
||||
# Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz`
|
||||
Source0: jellyfin-web-%{version}.tar.gz
|
||||
|
||||
BuildArch: noarch
|
||||
%if 0%{?rhel} > 0 && 0%{?rhel} < 8
|
||||
BuildRequires: nodejs
|
||||
%if 0%{?centos}
|
||||
BuildRequires: yarn
|
||||
# sadly the yarn RPM at https://dl.yarnpkg.com/rpm/ uses git but doesn't Requires: it
|
||||
BuildRequires: git
|
||||
%else
|
||||
BuildRequires: git
|
||||
BuildRequires: npm
|
||||
BuildRequires: nodejs-yarn
|
||||
%endif
|
||||
BuildArch: noarch
|
||||
|
||||
# Disable Automatic Dependency Processing
|
||||
AutoReqProv: no
|
||||
|
||||
%description
|
||||
Jellyfin is a free software media system that puts you in control of managing and streaming your media.
|
||||
@@ -24,53 +28,26 @@ Jellyfin is a free software media system that puts you in control of managing an
|
||||
%prep
|
||||
%autosetup -n jellyfin-web-%{version} -b 0
|
||||
|
||||
%if 0%{?rhel} > 0 && 0%{?rhel} < 8
|
||||
# Required for CentOS build
|
||||
chown root:root -R .
|
||||
%endif
|
||||
|
||||
|
||||
%build
|
||||
npm ci --no-audit --unsafe-perm
|
||||
|
||||
|
||||
%install
|
||||
%{__mkdir} -p %{buildroot}%{_libdir}/jellyfin/jellyfin-web
|
||||
%{__cp} -r dist/* %{buildroot}%{_libdir}/jellyfin/jellyfin-web
|
||||
|
||||
yarn install
|
||||
%{__mkdir} -p %{buildroot}%{_datadir}
|
||||
mv dist %{buildroot}%{_datadir}/jellyfin-web
|
||||
%{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/jellyfin/LICENSE
|
||||
|
||||
%files
|
||||
%defattr(644,root,root,755)
|
||||
%{_libdir}/jellyfin/jellyfin-web
|
||||
%license LICENSE
|
||||
|
||||
%attr(755,root,root) %{_datadir}/jellyfin-web
|
||||
%{_datadir}/licenses/jellyfin/LICENSE
|
||||
|
||||
%changelog
|
||||
* Tue Nov 28 2023 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.13; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.13
|
||||
* Sat Nov 04 2023 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.12; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.12
|
||||
* Sat Sep 23 2023 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.11; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.11
|
||||
* Sun Apr 23 2023 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.10; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.10
|
||||
* Sun Jan 22 2023 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.9; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.9
|
||||
* Tue Nov 29 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.8; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.8
|
||||
* Mon Oct 31 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.7; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.7
|
||||
* Fri Oct 28 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.6; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.6
|
||||
* Sat Sep 24 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.5; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.5
|
||||
* Sat Aug 13 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.4; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.4
|
||||
* Mon Aug 01 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.3; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.3
|
||||
* Mon Aug 01 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.2; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.2
|
||||
* Sun Jun 26 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.1; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.1
|
||||
* Fri Jun 10 2022 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.8.0; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.0
|
||||
* Sun Aug 30 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.6.4; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.4
|
||||
* Sun Aug 16 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.6.3; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.3
|
||||
* Sun Aug 02 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.6.2; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.2
|
||||
* Mon Jul 27 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.6.1; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.1
|
||||
* Mon Mar 23 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- Forthcoming stable release
|
||||
|
||||
204
gulpfile.js
Normal file
@@ -0,0 +1,204 @@
|
||||
const { src, dest, series, parallel, watch } = require('gulp');
|
||||
const browserSync = require('browser-sync').create();
|
||||
const del = require('del');
|
||||
const babel = require('gulp-babel');
|
||||
const concat = require('gulp-concat');
|
||||
const terser = require('gulp-terser');
|
||||
const htmlmin = require('gulp-htmlmin');
|
||||
const imagemin = require('gulp-imagemin');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const mode = require('gulp-mode')({
|
||||
modes: ['development', 'production'],
|
||||
default: 'development',
|
||||
verbose: false
|
||||
});
|
||||
const stream = require('webpack-stream');
|
||||
const inject = require('gulp-inject');
|
||||
const postcss = require('gulp-postcss');
|
||||
const sass = require('gulp-sass');
|
||||
const gulpif = require('gulp-if');
|
||||
const lazypipe = require('lazypipe');
|
||||
|
||||
sass.compiler = require('node-sass');
|
||||
|
||||
let config;
|
||||
if (mode.production()) {
|
||||
config = require('./webpack.prod.js');
|
||||
} else {
|
||||
config = require('./webpack.dev.js');
|
||||
}
|
||||
|
||||
const options = {
|
||||
javascript: {
|
||||
query: ['src/**/*.js', '!src/bundle.js', '!src/standalone.js', '!src/scripts/apploader.js']
|
||||
},
|
||||
apploader: {
|
||||
query: ['src/standalone.js', 'src/scripts/apploader.js']
|
||||
},
|
||||
css: {
|
||||
query: ['src/**/*.css', 'src/**/*.scss']
|
||||
},
|
||||
html: {
|
||||
query: ['src/**/*.html', '!src/index.html']
|
||||
},
|
||||
images: {
|
||||
query: ['src/**/*.png', 'src/**/*.jpg', 'src/**/*.gif', 'src/**/*.svg']
|
||||
},
|
||||
copy: {
|
||||
query: ['src/**/*.json', 'src/**/*.ico', 'src/**/*.mp3']
|
||||
},
|
||||
injectBundle: {
|
||||
query: 'src/index.html'
|
||||
}
|
||||
};
|
||||
|
||||
function serve() {
|
||||
browserSync.init({
|
||||
server: {
|
||||
baseDir: './dist'
|
||||
},
|
||||
port: 8080
|
||||
});
|
||||
|
||||
const events = ['add', 'change'];
|
||||
|
||||
watch(options.javascript.query).on('all', function (event, path) {
|
||||
if (events.includes(event)) {
|
||||
javascript(path);
|
||||
}
|
||||
});
|
||||
|
||||
watch(options.apploader.query, apploader(true));
|
||||
|
||||
watch('src/bundle.js', webpack);
|
||||
|
||||
watch(options.css.query).on('all', function (event, path) {
|
||||
if (events.includes(event)) {
|
||||
css(path);
|
||||
}
|
||||
});
|
||||
|
||||
watch(options.html.query).on('all', function (event, path) {
|
||||
if (events.includes(event)) {
|
||||
html(path);
|
||||
}
|
||||
});
|
||||
|
||||
watch(options.images.query).on('all', function (event, path) {
|
||||
if (events.includes(event)) {
|
||||
images(path);
|
||||
}
|
||||
});
|
||||
|
||||
watch(options.copy.query).on('all', function (event, path) {
|
||||
if (events.includes(event)) {
|
||||
copy(path);
|
||||
}
|
||||
});
|
||||
|
||||
watch(options.injectBundle.query, injectBundle);
|
||||
}
|
||||
|
||||
function clean() {
|
||||
return del(['dist/']);
|
||||
}
|
||||
|
||||
const pipelineJavascript = lazypipe()
|
||||
.pipe(function () {
|
||||
return mode.development(sourcemaps.init({ loadMaps: true }));
|
||||
})
|
||||
.pipe(function () {
|
||||
return babel({
|
||||
presets: [
|
||||
['@babel/preset-env']
|
||||
]
|
||||
});
|
||||
})
|
||||
.pipe(function () {
|
||||
return terser({
|
||||
keep_fnames: true,
|
||||
mangle: false
|
||||
});
|
||||
})
|
||||
.pipe(function () {
|
||||
return mode.development(sourcemaps.write('.'));
|
||||
});
|
||||
|
||||
function javascript(query) {
|
||||
return src(typeof query !== 'function' ? query : options.javascript.query, { base: './src/' })
|
||||
.pipe(pipelineJavascript())
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function apploader(standalone) {
|
||||
function task() {
|
||||
return src(options.apploader.query, { base: './src/' })
|
||||
.pipe(gulpif(standalone, concat('scripts/apploader.js')))
|
||||
.pipe(pipelineJavascript())
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
task.displayName = 'apploader';
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
function webpack() {
|
||||
return stream(config)
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function css(query) {
|
||||
return src(typeof query !== 'function' ? query : options.css.query, { base: './src/' })
|
||||
.pipe(mode.development(sourcemaps.init({ loadMaps: true })))
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
.pipe(postcss())
|
||||
.pipe(mode.development(sourcemaps.write('.')))
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function html(query) {
|
||||
return src(typeof query !== 'function' ? query : options.html.query, { base: './src/' })
|
||||
.pipe(mode.production(htmlmin({ collapseWhitespace: true })))
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function images(query) {
|
||||
return src(typeof query !== 'function' ? query : options.images.query, { base: './src/' })
|
||||
.pipe(mode.production(imagemin()))
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function copy(query) {
|
||||
return src(typeof query !== 'function' ? query : options.copy.query, { base: './src/' })
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function injectBundle() {
|
||||
return src(options.injectBundle.query, { base: './src/' })
|
||||
.pipe(inject(
|
||||
src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), {
|
||||
relative: true,
|
||||
transform: function (filepath) {
|
||||
return `<script src="${filepath}" defer></script>`;
|
||||
}
|
||||
}
|
||||
))
|
||||
.pipe(dest('dist/'))
|
||||
.pipe(browserSync.stream());
|
||||
}
|
||||
|
||||
function build(standalone) {
|
||||
return series(clean, parallel(javascript, apploader(standalone), webpack, css, html, images, copy));
|
||||
}
|
||||
|
||||
exports.default = series(build(false), injectBundle);
|
||||
exports.standalone = series(build(true), injectBundle);
|
||||
exports.serve = series(exports.standalone, serve);
|
||||
15705
package-lock.json
generated
254
package.json
@@ -1,109 +1,150 @@
|
||||
{
|
||||
"name": "jellyfin-web",
|
||||
"version": "10.8.13",
|
||||
"version": "0.0.0",
|
||||
"description": "Web interface for Jellyfin",
|
||||
"repository": "https://github.com/jellyfin/jellyfin-web",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.17.7",
|
||||
"@babel/eslint-parser": "7.17.0",
|
||||
"@babel/eslint-plugin": "7.17.7",
|
||||
"@babel/plugin-proposal-class-properties": "7.16.7",
|
||||
"@babel/plugin-proposal-private-methods": "7.16.11",
|
||||
"@babel/plugin-transform-modules-umd": "7.16.7",
|
||||
"@babel/preset-env": "7.16.11",
|
||||
"@babel/preset-react": "7.16.7",
|
||||
"@babel/preset-typescript": "7.16.7",
|
||||
"@thornbill/jellyfin-sdk": "0.4.1",
|
||||
"@types/escape-html": "1.0.1",
|
||||
"@types/lodash-es": "4.17.6",
|
||||
"@types/react": "17.0.40",
|
||||
"@types/react-dom": "17.0.13",
|
||||
"@typescript-eslint/eslint-plugin": "5.15.0",
|
||||
"@typescript-eslint/parser": "5.15.0",
|
||||
"@uupaa/dynamic-import-polyfill": "1.0.2",
|
||||
"autoprefixer": "10.4.4",
|
||||
"babel-loader": "8.2.3",
|
||||
"babel-plugin-dynamic-import-polyfill": "1.0.0",
|
||||
"clean-webpack-plugin": "4.0.0",
|
||||
"confusing-browser-globals": "1.0.11",
|
||||
"copy-webpack-plugin": "10.2.4",
|
||||
"css-loader": "6.7.1",
|
||||
"cssnano": "5.1.4",
|
||||
"eslint": "8.11.0",
|
||||
"eslint-plugin-compat": "4.0.2",
|
||||
"eslint-plugin-eslint-comments": "3.2.0",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-jsx-a11y": "6.5.1",
|
||||
"eslint-plugin-promise": "6.0.0",
|
||||
"eslint-plugin-react": "7.29.4",
|
||||
"eslint-plugin-react-hooks": "4.3.0",
|
||||
"expose-loader": "3.1.0",
|
||||
"html-loader": "3.1.0",
|
||||
"html-webpack-plugin": "5.5.0",
|
||||
"postcss": "8.4.12",
|
||||
"postcss-loader": "6.2.1",
|
||||
"postcss-preset-env": "7.4.2",
|
||||
"postcss-scss": "4.0.3",
|
||||
"sass": "1.49.9",
|
||||
"sass-loader": "12.6.0",
|
||||
"source-map-loader": "3.0.1",
|
||||
"style-loader": "3.3.1",
|
||||
"stylelint": "14.6.0",
|
||||
"stylelint-config-rational-order": "0.1.2",
|
||||
"stylelint-no-browser-hacks": "1.2.1",
|
||||
"stylelint-order": "5.0.0",
|
||||
"stylelint-scss": "4.2.0",
|
||||
"ts-loader": "9.2.8",
|
||||
"typescript": "4.6.2",
|
||||
"webpack": "5.70.0",
|
||||
"webpack-cli": "4.9.2",
|
||||
"webpack-dev-server": "4.7.4",
|
||||
"webpack-merge": "5.8.0",
|
||||
"workbox-webpack-plugin": "6.5.1",
|
||||
"worker-loader": "3.0.8"
|
||||
"@babel/core": "^7.10.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.10.1",
|
||||
"@babel/plugin-proposal-private-methods": "^7.10.1",
|
||||
"@babel/plugin-transform-modules-amd": "^7.9.6",
|
||||
"@babel/polyfill": "^7.8.7",
|
||||
"@babel/preset-env": "^7.10.3",
|
||||
"autoprefixer": "^9.8.5",
|
||||
"babel-eslint": "^11.0.0-beta.2",
|
||||
"babel-loader": "^8.0.6",
|
||||
"browser-sync": "^2.26.7",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"css-loader": "^3.6.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"del": "^5.1.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-plugin-compat": "^3.5.1",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.21.2",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"file-loader": "^6.0.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-babel": "^8.0.0",
|
||||
"gulp-cli": "^2.3.0",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-htmlmin": "^5.0.1",
|
||||
"gulp-if": "^3.0.0",
|
||||
"gulp-imagemin": "^7.1.0",
|
||||
"gulp-inject": "^5.0.5",
|
||||
"gulp-mode": "^1.0.2",
|
||||
"gulp-postcss": "^8.0.0",
|
||||
"gulp-sass": "^4.0.2",
|
||||
"gulp-sourcemaps": "^2.6.5",
|
||||
"gulp-terser": "^1.2.0",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"lazypipe": "^1.0.2",
|
||||
"node-sass": "^4.13.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"style-loader": "^1.1.3",
|
||||
"stylelint": "^13.6.1",
|
||||
"stylelint-config-rational-order": "^0.1.2",
|
||||
"stylelint-no-browser-hacks": "^1.2.1",
|
||||
"stylelint-order": "^4.1.0",
|
||||
"webpack": "^4.41.5",
|
||||
"webpack-merge": "^4.2.2",
|
||||
"webpack-stream": "^5.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/noto-sans": "4.5.1",
|
||||
"@fontsource/noto-sans-hk": "4.5.2",
|
||||
"@fontsource/noto-sans-jp": "4.5.2",
|
||||
"@fontsource/noto-sans-kr": "4.5.2",
|
||||
"@fontsource/noto-sans-sc": "4.5.2",
|
||||
"@fontsource/noto-sans-tc": "4.5.2",
|
||||
"@jellyfin/libass-wasm": "4.1.1",
|
||||
"blurhash": "1.1.4",
|
||||
"alameda": "^1.4.0",
|
||||
"blurhash": "^1.1.3",
|
||||
"classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz",
|
||||
"classnames": "2.3.1",
|
||||
"core-js": "3.20.2",
|
||||
"date-fns": "2.28.0",
|
||||
"dompurify": "2.3.4",
|
||||
"epubjs": "0.3.93",
|
||||
"escape-html": "1.0.3",
|
||||
"fast-text-encoding": "1.0.3",
|
||||
"flv.js": "1.6.2",
|
||||
"headroom.js": "0.12.0",
|
||||
"hls.js": "0.14.17",
|
||||
"intersection-observer": "0.12.0",
|
||||
"jellyfin-apiclient": "1.10.0",
|
||||
"jquery": "3.6.0",
|
||||
"jstree": "3.3.12",
|
||||
"libarchive.js": "1.3.0",
|
||||
"lodash-es": "4.17.21",
|
||||
"marked": "4.0.10",
|
||||
"material-design-icons-iconfont": "6.1.1",
|
||||
"native-promise-only": "0.8.1",
|
||||
"page": "1.11.6",
|
||||
"pdfjs-dist": "2.12.313",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"resize-observer-polyfill": "1.5.1",
|
||||
"screenfull": "6.0.0",
|
||||
"sortablejs": "1.14.0",
|
||||
"swiper": "6.8.4",
|
||||
"webcomponents.js": "0.7.24",
|
||||
"whatwg-fetch": "3.6.2",
|
||||
"workbox-core": "6.2.4",
|
||||
"workbox-precaching": "6.2.4"
|
||||
"core-js": "^3.6.5",
|
||||
"date-fns": "^2.14.0",
|
||||
"epubjs": "^0.3.85",
|
||||
"fast-text-encoding": "^1.0.3",
|
||||
"flv.js": "^1.5.0",
|
||||
"headroom.js": "^0.11.0",
|
||||
"hls.js": "^0.14.0",
|
||||
"howler": "^2.2.0",
|
||||
"intersection-observer": "^0.11.0",
|
||||
"jellyfin-apiclient": "^1.4.1",
|
||||
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
|
||||
"jquery": "^3.5.1",
|
||||
"jstree": "^3.3.10",
|
||||
"libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf-smarttv",
|
||||
"material-design-icons-iconfont": "^5.0.1",
|
||||
"native-promise-only": "^0.8.0-a",
|
||||
"page": "^1.11.6",
|
||||
"query-string": "^6.13.1",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"screenfull": "^5.0.2",
|
||||
"shaka-player": "^2.5.13",
|
||||
"sortablejs": "^1.10.2",
|
||||
"swiper": "^5.4.5",
|
||||
"webcomponents.js": "^0.7.24",
|
||||
"whatwg-fetch": "^3.2.0"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"@babel/preset-env"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"test": [
|
||||
"src/components/accessSchedule/accessSchedule.js",
|
||||
"src/components/actionSheet/actionSheet.js",
|
||||
"src/components/autoFocuser.js",
|
||||
"src/components/cardbuilder/cardBuilder.js",
|
||||
"src/components/cardbuilder/chaptercardbuilder.js",
|
||||
"src/components/cardbuilder/peoplecardbuilder.js",
|
||||
"src/components/images/imageLoader.js",
|
||||
"src/components/indicators/indicators.js",
|
||||
"src/components/lazyLoader/lazyLoaderIntersectionObserver.js",
|
||||
"src/components/playback/brightnessosd.js",
|
||||
"src/components/playback/mediasession.js",
|
||||
"src/components/playback/nowplayinghelper.js",
|
||||
"src/components/playback/playbackorientation.js",
|
||||
"src/components/playback/playerSelectionMenu.js",
|
||||
"src/components/playback/playersettingsmenu.js",
|
||||
"src/components/playback/playmethodhelper.js",
|
||||
"src/components/playback/remotecontrolautoplay.js",
|
||||
"src/components/playback/volumeosd.js",
|
||||
"src/components/playmenu.js",
|
||||
"src/components/sanatizefilename.js",
|
||||
"src/components/scrollManager.js",
|
||||
"src/components/syncPlay/groupSelectionMenu.js",
|
||||
"src/components/syncPlay/playbackPermissionManager.js",
|
||||
"src/components/syncPlay/syncPlayManager.js",
|
||||
"src/components/syncPlay/timeSyncManager.js",
|
||||
"src/controllers/dashboard/logs.js",
|
||||
"src/controllers/dashboard/plugins/repositories.js",
|
||||
"src/controllers/user/display.js",
|
||||
"src/controllers/user/home.js",
|
||||
"src/controllers/user/playback.js",
|
||||
"src/controllers/user/subtitles.js",
|
||||
"src/plugins/bookPlayer/plugin.js",
|
||||
"src/plugins/bookPlayer/tableOfContents.js",
|
||||
"src/plugins/photoPlayer/plugin.js",
|
||||
"src/scripts/deleteHelper.js",
|
||||
"src/scripts/dfnshelper.js",
|
||||
"src/scripts/dom.js",
|
||||
"src/scripts/fileDownloader.js",
|
||||
"src/scripts/filesystem.js",
|
||||
"src/scripts/imagehelper.js",
|
||||
"src/scripts/inputManager.js",
|
||||
"src/plugins/backdropScreensaver/plugin.js",
|
||||
"src/components/filterdialog/filterdialog.js",
|
||||
"src/components/fetchhelper.js",
|
||||
"src/scripts/keyboardNavigation.js",
|
||||
"src/scripts/settings/appSettings.js",
|
||||
"src/scripts/settings/userSettings.js",
|
||||
"src/scripts/settings/webSettings.js"
|
||||
],
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-modules-amd",
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-proposal-private-methods"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"browserslist": [
|
||||
"last 2 Firefox versions",
|
||||
@@ -122,17 +163,12 @@
|
||||
"Firefox ESR"
|
||||
],
|
||||
"scripts": {
|
||||
"start": "npm run serve",
|
||||
"serve": "webpack serve --config webpack.dev.js",
|
||||
"prepare": "node ./scripts/prepare.js",
|
||||
"build:development": "webpack --config webpack.dev.js",
|
||||
"build:production": "webpack --config webpack.prod.js",
|
||||
"lint": "eslint \"src/\"",
|
||||
"stylelint": "npm run stylelint:css && npm run stylelint:scss",
|
||||
"stylelint:css": "stylelint \"src/**/*.css\"",
|
||||
"stylelint:scss": "stylelint --config=\".stylelintrc.scss.json\" \"src/**/*.scss\""
|
||||
},
|
||||
"engines": {
|
||||
"yarn": "YARN NO LONGER USED - use npm instead."
|
||||
"serve": "gulp serve --development",
|
||||
"prepare": "gulp --production",
|
||||
"build:development": "gulp --development",
|
||||
"build:production": "gulp --production",
|
||||
"build:standalone": "gulp standalone --development",
|
||||
"lint": "eslint \".\"",
|
||||
"stylelint": "stylelint \"src/**/*.css\""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
# load every string in the source language
|
||||
# print all duplicate values to a file
|
||||
|
||||
cwd = os.getcwd()
|
||||
source = cwd + '/../src/strings/en-us.json'
|
||||
|
||||
reverse = {}
|
||||
duplicates = {}
|
||||
|
||||
with open(source) as en:
|
||||
strings = json.load(en)
|
||||
for key, value in strings.items():
|
||||
if value not in reverse:
|
||||
reverse[value] = [key]
|
||||
else:
|
||||
reverse[value].append(key)
|
||||
|
||||
for key, value in reverse.items():
|
||||
if len(value) > 1:
|
||||
duplicates[key] = value
|
||||
|
||||
print('LENGTH: ' + str(len(duplicates)))
|
||||
with open('duplicates.txt', 'w') as out:
|
||||
for item in duplicates:
|
||||
out.write(json.dumps(item) + ': ')
|
||||
out.write(json.dumps(duplicates[item]) + '\n')
|
||||
out.close()
|
||||
|
||||
print('DONE')
|
||||
@@ -1,12 +0,0 @@
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
/**
|
||||
* The npm `prepare` script needs to run a build to support installing
|
||||
* a package from git repositories (this is dumb but a limitation of how
|
||||
* npm behaves). We don't want to run these in CI though because
|
||||
* building is slow so this script will skip the build when the
|
||||
* `SKIP_PREPARE` environment variable has been set.
|
||||
*/
|
||||
if (!process.env.SKIP_PREPARE) {
|
||||
execSync('webpack --config webpack.prod.js', { stdio: 'inherit' });
|
||||
}
|
||||
@@ -16,7 +16,7 @@ langlst.append('en-us.json')
|
||||
dep = []
|
||||
|
||||
def grep(key):
|
||||
command = 'grep -r -E "(\\\"|\'|\{)%s(\\\"|\'|\})" --include=\*.{js,html} --exclude-dir=../src/strings ../src' % 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:
|
||||
@@ -11,7 +11,7 @@ langlst = os.listdir(langdir)
|
||||
|
||||
keys = []
|
||||
|
||||
with open('unused.txt', 'r') as f:
|
||||
with open('scout.txt', 'r') as f:
|
||||
for line in f:
|
||||
keys.append(line.strip('\n'))
|
||||
|
||||
@@ -34,9 +34,7 @@
|
||||
<div class="readOnlyContent">
|
||||
<div is="emby-collapse" title="${HeaderDeveloperInfo}">
|
||||
<div class="collapseContent">
|
||||
<p>${LabelDeveloper}: <span id="developer"></span></p>
|
||||
<p>${LabelRepositoryName}: <span id="repositoryName"></span></p>
|
||||
<p>${LabelRepositoryUrl}: <span id="repositoryUrl"></span></p>
|
||||
<p id="developer"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<br />
|
||||
<button is="emby-button" type="submit" class="raised button-submit block">
|
||||
<span>${Connect}</span>
|
||||
<span>${ButtonConnect}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block btnCancel">
|
||||
<span>${ButtonCancel}</span>
|
||||
352
src/apiclient.d.ts
vendored
@@ -1,352 +0,0 @@
|
||||
// TODO: Move to jellyfin-apiclient
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
declare module 'jellyfin-apiclient' {
|
||||
import type {
|
||||
AllThemeMediaResult,
|
||||
AuthenticationResult,
|
||||
BaseItemDto,
|
||||
BaseItemDtoQueryResult,
|
||||
BufferRequestDto,
|
||||
ClientCapabilities,
|
||||
CountryInfo,
|
||||
CultureDto,
|
||||
DeviceOptions,
|
||||
DisplayPreferencesDto,
|
||||
EndPointInfo,
|
||||
FileSystemEntryInfo,
|
||||
GeneralCommand,
|
||||
GroupInfoDto,
|
||||
GuideInfo,
|
||||
IgnoreWaitRequestDto,
|
||||
ImageInfo,
|
||||
ImageProviderInfo,
|
||||
ImageType,
|
||||
ItemCounts,
|
||||
LiveTvInfo,
|
||||
MovePlaylistItemRequestDto,
|
||||
NewGroupRequestDto,
|
||||
NextItemRequestDto,
|
||||
NotificationResultDto,
|
||||
NotificationsSummaryDto,
|
||||
ParentalRating,
|
||||
PingRequestDto,
|
||||
PlaybackInfoResponse,
|
||||
PlaybackProgressInfo,
|
||||
PlaybackStartInfo,
|
||||
PlaybackStopInfo,
|
||||
PlayCommand,
|
||||
PlaystateCommand,
|
||||
PluginInfo,
|
||||
PluginSecurityInfo,
|
||||
PreviousItemRequestDto,
|
||||
QueryFiltersLegacy,
|
||||
QueueRequestDto,
|
||||
QuickConnectResult,
|
||||
QuickConnectState,
|
||||
ReadyRequestDto,
|
||||
RecommendationDto,
|
||||
RemoteImageResult,
|
||||
RemoveFromPlaylistRequestDto,
|
||||
SearchHintResult,
|
||||
SeekRequestDto,
|
||||
SeriesTimerInfoDto,
|
||||
SeriesTimerInfoDtoQueryResult,
|
||||
ServerConfiguration,
|
||||
SessionInfo,
|
||||
SetPlaylistItemRequestDto,
|
||||
SetRepeatModeRequestDto,
|
||||
SetShuffleModeRequestDto,
|
||||
SystemInfo,
|
||||
TaskInfo,
|
||||
TaskTriggerInfo,
|
||||
TimerInfoDto,
|
||||
TimerInfoDtoQueryResult,
|
||||
UserConfiguration,
|
||||
UserDto,
|
||||
UserItemDataDto,
|
||||
UserPolicy,
|
||||
UtcTimeResponse,
|
||||
VirtualFolderInfo
|
||||
} from '@thornbill/jellyfin-sdk/dist/generated-client';
|
||||
|
||||
class ApiClient {
|
||||
constructor(serverAddress: string, appName: string, appVersion: string, deviceName: string, deviceId: string);
|
||||
|
||||
accessToken(): string;
|
||||
addMediaPath(virtualFolderName: string, mediaPath: string, networkSharePath: string, refreshLibrary?: boolean): Promise<void>;
|
||||
addVirtualFolder(name: string, type?: string, refreshLibrary?: boolean, libraryOptions?: any): Promise<void>;
|
||||
appName(): string;
|
||||
appVersion(): string;
|
||||
authenticateUserByName(name: string, password: string): Promise<AuthenticationResult>;
|
||||
cancelLiveTvSeriesTimer(id: string): Promise<void>;
|
||||
cancelLiveTvTimer(id: string): Promise<void>;
|
||||
cancelSyncItems(itemIds: string[], targetId?: string): Promise<void>;
|
||||
clearAuthenticationInfo(): void;
|
||||
clearUserItemRating(userId: string, itemId: string): Promise<UserItemDataDto>;
|
||||
closeWebSocket(): void;
|
||||
createLiveTvSeriesTimer(item: string): Promise<void>;
|
||||
createLiveTvTimer(item: string): Promise<void>;
|
||||
createPackageReview(review: any): Promise<any>;
|
||||
createSyncPlayGroup(options?: NewGroupRequestDto): Promise<void>;
|
||||
createUser(user: UserDto): Promise<UserDto>;
|
||||
deleteDevice(deviceId: string): Promise<void>;
|
||||
deleteItemImage(itemId: string, imageType: ImageType, imageIndex?: number): Promise<void>;
|
||||
deleteItem(itemId: string): Promise<void>;
|
||||
deleteLiveTvRecording(id: string): Promise<void>;
|
||||
deleteUserImage(userId: string, imageType: ImageType, imageIndex?: number): Promise<void>;
|
||||
deleteUser(userId: string): Promise<void>;
|
||||
detectBitrate(force: boolean): Promise<number>;
|
||||
deviceId(): string;
|
||||
deviceName(): string;
|
||||
disablePlugin(id: string, version: string): Promise<void>;
|
||||
downloadRemoteImage(options: any): Promise<void>;
|
||||
enablePlugin(id: string, version: string): Promise<void>;
|
||||
encodeName(name: string): string;
|
||||
ensureWebSocket(): void;
|
||||
fetch(request: any, includeAuthorization?: boolean): Promise<any>;
|
||||
fetchWithFailover(request: any, enableReconnection?: boolean): Promise<any>;
|
||||
getAdditionalVideoParts(userId?: string, itemId: string): Promise<BaseItemDtoQueryResult>;
|
||||
getAlbumArtists(userId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getAncestorItems(itemId: string, userId?: string): Promise<BaseItemDto[]>;
|
||||
getArtist(name: string, userId?: string): Promise<BaseItemDto>;
|
||||
getArtists(userId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getAvailablePlugins(options?: any): Promise<PluginInfo[]>;
|
||||
getAvailableRemoteImages(options: any): Promise<RemoteImageResult>;
|
||||
getContentUploadHistory(): Promise<any>;
|
||||
getCountries(): Promise<CountryInfo[]>;
|
||||
getCriticReviews(itemId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getCultures(): Promise<CultureDto[]>;
|
||||
getCurrentUserId(): string;
|
||||
getDateParamValue(date: Date): string;
|
||||
getDefaultImageQuality(imageType: ImageType): number;
|
||||
getDevicesOptions(): Promise<DeviceOptions>;
|
||||
getDirectoryContents(path: string, options?: any): Promise<FileSystemEntryInfo[]>;
|
||||
getDisplayPreferences(id: string, userId: string, app: string): Promise<DisplayPreferencesDto>;
|
||||
getDownloadSpeed(byteSize: number): Promise<number>;
|
||||
getDrives(): Promise<FileSystemEntryInfo[]>;
|
||||
getEndpointInfo(): Promise<EndPointInfo>;
|
||||
getEpisodes(itemId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getFilters(options?: any): Promise<QueryFiltersLegacy>;
|
||||
getGenre(name: string, userId?: string): Promise<BaseItemDto>;
|
||||
getGenres(userId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getImageUrl(itemId: string, options?: any): string;
|
||||
getInstalledPlugins(): Promise<PluginInfo[]>;
|
||||
getInstantMixFromItem(itemId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getIntros(itemId: string): Promise<BaseItemDtoQueryResult>;
|
||||
getItemCounts(userId?: string): Promise<ItemCounts>;
|
||||
getItemDownloadUrl(itemId: string): string;
|
||||
getItemImageInfos(itemId: string): Promise<ImageInfo[]>;
|
||||
getItems(userId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getItem(userId: string, itemId: string): Promise<BaseItemDto>;
|
||||
getJSON(url: string, includeAuthorization?: boolean): Promise<any>;
|
||||
getLatestItems(options?: any): Promise<BaseItemDto[]>;
|
||||
getLiveStreamMediaInfo(liveStreamId: string): Promise<any>;
|
||||
getLiveTvChannel(id: string, userId?: string): Promise<BaseItemDto>;
|
||||
getLiveTvChannels(options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getLiveTvGuideInfo(userId: string): Promise<GuideInfo>;
|
||||
getLiveTvInfo(userId: string): Promise<LiveTvInfo>;
|
||||
getLiveTvProgram(id: string, userId?: string): Promise<BaseItemDto>;
|
||||
getLiveTvPrograms(options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getLiveTvRecommendedPrograms(options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getLiveTvRecordingGroup(id: string): Promise<BaseItemDto>;
|
||||
getLiveTvRecordingGroups(options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getLiveTvRecording(id: string, userId?: string): Promise<BaseItemDto>;
|
||||
getLiveTvRecordingSeries(options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getLiveTvRecordings(options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getLiveTvSeriesTimer(id: string): Promise<SeriesTimerInfoDto>;
|
||||
getLiveTvSeriesTimers(options?: any): Promise<SeriesTimerInfoDtoQueryResult>;
|
||||
getLiveTvTimer(id: string): Promise<TimerInfoDto>;
|
||||
getLiveTvTimers(options?: any): Promise<TimerInfoDtoQueryResult>;
|
||||
getLocalTrailers(userId: string, itemId: string): Promise<BaseItemDto[]>;
|
||||
getMovieRecommendations(options?: any): Promise<RecommendationDto[]>;
|
||||
getMusicGenre(name: string, userId?: string): Promise<BaseItemDto>;
|
||||
getMusicGenres(userId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getNamedConfiguration(name: string): Promise<any>;
|
||||
getNetworkDevices(): Promise<any>;
|
||||
getNetworkShares(path: string): Promise<FileSystemEntryInfo[]>;
|
||||
getNewLiveTvTimerDefaults(options?: any): Promise<SeriesTimerInfoDto>;
|
||||
getNextUpEpisodes(options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getNotificationSummary(userId: string): Promise<NotificationsSummaryDto>;
|
||||
getNotifications(userId: string, options?: any): Promise<NotificationResultDto>;
|
||||
getPackageInfo(name: string, guid: string): Promise<PackageInfo>;
|
||||
getPackageReviews(packageId: string, minRating?: string, maxRating?: string, limit?: string): Promise<any>;
|
||||
getParentalRatings(): Promise<ParentalRating[]>;
|
||||
getParentPath(path: string): Promise<string>;
|
||||
getPeople(userId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getPerson(name: string, userId?: string): Promise<BaseItemDto>;
|
||||
getPhysicalPaths(): Promise<string[]>;
|
||||
getPlaybackInfo(itemId: string, options: any, deviceProfile: any): Promise<PlaybackInfoResponse>;
|
||||
getPluginConfiguration(id: string): Promise<any>;
|
||||
getPublicSystemInfo(): Promise<PublicSystemInfo>;
|
||||
getPublicUsers(): Promise<UserDto[]>;
|
||||
getQuickConnect(verb: string): Promise<void|boolean|number|QuickConnectResult|QuickConnectState>;
|
||||
getReadySyncItems(deviceId: string): Promise<any>;
|
||||
getRecordingFolders(userId: string): Promise<BaseItemDtoQueryResult>;
|
||||
getRegistrationInfo(feature: string): Promise<any>;
|
||||
getRemoteImageProviders(options: any): Promise<ImageProviderInfo[]>;
|
||||
getResumableItems(userId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getRootFolder(userId: string): Promise<BaseItemDto>;
|
||||
getSavedEndpointInfo(): EndPointInfo;
|
||||
getScaledImageUrl(itemId: string, options?: any): string;
|
||||
getScheduledTask(id: string): Promise<TaskInfo>;
|
||||
getScheduledTasks(options?: any): Promise<TaskInfo[]>;
|
||||
getSearchHints(options?: any): Promise<SearchHintResult>;
|
||||
getSeasons(itemId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getServerConfiguration(): Promise<ServerConfiguration>;
|
||||
getServerTime(): Promise<UtcTimeResponse>;
|
||||
getSessions(options?: any): Promise<SessionInfo[]>;
|
||||
getSimilarItems(itemId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getSpecialFeatures(userId: string, itemId: string): Promise<BaseItemDto[]>;
|
||||
getStudio(name: string, userId?: string): Promise<BaseItemDto>;
|
||||
getStudios(userId: string, options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getSyncPlayGroups(): Promise<GroupInfoDto[]>;
|
||||
getSyncStatus(itemId: string): Promise<any>;
|
||||
getSystemInfo(): Promise<SystemInfo>;
|
||||
getThemeMedia(userId?: string, itemId: string, inherit?: boolean): Promise<AllThemeMediaResult>;
|
||||
getThumbImageUrl(item: BaseItemDto, options?: any): string;
|
||||
getUpcomingEpisodes(options?: any): Promise<BaseItemDtoQueryResult>;
|
||||
getUrl(name: string, params?: any, serverAddress?: string): string;
|
||||
get(url: string): Promise<any>;
|
||||
getUserImageUrl(userId: string, options?: any): string;
|
||||
getUsers(options?: any): Promise<UserDto[]>;
|
||||
getUser(userId: string): Promise<UserDto>;
|
||||
getUserViews(options?: any, userId: string): Promise<BaseItemDtoQueryResult>;
|
||||
getVirtualFolders(): Promise<VirtualFolderInfo[]>;
|
||||
handleMessageReceived(msg: any): void;
|
||||
installPlugin(name: string, guid: string, version?: string): Promise<void>;
|
||||
isLoggedIn(): boolean;
|
||||
isMessageChannelOpen(): boolean;
|
||||
isMinServerVersion(version: string): boolean;
|
||||
isWebSocketOpen(): boolean;
|
||||
isWebSocketOpenOrConnecting(): boolean;
|
||||
isWebSocketSupported(): boolean;
|
||||
joinSyncPlayGroup(options?: any): Promise<void>;
|
||||
leaveSyncPlayGroup(): Promise<void>;
|
||||
logout(): Promise<void>;
|
||||
markNotificationsRead(userId: string, idList: string[], isRead: boolean): Promise<void>;
|
||||
markPlayed(userId: string, itemId: string, date: Date): Promise<UserItemDataDto>;
|
||||
markUnplayed(userId: string, itemId: string, date: Date): Promise<UserItemDataDto>;
|
||||
openWebSocket(): void;
|
||||
quickConnect(secret: string): Promise<AuthenticationResult>;
|
||||
refreshItem(itemId: string, options?: any): Promise<void>;
|
||||
removeMediaPath(virtualFolderName: string, mediaPath: string, refreshLibrary?: boolean): Promise<void>;
|
||||
removeVirtualFolder(name: string, refreshLibrary?: boolean): Promise<void>;
|
||||
renameVirtualFolder(name: string, newName: string, refreshLibrary?: boolean): Promise<void>;
|
||||
reportCapabilities(capabilities: ClientCapabilities): Promise<void>;
|
||||
reportOfflineActions(actions: any): Promise<any>;
|
||||
reportPlaybackProgress(options: PlaybackProgressInfo): Promise<void>;
|
||||
reportPlaybackStart(options: PlaybackStartInfo): Promise<void>;
|
||||
reportPlaybackStopped(options: PlaybackStopInfo): Promise<void>;
|
||||
reportSyncJobItemTransferred(syncJobItemId: string): Promise<any>;
|
||||
requestSyncPlayBuffering(options?: BufferRequestDto): Promise<void>;
|
||||
requestSyncPlayMovePlaylistItem(options?: MovePlaylistItemRequestDto): Promise<void>;
|
||||
requestSyncPlayNextItem(options?: NextItemRequestDto): Promise<void>;
|
||||
requestSyncPlayPause(): Promise<void>;
|
||||
requestSyncPlayPreviousItem(options?: PreviousItemRequestDto): Promise<void>;
|
||||
requestSyncPlayQueue(options?: QueueRequestDto): Promise<void>;
|
||||
requestSyncPlayReady(options?: ReadyRequestDto): Promise<void>;
|
||||
requestSyncPlayRemoveFromPlaylist(options?: RemoveFromPlaylistRequestDto): Promise<void>;
|
||||
requestSyncPlaySeek(options?: SeekRequestDto): Promise<void>;
|
||||
requestSyncPlaySetIgnoreWait(options?: IgnoreWaitRequestDto): Promise<void>;
|
||||
requestSyncPlaySetNewQueue(options?: NewGroupRequestDto): Promise<void>;
|
||||
requestSyncPlaySetPlaylistItem(options?: SetPlaylistItemRequestDto): Promise<void>;
|
||||
requestSyncPlaySetRepeatMode(options?: SetRepeatModeRequestDto): Promise<void>;
|
||||
requestSyncPlaySetShuffleMode(options?: SetShuffleModeRequestDto): Promise<void>;
|
||||
requestSyncPlayUnpause(): Promise<void>;
|
||||
resetEasyPassword(userId: string): Promise<void>;
|
||||
resetLiveTvTuner(id: string): Promise<void>;
|
||||
resetUserPassword(userId: string): Promise<void>;
|
||||
restartServer(): Promise<void>;
|
||||
sendCommand(sessionId: string, command: any): Promise<void>;
|
||||
sendMessageCommand(sessionId: string, options: GeneralCommand): Promise<void>;
|
||||
sendMessage(name: string, data: any): void;
|
||||
sendPlayCommand(sessionId: string, options: PlayCommand): Promise<void>;
|
||||
sendPlayStateCommand(sessionId: string, command: PlaystateCommand, options?: any): Promise<void>;
|
||||
sendSyncPlayPing(options?: PingRequestDto): Promise<void>;
|
||||
sendWebSocketMessage(name: string, data: any): void;
|
||||
serverAddress(val?: string): string;
|
||||
serverId(): string;
|
||||
serverVersion(): string
|
||||
setAuthenticationInfo(accessKey?: string, userId?: string): void;
|
||||
setRequestHeaders(headers: any): void;
|
||||
setSystemInfo(info: SystemInfo): void;
|
||||
shutdownServer(): Promise<void>;
|
||||
startScheduledTask(id: string): Promise<void>;
|
||||
stopActiveEncodings(playSessionId: string): Promise<void>;
|
||||
stopScheduledTask(id: string): Promise<void>;
|
||||
syncData(data: any): Promise<any>;
|
||||
uninstallPluginByVersion(id: string, version: string): Promise<void>;
|
||||
uninstallPlugin(id: string): Promise<void>;
|
||||
updateDisplayPreferences(id: string, obj: DisplayPreferencesDto, userId: string, app: string): Promise<void>;
|
||||
updateEasyPassword(userId: string, newPassword: string): Promise<void>;
|
||||
updateFavoriteStatus(userId: string, itemId: string, isFavorite: boolean): Promise<UserItemDataDto>;
|
||||
updateItemImageIndex(itemId: string, imageType: ImageType, imageIndex: number, newIndex: number): Promise<any>;
|
||||
updateItem(item: BaseItemDto): Promise<void>;
|
||||
updateLiveTvSeriesTimer(item: SeriesTimerInfoDto): Promise<void>;
|
||||
updateLiveTvTimer(item: TimerInfoDto): Promise<void>;
|
||||
updateMediaPath(virtualFolderName: string, pathInfo: any): Promise<void>;
|
||||
updateNamedConfiguration(name: string, configuration: any): Promise<void>;
|
||||
updatePluginConfiguration(id: string, configuration: any): Promise<void>;
|
||||
updatePluginSecurityInfo(info: PluginSecurityInfo): Promise<void>;
|
||||
updateScheduledTaskTriggers(id: string, triggers: TaskTriggerInfo[]): Promise<void>;
|
||||
updateServerConfiguration(configuration: ServerConfiguration): Promise<void>;
|
||||
updateServerInfo(server: any, serverUrl: string): void;
|
||||
updateUserConfiguration(userId: string, configuration: UserConfiguration): Promise<void>;
|
||||
updateUserItemRating(userId: string, itemId: string, likes: boolean): Promise<UserItemDataDto>;
|
||||
updateUserPassword(userId: string, currentPassword: string, newPassword: string): Promise<void>;
|
||||
updateUserPolicy(userId: string, policy: UserPolicy): Promise<void>;
|
||||
updateUser(user: UserDto): Promise<void>;
|
||||
updateVirtualFolderOptions(id: string, libraryOptions?: any): Promise<void>;
|
||||
uploadItemImage(itemId: string, imageType: ImageType, file: File): Promise<void>;
|
||||
uploadItemSubtitle(itemId: string, language: string, isForced: boolean, file: File): Promise<void>;
|
||||
uploadUserImage(userId: string, imageType: ImageType, file: File): Promise<void>;
|
||||
}
|
||||
|
||||
class AppStore {
|
||||
constructor();
|
||||
|
||||
getItem(name: string): string|null;
|
||||
removeItem(name: string): void;
|
||||
setItem(name: string, value: string): void;
|
||||
}
|
||||
|
||||
class ConnectionManager {
|
||||
constructor(credentialProvider: Credentials, appName: string, appVersion: string, deviceName: string, deviceId: string, capabilities: ClientCapabilities);
|
||||
|
||||
addApiClient(apiClient: ApiClient): void;
|
||||
clearData(): void;
|
||||
connect(options?: any): Promise<any>;
|
||||
connectToAddress(address: string, options?: any): Promise<any>;
|
||||
connectToServer(server: any, options?: any): Promise<any>;
|
||||
connectToServers(servers: any[], options?: any): Promise<any>;
|
||||
deleteServer(serverId: string): Promise<void>;
|
||||
getApiClient(item: BaseItemDto|string): ApiClient;
|
||||
getApiClients(): ApiClient[];
|
||||
getAvailableServers(): any[];
|
||||
getOrCreateApiClient(serverId: string): ApiClient;
|
||||
getSavedServers(): any[];
|
||||
handleMessageReceived(msg: any): void;
|
||||
logout(): Promise<void>;
|
||||
minServerVersion(val?: string): string;
|
||||
user(apiClient: ApiClient): Promise<any>;
|
||||
}
|
||||
|
||||
class Credentials {
|
||||
constructor(key?: string);
|
||||
|
||||
addOrUpdateServer(list: any[], server: any): any;
|
||||
clear(): void;
|
||||
credentials(data?: any): any;
|
||||
}
|
||||
|
||||
interface Event {
|
||||
type: string;
|
||||
}
|
||||
|
||||
const Events: {
|
||||
off(obj: any, eventName: string, fn: (e: Event, ...args: any[]) => void): void;
|
||||
on(obj: any, eventName: string, fn: (e: Event, ...args: any[]) => void): void;
|
||||
trigger(obj: any, eventName: string, ...args: any[]): void;
|
||||
};
|
||||
}
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="content-primary">
|
||||
<div class="detailSectionHeader">
|
||||
<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="${Add}">
|
||||
<button is="emby-button" type="button" class="fab btnNewKey submit" style="margin-left:1em;" title="${ButtonAdd}">
|
||||
<span class="material-icons add" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -127,8 +127,8 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
}
|
||||
|
||||
.sessionAppInfo img {
|
||||
max-width: 2.5em;
|
||||
max-height: 2.5em;
|
||||
max-width: 40px;
|
||||
max-height: 40px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
@@ -204,17 +204,12 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.dashboardActionsContainer {
|
||||
margin: 1em -0.3em 0;
|
||||
}
|
||||
|
||||
.sessionNowPlayingContent {
|
||||
-webkit-background-size: cover;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
position: absolute;
|
||||
border-radius: 0.2em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
@@ -236,13 +231,6 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.dashboardSection .sectionTitleTextButton > .material-icons.material-icons {
|
||||
font-size: 1.17em;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.activeRecordingItems > .card {
|
||||
width: 50%;
|
||||
}
|
||||
@@ -258,12 +246,20 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
|
||||
@media all and (min-width: 70em) {
|
||||
.dashboardSections {
|
||||
-webkit-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.dashboardColumn-2-60 {
|
||||
flex-grow: 2;
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.dashboardColumn-2-40 {
|
||||
width: 27%;
|
||||
}
|
||||
|
||||
.dashboardSection {
|
||||
@@ -295,7 +291,6 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
}
|
||||
|
||||
.activeSession {
|
||||
min-width: 20rem;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
@@ -309,24 +304,27 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
@media all and (min-width: 40em) {
|
||||
.activeSession {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 50em) {
|
||||
.activeSession {
|
||||
max-width: 25rem;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 50%;
|
||||
width: 50% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sessionCardFooter {
|
||||
padding-top: 0.5em !important;
|
||||
padding-bottom: 1em !important;
|
||||
border-top: 1px solid #eee;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sessionAppInfo {
|
||||
flex-grow: 1;
|
||||
padding: 0.5em;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -346,13 +344,11 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
font-weight: 400;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.darkenContent {
|
||||
.sessionNowPlayingContent-withbackground + .sessionNowPlayingInnerContent {
|
||||
color: #fff !important;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.sessionAppName {
|
||||
@@ -362,6 +358,9 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
|
||||
.sessionNowPlayingDetails {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sessionNowPlayingInfo {
|
||||
@@ -377,6 +376,10 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
padding: 0.8em 0.5em;
|
||||
}
|
||||
|
||||
.sessionNowPlayingStreamInfo {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.playbackProgress,
|
||||
.transcodingProgress {
|
||||
margin: 0;
|
||||
@@ -384,12 +387,6 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.activeDevices.itemsContainer {
|
||||
/* offset for cardBox margin */
|
||||
margin: -0.6em;
|
||||
}
|
||||
|
||||
.activeSession .backgroundProgress,
|
||||
.activeSession .playbackProgress,
|
||||
.activeSession .transcodingProgress {
|
||||
position: absolute;
|
||||
@@ -406,14 +403,9 @@ div[data-role=controlgroup] a.ui-btn-active {
|
||||
}
|
||||
|
||||
.transcodingProgress > div {
|
||||
z-index: 10;
|
||||
background-color: #dd4919;
|
||||
}
|
||||
|
||||
.backgroundProgress > div {
|
||||
background-color: #303030;
|
||||
}
|
||||
|
||||
@media all and (max-width: 34.375em) {
|
||||
.sessionAppName {
|
||||
max-width: 160px;
|
||||
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,56 +0,0 @@
|
||||
@import "../../styles/noto-sans/index.scss";
|
||||
|
||||
@mixin font($weight: null, $size: null) {
|
||||
font-weight: $weight;
|
||||
font-size: $size;
|
||||
}
|
||||
|
||||
html {
|
||||
@include font($size: 93%);
|
||||
font-family: "Noto Sans", "Noto Sans HK", "Noto Sans JP", "Noto Sans KR", "Noto Sans SC", "Noto Sans TC", sans-serif;
|
||||
text-size-adjust: 100%;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
html[lang|="ja"] {
|
||||
font-family: "Noto Sans", "Noto Sans JP", "Noto Sans HK", "Noto Sans KR", "Noto Sans SC", "Noto Sans TC", sans-serif;
|
||||
}
|
||||
|
||||
html[lang|="ko"] {
|
||||
font-family: "Noto Sans", "Noto Sans KR", "Noto Sans HK", "Noto Sans JP", "Noto Sans SC", "Noto Sans TC", sans-serif;
|
||||
}
|
||||
|
||||
html[lang|="zh-CN"] {
|
||||
font-family: "Noto Sans", "Noto Sans SC", "Noto Sans HK", "Noto Sans JP", "Noto Sans KR", "Noto Sans TC", sans-serif;
|
||||
}
|
||||
|
||||
html[lang|="zh-TW"] {
|
||||
font-family: "Noto Sans", "Noto Sans TC", "Noto Sans HK", "Noto Sans JP", "Noto Sans KR", "Noto Sans SC", sans-serif;
|
||||
}
|
||||
|
||||
html[lang|="zh-HK"] {
|
||||
font-family: "Noto Sans", "Noto Sans HK", "Noto Sans JP", "Noto Sans KR", "Noto Sans SC", "Noto Sans TC", sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include font(400, 1.8em);
|
||||
}
|
||||
|
||||
h2 {
|
||||
@include font(400, 1.5em);
|
||||
}
|
||||
|
||||
h3 {
|
||||
@include font(400, 1.17em);
|
||||
}
|
||||
|
||||
.layout-tv {
|
||||
/* Per WebOS and Tizen guidelines, fonts must be 20px minimum.
|
||||
This takes the 16px baseline and multiplies it by 1.25 to get 20px. */
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
.layout-mobile {
|
||||
font-size: 90%;
|
||||
}
|
||||
31
src/assets/css/fonts.sized.css
Normal file
@@ -0,0 +1,31 @@
|
||||
h1 {
|
||||
font-weight: 400;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
.layout-desktop h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 400;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: 400;
|
||||
font-size: 1.17em;
|
||||
}
|
||||
|
||||
@media all and (min-height: 720px) {
|
||||
html {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is supposed to be 1080p, but had to reduce the min height to account for possible browser chrome */
|
||||
@media all and (min-height: 1000px) {
|
||||
html {
|
||||
font-size: 27px;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
@mixin header-font($size: null) {
|
||||
font-weight: 400;
|
||||
font-size: $size;
|
||||
}
|
||||
|
||||
html {
|
||||
@media all and (min-height: 720px) {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* This is supposed to be 1080p, but had to reduce the min height to account for possible browser chrome */
|
||||
@media all and (min-height: 1000px) {
|
||||
font-size: 27px;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include header-font(1.8em);
|
||||
|
||||
.layout-desktop & {
|
||||
font-size: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
@include header-font(1.8em);
|
||||
}
|
||||
|
||||
h3 {
|
||||
@include header-font(1.17em);
|
||||
}
|
||||
@@ -1,37 +1,3 @@
|
||||
// The padding of the header content on mobile needs to be adjusted
|
||||
// based on the size of the poster card (values from card.scss)
|
||||
@mixin header-poster-padding() {
|
||||
padding-left: 37.5%;
|
||||
|
||||
@media all and (min-width: 43.75em) {
|
||||
padding-left: 25%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 50em) {
|
||||
padding-left: 20%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 75em) {
|
||||
padding-left: 16.666666666666666666666666666667%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 87.5em) {
|
||||
padding-left: 14.285714285714285714285714285714%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 100em) {
|
||||
padding-left: 12.5%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 120em) {
|
||||
padding-left: 11.111111111111111111111111111111%;
|
||||
}
|
||||
|
||||
@media all and (min-width: 131.25em) {
|
||||
padding-left: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
.headerUserImage,
|
||||
.navMenuOption,
|
||||
.pageTitle {
|
||||
@@ -62,10 +28,6 @@
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.layout-tv .itemDetailPage {
|
||||
padding-top: 4.2em !important;
|
||||
}
|
||||
|
||||
.standalonePage {
|
||||
padding-top: 4.5em !important;
|
||||
}
|
||||
@@ -86,6 +48,8 @@
|
||||
z-index: 1;
|
||||
margin: 0 !important;
|
||||
top: 6.9em !important;
|
||||
-webkit-transition: -webkit-transform 0.2s ease-out;
|
||||
-o-transition: transform 0.2s ease-out;
|
||||
transition: transform 0.2s ease-out;
|
||||
}
|
||||
|
||||
@@ -94,14 +58,17 @@
|
||||
}
|
||||
|
||||
.headerUserImage {
|
||||
-webkit-background-size: contain;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
-webkit-border-radius: 100em;
|
||||
border-radius: 100em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.headerUserButtonRound div {
|
||||
-webkit-border-radius: 100em;
|
||||
border-radius: 100em;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
@@ -109,6 +76,7 @@
|
||||
}
|
||||
|
||||
.headerButton {
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -118,15 +86,23 @@
|
||||
|
||||
.headerLeft {
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.headerRight {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: end;
|
||||
-webkit-justify-content: flex-end;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@@ -136,10 +112,15 @@
|
||||
}
|
||||
|
||||
.pageTitle {
|
||||
display: -webkit-inline-box;
|
||||
display: -webkit-inline-flex;
|
||||
display: inline-flex;
|
||||
margin: 0 0 0 0.5em;
|
||||
height: 1.7em;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
-webkit-flex-shrink: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
@@ -149,16 +130,21 @@
|
||||
|
||||
.headerLeft,
|
||||
.skinHeader {
|
||||
display: flex;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
}
|
||||
|
||||
.detailButton,
|
||||
.skinHeader {
|
||||
flex-direction: column;
|
||||
-webkit-flex-direction: column;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
}
|
||||
|
||||
.pageTitleWithLogo {
|
||||
background-position: left center;
|
||||
-webkit-background-size: contain;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
width: 13.2em;
|
||||
@@ -177,12 +163,6 @@
|
||||
transition: background ease-in-out 0.5s;
|
||||
}
|
||||
|
||||
.layout-tv .skinHeader {
|
||||
/* In TV layout, it makes more sense to keep the top bar at the top of the page
|
||||
Having it follow the view only makes us lose vertical space, while not being focusable */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hiddenViewMenuBar .skinHeader {
|
||||
display: none;
|
||||
}
|
||||
@@ -204,19 +184,27 @@
|
||||
}
|
||||
|
||||
.navMenuOption {
|
||||
display: -webkit-box !important;
|
||||
display: -webkit-flex !important;
|
||||
display: flex !important;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
padding: 0.9em 0 0.9em 2.4em !important;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
flex-grow: 1;
|
||||
font-weight: 400 !important;
|
||||
margin: 0 !important;
|
||||
-webkit-border-radius: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.navMenuOptionIcon {
|
||||
margin-right: 1.2em;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -231,6 +219,8 @@
|
||||
}
|
||||
|
||||
.dashboardDocument .skinBody {
|
||||
-webkit-transition: left ease-in-out 0.3s, padding ease-in-out 0.3s;
|
||||
-o-transition: left ease-in-out 0.3s, padding ease-in-out 0.3s;
|
||||
transition: left ease-in-out 0.3s, padding ease-in-out 0.3s;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -246,6 +236,12 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.layout-desktop .searchTabButton,
|
||||
.layout-mobile .searchTabButton,
|
||||
.layout-tv .headerSearchButton {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mainDrawer-scrollContainer {
|
||||
padding-bottom: 10vh;
|
||||
}
|
||||
@@ -260,7 +256,9 @@
|
||||
z-index: inherit !important;
|
||||
left: 0 !important;
|
||||
top: 0 !important;
|
||||
-webkit-transform: none !important;
|
||||
transform: none !important;
|
||||
-webkit-box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
width: 20.205em !important;
|
||||
font-size: 94%;
|
||||
@@ -295,9 +293,14 @@
|
||||
}
|
||||
|
||||
.headerTabs {
|
||||
-webkit-align-self: center;
|
||||
align-self: center;
|
||||
width: auto;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
margin-top: -4.3em;
|
||||
@@ -354,6 +357,8 @@
|
||||
}
|
||||
|
||||
.flexPageTabContent.is-active {
|
||||
display: -webkit-box !important;
|
||||
display: -webkit-flex !important;
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
@@ -374,17 +379,13 @@
|
||||
margin: 1.5em 0;
|
||||
background: #222;
|
||||
padding: 0.8em 0.8em 0.8em 3em;
|
||||
-webkit-border-radius: 0.3em;
|
||||
border-radius: 0.3em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.detailLogo {
|
||||
width: 25vw;
|
||||
height: 16vh;
|
||||
position: absolute;
|
||||
top: 10vh;
|
||||
right: 25vw;
|
||||
background-size: contain;
|
||||
.detailLogo,
|
||||
.itemBackdrop {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
@@ -437,34 +438,32 @@
|
||||
}
|
||||
|
||||
.itemBackdrop {
|
||||
-webkit-background-size: cover;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
height: 40vh;
|
||||
position: relative;
|
||||
animation: backdrop-fadein 800ms ease-in normal both;
|
||||
|
||||
.layout-mobile & {
|
||||
background-attachment: initial;
|
||||
background-position: top center;
|
||||
margin-top: 3rem;
|
||||
|
||||
@media all and (orientation: portrait) and (max-width: 40em) {
|
||||
height: 30vh;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-desktop &::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-tv .itemBackdrop {
|
||||
.layout-mobile .itemBackdrop {
|
||||
background-attachment: scroll;
|
||||
height: 26.5vh;
|
||||
}
|
||||
|
||||
.layout-desktop .itemBackdrop::after,
|
||||
.layout-tv .itemBackdrop::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layout-desktop .noBackdrop .itemBackdrop,
|
||||
.layout-tv .noBackdrop .itemBackdrop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -473,18 +472,26 @@
|
||||
flex-direction: column;
|
||||
padding-left: 32.45vw;
|
||||
padding-right: 2%;
|
||||
}
|
||||
|
||||
.layout-mobile & {
|
||||
padding-left: 5%;
|
||||
padding-right: 5%;
|
||||
}
|
||||
.layout-mobile .detailPageContent {
|
||||
padding-left: 5%;
|
||||
padding-right: 5%;
|
||||
}
|
||||
|
||||
.layout-desktop &,
|
||||
.layout-tv & {
|
||||
.emby-scroller {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.layout-desktop .detailPageContent .emby-scroller,
|
||||
.layout-tv .detailPageContent .emby-scroller {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.layout-desktop .noBackdrop .detailPageContent,
|
||||
.layout-tv .noBackdrop .detailPageContent {
|
||||
margin-top: 2.5em;
|
||||
}
|
||||
|
||||
.layout-desktop .noBackdrop .detailImageContainer img,
|
||||
.layout-tv .noBackdrop .detailImageContainer img {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.detailSectionContent a {
|
||||
@@ -524,8 +531,14 @@
|
||||
margin: -0.25em 0 0.25em;
|
||||
}
|
||||
|
||||
.layout-mobile .itemExternalLinks {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mainDetailButtons {
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
margin: 1em 0;
|
||||
}
|
||||
@@ -533,19 +546,13 @@
|
||||
.detailButton,
|
||||
.mainDetailButtons {
|
||||
display: flex;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
}
|
||||
|
||||
.itemName {
|
||||
margin: 0.5em 0;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
|
||||
.layout-mobile & {
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.itemName.originalTitle {
|
||||
@@ -584,19 +591,14 @@
|
||||
}
|
||||
|
||||
.itemMiscInfo {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
|
||||
.layout-mobile & {
|
||||
@media all and (orientation: portrait) and (max-width: 40em) {
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
.mediaInfoItem {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout-mobile .parentName,
|
||||
@@ -611,28 +613,14 @@
|
||||
.layout-mobile .mainDetailButtons {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: 0;
|
||||
|
||||
@include header-poster-padding;
|
||||
|
||||
// The buttons row is full width on small screens
|
||||
@media all and (max-width: 32em) {
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin: 0.15em 0 0.2em;
|
||||
|
||||
// Leave room for a focused button
|
||||
margin-left: -1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.layout-mobile .subtitle {
|
||||
margin: 0.2em 0 0.2em;
|
||||
padding-left: 0; // Reset padding for focused button since 'margin-left' is 0
|
||||
}
|
||||
|
||||
.detailPagePrimaryContainer {
|
||||
@@ -640,52 +628,47 @@
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
z-index: 2;
|
||||
|
||||
.layout-mobile & {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 0.5rem 5%;
|
||||
}
|
||||
|
||||
.layout-desktop & {
|
||||
position: relative;
|
||||
padding-left: 32.45vw;
|
||||
}
|
||||
|
||||
.layout-tv & {
|
||||
display: block;
|
||||
padding-left: 32.45vw;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-desktop .detailRibbon {
|
||||
.layout-mobile .detailPagePrimaryContainer {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 0.5em 3.3% 0.5em;
|
||||
}
|
||||
|
||||
.layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer,
|
||||
.layout-desktop #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer {
|
||||
position: relative;
|
||||
top: 0;
|
||||
padding-left: 32.45vw;
|
||||
}
|
||||
|
||||
.layout-desktop .detailRibbon,
|
||||
.layout-tv .detailRibbon {
|
||||
margin-top: -7.2em;
|
||||
height: 7.2em;
|
||||
}
|
||||
|
||||
.layout-tv .detailRibbon {
|
||||
.layout-desktop .noBackdrop .detailRibbon,
|
||||
.layout-tv .noBackdrop .detailRibbon {
|
||||
margin-top: 0;
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
.infoWrapper {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
flex: 1 0 0;
|
||||
|
||||
.layout-mobile & {
|
||||
@include header-poster-padding;
|
||||
|
||||
@media all and (max-width: 32em) {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.infoText {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-align: left;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.layout-mobile .infoText {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.detailPageSecondaryContainer {
|
||||
@@ -696,66 +679,46 @@
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.layout-mobile .detailImageContainer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.detailImageContainer .card {
|
||||
// important is needed here to override :focus setting
|
||||
// the position to relative in the tv layout
|
||||
position: absolute !important;
|
||||
top: 20%;
|
||||
max-width: 25vw;
|
||||
max-height: 80vh;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
float: left;
|
||||
width: 25vw;
|
||||
z-index: 3;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.cardBox {
|
||||
margin: 0;
|
||||
}
|
||||
.detailImageContainer .card.backdropCard {
|
||||
top: 35%;
|
||||
}
|
||||
|
||||
&.backdropCard {
|
||||
top: 35%;
|
||||
}
|
||||
.detailImageContainer .card.squareCard {
|
||||
top: 40%;
|
||||
}
|
||||
|
||||
&.squareCard {
|
||||
top: 40%;
|
||||
}
|
||||
|
||||
.layout-mobile & {
|
||||
left: 5%;
|
||||
bottom: 1rem;
|
||||
max-width: 30vw;
|
||||
filter: drop-shadow(0 0 0.5rem #000);
|
||||
|
||||
@media all and (max-width: 32em) {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&,
|
||||
&.backdropCard,
|
||||
&.squareCard {
|
||||
top: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-desktop & {
|
||||
left: 3.3%;
|
||||
top: -80%;
|
||||
width: 25vw;
|
||||
// FIXME: the fixed width + max height cause the card to be cropped this needs a proper fix
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.layout-tv & {
|
||||
left: 5%;
|
||||
top: 50%;
|
||||
width: 25vw;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.layout-desktop .noBackdrop .detailImageContainer,
|
||||
.layout-tv .noBackdrop .detailImageContainer {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.detailPagePrimaryContent {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layout-mobile .detailLogo {
|
||||
.detailLogo {
|
||||
width: 25vw;
|
||||
height: 16vh;
|
||||
position: absolute;
|
||||
top: 10vh;
|
||||
right: 25vw;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.noBackdrop .detailLogo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -767,6 +730,7 @@
|
||||
|
||||
.itemDetailImage {
|
||||
width: 100% !important;
|
||||
-webkit-box-shadow: 0 0.1em 0.5em 0 rgba(0, 0, 0, 0.75);
|
||||
box-shadow: 0 0.1em 0.5em 0 rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
@@ -779,17 +743,6 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
height: 23vw;
|
||||
}
|
||||
|
||||
.sectionTitleTextButton > .material-icons {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 0.35em;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.layout-mobile .sectionTitleTextButton > .material-icons {
|
||||
margin-bottom: 0;
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
|
||||
.itemDetailGalleryLink.defaultCardBackground > .material-icons {
|
||||
font-size: 15vw;
|
||||
margin-top: 50%;
|
||||
@@ -801,7 +754,8 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layout-desktop .itemBackdrop {
|
||||
.layout-desktop .itemBackdrop,
|
||||
.layout-tv .itemBackdrop {
|
||||
height: 40vh;
|
||||
}
|
||||
|
||||
@@ -827,8 +781,13 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
}
|
||||
|
||||
.emby-button.detailFloatingButton {
|
||||
font-size: 1.4em;
|
||||
margin-right: 0.5em !important;
|
||||
position: absolute;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 3;
|
||||
top: 100%;
|
||||
left: 90%;
|
||||
margin: -2.2em 0 0 -2.2em;
|
||||
padding: 0.4em;
|
||||
color: rgba(255, 255, 255, 0.76);
|
||||
}
|
||||
|
||||
@@ -873,6 +832,7 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
.recordingFields button {
|
||||
margin-left: 0;
|
||||
margin-right: 0.5em;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -883,10 +843,14 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
.detailButton {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
margin: 0 !important;
|
||||
padding: 0.7em 0.7em !important;
|
||||
padding: 0.5em 0.7em !important;
|
||||
}
|
||||
|
||||
@media all and (min-width: 29em) {
|
||||
@@ -911,9 +875,18 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
}
|
||||
|
||||
.detailButton-content {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@@ -946,6 +919,10 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
}
|
||||
|
||||
@media all and (min-width: 100em) {
|
||||
.detailFloatingButton {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.personBackdrop {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -954,11 +931,6 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
font-size: 108%;
|
||||
margin: 1.25em 0;
|
||||
}
|
||||
|
||||
.layout-tv .mainDetailButtons {
|
||||
font-size: 108%;
|
||||
margin: 1em 0 1.25em;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 50em) {
|
||||
@@ -970,6 +942,8 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
@media all and (max-width: 31.25em) {
|
||||
.mobileDetails .itemMiscInfo {
|
||||
text-align: center;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@@ -991,8 +965,9 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.mediaInfoContent .btnCopy .material-icons {
|
||||
font-size: inherit;
|
||||
.layout-desktop .noBackdrop .detailPageWrapperContainer,
|
||||
.layout-tv .noBackdrop .detailPageWrapperContainer {
|
||||
margin-top: 3.8em;
|
||||
}
|
||||
|
||||
.mediaInfoStream {
|
||||
@@ -1003,10 +978,6 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
|
||||
.mediaInfoStreamType {
|
||||
display: block;
|
||||
margin: 0.622em 0; /* copy button height compensation */
|
||||
}
|
||||
|
||||
.layout-tv .mediaInfoStreamType {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
@@ -1058,9 +1029,14 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
}
|
||||
|
||||
.mediaInfoIcons {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
margin: 1em 0;
|
||||
-webkit-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@@ -1075,7 +1051,7 @@ div.itemDetailGalleryLink.defaultCardBackground {
|
||||
.sectionTitleButton,
|
||||
.sectionTitleIconButton {
|
||||
margin-right: 0 !important;
|
||||
display: inline-flex;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@@ -1108,6 +1084,7 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||
|
||||
.sectionTitleButton {
|
||||
margin-left: 1.5em !important;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -1117,17 +1094,22 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||
|
||||
.sectionTitleIconButton {
|
||||
margin-left: 1.5em !important;
|
||||
-webkit-flex-shrink: 0;
|
||||
flex-shrink: 0;
|
||||
font-size: 84% !important;
|
||||
padding: 0.5em !important;
|
||||
}
|
||||
|
||||
.horizontalItemsContainer {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.sectionTitleTextButton {
|
||||
margin: 0 !important;
|
||||
display: -webkit-inline-box !important;
|
||||
display: -webkit-inline-flex !important;
|
||||
display: inline-flex !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
@@ -1164,13 +1146,13 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||
}
|
||||
|
||||
.layout-tv .padded-top-focusscale {
|
||||
padding-top: 1.5em;
|
||||
margin-top: -1.5em;
|
||||
padding-top: 1em;
|
||||
margin-top: -1em;
|
||||
}
|
||||
|
||||
.layout-tv .padded-bottom-focusscale {
|
||||
padding-bottom: 1.5em;
|
||||
margin-bottom: -1.5em;
|
||||
padding-bottom: 1em;
|
||||
margin-bottom: -1em;
|
||||
}
|
||||
|
||||
@media all and (min-height: 31.25em) {
|
||||
@@ -1195,6 +1177,8 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||
}
|
||||
|
||||
.itemsViewSettingsContainer {
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@@ -1219,7 +1203,7 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
|
||||
}
|
||||
|
||||
.itemDetailsGroup {
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.trackSelections {
|
||||
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,14 +0,0 @@
|
||||
.guideVerticalScroller {
|
||||
padding-bottom: 15em;
|
||||
}
|
||||
|
||||
#guideTab {
|
||||
@media all and (min-width: 62.5em) {
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: background sizing for cards really needs revisited, but these are particularly terrible
|
||||
#channelsTab .cardImageContainer {
|
||||
background-size: contain;
|
||||
}
|
||||
@@ -1,19 +1,14 @@
|
||||
@mixin fullpage {
|
||||
body,
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
@include fullpage;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
body {
|
||||
@include fullpage;
|
||||
overflow-x: hidden;
|
||||
background-color: transparent !important;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
.layout-mobile,
|
||||
.layout-tv {
|
||||
-webkit-touch-callout: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.clipForScreenReader {
|
||||
@@ -41,10 +36,14 @@ body {
|
||||
contain: strict;
|
||||
}
|
||||
|
||||
.layout-mobile,
|
||||
.layout-tv {
|
||||
-webkit-touch-callout: none;
|
||||
user-select: none;
|
||||
html {
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
background-color: transparent !important;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.mainAnimatedPage {
|
||||
@@ -59,7 +58,7 @@ body {
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
|
||||
div[data-role="page"] {
|
||||
div[data-role=page] {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
@@ -72,10 +71,10 @@ div[data-role="page"] {
|
||||
padding-left: 0.15em;
|
||||
font-weight: 400;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
+ .fieldDescription {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
.fieldDescription + .fieldDescription {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
|
||||
.content-primary,
|
||||
@@ -86,14 +85,9 @@ div[data-role="page"] {
|
||||
padding-bottom: 5em !important;
|
||||
}
|
||||
|
||||
.readOnlyContent {
|
||||
@media all and (min-width: 50em) {
|
||||
max-width: 54em;
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
@media all and (min-width: 50em) {
|
||||
@media all and (min-width: 50em) {
|
||||
.readOnlyContent,
|
||||
form {
|
||||
max-width: 54em;
|
||||
}
|
||||
}
|
||||
@@ -113,14 +107,14 @@ form {
|
||||
.headroom {
|
||||
will-change: transform;
|
||||
transition: transform 200ms linear;
|
||||
}
|
||||
|
||||
&--pinned {
|
||||
transform: translateY(0%);
|
||||
}
|
||||
.headroom--pinned {
|
||||
transform: translateY(0%);
|
||||
}
|
||||
|
||||
&--unpinned {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
.headroom--unpinned {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.drawerContent {
|
||||
@@ -135,17 +129,3 @@ form {
|
||||
.hide-scroll {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.margin-auto-x {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.margin-auto-y {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
@@ -6,45 +6,29 @@
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.osdPoster img,
|
||||
.videoOsdBottom {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
position: fixed;
|
||||
background: linear-gradient(0deg, rgba(16, 16, 16, 0.75) 0%, rgba(16, 16, 16, 0) 100%);
|
||||
padding-top: 7.5em;
|
||||
padding-bottom: 1.75em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
will-change: opacity;
|
||||
transition: opacity 0.3s ease-out;
|
||||
color: #fff;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.skinHeader-withBackground.osdHeader {
|
||||
.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: linear-gradient(180deg, rgba(16, 16, 16, 0.75) 0%, rgba(16, 16, 16, 0) 100%);
|
||||
backdrop-filter: none;
|
||||
color: #eee;
|
||||
height: 7.5em;
|
||||
pointer-events: none;
|
||||
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 .headerTop {
|
||||
pointer-events: all;
|
||||
max-height: 3.5em;
|
||||
}
|
||||
|
||||
.osdHeader .headerButton:not(.headerBackButton):not(.headerCastButton):not(.headerSyncButton) {
|
||||
display: none;
|
||||
}
|
||||
@@ -102,18 +86,34 @@
|
||||
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 {
|
||||
pointer-events: all;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex-grow: 1;
|
||||
flex-grow: 1;
|
||||
padding: 0 0.8em;
|
||||
}
|
||||
|
||||
.layout-desktop .osdControls {
|
||||
max-width: calc(100vh * 1.77 - 2vh);
|
||||
}
|
||||
|
||||
.videoOsdBottom .buttons {
|
||||
@@ -145,7 +145,7 @@
|
||||
}
|
||||
|
||||
.volumeButtons {
|
||||
margin: 0 1em 0 0.29em;
|
||||
margin: 0 0.5em 0 auto;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
align-items: center;
|
||||
@@ -153,13 +153,33 @@
|
||||
|
||||
.osdTimeText {
|
||||
margin-left: 1em;
|
||||
margin-right: auto;
|
||||
-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;
|
||||
@@ -228,6 +248,8 @@
|
||||
}
|
||||
|
||||
@media all and (max-width: 30em) {
|
||||
.btnFastForward,
|
||||
.btnRewind,
|
||||
.osdMediaInfo,
|
||||
.osdPoster {
|
||||
display: none !important;
|
||||
@@ -259,119 +281,3 @@
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.syncPlayContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.primary-icon {
|
||||
position: absolute;
|
||||
font-size: 64px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.primary-icon.spin {
|
||||
font-size: 76px !important;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
.secondary-icon {
|
||||
position: absolute;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.secondary-icon.centered {
|
||||
font-size: 28px !important;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.secondary-icon.shifted {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
font-size: 52px;
|
||||
}
|
||||
|
||||
.syncPlayIconCircle {
|
||||
position: relative;
|
||||
visibility: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
border-radius: 50%;
|
||||
margin: 60px;
|
||||
height: 96px;
|
||||
width: 96px;
|
||||
|
||||
color: rgba(0, 164, 220, 0);
|
||||
background: rgba(0, 164, 220, 0);
|
||||
box-shadow: 0 0 0 0 rgba(0, 164, 220, 0);
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.syncPlayIconCircle.oneShotPulse {
|
||||
animation: pulse 1.5s 1;
|
||||
}
|
||||
|
||||
.syncPlayIconCircle.infinitePulse {
|
||||
animation: infinite-pulse 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
transform: scale(0.95);
|
||||
color: rgba(0, 164, 220, 0.7);
|
||||
background: rgba(0, 164, 220, 0.3);
|
||||
box-shadow: 0 0 0 0 rgba(0, 164, 220, 0.3);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(1);
|
||||
color: rgba(0, 164, 220, 0);
|
||||
background: rgba(0, 164, 220, 0);
|
||||
box-shadow: 0 0 0 60px rgba(0, 164, 220, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0.95);
|
||||
color: rgba(0, 164, 220, 0);
|
||||
background: rgba(0, 164, 220, 0);
|
||||
box-shadow: 0 0 0 0 rgba(0, 164, 220, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes infinite-pulse {
|
||||
0% {
|
||||
transform: scale(0.95);
|
||||
color: rgba(0, 164, 220, 0.7);
|
||||
background: rgba(0, 164, 220, 0.3);
|
||||
box-shadow: 0 0 0 0 rgba(0, 164, 220, 0.3);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(1);
|
||||
color: rgba(0, 164, 220, 0.6);
|
||||
background: rgba(0, 164, 220, 0);
|
||||
box-shadow: 0 0 0 60px rgba(0, 164, 220, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0.95);
|
||||
color: rgba(0, 164, 220, 0.7);
|
||||
background: rgba(0, 164, 220, 0.3);
|
||||
box-shadow: 0 0 0 0 rgba(0, 164, 220, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 3.5 KiB |
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Apple</title><path d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 663 B |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 43 KiB |