mirror of
https://github.com/danbulant/dribbblish-dynamic-theme
synced 2026-06-19 06:31:09 +00:00
Merge branch 'main' into colorthief
This commit is contained in:
commit
da404f4c7b
10 changed files with 193 additions and 51 deletions
|
|
@ -1,14 +1,18 @@
|
|||
Added:
|
||||
- `Report Bugs` and `Changelog` buttons to `Settings > About`
|
||||
- Markdown parsing for settings descriptions
|
||||
- Option to have a button to open the settings next to your profile picture
|
||||
|
||||
Fixed:
|
||||
- Fonts looking blurry
|
||||
- Notification popups are being invisible when the (dribbblish) settings are open
|
||||
- Missing on/off times settings for `Based on Time` dark mode (#107)
|
||||
- Playing icon position being wrong when listening to a playlist that is inside a folder ([#106 (comment)](https://github.com/JulienMaille/dribbblish-dynamic-theme/issues/106#issuecomment-967208507))
|
||||
- Alignment of right expanded cover
|
||||
- Slider tooltip is incorrect after a reset (#111)
|
||||
|
||||
Improved:
|
||||
- The settings UI now better represents grouped items
|
||||
- Settings that have been changed from default will now show a line next to them. Inspired by the [Visual Studio Code settings UI](https://d33wubrfki0l68.cloudfront.net/d1f1ea4def506997ced23d3d912154794e530e1c/063d2/assets/img/blog/2020-09-17-vscode-settings/settings-ui.png)
|
||||
- Checkbox / Switch input styles are now more in line with other input styles
|
||||
- Available updates are now shown as a clickable button next to your user icon instead of having to open the user menu
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
"jquery": "^3.6.0",
|
||||
"markdown-it": "^12.2.0",
|
||||
"markdown-it-attrs": "^4.1.0",
|
||||
"markdown-it-bracketed-spans": "^1.0.1",
|
||||
"moment": "^2.29.1",
|
||||
"node-vibrant": "^3.1.6"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import $ from "jquery";
|
||||
import MarkdownIt from "markdown-it";
|
||||
import MarkdownItAttrs from "markdown-it-attrs";
|
||||
import markdownItBracketedSpans from "markdown-it-bracketed-spans";
|
||||
|
||||
import svgUndo from "svg/undo";
|
||||
|
||||
|
|
@ -11,7 +12,7 @@ export default class ConfigMenu {
|
|||
* @property {String|DribbblishConfigArea} [area={name: "Main Settings", order: 0}]
|
||||
* @property {any} [data={}]
|
||||
* @property {Number} [order=0] order < 0 = Higher up | order > 0 = Lower Down
|
||||
* @property {String} [key] defaults to `${area}_${name]`. e.g: About_Info
|
||||
* @property {String} key
|
||||
* @property {String} name
|
||||
* @property {String} [description=""]
|
||||
* @property {any} [defaultValue]
|
||||
|
|
@ -20,6 +21,7 @@ export default class ConfigMenu {
|
|||
* @property {Boolean} [insertOnTop=false]
|
||||
* @property {Boolean} [fireInitialChange=true]
|
||||
* @property {Boolean} [save=true]
|
||||
* @property {validate} [validate]
|
||||
* @property {showChildren} [showChildren]
|
||||
* @property {onAppended} [onAppended]
|
||||
* @property {onChange} [onChange]
|
||||
|
|
@ -34,6 +36,13 @@ export default class ConfigMenu {
|
|||
* @property {Boolean} [toggleable=true]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback validate
|
||||
* @this {DribbblishConfigItem}
|
||||
* @param {any} value
|
||||
* @returns {Boolean | String}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback showChildren
|
||||
* @this {DribbblishConfigItem}
|
||||
|
|
@ -74,6 +83,7 @@ export default class ConfigMenu {
|
|||
typographer: true
|
||||
});
|
||||
this.#md.use(MarkdownItAttrs);
|
||||
this.#md.use(markdownItBracketedSpans);
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.id = "dribbblish-config";
|
||||
|
|
@ -116,6 +126,7 @@ export default class ConfigMenu {
|
|||
elem.setAttribute("type", options.type);
|
||||
if (options.hidden) elem.setAttribute("hidden", true);
|
||||
if (options.childOf) elem.setAttribute("parent", options.childOf);
|
||||
if (options.children.length > 0) elem.setAttribute("children", options.children.map((c) => c.key).join(" "));
|
||||
elem.innerHTML = /* html */ `
|
||||
${
|
||||
options.name != null && options.description != null
|
||||
|
|
@ -154,6 +165,7 @@ export default class ConfigMenu {
|
|||
$inputElem.prop("checked", defaultVal);
|
||||
} else {
|
||||
$inputElem.prop("value", defaultVal);
|
||||
if (options.type == "slider") $inputElem.attr("tooltip", defaultVal);
|
||||
}
|
||||
options.onChange(defaultVal);
|
||||
});
|
||||
|
|
@ -177,6 +189,7 @@ export default class ConfigMenu {
|
|||
insertOnTop: false,
|
||||
fireInitialChange: true,
|
||||
save: true,
|
||||
validate: () => true,
|
||||
showChildren: () => true,
|
||||
onAppended: () => {},
|
||||
onChange: () => {},
|
||||
|
|
@ -186,7 +199,6 @@ export default class ConfigMenu {
|
|||
// Set Defaults
|
||||
options = { ...defaultOptions, ...options };
|
||||
if (typeof options.area == "string") options.area = { name: options.area, order: 0 };
|
||||
if (options.key == null) options.key = `${options.area.name}_${options.name}`.split(" ").join("_");
|
||||
options.description = options.description
|
||||
.split("\n")
|
||||
.filter((line) => line.trim() != "")
|
||||
|
|
@ -194,7 +206,11 @@ export default class ConfigMenu {
|
|||
.join("\n");
|
||||
options._onChange = options.onChange;
|
||||
options.onChange = (val) => {
|
||||
$(`.dribbblish-config-item[key="${options.key}"]`).attr("changed", options.save && val != options.defaultValue ? "" : null);
|
||||
const isValid = validate(val);
|
||||
$(`.dribbblish-config-item[key="${options.key}"]`).attr("changed", isValid === true && val != options.defaultValue ? "" : null);
|
||||
if (!isValid) return;
|
||||
this.set(options.key, val, options.save);
|
||||
|
||||
options._onChange.call(options, val);
|
||||
const show = options.showChildren.call(options, val);
|
||||
options.children.forEach((child) => this.#setHidden(child.key, Array.isArray(show) ? !show.includes(child.key) : !show));
|
||||
|
|
@ -205,6 +221,18 @@ export default class ConfigMenu {
|
|||
|
||||
this.#config[options.key] = options;
|
||||
|
||||
function validate(val) {
|
||||
const isValid = options.validate.call(options, val);
|
||||
const $elem = $(`.dribbblish-config-item[key="${options.key}"]`);
|
||||
if (isValid === true) {
|
||||
$elem.attr("invalid", null).css("--validation-error", "");
|
||||
} else {
|
||||
const error = isValid === false ? "Invalid" : isValid;
|
||||
$elem.attr("invalid", "").css("--validation-error", `"${error.replace(/"/g, `\\"`)}"`);
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
if (options.type == "checkbox") {
|
||||
const input = /* html */ `
|
||||
<input id="dribbblish-config-input-${options.key}" class="x-toggle-input" type="checkbox"${this.get(options.key) ? " checked" : ""}>
|
||||
|
|
@ -215,8 +243,7 @@ export default class ConfigMenu {
|
|||
this.#addInputHTML({ ...options, input });
|
||||
|
||||
$(`#dribbblish-config-input-${options.key}`).on("change", (e) => {
|
||||
this.set(options.key, e.target.checked, options.save);
|
||||
options.onChange(this.get(options.key));
|
||||
options.onChange(e.target.checked);
|
||||
});
|
||||
} else if (options.type == "select") {
|
||||
// Validate
|
||||
|
|
@ -233,8 +260,7 @@ export default class ConfigMenu {
|
|||
this.#addInputHTML({ ...options, input });
|
||||
|
||||
$(`#dribbblish-config-input-${options.key}`).on("change", (e) => {
|
||||
this.set(options.key, e.target.value, options.save);
|
||||
options.onChange(this.get(options.key));
|
||||
options.onChange(e.target.value);
|
||||
});
|
||||
} else if (options.type == "button") {
|
||||
if (typeof options.data != "string") options.data = options.name;
|
||||
|
|
@ -257,9 +283,9 @@ export default class ConfigMenu {
|
|||
} else if (options.type == "number") {
|
||||
// Validate
|
||||
if (options.defaultValue == null) options.defaultValue = 0;
|
||||
const val = this.get(options.key);
|
||||
if (options.data.min != null && val < options.data.min) this.set(options.key, options.data.min, options.save);
|
||||
if (options.data.max != null && val > options.data.max) this.set(options.key, options.data.max, options.save);
|
||||
const _val = this.get(options.key);
|
||||
if (options.data.min != null && _val < options.data.min) this.set(options.key, options.data.min, options.save);
|
||||
if (options.data.max != null && _val > options.data.max) this.set(options.key, options.data.max, options.save);
|
||||
|
||||
const input = /* html */ `
|
||||
<input
|
||||
|
|
@ -282,8 +308,7 @@ export default class ConfigMenu {
|
|||
if (options.data.min != null && e.target.value < options.data.min) e.target.value = options.data.min;
|
||||
if (options.data.max != null && e.target.value > options.data.max) e.target.value = options.data.max;
|
||||
|
||||
this.set(options.key, Number(e.target.value), options.save);
|
||||
options.onChange(this.get(options.key));
|
||||
options.onChange(Number(e.target.value));
|
||||
});
|
||||
} else if (options.type == "text") {
|
||||
if (options.defaultValue == null) options.defaultValue = "";
|
||||
|
|
@ -294,9 +319,10 @@ export default class ConfigMenu {
|
|||
this.#addInputHTML({ ...options, input });
|
||||
|
||||
$(`#dribbblish-config-input-${options.key}`).on("input", (e) => {
|
||||
// TODO: maybe add an validation function via `data.validate`
|
||||
this.set(options.key, e.target.value, options.save);
|
||||
options.onChange(this.get(options.key));
|
||||
const val = e.target.value;
|
||||
if (!validate(val)) return;
|
||||
this.set(options.key, val, options.save);
|
||||
options.onChange(val);
|
||||
});
|
||||
} else if (options.type == "textarea") {
|
||||
if (options.defaultValue == null) options.defaultValue = "";
|
||||
|
|
@ -307,9 +333,7 @@ export default class ConfigMenu {
|
|||
this.#addInputHTML({ ...options, input });
|
||||
|
||||
$(`#dribbblish-config-input-${options.key}`).on("input", (e) => {
|
||||
// TODO: maybe add an validation function via `data.validate`
|
||||
this.set(options.key, e.target.value, options.save);
|
||||
options.onChange(this.get(options.key));
|
||||
options.onChange(e.target.value);
|
||||
});
|
||||
} else if (options.type == "slider") {
|
||||
// Validate
|
||||
|
|
@ -336,8 +360,7 @@ export default class ConfigMenu {
|
|||
$(`#dribbblish-config-input-${options.key}`).attr("tooltip", `${e.target.value}${options.data?.suffix ?? ""}`);
|
||||
$(`#dribbblish-config-input-${options.key}`).attr("value", e.target.value);
|
||||
|
||||
this.set(options.key, Number(e.target.value), options.save);
|
||||
options.onChange(this.get(options.key));
|
||||
options.onChange(Number(e.target.value));
|
||||
});
|
||||
} else if (options.type == "time") {
|
||||
// Validate
|
||||
|
|
@ -350,8 +373,7 @@ export default class ConfigMenu {
|
|||
$(`#dribbblish-config-input-${options.key}`).on("input", (e) => {
|
||||
$(`#dribbblish-config-input-${options.key}`).attr("value", e.target.value);
|
||||
|
||||
this.set(options.key, e.target.value, options.save);
|
||||
options.onChange(this.get(options.key));
|
||||
options.onChange(e.target.value);
|
||||
});
|
||||
} else if (options.type == "color") {
|
||||
// Validate
|
||||
|
|
@ -362,8 +384,7 @@ export default class ConfigMenu {
|
|||
this.#addInputHTML({ ...options, input });
|
||||
|
||||
$(`#dribbblish-config-input-${options.key}`).on("input", (e) => {
|
||||
this.set(options.key, e.target.value, options.save);
|
||||
options.onChange(this.get(options.key));
|
||||
options.onChange(e.target.value);
|
||||
});
|
||||
} else {
|
||||
throw new Error(`Config Type "${options.type}" invalid`);
|
||||
|
|
@ -372,6 +393,7 @@ export default class ConfigMenu {
|
|||
// Re-write internal config since some values may have changed
|
||||
this.#config[options.key] = options;
|
||||
|
||||
validate(this.get(options.key));
|
||||
$(`.dribbblish-config-item[key="${options.key}"]`).attr("changed", options.save && this.get(options.key) != options.defaultValue ? "" : null);
|
||||
|
||||
options.children.forEach((child) => this.register(child));
|
||||
|
|
@ -466,7 +488,32 @@ export default class ConfigMenu {
|
|||
*/
|
||||
#setHidden(key, hidden) {
|
||||
this.#config[key].hidden = hidden;
|
||||
$(`.dribbblish-config-item[key="${key}"]`).attr("hidden", hidden ? "" : null);
|
||||
const $elem = $(`.dribbblish-config-item[key="${key}"]`);
|
||||
$elem.attr("hidden", hidden ? "" : null);
|
||||
|
||||
// If element has children or a parent
|
||||
if ($elem.attr("parent") != null || $elem.attr("children") != null) {
|
||||
// Get parent of element block
|
||||
const $parent = $elem.attr("parent") != null ? $(`[children~="${key}"]`) : $elem;
|
||||
const $nextChildren = $parent.nextAll(`[parent="${$parent.attr("key")}"]`);
|
||||
|
||||
// Make parent connect on bottom when children are visible
|
||||
$parent.attr("connect-bottom", $nextChildren.filter(":not([hidden])").length > 0 ? "" : null);
|
||||
|
||||
// Reset all children's bottom connection
|
||||
$nextChildren.each(function () {
|
||||
$(this).attr("connect-bottom", null);
|
||||
});
|
||||
// Add bottom connection to all but the last visible child
|
||||
$nextChildren
|
||||
.filter(":not([hidden])")
|
||||
.slice(0, -1)
|
||||
.each(function () {
|
||||
$(this).attr("connect-bottom", "");
|
||||
});
|
||||
|
||||
//* NOTE: All children automatically have a top connection
|
||||
}
|
||||
}
|
||||
|
||||
getOptions(key) {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,17 @@ export default class Info {
|
|||
* @property {String} [text]
|
||||
* @property {String} [tooltip]
|
||||
* @property {String} [icon]
|
||||
* @property {{fg: String, bg: String}} [color] defaults to {fg: "sidebar-text", bg: "button"}
|
||||
* @property {DribbblishInfoColor} [color]
|
||||
* @property {Number} [order=0] order < 0 = More to the Left | order > 0 = More to the Right
|
||||
* @property {onClick} [onClick]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} DribbblishInfoColor
|
||||
* @property {String} [fg]
|
||||
* @property {String} [bg]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback onClick
|
||||
* @returns {void}
|
||||
|
|
@ -58,9 +64,9 @@ export default class Info {
|
|||
if (info.tooltip != null) elem.setAttribute("title", info.tooltip);
|
||||
if (info.onClick != null) elem.setAttribute("clickable", "");
|
||||
if (info.color != null) {
|
||||
const { bg, fg } = info.color;
|
||||
if (bg != null) elem.style.backgroundColor = bg;
|
||||
const { fg, bg } = info.color;
|
||||
if (fg != null) elem.style.color = fg;
|
||||
if (bg != null) elem.style.backgroundColor = bg;
|
||||
}
|
||||
if (info.order != 0) elem.style.order = info.order;
|
||||
elem.innerHTML = `${info.text ?? ""}${info.icon ?? ""}`;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import Info from "./Info";
|
|||
import svgArrowDown from "svg/arrow-down";
|
||||
import svgCode from "svg/code";
|
||||
import svgWifiSlash from "svg/wifi-slash";
|
||||
import svgCog from "svg/cog";
|
||||
|
||||
const Dribbblish = {
|
||||
config: new ConfigMenu(),
|
||||
|
|
@ -20,6 +21,25 @@ const colorThief = new ColorThief();
|
|||
// To expose to external scripts
|
||||
window.Dribbblish = Dribbblish;
|
||||
|
||||
Dribbblish.config.register({
|
||||
type: "checkbox",
|
||||
key: "openSettingsInfo",
|
||||
name: "Open Settings Icon",
|
||||
description: "Show an icon next to your profile image to open the dribbblish settings",
|
||||
defaultValue: true,
|
||||
onChange: (val) =>
|
||||
Dribbblish.info[val ? "set" : "remove"]("settings", {
|
||||
icon: svgCog,
|
||||
color: {
|
||||
fg: "var(--spice-subtext)",
|
||||
bg: "rgba(var(--spice-rgb-subtext), calc(0.1 + var(--is_light) * 0.05))"
|
||||
},
|
||||
order: 999,
|
||||
tooltip: "Open Dribbblish Settings",
|
||||
onClick: () => Dribbblish.config.open()
|
||||
})
|
||||
});
|
||||
|
||||
Dribbblish.config.register({
|
||||
type: "checkbox",
|
||||
key: "rightBigCover",
|
||||
|
|
@ -598,7 +618,7 @@ Dribbblish.config.register({
|
|||
key: "theme",
|
||||
name: "Theme",
|
||||
description: "Select Dark / Bright mode",
|
||||
defaultValue: "dark",
|
||||
defaultValue: "time",
|
||||
showChildren: (val) => {
|
||||
if (val == "time") return ["darkModeOnTime", "darkModeOffTime"];
|
||||
return false;
|
||||
|
|
@ -803,7 +823,7 @@ waitForElement([".main-topBar-container"], ([topBarContainer]) => {
|
|||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
const isDev = process.env.DRIBBBLISH_VERSION == "Dev";
|
||||
Dribbblish.info.set("upd", isDev || data.tag_name > process.env.DRIBBBLISH_VERSION ? { text: `v${data.tag_name}`, tooltip: "Open Release page to download", icon: svgArrowDown, onClick: () => window.open("https://github.com/JulienMaille/dribbblish-dynamic-theme/releases/latest", "_blank") } : null);
|
||||
Dribbblish.info.set("update", isDev || data.tag_name > process.env.DRIBBBLISH_VERSION ? { text: `v${data.tag_name}`, tooltip: "Open Release page to download", icon: svgArrowDown, onClick: () => window.open("https://github.com/JulienMaille/dribbblish-dynamic-theme/releases/latest", "_blank") } : null);
|
||||
Dribbblish.info.set("dev", isDev ? { tooltip: "Dev build", icon: svgCode } : null);
|
||||
})
|
||||
.catch(console.error);
|
||||
|
|
@ -818,7 +838,7 @@ window.addEventListener("offline", () =>
|
|||
Dribbblish.info.set("offline", {
|
||||
tooltip: "Offline",
|
||||
icon: svgWifiSlash,
|
||||
order: 999,
|
||||
order: 998,
|
||||
color: {
|
||||
fg: "#ffffff",
|
||||
bg: "#ff2323"
|
||||
|
|
|
|||
|
|
@ -46,10 +46,13 @@ $props-to-transition: ("sidebar", "main", "text", "button");
|
|||
}
|
||||
|
||||
// Color Function
|
||||
@function spiceColor($key, $alpha: 1) {
|
||||
// $light-offset is added when in light mode
|
||||
@function spiceColor($key, $alpha: 1, $light-offset: 0) {
|
||||
@if $alpha == 1 {
|
||||
@return var(--spice-#{$key});
|
||||
} @else {
|
||||
} @else if $light-offset == 0 {
|
||||
@return rgba(var(--spice-rgb-#{$key}), $alpha);
|
||||
} @else {
|
||||
@return rgba(var(--spice-rgb-#{$key}), calc($alpha + var(--is_light) * $light-offset));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
z-index: 1;
|
||||
position: relative;
|
||||
width: clamp(500px, 50%, 650px);
|
||||
background-color: spiceColor("main", 0.9);
|
||||
background-color: spiceColor("main", 0.95);
|
||||
backdrop-filter: blur(3px);
|
||||
padding: 20px 15px;
|
||||
border-radius: var(--main-corner-radius);
|
||||
|
|
@ -44,22 +44,23 @@
|
|||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
gap: 8px;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
padding: 0px 50px;
|
||||
padding: 0px 25px;
|
||||
|
||||
.dribbblish-config-area {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
&[collapsed] {
|
||||
overflow: hidden;
|
||||
min-height: 38px; //for some reason height alone isn't enough
|
||||
height: 38px;
|
||||
|
||||
> h2 svg {
|
||||
.dribbblish-config-area-header svg {
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
}
|
||||
|
|
@ -71,6 +72,7 @@
|
|||
.dribbblish-config-area-header {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: fit-content;
|
||||
height: 38px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
|
|
@ -89,7 +91,8 @@
|
|||
.dribbblish-config-area-items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
|
||||
.dribbblish-config-item {
|
||||
position: relative;
|
||||
|
|
@ -99,23 +102,58 @@
|
|||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 16px;
|
||||
|
||||
&[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&[parent] {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
&[changed]::before {
|
||||
&::before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -13px;
|
||||
top: -3px;
|
||||
bottom: -3px;
|
||||
width: 3px;
|
||||
background-color: spiceColor("sidebar");
|
||||
inset: 0px;
|
||||
border-radius: var(--main-corner-radius);
|
||||
background-color: spiceColor("subtext", 0.03, 0.04);
|
||||
}
|
||||
|
||||
&[parent]::before {
|
||||
top: -8px;
|
||||
border-top-left-radius: 0px;
|
||||
border-top-right-radius: 0px;
|
||||
}
|
||||
|
||||
&[connect-bottom]::before {
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
&[invalid]::before {
|
||||
border: 2px solid rgba(red, 0.8);
|
||||
}
|
||||
|
||||
&[changed] {
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
width: 5px;
|
||||
background-color: spiceColor("text");
|
||||
border-top-left-radius: var(--main-corner-radius);
|
||||
border-bottom-left-radius: var(--main-corner-radius);
|
||||
}
|
||||
|
||||
&[parent]::after {
|
||||
top: -4px;
|
||||
border-top-left-radius: 0px;
|
||||
}
|
||||
|
||||
&[connect-bottom]::after {
|
||||
bottom: -4px;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.dribbblish-config-item-header {
|
||||
|
|
@ -152,6 +190,7 @@
|
|||
height: min-content;
|
||||
color: spiceColor("subtext");
|
||||
line-height: calc(1em + 6px); // To have line gaps
|
||||
line-break: anywhere;
|
||||
}
|
||||
|
||||
.x-settings-secondColumn {
|
||||
|
|
@ -162,6 +201,12 @@
|
|||
|
||||
.dribbblish-config-item-input {
|
||||
min-width: fit-content;
|
||||
|
||||
&::before {
|
||||
content: var(--validation-error);
|
||||
margin-right: 8px;
|
||||
color: rgba(red, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,17 @@ button.main-button-primary {
|
|||
}
|
||||
}
|
||||
|
||||
// Modals
|
||||
.GenericModal button.main-button-primary {
|
||||
background-color: spiceColor("subtext", 0.6) !important;
|
||||
color: spiceColor("main") !important;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
background-color: spiceColor("subtext") !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Checkbox
|
||||
.x-toggle-indicatorWrapper {
|
||||
background-color: spiceColor("subtext", 0.1);
|
||||
|
|
|
|||
|
|
@ -973,6 +973,7 @@ span.main-userWidget-displayName,
|
|||
}
|
||||
|
||||
.main-rootlist-wrapper > div:nth-child(2) > li img,
|
||||
.main-navBar-navBarLink > svg,
|
||||
.main-navBar-navBarLink > .icon {
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
@ -1055,12 +1056,12 @@ div.GlueDropTarget.personal-library > *.active {
|
|||
}
|
||||
|
||||
html.right-expanded-cover .main-coverSlotExpanded-container {
|
||||
right: calc(var(--main-gap) + 10px);
|
||||
right: var(--main-gap);
|
||||
left: unset;
|
||||
}
|
||||
|
||||
html.right-expanded-cover.buddyfeed-visible .main-coverSlotExpanded-container {
|
||||
right: calc(var(--main-gap) + var(--buddy-feed-width) + 10px);
|
||||
right: calc(var(--main-gap) + var(--buddy-feed-width));
|
||||
left: unset;
|
||||
}
|
||||
|
||||
|
|
@ -1225,6 +1226,7 @@ html.right-expanded-cover.buddyfeed-visible .main-coverSlotExpanded-container {
|
|||
}
|
||||
.main-view-container__scroll-node-child {
|
||||
height: 100%;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
// Hide default Sporify "Offline" notice
|
||||
|
|
|
|||
3
src/svg/cog.svg
Normal file
3
src/svg/cog.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16">
|
||||
<path fill="currentColor" d="M487.4 315.7l-42.6-24.6c4.3-23.2 4.3-47 0-70.2l42.6-24.6c4.9-2.8 7.1-8.6 5.5-14-11.1-35.6-30-67.8-54.7-94.6-3.8-4.1-10-5.1-14.8-2.3L380.8 110c-17.9-15.4-38.5-27.3-60.8-35.1V25.8c0-5.6-3.9-10.5-9.4-11.7-36.7-8.2-74.3-7.8-109.2 0-5.5 1.2-9.4 6.1-9.4 11.7V75c-22.2 7.9-42.8 19.8-60.8 35.1L88.7 85.5c-4.9-2.8-11-1.9-14.8 2.3-24.7 26.7-43.6 58.9-54.7 94.6-1.7 5.4.6 11.2 5.5 14L67.3 221c-4.3 23.2-4.3 47 0 70.2l-42.6 24.6c-4.9 2.8-7.1 8.6-5.5 14 11.1 35.6 30 67.8 54.7 94.6 3.8 4.1 10 5.1 14.8 2.3l42.6-24.6c17.9 15.4 38.5 27.3 60.8 35.1v49.2c0 5.6 3.9 10.5 9.4 11.7 36.7 8.2 74.3 7.8 109.2 0 5.5-1.2 9.4-6.1 9.4-11.7v-49.2c22.2-7.9 42.8-19.8 60.8-35.1l42.6 24.6c4.9 2.8 11 1.9 14.8-2.3 24.7-26.7 43.6-58.9 54.7-94.6 1.5-5.5-.7-11.3-5.6-14.1zM256 336c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 945 B |
Loading…
Reference in a new issue