diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-10-21 00:28:30 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-10-21 00:28:30 +0900 |
| commit | 5ca6e6b5df2e18f003efccc440edef513929cae2 (patch) | |
| tree | 88b03f847d93c8289b468bb2f5c50b8377cab7f1 /src/client/pages | |
| parent | fix(activitypub): not reacted な Undo.Like がinboxに滞留するのを修正 (diff) | |
| parent | Update CHANGELOG.md (diff) | |
| download | misskey-5ca6e6b5df2e18f003efccc440edef513929cae2.tar.gz misskey-5ca6e6b5df2e18f003efccc440edef513929cae2.tar.bz2 misskey-5ca6e6b5df2e18f003efccc440edef513929cae2.zip | |
Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop
Diffstat (limited to 'src/client/pages')
| -rw-r--r-- | src/client/pages/share.vue | 158 |
1 files changed, 139 insertions, 19 deletions
diff --git a/src/client/pages/share.vue b/src/client/pages/share.vue index 67e598fa8f..70a9661dd0 100644 --- a/src/client/pages/share.vue +++ b/src/client/pages/share.vue @@ -1,22 +1,38 @@ <template> <div class=""> <section class="_section"> - <div class="_title" v-if="title">{{ title }}</div> <div class="_content"> - <XPostForm v-if="!posted" fixed :instant="true" :initial-text="initialText" @posted="posted = true" class="_panel"/> - <MkButton v-else primary @click="close()">{{ $ts.close }}</MkButton> + <XPostForm + v-if="state === 'writing'" + fixed + :share="true" + :initial-text="initialText" + :initial-visibility="visibility" + :initial-files="files" + :initial-local-only="localOnly" + :reply="reply" + :renote="renote" + :visible-users="visibleUsers" + @posted="state = 'posted'" + class="_panel" + /> + <MkButton v-else-if="state === 'posted'" primary @click="close()" class="close">{{ $ts.close }}</MkButton> </div> - <div class="_footer" v-if="url">{{ url }}</div> </section> </div> </template> <script lang="ts"> +// SPECIFICATION: /src/docs/ja-JP/advanced/share-page.md + import { defineComponent } from 'vue'; import MkButton from '@client/components/ui/button.vue'; import XPostForm from '@client/components/post-form.vue'; import * as os from '@client/os'; +import { noteVisibilities } from '@/types'; +import { parseAcct } from '@/misc/acct'; import * as symbols from '@client/symbols'; +import * as Misskey from 'misskey-js'; export default defineComponent({ components: { @@ -30,35 +46,139 @@ export default defineComponent({ title: this.$ts.share, icon: 'fas fa-share-alt' }, - title: null, - text: null, - url: null, - initialText: null, - posted: false, + state: 'fetching' as 'fetching' | 'writing' | 'posted', + title: null as string | null, + initialText: null as string | null, + reply: null as Misskey.entities.Note | null, + renote: null as Misskey.entities.Note | null, + visibility: null as string | null, + localOnly: null as boolean | null, + files: [] as Misskey.entities.DriveFile[], + visibleUsers: [] as Misskey.entities.User[], } }, - created() { + async created() { const urlParams = new URLSearchParams(window.location.search); + this.title = urlParams.get('title'); - this.text = urlParams.get('text'); - this.url = urlParams.get('url'); - - let text = ''; - if (this.title) text += `【${this.title}】\n`; - if (this.text) text += `${this.text}\n`; - if (this.url) text += `${this.url}`; - this.initialText = text.trim(); + const text = urlParams.get('text'); + const url = urlParams.get('url'); + + let noteText = ''; + if (this.title) noteText += `[ ${this.title} ]\n`; + // Googleニュース対策 + if (text?.startsWith(`${this.title}.\n`)) noteText += text.replace(`${this.title}.\n`, ''); + else if (text && this.title !== text) noteText += `${text}\n`; + if (url) noteText += `${url}`; + this.initialText = noteText.trim(); + + const visibility = urlParams.get('visibility'); + if (noteVisibilities.includes(visibility)) { + this.visibility = visibility; + } + + if (this.visibility === 'specified') { + const visibleUserIds = urlParams.get('visibleUserIds'); + const visibleAccts = urlParams.get('visibleAccts'); + await Promise.all( + [ + ...(visibleUserIds ? visibleUserIds.split(',').map(userId => ({ userId })) : []), + ...(visibleAccts ? visibleAccts.split(',').map(parseAcct) : []) + ] + // TypeScriptの指示通りに変換する + .map(q => 'username' in q ? { username: q.username, host: q.host === null ? undefined : q.host } : q) + .map(q => os.api('users/show', q) + .then(user => { + this.visibleUsers.push(user); + }, () => { + console.error(`Invalid user query: ${JSON.stringify(q)}`); + }) + ) + ); + } + + const localOnly = urlParams.get('localOnly'); + if (localOnly === '0') this.localOnly = false; + else if (localOnly === '1') this.localOnly = true; + + try { + //#region Reply + const replyId = urlParams.get('replyId'); + const replyUri = urlParams.get('replyUri'); + if (replyId) { + this.reply = await os.api('notes/show', { + noteId: replyId + }); + } else if (replyUri) { + const obj = await os.api('ap/show', { + uri: replyUri + }); + if (obj.type === 'Note') { + this.reply = obj.object; + } + } + //#endregion + + //#region Renote + const renoteId = urlParams.get('renoteId'); + const renoteUri = urlParams.get('renoteUri'); + if (renoteId) { + this.renote = await os.api('notes/show', { + noteId: renoteId + }); + } else if (renoteUri) { + const obj = await os.api('ap/show', { + uri: renoteUri + }); + if (obj.type === 'Note') { + this.renote = obj.object; + } + } + //#endregion + + //#region Drive files + const fileIds = urlParams.get('fileIds'); + if (fileIds) { + await Promise.all( + fileIds.split(',') + .map(fileId => os.api('drive/files/show', { fileId }) + .then(file => { + this.files.push(file); + }, () => { + console.error(`Failed to fetch a file ${fileId}`); + }) + ) + ); + } + //#endregion + } catch (e) { + os.dialog({ + type: 'error', + title: e.message, + text: e.name + }); + } + + this.state = 'writing'; }, methods: { close() { - window.close() + window.close(); + + // 閉じなければ100ms後タイムラインに + setTimeout(() => { + this.$router.push('/'); + }, 100); } } }); </script> <style lang="scss" scoped> +.close { + margin: 16px auto; +} </style> |