Compare commits
3
Commits
64e4e31b3d
...
6909f9fc20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6909f9fc20 | ||
|
|
778c0155bd | ||
|
|
c52d483074 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
||||
body {
|
||||
--custom-guild-sidebar-width: 500px !important;
|
||||
--user-area-width: 450px !important;
|
||||
--custom-member-list-width: 550px !important;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"download": true,
|
||||
"emoteMenu": true,
|
||||
"hideEmojiMenu": false,
|
||||
"modifiers": true,
|
||||
"animateOnHover": false
|
||||
},
|
||||
"categories": {
|
||||
"twitchglobal": true,
|
||||
"twitchsubscriber": false,
|
||||
"frankerfacez": true,
|
||||
"bttv": true
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"version": "1.13.14",
|
||||
"drawerStates": {
|
||||
"settings": {
|
||||
"addons": true,
|
||||
"store": true,
|
||||
"customcss": true,
|
||||
"editor": true,
|
||||
"window": true,
|
||||
"developer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"PluginRepo": false,
|
||||
"BDFDB": true,
|
||||
"GameActivityToggle": true,
|
||||
"ReadAllNotificationsButton": true,
|
||||
"ThemeRepo": false,
|
||||
"ZeresPluginLibrary": true,
|
||||
"AuroraGSI": false,
|
||||
"BetterFormattingRedux": true,
|
||||
"BetterRoleColors": false,
|
||||
"ShowConnections": true,
|
||||
"ThemeSettings": false,
|
||||
"VoiceEvents": false,
|
||||
"WhoReacted": true,
|
||||
"serverthemes": false,
|
||||
"betterdiscord-google-fonts": true,
|
||||
"PronounDB": false,
|
||||
"VoiceActivity": true,
|
||||
"InMyVoice": true,
|
||||
"VoiceChatNotifications": true,
|
||||
"AvatarHover": true,
|
||||
"BetterChatNames": true,
|
||||
"HideServersChannelsRedux": false,
|
||||
"ShowBadgesInChat": true,
|
||||
"removeTrackingURL": false,
|
||||
"BetterGuildTooltip": true,
|
||||
"Translator": true,
|
||||
"ChannelsBadges": false,
|
||||
"DisplayUsernames": true,
|
||||
"enhancecodeblocks": false,
|
||||
"StickerEmojiPreview": true,
|
||||
"WiderUserArea": true,
|
||||
"Animations": false,
|
||||
"ServerDetails": true,
|
||||
"ActivityIcons": false,
|
||||
"PermissionsViewer": true,
|
||||
"ChannelPermissions": false,
|
||||
"BetterChannelList": false,
|
||||
"ChannelTabs": false,
|
||||
"NotificationSounds": true,
|
||||
"MoreRoleColors": true,
|
||||
"BetterAnimations": false,
|
||||
"DoNotTrack": true,
|
||||
"ViewProfilePicture": true
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"general": {
|
||||
"voiceDisconnect": false,
|
||||
"showToasts": true,
|
||||
"mediaKeys": true,
|
||||
"themeAttributes": true,
|
||||
"notificationPosition": "top-right",
|
||||
"notificationEnabled": true
|
||||
},
|
||||
"addons": {
|
||||
"addonErrors": true,
|
||||
"editAction": "detached",
|
||||
"checkForUpdates": true,
|
||||
"updateInterval": 4
|
||||
},
|
||||
"store": {
|
||||
"bdAddonStore": true,
|
||||
"alwaysEnable": false,
|
||||
"addonEmbeds": true
|
||||
},
|
||||
"customcss": {
|
||||
"customcss": true,
|
||||
"liveUpdate": true,
|
||||
"openAction": "settings"
|
||||
},
|
||||
"editor": {
|
||||
"theme": "system",
|
||||
"lineNumbers": true,
|
||||
"minimap": true,
|
||||
"hover": true,
|
||||
"quickSuggestions": true,
|
||||
"insertSpaces": false,
|
||||
"tabSize": 4,
|
||||
"fontSize": 14,
|
||||
"renderWhitespace": "selection"
|
||||
},
|
||||
"window": {
|
||||
"transparency": true,
|
||||
"removeMinimumSize": false,
|
||||
"frame": true,
|
||||
"inAppTrafficLights": false
|
||||
},
|
||||
"developer": {
|
||||
"debugLogs": false,
|
||||
"devTools": true,
|
||||
"debuggerHotkey": false,
|
||||
"reactDevTools": false,
|
||||
"inspectElement": false,
|
||||
"devToolsWarning": false,
|
||||
"recovery": true,
|
||||
"canary": false
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"Arindy": false,
|
||||
"FVUI": false,
|
||||
"Translucence": true
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
{
|
||||
"core-SimpleMarkdownWrapper": "46054",
|
||||
"core-React": "64700",
|
||||
"core-Dispatcher": "228366",
|
||||
"core-ReactSpring": "278420",
|
||||
"core-AccessibilityContext": "844222",
|
||||
"core-Tooltip": "781696",
|
||||
"core-contextmenu-Actions": "442433",
|
||||
"core-commandmanager-appIcons": "649671",
|
||||
"core-settings-search": "368631",
|
||||
"0PluginLibrary:1254924683": "64700",
|
||||
"0PluginLibrary:341512209": "64700",
|
||||
"0PluginLibrary:3695157183": "350535",
|
||||
"0PluginLibrary:1032993886": "350535",
|
||||
"0PluginLibrary:2508050256": "750506",
|
||||
"0PluginLibrary:3026836349": "623646",
|
||||
"0PluginLibrary:4136795093": "267102",
|
||||
"0PluginLibrary:3050996723": "652215",
|
||||
"0PluginLibrary:951786541": "158954",
|
||||
"0PluginLibrary:83147845": "64700",
|
||||
"0PluginLibrary:3075157097": "363195",
|
||||
"0PluginLibrary:377304194": "558179",
|
||||
"0PluginLibrary:2879910472": "46054",
|
||||
"BetterChatNames:1201": "967198",
|
||||
"BetterChatNames:1233": "309010",
|
||||
"BetterChatNames:1319": "166444",
|
||||
"BetterChatNames:1349": "742589",
|
||||
"BetterChatNames:1385": "415409",
|
||||
"BetterChatNames:1412": "232042",
|
||||
"BetterFormattingRedux:22226": "720149",
|
||||
"BetterFormattingRedux:22258": "266599",
|
||||
"BetterGuildTooltip:1392": "228366",
|
||||
"BetterGuildTooltip:1479": "17928",
|
||||
"BetterGuildTooltip:1803": "17928",
|
||||
"BetterGuildTooltip:1878": "485366",
|
||||
"BetterGuildTooltip:2014": "308528",
|
||||
"BetterGuildTooltip:2109": "253363",
|
||||
"0PluginLibrary:3508192550": "635071",
|
||||
"DoNotTrack:6603": "594061",
|
||||
"DoNotTrack:6630": "406935",
|
||||
"DoNotTrack:6659": "174459",
|
||||
"DoNotTrack:6693": "19575",
|
||||
"EnhanceCodeBlocks:3413228107": "278420",
|
||||
"EnhanceCodeBlocks:1829278509": "855522",
|
||||
"EnhanceCodeBlocks:1929428925": "28728",
|
||||
"EnhanceCodeBlocks:1078947860": "459127",
|
||||
"EnhanceCodeBlocks:1946862927": "102741",
|
||||
"EnhanceCodeBlocks:1082876702": "397927",
|
||||
"EnhanceCodeBlocks:1859630996": "158954",
|
||||
"EnhanceCodeBlocks:2928343028": "397927",
|
||||
"EnhanceCodeBlocks:3078982459": "453903",
|
||||
"EnhanceCodeBlocks:830998530": "103552",
|
||||
"InMyVoice:1637": "679740",
|
||||
"InMyVoice:1672": "931228",
|
||||
"InMyVoice:1864": "607567",
|
||||
"InMyVoice:1895": "607567",
|
||||
"InMyVoice:1919": "709066",
|
||||
"InMyVoice:1958": "311907",
|
||||
"MoreRoleColors:453": "304960",
|
||||
"MoreRoleColors:611": "147192",
|
||||
"MoreRoleColors:628": "288539",
|
||||
"MoreRoleColors:772": "17928",
|
||||
"MoreRoleColors:21476720": "613306",
|
||||
"MoreRoleColors:24485674": "485947",
|
||||
"MoreRoleColors:26065620": "320819",
|
||||
"MoreRoleColors:27696461": "709066",
|
||||
"PermissionsViewer:12806": "652215",
|
||||
"PermissionsViewer:12833": "3451",
|
||||
"PermissionsViewer:12870": "19575",
|
||||
"PermissionsViewer:12897": "375708",
|
||||
"PermissionsViewer:3028674": "773669",
|
||||
"PermissionsViewer:14663700": "889277",
|
||||
"PermissionsViewer:14698296": "746413",
|
||||
"PermissionsViewer:14725204": "949296",
|
||||
"PermissionsViewer:15024075": "316933",
|
||||
"PronounDB:2502": "311907",
|
||||
"PronounDB:2547": "311907",
|
||||
"StickerEmojiPreview:4460131": "151271",
|
||||
"StickerEmojiPreview:5010": "265690",
|
||||
"StickerEmojiPreview:5144": "499867",
|
||||
"StickerEmojiPreview:4461902": "182922",
|
||||
"StickerEmojiPreview:6543603": "922016",
|
||||
"StickerEmojiPreview:10469": "395515",
|
||||
"ViewProfilePicture:10993": "265690",
|
||||
"ViewProfilePicture:11127": "499867",
|
||||
"ViewProfilePicture:12451": "192308",
|
||||
"ViewProfilePicture:12492": "935462",
|
||||
"ViewProfilePicture:13508": "781696",
|
||||
"ViewProfilePicture:15403": "9578",
|
||||
"ViewProfilePicture:15425": "154872",
|
||||
"ViewProfilePicture:15619": "717421",
|
||||
"ViewProfilePicture:15639": "454290",
|
||||
"ViewProfilePicture:17226": "310784",
|
||||
"ViewProfilePicture:18000": "661531",
|
||||
"ViewProfilePicture:19610": "654107",
|
||||
"ViewProfilePicture:19993": "710016",
|
||||
"ViewProfilePicture:20235": "158954",
|
||||
"ViewProfilePicture:22447": "946356",
|
||||
"ViewProfilePicture:23582": "158954",
|
||||
"ViewProfilePicture:26590": "158954",
|
||||
"VoiceActivity:5346226": "17928",
|
||||
"VoiceActivity:5347121": "589158",
|
||||
"VoiceActivity:5408780": "696157",
|
||||
"VoiceActivity:5347431": "125787",
|
||||
"VoiceActivity:5347552": "652215",
|
||||
"VoiceActivity:525973814": "352139",
|
||||
"VoiceActivity:5347837": "714114",
|
||||
"VoiceActivity:434714749": "358618",
|
||||
"VoiceActivity:434714778": "83107",
|
||||
"VoiceActivity:434714908": "615675",
|
||||
"VoiceActivity:434715029": "990836",
|
||||
"VoiceActivity:434715159": "615675",
|
||||
"VoiceActivity:434715274": "428689",
|
||||
"VoiceActivity:5357596": "10862",
|
||||
"VoiceActivity:5357907": "976860",
|
||||
"core-SimpleMarkdown": "791332",
|
||||
"0BDFDB:3340963209": "287809",
|
||||
"BetterChatNames:1262": "976860",
|
||||
"0BDFDB:3538865044": "287809",
|
||||
"core-changelog-anchorClasses": "983763",
|
||||
"core-commandmanager-iconClasses": "824527",
|
||||
"core-commandmanager-builtInSeparatorClasses": "282214",
|
||||
"core-mdinstallcss-codeBlockStyles": "830412",
|
||||
"core-themeattributes-MessageComponent": "371741",
|
||||
"core-themeattributes-messageHook": "672341",
|
||||
"core-themeattributes-VoiceUserComponent": "481947",
|
||||
"core-themeattributes-ChatAvatar": "643204",
|
||||
"core-themeattributes-AvatarImg": "97808",
|
||||
"BetterChatNames:1263": "967198",
|
||||
"BetterChatNames:1295": "309010",
|
||||
"BetterChatNames:1324": "976860",
|
||||
"BetterChatNames:1381": "166444",
|
||||
"BetterChatNames:1411": "742589",
|
||||
"BetterChatNames:1447": "112541",
|
||||
"BetterChatNames:1474": "232042",
|
||||
"core-stores-Flux": "17928",
|
||||
"core-commandmanager-user": "889227",
|
||||
"core-commandmanager-messages": "720149",
|
||||
"core-commandmanager-icons": "3451",
|
||||
"core-addoncard-ChannelActions": "730852",
|
||||
"core-contextmenu-menu": "980707",
|
||||
"core-contextmenu-classes": "32271",
|
||||
"core-LinkParser": "527214",
|
||||
"core-themeattributes-TabBar": "761508",
|
||||
"MoreRoleColors:679": "17928",
|
||||
"ViewProfilePicture:8420": "265690",
|
||||
"ViewProfilePicture:8554": "499867",
|
||||
"ViewProfilePicture:9695": "781696",
|
||||
"ViewProfilePicture:10304084": "256905",
|
||||
"ViewProfilePicture:10778": "310784",
|
||||
"ViewProfilePicture:11426": "654107",
|
||||
"ViewProfilePicture:12403": "946356",
|
||||
"ViewProfilePicture:12456": "915614",
|
||||
"ViewProfilePicture:14220": "395515",
|
||||
"ViewProfilePicture:16887": "534514",
|
||||
"VoiceActivity:5347583": "652215",
|
||||
"VoiceActivity:525973845": "352139",
|
||||
"VoiceActivity:5347868": "714114",
|
||||
"VoiceActivity:434714780": "358618",
|
||||
"VoiceActivity:434714809": "83107",
|
||||
"VoiceActivity:434714939": "615675",
|
||||
"VoiceActivity:434715060": "990836",
|
||||
"VoiceActivity:434715190": "615675",
|
||||
"VoiceActivity:434715305": "428689",
|
||||
"VoiceActivity:5357627": "10862",
|
||||
"VoiceActivity:5357938": "976860",
|
||||
"PermissionsViewer:212173": "652215",
|
||||
"PermissionsViewer:217004": "652215",
|
||||
"PermissionsViewer:217032": "375708",
|
||||
"PermissionsViewer:3233088": "773669",
|
||||
"PermissionsViewer:211096905": "746413",
|
||||
"PermissionsViewer:211153604": "920531",
|
||||
"BetterGuildTooltip:1423": "228366",
|
||||
"BetterGuildTooltip:1510": "17928",
|
||||
"BetterGuildTooltip:1834": "17928",
|
||||
"BetterGuildTooltip:1909": "306571",
|
||||
"BetterGuildTooltip:2045": "308528",
|
||||
"BetterGuildTooltip:2169": "254472",
|
||||
"InMyVoice:1668": "334211",
|
||||
"InMyVoice:1703": "763697",
|
||||
"InMyVoice:1926": "635071",
|
||||
"InMyVoice:1950": "709066",
|
||||
"InMyVoice:1989": "17928",
|
||||
"ViewProfilePicture:12549": "915614",
|
||||
"ViewProfilePicture:14313": "395515",
|
||||
"ViewProfilePicture:16980": "534514",
|
||||
"BetterChatNames:3459093": "967198",
|
||||
"BetterChatNames:3489845": "309010",
|
||||
"BetterChatNames:3517714": "976860",
|
||||
"MoreRoleColors:18368": "288539",
|
||||
"BetterChatNames:3601310": "742589",
|
||||
"BetterChatNames:3635906": "112541",
|
||||
"BetterChatNames:3661853": "232042"
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"ClassModuleCache": {
|
||||
"AccountDetails": "489902",
|
||||
"AccountDetailsButtons": "270082",
|
||||
"AppMount": "343166",
|
||||
"AppOuter": "906292",
|
||||
"Avatar": "282291",
|
||||
"BotTag": "763697",
|
||||
"Button": "809657",
|
||||
"ChannelTextArea": "266599",
|
||||
"ChannelTextAreaButton": "124767",
|
||||
"ChatWindow": "964623",
|
||||
"Flex": "392245",
|
||||
"FlowerStar": "767246",
|
||||
"GifFavoriteButton": "280312",
|
||||
"GuildFolder": "273923",
|
||||
"GuildIcon": "155570",
|
||||
"GuildItem": "266062",
|
||||
"GuildsListItem": "547732",
|
||||
"GuildsListItemTooltip": "621035",
|
||||
"GuildsWrapper": "803921",
|
||||
"Input": "482188",
|
||||
"ItemLayerContainer": "56553",
|
||||
"Layers": "783775",
|
||||
"LottieIcon": "274661",
|
||||
"Margins": "818050",
|
||||
"Member": "28371",
|
||||
"Menu": "32271",
|
||||
"Message": "701628",
|
||||
"MessageToolbarItems": "874280",
|
||||
"MessagesPopoutTabBar": "716030",
|
||||
"Modal": "889277",
|
||||
"ModalNew": "967744",
|
||||
"ModalSub": "243926",
|
||||
"NameTag": "786627",
|
||||
"Notice": "580537",
|
||||
"NoticePlatform": "448759",
|
||||
"PeoplesNowPlayingMember": "564450",
|
||||
"PictureInPicture": "201181",
|
||||
"Scroller": "45596",
|
||||
"SettingsItems": "714304",
|
||||
"Slider": "160671",
|
||||
"Switch": "180846",
|
||||
"Tooltip": "418519",
|
||||
"TooltipGuild": "621035",
|
||||
"UserBadges": "992028",
|
||||
"UserHeaderUsername": "874644",
|
||||
"UserPopoutBody": "447349",
|
||||
"UserSummaryItem": "227568"
|
||||
},
|
||||
"ModuleIdCache": {
|
||||
"Account": "224196",
|
||||
"ChannelTextAreaButtons": "729666",
|
||||
"ChannelTextAreaEditor": "112541",
|
||||
"DiscordTag": "297413",
|
||||
"Embed": "175671",
|
||||
"EmojiPickerListRow": "267889",
|
||||
"Menu": "980707",
|
||||
"UnreadDMs": "254472",
|
||||
"UserProfile": "939496"
|
||||
},
|
||||
"changeLogs": {
|
||||
"BDFDB": "4.5.2",
|
||||
"GameActivityToggle": "1.4.0",
|
||||
"NotificationSounds": "4.0.8",
|
||||
"PluginRepo": "2.6.0",
|
||||
"ReadAllNotificationsButton": "1.8.5",
|
||||
"ServerDetails": "1.3.6",
|
||||
"ShowBadgesInChat": "2.1.5",
|
||||
"ShowConnections": "1.3.3",
|
||||
"ThemeRepo": "2.6.0",
|
||||
"ThemeSettings": "9.9.9",
|
||||
"Translator": "2.8.2"
|
||||
},
|
||||
"choices": {
|
||||
"toastPosition": "right"
|
||||
},
|
||||
"general": {
|
||||
"shareData": true,
|
||||
"showToasts": true,
|
||||
"checkForUpdates": false,
|
||||
"showSupportBadges": true,
|
||||
"useChromium": false
|
||||
},
|
||||
"hashes": {
|
||||
"0BDFDB.data.json": "c8b3be9d284601d0f03d841a3c3d41217a8b9e32",
|
||||
"0BDFDB.raw.css": "85b1d2469d341d569f77f84d1c32dc09d6d0c042"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"settings": {
|
||||
"normalActivityIcons": true,
|
||||
"richPresenceIcons": true,
|
||||
"platformIcons": true,
|
||||
"listeningIcons": true,
|
||||
"watchingIcons": true
|
||||
},
|
||||
"currentVersionInfo": {
|
||||
"version": "1.4.11",
|
||||
"hasShownChangelog": true
|
||||
},
|
||||
"changelogVersion": "1.5.3"
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
{
|
||||
"settings": {
|
||||
"buttons": {
|
||||
"custom": {
|
||||
"enabled": false,
|
||||
"frames": [
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
},
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
},
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
}
|
||||
],
|
||||
"page": 0
|
||||
},
|
||||
"delay": 0.1,
|
||||
"duration": 0.3,
|
||||
"enabled": true,
|
||||
"name": "slide-down-right",
|
||||
"page": 1,
|
||||
"selectors": "",
|
||||
"sequence": "fromLast",
|
||||
"timing": "linear"
|
||||
},
|
||||
"lists": {
|
||||
"custom": {
|
||||
"enabled": false,
|
||||
"frames": [
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
},
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
},
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
}
|
||||
],
|
||||
"page": 2
|
||||
},
|
||||
"delay": "0.015",
|
||||
"duration": "0.01",
|
||||
"enabled": true,
|
||||
"name": "slide-down-right",
|
||||
"page": 1,
|
||||
"selectors": "",
|
||||
"sequence": "fromFirst",
|
||||
"timing": "linear"
|
||||
},
|
||||
"messages": {
|
||||
"custom": {
|
||||
"enabled": false,
|
||||
"frames": [
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
},
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
},
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
}
|
||||
],
|
||||
"page": 0
|
||||
},
|
||||
"delay": 0.055,
|
||||
"duration": 0.3,
|
||||
"enabled": true,
|
||||
"limit": 30,
|
||||
"name": "slide-down-right",
|
||||
"page": 2,
|
||||
"sending": {
|
||||
"custom": {
|
||||
"enabled": false,
|
||||
"frames": [
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
},
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
},
|
||||
{
|
||||
"anim": "",
|
||||
"start": ""
|
||||
}
|
||||
],
|
||||
"page": 0
|
||||
},
|
||||
"enabled": "onsent",
|
||||
"name": "slide-down-left",
|
||||
"page": 1
|
||||
},
|
||||
"timing": "linear"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.1.7",
|
||||
"hasShownChangelog": true
|
||||
},
|
||||
"settings": {
|
||||
"lastMessage": {
|
||||
"enabled": true,
|
||||
"roleColors": true
|
||||
},
|
||||
"redesign": {
|
||||
"enabled": true,
|
||||
"iconSize": "small"
|
||||
},
|
||||
"resizer": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
/**
|
||||
* @name BetterChatNames
|
||||
* @author Break
|
||||
* @description Improves chat names by automatically capitalising them and/or removing dashes/underscores
|
||||
* @version 1.9.1
|
||||
* @authorLink https://github.com/Break-Ben
|
||||
* @website https://github.com/Break-Ben/BetterDiscordAddons
|
||||
* @source https://github.com/Break-Ben/BetterDiscordAddons/tree/main/BetterChatNames
|
||||
* @updateUrl https://raw.githubusercontent.com/Break-Ben/BetterDiscordAddons/main/BetterChatNames/BetterChatNames.plugin.js
|
||||
*/
|
||||
|
||||
const defaultSettings = {
|
||||
capitalise: true,
|
||||
removeDashes: true,
|
||||
removeEmojis: false,
|
||||
patchUnrestricted: true,
|
||||
capitalOverrides: 'and, or, of, the, for, to, at, a, FAQ, VC, GitHub'
|
||||
}
|
||||
|
||||
const unrestrictedChannels = {
|
||||
voice: 2,
|
||||
thread: 11,
|
||||
stage: 13
|
||||
}
|
||||
const regex = {
|
||||
dash: /-|_/g,
|
||||
capital: /(?<=(^|[^\p{L}'’]))\p{L}/gu,
|
||||
word: /\b\p{L}+\b/gu,
|
||||
emoji: /([-_]?\p{Extended_Pictographic}[-_┃]?)|(\uFE0F\u20E3)/gu
|
||||
}
|
||||
const debounceTimeMs = 1000
|
||||
|
||||
const searchOptions = { walkable: ['children', 'props'] } // For Utils.findInTree
|
||||
const { Webpack, Patcher, Utils, Data, UI } = new BdApi('BetterChatNames')
|
||||
const { waitForModule, getByStrings, getByKeys, getByPrototypeKeys } = Webpack
|
||||
const { findInTree } = Utils
|
||||
const modules = {}
|
||||
let titleObserver
|
||||
|
||||
module.exports = class BetterChatNames {
|
||||
async start() {
|
||||
this.settings = Object.assign({}, defaultSettings, Data.load('settings'))
|
||||
await this.getModules()
|
||||
|
||||
this.updateOverrideMap()
|
||||
this.observeAppTitle()
|
||||
this.patchNames()
|
||||
this.refreshChannel()
|
||||
}
|
||||
|
||||
stop() {
|
||||
titleObserver.disconnect()
|
||||
Patcher.unpatchAll()
|
||||
this.refreshChannel()
|
||||
}
|
||||
|
||||
getSettingsPanel = () => UI.buildSettingsPanel({
|
||||
settings: [
|
||||
{
|
||||
id: 'capitalise',
|
||||
name: 'Capitalise Words',
|
||||
type: 'switch',
|
||||
value: this.settings.capitalise
|
||||
},
|
||||
{
|
||||
id: 'removeDashes',
|
||||
name: 'Remove Dashes and Underscores',
|
||||
type: 'switch',
|
||||
value: this.settings.removeDashes
|
||||
},
|
||||
{
|
||||
id: 'removeEmojis',
|
||||
name: 'Remove Emojis',
|
||||
type: 'switch',
|
||||
value: this.settings.removeEmojis
|
||||
},
|
||||
{
|
||||
id: 'patchUnrestricted',
|
||||
name: 'Patch Unrestricted Channels',
|
||||
note: 'Change the names of channels that can already contain capital letters and spaces, such as voice channels, threads, and stages.',
|
||||
type: 'switch',
|
||||
value: this.settings.patchUnrestricted
|
||||
},
|
||||
{
|
||||
id: 'capitalOverrides',
|
||||
name: 'Capitalisation Overrides',
|
||||
note: 'A comma-separated list of words with custom capitalisations. For example: "and, FAQ, GitHub, iPhone". Only enabled if "Capitalise Words" is enabled, and can be cleared to be disabled.',
|
||||
type: 'text',
|
||||
inline: false,
|
||||
value: this.settings.capitalOverrides
|
||||
}
|
||||
],
|
||||
onChange: (_, id, value) => {
|
||||
if (id === 'capitalOverrides') {
|
||||
clearTimeout(this.debounceTimer)
|
||||
this.debounceTimer = setTimeout(() => {
|
||||
this.settings[id] = value
|
||||
Data.save('settings', this.settings)
|
||||
this.updateOverrideMap()
|
||||
if (this.settings.capitalise)
|
||||
this.refreshChannel()
|
||||
}, debounceTimeMs)
|
||||
return
|
||||
}
|
||||
|
||||
this.settings[id] = value
|
||||
Data.save('settings', this.settings)
|
||||
this.refreshChannel()
|
||||
}
|
||||
})
|
||||
|
||||
async getModules() {
|
||||
modules.currentServer = getByKeys('getLastSelectedGuildId')
|
||||
modules.currentChannel = getByKeys('getLastSelectedChannelId')
|
||||
modules.transitionTo = getByStrings('transitionTo - Transitioning to', { searchExports: true })
|
||||
|
||||
modules.sidebar = await waitForModule(m => m?.render?.toString()?.includes('.CHANNEL'))
|
||||
modules.header = getByStrings('.HEADER_BAR)', { defaultExport: false })
|
||||
modules.placeholder = getByPrototypeKeys('getPlaceholder').prototype
|
||||
modules.mention = getByStrings('channelWithIcon', { defaultExport: false })
|
||||
}
|
||||
|
||||
observeAppTitle() {
|
||||
let lastUnpatchedAppTitle
|
||||
titleObserver = new MutationObserver(() => {
|
||||
if (document.title !== lastUnpatchedAppTitle) { // Resolves conflicts with EditChannels' MutationObserver
|
||||
lastUnpatchedAppTitle = document.title
|
||||
this.patchAppTitle()
|
||||
}
|
||||
})
|
||||
titleObserver.observe(document.querySelector('title'), { childList: true })
|
||||
}
|
||||
|
||||
patchAppTitle() {
|
||||
const patchedTitle = this.patchText(document.title)
|
||||
|
||||
if (modules.currentServer?.getGuildId() && document.title !== patchedTitle) // If in server and title not already patched
|
||||
document.title = patchedTitle
|
||||
}
|
||||
|
||||
patchNames() {
|
||||
this.patchSidebar()
|
||||
this.patchHeader()
|
||||
this.patchChatPlaceholder()
|
||||
this.patchMention()
|
||||
}
|
||||
|
||||
patchSidebar() {
|
||||
Patcher.after(modules.sidebar, 'render', (_, __, data) => {
|
||||
const channelName = findInTree(data, prop => prop?.name, searchOptions)
|
||||
const channelType = findInTree(data, prop => prop?.channel, searchOptions).channel.type
|
||||
|
||||
if (!Object.values(unrestrictedChannels).includes(channelType) || this.settings.patchUnrestricted) // If not a voice/stage channel or patchUnrestricted is enabled
|
||||
channelName.name = this.patchText(channelName.name)
|
||||
})
|
||||
}
|
||||
|
||||
patchHeader() {
|
||||
Patcher.after(modules.header, 'A', (_, __, data) => {
|
||||
const rootChannel = findInTree(data, prop => prop?.level, searchOptions)
|
||||
if (!rootChannel)
|
||||
return
|
||||
|
||||
if (rootChannel.level === 1) // If not in thread
|
||||
rootChannel.children.props.children[2] = this.patchText(rootChannel.children.props.children[2])
|
||||
else if (rootChannel.level === 2) { // If in thread
|
||||
rootChannel.children = this.patchText(rootChannel.children)
|
||||
if (this.settings.patchUnrestricted) {
|
||||
const threadName = findInTree(data, prop => Array.isArray(prop) && prop[1] === ' ', searchOptions)
|
||||
threadName[2] = this.patchText(threadName[2])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
patchChatPlaceholder() {
|
||||
Patcher.after(modules.placeholder, 'render', (_, __, data) => {
|
||||
const textArea = findInTree(data, prop => prop.channel, searchOptions)
|
||||
const isThread = textArea.channel.type === unrestrictedChannels.thread
|
||||
|
||||
if (textArea.channel.guild_id && (!isThread || this.settings.patchUnrestricted) && !textArea.disabled && textArea.type.analyticsName === 'normal') { // If in a server, not in a thread (or patchUnrestricted is enabled), can message and not editing a message
|
||||
const splitIndex = (isThread ? textArea.placeholder.indexOf('"') : textArea.placeholder.indexOf('#')) + 1 // Indicates where the channel name starts
|
||||
textArea.placeholder = textArea.placeholder.substring(0, splitIndex) + this.patchText(textArea.placeholder.substr(splitIndex))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
patchMention() {
|
||||
Patcher.after(modules.mention, 'A', (_, __, data) => {
|
||||
const channelName = findInTree(data, prop => typeof prop.children === 'string', searchOptions)
|
||||
|
||||
if (data.props.className.includes('iconMentionText') || this.settings.patchUnrestricted) // If is a normal chat mention (not a thread) or patchUnrestricted is enabled
|
||||
channelName.children = this.patchText(channelName.children)
|
||||
})
|
||||
}
|
||||
|
||||
patchText(text) {
|
||||
if (this.settings.removeEmojis)
|
||||
text = text.replace(regex.emoji, '')
|
||||
|
||||
if (this.settings.removeDashes)
|
||||
text = text.replace(regex.dash, ' ')
|
||||
|
||||
if (this.settings.capitalise) {
|
||||
text = text.replace(regex.capital, letter => letter.toUpperCase())
|
||||
|
||||
if (this.settings.capitalOverrides) {
|
||||
let wordCount = 0
|
||||
text = text.replace(regex.word, word => {
|
||||
wordCount++
|
||||
const wordLower = word.toLowerCase()
|
||||
if (!this.overrideMap.has(wordLower))
|
||||
return word
|
||||
|
||||
const wordOverride = this.overrideMap.get(wordLower)
|
||||
if (wordCount == 1 && wordOverride === wordLower)
|
||||
return word
|
||||
|
||||
return wordOverride
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
refreshChannel() {
|
||||
const currentServerId = modules.currentServer?.getGuildId()
|
||||
const currentChannelId = modules.currentChannel?.getChannelId()
|
||||
|
||||
if (currentServerId) { // If not in a DM
|
||||
modules.transitionTo('/channels/@me')
|
||||
setImmediate(() => modules.transitionTo(`/channels/${currentServerId}/${currentChannelId}`))
|
||||
}
|
||||
}
|
||||
|
||||
updateOverrideMap() {
|
||||
// Maps lowercase words to their custom capitalised versions
|
||||
this.overrideMap = new Map((this.settings.capitalOverrides).split(',').map(w => w.trim()).filter(w => w).map(w => [w.toLowerCase(), w]))
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "2.3.14",
|
||||
"hasShownChangelog": true
|
||||
},
|
||||
"settings": {
|
||||
"toolbar": {
|
||||
"bold": true,
|
||||
"italic": true,
|
||||
"underline": true,
|
||||
"strikethrough": true,
|
||||
"spoiler": true,
|
||||
"code": true,
|
||||
"codeblock": true,
|
||||
"superscript": true,
|
||||
"smallcaps": true,
|
||||
"fullwidth": true,
|
||||
"upsidedown": true,
|
||||
"varied": true,
|
||||
"leet": false,
|
||||
"thicc": false
|
||||
},
|
||||
"formats": {
|
||||
"superscript": true,
|
||||
"smallcaps": true,
|
||||
"fullwidth": true,
|
||||
"upsidedown": true,
|
||||
"varied": true,
|
||||
"leet": false,
|
||||
"thicc": false
|
||||
},
|
||||
"wrappers": {
|
||||
"superscript": "^^",
|
||||
"smallcaps": "%%",
|
||||
"fullwidth": "##",
|
||||
"upsidedown": "&&",
|
||||
"varied": "==",
|
||||
"leet": "++",
|
||||
"thicc": "$$"
|
||||
},
|
||||
"formatting": {
|
||||
"fullWidthMap": true,
|
||||
"reorderUpsidedown": true,
|
||||
"fullwidth": true
|
||||
},
|
||||
"plugin": {
|
||||
"hoverOpen": true,
|
||||
"chainFormats": true,
|
||||
"closeOnSend": true
|
||||
},
|
||||
"style": {
|
||||
"icons": true,
|
||||
"rightSide": true,
|
||||
"toolbarOpacity": 1,
|
||||
"fontSize": 85
|
||||
}
|
||||
},
|
||||
"version": "2.3.15"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.2.4",
|
||||
"hasShownChangelog": true
|
||||
}
|
||||
}
|
||||
@@ -1,312 +0,0 @@
|
||||
/**
|
||||
* @name BetterGuildTooltip
|
||||
* @author arg0NNY
|
||||
* @authorId 633223783204782090
|
||||
* @invite M8DBtcZjXD
|
||||
* @version 1.2.4
|
||||
* @description Displays an online and total member count in the guild tooltip.
|
||||
* @website https://github.com/arg0NNY/DiscordPlugins/tree/master/BetterGuildTooltip
|
||||
* @source https://raw.githubusercontent.com/arg0NNY/DiscordPlugins/master/BetterGuildTooltip/BetterGuildTooltip.plugin.js
|
||||
* @updateUrl https://raw.githubusercontent.com/arg0NNY/DiscordPlugins/master/BetterGuildTooltip/BetterGuildTooltip.plugin.js
|
||||
* @runAt idle
|
||||
*/
|
||||
|
||||
/* ### CONFIG START ### */
|
||||
const config = {
|
||||
info: {
|
||||
name: 'BetterGuildTooltip',
|
||||
version: '1.2.4',
|
||||
description: 'Displays an online and total member count in the guild tooltip.'
|
||||
},
|
||||
changelog: [
|
||||
{
|
||||
type: 'fixed',
|
||||
title: 'Fixes',
|
||||
items: [
|
||||
'Updated to work in the latest release of Discord.'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
/* ### CONFIG END ### */
|
||||
|
||||
const {
|
||||
Webpack,
|
||||
UI,
|
||||
Patcher,
|
||||
React,
|
||||
Utils,
|
||||
Data
|
||||
} = new BdApi(config.info.name)
|
||||
const { Filters } = Webpack
|
||||
|
||||
const Dispatcher = Webpack.getModule(Filters.byKeys('dispatch', 'subscribe'), { searchExports: true })
|
||||
const GuildMemberCountStore = Webpack.getStore('GuildMemberCountStore')
|
||||
const GuildChannelStore = Webpack.getStore('GuildChannelStore')
|
||||
const Flux = Webpack.getByKeys('Store', 'connectStores')
|
||||
|
||||
const ActionTypes = {
|
||||
CONNECTION_OPEN: 'CONNECTION_OPEN',
|
||||
GUILD_CREATE: 'GUILD_CREATE',
|
||||
GUILD_DELETE: 'GUILD_DELETE',
|
||||
GUILD_MEMBER_LIST_UPDATE: 'GUILD_MEMBER_LIST_UPDATE',
|
||||
ONLINE_GUILD_MEMBER_COUNT_UPDATE: 'ONLINE_GUILD_MEMBER_COUNT_UPDATE'
|
||||
}
|
||||
|
||||
const useStateFromStores = Webpack.getModule(Filters.byStrings('useStateFromStores'), { searchExports: true })
|
||||
|
||||
const Selectors = {
|
||||
Guild: Webpack.getByKeys('statusOffline', 'guildDetail')
|
||||
}
|
||||
|
||||
const GuildStore = Webpack.getStore('GuildStore')
|
||||
const GuildActions = Webpack.getByKeys('preload', 'closePrivateChannel')
|
||||
const GuildTooltip = [...Webpack.getWithKey(Filters.byStrings('guild', '__unsupportedReactNodeAsText'), { target: Webpack.getBySource('GuildTooltip', { raw: true })?.declarations })]
|
||||
|
||||
const memberCounts = new Map()
|
||||
const onlineMemberCounts = new Map()
|
||||
|
||||
function handleConnectionOpen ({ guilds }) {
|
||||
for (const guild of guilds) {
|
||||
memberCounts.set(guild.id, guild.member_count)
|
||||
}
|
||||
}
|
||||
|
||||
function handleGuildCreate ({ guild }) {
|
||||
memberCounts.set(guild.id, guild.member_count)
|
||||
}
|
||||
|
||||
function handleGuildDelete ({ guild }) {
|
||||
memberCounts.delete(guild.id)
|
||||
onlineMemberCounts.delete(guild.id)
|
||||
}
|
||||
|
||||
function handleGuildMemberListUpdate ({ guildId, memberCount, groups }) {
|
||||
if (memberCount !== 0) {
|
||||
memberCounts.set(guildId, memberCount)
|
||||
}
|
||||
|
||||
onlineMemberCounts.set(
|
||||
guildId,
|
||||
groups.reduce((total, group) => {
|
||||
return group.id !== 'offline' ? total + group.count : total
|
||||
}, 0)
|
||||
)
|
||||
}
|
||||
|
||||
function handleOnlineGuildMemberCountUpdate ({ guildId, count }) {
|
||||
onlineMemberCounts.set(guildId, count)
|
||||
}
|
||||
|
||||
const MemberCountsStore = new class extends Flux.Store {
|
||||
initialize () {
|
||||
const nativeMemberCounts = GuildMemberCountStore.getMemberCounts()
|
||||
for (const guildId in nativeMemberCounts) {
|
||||
memberCounts.set(guildId, nativeMemberCounts[guildId])
|
||||
}
|
||||
};
|
||||
|
||||
getMemberCounts (guildId) {
|
||||
return {
|
||||
members: memberCounts.get(guildId),
|
||||
membersOnline: onlineMemberCounts.get(guildId)
|
||||
}
|
||||
};
|
||||
}(Dispatcher, {
|
||||
[ActionTypes.CONNECTION_OPEN]: handleConnectionOpen,
|
||||
[ActionTypes.GUILD_CREATE]: handleGuildCreate,
|
||||
[ActionTypes.GUILD_DELETE]: handleGuildDelete,
|
||||
[ActionTypes.GUILD_MEMBER_LIST_UPDATE]: handleGuildMemberListUpdate,
|
||||
[ActionTypes.ONLINE_GUILD_MEMBER_COUNT_UPDATE]: handleOnlineGuildMemberCountUpdate
|
||||
})
|
||||
|
||||
function formatNumber (number) {
|
||||
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ')
|
||||
}
|
||||
|
||||
function GuildTooltipCounters (props) {
|
||||
MemberCountsStore.initialize()
|
||||
|
||||
const { presenceCount, memberCount } = useStateFromStores([GuildStore], () =>
|
||||
GuildStore.getGuild(props.guild.id) ?? {}
|
||||
)
|
||||
const { members, membersOnline } = useStateFromStores([MemberCountsStore], () =>
|
||||
MemberCountsStore.getMemberCounts(props.guild.id)
|
||||
)
|
||||
|
||||
const onlineDisplayed = props.settings.displayOnline && (membersOnline || presenceCount)
|
||||
const totalDisplayed = props.settings.displayTotal && (memberCount || members)
|
||||
|
||||
return onlineDisplayed || totalDisplayed ? React.createElement(
|
||||
'div',
|
||||
{
|
||||
className: Selectors.Guild.guildDetail,
|
||||
style: props.isPopout ? {
|
||||
fontWeight: '600'
|
||||
} : {
|
||||
marginTop: '5px',
|
||||
marginBottom: '5px'
|
||||
}
|
||||
},
|
||||
React.createElement(
|
||||
'div',
|
||||
{
|
||||
className: Selectors.Guild.statusCounts,
|
||||
style: {
|
||||
columnGap: 0,
|
||||
'-webkit-column-gap': 0
|
||||
}
|
||||
},
|
||||
[
|
||||
...(onlineDisplayed ? [React.createElement(
|
||||
'i',
|
||||
{
|
||||
className: Selectors.Guild.statusOnline
|
||||
}
|
||||
),
|
||||
React.createElement(
|
||||
'span',
|
||||
{
|
||||
className: Selectors.Guild.count
|
||||
},
|
||||
formatNumber(membersOnline ?? presenceCount)
|
||||
)] : []),
|
||||
...(totalDisplayed ? [React.createElement(
|
||||
'i',
|
||||
{
|
||||
className: Selectors.Guild.statusOffline
|
||||
}
|
||||
),
|
||||
React.createElement(
|
||||
'span',
|
||||
{
|
||||
className: Selectors.Guild.count
|
||||
},
|
||||
formatNumber(memberCount ?? members)
|
||||
)] : [])
|
||||
]
|
||||
)
|
||||
) : React.createElement('div')
|
||||
}
|
||||
|
||||
const PRELOAD_DELAY = 200
|
||||
|
||||
module.exports = class BetterGuildTooltip {
|
||||
start () {
|
||||
this.patchGuildTooltip()
|
||||
|
||||
this.preloadInProccess = false
|
||||
this.preloadNext = null
|
||||
}
|
||||
|
||||
preloadGuild (guild) {
|
||||
if (!guild || this.preloadInProccess) return this.preloadNext = guild
|
||||
|
||||
this._preloadGuild(guild)
|
||||
this.preloadInProccess = true
|
||||
setTimeout(() => {
|
||||
this.preloadInProccess = false
|
||||
this.preloadGuild(this.preloadNext)
|
||||
this.preloadNext = null
|
||||
}, PRELOAD_DELAY)
|
||||
}
|
||||
|
||||
_preloadGuild (guild) {
|
||||
GuildActions.preload(
|
||||
guild.id,
|
||||
GuildChannelStore.getDefaultChannel(guild.id).id
|
||||
)
|
||||
}
|
||||
|
||||
patchGuildTooltip () {
|
||||
const callback = (index, props = {}) => (self, [{ guild }], value) => {
|
||||
if (!this.settings.displayOnline && !this.settings.displayTotal) return
|
||||
if (this.settings.displayOnline && !onlineMemberCounts.has(guild.id)) this.preloadGuild(guild)
|
||||
value.props.children.splice(index, 0, React.createElement(GuildTooltipCounters, {
|
||||
guild,
|
||||
settings: this.settings,
|
||||
...props
|
||||
}))
|
||||
}
|
||||
|
||||
Patcher.after(...GuildTooltip, (self, _, value) => {
|
||||
const nodeRef = React.useRef()
|
||||
|
||||
if (!this.settings.displayOnline && !this.settings.displayTotal) return
|
||||
|
||||
const node = Utils.findInTree(
|
||||
value,
|
||||
m => Filters.byStrings('isViewingRoles')(m?.type),
|
||||
{ walkable: ['props', 'children', '__unsupportedReactNodeAsText'] }
|
||||
)
|
||||
if (!node || nodeRef.current === node) return
|
||||
|
||||
Patcher.after(node, 'type', callback(1))
|
||||
nodeRef.current = node
|
||||
})
|
||||
}
|
||||
|
||||
stop () {
|
||||
Patcher.unpatchAll()
|
||||
}
|
||||
|
||||
constructor () {
|
||||
this.defaultSettings = {
|
||||
displayOnline: true,
|
||||
displayTotal: true
|
||||
}
|
||||
|
||||
this.settings = this.loadSettings(this.defaultSettings)
|
||||
|
||||
this.showChangelogIfNeeded()
|
||||
}
|
||||
|
||||
loadSettings (defaults = {}) {
|
||||
return Utils.extend({}, defaults, Data.load('settings'))
|
||||
}
|
||||
saveSettings (settings = this.settings) {
|
||||
return Data.save('settings', settings)
|
||||
}
|
||||
|
||||
showChangelogIfNeeded () {
|
||||
const currentVersionInfo = Utils.extend(
|
||||
{ version: config.info.version, hasShownChangelog: false },
|
||||
Data.load('currentVersionInfo')
|
||||
)
|
||||
if (currentVersionInfo.version === config.info.version && currentVersionInfo.hasShownChangelog) return
|
||||
|
||||
this.showChangelog()
|
||||
Data.save('currentVersionInfo', { version: config.info.version, hasShownChangelog: true })
|
||||
}
|
||||
showChangelog () {
|
||||
return UI.showChangelogModal({
|
||||
title: config.info.name,
|
||||
subtitle: 'Version ' + config.info.version,
|
||||
changes: config.changelog
|
||||
})
|
||||
}
|
||||
|
||||
getSettingsPanel () {
|
||||
return UI.buildSettingsPanel({
|
||||
onChange: () => this.saveSettings(),
|
||||
settings: [
|
||||
{
|
||||
type: 'switch',
|
||||
id: 'displayOnline',
|
||||
name: 'Display online count',
|
||||
note: 'Displays an online member count in the guild tooltip.',
|
||||
value: this.settings.displayOnline,
|
||||
onChange: e => this.settings.displayOnline = e
|
||||
},
|
||||
{
|
||||
type: 'switch',
|
||||
id: 'displayTotal',
|
||||
name: 'Display total count',
|
||||
note: 'Displays a total member count in the guild tooltip.',
|
||||
value: this.settings.displayTotal,
|
||||
onChange: e => this.settings.displayTotal = e
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "0.10.4",
|
||||
"hasShownChangelog": true
|
||||
},
|
||||
"settings": {
|
||||
"global": {
|
||||
"important": false
|
||||
},
|
||||
"modules": {
|
||||
"typing": true,
|
||||
"voice": true,
|
||||
"mentions": true,
|
||||
"chat": false,
|
||||
"botTags": true,
|
||||
"memberList": true
|
||||
},
|
||||
"popouts": {
|
||||
"username": true,
|
||||
"discriminator": true,
|
||||
"nickname": true,
|
||||
"fallback": true
|
||||
},
|
||||
"modals": {
|
||||
"username": true,
|
||||
"discriminator": true
|
||||
},
|
||||
"auditLog": {
|
||||
"username": true,
|
||||
"discriminator": false
|
||||
},
|
||||
"account": {
|
||||
"username": true,
|
||||
"discriminator": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "2.6.15",
|
||||
"hasShownChangelog": true
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
{
|
||||
"settings": {
|
||||
"tabs": [
|
||||
{
|
||||
"name": "#🤡│facereveal",
|
||||
"url": "/channels/821835978334535740/987679407114178620",
|
||||
"selected": true,
|
||||
"currentStatus": "none",
|
||||
"iconUrl": "https://cdn.discordapp.com/icons/821835978334535740/f03c55415ef5c81b99585e10c1008c3b.webp?size=32",
|
||||
"channelId": "987679407114178620"
|
||||
}
|
||||
],
|
||||
"favs": [
|
||||
{
|
||||
"name": "#🧀│allgemein",
|
||||
"iconUrl": "https://cdn.discordapp.com/icons/821835978334535740/f03c55415ef5c81b99585e10c1008c3b.webp?size=32",
|
||||
"url": "/channels/821835978334535740/821835978767073292",
|
||||
"channelId": "821835978767073292",
|
||||
"groupId": -1
|
||||
},
|
||||
{
|
||||
"name": "#schwitzies",
|
||||
"iconUrl": "https://cdn.discordapp.com/icons/230708419995107330/aa16ef21ab85c9e89ff8ba36a7260e20.webp?size=32",
|
||||
"url": "/channels/230708419995107330/775452873377972254",
|
||||
"channelId": "775452873377972254",
|
||||
"groupId": -1
|
||||
}
|
||||
],
|
||||
"favGroups": [],
|
||||
"showTabBar": true,
|
||||
"showFavBar": true,
|
||||
"reopenLastChannel": true,
|
||||
"showFavUnreadBadges": true,
|
||||
"showFavMentionBadges": true,
|
||||
"showFavTypingBadge": true,
|
||||
"showEmptyFavBadges": false,
|
||||
"showTabUnreadBadges": true,
|
||||
"showTabMentionBadges": true,
|
||||
"showTabTypingBadge": true,
|
||||
"showEmptyTabBadges": false,
|
||||
"showActiveTabUnreadBadges": false,
|
||||
"showActiveTabMentionBadges": false,
|
||||
"showActiveTabTypingBadge": false,
|
||||
"showEmptyActiveTabBadges": false,
|
||||
"compactStyle": true,
|
||||
"privacyMode": false,
|
||||
"radialStatusMode": true,
|
||||
"tabWidthMin": 100,
|
||||
"showFavGroupUnreadBadges": true,
|
||||
"showFavGroupMentionBadges": true,
|
||||
"showFavGroupTypingBadge": true,
|
||||
"showEmptyFavGroupBadges": false,
|
||||
"showQuickSettings": true,
|
||||
"showNavButtons": true,
|
||||
"alwaysFocusNewTabs": false,
|
||||
"useStandardNav": true
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"CBsettings": {
|
||||
"version": "1.1.7",
|
||||
"voice": {
|
||||
"voice": true,
|
||||
"text": true,
|
||||
"emoji": true,
|
||||
"voice_color": "#1ABC9C"
|
||||
},
|
||||
"forum": {
|
||||
"forum": true,
|
||||
"text": true,
|
||||
"emoji": true,
|
||||
"forum_color": "#206694"
|
||||
},
|
||||
"nsfw": {
|
||||
"nsfw": true,
|
||||
"text": true,
|
||||
"emoji": true,
|
||||
"nsfw_color": "#F23F42"
|
||||
},
|
||||
"rule": {
|
||||
"rule": true,
|
||||
"text": true,
|
||||
"emoji": true,
|
||||
"rule_color": "#FF9B2B"
|
||||
},
|
||||
"ads": {
|
||||
"ads": true,
|
||||
"text": true,
|
||||
"emoji": true,
|
||||
"ads_color": "#FF2BC2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.4.2",
|
||||
"hasShownChangelog": true
|
||||
}
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
/**
|
||||
* @name DisplayUsernames
|
||||
* @author HG
|
||||
* @authorId 124667638298181632
|
||||
* @authorLink https://youtube.com/HudsonGTV
|
||||
* @description Displays Discord handle next to display names in chat and adds '@' symbol in profile cards.
|
||||
* @version 1.4.2
|
||||
* @website https://hudsongreen.com/
|
||||
* @invite H3bebA97tV
|
||||
* @donate https://www.paypal.com/donate/?business=REFHYLZAZUWHJ
|
||||
* @source https://github.com/HudsonGTV/BetterDiscordPlugins/blob/main/DisplayUsernames/DisplayUsernames.plugin.js
|
||||
*/
|
||||
|
||||
const request = require("request");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const config = {
|
||||
info: {
|
||||
name: "DisplayUsernames",
|
||||
authors: [
|
||||
{
|
||||
name: "HG",
|
||||
discord_id: "124667638298181632",
|
||||
github_username: "HudsonGTV",
|
||||
twitter_username: "HudsonKazuto"
|
||||
}
|
||||
],
|
||||
version: "1.4.2",
|
||||
description: "Displays Discord handle next to display names in chat and adds '`@`' symbol in profile cards.",
|
||||
github: "https://github.com/HudsonGTV/BetterDiscordPlugins/blob/main/DisplayUsernames/DisplayUsernames.plugin.js",
|
||||
github_raw: "https://raw.githubusercontent.com/HudsonGTV/BetterDiscordPlugins/main/DisplayUsernames/DisplayUsernames.plugin.js"
|
||||
},
|
||||
changelog: [
|
||||
{
|
||||
title: "Fixes",
|
||||
type: "fixed",
|
||||
items: [
|
||||
"`[1.4.2]` Fixed bug with usernames appearing in command replies",
|
||||
"`[1.4.1]` Fixed bug with seperator symbol in replies",
|
||||
"`[1.4.0]` Fixed username prefix not appearing due to recent Discord revamp.",
|
||||
"`[1.4.0]` Fixed bug with username handle in chat being black with certain themes."
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Additions",
|
||||
type: "added",
|
||||
items: [
|
||||
"`[1.4.2]` Added ability to hide the username in replies.",
|
||||
"`[1.4.1]` Added ability to change seperator color seperately.",
|
||||
"`[1.4.0]` Added ability to change username handle color in chat."
|
||||
]
|
||||
},
|
||||
/*{
|
||||
title: "Improvements",
|
||||
type: "improved",
|
||||
items: [
|
||||
"`[1.2.0]` Settings now apply without the need to restart Discord (Except handle symbol changes)."
|
||||
]
|
||||
}*/
|
||||
],
|
||||
defaultConfig: [
|
||||
{
|
||||
type: "textbox",
|
||||
id: "handlesymbol",
|
||||
name: "[Needs restart to fully apply] Username Handle Prefix Symbol",
|
||||
note: "The symbol used as a prefix for usernames (the @ in @username).",
|
||||
placeholder: "Blank for none; default: @",
|
||||
value: "@"
|
||||
},
|
||||
{
|
||||
type: "color",
|
||||
id: "usernamecolor",
|
||||
name: "Username Color",
|
||||
note: "The color used when displaying the username in the chat",
|
||||
value: "#949BA4"
|
||||
},
|
||||
{
|
||||
type: "color",
|
||||
id: "seperatorcolor",
|
||||
name: "Seperator Color",
|
||||
note: "The color used for the symbol that either seperates the username from the message timestamp (@username • timestamp) or the suffix in replies (@username: message)",
|
||||
value: "#949BA4"
|
||||
},
|
||||
{
|
||||
type: "switch",
|
||||
id: "usernamechat",
|
||||
name: "Show Username In Chat",
|
||||
note: "Display the message author's username next to the message timestamp.",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
type: "switch",
|
||||
id: "showinreplies",
|
||||
name: "Show Username in Chat Replies",
|
||||
note: "Shows the username in the replied message text.",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
type: "switch",
|
||||
id: "profilecard",
|
||||
name: "Show Handle Prefix In Profile Card & Friends List",
|
||||
note: "Display the username handle prefix in profile cards/popups as well as the friends list.",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
type: "switch",
|
||||
id: "friendslist",
|
||||
name: "Always Show Friends List Username",
|
||||
note: "Force Discord to always display usernames next to display names in friends list. Turn off for default Discord behavior (only show on hover).",
|
||||
value: true
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
module.exports = !global.ZeresPluginLibrary ? class {
|
||||
|
||||
constructor() {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
load() {
|
||||
BdApi.showConfirmationModal("Library plugin is needed",
|
||||
`The library plugin needed for ZeresPluginLibrary is missing. Please click Download Now to install it.`, {
|
||||
confirmText: "Download",
|
||||
cancelText: "Cancel",
|
||||
onConfirm: () => {
|
||||
request.get("https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js", (error, response, body) => {
|
||||
if (error)
|
||||
return electron.shell.openExternal("https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js");
|
||||
|
||||
fs.writeFileSync(path.join(BdApi.Plugins.folder, "0PluginLibrary.plugin.js"), body);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
start() { }
|
||||
stop() { }
|
||||
|
||||
} : (([Plugin, Library]) => {
|
||||
|
||||
const { DiscordModules, WebpackModules, Patcher, PluginUtilities } = Library;
|
||||
const { React } = DiscordModules;
|
||||
|
||||
class plugin extends Plugin {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
onStart() {
|
||||
|
||||
// Apply CSS Styles
|
||||
this.applyStyles();
|
||||
|
||||
// Bind usernames if enabled
|
||||
if(this.settings.usernamechat) this.applyUsername();
|
||||
|
||||
}
|
||||
|
||||
onStop() {
|
||||
Patcher.unpatchAll();
|
||||
this.removeStyles();
|
||||
}
|
||||
|
||||
// Manage settings panel
|
||||
getSettingsPanel() {
|
||||
|
||||
const panel = this.buildSettingsPanel();
|
||||
|
||||
// Listen for changes in settings
|
||||
panel.addListener((id, val) => {
|
||||
switch(id) {
|
||||
case "usernamechat":
|
||||
// Check bool val
|
||||
if(val)
|
||||
this.applyUsername();
|
||||
else
|
||||
Patcher.unpatchAll(); // Change this if I add more patches to plugin
|
||||
break;
|
||||
case "showinreplies":
|
||||
case "usernamecolor":
|
||||
case "seperatorcolor":
|
||||
case "profilecard":
|
||||
case "friendslist":
|
||||
// Reload CSS
|
||||
this.removeStyles();
|
||||
this.applyStyles();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Display settings panel
|
||||
return panel.getElement();
|
||||
}
|
||||
|
||||
applyStyles() {
|
||||
// Chat message username styles (required - configured via applyUsername())
|
||||
PluginUtilities.addStyle(
|
||||
"DisplayUsernames-ChatMessage",
|
||||
`
|
||||
/* style username in messages */
|
||||
.hg-username-handle {
|
||||
margin-left: 0.25rem;
|
||||
font-size: 0.75rem;
|
||||
color: ${this.settings.usernamecolor};
|
||||
}
|
||||
/* seperator dot */
|
||||
.hg-username-handle::after {
|
||||
margin-left: 0.5rem;
|
||||
content: "•";
|
||||
color: ${this.settings.seperatorcolor};
|
||||
}
|
||||
/* fix timestamp margin (discord likes to change it randomly) */
|
||||
.roleDot_c01716, .cozy_f5c119 .headerText_f47574, .compact__54ecc .headerText_f47574 {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
/* hide username in command replies */
|
||||
.repliedMessage_f9f2ca > .hg-username-handle {
|
||||
display: none;
|
||||
}
|
||||
/* but dont hide handle in normal replies if user wants them visible */
|
||||
[id*="message-reply-context-"] > .hg-username-handle {
|
||||
margin-left: 0;
|
||||
display: ${this.settings.showinreplies ? "inline" : "none"};
|
||||
}
|
||||
/* change seperator in replies */
|
||||
[id*="message-reply-context-"] > .hg-username-handle::after {
|
||||
margin-left: 0;
|
||||
content: ": ";
|
||||
}
|
||||
`
|
||||
);
|
||||
// Display handle symbol infront of username in profile card/friends list
|
||||
if(this.settings.profilecard) PluginUtilities.addStyle(
|
||||
"DisplayUsernames-ProfileCard",
|
||||
`
|
||||
/* display handle symbol infront of username */
|
||||
span.userTagUsername_c32acf::before, /* profile cards */
|
||||
span.discriminator_f3939d::before /* friends list */ {
|
||||
color: #777;
|
||||
content: "${this.settings.handlesymbol}";
|
||||
}
|
||||
`
|
||||
);
|
||||
// Always display usernames in friends list
|
||||
if(this.settings.friendslist) PluginUtilities.addStyle(
|
||||
"DisplayUsernames-FriendsList",
|
||||
`
|
||||
/* always show username in friends list */
|
||||
.discriminator_f3939d {
|
||||
visibility: visible !important;
|
||||
}
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
removeStyles() {
|
||||
PluginUtilities.removeStyle("DisplayUsernames-ChatMessage");
|
||||
PluginUtilities.removeStyle("DisplayUsernames-ProfileCard");
|
||||
PluginUtilities.removeStyle("DisplayUsernames-FriendsList");
|
||||
}
|
||||
|
||||
applyUsername() {
|
||||
|
||||
const [ module, key ] = BdApi.Webpack.getWithKey(BdApi.Webpack.Filters.byStrings("userOverride", "withMentionPrefix"), { searchExports: false });
|
||||
|
||||
Patcher.after(module, key, (_, args, ret) => {
|
||||
let author = args[0].message.author;
|
||||
let discrim = author.discriminator;
|
||||
// Ensure this is not a webhook or system message
|
||||
if(discrim != "0000")
|
||||
ret.props.children.push(
|
||||
React.createElement("span", { class: "hg-username-handle" }, this.settings.handlesymbol + author.username + (discrim != "0" ? "#" + discrim : ""))
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return plugin;
|
||||
|
||||
})(global.ZeresPluginLibrary.buildPlugin(config));
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"version": "0.1.0"
|
||||
}
|
||||
@@ -1,277 +0,0 @@
|
||||
/**
|
||||
* @name DoNotTrack
|
||||
* @description Stops Discord from tracking everything you do like Sentry and Analytics.
|
||||
* @version 0.1.0
|
||||
* @author Zerebos
|
||||
* @authorId 249746236008169473
|
||||
* @website https://github.com/zerebos/BetterDiscordAddons/tree/master/Plugins/DoNotTrack
|
||||
* @source https://raw.githubusercontent.com/zerebos/BetterDiscordAddons/master/Plugins/DoNotTrack/DoNotTrack.plugin.js
|
||||
*/
|
||||
|
||||
/*@cc_on
|
||||
@if (@_jscript)
|
||||
|
||||
// Offer to self-install for clueless users that try to run this directly.
|
||||
var shell = WScript.CreateObject("WScript.Shell");
|
||||
var fs = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\\BetterDiscord\\plugins");
|
||||
var pathSelf = WScript.ScriptFullName;
|
||||
// Put the user at ease by addressing them in the first person
|
||||
shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30);
|
||||
if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) {
|
||||
shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40);
|
||||
} else if (!fs.FolderExists(pathPlugins)) {
|
||||
shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10);
|
||||
} else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) {
|
||||
fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true);
|
||||
// Show the user where to put plugins in the future
|
||||
shell.Exec("explorer " + pathPlugins);
|
||||
shell.Popup("I'm installed!", 0, "Successfully installed", 0x40);
|
||||
}
|
||||
WScript.Quit();
|
||||
|
||||
@else@*/
|
||||
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/plugins/DoNotTrack/index.ts
|
||||
var DoNotTrack_exports = {};
|
||||
__export(DoNotTrack_exports, {
|
||||
default: () => DoNotTrack
|
||||
});
|
||||
module.exports = __toCommonJS(DoNotTrack_exports);
|
||||
|
||||
// src/common/plugin.ts
|
||||
var Plugin = class {
|
||||
meta;
|
||||
manifest;
|
||||
settings;
|
||||
defaultSettings;
|
||||
LocaleManager;
|
||||
get strings() {
|
||||
if (!this.manifest.strings) return {};
|
||||
const locale = this.LocaleManager?.getLocale().split("-")[0] ?? "en";
|
||||
if (this.manifest.strings.hasOwnProperty(locale)) return this.manifest.strings[locale];
|
||||
if (this.manifest.strings.hasOwnProperty("en")) return this.manifest.strings.en;
|
||||
return this.manifest.strings;
|
||||
}
|
||||
constructor(meta, zplConfig) {
|
||||
this.meta = meta;
|
||||
this.manifest = zplConfig;
|
||||
if (typeof this.manifest.config !== "undefined") {
|
||||
this.defaultSettings = {};
|
||||
for (let s = 0; s < this.manifest.config.length; s++) {
|
||||
const current = this.manifest.config[s];
|
||||
if (current.type != "category") {
|
||||
this.defaultSettings[current.id] = current.value;
|
||||
} else {
|
||||
for (let si = 0; si < current.settings.length; si++) {
|
||||
const subCurrent = current.settings[si];
|
||||
this.defaultSettings[subCurrent.id] = subCurrent.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.settings = BdApi.Utils.extend({}, this.defaultSettings);
|
||||
}
|
||||
const currentVersionInfo = BdApi.Data.load(this.meta.name, "version");
|
||||
if (currentVersionInfo !== this.meta.version) {
|
||||
this.#showChangelog();
|
||||
BdApi.Data.save(this.meta.name, "version", this.meta.version);
|
||||
}
|
||||
if (this.manifest.strings) this.LocaleManager = BdApi.Webpack.getModule((m) => m?.Messages && Object.keys(m?.Messages).length > 0);
|
||||
if (this.manifest.config && !this.getSettingsPanel) {
|
||||
this.getSettingsPanel = () => {
|
||||
this.#updateConfig();
|
||||
return BdApi.UI.buildSettingsPanel({
|
||||
onChange: (_, id, value) => {
|
||||
this.settings[id] = value;
|
||||
this.saveSettings();
|
||||
},
|
||||
settings: this.manifest.config
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
async start() {
|
||||
BdApi.Logger.info(this.meta.name, `version ${this.meta.version} has started.`);
|
||||
if (this.defaultSettings) this.settings = this.loadSettings();
|
||||
if (typeof this.onStart == "function") this.onStart();
|
||||
}
|
||||
stop() {
|
||||
BdApi.Logger.info(this.meta.name, `version ${this.meta.version} has stopped.`);
|
||||
if (typeof this.onStop == "function") this.onStop();
|
||||
}
|
||||
#showChangelog() {
|
||||
if (typeof this.manifest.changelog == "undefined") return;
|
||||
const changelog = {
|
||||
title: this.meta.name + " Changelog",
|
||||
subtitle: `v${this.meta.version}`,
|
||||
changes: []
|
||||
};
|
||||
if (!Array.isArray(this.manifest.changelog)) Object.assign(changelog, this.manifest.changelog);
|
||||
else changelog.changes = this.manifest.changelog;
|
||||
BdApi.UI.showChangelogModal(changelog);
|
||||
}
|
||||
saveSettings() {
|
||||
BdApi.Data.save(this.meta.name, "settings", this.settings);
|
||||
}
|
||||
loadSettings() {
|
||||
return BdApi.Utils.extend({}, this.defaultSettings ?? {}, BdApi.Data.load(this.meta.name, "settings"));
|
||||
}
|
||||
#updateConfig() {
|
||||
if (!this.manifest.config) return;
|
||||
for (const setting of this.manifest.config) {
|
||||
if (setting.type !== "category") {
|
||||
setting.value = this.settings[setting.id] ?? setting.value;
|
||||
} else {
|
||||
for (const subsetting of setting.settings) {
|
||||
subsetting.value = this.settings[subsetting.id] ?? subsetting.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
buildSettingsPanel(onChange) {
|
||||
this.#updateConfig();
|
||||
return BdApi.UI.buildSettingsPanel({
|
||||
onChange: (groupId, id, value) => {
|
||||
this.settings[id] = value;
|
||||
onChange?.(groupId, id, value);
|
||||
this.saveSettings();
|
||||
},
|
||||
settings: this.manifest.config
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// src/plugins/DoNotTrack/config.ts
|
||||
var manifest = {
|
||||
info: {
|
||||
name: "DoNotTrack",
|
||||
authors: [{
|
||||
name: "Zerebos",
|
||||
discord_id: "249746236008169473",
|
||||
github_username: "zerebos",
|
||||
twitter_username: "IAmZerebos"
|
||||
}],
|
||||
version: "0.1.0",
|
||||
description: "Stops Discord from tracking everything you do like Sentry and Analytics.",
|
||||
github: "https://github.com/zerebos/BetterDiscordAddons/tree/master/Plugins/DoNotTrack",
|
||||
github_raw: "https://raw.githubusercontent.com/zerebos/BetterDiscordAddons/master/Plugins/DoNotTrack/DoNotTrack.plugin.js"
|
||||
},
|
||||
changelog: [
|
||||
{
|
||||
title: "What's New?",
|
||||
type: "added",
|
||||
items: [
|
||||
"Plugin no longer relies on ZeresPluginLibrary!",
|
||||
"DoNotTrack should be more resilient to Discord's changes."
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Fixes",
|
||||
type: "fixed",
|
||||
items: [
|
||||
"Fixed startup issues.",
|
||||
"Hopefully fixed issues with the process monitor."
|
||||
]
|
||||
}
|
||||
],
|
||||
main: "index.ts",
|
||||
config: [
|
||||
{
|
||||
type: "switch",
|
||||
id: "stopProcessMonitor",
|
||||
name: "Stop Process Monitor",
|
||||
note: "This setting stops Discord from monitoring the processes on your PC and prevents your currently played game from showing.",
|
||||
value: true
|
||||
}
|
||||
]
|
||||
};
|
||||
var config_default = manifest;
|
||||
|
||||
// src/plugins/DoNotTrack/index.ts
|
||||
var { Patcher, Webpack, UI } = BdApi;
|
||||
var SettingsManager = Webpack.getModule((m) => m?.updateAsync && m?.type === 1, { searchExports: true });
|
||||
var BoolSetting = Webpack.getModule((m) => m?.typeName?.includes("Bool"), { searchExports: true });
|
||||
var Analytics = Webpack.getByKeys("AnalyticEventConfigs");
|
||||
var NativeModule = Webpack.getByKeys("getDiscordUtils");
|
||||
var DoNotTrack = class extends Plugin {
|
||||
constructor(meta) {
|
||||
super(meta, config_default);
|
||||
}
|
||||
onStart() {
|
||||
if (Analytics) {
|
||||
Patcher.instead(this.meta.name, Analytics.default, "track", () => {
|
||||
});
|
||||
}
|
||||
if (NativeModule) {
|
||||
Patcher.instead(this.meta.name, NativeModule, "ensureModule", (_, [moduleName], originalFunction) => {
|
||||
if (moduleName?.includes("discord_rpc")) return;
|
||||
return originalFunction(moduleName);
|
||||
});
|
||||
}
|
||||
window?.__SENTRY__?.globalEventProcessors?.splice(0, window?.__SENTRY__?.globalEventProcessors?.length);
|
||||
window?.__SENTRY__?.logger?.disable();
|
||||
const SentryHub = window.DiscordSentry?.getCurrentHub?.();
|
||||
if (SentryHub) {
|
||||
SentryHub.getClient()?.close?.(0);
|
||||
const scope = SentryHub.getScope();
|
||||
scope?.clear?.();
|
||||
scope?.setFingerprint?.(null);
|
||||
SentryHub?.setUser(null);
|
||||
SentryHub?.setTags({});
|
||||
SentryHub?.setExtras({});
|
||||
SentryHub?.endSession();
|
||||
}
|
||||
for (const method in console) {
|
||||
if (!Object.hasOwn(console[method], "__sentry_original__")) continue;
|
||||
console[method] = console[method].__sentry_original__;
|
||||
}
|
||||
if (this.settings.stopProcessMonitor) this.disableProcessMonitor();
|
||||
}
|
||||
onStop() {
|
||||
Patcher.unpatchAll(this.meta.name);
|
||||
}
|
||||
disableProcessMonitor() {
|
||||
SettingsManager?.updateAsync("status", (settings) => settings.showCurrentGame = BoolSetting?.create({ value: false }), 0);
|
||||
const DiscordUtils = NativeModule?.getDiscordUtils();
|
||||
if (!DiscordUtils) return UI.alert("DoNotTrack", "Unable to disable process monitor!");
|
||||
DiscordUtils.setObservedGamesCallback([], () => {
|
||||
});
|
||||
Patcher.instead(this.meta.name, DiscordUtils, "setObservedGamesCallback", () => {
|
||||
});
|
||||
}
|
||||
enableProcessMonitor() {
|
||||
SettingsManager?.updateAsync("status", (settings) => settings.showCurrentGame = BoolSetting?.create({ value: true }), 0);
|
||||
UI.showConfirmationModal("Reload Discord?", "To reenable the process monitor Discord needs to be reloaded.", {
|
||||
confirmText: "Reload",
|
||||
cancelText: "Later",
|
||||
onConfirm: () => window.location.reload()
|
||||
});
|
||||
}
|
||||
getSettingsPanel() {
|
||||
return this.buildSettingsPanel((_, id, value) => {
|
||||
if (id !== "stopProcessMonitor") return;
|
||||
if (value) return this.disableProcessMonitor();
|
||||
return this.enableProcessMonitor();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*@end@*/
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"cachedState": {
|
||||
"date": "2026-01-24T10:37:57.110Z",
|
||||
"value": false
|
||||
},
|
||||
"general": {
|
||||
"showButton": true,
|
||||
"showItem": false,
|
||||
"playEnable": true,
|
||||
"playDisable": true
|
||||
},
|
||||
"selections": {
|
||||
"enableSound": "stream_started",
|
||||
"disableSound": "stream_ended"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,493 +0,0 @@
|
||||
/**
|
||||
* @name GameActivityToggle
|
||||
* @author DevilBro
|
||||
* @authorId 278543574059057154
|
||||
* @version 1.4.0
|
||||
* @description Adds a Quick-Toggle Game Activity Button
|
||||
* @invite Jx3TjNS
|
||||
* @donate https://www.paypal.me/MircoWittrien
|
||||
* @patreon https://www.patreon.com/MircoWittrien
|
||||
* @website https://mwittrien.github.io/
|
||||
* @source https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/GameActivityToggle/
|
||||
* @updateUrl https://mwittrien.github.io/BetterDiscordAddons/Plugins/GameActivityToggle/GameActivityToggle.plugin.js
|
||||
*/
|
||||
|
||||
module.exports = (_ => {
|
||||
const changeLog = {
|
||||
|
||||
};
|
||||
|
||||
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
|
||||
constructor (meta) {for (let key in meta) this[key] = meta[key];}
|
||||
getName () {return this.name;}
|
||||
getAuthor () {return this.author;}
|
||||
getVersion () {return this.version;}
|
||||
getDescription () {return `The Library Plugin needed for ${this.name} is missing. Open the Plugin Settings to download it. \n\n${this.description}`;}
|
||||
|
||||
downloadLibrary () {
|
||||
BdApi.Net.fetch("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js").then(r => {
|
||||
if (!r || r.status != 200) throw new Error();
|
||||
else return r.text();
|
||||
}).then(b => {
|
||||
if (!b) throw new Error();
|
||||
else return require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.UI.showToast("Finished downloading BDFDB Library", {type: "success"}));
|
||||
}).catch(error => {
|
||||
BdApi.UI.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
|
||||
});
|
||||
}
|
||||
|
||||
load () {
|
||||
if (!window.BDFDB_Global || !Array.isArray(window.BDFDB_Global.pluginQueue)) window.BDFDB_Global = Object.assign({}, window.BDFDB_Global, {pluginQueue: []});
|
||||
if (!window.BDFDB_Global.downloadModal) {
|
||||
window.BDFDB_Global.downloadModal = true;
|
||||
BdApi.UI.showConfirmationModal("Library Missing", `The Library Plugin needed for ${this.name} is missing. Please click "Download Now" to install it.`, {
|
||||
confirmText: "Download Now",
|
||||
cancelText: "Cancel",
|
||||
onCancel: _ => {delete window.BDFDB_Global.downloadModal;},
|
||||
onConfirm: _ => {
|
||||
delete window.BDFDB_Global.downloadModal;
|
||||
this.downloadLibrary();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!window.BDFDB_Global.pluginQueue.includes(this.name)) window.BDFDB_Global.pluginQueue.push(this.name);
|
||||
}
|
||||
start () {this.load();}
|
||||
stop () {}
|
||||
getSettingsPanel () {
|
||||
let template = document.createElement("template");
|
||||
template.innerHTML = `<div style="color: var(--text-strong); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${this.name} is missing.\nPlease click <a style="font-weight: 500;">Download Now</a> to install it.</div>`;
|
||||
template.content.firstElementChild.querySelector("a").addEventListener("click", this.downloadLibrary);
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
} : (([Plugin, BDFDB]) => {
|
||||
var _this;
|
||||
var toggleButton, toggleItem;
|
||||
|
||||
const ActivityToggleComponent = class ActivityToggle extends BdApi.React.Component {
|
||||
componentDidMount() {
|
||||
toggleButton = this;
|
||||
}
|
||||
render() {
|
||||
const enabled = this.props.forceState != undefined ? this.props.forceState : BDFDB.DiscordUtils.getSetting("status", "showCurrentGame");
|
||||
delete this.props.forceState;
|
||||
return BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN._gameactivitytogglebutton,
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.PanelButton, Object.assign({}, this.props, {
|
||||
redGlow: !enabled,
|
||||
tooltipText: enabled ? _this.labels.disable_activity : _this.labels.enable_activity,
|
||||
icon: iconProps => BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN.lottieicon,
|
||||
style: {
|
||||
"--__lottieIconColor": enabled ? "currentColor" : BDFDB.DiscordConstants.ColorsCSS.STATUS_DANGER,
|
||||
"display": "flex",
|
||||
"width": "20px",
|
||||
"height": "20px"
|
||||
},
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, Object.assign({}, iconProps, {
|
||||
nativeClass: true,
|
||||
width: 20,
|
||||
height: 20,
|
||||
color: "var(--__lottieIconColor)",
|
||||
name: enabled ? BDFDB.LibraryComponents.SvgIcon.Names.GAMEPAD : BDFDB.LibraryComponents.SvgIcon.Names.GAMEPAD_DISABLED
|
||||
}))
|
||||
}),
|
||||
onClick: _ => {
|
||||
_this.toggle();
|
||||
if (toggleItem) BDFDB.ReactUtils.forceUpdate(toggleItem);
|
||||
}
|
||||
}))
|
||||
}, true);
|
||||
}
|
||||
};
|
||||
|
||||
const ActivityToggleItemComponent = class ActivityToggleItem extends BdApi.React.Component {
|
||||
componentDidMount() {
|
||||
toggleItem = this;
|
||||
}
|
||||
componentWillUnmount() {
|
||||
toggleItem = null;
|
||||
}
|
||||
render() {
|
||||
const enabled = this.props.forceState != undefined ? this.props.forceState : BDFDB.DiscordUtils.getSetting("status", "showCurrentGame");
|
||||
delete this.props.forceState;
|
||||
return BDFDB.ReactUtils.createElement("li", {
|
||||
className: BDFDB.disCN.userpopoutmenuitem,
|
||||
children: BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN.userpopoutmenuiteminner,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, {
|
||||
className: BDFDB.disCN.userpopoutmenuitemcontent,
|
||||
onClick: _ => {
|
||||
_this.toggle();
|
||||
if (toggleButton) BDFDB.ReactUtils.forceUpdate(toggleButton);
|
||||
},
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
|
||||
className: BDFDB.disCN.userpopoutmenuitemicon,
|
||||
name: BDFDB.LibraryComponents.SvgIcon.Names.GAMEPAD,
|
||||
nativeClass: true,
|
||||
width: 16,
|
||||
height: 16
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN.userpopoutmenuitemlabel,
|
||||
children: BDFDB.ReactUtils.createElement("div", {
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextElement, {
|
||||
className: BDFDB.disCN.userpopoutmenuitemlabel,
|
||||
size: BDFDB.LibraryComponents.TextElement.Sizes.SIZE_14,
|
||||
children: BDFDB.LanguageUtils.LanguageStrings.GAME_ACTIVITY
|
||||
})
|
||||
})
|
||||
})
|
||||
]
|
||||
}),
|
||||
enabled ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
|
||||
className: BDFDB.disCN.menucolordefault,
|
||||
background: BDFDB.disCN.menucheckbox,
|
||||
foreground: BDFDB.disCN.menucheck,
|
||||
name: BDFDB.LibraryComponents.SvgIcon.Names.CHECKBOX,
|
||||
style: {background: "unset"}
|
||||
}) : BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
|
||||
className: BDFDB.disCN.menucolordefault,
|
||||
name: BDFDB.LibraryComponents.SvgIcon.Names.CHECKBOX_EMPTY,
|
||||
style: {background: "unset"}
|
||||
})
|
||||
]
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var sounds = [], keybind;
|
||||
|
||||
return class GameActivityToggle extends Plugin {
|
||||
onLoad () {
|
||||
_this = this;
|
||||
|
||||
this.defaults = {
|
||||
general: {
|
||||
showButton: {value: true, description: "Show Quick Toggle Button"},
|
||||
showItem: {value: false, description: "Show Quick Toggle Item"},
|
||||
playEnable: {value: true, description: "Play Enable Sound"},
|
||||
playDisable: {value: true, description: "Play Disable Sound"}
|
||||
},
|
||||
selections: {
|
||||
enableSound: {value: "stream_started", description: "Enable Sound"},
|
||||
disableSound: {value: "stream_ended", description: "Disable Sound"}
|
||||
}
|
||||
};
|
||||
|
||||
this.modulePatches = {
|
||||
after: [
|
||||
"Account",
|
||||
"UserProfile"
|
||||
]
|
||||
};
|
||||
|
||||
this.css = `
|
||||
${BDFDB.dotCNS._gameactivitytoggleadded + BDFDB.dotCN._gameactivitytogglebutton} {
|
||||
margin-right: 4px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
onStart () {
|
||||
sounds = [BDFDB.LibraryModules.SoundParser && BDFDB.LibraryModules.SoundParser.keys()].flat(10).filter(n => n).map(s => s.replace("./", "").split(".")[0]).sort();
|
||||
|
||||
let cachedState = BDFDB.DataUtils.load(this, "cachedState");
|
||||
let state = BDFDB.DiscordUtils.getSetting("status", "showCurrentGame");
|
||||
if (!cachedState.date || (new Date() - cachedState.date) > 1000*60*60*24*3) {
|
||||
cachedState.value = state;
|
||||
cachedState.date = new Date();
|
||||
BDFDB.DataUtils.save(cachedState, this, "cachedState");
|
||||
}
|
||||
else if (cachedState.value != null && cachedState.value != state) BDFDB.DiscordUtils.setSetting("status", "showCurrentGame", cachedState.value);
|
||||
|
||||
let SettingsStore = BDFDB.DiscordUtils.getSettingsStore();
|
||||
if (SettingsStore) BDFDB.PatchUtils.patch(this, SettingsStore, "updateAsync", {after: e => {
|
||||
if (e.methodArguments[0] != "status") return;
|
||||
let newSettings = {value: undefined};
|
||||
e.methodArguments[1](newSettings);
|
||||
if (newSettings.showCurrentGame != undefined) {
|
||||
if (toggleButton) toggleButton.props.forceState = newSettings.showCurrentGame.value;
|
||||
BDFDB.ReactUtils.forceUpdate(toggleButton);
|
||||
if (toggleItem) toggleItem.props.forceState = newSettings.showCurrentGame.value;
|
||||
BDFDB.ReactUtils.forceUpdate(toggleItem);
|
||||
BDFDB.DataUtils.save({date: new Date(), value: newSettings.showCurrentGame.value}, this, "cachedState");
|
||||
}
|
||||
}});
|
||||
|
||||
keybind = BDFDB.DataUtils.load(this, "keybind");
|
||||
keybind = BDFDB.ArrayUtils.is(keybind) ? keybind : [];
|
||||
this.activateKeybind();
|
||||
|
||||
BDFDB.DiscordUtils.rerenderAll();
|
||||
}
|
||||
|
||||
onStop () {
|
||||
BDFDB.DiscordUtils.rerenderAll();
|
||||
}
|
||||
|
||||
getSettingsPanel (collapseStates = {}) {
|
||||
let settingsPanel;
|
||||
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, {
|
||||
collapseStates: collapseStates,
|
||||
children: _ => {
|
||||
let settingsItems = [];
|
||||
|
||||
for (let key in this.defaults.general) settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Switch",
|
||||
plugin: this,
|
||||
keys: ["general", key],
|
||||
label: this.defaults.general[key].description,
|
||||
value: this.settings.general[key]
|
||||
}));
|
||||
|
||||
for (let key in this.defaults.selections) settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Select",
|
||||
plugin: this,
|
||||
keys: ["selections", key],
|
||||
label: this.defaults.selections[key].description,
|
||||
basis: "50%",
|
||||
options: sounds.map(o => ({value: o, label: o.split(/[-_]/g).map(BDFDB.StringUtils.upperCaseFirstChar).join(" ")})),
|
||||
value: this.settings.selections[key],
|
||||
onChange: value => BDFDB.LibraryModules.SoundUtils.playSound(value, .4)
|
||||
}));
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN.settingsrowcontainer,
|
||||
children: BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN.settingsrowlabel,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsLabel, {
|
||||
label: "Global Hotkey"
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
className: BDFDB.disCNS.settingsrowcontrol + BDFDB.disCN.flexchild,
|
||||
grow: 0,
|
||||
wrap: true,
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.KeybindRecorder, {
|
||||
value: !keybind ? [] : keybind,
|
||||
reset: true,
|
||||
onChange: value => {
|
||||
keybind = value;
|
||||
BDFDB.DataUtils.save(keybind, this, "keybind")
|
||||
this.activateKeybind();
|
||||
}
|
||||
})
|
||||
})
|
||||
].flat(10).filter(n => n)
|
||||
})
|
||||
}));
|
||||
|
||||
return settingsItems;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
processAccount (e) {
|
||||
if (!this.settings.general.showButton) return;
|
||||
let insertButton = returnvalue => {
|
||||
let accountinfo = BDFDB.ReactUtils.findChild(returnvalue, {props: [["className", BDFDB.disCN.accountinfo]]});
|
||||
if (!accountinfo) return;
|
||||
let buttons = BDFDB.ReactUtils.findChild(returnvalue, {props: [["className", BDFDB.disCN.accountinfobuttons]]});
|
||||
if (buttons) {
|
||||
accountinfo.props.className = BDFDB.DOMUtils.formatClassName(accountinfo.props.className, BDFDB.disCN._gameactivitytoggleadded);
|
||||
buttons.props.children.unshift(BDFDB.ReactUtils.createElement(ActivityToggleComponent, {}));
|
||||
}
|
||||
else {
|
||||
let [children, index] = BDFDB.ReactUtils.findParent(returnvalue, {name: "AccountButtons"});
|
||||
if (index > -1) {
|
||||
accountinfo.props.className = BDFDB.DOMUtils.formatClassName(accountinfo.props.className, BDFDB.disCN._gameactivitytoggleadded);
|
||||
children.splice(index, 0, BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN.accountinfobuttons,
|
||||
children: BDFDB.ReactUtils.createElement(ActivityToggleComponent, {})
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
if (e.returnvalue.props.children && e.returnvalue.props.children[0] && e.returnvalue.props.children[0].props && typeof e.returnvalue.props.children[0].props.children == "function") {
|
||||
let childrenRender = e.returnvalue.props.children[0].props.children;
|
||||
e.returnvalue.props.children[0].props.children = BDFDB.TimeUtils.suppress((...args) => {
|
||||
let renderedChildren = childrenRender(...args);
|
||||
insertButton(renderedChildren);
|
||||
return renderedChildren;
|
||||
}, "Error in Children Render in Account!", this);
|
||||
}
|
||||
else if (typeof e.returnvalue.props.children[0] == "function") {
|
||||
let childrenRender = e.returnvalue.props.children;
|
||||
e.returnvalue.props.children = BDFDB.TimeUtils.suppress((...args) => {
|
||||
let renderedChildren = childrenRender(...args);
|
||||
insertButton(renderedChildren);
|
||||
return renderedChildren;
|
||||
}, "Error in Children Render in Account!", this);
|
||||
}
|
||||
else insertButton(e.returnvalue.props.children);
|
||||
}
|
||||
|
||||
processUserProfile (e) {
|
||||
if (!this.settings.general.showItem) return;
|
||||
let userpopoutMenus = BDFDB.ReactUtils.findChild(e.returnvalue, {props: [["className", BDFDB.disCN.userpopoutmenus]]});
|
||||
if (!userpopoutMenus) return;
|
||||
userpopoutMenus.props.children.splice(1, 0, BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCNS.userpopoutoverlay + BDFDB.disCN.userpopoutmenuoverlay,
|
||||
children: BDFDB.ReactUtils.createElement("ul", {
|
||||
children: BDFDB.ReactUtils.createElement(ActivityToggleItemComponent, {})
|
||||
})
|
||||
}));
|
||||
}
|
||||
|
||||
activateKeybind () {
|
||||
if (keybind && keybind.length) BDFDB.ListenerUtils.addGlobal(this, "GAMEACTIVITY_TOGGLE", keybind, _ => this.toggle());
|
||||
else BDFDB.ListenerUtils.removeGlobal(this, "GAMEACTIVITY_TOGGLE");
|
||||
}
|
||||
|
||||
toggle () {
|
||||
const shouldEnable = !BDFDB.DiscordUtils.getSetting("status", "showCurrentGame");
|
||||
this.settings.general[shouldEnable ? "playEnable" : "playDisable"] && BDFDB.LibraryModules.SoundUtils.playSound(this.settings.selections[shouldEnable ? "enableSound" : "disableSound"], .4);
|
||||
BDFDB.DiscordUtils.setSetting("status", "showCurrentGame", shouldEnable);
|
||||
}
|
||||
|
||||
setLabelsByLanguage () {
|
||||
switch (BDFDB.LanguageUtils.getLanguage().id) {
|
||||
case "bg": // Bulgarian
|
||||
return {
|
||||
disable_activity: "Деактивирайте активността в играта",
|
||||
enable_activity: "Активирайте Game Activity"
|
||||
};
|
||||
case "da": // Danish
|
||||
return {
|
||||
disable_activity: "Deaktiver spilaktivitet",
|
||||
enable_activity: "Aktivér spilaktivitet"
|
||||
};
|
||||
case "de": // German
|
||||
return {
|
||||
disable_activity: "Spieleaktivität deaktivieren",
|
||||
enable_activity: "Spieleaktivität aktivieren"
|
||||
};
|
||||
case "el": // Greek
|
||||
return {
|
||||
disable_activity: "Απενεργοποίηση δραστηριότητας παιχνιδιού",
|
||||
enable_activity: "Ενεργοποίηση δραστηριότητας παιχνιδιού"
|
||||
};
|
||||
case "es": // Spanish
|
||||
return {
|
||||
disable_activity: "Deshabilitar la actividad del juego",
|
||||
enable_activity: "Habilitar la actividad del juego"
|
||||
};
|
||||
case "fi": // Finnish
|
||||
return {
|
||||
disable_activity: "Poista pelitoiminto käytöstä",
|
||||
enable_activity: "Ota pelitoiminta käyttöön"
|
||||
};
|
||||
case "fr": // French
|
||||
return {
|
||||
disable_activity: "Désactiver l'activité de jeu",
|
||||
enable_activity: "Activer l'activité de jeu"
|
||||
};
|
||||
case "hr": // Croatian
|
||||
return {
|
||||
disable_activity: "Onemogući aktivnost igre",
|
||||
enable_activity: "Omogući aktivnost u igrama"
|
||||
};
|
||||
case "hu": // Hungarian
|
||||
return {
|
||||
disable_activity: "Tiltsa le a játéktevékenységet",
|
||||
enable_activity: "Engedélyezze a játéktevékenységet"
|
||||
};
|
||||
case "it": // Italian
|
||||
return {
|
||||
disable_activity: "Disabilita l'attività di gioco",
|
||||
enable_activity: "Abilita attività di gioco"
|
||||
};
|
||||
case "ja": // Japanese
|
||||
return {
|
||||
disable_activity: "ゲームアクティビティを無効にする",
|
||||
enable_activity: "ゲームアクティビティを有効にする"
|
||||
};
|
||||
case "ko": // Korean
|
||||
return {
|
||||
disable_activity: "게임 활동 비활성화",
|
||||
enable_activity: "게임 활동 활성화"
|
||||
};
|
||||
case "lt": // Lithuanian
|
||||
return {
|
||||
disable_activity: "Išjungti žaidimų veiklą",
|
||||
enable_activity: "Įgalinti žaidimų veiklą"
|
||||
};
|
||||
case "nl": // Dutch
|
||||
return {
|
||||
disable_activity: "Schakel spelactiviteit uit",
|
||||
enable_activity: "Schakel spelactiviteit in"
|
||||
};
|
||||
case "no": // Norwegian
|
||||
return {
|
||||
disable_activity: "Deaktiver spillaktivitet",
|
||||
enable_activity: "Aktiver spillaktivitet"
|
||||
};
|
||||
case "pl": // Polish
|
||||
return {
|
||||
disable_activity: "Wyłącz aktywność w grach",
|
||||
enable_activity: "Włącz aktywność w grach"
|
||||
};
|
||||
case "pt-BR": // Portuguese (Brazil)
|
||||
return {
|
||||
disable_activity: "Desativar atividade de jogo",
|
||||
enable_activity: "Habilitar atividade de jogo"
|
||||
};
|
||||
case "ro": // Romanian
|
||||
return {
|
||||
disable_activity: "Dezactivați Activitatea jocului",
|
||||
enable_activity: "Activați Activitatea jocului"
|
||||
};
|
||||
case "ru": // Russian
|
||||
return {
|
||||
disable_activity: "Отключить игровую активность",
|
||||
enable_activity: "Включить игровую активность"
|
||||
};
|
||||
case "sv": // Swedish
|
||||
return {
|
||||
disable_activity: "Inaktivera spelaktivitet",
|
||||
enable_activity: "Aktivera spelaktivitet"
|
||||
};
|
||||
case "th": // Thai
|
||||
return {
|
||||
disable_activity: "ปิดการใช้งานกิจกรรมของเกม",
|
||||
enable_activity: "เปิดใช้งานกิจกรรมเกม"
|
||||
};
|
||||
case "tr": // Turkish
|
||||
return {
|
||||
disable_activity: "Oyun Etkinliğini Devre Dışı Bırak",
|
||||
enable_activity: "Oyun Etkinliğini Etkinleştir"
|
||||
};
|
||||
case "uk": // Ukrainian
|
||||
return {
|
||||
disable_activity: "Вимкнути ігрову активність",
|
||||
enable_activity: "Увімкнути ігрову активність"
|
||||
};
|
||||
case "vi": // Vietnamese
|
||||
return {
|
||||
disable_activity: "Tắt hoạt động trò chơi",
|
||||
enable_activity: "Bật hoạt động trò chơi"
|
||||
};
|
||||
case "zh-CN": // Chinese (China)
|
||||
return {
|
||||
disable_activity: "禁用游戏活动",
|
||||
enable_activity: "启用游戏活动"
|
||||
};
|
||||
case "zh-TW": // Chinese (Taiwan)
|
||||
return {
|
||||
disable_activity: "禁用遊戲活動",
|
||||
enable_activity: "啟用遊戲活動"
|
||||
};
|
||||
default: // English
|
||||
return {
|
||||
disable_activity: "Disable Game Activity",
|
||||
enable_activity: "Enable Game Activity"
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));
|
||||
})();
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.0.1",
|
||||
"hasShownChangelog": true
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.1.13",
|
||||
"hasShownChangelog": true
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.2.3",
|
||||
"hasShownChangelog": true
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
/**
|
||||
* @name InMyVoice
|
||||
* @author arg0NNY
|
||||
* @authorLink https://github.com/arg0NNY/DiscordPlugins
|
||||
* @invite M8DBtcZjXD
|
||||
* @donate https://donationalerts.com/r/arg0nny
|
||||
* @version 1.2.3
|
||||
* @description Shows if a person in the text chat is also in a voice chat you're in.
|
||||
* @website https://github.com/arg0NNY/DiscordPlugins/tree/master/InMyVoice
|
||||
* @source https://github.com/arg0NNY/DiscordPlugins/blob/master/InMyVoice/InMyVoice.plugin.js
|
||||
* @updateUrl https://raw.githubusercontent.com/arg0NNY/DiscordPlugins/master/InMyVoice/InMyVoice.plugin.js
|
||||
* @runAt idle
|
||||
*/
|
||||
|
||||
/* ### CONFIG START ### */
|
||||
const config = {
|
||||
info: {
|
||||
name: 'InMyVoice',
|
||||
version: '1.2.3',
|
||||
description: 'Shows if a person in the text chat is also in a voice chat you\'re in.'
|
||||
},
|
||||
changelog: [
|
||||
{
|
||||
type: 'fixed',
|
||||
title: 'Fixes',
|
||||
items: [
|
||||
'Updated to work in the latest release of Discord.'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
/* ### CONFIG END ### */
|
||||
|
||||
const {
|
||||
Webpack,
|
||||
UI,
|
||||
React,
|
||||
Patcher,
|
||||
Utils,
|
||||
Data
|
||||
} = new BdApi(config.info.name)
|
||||
|
||||
const UserStore = Webpack.getStore('UserStore')
|
||||
const ChannelStore = Webpack.getStore('ChannelStore')
|
||||
const SelectedChannelStore = Webpack.getStore('SelectedChannelStore')
|
||||
|
||||
const findInReactTree = (tree, searchFilter) => Utils.findInTree(tree, searchFilter, { walkable: ['props', 'children', 'child', 'sibling'] })
|
||||
|
||||
const Selectors = {
|
||||
BotTag: {
|
||||
botTagCozy: Webpack.getByKeys('botTagCozy').botTagCozy,
|
||||
botTagVerified: Webpack.getByKeys('botTagVerified').botTagVerified
|
||||
}
|
||||
}
|
||||
|
||||
const UNIQUE_TAG = 'InMyVoiceTag'
|
||||
|
||||
const VoiceChannelStore = Webpack.getByKeys('getVoiceStatesForChannel')
|
||||
const MessageHeader = [...Webpack.getWithKey(Webpack.Filters.byStrings('decorations', 'withMentionPrefix'))]
|
||||
const BotTag = [...Webpack.getWithKey(m => m?.Types?.SYSTEM_DM)]
|
||||
const useStateFromStores = Webpack.getModule(Webpack.Filters.byStrings('useStateFromStores'), { searchExports: true })
|
||||
|
||||
function isInMyVoice (user) {
|
||||
const voiceChannelId = useStateFromStores([SelectedChannelStore], () => SelectedChannelStore.getVoiceChannelId())
|
||||
const currentUser = useStateFromStores([UserStore], () => UserStore.getCurrentUser())
|
||||
const channel = useStateFromStores([ChannelStore], () => voiceChannelId && ChannelStore.getChannel(voiceChannelId))
|
||||
const voiceState = useStateFromStores([VoiceChannelStore], () => channel && VoiceChannelStore.getVoiceStatesForChannel(channel))
|
||||
|
||||
if (currentUser.id === user.id || !channel) return false
|
||||
|
||||
const values = Object.values(voiceState)
|
||||
return values.findIndex(x => x.user?.id === user.id) !== -1
|
||||
}
|
||||
|
||||
function InVoiceTag ({ user }) {
|
||||
if (!isInMyVoice(user)) return null
|
||||
|
||||
return React.createElement(BotTag[0][BotTag[1]], {
|
||||
className: `${Selectors.BotTag.botTagCozy} ${UNIQUE_TAG}`,
|
||||
useRemSizes: true,
|
||||
type: 'IN_VOICE'
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = class InMyVoice {
|
||||
start () {
|
||||
this.patches()
|
||||
}
|
||||
|
||||
patches () {
|
||||
this.patchMessages()
|
||||
this.patchBotTags()
|
||||
}
|
||||
|
||||
patchMessages () {
|
||||
Patcher.before(...MessageHeader, (self, [{ decorations, message }]) => {
|
||||
if (!decorations || typeof decorations[1] !== 'object' || !'length' in decorations[1]) return
|
||||
|
||||
decorations[1].unshift(
|
||||
React.createElement(InVoiceTag, { user: message.author })
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
patchBotTags () {
|
||||
Patcher.after(...BotTag, (self, _, value) => {
|
||||
if (!value?.props?.className?.includes(UNIQUE_TAG)) return
|
||||
|
||||
const TagContainer = findInReactTree(value, e => e.children?.some(c => typeof c?.props?.children === 'string'))
|
||||
|
||||
TagContainer.children.find(c => typeof c?.props?.children === 'string').props.children = this.settings.text.toUpperCase()
|
||||
TagContainer.children.unshift(this.buildInVoiceIcon())
|
||||
})
|
||||
}
|
||||
|
||||
buildInVoiceIcon () {
|
||||
return React.createElement(
|
||||
'svg',
|
||||
{
|
||||
className: Selectors.BotTag.botTagVerified,
|
||||
width: 16,
|
||||
height: 16,
|
||||
viewBox: '0 0 28 28',
|
||||
style: {
|
||||
position: 'relative',
|
||||
top: '1px',
|
||||
left: '1px',
|
||||
marginRight: '1px'
|
||||
}
|
||||
},
|
||||
React.createElement('path', {
|
||||
fill: 'currentColor',
|
||||
d: 'M3 10v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71V6.41c0-.89-1.08-1.34-1.71-.71L7 9H4c-.55 0-1 .45-1 1zm13.5 2c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 4.45v.2c0 .38.25.71.6.85C17.18 6.53 19 9.06 19 12s-1.82 5.47-4.4 6.5c-.36.14-.6.47-.6.85v.2c0 .63.63 1.07 1.21.85C18.6 19.11 21 15.84 21 12s-2.4-7.11-5.79-8.4c-.58-.23-1.21.22-1.21.85z'
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
stop () {
|
||||
Patcher.unpatchAll()
|
||||
}
|
||||
|
||||
constructor () {
|
||||
this.defaultSettings = {
|
||||
text: 'In voice'
|
||||
}
|
||||
|
||||
this.settings = this.loadSettings(this.defaultSettings)
|
||||
|
||||
this.showChangelogIfNeeded()
|
||||
}
|
||||
|
||||
loadSettings (defaults = {}) {
|
||||
return Utils.extend({}, defaults, Data.load('settings'))
|
||||
}
|
||||
saveSettings (settings = this.settings) {
|
||||
return Data.save('settings', settings)
|
||||
}
|
||||
|
||||
showChangelogIfNeeded () {
|
||||
const currentVersionInfo = Utils.extend(
|
||||
{ version: config.info.version, hasShownChangelog: false },
|
||||
Data.load('currentVersionInfo')
|
||||
)
|
||||
if (currentVersionInfo.version === config.info.version && currentVersionInfo.hasShownChangelog) return
|
||||
|
||||
this.showChangelog()
|
||||
Data.save('currentVersionInfo', { version: config.info.version, hasShownChangelog: true })
|
||||
}
|
||||
showChangelog () {
|
||||
return UI.showChangelogModal({
|
||||
title: config.info.name,
|
||||
subtitle: 'Version ' + config.info.version,
|
||||
changes: config.changelog
|
||||
})
|
||||
}
|
||||
|
||||
getSettingsPanel () {
|
||||
return UI.buildSettingsPanel({
|
||||
onChange: () => this.saveSettings(),
|
||||
settings: [
|
||||
{
|
||||
type: 'text',
|
||||
id: 'text',
|
||||
name: 'Tag Text',
|
||||
note: 'Sets up tag\'s text near user\'s name.',
|
||||
value: this.settings.text,
|
||||
onChange: e => this.settings.text = e
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"lastVersion": "2.0.15"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,420 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"choices": {
|
||||
"activity_end": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"activity_launch": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"activity_user_join": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"activity_user_left": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"call_calling": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": null,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"call_ringing": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": null,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"call_ringing_snow_halation": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": null,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"call_ringing_snowsgiving": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": null,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"clip_error": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"clip_save": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"deafen": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"disconnect": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"highfive_clap": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"highfive_whistle": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"ddr-down": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"ddr-left": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"ddr-right": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"ddr-up": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"reconnect": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"message1": {
|
||||
"category": "Discord",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "Message (Current Channel)",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"message3": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"dm": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"groupdm": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"mentioned": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"everyone": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"here": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"reply": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"role": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": true,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"mute": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"ptt_start": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"ptt_stop": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"stage_waiting": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"stream_ended": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"stream_started": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"stream_user_joined": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"stream_user_left": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"success": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"undeafen": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"unmute": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"vibing_wumpus": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"user_join": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"user_leave": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"user_moved": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"voice_filter_loopback_off": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"voice_filter_loopback_on": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"voice_filter_off": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"voice_filter_on": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"voice_filter_swap": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"camera_off": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"camera_on": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
},
|
||||
"hang_status_select": {
|
||||
"category": "---",
|
||||
"invisibleMute": false,
|
||||
"mute": false,
|
||||
"sound": "---",
|
||||
"streamMute": false,
|
||||
"volume": 100
|
||||
}
|
||||
},
|
||||
"toggles": {
|
||||
"playIfMuted": false
|
||||
},
|
||||
"volumes": {
|
||||
"globalVolume": 100
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,765 +0,0 @@
|
||||
/**
|
||||
* @name NotificationSounds
|
||||
* @author DevilBro
|
||||
* @authorId 278543574059057154
|
||||
* @version 4.0.8
|
||||
* @description Allows you to replace the native Sounds with custom Sounds
|
||||
* @invite Jx3TjNS
|
||||
* @donate https://www.paypal.me/MircoWittrien
|
||||
* @patreon https://www.patreon.com/MircoWittrien
|
||||
* @website https://mwittrien.github.io/
|
||||
* @source https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/NotificationSounds/
|
||||
* @updateUrl https://mwittrien.github.io/BetterDiscordAddons/Plugins/NotificationSounds/NotificationSounds.plugin.js
|
||||
*/
|
||||
|
||||
module.exports = (_ => {
|
||||
const changeLog = {
|
||||
|
||||
};
|
||||
|
||||
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
|
||||
constructor (meta) {for (let key in meta) this[key] = meta[key];}
|
||||
getName () {return this.name;}
|
||||
getAuthor () {return this.author;}
|
||||
getVersion () {return this.version;}
|
||||
getDescription () {return `The Library Plugin needed for ${this.name} is missing. Open the Plugin Settings to download it. \n\n${this.description}`;}
|
||||
|
||||
downloadLibrary () {
|
||||
BdApi.Net.fetch("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js").then(r => {
|
||||
if (!r || r.status != 200) throw new Error();
|
||||
else return r.text();
|
||||
}).then(b => {
|
||||
if (!b) throw new Error();
|
||||
else return require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.UI.showToast("Finished downloading BDFDB Library", {type: "success"}));
|
||||
}).catch(error => {
|
||||
BdApi.UI.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
|
||||
});
|
||||
}
|
||||
|
||||
load () {
|
||||
if (!window.BDFDB_Global || !Array.isArray(window.BDFDB_Global.pluginQueue)) window.BDFDB_Global = Object.assign({}, window.BDFDB_Global, {pluginQueue: []});
|
||||
if (!window.BDFDB_Global.downloadModal) {
|
||||
window.BDFDB_Global.downloadModal = true;
|
||||
BdApi.UI.showConfirmationModal("Library Missing", `The Library Plugin needed for ${this.name} is missing. Please click "Download Now" to install it.`, {
|
||||
confirmText: "Download Now",
|
||||
cancelText: "Cancel",
|
||||
onCancel: _ => {delete window.BDFDB_Global.downloadModal;},
|
||||
onConfirm: _ => {
|
||||
delete window.BDFDB_Global.downloadModal;
|
||||
this.downloadLibrary();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!window.BDFDB_Global.pluginQueue.includes(this.name)) window.BDFDB_Global.pluginQueue.push(this.name);
|
||||
}
|
||||
start () {this.load();}
|
||||
stop () {}
|
||||
getSettingsPanel () {
|
||||
let template = document.createElement("template");
|
||||
template.innerHTML = `<div style="color: var(--text-strong); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${this.name} is missing.\nPlease click <a style="font-weight: 500;">Download Now</a> to install it.</div>`;
|
||||
template.content.firstElementChild.querySelector("a").addEventListener("click", this.downloadLibrary);
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
} : (([Plugin, BDFDB]) => {
|
||||
var audios, choices, firedEvents;
|
||||
var volumes = {};
|
||||
var toggles = {};
|
||||
|
||||
const removeAllKey = "REMOVE_ALL_BDFDB_DEVILBRO_DO_NOT_COPY";
|
||||
const defaultDevice = "default";
|
||||
|
||||
var currentDevice = defaultDevice, createdAudios = {};
|
||||
|
||||
let types = {}, soundPacks = [];
|
||||
|
||||
const message1Types = {
|
||||
dm: {src: "./message3.mp3", name: "Message (Direct Message)"},
|
||||
groupdm: {src: "./message3.mp3", name: "Message (Group Message)"},
|
||||
mentioned: {src: "./message2.mp3", name: "Message Mentioned"},
|
||||
reply: {src: "./message2.mp3", name: "Message Mentioned (reply)"},
|
||||
role: {src: "./mention1.mp3", name: "Message Mentioned (role)"},
|
||||
everyone: {src: "./mention2.mp3", name: "Message Mentioned (@everyone)"},
|
||||
here: {src: "./mention3.mp3", name: "Message Mentioned (@here)"}
|
||||
};
|
||||
|
||||
const namePrefixes = {
|
||||
"user_join": "Voice Channel",
|
||||
"user_leave": "Voice Channel",
|
||||
"user_moved": "Voice Channel"
|
||||
};
|
||||
|
||||
const nameSynonymes = {
|
||||
"message3": "Message (Current Channel)",
|
||||
"reconnect": "Invited To Speak"
|
||||
};
|
||||
|
||||
const defaultAudios = {
|
||||
"---": {
|
||||
"---": null
|
||||
},
|
||||
"Discord": {}
|
||||
};
|
||||
|
||||
const WebAudioSound = class WebAudioSound {
|
||||
constructor (type) {
|
||||
this.name = type;
|
||||
this._src = choices[type] && audios[choices[type].category][choices[type].sound] || types[type] && types[type].src || BDFDB.LibraryModules.SoundParser(`./${type}.mp3`);
|
||||
this._volume = (choices[type] ? choices[type].volume : 100) / 100;
|
||||
}
|
||||
loop () {
|
||||
this._ensureAudio().then(audio => {
|
||||
audio.loop = true;
|
||||
audio.play();
|
||||
});
|
||||
}
|
||||
play () {
|
||||
this._ensureAudio().then(audio => {
|
||||
audio.loop = false;
|
||||
audio.play();
|
||||
});
|
||||
}
|
||||
playWithListener (duration) {
|
||||
return new Promise((callback, errorCallback) => {
|
||||
this._ensureAudio().then(audio => {
|
||||
if (!duration && duration !== 0) errorCallback(new Error("sound has no duration"));
|
||||
audio.loop = false;
|
||||
audio.play();
|
||||
setTimeout(_ => callback(true), duration);
|
||||
});
|
||||
});
|
||||
}
|
||||
pause () {
|
||||
this._audio.then(audio => {
|
||||
audio.pause();
|
||||
});
|
||||
}
|
||||
stop () {
|
||||
this._destroyAudio();
|
||||
}
|
||||
setTime (time) {
|
||||
this._audio.then(audio => {
|
||||
audio.currentTime = time;
|
||||
});
|
||||
}
|
||||
setLoop (loop) {
|
||||
this._audio.then(audio => {
|
||||
audio.loop = loop;
|
||||
});
|
||||
}
|
||||
_destroyAudio () {
|
||||
if (this._audio) {
|
||||
this._audio.then(audio => {
|
||||
audio.pause();
|
||||
audio.src = "";
|
||||
});
|
||||
this._audio = null;
|
||||
}
|
||||
}
|
||||
_ensureAudio () {
|
||||
return this._audio = this._audio || new Promise((callback, errorCallback) => {
|
||||
let audio = new Audio;
|
||||
audio.src = this._src && this._src.startsWith("data") ? this._src.replace(/ /g, "") : this._src;
|
||||
audio.onloadeddata = _ => {
|
||||
audio.volume = Math.min((BDFDB.LibraryStores.MediaEngineStore.getOutputVolume() / 100) * this._volume * (volumes.globalVolume / 100), 1);
|
||||
BDFDB.DiscordUtils.isPlaformEmbedded() && audio.setSinkId(currentDevice || defaultDevice);
|
||||
callback(audio);
|
||||
};
|
||||
audio.onerror = _ => errorCallback(new Error("could not play audio"));
|
||||
audio.onended = _ => this._destroyAudio();
|
||||
audio.load();
|
||||
}), this._audio;
|
||||
}
|
||||
};
|
||||
|
||||
return class NotificationSounds extends Plugin {
|
||||
onLoad () {
|
||||
audios = {};
|
||||
choices = {};
|
||||
firedEvents = {};
|
||||
|
||||
this.defaults = {
|
||||
volumes: {
|
||||
globalVolume: {value: 100, description: "Global Notification Sounds Volume"}
|
||||
},
|
||||
toggles: {
|
||||
playIfMuted: {value: false, description: "Play Sounds Of Muted Channels/Servers"}
|
||||
}
|
||||
};
|
||||
|
||||
this.patchPriority = 9;
|
||||
}
|
||||
|
||||
onStart () {
|
||||
soundPacks = [];
|
||||
const soundKeys = BDFDB.LibraryModules.SoundParser.keys();
|
||||
for (let key of soundKeys) {
|
||||
const id = key.replace("./", "").replace(".mp3", "");
|
||||
const name = [namePrefixes[id], (nameSynonymes[id] || id).replace("ddr-", "HotKeys_").replace("ptt_", "Push2Talk_").split(/[_-]/)].flat(10).filter(n => n).map(BDFDB.StringUtils.upperCaseFirstChar).join(" ").replace(/1$/g, "");
|
||||
const src = BDFDB.LibraryModules.SoundParser(key);
|
||||
|
||||
let soundPackName = id.split("_")[0];
|
||||
if (soundPackName != id && soundKeys.filter(n => n.indexOf(`./${soundPackName}`) > -1).length > 8) {
|
||||
soundPacks.push(soundPackName);
|
||||
soundPackName = BDFDB.StringUtils.upperCaseFirstChar(soundPackName);
|
||||
if (!defaultAudios[soundPackName]) defaultAudios[soundPackName] = {};
|
||||
defaultAudios[soundPackName][name.replace(new RegExp(`${soundPackName} `, "i"), "").replace(/bootup/i, "Discodo")] = src;
|
||||
}
|
||||
else {
|
||||
defaultAudios.Discord[name] = src;
|
||||
if (this.isSoundUsedAnywhere(id)) types[id] = {
|
||||
name: name,
|
||||
src: src,
|
||||
mute: id.startsWith("call_") ? null : false,
|
||||
streamMute: false,
|
||||
invisibleMute: false
|
||||
};
|
||||
if (id == "message1" || id == "message3") {
|
||||
types[id].mute = true;
|
||||
types[id].streamMute = false;
|
||||
types[id].invisibleMute = false;
|
||||
if (id == "message1") for (let subType in message1Types) types[subType] = {
|
||||
name: message1Types[subType].name,
|
||||
src: BDFDB.LibraryModules.SoundParser(message1Types[subType].src),
|
||||
mute: true,
|
||||
streamMute: false,
|
||||
invisibleMute: false
|
||||
}
|
||||
}
|
||||
}
|
||||
types = BDFDB.ObjectUtils.sort(types, "name");
|
||||
}
|
||||
for (let pack in defaultAudios) defaultAudios[pack] = BDFDB.ObjectUtils.sort(defaultAudios[pack]);
|
||||
|
||||
if (BDFDB.DiscordUtils.isPlaformEmbedded()) {
|
||||
let change = _ => {
|
||||
if (window.navigator.mediaDevices && window.navigator.mediaDevices.enumerateDevices) {
|
||||
window.navigator.mediaDevices.enumerateDevices().then(enumeratedDevices => {
|
||||
let id = BDFDB.LibraryStores.MediaEngineStore.getOutputDeviceId();
|
||||
let allDevices = BDFDB.LibraryStores.MediaEngineStore.getOutputDevices();
|
||||
let filteredDevices = enumeratedDevices.filter(d => d.kind == "audiooutput" && d.deviceId != "communications");
|
||||
let deviceIndex = BDFDB.LibraryModules.ArrayUtils(allDevices).sortBy(d => d.index).findIndex(d => d.id == id);
|
||||
let deviceViaId = allDevices[id];
|
||||
let deviceViaIndex = filteredDevices[deviceIndex];
|
||||
if (deviceViaId && deviceViaIndex && deviceViaIndex.label != deviceViaId.name) deviceViaIndex = filteredDevices.find(d => d.label == deviceViaId.name);
|
||||
currentDevice = deviceViaIndex ? deviceViaIndex.deviceId : defaultDevice;
|
||||
}).catch(_ => {
|
||||
currentDevice = defaultDevice;
|
||||
});
|
||||
}
|
||||
};
|
||||
BDFDB.StoreChangeUtils.add(this, BDFDB.LibraryStores.MediaEngineStore, change);
|
||||
change();
|
||||
}
|
||||
|
||||
BDFDB.PatchUtils.patch(this, BDFDB.LibraryModules.DispatchApiUtils, "dispatch", {after: e => {
|
||||
if (BDFDB.ObjectUtils.is(e.methodArguments[0]) && (e.methodArguments[0].type == "CALL_DELETE" || e.methodArguments[0].type == "CALL_UPDATE" && !e.methodArguments[0].ringing.includes(BDFDB.UserUtils.me.id))) {
|
||||
["call_ringing", "call_calling"].forEach(type => {
|
||||
if (createdAudios[type]) createdAudios[type].stop();
|
||||
});
|
||||
}
|
||||
|
||||
}, before: e => {
|
||||
if (BDFDB.ObjectUtils.is(e.methodArguments[0]) && e.methodArguments[0].type == "MESSAGE_CREATE" && e.methodArguments[0].message) {
|
||||
const message = e.methodArguments[0].message;
|
||||
const guildId = message.guild_id || null;
|
||||
if (message.author.id != BDFDB.UserUtils.me.id && !BDFDB.LibraryStores.RelationshipStore.isBlocked(message.author.id)) {
|
||||
const channel = BDFDB.LibraryStores.ChannelStore.getChannel(message.channel_id);
|
||||
|
||||
const isCurrent = BDFDB.LibraryStores.SelectedChannelStore.getChannelId() == channel.id;
|
||||
const isGroupDM = channel.isGroupDM();
|
||||
const isThread = BDFDB.ChannelUtils.isThread(channel);
|
||||
const isCurrentAndFocused = isCurrent && document.hasFocus();
|
||||
|
||||
if (!toggles.playIfMuted) {
|
||||
if ((isThread && BDFDB.LibraryStores.JoinedThreadsStore.isMuted(channel.id)) || (!isThread && BDFDB.LibraryStores.UserGuildSettingsStore.isGuildOrCategoryOrChannelMuted(guildId, channel.id))) return;
|
||||
}
|
||||
|
||||
if (isCurrent && BDFDB.LibraryStores.NotificationSettingsStore.getNotifyMessagesInSelectedChannel()) {
|
||||
this.fireEvent("message3");
|
||||
this.playAudio("message3");
|
||||
return;
|
||||
}
|
||||
else if (!guildId) {
|
||||
this.fireEvent(isGroupDM ? "groupdm" : "dm");
|
||||
!isCurrentAndFocused && this.playAudio(isGroupDM ? "groupdm" : "dm");
|
||||
return;
|
||||
}
|
||||
else if (guildId) {
|
||||
if (BDFDB.LibraryModules.MentionUtils.isRawMessageMentioned({rawMessage: message, userId: BDFDB.UserUtils.me.id})) {
|
||||
if (message.mentions.length && !this.isSuppressMentionsEnabled(guildId, channel.id)) for (const mention of message.mentions) if (mention.id == BDFDB.UserUtils.me.id) {
|
||||
if (message.message_reference && !message.interaction) {
|
||||
this.fireEvent("reply");
|
||||
!isCurrentAndFocused && this.playAudio("reply");
|
||||
return;
|
||||
}
|
||||
if (!message.message_reference) {
|
||||
this.fireEvent("mentioned");
|
||||
!isCurrentAndFocused && this.playAudio("mentioned");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (message.mention_roles.length && !BDFDB.LibraryStores.UserGuildSettingsStore.isSuppressRolesEnabled(guildId, channel.id)) {
|
||||
const member = BDFDB.LibraryStores.GuildMemberStore.getMember(guildId, BDFDB.UserUtils.me.id);
|
||||
if (member && member.roles.length) for (const roleId of message.mention_roles) if (member.roles.includes(roleId)) {
|
||||
this.fireEvent("role");
|
||||
!isCurrentAndFocused && this.playAudio("role");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (message.mention_everyone && !BDFDB.LibraryStores.UserGuildSettingsStore.isSuppressEveryoneEnabled(guildId, channel.id)) {
|
||||
if (message.content.indexOf("@everyone") > -1) {
|
||||
this.fireEvent("everyone");
|
||||
!isCurrentAndFocused && this.playAudio("everyone");
|
||||
return;
|
||||
}
|
||||
if (message.content.indexOf("@here") > -1) {
|
||||
this.fireEvent("here");
|
||||
!isCurrentAndFocused && this.playAudio("here");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (BDFDB.LibraryStores.UserGuildSettingsStore.allowAllMessages(channel) && !(isThread && !BDFDB.LibraryStores.JoinedThreadsStore.hasJoined(channel.id))) {
|
||||
this.fireEvent("message1");
|
||||
!isCurrentAndFocused && this.playAudio("message1");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}});
|
||||
|
||||
BDFDB.PatchUtils.patch(this, BDFDB.LibraryModules.DesktopNotificationUtils, "showNotification", {before: e => {
|
||||
let soundObjIndex = Array.from(e.methodArguments).findIndex(n => n && n.sound);
|
||||
if (soundObjIndex && e.methodArguments[soundObjIndex].sound.includes("message")) e.methodArguments[soundObjIndex].sound = null;
|
||||
}});
|
||||
if (BDFDB.LibraryModules.SoundUtils && BDFDB.LibraryModules.SoundUtils.createSound) {
|
||||
let cancel = BDFDB.PatchUtils.patch(this, BDFDB.LibraryModules.SoundUtils, "createSound", {after: e => {
|
||||
if (e.returnValue && e.returnValue.constructor && e.returnValue.constructor.prototype && typeof e.returnValue.constructor.prototype.play == "function") {
|
||||
cancel();
|
||||
BDFDB.PatchUtils.patch(this, e.returnValue.constructor.prototype, ["play", "loop", "playWithListener"], {instead: e2 => {
|
||||
let type = e2.instance && e2.instance.name;
|
||||
if (type && choices[type]) {
|
||||
e2.stopOriginalMethodCall();
|
||||
if (type == "message1" || type == "message3") BDFDB.TimeUtils.timeout(_ => {
|
||||
let called = false;
|
||||
for (let subType of [type].concat(Object.keys(message1Types))) if (firedEvents[subType]) {
|
||||
delete firedEvents[subType];
|
||||
called = true;
|
||||
break;
|
||||
}
|
||||
if (!called) return this.playAudio(type, e2.originalMethodName, e2.instance.duration);
|
||||
});
|
||||
else return this.playAudio(type, e2.originalMethodName, e2.instance.duration);
|
||||
}
|
||||
else return this.playAudio(type, e2.originalMethodName, e2.instance.duration);
|
||||
}});
|
||||
BDFDB.PatchUtils.patch(this, e.returnValue.constructor.prototype, "stop", {after: e2 => {
|
||||
let type = e2.instance && e2.instance.name;
|
||||
if (type && createdAudios[type]) createdAudios[type].stop();
|
||||
}});
|
||||
}
|
||||
}}, {noCache: true});
|
||||
BDFDB.LibraryModules.SoundUtils.createSound("call_calling");
|
||||
}
|
||||
|
||||
this.loadAudios();
|
||||
this.loadChoices();
|
||||
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
|
||||
onStop () {
|
||||
for (let type in createdAudios) if (createdAudios[type]) createdAudios[type].stop();
|
||||
}
|
||||
|
||||
getSettingsPanel (collapseStates = {}) {
|
||||
let successSavedAudio = data => {
|
||||
BDFDB.NotificationUtils.toast(`Sound ${data.sound} was added to category ${data.category}.`, {type: "success"});
|
||||
if (!audios[data.category]) audios[data.category] = {};
|
||||
audios[data.category][data.sound] = data.source;
|
||||
BDFDB.DataUtils.save(audios, this, "audios");
|
||||
BDFDB.PluginUtils.refreshSettingsPanel(this, settingsPanel, collapseStates);
|
||||
|
||||
};
|
||||
|
||||
let settingsPanel;
|
||||
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, {
|
||||
collapseStates: collapseStates,
|
||||
children: _ => {
|
||||
let settingsItems = [];
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "Settings",
|
||||
collapseStates: collapseStates,
|
||||
children: [
|
||||
...Object.keys(volumes).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Slider",
|
||||
plugin: this,
|
||||
keys: ["volumes", key],
|
||||
basis: "50%",
|
||||
label: this.defaults.volumes[key].description,
|
||||
value: volumes[key]
|
||||
})),
|
||||
...Object.keys(toggles).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Switch",
|
||||
plugin: this,
|
||||
keys: ["toggles", key],
|
||||
label: this.defaults.toggles[key].description,
|
||||
value: toggles[key]
|
||||
}))
|
||||
]
|
||||
}));
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "Add new Sound",
|
||||
collapseStates: collapseStates,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
className: BDFDB.disCN.margintop4,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormItem, {
|
||||
title: "Categoryname",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextInput, {
|
||||
className: "input-newsound input-category",
|
||||
value: "",
|
||||
placeholder: "Categoryname"
|
||||
})
|
||||
})
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormItem, {
|
||||
title: "Soundname",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextInput, {
|
||||
className: "input-newsound input-sound",
|
||||
value: "",
|
||||
placeholder: "Soundname"
|
||||
})
|
||||
})
|
||||
})
|
||||
]
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
className: BDFDB.disCN.margintop4,
|
||||
align: BDFDB.LibraryComponents.Flex.Align.END,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormItem, {
|
||||
title: "Source",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TextInput, {
|
||||
className: "input-newsound input-source",
|
||||
type: "file",
|
||||
filter: ["audio", "video"],
|
||||
value: "",
|
||||
placeholder: "Source"
|
||||
})
|
||||
})
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
|
||||
style: {marginBottom: 4},
|
||||
onClick: _ => {
|
||||
for (let input of settingsPanel.props._node.querySelectorAll(".input-newsound " + BDFDB.dotCN.input)) if (!input.value || input.value.length == 0 || input.value.trim().length == 0) return BDFDB.NotificationUtils.toast("Fill out all Fields to add a new Sound", {type: "danger"});
|
||||
let category = settingsPanel.props._node.querySelector(".input-category " + BDFDB.dotCN.input).value.trim();
|
||||
let sound = settingsPanel.props._node.querySelector(".input-sound " + BDFDB.dotCN.input).value.trim();
|
||||
let source = settingsPanel.props._node.querySelector(".input-source " + BDFDB.dotCN.input);
|
||||
let value = source && (source.getAttribute("file") || source.value).trim();
|
||||
if (value.indexOf("http") == 0) BDFDB.LibraryRequires.request(value, (error, response, result) => {
|
||||
if (response) {
|
||||
let type = response.headers["content-type"];
|
||||
if (type && (type.indexOf("octet-stream") > -1 || type.indexOf("audio") > -1 || type.indexOf("video") > -1)) return successSavedAudio({category, sound, source: value});
|
||||
}
|
||||
BDFDB.NotificationUtils.toast("Use a valid direct link to a video or audio source, they usually end on something like .mp3, .mp4 or .wav", {type: "danger"});
|
||||
});
|
||||
else if (value.indexOf("data:") == 0) return successSavedAudio({category, sound, source: value});
|
||||
},
|
||||
children: BDFDB.LanguageUtils.LanguageStrings.SAVE
|
||||
})
|
||||
]
|
||||
})
|
||||
]
|
||||
}));
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "Sound Configuration",
|
||||
collapseStates: collapseStates,
|
||||
children: Object.keys(types).map(type => type == "message3" && !BDFDB.LibraryStores.NotificationSettingsStore.getNotifyMessagesInSelectedChannel() ? null : [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
className: BDFDB.disCN.marginbottom8,
|
||||
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
|
||||
direction: BDFDB.LibraryComponents.Flex.Direction.HORIZONTAL,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsLabel, {
|
||||
label: types[type].name
|
||||
}),
|
||||
["mute", "streamMute", "invisibleMute"].some(n => types[type][n] !== null) && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, {
|
||||
onClick: event => BDFDB.ContextMenuUtils.open(this, event, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
|
||||
children: [
|
||||
{key: "mute", label: ["Mute in", BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.StatusComponents.Status, {style: {marginLeft: 6}, size: 12, status: BDFDB.DiscordConstants.StatusTypes.DND})]},
|
||||
{key: "invisibleMute", label: ["Mute in", BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.StatusComponents.Status, {style: {marginLeft: 6}, size: 12, status: BDFDB.DiscordConstants.StatusTypes.INVISIBLE})]},
|
||||
{key: "streamMute", label: ["Mute while", BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.StatusComponents.Status, {style: {marginLeft: 6}, size: 12, status: BDFDB.DiscordConstants.StatusTypes.STREAMING})]}
|
||||
].map(n => types[type][n.key] !== null && BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuCheckboxItem, {
|
||||
label: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
|
||||
children: n.label
|
||||
}),
|
||||
icon: _ => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.MenuItems.MenuHint, {
|
||||
hint: n.hint
|
||||
}),
|
||||
id: BDFDB.ContextMenuUtils.createItemId(this.name, type, n.key),
|
||||
checked: choices[type][n.key],
|
||||
action: state => {
|
||||
choices[type][n.key] = state;
|
||||
this.saveChoice(type, false);
|
||||
}
|
||||
})).filter(n => n)
|
||||
})),
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
|
||||
width: 20,
|
||||
height: 20,
|
||||
name: BDFDB.LibraryComponents.SvgIcon.Names.COG
|
||||
})
|
||||
})
|
||||
].filter(n => n)
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
className: BDFDB.disCN.marginbottom8,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
grow: 0,
|
||||
shrink: 0,
|
||||
basis: "31%",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormItem, {
|
||||
title: "Category",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Select, {
|
||||
value: choices[type].category,
|
||||
options: Object.keys(audios).map(name => ({value: name, label: name})),
|
||||
searchable: true,
|
||||
onChange: value => {
|
||||
const categorySounds = audios[value] || {};
|
||||
choices[type].category = value;
|
||||
choices[type].sound = categorySounds[types[type].name] ? types[type].name : Object.keys(categorySounds)[0];
|
||||
this.saveChoice(type, true);
|
||||
BDFDB.PluginUtils.refreshSettingsPanel(this, settingsPanel, collapseStates);
|
||||
}
|
||||
})
|
||||
})
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
grow: 0,
|
||||
shrink: 0,
|
||||
basis: "31%",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormItem, {
|
||||
title: "Sound",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Select, {
|
||||
value: choices[type].sound,
|
||||
options: Object.keys(audios[choices[type].category] || {}).map(name => ({value: name, label: name})),
|
||||
searchable: true,
|
||||
onChange: value => {
|
||||
choices[type].sound = value;
|
||||
this.saveChoice(type, true);
|
||||
BDFDB.PluginUtils.refreshSettingsPanel(this, settingsPanel, collapseStates);
|
||||
}
|
||||
})
|
||||
})
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
grow: 0,
|
||||
shrink: 0,
|
||||
basis: "31%",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormItem, {
|
||||
title: "Volume",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Slider, {
|
||||
defaultValue: choices[type].volume,
|
||||
digits: 1,
|
||||
onValueRender: value => {
|
||||
return value + "%";
|
||||
},
|
||||
onValueChange: value => {
|
||||
choices[type].volume = value;
|
||||
this.saveChoice(type, true);
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
]
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormDivider, {
|
||||
className: BDFDB.disCN.marginbottom8
|
||||
})
|
||||
]).flat(10).filter(n => n)
|
||||
}));
|
||||
|
||||
let removeableCategories = [{value: removeAllKey, label: BDFDB.LanguageUtils.LanguageStrings.ALL}].concat(Object.keys(audios).filter(category => !(defaultAudios[category] && !Object.keys(audios[category] || {}).filter(sound => defaultAudios[category][sound] === undefined).length)).map(name => ({value: name, label: name})));
|
||||
let removeableSounds = {};
|
||||
for (let category of removeableCategories) removeableSounds[category.value] = [{value: removeAllKey, label: BDFDB.LanguageUtils.LanguageStrings.ALL}].concat(Object.keys(audios[category.value] || {}).filter(sound => !(defaultAudios[category.value] && defaultAudios[category.value][sound] !== undefined)).map(name => ({value: name, label: name})));
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "Remove Sounds",
|
||||
collapseStates: collapseStates,
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
className: BDFDB.disCN.margintop4,
|
||||
align: BDFDB.LibraryComponents.Flex.Align.END,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
grow: 0,
|
||||
shrink: 0,
|
||||
basis: "35%",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormItem, {
|
||||
title: "Category",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Select, {
|
||||
key: "REMOVE_CATEGORY",
|
||||
value: removeAllKey,
|
||||
options: removeableCategories,
|
||||
searchable: true,
|
||||
onChange: (category, instance) => {
|
||||
let soundSelectIns = BDFDB.ReactUtils.findOwner(BDFDB.ReactUtils.findOwner(instance, {name: ["BDFDB_Modal", "BDFDB_SettingsPanel"], up: true}), {key: "REMOVE_SOUND"});
|
||||
if (soundSelectIns && removeableSounds[category]) {
|
||||
soundSelectIns.props.options = removeableSounds[category];
|
||||
soundSelectIns.props.value = removeAllKey;
|
||||
BDFDB.ReactUtils.forceUpdate(soundSelectIns);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
grow: 0,
|
||||
shrink: 0,
|
||||
basis: "35%",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormItem, {
|
||||
title: "Sound",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Select, {
|
||||
key: "REMOVE_SOUND",
|
||||
value: removeAllKey,
|
||||
options: removeableSounds[removeAllKey],
|
||||
searchable: true
|
||||
})
|
||||
})
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
grow: 0,
|
||||
shrink: 1,
|
||||
basis: "25%",
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Button, {
|
||||
style: {marginBottom: 4},
|
||||
color: BDFDB.LibraryComponents.Button.Colors.RED,
|
||||
onClick: (event, instance) => {
|
||||
let wrapperIns = BDFDB.ReactUtils.findOwner(instance, {name: ["BDFDB_Modal", "BDFDB_SettingsPanel"], up: true});
|
||||
let categorySelectIns = BDFDB.ReactUtils.findOwner(wrapperIns, {key: "REMOVE_CATEGORY"});
|
||||
let soundSelectIns = BDFDB.ReactUtils.findOwner(wrapperIns, {key: "REMOVE_SOUND"});
|
||||
if (categorySelectIns && soundSelectIns) {
|
||||
let soundAmount = 0;
|
||||
let catAll = categorySelectIns.props.value == removeAllKey;
|
||||
let soundAll = soundSelectIns.props.value == removeAllKey;
|
||||
if (catAll) soundAmount = BDFDB.ArrayUtils.sum(Object.keys(audios).map(category => Object.keys(audios[category] || {}).filter(sound => !(defaultAudios[category] && defaultAudios[category][sound] !== undefined)).length));
|
||||
else if (soundAll) soundAmount = Object.keys(audios[categorySelectIns.props.value] || {}).filter(sound => !(defaultAudios[categorySelectIns.props.value] && defaultAudios[categorySelectIns.props.value][sound] !== undefined)).length;
|
||||
else if (audios[categorySelectIns.props.value][soundSelectIns.props.value]) soundAmount = 1;
|
||||
|
||||
if (soundAmount) BDFDB.ModalUtils.confirm(this, `Are you sure you want to delete ${soundAmount} added Sound${soundAmount == 1 ? "" : "s"}?`, _ => {
|
||||
if (catAll) BDFDB.DataUtils.remove(this, "audios");
|
||||
else if (soundAll) BDFDB.DataUtils.remove(this, "audios", categorySelectIns.props.value);
|
||||
else {
|
||||
delete audios[categorySelectIns.props.value][soundSelectIns.props.value];
|
||||
if (BDFDB.ObjectUtils.isEmpty(audios[categorySelectIns.props.value])) delete audios[categorySelectIns.props.value];
|
||||
BDFDB.DataUtils.save(audios, this, "audios");
|
||||
}
|
||||
this.loadAudios();
|
||||
this.loadChoices();
|
||||
BDFDB.PluginUtils.refreshSettingsPanel(this, settingsPanel, collapseStates);
|
||||
});
|
||||
else BDFDB.NotificationUtils.toast("No Sounds to delete", {type: "danger"});
|
||||
}
|
||||
},
|
||||
children: BDFDB.LanguageUtils.LanguageStrings.DELETE
|
||||
})
|
||||
})
|
||||
]
|
||||
})
|
||||
}));
|
||||
|
||||
return settingsItems;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onSettingsClosed () {
|
||||
if (this.SettingsUpdated) {
|
||||
delete this.SettingsUpdated;
|
||||
for (let type in createdAudios) if (createdAudios[type]) createdAudios[type].stop();
|
||||
createdAudios = {};
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
}
|
||||
|
||||
forceUpdateAll () {
|
||||
volumes = BDFDB.DataUtils.get(this, "volumes");
|
||||
toggles = BDFDB.DataUtils.get(this, "toggles");
|
||||
|
||||
BDFDB.PatchUtils.forceAllUpdates(this);
|
||||
BDFDB.DiscordUtils.rerenderAll();
|
||||
}
|
||||
|
||||
loadAudios () {
|
||||
audios = Object.assign({}, BDFDB.DataUtils.load(this, "audios"), defaultAudios);
|
||||
BDFDB.DataUtils.save(BDFDB.ObjectUtils.exclude(audios, Object.keys(defaultAudios)), this, "audios");
|
||||
}
|
||||
|
||||
loadChoices () {
|
||||
let loadedChoices = BDFDB.DataUtils.load(this, "choices");
|
||||
for (let type in types) {
|
||||
let choice = loadedChoices[type] || {}, soundFound = false;
|
||||
for (let category in audios) if (choice.category == category) for (let sound in audios[category]) if (choice.sound == sound) {
|
||||
soundFound = true;
|
||||
break;
|
||||
}
|
||||
if (!soundFound) choice = {
|
||||
category: "---",
|
||||
sound: "---",
|
||||
volume: 100,
|
||||
mute: types[type].mute,
|
||||
streamMute: types[type].streamMute,
|
||||
invisibleMute: types[type].invisibleMute
|
||||
};
|
||||
choices[type] = choice;
|
||||
this.saveChoice(type, false);
|
||||
}
|
||||
}
|
||||
|
||||
saveChoice (type, play) {
|
||||
if (!choices[type]) return;
|
||||
BDFDB.DataUtils.save(choices[type], this, "choices", type);
|
||||
if (play) {
|
||||
this.SettingsUpdated = true;
|
||||
this.playAudio(type);
|
||||
}
|
||||
}
|
||||
|
||||
playAudio (type, functionCall = "play", duration = 0) {
|
||||
type = soundPacks.some(soundPack => type.startsWith(soundPack + "_")) ? type.split("_").splice(1).join("_") : type;
|
||||
if (this.dontPlayAudio(type) || BDFDB.LibraryStores.StreamerModeStore.disableSounds) return;
|
||||
if (createdAudios[type]) createdAudios[type].stop();
|
||||
createdAudios[type] = new WebAudioSound(type);
|
||||
return createdAudios[type][typeof createdAudios[type][functionCall] == "function" ? functionCall : "play"](duration);
|
||||
}
|
||||
|
||||
isSuppressMentionsEnabled (guildId, channelId) {
|
||||
let channelSettings = BDFDB.LibraryStores.UserGuildSettingsStore.getChannelMessageNotifications(guildId, channelId);
|
||||
return channelSettings && (channelSettings == BDFDB.DiscordConstants.UserNotificationSettings.NO_MESSAGES || channelSettings == BDFDB.DiscordConstants.UserNotificationSettings.NULL && BDFDB.LibraryStores.UserGuildSettingsStore.getMessageNotifications(guildId) == BDFDB.DiscordConstants.UserNotificationSettings.NO_MESSAGES);
|
||||
}
|
||||
|
||||
dontPlayAudio (type) {
|
||||
let status = BDFDB.UserUtils.getStatus();
|
||||
return choices[type] && (choices[type].mute && status == "dnd" || choices[type].streamMute && status == "streaming" || choices[type].invisibleMute && (status == "offline" || status == "invisible"));
|
||||
}
|
||||
|
||||
fireEvent (type) {
|
||||
firedEvents[type] = true;
|
||||
BDFDB.TimeUtils.timeout(_ => delete firedEvents[type], 3000);
|
||||
}
|
||||
|
||||
isSoundUsedAnywhere (type) {
|
||||
return type && type.indexOf("poggermode_") != 0 && type != "human_man" && type != "robot_man" && type != "discodo" && type != "overlayunlock" && type != "call_ringing_beat" && !(type != "message1" && type != "message3" && /\d$/.test(type));
|
||||
}
|
||||
};
|
||||
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));
|
||||
})();
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "0.2.11",
|
||||
"hasShownChangelog": true
|
||||
},
|
||||
"settings": {
|
||||
"contextMenus": true,
|
||||
"popouts": true,
|
||||
"displayMode": "cozy"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"cached": "2 7 8 9 11 14 15 17 28 29 30 59 60 61 62 63 64 65 66 67 70 71 73 74 75 76 77 80 81 82 83 85 86 87 88 89 91 92 93 94 95 96 97 98 99 100 101 102 104 105 106 108 109 110 111 120 126 127 131 132 138 139 146 157 158 159 160 162 171 176 179 181 182 183 184 186 188 189 190 193 195 196 197 228 237 240 245 262 274 278 287 291 292 293 295 306 312 314 317 318 323 331 344 350 352 353 354 356 366 368 377 379 381 382 383 390 395 401 420 421 429 442 476 479 489 518 520 523 525 535 539 547 554 577 579 589 592 593 598 599 606 608 611 614 620 638 644 645 670 671 679 686 692 693 694 699 708 760 762 772 798 802 805 806 807 819 827 843 850 856 859 867 878 881 882 883 930 936 938 953 954 970 971 979 989 996 1000 1005 1010 1016 1023 1040 1041 1044 1048 1049 1058 1063 1066 1067 1068 1069 1070 1074 1075 1077 1078 1079 1080 1081 1087 1090 1092 1097 1115 1124 1126 1130 1132 1141 1157 1163 1166 1172 1175 1185 1188 1190 1191 1204 1205 1206 1210",
|
||||
"filters": {
|
||||
"updated": true,
|
||||
"outdated": true,
|
||||
"downloadable": true
|
||||
},
|
||||
"general": {
|
||||
"notifyOutdated": true,
|
||||
"notifyNewEntries": true,
|
||||
"startDownloaded": false,
|
||||
"startUpdated": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.2.1",
|
||||
"hasShownChangelog": true
|
||||
},
|
||||
"settings": {
|
||||
"lastVersion": "1.4.0"
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"batch": {
|
||||
"dms": false,
|
||||
"guilds": true,
|
||||
"muted": true
|
||||
},
|
||||
"blacklist": [
|
||||
"775772308261830737",
|
||||
"230708419995107330",
|
||||
"594829566330273792",
|
||||
"230708419995107330",
|
||||
"594829566330273792",
|
||||
"710203122106105927",
|
||||
"775772308261830737",
|
||||
"413603118832680960",
|
||||
"707267476391723008",
|
||||
"230708419995107330",
|
||||
"594829566330273792",
|
||||
"710203122106105927",
|
||||
"775772308261830737",
|
||||
"413603118832680960",
|
||||
"707267476391723008",
|
||||
"340262122782982147",
|
||||
"738872654928281620",
|
||||
"230708419995107330",
|
||||
"594829566330273792",
|
||||
"710203122106105927",
|
||||
"775772308261830737",
|
||||
"413603118832680960",
|
||||
"340262122782982147",
|
||||
"707267476391723008",
|
||||
"738872654928281620",
|
||||
"703597941809741834",
|
||||
"821835978334535740"
|
||||
],
|
||||
"general": {
|
||||
"addClearButton": true,
|
||||
"confirmClear": false
|
||||
},
|
||||
"settings": {
|
||||
"addClearButton": true,
|
||||
"confirmClear": false,
|
||||
"includeGuilds": true,
|
||||
"includeMuted": false,
|
||||
"includeDMs": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,700 +0,0 @@
|
||||
/**
|
||||
* @name ReadAllNotificationsButton
|
||||
* @author DevilBro
|
||||
* @authorId 278543574059057154
|
||||
* @version 1.8.5
|
||||
* @description Adds a Clear Button to the Server List and the Mentions Popout
|
||||
* @invite Jx3TjNS
|
||||
* @donate https://www.paypal.me/MircoWittrien
|
||||
* @patreon https://www.patreon.com/MircoWittrien
|
||||
* @website https://mwittrien.github.io/
|
||||
* @source https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/ReadAllNotificationsButton/
|
||||
* @updateUrl https://mwittrien.github.io/BetterDiscordAddons/Plugins/ReadAllNotificationsButton/ReadAllNotificationsButton.plugin.js
|
||||
*/
|
||||
|
||||
module.exports = (_ => {
|
||||
const changeLog = {
|
||||
|
||||
};
|
||||
|
||||
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
|
||||
constructor (meta) {for (let key in meta) this[key] = meta[key];}
|
||||
getName () {return this.name;}
|
||||
getAuthor () {return this.author;}
|
||||
getVersion () {return this.version;}
|
||||
getDescription () {return `The Library Plugin needed for ${this.name} is missing. Open the Plugin Settings to download it. \n\n${this.description}`;}
|
||||
|
||||
downloadLibrary () {
|
||||
BdApi.Net.fetch("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js").then(r => {
|
||||
if (!r || r.status != 200) throw new Error();
|
||||
else return r.text();
|
||||
}).then(b => {
|
||||
if (!b) throw new Error();
|
||||
else return require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.UI.showToast("Finished downloading BDFDB Library", {type: "success"}));
|
||||
}).catch(error => {
|
||||
BdApi.UI.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
|
||||
});
|
||||
}
|
||||
|
||||
load () {
|
||||
if (!window.BDFDB_Global || !Array.isArray(window.BDFDB_Global.pluginQueue)) window.BDFDB_Global = Object.assign({}, window.BDFDB_Global, {pluginQueue: []});
|
||||
if (!window.BDFDB_Global.downloadModal) {
|
||||
window.BDFDB_Global.downloadModal = true;
|
||||
BdApi.UI.showConfirmationModal("Library Missing", `The Library Plugin needed for ${this.name} is missing. Please click "Download Now" to install it.`, {
|
||||
confirmText: "Download Now",
|
||||
cancelText: "Cancel",
|
||||
onCancel: _ => {delete window.BDFDB_Global.downloadModal;},
|
||||
onConfirm: _ => {
|
||||
delete window.BDFDB_Global.downloadModal;
|
||||
this.downloadLibrary();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!window.BDFDB_Global.pluginQueue.includes(this.name)) window.BDFDB_Global.pluginQueue.push(this.name);
|
||||
}
|
||||
start () {this.load();}
|
||||
stop () {}
|
||||
getSettingsPanel () {
|
||||
let template = document.createElement("template");
|
||||
template.innerHTML = `<div style="color: var(--text-strong); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${this.name} is missing.\nPlease click <a style="font-weight: 500;">Download Now</a> to install it.</div>`;
|
||||
template.content.firstElementChild.querySelector("a").addEventListener("click", this.downloadLibrary);
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
} : (([Plugin, BDFDB]) => {
|
||||
var _this;
|
||||
var blacklist, clearing;
|
||||
|
||||
const ReadAllButtonComponent = class ReadAllButton extends BdApi.React.Component {
|
||||
clearClick() {
|
||||
if (_this.settings.batch.guilds) this.clearGuilds(_this.settings.batch.muted ? this.getGuilds() : this.getUnread());
|
||||
if (_this.settings.batch.dms) BDFDB.DMUtils.markAsRead(this.getPingedDMs());
|
||||
}
|
||||
clearGuilds(guildIds) {
|
||||
BDFDB.GuildUtils.markAsRead(guildIds.filter(id => id && !blacklist.includes(id)));
|
||||
}
|
||||
getGuilds() {
|
||||
return BDFDB.LibraryStores.SortedGuildStore.getFlattenedGuildIds().map(BDFDB.LibraryStores.GuildStore.getGuild).map(g => g.id).filter(n => n);
|
||||
}
|
||||
getUnread() {
|
||||
return this.getGuilds().filter(id => BDFDB.LibraryStores.GuildReadStateStore.hasUnread(id) || BDFDB.LibraryStores.GuildReadStateStore.getMentionCount(id) > 0);
|
||||
}
|
||||
getPinged() {
|
||||
return this.getGuilds().filter(id => BDFDB.LibraryStores.GuildReadStateStore.getMentionCount(id) > 0);
|
||||
}
|
||||
getMuted() {
|
||||
return this.getGuilds().filter(id => BDFDB.LibraryStores.UserGuildSettingsStore.isGuildOrCategoryOrChannelMuted(id));
|
||||
}
|
||||
getPingedDMs() {
|
||||
return BDFDB.LibraryStores.ChannelStore.getSortedPrivateChannels().map(c => c.id).filter(id => id && BDFDB.LibraryStores.ReadStateStore.getMentionCount(id) > 0);
|
||||
}
|
||||
render() {
|
||||
return BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCNS.guildouter + BDFDB.disCN._readallnotificationsbuttonframe,
|
||||
children: BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCNS.guildiconwrapper + BDFDB.disCN._readallnotificationsbuttoninner,
|
||||
children: BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCNS.guildiconchildwrapper + BDFDB.disCNS.guildiconchildwrappernohoverbg + BDFDB.disCN._readallnotificationsbuttonbutton,
|
||||
children: "read all",
|
||||
onClick: _ => {
|
||||
if (!_this.settings.general.confirmClear) this.clearClick();
|
||||
else BDFDB.ModalUtils.confirm(_this, _this.labels.modal_confirmnotifications, _ => this.clearClick());
|
||||
},
|
||||
onContextMenu: event => BDFDB.ContextMenuUtils.open(_this, event, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
|
||||
children: [
|
||||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||||
label: _this.labels.context_unreadguilds,
|
||||
id: BDFDB.ContextMenuUtils.createItemId(_this.name, "mark-unread-read"),
|
||||
action: _ => this.clearGuilds(this.getUnread())
|
||||
}),
|
||||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||||
label: _this.labels.context_pingedguilds,
|
||||
id: BDFDB.ContextMenuUtils.createItemId(_this.name, "mark-pinged-read"),
|
||||
action: _ => this.clearGuilds(this.getPinged())
|
||||
}),
|
||||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||||
label: _this.labels.context_mutedguilds,
|
||||
id: BDFDB.ContextMenuUtils.createItemId(_this.name, "mark-muted-read"),
|
||||
action: _ => this.clearGuilds(this.getMuted())
|
||||
}),
|
||||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||||
label: _this.labels.context_guilds,
|
||||
id: BDFDB.ContextMenuUtils.createItemId(_this.name, "mark-all-read"),
|
||||
action: _ => this.clearGuilds(this.getGuilds())
|
||||
}),
|
||||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||||
label: _this.labels.context_dms,
|
||||
id: BDFDB.ContextMenuUtils.createItemId(_this.name, "mark-dms-read"),
|
||||
action: _ => BDFDB.DMUtils.markAsRead(this.getPingedDMs())
|
||||
})
|
||||
]
|
||||
}))
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return class ReadAllNotificationsButton extends Plugin {
|
||||
onLoad () {
|
||||
_this = this;
|
||||
|
||||
this.defaults = {
|
||||
general: {
|
||||
addClearButton: {value: true, description: "Adds a 'Clear Mentions' button to the recent mentions popout"},
|
||||
confirmClear: {value: false, description: "Asks for your confirmation before clearing reads"}
|
||||
},
|
||||
batch: {
|
||||
guilds: {value: true, description: "unread Servers"},
|
||||
muted: {value: false, description: "muted unread Servers"},
|
||||
dms: {value: false, description: "unread DMs"}
|
||||
}
|
||||
};
|
||||
|
||||
this.modulePatches = {
|
||||
after: [
|
||||
"UnreadDMs",
|
||||
"InboxHeader"
|
||||
]
|
||||
};
|
||||
|
||||
this.css = `
|
||||
${BDFDB.dotCN.messagespopouttabbar} {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
${BDFDB.dotCN.messagespopoutcontrols} {
|
||||
display: flex;
|
||||
}
|
||||
${BDFDB.dotCN.messagespopoutcontrols} > * {
|
||||
margin-left: 10px;
|
||||
}
|
||||
${BDFDB.dotCN._readallnotificationsbuttonframe} {
|
||||
--guildbar-avatar-size: 48px;
|
||||
}
|
||||
${BDFDB.dotCN._readallnotificationsbuttonframe}:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
#app-mount ${BDFDB.dotCN._readallnotificationsbuttonframe},
|
||||
#app-mount ${BDFDB.dotCN._readallnotificationsbuttoninner},
|
||||
#app-mount ${BDFDB.dotCN._readallnotificationsbuttonbutton} {
|
||||
height: 24px;
|
||||
}
|
||||
${BDFDB.dotCN._readallnotificationsbuttonbutton} {
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 1.3;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
onStart () {
|
||||
let loadedBlacklist = BDFDB.DataUtils.load(this, "blacklist");
|
||||
this.saveBlacklist(!BDFDB.ArrayUtils.is(loadedBlacklist) ? [] : loadedBlacklist);
|
||||
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
|
||||
onStop () {
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
|
||||
getSettingsPanel (collapseStates = {}) {
|
||||
let settingsPanel, settingsItems = [];
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "Settings",
|
||||
collapseStates: collapseStates,
|
||||
children: Object.keys(this.defaults.general).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Switch",
|
||||
plugin: this,
|
||||
keys: ["general", key],
|
||||
label: this.defaults.general[key].description,
|
||||
value: this.settings.general[key]
|
||||
})).concat(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsPanelList, {
|
||||
title: "When left clicking the 'read all' Button mark following Elements as read:",
|
||||
first: false,
|
||||
last: true,
|
||||
children: Object.keys(this.defaults.batch).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Switch",
|
||||
plugin: this,
|
||||
keys: ["batch", key],
|
||||
label: this.defaults.batch[key].description,
|
||||
value: this.settings.batch[key]
|
||||
}))
|
||||
}))
|
||||
}));
|
||||
|
||||
let listInstance = null, batchSetGuilds = value => {
|
||||
if (!value) {
|
||||
for (let id of BDFDB.LibraryStores.SortedGuildStore.getFlattenedGuildIds()) blacklist.push(id);
|
||||
blacklist = BDFDB.ArrayUtils.removeCopies(blacklist);
|
||||
}
|
||||
else blacklist = [];
|
||||
this.saveBlacklist(blacklist);
|
||||
if (listInstance) {
|
||||
listInstance.props.disabled = blacklist;
|
||||
BDFDB.ReactUtils.forceUpdate(listInstance);
|
||||
}
|
||||
};
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "Server Black List",
|
||||
collapseStates: collapseStates,
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsGuildList, {
|
||||
className: BDFDB.disCN.marginbottom20,
|
||||
disabled: BDFDB.DataUtils.load(this, "blacklist"),
|
||||
onClick: disabledGuilds => this.saveBlacklist(disabledGuilds),
|
||||
ref: instance => {listInstance = instance;}
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
|
||||
type: "Button",
|
||||
color: BDFDB.LibraryComponents.Button.Colors.GREEN,
|
||||
label: "Enable for all Servers",
|
||||
onClick: _ => batchSetGuilds(true),
|
||||
children: BDFDB.LanguageUtils.LanguageStrings.ENABLE
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
|
||||
type: "Button",
|
||||
color: BDFDB.LibraryComponents.Button.Colors.PRIMARY,
|
||||
label: "Disable for all Servers",
|
||||
onClick: _ => batchSetGuilds(false),
|
||||
children: BDFDB.LanguageUtils.LanguageStrings.DISABLE
|
||||
})
|
||||
]
|
||||
}));
|
||||
|
||||
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, settingsItems);
|
||||
}
|
||||
|
||||
onSettingsClosed () {
|
||||
if (this.SettingsUpdated) {
|
||||
delete this.SettingsUpdated;
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
}
|
||||
|
||||
forceUpdateAll () {
|
||||
BDFDB.DiscordUtils.rerenderAll();
|
||||
}
|
||||
|
||||
processUnreadDMs (e) {
|
||||
e.returnvalue = [e.returnvalue].flat(10);
|
||||
e.returnvalue.push(BDFDB.ReactUtils.createElement(ReadAllButtonComponent, {}));
|
||||
}
|
||||
|
||||
processInboxHeader (e) {
|
||||
if (!this.settings.general.addClearButton || e.instance.props.tab != BDFDB.DiscordConstants.InboxTabs.MENTIONS) return;
|
||||
let mentionedMessages = BDFDB.LibraryStores.RecentMentionsStore.getMentions();
|
||||
if (!mentionedMessages || !mentionedMessages.length) return;
|
||||
let controls = BDFDB.ReactUtils.findChild(e.returnvalue, {props: [["className", BDFDB.disCN.messagespopoutcontrols]]});
|
||||
if (controls) controls.props.children = [
|
||||
controls.props.children,
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
|
||||
text: `${BDFDB.LanguageUtils.LanguageStrings.CLOSE} (${BDFDB.LanguageUtils.LanguageStrings.ALL})`,
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, {
|
||||
className: BDFDB.disCNS.messagespopoutbutton + BDFDB.disCNS.messagespopoutbuttonsm + BDFDB.disCN.messagespopoutbuttonsecondary,
|
||||
children: BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN.messagespopoutbuttonchildrenwrapper,
|
||||
children: BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN.messagespopoutbuttonchildren,
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
|
||||
nativeClass: true,
|
||||
name: BDFDB.LibraryComponents.SvgIcon.Names.CLOSE,
|
||||
width: 16,
|
||||
height: 16
|
||||
})
|
||||
})
|
||||
}),
|
||||
onClick: _ => {
|
||||
let clear = _ => {
|
||||
if (clearing) return BDFDB.NotificationUtils.toast(`${this.labels.toast_alreadyclearing} - ${BDFDB.LanguageUtils.LibraryStrings.please_wait}`, {type: "danger"});
|
||||
let messages = [].concat(mentionedMessages).filter(n => n);
|
||||
if (messages.length) {
|
||||
clearing = true;
|
||||
let toast = BDFDB.NotificationUtils.toast(`${this.labels.toast_clearing} - ${BDFDB.LanguageUtils.LibraryStrings.please_wait}`, {timeout: 0, ellipsis: true});
|
||||
for (let i = 0; i < messages.length; i++) BDFDB.TimeUtils.timeout(_ => {
|
||||
BDFDB.LibraryModules.HTTPUtils.del({
|
||||
url: BDFDB.DiscordConstants.Endpoints.MENTIONS_MESSAGE_ID(messages[i].id),
|
||||
retries: 2,
|
||||
oldFormErrors: true
|
||||
});
|
||||
if (i == messages.length - 1) {
|
||||
clearing = false;
|
||||
toast.close();
|
||||
BDFDB.NotificationUtils.toast(this.labels.toastcleared, {type: "success"});
|
||||
}
|
||||
}, i * 1000);
|
||||
}
|
||||
};
|
||||
if (this.settings.general.confirmClear) BDFDB.ModalUtils.confirm(this, this.labels.modal_confirmmentions, clear);
|
||||
else clear();
|
||||
}
|
||||
})
|
||||
})
|
||||
].flat(10);
|
||||
}
|
||||
|
||||
saveBlacklist (savedBlacklist) {
|
||||
blacklist = savedBlacklist;
|
||||
BDFDB.DataUtils.save(savedBlacklist, this, "blacklist");
|
||||
}
|
||||
|
||||
setLabelsByLanguage () {
|
||||
switch (BDFDB.LanguageUtils.getLanguage().id) {
|
||||
case "bg": // Bulgarian
|
||||
return {
|
||||
context_dms: "Директно съобщение",
|
||||
context_guilds: "Всички сървъри",
|
||||
context_mutedguilds: "Приглушени сървъри",
|
||||
context_pingedguilds: "Pinged сървъри",
|
||||
context_unreadguilds: "Непрочетени сървъри",
|
||||
modal_confirmmentions: "Наистина ли искате да изтриете всички непрочетени споменавания?",
|
||||
modal_confirmnotifications: "Наистина ли искате да изтриете всички непрочетени известия?",
|
||||
toast_alreadyclearing: "Изтрива някои споменавания вече",
|
||||
toast_cleared: "Всички последни споменавания бяха изтрити",
|
||||
toast_clearing: "Изчиства всички скорошни споменавания"
|
||||
};
|
||||
case "da": // Danish
|
||||
return {
|
||||
context_dms: "Direkte beskeder",
|
||||
context_guilds: "Alle servere",
|
||||
context_mutedguilds: "Dæmpede servere",
|
||||
context_pingedguilds: "Pingede servere",
|
||||
context_unreadguilds: "Ulæste servere",
|
||||
modal_confirmmentions: "Er du sikker på, at du vil slette alle ulæste omtaler?",
|
||||
modal_confirmnotifications: "Er du sikker på, at du vil slette alle ulæste meddelelser?",
|
||||
toast_alreadyclearing: "Sletter allerede nogle omtaler",
|
||||
toast_cleared: "Alle nylige omtaler er blevet slettet",
|
||||
toast_clearing: "Rydder alle nylige omtaler"
|
||||
};
|
||||
case "de": // German
|
||||
return {
|
||||
context_dms: "Direktnachrichten",
|
||||
context_guilds: "Alle Server",
|
||||
context_mutedguilds: "Stummgeschaltete Server",
|
||||
context_pingedguilds: "Gepingte Server",
|
||||
context_unreadguilds: "Ungelesene Server",
|
||||
modal_confirmmentions: "Möchten Sie wirklich alle ungelesenen Erwähnungen löschen?",
|
||||
modal_confirmnotifications: "Möchten Sie wirklich alle ungelesenen Benachrichtigungen löschen?",
|
||||
toast_alreadyclearing: "Löscht bereits einige Erwähnungen",
|
||||
toast_cleared: "Alle kürzlich Erwähnungen wurden gelöscht",
|
||||
toast_clearing: "Löscht alle letzten Erwähnungen"
|
||||
};
|
||||
case "el": // Greek
|
||||
return {
|
||||
context_dms: "Αμεσα μηνύματα",
|
||||
context_guilds: "Όλοι οι διακομιστές",
|
||||
context_mutedguilds: "Σίγαση διακομιστών",
|
||||
context_pingedguilds: "Διακομιστές Ping",
|
||||
context_unreadguilds: "Μη αναγνωσμένοι διακομιστές",
|
||||
modal_confirmmentions: "Είστε βέβαιοι ότι θέλετε να διαγράψετε όλες τις μη αναγνωσμένες αναφορές;",
|
||||
modal_confirmnotifications: "Είστε βέβαιοι ότι θέλετε να διαγράψετε όλες τις μη αναγνωσμένες ειδοποιήσεις;",
|
||||
toast_alreadyclearing: "Διαγράφει ήδη κάποιες αναφορές",
|
||||
toast_cleared: "Όλες οι πρόσφατες αναφορές έχουν διαγραφεί",
|
||||
toast_clearing: "Διαγράφει όλες τις πρόσφατες αναφορές"
|
||||
};
|
||||
case "es": // Spanish
|
||||
return {
|
||||
context_dms: "Mensajes directos",
|
||||
context_guilds: "Todos los servidores",
|
||||
context_mutedguilds: "Servidores silenciados",
|
||||
context_pingedguilds: "Servidores con ping",
|
||||
context_unreadguilds: "Servidores no leídos",
|
||||
modal_confirmmentions: "¿Estás seguro de que deseas eliminar todas las menciones no leídas?",
|
||||
modal_confirmnotifications: "¿Está seguro de que desea eliminar todas las notificaciones no leídas?",
|
||||
toast_alreadyclearing: "Elimina algunas menciones ya",
|
||||
toast_cleared: "Se han eliminado todas las menciones recientes",
|
||||
toast_clearing: "Borra todas las menciones recientes"
|
||||
};
|
||||
case "fi": // Finnish
|
||||
return {
|
||||
context_dms: "Suorat viestit",
|
||||
context_guilds: "Kaikki palvelimet",
|
||||
context_mutedguilds: "Mykistetyt palvelimet",
|
||||
context_pingedguilds: "Pinged-palvelimet",
|
||||
context_unreadguilds: "Lukemattomat palvelimet",
|
||||
modal_confirmmentions: "Haluatko varmasti poistaa kaikki lukemattomat maininnat?",
|
||||
modal_confirmnotifications: "Haluatko varmasti poistaa kaikki lukemattomat ilmoitukset?",
|
||||
toast_alreadyclearing: "Poistaa jo joitain mainintoja",
|
||||
toast_cleared: "Kaikki viimeisimmät maininnat on poistettu",
|
||||
toast_clearing: "Tyhjentää kaikki viimeisimmät maininnat"
|
||||
};
|
||||
case "fr": // French
|
||||
return {
|
||||
context_dms: "Messages directs",
|
||||
context_guilds: "Tous les serveurs",
|
||||
context_mutedguilds: "Serveurs muets",
|
||||
context_pingedguilds: "Serveurs ping",
|
||||
context_unreadguilds: "Serveurs non lus",
|
||||
modal_confirmmentions: "Voulez-vous vraiment supprimer toutes les mentions non lues?",
|
||||
modal_confirmnotifications: "Voulez-vous vraiment supprimer toutes les notifications non lues?",
|
||||
toast_alreadyclearing: "Supprime déjà certaines mentions",
|
||||
toast_cleared: "Toutes les mentions récentes ont été supprimées",
|
||||
toast_clearing: "Efface toutes les mentions récentes"
|
||||
};
|
||||
case "hr": // Croatian
|
||||
return {
|
||||
context_dms: "Direktna poruka",
|
||||
context_guilds: "Svi poslužitelji",
|
||||
context_mutedguilds: "Prigušeni poslužitelji",
|
||||
context_pingedguilds: "Pingirani poslužitelji",
|
||||
context_unreadguilds: "Nepročitani poslužitelji",
|
||||
modal_confirmmentions: "Jeste li sigurni da želite izbrisati sva nepročitana spominjanja?",
|
||||
modal_confirmnotifications: "Jeste li sigurni da želite izbrisati sve nepročitane obavijesti?",
|
||||
toast_alreadyclearing: "Briše već spomenute",
|
||||
toast_cleared: "Sva nedavna spominjanja su izbrisana",
|
||||
toast_clearing: "Briše sva nedavna spominjanja"
|
||||
};
|
||||
case "hu": // Hungarian
|
||||
return {
|
||||
context_dms: "Közvetlen üzenet",
|
||||
context_guilds: "Minden szerver",
|
||||
context_mutedguilds: "Némított szerverek",
|
||||
context_pingedguilds: "Pingelt szerverek",
|
||||
context_unreadguilds: "Olvasatlan szerverek",
|
||||
modal_confirmmentions: "Biztosan törli az összes olvasatlan említést?",
|
||||
modal_confirmnotifications: "Biztosan törli az összes olvasatlan értesítést?",
|
||||
toast_alreadyclearing: "Néhány említést már töröl",
|
||||
toast_cleared: "Az összes közelmúltbeli említést törölték",
|
||||
toast_clearing: "Törli az összes közelmúltbeli említést"
|
||||
};
|
||||
case "it": // Italian
|
||||
return {
|
||||
context_dms: "Messaggi diretti",
|
||||
context_guilds: "Tutti i server",
|
||||
context_mutedguilds: "Server disattivati",
|
||||
context_pingedguilds: "Server sottoposti a ping",
|
||||
context_unreadguilds: "Server non letti",
|
||||
modal_confirmmentions: "Sei sicuro di voler eliminare tutte le menzioni non lette?",
|
||||
modal_confirmnotifications: "Sei sicuro di voler eliminare tutte le notifiche non lette?",
|
||||
toast_alreadyclearing: "Elimina già alcune menzioni",
|
||||
toast_cleared: "Tutte le menzioni recenti sono state eliminate",
|
||||
toast_clearing: "Cancella tutte le menzioni recenti"
|
||||
};
|
||||
case "ja": // Japanese
|
||||
return {
|
||||
context_dms: "ダイレクトメッセージ",
|
||||
context_guilds: "すべてのサーバー",
|
||||
context_mutedguilds: "ミュートされたサーバー",
|
||||
context_pingedguilds: "pingされたサーバー",
|
||||
context_unreadguilds: "未読サーバー",
|
||||
modal_confirmmentions: "未読のメンションをすべて削除してもよろしいですか?",
|
||||
modal_confirmnotifications: "未読の通知をすべて削除してもよろしいですか?",
|
||||
toast_alreadyclearing: "すでにいくつかの言及を削除します",
|
||||
toast_cleared: "最近の言及はすべて削除されました",
|
||||
toast_clearing: "最近の言及をすべてクリアします"
|
||||
};
|
||||
case "ko": // Korean
|
||||
return {
|
||||
context_dms: "쪽지",
|
||||
context_guilds: "모든 서버",
|
||||
context_mutedguilds: "음소거 된 서버",
|
||||
context_pingedguilds: "핑된 서버",
|
||||
context_unreadguilds: "읽지 않은 서버",
|
||||
modal_confirmmentions: "읽지 않은 모든 멘션을 삭제 하시겠습니까?",
|
||||
modal_confirmnotifications: "읽지 않은 모든 알림을 삭제 하시겠습니까?",
|
||||
toast_alreadyclearing: "이미 일부 멘션을 삭제합니다.",
|
||||
toast_cleared: "모든 최근 멘션이 삭제되었습니다.",
|
||||
toast_clearing: "최근 멘션을 모두 지 웁니다."
|
||||
};
|
||||
case "lt": // Lithuanian
|
||||
return {
|
||||
context_dms: "Tiesioginiai pranešimai",
|
||||
context_guilds: "Visi serveriai",
|
||||
context_mutedguilds: "Nutildyti serveriai",
|
||||
context_pingedguilds: "„Pinged“ serveriai",
|
||||
context_unreadguilds: "Neskaityti serveriai",
|
||||
modal_confirmmentions: "Ar tikrai norite ištrinti visus neperskaitytus paminėjimus?",
|
||||
modal_confirmnotifications: "Ar tikrai norite ištrinti visus neperskaitytus pranešimus?",
|
||||
toast_alreadyclearing: "Kai kurie paminėjimai jau ištrinami",
|
||||
toast_cleared: "Visi naujausi paminėjimai buvo ištrinti",
|
||||
toast_clearing: "Išvalo visus naujausius paminėjimus"
|
||||
};
|
||||
case "nl": // Dutch
|
||||
return {
|
||||
context_dms: "Directe berichten",
|
||||
context_guilds: "Alle servers",
|
||||
context_mutedguilds: "Gedempte servers",
|
||||
context_pingedguilds: "Gepingde servers",
|
||||
context_unreadguilds: "Ongelezen servers",
|
||||
modal_confirmmentions: "Weet u zeker dat u alle ongelezen vermeldingen wilt verwijderen?",
|
||||
modal_confirmnotifications: "Weet u zeker dat u alle ongelezen meldingen wilt verwijderen?",
|
||||
toast_alreadyclearing: "Verwijdert al enkele vermeldingen",
|
||||
toast_cleared: "Alle recente vermeldingen zijn verwijderd",
|
||||
toast_clearing: "Wist alle recente vermeldingen"
|
||||
};
|
||||
case "no": // Norwegian
|
||||
return {
|
||||
context_dms: "Direktemeldinger",
|
||||
context_guilds: "Alle servere",
|
||||
context_mutedguilds: "Dempede servere",
|
||||
context_pingedguilds: "Pingede servere",
|
||||
context_unreadguilds: "Uleste servere",
|
||||
modal_confirmmentions: "Er du sikker på at du vil slette alle uleste omtaler?",
|
||||
modal_confirmnotifications: "Er du sikker på at du vil slette alle uleste varsler?",
|
||||
toast_alreadyclearing: "Sletter allerede noen omtaler",
|
||||
toast_cleared: "Alle nylige omtaler er slettet",
|
||||
toast_clearing: "Fjerner alle nylige omtaler"
|
||||
};
|
||||
case "pl": // Polish
|
||||
return {
|
||||
context_dms: "Bezpośrednie wiadomości",
|
||||
context_guilds: "Wszystkie serwery",
|
||||
context_mutedguilds: "Wyciszone serwery",
|
||||
context_pingedguilds: "Serwery pingowane",
|
||||
context_unreadguilds: "Nieprzeczytane serwery",
|
||||
modal_confirmmentions: "Czy na pewno chcesz usunąć wszystkie nieprzeczytane wzmianki?",
|
||||
modal_confirmnotifications: "Czy na pewno chcesz usunąć wszystkie nieprzeczytane powiadomienia?",
|
||||
toast_alreadyclearing: "Usuwa już niektóre wzmianki",
|
||||
toast_cleared: "Wszystkie ostatnie wzmianki zostały usunięte",
|
||||
toast_clearing: "Usuwa wszystkie ostatnie wzmianki"
|
||||
};
|
||||
case "pt-BR": // Portuguese (Brazil)
|
||||
return {
|
||||
context_dms: "Mensagens diretas",
|
||||
context_guilds: "Todos os servidores",
|
||||
context_mutedguilds: "Servidores Silenciados",
|
||||
context_pingedguilds: "Servidores com ping",
|
||||
context_unreadguilds: "Servidores não lidos",
|
||||
modal_confirmmentions: "Tem certeza de que deseja excluir todas as menções não lidas?",
|
||||
modal_confirmnotifications: "Tem certeza de que deseja excluir todas as notificações não lidas?",
|
||||
toast_alreadyclearing: "Exclui algumas menções já",
|
||||
toast_cleared: "Todas as menções recentes foram excluídas",
|
||||
toast_clearing: "Limpa todas as menções recentes"
|
||||
};
|
||||
case "ro": // Romanian
|
||||
return {
|
||||
context_dms: "Mesaje directe",
|
||||
context_guilds: "Toate serverele",
|
||||
context_mutedguilds: "Servere mutate",
|
||||
context_pingedguilds: "Servere pinged",
|
||||
context_unreadguilds: "Servere necitite",
|
||||
modal_confirmmentions: "Sigur doriți să ștergeți toate mențiunile necitite?",
|
||||
modal_confirmnotifications: "Sigur doriți să ștergeți toate notificările necitite?",
|
||||
toast_alreadyclearing: "Șterge deja câteva mențiuni",
|
||||
toast_cleared: "Toate mențiunile recente au fost șterse",
|
||||
toast_clearing: "Șterge toate mențiunile recente"
|
||||
};
|
||||
case "ru": // Russian
|
||||
return {
|
||||
context_dms: "Прямые сообщения",
|
||||
context_guilds: "Все серверы",
|
||||
context_mutedguilds: "Отключенные серверы",
|
||||
context_pingedguilds: "Проверенные серверы",
|
||||
context_unreadguilds: "Непрочитанные серверы",
|
||||
modal_confirmmentions: "Вы уверены, что хотите удалить все непрочитанные упоминания?",
|
||||
modal_confirmnotifications: "Вы действительно хотите удалить все непрочитанные уведомления?",
|
||||
toast_alreadyclearing: "Удаляет уже некоторые упоминания",
|
||||
toast_cleared: "Все недавние упоминания были удалены",
|
||||
toast_clearing: "Удаляет все недавние упоминания"
|
||||
};
|
||||
case "sv": // Swedish
|
||||
return {
|
||||
context_dms: "Direktmeddelanden",
|
||||
context_guilds: "Alla servrar",
|
||||
context_mutedguilds: "Dämpade servrar",
|
||||
context_pingedguilds: "Pingade servrar",
|
||||
context_unreadguilds: "Olästa servrar",
|
||||
modal_confirmmentions: "Är du säker på att du vill ta bort alla olästa omnämnanden?",
|
||||
modal_confirmnotifications: "Är du säker på att du vill ta bort alla olästa aviseringar?",
|
||||
toast_alreadyclearing: "Raderar några omnämnanden redan",
|
||||
toast_cleared: "Alla nya omnämnanden har tagits bort",
|
||||
toast_clearing: "Rensar alla senaste omnämnanden"
|
||||
};
|
||||
case "th": // Thai
|
||||
return {
|
||||
context_dms: "ข้อความโดยตรง",
|
||||
context_guilds: "เซิร์ฟเวอร์ทั้งหมด",
|
||||
context_mutedguilds: "เซิร์ฟเวอร์ที่ปิดเสียง",
|
||||
context_pingedguilds: "เซิร์ฟเวอร์ Pinged",
|
||||
context_unreadguilds: "เซิร์ฟเวอร์ที่ยังไม่ได้อ่าน",
|
||||
modal_confirmmentions: "แน่ใจไหมว่าต้องการลบข้อความที่ยังไม่ได้อ่านทั้งหมด",
|
||||
modal_confirmnotifications: "แน่ใจไหมว่าต้องการลบการแจ้งเตือนที่ยังไม่ได้อ่านทั้งหมด",
|
||||
toast_alreadyclearing: "ลบการกล่าวถึงบางส่วนแล้ว",
|
||||
toast_cleared: "ลบการกล่าวถึงล่าสุดทั้งหมดแล้ว",
|
||||
toast_clearing: "ล้างการพูดถึงล่าสุดทั้งหมด"
|
||||
};
|
||||
case "tr": // Turkish
|
||||
return {
|
||||
context_dms: "Direkt Mesajlar",
|
||||
context_guilds: "Tüm Sunucular",
|
||||
context_mutedguilds: "Sessiz Sunucular",
|
||||
context_pingedguilds: "Ping Gönderilen Sunucular",
|
||||
context_unreadguilds: "Okunmamış Sunucular",
|
||||
modal_confirmmentions: "Okunmamış tüm bahisleri silmek istediğinizden emin misiniz?",
|
||||
modal_confirmnotifications: "Okunmamış tüm bildirimleri silmek istediğinizden emin misiniz?",
|
||||
toast_alreadyclearing: "Zaten bazı bahsetmeleri siler",
|
||||
toast_cleared: "Son bahsedenlerin tümü silindi",
|
||||
toast_clearing: "Tüm son bahsedilenleri temizler"
|
||||
};
|
||||
case "uk": // Ukrainian
|
||||
return {
|
||||
context_dms: "Прямі повідомлення",
|
||||
context_guilds: "Усі сервери",
|
||||
context_mutedguilds: "Приглушені сервери",
|
||||
context_pingedguilds: "Pinged сервери",
|
||||
context_unreadguilds: "Непрочитані сервери",
|
||||
modal_confirmmentions: "Ви впевнені, що хочете видалити всі непрочитані згадки?",
|
||||
modal_confirmnotifications: "Ви впевнені, що хочете видалити всі непрочитані сповіщення?",
|
||||
toast_alreadyclearing: "Видаляє деякі згадки вже",
|
||||
toast_cleared: "Усі останні згадування були видалені",
|
||||
toast_clearing: "Очищає всі останні згадування"
|
||||
};
|
||||
case "vi": // Vietnamese
|
||||
return {
|
||||
context_dms: "Tin nhắn trực tiếp",
|
||||
context_guilds: "Tất cả máy chủ",
|
||||
context_mutedguilds: "Máy chủ bị tắt tiếng",
|
||||
context_pingedguilds: "Máy chủ Pinged",
|
||||
context_unreadguilds: "Máy chủ chưa đọc",
|
||||
modal_confirmmentions: "Bạn có chắc chắn muốn xóa tất cả các đề cập chưa đọc không?",
|
||||
modal_confirmnotifications: "Bạn có chắc chắn muốn xóa tất cả các thông báo chưa đọc không?",
|
||||
toast_alreadyclearing: "Đã xóa một số đề cập",
|
||||
toast_cleared: "Tất cả các đề cập gần đây đã bị xóa",
|
||||
toast_clearing: "Xóa tất cả các đề cập gần đây"
|
||||
};
|
||||
case "zh-CN": // Chinese (China)
|
||||
return {
|
||||
context_dms: "直接讯息",
|
||||
context_guilds: "所有服务器",
|
||||
context_mutedguilds: "静音服务器",
|
||||
context_pingedguilds: "绑定服务器",
|
||||
context_unreadguilds: "未读服务器",
|
||||
modal_confirmmentions: "您确定要删除所有未读的提及吗?",
|
||||
modal_confirmnotifications: "您确定要删除所有未读的通知吗?",
|
||||
toast_alreadyclearing: "已删除一些提及",
|
||||
toast_cleared: "最近所有提及的内容均已删除",
|
||||
toast_clearing: "清除所有最近提及的内容"
|
||||
};
|
||||
case "zh-TW": // Chinese (Taiwan)
|
||||
return {
|
||||
context_dms: "直接訊息",
|
||||
context_guilds: "所有服務器",
|
||||
context_mutedguilds: "靜音服務器",
|
||||
context_pingedguilds: "綁定服務器",
|
||||
context_unreadguilds: "未讀服務器",
|
||||
modal_confirmmentions: "您確定要刪除所有未讀的提及嗎?",
|
||||
modal_confirmnotifications: "您確定要刪除所有未讀的通知嗎?",
|
||||
toast_alreadyclearing: "已刪除一些提及",
|
||||
toast_cleared: "最近所有提及的內容均已刪除",
|
||||
toast_clearing: "清除所有最近提及的內容"
|
||||
};
|
||||
default: // English
|
||||
return {
|
||||
context_dms: "Direct Messages",
|
||||
context_guilds: "All Servers",
|
||||
context_mutedguilds: "Muted Servers",
|
||||
context_pingedguilds: "Pinged Servers",
|
||||
context_unreadguilds: "Unread Servers",
|
||||
modal_confirmmentions: "Are you sure you want to delete all unread Mentions?",
|
||||
modal_confirmnotifications: "Are you sure you want to delete all unread Notifications?",
|
||||
toast_alreadyclearing: "Already clearing some Mentions",
|
||||
toast_cleared: "All recent Mentions have been cleared",
|
||||
toast_clearing: "Clearing all recent Mentions"
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));
|
||||
})();
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"amounts": {
|
||||
"tooltipDelay": 0,
|
||||
"tooltipWidth": 300
|
||||
},
|
||||
"colors": {
|
||||
"tooltipColor": ""
|
||||
},
|
||||
"dates": {
|
||||
"tooltipDates": {}
|
||||
},
|
||||
"general": {
|
||||
"onlyShowOnShift": false
|
||||
},
|
||||
"items": {
|
||||
"icon": true,
|
||||
"owner": true,
|
||||
"creationDate": true,
|
||||
"joinDate": true,
|
||||
"members": true,
|
||||
"channels": true,
|
||||
"roles": true,
|
||||
"boosts": true,
|
||||
"language": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,577 +0,0 @@
|
||||
/**
|
||||
* @name ServerDetails
|
||||
* @author DevilBro
|
||||
* @authorId 278543574059057154
|
||||
* @version 1.3.6
|
||||
* @description Shows Server Details in the Server List Tooltip
|
||||
* @invite Jx3TjNS
|
||||
* @donate https://www.paypal.me/MircoWittrien
|
||||
* @patreon https://www.patreon.com/MircoWittrien
|
||||
* @website https://mwittrien.github.io/
|
||||
* @source https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/ServerDetails/
|
||||
* @updateUrl https://mwittrien.github.io/BetterDiscordAddons/Plugins/ServerDetails/ServerDetails.plugin.js
|
||||
*/
|
||||
|
||||
module.exports = (_ => {
|
||||
const changeLog = {
|
||||
|
||||
};
|
||||
|
||||
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
|
||||
constructor (meta) {for (let key in meta) this[key] = meta[key];}
|
||||
getName () {return this.name;}
|
||||
getAuthor () {return this.author;}
|
||||
getVersion () {return this.version;}
|
||||
getDescription () {return `The Library Plugin needed for ${this.name} is missing. Open the Plugin Settings to download it. \n\n${this.description}`;}
|
||||
|
||||
downloadLibrary () {
|
||||
BdApi.Net.fetch("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js").then(r => {
|
||||
if (!r || r.status != 200) throw new Error();
|
||||
else return r.text();
|
||||
}).then(b => {
|
||||
if (!b) throw new Error();
|
||||
else return require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.UI.showToast("Finished downloading BDFDB Library", {type: "success"}));
|
||||
}).catch(error => {
|
||||
BdApi.UI.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
|
||||
});
|
||||
}
|
||||
|
||||
load () {
|
||||
if (!window.BDFDB_Global || !Array.isArray(window.BDFDB_Global.pluginQueue)) window.BDFDB_Global = Object.assign({}, window.BDFDB_Global, {pluginQueue: []});
|
||||
if (!window.BDFDB_Global.downloadModal) {
|
||||
window.BDFDB_Global.downloadModal = true;
|
||||
BdApi.UI.showConfirmationModal("Library Missing", `The Library Plugin needed for ${this.name} is missing. Please click "Download Now" to install it.`, {
|
||||
confirmText: "Download Now",
|
||||
cancelText: "Cancel",
|
||||
onCancel: _ => {delete window.BDFDB_Global.downloadModal;},
|
||||
onConfirm: _ => {
|
||||
delete window.BDFDB_Global.downloadModal;
|
||||
this.downloadLibrary();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!window.BDFDB_Global.pluginQueue.includes(this.name)) window.BDFDB_Global.pluginQueue.push(this.name);
|
||||
}
|
||||
start () {this.load();}
|
||||
stop () {}
|
||||
getSettingsPanel () {
|
||||
let template = document.createElement("template");
|
||||
template.innerHTML = `<div style="color: var(--text-strong); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${this.name} is missing.\nPlease click <a style="font-weight: 500;">Download Now</a> to install it.</div>`;
|
||||
template.content.firstElementChild.querySelector("a").addEventListener("click", this.downloadLibrary);
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
} : (([Plugin, BDFDB]) => {
|
||||
var _this;
|
||||
|
||||
const GuildDetailsComponent = class GuildDetails extends BdApi.React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {fetchedOwner: false, delayed: false, repositioned: false, shouldReposition: false, forced: false};
|
||||
}
|
||||
componentDidUpdate() {
|
||||
let tooltip = BDFDB.DOMUtils.getParent(BDFDB.dotCN.tooltip, BDFDB.ReactUtils.findDOMNode(this));
|
||||
if (tooltip) BDFDB.DOMUtils.addClass(tooltip, BDFDB.disCN._serverdetailstooltip);
|
||||
else if (this.props.tooltipContainer && this.props.tooltipContainer.tooltip) BDFDB.DOMUtils.removeClass(this.props.tooltipContainer.tooltip.firstElementChild, BDFDB.disCN._serverdetailstooltip);
|
||||
if (this.state.shouldReposition || _this.settings.amounts.tooltipDelay && this.state.delayed && !this.state.repositioned) {
|
||||
this.state.repositioned = true;
|
||||
this.state.shouldReposition = false;
|
||||
if (this.props.tooltipContainer && this.props.tooltipContainer.tooltip) this.props.tooltipContainer.tooltip.update();
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
if (!_this.settings.amounts.tooltipDelay && (!_this.settings.general.onlyShowOnShift || _this.settings.general.onlyShowOnShift && this.props.shiftKey)) BDFDB.DOMUtils.addClass(BDFDB.DOMUtils.getParent(BDFDB.dotCN.tooltip, BDFDB.ReactUtils.findDOMNode(this)), BDFDB.disCN._serverdetailstooltip);
|
||||
}
|
||||
render() {
|
||||
if (_this.settings.general.onlyShowOnShift) {
|
||||
let addListener = expanded => {
|
||||
let triggered = false, listener = event => {
|
||||
if (event.which != 16 || triggered) return;
|
||||
triggered = true;
|
||||
document.removeEventListener(expanded ? "keyup" : "keydown", listener);
|
||||
this.props.shiftKey = !expanded;
|
||||
this.state.forced = !expanded;
|
||||
this.state.repositioned = false;
|
||||
this.state.shouldReposition = true;
|
||||
BDFDB.ReactUtils.forceUpdate(this);
|
||||
};
|
||||
document.addEventListener(expanded ? "keyup" : "keydown", listener);
|
||||
};
|
||||
if (!this.props.shiftKey) {
|
||||
addListener(false);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
addListener(true);
|
||||
}
|
||||
}
|
||||
let owner = BDFDB.LibraryStores.UserStore.getUser(this.props.guild.ownerId);
|
||||
if (!owner && !this.state.fetchedOwner) {
|
||||
this.state.fetchedOwner = true;
|
||||
BDFDB.LibraryModules.UserProfileUtils.getUser(this.props.guild.ownerId).then(_ => BDFDB.ReactUtils.forceUpdate(this));
|
||||
}
|
||||
if (_this.settings.amounts.tooltipDelay && !this.state.delayed && !this.state.shouldReposition) {
|
||||
BDFDB.TimeUtils.timeout(_ => {
|
||||
this.state.delayed = true;
|
||||
BDFDB.ReactUtils.forceUpdate(this);
|
||||
}, this.state.forced ? 0 : (_this.settings.amounts.tooltipDelay * 1000));
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
let src = BDFDB.GuildUtils.getIcon(this.props.guild.id, 4096, this.props.guild.icon && BDFDB.LibraryModules.IconUtils.isAnimatedIconHash(this.props.guild.icon));
|
||||
let roles = BDFDB.LibraryStores.GuildRoleStore.getSortedRoles(this.props.guild.id);
|
||||
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
direction: BDFDB.LibraryComponents.Flex.Direction.VERTICAL,
|
||||
align: BDFDB.LibraryComponents.Flex.Align.CENTER,
|
||||
children: [
|
||||
_this.settings.items.icon && (src ? BDFDB.ReactUtils.createElement("img", {
|
||||
className: BDFDB.disCN._serverdetailsicon,
|
||||
src: src
|
||||
}) : BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN._serverdetailsicon,
|
||||
children: this.props.guild.acronym
|
||||
})),
|
||||
_this.settings.items.owner && BDFDB.ReactUtils.createElement(GuildDetailsRowComponent, {
|
||||
prefix: BDFDB.LanguageUtils.LanguageStrings.SERVER_OWNER,
|
||||
string: !owner ? BDFDB.LanguageUtils.LanguageStrings.UNKNOWN_USER : owner.username
|
||||
}),
|
||||
_this.settings.items.creationDate && BDFDB.ReactUtils.createElement(GuildDetailsRowComponent, {
|
||||
prefix: _this.labels.creation_date,
|
||||
string: BDFDB.LibraryComponents.DateInput.format(_this.settings.dates.tooltipDates, BDFDB.LibraryModules.TimestampUtils.extractTimestamp(this.props.guild.id))
|
||||
}),
|
||||
_this.settings.items.joinDate && BDFDB.ReactUtils.createElement(GuildDetailsRowComponent, {
|
||||
prefix: _this.labels.join_date,
|
||||
string: BDFDB.LibraryComponents.DateInput.format(_this.settings.dates.tooltipDates, this.props.guild.joinedAt)
|
||||
}),
|
||||
_this.settings.items.members && BDFDB.ReactUtils.createElement(GuildDetailsRowComponent, {
|
||||
prefix: BDFDB.LanguageUtils.LanguageStrings.MEMBERS,
|
||||
string: BDFDB.LibraryStores.GuildMemberCountStore.getMemberCount(this.props.guild.id)
|
||||
}),
|
||||
_this.settings.items.boosts && BDFDB.ReactUtils.createElement(GuildDetailsRowComponent, {
|
||||
prefix: _this.labels.boosts,
|
||||
string: this.props.guild.premiumSubscriberCount
|
||||
}),
|
||||
_this.settings.items.channels && BDFDB.ReactUtils.createElement(GuildDetailsRowComponent, {
|
||||
prefix: BDFDB.LanguageUtils.LanguageStrings.CHANNELS,
|
||||
string: BDFDB.LibraryStores.GuildChannelStore.getChannels(this.props.guild.id).count
|
||||
}),
|
||||
_this.settings.items.roles && roles && roles.length && BDFDB.ReactUtils.createElement(GuildDetailsRowComponent, {
|
||||
prefix: BDFDB.LanguageUtils.LanguageStrings.ROLES,
|
||||
string: roles.filter(n => n.id != this.props.guild.id).length
|
||||
}),
|
||||
_this.settings.items.language && BDFDB.ReactUtils.createElement(GuildDetailsRowComponent, {
|
||||
prefix: BDFDB.LanguageUtils.LanguageStrings.LANGUAGE,
|
||||
string: BDFDB.LanguageUtils.getName(BDFDB.LanguageUtils.languages[this.props.guild.preferredLocale]) || this.props.guild.preferredLocale
|
||||
})
|
||||
].flat(10).filter(n => n)
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const GuildDetailsRowComponent = class GuildDetailsRow extends BdApi.React.Component {
|
||||
render() {
|
||||
return (this.props.prefix.length + this.props.string.length) > Math.round(34 * (_this.settings.amounts.tooltipWidth/300)) ? [
|
||||
BDFDB.ReactUtils.createElement("div", {
|
||||
children: `${this.props.prefix}:`
|
||||
}),
|
||||
BDFDB.ReactUtils.createElement("div", {
|
||||
children: this.props.string
|
||||
})
|
||||
] : BDFDB.ReactUtils.createElement("div", {
|
||||
children: `${BDFDB.StringUtils.upperCaseFirstChar(this.props.prefix)}: ${this.props.string}`
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return class ServerDetails extends Plugin {
|
||||
onLoad () {
|
||||
_this = this;
|
||||
|
||||
this.defaults = {
|
||||
general: {
|
||||
onlyShowOnShift: {value: false, description: "Only show the Details Tooltip, while holding 'Shift'"}
|
||||
},
|
||||
items: {
|
||||
icon: {value: true, description: "icon"},
|
||||
owner: {value: true, description: "SERVER_OWNER"},
|
||||
creationDate: {value: true, description: "creation_date"},
|
||||
joinDate: {value: true, description: "join_date"},
|
||||
members: {value: true, description: "MEMBERS"},
|
||||
channels: {value: true, description: "CHANNELS"},
|
||||
roles: {value: true, description: "ROLES"},
|
||||
boosts: {value: true, description: "boosts"},
|
||||
language: {value: true, description: "LANGUAGE"}
|
||||
},
|
||||
dates: {
|
||||
tooltipDates: {value: {}, description: "Tooltip Dates"}
|
||||
},
|
||||
colors: {
|
||||
tooltipColor: {value: "", description: "Tooltip Color"}
|
||||
},
|
||||
amounts: {
|
||||
tooltipDelay: {value: 0, min: 0, max: 10, digits: 1, unit: "s", description: "Tooltip Delay"},
|
||||
tooltipWidth: {value: 300, min: 200, max: 600, digits: 0, unit: "px", description: "Tooltip Width"}
|
||||
}
|
||||
};
|
||||
|
||||
this.modulePatches = {
|
||||
after: [
|
||||
"GuildItem"
|
||||
]
|
||||
};
|
||||
|
||||
this.patchPriority = 9;
|
||||
|
||||
this.css = `
|
||||
${BDFDB.dotCNS._serverdetailstooltip + BDFDB.dotCN.tooltipcontent} {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
max-width: unset;
|
||||
word-wrap: unset;
|
||||
}
|
||||
${BDFDB.dotCNS._serverdetailstooltip + BDFDB.dotCN._serverdetailsicon} {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
${BDFDB.dotCN._serverdetailstooltip} div${BDFDB.dotCN._serverdetailsicon} {
|
||||
background-color: var(--background-base-low);
|
||||
color: var(--text-subtle);
|
||||
font-size: 40px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
onStart () {
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
|
||||
onStop () {
|
||||
this.forceUpdateAll();
|
||||
|
||||
BDFDB.DOMUtils.removeLocalStyle(this.name + "TooltipWidth");
|
||||
}
|
||||
|
||||
getSettingsPanel (collapseStates = {}) {
|
||||
let settingsPanel;
|
||||
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, {
|
||||
collapseStates: collapseStates,
|
||||
children: _ => {
|
||||
let settingsItems = [];
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "General",
|
||||
collapseStates: collapseStates,
|
||||
children: Object.keys(this.defaults.general).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Switch",
|
||||
plugin: this,
|
||||
keys: ["general", key],
|
||||
label: this.defaults.general[key].description,
|
||||
value: this.settings.general[key]
|
||||
}))
|
||||
}));
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "Tooltip Items",
|
||||
collapseStates: collapseStates,
|
||||
children: Object.keys(this.defaults.items).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Switch",
|
||||
plugin: this,
|
||||
keys: ["items", key],
|
||||
label: this.labels[this.defaults.items[key].description] || BDFDB.LanguageUtils.LanguageStrings[this.defaults.items[key].description],
|
||||
value: this.settings.items[key]
|
||||
}))
|
||||
}));
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.CollapseContainer, {
|
||||
title: "Tooltip Format",
|
||||
collapseStates: collapseStates,
|
||||
children: Object.keys(this.defaults.dates).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.DateInput, Object.assign({}, this.settings.dates[key], {
|
||||
label: this.defaults.dates[key].description,
|
||||
onChange: valueObj => {
|
||||
this.SettingsUpdated = true;
|
||||
this.settings.dates[key] = valueObj;
|
||||
BDFDB.DataUtils.save(this.settings.dates, this, "dates");
|
||||
}
|
||||
}))).concat(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormDivider, {
|
||||
className: BDFDB.disCN.marginbottom8
|
||||
})).concat(Object.keys(this.defaults.amounts).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Slider",
|
||||
plugin: this,
|
||||
keys: ["amounts", key],
|
||||
label: this.defaults.amounts[key].description,
|
||||
basis: "70%",
|
||||
min: this.defaults.amounts[key].min,
|
||||
max: this.defaults.amounts[key].max,
|
||||
digits: this.defaults.amounts[key].digits,
|
||||
markerAmount: 11,
|
||||
onValueRender: value => value + this.defaults.amounts[key].unit,
|
||||
childProps: {type: "number"},
|
||||
value: this.settings.amounts[key]
|
||||
}))).concat(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormDivider, {
|
||||
className: BDFDB.disCN.marginbottom8
|
||||
})).concat(Object.keys(this.defaults.colors).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "TextInput",
|
||||
plugin: this,
|
||||
keys: ["colors", key],
|
||||
basis: "70%",
|
||||
label: this.defaults.colors[key].description,
|
||||
value: this.settings.colors[key],
|
||||
childProps: {type: "color"},
|
||||
placeholder: this.settings.colors[key]
|
||||
})))
|
||||
}));
|
||||
|
||||
return settingsItems;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onSettingsClosed () {
|
||||
if (this.SettingsUpdated) {
|
||||
delete this.SettingsUpdated;
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
}
|
||||
|
||||
forceUpdateAll () {
|
||||
let iconSize = this.settings.amounts.tooltipWidth - 80;
|
||||
BDFDB.DOMUtils.appendLocalStyle(this.name + "TooltipWidth", `
|
||||
${BDFDB.dotCN._serverdetailstooltip} {
|
||||
min-width: ${this.settings.amounts.tooltipWidth}px !important;
|
||||
width: unset !important;
|
||||
max-width: unset !important;
|
||||
}
|
||||
${BDFDB.dotCNS._serverdetailstooltip + BDFDB.dotCN._serverdetailsicon} {
|
||||
width: ${iconSize > 0 ? iconSize : 30}px;
|
||||
height: ${iconSize > 0 ? iconSize : 30}px;
|
||||
}
|
||||
`);
|
||||
|
||||
BDFDB.DiscordUtils.rerenderAll();
|
||||
}
|
||||
|
||||
processGuildItem (e) {
|
||||
if (!e.instance.props.guild) return;
|
||||
if (!BDFDB.GuildUtils.is(e.instance.props.guild)) return;
|
||||
let tooltipContainer;
|
||||
e.returnvalue.props.children[1] = BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, Object.assign({}, e.returnvalue.props, {
|
||||
ref: instance => {if (instance) tooltipContainer = instance;},
|
||||
tooltipConfig: Object.assign({
|
||||
backgroundColor: this.settings.colors.tooltipColor
|
||||
}, e.returnvalue.props.children[1].props.tooltipConfig, {
|
||||
type: "right",
|
||||
guild: e.instance.props.guild,
|
||||
list: true,
|
||||
offset: 4
|
||||
}),
|
||||
text: (instance, event) => BDFDB.ReactUtils.createElement(GuildDetailsComponent, {
|
||||
shiftKey: event.shiftKey,
|
||||
tooltipContainer: tooltipContainer,
|
||||
guild: e.instance.props.guild
|
||||
}),
|
||||
children: e.returnvalue.props.children[1].props.children
|
||||
}));
|
||||
}
|
||||
|
||||
setLabelsByLanguage () {
|
||||
switch (BDFDB.LanguageUtils.getLanguage().id) {
|
||||
case "bg": // Bulgarian
|
||||
return {
|
||||
boosts: "Бустери",
|
||||
creation_date: "Дата на създаване",
|
||||
icon: "Икона",
|
||||
join_date: "Дата на присъединяване"
|
||||
};
|
||||
case "da": // Danish
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Oprettelsesdato",
|
||||
icon: "Ikon",
|
||||
join_date: "Deltag i dato"
|
||||
};
|
||||
case "de": // German
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Erstellungsdatum",
|
||||
icon: "Symbol",
|
||||
join_date: "Beitrittsdatum"
|
||||
};
|
||||
case "el": // Greek
|
||||
return {
|
||||
boosts: "Ενισχυτές",
|
||||
creation_date: "Ημερομηνία δημιουργίας",
|
||||
icon: "Εικονίδιο",
|
||||
join_date: "Ημερομηνία προσχώρησης"
|
||||
};
|
||||
case "es": // Spanish
|
||||
return {
|
||||
boosts: "Impulsores",
|
||||
creation_date: "Fecha de creación",
|
||||
icon: "Icono",
|
||||
join_date: "Fecha de Ingreso"
|
||||
};
|
||||
case "fi": // Finnish
|
||||
return {
|
||||
boosts: "Tehostimet",
|
||||
creation_date: "Luomispäivä",
|
||||
icon: "Kuvake",
|
||||
join_date: "Liittymispäivä"
|
||||
};
|
||||
case "fr": // French
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Date de création",
|
||||
icon: "Icône",
|
||||
join_date: "Date d'inscription"
|
||||
};
|
||||
case "hr": // Croatian
|
||||
return {
|
||||
boosts: "Pojačala",
|
||||
creation_date: "Datum stvaranja",
|
||||
icon: "Ikona",
|
||||
join_date: "Datum pridruživanja"
|
||||
};
|
||||
case "hu": // Hungarian
|
||||
return {
|
||||
boosts: "Emlékeztetők",
|
||||
creation_date: "Létrehozás dátuma",
|
||||
icon: "Ikon",
|
||||
join_date: "Csatlakozás dátuma"
|
||||
};
|
||||
case "it": // Italian
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Data di creazione",
|
||||
icon: "Icona",
|
||||
join_date: "Data di iscrizione"
|
||||
};
|
||||
case "ja": // Japanese
|
||||
return {
|
||||
boosts: "ブースター",
|
||||
creation_date: "作成日",
|
||||
icon: "アイコン",
|
||||
join_date: "参加日"
|
||||
};
|
||||
case "ko": // Korean
|
||||
return {
|
||||
boosts: "부스터",
|
||||
creation_date: "제작 일",
|
||||
icon: "상",
|
||||
join_date: "가입 날짜"
|
||||
};
|
||||
case "lt": // Lithuanian
|
||||
return {
|
||||
boosts: "Stiprintuvai",
|
||||
creation_date: "Sukūrimo data",
|
||||
icon: "Piktograma",
|
||||
join_date: "Įstojimo data"
|
||||
};
|
||||
case "nl": // Dutch
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Aanmaakdatum",
|
||||
icon: "Icoon",
|
||||
join_date: "Toetredingsdatum"
|
||||
};
|
||||
case "no": // Norwegian
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Opprettelsesdato",
|
||||
icon: "Ikon",
|
||||
join_date: "Bli med på dato"
|
||||
};
|
||||
case "pl": // Polish
|
||||
return {
|
||||
boosts: "Boosty",
|
||||
creation_date: "Data utworzenia",
|
||||
icon: "Ikona",
|
||||
join_date: "Data dołączenia"
|
||||
};
|
||||
case "pt-BR": // Portuguese (Brazil)
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Data de criação",
|
||||
icon: "Ícone",
|
||||
join_date: "Data de afiliação"
|
||||
};
|
||||
case "ro": // Romanian
|
||||
return {
|
||||
boosts: "Amplificatoare",
|
||||
creation_date: "Data crearii",
|
||||
icon: "Pictogramă",
|
||||
join_date: "Data înscrierii"
|
||||
};
|
||||
case "ru": // Russian
|
||||
return {
|
||||
boosts: "Бустеры",
|
||||
creation_date: "Дата создания",
|
||||
icon: "Икона",
|
||||
join_date: "Дате вступления"
|
||||
};
|
||||
case "sv": // Swedish
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Skapelsedagen",
|
||||
icon: "Ikon",
|
||||
join_date: "Gå med datum"
|
||||
};
|
||||
case "th": // Thai
|
||||
return {
|
||||
boosts: "บูสเตอร์",
|
||||
creation_date: "วันที่สร้าง",
|
||||
icon: "ไอคอน",
|
||||
join_date: "วันที่เข้าร่วม"
|
||||
};
|
||||
case "tr": // Turkish
|
||||
return {
|
||||
boosts: "Güçlendiriciler",
|
||||
creation_date: "Oluşturulma tarihi",
|
||||
icon: "Simge",
|
||||
join_date: "Üyelik Tarihi"
|
||||
};
|
||||
case "uk": // Ukrainian
|
||||
return {
|
||||
boosts: "Підсилювачі",
|
||||
creation_date: "Дата створення",
|
||||
icon: "Піктограма",
|
||||
join_date: "Дата приєднання"
|
||||
};
|
||||
case "vi": // Vietnamese
|
||||
return {
|
||||
boosts: "Bộ tăng tốc",
|
||||
creation_date: "Ngày thành lập",
|
||||
icon: "Biểu tượng",
|
||||
join_date: "Ngày tham gia"
|
||||
};
|
||||
case "zh-CN": // Chinese (China)
|
||||
return {
|
||||
boosts: "助推器",
|
||||
creation_date: "创建日期",
|
||||
icon: "图标",
|
||||
join_date: "参加日期"
|
||||
};
|
||||
case "zh-TW": // Chinese (Taiwan)
|
||||
return {
|
||||
boosts: "加成數",
|
||||
creation_date: "創建日期",
|
||||
icon: "圖示",
|
||||
join_date: "參加日期"
|
||||
};
|
||||
default: // English
|
||||
return {
|
||||
boosts: "Boosts",
|
||||
creation_date: "Creation Date",
|
||||
icon: "Icon",
|
||||
join_date: "Join Date"
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));
|
||||
})();
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"themeAssignments": {
|
||||
"noguild": "Frosted Glass",
|
||||
"191163742346543104": "Default",
|
||||
"230708419995107330": "Default",
|
||||
"301021184051642369": "Default",
|
||||
"340262122782982147": " Lluna Plena",
|
||||
"413603118832680960": "Default",
|
||||
"423075122610700288": "Default",
|
||||
"501047524963123212": "Default",
|
||||
"514422760781643786": "Default",
|
||||
"594829566330273792": "Default",
|
||||
"607901720806293515": "Default",
|
||||
"609090770712002575": "Default",
|
||||
"679071578021167135": "Default",
|
||||
"703597941809741834": "Default",
|
||||
"707267476391723008": "Default",
|
||||
"710203122106105927": "Default",
|
||||
"734060708219846666": "Default",
|
||||
"738872654928281620": "Default",
|
||||
"775772308261830737": "Default",
|
||||
"834834066008309800": "Default"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,411 +0,0 @@
|
||||
/**
|
||||
* @name ShowBadgesInChat
|
||||
* @author DevilBro
|
||||
* @authorId 278543574059057154
|
||||
* @version 2.1.5
|
||||
* @description Displays Badges (Nitro, Hypesquad, etc...) in the Chat/MemberList/DMList
|
||||
* @invite Jx3TjNS
|
||||
* @donate https://www.paypal.me/MircoWittrien
|
||||
* @patreon https://www.patreon.com/MircoWittrien
|
||||
* @website https://mwittrien.github.io/
|
||||
* @source https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/ShowBadgesInChat/
|
||||
* @updateUrl https://mwittrien.github.io/BetterDiscordAddons/Plugins/ShowBadgesInChat/ShowBadgesInChat.plugin.js
|
||||
*/
|
||||
|
||||
module.exports = (_ => {
|
||||
const changeLog = {
|
||||
|
||||
};
|
||||
|
||||
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
|
||||
constructor (meta) {for (let key in meta) this[key] = meta[key];}
|
||||
getName () {return this.name;}
|
||||
getAuthor () {return this.author;}
|
||||
getVersion () {return this.version;}
|
||||
getDescription () {return `The Library Plugin needed for ${this.name} is missing. Open the Plugin Settings to download it. \n\n${this.description}`;}
|
||||
|
||||
downloadLibrary () {
|
||||
BdApi.Net.fetch("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js").then(r => {
|
||||
if (!r || r.status != 200) throw new Error();
|
||||
else return r.text();
|
||||
}).then(b => {
|
||||
if (!b) throw new Error();
|
||||
else return require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.UI.showToast("Finished downloading BDFDB Library", {type: "success"}));
|
||||
}).catch(error => {
|
||||
BdApi.UI.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
|
||||
});
|
||||
}
|
||||
|
||||
load () {
|
||||
if (!window.BDFDB_Global || !Array.isArray(window.BDFDB_Global.pluginQueue)) window.BDFDB_Global = Object.assign({}, window.BDFDB_Global, {pluginQueue: []});
|
||||
if (!window.BDFDB_Global.downloadModal) {
|
||||
window.BDFDB_Global.downloadModal = true;
|
||||
BdApi.UI.showConfirmationModal("Library Missing", `The Library Plugin needed for ${this.name} is missing. Please click "Download Now" to install it.`, {
|
||||
confirmText: "Download Now",
|
||||
cancelText: "Cancel",
|
||||
onCancel: _ => {delete window.BDFDB_Global.downloadModal;},
|
||||
onConfirm: _ => {
|
||||
delete window.BDFDB_Global.downloadModal;
|
||||
this.downloadLibrary();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!window.BDFDB_Global.pluginQueue.includes(this.name)) window.BDFDB_Global.pluginQueue.push(this.name);
|
||||
}
|
||||
start () {this.load();}
|
||||
stop () {}
|
||||
getSettingsPanel () {
|
||||
let template = document.createElement("template");
|
||||
template.innerHTML = `<div style="color: var(--text-strong); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${this.name} is missing.\nPlease click <a style="font-weight: 500;">Download Now</a> to install it.</div>`;
|
||||
template.content.firstElementChild.querySelector("a").addEventListener("click", this.downloadLibrary);
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
} : (([Plugin, BDFDB]) => {
|
||||
var _this;
|
||||
var badgeConfigs = {}, loadedUsers = {}, queuedInstances = {}, requestQueue = {queue: [], timeout: null, id: null}, cacheTimeout;
|
||||
|
||||
const places = ["chat", "memberList", "dmsList"];
|
||||
|
||||
const userBadgeFlagNameMap = {
|
||||
"BOT_HTTP_INTERACTIONS": "bot_commands",
|
||||
"HYPESQUAD_ONLINE_HOUSE_1": "hypesquad_house_1",
|
||||
"HYPESQUAD_ONLINE_HOUSE_2": "hypesquad_house_2",
|
||||
"HYPESQUAD_ONLINE_HOUSE_3": "hypesquad_house_3",
|
||||
"bot_commands": "BOT_HTTP_INTERACTIONS",
|
||||
"hypesquad_house_1": "HYPESQUAD_ONLINE_HOUSE_1",
|
||||
"hypesquad_house_2": "HYPESQUAD_ONLINE_HOUSE_2",
|
||||
"hypesquad_house_3": "HYPESQUAD_ONLINE_HOUSE_3"
|
||||
};
|
||||
|
||||
const badges = {};
|
||||
|
||||
return class ShowBadgesInChat extends Plugin {
|
||||
onLoad () {
|
||||
_this = this;
|
||||
|
||||
this.modulePatches = {
|
||||
before: [
|
||||
"MessageUsername"
|
||||
],
|
||||
after: [
|
||||
"NameContainerDecorators",
|
||||
"PrivateChannel",
|
||||
"UserBadges"
|
||||
]
|
||||
};
|
||||
|
||||
for (let key in BDFDB.DiscordConstants.UserBadges) {
|
||||
let basicKey = key.replace(/_lvl\d+|_tenure_\d+_month_v2/g, "");
|
||||
if (!badges[basicKey]) badges[basicKey] = {value: true, keys: []};
|
||||
badges[basicKey].keys.push(key);
|
||||
}
|
||||
|
||||
this.css = `
|
||||
${BDFDB.dotCN._showbadgesinchatbadges} {
|
||||
display: inline-flex !important;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
position: relative;
|
||||
margin: 0 0 0 4px;
|
||||
padding: 0;
|
||||
user-select: none;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
${BDFDB.dotCN._showbadgesinchatbadges} > * {
|
||||
margin: 0;
|
||||
}
|
||||
${BDFDB.dotCNS._showbadgesinchatbadges + BDFDB.dotCN.userbadge} {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
${BDFDB.dotCNS._showbadgesinchatbadges + BDFDB.dotCN.userbadge + BDFDB.dotCN._showbadgesinchatindicator}::before {
|
||||
display: none;
|
||||
}
|
||||
${BDFDB.dotCNS._showbadgesinchatbadgessettings + BDFDB.dotCN.userbadge} {
|
||||
width: 24px !important;
|
||||
height: 20px !important;
|
||||
}
|
||||
${BDFDB.dotCN.memberpremiumicon} {
|
||||
display: none;
|
||||
}
|
||||
${BDFDB.dotCNS._showbadgesinchatbadges + BDFDB.dotCN.memberpremiumicon} {
|
||||
display: block;
|
||||
position: static;
|
||||
margin: 0;
|
||||
}
|
||||
${BDFDB.dotCNS.messageheadertext + BDFDB.dotCN._showbadgesinchatbadgeschat} {
|
||||
top: 0.2rem;
|
||||
}
|
||||
${BDFDB.dotCNS.messagerepliedmessage + BDFDB.dotCN._showbadgesinchatbadgeschat} {
|
||||
top: 0;
|
||||
}
|
||||
${BDFDB.dotCN.messageheadertext}:has(${BDFDB.dotCN._showbadgesinchatbadges}) ${BDFDB.dotCN.bottag} {
|
||||
top: 0.4rem;
|
||||
}
|
||||
${BDFDB.dotCNS.messagecompact + BDFDB.dotCN.messageusername} ~ ${BDFDB.dotCN._showbadgesinchatbadges},
|
||||
${BDFDB.dotCNS.messagerepliedmessage + BDFDB.dotCN.messageusername} ~ ${BDFDB.dotCN._showbadgesinchatbadges} {
|
||||
text-indent: 0;
|
||||
}
|
||||
${BDFDB.dotCNS.messagerepliedmessage + BDFDB.dotCN.messageusername} ~ ${BDFDB.dotCN._showbadgesinchatbadges} {
|
||||
margin-left: 0;
|
||||
margin-right: .25rem;
|
||||
}
|
||||
|
||||
${BDFDB.dotCN._showbadgesinchatbadgessettings} {
|
||||
color: var(--text-strong);
|
||||
}
|
||||
${BDFDB.dotCN._showbadgesinchatbadgessettings} * {
|
||||
cursor: default;
|
||||
}
|
||||
${BDFDB.dotCN._showbadgesinchatbadgessettings}:last-child {
|
||||
margin-right: 8px;
|
||||
}
|
||||
${BDFDB.dotCN._showbadgesinchatbadges} .bd-profile-badge {
|
||||
height: 15px;
|
||||
}
|
||||
${BDFDB.dotCN._showbadgesinchatbadgeschat} .bd-profile-badge {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
${BDFDB.dotCN._showbadgesinchatbadgesmemberlist} .bd-profile-badge {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
onStart () {
|
||||
queuedInstances = {}, loadedUsers = {};
|
||||
requestQueue = {queue: [], timeout: null, id: null};
|
||||
|
||||
badgeConfigs = BDFDB.DataUtils.load(this, "badgeConfigs");
|
||||
for (let key in badges) {
|
||||
if (!badgeConfigs[key]) badgeConfigs[key] = {};
|
||||
for (let key2 of places) if (badgeConfigs[key][key2] == undefined) badgeConfigs[key][key2] = true;
|
||||
badgeConfigs[key].key = key;
|
||||
}
|
||||
|
||||
let badgeCache = BDFDB.DataUtils.load(this, "badgeCache");
|
||||
if (badgeCache) {
|
||||
let now = (new Date()).getTime(), month = 1000*60*60*24*30;
|
||||
for (let id in badgeCache) {
|
||||
if (now - badgeCache[id].date > month) delete badgeCache[id];
|
||||
else loadedUsers[id] = badgeCache[id];
|
||||
}
|
||||
BDFDB.DataUtils.save(badgeCache, this, "badgeCache");
|
||||
}
|
||||
|
||||
const processUser = (id, data) => {
|
||||
loadedUsers[id] = {}
|
||||
loadedUsers[id].badges = data.badges;
|
||||
loadedUsers[id].date = (new Date()).getTime();
|
||||
|
||||
BDFDB.TimeUtils.clear(cacheTimeout);
|
||||
cacheTimeout = BDFDB.TimeUtils.timeout(_ => BDFDB.DataUtils.save(loadedUsers, this, "badgeCache"), 5000);
|
||||
|
||||
if (requestQueue.id && requestQueue.id == id) {
|
||||
BDFDB.ReactUtils.forceUpdate(queuedInstances[requestQueue.id]);
|
||||
delete queuedInstances[requestQueue.id];
|
||||
requestQueue.id = null;
|
||||
BDFDB.TimeUtils.timeout(_ => this.runQueue(), 1000);
|
||||
}
|
||||
};
|
||||
BDFDB.PatchUtils.patch(this, BDFDB.LibraryModules.DispatchApiUtils, "dispatch", {after: e => {
|
||||
if (BDFDB.ObjectUtils.is(e.methodArguments[0]) && e.methodArguments[0].type == "USER_PROFILE_FETCH_FAILURE" && e.methodArguments[0].userId) {
|
||||
const user = BDFDB.LibraryStores.UserStore.getUser(e.methodArguments[0].userId);
|
||||
if (user && !loadedUsers[user.id]) processUser(e.methodArguments[0].userId, {user: user || {}, flags: user ? user.publicFlags : 0});
|
||||
}
|
||||
else if (BDFDB.ObjectUtils.is(e.methodArguments[0]) && e.methodArguments[0].type == "USER_PROFILE_FETCH_SUCCESS") {
|
||||
let userProfile = e.methodArguments[0].userProfile || e.methodArguments[0];
|
||||
if (userProfile && userProfile.user) processUser(userProfile.user.id, userProfile);
|
||||
}
|
||||
}});
|
||||
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
|
||||
onStop () {
|
||||
BDFDB.TimeUtils.clear(requestQueue.timeout);
|
||||
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
|
||||
getSettingsPanel (collapseStates = {}) {
|
||||
let settingsPanel;
|
||||
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, {
|
||||
collapseStates: collapseStates,
|
||||
children: _ => {
|
||||
let settingsItems = [];
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FormTitle.Title, {
|
||||
className: BDFDB.disCN.marginbottom4,
|
||||
tag: BDFDB.LibraryComponents.FormTitle.Tags.H3,
|
||||
children: "Show Badges in"
|
||||
}));
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsList, {
|
||||
settings: places,
|
||||
data: Object.keys(badges).filter(n => n.indexOf("BOT_") != 0).map(key => badgeConfigs[key]),
|
||||
noRemove: true,
|
||||
renderLabel: (cardData, instance) => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex.Child, {
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Clickable, {
|
||||
onClick: _ => {
|
||||
for (let settingId of places) badgeConfigs[cardData.key][settingId] = true;
|
||||
BDFDB.DataUtils.save(badgeConfigs, this, "badgeConfigs");
|
||||
BDFDB.ReactUtils.forceUpdate(instance);
|
||||
this.SettingsUpdated = true;
|
||||
},
|
||||
onContextMenu: _ => {
|
||||
for (let settingId of places) badgeConfigs[cardData.key][settingId] = false;
|
||||
BDFDB.DataUtils.save(badgeConfigs, this, "badgeConfigs");
|
||||
BDFDB.ReactUtils.forceUpdate(instance);
|
||||
this.SettingsUpdated = true;
|
||||
},
|
||||
children: cardData.key.split("_").map(n => BDFDB.StringUtils.upperCaseFirstChar(n.toLowerCase())).join(" ")
|
||||
})
|
||||
}),
|
||||
badges[cardData.key] && badges[cardData.key].keys.map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.UserBadges, {
|
||||
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN._showbadgesinchatbadges, BDFDB.disCN._showbadgesinchatbadgessettings),
|
||||
place: "settings",
|
||||
custom: true,
|
||||
badges: [{id: key, icon: BDFDB.DiscordConstants.UserBadges[key]}]
|
||||
}))
|
||||
]
|
||||
}),
|
||||
onHeaderClick: (settingId, instance) => {
|
||||
for (let key in badgeConfigs) badgeConfigs[key][settingId] = true;
|
||||
BDFDB.DataUtils.save(badgeConfigs, this, "badgeConfigs");
|
||||
BDFDB.ReactUtils.forceUpdate(instance);
|
||||
this.SettingsUpdated = true;
|
||||
},
|
||||
onHeaderContextMenu: (settingId, instance) => {
|
||||
for (let key in badgeConfigs) badgeConfigs[key][settingId] = false;
|
||||
BDFDB.DataUtils.save(badgeConfigs, this, "badgeConfigs");
|
||||
BDFDB.ReactUtils.forceUpdate(instance);
|
||||
this.SettingsUpdated = true;
|
||||
},
|
||||
onCheckboxChange: (value, instance) => {
|
||||
badgeConfigs[instance.props.cardId][instance.props.settingId] = value;
|
||||
BDFDB.DataUtils.save(badgeConfigs, this, "badgeConfigs");
|
||||
this.SettingsUpdated = true;
|
||||
}
|
||||
}));
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsItem, {
|
||||
type: "Button",
|
||||
color: BDFDB.LibraryComponents.Button.Colors.RED,
|
||||
label: "Reset cached Badge Data",
|
||||
onClick: _ => BDFDB.ModalUtils.confirm(this, "Are you sure you want to reset the Badge Cache? This will force all Badges to rerender.", _ => {
|
||||
BDFDB.DataUtils.remove(this, "badgeCache");
|
||||
this.SettingsUpdated = true;
|
||||
}),
|
||||
children: BDFDB.LanguageUtils.LanguageStrings.RESET
|
||||
}));
|
||||
|
||||
return settingsItems;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onSettingsClosed () {
|
||||
if (this.SettingsUpdated) {
|
||||
delete this.SettingsUpdated;
|
||||
this.forceUpdateAll();
|
||||
}
|
||||
}
|
||||
|
||||
forceUpdateAll () {
|
||||
BDFDB.PatchUtils.forceAllUpdates(this);
|
||||
BDFDB.MessageUtils.rerenderAll();
|
||||
}
|
||||
|
||||
processMessageUsername (e) {
|
||||
if (!e.instance.props.message) return;
|
||||
const author = e.instance.props.userOverride || e.instance.props.message.author;
|
||||
let index = e.instance.props.compact ? 1 : 0;
|
||||
if (!BDFDB.ArrayUtils.is(e.instance.props.decorations[index])) e.instance.props.decorations[index] = [e.instance.props.decorations[index]].filter(n => n);
|
||||
this.injectBadges(e.instance.props.decorations[index], author, (BDFDB.LibraryStores.ChannelStore.getChannel(e.instance.props.message.channel_id) || {}).guild_id, "chat");
|
||||
}
|
||||
|
||||
processNameContainerDecorators (e) {
|
||||
if (!e.instance.props.user) return;
|
||||
this.injectBadges(e.returnvalue.props.children, e.instance.props.user, BDFDB.LibraryStores.SelectedGuildStore.getGuildId(), "memberList");
|
||||
}
|
||||
|
||||
processPrivateChannel (e) {
|
||||
if (!e.instance.props.user) return;
|
||||
let wrapper = e.returnvalue && e.returnvalue.props.children && e.returnvalue.props.children.props && typeof e.returnvalue.props.children.props.children == "function" ? e.returnvalue.props.children : e.returnvalue;
|
||||
if (typeof wrapper.props.children == "function") {
|
||||
let childrenRender = wrapper.props.children;
|
||||
wrapper.props.children = BDFDB.TimeUtils.suppress((...args) => {
|
||||
let children = childrenRender(...args);
|
||||
this._processPrivateChannel(e.instance, children);
|
||||
return children;
|
||||
}, "Error in Children Render of PrivateChannel!", this);
|
||||
}
|
||||
else this._processPrivateChannel(e.instance, wrapper);
|
||||
}
|
||||
|
||||
_processPrivateChannel (instance, returnvalue, a) {
|
||||
const wrapper = returnvalue.props.decorators ? returnvalue : BDFDB.ReactUtils.findChild(returnvalue, {props: ["decorators"]}) || returnvalue;
|
||||
if (!wrapper) return;
|
||||
wrapper.props.decorators = [wrapper.props.decorators].flat(10);
|
||||
this.injectBadges(wrapper.props.decorators, instance.props.user, null, "dmsList");
|
||||
}
|
||||
|
||||
processUserBadges (e) {
|
||||
if (!e.instance.props.custom) return;
|
||||
let filter = e.instance.props.place != "settings";
|
||||
for (let i in e.returnvalue.props.children) if (e.returnvalue.props.children[i]) {
|
||||
let keyName = filter && Object.keys(badges).find(n => badges[n].keys.includes(e.returnvalue.props.children[i].key.split("-")[0]));
|
||||
if (keyName && badgeConfigs[keyName] && !badgeConfigs[keyName][e.instance.props.place]) e.returnvalue.props.children[i] = null;
|
||||
else if (typeof e.returnvalue.props.children[i].props.children == "function" && e.returnvalue.props.children[i].props.text) {
|
||||
e.returnvalue.props.children[i] = BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, e.returnvalue.props.children[i].props);
|
||||
}
|
||||
}
|
||||
if (!e.returnvalue.props.children.filter(n => n).length) return null;
|
||||
}
|
||||
|
||||
injectBadges (children, user, guildId, place) {
|
||||
if (!BDFDB.ArrayUtils.is(children) || !user || user.isNonUserBot()) return;
|
||||
if (!loadedUsers[user.id] || !loadedUsers[user.id].badges || ((new Date()).getTime() - loadedUsers[user.id].date >= 1000*60*60*24*7)) {
|
||||
queuedInstances[user.id] = [].concat(queuedInstances[user.id]).filter(n => n);
|
||||
if (requestQueue.queue.indexOf(user.id) == -1) requestQueue.queue.push(user.id);
|
||||
this.runQueue();
|
||||
}
|
||||
children.push(BDFDB.ReactUtils.createElement(class extends BDFDB.ReactUtils.Component {
|
||||
render() {
|
||||
if (!loadedUsers[user.id] || !loadedUsers[user.id].badges || ((new Date()).getTime() - loadedUsers[user.id].date >= 1000*60*60*24*7)) {
|
||||
queuedInstances[user.id] = [].concat(queuedInstances[user.id]).filter(n => n);
|
||||
if (queuedInstances[user.id].indexOf(this) == -1) queuedInstances[user.id].push(this);
|
||||
return null;
|
||||
}
|
||||
else return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.UserBadges, {
|
||||
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN._showbadgesinchatbadges, BDFDB.disCN[`_showbadgesinchatbadges${place.toLowerCase()}`]),
|
||||
place: place,
|
||||
custom: true,
|
||||
badges: loadedUsers[user.id].badges
|
||||
});
|
||||
}
|
||||
}, {}, true));
|
||||
}
|
||||
|
||||
runQueue () {
|
||||
if (!requestQueue.id) {
|
||||
let id = requestQueue.queue.shift();
|
||||
if (id) {
|
||||
requestQueue.id = id;
|
||||
BDFDB.TimeUtils.clear(requestQueue.timeout);
|
||||
requestQueue.timeout = BDFDB.TimeUtils.timeout(_ => {
|
||||
requestQueue.id = null;
|
||||
this.runQueue();
|
||||
}, 30000);
|
||||
|
||||
BDFDB.LibraryModules.UserProfileUtils.fetchProfile(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));
|
||||
})();
|
||||
@@ -1,43 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"connections": {
|
||||
"amazon-music": true,
|
||||
"battlenet": true,
|
||||
"bluesky": true,
|
||||
"bungie": true,
|
||||
"crunchyroll": true,
|
||||
"domain": true,
|
||||
"ebay": true,
|
||||
"epicgames": true,
|
||||
"facebook": true,
|
||||
"github": true,
|
||||
"instagram": true,
|
||||
"leagueoflegends": true,
|
||||
"mastodon": true,
|
||||
"meta_quest_or_horizon": true,
|
||||
"paypal": true,
|
||||
"playstation": true,
|
||||
"playstation-stg": true,
|
||||
"reddit": true,
|
||||
"riotgames": true,
|
||||
"roblox": true,
|
||||
"samsung": true,
|
||||
"skype": true,
|
||||
"spotify": true,
|
||||
"steam": true,
|
||||
"tiktok": true,
|
||||
"twitch": true,
|
||||
"twitter_legacy": true,
|
||||
"twitter": true,
|
||||
"xbox": true,
|
||||
"youtube": true
|
||||
},
|
||||
"general": {
|
||||
"useColoredIcons": false,
|
||||
"useColoredTooltips": false,
|
||||
"showDetails": true,
|
||||
"showVerifiedBadge": true,
|
||||
"openWebpage": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
/**
|
||||
* @name ShowConnections
|
||||
* @author DevilBro
|
||||
* @authorId 278543574059057154
|
||||
* @version 1.3.3
|
||||
* @description Shows the connected Accounts of a User in the UserPopout
|
||||
* @invite Jx3TjNS
|
||||
* @donate https://www.paypal.me/MircoWittrien
|
||||
* @patreon https://www.patreon.com/MircoWittrien
|
||||
* @website https://mwittrien.github.io/
|
||||
* @source https://github.com/mwittrien/BetterDiscordAddons/tree/master/Plugins/ShowConnections/
|
||||
* @updateUrl https://mwittrien.github.io/BetterDiscordAddons/Plugins/ShowConnections/ShowConnections.plugin.js
|
||||
*/
|
||||
|
||||
module.exports = (_ => {
|
||||
const changeLog = {
|
||||
|
||||
};
|
||||
|
||||
return !window.BDFDB_Global || (!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) ? class {
|
||||
constructor (meta) {for (let key in meta) this[key] = meta[key];}
|
||||
getName () {return this.name;}
|
||||
getAuthor () {return this.author;}
|
||||
getVersion () {return this.version;}
|
||||
getDescription () {return `The Library Plugin needed for ${this.name} is missing. Open the Plugin Settings to download it. \n\n${this.description}`;}
|
||||
|
||||
downloadLibrary () {
|
||||
BdApi.Net.fetch("https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js").then(r => {
|
||||
if (!r || r.status != 200) throw new Error();
|
||||
else return r.text();
|
||||
}).then(b => {
|
||||
if (!b) throw new Error();
|
||||
else return require("fs").writeFile(require("path").join(BdApi.Plugins.folder, "0BDFDB.plugin.js"), b, _ => BdApi.UI.showToast("Finished downloading BDFDB Library", {type: "success"}));
|
||||
}).catch(error => {
|
||||
BdApi.UI.alert("Error", "Could not download BDFDB Library Plugin. Try again later or download it manually from GitHub: https://mwittrien.github.io/downloader/?library");
|
||||
});
|
||||
}
|
||||
|
||||
load () {
|
||||
if (!window.BDFDB_Global || !Array.isArray(window.BDFDB_Global.pluginQueue)) window.BDFDB_Global = Object.assign({}, window.BDFDB_Global, {pluginQueue: []});
|
||||
if (!window.BDFDB_Global.downloadModal) {
|
||||
window.BDFDB_Global.downloadModal = true;
|
||||
BdApi.UI.showConfirmationModal("Library Missing", `The Library Plugin needed for ${this.name} is missing. Please click "Download Now" to install it.`, {
|
||||
confirmText: "Download Now",
|
||||
cancelText: "Cancel",
|
||||
onCancel: _ => {delete window.BDFDB_Global.downloadModal;},
|
||||
onConfirm: _ => {
|
||||
delete window.BDFDB_Global.downloadModal;
|
||||
this.downloadLibrary();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!window.BDFDB_Global.pluginQueue.includes(this.name)) window.BDFDB_Global.pluginQueue.push(this.name);
|
||||
}
|
||||
start () {this.load();}
|
||||
stop () {}
|
||||
getSettingsPanel () {
|
||||
let template = document.createElement("template");
|
||||
template.innerHTML = `<div style="color: var(--text-strong); font-size: 16px; font-weight: 300; white-space: pre; line-height: 22px;">The Library Plugin needed for ${this.name} is missing.\nPlease click <a style="font-weight: 500;">Download Now</a> to install it.</div>`;
|
||||
template.content.firstElementChild.querySelector("a").addEventListener("click", this.downloadLibrary);
|
||||
return template.content.firstElementChild;
|
||||
}
|
||||
} : (([Plugin, BDFDB]) => {
|
||||
var _this;
|
||||
var loadedUsers, requestedUsers, queuedInstances;
|
||||
|
||||
const UserConnectionsComponents = class UserConnections extends BdApi.React.Component {
|
||||
render() {
|
||||
if (!loadedUsers[this.props.user.id] && !requestedUsers[this.props.user.id]) {
|
||||
requestedUsers[this.props.user.id] = true;
|
||||
queuedInstances[this.props.user.id] = [].concat(queuedInstances[this.props.user.id]).filter(n => n);
|
||||
BDFDB.LibraryModules.UserProfileUtils.fetchProfile(this.props.user.id);
|
||||
}
|
||||
if (!loadedUsers[this.props.user.id]) {
|
||||
if (queuedInstances[this.props.user.id].indexOf(this) == -1) queuedInstances[this.props.user.id].push(this);
|
||||
return null;
|
||||
}
|
||||
let connections = loadedUsers[this.props.user.id].filter(c => _this.settings.connections[c.type]);
|
||||
if (!connections.length) return null;
|
||||
let isLightTheme = (!this.props.theme || this.props.theme == "light") && BDFDB.DiscordUtils.getTheme() == BDFDB.disCN.themelight;
|
||||
return BDFDB.ReactUtils.createElement("section", {
|
||||
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN.userprofilesection, BDFDB.disCN._showconnectionsconnectionswrapper),
|
||||
children: BDFDB.ReactUtils.createElement("div", {
|
||||
className: BDFDB.disCN._showconnectionsconnections,
|
||||
children: connections.map(c => {
|
||||
let provider = BDFDB.LibraryModules.ConnectionProviderUtils.get(c.type);
|
||||
let url = _this.settings.general.openWebpage && provider.getPlatformUserUrl && provider.getPlatformUserUrl(c);
|
||||
let metadata = [];
|
||||
if (_this.settings.general.showDetails && provider.hasMetadata && c.metadata) {
|
||||
if (c.metadata.created_at) metadata.push(BDFDB.ReactUtils.createElement("span", {children: BDFDB.LanguageUtils.LanguageStringsFormat("MEMBER_SINCE_PLACEHOLDER", (new Date(c.metadata.created_at)).toLocaleDateString("default", {year: "numeric", month: "long", day: "numeric"}))}));
|
||||
}
|
||||
return BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
|
||||
text: `${provider.name}: ${c.name}`,
|
||||
note: metadata && metadata.length ? BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.Flex, {
|
||||
direction: BDFDB.LibraryComponents.Flex.Direction.VERTICAL,
|
||||
children: metadata
|
||||
}): null,
|
||||
tooltipConfig: {backgroundColor: _this.settings.general.useColoredTooltips && BDFDB.ColorUtils.change(provider.color, -0.3), color: !_this.settings.general.useColoredTooltips || !provider.color ? "primary" : null},
|
||||
children: BDFDB.ReactUtils.createElement(!url ? "div" : BDFDB.LibraryComponents.Anchor, Object.assign(!url ? {} : {
|
||||
href: url
|
||||
}, {
|
||||
className: BDFDB.DOMUtils.formatClassName(BDFDB.disCN._showconnectionsconnection, url && BDFDB.disCN.cursorpointer),
|
||||
onContextMenu: event => {
|
||||
BDFDB.ContextMenuUtils.open(_this, event, BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuGroup, {
|
||||
children: [
|
||||
BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||||
label: BDFDB.LanguageUtils.LibraryStringsFormat("copy", BDFDB.LanguageUtils.LanguageStrings.USERNAME),
|
||||
id: BDFDB.ContextMenuUtils.createItemId(_this.name, "copy-name"),
|
||||
action: _ => BDFDB.LibraryModules.WindowUtils.copy(c.name)
|
||||
}),
|
||||
url && BDFDB.ContextMenuUtils.createItem(BDFDB.LibraryComponents.MenuItems.MenuItem, {
|
||||
label: BDFDB.LanguageUtils.LibraryStringsFormat("copy", BDFDB.LanguageUtils.LanguageStrings.COPY_LINK),
|
||||
id: BDFDB.ContextMenuUtils.createItemId(_this.name, "copy-url"),
|
||||
action: _ => BDFDB.LibraryModules.WindowUtils.copy(url)
|
||||
})
|
||||
]
|
||||
}));
|
||||
},
|
||||
children: [
|
||||
BDFDB.ReactUtils.createElement("img", {
|
||||
className: BDFDB.disCN._showconnectionsicon,
|
||||
alt: BDFDB.LanguageUtils.LanguageStringsFormat("PLACEHOLDER_LOGO", provider.name),
|
||||
src: provider.icon[this.props.popoutColor ? (BDFDB.ColorUtils.isBright(this.props.popoutColor) ? "lightSVG" : "darkSVG") : (_this.settings.general.useColoredIcons ? (isLightTheme ? "lightSVG" : "darkSVG") : "whiteSVG")]
|
||||
}),
|
||||
_this.settings.general.showVerifiedBadge && c.verified && BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.TooltipContainer, {
|
||||
text: BDFDB.LanguageUtils.LanguageStrings.VERIFIED_CONNECTION,
|
||||
tooltipConfig: {color: "brand", type: "bottom"},
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.FlowerStar, {
|
||||
className: BDFDB.disCN._showconnectionsverifiedbadge,
|
||||
size: "50%",
|
||||
color: isLightTheme ? BDFDB.DiscordConstants.Colors.PRIMARY_200 : BDFDB.DiscordConstants.Colors.PRIMARY,
|
||||
children: BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SvgIcon, {
|
||||
name: BDFDB.LibraryComponents.SvgIcon.Names.CHECKMARK,
|
||||
width: "70%",
|
||||
height: "70%",
|
||||
color: isLightTheme ? BDFDB.DiscordConstants.Colors.PRIMARY_500 : BDFDB.DiscordConstants.Colors.WHITE
|
||||
})
|
||||
})
|
||||
})
|
||||
]
|
||||
}))
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return class ShowConnections extends Plugin {
|
||||
onLoad () {
|
||||
_this = this;
|
||||
loadedUsers = {};
|
||||
requestedUsers = {};
|
||||
queuedInstances = {};
|
||||
|
||||
this.patchPriority = 9;
|
||||
|
||||
this.modulePatches = {
|
||||
after: [
|
||||
"UserHeaderUsername"
|
||||
]
|
||||
};
|
||||
|
||||
this.defaults = {
|
||||
general: {
|
||||
useColoredIcons: {value: true, description: "Uses colored Version of the Icons"},
|
||||
useColoredTooltips: {value: true, description: "Uses colored Version of the Tooltips"},
|
||||
showDetails: {value: true, description: "Shows Details of Connection on hover"},
|
||||
showVerifiedBadge: {value: true, description: "Shows the Badge for verified Connections"},
|
||||
openWebpage: {value: true, description: "Opens the Connection Page when clicking the Icon"}
|
||||
},
|
||||
connections: {}
|
||||
};
|
||||
|
||||
for (let connection of BDFDB.LibraryModules.ConnectionProviderUtils.filter(n => n)) this.defaults.connections[connection.type] = Object.assign({}, connection, {value: true});
|
||||
|
||||
this.css = `
|
||||
${BDFDB.dotCN._showconnectionsconnectionswrapper} {
|
||||
order: 999;
|
||||
}
|
||||
${BDFDB.dotCN._showconnectionsconnections} {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
${BDFDB.dotCN._showconnectionsconnection} {
|
||||
position: relative;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin: 4px 10px 6px 0;
|
||||
}
|
||||
${BDFDB.dotCN._showconnectionsicon} {
|
||||
margin: -15% 0 0 -15%;
|
||||
width: 130%;
|
||||
height: 130%;
|
||||
}
|
||||
${BDFDB.dotCN._showconnectionsverifiedbadge} {
|
||||
position: absolute;
|
||||
bottom: -10%;
|
||||
right: -10%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
onStart () {
|
||||
BDFDB.PatchUtils.patch(this, BDFDB.LibraryModules.DispatchApiUtils, "dispatch", {after: e => {
|
||||
if (BDFDB.ObjectUtils.is(e.methodArguments[0]) && e.methodArguments[0].type == "USER_PROFILE_FETCH_SUCCESS") {
|
||||
let userProfile = e.methodArguments[0].userProfile || e.methodArguments[0];
|
||||
if (userProfile.user && userProfile.connected_accounts) {
|
||||
delete requestedUsers[userProfile.user.id];
|
||||
loadedUsers[userProfile.user.id] = userProfile.connected_accounts;
|
||||
BDFDB.ReactUtils.forceUpdate(queuedInstances[userProfile.user.id]);
|
||||
delete queuedInstances[userProfile.user.id];
|
||||
}
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
onStop () {}
|
||||
|
||||
getSettingsPanel (collapseStates = {}) {
|
||||
let settingsPanel;
|
||||
return settingsPanel = BDFDB.PluginUtils.createSettingsPanel(this, {
|
||||
collapseStates: collapseStates,
|
||||
children: _ => {
|
||||
let settingsItems = [];
|
||||
|
||||
for (let key in this.defaults.general) settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Switch",
|
||||
plugin: this,
|
||||
keys: ["general", key],
|
||||
label: this.defaults.general[key].description,
|
||||
value: this.settings.general[key]
|
||||
}));
|
||||
|
||||
settingsItems.push(BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsPanelList, {
|
||||
title: "Display Connections:",
|
||||
children: Object.keys(this.defaults.connections).map(key => BDFDB.ReactUtils.createElement(BDFDB.LibraryComponents.SettingsSaveItem, {
|
||||
type: "Switch",
|
||||
plugin: this,
|
||||
keys: ["connections", key],
|
||||
label: this.defaults.connections[key].name,
|
||||
value: this.settings.connections[key],
|
||||
labelChildren: [
|
||||
BDFDB.ReactUtils.createElement("img", {style: {width: 28, height: 28}, src: this.defaults.connections[key].icon.lightSVG}),
|
||||
BDFDB.ReactUtils.createElement("img", {style: {width: 28, height: 28}, src: this.defaults.connections[key].icon.whiteSVG})
|
||||
]
|
||||
}))
|
||||
}));
|
||||
|
||||
return settingsItems;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
processUserHeaderUsername (e) {
|
||||
let themeType = BDFDB.ObjectUtils.get(e.instance, "props.trailing.props.themeType");
|
||||
if (themeType != "SIDEBAR" && themeType != "POPOUT" || e.instance.props.className) return;
|
||||
let user = e.instance.props.user || BDFDB.LibraryStores.UserStore.getUser(e.instance.props.userId);
|
||||
if (!user || user.isNonUserBot()) return;
|
||||
e.returnvalue = [e.returnvalue].flat(10);
|
||||
e.returnvalue.push(BDFDB.ReactUtils.createElement(UserConnectionsComponents, {
|
||||
user: user,
|
||||
popoutColor: BDFDB.ObjectUtils.get(e.instance, "props.trailing.props.displayProfile.themeColors.1"),
|
||||
theme: e.instance.props.theme
|
||||
}, true));
|
||||
}
|
||||
};
|
||||
})(window.BDFDB_Global.PluginUtils.buildPlugin(changeLog));
|
||||
})();
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"settings": {
|
||||
"previewState": false,
|
||||
"previewDefaultState": false
|
||||
}
|
||||
}
|
||||
@@ -1,375 +0,0 @@
|
||||
/**
|
||||
* @name StickerEmojiPreview
|
||||
* @description Adds a zoomed preview to those tiny Stickers and Emojis
|
||||
* @version 1.3.3
|
||||
* @author Skamt
|
||||
* @website https://github.com/Skamt/BDAddons/tree/main/StickerEmojiPreview
|
||||
* @source https://raw.githubusercontent.com/Skamt/BDAddons/main/StickerEmojiPreview/StickerEmojiPreview.plugin.js
|
||||
*/
|
||||
|
||||
// config:@Config
|
||||
var Config_default = {
|
||||
"info": {
|
||||
"name": "StickerEmojiPreview",
|
||||
"version": "1.3.3",
|
||||
"description": "Adds a zoomed preview to those tiny Stickers and Emojis",
|
||||
"source": "https://raw.githubusercontent.com/Skamt/BDAddons/main/StickerEmojiPreview/StickerEmojiPreview.plugin.js",
|
||||
"github": "https://github.com/Skamt/BDAddons/tree/main/StickerEmojiPreview",
|
||||
"authors": [{
|
||||
"name": "Skamt"
|
||||
}]
|
||||
},
|
||||
"settings": {
|
||||
"previewState": false,
|
||||
"previewDefaultState": false
|
||||
}
|
||||
};
|
||||
|
||||
// common/Api.js
|
||||
var Api = new BdApi(Config_default.info.name);
|
||||
var DOM = /* @__PURE__ */ (() => Api.DOM)();
|
||||
var Data = /* @__PURE__ */ (() => Api.Data)();
|
||||
var React = /* @__PURE__ */ (() => Api.React)();
|
||||
var Patcher = /* @__PURE__ */ (() => Api.Patcher)();
|
||||
var Logger = /* @__PURE__ */ (() => Api.Logger)();
|
||||
var Webpack = /* @__PURE__ */ (() => Api.Webpack)();
|
||||
|
||||
// common/Utils/Logger.js
|
||||
Logger.patchError = (patchId) => {
|
||||
console.error(`%c[${Config_default.info.name}] %cCould not find module for %c[${patchId}]`, "color: #3a71c1;font-weight: bold;", "", "color: red;font-weight: bold;");
|
||||
};
|
||||
var Logger_default = Logger;
|
||||
|
||||
// common/Utils/EventEmitter.js
|
||||
var EventEmitter_default = class {
|
||||
constructor() {
|
||||
this.listeners = {};
|
||||
}
|
||||
isInValid(event, handler) {
|
||||
return typeof event !== "string" || typeof handler !== "function";
|
||||
}
|
||||
once(event, handler) {
|
||||
if (this.isInValid(event, handler)) return;
|
||||
if (!this.listeners[event]) this.listeners[event] = /* @__PURE__ */ new Set();
|
||||
const wrapper = () => {
|
||||
handler();
|
||||
this.off(event, wrapper);
|
||||
};
|
||||
this.listeners[event].add(wrapper);
|
||||
}
|
||||
on(event, handler) {
|
||||
if (this.isInValid(event, handler)) return;
|
||||
if (!this.listeners[event]) this.listeners[event] = /* @__PURE__ */ new Set();
|
||||
this.listeners[event].add(handler);
|
||||
return () => this.off(event, handler);
|
||||
}
|
||||
off(event, handler) {
|
||||
if (this.isInValid(event, handler)) return;
|
||||
if (!this.listeners[event]) return;
|
||||
this.listeners[event].delete(handler);
|
||||
if (this.listeners[event].size !== 0) return;
|
||||
delete this.listeners[event];
|
||||
}
|
||||
emit(event, ...payload) {
|
||||
if (!this.listeners[event]) return;
|
||||
for (const listener of this.listeners[event]) {
|
||||
try {
|
||||
listener.apply(null, payload);
|
||||
} catch (err) {
|
||||
Logger_default.error(`Could not run listener for ${event}`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// common/Utils/Plugin.js
|
||||
var Events = {
|
||||
START: "START",
|
||||
STOP: "STOP"
|
||||
};
|
||||
var Plugin_default = new class extends EventEmitter_default {
|
||||
start() {
|
||||
this.emit(Events.START);
|
||||
}
|
||||
stop() {
|
||||
this.emit(Events.STOP);
|
||||
}
|
||||
}();
|
||||
|
||||
// common/Utils/StylesLoader.js
|
||||
var styleLoader = {
|
||||
_styles: [],
|
||||
push(styles) {
|
||||
this._styles.push(styles);
|
||||
}
|
||||
};
|
||||
Plugin_default.on(Events.START, () => {
|
||||
DOM.addStyle(styleLoader._styles.join("\n"));
|
||||
});
|
||||
Plugin_default.on(Events.STOP, () => {
|
||||
DOM.removeStyle();
|
||||
});
|
||||
var StylesLoader_default = styleLoader;
|
||||
|
||||
// src/StickerEmojiPreview/styles.css
|
||||
StylesLoader_default.push(`.stickersPreview {
|
||||
width: 400px;
|
||||
font-size: 14px;
|
||||
background: oklab(0.278867 0.00249027 -0.00875303);
|
||||
border-radius: 5px;
|
||||
padding: 0.5em;
|
||||
box-shadow: var(--elevation-high);
|
||||
}
|
||||
|
||||
.stickersPreview img {
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.animated img {
|
||||
border: 1px dashed #ff8f09;
|
||||
padding: 1px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
`);
|
||||
|
||||
// common/React.jsx
|
||||
var useRef = /* @__PURE__ */ (() => React.useRef)();
|
||||
var React_default = /* @__PURE__ */ (() => React)();
|
||||
|
||||
// common/Webpack.js
|
||||
var getModule = /* @__PURE__ */ (() => Webpack.getModule)();
|
||||
var Filters = /* @__PURE__ */ (() => Webpack.Filters)();
|
||||
var getMangled = /* @__PURE__ */ (() => Webpack.getMangled)();
|
||||
|
||||
function getModuleAndKey(filter, options) {
|
||||
let module2;
|
||||
const target = getModule((entry, m) => filter(entry) ? module2 = m : false, options);
|
||||
module2 = module2?.exports;
|
||||
if (!module2) return;
|
||||
const key = Object.keys(module2).find((k) => module2[k] === target);
|
||||
if (!key) return;
|
||||
return { module: module2, key };
|
||||
}
|
||||
|
||||
// MODULES-AUTO-LOADER:@Patch/CloseExpressionPicker
|
||||
var CloseExpressionPicker_default = getModuleAndKey(Filters.byStrings("activeView:null,activeViewType:null"), { searchExports: true }) || {};
|
||||
|
||||
// common/DiscordModules/zustand.js
|
||||
var { zustand } = getMangled(Filters.bySource("useSyncExternalStoreWithSelector", "useDebugValue", "subscribe"), {
|
||||
_: Filters.byStrings("subscribe"),
|
||||
zustand: () => true
|
||||
});
|
||||
var subscribeWithSelector = getModule(Filters.byStrings("getState", "equalityFn", "fireImmediately"), { searchExports: true });
|
||||
|
||||
function create(initialState) {
|
||||
const Store = zustand(initialState);
|
||||
Object.defineProperty(Store, "state", {
|
||||
configurable: false,
|
||||
get: () => Store.getState()
|
||||
});
|
||||
return Store;
|
||||
}
|
||||
|
||||
// common/Utils/index.js
|
||||
var nop = () => {};
|
||||
|
||||
// common/Utils/Settings.js
|
||||
var SettingsStore = create(subscribeWithSelector(() => Object.assign(Config_default.settings, Data.load("settings") || {})));
|
||||
((state) => {
|
||||
const selectors = {};
|
||||
const actions = {};
|
||||
for (const [key, value] of Object.entries(state)) {
|
||||
actions[`set${key}`] = (newValue) => SettingsStore.setState({
|
||||
[key]: newValue });
|
||||
selectors[key] = (state2) => state2[key];
|
||||
}
|
||||
Object.defineProperty(SettingsStore, "selectors", { value: Object.assign(selectors) });
|
||||
Object.assign(SettingsStore, actions);
|
||||
})(SettingsStore.getInitialState());
|
||||
SettingsStore.subscribe(
|
||||
(state) => state,
|
||||
() => Data.save("settings", SettingsStore.state)
|
||||
);
|
||||
Object.assign(SettingsStore, {
|
||||
useSetting: (key) => {
|
||||
const val = SettingsStore((state) => state[key]);
|
||||
return [val, SettingsStore[`set${key}`]];
|
||||
}
|
||||
});
|
||||
var Settings_default = SettingsStore;
|
||||
|
||||
// src/StickerEmojiPreview/patches/patchCloseExpressionPicker.js
|
||||
Plugin_default.on(Events.START, () => {
|
||||
const { module: module2, key } = CloseExpressionPicker_default;
|
||||
if (!module2 || !key) return Logger_default.patchError("CloseExpressionPicker");
|
||||
const unpatch = Patcher.after(module2, key, (_, args, ret) => {
|
||||
Settings_default.setpreviewState(Settings_default.state.previewDefaultState);
|
||||
});
|
||||
Plugin_default.once(Events.STOP, unpatch);
|
||||
});
|
||||
|
||||
// MODULES-AUTO-LOADER:@Patch/ExpressionPickerInspector
|
||||
var ExpressionPickerInspector_default = getModuleAndKey(Filters.byStrings("graphicPrimary", "titlePrimary"), { searchExports: false }) || {};
|
||||
|
||||
// common/DiscordModules/Modules.js
|
||||
var DiscordPopout = /* @__PURE__ */ (() => getModule((a) => a?.prototype?.render && a.Animation, { searchExports: true }))();
|
||||
|
||||
// src/StickerEmojiPreview/Constants.js
|
||||
var PREVIEW_SIZE = 300;
|
||||
var PREVIEW_UNAVAILABLE = `data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="rgb(202 204 206)" d="M12 2C6.477 2 2 6.477 2 12C2 17.522 6.477 22 12 22C17.523 22 22 17.522 22 12C22 6.477 17.523 2 12 2ZM8 6C9.104 6 10 6.896 10 8C10 9.105 9.104 10 8 10C6.896 10 6 9.105 6 8C6 6.896 6.896 6 8 6ZM18 14C18 16.617 15.14 19 12 19C8.86 19 6 16.617 6 14V13H18V14ZM16 10C14.896 10 14 9.105 14 8C14 6.896 14.896 6 16 6C17.104 6 18 6.896 18 8C18 9.105 17.104 10 16 10Z"></path></svg>`;
|
||||
|
||||
// src/StickerEmojiPreview/components/PreviewComponent.jsx
|
||||
var PreviewComponent_default = ({ target, previewComponent }) => {
|
||||
const [show, setShow] = Settings_default.useSetting("previewState");
|
||||
const ref = useRef();
|
||||
React_default.useEffect(() => {
|
||||
function keyupHandler(e) {
|
||||
if (e.key === "Control") {
|
||||
setShow(!show);
|
||||
}
|
||||
}
|
||||
document.addEventListener("keyup", keyupHandler);
|
||||
return () => document.removeEventListener("keyup", keyupHandler);
|
||||
}, [show]);
|
||||
return /* @__PURE__ */ React_default.createElement(
|
||||
DiscordPopout, {
|
||||
renderPopout: () => /* @__PURE__ */ React_default.createElement(
|
||||
"div", {
|
||||
className: "stickersPreview",
|
||||
style: { width: `${PREVIEW_SIZE}px` }
|
||||
},
|
||||
previewComponent
|
||||
),
|
||||
targetElementRef: ref,
|
||||
shouldShow: show,
|
||||
position: "left",
|
||||
align: "bottom",
|
||||
animation: "1",
|
||||
spacing: 60
|
||||
},
|
||||
() => React_default.cloneElement(target, { ref })
|
||||
);
|
||||
};
|
||||
|
||||
// common/Components/ErrorBoundary/index.jsx
|
||||
var ErrorBoundary = class extends React_default.Component {
|
||||
state = { hasError: false, error: null, info: null };
|
||||
componentDidCatch(error, info) {
|
||||
this.setState({ error, info, hasError: true });
|
||||
const errorMessage = `
|
||||
${error?.message || ""}${(info?.componentStack || "").split("\n").slice(0, 20).join("\n")}`;
|
||||
console.error(`%c[${Config_default?.info?.name || "Unknown Plugin"}] %cthrew an exception at %c[${this.props.id}]
|
||||
`, "color: #3a71c1;font-weight: bold;", "", "color: red;font-weight: bold;", errorMessage);
|
||||
}
|
||||
renderErrorBoundary() {
|
||||
return /* @__PURE__ */ React_default.createElement("div", { style: { background: "#292c2c", padding: "20px", borderRadius: "10px" } }, /* @__PURE__ */ React_default.createElement("b", { style: { color: "#e0e1e5" } }, "An error has occured while rendering ", /* @__PURE__ */ React_default.createElement("span", { style: { color: "orange" } }, this.props.id)));
|
||||
}
|
||||
renderFallback() {
|
||||
if (React_default.isValidElement(this.props.fallback)) {
|
||||
if (this.props.passMetaProps)
|
||||
this.props.fallback.props = {
|
||||
id: this.props.id,
|
||||
plugin: Config_default?.info?.name || "Unknown Plugin",
|
||||
...this.props.fallback.props
|
||||
};
|
||||
return this.props.fallback;
|
||||
}
|
||||
return /* @__PURE__ */ React_default.createElement(
|
||||
this.props.fallback, {
|
||||
id: this.props.id,
|
||||
plugin: Config_default?.info?.name || "Unknown Plugin"
|
||||
}
|
||||
);
|
||||
}
|
||||
render() {
|
||||
if (!this.state.hasError) return this.props.children;
|
||||
return this.props.fallback ? this.renderFallback() : this.renderErrorBoundary();
|
||||
}
|
||||
};
|
||||
|
||||
// src/StickerEmojiPreview/patches/patchPickerInspector.jsx
|
||||
function getMediaInfo({ props, type }) {
|
||||
if (props.sticker) return [type, props];
|
||||
if (props.src) return [type, { src: props.src.replace(/([?&]size=)(\d+)/, `$1${PREVIEW_SIZE}`) || PREVIEW_UNAVAILABLE }];
|
||||
return ["img", null];
|
||||
}
|
||||
|
||||
function getPreviewComponent(graphicPrimary) {
|
||||
const [TypeComponent, props] = getMediaInfo(graphicPrimary);
|
||||
return /* @__PURE__ */ React.createElement(
|
||||
TypeComponent, {
|
||||
...props,
|
||||
disableAnimation: false,
|
||||
size: PREVIEW_SIZE
|
||||
}
|
||||
);
|
||||
}
|
||||
Plugin_default.on(Events.START, () => {
|
||||
const { module: module2, key } = ExpressionPickerInspector_default;
|
||||
if (!module2 || !key) return Logger_default.patchError("ExpressionPickerInspector");
|
||||
const unpatch = Patcher.after(module2, key, (_, [{ graphicPrimary, titlePrimary }], ret) => {
|
||||
if (titlePrimary?.toLowerCase().includes("upload")) return;
|
||||
return /* @__PURE__ */ React.createElement(
|
||||
ErrorBoundary, {
|
||||
id: "PreviewComponent",
|
||||
plugin: Config_default.info.name,
|
||||
fallback: ret
|
||||
},
|
||||
/* @__PURE__ */
|
||||
React.createElement(
|
||||
PreviewComponent_default, {
|
||||
target: ret,
|
||||
previewComponent: getPreviewComponent(graphicPrimary)
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
Plugin_default.once(Events.STOP, unpatch);
|
||||
});
|
||||
|
||||
// MODULES-AUTO-LOADER:@Modules/FormSwitch
|
||||
var FormSwitch_default = getModule(Filters.byStrings("note", "tooltipNote"), { searchExports: true });
|
||||
|
||||
// common/Components/Switch/index.jsx
|
||||
var Switch_default = getModule(Filters.byStrings('"data-toggleable-component":"switch"', 'layout:"horizontal"'), { searchExports: true }) || function SwitchComponentFallback(props) {
|
||||
return /* @__PURE__ */ React.createElement("div", { style: { color: "#fff" } }, props.children, /* @__PURE__ */ React.createElement(
|
||||
"input", {
|
||||
type: "checkbox",
|
||||
checked: props.value,
|
||||
onChange: (e) => props.onChange(e.target.checked)
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
// common/Components/SettingSwtich/index.jsx
|
||||
function SettingSwtich({ settingKey, note, onChange = nop, description, ...rest }) {
|
||||
const [val, set] = Settings_default.useSetting(settingKey);
|
||||
return /* @__PURE__ */ React.createElement(
|
||||
Switch_default, {
|
||||
...rest,
|
||||
checked: val,
|
||||
label: description || settingKey,
|
||||
description: note,
|
||||
onChange: (e) => {
|
||||
set(e);
|
||||
onChange(e);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// src/StickerEmojiPreview/components/SettingComponent.jsx
|
||||
function SettingComponent() {
|
||||
return [{
|
||||
settingKey: "previewDefaultState",
|
||||
description: "Preview open by default.",
|
||||
onChange() {
|
||||
Settings_default.setpreviewState(Settings_default.state.previewDefaultState);
|
||||
}
|
||||
}].map(SettingSwtich);
|
||||
}
|
||||
|
||||
// src/StickerEmojiPreview/index.jsx
|
||||
Plugin_default.getSettingsPanel = () => /* @__PURE__ */ React_default.createElement(SettingComponent, null);
|
||||
module.exports = () => Plugin_default;
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"cached": "1 3 16 18 22 23 32 33 39 40 41 45 46 47 48 49 52 53 56 112 124 125 142 144 147 153 155 156 161 166 172 174 177 204 205 209 218 226 252 256 257 286 296 308 320 342 359 371 385 412 422 439 468 483 507 508 515 541 553 572 576 580 581 597 601 607 613 636 637 641 642 643 653 659 662 664 695 712 713 714 722 734 735 736 746 752 753 770 813 823 858 865 866 894 915 922 928 929 933 973 1006 1008 1014 1030 1033 1098 1125 1128 1138 1143 1152 1183 1221",
|
||||
"filters": {
|
||||
"updated": true,
|
||||
"outdated": true,
|
||||
"downloadable": true
|
||||
},
|
||||
"general": {
|
||||
"notifyOutdated": true,
|
||||
"notifyNewEntries": true,
|
||||
"startDownloaded": false,
|
||||
"startUpdated": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"all": {
|
||||
"choices": {
|
||||
"received": {
|
||||
"input": "auto",
|
||||
"output": "$discord"
|
||||
},
|
||||
"sent": {
|
||||
"input": "auto",
|
||||
"output": "$discord"
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"translator": "googleapi",
|
||||
"backup": "----"
|
||||
},
|
||||
"exceptions": {
|
||||
"wordStart": [
|
||||
"!"
|
||||
]
|
||||
},
|
||||
"general": {
|
||||
"addTranslateButton": true,
|
||||
"addQuickTranslateButton": true,
|
||||
"usePerChatTranslation": true,
|
||||
"sendOriginalMessage": false,
|
||||
"showOriginalMessage": false,
|
||||
"useSpoilerInOriginal": false
|
||||
},
|
||||
"prefixes": {
|
||||
"translationPrefixData": [
|
||||
{
|
||||
"prefix": "$fr",
|
||||
"language": "fr"
|
||||
},
|
||||
{
|
||||
"prefix": "$de",
|
||||
"language": "de"
|
||||
},
|
||||
{
|
||||
"prefix": "$es",
|
||||
"language": "es"
|
||||
},
|
||||
{
|
||||
"prefix": "$jp",
|
||||
"language": "ja"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"settings": {
|
||||
"showOnHover": true,
|
||||
"bannerColor": false
|
||||
}
|
||||
}
|
||||
@@ -1,588 +0,0 @@
|
||||
/**
|
||||
* @runAt idle
|
||||
* @name ViewProfilePicture
|
||||
* @description Adds a button to the user popout and profile that allows you to view the Avatar and banner.
|
||||
* @version 1.3.13
|
||||
* @author Skamt
|
||||
* @website https://github.com/Skamt/BDAddons/tree/main/ViewProfilePicture
|
||||
* @source https://raw.githubusercontent.com/Skamt/BDAddons/main/ViewProfilePicture/ViewProfilePicture.plugin.js
|
||||
*/
|
||||
|
||||
// config:@Config
|
||||
var Config_default = {
|
||||
"info": {
|
||||
"name": "ViewProfilePicture",
|
||||
"version": "1.3.13",
|
||||
"description": "Adds a button to the user popout and profile that allows you to view the Avatar and banner.",
|
||||
"source": "https://raw.githubusercontent.com/Skamt/BDAddons/main/ViewProfilePicture/ViewProfilePicture.plugin.js",
|
||||
"github": "https://github.com/Skamt/BDAddons/tree/main/ViewProfilePicture",
|
||||
"authors": [{
|
||||
"name": "Skamt"
|
||||
}]
|
||||
},
|
||||
"settings": {
|
||||
"showOnHover": false,
|
||||
"bannerColor": false
|
||||
}
|
||||
};
|
||||
|
||||
// common/Api.js
|
||||
var Api = new BdApi(Config_default.info.name);
|
||||
var DOM = /* @__PURE__ */ (() => Api.DOM)();
|
||||
var Data = /* @__PURE__ */ (() => Api.Data)();
|
||||
var React = /* @__PURE__ */ (() => Api.React)();
|
||||
var Patcher = /* @__PURE__ */ (() => Api.Patcher)();
|
||||
var Logger = /* @__PURE__ */ (() => Api.Logger)();
|
||||
var Webpack = /* @__PURE__ */ (() => Api.Webpack)();
|
||||
var findInTree = /* @__PURE__ */ (() => Api.Utils.findInTree)();
|
||||
|
||||
// common/Utils/Logger.js
|
||||
Logger.patchError = (patchId) => {
|
||||
console.error(`%c[${Config_default.info.name}] %cCould not find module for %c[${patchId}]`, "color: #3a71c1;font-weight: bold;", "", "color: red;font-weight: bold;");
|
||||
};
|
||||
var Logger_default = Logger;
|
||||
|
||||
// common/Utils/EventEmitter.js
|
||||
var EventEmitter_default = class {
|
||||
constructor() {
|
||||
this.listeners = {};
|
||||
}
|
||||
isInValid(event, handler) {
|
||||
return typeof event !== "string" || typeof handler !== "function";
|
||||
}
|
||||
once(event, handler) {
|
||||
if (this.isInValid(event, handler)) return;
|
||||
if (!this.listeners[event]) this.listeners[event] = /* @__PURE__ */ new Set();
|
||||
const wrapper2 = () => {
|
||||
handler();
|
||||
this.off(event, wrapper2);
|
||||
};
|
||||
this.listeners[event].add(wrapper2);
|
||||
}
|
||||
on(event, handler) {
|
||||
if (this.isInValid(event, handler)) return;
|
||||
if (!this.listeners[event]) this.listeners[event] = /* @__PURE__ */ new Set();
|
||||
this.listeners[event].add(handler);
|
||||
return () => this.off(event, handler);
|
||||
}
|
||||
off(event, handler) {
|
||||
if (this.isInValid(event, handler)) return;
|
||||
if (!this.listeners[event]) return;
|
||||
this.listeners[event].delete(handler);
|
||||
if (this.listeners[event].size !== 0) return;
|
||||
delete this.listeners[event];
|
||||
}
|
||||
emit(event, ...payload) {
|
||||
if (!this.listeners[event]) return;
|
||||
for (const listener of this.listeners[event]) {
|
||||
try {
|
||||
listener.apply(null, payload);
|
||||
} catch (err) {
|
||||
Logger_default.error(`Could not run listener for ${event}`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// common/Utils/Plugin.js
|
||||
var Events = {
|
||||
START: "START",
|
||||
STOP: "STOP"
|
||||
};
|
||||
var Plugin_default = new class extends EventEmitter_default {
|
||||
start() {
|
||||
this.emit(Events.START);
|
||||
}
|
||||
stop() {
|
||||
this.emit(Events.STOP);
|
||||
}
|
||||
}();
|
||||
|
||||
// common/Utils/StylesLoader.js
|
||||
var styleLoader = {
|
||||
_styles: [],
|
||||
push(styles) {
|
||||
this._styles.push(styles);
|
||||
}
|
||||
};
|
||||
Plugin_default.on(Events.START, () => {
|
||||
DOM.addStyle(styleLoader._styles.join("\n"));
|
||||
});
|
||||
Plugin_default.on(Events.STOP, () => {
|
||||
DOM.removeStyle();
|
||||
});
|
||||
var StylesLoader_default = styleLoader;
|
||||
|
||||
// src/ViewProfilePicture/styles.css
|
||||
StylesLoader_default.push(`/* View Profile Button */
|
||||
.VPP-Button {
|
||||
background: rgb(1 0 1 / 54%);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.VPP-Button svg {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
/* Profile Modal_V2 */
|
||||
.VPP-float {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.VPP-Button:hover {
|
||||
background: rgb(1 0 1 / 64%);
|
||||
}
|
||||
|
||||
.VPP-hover {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.VPP-container:hover .VPP-hover {
|
||||
opacity: 1;
|
||||
}
|
||||
`);
|
||||
|
||||
// common/Utils/index.js
|
||||
function fit({ width, height, gap = 0.8 }) {
|
||||
const ratio = Math.min(innerWidth / width, innerHeight / height);
|
||||
width = Math.round(width * ratio);
|
||||
height = Math.round(height * ratio);
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
maxHeight: height * gap,
|
||||
maxWidth: width * gap
|
||||
};
|
||||
}
|
||||
var promiseHandler = (promise) => promise.then((data) => [void 0, data]).catch((err) => [err]);
|
||||
var nop = () => {};
|
||||
|
||||
function getImageDimensions(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.onload = () => resolve({
|
||||
width: img.width,
|
||||
height: img.height
|
||||
});
|
||||
img.onerror = reject;
|
||||
img.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
// common/Utils/css.js
|
||||
function join(...args) {
|
||||
const classNames = /* @__PURE__ */ new Set();
|
||||
for (const arg of args) {
|
||||
if (arg && typeof arg === "string") classNames.add(arg);
|
||||
else if (Array.isArray(arg)) arg.forEach((name) => classNames.add(name));
|
||||
else if (arg && typeof arg === "object") Object.entries(arg).forEach(([name, value]) => value && classNames.add(name));
|
||||
}
|
||||
return Array.from(classNames).join(" ");
|
||||
}
|
||||
var classNameFactory = (prefix = "", connector = "-") => (...args) => {
|
||||
const classNames = /* @__PURE__ */ new Set();
|
||||
for (const arg of args) {
|
||||
if (arg && typeof arg === "string") classNames.add(arg);
|
||||
else if (Array.isArray(arg)) arg.forEach((name) => classNames.add(name));
|
||||
else if (arg && typeof arg === "object") Object.entries(arg).forEach(([name, value]) => value && classNames.add(name));
|
||||
}
|
||||
return Array.from(classNames, (name) => `${prefix}${connector}${name}`).join(" ");
|
||||
};
|
||||
|
||||
// common/React.jsx
|
||||
var React_default = /* @__PURE__ */ (() => React)();
|
||||
|
||||
// common/Components/ErrorBoundary/index.jsx
|
||||
var ErrorBoundary = class extends React_default.Component {
|
||||
state = { hasError: false, error: null, info: null };
|
||||
componentDidCatch(error, info) {
|
||||
this.setState({ error, info, hasError: true });
|
||||
const errorMessage = `
|
||||
${error?.message || ""}${(info?.componentStack || "").split("\n").slice(0, 20).join("\n")}`;
|
||||
console.error(`%c[${Config_default?.info?.name || "Unknown Plugin"}] %cthrew an exception at %c[${this.props.id}]
|
||||
`, "color: #3a71c1;font-weight: bold;", "", "color: red;font-weight: bold;", errorMessage);
|
||||
}
|
||||
renderErrorBoundary() {
|
||||
return /* @__PURE__ */ React_default.createElement("div", { style: { background: "#292c2c", padding: "20px", borderRadius: "10px" } }, /* @__PURE__ */ React_default.createElement("b", { style: { color: "#e0e1e5" } }, "An error has occured while rendering ", /* @__PURE__ */ React_default.createElement("span", { style: { color: "orange" } }, this.props.id)));
|
||||
}
|
||||
renderFallback() {
|
||||
if (React_default.isValidElement(this.props.fallback)) {
|
||||
if (this.props.passMetaProps)
|
||||
this.props.fallback.props = {
|
||||
id: this.props.id,
|
||||
plugin: Config_default?.info?.name || "Unknown Plugin",
|
||||
...this.props.fallback.props
|
||||
};
|
||||
return this.props.fallback;
|
||||
}
|
||||
return /* @__PURE__ */ React_default.createElement(
|
||||
this.props.fallback, {
|
||||
id: this.props.id,
|
||||
plugin: Config_default?.info?.name || "Unknown Plugin"
|
||||
}
|
||||
);
|
||||
}
|
||||
render() {
|
||||
if (!this.state.hasError) return this.props.children;
|
||||
return this.props.fallback ? this.renderFallback() : this.renderErrorBoundary();
|
||||
}
|
||||
};
|
||||
|
||||
// common/Components/icons/ErrorIcon/index.jsx
|
||||
var ErrorIcon_default = (props) => /* @__PURE__ */ React.createElement("div", { ...props }, /* @__PURE__ */ React.createElement(
|
||||
"svg", {
|
||||
xmlns: "http://www.w3.org/2000/svg",
|
||||
viewBox: "0 0 24 24",
|
||||
fill: "red",
|
||||
width: "18",
|
||||
height: "18"
|
||||
},
|
||||
/* @__PURE__ */
|
||||
React.createElement(
|
||||
"path", {
|
||||
d: "M0 0h24v24H0z",
|
||||
fill: "none"
|
||||
}
|
||||
),
|
||||
/* @__PURE__ */
|
||||
React.createElement("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" })
|
||||
));
|
||||
|
||||
// common/Webpack.js
|
||||
var getModule = /* @__PURE__ */ (() => Webpack.getModule)();
|
||||
var Filters = /* @__PURE__ */ (() => Webpack.Filters)();
|
||||
var waitForModule = /* @__PURE__ */ (() => Webpack.waitForModule)();
|
||||
var getMangled = /* @__PURE__ */ (() => Webpack.getMangled)();
|
||||
|
||||
// common/DiscordModules/zustand.js
|
||||
var { zustand } = getMangled(Filters.bySource("useSyncExternalStoreWithSelector", "useDebugValue", "subscribe"), {
|
||||
_: Filters.byStrings("subscribe"),
|
||||
zustand: () => true
|
||||
});
|
||||
var subscribeWithSelector = getModule(Filters.byStrings("getState", "equalityFn", "fireImmediately"), { searchExports: true });
|
||||
|
||||
function create(initialState) {
|
||||
const Store = zustand(initialState);
|
||||
Object.defineProperty(Store, "state", {
|
||||
configurable: false,
|
||||
get: () => Store.getState()
|
||||
});
|
||||
return Store;
|
||||
}
|
||||
|
||||
// common/Utils/Settings.js
|
||||
var SettingsStore = create(subscribeWithSelector(() => Object.assign(Config_default.settings, Data.load("settings") || {})));
|
||||
((state) => {
|
||||
const selectors = {};
|
||||
const actions = {};
|
||||
for (const [key, value] of Object.entries(state)) {
|
||||
actions[`set${key}`] = (newValue) => SettingsStore.setState({
|
||||
[key]: newValue });
|
||||
selectors[key] = (state2) => state2[key];
|
||||
}
|
||||
Object.defineProperty(SettingsStore, "selectors", { value: Object.assign(selectors) });
|
||||
Object.assign(SettingsStore, actions);
|
||||
})(SettingsStore.getInitialState());
|
||||
SettingsStore.subscribe(
|
||||
(state) => state,
|
||||
() => Data.save("settings", SettingsStore.state)
|
||||
);
|
||||
Object.assign(SettingsStore, {
|
||||
useSetting: (key) => {
|
||||
const val = SettingsStore((state) => state[key]);
|
||||
return [val, SettingsStore[`set${key}`]];
|
||||
}
|
||||
});
|
||||
var Settings_default = SettingsStore;
|
||||
|
||||
// MODULES-AUTO-LOADER:@Modules/Tooltip
|
||||
var Tooltip_default = getModule(Filters.byPrototypeKeys("renderTooltip"), { searchExports: true });
|
||||
|
||||
// common/Components/Tooltip/index.jsx
|
||||
var Tooltip_default2 = ({ note, position, children }) => {
|
||||
return /* @__PURE__ */ React.createElement(
|
||||
Tooltip_default, {
|
||||
text: note,
|
||||
position: position || "top"
|
||||
},
|
||||
(props) => React.cloneElement(children, {
|
||||
...props,
|
||||
...children.props
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
// common/Components/icons/ImageIcon/index.jsx
|
||||
function ImageIcon(props) {
|
||||
return /* @__PURE__ */ React.createElement(
|
||||
"svg", {
|
||||
fill: "currentColor",
|
||||
width: "24",
|
||||
height: "24",
|
||||
viewBox: "-50 -50 484 484",
|
||||
...props
|
||||
},
|
||||
/* @__PURE__ */
|
||||
React.createElement("path", { d: "M341.333,0H42.667C19.093,0,0,19.093,0,42.667v298.667C0,364.907,19.093,384,42.667,384h298.667 C364.907,384,384,364.907,384,341.333V42.667C384,19.093,364.907,0,341.333,0z M42.667,320l74.667-96l53.333,64.107L245.333,192l96,128H42.667z" })
|
||||
);
|
||||
}
|
||||
|
||||
// common/DiscordModules/Modules.js
|
||||
var MediaViewerModal = /* @__PURE__ */ (() => getMangled("Media Viewer Modal", { MediaViewerModal: (a) => typeof a !== "string" }).MediaViewerModal)();
|
||||
|
||||
// MODULES-AUTO-LOADER:@Modules/Color
|
||||
var Color_default = getModule(Filters.byKeys("Color", "hex", "hsl"), { searchExports: false });
|
||||
|
||||
// src/ViewProfilePicture/components/VPPButton.jsx
|
||||
function getColorImg(color) {
|
||||
const canvas = document.createElement("canvas");
|
||||
const width = window.innerWidth * 0.7;
|
||||
const height = window.innerHeight * 0.5;
|
||||
canvas.setAttribute("width", width);
|
||||
canvas.setAttribute("height", height);
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = Color_default(color || "#555").hex();
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
return {
|
||||
url: canvas.toDataURL(),
|
||||
...fit({ width, height })
|
||||
};
|
||||
}
|
||||
async function getFittedDims(url) {
|
||||
const [err, dims] = await promiseHandler(getImageDimensions(url));
|
||||
return err ? {} : fit(dims);
|
||||
}
|
||||
var palletHook = getModule(Filters.byStrings("toHexString", "toHsl", "palette"), { searchExports: true }) || {};
|
||||
var VPPButton_default = ({ className, user, displayProfile }) => {
|
||||
const showOnHover = Settings_default(Settings_default.selectors.showOnHover);
|
||||
const colorFromPfp = palletHook(user.getAvatarURL(displayProfile?.guildId, 80))[0];
|
||||
const handler = async () => {
|
||||
const avatarURL = user.getAvatarURL(displayProfile.guildId, 4096, true);
|
||||
const bannerURL = displayProfile.getBannerURL({ canAnimate: true, size: 4096 });
|
||||
const color = displayProfile.accentColor ?? (displayProfile.primaryColor || colorFromPfp);
|
||||
const items = [{
|
||||
url: avatarURL,
|
||||
...fit({ width: 4096, height: 4096 })
|
||||
},
|
||||
bannerURL && {
|
||||
url: bannerURL,
|
||||
...await getFittedDims(displayProfile.getBannerURL({ canAnimate: true, size: 20 }))
|
||||
},
|
||||
(!bannerURL || Settings_default.getState().bannerColor) && getColorImg(color)
|
||||
].filter(Boolean).map((a) => ({ "type": "IMAGE", ...a }));
|
||||
MediaViewerModal({ items });
|
||||
};
|
||||
return /* @__PURE__ */ React_default.createElement(Tooltip_default2, { note: "View profile picture" }, /* @__PURE__ */ React_default.createElement(
|
||||
"div", {
|
||||
onClick: handler,
|
||||
className: join(className, showOnHover && "VPP-hover")
|
||||
},
|
||||
/* @__PURE__ */
|
||||
React_default.createElement(ImageIcon, null)
|
||||
));
|
||||
};
|
||||
|
||||
// src/ViewProfilePicture/patches/patchVPPButton.jsx
|
||||
var UserProfileModalforwardRef = getModule(Filters.byKeys("Overlay", "render"));
|
||||
var wrapper;
|
||||
waitForModule((a, _, id) => id === 587168).then((match) => {
|
||||
wrapper = match.A;
|
||||
});
|
||||
var UserProfileBanner = getMangled(Filters.bySource("avatarOffsetX", "foreignObject"), {
|
||||
Banner: Filters.byStrings("canUsePremiumProfileCustomization")
|
||||
});
|
||||
Plugin_default.on(Events.START, () => {
|
||||
Patcher.after(UserProfileBanner, "Banner", (_, [props], ret) => {
|
||||
if (props.themeType !== "MODAL_V2") return ret;
|
||||
return [
|
||||
ret,
|
||||
/* @__PURE__ */
|
||||
React.createElement(
|
||||
ErrorBoundary, {
|
||||
id: "VPPButton",
|
||||
plugin: Config_default.info.name,
|
||||
fallback: /* @__PURE__ */ React.createElement(ErrorIcon_default, { className: "VPP-Button" })
|
||||
},
|
||||
/* @__PURE__ */
|
||||
React.createElement(
|
||||
VPPButton_default, {
|
||||
className: join("VPP-Button", "VPP-float"),
|
||||
user: props.user,
|
||||
displayProfile: props.displayProfile
|
||||
}
|
||||
)
|
||||
)
|
||||
];
|
||||
});
|
||||
Patcher.after(UserProfileModalforwardRef, "render", (_, [props], ret) => {
|
||||
ret.props.className = `${ret.props.className} VPP-container`;
|
||||
const target = findInTree(ret, (a) => wrapper && wrapper === a?.type, { walkable: ["props", "children"] });
|
||||
if (!target) return;
|
||||
const children = Array.isArray(target.props.children) ? target.props.children : [target.props.children];
|
||||
children.unshift(
|
||||
/* @__PURE__ */
|
||||
React.createElement(
|
||||
ErrorBoundary, {
|
||||
id: "VPPButton",
|
||||
plugin: Config_default.info.name,
|
||||
fallback: /* @__PURE__ */ React.createElement(ErrorIcon_default, { className: "VPP-Button" })
|
||||
},
|
||||
/* @__PURE__ */
|
||||
React.createElement(
|
||||
VPPButton_default, {
|
||||
className: join("VPP-Button"),
|
||||
user: props.user,
|
||||
displayProfile: props.displayProfile
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
target.props.children = children;
|
||||
});
|
||||
});
|
||||
|
||||
// MODULES-AUTO-LOADER:@Modules/FormSwitch
|
||||
var FormSwitch_default = getModule(Filters.byStrings("note", "tooltipNote"), { searchExports: true });
|
||||
|
||||
// common/Components/Switch/index.jsx
|
||||
var Switch_default = getModule(Filters.byStrings('"data-toggleable-component":"switch"', 'layout:"horizontal"'), { searchExports: true }) || function SwitchComponentFallback(props) {
|
||||
return /* @__PURE__ */ React.createElement("div", { style: { color: "#fff" } }, props.children, /* @__PURE__ */ React.createElement(
|
||||
"input", {
|
||||
type: "checkbox",
|
||||
checked: props.value,
|
||||
onChange: (e) => props.onChange(e.target.checked)
|
||||
}
|
||||
));
|
||||
};
|
||||
|
||||
// common/Components/Divider/styles.css
|
||||
StylesLoader_default.push(`.divider-horizontal {
|
||||
border-top: thin solid var(--border-subtle);
|
||||
align-self: stretch;
|
||||
margin:var(--divider-gap) var(--divider-gutter) var(--divider-gap) var(--divider-gutter) ;
|
||||
}
|
||||
|
||||
.divider-vertical {
|
||||
border-left: thin solid var(--border-subtle);
|
||||
align-self: stretch;
|
||||
margin:var(--divider-gutter) var(--divider-gap) var(--divider-gutter) var(--divider-gap);
|
||||
}
|
||||
`);
|
||||
|
||||
// common/Components/Divider/index.jsx
|
||||
var c = classNameFactory("divider");
|
||||
|
||||
function Divider({ gap = 15, gutter = 0, direction = Divider.direction.HORIZONTAL }) {
|
||||
return /* @__PURE__ */ React_default.createElement(
|
||||
"div", {
|
||||
style: { "--divider-gap": `${gap}px`, "--divider-gutter": `${gutter}%` },
|
||||
className: c("base", direction)
|
||||
}
|
||||
);
|
||||
}
|
||||
Divider.direction = {
|
||||
HORIZONTAL: "horizontal",
|
||||
VERTICAL: "vertical"
|
||||
};
|
||||
|
||||
// common/Components/SettingSwtich/index.jsx
|
||||
function SettingSwtich({ settingKey, note, border = false, onChange = nop, description, ...rest }) {
|
||||
const [val, set] = Settings_default.useSetting(settingKey);
|
||||
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
||||
Switch_default, {
|
||||
...rest,
|
||||
checked: val,
|
||||
label: description || settingKey,
|
||||
description: note,
|
||||
onChange: (e) => {
|
||||
set(e);
|
||||
onChange(e);
|
||||
}
|
||||
}
|
||||
), border && /* @__PURE__ */ React.createElement(Divider, { gap: 15 }));
|
||||
}
|
||||
|
||||
// common/Components/FieldSet/styles.css
|
||||
StylesLoader_default.push(`.fieldset-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.fieldset-label {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.fieldset-description {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.fieldset-label + .fieldset-description{
|
||||
margin-top:-8px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.fieldset-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
`);
|
||||
|
||||
// MODULES-AUTO-LOADER:@Modules/Heading
|
||||
var Heading_default = getModule((a) => a?.render?.toString().includes("data-excessive-heading-level"), { searchExports: true });
|
||||
|
||||
// common/Components/FieldSet/index.jsx
|
||||
var c2 = classNameFactory("fieldset");
|
||||
|
||||
function FieldSet({ label, description, children, contentGap = 16 }) {
|
||||
return /* @__PURE__ */ React_default.createElement("fieldset", { className: c2("container") }, label && /* @__PURE__ */ React_default.createElement(
|
||||
Heading_default, {
|
||||
className: c2("label"),
|
||||
tag: "legend",
|
||||
variant: "text-lg/medium"
|
||||
},
|
||||
label
|
||||
), description && /* @__PURE__ */ React_default.createElement(
|
||||
Heading_default, {
|
||||
className: c2("description"),
|
||||
variant: "text-sm/normal",
|
||||
color: "text-secondary"
|
||||
},
|
||||
description
|
||||
), /* @__PURE__ */ React_default.createElement("div", { className: c2("content"), style: { gap: contentGap } }, children));
|
||||
}
|
||||
|
||||
// src/ViewProfilePicture/components/SettingComponent.jsx
|
||||
function SettingComponent() {
|
||||
return /* @__PURE__ */ React_default.createElement(FieldSet, { contentGap: 8 }, [{
|
||||
settingKey: "showOnHover",
|
||||
note: "By default hide ViewProfilePicture button and show on hover.",
|
||||
description: "Show on hover"
|
||||
},
|
||||
{
|
||||
settingKey: "bannerColor",
|
||||
note: "Always include banner color in carousel, even if a banner is present.",
|
||||
description: "Include banner color."
|
||||
}
|
||||
].map(SettingSwtich));
|
||||
}
|
||||
|
||||
// src/ViewProfilePicture/index.jsx
|
||||
Plugin_default.getSettingsPanel = () => /* @__PURE__ */ React_default.createElement(SettingComponent, null);
|
||||
Plugin_default.on(Events.STOP, () => {
|
||||
Patcher.unpatchAll();
|
||||
});
|
||||
module.exports = () => Plugin_default;
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.8.33",
|
||||
"hasShownChangelog": true
|
||||
},
|
||||
"settings": {
|
||||
"showMemberListIcons": true,
|
||||
"showDMListIcons": true,
|
||||
"showPeopleListIcons": true,
|
||||
"currentChannelColor": true,
|
||||
"ignoreEnabled": false,
|
||||
"ignoredChannels": [],
|
||||
"ignoredGuilds": []
|
||||
},
|
||||
"changelogVersion": "1.12.3"
|
||||
}
|
||||
@@ -1,893 +0,0 @@
|
||||
/**
|
||||
* @name VoiceActivity
|
||||
* @author Neodymium
|
||||
* @version 1.12.3
|
||||
* @description Shows icons and info in popouts, the member list, and more when someone is in a voice channel.
|
||||
* @source https://github.com/Neodymium7/BetterDiscordStuff/blob/main/VoiceActivity/VoiceActivity.plugin.js
|
||||
* @invite fRbsqH87Av
|
||||
*/
|
||||
|
||||
/*@cc_on
|
||||
@if (@_jscript)
|
||||
|
||||
// Offer to self-install for clueless users that try to run this directly.
|
||||
var shell = WScript.CreateObject("WScript.Shell");
|
||||
var fs = new ActiveXObject("Scripting.FileSystemObject");
|
||||
var pathPlugins = shell.ExpandEnvironmentStrings("%APPDATA%\BetterDiscord\plugins");
|
||||
var pathSelf = WScript.ScriptFullName;
|
||||
// Put the user at ease by addressing them in the first person
|
||||
shell.Popup("It looks like you've mistakenly tried to run me directly. \n(Don't do that!)", 0, "I'm a plugin for BetterDiscord", 0x30);
|
||||
if (fs.GetParentFolderName(pathSelf) === fs.GetAbsolutePathName(pathPlugins)) {
|
||||
shell.Popup("I'm in the correct folder already.", 0, "I'm already installed", 0x40);
|
||||
} else if (!fs.FolderExists(pathPlugins)) {
|
||||
shell.Popup("I can't find the BetterDiscord plugins folder.\nAre you sure it's even installed?", 0, "Can't install myself", 0x10);
|
||||
} else if (shell.Popup("Should I copy myself to BetterDiscord's plugins folder for you?", 0, "Do you need some help?", 0x34) === 6) {
|
||||
fs.CopyFile(pathSelf, fs.BuildPath(pathPlugins, fs.GetFileName(pathSelf)), true);
|
||||
// Show the user where to put plugins in the future
|
||||
shell.Exec("explorer " + pathPlugins);
|
||||
shell.Popup("I'm installed!", 0, "Successfully installed", 0x40);
|
||||
}
|
||||
WScript.Quit();
|
||||
|
||||
@else@*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const betterdiscord = new BdApi("VoiceActivity");
|
||||
const react = BdApi.React;
|
||||
|
||||
// styles
|
||||
let _styles = "";
|
||||
function _loadStyle(path, css) {
|
||||
_styles += "/*" + path + "*/\n" + css + "\n";
|
||||
}
|
||||
function styles() {
|
||||
return _styles;
|
||||
}
|
||||
|
||||
// @lib/settings.ts
|
||||
class SettingsManager {
|
||||
settings = betterdiscord.Data.load("settings");
|
||||
listeners = new Set();
|
||||
constructor(defaultSettings) {
|
||||
if (!this.settings) {
|
||||
betterdiscord.Data.save("settings", defaultSettings);
|
||||
this.settings = defaultSettings;
|
||||
return;
|
||||
}
|
||||
if (Object.keys(this.settings) !== Object.keys(defaultSettings)) {
|
||||
this.settings = { ...defaultSettings, ...this.settings };
|
||||
let changed = false;
|
||||
for (const key in this.settings) {
|
||||
if (!(key in defaultSettings)) {
|
||||
delete this.settings[key];
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) betterdiscord.Data.save("settings", this.settings);
|
||||
}
|
||||
}
|
||||
addListener(listener) {
|
||||
this.listeners.add(listener);
|
||||
return () => {
|
||||
this.listeners.delete(listener);
|
||||
};
|
||||
}
|
||||
clearListeners() {
|
||||
this.listeners.clear();
|
||||
}
|
||||
useSettingsState(...keys) {
|
||||
let initialState = this.settings;
|
||||
if (keys.length) initialState = Object.fromEntries(keys.map((key) => [key, initialState[key]]));
|
||||
const [state, setState] = react.useState(initialState);
|
||||
react.useEffect(() => {
|
||||
return this.addListener((key, value) => {
|
||||
if (!keys.length || keys.includes(key)) setState((state2) => ({ ...state2, [key]: value }));
|
||||
});
|
||||
}, []);
|
||||
return state;
|
||||
}
|
||||
get(key) {
|
||||
return this.settings[key];
|
||||
}
|
||||
set(key, value) {
|
||||
this.settings[key] = value;
|
||||
betterdiscord.Data.save("settings", this.settings);
|
||||
for (const listener of this.listeners) listener(key, value);
|
||||
}
|
||||
}
|
||||
function buildSettingsPanel(settingsManager, settings) {
|
||||
for (const setting of settings) {
|
||||
setting.value = settingsManager.get(setting.id);
|
||||
}
|
||||
return betterdiscord.UI.buildSettingsPanel({
|
||||
settings,
|
||||
onChange: (_, id, value) => settingsManager.set(id, value)
|
||||
});
|
||||
}
|
||||
|
||||
// @lib/strings.ts
|
||||
const LocaleStore = betterdiscord.Webpack.Stores.LocaleStore;
|
||||
class StringsManager {
|
||||
locales;
|
||||
defaultLocale;
|
||||
strings;
|
||||
constructor(locales, defaultLocale) {
|
||||
this.locales = locales;
|
||||
this.defaultLocale = defaultLocale;
|
||||
this.strings = locales[defaultLocale];
|
||||
}
|
||||
setLocale = () => {
|
||||
this.strings = this.locales[LocaleStore.locale] || this.locales[this.defaultLocale];
|
||||
};
|
||||
subscribe() {
|
||||
this.setLocale();
|
||||
LocaleStore.addChangeListener(this.setLocale);
|
||||
}
|
||||
unsubscribe() {
|
||||
LocaleStore.removeChangeListener(this.setLocale);
|
||||
}
|
||||
get(key) {
|
||||
return this.strings[key] || this.locales[this.defaultLocale][key];
|
||||
}
|
||||
}
|
||||
|
||||
// @lib/changelog.ts
|
||||
function showChangelog(changes, meta) {
|
||||
if (!changes || changes.length == 0) return;
|
||||
const changelogVersion = betterdiscord.Data.load("changelogVersion");
|
||||
if (meta.version === changelogVersion) return;
|
||||
betterdiscord.UI.showChangelogModal({
|
||||
title: meta.name,
|
||||
subtitle: meta.version,
|
||||
changes
|
||||
});
|
||||
betterdiscord.Data.save("changelogVersion", meta.version);
|
||||
}
|
||||
|
||||
// @lib/utils/webpack.ts
|
||||
function getClasses(...classes) {
|
||||
return betterdiscord.Webpack.getModule((m) => betterdiscord.Webpack.Filters.byKeys(...classes)(m) && typeof m[classes[0]] == "string");
|
||||
}
|
||||
function getSelectors(...classes) {
|
||||
const module = getClasses(...classes);
|
||||
if (!module) return void 0;
|
||||
return classes.reduce((obj, className) => {
|
||||
obj[className] = "." + module[className].replaceAll(" ", ".");
|
||||
return obj;
|
||||
}, {});
|
||||
}
|
||||
function getIcon(searchString) {
|
||||
const filter = (m) => betterdiscord.Webpack.Filters.byStrings(searchString, '"svg"')(m) && typeof m === "function";
|
||||
return betterdiscord.Webpack.getModule(filter, {
|
||||
searchExports: true
|
||||
});
|
||||
}
|
||||
function expect(object, options) {
|
||||
if (object) return object;
|
||||
const fallbackMessage = !options.fatal && options.fallback ? " Using fallback value instead." : "";
|
||||
const errorMessage = `Module ${options.name} not found.${fallbackMessage}\n\nContact the plugin developer to inform them of this error.`;
|
||||
betterdiscord.Logger.error(errorMessage);
|
||||
options.onError?.();
|
||||
if (options.fatal) throw new Error(errorMessage);
|
||||
return options.fallback;
|
||||
}
|
||||
function expectModule(options) {
|
||||
return expect(betterdiscord.Webpack.getModule(options.filter, options), options);
|
||||
}
|
||||
function expectWithKey(options) {
|
||||
const [module, key] = betterdiscord.Webpack.getWithKey(options.filter, options);
|
||||
if (module) return [module, key];
|
||||
const fallback = expect(module, options);
|
||||
if (fallback) {
|
||||
const key2 = "__key";
|
||||
return [{ [key2]: fallback }, key2];
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
function expectSelectors(name, classes) {
|
||||
return expect(getSelectors(...classes), {
|
||||
name
|
||||
});
|
||||
}
|
||||
function expectIcon(name, searchString) {
|
||||
return expect(getIcon(searchString), {
|
||||
name,
|
||||
fallback: (_props) => null
|
||||
});
|
||||
}
|
||||
function byType(type) {
|
||||
return (e) => typeof e === type;
|
||||
}
|
||||
|
||||
// manifest.json
|
||||
const changelog = [
|
||||
{
|
||||
title: "Fixed",
|
||||
type: "fixed",
|
||||
items: [
|
||||
"Fixed friends list icons."
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// @discord/stores.ts
|
||||
const UserStore = betterdiscord.Webpack.getStore("UserStore");
|
||||
const VoiceStateStore = betterdiscord.Webpack.getStore("VoiceStateStore");
|
||||
const GuildStore = betterdiscord.Webpack.getStore("GuildStore");
|
||||
const ChannelStore = betterdiscord.Webpack.getStore("ChannelStore");
|
||||
const PermissionStore = betterdiscord.Webpack.getStore("PermissionStore");
|
||||
const useStateFromStores = expectModule({
|
||||
filter: betterdiscord.Webpack.Filters.byStrings("useStateFromStores"),
|
||||
name: "Flux",
|
||||
fallback(stores, callback) {
|
||||
return callback();
|
||||
},
|
||||
searchExports: true
|
||||
});
|
||||
|
||||
// modules/discordmodules.tsx
|
||||
function useUserVoiceStateFallback({ userId }) {
|
||||
const voiceState = useStateFromStores(
|
||||
[VoiceStateStore],
|
||||
() => userId && VoiceStateStore.getDiscoverableVoiceStateForUser(userId)
|
||||
);
|
||||
const channel = useStateFromStores([ChannelStore], () => {
|
||||
if (voiceState?.channelId) return ChannelStore.getChannel(voiceState?.channelId);
|
||||
});
|
||||
const visible = useStateFromStores(
|
||||
[PermissionStore],
|
||||
() => channel?.isPrivate() || PermissionStore.can(Permissions.VIEW_CHANNEL, channel)
|
||||
);
|
||||
if (visible) {
|
||||
return {
|
||||
voiceState,
|
||||
voiceChannel: channel
|
||||
};
|
||||
} else return {};
|
||||
}
|
||||
const MemberListItem = expectModule({
|
||||
filter: (m) => m.type?.toString?.().includes("memberListItem"),
|
||||
name: "MemberListItem",
|
||||
searchExports: true
|
||||
});
|
||||
const PrivateChannel = expectWithKey({
|
||||
filter: betterdiscord.Webpack.Filters.byStrings("getTypingUsers", "isMultiUserDM", "getRecipientId"),
|
||||
name: "PrivateChannel",
|
||||
searchExports: true
|
||||
});
|
||||
const PeopleListItem = expectModule({
|
||||
filter: betterdiscord.Webpack.Filters.bySource("peopleListItemRef"),
|
||||
declarationFilter: betterdiscord.Webpack.Filters.byStrings("peopleListItemRef"),
|
||||
name: "PeopleListItem"
|
||||
});
|
||||
const Permissions = expectModule({
|
||||
filter: betterdiscord.Webpack.Filters.byKeys("VIEW_CREATOR_MONETIZATION_ANALYTICS"),
|
||||
searchExports: true,
|
||||
name: "Permissions",
|
||||
fallback: {
|
||||
VIEW_CHANNEL: 1024n
|
||||
}
|
||||
});
|
||||
const memberSelectors = expectSelectors("Children Class", ["avatar", "children", "layout"]);
|
||||
const useUserVoiceState = expectModule({
|
||||
filter: betterdiscord.Webpack.Filters.byStrings("getDiscoverableVoiceState", "getDiscoverableVoiceStateForUser"),
|
||||
name: "useUserVoiceState",
|
||||
fallback: useUserVoiceStateFallback
|
||||
});
|
||||
|
||||
// locales.json
|
||||
const el = {
|
||||
SETTINGS_PROFILE: "Τομέας Προφίλ",
|
||||
SETTINGS_PROFILE_NOTE: "Εμφανίζει τον τομέα προφίλ για την τρέχουσα δραστηριότητα φωνής στα αναδυόμενα χρήστη και στην πλευρικές μπάρες προφίλ των Άμεσων Μηνυμάτων.",
|
||||
SETTINGS_ICONS: "Εικονίδια Λίστας Μελών",
|
||||
SETTINGS_ICONS_NOTE: "Εμφανίζει εικονίδια στη λίστα μελών όταν κάποιος είναι σε κανάλι φωνής.",
|
||||
SETTINGS_DM_ICONS: "Εικονίδια Άμεσων Μηνυμάτων",
|
||||
SETTINGS_DM_ICONS_NOTE: "Εμφανίζει εικονίδια στη λίστα Άμεσων Μηνυμάτων όταν κάποιος είναι σε κανάλι φωνής.",
|
||||
SETTINGS_PEOPLE_ICONS: "Εικονίδια Λίστας Φίλων",
|
||||
SETTINGS_PEOPLE_ICONS_NOTE: "Εμφανίζει εικονίδια στη λίστα φίλων όταν κάποιος είναι σε κανάλι φωνής.",
|
||||
SETTINGS_GUILD_ICONS: "Εικονίδια Συντεχνίας",
|
||||
SETTINGS_GUILD_ICONS_NOTE: "Εμφανίζει εικονίδια στις συντεχνίες ακόμα και αν δεν συμμετέχετε.",
|
||||
SETTINGS_COLOR: "Λίστα Μελών - Χρώμα Εικονιδίου Τρέχοντος Καναλιού",
|
||||
SETTINGS_COLOR_NOTE: "Αλλάζει τα εικονίδια της Λίστας Μελών σε πράσινα όταν ο χρήστης είναι στο δικό σας τρέχον κανάλι φωνής.",
|
||||
SETTINGS_STATUS: "Λίστα Μελών - Εμφάνιση Εικονιδίων Κατάστασης",
|
||||
SETTINGS_STATUS_NOTE: "Αλλάζει τα εικονίδια της Λίστας Μελών όταν ο χρήστης είναι σε Σίγαση, Κώφωση ή έχε ενεργοποιημένο Βίντεο.",
|
||||
SETTINGS_IGNORE: "Αγνόηση",
|
||||
SETTINGS_IGNORE_NOTE: "Προσθέτει μια επιλογή στο Κανάλι Φωνής και στα μενού περιεχομένου Συντεχνίας για αγνόηση αυτού του καναλιού/συντεχνίας στα Εικονίδια Λϊστας Μελών και στα Αναδυόμενα Χρήστη.",
|
||||
CONTEXT_IGNORE: "Αγνόηση στη Δραστηριότητα Φωνής",
|
||||
VOICE_CALL: "Φωνητική Κλήση",
|
||||
PRIVATE_CALL: "Ιδιωτική Κλήση",
|
||||
GROUP_CALL: "Ομαδική Κλήση",
|
||||
LIVE: "Ζωντανά",
|
||||
HEADER: "Σε ένα Κανάλι Φωνής",
|
||||
HEADER_VOICE: "Σε μια Κλήση Φωνής",
|
||||
HEADER_PRIVATE: "Σε μια Ιδιωτική Κλήση",
|
||||
HEADER_GROUP: "Σε μια Ομαδική Κλήση",
|
||||
HEADER_STAGE: "Σε ένα Κανάλι Σταδίου",
|
||||
VIEW: "Προβολή Καναλιού",
|
||||
VIEW_CALL: "Προβολή Κλήσης",
|
||||
JOIN: "Συμμετοχή σε Κανάλι",
|
||||
JOIN_CALL: "Συμμετοχή σε Κλήση",
|
||||
JOIN_DISABLED: "Ήδη σε Κανάλι",
|
||||
JOIN_DISABLED_CALL: "Ήδη σε Κλήση",
|
||||
JOIN_VIDEO: "Συμμετοχή με Βίντεο"
|
||||
};
|
||||
const ru = {
|
||||
SETTINGS_PROFILE: "Раздел в Профиле",
|
||||
SETTINGS_PROFILE_NOTE: "Показывает раздел для текущей голосовой активности в профиле, всплывающих окнах и боковых панелях в ЛС.",
|
||||
SETTINGS_ICONS: "Иконки в Списке Участников",
|
||||
SETTINGS_ICONS_NOTE: "Показывает иконки в списке участников когда пользователь в голосовом канале.",
|
||||
SETTINGS_DM_ICONS: "Иконки в ЛС",
|
||||
SETTINGS_DM_ICONS_NOTE: "Показывает иконки в списке участников ЛС когда пользователь в голосовом канале.",
|
||||
SETTINGS_PEOPLE_ICONS: "Иконки в Списке Друзей",
|
||||
SETTINGS_PEOPLE_ICONS_NOTE: "Показывает иконки в списке друзей когда пользователь в голосовом канале.",
|
||||
SETTINGS_GUILD_ICONS: "Иконки Сервера",
|
||||
SETTINGS_GUILD_ICONS_NOTE: "Показывает голосовые иконки на серверах даже когда вы не участвуете.",
|
||||
SETTINGS_COLOR: "Цвет Иконки Голосовой Активности",
|
||||
SETTINGS_COLOR_NOTE: "Делает иконки в Списке Участников зелёными когда пользователь в голосовом канале вместе с вами.",
|
||||
SETTINGS_STATUS: "Показывать Иконки Статуса",
|
||||
SETTINGS_STATUS_NOTE: "Меняет иконки в Списке Участников когда пользователь Выключил Микрофон/Звук или Начал трансляцию.",
|
||||
SETTINGS_IGNORE: "Ингор",
|
||||
SETTINGS_IGNORE_NOTE: "Добавляет возможность в контекстных меню Голосовых Каналов и Серверов игнорировать этот канал/сервер в Списке Участников и Профилях Пользователей.",
|
||||
CONTEXT_IGNORE: "Игнор (Голосовая Активность)",
|
||||
VOICE_CALL: "Голосовой звонок",
|
||||
PRIVATE_CALL: "Приватный звонок",
|
||||
GROUP_CALL: "Групповой звонок",
|
||||
LIVE: "В ЭФИРЕ",
|
||||
HEADER: "В Голосовом Канале",
|
||||
HEADER_VOICE: "В Голосовом Звонке",
|
||||
HEADER_PRIVATE: "В Приватном Звонке",
|
||||
HEADER_GROUP: "В Групповом Звонке",
|
||||
HEADER_STAGE: "В Канале Трибуны",
|
||||
VIEW: "Просмотреть Канал",
|
||||
VIEW_CALL: "Просмотреть Звонок",
|
||||
JOIN: "Присоединиться к Каналу",
|
||||
JOIN_CALL: "Присоединиться к Звонку",
|
||||
JOIN_DISABLED: "Уже в Канале",
|
||||
JOIN_DISABLED_CALL: "Уже в Звонке",
|
||||
JOIN_VIDEO: "Присоединиться с Видео"
|
||||
};
|
||||
const de = {
|
||||
SETTINGS_PROFILE: "Profilbereich",
|
||||
SETTINGS_PROFILE_NOTE: "Zeigt den Profilbereich für die aktuelle Sprachaktivität in Benutzer-Popouts und DM-Profilseitenleisten an.",
|
||||
SETTINGS_ICONS: "Symbole in der Mitgliederliste",
|
||||
SETTINGS_ICONS_NOTE: "Zeigt Symbole in der Mitgliederliste an, wenn sich jemand in einem Sprachkanal befindet.",
|
||||
SETTINGS_DM_ICONS: "DM-Symbole",
|
||||
SETTINGS_DM_ICONS_NOTE: "Zeigt Symbole in der DM-Liste an, wenn sich jemand in einem Sprachkanal befindet.",
|
||||
SETTINGS_PEOPLE_ICONS: "Symbole in der Freundesliste",
|
||||
SETTINGS_PEOPLE_ICONS_NOTE: "Zeigt Symbole in der Freundesliste an, wenn sich jemand in einem Sprachkanal befindet.",
|
||||
SETTINGS_GUILD_ICONS: "Gildensymbole",
|
||||
SETTINGS_GUILD_ICONS_NOTE: "Zeigt Symbole für Gilden an, auch wenn du nicht teilnimmst.",
|
||||
SETTINGS_COLOR: "Mitgliederliste - Farbe des aktuellen Kanalsymbols",
|
||||
SETTINGS_COLOR_NOTE: "Die Symbole in der Mitgliederliste werden grün, wenn sich der Benutzer in Ihrem aktuellen Sprachkanal befindet.",
|
||||
SETTINGS_STATUS: "Mitgliederliste - Statussymbole anzeigen",
|
||||
SETTINGS_STATUS_NOTE: "Ändert die Symbole in der Mitgliederliste, wenn ein Benutzer stummgeschaltet oder mit aktiviertem Video ist.",
|
||||
SETTINGS_IGNORE: "Ignorieren",
|
||||
SETTINGS_IGNORE_NOTE: "Fügt eine Option in die Kontextmenüs von Sprachkanälen und Gilden hinzu, um diesen Kanal/diese Gilde in der Mitgliederliste und Benutzer-Popouts zu ignorieren.",
|
||||
CONTEXT_IGNORE: "Bei Sprachaktivität ignorieren",
|
||||
VOICE_CALL: "Sprachanruf",
|
||||
PRIVATE_CALL: "Privatanruf",
|
||||
GROUP_CALL: "Gruppenanruf",
|
||||
LIVE: "Live",
|
||||
HEADER: "In einem Sprachkanal",
|
||||
HEADER_VOICE: "In einem Sprachanruf",
|
||||
HEADER_PRIVATE: "In einem privaten Anruf",
|
||||
HEADER_GROUP: "In einem Gruppenruf",
|
||||
HEADER_STAGE: "In einem Stage Kanal",
|
||||
VIEW: "Kanal anzeigen",
|
||||
VIEW_CALL: "Anruf anzeigen",
|
||||
JOIN: "Kanal beitreten",
|
||||
JOIN_CALL: "Anruf beitreten",
|
||||
JOIN_DISABLED: "Bereits im Kanal",
|
||||
JOIN_DISABLED_CALL: "Bereits im Aufruf",
|
||||
JOIN_VIDEO: "Beitreten mit Video"
|
||||
};
|
||||
const fr = {
|
||||
SETTINGS_PROFILE: "Section de profil",
|
||||
SETTINGS_PROFILE_NOTE: "Affiche une section de profile pour l'activité vocale actuelle dans les popouts utilisateur et les profiles latéraux de MP.",
|
||||
SETTINGS_ICONS: "Icônes de la liste de membre",
|
||||
SETTINGS_ICONS_NOTE: "Affiche des icônes dans la liste de membre quand quelqu'un est dans un salon vocal.",
|
||||
SETTINGS_DM_ICONS: "Icônes de MP",
|
||||
SETTINGS_DM_ICONS_NOTE: "Affiche des icônes dans la liste de MP quand quelqu'un est dans un salon vocal.",
|
||||
SETTINGS_PEOPLE_ICONS: "Icônes de la liste d'amis",
|
||||
SETTINGS_PEOPLE_ICONS_NOTE: "Affiche des icônes dans la liste d'amis quand quelqu'un est dans un salon vocal.",
|
||||
SETTINGS_GUILD_ICONS: "Icônes de serveur",
|
||||
SETTINGS_GUILD_ICONS_NOTE: "Affiche des icônes de vocal sur les serveurs même quand vous ne participez pas.",
|
||||
SETTINGS_COLOR: "Liste de membre - Couleur d'icône du salon actuel",
|
||||
SETTINGS_COLOR_NOTE: "Rends les icônes de la liste de membre vertes quand un utilisateur est dans le salon vocal actuel.",
|
||||
SETTINGS_STATUS: "Liste de membre - Afficher les icônes de status",
|
||||
SETTINGS_STATUS_NOTE: "Change les icônes de la liste de membre quand un utilisateur est muet, mis en sourdine, ou a la vidéo activée.",
|
||||
SETTINGS_IGNORE: "Ignorer",
|
||||
SETTINGS_IGNORE_NOTE: "Ajoute une option dans les menus contextuels des salons vocaux et serveurs pour ignorer le dit salon/serveur dans les icônes de liste de membre et popouts utilisateur.",
|
||||
CONTEXT_IGNORE: "Ignorer dans Activité Vocale",
|
||||
VOICE_CALL: "Appel vocal",
|
||||
PRIVATE_CALL: "Appel privé",
|
||||
GROUP_CALL: "Appel de groupe",
|
||||
LIVE: "Live",
|
||||
HEADER: "Dans un salon vocal",
|
||||
HEADER_VOICE: "Dans un appel vocal",
|
||||
HEADER_PRIVATE: "Dans un appel privé",
|
||||
HEADER_GROUP: "Dans un appel de groupe",
|
||||
HEADER_STAGE: "Dans un salon de conférence",
|
||||
VIEW: "Voir le salon",
|
||||
VIEW_CALL: "Voir l'appel",
|
||||
JOIN: "Rejoindre le salon",
|
||||
JOIN_CALL: "Rejoindre l'appel",
|
||||
JOIN_DISABLED: "Déjà dans le salon",
|
||||
JOIN_DISABLED_CALL: "Déjà en appel",
|
||||
JOIN_VIDEO: "Rejoidre avec vidéo",
|
||||
MEMBER: "Membre",
|
||||
MEMBERS: "Membres"
|
||||
};
|
||||
const locales = {
|
||||
"en-US": {
|
||||
SETTINGS_PROFILE: "Profile Section",
|
||||
SETTINGS_PROFILE_NOTE: "Shows profile section for current voice activity in user popouts and DM profile sidebars.",
|
||||
SETTINGS_ICONS: "Member List Icons",
|
||||
SETTINGS_ICONS_NOTE: "Shows icons on the member list when someone is in a voice channel.",
|
||||
SETTINGS_DM_ICONS: "DM Icons",
|
||||
SETTINGS_DM_ICONS_NOTE: "Shows icons on the DM list when someone is in a voice channel.",
|
||||
SETTINGS_PEOPLE_ICONS: "Friends List Icons",
|
||||
SETTINGS_PEOPLE_ICONS_NOTE: "Shows icons on the friends list when someone is in a voice channel.",
|
||||
SETTINGS_GUILD_ICONS: "Server Icons",
|
||||
SETTINGS_GUILD_ICONS_NOTE: "Shows voice icons on servers even when you're not participating.",
|
||||
SETTINGS_COLOR: "Member List - Current Channel Icon Color",
|
||||
SETTINGS_COLOR_NOTE: "Makes the Member List icons green when the user is in your current voice channel.",
|
||||
SETTINGS_STATUS: "Member List - Show Status Icons",
|
||||
SETTINGS_STATUS_NOTE: "Changes the Member List icons when a user is Muted, Deafened, or has Video enabled.",
|
||||
SETTINGS_CURRENT_USER: "Current User Icon",
|
||||
SETTINGS_CURRENT_USER_NOTE: "Toggles displaying a voice channel icon for the current user.",
|
||||
SETTINGS_IGNORE: "Ignore",
|
||||
SETTINGS_IGNORE_NOTE: "Adds an option on Voice Channel and Server context menus to ignore that channel/server in Member List Icons and User Popouts.",
|
||||
CONTEXT_IGNORE: "Ignore in Voice Activity",
|
||||
VOICE_CALL: "Voice Call",
|
||||
PRIVATE_CALL: "Private Call",
|
||||
GROUP_CALL: "Group Call",
|
||||
LIVE: "Live",
|
||||
HEADER: "In a Voice Channel",
|
||||
HEADER_VOICE: "In a Voice Call",
|
||||
HEADER_PRIVATE: "In a Private Call",
|
||||
HEADER_GROUP: "In a Group Call",
|
||||
HEADER_STAGE: "In a Stage Channel",
|
||||
VIEW: "View Channel",
|
||||
VIEW_CALL: "View Call",
|
||||
JOIN: "Join Channel",
|
||||
JOIN_CALL: "Join Call",
|
||||
JOIN_DISABLED: "Already in Channel",
|
||||
JOIN_DISABLED_CALL: "Already in Call",
|
||||
JOIN_VIDEO: "Join With Video",
|
||||
MEMBER: "Member",
|
||||
MEMBERS: "Members"
|
||||
},
|
||||
el: el,
|
||||
ru: ru,
|
||||
de: de,
|
||||
fr: fr
|
||||
};
|
||||
|
||||
// modules/utils.ts
|
||||
const Settings = new SettingsManager({
|
||||
showMemberListIcons: true,
|
||||
showDMListIcons: true,
|
||||
showPeopleListIcons: true,
|
||||
currentChannelColor: true,
|
||||
showStatusIcons: true,
|
||||
currentUserIcon: true,
|
||||
ignoreEnabled: false,
|
||||
ignoredChannels: [],
|
||||
ignoredGuilds: []
|
||||
});
|
||||
const Strings = new StringsManager(locales, "en-US");
|
||||
function groupDMName(members) {
|
||||
if (members.length === 1) {
|
||||
return UserStore.getUser(members[0]).globalName;
|
||||
} else if (members.length > 1) {
|
||||
let name = "";
|
||||
for (let i = 0; i < members.length; i++) {
|
||||
if (i === members.length - 1) name += UserStore.getUser(members[i]).globalName;
|
||||
else name += UserStore.getUser(members[i]).globalName + ", ";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
return "Unnamed";
|
||||
}
|
||||
|
||||
// styles/voiceicon.module.css
|
||||
const css = `
|
||||
.VoiceActivity-voiceicon-icon {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
min-width: 20px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--background-accent);
|
||||
cursor: pointer;
|
||||
svg {
|
||||
padding: 3px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.VoiceActivity-voiceicon-iconCurrentCall {
|
||||
background-color: var(--status-positive);
|
||||
}
|
||||
.VoiceActivity-voiceicon-iconLive {
|
||||
height: 16px;
|
||||
border-radius: 16px;
|
||||
background-color: var(--red-400);
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
font-weight: 600;
|
||||
font-family: var(--font-display);
|
||||
text-transform: uppercase;
|
||||
& > div {
|
||||
padding: 0 6px;
|
||||
}
|
||||
}
|
||||
.VoiceActivity-voiceicon-tooltip {
|
||||
.VoiceActivity-voiceicon-header {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.VoiceActivity-voiceicon-subtext {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 3px;
|
||||
& > div {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
.VoiceActivity-voiceicon-tooltipIcon {
|
||||
min-width: 16px;
|
||||
margin-right: 3px;
|
||||
color: var(--interactive-normal);
|
||||
}
|
||||
}
|
||||
.VoiceActivity-voiceicon-iconContainer {
|
||||
margin-left: auto;
|
||||
}
|
||||
.VoiceActivity-voiceicon-peopleListIcon {
|
||||
margin-right: 16px;
|
||||
}`;
|
||||
_loadStyle("voiceicon.module.css", css);
|
||||
const modules_1af761ba = {
|
||||
"icon": "VoiceActivity-voiceicon-icon",
|
||||
"iconCurrentCall": "VoiceActivity-voiceicon-iconCurrentCall",
|
||||
"iconLive": "VoiceActivity-voiceicon-iconLive",
|
||||
"tooltip": "VoiceActivity-voiceicon-tooltip",
|
||||
"header": "VoiceActivity-voiceicon-header",
|
||||
"subtext": "VoiceActivity-voiceicon-subtext",
|
||||
"tooltipIcon": "VoiceActivity-voiceicon-tooltipIcon",
|
||||
"iconContainer": "VoiceActivity-voiceicon-iconContainer",
|
||||
"peopleListIcon": "VoiceActivity-voiceicon-peopleListIcon"
|
||||
};
|
||||
const iconStyles = modules_1af761ba;
|
||||
|
||||
// @discord/icons.tsx
|
||||
const Speaker = expectIcon("Speaker", "M12 3a1 1 0 0 0-1-1h-.06a1 1 0 0 0-.74.32L5.92 7H3a1 1");
|
||||
const Muted = expectIcon(
|
||||
"Muted",
|
||||
"m2.7 22.7 20-20a1 1 0 0 0-1.4-1.4l-20 20a1 1 0 1 0 1.4 1.4ZM10.8 17.32c-.21.21-.1.58.2.62V20H9a1"
|
||||
);
|
||||
const ServerMuted = expectIcon(
|
||||
"ServerMuted",
|
||||
"M21.76.83a5.02 5.02 0 0 1 .78 7.7 5 5 0 0 1-7.07 0 5.02 5.02 0 0 1 0-7.07"
|
||||
);
|
||||
const Deafened = expectIcon(
|
||||
"Deafened",
|
||||
"M22.7 2.7a1 1 0 0 0-1.4-1.4l-20 20a1 1 0 1 0 1.4 1.4l20-20ZM17.06"
|
||||
);
|
||||
const ServerDeafened = expectIcon(
|
||||
"ServerDeafened",
|
||||
"M12.38 1c.38.02.58.45.4.78-.15.3-.3.62-.4.95A.4.4 0 0 1 12 3a9 9 0 0 0-8.95 10h1.87a5"
|
||||
);
|
||||
const Video = expectIcon("Video", "M4 4a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h11a3 3");
|
||||
const ChannelIcon = expectModule({
|
||||
filter: betterdiscord.Webpack.Filters.combine(
|
||||
betterdiscord.Webpack.Filters.byStrings("isGuildStageVoice", "isGroupDM", "isPrivate"),
|
||||
(m) => !m.toString?.().includes("intl")
|
||||
),
|
||||
name: "ChannelIcon",
|
||||
fallback: (_props) => null
|
||||
});
|
||||
|
||||
// @discord/modules.ts
|
||||
const transitionTo = expectModule({
|
||||
filter: betterdiscord.Webpack.Filters.combine(
|
||||
betterdiscord.Webpack.Filters.byStrings("transitionTo -"),
|
||||
byType("function")
|
||||
),
|
||||
searchExports: true,
|
||||
name: "transitionTo"
|
||||
});
|
||||
|
||||
// components/VoiceIcon.tsx
|
||||
function VoiceIcon(props) {
|
||||
const settingsState = Settings.useSettingsState(
|
||||
"showMemberListIcons",
|
||||
"showDMListIcons",
|
||||
"showPeopleListIcons",
|
||||
"ignoreEnabled",
|
||||
"ignoredChannels",
|
||||
"ignoredGuilds",
|
||||
"currentChannelColor",
|
||||
"showStatusIcons",
|
||||
"currentUserIcon"
|
||||
);
|
||||
const currentUser = UserStore.getCurrentUser();
|
||||
const { voiceState, voiceChannel: channel } = useUserVoiceState({ userId: props.userId });
|
||||
const { voiceState: currentUserVoiceState } = useUserVoiceState({ userId: currentUser?.id });
|
||||
if (props.context === "memberlist" && !settingsState.showMemberListIcons) return null;
|
||||
if (props.context === "dmlist" && !settingsState.showDMListIcons) return null;
|
||||
if (props.context === "peoplelist" && !settingsState.showPeopleListIcons) return null;
|
||||
if (props.userId === currentUser?.id && !settingsState.currentUserIcon) return null;
|
||||
if (!voiceState) return null;
|
||||
const guild = GuildStore.getGuild(channel.guild_id);
|
||||
const ignored = settingsState.ignoredChannels.includes(channel.id) || settingsState.ignoredGuilds.includes(guild?.id);
|
||||
if (settingsState.ignoreEnabled && ignored) return null;
|
||||
let text;
|
||||
let subtext;
|
||||
let channelPath;
|
||||
let className = iconStyles.icon;
|
||||
if (settingsState.currentChannelColor && channel.id === currentUserVoiceState?.channelId)
|
||||
className = `${iconStyles.icon} ${iconStyles.iconCurrentCall}`;
|
||||
if (voiceState.selfStream) className = iconStyles.iconLive;
|
||||
if (guild) {
|
||||
text = guild.name;
|
||||
subtext = channel.name;
|
||||
channelPath = `/channels/${guild.id}/${channel.id}`;
|
||||
} else {
|
||||
text = channel.name;
|
||||
subtext = Strings.get("VOICE_CALL");
|
||||
channelPath = `/channels/@me/${channel.id}`;
|
||||
}
|
||||
switch (channel.type) {
|
||||
case 1:
|
||||
text = UserStore.getUser(channel.recipients[0]).globalName;
|
||||
subtext = Strings.get("PRIVATE_CALL");
|
||||
break;
|
||||
case 3:
|
||||
text = channel.name || groupDMName(channel.recipients);
|
||||
subtext = Strings.get("GROUP_CALL");
|
||||
break;
|
||||
}
|
||||
let Icon = Speaker;
|
||||
if (settingsState.showStatusIcons) {
|
||||
if (voiceState.selfVideo) Icon = Video;
|
||||
else if (voiceState.deaf) Icon = ServerDeafened;
|
||||
else if (voiceState.selfDeaf) Icon = Deafened;
|
||||
else if (voiceState.mute) Icon = ServerMuted;
|
||||
else if (voiceState.selfMute) Icon = Muted;
|
||||
}
|
||||
return BdApi.React.createElement(
|
||||
"div",
|
||||
{
|
||||
className,
|
||||
onClick: (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (channelPath) transitionTo?.(channelPath);
|
||||
}
|
||||
},
|
||||
BdApi.React.createElement(
|
||||
betterdiscord.Components.Tooltip,
|
||||
{
|
||||
text: BdApi.React.createElement("div", { className: iconStyles.tooltip }, BdApi.React.createElement("div", { className: iconStyles.header, style: { fontWeight: "600" } }, text), BdApi.React.createElement("div", { className: iconStyles.subtext }, BdApi.React.createElement(
|
||||
ChannelIcon,
|
||||
{
|
||||
className: iconStyles.tooltipIcon,
|
||||
size: "16",
|
||||
width: "16",
|
||||
height: "16",
|
||||
color: "currentColor",
|
||||
channel
|
||||
}
|
||||
), BdApi.React.createElement("div", { style: { fontWeight: "400" } }, subtext)))
|
||||
},
|
||||
(props2) => BdApi.React.createElement("div", { ...props2 }, !voiceState.selfStream ? BdApi.React.createElement(Icon, { size: "14", width: "14", height: "14", color: "currentColor" }) : Strings.get("LIVE"))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// index.tsx
|
||||
class VoiceActivity {
|
||||
meta;
|
||||
contextMenuUnpatches = new Set();
|
||||
constructor(meta) {
|
||||
this.meta = meta;
|
||||
}
|
||||
start() {
|
||||
showChangelog(changelog, this.meta);
|
||||
betterdiscord.DOM.addStyle(
|
||||
styles() + `${memberSelectors?.children}:empty { margin-left: 0; } ${memberSelectors?.children} { display: flex; gap: 8px; } ${memberSelectors?.layout} { width: 100%; }`
|
||||
);
|
||||
Strings.subscribe();
|
||||
this.patchPeopleListItem();
|
||||
this.patchMemberListItem();
|
||||
this.patchPrivateChannel();
|
||||
this.patchChannelContextMenu();
|
||||
this.patchGuildContextMenu();
|
||||
betterdiscord.Patcher.instead(VoiceStateStore, "getDiscoverableVoiceState", (_, [guildId, userId]) => {
|
||||
return VoiceStateStore.getDiscoverableVoiceStateForUser(userId);
|
||||
});
|
||||
}
|
||||
patchMemberListItem() {
|
||||
if (!MemberListItem) return;
|
||||
betterdiscord.Patcher.after(MemberListItem, "type", (_, [props], ret) => {
|
||||
if (!props.user) return ret;
|
||||
const children = ret.props.children;
|
||||
ret.props.children = (childrenProps) => {
|
||||
const childrenRet = children(childrenProps);
|
||||
const target = betterdiscord.Utils.findInTree(childrenRet, (x) => x.props?.avatar && x.props?.decorators, {
|
||||
walkable: ["props", "children"]
|
||||
});
|
||||
const icon = BdApi.React.createElement(VoiceIcon, { userId: props.user.id, context: "memberlist" });
|
||||
Array.isArray(target.props.children) ? target.props.children.unshift(icon) : target.props.children = [icon];
|
||||
return childrenRet;
|
||||
};
|
||||
});
|
||||
}
|
||||
patchPrivateChannel() {
|
||||
if (!PrivateChannel) return;
|
||||
const patchType = (props, ret) => {
|
||||
if (props.channel.type !== 1) return;
|
||||
const target = betterdiscord.Utils.findInTree(ret, (e) => typeof e?.props?.children !== "function", {
|
||||
walkable: ["children", "props"]
|
||||
})?.props?.children ?? ret;
|
||||
if (!target) return;
|
||||
const children = target.props.children;
|
||||
target.props.children = (childrenProps) => {
|
||||
const childrenRet = children(childrenProps);
|
||||
const privateChannel = betterdiscord.Utils.findInTree(childrenRet, (e) => e?.children?.props?.avatar, {
|
||||
walkable: ["children", "props"]
|
||||
});
|
||||
privateChannel.children = [
|
||||
privateChannel.children,
|
||||
BdApi.React.createElement("div", { className: iconStyles.iconContainer }, BdApi.React.createElement(VoiceIcon, { userId: props.user.id, context: "dmlist" }))
|
||||
];
|
||||
return childrenRet;
|
||||
};
|
||||
};
|
||||
let patchedType;
|
||||
betterdiscord.Patcher.after(...PrivateChannel, (_, __, containerRet) => {
|
||||
let target = containerRet.children || containerRet;
|
||||
if (patchedType) {
|
||||
target.type = patchedType;
|
||||
return containerRet;
|
||||
}
|
||||
const original = target.type;
|
||||
patchedType = (props) => {
|
||||
const ret = original(props);
|
||||
patchType(props, ret);
|
||||
return ret;
|
||||
};
|
||||
target.type = patchedType;
|
||||
});
|
||||
}
|
||||
patchPeopleListItem() {
|
||||
if (!PeopleListItem) return;
|
||||
betterdiscord.Patcher.after(PeopleListItem.prototype, "render", (that, _, ret) => {
|
||||
if (!that.props.user) return;
|
||||
const children = ret.props.children;
|
||||
ret.props.children = (childrenProps) => {
|
||||
const childrenRet = children(childrenProps);
|
||||
betterdiscord.Utils.findInTree(childrenRet, (i) => Array.isArray(i), { walkable: ["props", "children"] }).splice(
|
||||
1,
|
||||
0,
|
||||
BdApi.React.createElement("div", { className: `${iconStyles.iconContainer} ${iconStyles.peopleListIcon}` }, BdApi.React.createElement(VoiceIcon, { userId: that.props.user.id, context: "peoplelist" }))
|
||||
);
|
||||
return childrenRet;
|
||||
};
|
||||
});
|
||||
}
|
||||
patchChannelContextMenu() {
|
||||
const unpatch = betterdiscord.ContextMenu.patch("channel-context", (ret, props) => {
|
||||
if (!Settings.get("ignoreEnabled")) return ret;
|
||||
if (props.channel.type !== 2 && props.channel.type !== 13) return ret;
|
||||
const { ignoredChannels } = Settings.useSettingsState("ignoredChannels");
|
||||
const ignored = ignoredChannels.includes(props.channel.id);
|
||||
const menuItem = betterdiscord.ContextMenu.buildItem({
|
||||
type: "toggle",
|
||||
label: Strings.get("CONTEXT_IGNORE"),
|
||||
id: "voiceactivity-ignore",
|
||||
checked: ignored,
|
||||
action: () => {
|
||||
if (ignored) {
|
||||
const newIgnoredChannels = ignoredChannels.filter((id) => id !== props.channel.id);
|
||||
Settings.set("ignoredChannels", newIgnoredChannels);
|
||||
} else {
|
||||
const newIgnoredChannels = [...ignoredChannels, props.channel.id];
|
||||
Settings.set("ignoredChannels", newIgnoredChannels);
|
||||
}
|
||||
}
|
||||
});
|
||||
ret.props.children[3].props.children.splice(4, 0, menuItem);
|
||||
});
|
||||
this.contextMenuUnpatches.add(unpatch);
|
||||
}
|
||||
patchGuildContextMenu() {
|
||||
const unpatch = betterdiscord.ContextMenu.patch("guild-context", (ret, props) => {
|
||||
if (!props.guild) return ret;
|
||||
if (!Settings.get("ignoreEnabled")) return ret;
|
||||
const { ignoredGuilds } = Settings.useSettingsState("ignoredGuilds");
|
||||
const ignored = ignoredGuilds.includes(props.guild.id);
|
||||
const menuItem = betterdiscord.ContextMenu.buildItem({
|
||||
type: "toggle",
|
||||
label: Strings.get("CONTEXT_IGNORE"),
|
||||
id: "voiceactivity-ignore",
|
||||
checked: ignored,
|
||||
action: () => {
|
||||
if (ignored) {
|
||||
const newIgnoredGuilds = ignoredGuilds.filter((id) => id !== props.guild.id);
|
||||
Settings.set("ignoredGuilds", newIgnoredGuilds);
|
||||
} else {
|
||||
const newIgnoredGuilds = [...ignoredGuilds, props.guild.id];
|
||||
Settings.set("ignoredGuilds", newIgnoredGuilds);
|
||||
}
|
||||
}
|
||||
});
|
||||
ret.props.children[2].props.children.push(menuItem);
|
||||
});
|
||||
this.contextMenuUnpatches.add(unpatch);
|
||||
}
|
||||
stop() {
|
||||
betterdiscord.DOM.removeStyle();
|
||||
betterdiscord.Patcher.unpatchAll();
|
||||
this.contextMenuUnpatches.forEach((unpatch) => unpatch());
|
||||
this.contextMenuUnpatches.clear();
|
||||
Strings.unsubscribe();
|
||||
}
|
||||
getSettingsPanel() {
|
||||
return buildSettingsPanel(Settings, [
|
||||
{
|
||||
id: "showMemberListIcons",
|
||||
type: "switch",
|
||||
name: Strings.get("SETTINGS_ICONS"),
|
||||
note: Strings.get("SETTINGS_ICONS_NOTE")
|
||||
},
|
||||
{
|
||||
id: "showDMListIcons",
|
||||
type: "switch",
|
||||
name: Strings.get("SETTINGS_DM_ICONS"),
|
||||
note: Strings.get("SETTINGS_DM_ICONS_NOTE")
|
||||
},
|
||||
{
|
||||
id: "showPeopleListIcons",
|
||||
type: "switch",
|
||||
name: Strings.get("SETTINGS_PEOPLE_ICONS"),
|
||||
note: Strings.get("SETTINGS_PEOPLE_ICONS_NOTE")
|
||||
},
|
||||
{
|
||||
id: "currentChannelColor",
|
||||
type: "switch",
|
||||
name: Strings.get("SETTINGS_COLOR"),
|
||||
note: Strings.get("SETTINGS_COLOR_NOTE")
|
||||
},
|
||||
{
|
||||
id: "showStatusIcons",
|
||||
type: "switch",
|
||||
name: Strings.get("SETTINGS_STATUS"),
|
||||
note: Strings.get("SETTINGS_STATUS_NOTE")
|
||||
},
|
||||
{
|
||||
id: "currentUserIcon",
|
||||
type: "switch",
|
||||
name: Strings.get("SETTINGS_CURRENT_USER"),
|
||||
note: Strings.get("SETTINGS_CURRENT_USER_NOTE")
|
||||
},
|
||||
{
|
||||
id: "ignoreEnabled",
|
||||
type: "switch",
|
||||
name: Strings.get("SETTINGS_IGNORE"),
|
||||
note: Strings.get("SETTINGS_IGNORE_NOTE")
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = VoiceActivity;
|
||||
|
||||
/*@end@*/
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "1.2.5",
|
||||
"hasShownChangelog": true
|
||||
},
|
||||
"settings": {
|
||||
"maxUsersShown": 6,
|
||||
"avatarSize": 16,
|
||||
"reactionThreshold": 10,
|
||||
"userThreshold": 100,
|
||||
"useHighestUserCount": true,
|
||||
"showSelf": false,
|
||||
"showBots": false
|
||||
}
|
||||
}
|
||||
@@ -1,288 +0,0 @@
|
||||
/**
|
||||
* @name WiderUserArea
|
||||
* @version 0.2.5
|
||||
* @description A BetterDiscord plugin that expands your user area into the server list, compatible with most themes
|
||||
* @author TheLazySquid
|
||||
* @authorId 619261917352951815
|
||||
* @website https://github.com/TheLazySquid/DiscordWiderUserArea
|
||||
* @source https://github.com/TheLazySquid/DiscordWiderUserArea/blob/main/build/WiderUserArea.plugin.js
|
||||
*/
|
||||
module.exports = class {
|
||||
constructor() {
|
||||
'use strict';
|
||||
|
||||
var styles = ":root {\r\n --user-area-bottom: 0;\r\n --user-area-left: 0;\r\n}\r\n\r\nnav[class*=\"guilds_\"] {\r\n height: var(--sidebar-height);\r\n}\r\n\r\n[class*=\"sidebar_\"] {\r\n height: calc(var(--sidebar-height) - var(--notices-height));\r\n}\r\n\r\n/* user area */\r\nsection[class*=\"panels_\"] {\r\n position: fixed;\r\n overflow: hidden;\r\n bottom: var(--user-area-bottom);\r\n left: var(--user-area-left);\r\n width: var(--user-area-width);\r\n}\r\n\r\nsection[class*=\"panels_\"] [class*=\"avatarWrapper_\"] {\r\n flex-grow: 1;\r\n}\r\n\r\n/* prevent the user info popout from clipping */\r\n[class*=\"accountProfilePopoutWrapper\"] {\r\n left: 0;\r\n}";
|
||||
|
||||
const userAreaSelector = 'section[class*="panels_"]';
|
||||
const serverListSelector = 'nav[class*="guilds_"]';
|
||||
const containerSelector = `div:has(> ${serverListSelector})`;
|
||||
const layerSelector = `[class*="baseLayer"]`;
|
||||
const channelsSelector = '[class*="sidebar_"] > nav';
|
||||
const scaleRegex = /scale\((.*)\)/;
|
||||
const UAButtonsSelector = 'div[class*="avatarWrapper_"] + div';
|
||||
const firstServerListSelector = `${serverListSelector}:first-child`;
|
||||
const secondServerListSelector = `${serverListSelector}:nth-child(2)`;
|
||||
|
||||
function scaleDOMRect(rect, scale, scaleCenterX, scaleCenterY) {
|
||||
// Calculate the distance of the rect from the scale center
|
||||
const distX = rect.x - scaleCenterX;
|
||||
const distY = rect.y - scaleCenterY;
|
||||
// Scale the distances
|
||||
const newDistX = distX * scale;
|
||||
const newDistY = distY * scale;
|
||||
// Calculate the new position of the rect
|
||||
const newX = scaleCenterX + newDistX;
|
||||
const newY = scaleCenterY + newDistY;
|
||||
// Scale the dimensions of the rect
|
||||
const newWidth = rect.width * scale;
|
||||
const newHeight = rect.height * scale;
|
||||
// Create a new DOMRect with the new dimensions and position
|
||||
const newRect = new DOMRect(newX, newY, newWidth, newHeight);
|
||||
return newRect;
|
||||
}
|
||||
|
||||
const createCallbackHandler = (callbackName) => {
|
||||
const fullName = callbackName + "Callbacks";
|
||||
this[fullName] = [];
|
||||
this[callbackName] = () => {
|
||||
for (let i = 0; i < this[fullName].length; i++) {
|
||||
this[fullName][i].callback();
|
||||
}
|
||||
};
|
||||
return (callback, once, id) => {
|
||||
let object = { callback };
|
||||
const delCallback = () => {
|
||||
this[fullName].splice(this[fullName].indexOf(object), 1);
|
||||
};
|
||||
// if once is true delete it after use
|
||||
if (once === true) {
|
||||
object.callback = () => {
|
||||
callback();
|
||||
delCallback();
|
||||
};
|
||||
}
|
||||
if (id) {
|
||||
object.id = id;
|
||||
for (let i = 0; i < this[fullName].length; i++) {
|
||||
if (this[fullName][i].id === id) {
|
||||
this[fullName][i] = object;
|
||||
return delCallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
this[fullName].push(object);
|
||||
return delCallback;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* Takes a callback and fires it when the plugin is started
|
||||
* @param callback - The callback to be fired
|
||||
* @param once - If true, the callback will be deleted after use
|
||||
* @param id - The id of the callback - if it already exists, it will be replaced
|
||||
* @returns A function to delete the callback
|
||||
*/
|
||||
const onStart = createCallbackHandler("start");
|
||||
/**
|
||||
* Takes a callback and fires it when the plugin is stopped
|
||||
* @param callback - The callback to be fired
|
||||
* @param once - If true, the callback will be deleted after use
|
||||
* @param id - The id of the callback - if it already exists, it will be replaced
|
||||
* @returns A function to delete the callback
|
||||
*/
|
||||
const onStop = createCallbackHandler("stop");
|
||||
/**
|
||||
* Takes a callback and fires it when the user navigates
|
||||
* @param callback - The callback to be fired
|
||||
* @param once - If true, the callback will be deleted after use
|
||||
* @param id - The id of the callback - if it already exists, it will be replaced
|
||||
* @returns A function to delete the callback
|
||||
*/
|
||||
const onSwitch = createCallbackHandler("onSwitch");
|
||||
|
||||
/**
|
||||
* Watches for an element with a given selector to be added to the DOM
|
||||
* @param selector The CSS selector to watch
|
||||
* @param callback The callback to run whenever the matching element is added to the DOM
|
||||
* @returns A function to stop watching
|
||||
*/
|
||||
function watchElement(selector, callback) {
|
||||
let observer = new MutationObserver((mutations) => {
|
||||
for (let mutation of mutations) {
|
||||
if (mutation.addedNodes.length) {
|
||||
for (let node of mutation.addedNodes) {
|
||||
if (!(node instanceof HTMLElement))
|
||||
continue;
|
||||
if (node.matches && node.matches(selector)) {
|
||||
callback(node);
|
||||
}
|
||||
if (node.querySelectorAll) {
|
||||
for (let element of node.querySelectorAll(selector)) {
|
||||
callback(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let startDispose = onStart(() => {
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
for (let element of document.querySelectorAll(selector)) {
|
||||
callback(element);
|
||||
}
|
||||
});
|
||||
let stopDispose = onStop(() => {
|
||||
observer.disconnect();
|
||||
});
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
startDispose();
|
||||
stopDispose();
|
||||
};
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
let baseChannelHeight = 0;
|
||||
let baseChannelWidth = 0;
|
||||
let varsSet = new Set();
|
||||
const recalcDebounce = BdApi.Utils.debounce(() => {
|
||||
const userArea = document.querySelector(userAreaSelector);
|
||||
if (userArea)
|
||||
userAreaFound(userArea);
|
||||
}, 150);
|
||||
watchElement(userAreaSelector, userAreaFound);
|
||||
let userAreaObserver = new ResizeObserver(entries => {
|
||||
for (let entry of entries) {
|
||||
updateVar('--sidebar-height', `${baseChannelHeight - entry.contentRect.height}px`);
|
||||
}
|
||||
});
|
||||
let channelsRect;
|
||||
let secondChannelsRect;
|
||||
let channelsObserver = new ResizeObserver(entries => {
|
||||
for (let entry of entries) {
|
||||
channelsRect = entry.contentRect;
|
||||
// hide everything but the profile picture if the channel list is hidden
|
||||
let btns = document.querySelector(UAButtonsSelector);
|
||||
if (entry.contentRect.width === 0) {
|
||||
if (btns)
|
||||
btns.style.display = 'none';
|
||||
}
|
||||
else {
|
||||
if (btns)
|
||||
btns.style.display = '';
|
||||
}
|
||||
let newWidth = entry.contentRect.right - baseChannelWidth;
|
||||
if (secondChannelsRect)
|
||||
newWidth += secondChannelsRect.width;
|
||||
updateVar('--user-area-width', `${newWidth}px`);
|
||||
}
|
||||
});
|
||||
watchElement(channelsSelector, (element) => {
|
||||
channelsObserver.disconnect();
|
||||
channelsObserver.observe(element);
|
||||
});
|
||||
let secondServerListObserver = new ResizeObserver((entries) => {
|
||||
if (!channelsRect)
|
||||
return;
|
||||
for (let entry of entries) {
|
||||
secondChannelsRect = entry.contentRect;
|
||||
let width = entry.contentRect.width;
|
||||
updateVar('--user-area-width', `${channelsRect.right - baseChannelWidth + width}px`);
|
||||
}
|
||||
});
|
||||
watchElement(secondServerListSelector, (element) => {
|
||||
secondServerListObserver.disconnect();
|
||||
secondServerListObserver.observe(element);
|
||||
});
|
||||
let themesObserver = new MutationObserver(async () => {
|
||||
// wait a bit for it to apply
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
console.log('theme changed');
|
||||
// recalculate the user area
|
||||
const userArea = document.querySelector(userAreaSelector);
|
||||
if (userArea)
|
||||
userAreaFound(userArea);
|
||||
});
|
||||
let noticesHeight = 0;
|
||||
let noticesObserver = new ResizeObserver((entries) => {
|
||||
for (let entry of entries) {
|
||||
noticesHeight = entry.contentRect.height;
|
||||
updateVar('--notices-height', `${entry.contentRect.height}px`);
|
||||
}
|
||||
});
|
||||
watchElement("#bd-notices", (el) => {
|
||||
noticesObserver.disconnect();
|
||||
noticesObserver.observe(el);
|
||||
});
|
||||
function updateVar(name, value) {
|
||||
BdApi.DOM.removeStyle(`wua-${name}`);
|
||||
BdApi.DOM.addStyle(`wua-${name}`, `:root { ${name}: ${value} !important; }`);
|
||||
varsSet.add(name);
|
||||
}
|
||||
onSwitch(() => {
|
||||
// hacky fix for betteranimations sometimes giving a parent the "perspective" style breaking the fixed positioning
|
||||
setTimeout(() => {
|
||||
const userArea = document.querySelector(userAreaSelector);
|
||||
let parent = userArea?.parentElement;
|
||||
while (parent) {
|
||||
if (parent.style.perspective) {
|
||||
parent.style.perspective = '';
|
||||
break;
|
||||
}
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
userAreaFound(userArea);
|
||||
}, 5100);
|
||||
});
|
||||
function userAreaFound(element) {
|
||||
// remove the old style if it exists
|
||||
BdApi.DOM.removeStyle('wua-styles');
|
||||
const layer = document.querySelector(layerSelector);
|
||||
const container = document.querySelector(containerSelector);
|
||||
const serverList = document.querySelector(firstServerListSelector);
|
||||
const channels = document.querySelector(channelsSelector);
|
||||
const secondServerList = document.querySelector(secondServerListSelector);
|
||||
const layerScale = 1 / parseFloat(scaleRegex.exec(layer.style.transform)?.[1] ?? '1');
|
||||
const layerRect = layer.getBoundingClientRect();
|
||||
const centerX = layerRect.left + layerRect.width / 2;
|
||||
const centerY = layerRect.top + layerRect.height / 2;
|
||||
// this scaling is neccesary for compatibility with betterAnimations,
|
||||
// which sometimes scales the layer when in a settings menu, which is where theme switches would be.
|
||||
const rect = scaleDOMRect(element.getBoundingClientRect(), layerScale, centerX, centerY);
|
||||
const containerRect = scaleDOMRect(container.getBoundingClientRect(), layerScale, centerX, centerY);
|
||||
const serverListRect = scaleDOMRect(serverList.getBoundingClientRect(), layerScale, centerX, centerY);
|
||||
const channelsRect = scaleDOMRect(channels.getBoundingClientRect(), layerScale, centerX, centerY);
|
||||
// figure out how far from the bottom of the screen the user area is
|
||||
const bottom = containerRect.bottom - rect.bottom;
|
||||
baseChannelHeight = channelsRect.height + rect.height;
|
||||
baseChannelWidth = serverListRect.left - channelsRect.left;
|
||||
if (secondServerList) {
|
||||
const secondServerListRect = scaleDOMRect(secondServerList.getBoundingClientRect(), layerScale, centerX, centerY);
|
||||
baseChannelWidth += secondServerListRect.width;
|
||||
}
|
||||
// add the new style
|
||||
BdApi.DOM.addStyle('wua-styles', styles);
|
||||
updateVar('--sidebar-height', `${channelsRect.height + noticesHeight}px`);
|
||||
updateVar('--user-area-width', `${channelsRect.right - serverListRect.left}px`);
|
||||
updateVar('--user-area-left', `${serverListRect.left}px`);
|
||||
updateVar('--user-area-bottom', `${bottom}px`);
|
||||
userAreaObserver.observe(element);
|
||||
}
|
||||
onStart(() => {
|
||||
window.addEventListener('resize', recalcDebounce);
|
||||
updateVar('--notices-height', '0px');
|
||||
themesObserver.observe(document.querySelector("bd-themes"), { childList: true, subtree: true });
|
||||
});
|
||||
onStop(() => {
|
||||
userAreaObserver.disconnect();
|
||||
channelsObserver.disconnect();
|
||||
themesObserver.disconnect();
|
||||
secondServerListObserver.disconnect();
|
||||
noticesObserver.disconnect();
|
||||
BdApi.DOM.removeStyle('wua-styles');
|
||||
for (let varName of varsSet) {
|
||||
BdApi.DOM.removeStyle(`wua-${varName}`);
|
||||
}
|
||||
window.removeEventListener('resize', recalcDebounce);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"currentVersionInfo": {
|
||||
"version": "2.0.23",
|
||||
"hasShownChangelog": true
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,132 +0,0 @@
|
||||
/**
|
||||
* @name betterdiscord-google-fonts
|
||||
* @version 1.0.2
|
||||
* @description Allows use of Google Fonts through a simple settings UI
|
||||
* @author Mike Orozco
|
||||
* @authorLink https://mikeorozco.dev
|
||||
* @authorId 142347724392497152
|
||||
* @updateUrl https://raw.githubusercontent.com/notmike101/betterdiscord-google-fonts/release/betterdiscord-google-fonts.plugin.js
|
||||
* @source https://github.com/notmike101/betterdiscord-google-fonts
|
||||
*/
|
||||
|
||||
// sass:/home/runner/work/betterdiscord-google-fonts/betterdiscord-google-fonts/src/styles/Global.scss
|
||||
var Global_default = `
|
||||
`;
|
||||
|
||||
// _cqfx4ul6y:/home/runner/work/betterdiscord-google-fonts/betterdiscord-google-fonts/src/templates/SettingsPanel.html
|
||||
var SettingsPanel_default = '<div class="google-font-settings">\n <div class="bd-setting-item">\n <div class="bd-setting-header">\n <label for="google-font-select" class="bd-setting-title">Selected Font</label>\n </div>\n <div class="bd-select">\n <div class="bd-select-header-custom">\n <div class="bd-select-value">{{ CURRENT_FONT }}</div>\n <svg class="bd-select-arrow" fill="currentColor" viewBox="0 0 24 24">\n <path d="M8.12 9.29L12 13.17l3.88-3.88c.39-.39 1.02-.39 1.41 0 .39.39.39 1.02 0 1.41l-4.59 4.59c-.39.39-1.02.39-1.41 0L6.7 10.7c-.39-.39-.39-1.02 0-1.41.39-.38 1.03-.39 1.42 0z"></path>\n </svg>\n </div>\n <div class="bd-select-options"></div>\n </div>\n </div>\n</div>\n';
|
||||
|
||||
// sass:/home/runner/work/betterdiscord-google-fonts/betterdiscord-google-fonts/src/styles/SettingsPanel.scss
|
||||
var SettingsPanel_default2 = `
|
||||
.google-font-settings .bd-setting-item .bd-select {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.google-font-settings .bd-setting-item .bd-select .bd-select-header-custom {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
.google-font-settings .bd-setting-item .bd-select .bd-select-header-custom .bd-select-arrow {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.google-font-settings .bd-setting-item .bd-select .bd-select-options {
|
||||
display: none;
|
||||
position: initial;
|
||||
z-index: 0;
|
||||
}`;
|
||||
|
||||
// src/DiscordPlugin.ts
|
||||
var BdApi = window.BdApi || {};
|
||||
var DiscordPlugin = class {
|
||||
selectedFont;
|
||||
fonts;
|
||||
constructor() {
|
||||
this.selectedFont = null;
|
||||
this.fonts = [];
|
||||
}
|
||||
getName() {
|
||||
return "Google Fonts";
|
||||
}
|
||||
async load() {
|
||||
}
|
||||
async start() {
|
||||
BdApi.injectCSS("bd-google-fonts-global-css", Global_default);
|
||||
BdApi.injectCSS("bd-google-fonts-settingspanel", SettingsPanel_default2);
|
||||
this.fonts = await this.getAvailableFonts();
|
||||
this.selectedFont = BdApi.getData("betterdiscord-google-fonts", "font");
|
||||
this.updateDomFont();
|
||||
}
|
||||
stop() {
|
||||
BdApi.clearCSS("bd-google-fonts-global-css");
|
||||
BdApi.clearCSS("bd-google-fonts-custom-font");
|
||||
BdApi.clearCSS("bd-google-fonts-settingspanel");
|
||||
}
|
||||
async getAvailableFonts() {
|
||||
const existingData = BdApi.getData("betterdiscord-google-fonts", "fonts");
|
||||
const lastFetchTime = BdApi.getData("betterdiscord-google-fonts", "lastFetchTime");
|
||||
const lastFetchExpiration = new Date(lastFetchTime);
|
||||
lastFetchExpiration.setDate(lastFetchExpiration.getDate() + 1 * 7);
|
||||
if (!existingData || lastFetchTime < lastFetchExpiration) {
|
||||
const response = await fetch("https://www.googleapis.com/webfonts/v1/webfonts?key=AIzaSyCfxANDwWkAP3JjzGLv5UOPYcPEwaVAz3k");
|
||||
const json = await response.json();
|
||||
const fonts = json.items.map((font) => font.family);
|
||||
fonts.unshift("Default");
|
||||
BdApi.setData("betterdiscord-google-fonts", "fonts", fonts);
|
||||
BdApi.setData("betterdiscord-google-fonts", "lastFetchTime", new Date().getTime());
|
||||
return fonts;
|
||||
}
|
||||
return existingData;
|
||||
}
|
||||
updateDomFont() {
|
||||
BdApi.clearCSS("bd-google-fonts-custom-font");
|
||||
if (this.selectedFont) {
|
||||
const newStyle = `
|
||||
@import url('https://fonts.googleapis.com/css?family=${this.selectedFont}');
|
||||
|
||||
*:not([class*="hljs"]):not(code){
|
||||
font-family: ${this.selectedFont} !important;
|
||||
}
|
||||
`;
|
||||
BdApi.injectCSS("bd-google-fonts-custom-font", newStyle);
|
||||
}
|
||||
}
|
||||
getSettingsPanel() {
|
||||
const template = document.createElement("template");
|
||||
const currentFontString = this.selectedFont ? this.selectedFont : "Default";
|
||||
template.innerHTML = SettingsPanel_default.replace("{{ CURRENT_FONT }}", currentFontString);
|
||||
const settingsPanel = template.content.firstElementChild;
|
||||
const fontSelection = settingsPanel.querySelector(".bd-select-options");
|
||||
settingsPanel.querySelector(".bd-select").addEventListener("click", () => {
|
||||
const dropdown = settingsPanel.querySelector(".bd-select-options");
|
||||
if (dropdown.style.display === "none") {
|
||||
dropdown.style.display = "block";
|
||||
} else {
|
||||
dropdown.style.display = "none";
|
||||
}
|
||||
});
|
||||
this.fonts.forEach((font) => {
|
||||
const option = document.createElement("div");
|
||||
option.classList.add("bd-select-option");
|
||||
option.textContent = font;
|
||||
option.addEventListener("click", (e) => {
|
||||
const target = e.target;
|
||||
const selectedFont = target.textContent;
|
||||
if (selectedFont === "Default") {
|
||||
this.selectedFont = null;
|
||||
} else {
|
||||
this.selectedFont = selectedFont;
|
||||
}
|
||||
this.updateDomFont();
|
||||
document.querySelector(".google-font-settings .bd-select-value").textContent = selectedFont;
|
||||
BdApi.setData("betterdiscord-google-fonts", "font", this.selectedFont);
|
||||
});
|
||||
fontSelection.appendChild(option);
|
||||
});
|
||||
return settingsPanel;
|
||||
}
|
||||
};
|
||||
module.exports = DiscordPlugin;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,194 +0,0 @@
|
||||
/**
|
||||
* @name FVUI
|
||||
* @author feorev
|
||||
* @description Blur is the New Black
|
||||
* @version 2.0.0
|
||||
* @authorId 489785940546551831
|
||||
* @invite baEMQkgswT
|
||||
* @source https://github.com/FeoreV/Themes/tree/main/Discord/FVUI
|
||||
*/
|
||||
/* ! DO NOT TOUCH ! */
|
||||
@import url(https://feorev.github.io/Themes/Discord/FVUI/Cores/preload.css);
|
||||
@import url(https://feorev.github.io/Themes/Discord/FVUI/assets/Versions/v2.css);
|
||||
|
||||
/*=============================================
|
||||
= Info =
|
||||
==============================================*
|
||||
DiscordServer: https://discord.com/invite/baEMQkgswT
|
||||
DM - feorev
|
||||
Site - https://feorev.github.io/
|
||||
ThemeEditor - https://bdeditor.dev/theme/FVUI
|
||||
|
||||
Due to the inability to update the theme file frequently, many new additions to the theme will be posted on the discord server.
|
||||
The FVUI theme extends not only to discord, but also to other sites and areas. You can find a complete list of themes on the discord server.
|
||||
|
||||
|
||||
|
||||
/*=============================================
|
||||
= FAQ =
|
||||
==============================================*
|
||||
|
||||
/*---------- How to enable another subtheme? ----------*
|
||||
|
||||
IT IS RECOMMENDED TO USE AN EDITOR ( https://bdeditor.dev/theme/FVUI )
|
||||
|
||||
Select import and press ctrl+/
|
||||
|
||||
Enabled - @import url(...)
|
||||
Disabled - /*@import url(...)*/
|
||||
|
||||
|
||||
/*---------- I want ... ----------
|
||||
Make the background a picture - enable WIN11
|
||||
Make discord transparent - enable Mica
|
||||
Change background picture - Change the settings of the win11 subtheme - the --dark/light BG variable
|
||||
|
||||
/*---------- Any other questions? ----------
|
||||
Join the discord server c:
|
||||
https://discord.com/invite/baEMQkgswT
|
||||
|
||||
|
||||
|
||||
/*=============================================
|
||||
= Subthemes to choose =
|
||||
=============================================*/
|
||||
|
||||
/*---------- Default ----------*/
|
||||
/* Default */
|
||||
@import url(https://feorev.github.io/Themes/Discord/FVUI/assets/SubThemes/Default.css);
|
||||
/* Lite */
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/assets/SubThemes/Default_lite.css); */
|
||||
|
||||
/*---------- CustomBackground ----------*/
|
||||
/* WIN11 */
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/assets/SubThemes/CustomBackground.css); */
|
||||
/* Lite11 */
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/assets/SubThemes/CustomBackground_lite.css); */
|
||||
|
||||
/*---------- Other ----------*/
|
||||
/*MICA (Required "Mica For Everyone" and enabling transparency (Settings=>BD=>Settings=>Window preferences=>Enable transparency)*/
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/assets/SubThemes/Mica.css); */
|
||||
|
||||
|
||||
|
||||
/*=============================================
|
||||
= Addons =
|
||||
=============================================*/
|
||||
|
||||
/* Events (Any events and decorations for the holidays. For example, snow and New Year's attributes for the new year.) */
|
||||
@import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/Events/Events.css);
|
||||
|
||||
/* ServerRings */
|
||||
@import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/ServerRings.css);
|
||||
|
||||
/* RadialStatus */
|
||||
@import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/RadialStatus.css);
|
||||
|
||||
/* MaterialYou (The theme color scheme adjusts to the accent color) */
|
||||
@import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/MaterialYou.css); */
|
||||
|
||||
/* ModularDesign (Adds outline to main sections) */
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/ModularDesign.css); */
|
||||
|
||||
/* TopUserPanel (Moves the userpanel to the top corner) */
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/TopUserPanel.css); */
|
||||
|
||||
/* HorizontalServerList (Moves serverlist to the top or bottom corner. For FVUI, it is recommended to use this version of HSL, and not the official one.) */
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/HSL/HSL_top.css); */
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/HSL/HSL_bottom.css); */
|
||||
|
||||
/* TitleIsland */
|
||||
/* @import url(https://feorev.github.io/Themes/Discord/FVUI/Addons/TitleIsland.css); */
|
||||
|
||||
|
||||
|
||||
/*=============================================
|
||||
= SubThemes Settings =
|
||||
=============================================*/
|
||||
|
||||
/* Theme editor - https://bdeditor.dev/theme/FVUI */
|
||||
|
||||
/*---------- General ----------*/
|
||||
:root{
|
||||
--cursor : url('https://feorev.github.io/Themes/Discord/FVUI/assets/Cursor.cur'); /* Link to cursor / unset - to set standard */
|
||||
--font : "Comfortaa"; /* The font must be pre-installed or imported */
|
||||
--homeicon: url("https://feorev.github.io/Themes/Discord/FVUI/assets/HomeIcon/Icon.png"); /* Link to image */
|
||||
}
|
||||
|
||||
:root{
|
||||
--ColorOpacity : 1; /* Opacity multiplier / Default=1 (0.1-...) */
|
||||
--DisableOpacity: 0; /* Disable Opacity / Default=0 (0 or 1) */
|
||||
}
|
||||
|
||||
:root.theme-dark {
|
||||
--color1: 30, 40, 50; /* Additional BG / Default= | 30, 40, 50 | (any raw rgb value) */
|
||||
--color2: 9, 18, 24; /* Background / Default= | 9, 18, 24 | (any raw rgb value) */
|
||||
--color3: 35, 120, 200; /* Additional Color / Default= | 35, 120, 200 | (any raw rgb value) */
|
||||
--color4: 63, 43, 150; /* Gradient Color / Default= | 63, 43, 150 | (any raw rgb value) */
|
||||
}
|
||||
:root.theme-light {
|
||||
--color1: 211, 204, 227; /* Additional BG / Default= | 211, 204, 227 | (any raw rgb value) */
|
||||
--color2: 219, 219, 219; /* Background / Default= | 219, 219, 219 | (any raw rgb value) */
|
||||
--color3: 96, 205, 255; /* Additional Color / Default= | 96,205,255 | (any raw rgb value) */
|
||||
--color4: 63, 43, 150; /* Gradient Color / Default= | 63, 43, 150 | (any raw rgb value) */
|
||||
}
|
||||
|
||||
/*---------- CustomBackground ----------*/
|
||||
:root{
|
||||
--DarkBG : url(https://feorev.github.io/Themes/Discord/FVUI/assets/Wallpapers/dark.avif); /* Link to background image / Default= url(https://feorev.github.io/Themes/Discord/assets/Wallpapers/dark.avif) ( url(link) ) */
|
||||
--LightBG : url(https://feorev.github.io/Themes/Discord/FVUI/assets/Wallpapers/light.avif); /* Link to background image / Default= url(https://feorev.github.io/Themes/Discord/assets/Wallpapers/light.avif) ( url(link) ) */
|
||||
--OpacityBG: 60%; /* Background image transparency / Default=100% (0%-100%) */
|
||||
--BlurBG : 0px; /* Background image blur / Default=0px (any value in px) */
|
||||
}
|
||||
|
||||
|
||||
/*---------- Mica ----------*/
|
||||
:root{
|
||||
--BGopacity: 30%; /* Background image transparency / Default=30% (0%-100%) */
|
||||
--BGcolor : var(--color2); /* Сolor in RGB / Example = rgb(255,255,255) ( any value in RGB (like example) ) */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=============================================
|
||||
= Addons Settings =
|
||||
=============================================*/
|
||||
|
||||
/*---------- MaterialYou ----------*/
|
||||
:root.theme-dark{ /* First 2 HSL values / Default= | 210, 68% | https://g.co/kgs/83i83K */
|
||||
--accentcolor-HUE: 210;
|
||||
--accentcolor-SATURATION: 68%;
|
||||
}
|
||||
:root.theme-light{ /* First 2 HSL values / Default= | 199, 100% | https://g.co/kgs/83i83K */
|
||||
--accentcolor-HUE: 199;
|
||||
--accentcolor-SATURATION: 100%;
|
||||
}
|
||||
|
||||
/*---------- ModularDesign ----------*/
|
||||
:root{ /*MainModules*/
|
||||
--outline : 3px; /* outline size / Default=3px (any value in px) */
|
||||
--outlineCLR : var(--color03); /* outline color / Example = rgb(255,255,255) ( any value in RGB (like example) ) */
|
||||
--outlineBR : 16px; /* outline rounding / Default=16px (any value in px) */
|
||||
--outlineMG : 2rem; /* outline margin / Default=2rem (any value in px/rem/...) */
|
||||
--outlineBS : 15px; /* outline glow / Default = 15px */
|
||||
--outlineBG : unset; /* outline content background color / Example = rgb(255,255,255) ( any value in RGB (like example) */
|
||||
--outlineBLUR: 0; /* (ONLY WIN11) backdrop blur / Default=0 ( any value in px */
|
||||
}
|
||||
|
||||
:root{ /*AdditionalModules*/
|
||||
--outline2 : 0; /* outline size / Default=0px (disabled) (any value in px) */
|
||||
--outlineCLR2 : var(--outlineCLR); /* outline color / Example = rgb(255,255,255) ( any value in RGB (like example) ) */
|
||||
--outlineBR2 : var(--outlineBR); /* outline rounding / (any value in px) */
|
||||
--outlineMG2 : var(--outlineMG); /* outline margin / (any value in px/rem/...) */
|
||||
--outlineBS2 : 0; /* outline glow / Default = 0 */
|
||||
--outlineBG2 : unset; /* outline content background color / Example = rgb(255,255,255) ( any value in RGB (like example) */
|
||||
--outlineBLUR2: 0 /* (ONLY WIN11) (Not recommended - bad performance) backdrop blur / Default=0 ( any value in px ) */
|
||||
}
|
||||
|
||||
/*---------- Have you tuned the theme well? ----------*/
|
||||
/* You can share your vision of the world in the channel of the Discord server by sending the settings: https://discord.gg/baEMQkgswT */
|
||||
|
||||
/*=============================================
|
||||
= Credits =
|
||||
= gibbu - RadialStatus / ServerRings =
|
||||
=============================================*/
|
||||
@@ -1,90 +0,0 @@
|
||||
/**
|
||||
* @name Translucence
|
||||
* @version 1.0.7
|
||||
* @description A translucent/frosted glass Discord theme
|
||||
* @author CapnKitten
|
||||
*
|
||||
* @website http://github.com/CapnKitten
|
||||
* @source https://github.com/CapnKitten/BetterDiscord/blob/master/Themes/Translucence/css/source.css
|
||||
* @donate https://paypal.me/capnkitten
|
||||
* @invite jzJkA6Z
|
||||
*/
|
||||
|
||||
@import url(https://capnkitten.github.io/BetterDiscord/Themes/Translucence/css/source.css);
|
||||
|
||||
:root {
|
||||
/* APP ELEMENTS */
|
||||
--app-bg: "";
|
||||
--app-blur: 6px;
|
||||
--app-margin: 24px;
|
||||
--app-radius: 8px;
|
||||
|
||||
/* ACCENT HSL AND TEXT COLOR SETTINGS */
|
||||
--accent-hue: 156;
|
||||
--accent-saturation: 50%;
|
||||
--accent-lightness: 25%;
|
||||
--accent-opacity: 1;
|
||||
--accent-text-color: hsl(0,0%,0%);
|
||||
|
||||
/* SIDEBARS AND CHAT AREA COLOR SETTINGS */
|
||||
--sidebar-color: hsl(0,0%,0%,0.4);
|
||||
--main-content-color: hsl(0,0%,0%,0.2);
|
||||
|
||||
/* MESSAGE SETTINGS */
|
||||
--message-color: hsl(0,0%,0%,0.4);
|
||||
--message-radius: 8px;
|
||||
--message-padding-top: 8px;
|
||||
--message-padding-side: 8px;
|
||||
|
||||
/* REPLY HSL COLOR SETTINGS */
|
||||
--reply-hue: 226;
|
||||
--reply-saturation: 77.4%;
|
||||
--reply-lightness: 61.8%;
|
||||
--reply-opacity: 1;
|
||||
|
||||
/* TEXTAREA SETTINGS */
|
||||
--textarea-color: 255,255,255;
|
||||
--textarea-alpha: 0.1;
|
||||
--textarea-alpha-focus: 0.15;
|
||||
--textarea-text-color: hsl(0,0%,100%);
|
||||
--textarea-radius: 22px;
|
||||
|
||||
/* CARD SETTINGS */
|
||||
--card-color: hsl(0,0%,0%,0.4);
|
||||
--card-color-hover: hsl(0,0%,0%,0.5);
|
||||
--card-color-select: hsl(0,0%,0%,0.7);
|
||||
|
||||
/* BUTTON SETTINGS */
|
||||
--button-height: 32px;
|
||||
--button-padding: 0 16px;
|
||||
--button-action-color: hsl(0,0%,0%);
|
||||
--button-radius: 16px;
|
||||
}
|
||||
|
||||
@supports (color:color-mix(in lch,red,blue)) {
|
||||
.visual-refresh .theme-dark,
|
||||
.visual-refresh.theme-dark {
|
||||
/* TEXT COLOR SETTINGS */
|
||||
--text-primary: hsl(0,0%,100%);
|
||||
--text-secondary: hsl(0,0%,77%);
|
||||
|
||||
/* CHANNEL COLOR SETTINGS */
|
||||
--channels-default: hsl(0,0%,62%);
|
||||
--channel-icon: hsl(0,0%,62%);
|
||||
|
||||
/* ICON COLOR SETTINGS */
|
||||
--icon-primary: hsl(0,0%,96%);
|
||||
--icon-secondary: hsl(0,0%,84%);
|
||||
--icon-tertiary: hsl(0,0%,71%);
|
||||
|
||||
/* INTERACTIVE COLOR SETTINGS */
|
||||
--interactive-normal: hsl(0,0%,79%);
|
||||
--interactive-hover: hsl(0,0%,91%);
|
||||
--interactive-active: hsl(0,0%,100%);
|
||||
--interactive-muted: hsl(0,0%,43%);
|
||||
|
||||
/* BACKGROUND MODIFIER SETTINGS */
|
||||
--background-modifier-hover: hsl(0,0%,100%,0.075);
|
||||
--background-modifier-selected: hsl(0,0%,100%,0.125);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
* @name Arindy
|
||||
* @author FeoreV
|
||||
* @version 2.0.0
|
||||
* @description Blur is the new black
|
||||
* @source https://github.com/FeoreV/Themes/tree/main/Discord/FVUI
|
||||
* @invite baEMQkgswT
|
||||
* @website https://feorev.github.io/
|
||||
* @authorId 489785940546551831
|
||||
* @BDEditor FVUI
|
||||
*/
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Fira+Mono:wght@100;300;400;500;700&display=swap');
|
||||
@import url('https://feorev.github.io/Themes/Discord/FVUI/Cores/preload.css');
|
||||
@import url('https://feorev.github.io/Themes/Discord/FVUI/assets/SubThemes/Mica.css');
|
||||
@import url('https://feorev.github.io/Themes/Discord/FVUI/Addons/ModularDesign.css');
|
||||
@import url('https://feorev.github.io/Themes/Discord/FVUI/Addons/RadialStatus.css');
|
||||
@import url('https://feorev.github.io/Themes/Discord/FVUI/Addons/TitleIsland.css');
|
||||
|
||||
:root {
|
||||
--undefined: 0;
|
||||
--color1: 48,48,48;
|
||||
--color2: 0,0,0;
|
||||
--color3: 76,175,80;
|
||||
--undefined: 0;
|
||||
--ColorOpacity: 0.5;
|
||||
--DisableOpacity: 0;
|
||||
--cursor: transparent;
|
||||
--font: Fira Mono;
|
||||
--homeicon: url('https://feorev.github.io/Themes/Discord/FVUI/assets/HomeIcon/Icon.png');
|
||||
--undefined: 0;
|
||||
--FVUI: Arindy;
|
||||
--customdesc: "";
|
||||
--BGopacity: 50%;
|
||||
--BGcolor: #00000088;
|
||||
--undefined: 0;
|
||||
--outline: 1px;
|
||||
--outlineCLR: var(--color03);
|
||||
--outlineBR: 8px;
|
||||
--outlineMG: 0.7rem;
|
||||
--outlineBS: 14px;
|
||||
--outlineBGclr: unset;
|
||||
--outlineBGalpha: 1;
|
||||
--outlineBLUR: "";
|
||||
}
|
||||
|
||||
/* Any custom CSS below here */
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
[soe][BassEnhancer#0]
|
||||
amount=2
|
||||
@@ -0,0 +1,2 @@
|
||||
[sie][Compressor#0]
|
||||
sidechainMode=1
|
||||
@@ -0,0 +1,23 @@
|
||||
[Presets]
|
||||
lastLoadedInputPreset=male_voices_with_noise_reduction
|
||||
|
||||
[StreamInputs]
|
||||
inputDevice=alsa_input.usb-Kingston_HyperX_Quadcast_HyperX_QuadCast_SharkLatan-00.iec958-stereo
|
||||
mostUsedPresets=male_voices_with_noise_reduction
|
||||
plugins=gate#0,compressor#0,filter#0,deesser#0,rnnoise#0,limiter#0
|
||||
useDefaultInputDevice=false
|
||||
usedPresets=male_voices_with_noise_reduction:1
|
||||
visiblePlugin=gate#0
|
||||
|
||||
[StreamOutputs]
|
||||
outputDevice=alsa_output.pci-0000_09_00.4.pro-output-0
|
||||
plugins=bass_enhancer#0
|
||||
useDefaultOutputDevice=false
|
||||
visiblePage=pluginsPage
|
||||
visiblePlugin=bass_enhancer#0
|
||||
|
||||
[Window]
|
||||
autostartOnLogin=true
|
||||
height=1362
|
||||
noWindowAfterStarting=true
|
||||
width=1255
|
||||
@@ -0,0 +1,3 @@
|
||||
[sie][Filter#0]
|
||||
bypass=true
|
||||
frequency=80
|
||||
@@ -0,0 +1,3 @@
|
||||
[sie][Gate#0]
|
||||
attack=5
|
||||
bypass=true
|
||||
@@ -0,0 +1,2 @@
|
||||
[sie][Limiter#0]
|
||||
threshold=-1
|
||||
@@ -0,0 +1,2 @@
|
||||
[UiSettings]
|
||||
ColorScheme=KritaDarker
|
||||
@@ -0,0 +1,988 @@
|
||||
-- Set <space> as the leader key
|
||||
-- See `:help mapleader`
|
||||
-- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used)
|
||||
vim.g.mapleader = " "
|
||||
vim.g.maplocalleader = " "
|
||||
|
||||
-- Set to true if you have a Nerd Font installed and selected in the terminal
|
||||
vim.g.have_nerd_font = true
|
||||
|
||||
-- [[ Setting options ]]
|
||||
-- See `:help vim.o`
|
||||
-- NOTE: You can change these options as you wish!
|
||||
-- For more options, you can see `:help option-list`
|
||||
|
||||
-- Make line numbers default
|
||||
vim.o.number = true
|
||||
-- You can also add relative line numbers, to help with jumping.
|
||||
-- Experiment for yourself to see if you like it!
|
||||
vim.o.relativenumber = true
|
||||
|
||||
-- Enable mouse mode, can be useful for resizing splits for example!
|
||||
vim.o.mouse = "a"
|
||||
|
||||
-- Don't show the mode, since it's already in the status line
|
||||
vim.o.showmode = false
|
||||
|
||||
-- Sync clipboard between OS and Neovim.
|
||||
-- Schedule the setting after `UiEnter` because it can increase startup-time.
|
||||
-- Remove this option if you want your OS clipboard to remain independent.
|
||||
-- See `:help 'clipboard'`
|
||||
vim.schedule(function()
|
||||
vim.o.clipboard = "unnamedplus"
|
||||
end)
|
||||
|
||||
-- Enable break indent
|
||||
vim.o.breakindent = true
|
||||
|
||||
-- Enable undo/redo changes even after closing and reopening a file
|
||||
vim.o.undofile = true
|
||||
|
||||
-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
|
||||
vim.o.ignorecase = true
|
||||
vim.o.smartcase = true
|
||||
|
||||
-- Keep signcolumn on by default
|
||||
vim.o.signcolumn = "yes"
|
||||
|
||||
-- Decrease update time
|
||||
vim.o.updatetime = 250
|
||||
|
||||
-- Decrease mapped sequence wait time
|
||||
vim.o.timeoutlen = 300
|
||||
|
||||
-- Configure how new splits should be opened
|
||||
vim.o.splitright = true
|
||||
vim.o.splitbelow = true
|
||||
|
||||
-- Sets how neovim will display certain whitespace characters in the editor.
|
||||
-- See `:help 'list'`
|
||||
-- and `:help 'listchars'`
|
||||
--
|
||||
-- Notice listchars is set using `vim.opt` instead of `vim.o`.
|
||||
-- It is very similar to `vim.o` but offers an interface for conveniently interacting with tables.
|
||||
-- See `:help lua-options`
|
||||
-- and `:help lua-guide-options`
|
||||
vim.o.list = true
|
||||
vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" }
|
||||
|
||||
-- Preview substitutions live, as you type!
|
||||
vim.o.inccommand = "split"
|
||||
|
||||
-- Show which line your cursor is on
|
||||
vim.o.cursorline = true
|
||||
|
||||
-- Minimal number of screen lines to keep above and below the cursor.
|
||||
vim.o.scrolloff = 10
|
||||
|
||||
-- if performing an operation that would fail due to unsaved changes in the buffer (like `:q`),
|
||||
-- instead raise a dialog asking if you wish to save the current file(s)
|
||||
-- See `:help 'confirm'`
|
||||
vim.o.confirm = true
|
||||
|
||||
-- [[ Basic Keymaps ]]
|
||||
-- See `:help vim.keymap.set()`
|
||||
|
||||
-- Clear highlights on search when pressing <Esc> in normal mode
|
||||
-- See `:help hlsearch`
|
||||
vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>")
|
||||
|
||||
-- Diagnostic Config & Keymaps
|
||||
-- See :help vim.diagnostic.Opts
|
||||
vim.diagnostic.config({
|
||||
update_in_insert = false,
|
||||
severity_sort = true,
|
||||
float = { border = "rounded", source = "if_many" },
|
||||
underline = { severity = { min = vim.diagnostic.severity.WARN } },
|
||||
|
||||
-- Can switch between these as you prefer
|
||||
virtual_text = true, -- Text shows up at the end of the line
|
||||
virtual_lines = false, -- Text shows up underneath the line, with virtual lines
|
||||
|
||||
-- Auto open the float, so you can easily read the errors when jumping with `[d` and `]d`
|
||||
jump = { float = true },
|
||||
})
|
||||
|
||||
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" })
|
||||
|
||||
-- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier
|
||||
-- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which
|
||||
-- is not what someone will guess without a bit more experience.
|
||||
--
|
||||
-- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping
|
||||
-- or just use <C-\><C-n> to exit terminal mode
|
||||
vim.keymap.set("t", "<Esc><Esc>", "<C-\\><C-n>", { desc = "Exit terminal mode" })
|
||||
|
||||
-- TIP: Disable arrow keys in normal mode
|
||||
-- vim.keymap.set('n', '<left>', '<cmd>echo "Use h to move!!"<CR>')
|
||||
-- vim.keymap.set('n', '<right>', '<cmd>echo "Use l to move!!"<CR>')
|
||||
-- vim.keymap.set('n', '<up>', '<cmd>echo "Use k to move!!"<CR>')
|
||||
-- vim.keymap.set('n', '<down>', '<cmd>echo "Use j to move!!"<CR>')
|
||||
|
||||
-- Keybinds to make split navigation easier.
|
||||
-- Use CTRL+<hjkl> to switch between windows
|
||||
--
|
||||
-- See `:help wincmd` for a list of all window commands
|
||||
vim.keymap.set("n", "<C-h>", "<C-w><C-h>", { desc = "Move focus to the left window" })
|
||||
vim.keymap.set("n", "<C-l>", "<C-w><C-l>", { desc = "Move focus to the right window" })
|
||||
vim.keymap.set("n", "<C-j>", "<C-w><C-j>", { desc = "Move focus to the lower window" })
|
||||
vim.keymap.set("n", "<C-k>", "<C-w><C-k>", { desc = "Move focus to the upper window" })
|
||||
|
||||
-- NOTE: Some terminals have colliding keymaps or are not able to send distinct keycodes
|
||||
-- vim.keymap.set("n", "<C-S-h>", "<C-w>H", { desc = "Move window to the left" })
|
||||
-- vim.keymap.set("n", "<C-S-l>", "<C-w>L", { desc = "Move window to the right" })
|
||||
-- vim.keymap.set("n", "<C-S-j>", "<C-w>J", { desc = "Move window to the lower" })
|
||||
-- vim.keymap.set("n", "<C-S-k>", "<C-w>K", { desc = "Move window to the upper" })
|
||||
|
||||
-- [[ Basic Autocommands ]]
|
||||
-- See `:help lua-guide-autocommands`
|
||||
|
||||
-- Highlight when yanking (copying) text
|
||||
-- Try it with `yap` in normal mode
|
||||
-- See `:help vim.hl.on_yank()`
|
||||
vim.api.nvim_create_autocmd("TextYankPost", {
|
||||
desc = "Highlight when yanking (copying) text",
|
||||
group = vim.api.nvim_create_augroup("kickstart-highlight-yank", { clear = true }),
|
||||
callback = function()
|
||||
vim.hl.on_yank()
|
||||
end,
|
||||
})
|
||||
|
||||
-- [[ Install `lazy.nvim` plugin manager ]]
|
||||
-- See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info
|
||||
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
|
||||
if not (vim.uv or vim.loop).fs_stat(lazypath) then
|
||||
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
|
||||
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
|
||||
if vim.v.shell_error ~= 0 then
|
||||
error("Error cloning lazy.nvim:\n" .. out)
|
||||
end
|
||||
end
|
||||
|
||||
---@type vim.Option
|
||||
local rtp = vim.opt.rtp
|
||||
rtp:prepend(lazypath)
|
||||
|
||||
-- [[ Configure and install plugins ]]
|
||||
--
|
||||
-- To check the current status of your plugins, run
|
||||
-- :Lazy
|
||||
--
|
||||
-- You can press `?` in this menu for help. Use `:q` to close the window
|
||||
--
|
||||
-- To update plugins you can run
|
||||
-- :Lazy update
|
||||
--
|
||||
-- NOTE: Here is where you install your plugins.
|
||||
-- TODO: CleanUp
|
||||
require("lazy").setup({
|
||||
opts = {
|
||||
change_detection = {
|
||||
notify = false,
|
||||
},
|
||||
checker = {
|
||||
enabled = true,
|
||||
notify = false,
|
||||
},
|
||||
},
|
||||
-- NOTE: Plugins can be added via a link or github org/name. To run setup automatically, use `opts = {}`
|
||||
{ "NMAC427/guess-indent.nvim", opts = {} },
|
||||
|
||||
-- Alternatively, use `config = function() ... end` for full control over the configuration.
|
||||
-- If you prefer to call `setup` explicitly, use:
|
||||
-- {
|
||||
-- 'lewis6991/gitsigns.nvim',
|
||||
-- config = function()
|
||||
-- require('gitsigns').setup({
|
||||
-- -- Your gitsigns configuration here
|
||||
-- })
|
||||
-- end,
|
||||
-- }
|
||||
--
|
||||
-- Here is a more advanced example where we pass configuration
|
||||
-- options to `gitsigns.nvim`.
|
||||
--
|
||||
-- See `:help gitsigns` to understand what the configuration keys do
|
||||
{ -- Adds git related signs to the gutter, as well as utilities for managing changes
|
||||
"lewis6991/gitsigns.nvim",
|
||||
---@module 'gitsigns'
|
||||
---@type Gitsigns.Config
|
||||
---@diagnostic disable-next-line: missing-fields
|
||||
opts = {
|
||||
signs = {
|
||||
add = { text = "+" }, ---@diagnostic disable-line: missing-fields
|
||||
change = { text = "~" }, ---@diagnostic disable-line: missing-fields
|
||||
delete = { text = "_" }, ---@diagnostic disable-line: missing-fields
|
||||
topdelete = { text = "‾" }, ---@diagnostic disable-line: missing-fields
|
||||
changedelete = { text = "~" }, ---@diagnostic disable-line: missing-fields
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
-- NOTE: Plugins can also be configured to run Lua code when they are loaded.
|
||||
--
|
||||
-- This is often very useful to both group configuration, as well as handle
|
||||
-- lazy loading plugins that don't need to be loaded immediately at startup.
|
||||
--
|
||||
-- For example, in the following configuration, we use:
|
||||
-- event = 'VimEnter'
|
||||
--
|
||||
-- which loads which-key before all the UI elements are loaded. Events can be
|
||||
-- normal autocommands events (`:help autocmd-events`).
|
||||
--
|
||||
-- Then, because we use the `opts` key (recommended), the configuration runs
|
||||
-- after the plugin has been loaded as `require(MODULE).setup(opts)`.
|
||||
|
||||
{ -- Useful plugin to show you pending keybinds.
|
||||
"folke/which-key.nvim",
|
||||
event = "VimEnter",
|
||||
---@module 'which-key'
|
||||
---@type wk.Opts
|
||||
---@diagnostic disable-next-line: missing-fields
|
||||
opts = {
|
||||
-- delay between pressing a key and opening which-key (milliseconds)
|
||||
delay = 0,
|
||||
icons = { mappings = vim.g.have_nerd_font },
|
||||
|
||||
-- Document existing key chains
|
||||
gspec = {
|
||||
{ "<leader>s", group = "[S]earch", mode = { "n", "v" } },
|
||||
{ "<leader>t", group = "[T]oggle" },
|
||||
{ "<leader>h", group = "Git [H]unk", mode = { "n", "v" } }, -- Enable gitsigns recommended keymaps first
|
||||
{ "gr", group = "LSP Actions", mode = { "n" } },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
-- NOTE: Plugins can specify dependencies.
|
||||
--
|
||||
-- The dependencies are proper plugin specifications as well - anything
|
||||
-- you do for a plugin at the top level, you can do for a dependency.
|
||||
--
|
||||
-- Use the `dependencies` key to specify the dependencies of a particular plugin
|
||||
|
||||
{ -- Fuzzy Finder (files, lsp, etc)
|
||||
"nvim-telescope/telescope.nvim",
|
||||
-- By default, Telescope is included and acts as your picker for everything.
|
||||
|
||||
-- If you would like to switch to a different picker (like snacks, or fzf-lua)
|
||||
-- you can disable the Telescope plugin by setting enabled to false and enable
|
||||
-- your replacement picker by requiring it explicitly (e.g. 'custom.plugins.snacks')
|
||||
|
||||
-- Note: If you customize your config for yourself,
|
||||
-- it’s best to remove the Telescope plugin config entirely
|
||||
-- instead of just disabling it here, to keep your config clean.
|
||||
enabled = true,
|
||||
event = "VimEnter",
|
||||
dependencies = {
|
||||
"nvim-lua/plenary.nvim",
|
||||
{ -- If encountering errors, see telescope-fzf-native README for installation instructions
|
||||
"nvim-telescope/telescope-fzf-native.nvim",
|
||||
|
||||
-- `build` is used to run some command when the plugin is installed/updated.
|
||||
-- This is only run then, not every time Neovim starts up.
|
||||
build = "make",
|
||||
|
||||
-- `cond` is a condition used to determine whether this plugin should be
|
||||
-- installed and loaded.
|
||||
cond = function()
|
||||
return vim.fn.executable("make") == 1
|
||||
end,
|
||||
},
|
||||
{ "nvim-telescope/telescope-ui-select.nvim" },
|
||||
|
||||
-- Useful for getting pretty icons, but requires a Nerd Font.
|
||||
{ "nvim-tree/nvim-web-devicons", enabled = vim.g.have_nerd_font },
|
||||
},
|
||||
config = function()
|
||||
-- Telescope is a fuzzy finder that comes with a lot of different things that
|
||||
-- it can fuzzy find! It's more than just a "file finder", it can search
|
||||
-- many different aspects of Neovim, your workspace, LSP, and more!
|
||||
--
|
||||
-- The easiest way to use Telescope, is to start by doing something like:
|
||||
-- :Telescope help_tags
|
||||
--
|
||||
-- After running this command, a window will open up and you're able to
|
||||
-- type in the prompt window. You'll see a list of `help_tags` options and
|
||||
-- a corresponding preview of the help.
|
||||
--
|
||||
-- Two important keymaps to use while in Telescope are:
|
||||
-- - Insert mode: <c-/>
|
||||
-- - Normal mode: ?
|
||||
--
|
||||
-- This opens a window that shows you all of the keymaps for the current
|
||||
-- Telescope picker. This is really useful to discover what Telescope can
|
||||
-- do as well as how to actually do it!
|
||||
|
||||
-- [[ Configure Telescope ]]
|
||||
-- See `:help telescope` and `:help telescope.setup()`
|
||||
require("telescope").setup({
|
||||
-- You can put your default mappings / updates / etc. in here
|
||||
-- All the info you're looking for is in `:help telescope.setup()`
|
||||
--
|
||||
-- defaults = {
|
||||
-- mappings = {
|
||||
-- i = { ['<c-enter>'] = 'to_fuzzy_refine' },
|
||||
-- },
|
||||
-- },
|
||||
-- pickers = {}
|
||||
extensions = {
|
||||
["ui-select"] = { require("telescope.themes").get_dropdown() },
|
||||
},
|
||||
})
|
||||
|
||||
-- Enable Telescope extensions if they are installed
|
||||
pcall(require("telescope").load_extension, "fzf")
|
||||
pcall(require("telescope").load_extension, "ui-select")
|
||||
|
||||
-- See `:help telescope.builtin`
|
||||
local builtin = require("telescope.builtin")
|
||||
vim.keymap.set("n", "<leader>sh", builtin.help_tags, { desc = "[S]earch [H]elp" })
|
||||
vim.keymap.set("n", "<leader>sk", builtin.keymaps, { desc = "[S]earch [K]eymaps" })
|
||||
vim.keymap.set("n", "<leader>sf", builtin.find_files, { desc = "[S]earch [F]iles" })
|
||||
vim.keymap.set("n", "<leader>ss", builtin.builtin, { desc = "[S]earch [S]elect Telescope" })
|
||||
vim.keymap.set({ "n", "v" }, "<leader>sw", builtin.grep_string, { desc = "[S]earch current [W]ord" })
|
||||
vim.keymap.set("n", "<leader>sg", builtin.live_grep, { desc = "[S]earch by [G]rep" })
|
||||
vim.keymap.set("n", "<leader>sd", builtin.diagnostics, { desc = "[S]earch [D]iagnostics" })
|
||||
vim.keymap.set("n", "<leader>sr", builtin.resume, { desc = "[S]earch [R]esume" })
|
||||
vim.keymap.set("n", "<leader>s.", builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' })
|
||||
vim.keymap.set("n", "<leader>sc", builtin.commands, { desc = "[S]earch [C]ommands" })
|
||||
vim.keymap.set("n", "<leader><leader>", builtin.buffers, { desc = "[ ] Find existing buffers" })
|
||||
|
||||
-- This runs on LSP attach per buffer (see main LSP attach function in 'neovim/nvim-lspconfig' config for more info,
|
||||
-- it is better explained there). This allows easily switching between pickers if you prefer using something else!
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
group = vim.api.nvim_create_augroup("telescope-lsp-attach", { clear = true }),
|
||||
callback = function(event)
|
||||
local buf = event.buf
|
||||
|
||||
-- Find references for the word under your cursor.
|
||||
vim.keymap.set("n", "grr", builtin.lsp_references, { buffer = buf, desc = "[G]oto [R]eferences" })
|
||||
|
||||
-- Jump to the implementation of the word under your cursor.
|
||||
-- Useful when your language has ways of declaring types without an actual implementation.
|
||||
vim.keymap.set(
|
||||
"n",
|
||||
"gri",
|
||||
builtin.lsp_implementations,
|
||||
{ buffer = buf, desc = "[G]oto [I]mplementation" }
|
||||
)
|
||||
|
||||
-- Jump to the definition of the word under your cursor.
|
||||
-- This is where a variable was first declared, or where a function is defined, etc.
|
||||
-- To jump back, press <C-t>.
|
||||
vim.keymap.set("n", "grd", builtin.lsp_definitions, { buffer = buf, desc = "[G]oto [D]efinition" })
|
||||
|
||||
-- Fuzzy find all the symbols in your current document.
|
||||
-- Symbols are things like variables, functions, types, etc.
|
||||
vim.keymap.set(
|
||||
"n",
|
||||
"gO",
|
||||
builtin.lsp_document_symbols,
|
||||
{ buffer = buf, desc = "Open Document Symbols" }
|
||||
)
|
||||
|
||||
-- Fuzzy find all the symbols in your current workspace.
|
||||
-- Similar to document symbols, except searches over your entire project.
|
||||
vim.keymap.set(
|
||||
"n",
|
||||
"gW",
|
||||
builtin.lsp_dynamic_workspace_symbols,
|
||||
{ buffer = buf, desc = "Open Workspace Symbols" }
|
||||
)
|
||||
|
||||
-- Jump to the type of the word under your cursor.
|
||||
-- Useful when you're not sure what type a variable is and you want to see
|
||||
-- the definition of its *type*, not where it was *defined*.
|
||||
vim.keymap.set(
|
||||
"n",
|
||||
"grt",
|
||||
builtin.lsp_type_definitions,
|
||||
{ buffer = buf, desc = "[G]oto [T]ype Definition" }
|
||||
)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Override default behavior and theme when searching
|
||||
vim.keymap.set("n", "<leader>/", function()
|
||||
-- You can pass additional configuration to Telescope to change the theme, layout, etc.
|
||||
builtin.current_buffer_fuzzy_find(require("telescope.themes").get_dropdown({
|
||||
winblend = 10,
|
||||
previewer = false,
|
||||
}))
|
||||
end, { desc = "[/] Fuzzily search in current buffer" })
|
||||
|
||||
-- It's also possible to pass additional configuration options.
|
||||
-- See `:help telescope.builtin.live_grep()` for information about particular keys
|
||||
vim.keymap.set("n", "<leader>s/", function()
|
||||
builtin.live_grep({
|
||||
grep_open_files = true,
|
||||
prompt_title = "Live Grep in Open Files",
|
||||
})
|
||||
end, { desc = "[S]earch [/] in Open Files" })
|
||||
|
||||
-- Shortcut for searching your Neovim configuration files
|
||||
vim.keymap.set("n", "<leader>sn", function()
|
||||
builtin.find_files({ cwd = vim.fn.stdpath("config") })
|
||||
end, { desc = "[S]earch [N]eovim files" })
|
||||
end,
|
||||
},
|
||||
|
||||
-- LSP Plugins
|
||||
{
|
||||
-- Main LSP Configuration
|
||||
"neovim/nvim-lspconfig",
|
||||
dependencies = {
|
||||
-- Automatically install LSPs and related tools to stdpath for Neovim
|
||||
-- Mason must be loaded before its dependents so we need to set it up here.
|
||||
-- NOTE: `opts = {}` is the same as calling `require('mason').setup({})`
|
||||
{
|
||||
"mason-org/mason.nvim",
|
||||
---@module 'mason.settings'
|
||||
---@type MasonSettings
|
||||
---@diagnostic disable-next-line: missing-fields
|
||||
opts = {},
|
||||
},
|
||||
-- Maps LSP server names between nvim-lspconfig and Mason package names.
|
||||
"mason-org/mason-lspconfig.nvim",
|
||||
"WhoIsSethDaniel/mason-tool-installer.nvim",
|
||||
|
||||
-- Useful status updates for LSP.
|
||||
{ "j-hui/fidget.nvim", opts = {} },
|
||||
},
|
||||
config = function()
|
||||
-- Brief aside: **What is LSP?**
|
||||
--
|
||||
-- LSP is an initialism you've probably heard, but might not understand what it is.
|
||||
--
|
||||
-- LSP stands for Language Server Protocol. It's a protocol that helps editors
|
||||
-- and language tooling communicate in a standardized fashion.
|
||||
--
|
||||
-- In general, you have a "server" which is some tool built to understand a particular
|
||||
-- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers
|
||||
-- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone
|
||||
-- processes that communicate with some "client" - in this case, Neovim!
|
||||
--
|
||||
-- LSP provides Neovim with features like:
|
||||
-- - Go to definition
|
||||
-- - Find references
|
||||
-- - Autocompletion
|
||||
-- - Symbol Search
|
||||
-- - and more!
|
||||
--
|
||||
-- Thus, Language Servers are external tools that must be installed separately from
|
||||
-- Neovim. This is where `mason` and related plugins come into play.
|
||||
--
|
||||
-- If you're wondering about lsp vs treesitter, you can check out the wonderfully
|
||||
-- and elegantly composed help section, `:help lsp-vs-treesitter`
|
||||
|
||||
-- This function gets run when an LSP attaches to a particular buffer.
|
||||
-- That is to say, every time a new file is opened that is associated with
|
||||
-- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this
|
||||
-- function will be executed to configure the current buffer
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
group = vim.api.nvim_create_augroup("kickstart-lsp-attach", { clear = true }),
|
||||
callback = function(event)
|
||||
-- NOTE: Remember that Lua is a real programming language, and as such it is possible
|
||||
-- to define small helper and utility functions so you don't have to repeat yourself.
|
||||
--
|
||||
-- In this case, we create a function that lets us more easily define mappings specific
|
||||
-- for LSP related items. It sets the mode, buffer and description for us each time.
|
||||
local map = function(keys, func, desc, mode)
|
||||
mode = mode or "n"
|
||||
vim.keymap.set(mode, keys, func, { buffer = event.buf, desc = "LSP: " .. desc })
|
||||
end
|
||||
|
||||
-- Rename the variable under your cursor.
|
||||
-- Most Language Servers support renaming across files, etc.
|
||||
map("grn", vim.lsp.buf.rename, "[R]e[n]ame")
|
||||
|
||||
-- Execute a code action, usually your cursor needs to be on top of an error
|
||||
-- or a suggestion from your LSP for this to activate.
|
||||
map("gra", vim.lsp.buf.code_action, "[G]oto Code [A]ction", { "n", "x" })
|
||||
|
||||
-- WARN: This is not Goto Definition, this is Goto Declaration.
|
||||
-- For example, in C this would take you to the header.
|
||||
map("grD", vim.lsp.buf.declaration, "[G]oto [D]eclaration")
|
||||
|
||||
-- The following two autocommands are used to highlight references of the
|
||||
-- word under your cursor when your cursor rests there for a little while.
|
||||
-- See `:help CursorHold` for information about when this is executed
|
||||
--
|
||||
-- When you move your cursor, the highlights will be cleared (the second autocommand).
|
||||
local client = vim.lsp.get_client_by_id(event.data.client_id)
|
||||
if client and client:supports_method("textDocument/documentHighlight", event.buf) then
|
||||
local highlight_augroup =
|
||||
vim.api.nvim_create_augroup("kickstart-lsp-highlight", { clear = false })
|
||||
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
|
||||
buffer = event.buf,
|
||||
group = highlight_augroup,
|
||||
callback = vim.lsp.buf.document_highlight,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
|
||||
buffer = event.buf,
|
||||
group = highlight_augroup,
|
||||
callback = vim.lsp.buf.clear_references,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("LspDetach", {
|
||||
group = vim.api.nvim_create_augroup("kickstart-lsp-detach", { clear = true }),
|
||||
callback = function(event2)
|
||||
vim.lsp.buf.clear_references()
|
||||
vim.api.nvim_clear_autocmds({ group = "kickstart-lsp-highlight", buffer = event2.buf })
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
-- The following code creates a keymap to toggle inlay hints in your
|
||||
-- code, if the language server you are using supports them
|
||||
--
|
||||
-- This may be unwanted, since they displace some of your code
|
||||
if client and client:supports_method("textDocument/inlayHint", event.buf) then
|
||||
map("<leader>th", function()
|
||||
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = event.buf }))
|
||||
end, "[T]oggle Inlay [H]ints")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Enable the following language servers
|
||||
-- Feel free to add/remove any LSPs that you want here. They will automatically be installed.
|
||||
-- See `:help lsp-config` for information about keys and how to configure
|
||||
---@type table<string, vim.lsp.Config>
|
||||
local servers = {
|
||||
-- clangd = {},
|
||||
-- gopls = {},
|
||||
-- pyright = {},
|
||||
-- rust_analyzer = {},
|
||||
texlab = {},
|
||||
kotlin_lsp = {},
|
||||
-- Some languages (like typescript) have entire language plugins that can be useful:
|
||||
-- https://github.com/pmizio/typescript-tools.nvim
|
||||
--
|
||||
-- But for many setups, the LSP (`ts_ls`) will work just fine
|
||||
-- ts_ls = {},
|
||||
|
||||
stylua = {}, -- Used to format Lua code
|
||||
|
||||
-- Special Lua Config, as recommended by neovim help docs
|
||||
lua_ls = {
|
||||
on_init = function(client)
|
||||
client.server_capabilities.documentFormattingProvider = false -- Disable formatting (formatting is done by stylua)
|
||||
|
||||
if client.workspace_folders then
|
||||
local path = client.workspace_folders[1].name
|
||||
if
|
||||
path ~= vim.fn.stdpath("config")
|
||||
and (vim.uv.fs_stat(path .. "/.luarc.json") or vim.uv.fs_stat(path .. "/.luarc.jsonc"))
|
||||
then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
client.config.settings.Lua = vim.tbl_deep_extend("force", client.config.settings.Lua, {
|
||||
runtime = {
|
||||
version = "LuaJIT",
|
||||
path = { "lua/?.lua", "lua/?/init.lua" },
|
||||
},
|
||||
workspace = {
|
||||
checkThirdParty = false,
|
||||
-- NOTE: this is a lot slower and will cause issues when working on your own configuration.
|
||||
-- See https://github.com/neovim/nvim-lspconfig/issues/3189
|
||||
library = vim.tbl_extend("force", vim.api.nvim_get_runtime_file("", true), {
|
||||
"${3rd}/luv/library",
|
||||
"${3rd}/busted/library",
|
||||
}),
|
||||
},
|
||||
})
|
||||
end,
|
||||
---@type lspconfig.settings.lua_ls
|
||||
settings = {
|
||||
Lua = {
|
||||
format = { enable = false }, -- Disable formatting (formatting is done by stylua)
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Ensure the servers and tools above are installed
|
||||
--
|
||||
-- To check the current status of installed tools and/or manually install
|
||||
-- other tools, you can run
|
||||
-- :Mason
|
||||
--
|
||||
-- You can press `g?` for help in this menu.
|
||||
local ensure_installed = vim.tbl_keys(servers or {})
|
||||
vim.list_extend(ensure_installed, {
|
||||
-- You can add other tools here that you want Mason to install
|
||||
})
|
||||
|
||||
require("mason-tool-installer").setup({ ensure_installed = ensure_installed })
|
||||
|
||||
for name, server in pairs(servers) do
|
||||
vim.lsp.config(name, server)
|
||||
vim.lsp.enable(name)
|
||||
end
|
||||
end,
|
||||
},
|
||||
|
||||
{ -- Autoformat
|
||||
"stevearc/conform.nvim",
|
||||
event = { "BufWritePre" },
|
||||
cmd = { "ConformInfo" },
|
||||
keys = {
|
||||
{
|
||||
"<leader>f",
|
||||
function()
|
||||
require("conform").format({ async = true })
|
||||
end,
|
||||
mode = "",
|
||||
desc = "[F]ormat buffer",
|
||||
},
|
||||
},
|
||||
---@module 'conform'
|
||||
---@type conform.setupOpts
|
||||
opts = {
|
||||
notify_on_error = false,
|
||||
format_on_save = function(bufnr)
|
||||
-- You can specify filetypes to autoformat on save here:
|
||||
local enabled_filetypes = {
|
||||
-- lua = true,
|
||||
-- python = true,
|
||||
}
|
||||
if enabled_filetypes[vim.bo[bufnr].filetype] then
|
||||
return { timeout_ms = 500 }
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
default_format_opts = {
|
||||
lsp_format = "fallback", -- Use external formatters if configured below, otherwise use LSP formatting. Set to `false` to disable LSP formatting entirely.
|
||||
},
|
||||
-- You can also specify external formatters in here.
|
||||
formatters_by_ft = {
|
||||
-- rust = { 'rustfmt' },
|
||||
-- Conform can also run multiple formatters sequentially
|
||||
-- python = { "isort", "black" },
|
||||
--
|
||||
-- You can use 'stop_after_first' to run the first available formatter from the list
|
||||
-- javascript = { "prettierd", "prettier", stop_after_first = true },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{ -- Autocompletion
|
||||
"saghen/blink.cmp",
|
||||
event = "VimEnter",
|
||||
version = "1.*",
|
||||
dependencies = {
|
||||
-- Snippet Engine
|
||||
{
|
||||
"L3MON4D3/LuaSnip",
|
||||
version = "2.*",
|
||||
build = (function()
|
||||
-- Build Step is needed for regex support in snippets.
|
||||
-- This step is not supported in many windows environments.
|
||||
-- Remove the below condition to re-enable on windows.
|
||||
if vim.fn.has("win32") == 1 or vim.fn.executable("make") == 0 then
|
||||
return
|
||||
end
|
||||
return "make install_jsregexp"
|
||||
end)(),
|
||||
dependencies = {
|
||||
-- `friendly-snippets` contains a variety of premade snippets.
|
||||
-- See the README about individual language/framework/plugin snippets:
|
||||
-- https://github.com/rafamadriz/friendly-snippets
|
||||
-- {
|
||||
-- 'rafamadriz/friendly-snippets',
|
||||
-- config = function()
|
||||
-- require('luasnip.loaders.from_vscode').lazy_load()
|
||||
-- end,
|
||||
-- },
|
||||
},
|
||||
opts = {},
|
||||
},
|
||||
},
|
||||
---@module 'blink.cmp'
|
||||
---@type blink.cmp.Config
|
||||
opts = {
|
||||
keymap = {
|
||||
-- 'default' (recommended) for mappings similar to built-in completions
|
||||
-- <c-y> to accept ([y]es) the completion.
|
||||
-- This will auto-import if your LSP supports it.
|
||||
-- This will expand snippets if the LSP sent a snippet.
|
||||
-- 'super-tab' for tab to accept
|
||||
-- 'enter' for enter to accept
|
||||
-- 'none' for no mappings
|
||||
--
|
||||
-- For an understanding of why the 'default' preset is recommended,
|
||||
-- you will need to read `:help ins-completion`
|
||||
--
|
||||
-- No, but seriously. Please read `:help ins-completion`, it is really good!
|
||||
--
|
||||
-- All presets have the following mappings:
|
||||
-- <tab>/<s-tab>: move to right/left of your snippet expansion
|
||||
-- <c-space>: Open menu or open docs if already open
|
||||
-- <c-n>/<c-p> or <up>/<down>: Select next/previous item
|
||||
-- <c-e>: Hide menu
|
||||
-- <c-k>: Toggle signature help
|
||||
--
|
||||
-- See :h blink-cmp-config-keymap for defining your own keymap
|
||||
preset = "default",
|
||||
|
||||
-- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
|
||||
-- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
|
||||
},
|
||||
|
||||
appearance = {
|
||||
-- 'mono' (default) for 'Nerd Font Mono' or 'normal' for 'Nerd Font'
|
||||
-- Adjusts spacing to ensure icons are aligned
|
||||
nerd_font_variant = "mono",
|
||||
},
|
||||
|
||||
completion = {
|
||||
-- By default, you may press `<c-space>` to show the documentation.
|
||||
-- Optionally, set `auto_show = true` to show the documentation after a delay.
|
||||
documentation = { auto_show = false, auto_show_delay_ms = 500 },
|
||||
},
|
||||
|
||||
sources = {
|
||||
default = { "lsp", "path", "snippets" },
|
||||
},
|
||||
|
||||
snippets = { preset = "luasnip" },
|
||||
|
||||
-- Blink.cmp includes an optional, recommended rust fuzzy matcher,
|
||||
-- which automatically downloads a prebuilt binary when enabled.
|
||||
--
|
||||
-- By default, we use the Lua implementation instead, but you may enable
|
||||
-- the rust implementation via `'prefer_rust_with_warning'`
|
||||
--
|
||||
-- See :h blink-cmp-config-fuzzy for more information
|
||||
fuzzy = { implementation = "lua" },
|
||||
|
||||
-- Shows a signature help window while you type arguments for a function
|
||||
signature = { enabled = true },
|
||||
},
|
||||
},
|
||||
|
||||
{ -- You can easily change to a different colorscheme.
|
||||
-- Change the name of the colorscheme plugin below, and then
|
||||
-- change the command in the config to whatever the name of that colorscheme is.
|
||||
--
|
||||
-- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`.
|
||||
"folke/tokyonight.nvim",
|
||||
priority = 1000, -- Make sure to load this before all the other start plugins.
|
||||
config = function()
|
||||
---@diagnostic disable-next-line: missing-fields
|
||||
require("tokyonight").setup({
|
||||
styles = {
|
||||
comments = { italic = false }, -- Disable italics in comments
|
||||
},
|
||||
})
|
||||
|
||||
-- Load the colorscheme here.
|
||||
-- Like many other themes, this one has different styles, and you could load
|
||||
-- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'.
|
||||
-- vim.cmd.colorscheme("tokyonight-night")
|
||||
end,
|
||||
},
|
||||
require("themes.Serpensortia").setup({}),
|
||||
|
||||
|
||||
-- Highlight todo, notes, etc in comments
|
||||
{
|
||||
"folke/todo-comments.nvim",
|
||||
event = "VimEnter",
|
||||
dependencies = { "nvim-lua/plenary.nvim" },
|
||||
---@module 'todo-comments'
|
||||
---@type TodoOptions
|
||||
---@diagnostic disable-next-line: missing-fields
|
||||
opts = { signs = false },
|
||||
},
|
||||
|
||||
{ -- Collection of various small independent plugins/modules
|
||||
"nvim-mini/mini.nvim",
|
||||
config = function()
|
||||
-- Better Around/Inside textobjects
|
||||
--
|
||||
-- Examples:
|
||||
-- - va) - [V]isually select [A]round [)]paren
|
||||
-- - yiiq - [Y]ank [I]nside [I]+1 [Q]uote
|
||||
-- - ci' - [C]hange [I]nside [']quote
|
||||
require("mini.ai").setup({
|
||||
-- NOTE: Avoid conflicts with the built-in incremental selection mappings on Neovim>=0.12 (see `:help treesitter-incremental-selection`)
|
||||
mappings = {
|
||||
around_next = "aa",
|
||||
inside_next = "ii",
|
||||
},
|
||||
n_lines = 500,
|
||||
})
|
||||
|
||||
-- Add/delete/replace surroundings (brackets, quotes, etc.)
|
||||
--
|
||||
-- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren
|
||||
-- - sd' - [S]urround [D]elete [']quotes
|
||||
-- - sr)' - [S]urround [R]eplace [)] [']
|
||||
require("mini.surround").setup()
|
||||
|
||||
-- Simple and easy statusline.
|
||||
-- You could remove this setup call if you don't like it,
|
||||
-- and try some other statusline plugin
|
||||
local statusline = require("mini.statusline")
|
||||
-- set use_icons to true if you have a Nerd Font
|
||||
statusline.setup({ use_icons = vim.g.have_nerd_font })
|
||||
|
||||
-- You can configure sections in the statusline by overriding their
|
||||
-- default behavior. For example, here we set the section for
|
||||
-- cursor location to LINE:COLUMN
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
statusline.section_location = function()
|
||||
return "%2l:%-2v"
|
||||
end
|
||||
|
||||
-- ... and there is more!
|
||||
-- Check out: https://github.com/nvim-mini/mini.nvim
|
||||
end,
|
||||
},
|
||||
|
||||
{ -- Highlight, edit, and navigate code
|
||||
"nvim-treesitter/nvim-treesitter",
|
||||
lazy = false,
|
||||
build = ":TSUpdate",
|
||||
branch = "main",
|
||||
-- [[ Configure Treesitter ]] See `:help nvim-treesitter-intro`
|
||||
config = function()
|
||||
-- ensure basic parser are installed
|
||||
local parsers = {
|
||||
"bash",
|
||||
"c",
|
||||
"diff",
|
||||
"html",
|
||||
"lua",
|
||||
"luadoc",
|
||||
"markdown",
|
||||
"markdown_inline",
|
||||
"query",
|
||||
"vim",
|
||||
"vimdoc",
|
||||
}
|
||||
require("nvim-treesitter").install(parsers)
|
||||
|
||||
---@param buf integer
|
||||
---@param language string
|
||||
local function treesitter_try_attach(buf, language)
|
||||
-- check if parser exists and load it
|
||||
if not vim.treesitter.language.add(language) then
|
||||
return
|
||||
end
|
||||
-- enables syntax highlighting and other treesitter features
|
||||
vim.treesitter.start(buf, language)
|
||||
|
||||
-- enables treesitter based folds
|
||||
-- for more info on folds see `:help folds`
|
||||
-- vim.wo.foldexpr = 'v:lua.vim.treesitter.foldexpr()'
|
||||
-- vim.wo.foldmethod = 'expr'
|
||||
|
||||
-- check if treesitter indentation is available for this language, and if so enable it
|
||||
-- in case there is no indent query, the indentexpr will fallback to the vim's built in one
|
||||
local has_indent_query = vim.treesitter.query.get(language, "indents") ~= nil
|
||||
|
||||
-- enables treesitter based indentation
|
||||
if has_indent_query then
|
||||
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
|
||||
end
|
||||
end
|
||||
|
||||
local available_parsers = require("nvim-treesitter").get_available()
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
callback = function(args)
|
||||
local buf, filetype = args.buf, args.match
|
||||
|
||||
local language = vim.treesitter.language.get_lang(filetype)
|
||||
if not language then
|
||||
return
|
||||
end
|
||||
|
||||
local installed_parsers = require("nvim-treesitter").get_installed("parsers")
|
||||
|
||||
if vim.tbl_contains(installed_parsers, language) then
|
||||
-- enable the parser if it is installed
|
||||
treesitter_try_attach(buf, language)
|
||||
elseif vim.tbl_contains(available_parsers, language) then
|
||||
-- if a parser is available in `nvim-treesitter` auto install it, and enable it after the installation is done
|
||||
require("nvim-treesitter").install(language):await(function()
|
||||
treesitter_try_attach(buf, language)
|
||||
end)
|
||||
else
|
||||
-- try to enable treesitter features in case the parser exists but is not available from `nvim-treesitter`
|
||||
treesitter_try_attach(buf, language)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end,
|
||||
},
|
||||
{
|
||||
"Goshujinsama/nvim-strudel",
|
||||
ft = "strudel",
|
||||
build = "cd server && npm install && npm run build",
|
||||
keys = {
|
||||
{ "<C-CR>", "<cmd>StrudelEval<cr>", ft = "strudel", desc = "Strudel: Eval" },
|
||||
{ "<leader>ss", "<cmd>StrudelStop<cr>", ft = "strudel", desc = "Strudel: Stop" },
|
||||
},
|
||||
config = function()
|
||||
require("strudel").setup()
|
||||
end,
|
||||
},
|
||||
|
||||
-- The following comments only work if you have downloaded the kickstart repo, not just copy pasted the
|
||||
-- init.lua. If you want these files, they are in the repository, so you can just download them and
|
||||
-- place them in the correct locations.
|
||||
|
||||
-- NOTE: Next step on your Neovim journey: Add/Configure additional plugins for Kickstart
|
||||
--
|
||||
-- Here are some example plugins that I've included in the Kickstart repository.
|
||||
-- Uncomment any of the lines below to enable them (you will need to restart nvim).
|
||||
--
|
||||
-- require 'kickstart.plugins.debug',
|
||||
-- require 'kickstart.plugins.indent_line',
|
||||
-- require 'kickstart.plugins.lint',
|
||||
-- require 'kickstart.plugins.autopairs',
|
||||
-- require 'kickstart.plugins.neo-tree',
|
||||
-- require 'kickstart.plugins.gitsigns', -- adds gitsigns recommended keymaps
|
||||
|
||||
-- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua`
|
||||
-- This is the easiest way to modularize your config.
|
||||
--
|
||||
-- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going.
|
||||
-- { import = 'custom.plugins' },
|
||||
--
|
||||
-- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec`
|
||||
-- Or use telescope!
|
||||
-- In normal mode type `<space>sh` then write `lazy.nvim-plugin`
|
||||
-- you can continue same window with `<space>sr` which resumes last telescope search
|
||||
}, { ---@diagnostic disable-line: missing-fields
|
||||
ui = {
|
||||
-- If you are using a Nerd Font: set icons to an empty table which will use the
|
||||
-- default lazy.nvim defined Nerd Font icons, otherwise define a unicode icons table
|
||||
icons = vim.g.have_nerd_font and {} or {
|
||||
cmd = "⌘",
|
||||
config = "🛠",
|
||||
event = "📅",
|
||||
ft = "📂",
|
||||
init = "⚙",
|
||||
keys = "🗝",
|
||||
plugin = "🔌",
|
||||
runtime = "💻",
|
||||
require = "🌙",
|
||||
source = "📄",
|
||||
start = "🚀",
|
||||
task = "📌",
|
||||
lazy = "💤 ",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- The line beneath this is called `modeline`. See `:help modeline`
|
||||
-- vim: ts=2 sts=2 sw=2 et
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"LuaSnip": { "branch": "master", "commit": "642b0c595e11608b4c18219e93b88d7637af27bc" },
|
||||
"blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" },
|
||||
"conform.nvim": { "branch": "master", "commit": "18aeab3d63d350dcf44d64c462cc489a3412af40" },
|
||||
"darcula-dark.nvim": { "branch": "main", "commit": "285c1fe3225ef19ef2639a3080551ee9669f263b" },
|
||||
"fidget.nvim": { "branch": "main", "commit": "889e2e96edef4e144965571d46f7a77bcc4d0ddf" },
|
||||
"gitsigns.nvim": { "branch": "main", "commit": "dd3f588bacbeb041be6facf1742e42097f62165d" },
|
||||
"guess-indent.nvim": { "branch": "main", "commit": "84a4987ff36798c2fc1169cbaff67960aed9776f" },
|
||||
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
||||
"mason-lspconfig.nvim": { "branch": "main", "commit": "7b01e2974a47d489bb92f47a41e4c0088ea8f86e" },
|
||||
"mason-tool-installer.nvim": { "branch": "main", "commit": "443f1ef8b5e6bf47045cb2217b6f748a223cf7dc" },
|
||||
"mason.nvim": { "branch": "main", "commit": "8e921c2b68571e978db5d4d3fef9c9a7f8755473" },
|
||||
"mini.nvim": { "branch": "main", "commit": "6a8aab4b07c6caa1d0643c1c9dccd5b2d5f5e094" },
|
||||
"nvim-lspconfig": { "branch": "master", "commit": "3de240997fc3208eb29df5e5c17ba4665961bd84" },
|
||||
"nvim-strudel": { "branch": "main", "commit": "0be8675ab8c8fc12df32ac9f9b8d75029ddf2a00" },
|
||||
"nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
|
||||
"nvim-web-devicons": { "branch": "master", "commit": "7d8dad2c837fcdf2e65997e68657c1a21c568074" },
|
||||
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
|
||||
"telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" },
|
||||
"telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
|
||||
"telescope.nvim": { "branch": "master", "commit": "7d324792b7943e4aa16ad007212e6acc6f9fe335" },
|
||||
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
|
||||
"tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" },
|
||||
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
---@diagnostic disable: undefined-global
|
||||
local M = {}
|
||||
|
||||
function M.setup()
|
||||
vim.cmd("highlight clear")
|
||||
if vim.fn.exists("syntax_on") == 1 then
|
||||
vim.cmd("syntax reset")
|
||||
end
|
||||
|
||||
vim.o.termguicolors = true
|
||||
vim.g.colors_name = "Serpensortia"
|
||||
|
||||
local c = {
|
||||
bg = "#080c08",
|
||||
surface = "#131d13",
|
||||
surface2 = "#424a42",
|
||||
fg = "#c0c0c0",
|
||||
muted = "#424a42",
|
||||
border = "#0b110b",
|
||||
accent = "#1c7a44",
|
||||
warn = "#dc143c",
|
||||
|
||||
-- richer editor palette inspired by Islands Dark / Darcula-like schemes
|
||||
green = "#1c7a44",
|
||||
red = "#dc143c",
|
||||
blue = "#6ca0ff",
|
||||
cyan = "#67c7ff",
|
||||
yellow = "#d9c36a",
|
||||
orange = "#d78a4a",
|
||||
purple = "#b48ef7",
|
||||
teal = "#4db6ac",
|
||||
|
||||
subtle = "#989898",
|
||||
comment = "#424a42",
|
||||
add = "#0c2415",
|
||||
change = "#292c29",
|
||||
delete = "#320e12",
|
||||
}
|
||||
|
||||
local function hi(group, opts)
|
||||
vim.api.nvim_set_hl(0, group, opts)
|
||||
end
|
||||
|
||||
-- Base UI
|
||||
hi("Normal", { fg = c.fg, bg = c.bg })
|
||||
hi("NormalNC", { fg = c.fg, bg = c.bg })
|
||||
hi("NormalFloat", { fg = c.fg, bg = c.surface })
|
||||
hi("FloatBorder", { fg = c.border, bg = c.surface })
|
||||
hi("FloatTitle", { fg = c.green, bg = c.surface, bold = true })
|
||||
hi("CursorLine", { bg = c.surface })
|
||||
hi("CursorColumn", { bg = c.surface })
|
||||
hi("ColorColumn", { bg = c.surface })
|
||||
hi("Conceal", { fg = c.muted })
|
||||
hi("LineNr", { fg = c.muted, bg = c.bg })
|
||||
hi("CursorLineNr", { fg = c.green, bg = c.bg, bold = true })
|
||||
hi("SignColumn", { fg = c.fg, bg = c.bg })
|
||||
hi("EndOfBuffer", { fg = c.bg, bg = c.bg })
|
||||
hi("VertSplit", { fg = c.border, bg = c.bg })
|
||||
hi("WinSeparator", { fg = c.border, bg = c.bg })
|
||||
hi("Folded", { fg = c.muted, bg = c.surface })
|
||||
hi("FoldColumn", { fg = c.muted, bg = c.bg })
|
||||
hi("MatchParen", { fg = c.yellow, bg = c.surface2, bold = true })
|
||||
hi("Whitespace", { fg = c.border })
|
||||
hi("NonText", { fg = c.border })
|
||||
|
||||
-- Selection / search
|
||||
hi("Visual", { bg = c.surface2 })
|
||||
hi("VisualNOS", { bg = c.surface2 })
|
||||
hi("Search", { fg = c.bg, bg = c.yellow, bold = true })
|
||||
hi("IncSearch", { fg = c.bg, bg = c.orange, bold = true })
|
||||
hi("CurSearch", { fg = c.bg, bg = c.orange, bold = true })
|
||||
hi("Substitute", { fg = c.bg, bg = c.green, bold = true })
|
||||
|
||||
-- Popup menu
|
||||
hi("Pmenu", { fg = c.fg, bg = c.surface })
|
||||
hi("PmenuSel", { fg = c.bg, bg = c.green, bold = true })
|
||||
hi("PmenuKind", { fg = c.cyan, bg = c.surface })
|
||||
hi("PmenuKindSel", { fg = c.bg, bg = c.green, bold = true })
|
||||
hi("PmenuExtra", { fg = c.muted, bg = c.surface })
|
||||
hi("PmenuExtraSel", { fg = c.bg, bg = c.green })
|
||||
hi("PmenuSbar", { bg = c.surface2 })
|
||||
hi("PmenuThumb", { bg = c.border })
|
||||
|
||||
-- Tabs / status
|
||||
hi("StatusLine", { fg = c.fg, bg = c.surface })
|
||||
hi("StatusLineNC", { fg = c.muted, bg = c.surface })
|
||||
hi("TabLine", { fg = c.muted, bg = c.surface })
|
||||
hi("TabLineSel", { fg = c.fg, bg = c.bg, bold = true })
|
||||
hi("TabLineFill", { bg = c.surface })
|
||||
hi("WinBar", { fg = c.fg, bg = c.bg })
|
||||
hi("WinBarNC", { fg = c.muted, bg = c.bg })
|
||||
|
||||
-- Syntax
|
||||
hi("Comment", { fg = c.comment, italic = true })
|
||||
hi("Constant", { fg = c.yellow, bold = true })
|
||||
hi("String", { fg = c.orange })
|
||||
hi("Character", { fg = c.orange })
|
||||
hi("Number", { fg = c.yellow, bold = true })
|
||||
hi("Boolean", { fg = c.purple, bold = true })
|
||||
hi("Float", { fg = c.yellow })
|
||||
hi("Identifier", { fg = c.fg })
|
||||
hi("Function", { fg = c.green, bold = true })
|
||||
hi("Statement", { fg = c.purple, bold = true })
|
||||
hi("Conditional", { fg = c.purple, bold = true })
|
||||
hi("Repeat", { fg = c.purple, bold = true })
|
||||
hi("Label", { fg = c.orange })
|
||||
hi("Operator", { fg = c.subtle })
|
||||
hi("Keyword", { fg = c.purple, italic = true, bold = true })
|
||||
hi("Exception", { fg = c.red, bold = true })
|
||||
hi("PreProc", { fg = c.blue })
|
||||
hi("Include", { fg = c.blue, italic = true })
|
||||
hi("Define", { fg = c.purple })
|
||||
hi("Macro", { fg = c.purple, bold = true })
|
||||
hi("PreCondit", { fg = c.blue })
|
||||
hi("Type", { fg = c.cyan, bold = true })
|
||||
hi("Typedef", { fg = c.cyan, bold = true })
|
||||
hi("StorageClass", { fg = c.blue, italic = true })
|
||||
hi("Structure", { fg = c.cyan, bold = true })
|
||||
hi("Special", { fg = c.teal })
|
||||
hi("SpecialChar", { fg = c.orange })
|
||||
hi("Tag", { fg = c.green })
|
||||
hi("Delimiter", { fg = c.subtle })
|
||||
hi("SpecialComment", { fg = c.comment, italic = true })
|
||||
hi("Debug", { fg = c.red, bold = true })
|
||||
hi("Title", { fg = c.green, bold = true })
|
||||
hi("Todo", { fg = c.bg, bg = c.yellow, bold = true })
|
||||
|
||||
-- Diagnostics
|
||||
hi("DiagnosticError", { fg = c.red })
|
||||
hi("DiagnosticWarn", { fg = c.orange })
|
||||
hi("DiagnosticInfo", { fg = c.blue })
|
||||
hi("DiagnosticHint", { fg = c.teal })
|
||||
hi("DiagnosticOk", { fg = c.green })
|
||||
|
||||
hi("DiagnosticVirtualTextError", { fg = c.red, bg = c.delete })
|
||||
hi("DiagnosticVirtualTextWarn", { fg = c.orange, bg = c.surface })
|
||||
hi("DiagnosticVirtualTextInfo", { fg = c.blue, bg = c.surface })
|
||||
hi("DiagnosticVirtualTextHint", { fg = c.teal, bg = c.surface })
|
||||
|
||||
hi("DiagnosticUnderlineError", { undercurl = true, sp = c.red })
|
||||
hi("DiagnosticUnderlineWarn", { undercurl = true, sp = c.orange })
|
||||
hi("DiagnosticUnderlineInfo", { undercurl = true, sp = c.blue })
|
||||
hi("DiagnosticUnderlineHint", { undercurl = true, sp = c.teal })
|
||||
|
||||
hi("DiagnosticSignError", { fg = c.red, bg = c.bg })
|
||||
hi("DiagnosticSignWarn", { fg = c.orange, bg = c.bg })
|
||||
hi("DiagnosticSignInfo", { fg = c.blue, bg = c.bg })
|
||||
hi("DiagnosticSignHint", { fg = c.teal, bg = c.bg })
|
||||
|
||||
-- LSP references / semantic-ish
|
||||
hi("LspReferenceText", { bg = c.surface2 })
|
||||
hi("LspReferenceRead", { bg = c.surface2 })
|
||||
hi("LspReferenceWrite", { bg = c.surface2, bold = true })
|
||||
hi("LspInlayHint", { fg = c.muted, bg = c.surface, italic = true })
|
||||
hi("LspCodeLens", { fg = c.muted, italic = true })
|
||||
hi("LspCodeLensSeparator", { fg = c.border })
|
||||
|
||||
-- Diff / Git
|
||||
hi("DiffAdd", { bg = c.add, fg = c.green })
|
||||
hi("DiffChange", { bg = c.change, fg = c.blue })
|
||||
hi("DiffDelete", { bg = c.delete, fg = c.red })
|
||||
hi("DiffText", { bg = c.blue, fg = c.bg, bold = true })
|
||||
|
||||
hi("Added", { fg = c.green })
|
||||
hi("Changed", { fg = c.blue })
|
||||
hi("Removed", { fg = c.red })
|
||||
|
||||
hi("GitSignsAdd", { fg = c.green, bg = c.bg })
|
||||
hi("GitSignsChange", { fg = c.blue, bg = c.bg })
|
||||
hi("GitSignsDelete", { fg = c.red, bg = c.bg })
|
||||
hi("GitSignsCurrentLineBlame", { fg = c.muted, italic = true })
|
||||
|
||||
-- Treesitter
|
||||
hi("@comment", { link = "Comment" })
|
||||
hi("@comment.documentation", { fg = c.comment, italic = true })
|
||||
|
||||
hi("@string", { link = "String" })
|
||||
hi("@string.escape", { fg = c.yellow, bold = true })
|
||||
hi("@string.regex", { fg = c.orange })
|
||||
hi("@string.special", { fg = c.orange })
|
||||
|
||||
hi("@character", { link = "Character" })
|
||||
hi("@character.special", { fg = c.orange })
|
||||
|
||||
hi("@number", { link = "Number" })
|
||||
hi("@number.float", { link = "Float" })
|
||||
hi("@boolean", { link = "Boolean" })
|
||||
hi("@constant", { link = "Constant" })
|
||||
hi("@constant.builtin", { fg = c.yellow, italic = true })
|
||||
hi("@constant.macro", { fg = c.purple, bold = true })
|
||||
|
||||
hi("@variable", { fg = c.fg })
|
||||
hi("@variable.builtin", { fg = c.red, italic = true })
|
||||
hi("@variable.parameter", { fg = c.fg, italic = true })
|
||||
hi("@variable.member", { fg = c.cyan })
|
||||
|
||||
hi("@module", { fg = c.blue })
|
||||
hi("@module.builtin", { fg = c.blue, italic = true })
|
||||
hi("@label", { fg = c.orange })
|
||||
|
||||
hi("@function", { link = "Function" })
|
||||
hi("@function.builtin", { fg = c.blue, italic = true, bold = true })
|
||||
hi("@function.call", { fg = c.green })
|
||||
hi("@function.macro", { fg = c.purple, bold = true })
|
||||
hi("@method", { fg = c.green })
|
||||
hi("@method.call", { fg = c.green })
|
||||
|
||||
hi("@constructor", { fg = c.cyan, bold = true })
|
||||
hi("@operator", { link = "Operator" })
|
||||
|
||||
hi("@keyword", { link = "Keyword" })
|
||||
hi("@keyword.function", { fg = c.purple, bold = true })
|
||||
hi("@keyword.operator", { fg = c.purple, italic = true })
|
||||
hi("@keyword.return", { fg = c.purple, bold = true, italic = true })
|
||||
hi("@keyword.import", { fg = c.blue, italic = true })
|
||||
hi("@keyword.conditional", { fg = c.purple, bold = true })
|
||||
hi("@keyword.repeat", { fg = c.purple, bold = true })
|
||||
hi("@keyword.exception", { fg = c.red, bold = true })
|
||||
|
||||
hi("@type", { link = "Type" })
|
||||
hi("@type.builtin", { fg = c.blue, italic = true, bold = true })
|
||||
hi("@type.definition", { fg = c.cyan, bold = true })
|
||||
hi("@attribute", { fg = c.yellow })
|
||||
hi("@property", { fg = c.cyan })
|
||||
hi("@field", { fg = c.cyan })
|
||||
hi("@parameter", { fg = c.fg, italic = true })
|
||||
|
||||
hi("@punctuation.delimiter", { fg = c.subtle })
|
||||
hi("@punctuation.bracket", { fg = c.subtle })
|
||||
hi("@punctuation.special", { fg = c.orange })
|
||||
|
||||
hi("@tag", { fg = c.green, bold = true })
|
||||
hi("@tag.attribute", { fg = c.yellow })
|
||||
hi("@tag.delimiter", { fg = c.subtle })
|
||||
|
||||
-- Telescope
|
||||
hi("TelescopeNormal", { fg = c.fg, bg = c.surface })
|
||||
hi("TelescopeBorder", { fg = c.border, bg = c.surface })
|
||||
hi("TelescopeTitle", { fg = c.green, bg = c.surface, bold = true })
|
||||
hi("TelescopePromptNormal", { fg = c.fg, bg = c.surface })
|
||||
hi("TelescopePromptBorder", { fg = c.border, bg = c.surface })
|
||||
hi("TelescopePromptTitle", { fg = c.bg, bg = c.green, bold = true })
|
||||
hi("TelescopePromptPrefix", { fg = c.green, bg = c.surface })
|
||||
hi("TelescopeResultsNormal", { fg = c.fg, bg = c.surface })
|
||||
hi("TelescopeResultsBorder", { fg = c.border, bg = c.surface })
|
||||
hi("TelescopePreviewNormal", { fg = c.fg, bg = c.surface })
|
||||
hi("TelescopePreviewBorder", { fg = c.border, bg = c.surface })
|
||||
hi("TelescopeSelection", { fg = c.fg, bg = c.surface2 })
|
||||
hi("TelescopeSelectionCaret", { fg = c.green, bg = c.surface2 })
|
||||
hi("TelescopeMatching", { fg = c.yellow, bold = true })
|
||||
|
||||
-- nvim-cmp
|
||||
hi("CmpDocumentation", { fg = c.fg, bg = c.surface })
|
||||
hi("CmpDocumentationBorder", { fg = c.border, bg = c.surface })
|
||||
hi("CmpItemAbbr", { fg = c.fg })
|
||||
hi("CmpItemAbbrMatch", { fg = c.green, bold = true })
|
||||
hi("CmpItemAbbrMatchFuzzy", { fg = c.green, italic = true })
|
||||
hi("CmpItemAbbrDeprecated", { fg = c.muted, strikethrough = true })
|
||||
hi("CmpItemKind", { fg = c.cyan })
|
||||
hi("CmpItemMenu", { fg = c.muted })
|
||||
|
||||
hi("CmpItemKindFunction", { fg = c.green })
|
||||
hi("CmpItemKindMethod", { fg = c.green })
|
||||
hi("CmpItemKindConstructor", { fg = c.cyan })
|
||||
hi("CmpItemKindVariable", { fg = c.fg })
|
||||
hi("CmpItemKindField", { fg = c.cyan })
|
||||
hi("CmpItemKindProperty", { fg = c.cyan })
|
||||
hi("CmpItemKindClass", { fg = c.cyan })
|
||||
hi("CmpItemKindInterface", { fg = c.blue })
|
||||
hi("CmpItemKindStruct", { fg = c.cyan })
|
||||
hi("CmpItemKindModule", { fg = c.blue })
|
||||
hi("CmpItemKindKeyword", { fg = c.purple })
|
||||
hi("CmpItemKindText", { fg = c.fg })
|
||||
hi("CmpItemKindSnippet", { fg = c.orange })
|
||||
hi("CmpItemKindFile", { fg = c.fg })
|
||||
hi("CmpItemKindFolder", { fg = c.green })
|
||||
hi("CmpItemKindEnum", { fg = c.blue })
|
||||
hi("CmpItemKindEnumMember", { fg = c.yellow })
|
||||
hi("CmpItemKindConstant", { fg = c.yellow })
|
||||
hi("CmpItemKindValue", { fg = c.yellow })
|
||||
hi("CmpItemKindUnit", { fg = c.orange })
|
||||
|
||||
-- Neo-tree / NvimTree
|
||||
hi("Directory", { fg = c.green, bold = true })
|
||||
hi("NeoTreeNormal", { fg = c.fg, bg = c.bg })
|
||||
hi("NeoTreeNormalNC", { fg = c.fg, bg = c.bg })
|
||||
hi("NeoTreeDirectoryName", { fg = c.green, bold = true })
|
||||
hi("NeoTreeDirectoryIcon", { fg = c.green })
|
||||
hi("NeoTreeFileName", { fg = c.fg })
|
||||
hi("NeoTreeFileIcon", { fg = c.subtle })
|
||||
hi("NeoTreeIndentMarker", { fg = c.border })
|
||||
hi("NeoTreeRootName", { fg = c.cyan, bold = true })
|
||||
hi("NeoTreeGitAdded", { fg = c.green })
|
||||
hi("NeoTreeGitModified", { fg = c.blue })
|
||||
hi("NeoTreeGitDeleted", { fg = c.red })
|
||||
hi("NeoTreeGitConflict", { fg = c.orange, bold = true })
|
||||
hi("NeoTreeFloatBorder", { fg = c.border, bg = c.surface })
|
||||
hi("NeoTreeFloatTitle", { fg = c.green, bg = c.surface, bold = true })
|
||||
hi("NvimTreeNormal", { fg = c.fg, bg = c.bg })
|
||||
hi("NvimTreeFolderName", { fg = c.green, bold = true })
|
||||
hi("NvimTreeRootFolder", { fg = c.cyan, bold = true })
|
||||
hi("NvimTreeOpenedFolderName", { fg = c.green, bold = true })
|
||||
hi("NvimTreeIndentMarker", { fg = c.border })
|
||||
hi("NvimTreeGitDirty", { fg = c.blue })
|
||||
hi("NvimTreeGitNew", { fg = c.green })
|
||||
hi("NvimTreeGitDeleted", { fg = c.red })
|
||||
|
||||
-- which-key
|
||||
hi("WhichKey", { fg = c.green, bold = true })
|
||||
hi("WhichKeyGroup", { fg = c.cyan })
|
||||
hi("WhichKeyDesc", { fg = c.fg })
|
||||
hi("WhichKeySeparator", { fg = c.border })
|
||||
hi("WhichKeyFloat", { bg = c.surface })
|
||||
hi("WhichKeyBorder", { fg = c.border, bg = c.surface })
|
||||
hi("WhichKeyValue", { fg = c.muted })
|
||||
|
||||
-- Indent guides
|
||||
hi("IblIndent", { fg = c.border })
|
||||
hi("IblScope", { fg = c.blue })
|
||||
hi("IndentBlanklineChar", { fg = c.border })
|
||||
hi("IndentBlanklineContextChar", { fg = c.blue })
|
||||
|
||||
-- lazy.nvim
|
||||
hi("LazyNormal", { fg = c.fg, bg = c.surface })
|
||||
hi("LazyBorder", { fg = c.border, bg = c.surface })
|
||||
hi("LazyButton", { fg = c.fg, bg = c.surface2 })
|
||||
hi("LazyButtonActive", { fg = c.bg, bg = c.green, bold = true })
|
||||
hi("LazyH1", { fg = c.bg, bg = c.green, bold = true })
|
||||
hi("LazySpecial", { fg = c.purple })
|
||||
hi("LazyReasonPlugin", { fg = c.cyan })
|
||||
hi("LazyReasonEvent", { fg = c.yellow })
|
||||
hi("LazyReasonKeys", { fg = c.green })
|
||||
hi("LazyReasonCmd", { fg = c.orange })
|
||||
hi("LazyReasonStart", { fg = c.green })
|
||||
|
||||
-- Markdown / help
|
||||
hi("markdownHeadingDelimiter", { fg = c.green, bold = true })
|
||||
hi("markdownCode", { fg = c.orange })
|
||||
hi("markdownCodeBlock", { fg = c.orange })
|
||||
hi("markdownLinkText", { fg = c.cyan, underline = true })
|
||||
hi("markdownUrl", { fg = c.blue, underline = true })
|
||||
hi("helpCommand", { fg = c.green })
|
||||
hi("helpExample", { fg = c.orange })
|
||||
|
||||
-- Notifications / misc
|
||||
hi("ErrorMsg", { fg = c.red, bold = true })
|
||||
hi("WarningMsg", { fg = c.orange })
|
||||
hi("MoreMsg", { fg = c.green })
|
||||
hi("ModeMsg", { fg = c.cyan, bold = true })
|
||||
hi("Question", { fg = c.green, bold = true })
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,114 @@
|
||||
[General]
|
||||
Name=Arindy
|
||||
|
||||
[Output]
|
||||
Mode=Simple
|
||||
FilenameFormatting=%CCYY-%MM-%DD %hh-%mm-%ss
|
||||
DelayEnable=false
|
||||
DelaySec=20
|
||||
DelayPreserve=true
|
||||
Reconnect=true
|
||||
RetryDelay=2
|
||||
MaxRetries=25
|
||||
BindIP=default
|
||||
IPFamily=IPv4+IPv6
|
||||
NewSocketLoopEnable=false
|
||||
LowLatencyEnable=false
|
||||
|
||||
[Stream1]
|
||||
IgnoreRecommended=false
|
||||
EnableMultitrackVideo=false
|
||||
MultitrackVideoMaximumAggregateBitrateAuto=true
|
||||
MultitrackVideoMaximumVideoTracksAuto=true
|
||||
|
||||
[SimpleOutput]
|
||||
FilePath=/media/edwin/obs
|
||||
RecFormat2=mp4
|
||||
VBitrate=6000
|
||||
ABitrate=160
|
||||
Preset=veryfast
|
||||
NVENCPreset2=p5
|
||||
RecQuality=Stream
|
||||
RecRB=false
|
||||
RecRBTime=20
|
||||
RecRBSize=512
|
||||
RecRBPrefix=Replay
|
||||
StreamAudioEncoder=aac
|
||||
RecAudioEncoder=aac
|
||||
RecTracks=1
|
||||
StreamEncoder=x264
|
||||
RecEncoder=x264
|
||||
UseAdvanced=false
|
||||
FileNameWithoutSpace=true
|
||||
|
||||
[AdvOut]
|
||||
ApplyServiceSettings=true
|
||||
UseRescale=false
|
||||
TrackIndex=1
|
||||
VodTrackIndex=2
|
||||
Encoder=obs_x264
|
||||
RecType=Standard
|
||||
RecFilePath=/home/arindy
|
||||
RecFormat2=hybrid_mp4
|
||||
RecUseRescale=false
|
||||
RecTracks=1
|
||||
RecEncoder=none
|
||||
FLVTrack=1
|
||||
StreamMultiTrackAudioMixes=1
|
||||
FFOutputToFile=true
|
||||
FFFilePath=/home/arindy
|
||||
FFVBitrate=6000
|
||||
FFVGOPSize=250
|
||||
FFUseRescale=false
|
||||
FFIgnoreCompat=false
|
||||
FFABitrate=160
|
||||
FFAudioMixes=1
|
||||
Track1Bitrate=160
|
||||
Track2Bitrate=160
|
||||
Track3Bitrate=160
|
||||
Track4Bitrate=160
|
||||
Track5Bitrate=160
|
||||
Track6Bitrate=160
|
||||
RecSplitFileTime=15
|
||||
RecSplitFileSize=2048
|
||||
RecRB=false
|
||||
RecRBTime=20
|
||||
RecRBSize=512
|
||||
AudioEncoder=libfdk_aac
|
||||
RecAudioEncoder=libfdk_aac
|
||||
RecSplitFileType=Time
|
||||
FFFormat=
|
||||
FFFormatMimeType=
|
||||
FFVEncoderId=0
|
||||
FFVEncoder=
|
||||
FFAEncoderId=0
|
||||
FFAEncoder=
|
||||
FFExtension=mp4
|
||||
|
||||
[Video]
|
||||
BaseCX=1920
|
||||
BaseCY=1080
|
||||
OutputCX=1920
|
||||
OutputCY=1080
|
||||
FPSType=0
|
||||
FPSCommon=60
|
||||
FPSInt=30
|
||||
FPSNum=30
|
||||
FPSDen=1
|
||||
ScaleType=bicubic
|
||||
ColorFormat=NV12
|
||||
ColorSpace=709
|
||||
ColorRange=Partial
|
||||
SdrWhiteLevel=300
|
||||
HdrNominalPeakLevel=1000
|
||||
|
||||
[Audio]
|
||||
MonitoringDeviceId=default
|
||||
MonitoringDeviceName=Default
|
||||
SampleRate=48000
|
||||
ChannelSetup=Stereo
|
||||
MeterDecayRate=23.53
|
||||
PeakMeterType=0
|
||||
|
||||
[Panels]
|
||||
CookieId=F16A3C33A65F2D3B
|
||||
@@ -0,0 +1 @@
|
||||
{"type":"rtmp_common","settings":{"service":"Twitch","protocol":"RTMP","server":"auto","bwtest":false,"key":"***","stream_key_link":"https://dashboard.twitch.tv/settings/stream","multitrack_video_configuration_url":"https://ingest.twitch.tv/api/v3/GetClientConfiguration","multitrack_video_name":"Enhanced Broadcasting","multitrack_video_disclaimer":"Enhanced Broadcasting automatically optimises your settings to encode and send multiple video qualities to Twitch. Selecting this option will send Twitch information about your computer and software setup. <a href='https://help.twitch.tv/s/article/multiple-encodes'>Learn More</a>"}}
|
||||
@@ -0,0 +1,245 @@
|
||||
{
|
||||
"name": "Untitled",
|
||||
"DesktopAudioDevice1": {
|
||||
"prev_ver": 536936450,
|
||||
"name": "Desktop Audio",
|
||||
"uuid": "5abe3188-e870-4a3f-90a1-7b4a188e474c",
|
||||
"id": "pulse_output_capture",
|
||||
"versioned_id": "pulse_output_capture",
|
||||
"settings": {
|
||||
"device_id": "default"
|
||||
},
|
||||
"mixers": 255,
|
||||
"sync": 0,
|
||||
"flags": 0,
|
||||
"volume": 1.0,
|
||||
"balance": 0.5,
|
||||
"enabled": true,
|
||||
"muted": false,
|
||||
"push-to-mute": false,
|
||||
"push-to-mute-delay": 0,
|
||||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"hotkeys": {
|
||||
"libobs.mute": [],
|
||||
"libobs.unmute": [],
|
||||
"libobs.push-to-mute": [],
|
||||
"libobs.push-to-talk": []
|
||||
},
|
||||
"deinterlace_mode": 0,
|
||||
"deinterlace_field_order": 0,
|
||||
"monitoring_type": 0,
|
||||
"private_settings": {}
|
||||
},
|
||||
"AuxAudioDevice1": {
|
||||
"prev_ver": 536936450,
|
||||
"name": "Mic/Aux",
|
||||
"uuid": "64f713bb-c3be-4204-a83c-367d185c207e",
|
||||
"id": "pulse_input_capture",
|
||||
"versioned_id": "pulse_input_capture",
|
||||
"settings": {
|
||||
"device_id": "default"
|
||||
},
|
||||
"mixers": 255,
|
||||
"sync": 0,
|
||||
"flags": 0,
|
||||
"volume": 1.0,
|
||||
"balance": 0.5,
|
||||
"enabled": true,
|
||||
"muted": false,
|
||||
"push-to-mute": false,
|
||||
"push-to-mute-delay": 0,
|
||||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"hotkeys": {
|
||||
"libobs.mute": [],
|
||||
"libobs.unmute": [],
|
||||
"libobs.push-to-mute": [],
|
||||
"libobs.push-to-talk": []
|
||||
},
|
||||
"deinterlace_mode": 0,
|
||||
"deinterlace_field_order": 0,
|
||||
"monitoring_type": 0,
|
||||
"private_settings": {}
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"prev_ver": 536936450,
|
||||
"name": "Screen Capture (PipeWire)",
|
||||
"uuid": "6d5eee3c-aa2e-47f9-b521-325fa4aae3e5",
|
||||
"id": "pipewire-screen-capture-source",
|
||||
"versioned_id": "pipewire-screen-capture-source",
|
||||
"settings": {
|
||||
"RestoreToken": ""
|
||||
},
|
||||
"mixers": 0,
|
||||
"sync": 0,
|
||||
"flags": 0,
|
||||
"volume": 1.0,
|
||||
"balance": 0.5,
|
||||
"enabled": true,
|
||||
"muted": false,
|
||||
"push-to-mute": false,
|
||||
"push-to-mute-delay": 0,
|
||||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"hotkeys": {},
|
||||
"deinterlace_mode": 0,
|
||||
"deinterlace_field_order": 0,
|
||||
"monitoring_type": 0,
|
||||
"private_settings": {}
|
||||
},
|
||||
{
|
||||
"prev_ver": 536936450,
|
||||
"name": "Scene",
|
||||
"uuid": "2f9a2fe6-26d6-4590-818b-a22e0ed0c792",
|
||||
"id": "scene",
|
||||
"versioned_id": "scene",
|
||||
"settings": {
|
||||
"id_counter": 1,
|
||||
"custom_size": false,
|
||||
"items": [
|
||||
{
|
||||
"name": "Screen Capture (PipeWire)",
|
||||
"source_uuid": "6d5eee3c-aa2e-47f9-b521-325fa4aae3e5",
|
||||
"visible": true,
|
||||
"locked": false,
|
||||
"rot": 0.0,
|
||||
"scale_ref": {
|
||||
"x": 1920.0,
|
||||
"y": 1080.0
|
||||
},
|
||||
"align": 5,
|
||||
"bounds_type": 0,
|
||||
"bounds_align": 0,
|
||||
"bounds_crop": false,
|
||||
"crop_left": 0,
|
||||
"crop_top": 0,
|
||||
"crop_right": 0,
|
||||
"crop_bottom": 0,
|
||||
"id": 1,
|
||||
"group_item_backup": false,
|
||||
"pos": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
},
|
||||
"pos_rel": {
|
||||
"x": -1.7777777910232544,
|
||||
"y": -1.0
|
||||
},
|
||||
"scale": {
|
||||
"x": 0.75,
|
||||
"y": 0.75
|
||||
},
|
||||
"scale_rel": {
|
||||
"x": 0.75,
|
||||
"y": 0.75
|
||||
},
|
||||
"bounds": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
},
|
||||
"bounds_rel": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
},
|
||||
"scale_filter": "disable",
|
||||
"blend_method": "default",
|
||||
"blend_type": "normal",
|
||||
"show_transition": {
|
||||
"duration": 300
|
||||
},
|
||||
"hide_transition": {
|
||||
"duration": 300
|
||||
},
|
||||
"private_settings": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mixers": 0,
|
||||
"sync": 0,
|
||||
"flags": 0,
|
||||
"volume": 1.0,
|
||||
"balance": 0.5,
|
||||
"enabled": true,
|
||||
"muted": false,
|
||||
"push-to-mute": false,
|
||||
"push-to-mute-delay": 0,
|
||||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"hotkeys": {
|
||||
"OBSBasic.SelectScene": [],
|
||||
"libobs.show_scene_item.1": [],
|
||||
"libobs.hide_scene_item.1": []
|
||||
},
|
||||
"deinterlace_mode": 0,
|
||||
"deinterlace_field_order": 0,
|
||||
"monitoring_type": 0,
|
||||
"canvas_uuid": "6c69626f-6273-4c00-9d88-c5136d61696e",
|
||||
"private_settings": {}
|
||||
}
|
||||
],
|
||||
"groups": [],
|
||||
"scene_order": [
|
||||
{
|
||||
"name": "Scene"
|
||||
}
|
||||
],
|
||||
"current_scene": "Scene",
|
||||
"current_program_scene": "Scene",
|
||||
"canvases": [],
|
||||
"current_transition": "Fade",
|
||||
"transition_duration": 300,
|
||||
"transitions": [],
|
||||
"quick_transitions": [
|
||||
{
|
||||
"name": "Cut",
|
||||
"duration": 300,
|
||||
"hotkeys": [],
|
||||
"id": 1,
|
||||
"fade_to_black": false
|
||||
},
|
||||
{
|
||||
"name": "Fade",
|
||||
"duration": 300,
|
||||
"hotkeys": [],
|
||||
"id": 2,
|
||||
"fade_to_black": false
|
||||
},
|
||||
{
|
||||
"name": "Fade",
|
||||
"duration": 300,
|
||||
"hotkeys": [],
|
||||
"id": 3,
|
||||
"fade_to_black": true
|
||||
}
|
||||
],
|
||||
"saved_projectors": [],
|
||||
"preview_locked": false,
|
||||
"scaling_enabled": false,
|
||||
"scaling_level": -41,
|
||||
"scaling_off_x": 0.0,
|
||||
"scaling_off_y": 0.0,
|
||||
"virtual-camera": {
|
||||
"type2": 3
|
||||
},
|
||||
"modules": {
|
||||
"scripts-tool": [],
|
||||
"output-timer": {
|
||||
"streamTimerHours": 0,
|
||||
"streamTimerMinutes": 0,
|
||||
"streamTimerSeconds": 30,
|
||||
"recordTimerHours": 0,
|
||||
"recordTimerMinutes": 0,
|
||||
"recordTimerSeconds": 30,
|
||||
"autoStartStreamTimer": false,
|
||||
"autoStartRecordTimer": false,
|
||||
"pauseRecordTimer": true
|
||||
}
|
||||
},
|
||||
"resolution": {
|
||||
"x": 1920,
|
||||
"y": 1080
|
||||
},
|
||||
"version": 2
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
{
|
||||
"name": "Untitled",
|
||||
"DesktopAudioDevice1": {
|
||||
"prev_ver": 536936450,
|
||||
"name": "Desktop Audio",
|
||||
"uuid": "5abe3188-e870-4a3f-90a1-7b4a188e474c",
|
||||
"id": "pulse_output_capture",
|
||||
"versioned_id": "pulse_output_capture",
|
||||
"settings": {
|
||||
"device_id": "default"
|
||||
},
|
||||
"mixers": 255,
|
||||
"sync": 0,
|
||||
"flags": 0,
|
||||
"volume": 1.0,
|
||||
"balance": 0.5,
|
||||
"enabled": true,
|
||||
"muted": false,
|
||||
"push-to-mute": false,
|
||||
"push-to-mute-delay": 0,
|
||||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"hotkeys": {
|
||||
"libobs.mute": [],
|
||||
"libobs.unmute": [],
|
||||
"libobs.push-to-mute": [],
|
||||
"libobs.push-to-talk": []
|
||||
},
|
||||
"deinterlace_mode": 0,
|
||||
"deinterlace_field_order": 0,
|
||||
"monitoring_type": 0,
|
||||
"private_settings": {}
|
||||
},
|
||||
"AuxAudioDevice1": {
|
||||
"prev_ver": 536936450,
|
||||
"name": "Mic/Aux",
|
||||
"uuid": "64f713bb-c3be-4204-a83c-367d185c207e",
|
||||
"id": "pulse_input_capture",
|
||||
"versioned_id": "pulse_input_capture",
|
||||
"settings": {
|
||||
"device_id": "default"
|
||||
},
|
||||
"mixers": 255,
|
||||
"sync": 0,
|
||||
"flags": 0,
|
||||
"volume": 1.0,
|
||||
"balance": 0.5,
|
||||
"enabled": true,
|
||||
"muted": false,
|
||||
"push-to-mute": false,
|
||||
"push-to-mute-delay": 0,
|
||||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"hotkeys": {
|
||||
"libobs.mute": [],
|
||||
"libobs.unmute": [],
|
||||
"libobs.push-to-mute": [],
|
||||
"libobs.push-to-talk": []
|
||||
},
|
||||
"deinterlace_mode": 0,
|
||||
"deinterlace_field_order": 0,
|
||||
"monitoring_type": 0,
|
||||
"private_settings": {}
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"prev_ver": 536936450,
|
||||
"name": "Screen Capture (PipeWire)",
|
||||
"uuid": "6d5eee3c-aa2e-47f9-b521-325fa4aae3e5",
|
||||
"id": "pipewire-screen-capture-source",
|
||||
"versioned_id": "pipewire-screen-capture-source",
|
||||
"settings": {
|
||||
"RestoreToken": ""
|
||||
},
|
||||
"mixers": 0,
|
||||
"sync": 0,
|
||||
"flags": 0,
|
||||
"volume": 1.0,
|
||||
"balance": 0.5,
|
||||
"enabled": true,
|
||||
"muted": false,
|
||||
"push-to-mute": false,
|
||||
"push-to-mute-delay": 0,
|
||||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"hotkeys": {},
|
||||
"deinterlace_mode": 0,
|
||||
"deinterlace_field_order": 0,
|
||||
"monitoring_type": 0,
|
||||
"private_settings": {}
|
||||
},
|
||||
{
|
||||
"prev_ver": 536936450,
|
||||
"name": "Scene",
|
||||
"uuid": "2f9a2fe6-26d6-4590-818b-a22e0ed0c792",
|
||||
"id": "scene",
|
||||
"versioned_id": "scene",
|
||||
"settings": {
|
||||
"id_counter": 1,
|
||||
"custom_size": false,
|
||||
"items": [
|
||||
{
|
||||
"name": "Screen Capture (PipeWire)",
|
||||
"source_uuid": "6d5eee3c-aa2e-47f9-b521-325fa4aae3e5",
|
||||
"visible": true,
|
||||
"locked": false,
|
||||
"rot": 0.0,
|
||||
"scale_ref": {
|
||||
"x": 1920.0,
|
||||
"y": 1080.0
|
||||
},
|
||||
"align": 5,
|
||||
"bounds_type": 0,
|
||||
"bounds_align": 0,
|
||||
"bounds_crop": false,
|
||||
"crop_left": 0,
|
||||
"crop_top": 0,
|
||||
"crop_right": 0,
|
||||
"crop_bottom": 0,
|
||||
"id": 1,
|
||||
"group_item_backup": false,
|
||||
"pos": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
},
|
||||
"pos_rel": {
|
||||
"x": -1.7777777910232544,
|
||||
"y": -1.0
|
||||
},
|
||||
"scale": {
|
||||
"x": 0.75,
|
||||
"y": 0.75
|
||||
},
|
||||
"scale_rel": {
|
||||
"x": 0.75,
|
||||
"y": 0.75
|
||||
},
|
||||
"bounds": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
},
|
||||
"bounds_rel": {
|
||||
"x": 0.0,
|
||||
"y": 0.0
|
||||
},
|
||||
"scale_filter": "disable",
|
||||
"blend_method": "default",
|
||||
"blend_type": "normal",
|
||||
"show_transition": {
|
||||
"duration": 300
|
||||
},
|
||||
"hide_transition": {
|
||||
"duration": 300
|
||||
},
|
||||
"private_settings": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
"mixers": 0,
|
||||
"sync": 0,
|
||||
"flags": 0,
|
||||
"volume": 1.0,
|
||||
"balance": 0.5,
|
||||
"enabled": true,
|
||||
"muted": false,
|
||||
"push-to-mute": false,
|
||||
"push-to-mute-delay": 0,
|
||||
"push-to-talk": false,
|
||||
"push-to-talk-delay": 0,
|
||||
"hotkeys": {
|
||||
"OBSBasic.SelectScene": [],
|
||||
"libobs.show_scene_item.1": [],
|
||||
"libobs.hide_scene_item.1": []
|
||||
},
|
||||
"deinterlace_mode": 0,
|
||||
"deinterlace_field_order": 0,
|
||||
"monitoring_type": 0,
|
||||
"canvas_uuid": "6c69626f-6273-4c00-9d88-c5136d61696e",
|
||||
"private_settings": {}
|
||||
}
|
||||
],
|
||||
"groups": [],
|
||||
"scene_order": [
|
||||
{
|
||||
"name": "Scene"
|
||||
}
|
||||
],
|
||||
"current_scene": "Scene",
|
||||
"current_program_scene": "Scene",
|
||||
"canvases": [],
|
||||
"current_transition": "Fade",
|
||||
"transition_duration": 300,
|
||||
"transitions": [],
|
||||
"quick_transitions": [
|
||||
{
|
||||
"name": "Cut",
|
||||
"duration": 300,
|
||||
"hotkeys": [],
|
||||
"id": 1,
|
||||
"fade_to_black": false
|
||||
},
|
||||
{
|
||||
"name": "Fade",
|
||||
"duration": 300,
|
||||
"hotkeys": [],
|
||||
"id": 2,
|
||||
"fade_to_black": false
|
||||
},
|
||||
{
|
||||
"name": "Fade",
|
||||
"duration": 300,
|
||||
"hotkeys": [],
|
||||
"id": 3,
|
||||
"fade_to_black": true
|
||||
}
|
||||
],
|
||||
"saved_projectors": [],
|
||||
"preview_locked": false,
|
||||
"scaling_enabled": false,
|
||||
"scaling_level": -17,
|
||||
"scaling_off_x": 0.0,
|
||||
"scaling_off_y": 0.0,
|
||||
"virtual-camera": {
|
||||
"type2": 3
|
||||
},
|
||||
"modules": {
|
||||
"scripts-tool": [],
|
||||
"output-timer": {
|
||||
"streamTimerHours": 0,
|
||||
"streamTimerMinutes": 0,
|
||||
"streamTimerSeconds": 30,
|
||||
"recordTimerHours": 0,
|
||||
"recordTimerMinutes": 0,
|
||||
"recordTimerSeconds": 30,
|
||||
"autoStartStreamTimer": false,
|
||||
"autoStartRecordTimer": false,
|
||||
"pauseRecordTimer": true
|
||||
}
|
||||
},
|
||||
"resolution": {
|
||||
"x": 1920,
|
||||
"y": 1080
|
||||
},
|
||||
"version": 2
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
[General]
|
||||
MaxLogs=10
|
||||
InfoIncrement=-1
|
||||
ProcessPriority=Normal
|
||||
EnableAutoUpdates=true
|
||||
BrowserHWAccel=true
|
||||
LastVersion=536936450
|
||||
|
||||
[Video]
|
||||
Renderer=OpenGL
|
||||
|
||||
[Locations]
|
||||
Configuration=/home/arindy/.config
|
||||
SceneCollections=/home/arindy/.config
|
||||
Profiles=/home/arindy/.config
|
||||
PluginManagerSettings=/home/arindy/.config
|
||||
|
||||
[PropertiesWindow]
|
||||
cx=720
|
||||
cy=580
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"alerts_enabled": false,
|
||||
"auth_required": true,
|
||||
"first_load": false,
|
||||
"server_enabled": false,
|
||||
"server_password": "***",
|
||||
"server_port": 4455
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"ingests": [
|
||||
{
|
||||
"_id": 0,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Default",
|
||||
"url_template": "rtmp://ingest.global-contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://ingest.global-contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 0
|
||||
},
|
||||
{
|
||||
"_id": 1,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Europe (Frankfurt)",
|
||||
"url_template": "rtmp://euc10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://euc10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 1
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Europe (Paris)",
|
||||
"url_template": "rtmp://euw30.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://euw30.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 2
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Europe (Stockholm)",
|
||||
"url_template": "rtmp://eun10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://eun10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 3
|
||||
},
|
||||
{
|
||||
"_id": 4,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Europe (Ireland)",
|
||||
"url_template": "rtmp://euw10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://euw10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 4
|
||||
},
|
||||
{
|
||||
"_id": 5,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Mumbai)",
|
||||
"url_template": "rtmp://aps30.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://aps30.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 5
|
||||
},
|
||||
{
|
||||
"_id": 6,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "US East (N. Virginia)",
|
||||
"url_template": "rtmp://use10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://use10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 6
|
||||
},
|
||||
{
|
||||
"_id": 7,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "US East (Ohio)",
|
||||
"url_template": "rtmp://use20.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://use20.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 7
|
||||
},
|
||||
{
|
||||
"_id": 8,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Seoul)",
|
||||
"url_template": "rtmp://apn20.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://apn20.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 8
|
||||
},
|
||||
{
|
||||
"_id": 9,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "US West (Oregon)",
|
||||
"url_template": "rtmp://usw20.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://usw20.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 9
|
||||
},
|
||||
{
|
||||
"_id": 10,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Tokyo)",
|
||||
"url_template": "rtmp://apn10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://apn10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"_id": 11,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "South America (São Paulo)",
|
||||
"url_template": "rtmp://sae10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://sae10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 11
|
||||
},
|
||||
{
|
||||
"_id": 12,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Singapore)",
|
||||
"url_template": "rtmp://aps10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://aps10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 12
|
||||
},
|
||||
{
|
||||
"_id": 13,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Sydney)",
|
||||
"url_template": "rtmp://aps20.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://aps20.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 13
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"$schema":"schema/package-schema.json","url":"https://obsproject.com/obs2_update/rtmp-services/v5","version":286,"files":[{"name":"services.json","version":286}]}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"ingests": [
|
||||
{
|
||||
"_id": 0,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Default",
|
||||
"url_template": "rtmp://ingest.global-contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://ingest.global-contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 0
|
||||
},
|
||||
{
|
||||
"_id": 1,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Europe (Frankfurt)",
|
||||
"url_template": "rtmp://euc10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://euc10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 1
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Europe (Paris)",
|
||||
"url_template": "rtmp://euw30.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://euw30.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 2
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Europe (Stockholm)",
|
||||
"url_template": "rtmp://eun10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://eun10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 3
|
||||
},
|
||||
{
|
||||
"_id": 4,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Europe (Ireland)",
|
||||
"url_template": "rtmp://euw10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://euw10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 4
|
||||
},
|
||||
{
|
||||
"_id": 5,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Mumbai)",
|
||||
"url_template": "rtmp://aps30.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://aps30.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 5
|
||||
},
|
||||
{
|
||||
"_id": 6,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "US East (N. Virginia)",
|
||||
"url_template": "rtmp://use10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://use10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 6
|
||||
},
|
||||
{
|
||||
"_id": 7,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "US East (Ohio)",
|
||||
"url_template": "rtmp://use20.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://use20.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 7
|
||||
},
|
||||
{
|
||||
"_id": 8,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Seoul)",
|
||||
"url_template": "rtmp://apn20.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://apn20.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 8
|
||||
},
|
||||
{
|
||||
"_id": 9,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "US West (Oregon)",
|
||||
"url_template": "rtmp://usw20.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://usw20.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 9
|
||||
},
|
||||
{
|
||||
"_id": 10,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Tokyo)",
|
||||
"url_template": "rtmp://apn10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://apn10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"_id": 11,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "South America (São Paulo)",
|
||||
"url_template": "rtmp://sae10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://sae10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 11
|
||||
},
|
||||
{
|
||||
"_id": 12,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Singapore)",
|
||||
"url_template": "rtmp://aps10.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://aps10.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 12
|
||||
},
|
||||
{
|
||||
"_id": 13,
|
||||
"availability": 1.0,
|
||||
"default": false,
|
||||
"name": "Asia Pacific (Sydney)",
|
||||
"url_template": "rtmp://aps20.contribute.live-video.net/app/{stream_key}",
|
||||
"url_template_secure": "rtmps://aps20.contribute.live-video.net/app/{stream_key}",
|
||||
"priority": 13
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
[General]
|
||||
Pre19Defaults=false
|
||||
Pre21Defaults=false
|
||||
Pre23Defaults=false
|
||||
Pre24.1Defaults=false
|
||||
ConfirmOnExit=true
|
||||
HotkeyFocusType=NeverDisableHotkeys
|
||||
FirstRun=true
|
||||
|
||||
[BasicWindow]
|
||||
PreviewEnabled=true
|
||||
PreviewProgramMode=true
|
||||
SceneDuplicationMode=true
|
||||
SwapScenesMode=true
|
||||
SnappingEnabled=true
|
||||
ScreenSnapping=true
|
||||
SourceSnapping=true
|
||||
CenterSnapping=false
|
||||
SnapDistance=10
|
||||
SpacingHelpersEnabled=true
|
||||
RecordWhenStreaming=false
|
||||
KeepRecordingWhenStreamStops=false
|
||||
SysTrayEnabled=true
|
||||
SysTrayWhenStarted=false
|
||||
SaveProjectors=false
|
||||
ShowTransitions=true
|
||||
ShowListboxToolbars=true
|
||||
ShowStatusBar=true
|
||||
ShowSourceIcons=true
|
||||
ShowContextToolbars=true
|
||||
StudioModeLabels=true
|
||||
VerticalVolControl=true
|
||||
MultiviewMouseSwitch=true
|
||||
MultiviewDrawNames=true
|
||||
MultiviewDrawAreas=true
|
||||
MediaControlsCountdownTimer=true
|
||||
geometry=AdnQywADAAAAAAoA///6YAAADvX////hAAAAAAAAAAD////+/////gAAAAICAAAACgAAAAoA///6YAAADvX////h
|
||||
DockState=AAAA/wAAAAD9AAAAAgAAAAEAAALPAAAFSvwCAAAAA/sAAAAYAGMAbwBuAHQAcgBvAGwAcwBEAG8AYwBrAQAAABYAAAGtAAAAsgD////7AAAAEgBzAHQAYQB0AHMARABvAGMAawEAAAHGAAACYgAAAP0A////+wAAABIAbQBpAHgAZQByAEQAbwBjAGsBAAAEKwAAATUAAADvAP///wAAAAMAAAIkAAAAgvwBAAAAA/sAAAAUAHMAYwBlAG4AZQBzAEQAbwBjAGsBAAAAAAAAAK0AAACYAP////sAAAAWAHMAbwB1AHIAYwBlAHMARABvAGMAawEAAACwAAAArwAAAJgA////+wAAAB4AdAByAGEAbgBzAGkAdABpAG8AbgBzAEQAbwBjAGsBAAABYgAAAMIAAADBAP///wAAAiQAAATFAAAAAQAAAAIAAAABAAAAAvwAAAAA
|
||||
AlwaysOnTop=false
|
||||
EditPropertiesMode=false
|
||||
DocksLocked=true
|
||||
SideDocks=true
|
||||
gridMode=false
|
||||
OverflowAlwaysVisible=true
|
||||
OverflowHidden=false
|
||||
OverflowSelectionHidden=false
|
||||
TransitionOnDoubleClick=true
|
||||
WarnBeforeStartingStream=true
|
||||
WarnBeforeStoppingStream=true
|
||||
WarnBeforeStoppingRecord=false
|
||||
VerticalVolumeControl=true
|
||||
MixerShowInactive=false
|
||||
MixerKeepInactiveLast=false
|
||||
MixerShowHidden=false
|
||||
MixerKeepHiddenLast=false
|
||||
|
||||
[Appearance]
|
||||
FontScale=10
|
||||
Density=-3
|
||||
Theme=com.obsproject.Yami.Acri
|
||||
|
||||
[Basic]
|
||||
Profile=Arindy
|
||||
ProfileDir=Arindy
|
||||
SceneCollection=Untitled
|
||||
SceneCollectionFile=Untitled.json
|
||||
ConfigOnNewProfile=true
|
||||
|
||||
[Accessibility]
|
||||
SelectRed=255
|
||||
SelectGreen=65280
|
||||
SelectBlue=16744192
|
||||
MixerGreen=2522918
|
||||
MixerYellow=2523007
|
||||
MixerRed=2500223
|
||||
MixerGreenActive=5046092
|
||||
MixerYellowActive=5046271
|
||||
MixerRedActive=5000447
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"discordBranch": "stable",
|
||||
"minimizeToTray": true,
|
||||
"arRPC": true,
|
||||
"splashColor": "rgb(220, 220, 223)",
|
||||
"splashBackground": "rgba(0, 0, 0, 0)"
|
||||
}
|
||||
@@ -0,0 +1,603 @@
|
||||
{
|
||||
"autoUpdate": true,
|
||||
"autoUpdateNotification": true,
|
||||
"useQuickCss": true,
|
||||
"themeLinks": [],
|
||||
"eagerPatches": false,
|
||||
"enabledThemes": [
|
||||
"Serpensortia.theme.css"
|
||||
],
|
||||
"enableReactDevtools": false,
|
||||
"frameless": false,
|
||||
"transparent": true,
|
||||
"winCtrlQ": false,
|
||||
"windowsMaterial": "none",
|
||||
"disableMinSize": false,
|
||||
"winNativeTitleBar": false,
|
||||
"plugins": {
|
||||
"ChatInputButtonAPI": {
|
||||
"enabled": false
|
||||
},
|
||||
"CommandsAPI": {
|
||||
"enabled": true
|
||||
},
|
||||
"DynamicImageModalAPI": {
|
||||
"enabled": false
|
||||
},
|
||||
"MemberListDecoratorsAPI": {
|
||||
"enabled": false
|
||||
},
|
||||
"MessageAccessoriesAPI": {
|
||||
"enabled": true
|
||||
},
|
||||
"MessageDecorationsAPI": {
|
||||
"enabled": false
|
||||
},
|
||||
"MessageEventsAPI": {
|
||||
"enabled": true
|
||||
},
|
||||
"MessagePopoverAPI": {
|
||||
"enabled": false
|
||||
},
|
||||
"MessageUpdaterAPI": {
|
||||
"enabled": false
|
||||
},
|
||||
"ServerListAPI": {
|
||||
"enabled": true
|
||||
},
|
||||
"UserSettingsAPI": {
|
||||
"enabled": true
|
||||
},
|
||||
"AccountPanelServerProfile": {
|
||||
"enabled": false
|
||||
},
|
||||
"AlwaysAnimate": {
|
||||
"enabled": false
|
||||
},
|
||||
"AlwaysExpandRoles": {
|
||||
"enabled": false
|
||||
},
|
||||
"AlwaysTrust": {
|
||||
"enabled": false
|
||||
},
|
||||
"AnonymiseFileNames": {
|
||||
"enabled": true
|
||||
},
|
||||
"AppleMusicRichPresence": {
|
||||
"enabled": false
|
||||
},
|
||||
"WebRichPresence (arRPC)": {
|
||||
"enabled": false
|
||||
},
|
||||
"BetterFolders": {
|
||||
"enabled": true,
|
||||
"sidebar": true,
|
||||
"sidebarAnim": true,
|
||||
"closeAllFolders": false,
|
||||
"closeAllHomeButton": false,
|
||||
"closeOthers": false,
|
||||
"forceOpen": false,
|
||||
"keepIcons": false,
|
||||
"showFolderIcon": 1
|
||||
},
|
||||
"BetterGifAltText": {
|
||||
"enabled": false
|
||||
},
|
||||
"BetterGifPicker": {
|
||||
"enabled": false
|
||||
},
|
||||
"BetterRoleContext": {
|
||||
"enabled": false
|
||||
},
|
||||
"BetterRoleDot": {
|
||||
"enabled": false
|
||||
},
|
||||
"BetterSessions": {
|
||||
"enabled": false
|
||||
},
|
||||
"BetterSettings": {
|
||||
"enabled": false
|
||||
},
|
||||
"BetterUploadButton": {
|
||||
"enabled": false
|
||||
},
|
||||
"BiggerStreamPreview": {
|
||||
"enabled": true
|
||||
},
|
||||
"BlurNSFW": {
|
||||
"enabled": false
|
||||
},
|
||||
"CallTimer": {
|
||||
"enabled": false
|
||||
},
|
||||
"CharacterCounter": {
|
||||
"enabled": false
|
||||
},
|
||||
"ClearURLs": {
|
||||
"enabled": true
|
||||
},
|
||||
"ClientTheme": {
|
||||
"enabled": false
|
||||
},
|
||||
"ColorSighted": {
|
||||
"enabled": false
|
||||
},
|
||||
"ConsoleJanitor": {
|
||||
"enabled": false
|
||||
},
|
||||
"ConsoleShortcuts": {
|
||||
"enabled": false
|
||||
},
|
||||
"CopyEmojiMarkdown": {
|
||||
"enabled": false
|
||||
},
|
||||
"CopyFileContents": {
|
||||
"enabled": false
|
||||
},
|
||||
"CopyStickerLinks": {
|
||||
"enabled": false
|
||||
},
|
||||
"CopyUserURLs": {
|
||||
"enabled": false
|
||||
},
|
||||
"CrashHandler": {
|
||||
"enabled": true
|
||||
},
|
||||
"CustomCommands": {
|
||||
"enabled": false
|
||||
},
|
||||
"CustomIdle": {
|
||||
"enabled": false
|
||||
},
|
||||
"CustomRPC": {
|
||||
"enabled": false
|
||||
},
|
||||
"Dearrow": {
|
||||
"enabled": true,
|
||||
"hideButton": false,
|
||||
"replaceElements": 0,
|
||||
"dearrowByDefault": true
|
||||
},
|
||||
"Decor": {
|
||||
"enabled": false
|
||||
},
|
||||
"DisableCallIdle": {
|
||||
"enabled": false
|
||||
},
|
||||
"DontRoundMyTimestamps": {
|
||||
"enabled": false
|
||||
},
|
||||
"Experiments": {
|
||||
"enabled": false
|
||||
},
|
||||
"ExpressionCloner": {
|
||||
"enabled": false
|
||||
},
|
||||
"F8Break": {
|
||||
"enabled": false
|
||||
},
|
||||
"FakeNitro": {
|
||||
"enabled": false
|
||||
},
|
||||
"FakeProfileThemes": {
|
||||
"enabled": false
|
||||
},
|
||||
"FavoriteEmojiFirst": {
|
||||
"enabled": false
|
||||
},
|
||||
"FixCodeblockGap": {
|
||||
"enabled": false
|
||||
},
|
||||
"FixImagesQuality": {
|
||||
"enabled": true,
|
||||
"originalImagesInChat": false
|
||||
},
|
||||
"FixSpotifyEmbeds": {
|
||||
"enabled": false
|
||||
},
|
||||
"FixYoutubeEmbeds": {
|
||||
"enabled": true
|
||||
},
|
||||
"ForceOwnerCrown": {
|
||||
"enabled": false
|
||||
},
|
||||
"FriendInvites": {
|
||||
"enabled": false
|
||||
},
|
||||
"FullSearchContext": {
|
||||
"enabled": false
|
||||
},
|
||||
"FullUserInChatbox": {
|
||||
"enabled": false
|
||||
},
|
||||
"GameActivityToggle": {
|
||||
"enabled": true,
|
||||
"location": "PANEL",
|
||||
"oldIcon": false
|
||||
},
|
||||
"GifPaste": {
|
||||
"enabled": false
|
||||
},
|
||||
"GreetStickerPicker": {
|
||||
"enabled": false
|
||||
},
|
||||
"HideMedia": {
|
||||
"enabled": false
|
||||
},
|
||||
"iLoveSpam": {
|
||||
"enabled": false
|
||||
},
|
||||
"IgnoreActivities": {
|
||||
"enabled": false
|
||||
},
|
||||
"ImageFilename": {
|
||||
"enabled": false
|
||||
},
|
||||
"ImageLink": {
|
||||
"enabled": false
|
||||
},
|
||||
"ImageZoom": {
|
||||
"enabled": false
|
||||
},
|
||||
"ImplicitRelationships": {
|
||||
"enabled": false
|
||||
},
|
||||
"IrcColors": {
|
||||
"enabled": false
|
||||
},
|
||||
"KeepCurrentChannel": {
|
||||
"enabled": false
|
||||
},
|
||||
"LoadingQuotes": {
|
||||
"enabled": false
|
||||
},
|
||||
"MemberCount": {
|
||||
"enabled": false
|
||||
},
|
||||
"MentionAvatars": {
|
||||
"enabled": false
|
||||
},
|
||||
"MessageClickActions": {
|
||||
"enabled": false
|
||||
},
|
||||
"MessageLatency": {
|
||||
"enabled": false
|
||||
},
|
||||
"MessageLinkEmbeds": {
|
||||
"enabled": false
|
||||
},
|
||||
"MessageLogger": {
|
||||
"enabled": false
|
||||
},
|
||||
"MoreQuickReactions": {
|
||||
"enabled": false
|
||||
},
|
||||
"MusicRichPresence": {
|
||||
"enabled": false
|
||||
},
|
||||
"MutualGroupDMs": {
|
||||
"enabled": false
|
||||
},
|
||||
"NewGuildSettings": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoBlockedMessages": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoDevtoolsWarning": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoF1": {
|
||||
"enabled": true
|
||||
},
|
||||
"NoMaskedUrlPaste": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoMiddleClickPaste": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoMosaic": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoOnboardingDelay": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoPendingCount": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoProfileThemes": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoReplyMention": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoServerEmojis": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoTypingAnimation": {
|
||||
"enabled": false
|
||||
},
|
||||
"NoUnblockToJump": {
|
||||
"enabled": false
|
||||
},
|
||||
"NotificationVolume": {
|
||||
"enabled": false
|
||||
},
|
||||
"OnePingPerDM": {
|
||||
"enabled": false
|
||||
},
|
||||
"oneko": {
|
||||
"enabled": false
|
||||
},
|
||||
"OpenInApp": {
|
||||
"enabled": true,
|
||||
"spotify": true
|
||||
},
|
||||
"OverrideForumDefaults": {
|
||||
"enabled": false
|
||||
},
|
||||
"PauseInvitesForever": {
|
||||
"enabled": false
|
||||
},
|
||||
"PermissionFreeWill": {
|
||||
"enabled": false
|
||||
},
|
||||
"PermissionsViewer": {
|
||||
"enabled": false
|
||||
},
|
||||
"petpet": {
|
||||
"enabled": false
|
||||
},
|
||||
"PictureInPicture": {
|
||||
"enabled": false
|
||||
},
|
||||
"PinDMs": {
|
||||
"enabled": false
|
||||
},
|
||||
"PlainFolderIcon": {
|
||||
"enabled": false
|
||||
},
|
||||
"PlatformIndicators": {
|
||||
"enabled": false
|
||||
},
|
||||
"PreviewMessage": {
|
||||
"enabled": false
|
||||
},
|
||||
"QuickMention": {
|
||||
"enabled": false
|
||||
},
|
||||
"QuickReply": {
|
||||
"enabled": false
|
||||
},
|
||||
"ReactErrorDecoder": {
|
||||
"enabled": false
|
||||
},
|
||||
"ReadAllNotificationsButton": {
|
||||
"enabled": true
|
||||
},
|
||||
"RelationshipNotifier": {
|
||||
"enabled": false
|
||||
},
|
||||
"ReplaceGoogleSearch": {
|
||||
"enabled": true
|
||||
},
|
||||
"ReplyTimestamp": {
|
||||
"enabled": false
|
||||
},
|
||||
"RevealAllSpoilers": {
|
||||
"enabled": false
|
||||
},
|
||||
"ReverseImageSearch": {
|
||||
"enabled": false
|
||||
},
|
||||
"ReviewDB": {
|
||||
"enabled": false
|
||||
},
|
||||
"RoleColorEverywhere": {
|
||||
"enabled": true,
|
||||
"chatMentions": true,
|
||||
"memberList": true,
|
||||
"voiceUsers": true,
|
||||
"reactorsList": true,
|
||||
"pollResults": true,
|
||||
"colorChatMessages": false
|
||||
},
|
||||
"SecretRingToneEnabler": {
|
||||
"enabled": false
|
||||
},
|
||||
"Summaries": {
|
||||
"enabled": false
|
||||
},
|
||||
"SendTimestamps": {
|
||||
"enabled": false
|
||||
},
|
||||
"ServerInfo": {
|
||||
"enabled": false
|
||||
},
|
||||
"ServerListIndicators": {
|
||||
"enabled": false
|
||||
},
|
||||
"ShikiCodeblocks": {
|
||||
"enabled": false
|
||||
},
|
||||
"ShowAllMessageButtons": {
|
||||
"enabled": false
|
||||
},
|
||||
"ShowConnections": {
|
||||
"enabled": false
|
||||
},
|
||||
"ShowHiddenChannels": {
|
||||
"enabled": false
|
||||
},
|
||||
"ShowHiddenThings": {
|
||||
"enabled": false
|
||||
},
|
||||
"ShowMeYourName": {
|
||||
"enabled": true,
|
||||
"mode": "user-nick",
|
||||
"friendNicknames": "dms",
|
||||
"displayNames": false,
|
||||
"inReplies": false
|
||||
},
|
||||
"ShowTimeoutDuration": {
|
||||
"enabled": false
|
||||
},
|
||||
"SilentMessageToggle": {
|
||||
"enabled": false
|
||||
},
|
||||
"SilentTyping": {
|
||||
"enabled": false
|
||||
},
|
||||
"SortFriendRequests": {
|
||||
"enabled": false
|
||||
},
|
||||
"SpotifyControls": {
|
||||
"enabled": false
|
||||
},
|
||||
"SpotifyCrack": {
|
||||
"enabled": false
|
||||
},
|
||||
"SpotifyShareCommands": {
|
||||
"enabled": false
|
||||
},
|
||||
"StartupTimings": {
|
||||
"enabled": false
|
||||
},
|
||||
"StickerPaste": {
|
||||
"enabled": false
|
||||
},
|
||||
"StreamerModeOnStream": {
|
||||
"enabled": false
|
||||
},
|
||||
"SuperReactionTweaks": {
|
||||
"enabled": false
|
||||
},
|
||||
"TenorGifSearch": {
|
||||
"enabled": false
|
||||
},
|
||||
"TextReplace": {
|
||||
"enabled": false
|
||||
},
|
||||
"ThemeAttributes": {
|
||||
"enabled": false
|
||||
},
|
||||
"Translate": {
|
||||
"enabled": false
|
||||
},
|
||||
"TypingIndicator": {
|
||||
"enabled": false
|
||||
},
|
||||
"TypingTweaks": {
|
||||
"enabled": false
|
||||
},
|
||||
"Unindent": {
|
||||
"enabled": false
|
||||
},
|
||||
"UnlockedAvatarZoom": {
|
||||
"enabled": false
|
||||
},
|
||||
"UnsuppressEmbeds": {
|
||||
"enabled": false
|
||||
},
|
||||
"UserMessagesPronouns": {
|
||||
"enabled": false
|
||||
},
|
||||
"UserVoiceShow": {
|
||||
"enabled": false
|
||||
},
|
||||
"USRBG": {
|
||||
"enabled": false
|
||||
},
|
||||
"ValidReply": {
|
||||
"enabled": false
|
||||
},
|
||||
"ValidUser": {
|
||||
"enabled": false
|
||||
},
|
||||
"VoiceChatDoubleClick": {
|
||||
"enabled": false
|
||||
},
|
||||
"VcNarrator": {
|
||||
"enabled": false
|
||||
},
|
||||
"VencordToolbox": {
|
||||
"enabled": false
|
||||
},
|
||||
"ViewIcons": {
|
||||
"enabled": false
|
||||
},
|
||||
"ViewRaw": {
|
||||
"enabled": false
|
||||
},
|
||||
"VoiceDownload": {
|
||||
"enabled": false
|
||||
},
|
||||
"VoiceMessages": {
|
||||
"enabled": false
|
||||
},
|
||||
"VolumeBooster": {
|
||||
"enabled": false
|
||||
},
|
||||
"WebKeybinds": {
|
||||
"enabled": true
|
||||
},
|
||||
"WebScreenShareFixes": {
|
||||
"enabled": true
|
||||
},
|
||||
"WhoReacted": {
|
||||
"enabled": false
|
||||
},
|
||||
"XSOverlay": {
|
||||
"enabled": false
|
||||
},
|
||||
"YoutubeAdblock": {
|
||||
"enabled": false
|
||||
},
|
||||
"BadgeAPI": {
|
||||
"enabled": true
|
||||
},
|
||||
"NoTrack": {
|
||||
"enabled": true,
|
||||
"disableAnalytics": true
|
||||
},
|
||||
"Settings": {
|
||||
"enabled": true,
|
||||
"settingsLocation": "aboveNitro",
|
||||
"includeVencordInfoWhenCopying": true
|
||||
},
|
||||
"ConcatenatedComponentExtractor": {
|
||||
"enabled": true
|
||||
},
|
||||
"ContextMenuAPI": {
|
||||
"enabled": true
|
||||
},
|
||||
"DisableDeepLinks": {
|
||||
"enabled": true
|
||||
},
|
||||
"NoticesAPI": {
|
||||
"enabled": true
|
||||
},
|
||||
"SupportHelper": {
|
||||
"enabled": true
|
||||
},
|
||||
"WebContextMenus": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"uiElements": {
|
||||
"chatBarButtons": {},
|
||||
"messagePopoverButtons": {}
|
||||
},
|
||||
"notifications": {
|
||||
"timeout": 5000,
|
||||
"position": "bottom-right",
|
||||
"useNative": "not-focused",
|
||||
"logLimit": 50
|
||||
},
|
||||
"cloud": {
|
||||
"authenticated": false,
|
||||
"url": "https://api.vencord.dev/",
|
||||
"settingsSync": false,
|
||||
"settingsSyncVersion": 1785959318526
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,636 @@
|
||||
/**
|
||||
* @name Serpensortia
|
||||
* @author Sithego
|
||||
* @version 0.1
|
||||
* @description Self-contained BetterDiscord theme generated by Sithego
|
||||
*/
|
||||
|
||||
:root {
|
||||
--sithego-bg: #080c08;
|
||||
--sithego-surface: #131d13;
|
||||
--sithego-surface-alt: #424a42;
|
||||
--sithego-text: #c0c0c0;
|
||||
--sithego-muted: #424a42;
|
||||
--sithego-border: #0b110b;
|
||||
--sithego-accent: #1c7a44;
|
||||
--sithego-warn: #dc143c;
|
||||
|
||||
--sithego-shell-bg: transparent;
|
||||
--sithego-panel-bg: rgba(19, 29, 19, 0.16);
|
||||
--sithego-panel-bg-strong: rgba(66, 74, 66, 0.22);
|
||||
--sithego-guilds-bg: rgba(8, 12, 8, 0.10);
|
||||
--sithego-hover: rgba(66, 74, 66, 0.24);
|
||||
--sithego-selected: rgba(28, 122, 68, 0.18);
|
||||
--sithego-selected-strong: rgba(28, 122, 68, 0.28);
|
||||
--sithego-border-alpha: rgba(11, 17, 11, 0.30);
|
||||
--sithego-input-bg: rgba(66, 74, 66, 0.20);
|
||||
--sithego-danger-bg: rgba(220, 20, 60, 0.20);
|
||||
--sithego-unread-bar: rgba(192, 192, 192, 0.92);
|
||||
--sithego-mention-badge: rgba(220, 20, 60, 0.92);
|
||||
--sithego-mention-bg: rgba(28, 122, 68, 0.18);
|
||||
|
||||
--sithego-radius-sm: 4px;
|
||||
--sithego-radius: 8px;
|
||||
--sithego-radius-lg: 16px;
|
||||
|
||||
--background-primary: transparent;
|
||||
--background-secondary: transparent;
|
||||
--background-secondary-alt: transparent;
|
||||
--background-tertiary: transparent;
|
||||
--background-floating: var(--sithego-panel-bg);
|
||||
--background-base-lowest: transparent;
|
||||
--background-base-low: transparent;
|
||||
--background-base-lower: transparent;
|
||||
--background-base-high: transparent;
|
||||
--background-base-higher: transparent;
|
||||
--background-modifier-hover: var(--sithego-hover);
|
||||
--background-modifier-active: var(--sithego-selected);
|
||||
--background-modifier-selected: var(--sithego-selected-strong);
|
||||
--background-modifier-accent: var(--sithego-hover);
|
||||
|
||||
--text-normal: var(--sithego-text);
|
||||
--text-muted: var(--sithego-muted);
|
||||
--text-link: var(--sithego-accent);
|
||||
--header-primary: var(--sithego-text);
|
||||
--header-secondary: var(--sithego-muted);
|
||||
--interactive-normal: var(--sithego-text);
|
||||
--interactive-hover: var(--sithego-accent);
|
||||
--interactive-active: var(--sithego-text);
|
||||
--interactive-muted: var(--sithego-muted);
|
||||
|
||||
--channels-default: var(--sithego-muted);
|
||||
--channeltextarea-background: var(--sithego-input-bg);
|
||||
--scrollbar-thin-thumb: var(--sithego-border-alpha);
|
||||
--scrollbar-thin-track: transparent;
|
||||
|
||||
--button-filled-brand-background: var(--sithego-selected-strong);
|
||||
--button-filled-brand-background-hover: rgba(28, 122, 68, 0.36);
|
||||
--button-filled-brand-background-active: rgba(28, 122, 68, 0.42);
|
||||
|
||||
--status-danger: var(--sithego-warn);
|
||||
--info-danger-foreground: var(--sithego-warn);
|
||||
--border-subtle: var(--sithego-border-alpha);
|
||||
--border-normal: var(--sithego-border-alpha);
|
||||
}
|
||||
|
||||
/* fully transparent app shell */
|
||||
html,
|
||||
body,
|
||||
#app-mount,
|
||||
[class*="app_"],
|
||||
[class*="bg_"],
|
||||
[class*="layer_"],
|
||||
[class*="layers_"],
|
||||
[class*="base_"],
|
||||
[class*="container_"],
|
||||
[class*="content_"],
|
||||
[class*="chat_"],
|
||||
[class*="sidebar_"],
|
||||
[class*="membersWrap_"],
|
||||
[class*="members_"],
|
||||
[class*="panels_"],
|
||||
[class*="standardSidebarView_"],
|
||||
[class*="contentRegion_"],
|
||||
[class*="sidebarRegion_"],
|
||||
[class*="peopleColumn_"],
|
||||
[class*="nowPlayingColumn_"],
|
||||
[class*="applicationStore_"],
|
||||
[class*="pageWrapper_"],
|
||||
main,
|
||||
section {
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
color: var(--sithego-text) !important;
|
||||
}
|
||||
|
||||
/* guild bar */
|
||||
[class*="guilds_"] {
|
||||
background: var(--sithego-guilds-bg) !important;
|
||||
border-right: 1px solid var(--sithego-border-alpha) !important;
|
||||
backdrop-filter: none !important;
|
||||
-webkit-backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
/* keep guild/server icon containers crisp */
|
||||
[data-list-item-id^="guildsnav_"],
|
||||
[data-list-item-id^="guildsnav_"] *,
|
||||
[class*="guilds_"] [class*="listItem_"],
|
||||
[class*="guilds_"] [class*="blobContainer_"],
|
||||
[class*="guilds_"] [class*="wrapper_"],
|
||||
[class*="guilds_"] svg,
|
||||
[class*="guilds_"] img,
|
||||
[class*="guilds_"] foreignObject {
|
||||
backdrop-filter: none !important;
|
||||
-webkit-backdrop-filter: none !important;
|
||||
filter: none !important;
|
||||
}
|
||||
|
||||
/* glass panels */
|
||||
[class*="sidebar_"] nav,
|
||||
[class*="chatContent_"],
|
||||
[class*="members_"],
|
||||
[class*="panels_"],
|
||||
[class*="container_"][class*="themed_"],
|
||||
[class*="header_"],
|
||||
[class*="title_"],
|
||||
[class*="searchBar_"],
|
||||
[class*="menu_"],
|
||||
[class*="root_"],
|
||||
[class*="modal_"],
|
||||
[class*="autocomplete_"],
|
||||
[class*="messagesPopoutWrap_"],
|
||||
[class*="contentWrapper_"],
|
||||
[class*="drawerSizingWrapper_"],
|
||||
[class*="focusLock_"],
|
||||
[class*="card_"],
|
||||
[class*="bar_"],
|
||||
[class*="footer_"],
|
||||
form {
|
||||
background: var(--sithego-panel-bg) !important;
|
||||
border: 1px solid var(--sithego-border-alpha) !important;
|
||||
border-radius: var(--sithego-radius) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
box-shadow: none !important;
|
||||
backdrop-filter: blur(12px) !important;
|
||||
-webkit-backdrop-filter: blur(12px) !important;
|
||||
}
|
||||
|
||||
/* inputs */
|
||||
input,
|
||||
textarea,
|
||||
[class*="input_"],
|
||||
[class*="channelTextArea_"],
|
||||
[class*="editor_"] {
|
||||
background: var(--sithego-input-bg) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
border: 1px solid var(--sithego-border-alpha) !important;
|
||||
border-radius: var(--sithego-radius-sm) !important;
|
||||
box-shadow: none !important;
|
||||
backdrop-filter: blur(10px) !important;
|
||||
-webkit-backdrop-filter: blur(10px) !important;
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
button,
|
||||
[class*="button_"],
|
||||
[role="button"],
|
||||
[class*="item_"],
|
||||
[class*="tabBarItem_"] {
|
||||
background: transparent !important;
|
||||
border: 1px solid transparent !important;
|
||||
border-radius: var(--sithego-radius-sm) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
button:hover,
|
||||
[class*="button_"]:hover,
|
||||
[role="button"]:hover,
|
||||
[class*="item_"]:hover,
|
||||
[class*="interactive_"]:hover,
|
||||
[class*="clickable_"]:hover {
|
||||
background: var(--sithego-hover) !important;
|
||||
color: var(--sithego-accent) !important;
|
||||
border-color: var(--sithego-border-alpha) !important;
|
||||
}
|
||||
|
||||
[class*="selected_"],
|
||||
[class*="modeSelected_"],
|
||||
[class*="item_"][aria-selected="true"],
|
||||
[class*="clickable_"][class*="selected_"],
|
||||
[aria-checked="true"] {
|
||||
background: var(--sithego-selected) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
border-color: rgba(28, 122, 68, 0.45) !important;
|
||||
}
|
||||
|
||||
/* regular text */
|
||||
[class*="markup_"],
|
||||
[class*="messageContent_"],
|
||||
[class*="topic_"],
|
||||
[class*="title_"],
|
||||
[class*="defaultColor"],
|
||||
[class*="text-md"],
|
||||
[class*="text-sm"],
|
||||
[class*="text-xs"] {
|
||||
color: var(--sithego-text) !important;
|
||||
}
|
||||
|
||||
/* muted secondary text */
|
||||
[class*="subtext_"],
|
||||
[class*="description_"],
|
||||
[class*="hint_"],
|
||||
[class*="membersGroup_"],
|
||||
[class*="channelName_"],
|
||||
[class*="subtitle_"] {
|
||||
color: var(--sithego-muted) !important;
|
||||
}
|
||||
|
||||
a,
|
||||
[class*="anchor_"] {
|
||||
color: var(--sithego-accent) !important;
|
||||
}
|
||||
|
||||
/* generic icons */
|
||||
[class*="icon_"] {
|
||||
color: var(--sithego-muted) !important;
|
||||
}
|
||||
|
||||
button:hover [class*="icon_"],
|
||||
[class*="button_"]:hover [class*="icon_"],
|
||||
[class*="item_"]:hover [class*="icon_"],
|
||||
[class*="selected_"] [class*="icon_"] {
|
||||
color: var(--sithego-accent) !important;
|
||||
}
|
||||
|
||||
/* keep guild icons visible */
|
||||
[class*="guilds_"] svg,
|
||||
[data-list-item-id^="guildsnav_"] svg,
|
||||
[class*="blobContainer_"] svg,
|
||||
[class*="listItem_"] svg {
|
||||
color: inherit !important;
|
||||
fill: currentColor !important;
|
||||
}
|
||||
|
||||
/* keep guild list scrollable */
|
||||
[class*="guilds_"] [class*="scroller_"] {
|
||||
overflow-y: auto !important;
|
||||
overflow-x: visible !important;
|
||||
}
|
||||
|
||||
/* let native guild indicator render outside bounds */
|
||||
[class*="guilds_"] [class*="listItem_"],
|
||||
[class*="guilds_"] [class*="blobContainer_"],
|
||||
[class*="guilds_"] [class*="wrapper_"],
|
||||
[class*="guilds_"] [class*="overlay_"],
|
||||
[data-list-item-id^="guildsnav_"],
|
||||
[data-list-item-id^="guildsnav_"] > div {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* position guild items so the native indicator can anchor correctly */
|
||||
[class*="listItem_"],
|
||||
[class*="blobContainer_"] {
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
/* native guild unread/selected indicator wrapper */
|
||||
[class*="guilds_"] [class*="overlay_"],
|
||||
[class*="guilds_"] [class*="wrapper_"][aria-hidden="true"] {
|
||||
overflow: visible !important;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
z-index: 40 !important;
|
||||
}
|
||||
|
||||
/* native indicator element */
|
||||
[class*="guilds_"] [class*="overlay_"] [class*="item_"],
|
||||
[class*="guilds_"] [class*="wrapper_"][aria-hidden="true"] [class*="item_"] {
|
||||
display: block !important;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
background: var(--sithego-accent) !important;
|
||||
border-radius: 999px !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* preserve the small unread pill */
|
||||
[class*="guilds_"] [class*="overlay_"] [class*="item_"][style*="height: 8px"],
|
||||
[class*="guilds_"] [class*="wrapper_"][aria-hidden="true"] [class*="item_"][style*="height: 8px"] {
|
||||
width: 10px !important;
|
||||
height: 10px !important;
|
||||
min-height: 10px !important;
|
||||
}
|
||||
|
||||
/* preserve the larger active/unread variant */
|
||||
[class*="guilds_"] [class*="overlay_"] [class*="item_"][style*="height: 40px"],
|
||||
[class*="guilds_"] [class*="overlay_"] [class*="item_"][style*="height: 32px"],
|
||||
[class*="guilds_"] [class*="overlay_"] [class*="item_"][style*="height: 24px"],
|
||||
[class*="guilds_"] [class*="wrapper_"][aria-hidden="true"] [class*="item_"][style*="height: 40px"],
|
||||
[class*="guilds_"] [class*="wrapper_"][aria-hidden="true"] [class*="item_"][style*="height: 32px"],
|
||||
[class*="guilds_"] [class*="wrapper_"][aria-hidden="true"] [class*="item_"][style*="height: 24px"] {
|
||||
width: 4px !important;
|
||||
height: 20px !important;
|
||||
min-height: 20px !important;
|
||||
}
|
||||
|
||||
/* don't let selected guild styling hide the native rail */
|
||||
[class*="guilds_"] [aria-selected="true"] {
|
||||
box-shadow: inset 0 0 0 1px rgba(28, 122, 68, 0.35) !important;
|
||||
}
|
||||
|
||||
/* keep guild badges visible */
|
||||
[class*="guilds_"] [class*="numberBadge_"],
|
||||
[class*="guilds_"] [class*="iconBadge_"],
|
||||
[class*="guilds_"] [class*="lowerBadge_"],
|
||||
[class*="guilds_"] [class*="upperBadge_"] {
|
||||
background: var(--sithego-accent) !important;
|
||||
color: #080c08 !important;
|
||||
border: 1px solid rgba(220, 20, 60, 0.45) !important;
|
||||
border-radius: 999px !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* CHANNEL INDICATORS */
|
||||
[class*="modeUnreadImportant_"],
|
||||
[class*="modeUnread_"],
|
||||
[class*="channel_"][class*="unread_"] {
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
[class*="modeUnreadImportant_"] [class*="name_"],
|
||||
[class*="modeUnread_"] [class*="name_"],
|
||||
[class*="channel_"][class*="unread_"] [class*="name_"] {
|
||||
color: var(--sithego-accent) !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
[class*="modeUnreadImportant_"]::before,
|
||||
[class*="modeUnread_"]::before,
|
||||
[class*="channel_"][class*="unread_"]::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 6px;
|
||||
bottom: 6px;
|
||||
width: 3px;
|
||||
border-radius: 999px;
|
||||
background: var(--sithego-accent) !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
[class*="unread_"][class*="wrapper_"],
|
||||
[class*="wrapper_"][aria-label] [class*="unread_"],
|
||||
[class*="content_"] [class*="unread_"] {
|
||||
background: var(--sithego-accent) !important;
|
||||
color: var(--sithego-accent) !important;
|
||||
opacity: 1 !important;
|
||||
border-radius: 999px !important;
|
||||
}
|
||||
|
||||
/* channel mention badges */
|
||||
[class*="children_"] > [class*="numberBadge_"],
|
||||
[class*="link_"] [class*="numberBadge_"],
|
||||
[class*="containerDefault_"] [class*="numberBadge_"] {
|
||||
background: var(--sithego-accent) !important;
|
||||
color: #080c08 !important;
|
||||
border: 1px solid rgba(220, 20, 60, 0.45) !important;
|
||||
border-radius: 999px !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* mention-highlighted channels */
|
||||
[class*="modeUnreadImportant_"][class*="mentions_"],
|
||||
[class*="modeSelected_"][class*="mentions_"] {
|
||||
background: rgba(220, 20, 60, 0.10) !important;
|
||||
border-radius: var(--sithego-radius-sm) !important;
|
||||
}
|
||||
|
||||
/* mention badges */
|
||||
[class*="numberBadge_"],
|
||||
[class*="iconBadge_"],
|
||||
[class*="mentionsBadge_"],
|
||||
[class*="badge_"] {
|
||||
border-radius: 999px !important;
|
||||
}
|
||||
|
||||
[class*="numberBadge_"]:not([style*="background-color: rgb(36, 128, 70)"]),
|
||||
[class*="mentionsBadge_"],
|
||||
[class*="stack_"] > [class*="badge_"] {
|
||||
background: var(--sithego-mention-badge) !important;
|
||||
color: #080c08 !important;
|
||||
border: 1px solid rgba(220, 20, 60, 0.45) !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* mentioned messages */
|
||||
[class*="mentioned_"] {
|
||||
background: var(--sithego-mention-bg) !important;
|
||||
border-left: 2px solid var(--sithego-accent) !important;
|
||||
}
|
||||
|
||||
[class*="mentioned_"]::before {
|
||||
background: var(--sithego-accent) !important;
|
||||
}
|
||||
|
||||
/* unread / jump bars */
|
||||
[class*="newMessagesBar_"],
|
||||
[class*="jumpToPresentBar_"] {
|
||||
background: var(--sithego-selected-strong) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
border: 1px solid rgba(28, 122, 68, 0.40) !important;
|
||||
border-radius: var(--sithego-radius-sm) !important;
|
||||
}
|
||||
/* keep channel scroller unread bars readable */
|
||||
[class*="unreadTop_"],
|
||||
[class*="unreadBottom_"] {
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
padding: 0 !important;
|
||||
min-height: 0 !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* style only the actual unread bar */
|
||||
[class*="unreadTop_"] > [class*="unreadBar_"],
|
||||
[class*="unreadBottom_"] > [class*="unreadBar_"],
|
||||
[class*="unreadTop_"] > [class*="bar_"][class*="unread_"],
|
||||
[class*="unreadBottom_"] > [class*="bar_"][class*="unread_"] {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
width: calc(100% - 12px) !important;
|
||||
min-width: 0 !important;
|
||||
height: 18px !important;
|
||||
min-height: 18px !important;
|
||||
margin: 0 6px !important;
|
||||
padding: 0 8px !important;
|
||||
background: var(--sithego-selected) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
border: 1px solid rgba(28, 122, 68, 0.35) !important;
|
||||
border-radius: 999px !important;
|
||||
box-shadow: none !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
/* unread bar containers should stay invisible */
|
||||
[class*="unreadTop_"],
|
||||
[class*="unreadBottom_"] {
|
||||
background: transparent !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
min-height: 0 !important;
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* style only the actual unread bar */
|
||||
[class*="unreadTop_"] > [class*="unreadBar_"],
|
||||
[class*="unreadBottom_"] > [class*="unreadBar_"],
|
||||
[class*="unreadTop_"] > [class*="bar_"][class*="unread_"],
|
||||
[class*="unreadBottom_"] > [class*="bar_"][class*="unread_"] {
|
||||
display: inline-flex !important;
|
||||
flex-direction: row !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
position: relative !important;
|
||||
inset: auto !important;
|
||||
width: calc(100% - 12px) !important;
|
||||
max-width: calc(100% - 12px) !important;
|
||||
min-width: 0 !important;
|
||||
height: 18px !important;
|
||||
min-height: 18px !important;
|
||||
margin: 0 6px !important;
|
||||
padding: 0 8px !important;
|
||||
background: var(--sithego-selected) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
border: 1px solid rgba(28, 122, 68, 0.35) !important;
|
||||
border-radius: 999px !important;
|
||||
box-shadow: none !important;
|
||||
opacity: 1 !important;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
/* keep the unread bar text centered inside the pill */
|
||||
[class*="unreadTop_"] > [class*="unreadBar_"] [class*="text_"],
|
||||
[class*="unreadBottom_"] > [class*="unreadBar_"] [class*="text_"],
|
||||
[class*="unreadTop_"] > [class*="bar_"][class*="unread_"] [class*="text_"],
|
||||
[class*="unreadBottom_"] > [class*="bar_"][class*="unread_"] [class*="text_"] {
|
||||
display: inline !important;
|
||||
position: static !important;
|
||||
inset: auto !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
line-height: 1 !important;
|
||||
font-size: 10px !important;
|
||||
font-weight: 700 !important;
|
||||
letter-spacing: 0.04em !important;
|
||||
text-align: center !important;
|
||||
color: var(--sithego-text) !important;
|
||||
white-space: nowrap !important;
|
||||
transform: none !important;
|
||||
translate: none !important;
|
||||
top: auto !important;
|
||||
bottom: auto !important;
|
||||
left: auto !important;
|
||||
right: auto !important;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
/* neutralize pseudo elements that can offset label placement */
|
||||
[class*="unreadTop_"] > [class*="unreadBar_"]::before,
|
||||
[class*="unreadBottom_"] > [class*="unreadBar_"]::before,
|
||||
[class*="unreadTop_"] > [class*="unreadBar_"]::after,
|
||||
[class*="unreadBottom_"] > [class*="unreadBar_"]::after,
|
||||
[class*="unreadTop_"] > [class*="bar_"][class*="unread_"]::before,
|
||||
[class*="unreadBottom_"] > [class*="bar_"][class*="unread_"]::before,
|
||||
[class*="unreadTop_"] > [class*="bar_"][class*="unread_"]::after,
|
||||
[class*="unreadBottom_"] > [class*="bar_"][class*="unread_"]::after {
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
/* don't turn structural unread wrappers into pills */
|
||||
[class*="wrapper_"][aria-label] [class*="unread_"]:not([class*="unreadBar_"]):not([class*="unreadTop_"]):not([class*="unreadBottom_"]):not([class*="bar_"]),
|
||||
[class*="content_"] [class*="unread_"]:not([class*="unreadBar_"]):not([class*="unreadTop_"]):not([class*="unreadBottom_"]):not([class*="bar_"]) {
|
||||
background: var(--sithego-accent) !important;
|
||||
color: var(--sithego-accent) !important;
|
||||
opacity: 1 !important;
|
||||
border-radius: 999px !important;
|
||||
}
|
||||
|
||||
/* don't turn structural unread wrappers into green pills */
|
||||
[class*="wrapper_"][aria-label] [class*="unread_"]:not([class*="unreadBar_"]):not([class*="unreadTop_"]):not([class*="unreadBottom_"]):not([class*="bar_"]),
|
||||
[class*="content_"] [class*="unread_"]:not([class*="unreadBar_"]):not([class*="unreadTop_"]):not([class*="unreadBottom_"]):not([class*="bar_"]) {
|
||||
background: var(--sithego-accent) !important;
|
||||
color: var(--sithego-accent) !important;
|
||||
opacity: 1 !important;
|
||||
border-radius: 999px !important;
|
||||
}
|
||||
/* mention pills */
|
||||
[class*="mention"] {
|
||||
background: var(--sithego-mention-bg) !important;
|
||||
color: var(--sithego-accent) !important;
|
||||
border: 1px solid rgba(220, 20, 60, 0.35) !important;
|
||||
}
|
||||
|
||||
/* separators */
|
||||
[class*="divider_"],
|
||||
hr {
|
||||
border-color: var(--sithego-border-alpha) !important;
|
||||
}
|
||||
|
||||
/* danger */
|
||||
[class*="error_"],
|
||||
[class*="danger_"],
|
||||
[class*="colorDanger"] {
|
||||
color: var(--sithego-warn) !important;
|
||||
}
|
||||
|
||||
[class*="lookFilled_"][class*="colorBrand_"] {
|
||||
background: var(--button-filled-brand-background) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
border-color: rgba(28, 122, 68, 0.45) !important;
|
||||
}
|
||||
|
||||
[class*="lookFilled_"][class*="colorRed_"] {
|
||||
background: var(--sithego-danger-bg) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
border-color: rgba(220, 20, 60, 0.45) !important;
|
||||
}
|
||||
|
||||
/* attached autocomplete / emote popup */
|
||||
[class*="autocompleteAttached_"],
|
||||
[class*="autocompleteAttached_"] [class*="container_"],
|
||||
[class*="autocompleteAttached_"] [class*="content_"],
|
||||
[class*="autocompleteAttached_"] [class*="scroller_"],
|
||||
[class*="autocompleteAttached_"] [class*="header_"] {
|
||||
background: var(--sithego-surface) !important;
|
||||
border-color: var(--sithego-border-alpha) !important;
|
||||
color: var(--sithego-text) !important;
|
||||
}
|
||||
|
||||
[class*="clickable_"][role="option"] > [class*="base_"]:hover,
|
||||
[class*="clickable_"][role="option"][aria-selected="true"] > [class*="base_"] {
|
||||
background: var(--sithego-accent) !important;
|
||||
}
|
||||
|
||||
/* scrollbars */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--sithego-border-alpha) !important;
|
||||
border-radius: var(--sithego-radius-sm) !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
body {
|
||||
--custom-guild-sidebar-width: 500px !important;
|
||||
--user-area-width: 450px !important;
|
||||
--custom-member-list-width: 550px !important;
|
||||
}
|
||||
|
||||
[class*="topBar_"] {
|
||||
position: fixed !important;
|
||||
top: -600px !important;
|
||||
left: 50% !important;
|
||||
transform: translateX(-50%) !important;
|
||||
z-index: 1000 !important;
|
||||
width: 800px !important;
|
||||
|
||||
color: var(--sithego-accent) !important;
|
||||
|
||||
padding: 12px 16px !important;
|
||||
background: var(--sithego-bg) !important;
|
||||
border: 1px solid var(--sithego-border-alpha) !important;
|
||||
border-radius: var(--sithego-radius) !important;
|
||||
backdrop-filter: blur(12px) !important;
|
||||
-webkit-backdrop-filter: blur(12px) !important;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"input": {
|
||||
"blocklist": [],
|
||||
"compressor": {
|
||||
"attack": 20.0,
|
||||
"boost-amount": 6.0,
|
||||
"boost-threshold": -72.0,
|
||||
"hpf-frequency": 10.0,
|
||||
"hpf-mode": "off",
|
||||
"input-gain": 0.0,
|
||||
"knee": -6.0,
|
||||
"lpf-frequency": 20000.0,
|
||||
"lpf-mode": "off",
|
||||
"makeup": 0.0,
|
||||
"mode": "Downward",
|
||||
"output-gain": 0.0,
|
||||
"ratio": 4.0,
|
||||
"release": 100.0,
|
||||
"release-threshold": -120.0,
|
||||
"sidechain": {
|
||||
"lookahead": 0.0,
|
||||
"mode": "RMS",
|
||||
"preamp": 0.0,
|
||||
"reactivity": 10.0,
|
||||
"source": "Middle",
|
||||
"type": "Feed-forward"
|
||||
},
|
||||
"threshold": -12.0
|
||||
},
|
||||
"deesser": {
|
||||
"detection": "RMS",
|
||||
"f1-freq": 6000.0,
|
||||
"f1-level": 0.0,
|
||||
"f2-freq": 4500.0,
|
||||
"f2-level": 12.0,
|
||||
"f2-q": 1.0,
|
||||
"input-gain": 0.0,
|
||||
"laxity": 15,
|
||||
"makeup": 0.0,
|
||||
"mode": "Wide",
|
||||
"output-gain": 0.0,
|
||||
"ratio": 3.0,
|
||||
"sc-listen": false,
|
||||
"threshold": -18.0
|
||||
},
|
||||
"filter": {
|
||||
"frequency": 80.0,
|
||||
"inertia": 20.0,
|
||||
"input-gain": 0.0,
|
||||
"mode": "12dB/oct Highpass",
|
||||
"output-gain": 0.0,
|
||||
"resonance": -3.0
|
||||
},
|
||||
"gate": {
|
||||
"attack": 5.0,
|
||||
"detection": "RMS",
|
||||
"input-gain": 0.0,
|
||||
"knee": 9.0,
|
||||
"makeup": 0.0,
|
||||
"output-gain": 0.0,
|
||||
"range": -12.0,
|
||||
"ratio": 2.0,
|
||||
"release": 100.0,
|
||||
"stereo-link": "Average",
|
||||
"threshold": -18.0
|
||||
},
|
||||
"limiter": {
|
||||
"alr": false,
|
||||
"alr-attack": 5.0,
|
||||
"alr-knee": 0.0,
|
||||
"alr-release": 50.0,
|
||||
"attack": 5.0,
|
||||
"dithering": "None",
|
||||
"external-sidechain": false,
|
||||
"gain-boost": true,
|
||||
"input-gain": 0.0,
|
||||
"lookahead": 5.0,
|
||||
"mode": "Herm Thin",
|
||||
"output-gain": 0.0,
|
||||
"oversampling": "None",
|
||||
"release": 5.0,
|
||||
"sidechain-preamp": 0.0,
|
||||
"stereo-link": 100.0,
|
||||
"threshold": -1.0
|
||||
},
|
||||
"plugins_order": [
|
||||
"gate",
|
||||
"compressor",
|
||||
"filter",
|
||||
"deesser",
|
||||
"rnnoise",
|
||||
"limiter"
|
||||
],
|
||||
"rnnoise": {
|
||||
"input-gain": 0.0,
|
||||
"model-path": "",
|
||||
"output-gain": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
<#
|
||||
.Synopsis
|
||||
Activate a Python virtual environment for the current PowerShell session.
|
||||
|
||||
.Description
|
||||
Pushes the python executable for a virtual environment to the front of the
|
||||
$Env:PATH environment variable and sets the prompt to signify that you are
|
||||
in a Python virtual environment. Makes use of the command line switches as
|
||||
well as the `pyvenv.cfg` file values present in the virtual environment.
|
||||
|
||||
.Parameter VenvDir
|
||||
Path to the directory that contains the virtual environment to activate. The
|
||||
default value for this is the parent of the directory that the Activate.ps1
|
||||
script is located within.
|
||||
|
||||
.Parameter Prompt
|
||||
The prompt prefix to display when this virtual environment is activated. By
|
||||
default, this prompt is the name of the virtual environment folder (VenvDir)
|
||||
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
|
||||
|
||||
.Example
|
||||
Activate.ps1
|
||||
Activates the Python virtual environment that contains the Activate.ps1 script.
|
||||
|
||||
.Example
|
||||
Activate.ps1 -Verbose
|
||||
Activates the Python virtual environment that contains the Activate.ps1 script,
|
||||
and shows extra information about the activation as it executes.
|
||||
|
||||
.Example
|
||||
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
|
||||
Activates the Python virtual environment located in the specified location.
|
||||
|
||||
.Example
|
||||
Activate.ps1 -Prompt "MyPython"
|
||||
Activates the Python virtual environment that contains the Activate.ps1 script,
|
||||
and prefixes the current prompt with the specified string (surrounded in
|
||||
parentheses) while the virtual environment is active.
|
||||
|
||||
.Notes
|
||||
On Windows, it may be required to enable this Activate.ps1 script by setting the
|
||||
execution policy for the user. You can do this by issuing the following PowerShell
|
||||
command:
|
||||
|
||||
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||
|
||||
For more information on Execution Policies:
|
||||
https://go.microsoft.com/fwlink/?LinkID=135170
|
||||
|
||||
#>
|
||||
Param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[String]
|
||||
$VenvDir,
|
||||
[Parameter(Mandatory = $false)]
|
||||
[String]
|
||||
$Prompt
|
||||
)
|
||||
|
||||
<# Function declarations --------------------------------------------------- #>
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Remove all shell session elements added by the Activate script, including the
|
||||
addition of the virtual environment's Python executable from the beginning of
|
||||
the PATH variable.
|
||||
|
||||
.Parameter NonDestructive
|
||||
If present, do not remove this function from the global namespace for the
|
||||
session.
|
||||
|
||||
#>
|
||||
function global:deactivate ([switch]$NonDestructive) {
|
||||
# Revert to original values
|
||||
|
||||
# The prior prompt:
|
||||
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
|
||||
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
|
||||
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
|
||||
}
|
||||
|
||||
# The prior PYTHONHOME:
|
||||
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
|
||||
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
|
||||
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
|
||||
}
|
||||
|
||||
# The prior PATH:
|
||||
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
|
||||
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
|
||||
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
|
||||
}
|
||||
|
||||
# Just remove the VIRTUAL_ENV altogether:
|
||||
if (Test-Path -Path Env:VIRTUAL_ENV) {
|
||||
Remove-Item -Path env:VIRTUAL_ENV
|
||||
}
|
||||
|
||||
# Just remove VIRTUAL_ENV_PROMPT altogether.
|
||||
if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
|
||||
Remove-Item -Path env:VIRTUAL_ENV_PROMPT
|
||||
}
|
||||
|
||||
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
|
||||
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
|
||||
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
|
||||
}
|
||||
|
||||
# Leave deactivate function in the global namespace if requested:
|
||||
if (-not $NonDestructive) {
|
||||
Remove-Item -Path function:deactivate
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Description
|
||||
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
|
||||
given folder, and returns them in a map.
|
||||
|
||||
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
|
||||
two strings separated by `=` (with any amount of whitespace surrounding the =)
|
||||
then it is considered a `key = value` line. The left hand string is the key,
|
||||
the right hand is the value.
|
||||
|
||||
If the value starts with a `'` or a `"` then the first and last character is
|
||||
stripped from the value before being captured.
|
||||
|
||||
.Parameter ConfigDir
|
||||
Path to the directory that contains the `pyvenv.cfg` file.
|
||||
#>
|
||||
function Get-PyVenvConfig(
|
||||
[String]
|
||||
$ConfigDir
|
||||
) {
|
||||
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
|
||||
|
||||
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
|
||||
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
|
||||
|
||||
# An empty map will be returned if no config file is found.
|
||||
$pyvenvConfig = @{ }
|
||||
|
||||
if ($pyvenvConfigPath) {
|
||||
|
||||
Write-Verbose "File exists, parse `key = value` lines"
|
||||
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
|
||||
|
||||
$pyvenvConfigContent | ForEach-Object {
|
||||
$keyval = $PSItem -split "\s*=\s*", 2
|
||||
if ($keyval[0] -and $keyval[1]) {
|
||||
$val = $keyval[1]
|
||||
|
||||
# Remove extraneous quotations around a string value.
|
||||
if ("'""".Contains($val.Substring(0, 1))) {
|
||||
$val = $val.Substring(1, $val.Length - 2)
|
||||
}
|
||||
|
||||
$pyvenvConfig[$keyval[0]] = $val
|
||||
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
|
||||
}
|
||||
}
|
||||
}
|
||||
return $pyvenvConfig
|
||||
}
|
||||
|
||||
|
||||
<# Begin Activate script --------------------------------------------------- #>
|
||||
|
||||
# Determine the containing directory of this script
|
||||
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||
$VenvExecDir = Get-Item -Path $VenvExecPath
|
||||
|
||||
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
|
||||
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
|
||||
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
|
||||
|
||||
# Set values required in priority: CmdLine, ConfigFile, Default
|
||||
# First, get the location of the virtual environment, it might not be
|
||||
# VenvExecDir if specified on the command line.
|
||||
if ($VenvDir) {
|
||||
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
|
||||
}
|
||||
else {
|
||||
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
|
||||
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
|
||||
Write-Verbose "VenvDir=$VenvDir"
|
||||
}
|
||||
|
||||
# Next, read the `pyvenv.cfg` file to determine any required value such
|
||||
# as `prompt`.
|
||||
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
|
||||
|
||||
# Next, set the prompt from the command line, or the config file, or
|
||||
# just use the name of the virtual environment folder.
|
||||
if ($Prompt) {
|
||||
Write-Verbose "Prompt specified as argument, using '$Prompt'"
|
||||
}
|
||||
else {
|
||||
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
|
||||
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
|
||||
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
|
||||
$Prompt = $pyvenvCfg['prompt'];
|
||||
}
|
||||
else {
|
||||
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
|
||||
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
|
||||
$Prompt = Split-Path -Path $venvDir -Leaf
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose "Prompt = '$Prompt'"
|
||||
Write-Verbose "VenvDir='$VenvDir'"
|
||||
|
||||
# Deactivate any currently active virtual environment, but leave the
|
||||
# deactivate function in place.
|
||||
deactivate -nondestructive
|
||||
|
||||
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
|
||||
# that there is an activated venv.
|
||||
$env:VIRTUAL_ENV = $VenvDir
|
||||
|
||||
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
||||
|
||||
Write-Verbose "Setting prompt to '$Prompt'"
|
||||
|
||||
# Set the prompt to include the env name
|
||||
# Make sure _OLD_VIRTUAL_PROMPT is global
|
||||
function global:_OLD_VIRTUAL_PROMPT { "" }
|
||||
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
|
||||
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
|
||||
|
||||
function global:prompt {
|
||||
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
|
||||
_OLD_VIRTUAL_PROMPT
|
||||
}
|
||||
$env:VIRTUAL_ENV_PROMPT = $Prompt
|
||||
}
|
||||
|
||||
# Clear PYTHONHOME
|
||||
if (Test-Path -Path Env:PYTHONHOME) {
|
||||
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
|
||||
Remove-Item -Path Env:PYTHONHOME
|
||||
}
|
||||
|
||||
# Add the venv to the PATH
|
||||
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
|
||||
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user