Adjusts some more UI elements
This commit is contained in:
parent
5dc472c645
commit
618b577c75
|
@ -195,6 +195,7 @@ export default {
|
|||
},
|
||||
Addons: {
|
||||
title: "{{name}} v{{version}} by {{author}}",
|
||||
byline: "by {{author}}",
|
||||
openFolder: "Open {{type}} Folder",
|
||||
reload: "Reload",
|
||||
addonSettings: "Settings",
|
||||
|
|
|
@ -149,4 +149,6 @@ export default new class ComponentPatcher {
|
|||
});
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
// as part of utility classes, i would like a way to distinguish channel types from the .content-3at_AU element. other than that, can't think of anything
|
|
@ -35,6 +35,7 @@ export default new class PluginManager extends AddonManager {
|
|||
const errors = super.initialize();
|
||||
this.setupFunctions();
|
||||
Settings.registerPanel("plugins", Strings.Panels.plugins, {element: () => SettingsRenderer.getAddonPanel(Strings.Panels.plugins, this.addonList, this.state, {
|
||||
type: this.prefix,
|
||||
folder: this.addonFolder,
|
||||
onChange: this.togglePlugin.bind(this),
|
||||
reload: this.reloadPlugin.bind(this),
|
||||
|
@ -76,10 +77,10 @@ export default new class PluginManager extends AddonManager {
|
|||
const PluginClass = addon.exports;
|
||||
const thePlugin = new PluginClass();
|
||||
addon.instance = thePlugin;
|
||||
addon.name = thePlugin.getName() || addon.name;
|
||||
addon.author = thePlugin.getAuthor() || addon.author || "No author";
|
||||
addon.description = thePlugin.getDescription() || addon.description || "No description";
|
||||
addon.version = thePlugin.getVersion() || addon.version || "No version";
|
||||
addon.name = thePlugin.getName ? thePlugin.getName() : addon.name || "No name";
|
||||
addon.author = thePlugin.getAuthor ? thePlugin.getAuthor() : addon.author || "No author";
|
||||
addon.description = thePlugin.getDescription ? thePlugin.getDescription() : addon.description || "No description";
|
||||
addon.version = thePlugin.getVersion ? thePlugin.getVersion() : addon.version || "No version";
|
||||
try {
|
||||
if (typeof(addon.instance.load) == "function") addon.instance.load();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ export default new class ThemeManager extends AddonManager {
|
|||
initialize() {
|
||||
const errors = super.initialize();
|
||||
Settings.registerPanel("themes", Strings.Panels.themes, {element: () => SettingsRenderer.getAddonPanel(Strings.Panels.themes, this.addonList, this.state, {
|
||||
type: this.prefix,
|
||||
folder: this.addonFolder,
|
||||
onChange: this.toggleTheme.bind(this),
|
||||
reload: this.reloadTheme.bind(this),
|
||||
|
|
|
@ -54,7 +54,7 @@ export default new class PublicServersConnection {
|
|||
if (term) queries.push(`term=${term.replace(/ /g, "%20")}`);
|
||||
if (from) queries.push(`from=${from}`);
|
||||
const query = `?${queries.join("&")}`;
|
||||
|
||||
|
||||
try {
|
||||
const response = await fetch(`${this.endPoint}${query}`, {method: "GET"});
|
||||
const data = await response.json();
|
||||
|
|
|
@ -256,7 +256,12 @@
|
|||
.bd-pagination button:hover,
|
||||
.bd-pagination button:active {
|
||||
opacity: 1;
|
||||
background: transparent;
|
||||
background: var(--background-accent);
|
||||
}
|
||||
|
||||
.bd-pagination button:active {
|
||||
opacity: 1;
|
||||
background: var(--background-secondary);
|
||||
}
|
||||
|
||||
.bd-pagination button svg {
|
||||
|
|
|
@ -36,11 +36,9 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 20px;
|
||||
padding: 16px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
background: var(--background-secondary-alt);
|
||||
border: 1px solid var(--background-tertiary);
|
||||
background: var(--background-secondary);
|
||||
}
|
||||
|
||||
.bd-addon-list.bd-grid-view .bd-addon-card {
|
||||
|
@ -49,6 +47,8 @@
|
|||
|
||||
.bd-addon-list .bd-addon-header {
|
||||
color: var(--header-primary);
|
||||
background: var(--background-secondary-alt);
|
||||
padding: 16px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-weight: 600;
|
||||
|
@ -58,8 +58,42 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bd-addon-header .bd-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.bd-title,
|
||||
.bd-name,
|
||||
.bd-meta {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.bd-title {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.bd-meta {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.bd-name::after,
|
||||
.bd-version::after {
|
||||
display: inline;
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.bd-grid-view .bd-title {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.bd-grid-view .bd-meta {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.bd-description-wrap {
|
||||
flex: 1;
|
||||
padding: 8px 16px 0 16px;
|
||||
}
|
||||
|
||||
.bd-addon-list .bd-description {
|
||||
|
@ -88,8 +122,7 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-top: 8px;
|
||||
border-top: thin solid var(--background-modifier-accent);
|
||||
padding: 8px 16px 16px 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
<div class="bd-drop-container-wrap">
|
||||
<div class="bd-drop-container">
|
||||
<div class="bd-drop-icon"></div>
|
||||
<div class="bd-drop-title">Install Addon</div>
|
||||
<div class="bd-drop-message">Installs this plugin automatically</div>
|
||||
</div>
|
||||
</div>
|
||||
*/
|
||||
|
||||
/*
|
||||
.bd-drop-container-wrap {
|
||||
display: none;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgba(0,0,0,0.7);
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bd-drop-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #3e82e5;
|
||||
padding: 20px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.bd-drop-icon {
|
||||
background: url('https://maxcdn.icons8.com/Share/icon/p1em/Very_Basic/plus1600.png');
|
||||
background-size: contain;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
filter: invert();
|
||||
}
|
||||
|
||||
.bd-drop-title {
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
font-size: 24px;
|
||||
margin-top: 8px
|
||||
}
|
||||
|
||||
.bd-drop-message {
|
||||
color: white;
|
||||
margin-top: 8px;
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,11 @@
|
|||
import {React} from "modules";
|
||||
|
||||
export default class Extension extends React.Component {
|
||||
render() {
|
||||
const size = this.props.size || "24px";
|
||||
return <svg viewBox="0 0 24 24" fill="#FFFFFF" style={{width: size, height: size}} onClick={this.props.onClick} className={this.props.className}>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/>
|
||||
</svg>;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import {React} from "modules";
|
||||
|
||||
export default class Theme extends React.Component {
|
||||
render() {
|
||||
const size = this.props.size || "24px";
|
||||
return <svg viewBox="0 0 24 24" fill="#FFFFFF" style={{width: size, height: size}} onClick={this.props.onClick} className={this.props.className}>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/>
|
||||
</svg>;
|
||||
}
|
||||
}
|
|
@ -267,7 +267,7 @@ export default class Modals {
|
|||
|
||||
const mc = this.ModalComponents;
|
||||
const modal = props => {
|
||||
return React.createElement(mc.ModalRoot, Object.assign({size: mc.ModalSize.SMALL, className: "bd-addon-modal"}, props),
|
||||
return React.createElement(mc.ModalRoot, Object.assign({size: mc.ModalSize.MEDIUM, className: "bd-addon-modal"}, props),
|
||||
React.createElement(mc.ModalHeader, {separator: false, className: "bd-addon-modal-header"},
|
||||
React.createElement(this.FormTitle, {tag: "h4"}, `${name} Settings`),
|
||||
React.createElement(this.FlexElements.Child, {grow: 0},
|
||||
|
|
|
@ -16,8 +16,8 @@ const EMPTY_RESULTS = {
|
|||
servers: [],
|
||||
size: 0,
|
||||
total: 0,
|
||||
page: 0,
|
||||
numPages: 0
|
||||
page: 1,
|
||||
numPages: 1
|
||||
};
|
||||
|
||||
export default class PublicServers extends React.Component {
|
||||
|
@ -166,8 +166,7 @@ export default class PublicServers extends React.Component {
|
|||
return [React.createElement(SettingsTitle, {text: this.title, button: connectButton}),
|
||||
this.state.results.numPages > 1 && this.pagination,
|
||||
content,
|
||||
this.state.results.numPages > 1 && this.pagination,
|
||||
this.state.results.numPages > 1 && this.state.query && React.createElement(SettingsTitle, {text: this.title})
|
||||
this.state.results.numPages > 1 && this.pagination
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -179,6 +178,8 @@ export default class PublicServers extends React.Component {
|
|||
<div className="bd-placeholder-card"></div>
|
||||
<div className="bd-placeholder-card"></div>
|
||||
<div className="bd-placeholder-card"></div>
|
||||
<div className="bd-placeholder-card"></div>
|
||||
<div className="bd-placeholder-card"></div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,14 +78,20 @@ export default new class SettingsRenderer {
|
|||
if (collection.disabled) continue;
|
||||
insert({
|
||||
section: collection.name,
|
||||
label: collection.name,
|
||||
label: collection.name.toString(),
|
||||
className: `bd-${collection.id}-tab`,
|
||||
element: () => this.buildSettingsPanel(collection.id, collection.name, collection.settings, Settings.state[collection.id], Settings.onSettingChange.bind(Settings, collection.id), collection.button ? collection.button : null)
|
||||
});
|
||||
}
|
||||
for (const panel of Settings.panels.sort((a,b) => a.order > b.order)) {
|
||||
if (panel.clickListener) panel.onClick = (event) => panel.clickListener(thisObject, event, returnValue);
|
||||
if (!panel.className) panel.className = `bd-${panel.id}-tab`;
|
||||
if (typeof(panel.label) !== "string") panel.label = panel.label.toString();
|
||||
insert(panel);
|
||||
}
|
||||
// for (const tab of returnValue) {
|
||||
// if (!tab.className) tab.className = `${DOM.escapeID(tab.section).toLowerCase()}-tab`;
|
||||
// }
|
||||
});
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ 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";
|
||||
|
||||
|
@ -23,6 +25,11 @@ const LinkIcons = {
|
|||
};
|
||||
|
||||
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 {
|
||||
|
||||
|
@ -38,6 +45,7 @@ export default class AddonCard extends React.Component {
|
|||
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() {
|
||||
|
@ -66,15 +74,34 @@ export default class AddonCard extends React.Component {
|
|||
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 title = Strings.Addons.title.split(/({{[A-Za-z]+}})/);
|
||||
const nameIndex = title.findIndex(s => s == "{{name}}");
|
||||
if (nameIndex) title[nameIndex] = React.createElement("span", {className: "bd-name"}, name);
|
||||
const versionIndex = title.findIndex(s => s == "{{version}}");
|
||||
if (nameIndex) title[versionIndex] = React.createElement("span", {className: "bd-version"}, version);
|
||||
const authorIndex = title.findIndex(s => s == "{{author}}");
|
||||
if (nameIndex) title[authorIndex] = React.createElement("span", {className: "bd-author"}, author);
|
||||
return title.flat();
|
||||
const authorArray = Strings.Addons.byline.split(/({{[A-Za-z]+}})/);
|
||||
const authorComponent = author.link || author.id
|
||||
? <a className="bd-link bd-link-website" href={author.link || null} onClick={this.messageAuthor} target="_blank" rel="noopener noreferrer">{author.name}</a>
|
||||
: <span className="bd-author">{author.name}</span>;
|
||||
|
||||
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) {
|
||||
|
@ -139,7 +166,8 @@ export default class AddonCard extends React.Component {
|
|||
|
||||
return <div id={`${addon.id}-card`} className="bd-addon-card settings-closed">
|
||||
<div className="bd-addon-header">
|
||||
<span className="bd-title">{this.buildTitle(name, version, author)}</span>
|
||||
{this.props.type === "plugin" ? <ExtIcon size="18px" className="bd-icon" /> : <ThemeIcon size="18px" className="bd-icon" />}
|
||||
<div className="bd-title">{this.buildTitle(name, version, {name: author, id: this.props.addon.authorId, link: this.props.addon.authorLink})}</div>
|
||||
<Switch checked={this.props.enabled} onChange={this.onChange} />
|
||||
</div>
|
||||
<div className="bd-description-wrap scroller-wrap fade"><div className="bd-description scroller">{SimpleMarkdown.parseToReact(description)}</div></div>
|
||||
|
|
|
@ -41,16 +41,16 @@ export default class AddonList extends React.Component {
|
|||
|
||||
onControlChange(control, value) {
|
||||
const addonlistControls = DataStore.getBDData("addonlistControls") || {};
|
||||
if (!addonlistControls[this.props.title.toLowerCase()]) addonlistControls[this.props.title.toLowerCase()] = {};
|
||||
addonlistControls[this.props.title.toLowerCase()][control] = value;
|
||||
if (!addonlistControls[this.props.type]) addonlistControls[this.props.type] = {};
|
||||
addonlistControls[this.props.type][control] = value;
|
||||
DataStore.setBDData("addonlistControls", addonlistControls);
|
||||
}
|
||||
|
||||
getControlState(control, defaultValue) {
|
||||
const addonlistControls = DataStore.getBDData("addonlistControls") || {};
|
||||
if (!addonlistControls[this.props.title.toLowerCase()]) return defaultValue;
|
||||
if (!addonlistControls[this.props.title.toLowerCase()].hasOwnProperty(control)) return defaultValue;
|
||||
return addonlistControls[this.props.title.toLowerCase()][control];
|
||||
if (!addonlistControls[this.props.type]) return defaultValue;
|
||||
if (!addonlistControls[this.props.type].hasOwnProperty(control)) return defaultValue;
|
||||
return addonlistControls[this.props.type][control];
|
||||
}
|
||||
|
||||
update() {
|
||||
|
@ -107,9 +107,9 @@ export default class AddonList extends React.Component {
|
|||
}
|
||||
|
||||
get emptyImage() {
|
||||
const message = Strings.Addons.blankSlateMessage.format({link: `https://betterdiscordlibrary.com/${this.props.title.toLowerCase()}`, type: this.props.title}).toString();
|
||||
return <EmptyImage title={Strings.Addons.blankSlateHeader.format({type: this.props.title})} message={message}>
|
||||
<button className="bd-button" onClick={this.openFolder}>{Strings.Addons.openFolder.format({type: this.props.title})}</button>
|
||||
const message = Strings.Addons.blankSlateMessage.format({link: `https://betterdiscordlibrary.com/${this.props.type}`, type: this.props.type}).toString();
|
||||
return <EmptyImage title={Strings.Addons.blankSlateHeader.format({type: this.props.type})} message={message}>
|
||||
<button className="bd-button" onClick={this.openFolder}>{Strings.Addons.openFolder.format({type: this.props.type})}</button>
|
||||
</EmptyImage>;
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ export default class AddonList extends React.Component {
|
|||
const renderedCards = sortedAddons.map(addon => {
|
||||
const hasSettings = addon.instance && typeof(addon.instance.getSettingsPanel) === "function";
|
||||
const getSettings = hasSettings && addon.instance.getSettingsPanel.bind(addon.instance);
|
||||
return <ErrorBoundary><AddonCard editAddon={this.editAddon.bind(this, addon.id)} deleteAddon={this.deleteAddon.bind(this, addon.id)} showReloadIcon={showReloadIcon} key={addon.id} enabled={addonState[addon.id]} addon={addon} onChange={onChange} reload={reload} hasSettings={hasSettings} getSettingsPanel={getSettings} /></ErrorBoundary>;
|
||||
return <ErrorBoundary><AddonCard type={this.props.type} editAddon={this.editAddon.bind(this, addon.id)} deleteAddon={this.deleteAddon.bind(this, addon.id)} showReloadIcon={showReloadIcon} key={addon.id} enabled={addonState[addon.id]} addon={addon} onChange={onChange} reload={reload} hasSettings={hasSettings} getSettingsPanel={getSettings} /></ErrorBoundary>;
|
||||
});
|
||||
|
||||
const hasAddonsInstalled = this.props.addonList.length !== 0;
|
||||
|
|
Loading…
Reference in New Issue