Merge pull request #266 from JsSucks/content-browser

Content browser
This commit is contained in:
Alexei Stukov 2018-12-06 11:26:26 +02:00 committed by GitHub
commit 5a3aa553cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 462 additions and 100 deletions

232
client/src/dev/serveremu.js Normal file
View File

@ -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)}`;
}
}

View File

@ -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,

View File

@ -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;

View File

@ -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);
});

View File

@ -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;
}

View File

@ -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 {

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}