From 7827aeb6951bfd0dae1799601dff3f207a3d2363 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Apr 2019 19:40:23 +0900 Subject: [PATCH] Resolve #4735 --- locales/ja-JP.yml | 1 + src/client/app/common/scripts/search.ts | 64 +++++++++++++++++++ .../app/common/views/components/dialog.vue | 50 +++++++++------ .../views/components/ui.header.search.vue | 27 ++------ .../app/desktop/views/home/timeline.core.vue | 15 +++-- src/client/app/init.ts | 6 +- .../app/mobile/views/components/ui.nav.vue | 26 ++------ .../app/mobile/views/pages/home.timeline.vue | 10 +-- 8 files changed, 128 insertions(+), 71 deletions(-) create mode 100644 src/client/app/common/scripts/search.ts diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 0836386c6c..e9284f89a7 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -35,6 +35,7 @@ common: signup: "新規登録" signout: "ログアウト" reload-to-apply-the-setting: "この設定を反映するにはページをリロードする必要があります。今すぐリロードしますか?" + fetching-as-ap-object: "連合に照会中" got-it: "わかった" customization-tips: diff --git a/src/client/app/common/scripts/search.ts b/src/client/app/common/scripts/search.ts new file mode 100644 index 0000000000..c44581817b --- /dev/null +++ b/src/client/app/common/scripts/search.ts @@ -0,0 +1,64 @@ +import { faHistory } from '@fortawesome/free-solid-svg-icons'; + +export async function search(v: any, q: string) { + q = q.trim(); + + if (q.startsWith('@')) { + v.$router.push(`/${q}`); + return; + } + + if (q.startsWith('#')) { + v.$router.push(`/tags/${encodeURIComponent(q.substr(1))}`); + return; + } + + // like 2018/03/12 + if (/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}/.test(q.replace(/-/g, '/'))) { + const date = new Date(q.replace(/-/g, '/')); + + // 日付しか指定されてない場合、例えば 2018/03/12 ならユーザーは + // 2018/03/12 のコンテンツを「含む」結果になることを期待するはずなので + // 23時間59分進める(そのままだと 2018/03/12 00:00:00 「まで」の + // 結果になってしまい、2018/03/12 のコンテンツは含まれない) + if (q.replace(/-/g, '/').match(/^[0-9]{4}\/[0-9]{2}\/[0-9]{2}$/)) { + date.setHours(23, 59, 59, 999); + } + + v.$root.$emit('warp', date); + v.$root.dialog({ + icon: faHistory, + splash: true, + }); + return; + } + + if (q.startsWith('https://')) { + const dialog = v.$root.dialog({ + type: 'waiting', + text: v.$t('@.fetching-as-ap-object'), + showOkButton: false, + showCancelButton: false, + cancelableByBgClick: false + }); + + try { + const res = await v.$root.api('ap/show', { + uri: q + }); + dialog.close(); + if (res.type == 'User') { + v.$router.push(`/@${res.object.username}@${res.object.host}`); + } else if (res.type == 'Note') { + v.$router.push(`/notes/${res.object.id}`); + } + } catch (e) { + dialog.close(); + // TODO: Show error + } + + return; + } + + v.$router.push(`/search?q=${encodeURIComponent(q)}`); +} diff --git a/src/client/app/common/views/components/dialog.vue b/src/client/app/common/views/components/dialog.vue index 771b1237ee..c1ee7958c0 100644 --- a/src/client/app/common/views/components/dialog.vue +++ b/src/client/app/common/views/components/dialog.vue @@ -6,7 +6,17 @@ @@ -55,10 +65,21 @@ export default Vue.extend({ user: { required: false }, + icon: { + required: false + }, + showOkButton: { + type: Boolean, + default: true + }, showCancelButton: { type: Boolean, default: false }, + cancelableByBgClick: { + type: Boolean, + default: true + }, splash: { type: Boolean, default: false @@ -69,22 +90,11 @@ export default Vue.extend({ return { inputValue: this.input && this.input.default ? this.input.default : null, userInputValue: null, - selectedValue: null + selectedValue: null, + faTimesCircle, faQuestionCircle }; }, - computed: { - icon(): any { - switch (this.type) { - case 'success': return 'check'; - case 'error': return faTimesCircle; - case 'warning': return 'exclamation-triangle'; - case 'info': return 'info-circle'; - case 'question': return faQuestionCircle; - } - } - }, - mounted() { this.$nextTick(() => { (this.$refs.bg as any).style.pointerEvents = 'auto'; @@ -113,6 +123,8 @@ export default Vue.extend({ methods: { async ok() { + if (!this.showOkButton) return; + if (this.user) { const user = await this.$root.api('users/show', parseAcct(this.userInputValue)); if (user) { @@ -156,7 +168,9 @@ export default Vue.extend({ }, onBgClick() { - this.cancel(); + if (this.cancelableByBgClick) { + this.cancel(); + } }, onInputKeydown(e) { @@ -240,7 +254,7 @@ export default Vue.extend({ margin-top 8px > .body - margin 16px 0 + margin 16px 0 0 0 > .buttons margin-top 16px 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 4ade74bc64..0cf5ca6f32 100644 --- a/src/client/app/desktop/views/components/ui.header.search.vue +++ b/src/client/app/desktop/views/components/ui.header.search.vue @@ -9,6 +9,7 @@