From f7b1ef0690b7e30f5918ebf518854b28c0654157 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Thu, 18 Apr 2019 03:14:04 +0900 Subject: [PATCH 01/20] =?UTF-8?q?=E3=82=A2=E3=83=B3=E3=82=B1=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=82=A6=E3=82=A3=E3=82=B8=E3=83=83=E3=83=88=E3=81=A7?= =?UTF-8?q?=E3=82=82MFM=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=20v11=20(#4741)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * MFM in poll * use mfm --- src/client/app/desktop/views/widgets/polls.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/app/desktop/views/widgets/polls.vue b/src/client/app/desktop/views/widgets/polls.vue index 3567cae5e..c77762ecd 100644 --- a/src/client/app/desktop/views/widgets/polls.vue +++ b/src/client/app/desktop/views/widgets/polls.vue @@ -11,7 +11,9 @@
-

{{ poll.text }}

+

+ +

From 704aabd703de2be4d06b399929e6f33525526b57 Mon Sep 17 00:00:00 2001 From: tamaina Date: Thu, 18 Apr 2019 03:32:45 +0900 Subject: [PATCH 02/20] Use menu instead of prompt Fix #4540, Fix #342 (#4575) * Use menu instead prompt * fix * https://bit.ly/2U0JuVt * fix --- locales/ja-JP.yml | 12 ++- .../app/mobile/views/components/drive.vue | 77 +++++++++---------- src/client/app/mobile/views/pages/drive.vue | 46 +++++++++-- 3 files changed, 89 insertions(+), 46 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index eb87d4f20..6d68f0ca8 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1573,12 +1573,11 @@ mobile/views/components/drive.vue: file-count: "ファイル" nothing-in-drive: "ドライブには何もありません" folder-is-empty: "このフォルダは空です" - prompt: "何をしますか?(数字を入力してください): <1 → ファイルをアップロード | 2 → ファイルをURLでアップロード | 3 → フォルダ作成 | 4 → このフォルダ名を変更 | 5 → このフォルダを移動 | 6 → このフォルダを削除>" - deletion-alert: "ごめんなさい!フォルダの削除は未実装です...。" folder-name: "フォルダー名" here-is-root: "現在いる場所はルートで、フォルダではありません。" url-prompt: "アップロードしたいファイルのURL" uploading: "アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。" + folder-name-cannot-empty: "フォルダ名を空白にすることはできません。" mobile/views/components/drive-file-chooser.vue: select-file: "ファイルを選択" @@ -1668,6 +1667,15 @@ mobile/views/components/ui.nav.vue: admin: "管理" about: "Misskeyについて" +mobile/views/pages/drive.vue: + contextmenu: + upload: "ファイルをアップロード" + url-upload: "ファイルをURLでアップロード" + create-folder: "フォルダーを作成" + rename-folder: "フォルダー名を変更" + move-folder: "このフォルダを移動" + delete-folder: "このフォルダを削除" + mobile/views/pages/user-lists.vue: title: "リスト" enter-list-name: "リスト名を入力してください" diff --git a/src/client/app/mobile/views/components/drive.vue b/src/client/app/mobile/views/components/drive.vue index 477233386..b79c0b380 100644 --- a/src/client/app/mobile/views/components/drive.vue +++ b/src/client/app/mobile/views/components/drive.vue @@ -379,43 +379,30 @@ export default Vue.extend({ }); }, - openContextMenu() { - const fn = window.prompt(this.$t('prompt')); - if (fn == null || fn == '') return; - switch (fn) { - case '1': - this.selectLocalFile(); - break; - case '2': - this.urlUpload(); - break; - case '3': - this.createFolder(); - break; - case '4': - this.renameFolder(); - break; - case '5': - this.moveFolder(); - break; - case '6': - this.deleteFolder(); - break; - } - }, - selectLocalFile() { (this.$refs.file as any).click(); }, createFolder() { - const name = window.prompt(this.$t('folder-name')); - if (name == null || name == '') return; - this.$root.api('drive/folders/create', { - name: name, - parentId: this.folder ? this.folder.id : undefined - }).then(folder => { - this.addFolder(folder, true); + this.$root.dialog({ + title: this.$t('folder-name') + input: { + default: this.folder.name + } + }).then(({ result: name }) => { + if (!name) { + this.$root.dialog({ + type: 'error', + text: this.$t('folder-name-cannot-empty') + }); + return; + } + this.$root.api('drive/folders/create', { + name: name, + parentId: this.folder ? this.folder.id : undefined + }).then(folder => { + this.addFolder(folder, true); + }); }); }, @@ -427,13 +414,25 @@ export default Vue.extend({ }); return; } - const name = window.prompt(this.$t('folder-name'), this.folder.name); - if (name == null || name == '') return; - this.$root.api('drive/folders/update', { - name: name, - folderId: this.folder.id - }).then(folder => { - this.cd(folder); + this.$root.dialog({ + title: this.$t('folder-name') + input: { + default: this.folder.name + } + }).then(({ result: name }) => { + if (!name) { + this.$root.dialog({ + type: 'error', + text: this.$t('cannot-empty') + }); + return; + } + this.$root.api('drive/folders/update', { + name: name, + folderId: this.folder.id + }).then(folder => { + this.cd(folder); + }); }); }, diff --git a/src/client/app/mobile/views/pages/drive.vue b/src/client/app/mobile/views/pages/drive.vue index d2f51dc89..05163c6ed 100644 --- a/src/client/app/mobile/views/pages/drive.vue +++ b/src/client/app/mobile/views/pages/drive.vue @@ -5,7 +5,7 @@ - + import('../components/drive.vue').then(m => m.default), }, @@ -63,9 +66,6 @@ export default Vue.extend({ (this.$refs as any).browser.goRoot(true); } }, - fn() { - (this.$refs as any).browser.openContextMenu(); - }, onMoveRoot(silent) { const title = `${this.$root.instanceName} Drive`; @@ -104,6 +104,42 @@ export default Vue.extend({ this.file = file; this.folder = null; + }, + openContextMenu() { + this.$root.new(XMenu, { + items: [{ + type: 'item', + text: this.$t('contextmenu.upload'), + icon: 'upload', + action: this.$refs.browser.selectLocalFile + }, { + type: 'item', + text: this.$t('contextmenu.url-upload'), + icon: faCloudUploadAlt, + action: this.$refs.browser.urlUpload + }, { + type: 'item', + text: this.$t('contextmenu.create-folder'), + icon: ['far', 'folder'], + action: this.$refs.browser.createFolder + }, ...(this.folder ? [{ + type: 'item', + text: this.$t('contextmenu.rename-folder'), + icon: 'i-cursor', + action: this.$refs.browser.renameFolder + }, { + type: 'item', + text: this.$t('contextmenu.move-folder'), + icon: ['far', 'folder-open'], + action: this.$refs.browser.moveFolder + }, { + type: 'item', + text: this.$t('contextmenu.delete-folder'), + icon: faTrashAlt, + action: this.$refs.browser.deleteFolder + }] : [])], + source: this.$refs.contextSource, + }); } } }); From adff5382cad8b38381adfbfd0d6b35765948b6b9 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Thu, 18 Apr 2019 03:33:51 +0900 Subject: [PATCH 03/20] confirm silence (#4560) --- locales/ja-JP.yml | 2 ++ src/client/app/admin/views/users.vue | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 6d68f0ca8..bcdda6c67 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1336,7 +1336,9 @@ admin/views/users.vue: unsuspend-confirm: "凍結を解除しますか?" unsuspended: "凍結を解除しました" make-silence: "サイレンス" + silence-confirm: "サイレンスしますか?" unmake-silence: "サイレンスの解除" + unsilence-confirm: "サイレンスを解除しますか?" verify: "公式アカウントにする" verify-confirm: "公式アカウントにしますか?" verified: "公式アカウントにしました" diff --git a/src/client/app/admin/views/users.vue b/src/client/app/admin/views/users.vue index 0f46b564a..2d6aef337 100644 --- a/src/client/app/admin/views/users.vue +++ b/src/client/app/admin/views/users.vue @@ -232,6 +232,8 @@ export default Vue.extend({ }, async silenceUser() { + if (!await this.getConfirmed(this.$t('silence-confirm'))) return; + const process = async () => { await this.$root.api('admin/silence-user', { userId: this.user.id }); this.$root.dialog({ @@ -251,6 +253,8 @@ export default Vue.extend({ }, async unsilenceUser() { + if (!await this.getConfirmed(this.$t('unsilence-confirm'))) return; + const process = async () => { await this.$root.api('admin/unsilence-user', { userId: this.user.id }); this.$root.dialog({ From 9ec6afa37541a307631c2826b7f923160c6d4e0f Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Thu, 18 Apr 2019 03:36:06 +0900 Subject: [PATCH 04/20] confirm on user menu (#4553) --- locales/ja-JP.yml | 8 +++++ .../app/common/views/components/user-menu.vue | 33 ++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index bcdda6c67..0836386c6 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -527,8 +527,12 @@ common/views/components/user-menu.vue: mention: "メンション" mute: "ミュート" unmute: "ミュート解除" + mute-confirm: "このユーザーをミュートしますか?" + unmute-confirm: "このユーザーをミュート解除しますか?" block: "ブロック" unblock: "ブロック解除" + block-confirm: "このユーザーをブロックしますか?" + unblock-confirm: "このユーザーをブロック解除しますか?" push-to-list: "リストに追加" select-list: "リストを選択してください" report-abuse: "スパムを報告" @@ -536,8 +540,12 @@ common/views/components/user-menu.vue: report-abuse-reported: "管理者に報告されました。ご協力ありがとうございました。" silence: "サイレンス" unsilence: "サイレンス解除" + silence-confirm: "このユーザーをサイレンスしますか?" + unsilence-confirm: "このユーザーをサイレンス解除しますか?" suspend: "凍結" unsuspend: "凍結解除" + suspend-confirm: "このユーザーを凍結しますか?" + unsuspend-confirm: "このユーザーを凍結解除しますか?" common/views/components/poll.vue: vote-to: "「{}」に投票する" diff --git a/src/client/app/common/views/components/user-menu.vue b/src/client/app/common/views/components/user-menu.vue index a95f7a922..0af0fdb7e 100644 --- a/src/client/app/common/views/components/user-menu.vue +++ b/src/client/app/common/views/components/user-menu.vue @@ -89,8 +89,10 @@ export default Vue.extend({ }); }, - toggleMute() { + async toggleMute() { if (this.user.isMuted) { + if (!await this.getConfirmed(this.$t('unmute-confirm'))) return; + this.$root.api('mute/delete', { userId: this.user.id }).then(() => { @@ -102,6 +104,8 @@ export default Vue.extend({ }); }); } else { + if (!await this.getConfirmed(this.$t('mute-confirm'))) return; + this.$root.api('mute/create', { userId: this.user.id }).then(() => { @@ -115,8 +119,10 @@ export default Vue.extend({ } }, - toggleBlock() { + async toggleBlock() { if (this.user.isBlocking) { + if (!await this.getConfirmed(this.$t('unblock-confirm'))) return; + this.$root.api('blocking/delete', { userId: this.user.id }).then(() => { @@ -128,6 +134,8 @@ export default Vue.extend({ }); }); } else { + if (!await this.getConfirmed(this.$t('block-confirm'))) return; + this.$root.api('blocking/create', { userId: this.user.id }).then(() => { @@ -164,7 +172,9 @@ export default Vue.extend({ }); }, - toggleSilence() { + async toggleSilence() { + if (!await this.getConfirmed(this.$t(this.user.isSilenced ? 'unsilence-confirm' : 'silence-confirm'))) return; + this.$root.api(this.user.isSilenced ? 'admin/unsilence-user' : 'admin/silence-user', { userId: this.user.id }).then(() => { @@ -181,7 +191,9 @@ export default Vue.extend({ }); }, - toggleSuspend() { + async toggleSuspend() { + if (!await this.getConfirmed(this.$t(this.user.isSuspended ? 'unsuspend-confirm' : 'suspend-confirm'))) return; + this.$root.api(this.user.isSuspended ? 'admin/unsuspend-user' : 'admin/suspend-user', { userId: this.user.id }).then(() => { @@ -196,7 +208,18 @@ export default Vue.extend({ text: e }); }); - } + }, + + async getConfirmed(text: string): Promise { + const confirm = await this.$root.dialog({ + type: 'warning', + showCancelButton: true, + title: 'confirm', + text, + }); + + return !confirm.canceled; + }, } }); From 653b8f635290aa0204d507357e62a353942e9248 Mon Sep 17 00:00:00 2001 From: MeiMei <30769358+mei23@users.noreply.github.com> Date: Thu, 18 Apr 2019 03:37:49 +0900 Subject: [PATCH 05/20] =?UTF-8?q?=E3=82=B9=E3=83=97=E3=83=A9=E3=83=83?= =?UTF-8?q?=E3=82=B7=E3=83=A5=E3=81=8C=E3=82=AF=E3=83=AA=E3=83=83=E3=82=AF?= =?UTF-8?q?=E3=81=AB=E5=8F=8D=E5=BF=9C=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=20(#4561)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * confirm silence * Resolve #4554 * Revert "confirm silence" This reverts commit e1dbdc2bfc0f41c2b308b142c70e9e4573c98cf9. --- src/client/app/common/views/components/dialog.vue | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/client/app/common/views/components/dialog.vue b/src/client/app/common/views/components/dialog.vue index 6a074769d..771b1237e 100644 --- a/src/client/app/common/views/components/dialog.vue +++ b/src/client/app/common/views/components/dialog.vue @@ -183,9 +183,6 @@ export default Vue.extend({ height 100% &.splash - &, * - pointer-events none !important - > .main min-width 0 width initial From 683e5b6abec93f2883c4d4dafc130e2a079f3dda Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Apr 2019 14:29:17 +0900 Subject: [PATCH 06/20] Add type annotations --- test/streaming.ts | 4 ++-- test/utils.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/streaming.ts b/test/streaming.ts index 759472861..a29517148 100644 --- a/test/streaming.ts +++ b/test/streaming.ts @@ -32,7 +32,7 @@ describe('Streaming', () => { p.on('message', message => { if (message === 'ok') { (p.channel as any).onread = () => {}; - initDb(true).then(async connection => { + initDb(true).then(async (connection: any) => { Followings = connection.getRepository(Following); done(); }); @@ -44,7 +44,7 @@ describe('Streaming', () => { p.kill(); }); - const follow = async (follower, followee) => { + const follow = async (follower: any, followee: any) => { await Followings.save({ id: 'a', createdAt: new Date(), diff --git a/test/utils.ts b/test/utils.ts index fbba9a68c..f67baf004 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -76,7 +76,7 @@ export const uploadFile = (user: any, path?: string): Promise => new Promis }); }); -export function connectStream(user: any, channel: string, listener: any, params?: any): Promise { +export function connectStream(user: any, channel: string, listener: (message: Record) => any, params?: any): Promise { return new Promise((res, rej) => { const ws = new WebSocket(`ws://localhost/streaming?i=${user.token}`); From d78a5c0863b75ad51f739caf6c6eb129cc958b36 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Apr 2019 14:34:47 +0900 Subject: [PATCH 07/20] Fix #4703 --- .../api/stream/channels/hybrid-timeline.ts | 4 +-- test/streaming.ts | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/src/server/api/stream/channels/hybrid-timeline.ts index 18e6aa835..5bf23715e 100644 --- a/src/server/api/stream/channels/hybrid-timeline.ts +++ b/src/server/api/stream/channels/hybrid-timeline.ts @@ -20,11 +20,11 @@ export default class extends Channel { @autobind private async onNote(note: any) { - // 自分自身の投稿 または その投稿のユーザーをフォローしている または ローカルの投稿 の場合だけ + // 自分自身の投稿 または その投稿のユーザーをフォローしている または ホームのローカルの投稿 の場合だけ if (!( this.user!.id === note.userId || this.following.includes(note.userId) || - note.user.host == null + (note.user.host == null && note.visibility === 'home') )) return; if (['followers', 'specified'].includes(note.visibility)) { diff --git a/test/streaming.ts b/test/streaming.ts index a29517148..a9c90c216 100644 --- a/test/streaming.ts +++ b/test/streaming.ts @@ -484,6 +484,31 @@ describe('Streaming', () => { }); })); + it('フォローしていないローカルユーザーのホーム投稿は流れない', () => new Promise(async done => { + const alice = await signup({ username: 'alice' }); + const bob = await signup({ username: 'bob' }); + + let fired = false; + + const ws = await connectStream(alice, 'hybridTimeline', ({ type, body }) => { + if (type == 'note') { + fired = true; + } + }); + + // ホーム投稿 + post(bob, { + text: 'foo', + visibility: 'home' + }); + + setTimeout(() => { + assert.strictEqual(fired, false); + ws.close(); + done(); + }, 3000); + })); + it('フォローしていないローカルユーザーのフォロワー宛て投稿は流れない', () => new Promise(async done => { const alice = await signup({ username: 'alice' }); const bob = await signup({ username: 'bob' }); From 73b683bb4d4cdf7ed0bef59dd1058a6347955d86 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Apr 2019 14:39:49 +0900 Subject: [PATCH 08/20] Add test --- test/streaming.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/streaming.ts b/test/streaming.ts index a9c90c216..2dfede138 100644 --- a/test/streaming.ts +++ b/test/streaming.ts @@ -484,6 +484,31 @@ describe('Streaming', () => { }); })); + it('フォローしているユーザーのホーム投稿が流れる', () => new Promise(async done => { + const alice = await signup({ username: 'alice' }); + const bob = await signup({ username: 'bob' }); + + // Alice が Bob をフォロー + await request('/following/create', { + userId: bob.id + }, alice); + + const ws = await connectStream(alice, 'hybridTimeline', ({ type, body }) => { + if (type == 'note') { + assert.deepStrictEqual(body.userId, bob.id); + assert.deepStrictEqual(body.text, 'foo'); + ws.close(); + done(); + } + }); + + // ホーム投稿 + post(bob, { + text: 'foo', + visibility: 'home' + }); + })); + it('フォローしていないローカルユーザーのホーム投稿は流れない', () => new Promise(async done => { const alice = await signup({ username: 'alice' }); const bob = await signup({ username: 'bob' }); From 80b83c06248e27e0ea55fe89119d1d6241455411 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Apr 2019 14:41:51 +0900 Subject: [PATCH 09/20] =?UTF-8?q?=E9=96=93=E9=81=95=E3=81=88=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/api/stream/channels/hybrid-timeline.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/src/server/api/stream/channels/hybrid-timeline.ts index 5bf23715e..a8020bfcf 100644 --- a/src/server/api/stream/channels/hybrid-timeline.ts +++ b/src/server/api/stream/channels/hybrid-timeline.ts @@ -20,11 +20,11 @@ export default class extends Channel { @autobind private async onNote(note: any) { - // 自分自身の投稿 または その投稿のユーザーをフォローしている または ホームのローカルの投稿 の場合だけ + // 自分自身の投稿 または その投稿のユーザーをフォローしている または 全体公開のローカルの投稿 の場合だけ if (!( this.user!.id === note.userId || this.following.includes(note.userId) || - (note.user.host == null && note.visibility === 'home') + (note.user.host == null && note.visibility === 'public') )) return; if (['followers', 'specified'].includes(note.visibility)) { From cce768aaac9002cf23754b579bea79905fe3ac12 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Apr 2019 14:58:43 +0900 Subject: [PATCH 10/20] Fix API definition --- src/server/api/endpoints/notes/hybrid-timeline.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts index 6dfb14300..effee2b13 100644 --- a/src/server/api/endpoints/notes/hybrid-timeline.ts +++ b/src/server/api/endpoints/notes/hybrid-timeline.ts @@ -17,6 +17,8 @@ export const meta = { tags: ['notes'], + requireCredential: true, + params: { limit: { validator: $.optional.num.range(1, 100), From 7827aeb6951bfd0dae1799601dff3f207a3d2363 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Apr 2019 19:40:23 +0900 Subject: [PATCH 11/20] 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 0836386c6..e9284f89a 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 000000000..c44581817 --- /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 771b1237e..c1ee7958c 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 4ade74bc6..0cf5ca6f3 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 @@ + + diff --git a/src/client/app/desktop/views/components/ui.header.account.vue b/src/client/app/desktop/views/components/ui.header.account.vue index effd0ef0f..7f9decfdc 100644 --- a/src/client/app/desktop/views/components/ui.header.account.vue +++ b/src/client/app/desktop/views/components/ui.header.account.vue @@ -90,9 +90,8 @@ import Vue from 'vue'; import i18n from '../../../i18n'; import MkUserListsWindow from './user-lists-window.vue'; -import MkUserListWindow from './user-list-window.vue'; import MkFollowRequestsWindow from './received-follow-requests-window.vue'; -import MkSettingsWindow from './settings-window.vue'; +// import MkSettingsWindow from './settings-window.vue'; import MkDriveWindow from './drive-window.vue'; import contains from '../../../common/scripts/contains'; import { faHome, faColumns } from '@fortawesome/free-solid-svg-icons'; @@ -143,12 +142,7 @@ export default Vue.extend({ }, list() { this.close(); - const w = this.$root.new(MkUserListsWindow); - w.$once('choosen', list => { - this.$root.new(MkUserListWindow, { - list - }); - }); + this.$root.new(MkUserListsWindow); }, followRequests() { this.close(); diff --git a/src/client/app/desktop/views/components/ui.sidebar.vue b/src/client/app/desktop/views/components/ui.sidebar.vue index cb0e059c1..1c01f127b 100644 --- a/src/client/app/desktop/views/components/ui.sidebar.vue +++ b/src/client/app/desktop/views/components/ui.sidebar.vue @@ -148,10 +148,7 @@ export default Vue.extend({ }, list() { - const w = this.$root.new(MkUserListsWindow); - w.$once('choosen', list => { - this.$router.push(`i/lists/${ list.id }`); - }); + this.$root.new(MkUserListsWindow); }, followRequests() { diff --git a/src/client/app/desktop/views/components/user-lists-window.vue b/src/client/app/desktop/views/components/user-lists-window.vue index 7afcd6aa3..afea01d4a 100644 --- a/src/client/app/desktop/views/components/user-lists-window.vue +++ b/src/client/app/desktop/views/components/user-lists-window.vue @@ -1,85 +1,36 @@ - diff --git a/src/client/app/mobile/views/pages/user-lists.vue b/src/client/app/mobile/views/pages/user-lists.vue index 49006f41f..a3e9bd78b 100644 --- a/src/client/app/mobile/views/pages/user-lists.vue +++ b/src/client/app/mobile/views/pages/user-lists.vue @@ -1,20 +1,15 @@ diff --git a/src/server/api/endpoints/users/notes.ts b/src/server/api/endpoints/users/notes.ts index d3f17bd78..4691a9939 100644 --- a/src/server/api/endpoints/users/notes.ts +++ b/src/server/api/endpoints/users/notes.ts @@ -142,7 +142,7 @@ export default define(meta, async (ps, me) => { }); //#region Construct query - const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId) + const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) .andWhere('note.userId = :userId', { userId: user.id }) .leftJoinAndSelect('note.user', 'user'); From debe648a98b8ed62822d177bdf7aeb15373cc640 Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Apr 2019 22:00:53 +0900 Subject: [PATCH 20/20] 11.2.0 --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c45b02b5..1755ce43b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ If you encounter any problems with updating, please try the following: 1. `npm run clean` or `npm run cleanall` 2. Retry update (Don't forget `npm i`) +11.2.0 (2019/04/18) +------------------- +### Improvements +* 検索で日付(日時)を入力するとタイムラインをその時点まで遡るように +* APIコンソールでエンドポイントをサジェストするように +* モバイル版でドライブのメニューを使いやすく +* サイレンス時に確認を表示するように +* ユーザーメニューでブロックなどの操作を行う時に確認するように + +### Fixes +* アプリケーション連携画面でパーミッションが表示されない問題を修正 +* アンケートウィジットでもMFMを使用するように +* フォローしてないユーザーのホーム投稿がSTLに流れてくる問題を修正 +* モバイル版でウィジェットを設定できない問題を修正 +* スプラッシュがクリックに反応するように + 11.1.6 (2019/04/18) ------------------- ### Fixes diff --git a/package.json b/package.json index db2d9d0ea..409bdda15 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "misskey", "author": "syuilo ", - "version": "11.1.6", + "version": "11.2.0", "codename": "daybreak", "repository": { "type": "git",