Files
filebrowser/frontend/src/components/Search.vue
T

202 lines
4.7 KiB
Vue
Raw Normal View History

2018-02-01 12:17:04 +00:00
<template>
2021-03-21 12:51:58 +01:00
<div id="search" @click="open" v-bind:class="{ active, ongoing }">
2018-02-01 12:17:04 +00:00
<div id="input">
2019-01-05 16:12:09 +00:00
<button
v-if="active"
class="action"
@click="close"
:aria-label="$t('buttons.close')"
:title="$t('buttons.close')"
>
2018-02-01 12:17:04 +00:00
<i class="material-icons">arrow_back</i>
</button>
<i v-else class="material-icons">search</i>
2019-01-05 16:12:09 +00:00
<input
type="text"
@keyup.exact="keyup"
2018-02-01 12:17:04 +00:00
@keyup.enter="submit"
ref="input"
:autofocus="active"
v-model.trim="value"
2019-01-05 16:12:09 +00:00
:aria-label="$t('search.search')"
:placeholder="$t('search.search')"
2021-03-21 12:51:58 +01:00
/>
2018-02-01 12:17:04 +00:00
</div>
2019-01-06 10:06:08 +00:00
<div id="result" ref="result">
2018-02-01 12:17:04 +00:00
<div>
2019-01-05 16:12:09 +00:00
<template v-if="isEmpty">
2018-02-01 12:17:04 +00:00
<p>{{ text }}</p>
<template v-if="value.length === 0">
<div class="boxes">
2021-03-21 12:51:58 +01:00
<h3>{{ $t("search.types") }}</h3>
2018-02-01 12:17:04 +00:00
<div>
2019-01-05 16:12:09 +00:00
<div
tabindex="0"
2021-03-21 12:51:58 +01:00
v-for="(v, k) in boxes"
:key="k"
2018-02-01 12:17:04 +00:00
role="button"
2021-03-21 12:51:58 +01:00
@click="init('type:' + k)"
:aria-label="$t('search.' + v.label)"
2019-01-05 16:12:09 +00:00
>
2021-03-21 12:51:58 +01:00
<i class="material-icons">{{ v.icon }}</i>
<p>{{ $t("search." + v.label) }}</p>
2018-02-01 12:17:04 +00:00
</div>
</div>
</div>
</template>
</template>
2019-01-06 10:06:08 +00:00
<ul v-show="results.length > 0">
2021-03-21 12:51:58 +01:00
<li v-for="(s, k) in filteredResults" :key="k">
2020-09-29 14:04:43 +00:00
<router-link @click.native="close" :to="s.url">
2018-02-01 12:17:04 +00:00
<i v-if="s.dir" class="material-icons">folder</i>
<i v-else class="material-icons">insert_drive_file</i>
<span>./{{ s.path }}</span>
</router-link>
</li>
</ul>
</div>
2019-01-05 16:12:09 +00:00
<p id="renew">
<i class="material-icons spin">autorenew</i>
</p>
2018-02-01 12:17:04 +00:00
</div>
</div>
</template>
<script>
2021-03-21 12:51:58 +01:00
import { mapState, mapGetters, mapMutations } from "vuex";
import url from "@/utils/url";
import { search } from "@/api";
2019-01-05 16:12:09 +00:00
var boxes = {
2019-01-05 16:12:09 +00:00
image: { label: "images", icon: "insert_photo" },
audio: { label: "music", icon: "volume_up" },
video: { label: "video", icon: "movie" },
2021-03-21 12:51:58 +01:00
pdf: { label: "pdf", icon: "picture_as_pdf" },
};
2018-02-01 12:17:04 +00:00
export default {
2019-01-05 16:12:09 +00:00
name: "search",
2021-03-21 12:51:58 +01:00
data: function () {
2018-02-01 12:17:04 +00:00
return {
2019-01-05 16:12:09 +00:00
value: "",
2018-02-01 12:17:04 +00:00
active: false,
ongoing: false,
2019-01-05 16:12:09 +00:00
results: [],
2018-07-23 14:48:55 +01:00
reload: false,
resultsCount: 50,
2021-03-21 12:51:58 +01:00
scrollable: null,
};
2018-02-01 12:17:04 +00:00
},
watch: {
2021-03-21 12:51:58 +01:00
show(val, old) {
this.active = val === "search";
2018-02-01 12:17:04 +00:00
2019-01-05 16:12:09 +00:00
if (old === "search" && !this.active) {
2018-02-01 12:17:04 +00:00
if (this.reload) {
2021-03-21 12:51:58 +01:00
this.setReload(true);
2018-02-01 12:17:04 +00:00
}
2021-03-21 12:51:58 +01:00
document.body.style.overflow = "auto";
this.reset();
this.value = "";
this.active = false;
this.$refs.input.blur();
2019-01-05 16:12:09 +00:00
} else if (this.active) {
2021-03-21 12:51:58 +01:00
this.reload = false;
this.$refs.input.focus();
document.body.style.overflow = "hidden";
2018-02-01 12:17:04 +00:00
}
2019-01-06 10:06:08 +00:00
},
2021-03-21 12:51:58 +01:00
value() {
2019-01-06 10:06:08 +00:00
if (this.results.length) {
2021-03-21 12:51:58 +01:00
this.reset();
2019-01-06 10:06:08 +00:00
}
2021-03-21 12:51:58 +01:00
},
2018-02-01 12:17:04 +00:00
},
computed: {
2019-01-05 16:12:09 +00:00
...mapState(["user", "show"]),
...mapGetters(["isListing"]),
boxes() {
2021-03-21 12:51:58 +01:00
return boxes;
2019-01-05 16:12:09 +00:00
},
isEmpty() {
2021-03-21 12:51:58 +01:00
return this.results.length === 0;
2018-02-01 12:17:04 +00:00
},
2019-01-05 16:12:09 +00:00
text() {
2018-02-01 12:17:04 +00:00
if (this.ongoing) {
2021-03-21 12:51:58 +01:00
return "";
2018-02-01 12:17:04 +00:00
}
2021-03-21 12:51:58 +01:00
return this.value === ""
? this.$t("search.typeToSearch")
: this.$t("search.pressToSearch");
},
filteredResults() {
return this.results.slice(0, this.resultsCount);
2019-01-06 10:06:08 +00:00
},
2018-02-01 12:17:04 +00:00
},
2019-01-05 16:12:09 +00:00
mounted() {
2021-03-21 12:51:58 +01:00
this.$refs.result.addEventListener("scroll", (event) => {
if (
event.target.offsetHeight + event.target.scrollTop >=
event.target.scrollHeight - 100
) {
this.resultsCount += 50;
2019-01-06 10:06:08 +00:00
}
2021-03-21 12:51:58 +01:00
});
2018-02-01 12:17:04 +00:00
},
methods: {
2019-01-05 16:12:09 +00:00
...mapMutations(["showHover", "closeHovers", "setReload"]),
open() {
2021-03-21 12:51:58 +01:00
this.showHover("search");
2018-02-01 12:17:04 +00:00
},
2019-01-05 16:12:09 +00:00
close(event) {
2021-03-21 12:51:58 +01:00
event.stopPropagation();
event.preventDefault();
this.closeHovers();
2018-02-01 12:17:04 +00:00
},
2019-01-05 16:12:09 +00:00
keyup(event) {
if (event.keyCode === 27) {
2021-03-21 12:51:58 +01:00
this.close(event);
return;
2018-02-01 12:17:04 +00:00
}
2019-01-05 16:12:09 +00:00
2021-03-21 12:51:58 +01:00
this.results.length = 0;
2018-02-01 12:17:04 +00:00
},
2021-03-21 12:51:58 +01:00
init(string) {
this.value = `${string} `;
this.$refs.input.focus();
2018-02-01 12:17:04 +00:00
},
2021-03-21 12:51:58 +01:00
reset() {
this.ongoing = false;
this.resultsCount = 50;
this.results = [];
2018-02-01 12:17:04 +00:00
},
2019-01-05 16:12:09 +00:00
async submit(event) {
2021-03-21 12:51:58 +01:00
event.preventDefault();
2019-01-05 16:12:09 +00:00
2021-03-21 12:51:58 +01:00
if (this.value === "") {
return;
2018-02-01 12:17:04 +00:00
}
2021-03-21 12:51:58 +01:00
let path = this.$route.path;
2019-01-05 16:12:09 +00:00
if (!this.isListing) {
2021-03-21 12:51:58 +01:00
path = url.removeLastDir(path) + "/";
2018-02-01 12:17:04 +00:00
}
2021-03-21 12:51:58 +01:00
this.ongoing = true;
2018-02-01 12:17:04 +00:00
2020-09-29 14:04:43 +00:00
try {
2021-03-21 12:51:58 +01:00
this.results = await search(path, this.value);
2020-09-29 14:04:43 +00:00
} catch (error) {
2021-03-21 12:51:58 +01:00
this.$showError(error);
2020-09-29 14:04:43 +00:00
}
2019-01-06 10:06:08 +00:00
2021-03-21 12:51:58 +01:00
this.ongoing = false;
},
},
};
2018-02-01 12:17:04 +00:00
</script>