Initial themes view with enable/disable functional
This commit is contained in:
parent
2472743660
commit
e7b488316b
|
@ -38,10 +38,12 @@ class Theme {
|
|||
get id() { return this.name.toLowerCase().replace(/\s+/g, '-') }
|
||||
|
||||
enable() {
|
||||
this.userConfig.enabled = true;
|
||||
DOM.injectTheme(this.css, this.id);
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.userConfig.enabled = false;
|
||||
DOM.deleteTheme(this.id);
|
||||
}
|
||||
|
||||
|
@ -72,4 +74,21 @@ export default class extends ContentManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static async loadPlugin(paths, configs, info, main) {
|
||||
const plugin = window.require(paths.mainPath)(Plugin, {}, {});
|
||||
const instance = new plugin({ configs, info, main, paths: { contentPath: paths.contentPath, dirName: paths.dirName } });
|
||||
|
||||
if (instance.enabled) instance.start();
|
||||
return instance;
|
||||
}
|
||||
|
||||
static enableTheme(theme) {
|
||||
theme.enable();
|
||||
}
|
||||
|
||||
static disableTheme(theme) {
|
||||
theme.disable();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
@import './sidebarview.scss';
|
||||
@import './plugins.scss';
|
||||
@import './plugincard.scss';
|
||||
@import './themecard.scss';
|
||||
@import './tooltips.scss';
|
||||
@import './plugin-settings-modal.scss';
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
.bd-theme-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
background: transparent;
|
||||
border-bottom: 1px solid rgba(114, 118, 126, 0.3);
|
||||
padding: 10px 5px;
|
||||
min-height: 150px;
|
||||
color: #b9bbbe;
|
||||
margin-top: 10px;
|
||||
|
||||
.bd-theme-header {
|
||||
padding-bottom: 5px;
|
||||
display: flex;
|
||||
flex-grow: 0;
|
||||
font-weight: 700;
|
||||
align-items: center;
|
||||
|
||||
.bd-theme-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
> span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: #afb1b4;
|
||||
}
|
||||
}
|
||||
|
||||
.bd-theme-body {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
|
||||
.bd-theme-description {
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
max-height: 60px;
|
||||
min-height: 60px;
|
||||
color: #8a8c90;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 5px;
|
||||
border-radius: 8px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.bd-theme-footer {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: flex-end;
|
||||
|
||||
.bd-theme-extra {
|
||||
color: rgba(255, 255, 255, 0.15);
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.bd-controls {
|
||||
.bd-button-group {
|
||||
.bd-button {
|
||||
fill: #FFF;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bd-switch-wrapper {
|
||||
flex: 0 0 auto;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
|
||||
input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.bd-switch {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: #72767d;
|
||||
border-radius: 14px;
|
||||
transition: background .15s ease-in-out,box-shadow .15s ease-in-out,border .15s ease-in-out;
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
background: #f6f6f7;
|
||||
border-radius: 10px;
|
||||
transition: all .15s ease;
|
||||
box-shadow: 0 3px 1px 0 rgba(0,0,0,.05), 0 2px 2px 0 rgba(0,0,0,.1), 0 3px 3px 0 rgba(0,0,0,.05);
|
||||
}
|
||||
|
||||
&.bd-checked {
|
||||
background: $colbdblue;
|
||||
|
||||
&::before {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,6 +49,9 @@
|
|||
<div v-if="activeContent('plugins') || animatingContent('plugins')" :class="{active: activeContent('plugins'), animating: animatingContent('plugins')}">
|
||||
<PluginsView />
|
||||
</div>
|
||||
<div v-if="activeContent('themes') || animatingContent('themes')" :class="{active: activeContent('themes'), animating: animatingContent('themes')}">
|
||||
<ThemesView />
|
||||
</div>
|
||||
</ContentColumn>
|
||||
</SidebarView>
|
||||
</div>
|
||||
|
@ -58,7 +61,7 @@
|
|||
import { shell } from 'electron';
|
||||
import { Settings } from 'modules';
|
||||
import { SidebarView, Sidebar, SidebarItem, ContentColumn } from './sidebar';
|
||||
import { CoreSettings, UISettings, EmoteSettings, CssEditorView, PluginsView } from './bd';
|
||||
import { CoreSettings, UISettings, EmoteSettings, CssEditorView, PluginsView, ThemesView } from './bd';
|
||||
import { SvgX, MiGithubCircle, MiWeb, MiClose, MiTwitterCircle } from './common';
|
||||
|
||||
// Constants
|
||||
|
@ -92,7 +95,7 @@
|
|||
},
|
||||
components: {
|
||||
SidebarView, Sidebar, SidebarItem, ContentColumn,
|
||||
CoreSettings, UISettings, EmoteSettings, CssEditorView, PluginsView,
|
||||
CoreSettings, UISettings, EmoteSettings, CssEditorView, PluginsView, ThemesView,
|
||||
MiGithubCircle, MiWeb, MiClose, MiTwitterCircle
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* BetterDiscord Theme Card Component
|
||||
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
|
||||
* All rights reserved.
|
||||
* https://betterdiscord.net
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
<template>
|
||||
<div class="bd-theme-card">
|
||||
<div class="bd-theme-header">
|
||||
<div class="bd-theme-icon" :style="{backgroundImage: theme.icon ? `url(${theme.icon})` : null}">
|
||||
<MiExtension v-if="!theme.icon" :size="30" />
|
||||
</div>
|
||||
<span>{{theme.name}}</span>
|
||||
<div class="bd-flex-spacer" />
|
||||
<label class="bd-switch-wrapper" @click="() => { toggleTheme(theme); this.$forceUpdate(); }">
|
||||
<input type="checkbox" class="bd-switch-checkbox" />
|
||||
<div class="bd-switch" :class="{'bd-checked': theme.enabled}" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="bd-theme-body">
|
||||
<div class="bd-theme-description">{{theme.description}}</div>
|
||||
<div class="bd-theme-footer">
|
||||
<div class="bd-theme-extra">v{{theme.version}} by {{theme.authors.join(', ').replace(/,(?!.*,)/gmi, ' and')}}</div>
|
||||
<div class="bd-controls">
|
||||
<ButtonGroup>
|
||||
<Button v-tooltip="'Settings'" v-if="theme.hasSettings" :onClick="() => showSettings(theme)">
|
||||
<MiSettings size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Reload'" :onClick="() => reloadTheme(theme)">
|
||||
<MiRefresh size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Edit'" :onClick="editTheme">
|
||||
<MiPencil size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Uninstall'" type="err">
|
||||
<MiDelete size="18" />
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// Imports
|
||||
import { shell } from 'electron';
|
||||
import { Button, ButtonGroup, SettingSwitch, MiSettings, MiRefresh, MiPencil, MiDelete, MiExtension } from '../common';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
settingsOpen: false
|
||||
}
|
||||
},
|
||||
props: ['theme', 'toggleTheme', 'reloadTheme', 'showSettings'],
|
||||
components: {
|
||||
Button, ButtonGroup, SettingSwitch, MiSettings, MiRefresh, MiPencil, MiDelete, MiExtension
|
||||
},
|
||||
methods: {
|
||||
editTheme() {
|
||||
try {
|
||||
shell.openItem(this.theme.themePath);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* BetterDiscord Themes View Component
|
||||
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
|
||||
* All rights reserved.
|
||||
* https://betterdiscord.net
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
<template>
|
||||
<SettingsWrapper headertext="Themes">
|
||||
<div class="bd-flex bd-flex-col bd-themesView">
|
||||
<div class="bd-flex bd-tabheader">
|
||||
<div class="bd-flex-grow bd-button" :class="{'bd-active': local}" @click="showLocal">
|
||||
<h3>Local</h3>
|
||||
<div class="bd-material-button" @click="refreshLocal">
|
||||
<MiRefresh />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bd-flex-grow bd-button" :class="{'bd-active': !local}" @click="showOnline">
|
||||
<h3>Online</h3>
|
||||
<div class="bd-material-button">
|
||||
<MiRefresh />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="local" class="bd-flex bd-flex-grow bd-flex-col bd-themes-container bd-local-themes">
|
||||
<ThemeCard v-for="theme in localThemes" :theme="theme" :key="theme.id" :toggleTheme="toggleTheme" :reloadTheme="reloadTheme" :showSettings="showSettings" />
|
||||
</div>
|
||||
<div v-if="!local" class="bd-spinner-container">
|
||||
<div class="bd-spinner-2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</SettingsWrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Imports
|
||||
import { ThemeManager } from 'modules';
|
||||
import { SettingsWrapper } from './';
|
||||
import { MiRefresh } from '../common';
|
||||
import ThemeCard from './ThemeCard.vue';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
local: true,
|
||||
settingsOpen: null,
|
||||
localThemes: ThemeManager.localThemes
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SettingsWrapper, ThemeCard,
|
||||
MiRefresh
|
||||
},
|
||||
methods: {
|
||||
showLocal() {
|
||||
this.local = true;
|
||||
},
|
||||
showOnline() {
|
||||
this.local = false;
|
||||
},
|
||||
refreshLocal() {
|
||||
(async () => {
|
||||
await ThemeManager.refreshTheme();
|
||||
})();
|
||||
},
|
||||
toggleTheme(theme) {
|
||||
// TODO Display error if theme fails to enable/disable
|
||||
try {
|
||||
if (theme.enabled) {
|
||||
ThemeManager.disableTheme(theme);
|
||||
} else {
|
||||
ThemeManager.enableTheme(theme);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
reloadTheme(theme) {
|
||||
(async () => {
|
||||
try {
|
||||
await ThemeManager.reloadTheme(theme);
|
||||
this.$forceUpdate();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
})();
|
||||
},
|
||||
showSettings(theme) {
|
||||
this.settingsOpen = theme;
|
||||
},
|
||||
closeSettings() {
|
||||
this.settingsOpen = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
|
@ -4,4 +4,5 @@ export { default as UISettings } from './UISettings.vue';
|
|||
export { default as EmoteSettings } from './EmoteSettings.vue';
|
||||
export { default as CssEditorView } from './CssEditor.vue';
|
||||
export { default as PluginsView } from './PluginsView.vue';
|
||||
export { default as ThemesView } from './ThemesView.vue';
|
||||
export { default as BdBadge } from './BdBadge.vue';
|
||||
|
|
Loading…
Reference in New Issue