|
|
@@ -1,21 +1,33 @@
|
|
|
<template>
|
|
|
- <div class="content no-pad">
|
|
|
+ <div class="tab-installed">
|
|
|
<header class="flex">
|
|
|
<div class="flex-auto">
|
|
|
- <button v-text="i18n('buttonNew')" @click="newScript"></button>
|
|
|
- <button v-text="i18n('buttonUpdateAll')" @click="updateAll"></button>
|
|
|
- <button v-text="i18n('buttonInstallFromURL')" @click="installFromURL"></button>
|
|
|
- </div>
|
|
|
- <div v-dropdown>
|
|
|
- <button dropdown-toggle v-text="i18n('anchorGetMoreScripts')"></button>
|
|
|
- <div class="dropdown-menu">
|
|
|
- <a href="https://openuserjs.org/" target="_blank">OpenUserJS</a>
|
|
|
- <a href="https://greasyfork.org/scripts" target="_blank">GreasyFork</a>
|
|
|
+ <div v-dropdown="{autoClose: true}">
|
|
|
+ <button dropdown-toggle>
|
|
|
+ <svg class="icon"><use xlink:href="#plus" /></svg>
|
|
|
+ </button>
|
|
|
+ <div class="dropdown-menu">
|
|
|
+ <a href="#" v-text="i18n('buttonNew')" @click.prevent="newScript"></a>
|
|
|
+ <a v-text="i18n('installFrom', 'OpenUserJS')" href="https://openuserjs.org/" target="_blank"></a>
|
|
|
+ <a v-text="i18n('installFrom', 'GreasyFork')" href="https://greasyfork.org/scripts" target="_blank"></a>
|
|
|
+ <a href="#" v-text="i18n('buttonInstallFromURL')" @click.prevent="installFromURL"></a>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+ <tooltip :title="i18n('buttonUpdateAll')" placement="down">
|
|
|
+ <button @click="updateAll">
|
|
|
+ <svg class="icon"><use xlink:href="#refresh" /></svg>
|
|
|
+ </button>
|
|
|
+ </tooltip>
|
|
|
+ </div>
|
|
|
+ <div class="filter-search">
|
|
|
+ <input type="text" :placeholder="i18n('labelSearchScript')" v-model="search">
|
|
|
+ <svg class="icon"><use xlink:href="#search" /></svg>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
</div>
|
|
|
</header>
|
|
|
<div class="scripts">
|
|
|
- <item v-for="script in store.scripts" :key="script"
|
|
|
+ <item v-for="script in scripts" :key="script.id"
|
|
|
:script="script" @edit="editScript" @move="moveScript"></item>
|
|
|
</div>
|
|
|
<div class="backdrop" :class="{mask: store.loading}" v-show="message">
|
|
|
@@ -26,22 +38,30 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { i18n, sendMessage, noop } from 'src/common';
|
|
|
+import { i18n, sendMessage, noop, debounce } from 'src/common';
|
|
|
import Item from './script-item';
|
|
|
import Edit from './edit';
|
|
|
import { store, showMessage } from '../utils';
|
|
|
+import Tooltip from './tooltip';
|
|
|
|
|
|
export default {
|
|
|
components: {
|
|
|
Item,
|
|
|
Edit,
|
|
|
+ Tooltip,
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
store,
|
|
|
script: null,
|
|
|
+ search: null,
|
|
|
+ scripts: store.scripts,
|
|
|
};
|
|
|
},
|
|
|
+ watch: {
|
|
|
+ search: 'onUpdate',
|
|
|
+ 'store.scripts': 'onUpdate',
|
|
|
+ },
|
|
|
computed: {
|
|
|
message() {
|
|
|
if (this.store.loading) {
|
|
|
@@ -50,9 +70,19 @@ export default {
|
|
|
if (!this.store.scripts.length) {
|
|
|
return i18n('labelNoScripts');
|
|
|
}
|
|
|
+ if (!this.scripts.length) {
|
|
|
+ return i18n('labelNoSearchScripts');
|
|
|
+ }
|
|
|
},
|
|
|
},
|
|
|
methods: {
|
|
|
+ onUpdate: debounce(function onUpdate() {
|
|
|
+ const { search } = this;
|
|
|
+ const { scripts } = this.store;
|
|
|
+ this.scripts = search
|
|
|
+ ? scripts.filter(script => (script._search || '').includes(search.toLowerCase()))
|
|
|
+ : scripts;
|
|
|
+ }, 200),
|
|
|
newScript() {
|
|
|
sendMessage({ cmd: 'NewScript' })
|
|
|
.then((script) => {
|
|
|
@@ -62,6 +92,9 @@ export default {
|
|
|
updateAll() {
|
|
|
sendMessage({ cmd: 'CheckUpdateAll' });
|
|
|
},
|
|
|
+ openURL(url) {
|
|
|
+ window.open(url);
|
|
|
+ },
|
|
|
installFromURL() {
|
|
|
new Promise((resolve, reject) => {
|
|
|
showMessage({
|
|
|
@@ -124,10 +157,35 @@ export default {
|
|
|
</script>
|
|
|
|
|
|
<style>
|
|
|
+.tab-installed {
|
|
|
+ padding: 0;
|
|
|
+ > header {
|
|
|
+ height: 3rem;
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 .5rem;
|
|
|
+ line-height: 1.5;
|
|
|
+ border-bottom: 1px solid darkgray;
|
|
|
+ }
|
|
|
+ .dropdown-menu {
|
|
|
+ padding: .5rem;
|
|
|
+ white-space: nowrap;
|
|
|
+ > a {
|
|
|
+ display: block;
|
|
|
+ width: 100%;
|
|
|
+ padding: .5rem;
|
|
|
+ text-decoration: none;
|
|
|
+ color: #666;
|
|
|
+ &:hover {
|
|
|
+ color: inherit;
|
|
|
+ background: #fbfbfb;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
.backdrop,
|
|
|
.scripts {
|
|
|
position: absolute;
|
|
|
- top: 2rem;
|
|
|
+ top: 3rem;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
@@ -154,4 +212,19 @@ export default {
|
|
|
background: rgba(0,0,0,.08);
|
|
|
/*transition: opacity 1s;*/
|
|
|
}
|
|
|
+.filter-search {
|
|
|
+ position: relative;
|
|
|
+ width: 12rem;
|
|
|
+ .icon {
|
|
|
+ position: absolute;
|
|
|
+ height: 100%;
|
|
|
+ top: 0;
|
|
|
+ right: .5rem;
|
|
|
+ }
|
|
|
+ > input {
|
|
|
+ padding-left: .5rem;
|
|
|
+ padding-right: 2rem;
|
|
|
+ line-height: 2;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|