BS4 by default, BS5 optional
Bootstrap 4 w/ jQuery is used by default unless bs5 is enabled in settings/ui. bs4 also now has a jellyfin-style look.
This commit is contained in:
parent
ade935da4e
commit
adef32ef89
|
@ -1,13 +1,11 @@
|
|||
# ![jellyfin-accounts](https://raw.githubusercontent.com/hrfee/jellyfin-accounts/master/images/jellyfin-accounts-banner-wide.svg)
|
||||
|
||||
**This branch uses the bootstrap 5 alpha, which works well enough for the most part, but can sometimes be a bit glitchy. Also no more jquery.**
|
||||
|
||||
A basic account management system for [Jellyfin](https://github.com/jellyfin/jellyfin).
|
||||
* Provides a web interface for creating invite codes, and a simple account creation form
|
||||
* Sends out emails when a user requests a password reset
|
||||
* Uses a basic python jellyfin API client for communication with the server.
|
||||
* Uses [Flask](https://github.com/pallets/flask), [HTTPAuth](https://github.com/miguelgrinberg/Flask-HTTPAuth), [itsdangerous](https://github.com/pallets/itsdangerous), and [Waitress](https://github.com/Pylons/waitress)
|
||||
* Frontend uses [Bootstrap 5](https://v5.getbootstrap.com)
|
||||
* Frontend uses [Bootstrap](https://v5.getbootstrap.com)
|
||||
* Password resets are handled using smtplib, requests, and [jinja](https://github.com/pallets/jinja)
|
||||
## Interface
|
||||
<p align="center">
|
||||
|
|
|
@ -9,9 +9,9 @@ server = http://jellyfin.local:8096
|
|||
public_server = https://jellyf.in:443
|
||||
; this and below settings will show on the jellyfin dashboard when the program connects. you may as well leave them alone.
|
||||
client = jf-accounts
|
||||
version = 0.2.5
|
||||
version = 0.3.0
|
||||
device = jf-accounts
|
||||
device_id = jf-accounts-0.2.5
|
||||
device_id = jf-accounts-0.3.0
|
||||
|
||||
[ui]
|
||||
; settings related to the ui and program functionality.
|
||||
|
@ -33,6 +33,8 @@ contact_message = Need help? contact me.
|
|||
help_message = Enter your details to create an account.
|
||||
; displayed when a user creates an account
|
||||
success_message = Your account has been created. Click below to continue to Jellyfin.
|
||||
; use bootstrap 5 (currently in alpha). this also removes the need for jquery, so the page should load faster.
|
||||
bs5 = false
|
||||
|
||||
[password_validation]
|
||||
; password validation (minimum length, etc.)
|
||||
|
|
|
@ -142,6 +142,11 @@ def load_config(config_path, data_dir):
|
|||
or config["jellyfin"]["public_server"] == ""
|
||||
):
|
||||
config["jellyfin"]["public_server"] = config["jellyfin"]["server"]
|
||||
if (
|
||||
"bs5" not in config["ui"]
|
||||
or config["ui"]["bs5"] == ""
|
||||
):
|
||||
config["ui"]["bs5"] = "false"
|
||||
return config
|
||||
|
||||
|
||||
|
@ -185,8 +190,12 @@ data_store = JSONStorage(
|
|||
config["files"]["user_configuration"],
|
||||
)
|
||||
|
||||
if config.getboolean("ui", "bs5"):
|
||||
css_file = "bs5-jf.css"
|
||||
log.debug('Using Bootstrap 5')
|
||||
else:
|
||||
css_file = "bs4-jf.css"
|
||||
|
||||
css_file = "bs5-jf.css"
|
||||
if "custom_css" in config["files"]:
|
||||
if config["files"]["custom_css"] != "":
|
||||
try:
|
||||
|
|
|
@ -150,6 +150,14 @@
|
|||
"type": "text",
|
||||
"value": "Your account has been created. Click below to continue to Jellyfin.",
|
||||
"description": "Displayed when a user creates an account"
|
||||
},
|
||||
"bs5": {
|
||||
"name": "Use Bootstrap 5",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Use Bootstrap 5 (currently in alpha). This also removes the need for jQuery, so the page should load faster."
|
||||
}
|
||||
},
|
||||
"password_validation": {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -14,8 +14,15 @@
|
|||
|
||||
<title>404</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ css_file }}">
|
||||
{% if not bs5 %}
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
{% endif %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
{% if bs5 %}
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
|
||||
{% else %}
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<style>
|
||||
.messageBox {
|
||||
|
|
|
@ -12,11 +12,18 @@
|
|||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#603cba">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{ css_file }}">
|
||||
{% if not bs5 %}
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
{% endif %}
|
||||
<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>
|
||||
{% if bs5 %}
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
|
||||
{% else %}
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<style>
|
||||
.pageContainer {
|
||||
|
|
|
@ -1,8 +1,64 @@
|
|||
var loginModal = new bootstrap.Modal(document.getElementById('login'));
|
||||
var settingsModal = new bootstrap.Modal(document.getElementById('settingsMenu'));
|
||||
var userDefaultsModal = new bootstrap.Modal(document.getElementById('userDefaults'));
|
||||
var usersModal = new bootstrap.Modal(document.getElementById('users'));
|
||||
var restartModal = new bootstrap.Modal(document.getElementById('restartModal'));
|
||||
var bsVersion = {{ bsVersion }};
|
||||
|
||||
if (bsVersion == 5) {
|
||||
function createModal(id, find = false) {
|
||||
if (find) {
|
||||
return bootstrap.Modal.getInstance(document.getElementById(modalId));
|
||||
};
|
||||
return new bootstrap.Modal(document.getElementById(id));
|
||||
};
|
||||
function triggerTooltips() {
|
||||
document.getElementById('settingsMenu').addEventListener('shown.bs.modal', function() {
|
||||
// Hack to ensure anything dependent on checkboxes are disabled if necessary
|
||||
var checkboxes = document.getElementById('settingsMenu').querySelectorAll('input[type="checkbox"]');
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
checkboxes[i].click();
|
||||
checkboxes[i].click();
|
||||
};
|
||||
// Initialize tooltips
|
||||
var to_trigger = [].slice.call(document.querySelectorAll('a[data-toggle="tooltip"]'));
|
||||
var tooltips = to_trigger.map(function(el) {
|
||||
return new bootstrap.Tooltip(el);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// var loginModal = new bootstrap.Modal(document.getElementById('login'));
|
||||
// var settingsModal = new bootstrap.Modal(document.getElementById('settingsMenu'));
|
||||
// var userDefaultsModal = new bootstrap.Modal(document.getElementById('userDefaults'));
|
||||
// var usersModal = new bootstrap.Modal(document.getElementById('users'));
|
||||
// var restartModal = new bootstrap.Modal(document.getElementById('restartModal'));
|
||||
} else if (bsVersion == 4) {
|
||||
document.getElementById('send_to_address_enabled').classList.remove('form-check-input');
|
||||
function createModal(id, find = false) {
|
||||
return {
|
||||
show : function() {
|
||||
return $('#' + id).modal('show');
|
||||
},
|
||||
hide : function() {
|
||||
return $('#' + id).modal('hide');
|
||||
}
|
||||
};
|
||||
};
|
||||
function triggerTooltips() {
|
||||
$('#settingsMenu').on('shown.bs.modal', function() {
|
||||
var checkboxes = document.getElementById('settingsMenu').querySelectorAll('input[type="checkbox"]');
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
checkboxes[i].click();
|
||||
checkboxes[i].click();
|
||||
};
|
||||
$("a[data-toggle='tooltip']").each(function (i, obj) {
|
||||
$(obj).tooltip();
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
var loginModal = createModal('login');
|
||||
var settingsModal = createModal('settingsMenu');
|
||||
var userDefaultsModal = createModal('userDefaults');
|
||||
var usersModal = createModal('users');
|
||||
var restartModal = createModal('restartModal');
|
||||
|
||||
function parseInvite(invite, empty = false) {
|
||||
if (empty === true) {
|
||||
|
@ -612,19 +668,7 @@ document.getElementById('openSettings').onclick = function () {
|
|||
settingsModal.show();
|
||||
};
|
||||
|
||||
document.getElementById('settingsMenu').addEventListener('shown.bs.modal', function() {
|
||||
// Hack to ensure anything dependent on checkboxes are disabled if necessary
|
||||
var checkboxes = document.getElementById('settingsMenu').querySelectorAll('input[type="checkbox"]');
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
checkboxes[i].click();
|
||||
checkboxes[i].click();
|
||||
};
|
||||
// Initialize tooltips
|
||||
var to_trigger = [].slice.call(document.querySelectorAll('a[data-toggle="tooltip"]'));
|
||||
var tooltips = to_trigger.map(function(el) {
|
||||
return new bootstrap.Tooltip(el);
|
||||
});
|
||||
});
|
||||
triggerTooltips();
|
||||
//
|
||||
// $('#settingsMenu').on('shown.bs.modal', function() {
|
||||
// $("a[data-toggle='tooltip']").each(function (i, obj) {
|
||||
|
@ -642,7 +686,7 @@ function sendConfig(modalId) {
|
|||
req.onreadystatechange = function() {
|
||||
if (this.readyState == 4) {
|
||||
if (this.status == 200 || this.status == 204) {
|
||||
bootstrap.Modal.getInstance(document.getElementById(modalId)).hide();
|
||||
createModal(modalId, true).hide();
|
||||
if (modalId != 'settingsMenu') {
|
||||
settingsModal.hide();
|
||||
};
|
||||
|
@ -699,4 +743,3 @@ document.getElementById('settingsSave').onclick = function() {
|
|||
settingsModal.hide();
|
||||
};
|
||||
};
|
||||
|
|
@ -14,8 +14,15 @@
|
|||
|
||||
<!-- Bootstrap CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="{{ css_file }}">
|
||||
{% if not bs5 %}
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
{% endif %}
|
||||
<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>
|
||||
{% if bs5 %}
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
|
||||
{% else %}
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<style>
|
||||
.pageContainer {
|
||||
|
@ -109,7 +116,23 @@
|
|||
</div>
|
||||
<script src="serialize.js"></script>
|
||||
<script>
|
||||
var successBox = new bootstrap.Modal(document.getElementById('successBox'));
|
||||
{% if bs5 %}
|
||||
var bsVersion = 5;
|
||||
{% else %}
|
||||
var bsVersion = 4;
|
||||
{% endif %}
|
||||
if (bsVersion == 5) {
|
||||
var successBox = new bootstrap.Modal(document.getElementById('successBox'));
|
||||
} else if (bsVersion == 4) {
|
||||
var successBox = {
|
||||
show : function() {
|
||||
return $('#successBox').modal('show');
|
||||
},
|
||||
hide : function() {
|
||||
return $('#successBox').modal('hide');
|
||||
}
|
||||
};
|
||||
};
|
||||
var code = window.location.href.split('/').pop();
|
||||
function toggleSpinner () {
|
||||
var submitButton = document.getElementById('submitButton');
|
||||
|
|
|
@ -6,8 +6,15 @@
|
|||
<title>Invalid Code</title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="{{ css_file }}">
|
||||
{% if not bs5 %}
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
{% endif %}
|
||||
<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>
|
||||
{% if bs5 %}
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
|
||||
{% else %}
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<style>
|
||||
.messageBox {
|
||||
|
|
|
@ -11,6 +11,7 @@ def page_not_found(e):
|
|||
return (
|
||||
render_template(
|
||||
"404.html",
|
||||
bs5=config.getboolean('ui', 'bs5'),
|
||||
css_file=css_file,
|
||||
contactMessage=config["ui"]["contact_message"],
|
||||
),
|
||||
|
@ -23,6 +24,7 @@ def admin():
|
|||
# return app.send_static_file('admin.html')
|
||||
return render_template(
|
||||
"admin.html",
|
||||
bs5=config.getboolean('ui', 'bs5'),
|
||||
css_file=css_file,
|
||||
contactMessage="",
|
||||
email_enabled=config.getboolean("invite_emails", "enabled"),
|
||||
|
@ -32,10 +34,18 @@ def admin():
|
|||
@app.route("/<path:path>")
|
||||
def static_proxy(path):
|
||||
if "html" not in path:
|
||||
if "admin.js" in path:
|
||||
if config.getboolean('ui', 'bs5'):
|
||||
bsVersion = 5
|
||||
else:
|
||||
bsVersion = 4
|
||||
return render_template("admin.js",
|
||||
bsVersion=bsVersion)
|
||||
return app.send_static_file(path)
|
||||
return (
|
||||
render_template(
|
||||
"404.html",
|
||||
bs5=config.getboolean('ui', 'bs5'),
|
||||
css_file=css_file,
|
||||
contactMessage=config["ui"]["contact_message"],
|
||||
),
|
||||
|
@ -53,6 +63,7 @@ def inviteProxy(path):
|
|||
email = ""
|
||||
return render_template(
|
||||
"form.html",
|
||||
bs5=config.getboolean('ui', 'bs5'),
|
||||
css_file=css_file,
|
||||
contactMessage=config["ui"]["contact_message"],
|
||||
helpMessage=config["ui"]["help_message"],
|
||||
|
@ -69,6 +80,7 @@ def inviteProxy(path):
|
|||
log.debug("Attempted use of invalid invite")
|
||||
return render_template(
|
||||
"invalidCode.html",
|
||||
bs5=config.getboolean('ui', 'bs5'),
|
||||
css_file=css_file,
|
||||
contactMessage=config["ui"]["contact_message"],
|
||||
)
|
||||
|
|
|
@ -191,6 +191,11 @@
|
|||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.0.0-alpha1.tgz",
|
||||
"integrity": "sha512-iwKneP2pLXl8lN0YpnOuOARiNPTzmh/4cw+Un86u4OqrMLuQpyMC7nO07hvivvcg0B/ektJPjuPnS1s+YmRK9A=="
|
||||
},
|
||||
"bootstrap4": {
|
||||
"version": "npm:bootstrap@4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz",
|
||||
"integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
## 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.
|
||||
* `bs<4/5>-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.
|
||||
Note: For BS5, it assumes that bootstrap is installed in `../../node_modules/bootstrap` relative to itself.
|
||||
For BS4, it assumes that bootstrap is installed in `../../node_modules/bootstrap4` relative to itself. (`npm install bootstrap4@npm:bootstrap`)
|
||||
* 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.
|
||||
* If you're using `sassc`, run `./compile.sh bs<4/5>-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 building from source, copy the minified css to `<jf-accounts git directory>/jellyfin_accounts/data/static/bs<4/5>-jf.css`.
|
||||
* If you're just customizing your install, set `custom_css` in your config as the path to your minified css.
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,136 @@
|
|||
$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: #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);
|
||||
|
||||
$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;
|
||||
$body-color: $jf-text-primary;
|
||||
$border-color: $jf-gray-60;
|
||||
$component-active-color: $jf-text-bold;
|
||||
$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-90;
|
||||
$input-color: $jf-text-primary;
|
||||
$input-focus-bg: $jf-gray-60;
|
||||
$input-focus-border-color: $jf-blue-focus;
|
||||
$input-disabled-bg: $jf-gray-70;
|
||||
input:disabled {
|
||||
color: $text-muted;
|
||||
}
|
||||
$input-border-color: $jf-gray-60;
|
||||
$input-placeholder-color: $text-muted;
|
||||
|
||||
$form-check-input-bg: $jf-gray-60;
|
||||
$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;
|
||||
|
||||
$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/bootstrap4/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;
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ $list-group-action-active-bg: $jf-blue-focus;
|
|||
background-color: $success;
|
||||
}
|
||||
|
||||
@import "../node_modules/bootstrap/scss/bootstrap";
|
||||
@import "../../node_modules/bootstrap/scss/bootstrap";
|
||||
|
||||
.btn-primary, .btn-outline-primary:hover, .btn-outline-primary:active {
|
||||
color: $jf-text-bold;
|
|
@ -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."
|
Loading…
Reference in New Issue