import Logger from "common/logger"; import {React, Strings, WebpackModules, DiscordModules} from "modules"; import SimpleMarkdown from "../../structs/markdown"; import ReloadIcon from "../icons/reload"; import EditIcon from "../icons/edit"; import DeleteIcon from "../icons/delete"; import CogIcon from "../icons/cog"; import Switch from "./components/switch"; import GitHubIcon from "../icons/github"; import MoneyIcon from "../icons/dollarsign"; import WebIcon from "../icons/globe"; import PatreonIcon from "../icons/patreon"; import SupportIcon from "../icons/support"; import ExtIcon from "../icons/extension"; import ThemeIcon from "../icons/theme"; import Modals from "../modals"; import Toasts from "../toasts"; const LinkIcons = { website: WebIcon, source: GitHubIcon, invite: SupportIcon, donate: MoneyIcon, patreon: PatreonIcon }; const Tooltip = WebpackModules.getByDisplayName("Tooltip"); const LayerStack = WebpackModules.getByProps("popLayer"); const UserStore = WebpackModules.getByProps("getCurrentUser"); const ChannelStore = WebpackModules.getByProps("getDMFromUserId"); const PrivateChannelActions = WebpackModules.getByProps("openPrivateChannel"); const ChannelActions = WebpackModules.getByProps("selectPrivateChannel"); export default class AddonCard extends React.Component { constructor(props) { super(props); this.settingsPanel = ""; this.panelRef = React.createRef(); this.onChange = this.onChange.bind(this); this.reload = this.reload.bind(this); this.showSettings = this.showSettings.bind(this); this.messageAuthor = this.messageAuthor.bind(this); } showSettings() { if (!this.props.hasSettings || !this.props.enabled) return; const name = this.getString(this.props.addon.name); try { Modals.showAddonSettingsModal(name, this.props.getSettingsPanel()); } catch (err) { Toasts.show(Strings.Addons.settingsError.format({name}), {type: "error"}); Logger.stacktrace("Addon Settings", "Unable to get settings panel for " + name + ".", err); } } reload() { if (!this.props.reload) return; this.props.addon = this.props.reload(this.props.addon.id); this.forceUpdate(); } getString(value) {return typeof value == "string" ? value : value.toString();} onChange() { this.props.onChange && this.props.onChange(this.props.addon.id); this.props.enabled = !this.props.enabled; this.forceUpdate(); } messageAuthor() { if (!this.props.addon.authorId) return; if (LayerStack) LayerStack.popLayer(); if (!UserStore || !ChannelActions || !ChannelStore || !PrivateChannelActions) return; const selfId = UserStore.getCurrentUser().id; if (selfId == this.props.addon.authorId) return; const privateChannelId = ChannelStore.getDMFromUserId(this.props.addon.authorId); if (privateChannelId) return ChannelActions.selectPrivateChannel(privateChannelId); PrivateChannelActions.openPrivateChannel(selfId, this.props.addon.authorId); } buildTitle(name, version, author) { const authorArray = Strings.Addons.byline.split(/({{[A-Za-z]+}})/); const authorComponent = author.link || author.id ? {author.name} : {author.name}; const authorIndex = authorArray.findIndex(s => s == "{{author}}"); if (authorIndex) authorArray[authorIndex] = authorComponent; return [ React.createElement("div", {className: "bd-name"}, name), React.createElement("div", {className: "bd-meta"}, React.createElement("span", {className: "bd-version"}, `v${version}`), ...authorArray ) ]; } buildLink(which) { const url = this.props.addon[which]; if (!url) return null; const icon = React.createElement(LinkIcons[which]); const link = {icon}; if (which == "invite") { link.props.onClick = function(event) { event.preventDefault(); event.stopPropagation(); let code = url; const tester = /\.gg\/(.*)$/; if (tester.test(code)) code = code.match(tester)[1]; DiscordModules.LayerStack.popLayer(); DiscordModules.InviteActions.acceptInviteAndTransitionToInviteChannel(code); }; } return this.makeButton(Strings.Addons[which], link); } get controls() { // {this.props.hasSettings && } return
{this.props.hasSettings && this.makeControlButton(Strings.Addons.addonSettings, , this.showSettings, {disabled: !this.props.enabled})} {this.props.showReloadIcon && this.makeControlButton(Strings.Addons.reload, , this.reload)} {this.props.editAddon && this.makeControlButton(Strings.Addons.editAddon, , this.props.editAddon)} {this.props.deleteAddon && this.makeControlButton(Strings.Addons.deleteAddon, , this.props.deleteAddon, {danger: true})}
; } get footer() { const links = ["website", "source", "invite", "donate", "patreon"]; const linkComponents = links.map(this.buildLink.bind(this)).filter(c => c);// linkComponents.map((comp, i) => i < linkComponents.length - 1 ? [comp, " | "] : comp).flat() return
{linkComponents} {this.controls}
; } makeButton(title, children, action) { return {(props) => { return
{children}
; }}
; } makeControlButton(title, children, action, {danger = false, disabled = false} = {}) { return {(props) => { return ; }} ; } render() { const addon = this.props.addon; const name = this.getString(addon.name); const author = this.getString(addon.author); const description = this.getString(addon.description); const version = this.getString(addon.version); return
{this.props.type === "plugin" ? : }
{this.buildTitle(name, version, {name: author, id: this.props.addon.authorId, link: this.props.addon.authorLink})}
{SimpleMarkdown.parseToReact(description)}
{this.footer}
; } } const originalRender = AddonCard.prototype.render; Object.defineProperty(AddonCard.prototype, "render", { enumerable: false, configurable: false, set: function() {Logger.warn("AddonCard", "Addon policy for plugins #5 https://github.com/rauenzi/BetterDiscordApp/wiki/Addon-Policies#plugins");}, get: () => originalRender });