Skip Navigation

kbin-mod-options; Mod options made easy

kbin-mod-options

Description

The purpose of this script is to allow mods to more easily implement settings.

Functionality

Header

kmoAddHeader(<modName>, <{author: 'name', version: 'versionNumber', license: 'licenseType', url: 'modUrl'}>);

  • modName - required
  • info object - optional

Example

const settingHeader = kmoAddHeader(
    'kbin-mod-options examples',
    {
        author: 'Ori',
        version: '0.1',
        license: 'MIT',
        url: 'https://github.com/Oricul'
    }
);

Header Example

Toggle Switch

kmoAddToggle(<headerChildDiv>, <settingLabel>, <settingValue>, <settingDescription>);

  • headerChildDiv - required
  • settingLabel - required
  • settingValue - required
  • settingDescription - optional

Example

// Create toggle switch
const settingEnabled = kmoAddToggle(
    settingHeader,
    'Enabled',
    true,
    'Turns this mod on or off.'
);
// Listen for toggle
settingEnabled.addEventListener("click", () => {
    // Log enabled state to console.
    console.log( kmoGetToggle(settingEnabled) );
});

Toggle Switch Example

Drop-Down

kmoAddDropDown(<headerChildDiv>, <settingLabel>, <[{name: 'friendlyName', value: 'backendValue'},{name: 'friendlyNameTwo', value: 'backendValueTwo'}]>, <currentSetting>, <settingDescription>);

  • headerChildDiv - required
  • settingLabel - required
  • options array - required
  • name/value in options array - required
  • currentSetting - required
  • settingDescription - optional

Example

// Create drop down
const font = kmoAddDropDown(
    settingHeader,
    'Font',
    [
        {
            name: 'Arial',
            value: 'font-arial'
        },{
            name: 'Consolas',
            value: 'font-consolas'
        }
    ],
    'font-consolas',
    'Choose a font for kbin.'
);
// Listen for drop down change
font.addEventListener("change", () => {
    // Log drop down selection to console.
    console.log( kmoGetDropDown(font) );
});

Drop-Down Example

Button

kmoAddButton(<headerChildDiv>, <settingLabel>, <buttonLabel>, <settingDescription>);

  • headerChildDiv - required
  • settingLabel - required
  • buttonLabel - required
  • settingDescription - optional

Example

// Create button const
const resetButton = kmoAddButton(
    settingHeader,
    'Default Settings',
    'Reset',
    'Resets settings to defaults.'
);
// Listen for button press.
resetButton.addEventListener("click", () => {
    // Log press to console.
    console.log( 'button pressed!' );
});

Button Example

Color Dropper

kmoAddColorDropper(<headerChildDiv>, <settingLabel>, <currentColor>, <settingDescription>);

  • headerChildDiv - required
  • settingLabel - required
  • currentColor - required
  • settingDescription - optional

Example

// Create color dropper const
const primaryColor = kmoAddColorDropper(
    settingHeader,
    'Primary Color',
    '#0ff',
    'Select primary theme color'
);
// Listen for new color change
primaryColor.addEventListener("change", () => {
    // Log color selection out to console.
    console.log( primaryColor.value );
});

Color Dropper Example

Usage

Simply add kbin-mod-options to your script's requires.

// @require    https://github.com/Oricul/kbin-scripts/raw/main/kbin-mod-options.js

Example

// ==UserScript==
// @name         kbin-mod-options-dev
// @namespace    https://github.com/Oricul
// @version      0.1
// @description  Attempt at standardizing mod options.
// @author       0rito
// @license      MIT
// @match        https://kbin.social/*
// @match        https://kbin.sh/*
// @icon         https://kbin.social/favicon.svg
// @grant        none
// @require      file://H:/GoogleDrive/Personal/Documents/GitHub/kbin-scripts/kbin-mod-options.js
// ==/UserScript==

(function() {
    'use strict';

    // Section header - kmoAddHeader(<modName>, {author: 'name', version: 'versionNumber', license: 'licenseType', url: 'modUrl'});
    // modName - required, author - optional, version - optional, license - optional, url - optional
    const settingHeader = kmoAddHeader(
        'kbin-mod-options examples',
        {
            author: 'Ori',
            version: '0.1',
            license: 'MIT',
            url: 'https://github.com/Oricul'
        }
    );
    // Toggle switch - kmoAddToggle(<settingLabel>, <settingValue>, <settingDescription>);
    // settingLabel - required, settingValue - required, settingDescription - optional
    const settingOne = kmoAddToggle(
        settingHeader,
        'Enabled',
        true,
        'Turn this mod on or off.'
    );
    // Listener for toggle switch - kmoGetToggle(<toggleSwitchVar>);
    // toggleSwitchVar - required
    settingOne.addEventListener("click", () => {
            console.log(kmoGetToggle(settingOne));
    });
    // Dropdown Menu - kmoAddDropDown(<settingLabel>, [{name: 'name', value: 'value'},{name: 'name2', value: 'value2'}], <currentSetting>, <settingDescription>);
    // settingLabel - required, name & value - required, currentSetting - required, settingDescription - optional
    const settingTwo = kmoAddDropDown(
        settingHeader,
        'Font',
        [
            {
                name: 'Arial',
                value: 'font-arial'
            },{
                name: 'Consolas',
                value: 'font-consolas'
            }
        ],
        'font-consolas',
        'Choose a site-wide font.');
    // Listener for dropdown menu - kmoGetDropDown(<dropDownVar>);
    // dropDownVar - required
    settingTwo.addEventListener("change", () => {
        console.log(kmoGetDropDown(settingTwo));
    });
    // Button - kmoAddButton(<settingLabel>, <buttonLabel>, <settingDescription>);
    // settingLabel - required, buttonLabel - required, settingDescription - optional
    const settingThree = kmoAddButton(
        settingHeader,
        'Default Settings',
        'Reset',
        'Resets settings to defaults.'
    );
    // Listener example for buttons.
    settingThree.addEventListener("click", () => {
        console.log('button pressed');
    });
    // Color Dropper - kmoAddColorDropper(<settingLabel>, <currentColor>, <settingDescription>);
    // settingLabel - required, currentColor - required, settingDescription - optional
    const settingFour = kmoAddColorDropper(
        settingHeader,
        'Primary Color',
        '#0ff',
        'Select primary color for style.'
    );
    // Listener example for color dropper.
    settingFour.addEventListener("change", () => {
        console.log(settingFour.value);
    });
})();

20

You're viewing a single thread.

20 comments
  • @shazbot and I (mostly shazbot) have been working on something that's pretty similar, it isn't ready for the public yet, but it's almost there (there's a big pull request that we're working on finishing now). I'd love it if you join us so we can pool our efforts together! A unified settings menu is definitely something that we need for the community, and it'd be great if we could all work together on a single one so it can be perfect :)

    • Yep, I've looked at it, used it a bit. I feel as though the two projects are distinct enough that they could co-exist. Whereas megamod is a mod manager where you can toggle on/off, it becomes a burden for script writers to maintain two separate sets of options for their scripts - one for megamod and one for a standalone version.

      In contrast, this script isn't intended to be installed as a userscript. Instead, it's to supplement other developers userscripts. A userscript that is setup to work with megamod could still utilize this script and simply lightens the load on the developer.

      My reasoning is that I agree with @JohnEdwa and, subsequently, @SirPsychoMantis - at least partially. It makes sense for options to be standardized in one place, in this case the options menu. I also believe that if megamod does go mainstream, it's mod manager should be separate.

      Hope that makes sense. ( っ- ‸ - c)

      • The megamod is also going to have configuration options for each script, that's something shazbot is working on right now, but I do see your point about them coexisting.

        I totally get why you wanna put everything in one place, but personally I think it'll get too cluttered with a lot of scripts adding their settings to the sidebar. Hence the separate settings menu that fills the screen.

        I'm excited to see where you go with this!

        • Might be a little less cluttered visibly if settings sections were collapsed vertically to start. Might be something I look at tomorrow.

          • I bet that'd work well! If you're not opposed to using jquery, jquery-ui's accordion widget would make that pretty easy to do

      • I haven't picked this apart yet, but I am thinking about how we can blend these two approaches and perhaps utilize your logic in the megamod script, at least insofar as creating the input fields requested. I agree that it's a burden on authors to maintain two versions. I always assumed from the start that we would need to do some integration ("porting") on the megamod end if we choose to add in scripts. I don't think it's reasonable or necessary to track down every mod author and force them to push PRs into the repo solely for the purposes of adding a few LOC to add a toggle. However, basic interopability is obviously desirable and simplifies the process, but I'm not fundamentally against fragmentation, either.

        Current logic is:

        Recipient script "requests" the population of certain menu options by defining these a priori in the JSON manifest. E.g., I want a select field with these values, a, b, and c. Megamod builds up its menus based on these fields and when their state is changed, updates a locally cached object with the values for those parameters, calling the entry point function in the recipient script with these values. Megamod itself doesn't parse any of these values, merely hands them back to the recipient script.

        We have no control right now over how a script author chooses to write their entry point function. Some agreed-upon standard would be nice to have, but might not be possible. The other issue is that megamod does not intentionally try to stay in lock-step with remote scripts by sourcing them verbatim. The analogy is that megamod is more like a stable "distro" with manually whitelisted "packages" that are included after auditing and necessary changes are made. So megamod's versions might be slightly behind the bleeding-edge version, and it's the responsibility of megamod's maintainers to audit and update them as necessary. If a user wants access to bleeding-edge versions of any script without integration, they can use the *monkey extension's discovery panel to find and install remote scripts matching the TLD.

        @artillect

20 comments