From b7c5c71c6fdd139406166cff697a4e94bb11384a Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sun, 16 Dec 2018 08:45:10 +0900
Subject: [PATCH] [Client] Resolve #2951
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

あと検索フォームでサジェストを有効に
---
 .../views/components/messaging-room.form.vue      |  2 +-
 .../app/common/views/directives/autocomplete.ts   | 12 +++++++-----
 .../app/desktop/views/components/post-form.vue    |  4 ++--
 .../desktop/views/components/ui.header.search.vue | 15 +++++++++------
 .../app/desktop/views/widgets/post-form.vue       |  2 +-
 .../app/mobile/views/components/post-form.vue     |  4 ++--
 src/client/app/mobile/views/components/ui.nav.vue | 10 +++++++++-
 7 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/src/client/app/common/views/components/messaging-room.form.vue b/src/client/app/common/views/components/messaging-room.form.vue
index 97e2e16e4b..729ed640be 100644
--- a/src/client/app/common/views/components/messaging-room.form.vue
+++ b/src/client/app/common/views/components/messaging-room.form.vue
@@ -9,7 +9,7 @@
 		@keypress="onKeypress"
 		@paste="onPaste"
 		:placeholder="$t('input-message-here')"
-		v-autocomplete="'text'"
+		v-autocomplete="{ model: 'text' }"
 	></textarea>
 	<div class="file" @click="file = null" v-if="file">{{ file.name }}</div>
 	<mk-uploader ref="uploader" @uploaded="onUploaded"/>
diff --git a/src/client/app/common/views/directives/autocomplete.ts b/src/client/app/common/views/directives/autocomplete.ts
index 4440747e19..355e3bd523 100644
--- a/src/client/app/common/views/directives/autocomplete.ts
+++ b/src/client/app/common/views/directives/autocomplete.ts
@@ -21,21 +21,23 @@ class Autocomplete {
 	private suggestion: any;
 	private textarea: any;
 	private vm: any;
-	private model: any;
 	private currentType: string;
+	private opts: {
+		model: string;
+	};
 
 	private get text(): string {
-		return this.vm[this.model];
+		return this.vm[this.opts.model];
 	}
 
 	private set text(text: string) {
-		this.vm[this.model] = text;
+		this.vm[this.opts.model] = text;
 	}
 
 	/**
 	 * 対象のテキストエリアを与えてインスタンスを初期化します。
 	 */
-	constructor(textarea, vm, model) {
+	constructor(textarea, vm, opts) {
 		//#region BIND
 		this.onInput = this.onInput.bind(this);
 		this.complete = this.complete.bind(this);
@@ -45,7 +47,7 @@ class Autocomplete {
 		this.suggestion = null;
 		this.textarea = textarea;
 		this.vm = vm;
-		this.model = model;
+		this.opts = opts;
 	}
 
 	/**
diff --git a/src/client/app/desktop/views/components/post-form.vue b/src/client/app/desktop/views/components/post-form.vue
index c2f6a94f7f..0e86bbf9f8 100644
--- a/src/client/app/desktop/views/components/post-form.vue
+++ b/src/client/app/desktop/views/components/post-form.vue
@@ -17,12 +17,12 @@
 			<a v-for="tag in recentHashtags.slice(0, 5)" @click="addTag(tag)" :title="$t('click-to-tagging')">#{{ tag }}</a>
 		</div>
 		<div class="local-only" v-if="localOnly == true">{{ $t('local-only-message') }}</div>
-		<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="'cw'">
+		<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="{ model: 'cw' }">
 		<div class="textarea">
 			<textarea :class="{ with: (files.length != 0 || poll) }"
 				ref="text" v-model="text" :disabled="posting"
 				@keydown="onKeydown" @paste="onPaste" :placeholder="placeholder"
-				v-autocomplete="'text'"
+				v-autocomplete="{ model: 'text' }"
 			></textarea>
 			<button class="emoji" @click="emoji" ref="emoji">
 				<fa :icon="['far', 'laugh']"/>
diff --git a/src/client/app/desktop/views/components/ui.header.search.vue b/src/client/app/desktop/views/components/ui.header.search.vue
index ede9f9da0f..c2f9eab0ac 100644
--- a/src/client/app/desktop/views/components/ui.header.search.vue
+++ b/src/client/app/desktop/views/components/ui.header.search.vue
@@ -1,7 +1,7 @@
 <template>
-<form class="search" @submit.prevent="onSubmit">
+<form class="wlvfdpkp" @submit.prevent="onSubmit">
 	<i><fa icon="search"/></i>
-	<input v-model="q" type="search" :placeholder="$t('placeholder')"/>
+	<input v-model="q" type="search" :placeholder="$t('placeholder')" v-autocomplete="{ model: 'q' }"/>
 	<div class="result"></div>
 </form>
 </template>
@@ -19,10 +19,13 @@ export default Vue.extend({
 	},
 	methods: {
 		onSubmit() {
-			if (this.q.startsWith('#')) {
-				this.$router.push(`/tags/${encodeURIComponent(this.q.substr(1))}`);
+			const q = this.q.trim();
+			if (q.startsWith('@')) {
+				this.$router.push(`/${q}`);
+			} else if (q.startsWith('#')) {
+				this.$router.push(`/tags/${encodeURIComponent(q.substr(1))}`);
 			} else {
-				this.$router.push(`/search?q=${encodeURIComponent(this.q)}`);
+				this.$router.push(`/search?q=${encodeURIComponent(q)}`);
 			}
 		}
 	}
@@ -30,7 +33,7 @@ export default Vue.extend({
 </script>
 
 <style lang="stylus" scoped>
-.search
+.wlvfdpkp
 	@media (max-width 800px)
 		display none !important
 
diff --git a/src/client/app/desktop/views/widgets/post-form.vue b/src/client/app/desktop/views/widgets/post-form.vue
index 622e5c3345..e409760aaf 100644
--- a/src/client/app/desktop/views/widgets/post-form.vue
+++ b/src/client/app/desktop/views/widgets/post-form.vue
@@ -15,7 +15,7 @@
 					@paste="onPaste"
 					:placeholder="placeholder"
 					ref="text"
-					v-autocomplete="'text'"
+					v-autocomplete="{ model: 'text' }"
 				></textarea>
 				<button class="emoji" @click="emoji" ref="emoji">
 					<fa :icon="['far', 'laugh']"/>
diff --git a/src/client/app/mobile/views/components/post-form.vue b/src/client/app/mobile/views/components/post-form.vue
index 28e008279c..d9cf1471c5 100644
--- a/src/client/app/mobile/views/components/post-form.vue
+++ b/src/client/app/mobile/views/components/post-form.vue
@@ -19,8 +19,8 @@
 				</span>
 				<a @click="addVisibleUser">+{{ $t('add-visible-user') }}</a>
 			</div>
-			<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="'cw'">
-			<textarea v-model="text" ref="text" :disabled="posting" :placeholder="placeholder" v-autocomplete="'text'"></textarea>
+			<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="{ model: 'cw' }">
+			<textarea v-model="text" ref="text" :disabled="posting" :placeholder="placeholder" v-autocomplete="{ model: 'text' }"></textarea>
 			<div class="attaches" v-show="files.length != 0">
 				<x-draggable class="files" :list="files" :options="{ animation: 150 }">
 					<div class="file" v-for="file in files" :key="file.id">
diff --git a/src/client/app/mobile/views/components/ui.nav.vue b/src/client/app/mobile/views/components/ui.nav.vue
index 19e02523b7..d12a6f7d27 100644
--- a/src/client/app/mobile/views/components/ui.nav.vue
+++ b/src/client/app/mobile/views/components/ui.nav.vue
@@ -100,7 +100,15 @@ export default Vue.extend({
 				input: true
 			}).then(({ canceled, result: query }) => {
 				if (canceled) return;
-				this.$router.push(`/search?q=${encodeURIComponent(query)}`);
+
+				const q = query.trim();
+				if (q.startsWith('@')) {
+					this.$router.push(`/${q}`);
+				} else if (q.startsWith('#')) {
+					this.$router.push(`/tags/${encodeURIComponent(q.substr(1))}`);
+				} else {
+					this.$router.push(`/search?q=${encodeURIComponent(q)}`);
+				}
 			});
 		},