/** * @name BetterDiscordExperiments * @description Enables the experiments tab in discord's settings, using the JS snippet from Discord Previews. Made with love by Skye and Zrodevkaan * @author Riddim_GLiTCH, Zrodevkaan * @version 1.4 * @source https://github.com/Riddim-GLiTCH/BetterDiscordExperiments * @website https://riddim-glitch.is-a.dev * @invite aYxpgkvdvR */ /* @module @manifest */ const manifest = { "name": "BetterDiscordExperiments", "authors": [{ "name": "Riddim GLiTCH", "discord_id": "801089753038061669", "github_username": "Riddim-GLiTCH" }], "version": "1.2.3", "description": "Enables the experiments tab in discord's settings, using the JS snippet from Discord Previews. Made with love by Skye and Zrodevkaan.", "github": "https://github.com/Riddim-GLiTCH/BetterDiscordExperiments", "github_raw": "https://github.com/Riddim-GLiTCH/BetterDiscordEperiments/raw/main/BetterDiscordExperiments.plugin.js", "changelogImage": "https://RDG.monarchuploader.de/content/cdn/RQLhnpDHgffx/_489399f1-238f-426c-9769-5b79efe95cf6.jpg", "changelogDate": "2024-04-30T11:53:20+0000" }; /*@end*/ const BdApi = window.BdApi; const App = { Webpack: BdApi.Webpack, UI: BdApi.UI, Data: BdApi.Data, DOM: BdApi.DOM, React: { ...BdApi.React, useState: BdApi.React.useState, useEffect: BdApi.React.useEffect, createElement: BdApi.React.createElement, }, Components: { FormSwitch: BdApi.Webpack.getByKeys("FormSwitch"), }, Logs: BdApi.Webpack.getByStrings("logsUploaded:new Date().toISOString(),")(), Classes: BdApi.Webpack.getByKeys("devBanner"), }; const config = { name: "BetterDiscordExperiments", changelog: [ { title: "BDAPI Update", type: "Improved", items: [ "Moved the Plugin to the New BD-API as base.", "Actually Added a Changelog with BDAPI", "Remade Settings Panel with BD-API" ] }, { title: "Bugs Squashed", type: "fixed", items: [ "Attempted to fix random uninjection (hopefully)" ] }, { title: "On-going", type: "progress", items: [ "An option to disable the warning on the experiments page will be added." ] } ], settings: [ { type: "switch", id: "showBanner", name: "Show Developer Staging Branch", note: "Under the user account will show the edition of Discord and your version.", value: true }, { type: "category", id: "non-disable-:)", children: App.React.createElement('span', {style: {color: "gray", fontsize: '10px', bottom: '0', left: '-5px'}}, 'Made with love by Skye and Kaan <3') } ] } const css = ` #experiments-tab { [class^=sectionTitle] { margin-top: 100px; &:before { position: absolute; top: 20px; background-color: rgba(255, 0, 0, 0.200); padding: 5px; border: solid 1px red; border-radius: 5px; padding-bottom: 25px; padding-top: 40px; content: "Enabling some experiments may disrupt Discord's functionality," " and could lead to crashes, bugs, or glitches." " Some features may conflict with the app," " resulting in instability or unexpected behavior." ; text-align: center; color: red; font-size: larger; width: 650px; } &:after { position: absolute; top: 25px; text-align: center; color: red; content: "WARNING!"; font-size: xx-large; font-weight: 900; width: 661px; margin: 0px 5px; } } [class^=children_]:after { position: absolute; top: 120px; text-align: center; content: "Exercise caution, enabling some experiments may risk account suspension."; font-size: larger; color: red; width: 650px; margin: 0px 5px; font-weight: 700; } }`; function GetSetting(settingName) { return App.Data.load(config.name, "settings") || config.settings.find(x => x.id === settingName).value // this is a config. this needs to be a callback-as its always true } function SetSetting(settingName, value) { const mySettings = config.settings.find(x => x.id === settingName) || {}; mySettings.value = value; App.Data.save(config.name, "settings", mySettings); } class experiments { startStagingBanner() { const showBanner = GetSetting("showBanner"); if (!showBanner?.value) { const existingBanner = document.querySelector("[class*=devBanner_]"); if (existingBanner) { existingBanner.remove(); } return; } const existingBanner = document.querySelector("[class*=devBanner_]"); if (existingBanner) { return; } try { const banner = this.createBannerElement(App.Classes, App.Logs); const closeButton = banner.querySelector(`.${App.Classes.closeButton}`); if (closeButton) { closeButton.addEventListener('click', () => { banner.remove(); GetSetting("showBanner").value = false; }); } const panelsContainer = document.querySelector("[class*=panels_]"); if (panelsContainer) { panelsContainer.appendChild(banner); } else { throw new Error("Panels container not found"); } } catch (error) { console.error("Failed to create staging banner:", error); } } createBannerElement(classes, data) { const div = document.createElement("div"); div.className = `${classes.devBanner} ${classes.staging}`; div.style.backgroundColor = "var(--bg-overlay-1,var(--background-secondary-alt))"; const channelName = data.releaseChannel === "ptb" ? "PTB" : data.releaseChannel[0].toUpperCase() + data.releaseChannel.slice(1); div.innerHTML = ` ${channelName} ${data.buildNumber}