Compare commits
276 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd2bf25d92 | ||
|
|
5f31f40700 | ||
|
|
a26110a15e | ||
|
|
2a2859bc16 | ||
|
|
b72546b3eb | ||
|
|
84c4462648 | ||
|
|
a970349a1f | ||
|
|
deeb8976f6 | ||
|
|
a00e8b6352 | ||
|
|
4b63aa0c8c | ||
|
|
59a46ae222 | ||
|
|
03b7f0bc25 | ||
|
|
781ef1c9f8 | ||
|
|
6364927f99 | ||
|
|
cd8d71ada7 | ||
|
|
247175d753 | ||
|
|
94f7473108 | ||
|
|
f41d67cf39 | ||
|
|
68e00efcca | ||
|
|
fc8b88ee6b | ||
|
|
57c422ff87 | ||
|
|
d2f65e0060 | ||
|
|
c15c47111b | ||
|
|
438f1bd2fa | ||
|
|
e31d0e4c13 | ||
|
|
7b0ebf6e32 | ||
|
|
4d58525fa6 | ||
|
|
0be80d9956 | ||
|
|
5e10675eea | ||
|
|
426782031b | ||
|
|
814d84f4e6 | ||
|
|
82cdcd904a | ||
|
|
edac2f8254 | ||
|
|
1758ffead2 | ||
|
|
76cbeef6a1 | ||
|
|
b24f0d4b8c | ||
|
|
13383919ca | ||
|
|
583db6ea3d | ||
|
|
0317cc7ef2 | ||
|
|
ddfb13cf18 | ||
|
|
b334cc04df | ||
|
|
6872ddcbf5 | ||
|
|
c369e8942f | ||
|
|
f696f71b55 | ||
|
|
f7759d1418 | ||
|
|
da71d56088 | ||
|
|
372203cf87 | ||
|
|
eefb4080ac | ||
|
|
15b16315f0 | ||
|
|
abe5050ab5 | ||
|
|
03e5d663ec | ||
|
|
03e6f99a00 | ||
|
|
0dc14c2191 | ||
|
|
9ee68c38dd | ||
|
|
55edfbdd77 | ||
|
|
9b610b9c4f | ||
|
|
8efa7b80b8 | ||
|
|
5784ac08c1 | ||
|
|
8159cdd763 | ||
|
|
c93dfa61a6 | ||
|
|
5bee383228 | ||
|
|
bd5a78b2f3 | ||
|
|
24971e9bc2 | ||
|
|
7f6b80ce65 | ||
|
|
69f8d1004f | ||
|
|
f546a35c80 | ||
|
|
cc5ccb41a0 | ||
|
|
d1e0a7ab35 | ||
|
|
2861554bb5 | ||
|
|
0e8bf25559 | ||
|
|
da4c2824d0 | ||
|
|
85cb451ed5 | ||
|
|
69da666ceb | ||
|
|
4a57c46888 | ||
|
|
2e7c07e820 | ||
|
|
39b9d4b5e5 | ||
|
|
41e1213b8e | ||
|
|
0b361706ea | ||
|
|
556979db49 | ||
|
|
fd422ef9d6 | ||
|
|
9a093fb381 | ||
|
|
f451411c88 | ||
|
|
baab039506 | ||
|
|
6ae2cefcf6 | ||
|
|
577bed8f6b | ||
|
|
60e5920372 | ||
|
|
98c9f1a576 | ||
|
|
2869f6bb00 | ||
|
|
fafbae507b | ||
|
|
7df79b6508 | ||
|
|
523097da02 | ||
|
|
769ebaf694 | ||
|
|
a4859c24ca | ||
|
|
6132e8827a | ||
|
|
42fae9cffd | ||
|
|
90ac04ca02 | ||
|
|
db829681d1 | ||
|
|
568ff0e048 | ||
|
|
07d38f0642 | ||
|
|
5e3fd1e444 | ||
|
|
f5ce15889f | ||
|
|
ffd5161a00 | ||
|
|
c510b13652 | ||
|
|
3c8c1acadb | ||
|
|
d8c66651f9 | ||
|
|
d44fb6e009 | ||
|
|
6b6427dc34 | ||
|
|
09a0077a11 | ||
|
|
39f105953e | ||
|
|
650a5ff32b | ||
|
|
106655c5ff | ||
|
|
3dd71d66e7 | ||
|
|
9a86e3c4ed | ||
|
|
9c0429fceb | ||
|
|
28f2244e97 | ||
|
|
c68e663b61 | ||
|
|
0c08d71061 | ||
|
|
a75a99d6b7 | ||
|
|
383d8201ff | ||
|
|
000e629378 | ||
|
|
5b2fc436b3 | ||
|
|
058f1ad43b | ||
|
|
0781fdcb24 | ||
|
|
10f48817ab | ||
|
|
1b920fbf2b | ||
|
|
471e75484d | ||
|
|
ffff83d5e5 | ||
|
|
8e468d19be | ||
|
|
0f6bfbfce8 | ||
|
|
67dee46994 | ||
|
|
4c9eafeae3 | ||
|
|
e2a020fd2a | ||
|
|
80ae268a8d | ||
|
|
87e1c6fcf5 | ||
|
|
eb933dba57 | ||
|
|
50164fe5af | ||
|
|
e2a94a1f4e | ||
|
|
7d3911fb08 | ||
|
|
cdaca9d393 | ||
|
|
addca19af3 | ||
|
|
6223cb6f18 | ||
|
|
5acc963a56 | ||
|
|
ab116bd4c7 | ||
|
|
80b9b3e651 | ||
|
|
693438254d | ||
|
|
dd75463857 | ||
|
|
0605248f2f | ||
|
|
aa2dfed793 | ||
|
|
bd4775cf8f | ||
|
|
8ff2b10aaf | ||
|
|
d266fd109e | ||
|
|
8b8d948ba1 | ||
|
|
d6e8ed3d43 | ||
|
|
db40ecba08 | ||
|
|
97da2905de | ||
|
|
f71e386412 | ||
|
|
e1d361b544 | ||
|
|
17382207de | ||
|
|
c8649eef6b | ||
|
|
d8d343fe1a | ||
|
|
1450ce5974 | ||
|
|
78aeadff4f | ||
|
|
48b9cd3e95 | ||
|
|
c3566e30f7 | ||
|
|
1ef6cf899f | ||
|
|
c39f16e983 | ||
|
|
9ef4b40110 | ||
|
|
df8f15ad1c | ||
|
|
23b12cc3ea | ||
|
|
4ff7da8772 | ||
|
|
b987503f86 | ||
|
|
2162b79309 | ||
|
|
dce0da67ff | ||
|
|
9924e23b0d | ||
|
|
1269a4dec3 | ||
|
|
3e465cf4c8 | ||
|
|
b9511d2501 | ||
|
|
1cb7b215ab | ||
|
|
435c256ec3 | ||
|
|
0d1b0ceb76 | ||
|
|
93b25fc4f1 | ||
|
|
6f18c554f7 | ||
|
|
5e8c3e00d6 | ||
|
|
468334bb0b | ||
|
|
63d3de9bfa | ||
|
|
2acab28803 | ||
|
|
1b19253875 | ||
|
|
4b40c1a784 | ||
|
|
6b8e6738b4 | ||
|
|
c9c890a7f0 | ||
|
|
7900d7a0dc | ||
|
|
d951da15d9 | ||
|
|
34e0388afe | ||
|
|
76f5e3675b | ||
|
|
4160e753ff | ||
|
|
dd7100a730 | ||
|
|
86121c93e3 | ||
|
|
cfeaaaff50 | ||
|
|
b29b4d66b2 | ||
|
|
6896f08184 | ||
|
|
4b7fdd2457 | ||
|
|
0c21a8c617 | ||
|
|
d82164c01b | ||
|
|
6e95664ca3 | ||
|
|
40ba7ed152 | ||
|
|
8481cb96ed | ||
|
|
c35e9621c9 | ||
|
|
878b0a2705 | ||
|
|
3002c1defb | ||
|
|
425b898beb | ||
|
|
8d753a482c | ||
|
|
cdd488c655 | ||
|
|
99eed0d4d7 | ||
|
|
1f736cb6c2 | ||
|
|
a6a8435eb3 | ||
|
|
98baca7927 | ||
|
|
70c16248d4 | ||
|
|
5e0a6f66b3 | ||
|
|
cf73e6bafc | ||
|
|
b2cc79d9df | ||
|
|
0ea8e6fec5 | ||
|
|
d858ca509d | ||
|
|
60f353acd6 | ||
|
|
122a4585fa | ||
|
|
61b39924b1 | ||
|
|
446ba43add | ||
|
|
50b5480ce4 | ||
|
|
091d690ce4 | ||
|
|
e9fa65e407 | ||
|
|
68232e79ee | ||
|
|
e118d85259 | ||
|
|
f50afd93bf | ||
|
|
5569a04bd5 | ||
|
|
b9f8a53835 | ||
|
|
2b367476e5 | ||
|
|
20ef67df8d | ||
|
|
e8ef129c52 | ||
|
|
4671bcfea1 | ||
|
|
c254a29dd5 | ||
|
|
9cef7fead3 | ||
|
|
ba8467328b | ||
|
|
aa76f20398 | ||
|
|
d21d34c7e9 | ||
|
|
680d8120f3 | ||
|
|
79c4b736f2 | ||
|
|
e399488038 | ||
|
|
2bf9b79105 | ||
|
|
ee2bae7c93 | ||
|
|
9b6f9de69b | ||
|
|
3333fcae85 | ||
|
|
8a27eefbdb | ||
|
|
0dd8f485df | ||
|
|
9034cd0450 | ||
|
|
6d51f2ae6a | ||
|
|
be974af9b6 | ||
|
|
f1d3ccf27b | ||
|
|
a6be65e591 | ||
|
|
13d37ce6f0 | ||
|
|
609763b281 | ||
|
|
5357ab3c1c | ||
|
|
a31f13816f | ||
|
|
d1a3dbc74f | ||
|
|
39c1d9d4ff | ||
|
|
07753bf356 | ||
|
|
92fe6a35ff | ||
|
|
67f4031630 | ||
|
|
c7c2608e03 | ||
|
|
560a52a195 | ||
|
|
b383eb88bb | ||
|
|
fee1323b9b | ||
|
|
e3f2b68e14 | ||
|
|
403444fadb | ||
|
|
000077c265 | ||
|
|
6b92c15c13 | ||
|
|
be1bb73005 | ||
|
|
26758cec7d |
@@ -1,14 +1,18 @@
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Jellyfin.Plugin.SkinManager.Configuration
|
||||
{
|
||||
public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
public string selectedCss { get; set; }
|
||||
public string selectedSkin { get; set; }
|
||||
public string[] options { get; set; }
|
||||
|
||||
public PluginConfiguration()
|
||||
{
|
||||
selectedCss = "";
|
||||
selectedSkin = "";
|
||||
options = Array.Empty<String>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8508
Jellyfin.Plugin.SkinManager/Configuration/fontpicker.js
Normal file
@@ -3,8 +3,8 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<IsPackable>true</IsPackable>
|
||||
<AssemblyVersion>1.3.0</AssemblyVersion>
|
||||
<FileVersion>1.3.0</FileVersion>
|
||||
<AssemblyVersion>2.0.1</AssemblyVersion>
|
||||
<FileVersion>2.0.1</FileVersion>
|
||||
<Authors />
|
||||
<Company />
|
||||
</PropertyGroup>
|
||||
@@ -16,6 +16,9 @@
|
||||
<ItemGroup>
|
||||
<None Remove="Configuration\configurationpage.html" />
|
||||
<EmbeddedResource Include="Configuration\configurationpage.html" />
|
||||
|
||||
<None Remove="Configuration\fontpicker.js" />
|
||||
<EmbeddedResource Include="Configuration\fontpicker.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -34,6 +34,16 @@ namespace Jellyfin.Plugin.SkinManager
|
||||
{
|
||||
Name = "SkinManager",
|
||||
EmbeddedResourcePath = GetType().Namespace + ".Configuration.configurationpage.html"
|
||||
},
|
||||
new PluginPageInfo
|
||||
{
|
||||
Name = "fontpicker.js",
|
||||
EmbeddedResourcePath = GetType().Namespace + ".Configuration.fontpicker.js"
|
||||
},
|
||||
new PluginPageInfo
|
||||
{
|
||||
Name = "fontpicker.css",
|
||||
EmbeddedResourcePath = GetType().Namespace + ".Configuration.jquery.fontpicker.min.css"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
56
README.md
@@ -1,13 +1,31 @@
|
||||
<h1 align="center">Jellyfin Theme Songs Plugin</h1>
|
||||
<h3 align="center">Part of the <a href="https://jellyfin.media">Jellyfin Project</a></h3>
|
||||
<h1 align="center">Jellyfin Skin Manager Plugin</h1>
|
||||
<h3 align="center">Part of the <a href="https://jellyfin.org">Jellyfin Project</a></h3>
|
||||
|
||||
<p align="center">
|
||||
Jellyfin Skin Manager is a plugin that helps you to download and install skins;
|
||||
|
||||
</p>
|
||||
|
||||
## Install Process
|
||||
|
||||
|
||||
## From Repository
|
||||
1. In jellyfin, go to dashboard -> plugins -> Repositories -> add and paste this link https://raw.githubusercontent.com/danieladov/JellyfinPluginManifest/master/manifest.json
|
||||
2. Go to Catalog and search for Skin Manager
|
||||
3. Click on it and install
|
||||
4. Restart Jellyfin
|
||||
|
||||
|
||||
## From .zip file
|
||||
1. Download the .zip file from release page.
|
||||
2. Extract it and place the .dll file in a folder called ```plugins/SkinManager``` under the program data directory or inside the portable install directory.
|
||||
3. Restart Jellyfin.
|
||||
|
||||
## User Guide
|
||||
1. Go to Plugins, click on Skin Manager.
|
||||
2. Select the skin you want to install.
|
||||
3. Click set skin.
|
||||
|
||||
|
||||
|
||||
## Build Process
|
||||
@@ -20,3 +38,37 @@ dotnet publish --configuration Release --output bin
|
||||
4. Place the resulting .dll file in a folder called ```plugins/SkinManager``` under the program data directory or inside the portable install directory
|
||||
|
||||
|
||||
|
||||
## Using with reverse proxy
|
||||
When using the Nginx Reverse proxy config from the [Jellyfin docs](https://jellyfin.org/docs/general/networking/nginx.html) the theme might not work by default. (If you are using the subpath config, you can ignore all this.)
|
||||
|
||||
Because the config includes Content-Security-Policy which reduces risk of XSS, you need to add the URL from the skin repo and the fonts to the list of allowed external sources.
|
||||
|
||||
For example to use Kaleidochromic you need to do [this](https://github.com/CTalvio/Kaleidochromic/blob/main/README.md#using-with-reverse-proxy)
|
||||
|
||||
|
||||
## JSON
|
||||
## Skin Properties
|
||||
- name //The name of the skin
|
||||
- author //The author of the skin
|
||||
- defaultCss //The base css of the skin
|
||||
- options //An array of options that will modified the skin
|
||||
- ## Options Properties
|
||||
- type //the type of the input (checkBox, number, select, colorPicker)
|
||||
- name // the name of the option
|
||||
- description // the description of the option
|
||||
- css //The css code that will modified the skin $ symbols in this code will be replaced by the value selected by the user (in number, select and color picer)
|
||||
|
||||
Some option have custom properties:
|
||||
|
||||
- ## number properties
|
||||
- default //Default value
|
||||
- step //step of the input
|
||||
- ## selector properties
|
||||
- selections //Array of options
|
||||
- ## selections properties
|
||||
- name // name of the option
|
||||
- value // value of the option
|
||||
|
||||
|
||||
|
||||
|
||||
10
install.bat
Normal file
@@ -0,0 +1,10 @@
|
||||
@ECHO OFF
|
||||
@echo This will not work if you have installed jellyfin to a custom location
|
||||
set /p ask = Enter 'X' to continue or 'C' to cancel:
|
||||
if "%ask%" neq "x" goto:eof
|
||||
|
||||
@echo starting install...
|
||||
|
||||
dotnet publish --configuration Release --output bin
|
||||
|
||||
move bin\Jellyfin.Plugin.SkinManager.dll C:\ProgramData\Jellyfin\Server\plugins\SkinManager
|
||||
108
skins-2.0.json
Normal file
@@ -0,0 +1,108 @@
|
||||
[
|
||||
{
|
||||
"name": "Default",
|
||||
"author": "Jellyfin",
|
||||
"versions": [
|
||||
{
|
||||
"name": "Default",
|
||||
"description":"Default, stock, Jellyfin.",
|
||||
"css": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Jellyflix",
|
||||
"author": "prayagprajapati17",
|
||||
"versions": [
|
||||
{
|
||||
"name": "Default",
|
||||
"description":"A theme that aims to replicate the red and black look of Netflix. Theme is by prayag17.",
|
||||
"css": "@import url(https://prayag17.github.io/JellyFlix/default.css);"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Monochromic",
|
||||
"author": "EdgeMentality",
|
||||
"versions": [
|
||||
{
|
||||
"name": "Default",
|
||||
"description": "This theme aims to be minimalistic and somewhat muted in color. Add-ons and custom accent colors are possible, but not entirely supported by this plug-in. Visit the github of the theme for more information.",
|
||||
"css": "@import url(https://ctalvio.github.io/Monochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css');"
|
||||
},
|
||||
{
|
||||
"name": "Sharp corners",
|
||||
"description": "No rounded corners.",
|
||||
"css": "@import url(https://ctalvio.github.io/Monochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css'); :root {--rounding: 0px;}"
|
||||
},
|
||||
{
|
||||
"name": "Accent color - blue",
|
||||
"description": "Uses the default blue color for accents.",
|
||||
"css": "@import url(https://ctalvio.github.io/Monochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css'); @import url('https://ctalvio.github.io/Monochromic/jfblue_style.css');"
|
||||
},
|
||||
{
|
||||
"name": "Accent color - purple",
|
||||
"description": "Uses a purple shade, also suited for Jellyfin.",
|
||||
"css": "@import url(https://ctalvio.github.io/Monochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css'); @import url('https://ctalvio.github.io/Monochromic/jfpurple_style.css');"
|
||||
},
|
||||
{
|
||||
"name": "Accent color - blue - sharp",
|
||||
"description": "Uses the default blue color for accents. Sharp corners.",
|
||||
"css": "@import url(https://ctalvio.github.io/Monochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css'); @import url('https://ctalvio.github.io/Monochromic/jfblue_style.css'); :root {--rounding: 0px;}"
|
||||
},
|
||||
{
|
||||
"name": "Accent color - purple - sharp",
|
||||
"description": "Uses a purple shade, also suited for Jellyfin. Sharp corners.",
|
||||
"css": "@import url(https://ctalvio.github.io/Monochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css'); @import url('https://ctalvio.github.io/Monochromic/jfpurple_style.css'); :root {--rounding: 0px;}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Kaleidochromic",
|
||||
"author": "EdgeMentality",
|
||||
"versions": [
|
||||
{
|
||||
"name": "Default",
|
||||
"description": "This theme aims to be more colorful and minimalistic. Add-ons and custom accent colors are possible, but not entirely supported by this plug-in. Visit the github of the theme for more information.",
|
||||
"css": "@import url(https://ctalvio.github.io/Kaleidochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css');"
|
||||
},
|
||||
{
|
||||
"name": "Sharp corners",
|
||||
"description": "No rounded corners.",
|
||||
"css": "@import url(https://ctalvio.github.io/Kaleidochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css'); :root {--rounding: 0px;}"
|
||||
},
|
||||
{
|
||||
"name": "Accent color - blue",
|
||||
"description": "Uses the default blue color for accents.",
|
||||
"css": "@import url(https://ctalvio.github.io/Kaleidochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css'); @import url('https://ctalvio.github.io/Monochromic/jfblue_style.css');"
|
||||
},
|
||||
{
|
||||
"name": "Accent color - blue - sharp",
|
||||
"description": "Uses the default blue color for accents. Sharp corners.",
|
||||
"css": "@import url(https://ctalvio.github.io/Kaleidochromic/default_style.css); @import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css'); @import url('https://ctalvio.github.io/Monochromic/jfblue_style.css'); :root {--rounding: 0px;}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Novachromic",
|
||||
"author": "EdgeMentality",
|
||||
"versions":[
|
||||
{
|
||||
"name": "Default",
|
||||
"description": "Novachromic is essentially Monochromic, but with another layer of overrides on top.",
|
||||
"css" : "@import url('https://ctalvio.github.io/Novachromic/default_style.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "JellySkin",
|
||||
"author": "prayagprajapati17",
|
||||
"versions": [
|
||||
{
|
||||
"name": "Default",
|
||||
"description":"A very bright and colorful look using lots of drop shadows. Theme is by prayag17.",
|
||||
"css": "@import url('https://prayag17.github.io/JellySkin/default.css');"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
909
skins-3.0.json
Normal file
@@ -0,0 +1,909 @@
|
||||
[{
|
||||
"name": "Default",
|
||||
"author": "Jellyfin",
|
||||
"description": "Default, stock, Jellyfin.",
|
||||
"defaultCss": "",
|
||||
"previews": [{
|
||||
"name": "Login Page",
|
||||
"url": "https://raw.githubusercontent.com/danieladov/jellyfin-plugin-skin-manager/master/src/img/Default/1.png"
|
||||
},
|
||||
{
|
||||
"name": "Home/Index Page",
|
||||
"url": "https://raw.githubusercontent.com/danieladov/jellyfin-plugin-skin-manager/master/src/img/Default/2.png"
|
||||
},
|
||||
{
|
||||
"name": "Library Page",
|
||||
"url": "https://raw.githubusercontent.com/danieladov/jellyfin-plugin-skin-manager/master/src/img/Default/3.png"
|
||||
},
|
||||
{
|
||||
"name": "Title page",
|
||||
"url": "https://raw.githubusercontent.com/danieladov/jellyfin-plugin-skin-manager/master/src/img/Default/4.png"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": []
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "JellySkin",
|
||||
"author": "prayagprajapati17",
|
||||
"description": "A very bright and colorful look using lots of drop shadows. Theme is by prayag17.",
|
||||
"defaultCss": "@import url('https://cdn.jsdelivr.net/npm/jellyskin@latest/dist/main.css');",
|
||||
"previews": [{
|
||||
"name": "Login Page",
|
||||
"url": "https://cdn.jsdelivr.net/gh/prayag17/JellySkin/img/login.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Home/Index Page",
|
||||
"url": "https://cdn.jsdelivr.net/gh/prayag17/JellySkin/img/Home.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Library Page",
|
||||
"url": "https://cdn.jsdelivr.net/gh/prayag17/JellySkin/img/Movies.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Title page",
|
||||
"url": "https://cdn.jsdelivr.net/gh/prayag17/JellySkin/img/Title%20Page-Movie.jpg"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": [{
|
||||
"type": "selector",
|
||||
"name": "Gradient",
|
||||
"description": "Changes the Jellyfin themed Hover gradient",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/$.css');",
|
||||
"selections": [{
|
||||
"name": "Default",
|
||||
"value": "",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/default.css');"
|
||||
},
|
||||
{
|
||||
"name": "Sea Gradient",
|
||||
"value": "seaGradient",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/addons/Gradients/seaGradient.css');"
|
||||
},
|
||||
{
|
||||
"name": "Sunset Gradient",
|
||||
"value": "sunsetGradient",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/addons/Gradients/sunsetGradient.css');"
|
||||
|
||||
},
|
||||
{
|
||||
"name": "Mauve Gradient",
|
||||
"value": "morningGradient",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/addons/Gradients/mauveGradient.css');"
|
||||
|
||||
},
|
||||
{
|
||||
"name": "Night Sky Gradient",
|
||||
"value": "nightSkyGradient",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/addons/Gradients/nightSkyGradient.css');"
|
||||
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Theme Logo",
|
||||
"description": "Styles title page in such a way in which logos are used instead of Names.",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/addons/Logo.css');"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Compact Posters",
|
||||
"description": "If you want to display your posters to be compact.",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/addons/compact-poster.css');"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Improve Performance",
|
||||
"description": "Removes all gradient transparecy due to performance issues on older devices.",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellySkin/addons/imp-per.css');"
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "JellyFlix",
|
||||
"author": "prayagprajapati17",
|
||||
"description": "A theme that aims to replicate the red and black look of Netflix. Theme is by prayag17.",
|
||||
"defaultCss": "@import url(https://cdn.jsdelivr.net/gh/prayag17/JellyFlix@latest/default.css);",
|
||||
"previews": [{
|
||||
"name": "Login Page",
|
||||
"url": "https://cdn.jsdelivr.net/gh/prayag17/JellyFlix@latest/img/Login.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Home/Index Page",
|
||||
"url": "https://cdn.jsdelivr.net/gh/prayag17/JellyFlix@latest/img/Home.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Library Page",
|
||||
"url": "https://cdn.jsdelivr.net/gh/prayag17/JellyFlix@latest/img/Movies.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Title page",
|
||||
"url": "https://cdn.jsdelivr.net/gh/prayag17/JellyFlix@latest/img/Title%20Page-TV.jpg"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": [{
|
||||
"type": "checkBox",
|
||||
"name": "Theme Logo",
|
||||
"description": "Styles title page in such a way in which logos are used instead of Names.",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/prayag17/JellyFlix@latest/addons/Logo.css');"
|
||||
}]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Ultrachromic",
|
||||
"author": "Casper Talvio",
|
||||
"description": "The final form, the true evolution of the chromic theme saga! The old trilogy of chromic themes are deprecated, as their appearances can be replicated using Ultrachromic.",
|
||||
"defaultCss": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/base.css');@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/accentlist.css');",
|
||||
"previews": [{
|
||||
"name": "Login Page",
|
||||
"url": "https://user-images.githubusercontent.com/4365015/127768970-e827c7e4-f4ce-4229-a68a-b2e87a723ef0.png"
|
||||
},
|
||||
{
|
||||
"name": "Home/Index Page",
|
||||
"url": "https://user-images.githubusercontent.com/4365015/127774204-03957527-7178-4ea2-8674-d83fe6a97d1c.png"
|
||||
},
|
||||
{
|
||||
"name": "Library Page",
|
||||
"url": "https://raw.githubusercontent.com/danieladov/jellyfin-plugin-skin-manager/master/src/img/Monochromic/Lib.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Title page",
|
||||
"url": "https://user-images.githubusercontent.com/4365015/127778994-ddee8235-6bb2-42ae-a8b1-f9023dc69398.png"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Customization Details",
|
||||
"description": "Recommended only with the Custom theme. Not guaranteed to work with the presets.",
|
||||
"options": [{
|
||||
"type": "checkBox",
|
||||
"name": "Recommended Fixes",
|
||||
"description": "Contains various small tweaks all over the JF UI, an alignment here, a size tweak there.",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/fixes.css');"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Jellyfin Fonts",
|
||||
"description": "Make Jellyfin use the same font as its logo, for everything.",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/jf_font.css');"
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Rounding",
|
||||
"description": "Circlehover keeps the stock circle accent when hovering over things, otherwise the accent will be a rounded square like everythig else.",
|
||||
"css": "/* Rounding */",
|
||||
"selections": [{
|
||||
"name": "Default",
|
||||
"value": "default",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/rounding.css');"
|
||||
},
|
||||
{
|
||||
"name": "Circlehover",
|
||||
"value": "circlehover",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/rounding_circlehover.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Smaller Cast List",
|
||||
"description": "A smaller, square aspect ratio style cast list.",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/smallercast.css');"
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Compact episode list",
|
||||
"description": "A more easily scrolled episode list, there is the option to keep it as a list that is more compact, or turning the episode list into a grid menu.",
|
||||
"css": "/* Compact list */",
|
||||
"selections": [{
|
||||
"name": "Compact List",
|
||||
"value": "compactlist",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/episodelist/episodes_compactlist.css');"
|
||||
},
|
||||
{
|
||||
"name": "Grid",
|
||||
"value": "grid",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/episodelist/episodes_grid.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Transparent Top Bar",
|
||||
"description": "Transparent top bar.",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/header/header_transparent.css');"
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Login Screen",
|
||||
"description": "Login screen styles. The minimalistic option has no frame or prompt text.",
|
||||
"css": "/* Login frame */",
|
||||
"selections": [{
|
||||
"name": "Login Frame",
|
||||
"value": "loginframe",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/login/login_frame.css');"
|
||||
},
|
||||
{
|
||||
"name": "Login Minimalistic",
|
||||
"value": "loginminimalistic",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/login/login_minimalistic.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Input fields",
|
||||
"description": "Input field styles, with borders that highlight when selected, or with no borders, and the background highlights, when selected.",
|
||||
"css": "/* Input fields */",
|
||||
"selections": [{
|
||||
"name": "Border",
|
||||
"value": "fieldsborder",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/fields/fields_border.css');"
|
||||
},
|
||||
{
|
||||
"name": "No Border",
|
||||
"value": "fieldsnoborder",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/fields/fields_noborder.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Watched/Unwatched indicators",
|
||||
"description": "Two options, should the indicator be floating, or attached to the corner of the title card.",
|
||||
"css": "/* Watched/Unwatched */",
|
||||
"selections": [{
|
||||
"name": "Floating",
|
||||
"value": "indicatorfloating",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/cornerindicator/indicator_floating.css');"
|
||||
},
|
||||
{
|
||||
"name": "Corner",
|
||||
"value": "indicatorcorner",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/cornerindicator/indicator_corner.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Theme",
|
||||
"description": "Dark, light, and colorful type.",
|
||||
"css": "/* Theme */",
|
||||
"selections": [{
|
||||
"name": "Dark",
|
||||
"value": "darktheme",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/type/dark.css');"
|
||||
},
|
||||
{
|
||||
"name": "White",
|
||||
"value": "whitetheme",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/type/light.css');"
|
||||
},
|
||||
{
|
||||
"name": "Colorful",
|
||||
"value": "colorfultheme",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/type/colorful.css');"
|
||||
},
|
||||
{
|
||||
"name": "Dark with Accent",
|
||||
"value": "darkwithaccenttheme",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/type/dark_withaccent.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Title Page",
|
||||
"description": "Four options, two versions, each version can be used with or without a logo replacing title text.",
|
||||
"css": "/* Title page */",
|
||||
"selections": [{
|
||||
"name": "Simple",
|
||||
"value": "titlesimple",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/titlepage/title_simple.css');"
|
||||
},
|
||||
{
|
||||
"name": "Simple with Logo",
|
||||
"value": "titlesimplelogo",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/titlepage/title_simple-logo.css');"
|
||||
},
|
||||
{
|
||||
"name": "Banner",
|
||||
"value": "titlebanner",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/titlepage/title_banner.css');"
|
||||
},
|
||||
{
|
||||
"name": "Banner with Logo",
|
||||
"value": "titlebannerlogo",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/titlepage/title_banner-logo.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Progress bar",
|
||||
"description": "Default, overlay or floating style progress indicator for library items.",
|
||||
"css": "/* Progress bar */",
|
||||
"selections": [{
|
||||
"name": "Overlay",
|
||||
"value": "overlayprogress",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/overlayprogress.css');"
|
||||
},
|
||||
{
|
||||
"name": "Bottom Bar",
|
||||
"value": "bottombarprogress",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/bottombarprogress.css');"
|
||||
},
|
||||
{
|
||||
"name": "Floating",
|
||||
"value": "floatingprogress",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/progress/floating.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Hoverglow Effect",
|
||||
"description": "",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/effects/hoverglow.css');"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Glassy Effect",
|
||||
"description": "",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/effects/glassy.css');"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Pan-Animation Effect",
|
||||
"description": "Caution: Pan-animation can cause flickering on chromium based browsers when the backdrop is also modified",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/effects/pan-animation.css');"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Backdrop-Hack Effect",
|
||||
"description": "",
|
||||
"css": "@import url('https://ctalvio.github.io/Monochromic/backdrop-hack_style.css');"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Modify Backdrop Blur",
|
||||
"css": ".backdropImage {filter: blur($px);}",
|
||||
"default": "18",
|
||||
"description": ""
|
||||
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Modify Backdrop Saturation",
|
||||
"css": ".backdropImage {filter: saturate($%);}",
|
||||
"default": "120",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Modify Backdrop Contrast",
|
||||
"css": ".backdropImage {filter: contrast($%);}",
|
||||
"default": "120",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Modify Backdrop Brightness",
|
||||
"css": ".backdropImage {filter: brightness($%);}",
|
||||
"default": "40",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "Modify Login Background url",
|
||||
"css": "#loginPage {background: url($) !important;}",
|
||||
"default": "https://i.imgur.com/9vL4iNf.png",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"name": "Modify Accent Color",
|
||||
"css": ":root {--accent: $;}",
|
||||
"mode":"only_numbers",
|
||||
"default": "#6279cd",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Modify Rounding",
|
||||
"css": ":root {--rounding: $px;}",
|
||||
"default": "12",
|
||||
"description": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Monochromic",
|
||||
"author": "EdgeMentality",
|
||||
"description": "This theme aims to be minimalistic and somewhat muted in color. Add-ons and custom accent colors are possible, but not entirely supported by this plug-in. Visit the github of the theme for more information.",
|
||||
"defaultCss": "@import url('https://cdn.jsdelivr.net/gh/CTalvio/Ultrachromic/presets/monochromic_preset.css');",
|
||||
"previews": [{
|
||||
"name": "Login Page",
|
||||
"url": "https://github.com/danieladov/jellyfin-plugin-skin-manager/blob/master/src/img/Monochromic/login.jpg?raw=true"
|
||||
},
|
||||
{
|
||||
"name": "Home/Index Page",
|
||||
"url": "https://github.com/CTalvio/Monochromic/blob/master/screenshots/1.png?raw=true"
|
||||
},
|
||||
{
|
||||
"name": "Library Page",
|
||||
"url": "https://raw.githubusercontent.com/danieladov/jellyfin-plugin-skin-manager/master/src/img/Monochromic/Lib.jpg"
|
||||
},
|
||||
{
|
||||
"name": "Title page",
|
||||
"url": "https://github.com/CTalvio/Monochromic/raw/master/screenshots/2.png"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": [{
|
||||
"type": "checkBox",
|
||||
"name": "Improve performance",
|
||||
"description": "The theme uses mask-image to fade out items below the top bar as you scroll. This works well on most reasonable hardware but struggles on some phones and especially smart TVs. This switches to a method without using mask-image, but foregoes the fade-out effect. I may switch to this method being the default.",
|
||||
"css": "@import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css');"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "No rounded corners",
|
||||
"description": "In fact, squares off every rounded corner JF ever had.",
|
||||
"css": "@import url('https://ctalvio.github.io/Monochromic/sharp_style.css'); "
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Restore bottom bar style episode progress",
|
||||
"description": "Don't like my transparent view progress overlay? Use this to go back to the old style.",
|
||||
"css": "@import url('https://ctalvio.github.io/Monochromic/bottom-progress_style.css');"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Modify rounding",
|
||||
"description": "Amount of rounding. Zero is none.",
|
||||
"css": ":root {--rounding: $px;}",
|
||||
"default": "5"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"name": "Accent color",
|
||||
"mode":"only_numbers",
|
||||
"description": "Choose a custom accent color to use with the theme.",
|
||||
"css": "@import url('https://ctalvio.github.io/Monochromic/customcolor-advanced_style.css');:root {--accent: $;}",
|
||||
"default": ""
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Kaleidochromic",
|
||||
"author": "Casper Talvio",
|
||||
"description": "This theme aims to be more colorful and minimalistic. Add-ons and custom accent colors are possible, but not entirely supported by this plug-in. Visit the github of the theme for more information.",
|
||||
"defaultCss": "@import url('https://ctalvio.github.io/Kaleidochromic/default_style.css');",
|
||||
"previews": [{
|
||||
"name": "Login Page",
|
||||
"url": "https://github.com/danieladov/jellyfin-plugin-skin-manager/blob/master/src/img/Kaleidochromic/Login.jpg?raw=true"
|
||||
},
|
||||
{
|
||||
"name": "Home/Index Page",
|
||||
"url": "https://github.com/CTalvio/Kaleidochromic/raw/main/screenshots/6.png"
|
||||
},
|
||||
{
|
||||
"name": "Library Page",
|
||||
"url": "https://github.com/CTalvio/Kaleidochromic/raw/main/screenshots/5.png"
|
||||
},
|
||||
{
|
||||
"name": "Title page",
|
||||
"url": "https://github.com/CTalvio/Kaleidochromic/raw/main/screenshots/1.png"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": [{
|
||||
"type": "checkBox",
|
||||
"name": "Improve performance",
|
||||
"description": "The theme uses mask-image to fade out items below the top bar as you scroll. This works well on most reasonable hardware but struggles on some phones and especially smart TVs. This switches to a method without using mask-image, but foregoes the fade-out effect.",
|
||||
"css": "@import url('https://ctalvio.github.io/Monochromic/improve-performance_style.css');"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Restore bottom bar style episode progress",
|
||||
"description": "Don't like my transparent view progress overlay? Use this to go back to the old style.",
|
||||
"css": "@import url('https://ctalvio.github.io/Monochromic/bottom-progress_style.css');"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Modify rounding",
|
||||
"description": "Amount of rounding. Zero is none.",
|
||||
"css": ":root {--rounding: $px;}",
|
||||
"default": "12"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"name": "Accent color",
|
||||
"mode":"only_numbers",
|
||||
"description": "Choose a custom accent color to use with the theme.",
|
||||
"css": ":root {--accent: $;}",
|
||||
"default": "#6279cd"
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Novachromic",
|
||||
"author": "EdgeMentality",
|
||||
"description": "Novachromic is essentially Monochromic, but with another layer of overrides on top.",
|
||||
"defaultCss": "@import url('https://ctalvio.github.io/Novachromic/default_style.css');",
|
||||
"previews": [
|
||||
|
||||
{
|
||||
"name": "Home/Index Page",
|
||||
"url": "https://github.com/CTalvio/Novachromic/raw/main/screenshots/one.png"
|
||||
},
|
||||
{
|
||||
"name": "Library Page",
|
||||
"url": "https://github.com/CTalvio/Novachromic/raw/main/screenshots/six.png"
|
||||
},
|
||||
{
|
||||
"name": "Title page",
|
||||
"url": "https://github.com/CTalvio/Novachromic/raw/main/screenshots/four.png"
|
||||
},
|
||||
{
|
||||
"name": "Dashboard page",
|
||||
"url": "https://github.com/CTalvio/Novachromic/raw/main/screenshots/two.png"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": [{
|
||||
"type": "checkBox",
|
||||
"name": "Restore bottom bar style episode progress",
|
||||
"description": "Don't like my transparent view progress overlay? Use this to go back to the old style.",
|
||||
"css": "@import url('https://ctalvio.github.io/Monochromic/bottom-progress_style.css');"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Modify rounding",
|
||||
"description": "Amount of rounding. Zero is none.",
|
||||
"css": ":root {--rounding: $px;}",
|
||||
"default": "12"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"name": "Accent color",
|
||||
"mode":"only_numbers",
|
||||
"description": "Choose a custom accent color to use with the theme.",
|
||||
"css": ":root {--accent: $;}",
|
||||
"default": "#ffffff"
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Dark And Green",
|
||||
"author": "mbcooper83",
|
||||
"description": "A Dark And Green Theme for Jellyfin.",
|
||||
"defaultCss": "@import url('https://mbcooper83.github.io/jfcssdrkgrn/jellyfin-darkangreen.css');",
|
||||
"previews": [
|
||||
{
|
||||
"name": "Home/Index Page",
|
||||
"url": "https://camo.githubusercontent.com/6dd10c355679d68222c4bed4889be5e7c453e623acc0308bf0e5cab464fc5e66/68747470733a2f2f6d62636f6f70657238332e6769746875622e696f2f6a6663737364726b67726e2f6a6663737330312e706e673f7261773d74727565"
|
||||
},
|
||||
{
|
||||
"name": "Settings Page",
|
||||
"url": "https://camo.githubusercontent.com/fe309944755cf16b8a78ded952c28758bbf2fa8a2cd4a9f035953e9404747a50/68747470733a2f2f6d62636f6f70657238332e6769746875622e696f2f6a6663737364726b67726e2f6a6663737330322e706e673f7261773d74727565"
|
||||
},
|
||||
{
|
||||
"name": "Episode/season page",
|
||||
"url": "https://camo.githubusercontent.com/6d8dd75114e06bffbc9ea87f4fb2845dc8a49b9408b5f79322a6d4ce80b4ee50/68747470733a2f2f6d62636f6f70657238332e6769746875622e696f2f6a6663737364726b67726e2f6a6663737330332e706e673f7261773d74727565"
|
||||
},
|
||||
{
|
||||
"name": "Player",
|
||||
"url": "https://camo.githubusercontent.com/fcef7d4e498abf47f9dc44337436b2664ee2ce63195b93ec6ea564f1f689300c/68747470733a2f2f6d62636f6f70657238332e6769746875622e696f2f6a6663737364726b67726e2f6a6663737330342e706e673f7261773d74727565"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": []
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "JellyTheme",
|
||||
"author": "ShiniGandhi",
|
||||
"description": "A heavily modified theme for Jellyfin with a very original name.",
|
||||
"defaultCss": "/* JellyTheme */",
|
||||
"previews": [
|
||||
{
|
||||
"name": "Main page, with resized cards (optional)",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/raw/main/screenshots/Index-Resized-Cards.png"
|
||||
},
|
||||
{
|
||||
"name": "Main page, no resized cards",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/raw/main/screenshots/Index.png"
|
||||
},
|
||||
{
|
||||
"name": "Movie page with a single version and no trailer playing",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/raw/main/screenshots/Movie-No-Trailer_Single-Version.png"
|
||||
},
|
||||
{
|
||||
"name": "Movie page with multiple versions and a trailer playing",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/raw/main/screenshots/Movie-Trailer-and-Versions.png"
|
||||
},
|
||||
{
|
||||
"name": "TV show page",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/raw/main/screenshots/Show.png"
|
||||
},
|
||||
{
|
||||
"name": "TV show - compact seasons list (optional)",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/raw/main/screenshots/Season-List-Compact.png"
|
||||
},
|
||||
{
|
||||
"name": "TV show - episodes in season",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/raw/main/screenshots/Season.png"
|
||||
},
|
||||
{
|
||||
"name": "TV show - episode entry",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/raw/main/screenshots/Episode.png"
|
||||
},
|
||||
{
|
||||
"name": "Cleaner user settings (optional)",
|
||||
"url": "https://github.com/ShiniGandhi/JellyTheme/blob/main/screenshots/User-Settings.png?raw=true"
|
||||
}
|
||||
],
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": [{
|
||||
"type": "selector",
|
||||
"name": "Mode",
|
||||
"description": "Select cleaner for a slightly cleaner UI, with no backdrop in the main menu and a few more things .",
|
||||
"css": "/*mode*/",
|
||||
"selections": [{
|
||||
"name": "Normal",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/ShiniGandhi/JellyTheme@latest/latest/JellyTheme.css'); "
|
||||
},
|
||||
{
|
||||
"name": "Cleaner",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/ShiniGandhi/JellyTheme@latest/latest/Cleaner-UI.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"mode": "rgba",
|
||||
"name": "Accent color",
|
||||
"description": "Change the accent color.",
|
||||
"css": ":root {--accent:$!important;}",
|
||||
"default": "#6279cd"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Resize Some Elements",
|
||||
"description": "If you want Continue Watching, Next Up and the list of seasons to be smaller, as shown in my screenshots, check this",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/ShiniGandhi/JellyTheme@latest/latest/Resize-Cards.css');",
|
||||
"default":"false"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Right-to-Left Support",
|
||||
"description": "If your server's metadata is in Hebrew, Arabic (or any other language that is written right-to-left, check this:",
|
||||
"css": "@import url('https://cdn.jsdelivr.net/gh/ShiniGandhi/JellyTheme@latest/latest/RTL-Fix.css');",
|
||||
"default":"false"
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Custom",
|
||||
"author": "you",
|
||||
"description": "customize the look of jellyfin by your needs",
|
||||
"defaultCss": "/*Custom*/",
|
||||
"categories": [{
|
||||
"name": "Fonts",
|
||||
"options": [{
|
||||
"type": "googleFonts",
|
||||
"name": "Change Font",
|
||||
"css": "html {font-family: '$',sans-serif ; } body,h1,h2,h3 { font-family: '$' ,sans-serif;}"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Title Font Size",
|
||||
"description": "Change the size of the font used at titles.",
|
||||
"step": "0.1",
|
||||
"css": "h1 {font-size: $em;}",
|
||||
"default": "1.8"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Home/Dashboard Page",
|
||||
"options": [{
|
||||
"type": "checkBox",
|
||||
"name": "Enlarge Tab Buttons",
|
||||
"description": "Enlarges the tab buttons, suggested, genres, etc. By default they are really tiny, especially on mobile.",
|
||||
"css": ".headerTabs.sectionTabs {text-size-adjust: 110%; font-size: 110%;}.pageTitle {margin-top: auto; margin-bottom: auto;}.emby-tab-button {padding: 1.75em 1.7em;}"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Miscellaneous",
|
||||
"options": [{
|
||||
"type": "selector",
|
||||
"name": "Poster card hover effect",
|
||||
"description": "Changes the hover effect on Movie/TV show/Music poster card.",
|
||||
"css": "/*poster-eff*/",
|
||||
"selections": [{
|
||||
"name": "Scale in and out",
|
||||
"css": " /* Dynamic Poster effect-option1*/ .cardBox-bottompadded{margin-bottom; 1em !important;}.itemsContainer>.card>.cardBox {margin: 1em;background: rgba(0,0,0,0.5);transition: transform .2s;}.card:hover .cardBox{transform: scale(1.1);}"
|
||||
},
|
||||
{
|
||||
"name": "Pop up and down",
|
||||
"css": "/*Dynamic Poster effect-option2*/.itemsContainer>.card>.cardBox {margin: 1em;background: rgba(0,0,0,0.5);transition: transform .2s, box-shadow .2s;}.card:hover .cardBox{transform: translatey(-5px);box-shadow: 0px 5px 10px black;}"
|
||||
},
|
||||
{
|
||||
"name": "Poster Image in and out",
|
||||
"css": "/*Dynamic Poster effect-option3*/.card:hover .cardImageContainer{filter:background-size: 120%} .cardImageContainer{background-size: 105%;transition: all .2s;}"
|
||||
},
|
||||
{
|
||||
"name": "Poster Image blur",
|
||||
"css": "/*Dynamic Poster effect-option4*/.card:hover .cardImageContainer{filter: blur(2px);} .cardImageContainer{transition: all .2s;}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Icon Pack",
|
||||
"description": "Changes all icons like dashboard and play. Choose non google fonts if you are blocking google fonts",
|
||||
"css": "/*Icons*/",
|
||||
"selections": [{
|
||||
"name": "Default",
|
||||
"css": ""
|
||||
},
|
||||
{
|
||||
"name": "Outlined",
|
||||
"css": "@import url('https://prayag17.github.io/Jellyfin-Icons/Outline.css');"
|
||||
},
|
||||
{
|
||||
"name": "Rounded",
|
||||
"css": "@import url('https://prayag17.github.io/Jellyfin-Icons/round.css');"
|
||||
},
|
||||
{
|
||||
"name": "Sharp",
|
||||
"css": "@import url('https://prayag17.github.io/Jellyfin-Icons/Sharp.css');"
|
||||
}, {
|
||||
"name": "Outlined-Non google fonts",
|
||||
"css": "@import url('https://prayag17.github.io/Jellyfin-Icons/Outline.css');"
|
||||
},
|
||||
{
|
||||
"name": "Rounded-Non google fonts",
|
||||
"css": "@import url('https://prayag17.github.io/Jellyfin-Icons/round.css');"
|
||||
},
|
||||
{
|
||||
"name": "Sharp-Non google fonts",
|
||||
"css": "@import url('https://prayag17.github.io/Jellyfin-Icons/Sharp.css');"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Image gradient in title page",
|
||||
"description": "removes the bg of detail ribbon and replace it with image gradient",
|
||||
"css": ".detailRibbon {background: transparent;}.itemBackdrop {-webkit-mask: linear-gradient(to bottom, black 50%,transparent);mask: linear-gradient(to bottom, black 50%,transparent);}"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Minimal Actor's card",
|
||||
"description": "display actor's cards in minimal and compact way",
|
||||
"css": "/*Actors*/.card[data-type=Actor] .cardBox {background: none;position: relative;}.card[data-type=Actor] .cardScalable {height: 0;overflow: hidden;padding-top: 100%;border-radius: var(--rounding);}.card[data-type=Actor] .cardText {position: absolute;background: transparent !important;}.card[data-type=Actor] .cardImageContainer::after {content: '';background: linear-gradient(360deg, rgba(0,0,0,0.75), transparent 70%);width: 100%;bottom: 0;position: absolute;padding-top: 100%;}.card[data-type=Actor].cardText-secondary {bottom: 0%;width: -webkit-fill-available;border-radius: 0px 0px 10px 10px;height: 22px;}.card[data-type=Actor] .cardText-first {bottom: 23.5px;width: -webkit-fill-available;height: 22px;}.layout-mobile .card[data-type=Actor] .cardText-first {color: white !important;}.card[data-type=Actor] .cardScalable {overflow: hidden;border-radius: var(--rounding);height: 3rem;}.card[data-type=Actor] .cardOverlayButton-br {position: absolute;bottom: 23% !important;right: 0 !important;}.card[data-type=Actor] .cardPadder {background: none;}.card[data-type=Actor] .cardImageIcon {bottom: 41%;position: absolute;left: 50%;transform: translateX(-50%);}"
|
||||
},
|
||||
{
|
||||
"type": "selector",
|
||||
"name": "Episode View",
|
||||
"description": "Theme episode list",
|
||||
"selections": [{
|
||||
"name": "Card",
|
||||
"css": " #itemDetailPage .vertical-list {display: grid;grid-template-columns: 30% 30% 30%;padding: 0 6px !important;height: fit-content;justify-content: space-evenly;-webkit-box-orient: horizontal;-webkit-box-direction: normal;margin: -6px;width: calc(100% - 6px);}.listItem-withContentWrapper:hover .listItemImageButton.itemAction.paper-icon-button-light {opacity: 100%;}@media (max-width: 901px){#itemDetailPage .vertical-list {grid-template-columns: 30% 30%;}}.listItem-withContentWrapper {transition: none;height: fit-content;max-width: 100%;margin: 6px;border-radius: var(--rounding);overflow: hidden;padding: 0;overflow: hidden;}.listItem-withContentWrapper:hover{background: transparent;}.listItem-content {height: 100%;}.listItem-content {display: -webkit-flex;display: flex;-webkit-align-items: center;align-items: center;width: 100%;display: grid;grid-template-columns: 100%;}.listItemImage.listItemImage-large.itemAction.lazy {height: 14rem;width: 100%;padding: 0 !important;margin: 0 !important;top: 0;left: 0;}.layout-mobile #itemDetailPage .vertical-list {grid-template-columns: 100%;}.secondary.listItem-overview.listItemBodyText {height: fit-content;}.layout-mobile .listItem-bottomoverview {padding: 0 10px;}.listItemBody.itemAction {padding: 0 5px;}.listItemImageButton.itemAction.paper-icon-button-light {opacity: 0;color: var(--accent);transition: all .2s;}.layout-mobile .listItemImageButton.itemAction.paper-icon-button-light{opacity: 100% !important;}"
|
||||
},
|
||||
{
|
||||
"name": "Compact List",
|
||||
"css": ".listItemImage.listItemImage-large.itemAction.lazy {height: 110px;}.listItem-content {height: 115px;}.secondary.listItem-overview.listItemBodyText {height: 61px;margin: 0;}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Blur episode thumbnail",
|
||||
"description": "Blur episode thumbnail to prevent spoiler. Note: Doesn't in browser's that dont support backdrop-filter, i.e firefox(can be enabled though), opera and more(unknown).",
|
||||
"css": " .nextUpSection.verticalSection.detailVerticalSection>div>div>div>div.cardScalable>button {filter: blur(10px);}div.listItem>div>div>button:nth-child(1) {transition: none !important;border-radius: 0px;height: 100%;width: 100%;backdrop-filter: blur(10px);}div.listItem>div>div>button:nth-child(1):hover {transition: none !important;border-radius: 0px;height: 100%;width: 100%;backdrop-filter: blur(10px);}#childrenContent>div>div>div>div.listItemImage.listItemImage large.itemAction.lazy.non-blurhashable.lazy-image-fadein-fast>button {transition: none !important;border-radius: 0px;height: 100%;width: 100%;backdrop-filter: blur(10px);}#childrenContent>div>div>div>div.listItemImage.listItemImage-large.itemAction.lazy.non-blurhashable.lazy-image-fadein-fast>button:hover {border-radius: 0px;height: 85%;width: 85%;backdrop-filter: blur(20px);}@supports not ( (backdrop-filter: blur(10px)) or (--webkit-backdrop-filter: blur(10px))) {#childrenContent>div>div>div>div.listItemImage.listItemImage-large.itemAction.lazy.non-blurhashable.lazy-image-fadein-fast {filter: blur(10px);}}@supports not ( (backdrop-filter: blur(10px)) or (--webkit-backdrop-filter: blur(10px))) {#itemDetailPage>div.detailPageWrapperContainer>div.detailPageSecondaryContainer>div.detailPageContent>div.verticalSection.detailVerticalSection.moreFromSeasonSection.emby-scroller-container>div.padded-top-focusscale.padded-bottom-focusscale.emby-scroller>.itemsContainer>.card.overflowBackdropCard.card-hoverable.card-withuserdata>div>.cardScalable {background: rgba(0, 0, 0, .5);filter: blur(10px);transition: none !important;filter: blur(10px);}}#itemDetailPage>div.detailPageWrapperContainer>div.detailPageSecondaryContainer>div.detailPageContent>div.verticalSection.detailVerticalSection.moreFromSeasonSection.emby-scroller-container>div.padded-top-focusscale.padded-bottom-focusscale.emby-scroller>.itemsContainer>.card.overflowBackdropCard.card-hoverable.card-withuserdata>div>.cardScalable>button {border-radius: 0px;height: 0%;width: 0%;background: rgba(0, 0, 0, .5);filter: blur(10px);transition: none !important;backdrop-filter: blur(10px);}.cardScalable{overflow: hidden;}"
|
||||
},
|
||||
{
|
||||
"type": "checkBox",
|
||||
"name": "Blur Dialog Background",
|
||||
"description": "Blur Menu and dialog background. Note: Works in Chrome and Edge only, functionalty can be enable, click on help button for info.",
|
||||
"css": ".mainDrawer {background: transparent;backdrop-filter: blur(20px);}"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"mode": "hex",
|
||||
"name": "Title Page Button text color",
|
||||
"description": "change button's text color.",
|
||||
"css": ".raised{color: $;}",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"mode": "hex",
|
||||
"name": "Title Page Button background color",
|
||||
"description": "change background color of button.",
|
||||
"css": ".raised{background-color: $;}",
|
||||
"default": "#303030"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"mode": "hex",
|
||||
"name": "Idle button color-foreground",
|
||||
"description": "This modifies the color of buttons like cast and search.",
|
||||
"css": ".paper-icon-button-light{color: $; transititon: all .2s;}",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"mode": "hex",
|
||||
"name": "Idle button color-background",
|
||||
"description": "This modifies the background color of buttons like cast and search.",
|
||||
"css": ".paper-icon-button-light{background-color: $ !important; transition: all .2s;}",
|
||||
"default": "#00000000"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"mode": "hex",
|
||||
"name": "Hover button color-foreground",
|
||||
"description": "This modifies the color of buttons like cast and search when your cursor is on it.",
|
||||
"css": ".paper-icon-button-light:hover{color: $ !important;}",
|
||||
"default": "#00a4dc"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"mode": "hex",
|
||||
"name": "Hover button color-background",
|
||||
"description": "This modifies the background color of buttons like cast and search when your cursor is on it.",
|
||||
"css": ".paper-icon-button-light:hover{background-color: $ !important;}",
|
||||
"default": "#00a4db33"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "Border Radius",
|
||||
"description": "Change the rounding",
|
||||
"css": ":root{--btn-rounding: $px; --rounding: $px;} .missingIndicator, .unairedIndicator {border-radius: var(--rounding);}.formDialogHeader {border-top-left-radius: var(--rounding);border-top-right-radius: var(--rounding);}.formDialogFooter {border-bottom-left-radius: var(--rounding);border-bottom-right-radius: var(--rounding);}.cardOverlayContainer {border-radius: var(--rounding) !important;}.primaryImageWrapper>img, .toast, .paperList, .cardContent, .sessionNowPlayingInnerContent, .listItem:hover, .cardImage, .fab, .raised, .multiSelectCheckboxOutline, .itemSelectionPanel, .cardContent-button, .cardContent-shadow, .itemDetailImage, .cardOverlayButton-hover, .cardImageContainer, .cardPadder, .listItemImage, .listItemImageButton, .listItemButton, .headerButton, .paper-icon-button-light, .innerCardFooter, .blurhash-canvas, .dialog, .countIndicator, .playedIndicator, .listItemIcon, .listItem-border, .button-flat, .visualCardBox, .checkboxOutline, .emby-select-withcolor, .chapterThumbTextContainer, .chapterThumbContainer, .chapterThumb, .emby-input, .emby-textarea, .emby-select-withcolor, .nowPlayingPageImage, .upNextDialog-poster-img, .upNextContainer, .cardOverlayButtonIcon {border-radius: var(--rounding) !important;}.osdPoster img {border-radius: var(--rounding);border: none;}.mdl-slider::-moz-range-thumb {border-radius: var(--rounding);}.mdl-slider::-ms-thumb {border-radius: var(--rounding);}.mdl-slider::-webkit-slider-thumb {border-radius: var(--rounding);}div[data-role='controlgroup'] a[data-role='button']:first-child {border-bottom-left-radius: var(--rounding);border-top-left-radius: var(--rounding);}div[data-role='controlgroup'] a[data-role='button']:last-child {border-bottom-right-radius: var(--rounding);border-top-right-radius: var(--rounding);}#dashboardPage .cardContent, #dashboardPage .sessionNowPlayingInnerContent {border-radius: var(--rounding) var(--rounding) 0 0 !important;}#divVirtualFolders .cardImageContainer, #divVirtualFolders .cardContent {border-radius: var(--rounding) var(--rounding) 0 0 !important;}#userProfilesPage .cardImage, #userProfilesPage .cardContent {border-radius: var(--rounding) var(--rounding) 0 0 !important;}#user_usage_report_table, .detailTable {border-radius: var(--rounding);}progress {border-radius: var(--rounding);}progress::-webkit-progress-bar {border-radius: var(--rounding);}progress::-moz-progress-bar {border-radius: var(--rounding);}progress::-webkit-progress-value {border-radius: var(--rounding);}.taskProgressOuter, .taskProgressInner {border-radius: var(--rounding) !important;}::-webkit-scrollbar-thumb {border-radius: var(--rounding);} .paper-icon-button-light{border-radius: var(--btn-rounding) !impotant;}",
|
||||
"default": "0"
|
||||
},
|
||||
{
|
||||
"type": "colorPicker",
|
||||
"name": "Background-color",
|
||||
"description": "change background-color of the background",
|
||||
"css": ".backgroundContainer.withBackdrop {background-color: $;}",
|
||||
"default": "rgba(0, 0, 0, 0.86)"
|
||||
},
|
||||
{
|
||||
"type": "blurSlider",
|
||||
"name": "Backdrop Blur",
|
||||
"description": "adds blur to the backdrop images default is zero",
|
||||
"css": ":root{--bgblur: blur($px)}.backdropImage {filter: var(--bgblur);}",
|
||||
"default": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,4 +1,10 @@
|
||||
[
|
||||
{
|
||||
"name":"Default",
|
||||
"author":"Jellyfin",
|
||||
"css": ""
|
||||
|
||||
},
|
||||
{
|
||||
"name":"Jellyflix",
|
||||
"author":"prayagprajapati17",
|
||||
@@ -24,4 +30,4 @@
|
||||
"css": "@import url('https://prayag17.github.io/JellySkin/default.css');"
|
||||
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
8
src/bgBlur.css
Normal file
@@ -0,0 +1,8 @@
|
||||
:root{--bgblur: blur($px)}
|
||||
/*Blur backdrops, feel free to edit the intensity of the filter values*/
|
||||
.backdropImage {
|
||||
filter: var(--bgblur);
|
||||
}
|
||||
.backgroundContainer.withBackdrop {
|
||||
background-color: rgba(0,0,0,0);
|
||||
}
|
||||
75
src/border-radius.css
Normal file
@@ -0,0 +1,75 @@
|
||||
/*Setting border Radius*/
|
||||
:root {--rounding: 0px;}
|
||||
/*Rounded corners on pretty much everything-Source Monochromic*/
|
||||
.formDialogHeader {
|
||||
border-top-left-radius: var(--rounding);
|
||||
border-top-right-radius: var(--rounding);
|
||||
}
|
||||
.formDialogFooter {
|
||||
border-bottom-left-radius: var(--rounding);
|
||||
border-bottom-right-radius: var(--rounding);
|
||||
}
|
||||
.cardOverlayContainer {
|
||||
border-radius: var(--rounding) !important;
|
||||
}
|
||||
.toast,
|
||||
.paperList,
|
||||
.cardContent,
|
||||
.sessionNowPlayingInnerContent,
|
||||
.listItem:hover,
|
||||
.cardImage,
|
||||
.fab,
|
||||
.multiSelectCheckboxOutline,
|
||||
.itemSelectionPanel,
|
||||
.cardContent-button,
|
||||
.cardContent-shadow,
|
||||
.itemDetailImage,
|
||||
.cardOverlayButton-hover,
|
||||
.cardImageContainer,
|
||||
.cardPadder,
|
||||
.listItemImage,
|
||||
.listItemImageButton,
|
||||
.listItemButton,
|
||||
.headerButton,
|
||||
.paper-icon-button-light,
|
||||
.innerCardFooter,
|
||||
.blurhash-canvas,
|
||||
.actionSheetMenuItem:hover,
|
||||
.dialog,
|
||||
.listItemIcon,
|
||||
.listItem-border,
|
||||
.button-flat,
|
||||
.visualCardBox,
|
||||
.checkboxOutline,
|
||||
.emby-select-withcolor,
|
||||
.chapterThumbTextContainer,
|
||||
.chapterThumbContainer,
|
||||
.chapterThumb,
|
||||
.emby-input,
|
||||
.emby-textarea,
|
||||
.emby-select-withcolor,
|
||||
.cardOverlayButtonIcon,
|
||||
.subtitleappearance-preview.flex.align-items-center.justify-content-center {
|
||||
border-radius: var(--rounding) !important;
|
||||
}
|
||||
.osdPoster img {
|
||||
border-radius: var(--rounding); border: none;
|
||||
}
|
||||
.mdl-slider::-moz-range-thumb {
|
||||
border-radius: var(--rounding);
|
||||
}
|
||||
.mdl-slider::-ms-thumb {
|
||||
border-radius: var(--rounding);
|
||||
}
|
||||
.mdl-slider::-webkit-slider-thumb {
|
||||
border-radius: var(--rounding);
|
||||
}
|
||||
|
||||
div[data-role="controlgroup"] a[data-role="button"]:first-child {
|
||||
border-bottom-left-radius: var(--rounding);
|
||||
border-top-left-radius: var(--rounding);
|
||||
}
|
||||
div[data-role="controlgroup"] a[data-role="button"]:last-child {
|
||||
border-bottom-right-radius: var(--rounding);
|
||||
border-top-right-radius: var(--rounding);
|
||||
}
|
||||
68
src/html/about.html
Normal file
@@ -0,0 +1,68 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Skin Manager-About</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="icon" href="https://jellyfin.org/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<div class="header" align="center">
|
||||
<div class="innerHeader nav">
|
||||
<a href="https://github.com/danieladov/jellyfin-plugin-skin-manager" class="link text"><li>See on Github</li></a>
|
||||
<a href="https://github.com/danieladov/jellyfin-plugin-skin-manager/issues" class="link text"><li>Request a skin</li></a>
|
||||
<a href="https://prayag17.github.io/jellyfin-plugin-skin-manager/" class="link text"><li class="selected">About</li></a>
|
||||
<a href="https://jellyfin.org" class="logo link"><li><img src="https://jellyfin.org/images/banner-dark.svg" style="size: 1em;height: 50px;max-width: 80%;float: right;z-index: 1;"></li></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="About">
|
||||
<div class="inner">
|
||||
<h1>About Skin Manager</h1>
|
||||
<div class="description">
|
||||
<p>
|
||||
This plugin is used to create custom skins and also give you (the user) few great community Skins. You can add more skins by clicking on the "Request a Skin" button.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contributorsCont">
|
||||
<fieldset>
|
||||
<h3>Contributors</h3>
|
||||
<p>The people who have helped in the development of this plugin are listed below</p>
|
||||
<div class="cont">
|
||||
<a href="https://github.com/danieladov" class="contributorsLink">
|
||||
<div class="contibutorsNames" style="background:linear-gradient(180deg, #c4c4c4ab, #c4c4c4ab), url(https://avatars2.githubusercontent.com/u/29411250?s=400&v=4);">
|
||||
<div class="top">
|
||||
<h3>Daniel Álvarez</h3>
|
||||
</div>@danieladov
|
||||
<p class="description">
|
||||
He is the creator of 3 Plugins for Jellyfin, namely- Merge Songs, Theme Music and Skin Manager
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="https://github.com/prayag17" class="contributorsLink">
|
||||
<div class="contibutorsNames" style="margin-left: 3em;background:linear-gradient(180deg, #c4c4c4ab, #c4c4c4ab), url(https://avatars1.githubusercontent.com/u/55829513?s=460&u=3f232a3900ade07490ae8bdadd62ec5d0e9e4ecf&v=4);">
|
||||
<div class="top">
|
||||
<h3>Prayag Prajapati</h3>
|
||||
</div>@prayag17
|
||||
<p class="description">
|
||||
He is the creator of 2 jellyfin Skins, namely- JellySkin and JellyFlix. He has helped in creating the "Custom" option in this plugin.
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
<a href="https://github.com/prayag17" class="contributorsLink">
|
||||
<div class="contibutorsNames" style="margin-left: 3em;background:linear-gradient(180deg, #c4c4c4ab, #c4c4c4ab), url(https://avatars2.githubusercontent.com/u/4365015?s=400&v=4);">
|
||||
<div class="top">
|
||||
<h3>Casper Talvio</h3>
|
||||
</div>@CTalvio
|
||||
<p class="description">
|
||||
He is the creator of 2 jellyfin Skins namely- Monochromic and Kaleidochromic.
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
48
src/html/help.html
Normal file
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Skin Manager-Help</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="icon" href="https://jellyfin.org/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<div class="header" align="center">
|
||||
<div class="innerHeader nav">
|
||||
<a href="https://github.com/danieladov/jellyfin-plugin-skin-manager" class="link text"><li>See on Github</li></a>
|
||||
<a href="https://github.com/danieladov/jellyfin-plugin-skin-manager/issues" class="link text"><li>Request a skin</li></a>
|
||||
<a href="https://prayag17.github.io/jellyfin-plugin-skin-manager/src/html/about.html#" class="link text"><li>About</li></a>
|
||||
<a href="https://jellyfin.org" class="logo link"><li><img src="https://jellyfin.org/images/banner-dark.svg" style="size: 1em;height: 50px;max-width: 80%;float: right;z-index: 1;"></li></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body" style="color: #3a3a3a !important;">
|
||||
<div class="skinRequest">
|
||||
<fieldset>
|
||||
<h1>How To request a new Skin</h1>
|
||||
<div class="internal">
|
||||
<h3>Steps</h3>
|
||||
<br>
|
||||
<ul>
|
||||
<li>Open this<a href="https://github.com/danieladov/jellyfin-plugin-skin-manager/issues" class="link" style="color: #3a3a3a !important; text-decoration: underline;"> link </a>or click the "Request a Skin" option present in the header</li>
|
||||
<li>Then Create a New Issue with title- <code>Skin Request:</code> Done!</li>
|
||||
</ul>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<h1>How to enable bluring of background fo dialogs and episode previes for Firefox</h1>
|
||||
<div class="internal">
|
||||
<h3>Steps</h3>
|
||||
<br>
|
||||
<ul>
|
||||
<li>go to <a href="about:config"> about:config </a>in firefox and click on "Accept the Risk and Continue".</li>
|
||||
<li>Search for <code>layout.css.backdrop-filter.enabled</code> and change false to true.</li>
|
||||
<li>Search for <code>gfx.webrender.all</code> and change it to true. Done!</li>
|
||||
</ul>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
30
src/html/skin__request.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js" integrity="sha512-n/4gHW3atM3QqRcbCn6ewmpxcLAHGaDjpEBu4xZd47N0W2oQ+6q7oc3PXstrJYXcbNU1OHdQ1T7pAP+gi5Yu8g==" crossorigin="anonymous"></script>
|
||||
<script src="../js/json__compile.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<form>
|
||||
<input type="text" id="name" name="name">
|
||||
<input type="text" id="author" name="author">
|
||||
<input type=" text " id="desc" name="desc">
|
||||
<input type=" text " id="css" name="css">
|
||||
<h2>Images</h2>
|
||||
<input type=" text " id="login" name="login">
|
||||
<input type=" text " id="home" name="home">
|
||||
<input type=" text " id="lib" name="lib">
|
||||
<input type=" text " id="title" name="title">
|
||||
<h2>Categories</h2>
|
||||
<input type="button" id="add" value="Add a foryour options categorie" onclick="add__option()">
|
||||
<input type="button" id="no_op" value="Don't have any options/addons?" onclick="no__option()">
|
||||
<div id="cat"></div>
|
||||
<input type="hidden" value="1" id="total_chq">
|
||||
<input type="button" onclick="createJSON()" value="save" />
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
107
src/html/style.css
Normal file
@@ -0,0 +1,107 @@
|
||||
body{
|
||||
margin: 0;
|
||||
font-family: Arial;
|
||||
}
|
||||
.body {
|
||||
margin: 2em;
|
||||
}
|
||||
.header {
|
||||
height: 80px;
|
||||
width: 100%;
|
||||
background: #101010;
|
||||
display: block;
|
||||
top: 0;
|
||||
position: sticky;
|
||||
}
|
||||
.innerHeader {
|
||||
height: 100%;
|
||||
margin: 0 1.5em;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav a{
|
||||
display: table;
|
||||
height: 100%;
|
||||
float: right;
|
||||
padding: 0px 10px !important;
|
||||
}
|
||||
.nav a li {
|
||||
vertical-align: middle;
|
||||
display: table-cell;
|
||||
}
|
||||
fieldset {
|
||||
border-radius: 15px;
|
||||
background: #dadada;
|
||||
border: none;
|
||||
padding: 1em;
|
||||
margin-top: 2em;
|
||||
}
|
||||
.link{
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
a.logo.link {
|
||||
float: left;
|
||||
}
|
||||
.About {
|
||||
margin: 2em;
|
||||
}
|
||||
.inner {
|
||||
background: #c4c4c4;
|
||||
padding: 1em;
|
||||
border-radius: 15px;
|
||||
color: #3a3a3a;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.cont {
|
||||
display: flex;
|
||||
}
|
||||
.contibutorsNames {
|
||||
padding: 1em;
|
||||
border-radius: 15px;
|
||||
width: fit-content;
|
||||
max-width: 10em;
|
||||
min-width: 10em;
|
||||
flex-wrap: wrap;
|
||||
height: fit-content;
|
||||
transition: all .2s;
|
||||
max-height: 20em;
|
||||
min-height: 15em;
|
||||
background-size: cover !important;
|
||||
}
|
||||
.contibutorsNames:hover {
|
||||
box-shadow: 0 3px 5px 0px #6e6e6e;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.contributorsLink {
|
||||
color: #3a3a3a !important;
|
||||
}
|
||||
.text li {
|
||||
color: #9a9a9a;
|
||||
transition: color .25s, border .25s;
|
||||
border-bottom: 5px solid rgba(0,0,0,0);
|
||||
}
|
||||
.text li:hover {
|
||||
color: white !important;
|
||||
border-bottom-color: #00a4dc !important;
|
||||
}
|
||||
.selected {
|
||||
color: white !important;
|
||||
border-bottom-color: #aa5cc3 !important;
|
||||
}
|
||||
img.userImg {
|
||||
width: 50%;
|
||||
border-radius: 15px;
|
||||
}
|
||||
code {
|
||||
display: block !important;
|
||||
width: fit-content;
|
||||
background: #585858;
|
||||
color: white;
|
||||
padding: .5rem;
|
||||
border-radius: 5.5px;
|
||||
border: .5px solid #999999;
|
||||
}
|
||||
BIN
src/img/Default/1.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
src/img/Default/2.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
src/img/Default/3.png
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
BIN
src/img/Default/4.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
src/img/Kaleidochromic/Login.jpg
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
src/img/Monochromic/Lib.jpg
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
src/img/Monochromic/login.jpg
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
src/img/thumb.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
641
src/js/FontPicker.js
Normal file
@@ -0,0 +1,641 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = global || self, global.FontPicker = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
var __assign = function() {
|
||||
__assign = Object.assign || function __assign(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
|
||||
function __rest(s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
function __generator(thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
}
|
||||
|
||||
function styleInject(css, ref) {
|
||||
if ( ref === void 0 ) ref = {};
|
||||
var insertAt = ref.insertAt;
|
||||
|
||||
if (!css || typeof document === 'undefined') { return; }
|
||||
|
||||
var head = document.head || document.getElementsByTagName('head')[0];
|
||||
var style = document.createElement('style');
|
||||
style.type = 'text/css';
|
||||
|
||||
if (insertAt === 'top') {
|
||||
if (head.firstChild) {
|
||||
head.insertBefore(style, head.firstChild);
|
||||
} else {
|
||||
head.appendChild(style);
|
||||
}
|
||||
} else {
|
||||
head.appendChild(style);
|
||||
}
|
||||
|
||||
if (style.styleSheet) {
|
||||
style.styleSheet.cssText = css;
|
||||
} else {
|
||||
style.appendChild(document.createTextNode(css));
|
||||
}
|
||||
}
|
||||
|
||||
var css = "@charset \"UTF-8\";\ndiv[id^=font-picker] {\n position: relative;\n display: inline-block;\n width: 200px;\n box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);\n}\ndiv[id^=font-picker] * {\n box-sizing: border-box;\n}\ndiv[id^=font-picker] p {\n margin: 0;\n padding: 0;\n}\ndiv[id^=font-picker] button {\n color: inherit;\n font-size: inherit;\n background: none;\n border: 0;\n outline: none;\n cursor: pointer;\n}\ndiv[id^=font-picker] .dropdown-button {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 35px;\n padding: 0 10px;\n background: #cbcbcb;\n}\ndiv[id^=font-picker] .dropdown-button:hover, div[id^=font-picker] .dropdown-button:focus {\n background: #bebebe;\n}\ndiv[id^=font-picker] .dropdown-button .dropdown-font-name {\n overflow: hidden;\n white-space: nowrap;\n}\ndiv[id^=font-picker] .dropdown-icon {\n margin-left: 10px;\n}\n@-webkit-keyframes spinner {\n to {\n transform: rotate(360deg);\n }\n}\n@keyframes spinner {\n to {\n transform: rotate(360deg);\n }\n}\ndiv[id^=font-picker] .dropdown-icon.loading::before {\n display: block;\n width: 10px;\n height: 10px;\n border: 2px solid #b2b2b2;\n border-top-color: #000000;\n border-radius: 50%;\n -webkit-animation: spinner 0.6s linear infinite;\n animation: spinner 0.6s linear infinite;\n content: \"\";\n}\ndiv[id^=font-picker] .dropdown-icon.finished::before {\n display: block;\n width: 0;\n height: 0;\n margin: 0 2px;\n border-top: 6px solid #000000;\n border-right: 5px solid transparent;\n border-left: 5px solid transparent;\n transition: transform 0.3s;\n content: \"\";\n}\ndiv[id^=font-picker] .dropdown-icon.error::before {\n content: \"⚠\";\n}\ndiv[id^=font-picker].expanded .dropdown-icon.finished::before {\n transform: rotate(-180deg);\n}\ndiv[id^=font-picker].expanded ul {\n max-height: 200px;\n}\ndiv[id^=font-picker] ul {\n position: absolute;\n z-index: 1;\n width: 100%;\n max-height: 0;\n margin: 0;\n padding: 0;\n overflow-x: hidden;\n overflow-y: auto;\n background: #eaeaea;\n box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);\n transition: 0.3s;\n -webkit-overflow-scrolling: touch;\n}\ndiv[id^=font-picker] ul li {\n height: 35px;\n list-style: none;\n}\ndiv[id^=font-picker] ul li button {\n display: flex;\n align-items: center;\n width: 100%;\n height: 100%;\n padding: 0 10px;\n white-space: nowrap;\n}\ndiv[id^=font-picker] ul li button:hover, div[id^=font-picker] ul li button:focus {\n background: #dddddd;\n}\ndiv[id^=font-picker] ul li button.active-font {\n background: #d1d1d1;\n}";
|
||||
styleInject(css);
|
||||
|
||||
function getFontId(fontFamily) {
|
||||
return fontFamily.replace(/\s+/g, "-").toLowerCase();
|
||||
}
|
||||
function validatePickerId(pickerId) {
|
||||
if (pickerId.match(/[^0-9a-z]/i)) {
|
||||
throw Error("The `pickerId` parameter may only contain letters and digits");
|
||||
}
|
||||
}
|
||||
|
||||
function get(url) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.overrideMimeType("application/json");
|
||||
request.open("GET", url, true);
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4) {
|
||||
if (request.status !== 200) {
|
||||
reject(new Error("Response has status code " + request.status));
|
||||
}
|
||||
else {
|
||||
resolve(request.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
});
|
||||
}
|
||||
|
||||
var LIST_BASE_URL = "https://www.googleapis.com/webfonts/v1/webfonts";
|
||||
function getFontList(apiKey) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var url, response, json, fontsOriginal;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
url = new URL(LIST_BASE_URL);
|
||||
url.searchParams.append("sort", "popularity");
|
||||
url.searchParams.append("key", apiKey);
|
||||
return [4, get(url.href)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
json = JSON.parse(response);
|
||||
fontsOriginal = json.items;
|
||||
return [2, fontsOriginal.map(function (fontOriginal) {
|
||||
var family = fontOriginal.family, subsets = fontOriginal.subsets, others = __rest(fontOriginal, ["family", "subsets"]);
|
||||
return __assign(__assign({}, others), { family: family, id: getFontId(family), scripts: subsets });
|
||||
})];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var previewFontsStylesheet = document.createElement("style");
|
||||
document.head.appendChild(previewFontsStylesheet);
|
||||
function applyFontPreview(previewFont, selectorSuffix) {
|
||||
var fontId = getFontId(previewFont.family);
|
||||
var style = "\n\t\t\t#font-button-" + fontId + selectorSuffix + " {\n\t\t\t\tfont-family: \"" + previewFont.family + "\";\n\t\t\t}\n\t\t";
|
||||
previewFontsStylesheet.appendChild(document.createTextNode(style));
|
||||
}
|
||||
function getActiveFontStylesheet(selectorSuffix) {
|
||||
var stylesheetId = "active-font-" + selectorSuffix;
|
||||
var activeFontStylesheet = document.getElementById(stylesheetId);
|
||||
if (!activeFontStylesheet) {
|
||||
activeFontStylesheet = document.createElement("style");
|
||||
activeFontStylesheet.id = stylesheetId;
|
||||
document.head.appendChild(activeFontStylesheet);
|
||||
}
|
||||
return activeFontStylesheet;
|
||||
}
|
||||
function applyActiveFont(activeFont, previousFontFamily, selectorSuffix) {
|
||||
var style = "\n\t\t.apply-font" + selectorSuffix + " {\n\t\t\tfont-family: \"" + activeFont.family + "\"" + (previousFontFamily ? ", \"" + previousFontFamily + "\"" : "") + ";\n\t\t}\n\t";
|
||||
var activeFontStylesheet = getActiveFontStylesheet(selectorSuffix);
|
||||
activeFontStylesheet.innerHTML = style;
|
||||
}
|
||||
|
||||
var PREVIEW_ATTRIBUTE_NAME = "data-is-preview";
|
||||
function getStylesheetId(fontId) {
|
||||
return "font-" + fontId;
|
||||
}
|
||||
function stylesheetExists(fontId, isPreview) {
|
||||
var stylesheetNode = document.getElementById(getStylesheetId(fontId));
|
||||
if (isPreview === null || isPreview === undefined) {
|
||||
return stylesheetNode !== null;
|
||||
}
|
||||
return (stylesheetNode !== null &&
|
||||
stylesheetNode.getAttribute(PREVIEW_ATTRIBUTE_NAME) === isPreview.toString());
|
||||
}
|
||||
function createStylesheet(fontId, isPreview) {
|
||||
var stylesheetNode = document.createElement("style");
|
||||
stylesheetNode.id = getStylesheetId(fontId);
|
||||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString());
|
||||
document.head.appendChild(stylesheetNode);
|
||||
}
|
||||
function fillStylesheet(fontId, styles) {
|
||||
var stylesheetId = getStylesheetId(fontId);
|
||||
var stylesheetNode = document.getElementById(stylesheetId);
|
||||
if (stylesheetNode) {
|
||||
stylesheetNode.textContent = styles;
|
||||
}
|
||||
else {
|
||||
console.error("Could not fill stylesheet: Stylesheet with ID \"" + stylesheetId + "\" not found");
|
||||
}
|
||||
}
|
||||
function setStylesheetType(fontId, isPreview) {
|
||||
var stylesheetId = getStylesheetId(fontId);
|
||||
var stylesheetNode = document.getElementById(stylesheetId);
|
||||
if (stylesheetNode) {
|
||||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString());
|
||||
}
|
||||
else {
|
||||
console.error("Could not change stylesheet type: Stylesheet with ID \"" + stylesheetId + "\" not found");
|
||||
}
|
||||
}
|
||||
|
||||
function getMatches(regex, str) {
|
||||
var matches = [];
|
||||
var match;
|
||||
do {
|
||||
match = regex.exec(str);
|
||||
if (match) {
|
||||
matches.push(match[1]);
|
||||
}
|
||||
} while (match);
|
||||
return matches;
|
||||
}
|
||||
|
||||
var FONT_FACE_REGEX = /@font-face {([\s\S]*?)}/gm;
|
||||
var FONT_FAMILY_REGEX = /font-family: ['"](.*?)['"]/gm;
|
||||
function extractFontStyles(allFontStyles) {
|
||||
var rules = getMatches(FONT_FACE_REGEX, allFontStyles);
|
||||
var fontStyles = {};
|
||||
rules.forEach(function (rule) {
|
||||
var fontFamily = getMatches(FONT_FAMILY_REGEX, rule)[0];
|
||||
var fontId = getFontId(fontFamily);
|
||||
if (!(fontId in fontStyles)) {
|
||||
fontStyles[fontId] = "";
|
||||
}
|
||||
fontStyles[fontId] += "@font-face {\n" + rule + "\n}\n\n";
|
||||
});
|
||||
return fontStyles;
|
||||
}
|
||||
|
||||
var FONT_BASE_URL = "https://fonts.googleapis.com/css";
|
||||
function getStylesheet(fonts, scripts, variants, previewsOnly) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var url, variantsStr, familiesStr, familyNamesConcat, downloadChars;
|
||||
return __generator(this, function (_a) {
|
||||
url = new URL(FONT_BASE_URL);
|
||||
variantsStr = variants.join(",");
|
||||
familiesStr = fonts.map(function (font) { return font.family + ":" + variantsStr; });
|
||||
url.searchParams.append("family", familiesStr.join("|"));
|
||||
url.searchParams.append("subset", scripts.join(","));
|
||||
if (previewsOnly) {
|
||||
familyNamesConcat = fonts.map(function (font) { return font.family; }).join("");
|
||||
downloadChars = familyNamesConcat
|
||||
.split("")
|
||||
.filter(function (char, pos, self) { return self.indexOf(char) === pos; })
|
||||
.join("");
|
||||
url.searchParams.append("text", downloadChars);
|
||||
}
|
||||
url.searchParams.append("font-display", "swap");
|
||||
return [2, get(url.href)];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function loadFontPreviews(fonts, scripts, variants, selectorSuffix) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var fontsArray, fontsToFetch, response, fontStyles;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
fontsArray = Array.from(fonts.values());
|
||||
fontsToFetch = fontsArray
|
||||
.map(function (font) { return font.id; })
|
||||
.filter(function (fontId) { return !stylesheetExists(fontId); });
|
||||
fontsToFetch.forEach(function (fontId) { return createStylesheet(fontId, true); });
|
||||
return [4, getStylesheet(fontsArray, scripts, variants, true)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
fontStyles = extractFontStyles(response);
|
||||
fontsArray.forEach(function (font) {
|
||||
applyFontPreview(font, selectorSuffix);
|
||||
if (fontsToFetch.includes(font.id)) {
|
||||
if (!(font.id in fontStyles)) {
|
||||
console.error("Missing styles for font \"" + font.family + "\" (fontId \"" + font.id + "\") in Google Fonts response");
|
||||
return;
|
||||
}
|
||||
fillStylesheet(font.id, fontStyles[font.id]);
|
||||
}
|
||||
});
|
||||
return [2];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
function loadActiveFont(font, previousFontFamily, scripts, variants, selectorSuffix) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var fontStyle;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!stylesheetExists(font.id, false)) return [3, 1];
|
||||
applyActiveFont(font, previousFontFamily, selectorSuffix);
|
||||
return [3, 3];
|
||||
case 1:
|
||||
if (stylesheetExists(font.id, true)) {
|
||||
setStylesheetType(font.id, false);
|
||||
}
|
||||
else {
|
||||
createStylesheet(font.id, false);
|
||||
}
|
||||
return [4, getStylesheet([font], scripts, variants, false)];
|
||||
case 2:
|
||||
fontStyle = _a.sent();
|
||||
applyActiveFont(font, previousFontFamily, selectorSuffix);
|
||||
fillStylesheet(font.id, fontStyle);
|
||||
_a.label = 3;
|
||||
case 3: return [2];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var FONT_FAMILY_DEFAULT = "Open Sans";
|
||||
var OPTIONS_DEFAULTS = {
|
||||
pickerId: "",
|
||||
families: [],
|
||||
categories: [],
|
||||
scripts: ["latin"],
|
||||
variants: ["regular"],
|
||||
filter: function () { return true; },
|
||||
limit: 50,
|
||||
sort: "alphabet",
|
||||
};
|
||||
|
||||
var FontManager = (function () {
|
||||
function FontManager(apiKey, defaultFamily, _a, onChange) {
|
||||
if (defaultFamily === void 0) { defaultFamily = FONT_FAMILY_DEFAULT; }
|
||||
var _b = _a.pickerId, pickerId = _b === void 0 ? OPTIONS_DEFAULTS.pickerId : _b, _c = _a.families, families = _c === void 0 ? OPTIONS_DEFAULTS.families : _c, _d = _a.categories, categories = _d === void 0 ? OPTIONS_DEFAULTS.categories : _d, _e = _a.scripts, scripts = _e === void 0 ? OPTIONS_DEFAULTS.scripts : _e, _f = _a.variants, variants = _f === void 0 ? OPTIONS_DEFAULTS.variants : _f, _g = _a.filter, filter = _g === void 0 ? OPTIONS_DEFAULTS.filter : _g, _h = _a.limit, limit = _h === void 0 ? OPTIONS_DEFAULTS.limit : _h, _j = _a.sort, sort = _j === void 0 ? OPTIONS_DEFAULTS.sort : _j;
|
||||
if (onChange === void 0) { onChange = function () { }; }
|
||||
this.fonts = new Map();
|
||||
validatePickerId(pickerId);
|
||||
this.selectorSuffix = pickerId ? "-" + pickerId : "";
|
||||
this.apiKey = apiKey;
|
||||
this.options = {
|
||||
pickerId: pickerId,
|
||||
families: families,
|
||||
categories: categories,
|
||||
scripts: scripts,
|
||||
variants: variants,
|
||||
filter: filter,
|
||||
limit: limit,
|
||||
sort: sort,
|
||||
};
|
||||
this.onChange = onChange;
|
||||
this.addFont(defaultFamily, false);
|
||||
this.setActiveFont(defaultFamily, false);
|
||||
}
|
||||
FontManager.prototype.init = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var fonts, _loop_1, this_1, i, state_1, fontsToLoad;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4, getFontList(this.apiKey)];
|
||||
case 1:
|
||||
fonts = _a.sent();
|
||||
_loop_1 = function (i) {
|
||||
var font = fonts[i];
|
||||
if (this_1.fonts.size >= this_1.options.limit) {
|
||||
return "break";
|
||||
}
|
||||
if (!this_1.fonts.has(font.family) &&
|
||||
(this_1.options.families.length === 0 || this_1.options.families.includes(font.family)) &&
|
||||
(this_1.options.categories.length === 0 || this_1.options.categories.includes(font.category)) &&
|
||||
this_1.options.scripts.every(function (script) { return font.scripts.includes(script); }) &&
|
||||
this_1.options.variants.every(function (variant) { return font.variants.includes(variant); }) &&
|
||||
this_1.options.filter(font) === true) {
|
||||
this_1.fonts.set(font.family, font);
|
||||
}
|
||||
};
|
||||
this_1 = this;
|
||||
for (i = 0; i < fonts.length; i += 1) {
|
||||
state_1 = _loop_1(i);
|
||||
if (state_1 === "break")
|
||||
break;
|
||||
}
|
||||
fontsToLoad = new Map(this.fonts);
|
||||
fontsToLoad["delete"](this.activeFontFamily);
|
||||
loadFontPreviews(fontsToLoad, this.options.scripts, this.options.variants, this.selectorSuffix);
|
||||
return [2, this.fonts];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
FontManager.prototype.getFonts = function () {
|
||||
return this.fonts;
|
||||
};
|
||||
FontManager.prototype.addFont = function (fontFamily, downloadPreview) {
|
||||
if (downloadPreview === void 0) { downloadPreview = true; }
|
||||
var font = {
|
||||
family: fontFamily,
|
||||
id: getFontId(fontFamily),
|
||||
};
|
||||
this.fonts.set(fontFamily, font);
|
||||
if (downloadPreview) {
|
||||
var fontMap = new Map();
|
||||
fontMap.set(fontFamily, font);
|
||||
loadFontPreviews(fontMap, this.options.scripts, this.options.variants, this.selectorSuffix);
|
||||
}
|
||||
};
|
||||
FontManager.prototype.removeFont = function (fontFamily) {
|
||||
this.fonts["delete"](fontFamily);
|
||||
};
|
||||
FontManager.prototype.getActiveFont = function () {
|
||||
var activeFont = this.fonts.get(this.activeFontFamily);
|
||||
if (!activeFont) {
|
||||
throw Error("Cannot get active font: \"" + this.activeFontFamily + "\" is not in the font list");
|
||||
}
|
||||
else {
|
||||
return activeFont;
|
||||
}
|
||||
};
|
||||
FontManager.prototype.setActiveFont = function (fontFamily, runOnChange) {
|
||||
var _this = this;
|
||||
if (runOnChange === void 0) { runOnChange = true; }
|
||||
var previousFontFamily = this.activeFontFamily;
|
||||
var activeFont = this.fonts.get(fontFamily);
|
||||
if (!activeFont) {
|
||||
throw Error("Cannot update active font: \"" + fontFamily + "\" is not in the font list");
|
||||
}
|
||||
this.activeFontFamily = fontFamily;
|
||||
loadActiveFont(activeFont, previousFontFamily, this.options.scripts, this.options.variants, this.selectorSuffix).then(function () {
|
||||
if (runOnChange) {
|
||||
_this.onChange(activeFont);
|
||||
}
|
||||
});
|
||||
};
|
||||
FontManager.prototype.setOnChange = function (onChange) {
|
||||
this.onChange = onChange;
|
||||
};
|
||||
return FontManager;
|
||||
}());
|
||||
|
||||
var FontPicker = (function () {
|
||||
function FontPicker(apiKey, defaultFamily, _a, onChange) {
|
||||
if (defaultFamily === void 0) { defaultFamily = FONT_FAMILY_DEFAULT; }
|
||||
var _b = _a.pickerId, pickerId = _b === void 0 ? OPTIONS_DEFAULTS.pickerId : _b, _c = _a.families, families = _c === void 0 ? OPTIONS_DEFAULTS.families : _c, _d = _a.categories, categories = _d === void 0 ? OPTIONS_DEFAULTS.categories : _d, _e = _a.scripts, scripts = _e === void 0 ? OPTIONS_DEFAULTS.scripts : _e, _f = _a.variants, variants = _f === void 0 ? OPTIONS_DEFAULTS.variants : _f, _g = _a.filter, filter = _g === void 0 ? OPTIONS_DEFAULTS.filter : _g, _h = _a.limit, limit = _h === void 0 ? OPTIONS_DEFAULTS.limit : _h, _j = _a.sort, sort = _j === void 0 ? OPTIONS_DEFAULTS.sort : _j;
|
||||
if (onChange === void 0) { onChange = function () { }; }
|
||||
this.expanded = false;
|
||||
this.closeEventListener = this.closeEventListener.bind(this);
|
||||
this.toggleExpanded = this.toggleExpanded.bind(this);
|
||||
var options = {
|
||||
pickerId: pickerId,
|
||||
families: families,
|
||||
categories: categories,
|
||||
scripts: scripts,
|
||||
variants: variants,
|
||||
filter: filter,
|
||||
limit: limit,
|
||||
sort: sort,
|
||||
};
|
||||
this.fontManager = new FontManager(apiKey, defaultFamily, options, onChange);
|
||||
this.generateUI(sort);
|
||||
}
|
||||
FontPicker.prototype.generateUI = function (sort) {
|
||||
var _this = this;
|
||||
var selectorSuffix = this.fontManager.selectorSuffix;
|
||||
var pickerId = "font-picker" + selectorSuffix;
|
||||
this.fontPickerDiv = document.getElementById(pickerId);
|
||||
if (!this.fontPickerDiv) {
|
||||
throw Error("Missing div with id=\"" + pickerId + "\"");
|
||||
}
|
||||
var dropdownButton = document.createElement("button");
|
||||
dropdownButton.classList.add("dropdown-button");
|
||||
dropdownButton.onclick = this.toggleExpanded;
|
||||
dropdownButton.onkeypress = this.toggleExpanded;
|
||||
dropdownButton.type = "button";
|
||||
this.fontPickerDiv.appendChild(dropdownButton);
|
||||
this.dropdownFamily = document.createElement("p");
|
||||
this.dropdownFamily.textContent = this.fontManager.getActiveFont().family;
|
||||
this.dropdownFamily.classList.add("dropdown-font-family");
|
||||
dropdownButton.appendChild(this.dropdownFamily);
|
||||
var dropdownIcon = document.createElement("p");
|
||||
dropdownIcon.classList.add("dropdown-icon", "loading");
|
||||
dropdownButton.appendChild(dropdownIcon);
|
||||
this.fontManager
|
||||
.init()
|
||||
.then(function (fontMap) {
|
||||
var fonts = Array.from(fontMap.values());
|
||||
if (sort === "alphabet") {
|
||||
fonts.sort(function (font1, font2) {
|
||||
return font1.family.localeCompare(font2.family);
|
||||
});
|
||||
}
|
||||
_this.generateFontList(fonts);
|
||||
dropdownIcon.classList.replace("loading", "finished");
|
||||
})["catch"](function (err) {
|
||||
dropdownIcon.classList.replace("loading", "error");
|
||||
console.error("Error trying to fetch the list of available fonts");
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
FontPicker.prototype.generateFontList = function (fonts) {
|
||||
var _this = this;
|
||||
this.ul = document.createElement("ul");
|
||||
this.ul.classList.add("font-list");
|
||||
fonts.forEach(function (font) {
|
||||
_this.addFontLi(font);
|
||||
});
|
||||
this.fontPickerDiv.appendChild(this.ul);
|
||||
var activeFontFamily = this.fontManager.getActiveFont().family;
|
||||
var activeFontId = getFontId(activeFontFamily);
|
||||
var fontButtonId = "font-button-" + activeFontId + this.fontManager.selectorSuffix;
|
||||
this.activeFontButton = document.getElementById(fontButtonId);
|
||||
if (this.activeFontButton) {
|
||||
this.activeFontButton.classList.add("active-font");
|
||||
}
|
||||
else {
|
||||
console.error("Could not find font button with ID (" + fontButtonId + ")");
|
||||
}
|
||||
};
|
||||
FontPicker.prototype.addFontLi = function (font, listIndex) {
|
||||
var _this = this;
|
||||
var fontId = getFontId(font.family);
|
||||
var li = document.createElement("li");
|
||||
li.classList.add("font-list-item");
|
||||
var fontButton = document.createElement("button");
|
||||
fontButton.type = "button";
|
||||
fontButton.id = "font-button-" + fontId + this.fontManager.selectorSuffix;
|
||||
fontButton.classList.add("font-button");
|
||||
fontButton.textContent = font.family;
|
||||
var onActivate = function () {
|
||||
_this.toggleExpanded();
|
||||
_this.setActiveFont(font.family);
|
||||
};
|
||||
fontButton.onclick = onActivate;
|
||||
fontButton.onkeypress = onActivate;
|
||||
li.appendChild(fontButton);
|
||||
if (listIndex) {
|
||||
this.ul.insertBefore(li, this.ul.children[listIndex]);
|
||||
}
|
||||
else {
|
||||
this.ul.appendChild(li);
|
||||
}
|
||||
};
|
||||
FontPicker.prototype.closeEventListener = function (e) {
|
||||
var targetEl = e.target;
|
||||
var fontPickerEl = document.getElementById("font-picker" + this.fontManager.selectorSuffix);
|
||||
while (true) {
|
||||
if (targetEl === fontPickerEl) {
|
||||
return;
|
||||
}
|
||||
if (targetEl.parentNode) {
|
||||
targetEl = targetEl.parentNode;
|
||||
}
|
||||
else {
|
||||
this.toggleExpanded();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
FontPicker.prototype.toggleExpanded = function () {
|
||||
if (this.expanded) {
|
||||
this.expanded = false;
|
||||
this.fontPickerDiv.classList.remove("expanded");
|
||||
document.removeEventListener("click", this.closeEventListener);
|
||||
}
|
||||
else {
|
||||
this.expanded = true;
|
||||
this.fontPickerDiv.classList.add("expanded");
|
||||
document.addEventListener("click", this.closeEventListener);
|
||||
}
|
||||
};
|
||||
FontPicker.prototype.getFonts = function () {
|
||||
return this.fontManager.getFonts();
|
||||
};
|
||||
FontPicker.prototype.addFont = function (fontFamily, index) {
|
||||
if (Array.from(this.fontManager.getFonts().keys()).includes(fontFamily)) {
|
||||
throw Error("Did not add font to font picker: Font family \"" + fontFamily + "\" is already in the list");
|
||||
}
|
||||
this.fontManager.addFont(fontFamily, true);
|
||||
var font = this.fontManager.getFonts().get(fontFamily);
|
||||
if (font) {
|
||||
this.addFontLi(font, index);
|
||||
}
|
||||
else {
|
||||
console.error("Font \"" + fontFamily + "\" is missing in font list");
|
||||
}
|
||||
};
|
||||
FontPicker.prototype.removeFont = function (fontFamily) {
|
||||
this.fontManager.removeFont(fontFamily);
|
||||
var fontId = getFontId(fontFamily);
|
||||
var fontButton = document.getElementById("font-button-" + fontId + this.fontManager.selectorSuffix);
|
||||
if (fontButton) {
|
||||
var fontLi = fontButton.parentElement;
|
||||
fontButton.remove();
|
||||
if (fontLi) {
|
||||
fontLi.remove();
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw Error("Could not remove font from font picker: Font family \"" + fontFamily + "\" is not in the list");
|
||||
}
|
||||
};
|
||||
FontPicker.prototype.getActiveFont = function () {
|
||||
return this.fontManager.getActiveFont();
|
||||
};
|
||||
FontPicker.prototype.setActiveFont = function (fontFamily) {
|
||||
this.fontManager.setActiveFont(fontFamily);
|
||||
var fontId = getFontId(fontFamily);
|
||||
this.dropdownFamily.textContent = fontFamily;
|
||||
if (this.activeFontButton) {
|
||||
this.activeFontButton.classList.remove("active-font");
|
||||
this.activeFontButton = document.getElementById("font-button-" + fontId + this.fontManager.selectorSuffix);
|
||||
this.activeFontButton.classList.add("active-font");
|
||||
}
|
||||
else {
|
||||
console.error("`activeFontButton` is undefined");
|
||||
}
|
||||
};
|
||||
FontPicker.prototype.setOnChange = function (onChange) {
|
||||
this.fontManager.setOnChange(onChange);
|
||||
};
|
||||
return FontPicker;
|
||||
}());
|
||||
|
||||
return FontPicker;
|
||||
|
||||
})));
|
||||
88
src/js/json__compile.js
Normal file
@@ -0,0 +1,88 @@
|
||||
function add__option() {
|
||||
window.new_chq_no = parseInt($('#total_chq').val()) + 1;
|
||||
window.new_input = "<h3>Categorie Name</h3><input type='text' id='cat_name'><div id='op_cont'><div class='inner'><h4>option name</h4><input type='text' id='op_name'><h4>option type</h4><input type='text' id='op_type'><h4>option description</h4><input type='text' id='op_desc'><h4>option css</h4><input type='text' id='op_css'></div><input type='button' value='Add a new option'></div>";
|
||||
|
||||
$('#cat').append(new_input);
|
||||
|
||||
$('#total_chq').val(new_chq_no);
|
||||
}
|
||||
|
||||
function create_option_json() {
|
||||
var option__name = document.querySelectorAll('#op_name');
|
||||
option__name.forEach(option__name => function() {
|
||||
var json__options = {
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": [{
|
||||
"name": name
|
||||
}]
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
var categories = {}
|
||||
}
|
||||
|
||||
function no__option() {
|
||||
$('#no_op').on('click', function() {
|
||||
var json__options = {
|
||||
"categories": [{
|
||||
"name": "Default",
|
||||
"options": []
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function createJSON() {
|
||||
var name = document.getElementById("name").value;
|
||||
var author = document.getElementById("author").value;
|
||||
var desc = document.getElementById("desc").value;
|
||||
var CSS = document.getElementById("css").value;
|
||||
var login = document.getElementById("login").value;
|
||||
var home = document.getElementById("home").value;
|
||||
var lib = document.getElementById("lib").value;
|
||||
var title = document.getElementById("title").value;
|
||||
var json__compiled = {
|
||||
"name ": name,
|
||||
"author ": author,
|
||||
"description ": desc,
|
||||
"defaultCss ": CSS,
|
||||
"previews ": [{
|
||||
"name ": "Login Page ",
|
||||
"url ": login
|
||||
},
|
||||
{
|
||||
"name ": "Home/Index Page ",
|
||||
"url ": home
|
||||
},
|
||||
{
|
||||
"name ": "Library Page ",
|
||||
"url ": lib
|
||||
},
|
||||
{
|
||||
"name ": "Title page ",
|
||||
"url ": title
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
var json = JSON.stringify(json__compiled, null, 4);
|
||||
|
||||
json = [json];
|
||||
var json__blob = new Blob(json, { type: "text/plain;charset=utf-8" });
|
||||
|
||||
var isIE = false || !!document.documentMode;
|
||||
if (isIE) {
|
||||
window.navigator.msSaveBlob(json__blob, name + ".json");
|
||||
} else {
|
||||
var url = window.URL || window.webkitURL;
|
||||
link = url.createObjectURL(json__blob);
|
||||
var a = document.createElement("a");
|
||||
a.download = name + ".json";
|
||||
a.href = link;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
}
|
||||