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, '-') }
|
get id() { return this.name.toLowerCase().replace(/\s+/g, '-') }
|
||||||
|
|
||||||
enable() {
|
enable() {
|
||||||
|
this.userConfig.enabled = true;
|
||||||
DOM.injectTheme(this.css, this.id);
|
DOM.injectTheme(this.css, this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
disable() {
|
disable() {
|
||||||
|
this.userConfig.enabled = false;
|
||||||
DOM.deleteTheme(this.id);
|
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 './sidebarview.scss';
|
||||||
@import './plugins.scss';
|
@import './plugins.scss';
|
||||||
@import './plugincard.scss';
|
@import './plugincard.scss';
|
||||||
|
@import './themecard.scss';
|
||||||
@import './tooltips.scss';
|
@import './tooltips.scss';
|
||||||
@import './plugin-settings-modal.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')}">
|
<div v-if="activeContent('plugins') || animatingContent('plugins')" :class="{active: activeContent('plugins'), animating: animatingContent('plugins')}">
|
||||||
<PluginsView />
|
<PluginsView />
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="activeContent('themes') || animatingContent('themes')" :class="{active: activeContent('themes'), animating: animatingContent('themes')}">
|
||||||
|
<ThemesView />
|
||||||
|
</div>
|
||||||
</ContentColumn>
|
</ContentColumn>
|
||||||
</SidebarView>
|
</SidebarView>
|
||||||
</div>
|
</div>
|
||||||
|
@ -58,7 +61,7 @@
|
||||||
import { shell } from 'electron';
|
import { shell } from 'electron';
|
||||||
import { Settings } from 'modules';
|
import { Settings } from 'modules';
|
||||||
import { SidebarView, Sidebar, SidebarItem, ContentColumn } from './sidebar';
|
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';
|
import { SvgX, MiGithubCircle, MiWeb, MiClose, MiTwitterCircle } from './common';
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
@ -92,7 +95,7 @@
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
SidebarView, Sidebar, SidebarItem, ContentColumn,
|
SidebarView, Sidebar, SidebarItem, ContentColumn,
|
||||||
CoreSettings, UISettings, EmoteSettings, CssEditorView, PluginsView,
|
CoreSettings, UISettings, EmoteSettings, CssEditorView, PluginsView, ThemesView,
|
||||||
MiGithubCircle, MiWeb, MiClose, MiTwitterCircle
|
MiGithubCircle, MiWeb, MiClose, MiTwitterCircle
|
||||||
},
|
},
|
||||||
methods: {
|
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 EmoteSettings } from './EmoteSettings.vue';
|
||||||
export { default as CssEditorView } from './CssEditor.vue';
|
export { default as CssEditorView } from './CssEditor.vue';
|
||||||
export { default as PluginsView } from './PluginsView.vue';
|
export { default as PluginsView } from './PluginsView.vue';
|
||||||
|
export { default as ThemesView } from './ThemesView.vue';
|
||||||
export { default as BdBadge } from './BdBadge.vue';
|
export { default as BdBadge } from './BdBadge.vue';
|
||||||
|
|
Loading…
Reference in New Issue