commit
5a3aa553cd
|
@ -0,0 +1,232 @@
|
|||
const dummyTags = ['dark', 'light', 'simple', 'minimal', 'extra', 'something', 'tag', 'whatever', 'another', 'transparent'];
|
||||
|
||||
export default class ServerEmu {
|
||||
|
||||
static async themes(args) {
|
||||
if (!this._themes) this._themes = this.generateThemes();
|
||||
|
||||
await new Promise(r => setTimeout(r, Math.random() * 3000));
|
||||
|
||||
let docs = [];
|
||||
|
||||
if (args && args.sterm) {
|
||||
const { sterm } = args;
|
||||
const reg = new RegExp(sterm, 'gi');
|
||||
docs = this._themes.filter(doc => doc.tags.includes(sterm) || reg.exec(doc.name) || reg.exec(doc.description));
|
||||
} else {
|
||||
docs = this._themes;
|
||||
}
|
||||
|
||||
if (args.sort) {
|
||||
switch (args.sort) {
|
||||
case 'updated':
|
||||
if (args.ascending) docs = docs.sort((docA, docB) => new Date(docA.updated).getTime() - new Date(docB.updated).getTime());
|
||||
else docs = docs.sort((docA, docB) => new Date(docB.updated).getTime() - new Date(docA.updated).getTime());
|
||||
break;
|
||||
case 'installs':
|
||||
if (args.ascending) docs = docs.sort((docA, docB) => docA.installs - docB.installs);
|
||||
else docs = docs.sort((docA, docB) => docB.installs - docA.installs);
|
||||
break;
|
||||
case 'users':
|
||||
if (args.ascending) docs = docs.sort((docA, docB) => docA.activeUsers - docB.activeUsers);
|
||||
else docs = docs.sort((docA, docB) => docB.activeUsers - docA.activeUsers);
|
||||
break;
|
||||
case 'rating':
|
||||
if (args.ascending) docs = docs.sort((docA, docB) => docA.rating - docB.rating);
|
||||
else docs = docs.sort((docA, docB) => docB.rating - docA.rating);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const total = docs.length;
|
||||
const pages = Math.ceil(total / 9);
|
||||
|
||||
let page = 1;
|
||||
if (args && args.page) {
|
||||
page = args.page;
|
||||
docs = docs.slice((page - 1) * 9, page * 9);
|
||||
} else {
|
||||
docs = docs.slice(0, 9);
|
||||
}
|
||||
|
||||
return {
|
||||
docs,
|
||||
filters: {
|
||||
sterm: args.sterm || '',
|
||||
ascending: args.ascending || false,
|
||||
sort: args.sort || 'name'
|
||||
},
|
||||
pagination: {
|
||||
total,
|
||||
pages,
|
||||
limit: 9,
|
||||
page
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async plugins(args) {
|
||||
if (!this._plugins) this._plugins = this.generatePlugins();
|
||||
|
||||
await new Promise(r => setTimeout(r, Math.random() * 3000));
|
||||
|
||||
let docs = [];
|
||||
|
||||
if (args && args.sterm) {
|
||||
const { sterm } = args;
|
||||
const reg = new RegExp(sterm, 'gi');
|
||||
docs = this._plugins.filter(doc => doc.tags.includes(sterm) || reg.exec(doc.name) || reg.exec(doc.description));
|
||||
} else {
|
||||
docs = this._plugins;
|
||||
}
|
||||
|
||||
if (args.sort) {
|
||||
switch (args.sort) {
|
||||
case 'updated':
|
||||
if (args.ascending) docs = docs.sort((docA, docB) => new Date(docA.updated).getTime() - new Date(docB.updated).getTime());
|
||||
else docs = docs.sort((docA, docB) => new Date(docB.updated).getTime() - new Date(docA.updated).getTime());
|
||||
break;
|
||||
case 'installs':
|
||||
if (args.ascending) docs = docs.sort((docA, docB) => docA.installs - docB.installs);
|
||||
else docs = docs.sort((docA, docB) => docB.installs - docA.installs);
|
||||
break;
|
||||
case 'users':
|
||||
if (args.ascending) docs = docs.sort((docA, docB) => docA.activeUsers - docB.activeUsers);
|
||||
else docs = docs.sort((docA, docB) => docB.activeUsers - docA.activeUsers);
|
||||
break;
|
||||
case 'rating':
|
||||
if (args.ascending) docs = docs.sort((docA, docB) => docA.rating - docB.rating);
|
||||
else docs = docs.sort((docA, docB) => docB.rating - docA.rating);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const total = docs.length;
|
||||
const pages = Math.ceil(total / 9);
|
||||
|
||||
let page = 1;
|
||||
if (args && args.page) {
|
||||
page = args.page;
|
||||
docs = docs.slice((page - 1) * 9, page * 9);
|
||||
} else {
|
||||
docs = docs.slice(0, 9);
|
||||
}
|
||||
|
||||
return {
|
||||
docs,
|
||||
filters: {
|
||||
sterm: args.sterm || '',
|
||||
ascending: args.ascending || false,
|
||||
sort: args.sort || 'name'
|
||||
},
|
||||
pagination: {
|
||||
total,
|
||||
pages,
|
||||
limit: 9,
|
||||
page
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static generateThemes() {
|
||||
const docs = [];
|
||||
const count = Math.floor(Math.random() * 50 + 30);
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const id = `theme${i}-${this.randomId()}`;
|
||||
const name = `Dummy Theme ${i}`;
|
||||
const tags = dummyTags.sort(() => .5 - Math.random()).slice(0, 3);
|
||||
|
||||
docs.push({
|
||||
id,
|
||||
name,
|
||||
tags,
|
||||
installs: Math.floor(Math.random() * 5000) + 5000,
|
||||
updated: this.randomTimestamp(),
|
||||
rating: Math.floor(Math.random() * 500) + 500,
|
||||
activeUsers: Math.floor(Math.random() * 1000) + 1000,
|
||||
rated: Math.random() > .5,
|
||||
version: this.randomVersion(),
|
||||
repository: this.dummyThemeRepo,
|
||||
files: this.dummyFiles,
|
||||
author: this.dummyAuthor,
|
||||
description: ''
|
||||
});
|
||||
}
|
||||
|
||||
return docs;
|
||||
}
|
||||
|
||||
static generatePlugins() {
|
||||
const docs = [];
|
||||
const count = Math.floor(Math.random() * 50 + 30);
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const id = `plugin${i}-${this.randomId()}`;
|
||||
const name = `Dummy Plugin ${i}`;
|
||||
const tags = dummyTags.sort(() => .5 - Math.random()).slice(0, 3);
|
||||
|
||||
docs.push({
|
||||
id,
|
||||
name,
|
||||
tags,
|
||||
installs: Math.floor(Math.random() * 5000) + 5000,
|
||||
updated: this.randomTimestamp(),
|
||||
rating: Math.floor(Math.random() * 500) + 500,
|
||||
activeUsers: Math.floor(Math.random() * 1000) + 1000,
|
||||
rated: Math.random() > .5,
|
||||
version: this.randomVersion(),
|
||||
repository: this.dummyPluginRepo,
|
||||
files: this.dummyFiles,
|
||||
author: this.dummyAuthor,
|
||||
description: ''
|
||||
});
|
||||
}
|
||||
|
||||
return docs;
|
||||
}
|
||||
|
||||
static get dummyThemeRepo() {
|
||||
return {
|
||||
name: 'ExampleRepository',
|
||||
baseUri: 'https://github.com/Jiiks/ExampleRepository',
|
||||
rawUri: 'https://github.com/Jiiks/ExampleRepository/raw/master',
|
||||
assetUri: 'https://api.github.com/repos/Jiiks/ExampleRepository/releases/assets/10023264'
|
||||
}
|
||||
}
|
||||
|
||||
static get dummyPluginRepo() {
|
||||
return {
|
||||
name: 'ExampleRepository',
|
||||
baseUri: 'https://github.com/Jiiks/ExampleRepository',
|
||||
rawUri: 'https://github.com/Jiiks/ExampleRepository/raw/master',
|
||||
assetUri: 'https://api.github.com/repos/Jiiks/ExampleRepository/releases/assets/10023265'
|
||||
}
|
||||
}
|
||||
|
||||
static get dummyFiles() {
|
||||
return {
|
||||
readme: 'Example/readme.md',
|
||||
previews: [{
|
||||
large: 'Example/preview1-big.png',
|
||||
thumb: 'Example/preview1-small.png'
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
static get dummyAuthor() {
|
||||
return 'Someone';
|
||||
}
|
||||
|
||||
static randomId() {
|
||||
return btoa(Math.random()).substring(3, 9);
|
||||
}
|
||||
|
||||
static randomTimestamp() {
|
||||
return `2018-${Math.floor((Math.random() * 12) + 1).toString().padStart(2, '0')}-${Math.floor((Math.random() * 30) + 1).toString().padStart(2, '0')}T14:51:32.057Z`;
|
||||
}
|
||||
|
||||
static randomVersion() {
|
||||
return `${Math.round(Math.random() * 3)}.${Math.round(Math.random() * 10)}.${Math.round(Math.random() * 10)}`;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
import { DOM, BdUI, BdMenu, Modals, Toasts, Notifications, BdContextMenu, DiscordContextMenu } from 'ui';
|
||||
import BdCss from './styles/index.scss';
|
||||
import { Events, CssEditor, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, Vendor, Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi, BdWebApi, Connectivity, Cache, Reflection } from 'modules';
|
||||
import { Events, CssEditor, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, Vendor, Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi, BdWebApi, Connectivity, Cache, Reflection, PackageInstaller } from 'modules';
|
||||
import { ClientLogger as Logger, ClientIPC, Utils } from 'common';
|
||||
import { BuiltinManager, EmoteModule, ReactDevtoolsModule, VueDevtoolsModule, TrackingProtection, E2EE } from 'builtin';
|
||||
import electron from 'electron';
|
||||
|
@ -31,7 +31,7 @@ class BetterDiscord {
|
|||
DOM, BdUI, BdMenu, Modals, Reflection, Toasts, Notifications, BdContextMenu, DiscordContextMenu,
|
||||
|
||||
Events, CssEditor, Globals, Settings, Database, Updater,
|
||||
ModuleManager, PluginManager, ThemeManager, ExtModuleManager,
|
||||
ModuleManager, PluginManager, ThemeManager, ExtModuleManager, PackageInstaller,
|
||||
Vendor,
|
||||
|
||||
Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi,
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import ServerEmu from '../dev/serveremu';
|
||||
|
||||
import { request } from 'vendor';
|
||||
|
||||
const APIBASE = 'ifyouareinwebtestthenyouknowwhatthisshouldbe'; // Do not push
|
||||
|
@ -19,54 +21,6 @@ const ENDPOINTS = {
|
|||
'statistics': `${APIBASE}/statistics`
|
||||
};
|
||||
|
||||
const dummyTags = ['tag1', 'tag2', 'tag3', 'tag4', 'tag5'];
|
||||
const dummyRepo = {
|
||||
name: 'ExampleRepository',
|
||||
baseUri: 'https://github.com/Jiiks/ExampleRepository',
|
||||
rawUri: 'https://github.com/Jiiks/ExampleRepository/raw/master'
|
||||
};
|
||||
const dummyVersion = () => `${Math.round(Math.random() * 3)}.${Math.round(Math.random() * 10)}.${Math.round(Math.random() * 10)}`;
|
||||
const dummyFiles = {
|
||||
readme: 'Example/readme.md',
|
||||
previews: [{
|
||||
large: 'Example/preview1-big.png',
|
||||
thumb: 'Example/preview1-small.png'
|
||||
}]
|
||||
};
|
||||
const dummyAuthor = 'DummyAuthor';
|
||||
const dummyTimestamp = () => `2018-${Math.floor((Math.random() * 12) + 1).toString().padStart(2, '0')}-${Math.floor((Math.random() * 30) + 1).toString().padStart(2, '0')}T14:51:32.057Z`;
|
||||
|
||||
async function dummyThemes() {
|
||||
// Simulate get
|
||||
await new Promise(r => setTimeout(r, Math.random() * 3000));
|
||||
const dummies = [];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
dummies.push({
|
||||
id: `theme${i}${btoa(Math.random()).substring(3, 9)}`,
|
||||
name: `Dummy ${i}`,
|
||||
tags: dummyTags,
|
||||
installs: Math.floor(Math.random() * 10000),
|
||||
updated: dummyTimestamp(),
|
||||
rating: Math.floor(Math.random() * 1000),
|
||||
activeUsers: Math.floor(Math.random() * 1000),
|
||||
rated: Math.random() > .5,
|
||||
version: dummyVersion(),
|
||||
repository: dummyRepo,
|
||||
files: dummyFiles,
|
||||
author: dummyAuthor
|
||||
});
|
||||
}
|
||||
return {
|
||||
docs: dummies,
|
||||
pagination: {
|
||||
total: 25,
|
||||
pages: 3,
|
||||
limit: 9,
|
||||
page: 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default class BdWebApi {
|
||||
|
||||
static get themes() {
|
||||
|
@ -75,6 +29,12 @@ export default class BdWebApi {
|
|||
};
|
||||
}
|
||||
|
||||
static get plugins() {
|
||||
return {
|
||||
get: this.getPlugins
|
||||
};
|
||||
}
|
||||
|
||||
static get users() {
|
||||
return {
|
||||
get: this.getUsers
|
||||
|
@ -89,7 +49,8 @@ export default class BdWebApi {
|
|||
}
|
||||
|
||||
static getThemes(args) {
|
||||
return dummyThemes();
|
||||
return ServerEmu.themes(args);
|
||||
// return dummyThemes();
|
||||
/*
|
||||
if (!args) return request.get(ENDPOINTS.themes);
|
||||
const { id } = args;
|
||||
|
@ -99,6 +60,10 @@ export default class BdWebApi {
|
|||
*/
|
||||
}
|
||||
|
||||
static getPlugins(args) {
|
||||
return ServerEmu.plugins(args);
|
||||
}
|
||||
|
||||
static getUsers(args) {
|
||||
if (!args) return request.get(ENDPOINTS.users);
|
||||
const { id } = args;
|
||||
|
|
|
@ -103,7 +103,7 @@ export default class PackageInstaller {
|
|||
}
|
||||
|
||||
/**
|
||||
* Install package from remote location. Only github/bdapi is supoorted.
|
||||
* Install package from remote location. Only github/bdapi is supported.
|
||||
* @param {String} remoteLocation Remote resource location
|
||||
*/
|
||||
static async installRemotePackage(remoteLocation) {
|
||||
|
@ -113,6 +113,7 @@ export default class PackageInstaller {
|
|||
|
||||
const options = {
|
||||
uri: remoteLocation,
|
||||
encoding: null,
|
||||
headers: {
|
||||
'User-Agent': 'BetterDiscordClient',
|
||||
'Accept': 'application/octet-stream'
|
||||
|
@ -122,9 +123,10 @@ export default class PackageInstaller {
|
|||
const response = await request.get(options);
|
||||
const outputPath = path.join(Globals.getPath('tmp'), Security.hash('sha256', response, 'hex'));
|
||||
fs.writeFileSync(outputPath, response);
|
||||
console.log('response', response);
|
||||
console.log('output', outputPath);
|
||||
|
||||
await this.dragAndDropHandler(outputPath);
|
||||
|
||||
rimraf(outputPath, err => {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
|
|
|
@ -33,9 +33,49 @@
|
|||
}
|
||||
|
||||
.bd-searchSort {
|
||||
span {
|
||||
margin-top: 10px;
|
||||
justify-content: flex-end;
|
||||
|
||||
> span {
|
||||
color: #fff;
|
||||
line-height: 40px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
font-size: 12px;
|
||||
height: 14px;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
.bd-sort {
|
||||
display: flex;
|
||||
color: $coldimwhite;
|
||||
font-size: 12px;
|
||||
padding: 3px;
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
transition: color .2s ease-in-out;
|
||||
font-weight: 700;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.bd-active {
|
||||
color: $colbdgreen;
|
||||
}
|
||||
|
||||
.bd-materialDesignIcon {
|
||||
fill: $colbdgreen;
|
||||
}
|
||||
|
||||
svg {
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
&.bd-flipY {
|
||||
.bd-materialDesignIcon {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +84,7 @@
|
|||
margin-top: 10px;
|
||||
|
||||
.bd-spinnerContainer {
|
||||
min-height: 40px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,17 +5,13 @@
|
|||
border-radius: 0;
|
||||
border-bottom: 1px solid rgba(114, 118, 126, .3);
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.005);
|
||||
}
|
||||
|
||||
.bd-remoteCardTitle {
|
||||
color: #b9bbbe;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.bd-remoteCardLikes {
|
||||
color: #f00;
|
||||
color: $colerr;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
@ -52,8 +48,19 @@
|
|||
color: #828a97;
|
||||
font-size: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
|
||||
.bd-remoteCardTag {
|
||||
> div {
|
||||
display: inline;
|
||||
cursor: pointer;
|
||||
margin-left: 2px;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bd-buttonGroup {
|
||||
|
|
|
@ -28,18 +28,31 @@
|
|||
</ScrollerWrap>
|
||||
</div>
|
||||
<div v-else class="bd-onlinePh">
|
||||
<div class="bd-onlinePhHeader">
|
||||
<div class="bd-fancySearch" :class="{'bd-disabled': loadingOnline, 'bd-active': loadingOnline || (onlinePlugins && onlinePlugins.docs)}">
|
||||
<input type="text" class="bd-textInput" placeholder="Search" @keydown.enter="searchInput" @keyup.stop />
|
||||
<div class="bd-onlinePhHeader bd-flexCol">
|
||||
<div class="bd-flex bd-flexRow">
|
||||
<div v-if="loadingOnline" class="bd-spinnerContainer">
|
||||
<div class="bd-spinner7" />
|
||||
</div>
|
||||
<div class="bd-searchHint">{{searchHint}}</div>
|
||||
<div class="bd-fancySearch" :class="{'bd-disabled': loadingOnline, 'bd-active': loadingOnline || (onlinePlugins && onlinePlugins.docs)}">
|
||||
<input type="text" class="bd-textInput" placeholder="Search" @keydown.enter="searchInput" @keyup.stop :value="onlinePlugins.filters.sterm" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="loadingOnline" class="bd-spinnerContainer">
|
||||
<div class="bd-spinner7" />
|
||||
<div class="bd-flex bd-flexRow" v-if="onlinePlugins && onlinePlugins.docs && onlinePlugins.docs.length">
|
||||
<div class="bd-searchSort bd-flex bd-flexGrow">
|
||||
<div v-for="btn in sortBtns"
|
||||
class="bd-sort"
|
||||
:class="{'bd-active': onlinePlugins.filters.sort === btn.toLowerCase(), 'bd-flipY': onlinePlugins.filters.ascending}"
|
||||
@click="sortBy(btn.toLowerCase())">
|
||||
{{btn}}<MiChevronDown v-if="onlinePlugins.filters.sort === btn.toLowerCase()" size="18" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ScrollerWrap class="bd-onlinePhBody" v-if="!loadingOnline && onlinePlugins" :scrollend="scrollend">
|
||||
<RemoteCard v-if="onlinePlugins && onlinePlugins.docs" v-for="plugin in onlinePlugins.docs" :key="plugin.id" :item="plugin" />
|
||||
<div v-if="loadingMore" class="bd-spinnerContainer">
|
||||
<div class="bd-spinner7" />
|
||||
<RemoteCard v-if="onlinePlugins && onlinePlugins.docs" v-for="plugin in onlinePlugins.docs" :key="onlinePlugins.id" :item="plugin" :tagClicked="searchByTag" />
|
||||
<div class="bd-spinnerContainer">
|
||||
<div v-if="loadingMore" class="bd-spinner7" />
|
||||
</div>
|
||||
</ScrollerWrap>
|
||||
</div>
|
||||
|
@ -49,28 +62,45 @@
|
|||
|
||||
<script>
|
||||
// Imports
|
||||
import { PluginManager } from 'modules';
|
||||
import { PluginManager, BdWebApi } from 'modules';
|
||||
import { Modals } from 'ui';
|
||||
import { ClientLogger as Logger } from 'common';
|
||||
import { MiRefresh, ScrollerWrap } from '../common';
|
||||
import { MiRefresh, ScrollerWrap, MiChevronDown } from '../common';
|
||||
import SettingsWrapper from './SettingsWrapper.vue';
|
||||
import PluginCard from './PluginCard.vue';
|
||||
import RemoteCard from './RemoteCard.vue';
|
||||
import RefreshBtn from '../common/RefreshBtn.vue';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
PluginManager,
|
||||
sortBtns: ['Updated', 'Installs', 'Users', 'Rating'],
|
||||
local: true,
|
||||
localPlugins: PluginManager.localPlugins,
|
||||
onlinePlugins: null,
|
||||
onlinePlugins: {
|
||||
docs: [],
|
||||
filters: {
|
||||
sterm: '',
|
||||
sort: 'installs',
|
||||
ascending: false
|
||||
},
|
||||
pagination: {
|
||||
total: 0,
|
||||
pages: 0,
|
||||
limit: 9,
|
||||
page: 1
|
||||
}
|
||||
},
|
||||
loadingOnline: false,
|
||||
loadingMore: false
|
||||
loadingMore: false,
|
||||
searchHint: ''
|
||||
};
|
||||
},
|
||||
components: {
|
||||
SettingsWrapper, PluginCard,
|
||||
MiRefresh, ScrollerWrap,
|
||||
SettingsWrapper, PluginCard, RemoteCard,
|
||||
MiRefresh, MiChevronDown,
|
||||
ScrollerWrap,
|
||||
RefreshBtn
|
||||
},
|
||||
methods: {
|
||||
|
@ -84,7 +114,19 @@
|
|||
await this.PluginManager.refreshPlugins();
|
||||
},
|
||||
async refreshOnline() {
|
||||
// TODO
|
||||
this.searchHint = '';
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
this.loadingOnline = true;
|
||||
try {
|
||||
const getPlugins = await BdWebApi.plugins.get(this.onlinePlugins.filters);
|
||||
this.onlinePlugins = getPlugins;
|
||||
if (!this.onlinePlugins.docs) return;
|
||||
this.searchHint = `${this.onlinePlugins.pagination.total} Results`;
|
||||
} catch (err) {
|
||||
Logger.err('PluginsView', err);
|
||||
} finally {
|
||||
this.loadingOnline = false;
|
||||
}
|
||||
},
|
||||
async togglePlugin(plugin) {
|
||||
// TODO: display error if plugin fails to start/stop
|
||||
|
@ -116,21 +158,45 @@
|
|||
},
|
||||
searchInput(e) {
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
this.onlinePlugins.filters.sterm = e.target.value;
|
||||
this.refreshOnline();
|
||||
},
|
||||
async scrollend(e) {
|
||||
// TODO
|
||||
return;
|
||||
if (this.onlinePlugins.pagination.page >= this.onlinePlugins.pagination.pages) return;
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
this.loadingMore = true;
|
||||
|
||||
try {
|
||||
const getPlugins = await BdWebApi.plugins.get();
|
||||
const getPlugins = await BdWebApi.plugins.get({
|
||||
sterm: this.onlinePlugins.filters.sterm,
|
||||
page: this.onlinePlugins.pagination.page + 1,
|
||||
sort: this.onlinePlugins.filters.sort,
|
||||
ascending: this.onlinePlugins.filters.ascending
|
||||
});
|
||||
|
||||
this.onlinePlugins.docs = [...this.onlinePlugins.docs, ...getPlugins.docs];
|
||||
this.onlinePlugins.filters = getPlugins.filters;
|
||||
this.onlinePlugins.pagination = getPlugins.pagination;
|
||||
} catch (err) {
|
||||
Logger.err('PluginsView', err);
|
||||
} finally {
|
||||
this.loadingMore = false;
|
||||
}
|
||||
},
|
||||
async sortBy(by) {
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
if (this.onlinePlugins.filters.sort === by) {
|
||||
this.onlinePlugins.filters.ascending = !this.onlinePlugins.filters.ascending;
|
||||
} else {
|
||||
this.onlinePlugins.filters.sort = by;
|
||||
this.onlinePlugins.filters.ascending = false;
|
||||
}
|
||||
this.refreshOnline();
|
||||
},
|
||||
async searchByTag(tag) {
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
this.onlinePlugins.filters.sterm = tag;
|
||||
this.refreshOnline();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,13 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="bd-flexRow bd-flex bd-flexGrow">
|
||||
<div class="bd-flexGrow bd-remoteCardTags">{{item.tags.join(', ')}}</div>
|
||||
<div class="bd-flexGrow bd-remoteCardTags">
|
||||
<div v-for="(tag, index) in item.tags" class="bd-remoteCardTag">
|
||||
<div @click="tagClicked(tag)">{{tag}}</div><span v-if="index + 1 < item.tags.length">, </span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bd-buttonGroup">
|
||||
<div class="bd-button">Install</div>
|
||||
<div class="bd-button" @click="install">Install</div>
|
||||
<div class="bd-button">Preview</div>
|
||||
<div class="bd-button" @click="openSourceUrl">Source</div>
|
||||
</div>
|
||||
|
@ -36,17 +40,19 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { Reflection } from 'modules';
|
||||
import { Reflection, PackageInstaller } from 'modules';
|
||||
import { shell } from 'electron';
|
||||
|
||||
export default {
|
||||
props: ['item'],
|
||||
props: ['item', 'tagClicked'],
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
resolveThumb() {
|
||||
return `${this.item.repository.rawUri}/${this.item.files.previews[0].thumb}`;
|
||||
// TODO
|
||||
return '';
|
||||
// return `${this.item.repository.rawUri}/${this.item.files.previews[0].thumb}`;
|
||||
},
|
||||
fromNow() {
|
||||
const { Moment } = Reflection.modules;
|
||||
|
@ -56,6 +62,9 @@
|
|||
if (!this.item.repository || !this.item.repository.baseUri) return;
|
||||
if (Object.assign(document.createElement('a'), { href: this.item.repository.baseUri }).hostname !== 'github.com') return;
|
||||
shell.openExternal(this.item.repository.baseUri);
|
||||
},
|
||||
async install() {
|
||||
await PackageInstaller.installRemotePackage(this.item.repository.assetUri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,23 +35,23 @@
|
|||
</div>
|
||||
<div class="bd-searchHint">{{searchHint}}</div>
|
||||
<div class="bd-fancySearch" :class="{'bd-disabled': loadingOnline, 'bd-active': loadingOnline || (onlineThemes && onlineThemes.docs)}">
|
||||
<input type="text" class="bd-textInput" placeholder="Search" @keydown.enter="searchInput" @keyup.stop />
|
||||
<input type="text" class="bd-textInput" placeholder="Search" @keydown.enter="searchInput" @keyup.stop :value="onlineThemes.filters.sterm"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bd-flex bd-flexRow" v-if="onlineThemes && onlineThemes.docs && onlineThemes.docs.length">
|
||||
<div class="bd-searchSort bd-flex bd-flexGrow">
|
||||
<span class="bd-flexGrow">Sort by:</span>
|
||||
<div class="bd-sort">Name</div>
|
||||
<div class="bd-sort">Updated</div>
|
||||
<div class="bd-sort">Installs</div>
|
||||
<div class="bd-sort">Users</div>
|
||||
<div v-for="btn in sortBtns"
|
||||
class="bd-sort"
|
||||
:class="{'bd-active': onlineThemes.filters.sort === btn.toLowerCase(), 'bd-flipY': onlineThemes.filters.ascending}"
|
||||
@click="sortBy(btn.toLowerCase())">{{btn}}<MiChevronDown v-if="onlineThemes.filters.sort === btn.toLowerCase()" size="18" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ScrollerWrap class="bd-onlinePhBody" v-if="!loadingOnline && onlineThemes" :scrollend="scrollend">
|
||||
<RemoteCard v-if="onlineThemes && onlineThemes.docs" v-for="theme in onlineThemes.docs" :key="theme.id" :item="theme" />
|
||||
<div v-if="loadingMore" class="bd-spinnerContainer">
|
||||
<div class="bd-spinner7"/>
|
||||
<RemoteCard v-if="onlineThemes && onlineThemes.docs" v-for="theme in onlineThemes.docs" :key="theme.id" :item="theme" :tagClicked="searchByTag"/>
|
||||
<div class="bd-spinnerContainer">
|
||||
<div v-if="loadingMore" class="bd-spinner7"/>
|
||||
</div>
|
||||
</ScrollerWrap>
|
||||
</div>
|
||||
|
@ -64,7 +64,7 @@
|
|||
import { ThemeManager, BdWebApi } from 'modules';
|
||||
import { Modals } from 'ui';
|
||||
import { ClientLogger as Logger } from 'common';
|
||||
import { MiRefresh, ScrollerWrap } from '../common';
|
||||
import { MiRefresh, ScrollerWrap, MiChevronDown } from '../common';
|
||||
import SettingsWrapper from './SettingsWrapper.vue';
|
||||
import ThemeCard from './ThemeCard.vue';
|
||||
import RemoteCard from './RemoteCard.vue';
|
||||
|
@ -74,9 +74,23 @@
|
|||
data() {
|
||||
return {
|
||||
ThemeManager,
|
||||
sortBtns: ['Updated', 'Installs', 'Users', 'Rating'],
|
||||
local: true,
|
||||
localThemes: ThemeManager.localThemes,
|
||||
onlineThemes: null,
|
||||
onlineThemes: {
|
||||
docs: [],
|
||||
filters: {
|
||||
sterm: '',
|
||||
sort: 'installs',
|
||||
ascending: false
|
||||
},
|
||||
pagination: {
|
||||
total: 0,
|
||||
pages: 0,
|
||||
limit: 9,
|
||||
page: 1
|
||||
}
|
||||
},
|
||||
loadingOnline: false,
|
||||
loadingMore: false,
|
||||
searchHint: ''
|
||||
|
@ -84,7 +98,8 @@
|
|||
},
|
||||
components: {
|
||||
SettingsWrapper, ThemeCard, RemoteCard,
|
||||
MiRefresh, ScrollerWrap,
|
||||
MiRefresh, MiChevronDown,
|
||||
ScrollerWrap,
|
||||
RefreshBtn
|
||||
},
|
||||
methods: {
|
||||
|
@ -93,7 +108,6 @@
|
|||
},
|
||||
async showOnline() {
|
||||
this.local = false;
|
||||
if (this.loadingOnline || this.onlineThemes) return;
|
||||
},
|
||||
async refreshLocal() {
|
||||
await this.ThemeManager.refreshThemes();
|
||||
|
@ -103,7 +117,7 @@
|
|||
if (this.loadingOnline || this.loadingMore) return;
|
||||
this.loadingOnline = true;
|
||||
try {
|
||||
const getThemes = await BdWebApi.themes.get();
|
||||
const getThemes = await BdWebApi.themes.get(this.onlineThemes.filters);
|
||||
this.onlineThemes = getThemes;
|
||||
if (!this.onlineThemes.docs) return;
|
||||
this.searchHint = `${this.onlineThemes.pagination.total} Results`;
|
||||
|
@ -142,19 +156,45 @@
|
|||
},
|
||||
searchInput(e) {
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
this.onlineThemes.filters.sterm = e.target.value;
|
||||
this.refreshOnline();
|
||||
},
|
||||
async scrollend(e) {
|
||||
if (this.onlineThemes.pagination.page >= this.onlineThemes.pagination.pages) return;
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
this.loadingMore = true;
|
||||
|
||||
try {
|
||||
const getThemes = await BdWebApi.themes.get();
|
||||
const getThemes = await BdWebApi.themes.get({
|
||||
sterm: this.onlineThemes.filters.sterm,
|
||||
page: this.onlineThemes.pagination.page + 1,
|
||||
sort: this.onlineThemes.filters.sort,
|
||||
ascending: this.onlineThemes.filters.ascending
|
||||
});
|
||||
|
||||
this.onlineThemes.docs = [...this.onlineThemes.docs, ...getThemes.docs];
|
||||
this.onlineThemes.filters = getThemes.filters;
|
||||
this.onlineThemes.pagination = getThemes.pagination;
|
||||
} catch (err) {
|
||||
Logger.err('ThemesView', err);
|
||||
} finally {
|
||||
this.loadingMore = false;
|
||||
}
|
||||
},
|
||||
async sortBy(by) {
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
if (this.onlineThemes.filters.sort === by) {
|
||||
this.onlineThemes.filters.ascending = !this.onlineThemes.filters.ascending;
|
||||
} else {
|
||||
this.onlineThemes.filters.sort = by;
|
||||
this.onlineThemes.filters.ascending = false;
|
||||
}
|
||||
this.refreshOnline();
|
||||
},
|
||||
async searchByTag(tag) {
|
||||
if (this.loadingOnline || this.loadingMore) return;
|
||||
this.onlineThemes.filters.sterm = tag;
|
||||
this.refreshOnline();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue