OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
 
main @ 711 LINES
 
[ HISTORY ]  [ UP ]
 

{
  lib,
  pkgs,
  config,
  ...
}: let
  inherit (lib) mkIf mkOption mkEnableOption mkPackageOption;
  inherit (lib.types) listOf str int enum numbers oneOf bool strMatching;
  mkBoolOption = default: description:
    mkOption {
      type = bool;
      inherit default description;
    };

  mkLabelOption = default:
    mkOption {
      type = str;
      inherit default;
      description = "${default} label";
    };

  mkEquibopSelect = attr: v: attr.${v};
  listToString = sep: list: builtins.concatStringsSep sep list;

  rgbValue = ''([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'';
  rgbDecimal = strMatching ''${rgbValue}, *${rgbValue}, *${rgbValue}'';
  hexColor = strMatching "#[[:xdigit:]]{6}";

  mkHexColorOption = name:
    mkOption {
      type = oneOf [hexColor (enum [""])];
      default = "";
      description = "${name} color in hex format";
      example = "#ea6962";
    };

  cfg = config.programs.equicord;
in {
  options.programs.equicord = {
    enable = mkEnableOption "Enable Equicord, for of Vencord";
    package = mkPackageOption pkgs "equibop" {
      default = "equibop";
      example = pkgs.equicord;
    };
    settings = {
      autoUpdate = mkEnableOption "Enable auto updating for Equicord" // {default 
= true;};
      autoUpdateNotification = mkEnableOption "Notify when Equicord automatically 
updates";
      useQuickCss = mkEnableOption "Enable custom CSS";
      themeLinks = mkOption {
        type = listOf str;
        default = [];
        description = "List of Discord CSS themes to install via link";
        example = ["https://refact0r.github.io/midnight-discord/midnight.css"];
      };
      enabledThemes = mkOption {
        type = listOf str;
        default = [];
        description = "List of themes to enable from XDG_CONFIG_HOME/equibop/theme
s";
      };
      enableReactDevtools = mkEnableOption "Enable react dev tools extension";
      frameless = mkEnableOption "Enable frameless mode";
      transparent = mkEnableOption "Enable transparent mode. Requires a theme that
 supports transparency";
      disableMinSize = mkEnableOption "Disable minimum window size";
      notifications = {
        timeout = mkOption {
          type = int;
          default = 5000;
          description = "Notification timeout in ms, set to 0 to never automatical
ly time out";
          example = 0;
        };
        position = mkOption {
          type = enum ["bottom-right" "top-right"];
          default = "bottom-right";
          description = "Position of notifications";
          example = "top-right";
        };
        useNative = mkOption {
          type = enum ["always" "never" "not-focused"];
          default = "not-focused";
          description = "When should notifications be used";
          example = "always";
        };
        logLimit = mkOption {
          type = int;
          default = 50;
          description = ''
            The amount of notifications to save in the log until old ones are remo
ved.
            Set to 0 to disable log. Set to 0 to to disable notification log and 2
00 to
            never automatically remove old notifcations
          '';
        };
      };
      plugins = {
        # API plugins
        ChatInputButtonsAPI.enabled = mkBoolOption true "Chat Input API";
        CommandsAPI.enabled = mkBoolOption true "";
        DynamicImageModalAPI.enabled = mkBoolOption false "";
        MemberListDecoratorsAPI.enabled = mkBoolOption false "";
        MessageAccessoriesAPI.enabled = mkBoolOption true "";
        MessageDecorationsAPI.enabled = mkBoolOption false "";
        MessageEventsAPI.enabled = mkBoolOption false "";
        MessageUpdaterAPI.enabled = mkBoolOption false "";
        ServerListAPI.enabled = mkBoolOption false "";
        UserSettingsAPI.enabled = mkBoolOption true "";

        AccountPanelServerProfile = {
          enabled = mkEnableOption ''
            Right click your account panel in the bottom left to
            view your profile in the current server.
          '';
          prioritizeServerProfile = mkEnableOption ''
            Prioritize Server Profile when left clicking your account panel.
          '';
        };
        AllCallTimers = {
          enabled = mkEnableOption ''
            Add call timer to all users in a server voice channel.
          '';
          showWithoutHover = mkEnableOption ''
            Always show the timer without needing to hover.
          '';
          showRoleColor = mkEnableOption ''
            Show the users role color.
          '';
          trackSelf = mkEnableOption ''
            Also track yourself.
          '';
          showSeconds = mkEnableOption ''
            Show seconds in the timer.
          '';
          format = mkOption {
            type = enum ["stopwatch" "human"];
            default = "human";
            description = ''
              Compact or human readable format:
              - stopwatch: 30:23:00:42
              - human: 30d 23h 00m 42s
            '';
          };
          watchLargeGuilds = mkEnableOption ''
            Track users in large guild. Warning this may cause lag if your in a lo
t
            of guilds with active voice users.
          '';
        };
        AltKrispSwitch.enabled = mkEnableOption ''
          Makes the Noise Suppression Popout switch between None and Krisp instead
          of Krisp and Strandard.
        '';
        AlwaysAnimate = {
          enable = mkEnableOption ''
            Animates anything that can be animated.
          '';
        };
        AlwaysExpandRoles = {
          enabled = mkEnableOption "Always expand the role list in profile popouts
.";
          hideArrow = mkEnableOption "Hide Arrows.";
        };
        AlwaysTrust = {
          enabled = mkEnableOption ''
            Remove the untrusted domain and suspicious file popup.
          '';
          domain = mkEnableOption ''
            Remove the untrusted domain popup when opening links.
          '';
          file = mkEnableOption ''
            Remove the "Potentially Dangerous Download" popup when opening links.
          '';
        };
        AmITyping.enabled = mkEnableOption "Shows you if other people can see you 
typing.";
        Anammox = {
          enabled = mkEnableOption ''
            A microbial process that plays an important part in the nitrogen cycle
.
            Hide various discord nitro excusive features.
          '';
          dms = mkEnableOption "Remove shops above DMs list";
          billing = mkEnableOption "Remove billings settings";
          gift = mkEnableOption "Remove gift button";
          emojiList = mkEnableOption "Remove unavailable catagories from the emoji
 picker";
        };
        AnonymiseFileNames = {
          enabled = mkEnableOption "Anonymise uploaded file names";
          anonymiseByDefault = mkEnableOption "Whether to anonymise file names by 
default";
          method = mkOption {
            type = enum ["random characters" "consistant" "timestamp"];
            default = "random characters";
            apply = mkEquibopSelect {
              "random characters" = 0;
              "consistent" = 1;
              "timestamp" = 2;
            };
          };
          randomizedLength = mkOption {
            type = int;
            default = 7;
            description = "Random character length.";
          };
          consistent = mkOption {
            type = str;
            default = "image";
            description = "Consistant filename.";
            # doesn't appear to be an option you can change
            readOnly = true;
          };
        };
        AtSomeone.enabled = mkEnableOption "Mention someone randomly.";
        BANger = {
          enabled = mkEnableOption "Replaces the GIF i nthe ban dialogue with a cu
stom one.";
          source = mkOption {
            type = str;
            default = "";
            description = "Source to replace ban GIF with (video or GIF).";
            example = "https://i.imgur.com/wp5q52C.mp4";
          };
        };
        BannersEverywhere = {
          enabled = mkEnableOption "Display banners in the member list.";
          animate = mkEnableOption "Animate banners.";
        };
        BetterActivities = {
          enabled = mkEnableOption ''
            Shows activity icons in the member list and allows showing all activit
ies.
          '';
          memberList = mkEnableOption "Show activity icons in the member list";
          iconSize = mkOption {
            type = int;
            default = 15;
            description = "Size of the activity icons.";
          };
          specialFirst = mkEnableOption "Show special activities first (Currently 
Spotify and Twitch).";
          renderGifs = mkEnableOption "Allow rendering GIFs.";
          showAppDescription = mkEnableOption "Show application descriptions in th
e activity tooltip.";
          userPopout = mkEnableOption "Show all activities in the profile popout/s
idebar.";
          allActivitiesStyle = mkOption {
            type = enum ["corousel" "list"];
            default = "corousel";
            description = "Style for showing all activities";
          };
        };
        BetterAudioPlayer = {
          enabled = mkEnableOption ''
            Adds a spectograph and oscilloscope visualizer to audio attachment pla
yers.
          '';
          oscilloscope = mkEnableOption "Enable oscilloscope visualizer.";
          spectograph = mkEnableOption "Enable spectograph visualizer.";
          oscilloscopeSolidColor = mkEnableOption "Use colid color for oscilloscop
e.";
          oscilloscopeColor = mkOption {
            # not 100% sure if a hex color value can be set via json here
            type = rgbDecimal;
            default = "255, 255, 255";
            description = "RGB Color for the oscilloscope.";
            example = "10, 200, 130";
          };
          spectographSolidColor = mkEnableOption "Use solid color for spectograph.
";
          spectographColor = mkOption {
            type = rgbDecimal;
            default = "33, 150, 243";
            example = "10, 200, 130";
          };
        };
        BetterBanReasons = {
          enabled = mkEnableOption ''
            Create custom reasons to use in the Discord Ban modal, and/or
            show a test input by default instead of the options.
          '';
          reasons = mkOption {
            type = listOf str;
            default = [];
            description = "List of ban reasons";
            example = [
              "uses nix"
              "arch user"
            ];
          };
          textInputDefault = mkEnableOption ''
            Shows a text input instead of a select menu by default. (Equivalent to
 clicking the "Other" option).
          '';
        };
        BetterFolders = {
          enabled = mkEnableOption ''
            Shows server folders on dedicated sidebar and adds folder related impr
ovements.
          '';
          sidebar = mkEnableOption "Display servers from folder on dedicated sideb
ar.";
          sidebarAnim = mkEnableOption "Animate opening the folder sidebar.";
          closeAllFolders = mkEnableOption "Close all folders when selecting a ser
ver not in a folder.";
          closeOthers = mkEnableOption "Close other folders when opening a folder.
";
          forceOpen = mkEnableOption "Force a folder to open when switching to a s
erver of that folder.";
          keepIcons = mkEnableOption ''
            Keep showing guild icons in the primary guild bar folder when it's ope
n
            in the BetterFolders sidebar.
          '';
          showFoldersIcon = mkOption {
            type = enum ["never" "always" "when more than one folder is expanded"]
;
            default = "always";
            description = ''
              Show the folder icon above the folder guilds in the BetterFolders si
debar.
              Available options:
              - "never"
              - "always"
              - "when more than one folder is expanded"
            '';
            apply = mkEquibopSelect {
              "never" = 0;
              "always" = 1;
              "when more than one folder is expanded" = 2;
            };
          };
        };
        BetterGifAltText = mkEnableOption ''
          Change GIF alt text from simply being 'GIF' to containing the gif tags/f
ilename.
        '';
        BetterGifPicker = mkEnableOption "Makes the GIF picker open the favourite 
category by default";
        BetterInvites = mkEnableOption ''
          See invites expiration date, view inviter profile and preview discoverab
le servers before joining
          by clicking their name.
        '';
        BetterNotesBox = {
          enabled = mkEnableOption "Hide notes or disable spellcheck.";
          hide = mkEnableOption "Hide notes.";
          noSpellCheck = mkEnableOption "Disable spellcheck in notes";
        };
        BetterQuickReact = {
          enabled = mkEnableOption "Improves the quick react buttons in the messag
e context menu";
          frequentEmojis = mkEnableOption "Use frequently used emojis instead of f
avorite emojis";
          rows = mkOption {
            type = numbers.between 1 16;
            default = 2;
            description = "Rows of quick reactions to display. Number between 1-16
";
            example = 4;
          };
          columns = mkOption {
            type = numbers.between 1 12;
            default = 4;
            description = "Columns of quick reactions to display. Number betwen 1-
12";
            example = 6;
          };
          compactMode = mkEnableOption ''
            Scales the buttons to 75% of their original scale, whilst increasing t
he inner emoji to 125% scale.
            Emojis will be 93.75% of the original size. Reccomended to have a mini
mum of 5 columns.
          '';
          scroll = mkEnableOption "Enable scrolling the list of emojis";
        };
        BetterRoleContext = {
          enabled = mkEnableOption ''
            Adds options to copy role color / edit role / view role icon when righ
t clicking roles in
            in the user profile
          '';
          roleIconFileFormat = mkOption {
            type = enum ["webp" "png" "jpg"];
            default = "png";
            description = "File formate to use when viewing role icons";
          };
        };
        BetterRoleDot = {
          enabled = mkEnableOption ''
            Copy role colour on RoleDot (accessibility setting) click. Also allows
 using both
            RoleDot and coloured names simultaneously.
          '';
          bothStyles = mkEnableOption "Show both role dot and coloured names";
          copyRoleColorInProfilePopout = mkEnableOption "Allow click on role dot i
n profile popout to copy role color";
        };
        BetterSession = {
          enabled = mkEnableOption ''
            Enhances the sessions (devices) menu. Allows you to view exact timesta
mps, give each session a
            custom name, and receive notifications about new sessions.
          '';
          backgroundCheck = mkEnableOption ''
            Check for new sessions in the background, and display notifications wh
en they are detected.
          '';
          checkInterval = mkOption {
            type = int;
            default = 20;
            description = "How often to check for new sessions in the background (
if enabled), in minutes.";
          };
        };
        BetterSettings = {
          enabled = mkEnableOption "Enhances your settings-menu-opening experience
.";
          disableFade = mkEnableOption "Disable the crossfade animation.";
          organizeMenu = mkEnableOption "Organizes the settings cog context menu i
nto categories.";
          eagerLoad = mkEnableOption "Removes the loading delay when opening the m
enu for the first time.";
        };
        BetterUploadButton.enabled = mkEnableOption "Upload with a single click, o
pen menu with right click";
        BetterUserArea.enabled = mkEnableOption ''
          Reworks the user area styling to fit more buttons and overall look nicer
        '';
        BetterStreamPreview.enabled = mkEnableOption "Allows you to enlarge stream
 previews";
        BlockKeywords = {
          enabled = mkEnableOption ''
            Blocks messages containing specific user-defined keywords, as if the u
ser sending them was blocked.
          '';
          blockedWords = mkOption {
            type = str;
            default = "";
            description = "Comma-seperated list of words to block.";
            example = "arch,home-manager";
          };
          useRegex = mkEnableOption "Use each value as a regular expression when c
hecking message content (advanced)";
          caseSensitive = mkEnableOption "Whether to use a case sensitive search o
r not.";
          ignoreBlockedMessages = mkEnableOption "Completely ignores (recent) new 
messages bar";
        };
        BlockKrisp.enabled = mkEnableOption "Prevent Krist from loading";
        BlurNSFW = {
          enabled = mkEnableOption "Blur attachments in NSFW channels until hovere
d.";
          blurAmount = mkOption {
            type = int;
            default = 10;
            description = "Blur amount";
          };
        };
        BypassStatus = {
          enabled = mkEnableOption ''
            Still get notifications from specific sources when in do not disturb m
ode.
            Right-click on users/channels/guilds to set them to bypass do not dist
urb mode.
          '';
          guilds = mkOption {
            type = listOf str;
            default = [];
            description = ''
              Guilds to let bypass (notified when pinged anywhere in guild).
              List of comma seperated guild IDs.
            '';
            example = [
              "123451234512345123"
              "456456456456456456"
            ];
            apply = listToString ",";
          };
          channels = mkOption {
            type = listOf str;
            default = [];
            description = ''
              channels to let bypass (notified when pinged anywhere in channel).
              List of .
            '';
            example = [
              "123451234512345123"
              "456456456456456456"
            ];
            apply = listToString ",";
          };
          users = mkOption {
            type = listOf str;
            default = [];
            description = ''
              users to let bypass (notified when pinged anywhere in guild).
              List of comma seperated user IDs.
            '';
            example = [
              "123451234512345123"
              "456456456456456456"
            ];
            apply = listToString ",";
          };
          notificationSound = mkEnableOption "Whether the notification sound shoul
d be played";
          statusToUse = mkOption {
            type = enum ["dnd" "invisible" "idle"];
            default = "dnd";
            description = "Status to use for whitelist.";
          };
          allowOutsideOfDm = mkEnableOption ''
            Allow selected users to bypass status outside of DMs too
            (acts like a channel/guild bypass, but it's for all messages sent by t
he selected users).
          '';
        };
        CallTimer = {
          enabled = mkEnableOption "Adds a timer to vcs.";
          format = mkOption {
            type = enum ["human" "stopwatch"];
            default = "human";
            description = "The timer format.";
          };
        };
        ChannelBadges = {
          enabled = mkEnableOption "Adds badges to channels based on their type.";
          oneBadgePerChannel = mkEnableOption "Show only one badge per channel.";
          showTextBadge = mkEnableOption "Show Text badge";
          showVoiceBadge = mkEnableOption "Show Voice badge";
          showCategoryBadge = mkEnableOption "Show Category badge";
          showDirectoryBadge = mkEnableOption "Show Directory badge";
          showAnnouncementThreadBadge = mkEnableOption "Show Announcement Thread b
adge";
          showPublicThreadBadge = mkEnableOption "Show Public Thread badge";
          showPrivateThreadBadge = mkEnableOption "Show Private Thread badge";
          showStageBadge = mkEnableOption "Show Stage badge";
          showAnnouncementBadge = mkEnableOption "Show Announcement badge";
          showForumBadge = mkEnableOption "Show Forum badge";
          showMediaBadge = mkEnableOption "Show Media badge";
          showNSFWBadge = mkEnableOption "Show NSFW badge";
          showLockedBadge = mkEnableOption "Show Locked badge";
          showRulesBadge = mkEnableOption "Show Rules badge";
          showUnknownBadge = mkEnableOption "Show Unknown badge";
          textBadgeLabel = mkLabelOption "Text";
          voiceBadgeLabel = mkLabelOption "Voice";
          categoryBadgeLabel = mkLabelOption "Category";
          announcementBadgeLabel = mkLabelOption "News";
          announcementThreadBadgeLabel = mkLabelOption "News Thread";
          publicThreadBadgeLabel = mkLabelOption "Thread";
          privateThreadBadgeLabel = mkLabelOption "Private Thread";
          stageBadgeLabel = mkLabelOption "Stage";
          directoryBadgeLabel = mkLabelOption "Directory";
          forumBadgeLabel = mkLabelOption "Forum";
          mediaBadgeLabel = mkLabelOption "Media";
          nsfwBadgeLabel = mkLabelOption "NSFW";
          lockedBadgeLabel = mkLabelOption "Locked";
          rulesBadgeLabel = mkLabelOption "Rules";
          unknownBadgeLabel = mkLabelOption "Unknown";
          lockedBadgeColor = mkHexColorOption "Locked badge";
          rulesBadgeColor = mkHexColorOption "Rules badge";
          unknownBadgeColor = mkHexColorOption "Unknown badge";
          nsfwBadgeColor = mkHexColorOption "NSFW badge";
          mediaBadgeColor = mkHexColorOption "Media badge";
          forumBadgeColor = mkHexColorOption "Forum badge";
          directoryBadgeColor = mkHexColorOption "Directory badge";
          stageBadgeColor = mkHexColorOption "Stage badge";
          privateThreadBadgeColor = mkHexColorOption "Private Thread badge";
          publicThreadBadgeColor = mkHexColorOption "Public Thread badge";
          announcementThreadBadgeColor = mkHexColorOption "Announcement Thread bad
ge";
          announcementBadgeColor = mkHexColorOption "Announcement badge";
          categoryBadgeColor = mkHexColorOption "Category badge";
          voiceBadgeColor = mkHexColorOption "Voice badge";
          textBadgeColor = mkHexColorOption "Text Badge";
        };
        # doesn't seem to work for me. May require window decorations?
        ChannelTabs.enabled = mkEnableOption ''
          Group our commonly visited channels in tabs. Warning: this doesnt appear
 to be working.
        '';
        CharacterCounter = {
          enabled = mkEnableOption "Adds a character counter to the chat input.";
          colorEffects = mkEnableOption "Turn on or off color effects for getting 
close to the character limit";
          position = mkEnableOption "Move the character counter to the left side o
f the chat input";
        };
        CleanChannelName.enabled = mkEnableOption "Remove all emoji and decor from
 channel names";
        ClearURLs.enabled = mkEnableOption "Remove tracking garbage from URLs";
        ClientSideBlock = {
          enabled = mkEnableOption "Allows you to locally hide almost all content 
from any user";
          usersToBlock = mkOption {
            type = listOf str;
            default = [];
            description = "List of User IDs to block";
            example = [
              "123456789"
              "987654321"
            ];
            apply = listToString ", ";
          };
          hideBlockedUser = mkEnableOption "Should blocked users also be hidden ev
erywhere.";
          hideBlockedMessages = mkEnableOption "Should messages from blocked users
 be hidden fully.";
          hideEmptyRoles = mkEnableOption "Should role headers be hidden if all of
 their member are blocked.";
          blockedReplyDisplay = mkOption {
            type = enum ["displayText" "hideReply"];
            default = "displayText";
            description = ''
              What should display instead of the message when someone replies to s
omeone you have hidden.
              - "displayText": Display text saying a hidden message was replied to
.
              - "hideReply": Literally nothing
            '';
          };
          guildBlackList = mkOption {
            type = listOf str;
            default = [];
            description = "List of guild IDs to disable functionality in";
            apply = listToString ", ";
          };
          guildWhiteList = mkOption {
            type = listOf str;
            default = [];
            description = "List of guild IDs to enable functionality in";
            apply = listToString ", ";
          };
        };
        ClientTheme = {
          enabled = mkEnableOption "Recreation of the old client theme experiment.
 Add color to your Discord client theme";
          color = mkOption {
            type = strMatching "[[:xdigit:]]{6}";
            description = "Themes Color";
            default = "282828";
          };
        };
        ColorSighted.enabled = mkEnableOption "Removes the colorblind-friendly ico
ns from statuses, just like 2015-2017 Discord";
        CommandPalette = {
          enabled = mkEnableOption "Allows you to navigate the UI with a keyboard.
";
          hotkey = mkOption {
            # TODO: Regex this
            type = listOf str;
            default = [
              "control"
              "shift"
              "p"
            ];
            description = "HotKey to toggle the command palette.";
            example = [
              "control"
              "h"
            ];
          };
        };
        ConsoleJanitor = {
          enabled = mkEnableOption "Disables annoying console messages/errors";
          disableLoggers = mkEnableOption "Disables Discord loggers";
          disableSpotifyLoggers = mkEnableOption "Disable the Spotify logger, whic
h leaks account information and access token";
          whitlistedLoggers = mkOption {
            type = listOf str;
            default = [
              "GatewaySocket"
              "Routing/Utils"
            ];
            description = "List of loggers to allow even if others are hidden.";
            apply = listToString "; ";
          };
        };
        ConsoleShortcuts.enabled = mkEnableOption ''
          Adds shorter Aliases for many things on the window. Run 'shortcutList' f
or a list.
        '';
        CopyEmojiMarkdown = {
          enabled = mkEnableOption "Allows you to copy emojis as formatted string 
(<:blobcatcozy:1026533070955872337>).";
          copyUnicode = mkEnableOption "Copy the raw unicode character instead of 
:name: for default emojis.";
        };
        CopyFileContents.enabled = mkEnableOption "Adds a button to text file atta
chments to copy their contents.";
        CopyUserMention.enabled = mkEnableOption ''
          Adds a button to copy user's mention on the user context menu, works bes
t with ValidUser.
        '';
        CopyUserURLs.enabled = mkEnableOption "Adds a 'Copy User URL' option to th
e user context menu.";
        CrashHandler = {
          enabled = mkBoolOption true "Utility for handling and possibly recoverin
g from chrashes without restart.";
          attemptToPreventCrashes = mkBoolOption true "Whether to attempt to preve
nt Discord crashes.";
          attemptToNavigateToHome = mkEnableOption "Whether to attempt to navigate
 to the home when preventing Discord crashes.";
        };
        CtrlEnterSend = {
          enabled = mkEnableOption "Use Ctrl+Enter to send messages (customizable)
.";
          submitRule = mkOption {
            type = enum ["ctrl+enter" "shift+enter" "enter"];
            default = "ctrl+enter";
            description = ''
              The way to send a messages.
              Available options:
              - "ctrl+enter" (Enter of Shift+Enter for new line) (cmd+enter on mac
OS)
              - "shift+enter" (Enter for a new Line)
              - "enter" (Shift+Enter for new line; Discord default)
            '';
          };
          sendMessageInTheMiddleOfACodeBlock = mkEnableOption "Whether to send a m
essage in the middle of a code block.";
        };
        CustomIdle = {
          enabled = mkEnableOption "Allows you to set the time before Discord goes
 idle (or disable auto-idle)";
          idleTimeout = {
            type = numbers.between 0 60;
            default = 20;
            description = "Minutes before Discord goes idle (0 to disable auto-idl
e). 0.0 - 60.0";
          };
          remainInIdle = mkEnableOption "When you come back to Discord, remain idl
e until you confirm you want to go online";
        };
        CustomSounds.enabled = mkEnableOption "Replace Discord's sounds with your 
own, custom sounds must be defined via client";
        CustomTimestamps = let
          mkTimestampOption = default: description:
            mkOption {
              type = str;
              inherit default description;
            };
        in {
          enabled = mkEnableOption ''
            Custom timestamps on mesages and tooltips.
            See <https://momentjs.com/docs/#/displaying/format/> for documentation
 on formatting.
          '';
          cozyFormat = mkTimestampOption "[calander]" "Time format to use in messa
ges on cozy mode.";
          compactFormat = mkTimestampOption "LT" "Time format on compact mode and 
hovering messages.";
          tooltipFormat = mkTimestampOption "LLLL - [relative]" "Time format to us
e on tooltips.";
          sameDayFormat = mkTimestampOption "HH:mm:ss" "[calander] format for toda
y.";
          lastDayFormat = mkTimestampOption "[yesterday] HH:mm:ss" "[calander] for
mat for yesterday.";
          lastWeekFormat = mkTimestampOption "ddd DD.MM.YYYY HH:mm:ss" "[calander]
 format for last week.";
          sameElseFormat = mkTimestampOption "ddd DD.MM.YYYY HH:mm:ss" "[calander]
 format for older dates.";
        };
        # why weebs, why
        CuteAnimeBoys.enabled = mkEnableOption "Add a command to send cute anime b
oys in the chat";
        CuteNekos.enabled = mkEnableOption "Send Nekos to others";
        CutePats.enabled = mkEnableOption "Sending head pats.";
        DeadMembers.enabled = mkEnableOption "Shows when the sender of a message h
as left the guild.";
        Dearrow = {
          enabled = mkEnableOption "Makes YouTube embed titles and thumbnails less
 sensationalist, powered by Dearrow.";
          hideButton = mkEnableOption "Hides the Dearrow button from Youtube embed
s.";
          replaceElements = mkOption {
            type = enum ["everything" "titles" "thumbnails"];
            default = "everything";
            description = ''
              Choose which elements of the embed will be replaced.
              Available options:
              - "everything"
              - "titles"
              - "thumbnails"
            '';
            apply = mkEquibopSelect {
              "everything" = 0;
              "titles" = 1;
              "thumbnails" = 2;
            };
          };
          dearrowByDefault = mkEnableOption "Dearrow videos automatically";
        };
        DecodeBase64 = {
          enabled = mkEnableOption "Decode base64 content of any message and copy 
the decoded content.";
          clickMethod = mkOption {
            type = enum ["Left" "Right"];
            default = "Left";
          };
        };
      };
    };
  };
  config = mkIf cfg.enable {
    # test file until module is complete
    xdg.configFile."equibop/test.json".text = builtins.toJSON cfg.settings;
  };
}

{
  lib,
  pkgs,
  config,
  ...
}: let
  inherit (lib) mkIf mkOption mkEnableOption
 mkPackageOption;
  inherit (lib.types) listOf str int enum nu
mbers oneOf bool strMatching;
  mkBoolOption = default: description:
    mkOption {
      type = bool;
      inherit default description;
    };

  mkLabelOption = default:
    mkOption {
      type = str;
      inherit default;
      description = "${default} label";
    };

  mkEquibopSelect = attr: v: attr.${v};
  listToString = sep: list: builtins.concatS
tringsSep sep list;

  rgbValue = ''([1-9]?[0-9]|1[0-9]{2}|2[0-4]
[0-9]|25[0-5])'';
  rgbDecimal = strMatching ''${rgbValue}, *$
{rgbValue}, *${rgbValue}'';
  hexColor = strMatching "#[[:xdigit:]]{6}";

  mkHexColorOption = name:
    mkOption {
      type = oneOf [hexColor (enum [""])];
      default = "";
      description = "${name} color in hex fo
rmat";
      example = "#ea6962";
    };

  cfg = config.programs.equicord;
in {
  options.programs.equicord = {
    enable = mkEnableOption "Enable Equicord
, for of Vencord";
    package = mkPackageOption pkgs "equibop"
 {
      default = "equibop";
      example = pkgs.equicord;
    };
    settings = {
      autoUpdate = mkEnableOption "Enable au
to updating for Equicord" // {default = true
;};
      autoUpdateNotification = mkEnableOptio
n "Notify when Equicord automatically update
s";
      useQuickCss = mkEnableOption "Enable c
ustom CSS";
      themeLinks = mkOption {
        type = listOf str;
        default = [];
        description = "List of Discord CSS t
hemes to install via link";
        example = ["https://refact0r.github.
io/midnight-discord/midnight.css"];
      };
      enabledThemes = mkOption {
        type = listOf str;
        default = [];
        description = "List of themes to ena
ble from XDG_CONFIG_HOME/equibop/themes";
      };
      enableReactDevtools = mkEnableOption "
Enable react dev tools extension";
      frameless = mkEnableOption "Enable fra
meless mode";
      transparent = mkEnableOption "Enable t
ransparent mode. Requires a theme that suppo
rts transparency";
      disableMinSize = mkEnableOption "Disab
le minimum window size";
      notifications = {
        timeout = mkOption {
          type = int;
          default = 5000;
          description = "Notification timeou
t in ms, set to 0 to never automatically tim
e out";
          example = 0;
        };
        position = mkOption {
          type = enum ["bottom-right" "top-r
ight"];
          default = "bottom-right";
          description = "Position of notific
ations";
          example = "top-right";
        };
        useNative = mkOption {
          type = enum ["always" "never" "not
-focused"];
          default = "not-focused";
          description = "When should notific
ations be used";
          example = "always";
        };
        logLimit = mkOption {
          type = int;
          default = 50;
          description = ''
            The amount of notifications to s
ave in the log until old ones are removed.
            Set to 0 to disable log. Set to 
0 to to disable notification log and 200 to
            never automatically remove old n
otifcations
          '';
        };
      };
      plugins = {
        # API plugins
        ChatInputButtonsAPI.enabled = mkBool
Option true "Chat Input API";
        CommandsAPI.enabled = mkBoolOption t
rue "";
        DynamicImageModalAPI.enabled = mkBoo
lOption false "";
        MemberListDecoratorsAPI.enabled = mk
BoolOption false "";
        MessageAccessoriesAPI.enabled = mkBo
olOption true "";
        MessageDecorationsAPI.enabled = mkBo
olOption false "";
        MessageEventsAPI.enabled = mkBoolOpt
ion false "";
        MessageUpdaterAPI.enabled = mkBoolOp
tion false "";
        ServerListAPI.enabled = mkBoolOption
 false "";
        UserSettingsAPI.enabled = mkBoolOpti
on true "";

        AccountPanelServerProfile = {
          enabled = mkEnableOption ''
            Right click your account panel i
n the bottom left to
            view your profile in the current
 server.
          '';
          prioritizeServerProfile = mkEnable
Option ''
            Prioritize Server Profile when l
eft clicking your account panel.
          '';
        };
        AllCallTimers = {
          enabled = mkEnableOption ''
            Add call timer to all users in a
 server voice channel.
          '';
          showWithoutHover = mkEnableOption 
''
            Always show the timer without ne
eding to hover.
          '';
          showRoleColor = mkEnableOption ''
            Show the users role color.
          '';
          trackSelf = mkEnableOption ''
            Also track yourself.
          '';
          showSeconds = mkEnableOption ''
            Show seconds in the timer.
          '';
          format = mkOption {
            type = enum ["stopwatch" "human"
];
            default = "human";
            description = ''
              Compact or human readable form
at:
              - stopwatch: 30:23:00:42
              - human: 30d 23h 00m 42s
            '';
          };
          watchLargeGuilds = mkEnableOption 
''
            Track users in large guild. Warn
ing this may cause lag if your in a lot
            of guilds with active voice user
s.
          '';
        };
        AltKrispSwitch.enabled = mkEnableOpt
ion ''
          Makes the Noise Suppression Popout
 switch between None and Krisp instead
          of Krisp and Strandard.
        '';
        AlwaysAnimate = {
          enable = mkEnableOption ''
            Animates anything that can be an
imated.
          '';
        };
        AlwaysExpandRoles = {
          enabled = mkEnableOption "Always e
xpand the role list in profile popouts.";
          hideArrow = mkEnableOption "Hide A
rrows.";
        };
        AlwaysTrust = {
          enabled = mkEnableOption ''
            Remove the untrusted domain and 
suspicious file popup.
          '';
          domain = mkEnableOption ''
            Remove the untrusted domain popu
p when opening links.
          '';
          file = mkEnableOption ''
            Remove the "Potentially Dangerou
s Download" popup when opening links.
          '';
        };
        AmITyping.enabled = mkEnableOption "
Shows you if other people can see you typing
.";
        Anammox = {
          enabled = mkEnableOption ''
            A microbial process that plays a
n important part in the nitrogen cycle.
            Hide various discord nitro excus
ive features.
          '';
          dms = mkEnableOption "Remove shops
 above DMs list";
          billing = mkEnableOption "Remove b
illings settings";
          gift = mkEnableOption "Remove gift
 button";
          emojiList = mkEnableOption "Remove
 unavailable catagories from the emoji picke
r";
        };
        AnonymiseFileNames = {
          enabled = mkEnableOption "Anonymis
e uploaded file names";
          anonymiseByDefault = mkEnableOptio
n "Whether to anonymise file names by defaul
t";
          method = mkOption {
            type = enum ["random characters"
 "consistant" "timestamp"];
            default = "random characters";
            apply = mkEquibopSelect {
              "random characters" = 0;
              "consistent" = 1;
              "timestamp" = 2;
            };
          };
          randomizedLength = mkOption {
            type = int;
            default = 7;
            description = "Random character 
length.";
          };
          consistent = mkOption {
            type = str;
            default = "image";
            description = "Consistant filena
me.";
            # doesn't appear to be an option
 you can change
            readOnly = true;
          };
        };
        AtSomeone.enabled = mkEnableOption "
Mention someone randomly.";
        BANger = {
          enabled = mkEnableOption "Replaces
 the GIF i nthe ban dialogue with a custom o
ne.";
          source = mkOption {
            type = str;
            default = "";
            description = "Source to replace
 ban GIF with (video or GIF).";
            example = "https://i.imgur.com/w
p5q52C.mp4";
          };
        };
        BannersEverywhere = {
          enabled = mkEnableOption "Display 
banners in the member list.";
          animate = mkEnableOption "Animate 
banners.";
        };
        BetterActivities = {
          enabled = mkEnableOption ''
            Shows activity icons in the memb
er list and allows showing all activities.
          '';
          memberList = mkEnableOption "Show 
activity icons in the member list";
          iconSize = mkOption {
            type = int;
            default = 15;
            description = "Size of the activ
ity icons.";
          };
          specialFirst = mkEnableOption "Sho
w special activities first (Currently Spotif
y and Twitch).";
          renderGifs = mkEnableOption "Allow
 rendering GIFs.";
          showAppDescription = mkEnableOptio
n "Show application descriptions in the acti
vity tooltip.";
          userPopout = mkEnableOption "Show 
all activities in the profile popout/sidebar
.";
          allActivitiesStyle = mkOption {
            type = enum ["corousel" "list"];
            default = "corousel";
            description = "Style for showing
 all activities";
          };
        };
        BetterAudioPlayer = {
          enabled = mkEnableOption ''
            Adds a spectograph and oscillosc
ope visualizer to audio attachment players.
          '';
          oscilloscope = mkEnableOption "Ena
ble oscilloscope visualizer.";
          spectograph = mkEnableOption "Enab
le spectograph visualizer.";
          oscilloscopeSolidColor = mkEnableO
ption "Use colid color for oscilloscope.";
          oscilloscopeColor = mkOption {
            # not 100% sure if a hex color v
alue can be set via json here
            type = rgbDecimal;
            default = "255, 255, 255";
            description = "RGB Color for the
 oscilloscope.";
            example = "10, 200, 130";
          };
          spectographSolidColor = mkEnableOp
tion "Use solid color for spectograph.";
          spectographColor = mkOption {
            type = rgbDecimal;
            default = "33, 150, 243";
            example = "10, 200, 130";
          };
        };
        BetterBanReasons = {
          enabled = mkEnableOption ''
            Create custom reasons to use in 
the Discord Ban modal, and/or
            show a test input by default ins
tead of the options.
          '';
          reasons = mkOption {
            type = listOf str;
            default = [];
            description = "List of ban reaso
ns";
            example = [
              "uses nix"
              "arch user"
            ];
          };
          textInputDefault = mkEnableOption 
''
            Shows a text input instead of a 
select menu by default. (Equivalent to click
ing the "Other" option).
          '';
        };
        BetterFolders = {
          enabled = mkEnableOption ''
            Shows server folders on dedicate
d sidebar and adds folder related improvemen
ts.
          '';
          sidebar = mkEnableOption "Display 
servers from folder on dedicated sidebar.";
          sidebarAnim = mkEnableOption "Anim
ate opening the folder sidebar.";
          closeAllFolders = mkEnableOption "
Close all folders when selecting a server no
t in a folder.";
          closeOthers = mkEnableOption "Clos
e other folders when opening a folder.";
          forceOpen = mkEnableOption "Force 
a folder to open when switching to a server 
of that folder.";
          keepIcons = mkEnableOption ''
            Keep showing guild icons in the 
primary guild bar folder when it's open
            in the BetterFolders sidebar.
          '';
          showFoldersIcon = mkOption {
            type = enum ["never" "always" "w
hen more than one folder is expanded"];
            default = "always";
            description = ''
              Show the folder icon above the
 folder guilds in the BetterFolders sidebar.
              Available options:
              - "never"
              - "always"
              - "when more than one folder i
s expanded"
            '';
            apply = mkEquibopSelect {
              "never" = 0;
              "always" = 1;
              "when more than one folder is 
expanded" = 2;
            };
          };
        };
        BetterGifAltText = mkEnableOption ''
          Change GIF alt text from simply be
ing 'GIF' to containing the gif tags/filenam
e.
        '';
        BetterGifPicker = mkEnableOption "Ma
kes the GIF picker open the favourite catego
ry by default";
        BetterInvites = mkEnableOption ''
          See invites expiration date, view 
inviter profile and preview discoverable ser
vers before joining
          by clicking their name.
        '';
        BetterNotesBox = {
          enabled = mkEnableOption "Hide not
es or disable spellcheck.";
          hide = mkEnableOption "Hide notes.
";
          noSpellCheck = mkEnableOption "Dis
able spellcheck in notes";
        };
        BetterQuickReact = {
          enabled = mkEnableOption "Improves
 the quick react buttons in the message cont
ext menu";
          frequentEmojis = mkEnableOption "U
se frequently used emojis instead of favorit
e emojis";
          rows = mkOption {
            type = numbers.between 1 16;
            default = 2;
            description = "Rows of quick rea
ctions to display. Number between 1-16";
            example = 4;
          };
          columns = mkOption {
            type = numbers.between 1 12;
            default = 4;
            description = "Columns of quick 
reactions to display. Number betwen 1-12";
            example = 6;
          };
          compactMode = mkEnableOption ''
            Scales the buttons to 75% of the
ir original scale, whilst increasing the inn
er emoji to 125% scale.
            Emojis will be 93.75% of the ori
ginal size. Reccomended to have a minimum of
 5 columns.
          '';
          scroll = mkEnableOption "Enable sc
rolling the list of emojis";
        };
        BetterRoleContext = {
          enabled = mkEnableOption ''
            Adds options to copy role color 
/ edit role / view role icon when right clic
king roles in
            in the user profile
          '';
          roleIconFileFormat = mkOption {
            type = enum ["webp" "png" "jpg"]
;
            default = "png";
            description = "File formate to u
se when viewing role icons";
          };
        };
        BetterRoleDot = {
          enabled = mkEnableOption ''
            Copy role colour on RoleDot (acc
essibility setting) click. Also allows using
 both
            RoleDot and coloured names simul
taneously.
          '';
          bothStyles = mkEnableOption "Show 
both role dot and coloured names";
          copyRoleColorInProfilePopout = mkE
nableOption "Allow click on role dot in prof
ile popout to copy role color";
        };
        BetterSession = {
          enabled = mkEnableOption ''
            Enhances the sessions (devices) 
menu. Allows you to view exact timestamps, g
ive each session a
            custom name, and receive notific
ations about new sessions.
          '';
          backgroundCheck = mkEnableOption '
'
            Check for new sessions in the ba
ckground, and display notifications when the
y are detected.
          '';
          checkInterval = mkOption {
            type = int;
            default = 20;
            description = "How often to chec
k for new sessions in the background (if ena
bled), in minutes.";
          };
        };
        BetterSettings = {
          enabled = mkEnableOption "Enhances
 your settings-menu-opening experience.";
          disableFade = mkEnableOption "Disa
ble the crossfade animation.";
          organizeMenu = mkEnableOption "Org
anizes the settings cog context menu into ca
tegories.";
          eagerLoad = mkEnableOption "Remove
s the loading delay when opening the menu fo
r the first time.";
        };
        BetterUploadButton.enabled = mkEnabl
eOption "Upload with a single click, open me
nu with right click";
        BetterUserArea.enabled = mkEnableOpt
ion ''
          Reworks the user area styling to f
it more buttons and overall look nicer
        '';
        BetterStreamPreview.enabled = mkEnab
leOption "Allows you to enlarge stream previ
ews";
        BlockKeywords = {
          enabled = mkEnableOption ''
            Blocks messages containing speci
fic user-defined keywords, as if the user se
nding them was blocked.
          '';
          blockedWords = mkOption {
            type = str;
            default = "";
            description = "Comma-seperated l
ist of words to block.";
            example = "arch,home-manager";
          };
          useRegex = mkEnableOption "Use eac
h value as a regular expression when checkin
g message content (advanced)";
          caseSensitive = mkEnableOption "Wh
ether to use a case sensitive search or not.
";
          ignoreBlockedMessages = mkEnableOp
tion "Completely ignores (recent) new messag
es bar";
        };
        BlockKrisp.enabled = mkEnableOption 
"Prevent Krist from loading";
        BlurNSFW = {
          enabled = mkEnableOption "Blur att
achments in NSFW channels until hovered.";
          blurAmount = mkOption {
            type = int;
            default = 10;
            description = "Blur amount";
          };
        };
        BypassStatus = {
          enabled = mkEnableOption ''
            Still get notifications from spe
cific sources when in do not disturb mode.
            Right-click on users/channels/gu
ilds to set them to bypass do not disturb mo
de.
          '';
          guilds = mkOption {
            type = listOf str;
            default = [];
            description = ''
              Guilds to let bypass (notified
 when pinged anywhere in guild).
              List of comma seperated guild 
IDs.
            '';
            example = [
              "123451234512345123"
              "456456456456456456"
            ];
            apply = listToString ",";
          };
          channels = mkOption {
            type = listOf str;
            default = [];
            description = ''
              channels to let bypass (notifi
ed when pinged anywhere in channel).
              List of .
            '';
            example = [
              "123451234512345123"
              "456456456456456456"
            ];
            apply = listToString ",";
          };
          users = mkOption {
            type = listOf str;
            default = [];
            description = ''
              users to let bypass (notified 
when pinged anywhere in guild).
              List of comma seperated user I
Ds.
            '';
            example = [
              "123451234512345123"
              "456456456456456456"
            ];
            apply = listToString ",";
          };
          notificationSound = mkEnableOption
 "Whether the notification sound should be p
layed";
          statusToUse = mkOption {
            type = enum ["dnd" "invisible" "
idle"];
            default = "dnd";
            description = "Status to use for
 whitelist.";
          };
          allowOutsideOfDm = mkEnableOption 
''
            Allow selected users to bypass s
tatus outside of DMs too
            (acts like a channel/guild bypas
s, but it's for all messages sent by the sel
ected users).
          '';
        };
        CallTimer = {
          enabled = mkEnableOption "Adds a t
imer to vcs.";
          format = mkOption {
            type = enum ["human" "stopwatch"
];
            default = "human";
            description = "The timer format.
";
          };
        };
        ChannelBadges = {
          enabled = mkEnableOption "Adds bad
ges to channels based on their type.";
          oneBadgePerChannel = mkEnableOptio
n "Show only one badge per channel.";
          showTextBadge = mkEnableOption "Sh
ow Text badge";
          showVoiceBadge = mkEnableOption "S
how Voice badge";
          showCategoryBadge = mkEnableOption
 "Show Category badge";
          showDirectoryBadge = mkEnableOptio
n "Show Directory badge";
          showAnnouncementThreadBadge = mkEn
ableOption "Show Announcement Thread badge";
          showPublicThreadBadge = mkEnableOp
tion "Show Public Thread badge";
          showPrivateThreadBadge = mkEnableO
ption "Show Private Thread badge";
          showStageBadge = mkEnableOption "S
how Stage badge";
          showAnnouncementBadge = mkEnableOp
tion "Show Announcement badge";
          showForumBadge = mkEnableOption "S
how Forum badge";
          showMediaBadge = mkEnableOption "S
how Media badge";
          showNSFWBadge = mkEnableOption "Sh
ow NSFW badge";
          showLockedBadge = mkEnableOption "
Show Locked badge";
          showRulesBadge = mkEnableOption "S
how Rules badge";
          showUnknownBadge = mkEnableOption 
"Show Unknown badge";
          textBadgeLabel = mkLabelOption "Te
xt";
          voiceBadgeLabel = mkLabelOption "V
oice";
          categoryBadgeLabel = mkLabelOption
 "Category";
          announcementBadgeLabel = mkLabelOp
tion "News";
          announcementThreadBadgeLabel = mkL
abelOption "News Thread";
          publicThreadBadgeLabel = mkLabelOp
tion "Thread";
          privateThreadBadgeLabel = mkLabelO
ption "Private Thread";
          stageBadgeLabel = mkLabelOption "S
tage";
          directoryBadgeLabel = mkLabelOptio
n "Directory";
          forumBadgeLabel = mkLabelOption "F
orum";
          mediaBadgeLabel = mkLabelOption "M
edia";
          nsfwBadgeLabel = mkLabelOption "NS
FW";
          lockedBadgeLabel = mkLabelOption "
Locked";
          rulesBadgeLabel = mkLabelOption "R
ules";
          unknownBadgeLabel = mkLabelOption 
"Unknown";
          lockedBadgeColor = mkHexColorOptio
n "Locked badge";
          rulesBadgeColor = mkHexColorOption
 "Rules badge";
          unknownBadgeColor = mkHexColorOpti
on "Unknown badge";
          nsfwBadgeColor = mkHexColorOption 
"NSFW badge";
          mediaBadgeColor = mkHexColorOption
 "Media badge";
          forumBadgeColor = mkHexColorOption
 "Forum badge";
          directoryBadgeColor = mkHexColorOp
tion "Directory badge";
          stageBadgeColor = mkHexColorOption
 "Stage badge";
          privateThreadBadgeColor = mkHexCol
orOption "Private Thread badge";
          publicThreadBadgeColor = mkHexColo
rOption "Public Thread badge";
          announcementThreadBadgeColor = mkH
exColorOption "Announcement Thread badge";
          announcementBadgeColor = mkHexColo
rOption "Announcement badge";
          categoryBadgeColor = mkHexColorOpt
ion "Category badge";
          voiceBadgeColor = mkHexColorOption
 "Voice badge";
          textBadgeColor = mkHexColorOption 
"Text Badge";
        };
        # doesn't seem to work for me. May r
equire window decorations?
        ChannelTabs.enabled = mkEnableOption
 ''
          Group our commonly visited channel
s in tabs. Warning: this doesnt appear to be
 working.
        '';
        CharacterCounter = {
          enabled = mkEnableOption "Adds a c
haracter counter to the chat input.";
          colorEffects = mkEnableOption "Tur
n on or off color effects for getting close 
to the character limit";
          position = mkEnableOption "Move th
e character counter to the left side of the 
chat input";
        };
        CleanChannelName.enabled = mkEnableO
ption "Remove all emoji and decor from chann
el names";
        ClearURLs.enabled = mkEnableOption "
Remove tracking garbage from URLs";
        ClientSideBlock = {
          enabled = mkEnableOption "Allows y
ou to locally hide almost all content from a
ny user";
          usersToBlock = mkOption {
            type = listOf str;
            default = [];
            description = "List of User IDs 
to block";
            example = [
              "123456789"
              "987654321"
            ];
            apply = listToString ", ";
          };
          hideBlockedUser = mkEnableOption "
Should blocked users also be hidden everywhe
re.";
          hideBlockedMessages = mkEnableOpti
on "Should messages from blocked users be hi
dden fully.";
          hideEmptyRoles = mkEnableOption "S
hould role headers be hidden if all of their
 member are blocked.";
          blockedReplyDisplay = mkOption {
            type = enum ["displayText" "hide
Reply"];
            default = "displayText";
            description = ''
              What should display instead of
 the message when someone replies to someone
 you have hidden.
              - "displayText": Display text 
saying a hidden message was replied to.
              - "hideReply": Literally nothi
ng
            '';
          };
          guildBlackList = mkOption {
            type = listOf str;
            default = [];
            description = "List of guild IDs
 to disable functionality in";
            apply = listToString ", ";
          };
          guildWhiteList = mkOption {
            type = listOf str;
            default = [];
            description = "List of guild IDs
 to enable functionality in";
            apply = listToString ", ";
          };
        };
        ClientTheme = {
          enabled = mkEnableOption "Recreati
on of the old client theme experiment. Add c
olor to your Discord client theme";
          color = mkOption {
            type = strMatching "[[:xdigit:]]
{6}";
            description = "Themes Color";
            default = "282828";
          };
        };
        ColorSighted.enabled = mkEnableOptio
n "Removes the colorblind-friendly icons fro
m statuses, just like 2015-2017 Discord";
        CommandPalette = {
          enabled = mkEnableOption "Allows y
ou to navigate the UI with a keyboard.";
          hotkey = mkOption {
            # TODO: Regex this
            type = listOf str;
            default = [
              "control"
              "shift"
              "p"
            ];
            description = "HotKey to toggle 
the command palette.";
            example = [
              "control"
              "h"
            ];
          };
        };
        ConsoleJanitor = {
          enabled = mkEnableOption "Disables
 annoying console messages/errors";
          disableLoggers = mkEnableOption "D
isables Discord loggers";
          disableSpotifyLoggers = mkEnableOp
tion "Disable the Spotify logger, which leak
s account information and access token";
          whitlistedLoggers = mkOption {
            type = listOf str;
            default = [
              "GatewaySocket"
              "Routing/Utils"
            ];
            description = "List of loggers t
o allow even if others are hidden.";
            apply = listToString "; ";
          };
        };
        ConsoleShortcuts.enabled = mkEnableO
ption ''
          Adds shorter Aliases for many thin
gs on the window. Run 'shortcutList' for a l
ist.
        '';
        CopyEmojiMarkdown = {
          enabled = mkEnableOption "Allows y
ou to copy emojis as formatted string (<:blo
bcatcozy:1026533070955872337>).";
          copyUnicode = mkEnableOption "Copy
 the raw unicode character instead of :name:
 for default emojis.";
        };
        CopyFileContents.enabled = mkEnableO
ption "Adds a button to text file attachment
s to copy their contents.";
        CopyUserMention.enabled = mkEnableOp
tion ''
          Adds a button to copy user's menti
on on the user context menu, works best with
 ValidUser.
        '';
        CopyUserURLs.enabled = mkEnableOptio
n "Adds a 'Copy User URL' option to the user
 context menu.";
        CrashHandler = {
          enabled = mkBoolOption true "Utili
ty for handling and possibly recovering from
 chrashes without restart.";
          attemptToPreventCrashes = mkBoolOp
tion true "Whether to attempt to prevent Dis
cord crashes.";
          attemptToNavigateToHome = mkEnable
Option "Whether to attempt to navigate to th
e home when preventing Discord crashes.";
        };
        CtrlEnterSend = {
          enabled = mkEnableOption "Use Ctrl
+Enter to send messages (customizable).";
          submitRule = mkOption {
            type = enum ["ctrl+enter" "shift
+enter" "enter"];
            default = "ctrl+enter";
            description = ''
              The way to send a messages.
              Available options:
              - "ctrl+enter" (Enter of Shift
+Enter for new line) (cmd+enter on macOS)
              - "shift+enter" (Enter for a n
ew Line)
              - "enter" (Shift+Enter for new
 line; Discord default)
            '';
          };
          sendMessageInTheMiddleOfACodeBlock
 = mkEnableOption "Whether to send a message
 in the middle of a code block.";
        };
        CustomIdle = {
          enabled = mkEnableOption "Allows y
ou to set the time before Discord goes idle 
(or disable auto-idle)";
          idleTimeout = {
            type = numbers.between 0 60;
            default = 20;
            description = "Minutes before Di
scord goes idle (0 to disable auto-idle). 0.
0 - 60.0";
          };
          remainInIdle = mkEnableOption "Whe
n you come back to Discord, remain idle unti
l you confirm you want to go online";
        };
        CustomSounds.enabled = mkEnableOptio
n "Replace Discord's sounds with your own, c
ustom sounds must be defined via client";
        CustomTimestamps = let
          mkTimestampOption = default: descr
iption:
            mkOption {
              type = str;
              inherit default description;
            };
        in {
          enabled = mkEnableOption ''
            Custom timestamps on mesages and
 tooltips.
            See <https://momentjs.com/docs/#
/displaying/format/> for documentation on fo
rmatting.
          '';
          cozyFormat = mkTimestampOption "[c
alander]" "Time format to use in messages on
 cozy mode.";
          compactFormat = mkTimestampOption 
"LT" "Time format on compact mode and hoveri
ng messages.";
          tooltipFormat = mkTimestampOption 
"LLLL - [relative]" "Time format to use on t
ooltips.";
          sameDayFormat = mkTimestampOption 
"HH:mm:ss" "[calander] format for today.";
          lastDayFormat = mkTimestampOption 
"[yesterday] HH:mm:ss" "[calander] format fo
r yesterday.";
          lastWeekFormat = mkTimestampOption
 "ddd DD.MM.YYYY HH:mm:ss" "[calander] forma
t for last week.";
          sameElseFormat = mkTimestampOption
 "ddd DD.MM.YYYY HH:mm:ss" "[calander] forma
t for older dates.";
        };
        # why weebs, why
        CuteAnimeBoys.enabled = mkEnableOpti
on "Add a command to send cute anime boys in
 the chat";
        CuteNekos.enabled = mkEnableOption "
Send Nekos to others";
        CutePats.enabled = mkEnableOption "S
ending head pats.";
        DeadMembers.enabled = mkEnableOption
 "Shows when the sender of a message has lef
t the guild.";
        Dearrow = {
          enabled = mkEnableOption "Makes Yo
uTube embed titles and thumbnails less sensa
tionalist, powered by Dearrow.";
          hideButton = mkEnableOption "Hides
 the Dearrow button from Youtube embeds.";
          replaceElements = mkOption {
            type = enum ["everything" "title
s" "thumbnails"];
            default = "everything";
            description = ''
              Choose which elements of the e
mbed will be replaced.
              Available options:
              - "everything"
              - "titles"
              - "thumbnails"
            '';
            apply = mkEquibopSelect {
              "everything" = 0;
              "titles" = 1;
              "thumbnails" = 2;
            };
          };
          dearrowByDefault = mkEnableOption 
"Dearrow videos automatically";
        };
        DecodeBase64 = {
          enabled = mkEnableOption "Decode b
ase64 content of any message and copy the de
coded content.";
          clickMethod = mkOption {
            type = enum ["Left" "Right"];
            default = "Left";
          };
        };
      };
    };
  };
  config = mkIf cfg.enable {
    # test file until module is complete
    xdg.configFile."equibop/test.json".text 
= builtins.toJSON cfg.settings;
  };
}
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET