- // ==UserScript==
- // @name Libib - Custom status indicator style
- // @name:it Libib - Stile indicatore stato personalizzato
- // @description Set a custom color and style for libib.com item status indicator
- // @description:it Modifica i colori e lo stile dell'indicatore dello stato di un oggetto di libib.com
- // @author JetpackCat
- // @namespace https://github.com/JetpackCat-IT/libib-custom-status-style
- // @supportURL https://github.com/JetpackCat-IT/libib-custom-status-style/issues
- // @icon https://github.com/JetpackCat-IT/libib-custom-status-style/raw/v1.0.0/img/icon_64.png
- // @version 0.0.1pre
- // @license GPL-3.0
- // @match https://www.libib.com/library
- // @icon https://www.libib.com/img/favicon.png
- // @run-at document-idle
- // @require https://openuserjs.org/src/libs/sizzle/GM_config.js
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM.getValue
- // @grant GM.setValue
-
- // ==/UserScript==
-
- (function () {
- "use strict";
-
- // Get libib sidebar menu. The settings button will be added to the sidebar
- const libib_sidebar_menu = document.getElementById("primary-menu");
-
- // Create the element, it needs to be an <a> tag inside an <li> tag
- const settings_button_a = document.createElement("a");
- settings_button_a.appendChild(
- document.createTextNode("Libib status settings")
- );
-
- // Create <li> element and insert <a> element inside
- const settings_button_li = document.createElement("li");
- settings_button_li.appendChild(settings_button_a);
-
- // Assign click event handler to open the menu settings
- settings_button_li.addEventListener("click", function () {
- gmc.open();
- });
-
- // Add <li> element to the sidebar
- libib_sidebar_menu.appendChild(settings_button_li);
-
- // Create a container for the configuration elements
- const config_container = document.createElement("div");
- document.body.appendChild(config_container);
-
- // Adapt container background color and shadow based on libib theme (dark/light)
- const is_dark_scheme = document.body.classList.contains("dark");
- let background_color = "#fefefe";
- let shadow_color = "#838383";
-
- if (is_dark_scheme) {
- background_color = "#1b1b1b";
- shadow_color = "#e7e7e7";
- }
- const config_panel_css = `#libib_status_config{padding: 20px !important; background-color: ${background_color}; box-shadow: 0px 0px 9px 3px ${shadow_color}}; `;
-
- let gmc = new GM_config({
- id: "libib_status_config", // The id used for this instance of GM_config
- title: "Script Settings", // Panel Title
- types: {
- // Create color input type
- color: {
- default: null,
- toNode: function () {
- var field = this.settings,
- value = this.value,
- id = this.id,
- create = this.create,
- slash = null,
- retNode = create("div", {
- className: "config_var",
- id: this.configId + "_" + id + "_var",
- title: field.title || "",
- });
-
- // Create the field lable
- retNode.appendChild(
- create("label", {
- innerHTML: field.label,
- id: this.configId + "_" + id + "_field_label",
- for: this.configId + "_field_" + id,
- className: "field_label",
- })
- );
- // Create the actual input element
- var props = {
- id: this.configId + "_field_" + id,
- type: "color",
- value: value ?? "",
- };
- // Actually create and append the input element
- retNode.appendChild(create("input", props));
- return retNode;
- },
- toValue: function () {
- let input = document.getElementById(
- `${this.configId}_field_${this.id}`
- );
- return input.value;
- },
- reset: function () {
- let input = document.getElementById(
- `${this.configId}_field_${this.id}`
- );
- input.value = this.default;
- },
- },
- },
- // Fields object
- fields: {
- // This is the id of the field
- type: {
- label: "Indicator type", // Appears next to field
- type: "radio", // Makes this setting a radio field
- options: ["Triangle", "Border"], // Default = triangle
- default: "Triangle", // Default value if user doesn't change it
- },
- // This is the id of the field
- trianglePosition: {
- label: "Triangle position", // Appears next to field
- type: "select", // Makes this setting a select field
- options: ["Top left", "Top right", "Bottom left", "Bottom right"],
- default: "Top left", // Default value if user doesn't change it
- },
- // This is the id of the field
- borderPosition: {
- label: "Border position", // Appears next to field
- type: "select", // Makes this setting a select field
- options: ["Top", "Bottom"],
- default: "Top", // Default value if user doesn't change it
- },
- // This is the id of the field
- colorNotBegun: {
- label: '"Not begun" Color', // Appears next to field
- type: "color", // Makes this setting a text field
- default: "#ffffff", // Default value if user doesn't change it
- },
- // This is the id of the field
- colorCompleted: {
- label: '"Completed" Color', // Appears next to field
- type: "color", // Makes this setting a text field
- default: "#76eb99", // Default value if user doesn't change it
- },
- // This is the id of the field
- colorProgress: {
- label: '"In progress" Color', // Appears next to field
- type: "color", // Makes this setting a text field
- default: "#ffec8a", // Default value if user doesn't change it
- },
- // This is the id of the field
- colorAbandoned: {
- label: '"Abandoned" Color', // Appears next to field
- type: "color", // Makes this setting a text field
- default: "#ff7a7a", // Default value if user doesn't change it
- },
- },
- css: config_panel_css,
- frame: config_container,
- // Callback functions object
- events: {
- init: function () {
- let css = generateCSS(this);
- setCustomStyle(css);
- },
- save: function () {
- let css = generateCSS(this);
- setCustomStyle(css);
- this.close();
- },
- },
- });
-
- const generateCSS = function (GM_settings) {
- if (GM_settings == null) GM_settings = gmc;
-
- const not_begun_color = GM_settings.get("colorNotBegun");
- const completed_color = GM_settings.get("colorCompleted");
- const in_progress_color = GM_settings.get("colorProgress");
- const abandoned_color = GM_settings.get("colorAbandoned");
-
- let css_style = "";
- // Make libib buttons still clickable
- css_style += `
- .quick-edit-link{
- z-index: 10;
- }
- .batch-select{
- z-index: 10;
- }
- `;
- // Set the save, close and reset buttons color to white id dark mode
- css_style += `
- body.dark #libib_status_config_resetLink,body.dark #libib_status_config_saveBtn,body.dark #libib_status_config_closeBtn{
- color:white!important
- }`;
-
- // Triangle style
- if (GM_settings.get("type") == "Triangle") {
- let triangle_position = GM_settings.get("trianglePosition");
- if (triangle_position == "Top left") {
- css_style += `
- .cover .completed.cover-wrapper::after {
- border-left-color: ${completed_color};
- border-top-color: ${completed_color};
- }
- .cover .in-progress.cover-wrapper::after {
- border-left-color: ${in_progress_color};
- border-top-color: ${in_progress_color};
- }
- .cover .abandoned.cover-wrapper::after {
- border-left-color: ${abandoned_color};
- border-top-color: ${abandoned_color};
- }
- .cover .not-begun.cover-wrapper::after {
- border-left-color: ${not_begun_color};
- border-top-color: ${not_begun_color};
- }
- `;
- } else if (triangle_position == "Top right") {
- css_style += `
- .cover .cover-wrapper::after{
- right: 0;
- left: auto;
- }
- .cover .completed.cover-wrapper::after {
- border-left-color: transparent;
- border-right-color: ${completed_color};
- border-top-color: ${completed_color};
- }
- .cover .in-progress.cover-wrapper::after {
- border-left-color: transparent;
- border-right-color: ${in_progress_color};
- border-top-color: ${in_progress_color};
- }
- .cover .abandoned.cover-wrapper::after {
- border-left-color: transparent;
- border-right-color: ${abandoned_color};
- border-top-color: ${abandoned_color};
- }
- .cover .not-begun.cover-wrapper::after {
- border-left-color: transparent;
- border-right-color: ${not_begun_color};
- border-top-color: ${not_begun_color};
- }
- `;
- } else if (triangle_position == "Bottom left") {
- css_style += `
- .cover .cover-wrapper::after{
- bottom: 0;
- top: auto;
- }
- .cover .completed.cover-wrapper::after {
- border-top-color: transparent;
- border-left-color: ${completed_color};
- border-bottom-color: ${completed_color};
- }
- .cover .in-progress.cover-wrapper::after {
- border-top-color: transparent;
- border-left-color: ${in_progress_color};
- border-bottom-color: ${in_progress_color};
- }
- .cover .abandoned.cover-wrapper::after {
- border-top-color: transparent;
- border-left-color: ${abandoned_color};
- border-bottom-color: ${abandoned_color};
- }
- .cover .not-begun.cover-wrapper::after {
- border-top-color: transparent;
- border-left-color: ${not_begun_color};
- border-bottom-color: ${not_begun_color};
- }
- `;
- } else if (triangle_position == "Bottom right") {
- css_style += `
- .cover .cover-wrapper::after{
- bottom: 0;
- top: auto;
- left: auto;
- right: 0;
- }
- .cover .completed.cover-wrapper::after {
- border-top-color: transparent;
- border-left-color: transparent;
- border-right-color: ${completed_color};
- border-bottom-color: ${completed_color};
- }
- .cover .in-progress.cover-wrapper::after {
- border-top-color: transparent;
- border-left-color: transparent;
- border-right-color: ${in_progress_color};
- border-bottom-color: ${in_progress_color};
- }
- .cover .abandoned.cover-wrapper::after {
- border-top-color: transparent;
- border-left-color: transparent;
- border-right-color: ${abandoned_color};
- border-bottom-color: ${abandoned_color};
- }
- .cover .not-begun.cover-wrapper::after {
- border-top-color: transparent;
- border-left-color: transparent;
- border-right-color: ${not_begun_color};
- border-bottom-color: ${not_begun_color};
- }
- `;
- }
- } else if (GM_settings.get("type") == "Border") {
- let border_position = GM_settings.get("borderPosition");
- // The box-shadow prevents the click on the item, so it needs to be hidden on hover
- css_style += `
- .cover-wrapper {
- --shadow-y: ${border_position == "Top" ? "5px" : "-5px"};
- }
- .cover-wrapper:hover::after {
- display:none!important;
- --shadow-y: 0px;
- transition: all 0.25s;
- transition-behavior: allow-discrete;
- }`;
-
- css_style += `
- .cover .cover-wrapper::before, .cover .cover-wrapper::after {
- width: 100%;
- height: 100%;
- border-radius: 4px;
- display: block;
- border: none;
- z-index: 0;
- }
- .cover .completed.cover-wrapper::after {
- box-shadow: inset 0px var(--shadow-y) ${completed_color};
- }
- .cover .in-progress.cover-wrapper::after {
- box-shadow: inset 0px var(--shadow-y) ${in_progress_color};
- }
- .cover .abandoned.cover-wrapper::after {
- box-shadow: inset 0px var(--shadow-y) ${abandoned_color};
- }
- .cover .not-begun.cover-wrapper::after {
- box-shadow: inset 0px var(--shadow-y) ${not_begun_color};
- }
- `;
- }
- return css_style;
- };
-
- const setCustomStyle = function (css) {
- // Remove existing style if present
- const existingStyle = document.getElementById(
- "libib-custom-status-indicator-style"
- );
- if (existingStyle != null) {
- existingStyle.remove();
- }
-
- // Add style tag to document
- document.head.append(
- Object.assign(document.createElement("style"), {
- type: "text/css",
- id: "libib-custom-status-indicator-style",
- textContent: css,
- })
- );
- };
- })();