Search improvements

pull/144/head
Henrique Dias 2017-06-30 15:02:45 +01:00
parent 39f39cca29
commit 690f515439
No known key found for this signature in database
GPG Key ID: 936F5EB68D786730
2 changed files with 69 additions and 64 deletions

View File

@ -25,7 +25,7 @@
</template> </template>
<script> <script>
import { mapMutations } from 'vuex' import { mapMutations, mapGetters } from 'vuex'
import filesize from 'filesize' import filesize from 'filesize'
import moment from 'moment' import moment from 'moment'
import webdav from '../webdav.js' import webdav from '../webdav.js'
@ -35,8 +35,8 @@ export default {
name: 'item', name: 'item',
props: ['name', 'isDir', 'url', 'type', 'size', 'modified', 'index'], props: ['name', 'isDir', 'url', 'type', 'size', 'modified', 'index'],
methods: { methods: {
// ...mapGetters('selectedCount'), ...mapGetters(['selectedCount']),
...mapMutations('addSelected', 'removeSelected'), ...mapMutations(['addSelected', 'removeSelected']),
icon: function () { icon: function () {
if (this.isDir) return 'folder' if (this.isDir) return 'folder'
if (this.type === 'image') return 'insert_photo' if (this.type === 'image') return 'insert_photo'

View File

@ -1,53 +1,79 @@
<template> <template>
<div id="search" v-on:mouseleave="hover = false" v-on:click="click" v-bind:class="{ active: focus || hover }"> <div id="search" v-on:mouseleave="hover = false" v-on:click="click" v-bind:class="{ active: focus || hover, ongoing }">
<i class="material-icons" title="Search">search</i> <i class="material-icons" title="Search">search</i>
<input type="text" <input type="text"
v-on:focus="focus = true" v-model.trim="value"
v-on:blur="focus = false" v-on:focus="focus = true"
v-on:keyup="keyup" v-on:blur="focus = false"
v-on:keyup.enter="submit" v-on:keyup="keyup"
aria-label="Write here to search" v-on:keyup.enter="submit"
placeholder="Search or execute a command..."> aria-label="Write here to search"
<div v-on:mouseover="hover = true"> :placeholder="placeholder()">
<div>Loading...</div> <div v-on:mouseover="hover = true">
<p><i class="material-icons spin">autorenew</i></p> <div>
</div> <span v-if="search.length === 0 && commands.length === 0">{{ text() }}</span>
<ul v-else-if="search.length > 0">
<li v-for="s in search"><a :href="'.' + s">.{{ s }}</a></li>
</ul>
<ul v-else-if="commands.length > 0">
<li v-for="c in commands">{{ c }}</li>
</ul>
</div>
<p><i class="material-icons spin">autorenew</i></p>
</div> </div>
</div>
</template> </template>
<script> <script>
import page from '../page'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import page from '../page'
export default { export default {
name: 'search', name: 'search',
data: function () { data: function () {
return { return {
value: '',
hover: false, hover: false,
focus: false, focus: false,
ongoing: false,
scrollable: null, scrollable: null,
box: null, search: [],
input: null commands: []
} }
}, },
computed: mapState('user'), computed: mapState(['user']),
mounted: function () { mounted: function () {
this.scrollable = document.querySelector('#search > div') this.scrollable = document.querySelector('#search > div')
this.box = document.querySelector('#search > div div')
this.input = document.querySelector('#search input')
this.reset()
}, },
methods: { methods: {
reset: function () { placeholder: function () {
if (this.user.allowCommands && this.user.commands.length > 0) { if (this.user.allowCommands && this.user.commands.length > 0) {
this.box.innerHTML = `Search or use one of your supported commands: ${this.user.commands.join(', ')}.` return 'Search or execute a command...'
}
return 'Search...'
},
text: function () {
if (this.value.length === 0) {
if (this.user.allowCommands && this.user.commands.length > 0) {
return `Search or use one of your supported commands: ${this.user.commands.join(', ')}.`
}
return 'Type and press enter to search.'
}
if (!this.supported() || !this.user.allowCommands) {
return 'Press enter to search.'
} else { } else {
this.box.innerHTML = 'Type and press enter to search.' return 'Press enter to execute.'
} }
}, },
keyup: function () {
this.search.length = 0
this.commands.length = 0
},
supported: function () { supported: function () {
let value = this.input.value let pieces = this.value.split(' ')
let pieces = value.split(' ')
for (let i = 0; i < this.user.commands.length; i++) { for (let i = 0; i < this.user.commands.length; i++) {
if (pieces[0] === this.user.commands[0]) { if (pieces[0] === this.user.commands[0]) {
@ -61,68 +87,47 @@ export default {
event.currentTarget.classList.add('active') event.currentTarget.classList.add('active')
this.$el.querySelector('input').focus() this.$el.querySelector('input').focus()
}, },
keyup: function (event) {
let el = event.currentTarget
if (el.value.length === 0) {
this.reset()
return
}
if (!this.supported() || !this.user.allowCommands) {
this.box.innerHTML = 'Press enter to search.'
} else {
this.box.innerHTML = 'Press enter to execute.'
}
},
submit: function (event) { submit: function (event) {
this.box.innerHTML = '' this.ongoing = true
this.$el.classList.add('ongoing') let uri = window.location.host + window.location.pathname
let url = window.location.host + window.location.pathname if (this.$store.state.req.kind !== 'listing') {
uri = page.removeLastDir(uri)
if (document.getElementById('editor')) {
url = page.removeLastDir(url)
} }
let protocol = this.$store.state.ssl ? 'wss:' : 'ws:' uri = `${(this.$store.state.ssl ? 'wss:' : 'ws:')}//${uri}`
if (this.supported() && this.user.allowCommands) { if (this.supported() && this.user.allowCommands) {
let conn = new window.WebSocket(`${protocol}//${url}?command=true`) let conn = new window.WebSocket(`${uri}?command=true`)
conn.onopen = () => { conn.onopen = () => conn.send(this.value)
conn.send(this.input.value)
}
conn.onmessage = (event) => { conn.onmessage = (event) => {
this.box.innerHTML = event.data this.commands.push(event.data)
this.scrollable.scrollTop = this.scrollable.scrollHeight this.scrollable.scrollTop = this.scrollable.scrollHeight
} }
conn.onclose = (event) => { conn.onclose = (event) => {
this.$el.classList.remove('ongoing') this.ongoing = false
this.scrollable.scrollTop = this.scrollable.scrollHeight
page.reload() page.reload()
} }
return return
} }
this.box.innerHTML = '<ul></ul>' let conn = new window.WebSocket(`${uri}?search=true`)
let ul = this.box.querySelector('ul') conn.onopen = () => conn.send(this.value)
let conn = new window.WebSocket(`${protocol}//${url}?search=true`)
conn.onopen = () => {
conn.send(this.input.value)
}
conn.onmessage = (event) => { conn.onmessage = (event) => {
ul.innerHTML += `<li><a href=".${event.data}">${event.data}</a></li>` this.search.push(event.data)
this.scrollable.scrollTop = this.scrollable.scrollHeight this.scrollable.scrollTop = this.scrollable.scrollHeight
} }
conn.onclose = () => { conn.onclose = () => {
this.$el.classList.remove('ongoing') this.ongoing = false
this.scrollable.scrollTop = this.scrollable.scrollHeight
} }
} }
} }