jellyfin-lookin theme, changes from master, bump to 0.3.0

Now uses a customized bootstrap that looks something like Jellyfin. Some
small ui changes were needed. This be overridden by downloading bs5's css and using the custom_css
option if you don't like it. sass file is included for your own modification. Changes made to master have been added also.
This commit is contained in:
Harvey Tindall 2020-07-04 22:17:49 +01:00
parent 81bb2520ad
commit ade935da4e
21 changed files with 10512 additions and 6771 deletions

3
.gitignore vendored
View File

@ -11,7 +11,8 @@ pw-reset/
jfa/
colors.txt
theme.css
jellyfin_accounts/data/static/bootstrap-jf.css
jellyfin_accounts/__pycache__/
old/
.jf-accounts/
requirements.txt
package-lock.json

View File

@ -15,7 +15,7 @@ A basic account management system for [Jellyfin](https://github.com/jellyfin/jel
</p>
<p align="center">
<img src="https://raw.githubusercontent.com/hrfee/jellyfin-accounts/master/images/jfa.gif" width="48%" style="margin-right: 1.5%;" alt="Admin page"></img>
<img src="https://raw.githubusercontent.com/hrfee/jellyfin-accounts/master/images/admin.png" width="48%" style="margin-right: 1.5%;" alt="Admin page"></img>
<img src="https://raw.githubusercontent.com/hrfee/jellyfin-accounts/master/images/create.png" width="48%" style="margin-left: 1.5%;" alt="Account creation page"></img>
</p>

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3
__version__ = "0.2.6"
__version__ = "0.3.0"
import secrets
import configparser
@ -35,6 +35,9 @@ parser.add_argument(
),
action="store_true",
)
parser.add_argument(
"-i", "--install", help="attempt to install a system service.", action="store_true"
)
args, leftovers = parser.parse_known_args()
@ -70,10 +73,11 @@ else:
temp_config = configparser.RawConfigParser()
temp_config.read(config_path)
def create_log(name):
log = logging.getLogger(name)
handler = logging.StreamHandler(sys.stdout)
if temp_config.getboolean('ui', 'debug'):
if temp_config.getboolean("ui", "debug"):
log.setLevel(logging.DEBUG)
handler.setLevel(logging.DEBUG)
else:
@ -89,6 +93,7 @@ def create_log(name):
log = create_log("main")
def load_config(config_path, data_dir):
config = configparser.RawConfigParser()
config.read(config_path)
@ -139,6 +144,7 @@ def load_config(config_path, data_dir):
config["jellyfin"]["public_server"] = config["jellyfin"]["server"]
return config
config = load_config(config_path, data_dir)
web_log = create_log("waitress")
@ -180,38 +186,20 @@ data_store = JSONStorage(
)
def default_css():
css = {}
css[
"href"
] = "https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
css[
"integrity"
] = "sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
css["crossorigin"] = "anonymous"
return css
css = {}
css = default_css()
css_file = "bs5-jf.css"
if "custom_css" in config["files"]:
if config["files"]["custom_css"] != "":
try:
shutil.copy(
config["files"]["custom_css"], (local_dir / "static" / "bootstrap.css")
)
log.debug("Loaded custom CSS")
css["href"] = "/bootstrap.css"
css["integrity"] = ""
css["crossorigin"] = ""
css_path = Path(config["files"]["custom_css"])
shutil.copy(css_path, (local_dir / "static" / css_path.name))
log.debug('Loaded custom CSS "{css_path.name}"')
css_file = css_path.name
except FileNotFoundError:
log.error(
f'Custom CSS {config["files"]["custom_css"]} not found, using default.'
)
def resp(success=True, code=500):
if success:
r = jsonify({"success": True})
@ -226,7 +214,29 @@ def resp(success=True, code=500):
def main():
if args.get_defaults:
if args.install:
executable = sys.argv[0]
print(f'Assuming executable path "{executable}".')
options = ["systemd"]
for i, opt in enumerate(options):
print(f"{i+1}: {opt}")
success = False
while not success:
try:
method = options[int(input(">: ")) - 1]
success = True
except IndexError:
pass
if method == "systemd":
with open(local_dir / "services" / "jf-accounts.service", "r") as f:
data = f.read()
data = data.replace("{executable}", executable)
service_path = str(Path("jf-accounts.service").resolve())
with open(service_path, "w") as f:
f.write(data)
print(f"service written to the current directory\n({service_path}).")
print("Place this in the appropriate directory, and reload daemons.")
elif args.get_defaults:
import json
from jellyfin_accounts.jf_api import Jellyfin

View File

@ -0,0 +1,8 @@
[Unit]
Description=A basic account management system for Jellyfin.
[Service]
ExecStart={executable}
[Install]
WantedBy=default.target

View File

@ -44,7 +44,7 @@ function addItem(invite) {
// listCode.appendChild(document.createTextNode(" "));
var codeCopy = document.createElement('i');
codeCopy.onclick = function(){toClipboard(inviteCode)};
codeCopy.classList.add('fa', 'fa-clipboard');
codeCopy.classList.add('fa', 'fa-clipboard', 'icon-button');
listCode.appendChild(codeCopy);
if (typeof(invite[3]) != 'undefined') {
var sentTo = document.createElement('span');
@ -145,7 +145,7 @@ function addOptions(le, sel) {
function toClipboard(str) {
const el = document.createElement('textarea');
el.value = str;
el.setAttribute('readonly', '');
el.setAttribute('readOnly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
@ -392,30 +392,45 @@ document.getElementById('openUsers').onclick = function () {
var users = req.response['users'];
for (var i = 0; i < users.length; i++) {
var user = users[i]
var entry = document.createElement('p');
var entry = document.createElement('div');
entry.classList.add('form-group', 'list-group-item', 'py-1');
entry.id = 'user_' + user['name'];
entry.appendChild(document.createTextNode(user['name']));
var address = document.createElement('span');
address.setAttribute('style', 'margin-left: 2%; margin-right: 2%; color: grey;');
var label = document.createElement('label');
label.classList.add('d-inline-block');
label.setAttribute('for', 'address_' + user['email']);
label.appendChild(document.createTextNode(user['name']));
entry.appendChild(label);
var address = document.createElement('input');
address.setAttribute('type', 'email');
address.readOnly = true;
address.classList.add('form-control-plaintext', 'text-muted', 'd-inline-block');
//address.setAttribute('style', 'margin-left: 2%; margin-right: 2%; color: grey;');
address.classList.add('addressText');
address.id = 'address_' + user['email'];
if (typeof(user['email']) != 'undefined') {
address.appendChild(document.createTextNode(user['email']));
address.value = user['email'];
address.setAttribute('style', 'width: auto; margin-left: 2%;');
};
var editButton = document.createElement('i');
editButton.classList.add('fa', 'fa-edit');
editButton.classList.add('fa', 'fa-edit', 'd-inline-block', 'icon-button');
editButton.setAttribute('style', 'margin-left: 2%;');
editButton.onclick = function() {
this.classList.remove('fa', 'fa-edit');
var input = document.createElement('input');
input.setAttribute('type', 'email');
input.setAttribute('style', 'margin-left: 2%; color: grey;');
var addressElement = this.parentNode.getElementsByClassName('addressText')[0];
if (addressElement.textContent != '') {
input.value = addressElement.textContent;
} else {
input.placeholder = 'Email Address';
// var input = document.createElement('input');
// input.setAttribute('type', 'email');
// input.classList.add('email-input');
//var addressElement = this.parentNode.getElementsByClassName('addressText')[0];
var addressElement = this.parentNode.getElementsByClassName('form-control-plaintext')[0];
addressElement.classList.remove('form-control-plaintext', 'text-muted');
addressElement.classList.add('form-control');
addressElement.readOnly = false;
if (addressElement.value == '') {
// input.value = addressElement.textContent;
// } else {
addressElement.placeholder = 'Email Address';
address.setAttribute('style', 'width: auto; margin-left: 2%;');
};
this.parentNode.replaceChild(input, addressElement);
// this.parentNode.replaceChild(input, addressElement);
if (document.getElementById('saveUsers') == null) {
var footer = document.getElementById('userFooter')
var saveUsers = document.createElement('input');
@ -451,8 +466,8 @@ document.getElementById('openUsers').onclick = function () {
footer.appendChild(saveUsers);
};
};
entry.appendChild(address);
entry.appendChild(editButton);
entry.appendChild(address);
list.appendChild(entry);
};
var button = document.getElementById('openUsers');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,35 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#603cba">
<meta name="theme-color" content="#ffffff">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#603cba">
<meta name="theme-color" content="#ffffff">
<title>404</title>
<link rel="stylesheet" href="{{ css_href }}" integrity="{{ css_integrity }}" crossorigin="{{ css_crossorigin }}">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<style>
<title>404</title>
<link rel="stylesheet" type="text/css" href="{{ css_file }}">
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.messageBox {
margin: 20%;
}
</style>
</head>
<body>
</style>
</head>
<body>
<div class="messageBox">
<h1>Page not found.</h1>
<p>
{{ contactMessage }}
</p>
</div>
</body>
</body>
</html>

View File

@ -14,7 +14,7 @@
<meta name="theme-color" content="#ffffff">
<!-- Bootstrap CSS -->
<link rel="stylesheet" type="text/css" href="bs5-jf.css">
<link rel="stylesheet" type="text/css" href="{{ css_file }}">
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
@ -46,12 +46,6 @@
margin-top: 5%;
color: grey;
}
.fa-clipboard {
color: grey;
}
.fa-clipboard:hover {
color: black;
}
</style>
<title>Admin</title>
</head>
@ -173,13 +167,13 @@
<button type="button" class="btn btn-secondary" id="openSettings">
Settings <i class="fa fa-cog"></i>
</button>
<div class="card bg-light mb-3 linkGroup">
<div class="card mb-3 linkGroup">
<div class="card-header">Current Invites</div>
<ul class="list-group list-group-flush" id="invites">
</ul>
</div>
<div class="linkForm">
<div class="card bg-light mb-3">
<div class="card mb-3">
<div class="card-header">Generate Invite</div>
<div class="card-body">
<form action="#" method="POST" id="inviteForm">

View File

@ -13,7 +13,7 @@
<meta name="theme-color" content="#ffffff">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="{{ css_file }}">
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
@ -61,7 +61,7 @@
<div class="container" id="container">
<div class="row" id="cardContainer">
<div class="col-sm">
<div class="card bg-light mb-3">
<div class="card mb-3">
<div class="card-header">Details</div>
<div class="card-body">
<form action="#" method="POST" id="accountForm">
@ -90,7 +90,7 @@
</div>
{% if validate %}
<div class="col-sm" id="requirementBox">
<div class="card bg-light mb-3 requirementBox">
<div class="card mb-3 requirementBox">
<div class="card-header">Password Requirements</div>
<div class="card-body">
<ul class="list-group">

View File

@ -1,25 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Invalid Code</title>
<link rel="stylesheet" href="{{ css_href }}" integrity="{{ css_integrity }}" crossorigin="{{ css_crossorigin }}">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<style>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Invalid Code</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" type="text/css" href="{{ css_file }}">
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.messageBox {
margin: 20%;
}
</style>
</head>
<body>
</style>
</head>
<body>
<div class="messageBox">
<h1>Invalid Code.</h1>
<p>The above code is either incorrect, or has expired.</p>
<p>{{ contactMessage }}</p>
</div>
</body>
</body>
</html>

View File

@ -1,7 +1,7 @@
from pathlib import Path
from flask import Flask, send_from_directory, render_template
from jellyfin_accounts import app, g, css, data_store
from jellyfin_accounts import app, g, css_file, data_store
from jellyfin_accounts import web_log as log
from jellyfin_accounts.web_api import config, checkInvite, validator
@ -11,9 +11,7 @@ def page_not_found(e):
return (
render_template(
"404.html",
css_href=css["href"],
css_integrity=css["integrity"],
css_crossorigin=css["crossorigin"],
css_file=css_file,
contactMessage=config["ui"]["contact_message"],
),
404,
@ -25,9 +23,7 @@ def admin():
# return app.send_static_file('admin.html')
return render_template(
"admin.html",
css_href=css["href"],
css_integrity=css["integrity"],
css_crossorigin=css["crossorigin"],
css_file=css_file,
contactMessage="",
email_enabled=config.getboolean("invite_emails", "enabled"),
)
@ -40,9 +36,7 @@ def static_proxy(path):
return (
render_template(
"404.html",
css_href=css["href"],
css_integrity=css["integrity"],
css_crossorigin=css["crossorigin"],
css_file=css_file,
contactMessage=config["ui"]["contact_message"],
),
404,
@ -59,9 +53,7 @@ def inviteProxy(path):
email = ""
return render_template(
"form.html",
css_href=css["href"],
css_integrity=css["integrity"],
css_crossorigin=css["crossorigin"],
css_file=css_file,
contactMessage=config["ui"]["contact_message"],
helpMessage=config["ui"]["help_message"],
successMessage=config["ui"]["success_message"],
@ -77,8 +69,6 @@ def inviteProxy(path):
log.debug("Attempted use of invalid invite")
return render_template(
"invalidCode.html",
css_href=css["href"],
css_integrity=css["integrity"],
css_crossorigin=css["crossorigin"],
css_file=css_file,
contactMessage=config["ui"]["contact_message"],
)

8
jf-accounts.service Normal file
View File

@ -0,0 +1,8 @@
[Unit]
Description=A basic account management system for Jellyfin.
[Service]
ExecStart=/home/hrfee/.cache/pypoetry/virtualenvs/jellyfin-accounts-r2jcKHws-py3.8/bin/jf-accounts
[Install]
WantedBy=default.target

783
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "jellyfin-accounts"
version = "0.2.6"
version = "0.3.0"
readme = "README.md"
description = "A simple account management system for Jellyfin"
authors = ["Harvey Tindall <harveyltindall@gmail.com>"]
@ -9,7 +9,7 @@ homepage = "https://github.com/hrfee/jellyfin-accounts"
repository = "https://github.com/hrfee/jellyfin-accounts"
keywords = ["jellyfin", "jf-accounts"]
include = ["jellyfin_accounts/data/*"]
exclude = ["images/*"]
exclude = ["images/*", "scss/*"]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",

15
scss/README.md Normal file
View File

@ -0,0 +1,15 @@
## SCSS
* `bs5-jf.scss` contains the source for the customizations to bootstrap. To customize the UI, you can make modifications to this file and then compile it.
Note: assumes that bootstrap is installed in `../node_modules/bootstrap` relative to itself.
* Compilation requires a sass compiler of your choice, and `postcss-cli`, `autoprefixer` + `clean-css-cli` from npm.
* If you're using `sassc`, run `./compile.sh bs5-jf.scss` in this directory. This will create a .css file, and minified .css file.
* For `node-sass`, replace the `sassc` line in `compile.sh` with
```
node-sass --output-style expanded --precision 6 $1 $css_file
```
and run as above.
* If you're building from source, copy the minified css to `<jf-accounts git directory>/jellyfin_accounts/data/static/bs5-jf.css`.
* If you're just customizing your install, set `custom_css` in your config as the path to your minified css.

9438
scss/bs5-jf.css Normal file

File diff suppressed because one or more lines are too long

7
scss/bs5-jf.min.css vendored Normal file

File diff suppressed because one or more lines are too long

1
scss/bs5-jf.min.css.map Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,27 +1,40 @@
$jf-blue: rgb(0, 164, 220);
$jf-blue-hover: rgba(0, 164, 220, 0.2);
$jf-blue-focus: rgb(12, 176, 232);
$jf-blue-light: #4bb3dd;
$jf-red: rgb(204, 0, 0);
$jf-red-light: #e12026;
$jf-yellower: #ffc107;
$jf-yellow: #e1b222;
$jf-orange: #ff870f;
$jf-green: #6fbd45;
$jf-green-dark: #008040;
$jf-black: rgb(16, 16, 16);
$jf-gray-90: rgb(32, 32, 32);
$jf-gray-80: rgb(36, 36, 36); // jf-card
$jf-gray-70: rgb(41, 41, 41); // jf-input
$jf-gray-60: rgb(48, 48, 48); // jf-button
$jf-gray-50: rgb(56, 56, 56); // jf-button-focus
$jf-black: #101010; // 16 16 16
$jf-gray-90: #202020; // 32 32 32
$jf-gray-80: #242424; // jf-card 36 36 36
$jf-gray-70: #292929; // jf-input 41 41 41
$jf-gray-60: #303030; // jf-button 48 48 48
$jf-gray-50: #383838; // jf-button-focus 56 56 56
$jf-text-bold: rgba(255, 255, 255, 0.87);
$jf-text-primary: rgba(255, 255, 255, 0.8);
$jf-text-secondary: rgb(153, 153, 153);
$theme-colors: (
"primary": $jf-blue,
"secondary": $jf-gray-50,
"success": $jf-blue-focus,
"danger": $jf-red,
"light": $jf-text-primary,
"dark": $jf-gray-90
);
$primary: $jf-blue;
$secondary: $jf-gray-50;
$success: $jf-green-dark;
$danger: $jf-red-light;
$light: $jf-text-primary;
$dark: $jf-gray-90;
$info: $jf-yellow;
$warning: $jf-yellower;
$enable-gradients: false;
$enable-shadows: false;
$enable-rounded: false;
$body-bg: $jf-black;
@ -32,11 +45,14 @@ $component-active-bg: $jf-blue-focus;
$text-muted: $jf-text-secondary;
$link-color: $jf-blue-focus;
$btn-link-disabled-color: $jf-text-secondary;
$input-bg: $jf-gray-70;
$input-bg: $jf-gray-90;
$input-color: $jf-text-primary;
$input-focus-bg: $jf-gray-60;
$input-focus-border-color: $jf-blue-focus;
$input-disabled-bg: $jf-gray-90;
$input-disabled-bg: $jf-gray-70;
input:disabled {
color: $text-muted;
}
$input-border-color: $jf-gray-60;
$input-placeholder-color: $text-muted;
@ -45,7 +61,76 @@ $form-check-input-border: $jf-gray-50;
$form-check-input-checked-color: $jf-blue-focus;
$form-check-input-checked-bg-color: $jf-blue-hover;
$input-group-addon-bg: $input-bg;
// roughly @ line 696
$form-select-disabled-color: $jf-text-secondary;
$form-select-disabled-bg: $input-disabled-bg;
$form-select-indicator-color: $jf-gray-50;
$card-bg: $jf-gray-80;
$card-border-color: null;
$tooltip-color: $jf-text-bold;
$tooltip-bg: $jf-gray-50;
$modal-content-bg: $jf-gray-80;
$modal-content-border-color: $jf-gray-50;
$modal-header-border-color: null;
$modal-footer-border-color: null;
$list-group-bg: $card-bg;
$list-group-border-color: $jf-gray-50;
$list-group-hover-bg: $jf-blue-hover;
$list-group-active-bg: $jf-blue-focus;
$list-group-action-color: $jf-text-primary;
$list-group-action-hover-color: $jf-text-bold;
$list-group-action-active-color: $jf-text-bold;
$list-group-action-active-bg: $jf-blue-focus;
// idk why but i had to put these above and below the import
.list-group-item-danger {
color: $jf-text-bold;
background-color: $danger;
}
.list-group-item-success {
color: $jf-text-bold;
background-color: $success;
}
@import "../node_modules/bootstrap/scss/bootstrap";
.btn-primary, .btn-outline-primary:hover, .btn-outline-primary:active {
color: $jf-text-bold;
}
.close {
color: $jf-text-secondary;
}
.close:hover, .close:active {
color: $jf-text-primary;
}
.icon-button {
color: $text-muted;
}
.icon-button:hover {
color: $jf-text-bold;
}
.text-bright {
color: $jf-text-bold;
}
.list-group-item-danger {
color: $jf-text-bold;
background-color: $danger;
}
.list-group-item-success {
color: $jf-text-bold;
background-color: $success;
}

10
scss/compile.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
css_file=$(echo $1 | sed 's/scss/css/g')
min_file=$(echo $1 | sed 's/scss/min.css/g')
sassc -t expanded -p 6 $1 $css_file
echo "Compiled."
postcss $css_file --replace --use autoprefixer
echo "Prefixed."
echo "Written to $css_file."
cleancss --level 1 --format breakWith=lf --source-map --source-map-inline-sources --output $min_file $css_file
echo "Minified version written to $min_file."