Compare commits

..

21 Commits

Author SHA1 Message Date
dkanada
bc66fadb0e Merge pull request #613 from redSpoutnik/reset-subtitle-sync
reset subtitle offset on next episode play

(cherry picked from commit b67e31791d)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-12-06 10:53:02 -05:00
dkanada
298d8d7929 Merge pull request #612 from grafixeyehero/fix-searchresult-btnscroller
Fix Scroll arrows missing when searching

(cherry picked from commit b35a6e17eb)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-12-06 10:52:38 -05:00
dkanada
bdf8553728 Merge pull request #610 from YouKnowBlom/library-path-fix
Fix existing library folder path returning undefined

(cherry picked from commit 50ca98b2a2)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-12-06 10:52:13 -05:00
dkanada
8ac155fb7a Merge pull request #604 from grafixeyehero/collection-padding
Fix collection padding in TV layout

(cherry picked from commit ba8949aa36)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-12-06 10:51:54 -05:00
dkanada
54dee197fd Merge pull request #596 from Wunax/fix-input-user-avatar
Fix input field user avatar in a wrong position

(cherry picked from commit a9c1425ddd)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-12-06 10:49:37 -05:00
dkanada
7a3eb3ffad Merge pull request #594 from grafixeyehero/backdrop
Fix some issues with the backdrop image

(cherry picked from commit 78fd41ef05)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-12-06 10:46:27 -05:00
Joshua Boniface
15b987e0de Bump version for 10.4.3 2019-12-06 10:44:58 -05:00
dkanada
54b05ab27d Merge pull request #545 from ferferga/artworks2
Improved appearance of images and artworks - Part 3

(cherry picked from commit 79cd6a7552)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-11-24 15:45:05 -05:00
dkanada
e1308f01b6 Merge pull request #576 from anthonylavado/fix-manifest
Remove the leading /web/ from the manifest to avoid PWA titles

(cherry picked from commit 88db651eea)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-11-24 15:44:19 -05:00
dkanada
c596c19bfd Merge pull request #583 from Wunax/fix-player-aspect-ratio
Fixed set aspect ratio option in the player

(cherry picked from commit dca0700770)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-11-24 15:39:50 -05:00
dkanada
087d06debf Merge pull request #578 from ryan-hartzell/login-autofill-attributes
Add autocomplete attributes to login fields

(cherry picked from commit 109ea9e50c)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-11-24 15:39:38 -05:00
Joshua Boniface
0b4402b642 Bump version for 10.4.2 2019-11-24 15:37:19 -05:00
Joshua M. Boniface
b36369b562 Merge pull request #540 from grafixeyehero/identify-path
Add file path to itemidentifier

(cherry picked from commit 3ad7993d13)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-26 11:48:46 -04:00
Joshua M. Boniface
78a2ba73e7 Merge pull request #507 from redSpoutnik/fix-subtitle-sync
Fix subtitle sync

(cherry picked from commit ee1149644d)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-26 11:47:44 -04:00
Joshua M. Boniface
1be5e20363 Merge pull request #550 from grafixeyehero/metadata-editor-livetvloading
Fix Metadata Manager Live TV Loading..

(cherry picked from commit 47b8c2bcb3)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-26 11:45:26 -04:00
Joshua M. Boniface
9a130f5869 Merge pull request #542 from grafixeyehero/wizardfinsih
Improve wizard finish page redirect

(cherry picked from commit 5eb6a4b5ba)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-24 09:36:37 -04:00
Joshua M. Boniface
d6cec24d9e Merge pull request #519 from dhartung/fix-#518
Fix subtitle display from previous file in queue

(cherry picked from commit 6208f2b1c3)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-23 11:39:34 -04:00
dkanada
2044efc0c3 Merge pull request #524 from grafixeyehero/Live-TV-Pagination
Fix minor style on home section Live TV

(cherry picked from commit a5e71664ba)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-23 11:35:53 -04:00
Vasily
e12a8bc39d Merge pull request #513 from thornbill/fix-swiper
Revert Swiper to fix initialization error

(cherry picked from commit 66f3de495b)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-20 14:46:17 -04:00
Vasily
a885964e46 Merge pull request #521 from dkanada/nowplaying
Fix save button in now playing controller

(cherry picked from commit 5ce69ae514)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-20 14:44:40 -04:00
Vasily
efdc07e032 Merge pull request #523 from grafixeyehero/itemcontextmenu-icon
Add icon on item context menu

(cherry picked from commit d4862df266)
Signed-off-by: Joshua Boniface <joshua@boniface.me>
2019-10-20 14:44:16 -04:00
972 changed files with 91289 additions and 163344 deletions

View File

@@ -1,57 +0,0 @@
jobs:
- job: Build
displayName: 'Build'
strategy:
matrix:
Development:
BuildConfiguration: development
Production:
BuildConfiguration: production
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Install Node'
inputs:
versionSpec: '12.x'
- task: Cache@2
displayName: 'Cache node_modules'
inputs:
key: 'npm | package-lock.json'
path: 'node_modules'
- script: 'npm ci --no-audit'
displayName: 'Install Dependencies'
env:
SKIP_PREPARE: 'true'
- script: 'npm run build:development'
displayName: 'Build Development'
condition: eq(variables['BuildConfiguration'], 'development')
- script: 'npm run build:production'
displayName: 'Build Production'
condition: eq(variables['BuildConfiguration'], 'production')
- script: 'test -d dist'
displayName: 'Check Build'
- script: 'mv dist jellyfin-web'
displayName: 'Rename Directory'
- task: ArchiveFiles@2
displayName: 'Archive Directory'
inputs:
rootFolderOrFile: 'jellyfin-web'
includeRootFolder: true
archiveFile: 'jellyfin-web-$(BuildConfiguration)'
- task: PublishPipelineArtifact@1
displayName: 'Publish Release'
inputs:
targetPath: '$(Build.SourcesDirectory)/jellyfin-web-$(BuildConfiguration).zip'
artifactName: 'jellyfin-web-$(BuildConfiguration)'

View File

@@ -1,126 +0,0 @@
jobs:
- job: BuildPackage
displayName: 'Build Packages'
strategy:
matrix:
CentOS:
BuildConfiguration: centos
Debian:
BuildConfiguration: debian
Fedora:
BuildConfiguration: fedora
Portable:
BuildConfiguration: portable
pool:
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'))
- script: 'docker image ls -a && docker run -v $(pwd)/deployment/dist:/dist -v $(pwd):/jellyfin -e IS_UNSTABLE="yes" -e BUILD_ID=$(Build.BuildNumber) jellyfin-web-$(BuildConfiguration)'
displayName: 'Run Dockerfile (unstable)'
condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/master')
- script: 'docker image ls -a && docker run -v $(pwd)/deployment/dist:/dist -v $(pwd):/jellyfin -e IS_UNSTABLE="no" -e BUILD_ID=$(Build.BuildNumber) jellyfin-web-$(BuildConfiguration)'
displayName: 'Run Dockerfile (stable)'
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags')
- task: PublishPipelineArtifact@1
displayName: 'Publish Release'
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))
inputs:
targetPath: '$(Build.SourcesDirectory)/deployment/dist'
artifactName: 'jellyfin-web-$(BuildConfiguration)'
- task: SSH@0
displayName: 'Create target directory on repository server'
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))
inputs:
sshEndpoint: repository
runOptions: 'inline'
inline: 'mkdir -p /srv/repository/incoming/azure/$(Build.BuildNumber)/$(BuildConfiguration)'
- task: CopyFilesOverSSH@0
displayName: 'Upload artifacts to repository server'
condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))
inputs:
sshEndpoint: repository
sourceFolder: '$(Build.SourcesDirectory)/deployment/dist'
contents: '**'
targetFolder: '/srv/repository/incoming/azure/$(Build.BuildNumber)/$(BuildConfiguration)'
- job: BuildDocker
displayName: 'Build Docker'
pool:
vmImage: 'ubuntu-latest'
variables:
- name: JellyfinVersion
value: 0.0.0
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')
- task: Docker@2
displayName: 'Push Unstable Image'
condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/master')
inputs:
repository: 'jellyfin/jellyfin-web'
command: buildAndPush
buildContext: '.'
Dockerfile: 'deployment/Dockerfile.docker'
containerRegistry: Docker Hub
tags: |
unstable-$(Build.BuildNumber)
unstable
- task: Docker@2
displayName: 'Push Stable Image'
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags')
inputs:
repository: 'jellyfin/jellyfin-web'
command: buildAndPush
buildContext: '.'
Dockerfile: 'deployment/Dockerfile.docker'
containerRegistry: Docker Hub
tags: |
stable-$(Build.BuildNumber)
$(JellyfinVersion)
- job: CollectArtifacts
displayName: 'Collect Artifacts'
dependsOn:
- BuildPackage
- BuildDocker
condition: and(succeeded('BuildPackage'), succeeded('BuildDocker'))
pool:
vmImage: 'ubuntu-latest'
steps:
- task: SSH@0
displayName: 'Update Unstable Repository'
condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/master')
inputs:
sshEndpoint: repository
runOptions: 'inline'
inline: 'sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber) unstable'
- task: SSH@0
displayName: 'Update Stable Repository'
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags')
inputs:
sshEndpoint: repository
runOptions: 'inline'
inline: 'sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber) $(Build.SourceBranch)'

View File

@@ -2,15 +2,63 @@ trigger:
batch: true
branches:
include:
- '*'
- master
- release-*
tags:
include:
- '*'
pr:
branches:
include:
- '*'
jobs:
- template: azure-pipelines-build.yml
- template: azure-pipelines-package.yml
- job: main_build
displayName: 'Main Build'
dependsOn: lint
condition: succeeded()
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Install Node.js'
inputs:
versionSpec: '10.x'
- script: |
yarn install
displayName: 'Install dependencies'
- script: |
test -d dist
displayName: 'Check dist directory'
- script: |
yarn pack --filename jellyfin-web.tgz
displayName: 'Build package'
- task: PublishPipelineArtifact@1
displayName: 'Publish package'
condition: succeeded()
inputs:
targetPath: '$(Build.SourcesDirectory)/jellyfin-web.tgz'
artifactName: 'jellyfin-web'
- job: lint
displayName: 'Lint'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Install Node.js'
inputs:
versionSpec: '10.x'
- script: |
yarn install
displayName: 'Install dependencies'
- script: |
yarn run lint
displayName: 'Run ESLint'

1
.copr
View File

@@ -1 +0,0 @@
fedora/

View File

@@ -7,6 +7,3 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
[*.json]
indent_size = 2

View File

@@ -1,4 +0,0 @@
node_modules
dist
.idea
.vscode

View File

@@ -1,232 +0,0 @@
const restrictedGlobals = require('confusing-browser-globals');
module.exports = {
root: true,
plugins: [
'@babel',
'react',
'promise',
'import',
'eslint-comments'
],
env: {
node: true,
es6: true,
es2017: true,
es2020: true
},
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
ecmaFeatures: {
impliedStrict: true,
jsx: true
}
},
extends: [
'eslint:recommended',
'plugin:react/recommended',
// 'plugin:promise/recommended',
'plugin:import/errors',
'plugin:eslint-comments/recommended',
'plugin:compat/recommended'
],
rules: {
'array-callback-return': ['error'],
'block-spacing': ['error'],
'brace-style': ['error', '1tbs', { 'allowSingleLine': true }],
'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'],
'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'
]
},
overrides: [
{
files: [
'./src/**/*.js',
'./src/**/*.ts'
],
parser: '@babel/eslint-parser',
env: {
node: false,
amd: true,
browser: true,
es6: true,
es2017: true,
es2020: true
},
globals: {
// Browser globals
'MediaMetadata': 'readonly',
// Tizen globals
'tizen': 'readonly',
'webapis': 'readonly',
// WebOS globals
'webOS': 'readonly',
// Dependency globals
'$': 'readonly',
'jQuery': 'readonly',
// Jellyfin globals
'ApiClient': 'writable',
'Events': 'writable',
'chrome': 'writable',
'DlnaProfilePage': 'writable',
'DashboardPage': 'writable',
'Emby': 'readonly',
'getParameterByName': 'writable',
'getWindowLocationSearch': 'writable',
'Globalize': 'writable',
'Hls': 'writable',
'dfnshelper': 'writable',
'LibraryMenu': 'writable',
'LinkParser': 'writable',
'LiveTvHelpers': 'writable',
'Loading': 'writable',
'MetadataEditor': 'writable',
'PlaylistViewer': 'writable',
'ServerNotifications': 'writable',
'TaskButton': 'writable',
'UserParentalControlPage': 'writable',
'Windows': 'readonly'
},
rules: {
}
},
{
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
.eslintrc.yml Normal file
View File

@@ -0,0 +1,4 @@
env:
es6: true
browser: true
amd: true

36
.gitattributes vendored
View File

@@ -1,35 +1 @@
* text=auto
CONTRIBUTORS.md merge=union
README.md text
LICENSE text
*.css text
*.eot binary
*.gif binary
*.html text diff=html
*.ico binary
*.*ignore text
*.jpg binary
*.js text
*.json text
*.lock text -diff
*.map text -diff
*.md text
*.otf binary
*.png binary
*.py text diff=python
*.svg binary
*.ts text
*.ttf binary
*.sass text
*.vue text
*.webp binary
*.woff binary
*.woff2 binary
.editorconfig text
.gitattributes export-ignore
.gitignore export-ignore
*.gitattributes linguist-language=gitattributes
/CONTRIBUTORS.md merge=union

6
.github/CODEOWNERS vendored
View File

@@ -1,6 +0,0 @@
.ci @dkanada @EraYaN
.github @jellyfin/core
fedora @joshuaboniface
debian @joshuaboniface
.copr @joshuaboniface
deployment @joshuaboniface

View File

@@ -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. -->

View File

@@ -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. -->

View File

@@ -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]
* [ ] ...

View File

@@ -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. -->

View File

@@ -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
View File

@@ -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
View File

@@ -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"
}

19
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
# 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
# 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

View File

@@ -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 }}

View File

@@ -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

View File

@@ -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 }}

View File

@@ -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

View File

@@ -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).

586
.gitignore vendored
View File

@@ -1,21 +1,575 @@
# npm
dist
web
node_modules
# config
config.json
# Created by https://www.gitignore.io/api/node,rider,macos,linux,windows,visualstudio,visualstudiocode
# Edit at https://www.gitignore.io/?templates=node,rider,macos,linux,windows,visualstudio,visualstudiocode
# ide
.idea
.vscode
### Linux ###
*~
# log
yarn-error.log
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# vim
*.sw?
# KDE directory preferences
.directory
# build artifacts
fedora/jellyfin-web-*.src.rpm
fedora/jellyfin-web-*.tar.gz
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
### Rider ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
### Windows ###
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
### VisualStudio ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true
**/wwwroot/lib/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- Backup*.rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# End of https://www.gitignore.io/api/node,rider,macos,linux,windows,visualstudio,visualstudiocode
# dist for webpack output
dist

2
.npmrc
View File

@@ -1,2 +0,0 @@
fund=false
save-exact=true

View File

@@ -1,142 +0,0 @@
{
"plugins": [
"stylelint-no-browser-hacks/lib"
],
"rules": {
"at-rule-empty-line-before": [ "always", {
"except": [
"blockless-after-same-name-blockless",
"first-nested"
],
"ignore": ["after-comment"]
} ],
"at-rule-name-case": "lower",
"at-rule-name-space-after": "always-single-line",
"at-rule-no-unknown": true,
"at-rule-semicolon-newline-after": "always",
"block-closing-brace-empty-line-before": "never",
"block-closing-brace-newline-after": "always",
"block-closing-brace-newline-before": "always-multi-line",
"block-closing-brace-space-before": "always-single-line",
"block-no-empty": true,
"block-opening-brace-newline-after": "always-multi-line",
"block-opening-brace-space-after": "always-single-line",
"block-opening-brace-space-before": "always",
"color-hex-case": "lower",
"color-hex-length": "short",
"color-no-invalid-hex": true,
"comment-empty-line-before": [ "always", {
"except": ["first-nested"],
"ignore": ["stylelint-commands"]
} ],
"comment-no-empty": true,
"comment-whitespace-inside": "always",
"custom-property-empty-line-before": [ "always", {
"except": [
"after-custom-property",
"first-nested"
],
"ignore": [
"after-comment",
"inside-single-line-block"
]
} ],
"declaration-bang-space-after": "never",
"declaration-bang-space-before": "always",
"declaration-block-no-duplicate-properties": [
true,
{
"ignore": ["consecutive-duplicates-with-different-values"]
}
],
"declaration-block-no-shorthand-property-overrides": true,
"declaration-block-semicolon-newline-after": "always-multi-line",
"declaration-block-semicolon-space-after": "always-single-line",
"declaration-block-semicolon-space-before": "never",
"declaration-block-single-line-max-declarations": 1,
"declaration-block-trailing-semicolon": "always",
"declaration-colon-newline-after": "always-multi-line",
"declaration-colon-space-after": "always-single-line",
"declaration-colon-space-before": "never",
"font-family-no-duplicate-names": true,
"function-calc-no-unspaced-operator": true,
"function-comma-newline-after": "always-multi-line",
"function-comma-space-after": "always-single-line",
"function-comma-space-before": "never",
"function-linear-gradient-no-nonstandard-direction": true,
"function-max-empty-lines": 0,
"function-name-case": "lower",
"function-parentheses-newline-inside": "always-multi-line",
"function-parentheses-space-inside": "never-single-line",
"function-whitespace-after": "always",
"indentation": 4,
"keyframe-declaration-no-important": true,
"length-zero-no-unit": true,
"max-empty-lines": 1,
"media-feature-colon-space-after": "always",
"media-feature-colon-space-before": "never",
"media-feature-name-case": "lower",
"media-feature-name-no-unknown": true,
"media-feature-parentheses-space-inside": "never",
"media-feature-range-operator-space-after": "always",
"media-feature-range-operator-space-before": "always",
"media-query-list-comma-newline-after": "always-multi-line",
"media-query-list-comma-space-after": "always-single-line",
"media-query-list-comma-space-before": "never",
"no-descending-specificity": true,
"no-duplicate-at-import-rules": true,
"no-duplicate-selectors": true,
"no-empty-source": true,
"no-eol-whitespace": true,
"no-extra-semicolons": true,
"no-invalid-double-slash-comments": true,
"no-missing-end-of-source-newline": true,
"number-leading-zero": "always",
"number-no-trailing-zeros": true,
"plugin/no-browser-hacks": true,
"property-case": "lower",
"property-no-unknown": [
true,
{
"ignoreProperties": [
"user-drag"
]
}
],
"rule-empty-line-before": [ "always-multi-line", {
"except": ["first-nested"],
"ignore": ["after-comment"]
} ],
"selector-attribute-brackets-space-inside": "never",
"selector-attribute-operator-space-after": "never",
"selector-attribute-operator-space-before": "never",
"selector-combinator-space-after": "always",
"selector-combinator-space-before": "always",
"selector-descendant-combinator-no-non-space": true,
"selector-list-comma-newline-after": "always",
"selector-list-comma-space-before": "never",
"selector-max-empty-lines": 0,
"selector-pseudo-class-case": "lower",
"selector-pseudo-class-no-unknown": true,
"selector-pseudo-class-parentheses-space-inside": "never",
"selector-pseudo-element-case": "lower",
"selector-pseudo-element-colon-notation": "double",
"selector-pseudo-element-no-unknown": [
true,
{
"ignorePseudoElements": [
"cue"
]
}
],
"selector-type-case": "lower",
"selector-type-no-unknown": true,
"string-no-newline": true,
"unit-case": "lower",
"unit-no-unknown": true,
"value-list-comma-newline-after": "always-multi-line",
"value-list-comma-space-after": "always-single-line",
"value-list-comma-space-before": "never",
"value-list-max-empty-lines": 0
}
}

View File

@@ -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
}
}

View File

@@ -32,27 +32,6 @@
- [bilde2910](https://github.com/bilde2910)
- [Daniel Hartung](https://github.com/dhartung)
- [Ryan Hartzell](https://github.com/ryan-hartzell)
- [Thibault Nocchi](https://github.com/ThibaultNocchi)
- [MrTimscampi](https://github.com/MrTimscampi)
- [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 +95,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)

View File

@@ -1,72 +1,15 @@
<h1 align="center">Jellyfin Web</h1>
<h3 align="center">Part of the <a href="https://jellyfin.org">Jellyfin Project</a></h3>
<h3 align="center">The Free Software Media System</h3>
---
<p align="center">
<img alt="Logo Banner" src="https://raw.githubusercontent.com/jellyfin/jellyfin-ux/master/branding/SVG/banner-logo-solid.svg?sanitize=true"/>
<br/>
<br/>
<a href="https://github.com/jellyfin/jellyfin-web">
<img alt="GPL 2.0 License" src="https://img.shields.io/github/license/jellyfin/jellyfin-web.svg"/>
</a>
<a href="https://github.com/jellyfin/jellyfin-web/releases">
<img alt="Current Release" src="https://img.shields.io/github/release/jellyfin/jellyfin-web.svg"/>
</a>
<a href="https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/?utm_source=widget">
<img src="https://translate.jellyfin.org/widgets/jellyfin/-/jellyfin-web/svg-badge.svg" alt="Translation Status"/>
</a>
<br/>
<a href="https://opencollective.com/jellyfin">
<img alt="Donate" src="https://img.shields.io/opencollective/all/jellyfin.svg?label=backers"/>
</a>
<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://matrix.to/#/+jellyfin:matrix.org">
<img alt="Chat on Matrix" src="https://img.shields.io/matrix/jellyfin:matrix.org.svg?logo=matrix"/>
</a>
<a href="https://www.reddit.com/r/jellyfin">
<img alt="Join our Subreddit" src="https://img.shields.io/badge/reddit-r%2Fjellyfin-%23FF5700.svg"/>
</a>
<br/><br/>
<a href="https://github.com/jellyfin/jellyfin-web"><img alt="GPL 2.0 License" src="https://img.shields.io/github/license/jellyfin/jellyfin-web.svg"/></a>
<a href="https://github.com/jellyfin/jellyfin-web/releases"><img alt="Current Release" src="https://img.shields.io/github/release/jellyfin/jellyfin-web.svg"/></a>
</p>
Jellyfin Web is the frontend used for most of the clients available for end users, such as desktop browsers, Android, and iOS. We welcome all contributions and pull requests! If you have a larger feature in mind please open an issue so we can discuss the implementation before you start. Translations can be improved very easily from our <a href="https://translate.jellyfin.org/projects/jellyfin/jellyfin-web">Weblate</a> instance. Look through the following graphic to see if your native language could use some work!
---
<a href="https://translate.jellyfin.org/engage/jellyfin/?utm_source=widget">
<img src="https://translate.jellyfin.org/widgets/jellyfin/-/jellyfin-web/multi-auto.svg" alt="Detailed Translation Status"/>
</a>
## Build Process
### Dependencies
- [Node.js](https://nodejs.org/en/download)
- npm (included in Node.js)
### Getting Started
1. Clone or download this repository.
```sh
git clone https://github.com/jellyfin/jellyfin-web.git
cd jellyfin-web
```
2. Install build dependencies in the project directory.
```sh
npm install
```
3. Run the web client with webpack for local development.
```sh
npm start
```
4. Build the client with sourcemaps available.
```sh
npm run build:development
```
Jellyfin is a free software media system that puts you in control of managing and streaming your media.

View File

@@ -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'
]
};

110
build.sh
View File

@@ -1,110 +0,0 @@
#!/usr/bin/env bash
# build.sh - Build Jellyfin binary packages
# Part of the Jellyfin Project
set -o errexit
set -o pipefail
usage() {
echo -e "build.sh - Build Jellyfin binary packages"
echo -e "Usage:"
echo -e " $0 -t/--type <BUILD_TYPE> -p/--platform <PLATFORM> [-k/--keep-artifacts] [-l/--list-platforms]"
echo -e "Notes:"
echo -e " * BUILD_TYPE can be one of: [native, docker] and must be specified"
echo -e " * native: Build using the build script in the host OS"
echo -e " * docker: Build using the build script in a standardized Docker container"
echo -e " * PLATFORM can be any platform shown by -l/--list-platforms and must be specified"
echo -e " * If -k/--keep-artifacts is specified, transient artifacts (e.g. Docker containers) will be"
echo -e " retained after the build is finished; the source directory will still be cleaned"
echo -e " * If -l/--list-platforms is specified, all other arguments are ignored; the script will print"
echo -e " the list of supported platforms and exit"
}
list_platforms() {
declare -a platforms
platforms=(
$( find deployment -maxdepth 1 -mindepth 1 -name "build.*" | awk -F'.' '{ $1=""; printf $2; if ($3 != ""){ printf "." $3; }; if ($4 != ""){ printf "." $4; }; print ""; }' | sort )
)
echo -e "Valid platforms:"
echo
for platform in ${platforms[@]}; do
echo -e "* ${platform} : $( grep '^#=' deployment/build.${platform} | sed 's/^#= //' )"
done
}
do_build_native() {
export IS_DOCKER=NO
deployment/build.${PLATFORM}
}
do_build_docker() {
if ! [ $(uname -m) = "x86_64" ]; then
echo "Docker-based builds only support amd64-based cross-building; use a 'native' build instead."
exit 1
fi
if [[ ! -f deployment/Dockerfile.${PLATFORM} ]]; then
echo "Missing Dockerfile for platform ${PLATFORM}"
exit 1
fi
if [[ ${KEEP_ARTIFACTS} == YES ]]; then
docker_args=""
else
docker_args="--rm"
fi
docker build . -t "jellyfin-builder.${PLATFORM}" -f deployment/Dockerfile.${PLATFORM}
mkdir -p ${ARTIFACT_DIR}
docker run $docker_args -v "${SOURCE_DIR}:/jellyfin" -v "${ARTIFACT_DIR}:/dist" "jellyfin-builder.${PLATFORM}"
}
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-t|--type)
BUILD_TYPE="$2"
shift
shift
;;
-p|--platform)
PLATFORM="$2"
shift
shift
;;
-k|--keep-artifacts)
KEEP_ARTIFACTS=YES
shift
;;
-l|--list-platforms)
list_platforms
exit 0
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option $1"
usage
exit 1
;;
esac
done
if [[ -z ${BUILD_TYPE} || -z ${PLATFORM} ]]; then
usage
exit 1
fi
export SOURCE_DIR="$( pwd )"
export ARTIFACT_DIR="${SOURCE_DIR}/../bin/${PLATFORM}"
# Determine build type
case ${BUILD_TYPE} in
native)
do_build_native
;;
docker)
do_build_docker
;;
esac

View File

@@ -1,9 +0,0 @@
---
# We just wrap `build` so this is really it
name: "jellyfin-web"
version: "10.8.13"
packages:
- debian.all
- fedora.all
- centos.all
- portable

View File

@@ -1,92 +0,0 @@
#!/usr/bin/env bash
# bump_version - increase the shared version and generate changelogs
set -o errexit
set -o pipefail
set -o xtrace
usage() {
echo -e "bump_version - increase the shared version and generate changelogs"
echo -e ""
echo -e "Usage:"
echo -e " $ bump_version <new_version>"
}
if [[ -z $1 ]]; then
usage
exit 1
fi
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}"
# Bump the NPM version
new_version_sed="$( cut -f1 -d'-' <<<"${new_version}" )"
npm --no-git-tag-version --allow-same-version version v${new_version_sed}
# 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}
if [[ ${new_version} == *"-"* ]]; then
new_version_pkg="$( sed 's/-/~/g' <<<"${new_version}" )"
new_version_deb_sup=""
else
new_version_pkg="${new_version}"
new_version_deb_sup="-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
* New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v${new_version}
-- Jellyfin Packaging Team <packaging@jellyfin.org> $( date --rfc-2822 )
" >> ${debian_changelog_temp}
cat ${debian_changelog_file} >> ${debian_changelog_temp}
# Move into place
mv ${debian_changelog_temp} ${debian_changelog_file}
# Write out a temporary Yum changelog with our new stuff prepended and some templated formatting
fedora_spec_file="fedora/jellyfin-web.spec"
fedora_changelog_temp="$( mktemp )"
fedora_spec_temp_dir="$( mktemp -d )"
fedora_spec_temp="${fedora_spec_temp_dir}/jellyfin-web.spec.tmp"
# Make a copy of our spec file for hacking
cp ${fedora_spec_file} ${fedora_spec_temp_dir}/
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
# Remove the header from xx01
sed -i '/^%changelog/d' xx01
# Create new temp file with our changelog
echo -e "%changelog
* $( LANG=C date '+%a %b %d %Y' ) Jellyfin Packaging Team <packaging@jellyfin.org>
- New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v${new_version}" >> ${fedora_changelog_temp}
cat xx01 >> ${fedora_changelog_temp}
# Reassembble
cat xx00 ${fedora_changelog_temp} > ${fedora_spec_temp}
popd
# Move into place
mv ${fedora_spec_temp} ${fedora_spec_file}
# Clean up
rm -rf ${fedora_spec_temp_dir}
# Stage the changed files for commit
git add .
git status -v

95
debian/changelog vendored
View File

@@ -1,95 +0,0 @@
jellyfin-web (10.8.13-1) unstable; urgency=medium
* New upstream version 10.8.13; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.13
-- Jellyfin Packaging Team <packaging@jellyfin.org> Tue, 28 Nov 2023 22:21:29 -0500
jellyfin-web (10.8.12-1) unstable; urgency=medium
* New upstream version 10.8.12; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.12
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 04 Nov 2023 14:42:41 -0400
jellyfin-web (10.8.11-1) unstable; urgency=medium
* New upstream version 10.8.11; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.11
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 23 Sep 2023 21:41:40 -0400
jellyfin-web (10.8.10-1) unstable; urgency=medium
* New upstream version 10.8.10; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.8.10
-- 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-web (10.6.0-1) unstable; urgency=medium
* New upstream version 10.6.0; release changelog at https://github.com/jellyfin/jellyfin-web/releases/tag/v10.6.0
-- Jellyfin Packaging Team <packaging@jellyfin.org> Mon, 16 Mar 2020 11:15:00 -0400

1
debian/compat vendored
View File

@@ -1 +0,0 @@
8

1
debian/conffiles vendored
View File

@@ -1 +0,0 @@
/usr/share/jellyfin/web/config.json

16
debian/control vendored
View File

@@ -1,16 +0,0 @@
Source: jellyfin-web
Section: misc
Priority: optional
Maintainer: Jellyfin Team <team@jellyfin.org>
Build-Depends: debhelper (>= 9),
npm | nodejs
Standards-Version: 3.9.4
Homepage: https://jellyfin.org/
Vcs-Git: https://github.org/jellyfin/jellyfin-web.git
Vcs-Browser: https://github.org/jellyfin/jellyfin-web
Package: jellyfin-web
Recommends: jellyfin-server
Architecture: all
Description: Jellyfin is the Free Software Media System.
This package provides the Jellyfin web client.

28
debian/copyright vendored
View File

@@ -1,28 +0,0 @@
Format: http://dep.debian.net/deps/dep5
Upstream-Name: jellyfin-web
Source: https://github.com/jellyfin/jellyfin-web
Files: *
Copyright: 2018-2020 Jellyfin Team
License: GPL-3.0
Files: debian/*
Copyright: 2020 Joshua Boniface <joshua@boniface.me>
License: GPL-3.0
License: GPL-3.0
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

6
debian/gbp.conf vendored
View File

@@ -1,6 +0,0 @@
[DEFAULT]
pristine-tar = False
cleaner = fakeroot debian/rules clean
[import-orig]
filter = [ ".git*", ".hg*", ".vs*", ".vscode*" ]

1
debian/install vendored
View File

@@ -1 +0,0 @@
web usr/share/jellyfin/

View File

@@ -1 +0,0 @@
[type: gettext/rfc822deb] templates

View File

@@ -1,57 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: jellyfin-server\n"
"Report-Msgid-Bugs-To: jellyfin-server@packages.debian.org\n"
"POT-Creation-Date: 2015-06-12 20:51-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#. Type: note
#. Description
#: ../templates:1001
msgid "Jellyfin permission info:"
msgstr ""
#. Type: note
#. Description
#: ../templates:1001
msgid ""
"Jellyfin by default runs under a user named \"jellyfin\". Please ensure that the "
"user jellyfin has read and write access to any folders you wish to add to your "
"library. Otherwise please run jellyfin under a different user."
msgstr ""
#. Type: string
#. Description
#: ../templates:2001
msgid "Username to run Jellyfin as:"
msgstr ""
#. Type: string
#. Description
#: ../templates:2001
msgid "The user that jellyfin will run as."
msgstr ""
#. Type: note
#. Description
#: ../templates:3001
msgid "Jellyfin still running"
msgstr ""
#. Type: note
#. Description
#: ../templates:3001
msgid "Jellyfin is currently running. Please close it and try again."
msgstr ""

20
debian/rules vendored
View File

@@ -1,20 +0,0 @@
#! /usr/bin/make -f
export DH_VERBOSE=1
%:
dh $@
# disable "make check"
override_dh_auto_test:
# disable stripping debugging symbols
override_dh_clistrip:
override_dh_auto_build:
npm ci --no-audit --unsafe-perm
mv $(CURDIR)/dist $(CURDIR)/web
override_dh_auto_clean:
test -d $(CURDIR)/dist && rm -rf '$(CURDIR)/dist' || true
test -d $(CURDIR)/web && rm -rf '$(CURDIR)/web' || true
test -d $(CURDIR)/node_modules && rm -rf '$(CURDIR)/node_modules' || true

View File

@@ -1 +0,0 @@
1.0

View File

@@ -1,7 +0,0 @@
tar-ignore='.git*'
tar-ignore='**/.git'
tar-ignore='**/.hg'
tar-ignore='**/.vs'
tar-ignore='**/.vscode'
tar-ignore='deployment'
tar-ignore='*.deb'

View File

@@ -1,26 +0,0 @@
FROM centos:7
# Docker build arguments
ARG SOURCE_DIR=/jellyfin
ARG ARTIFACT_DIR=/dist
# Docker run environment
ENV SOURCE_DIR=/jellyfin
ENV ARTIFACT_DIR=/dist
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
# Link to build script
RUN ln -sf ${SOURCE_DIR}/deployment/build.centos /build.sh
VOLUME ${SOURCE_DIR}
VOLUME ${ARTIFACT_DIR}
ENTRYPOINT ["/build.sh"]

View File

@@ -1,27 +0,0 @@
FROM debian:10
# Docker build arguments
ARG SOURCE_DIR=/jellyfin
ARG ARTIFACT_DIR=/dist
# Docker run environment
ENV SOURCE_DIR=/jellyfin
ENV ARTIFACT_DIR=/dist
ENV DEB_BUILD_OPTIONS=noddebs
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
# Link to build script
RUN ln -sf ${SOURCE_DIR}/deployment/build.debian /build.sh
VOLUME ${SOURCE_DIR}
VOLUME ${ARTIFACT_DIR}
ENTRYPOINT ["/build.sh"]

View File

@@ -1,11 +0,0 @@
FROM node:lts-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
WORKDIR ${SOURCE_DIR}
COPY . .
RUN npm ci --no-audit --unsafe-perm && mv dist ${ARTIFACT_DIR}

View File

@@ -1,23 +0,0 @@
FROM fedora:36
# Docker build arguments
ARG SOURCE_DIR=/jellyfin
ARG ARTIFACT_DIR=/dist
# Docker run environment
ENV SOURCE_DIR=/jellyfin
ENV ARTIFACT_DIR=/dist
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
# Link to build script
RUN ln -sf ${SOURCE_DIR}/deployment/build.fedora /build.sh
VOLUME ${SOURCE_DIR}
VOLUME ${ARTIFACT_DIR}
ENTRYPOINT ["/build.sh"]

View File

@@ -1,25 +0,0 @@
FROM debian:10
# Docker build arguments
ARG SOURCE_DIR=/jellyfin
ARG ARTIFACT_DIR=/dist
# Docker run environment
ENV SOURCE_DIR=/jellyfin
ENV ARTIFACT_DIR=/dist
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
# Link to build script
RUN ln -sf ${SOURCE_DIR}/deployment/build.portable /build.sh
VOLUME ${SOURCE_DIR}
VOLUME ${ARTIFACT_DIR}
ENTRYPOINT ["/build.sh"]

View File

@@ -1,41 +0,0 @@
#!/bin/bash
set -o errexit
set -o xtrace
# move to source directory
pushd ${SOURCE_DIR}
cp -a package-lock.json /tmp/package-lock.json
# modify changelog to unstable configuration if IS_UNSTABLE
if [[ ${IS_UNSTABLE} == 'yes' ]]; then
pushd fedora
PR_ID=$( git log --grep 'Merge pull request' --oneline --single-worktree --first-parent | head -1 | grep --color=none -Eo '#[0-9]+' | tr -d '#' )
sed -i "s/Version:.*/Version: ${BUILD_ID}/" jellyfin-web.spec
sed -i "/%changelog/q" jellyfin-web.spec
cat <<EOF >>jellyfin-web.spec
* $( LANG=C date '+%a %b %d %Y' ) Jellyfin Packaging Team <packaging@jellyfin.org>
- Jellyfin Web unstable build ${BUILD_ID} for merged PR #${PR_ID}
EOF
popd
fi
# build rpm
make -f fedora/Makefile srpm outdir=/root/rpmbuild/SRPMS
rpmbuild --rebuild -bb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm
# move the artifacts
mv /root/rpmbuild/RPMS/noarch/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/
if [[ ${IS_DOCKER} == YES ]]; then
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}
fi
rm -f fedora/jellyfin*.tar.gz
cp -a /tmp/package-lock.json package-lock.json
popd

View File

@@ -1,39 +0,0 @@
#!/bin/bash
set -o errexit
set -o xtrace
# move to source directory
pushd ${SOURCE_DIR}
cp -a package-lock.json /tmp/package-lock.json
# modify changelog to unstable configuration if IS_UNSTABLE
if [[ ${IS_UNSTABLE} == 'yes' ]]; then
pushd debian
PR_ID=$( git log --grep 'Merge pull request' --oneline --single-worktree --first-parent | head -1 | grep --color=none -Eo '#[0-9]+' | tr -d '#' )
cat <<EOF >changelog
jellyfin-web (${BUILD_ID}-unstable) unstable; urgency=medium
* Jellyfin Web unstable build ${BUILD_ID} for merged PR #${PR_ID}
-- Jellyfin Packaging Team <packaging@jellyfin.org> $( date --rfc-2822 )
EOF
popd
fi
# build deb
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
if [[ ${IS_DOCKER} == YES ]]; then
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}
fi
popd

View File

@@ -1,41 +0,0 @@
#!/bin/bash
set -o errexit
set -o xtrace
# move to source directory
pushd ${SOURCE_DIR}
cp -a package-lock.json /tmp/package-lock.json
# modify changelog to unstable configuration if IS_UNSTABLE
if [[ ${IS_UNSTABLE} == 'yes' ]]; then
pushd fedora
PR_ID=$( git log --grep 'Merge pull request' --oneline --single-worktree --first-parent | head -1 | grep --color=none -Eo '#[0-9]+' | tr -d '#' )
sed -i "s/Version:.*/Version: ${BUILD_ID}/" jellyfin-web.spec
sed -i "/%changelog/q" jellyfin-web.spec
cat <<EOF >>jellyfin-web.spec
* $( LANG=C date '+%a %b %d %Y' ) Jellyfin Packaging Team <packaging@jellyfin.org>
- Jellyfin Web unstable build ${BUILD_ID} for merged PR #${PR_ID}
EOF
popd
fi
# build rpm
make -f fedora/Makefile srpm outdir=/root/rpmbuild/SRPMS
rpmbuild -rb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm
# move the artifacts
mv /root/rpmbuild/RPMS/noarch/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}
if [[ ${IS_DOCKER} == YES ]]; then
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}
fi
rm -f fedora/jellyfin*.tar.gz
cp -a /tmp/package-lock.json package-lock.json
popd

View File

@@ -1,30 +0,0 @@
#!/bin/bash
set -o errexit
set -o xtrace
# move to source directory
pushd ${SOURCE_DIR}
# get version
if [[ ${IS_UNSTABLE} == 'yes' ]]; then
version="${BUILD_ID}"
else
version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )"
fi
# build archives
npm ci --no-audit --unsafe-perm
mv dist jellyfin-web_${version}
tar -czf jellyfin-web_${version}_portable.tar.gz jellyfin-web_${version}
rm -rf dist
# move the artifacts
mkdir -p ${ARTIFACT_DIR}
mv jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}
if [[ ${IS_DOCKER} == YES ]]; then
chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR}
fi
popd

View File

@@ -1,48 +0,0 @@
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
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 $@) \
-C $${SOURCE_DIR} ./
$(DIR)/$(SRPM): $(DIR)/$(TARBALL) $(DIR)/jellyfin-web.spec
cd $(DIR)/; \
rpmbuild -bs $(NAME).spec \
--define "_sourcedir $$PWD/" \
--define "_srcrpmdir $(outdir)"
rpms: $(DIR)/$(SRPM)
mock $(addprefix --addrepo=, $($(TARGET)_repos)) \
--enable-network \
-r $(TARGET) $<

View File

@@ -1,76 +0,0 @@
%global debug_package %{nil}
Name: jellyfin-web
Version: 10.8.13
Release: 1%{?dist}
Summary: The Free Software Media System web client
License: GPLv2
URL: https://jellyfin.org
# 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
%else
BuildRequires: git
BuildRequires: npm
%endif
%description
Jellyfin is a free software media system that puts you in control of managing and streaming your media.
%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
%files
%defattr(644,root,root,755)
%{_libdir}/jellyfin/jellyfin-web
%license 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

15705
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,138 +1,35 @@
{
"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"
"copy-webpack-plugin": "^5.0.3",
"css-loader": "^2.1.0",
"eslint": "^5.16.0",
"file-loader": "^3.0.1",
"style-loader": "^0.23.1",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.1",
"webpack-merge": "^4.2.2"
},
"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",
"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"
"flv.js": "^1.5.0",
"hls.js": "^0.12.4",
"howler": "^2.1.2",
"jquery": "^3.4.1",
"jstree": "^3.3.7",
"libjass": "^0.11.0",
"shaka-player": "^2.5.5",
"sortablejs": "^1.9.0",
"swiper": "^3.4.2"
},
"browserslist": [
"last 2 Firefox versions",
"last 2 Chrome versions",
"last 2 ChromeAndroid versions",
"last 2 Safari versions",
"iOS > 10",
"last 2 Edge versions",
"Chrome 27",
"Chrome 38",
"Chrome 47",
"Chrome 53",
"Chrome 56",
"Chrome 63",
"Edge 18",
"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": "webpack-dev-server --config webpack.dev.js --open",
"build": "webpack --config webpack.prod.js",
"lint": "eslint \"src\"",
"prepare": "webpack --config webpack.prod.js"
}
}

View File

@@ -1,16 +0,0 @@
const packageConfig = require('./package.json');
const postcssPresetEnv = require('postcss-preset-env');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const config = () => ({
plugins: [
// Explicitly specify browserslist to override ones from node_modules
// For example, Swiper has it in its package.json
postcssPresetEnv({browsers: packageConfig.browserslist}),
autoprefixer({overrideBrowserslist: packageConfig.browserslist}),
cssnano()
]
});
module.exports = config;

View File

@@ -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')

View File

@@ -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' });
}

View File

@@ -1,34 +0,0 @@
import sys
import os
import json
# load text file containing unused keys
# remove the keys from all string files
cwd = os.getcwd()
langdir = cwd + '/../src/strings'
langlst = os.listdir(langdir)
keys = []
with open('unused.txt', 'r') as f:
for line in f:
keys.append(line.strip('\n'))
for lang in langlst:
with open(langdir + '/' + lang, 'r') as f:
inde = 2
if '\n \"' in f.read():
inde = 4
f.close()
with open(langdir + '/' + lang, 'r+') as f:
langjson = json.load(f)
for key in keys:
langjson.pop(key, None)
f.seek(0)
f.write(json.dumps(langjson, indent=inde, sort_keys=False, ensure_ascii=False))
f.write('\n')
f.truncate()
f.close()
print('DONE')

View File

@@ -1,52 +0,0 @@
import sys
import os
import json
# load every key in the source language
# check the keys in all translations
# remove keys that only exist in translations
cwd = os.getcwd()
langdir = cwd + '/../src/strings'
langlst = os.listdir(langdir)
langlst.remove('en-us.json')
print(langlst)
input('press enter to continue')
keysus = []
missing = []
with open(langdir + '/' + 'en-us.json') as en:
langus = json.load(en)
for key in langus:
keysus.append(key)
for lang in langlst:
with open(langdir + '/' + lang, 'r') as f:
inde = 2
if '\n \"' in f.read():
inde = 4
f.close()
with open(langdir + '/' + lang, 'r+') as f:
langjson = json.load(f)
langjnew = {}
for key in langjson:
if key in keysus:
langjnew[key] = langjson[key]
elif key not in missing:
missing.append(key)
f.seek(0)
f.write(json.dumps(langjnew, indent=inde, sort_keys=False, ensure_ascii=False))
f.write('\n')
f.truncate()
f.close()
print(missing)
print('LENGTH: ' + str(len(missing)))
with open('missing.txt', 'w') as out:
for item in missing:
out.write(item + '\n')
out.close()
print('DONE')

View File

@@ -1,40 +0,0 @@
import os
import subprocess
import json
# load all keys in the source language
# check entire codebase for usages
# print unused keys to a text file
# TODO: dynamic string usages cause false positives
cwd = os.getcwd()
langdir = cwd + '/../src/strings'
langlst = []
langlst.append('en-us.json')
# unused keys
dep = []
def grep(key):
command = 'grep -r -E "(\\\"|\'|\{)%s(\\\"|\'|\})" --include=\*.{js,html} --exclude-dir=../src/strings ../src' % key
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = p.stdout.readlines()
if output:
print('DONE: ' + key)
return True
print('UNUSED: ' + key)
dep.append(key)
return False
for lang in langlst:
with open(langdir + '/' + lang) as f:
langjson = json.load(f)
for key in langjson:
grep(key)
print(dep)
print('LENGTH: ' + str(len(dep)))
with open('unused.txt', 'w') as out:
for item in dep:
out.write(item + '\n')
out.close()

View File

@@ -1,15 +1,21 @@
<div id="addPluginPage" data-role="page" class="page type-interior pluginConfigurationPage" data-backbutton="true">
<div>
<div class="content-primary">
<div class="readOnlyContent">
<div class="verticalSection">
<div class="sectionTitleContainer flex align-items-center">
<h1 class="sectionTitle pluginName"></h1>
<a is="emby-linkbutton" rel="noopener noreferrer" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/server/plugins/index.html">${Help}</a>
<a is="emby-linkbutton" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/server/plugins/index.html">${Help}</a>
</div>
<p id="overview" style="font-style: italic;"></p>
<p id="description"></p>
<p id="tagline" style="font-style: italic;"></p>
<p id="pPreviewImage"></p>
<p id="overview"></p>
</div>
<div class="verticalSection">
@@ -21,12 +27,13 @@
<select id="selectVersion" name="selectVersion" is="emby-select" label="${LabelSelectVersionToInstall}"></select>
</div>
<div id="btnInstallDiv" class="hide">
<p id="btnInstallDiv" class="hide">
<button is="emby-button" type="submit" id="btnInstall" class="raised button-submit block">
<span>${Install}</span>
</button>
<div class="fieldDescription">${ServerRestartNeededAfterPluginInstall}</div>
</div>
</p>
<p id="nonServerMsg"></p>
</form>
</div>
</div>
@@ -34,9 +41,10 @@
<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>
<p id="pViewWebsite" style="display: none;">
<a is="emby-linkbutton" class="button-link" href="#" target="_blank">${ButtonViewWebsite}</a>
</p>
</div>
</div>

View File

@@ -1,14 +1,14 @@
<div data-role="page" class="page standalonePage">
<div class="padded-left padded-right padded-bottom-page">
<form class="addServerForm" style="margin: 0 auto;" novalidate>
<form class="addServerForm" style="margin: 0 auto;">
<h1>${HeaderConnectToServer}</h1>
<div class="inputContainer">
<input is="emby-input" type="url" id="txtServerHost" required="required" label="${LabelServerHost}"/>
<input is="emby-input" type="text" id="txtServerHost" required="required" label="${LabelServerHost}" autocomplete="off" spellcheck="false" autocapitalize="none" autocorrect="off" />
<div class="fieldDescription">${LabelServerHostHelp}</div>
</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
View File

@@ -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 */

View File

@@ -2,25 +2,26 @@
<div>
<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}">
<span class="material-icons add" aria-hidden="true"></span>
<h2 style="margin:.6em 0;vertical-align:middle;display:inline-block;">
${HeaderApiKeys}
</h2>
<button is="emby-button" type="button" class="fab btnNewKey submit" style="margin-left:1em;" title="${ButtonAdd}">
<i class="md-icon">add</i>
</button>
</div>
<p>${HeaderApiKeysHelp}</p>
<br />
<table class="tblApiKeys detailTable">
<caption class="clipForScreenReader">${ApiKeysCaption}</caption>
<thead>
<tr>
<th scope="col" class="detailTableHeaderCell"></th>
<th scope="col" class="detailTableHeaderCell">${HeaderApiKey}</th>
<th scope="col" class="detailTableHeaderCell">${HeaderApp}</th>
<th scope="col" class="detailTableHeaderCell">${HeaderDateIssued}</th>
<th class="detailTableHeaderCell"></th>
<th class="detailTableHeaderCell">${HeaderApiKey}</th>
<th class="detailTableHeaderCell">${HeaderApp}</th>
<th class="detailTableHeaderCell">${HeaderDateIssued}</th>
</tr>
</thead>
<tbody class="resultBody"></tbody>
</table>
</div>
</div>
</div>
</div>

Binary file not shown.

View File

@@ -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%;
}

View File

@@ -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);
}

View File

@@ -1,3 +0,0 @@
html {
font-size: 82% !important;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -1,151 +0,0 @@
@mixin fullpage {
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;
}
.clipForScreenReader {
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
width: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
}
.material-icons {
/* Fix font ligatures on older WebOS versions */
font-feature-settings: "liga";
}
.backgroundContainer {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
contain: strict;
}
.layout-mobile,
.layout-tv {
-webkit-touch-callout: none;
user-select: none;
}
.mainAnimatedPage {
contain: style size !important;
}
.pageContainer {
overflow-x: visible !important;
}
.bodyWithPopupOpen {
overflow-y: hidden !important;
}
div[data-role="page"] {
outline: 0;
}
.pageTitle {
margin-top: 0;
font-family: inherit;
}
.fieldDescription {
padding-left: 0.15em;
font-weight: 400;
white-space: normal !important;
+ .fieldDescription {
margin-top: 0.3em;
}
}
.content-primary,
.padded-bottom-page,
.page,
.pageWithAbsoluteTabs .pageTabContent {
/* provides room for the music controls */
padding-bottom: 5em !important;
}
.readOnlyContent {
@media all and (min-width: 50em) {
max-width: 54em;
}
}
form {
@media all and (min-width: 50em) {
max-width: 54em;
}
}
.headerHelpButton {
margin-left: 1.25em !important;
padding-bottom: 0.4em !important;
padding-top: 0.4em !important;
}
.mediaInfoContent {
margin-left: auto;
margin-right: auto;
width: 85%;
}
.headroom {
will-change: transform;
transition: transform 200ms linear;
&--pinned {
transform: translateY(0%);
}
&--unpinned {
transform: translateY(-100%);
}
}
.drawerContent {
/* make sure the bottom of the drawer is visible when music is playing */
padding-bottom: 4em;
}
.force-scroll {
overflow-y: scroll;
}
.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;
}

View File

@@ -1,377 +0,0 @@
.chapterThumbTextContainer,
.videoOsdBottom {
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.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 {
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;
}
.osdHeader-hidden {
opacity: 0;
}
.osdHeader .headerTop {
pointer-events: all;
max-height: 3.5em;
}
.osdHeader .headerButton:not(.headerBackButton):not(.headerCastButton):not(.headerSyncButton) {
display: none;
}
.chapterThumbContainer {
-webkit-box-shadow: 0 0 1.9vh #000;
box-shadow: 0 0 1.9vh #000;
-webkit-box-flex: 1;
-webkit-flex-grow: 1;
flex-grow: 1;
position: relative;
}
.chapterThumb {
background-position: center center;
-webkit-background-size: contain;
background-size: contain;
background-repeat: no-repeat;
border: 0;
height: 20vh;
min-width: 20vh;
}
@media all and (orientation: portrait) {
.chapterThumb {
height: 30vw;
min-width: 30vw;
}
}
@media all and (max-height: 50em) and (orientation: landscape) {
.chapterThumb {
height: 30vh;
min-width: 30vh;
}
}
.chapterThumbTextContainer {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.7);
padding: 0.25em 0.5em;
user-select: none;
}
.chapterThumbText {
padding: 0.25em 0;
margin: 0;
opacity: 1;
}
.chapterThumbText-dim {
opacity: 0.6;
}
.videoOsdBottom-hidden {
opacity: 0;
}
.osdControls {
pointer-events: all;
flex-grow: 1;
padding: 0 0.8em;
}
.layout-desktop .osdControls {
max-width: calc(100vh * 1.77 - 2vh);
}
.videoOsdBottom .buttons {
padding: 0.25em 0 0;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.osdVolumeSliderContainer {
width: 9em;
-webkit-box-flex: 1;
-webkit-flex-grow: 1;
flex-grow: 1;
}
.osdMediaInfo,
.volumeButtons {
display: flex;
display: -webkit-box;
display: -webkit-flex;
align-items: center;
-webkit-box-align: center;
}
.volumeButtons {
margin: 0 1em 0 0.29em;
display: flex;
-webkit-align-items: center;
align-items: center;
}
.osdTimeText {
margin-left: 1em;
margin-right: auto;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.osdTitle,
.osdTitleSmall {
margin: 0 1em 0 0;
}
.osdMediaInfo {
display: flex;
-webkit-align-items: center;
align-items: center;
}
.osdSecondaryMediaInfo {
padding-left: 0.6em !important;
}
.osdTextContainer {
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
margin-bottom: 0.7em;
padding-left: 0.5em;
}
.osdMainTextContainer {
-webkit-box-align: baseline;
-webkit-align-items: baseline;
align-items: baseline;
}
.osdMediaStatus {
margin-left: auto;
}
@-moz-keyframes spin {
100% {
-moz-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes spin {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spin {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.osdMediaStatus .animate {
-webkit-animation: spin 4s linear infinite;
-moz-animation: spin 4s linear infinite;
animation: spin 4s linear infinite;
}
@media all and (max-width: 30em) {
.osdMediaInfo,
.osdPoster {
display: none !important;
}
}
@media all and (max-width: 33.75em) {
.videoOsdBottom .paper-icon-button-light {
margin: 0;
}
}
@media all and (max-width: 43em) {
.videoOsdBottom .volumeButtons,
.osdMediaStatus span {
display: none !important;
}
}
@media all and (max-width: 50em) {
.videoOsdBottom .btnFastForward,
.videoOsdBottom .btnRewind {
display: none !important;
}
}
@media all and (max-width: 75em) {
.videoOsdBottom .endsAtText {
display: none !important;
}
}
.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);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M24 19H0a13.6 13.6 0 0 1 2.21-6.07A11.2 11.2 0 0 1 5.87 9.4l.41-.23-2.02-3.41a.51.51 0 0 1 .17-.7.5.5 0 0 1 .69.18l2.08 3.5a12.62 12.62 0 0 1 4.84-.9 12.2 12.2 0 0 1 4.75.9l2.07-3.5a.5.5 0 0 1 .7-.17.51.51 0 0 1 .16.7L17.7 9.19l.5.28a11.38 11.38 0 0 1 3.63 3.62A14.48 14.48 0 0 1 24 19zm-7.5-4.48a1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1 1 1 0 0 0-1 1zm-11 0a1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1 1 1 0 0 0-1 1z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 563 B

View File

@@ -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

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 24 24"><title>Microsoft Edge icon</title><path d="M21.86 17.86q.14 0 .25.12.1.13.1.25t-.11.33l-.32.46-.43.53-.44.5q-.21.25-.38.42l-.22.23q-.58.53-1.34 1.04-.76.51-1.6.91-.86.4-1.74.64t-1.67.24q-.9 0-1.69-.28-.8-.28-1.48-.78-.68-.5-1.22-1.17-.53-.66-.92-1.44-.38-.77-.58-1.6-.2-.83-.2-1.67 0-1 .32-1.96.33-.97.87-1.8.14.95.55 1.77.41.82 1.02 1.5.6.68 1.38 1.21.78.54 1.64.9.86.36 1.77.56.92.2 1.8.2 1.12 0 2.18-.24 1.06-.23 2.06-.72l.2-.1.2-.05zm-15.5-1.27q0 1.1.27 2.15.27 1.06.78 2.03.51.96 1.24 1.77.74.82 1.66 1.4-1.47-.2-2.8-.74-1.33-.55-2.48-1.37-1.15-.83-2.08-1.9-.92-1.07-1.58-2.33T.36 14.94Q0 13.54 0 12.06q0-.81.32-1.49.31-.68.83-1.23.53-.55 1.2-.96.66-.4 1.35-.66.74-.27 1.5-.39.78-.12 1.55-.12.7 0 1.42.1.72.12 1.4.35.68.23 1.32.57.63.35 1.16.83-.35 0-.7.07-.33.07-.65.23v-.02q-.63.28-1.2.74-.57.46-1.05 1.04-.48.58-.87 1.26-.38.67-.65 1.39-.27.71-.42 1.44-.15.72-.15 1.38zM11.96.06q1.7 0 3.33.39 1.63.38 3.07 1.15 1.43.77 2.62 1.93 1.18 1.16 1.98 2.7.49.94.76 1.96.28 1 .28 2.08 0 .89-.23 1.7-.24.8-.69 1.48-.45.68-1.1 1.22-.64.53-1.45.88-.54.24-1.11.36-.58.13-1.16.13-.42 0-.97-.03-.54-.03-1.1-.12-.55-.1-1.05-.28-.5-.19-.84-.5-.12-.09-.23-.24-.1-.16-.1-.33 0-.15.16-.35.16-.2.35-.5.2-.28.36-.68.16-.4.16-.95 0-1.06-.4-1.96-.4-.91-1.06-1.64-.66-.74-1.52-1.28-.86-.55-1.79-.89-.84-.3-1.72-.44-.87-.14-1.76-.14-1.55 0-3.06.45T.94 7.55q.71-1.74 1.81-3.13 1.1-1.38 2.52-2.35Q6.68 1.1 8.37.58q1.7-.52 3.58-.52Z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-36.173 -93.796)">
<g transform="matrix(.08 0 0 .08 40.527 88.485)">
<path d="m53.295 119.35v-39.688h79.375v79.375h-79.375z" fill="#fcfdfd" stroke-width=".26458"/>
</g>
<g transform="matrix(1.3761 0 0 1.3825 -26.63 -38.456)" fill="#fff">
<path transform="matrix(.08 0 0 .08 40.527 88.485)" d="m86.822 141.89c-4.738-4.7596-5.2168-5.3235-5.2168-6.1442 0-0.82158 0.47505-1.3787 5.2329-6.1365 4.7552-4.7552 5.3153-5.2329 6.1353-5.2329 0.81617 0 1.3676 0.46161 5.7678 4.8286 4.8692 4.8324 5.6182 5.7452 5.6182 6.8466 0 0.41218-1.5697 2.1641-5.2274 5.834-4.8206 4.8367-5.3 5.2449-6.1603 5.2449-0.86046 0-1.3378-0.40681-6.1497-5.2406zm22.168-12.455c-0.43656-0.27248-2.9071-2.6371-5.4901-5.2547-4.1957-4.2519-4.6964-4.8534-4.6964-5.6418 0-0.7938 0.52954-1.414 5.2644-6.1655 4.6582-4.6746 5.362-5.2829 6.1127-5.2829 0.75071 0 1.4546 0.60829 6.1127 5.2829 4.7729 4.7898 5.2644 5.3668 5.2644 6.1818 0 0.81542-0.48628 1.3851-5.2394 6.1382-5.6104 5.6104-5.7707 5.7142-7.3283 4.742zm-40.16-5.2731c-3.5636-3.5816-4.9518-5.1483-4.9518-5.5886 0-0.75745 9.3384-10.601 10.057-10.601 0.2584 0 0.54208 0.18833 0.63041 0.41851s0.1606 4.7624 0.1606 10.072c0 9.1098-0.10948 10.677-0.74606 10.677-0.10905 0-2.4266-2.2396-5.1501-4.9768zm13.2-1.5272c-0.08833-0.23018-0.1606-5.3558-0.1606-11.39 0-8.9734 0.06852-11.102 0.37621-11.686 0.20691-0.39296 2.447-2.7683 4.9781-5.2785 4.3226-4.2871 4.6624-4.5641 5.5987-4.5641 0.94583 0 1.2591 0.26717 6.1277 5.2255 4.658 4.7439 5.1315 5.3102 5.1376 6.1439 6e-3 0.85888-0.67407 1.6-10.506 11.443-5.782 5.7887-10.71 10.525-10.952 10.525s-0.51144-0.18833-0.59977-0.41852z" fill="#fff" stroke-width=".26458"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg id="svg3390" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="141.25" viewBox="0 0 138.75 141.25" width="138.75" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata id="metadata3396">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g id="layer1" fill="#f93208">
<path id="path3412" d="m20.154 40.829c-28.149 27.622-13.657 61.011-5.734 71.931 35.254 41.954 92.792 25.339 111.89-5.9071 4.7608-8.2027 22.554-53.467-23.976-78.009z"/>
<path id="path3471" d="m39.613 39.265 4.7778-8.8607 28.406-5.0384 11.119 9.2082z"/>
</g>
<g id="layer2">
<path id="path3437" d="m39.436 8.5696 8.9682-5.2826 6.7569 15.479c3.7925-6.3226 13.79-16.316 24.939-4.6684-4.7281 1.2636-7.5161 3.8553-7.7397 8.4768 15.145-4.1697 31.343 3.2127 33.539 9.0911-10.951-4.314-27.695 10.377-41.771 2.334 0.009 15.045-12.617 16.636-19.902 17.076 2.077-4.996 5.591-9.994 1.474-14.987-7.618 8.171-13.874 10.668-33.17 4.668 4.876-1.679 14.843-11.39 24.448-11.425-6.775-2.467-12.29-2.087-17.814-1.475 2.917-3.961 12.149-15.197 28.625-8.476z" fill="#02902e"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="145" height="140"><path fill="#0fc755" d="M47.4 35.342c-13.607-7.935-12.32-25.203 2.097-31.88 26.124-6.531 29.117 13.78 22.652 30.412-6.542 24.11 18.095 23.662 19.925 10.067 3.605-18.412 19.394-26.695 31.67-16.359 12.598 12.135 7.074 36.581-17.827 34.187-16.03-1.545-19.552 19.585.839 21.183 32.228 1.915 42.49 22.167 31.04 35.865-15.993 15.15-37.691-4.439-45.512-19.505-6.8-9.307-17.321.11-13.423 6.502 12.983 19.465 2.923 31.229-10.906 30.62-13.37-.85-20.96-9.06-13.214-29.15 3.897-12.481-8.595-15.386-16.57-5.45-11.707 19.61-28.865 13.68-33.976 4.19-3.243-7.621-2.921-25.846 24.119-23.696 16.688 4.137 11.776-12.561-.63-13.633-9.245-.443-30.501-7.304-22.86-24.54 7.34-11.056 24.958-11.768 33.348 6.293 3.037 4.232 8.361 11.042 18.037 5.033 3.51-5.197 1.21-13.9-8.809-20.135z"/></svg>

Before

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Some files were not shown because too many files have changed in this diff Show More