diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2019-07-08 04:27:18 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2019-07-08 04:27:18 +0900 |
| commit | 05862a420f7d97e1a9781036a4eb62311cd35b20 (patch) | |
| tree | 157725f75c909ed1d445938e040e875ae3d1f776 /src/client | |
| parent | https://github.com/syuilo/misskey/pull/4549#discussion_r287750004 (diff) | |
| parent | :art: (diff) | |
| download | sharkey-05862a420f7d97e1a9781036a4eb62311cd35b20.tar.gz sharkey-05862a420f7d97e1a9781036a4eb62311cd35b20.tar.bz2 sharkey-05862a420f7d97e1a9781036a4eb62311cd35b20.zip | |
Merge branch 'develop' into pr/4549
Diffstat (limited to 'src/client')
32 files changed, 325 insertions, 70 deletions
diff --git a/src/client/app/common/scripts/post-form.ts b/src/client/app/common/scripts/post-form.ts index 85a578484f..1d93b4c268 100644 --- a/src/client/app/common/scripts/post-form.ts +++ b/src/client/app/common/scripts/post-form.ts @@ -151,9 +151,16 @@ export default (opts) => ({ // 公開以外へのリプライ時は元の公開範囲を引き継ぐ if (this.reply && ['home', 'followers', 'specified'].includes(this.reply.visibility)) { this.visibility = this.reply.visibility; + if (this.reply.visibility === 'specified') { + this.$root.api('users/show', { + userIds: this.reply.visibleUserIds.filter(uid => uid !== this.$store.state.i.id && uid !== this.reply.userId) + }).then(users => { + this.visibleUsers.push(...users); + }); + } } - if (this.reply) { + if (this.reply && this.reply.userId !== this.$store.state.i.id) { this.$root.api('users/show', { userId: this.reply.userId }).then(user => { this.visibleUsers.push(user); }); @@ -238,7 +245,7 @@ export default (opts) => ({ }, upload(file) { - (this.$refs.uploader as any).upload(file); + (this.$refs.uploader as any).upload(file, this.$store.state.settings.uploadFolder); }, onChangeUploadings(uploads) { 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 1dfb0589e4..74e30d29e8 100644 --- a/src/client/app/common/views/components/messaging-room.form.vue +++ b/src/client/app/common/views/components/messaging-room.form.vue @@ -158,7 +158,7 @@ export default Vue.extend({ }, upload(file) { - (this.$refs.uploader as any).upload(file); + (this.$refs.uploader as any).upload(file, this.$store.state.settings.uploadFolder); }, onUploaded(file) { diff --git a/src/client/app/common/views/pages/page/page.block.vue b/src/client/app/common/views/components/page/page.block.vue index 1c421fc2c0..1c421fc2c0 100644 --- a/src/client/app/common/views/pages/page/page.block.vue +++ b/src/client/app/common/views/components/page/page.block.vue diff --git a/src/client/app/common/views/pages/page/page.button.vue b/src/client/app/common/views/components/page/page.button.vue index d3f0307625..87112aca0d 100644 --- a/src/client/app/common/views/pages/page/page.button.vue +++ b/src/client/app/common/views/components/page/page.button.vue @@ -30,7 +30,10 @@ export default Vue.extend({ } else if (this.value.action === 'pushEvent') { this.$root.api('page-push', { pageId: this.script.page.id, - event: this.value.event + event: this.value.event, + ...(this.value.var ? { + var: this.script.vars[this.value.var] + } : {}) }); this.$root.dialog({ @@ -46,7 +49,7 @@ export default Vue.extend({ <style lang="stylus" scoped> .kudkigyw display inline-block - min-width 300px + min-width 200px max-width 450px margin 8px 0 </style> diff --git a/src/client/app/common/views/pages/page/page.counter.vue b/src/client/app/common/views/components/page/page.counter.vue index 8d55319fe9..8d55319fe9 100644 --- a/src/client/app/common/views/pages/page/page.counter.vue +++ b/src/client/app/common/views/components/page/page.counter.vue diff --git a/src/client/app/common/views/pages/page/page.if.vue b/src/client/app/common/views/components/page/page.if.vue index 417ef0c553..417ef0c553 100644 --- a/src/client/app/common/views/pages/page/page.if.vue +++ b/src/client/app/common/views/components/page/page.if.vue diff --git a/src/client/app/common/views/pages/page/page.image.vue b/src/client/app/common/views/components/page/page.image.vue index 1285445eb0..1285445eb0 100644 --- a/src/client/app/common/views/pages/page/page.image.vue +++ b/src/client/app/common/views/components/page/page.image.vue diff --git a/src/client/app/common/views/pages/page/page.number-input.vue b/src/client/app/common/views/components/page/page.number-input.vue index 31da37330a..31da37330a 100644 --- a/src/client/app/common/views/pages/page/page.number-input.vue +++ b/src/client/app/common/views/components/page/page.number-input.vue diff --git a/src/client/app/common/views/pages/page/page.post.vue b/src/client/app/common/views/components/page/page.post.vue index cb695e21e9..cb695e21e9 100644 --- a/src/client/app/common/views/pages/page/page.post.vue +++ b/src/client/app/common/views/components/page/page.post.vue diff --git a/src/client/app/common/views/pages/page/page.section.vue b/src/client/app/common/views/components/page/page.section.vue index 03c009d9c3..03c009d9c3 100644 --- a/src/client/app/common/views/pages/page/page.section.vue +++ b/src/client/app/common/views/components/page/page.section.vue diff --git a/src/client/app/common/views/pages/page/page.switch.vue b/src/client/app/common/views/components/page/page.switch.vue index 53695f1b36..53695f1b36 100644 --- a/src/client/app/common/views/pages/page/page.switch.vue +++ b/src/client/app/common/views/components/page/page.switch.vue diff --git a/src/client/app/common/views/pages/page/page.text-input.vue b/src/client/app/common/views/components/page/page.text-input.vue index cf917dd5a8..cf917dd5a8 100644 --- a/src/client/app/common/views/pages/page/page.text-input.vue +++ b/src/client/app/common/views/components/page/page.text-input.vue diff --git a/src/client/app/common/views/pages/page/page.text.vue b/src/client/app/common/views/components/page/page.text.vue index 326fd39050..326fd39050 100644 --- a/src/client/app/common/views/pages/page/page.text.vue +++ b/src/client/app/common/views/components/page/page.text.vue diff --git a/src/client/app/common/views/pages/page/page.textarea-input.vue b/src/client/app/common/views/components/page/page.textarea-input.vue index eece59fefb..eece59fefb 100644 --- a/src/client/app/common/views/pages/page/page.textarea-input.vue +++ b/src/client/app/common/views/components/page/page.textarea-input.vue diff --git a/src/client/app/common/views/pages/page/page.textarea.vue b/src/client/app/common/views/components/page/page.textarea.vue index 03c8542cb0..03c8542cb0 100644 --- a/src/client/app/common/views/pages/page/page.textarea.vue +++ b/src/client/app/common/views/components/page/page.textarea.vue diff --git a/src/client/app/common/views/pages/page/page.vue b/src/client/app/common/views/components/page/page.vue index a93d5316d5..99e627fd89 100644 --- a/src/client/app/common/views/pages/page/page.vue +++ b/src/client/app/common/views/components/page/page.vue @@ -1,6 +1,6 @@ <template> -<div v-if="page" class="iroscrza" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners, center: page.alignCenter }" :style="{ fontFamily: page.font }" :key="path"> - <header> +<div class="iroscrza" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners, center: page.alignCenter }" :style="{ fontFamily: page.font }"> + <header v-if="showTitle"> <div class="title">{{ page.title }}</div> </header> @@ -8,9 +8,13 @@ <x-block v-for="child in page.content" :value="child" @input="v => updateBlock(v)" :page="page" :script="script" :key="child.id" :h="2"/> </div> - <footer> + <footer v-if="showFooter"> <small>@{{ page.user.username }}</small> - <router-link v-if="$store.getters.isSignedIn && $store.state.i.id === page.userId" :to="`/i/pages/edit/${page.id}`">{{ $t('edit-this-page') }}</router-link> + <template v-if="$store.getters.isSignedIn && $store.state.i.id === page.userId"> + <router-link :to="`/i/pages/edit/${page.id}`">{{ $t('edit-this-page') }}</router-link> + <a v-if="$store.state.i.pinnedPageId === page.id" @click="pin(false)">{{ $t('unpin-this-page') }}</a> + <a v-else @click="pin(true)">{{ $t('pin-this-page') }}</a> + </template> <router-link :to="`./${page.name}/view-source`">{{ $t('view-source') }}</router-link> <div class="like"> <button @click="unlike()" v-if="page.isLiked" :title="$t('unlike')"><fa :icon="faHeartS"/></button> @@ -25,7 +29,7 @@ import Vue from 'vue'; import i18n from '../../../../i18n'; import { faHeart as faHeartS } from '@fortawesome/free-solid-svg-icons'; -import { faHeart, faStickyNote } from '@fortawesome/free-regular-svg-icons'; +import { faHeart } from '@fortawesome/free-regular-svg-icons'; import XBlock from './page.block.vue'; import { ASEvaluator } from '../../../../../../misc/aiscript/evaluator'; import { collectPageVars } from '../../../scripts/collect-page-vars'; @@ -69,64 +73,43 @@ export default Vue.extend({ }, props: { - pageName: { - type: String, + page: { + type: Object, required: true }, - username: { - type: String, - required: true + showTitle: { + type: Boolean, + required: false, + default: true + }, + showFooter: { + type: Boolean, + required: false, + default: false }, }, data() { return { - page: null, script: null, faHeartS, faHeart }; }, - computed: { - path(): string { - return this.username + '/' + this.pageName; - } - }, - - watch: { - path() { - this.fetch(); - } - }, - created() { - this.fetch(); + const pageVars = this.getPageVars(); + this.script = new Script(this.page, new ASEvaluator(this.page.variables, pageVars, { + randomSeed: Math.random(), + user: this.page.user, + visitor: this.$store.state.i, + page: this.page, + url: url + }), e => { + console.dir(e); + }); }, methods: { - fetch() { - this.$root.api('pages/show', { - name: this.pageName, - username: this.username, - }).then(page => { - this.page = page; - this.$emit('init', { - title: this.page.title, - icon: faStickyNote - }); - const pageVars = this.getPageVars(); - this.script = new Script(this.page, new ASEvaluator(this.page.variables, pageVars, { - randomSeed: Math.random(), - user: page.user, - visitor: this.$store.state.i, - page: page, - url: url - }), e => { - console.dir(e); - }); - }); - }, - getPageVars() { return collectPageVars(this.page.content); }, @@ -147,6 +130,17 @@ export default Vue.extend({ this.page.isLiked = false; this.page.likedCount--; }); + }, + + pin(pin) { + this.$root.api('i/update', { + pinnedPageId: pin ? this.page.id : null, + }).then(() => { + this.$root.dialog({ + type: 'success', + splash: true + }); + }); } } }); diff --git a/src/client/app/common/views/components/settings/drive.vue b/src/client/app/common/views/components/settings/drive.vue index 7bdc806ae7..da028e85ef 100644 --- a/src/client/app/common/views/components/settings/drive.vue +++ b/src/client/app/common/views/components/settings/drive.vue @@ -11,6 +11,12 @@ <header>{{ $t('stats') }}</header> <div ref="chart" style="margin-bottom: -16px; margin-left: -8px; color: #000;"></div> </section> + + <section> + <header>{{ $t('default-upload-folder') }}</header> + <ui-input v-model="uploadFolderName" readonly>{{ $t('default-upload-folder-name') }}</ui-input> + <ui-button @click="chooseUploadFolder()">{{ $t('change-default-upload-folder') }}</ui-button> + </section> </ui-card> </template> @@ -26,7 +32,8 @@ export default Vue.extend({ return { fetching: true, usage: null, - capacity: null + capacity: null, + uploadFolderName: null }; }, @@ -40,10 +47,25 @@ export default Vue.extend({ l: 0.5 }) }; - } + }, + + uploadFolder: { + get() { return this.$store.state.settings.uploadFolder; }, + set(value) { this.$store.dispatch('settings/set', { key: 'uploadFolder', value }); } + }, }, mounted() { + if (this.uploadFolder == null) { + this.uploadFolderName = this.$t('@._settings.root'); + } else { + this.$root.api('drive/folders/show', { + folderId: this.uploadFolder + }).then(folder => { + this.uploadFolderName = folder.name; + }); + } + this.$root.api('drive').then(info => { this.capacity = info.capacity; this.usage = info.usage; @@ -89,6 +111,9 @@ export default Vue.extend({ height: 150, zoom: { enabled: false + }, + toolbar: { + show: false } }, plotOptions: { @@ -152,6 +177,13 @@ export default Vue.extend({ chart.render(); }); + }, + + chooseUploadFolder() { + this.$chooseDriveFolder().then(folder => { + this.uploadFolder = folder ? folder.id : null; + this.uploadFolderName = folder ? folder.name : this.$t('@._settings.root'); + }) } } }); diff --git a/src/client/app/common/views/deck/deck.notification.vue b/src/client/app/common/views/deck/deck.notification.vue index 522f9b0d35..e1d9669002 100644 --- a/src/client/app/common/views/deck/deck.notification.vue +++ b/src/client/app/common/views/deck/deck.notification.vue @@ -12,7 +12,7 @@ </header> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note)" :plain="true" :custom-emojis="notification.note.emojis"/> + <mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :custom-emojis="notification.note.emojis"/> <fa icon="quote-right"/> </router-link> </div> @@ -30,7 +30,7 @@ </header> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note.renote)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note.renote)" :plain="true" :custom-emojis="notification.note.renote.emojis"/> + <mfm :text="getNoteSummary(notification.note.renote)" :plain="true" :nowrap="true" :custom-emojis="notification.note.renote.emojis"/> <fa icon="quote-right"/> </router-link> </div> @@ -74,7 +74,7 @@ </header> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note)" :plain="true" :custom-emojis="notification.note.emojis"/> + <mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :custom-emojis="notification.note.emojis"/> <fa icon="quote-right"/> </router-link> </div> diff --git a/src/client/app/common/views/deck/deck.page-column.vue b/src/client/app/common/views/deck/deck.page-column.vue new file mode 100644 index 0000000000..0ef391a51d --- /dev/null +++ b/src/client/app/common/views/deck/deck.page-column.vue @@ -0,0 +1,69 @@ +<template> +<x-column> + <template #header> + <fa :icon="faStickyNote"/>{{ page ? page.name : '' }} + </template> + + <div v-if="page"> + <x-page :page="page" :key="page.id"/> + </div> +</x-column> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import { faStickyNote } from '@fortawesome/free-regular-svg-icons'; +import i18n from '../../../i18n'; +import XColumn from './deck.column.vue'; +import XPage from '../../../common/views/components/page/page.vue'; + +export default Vue.extend({ + i18n: i18n(), + + components: { + XColumn, + XPage + }, + + props: { + pageName: { + type: String, + required: true + }, + username: { + type: String, + required: true + }, + }, + + data() { + return { + page: null, + faStickyNote + }; + }, + + watch: { + $route: 'fetch' + }, + + created() { + this.fetch(); + }, + + methods: { + fetch() { + this.$root.api('pages/show', { + name: this.pageName, + username: this.username, + }).then(page => { + this.page = page; + this.$emit('init', { + title: this.page.title, + icon: faStickyNote + }); + }); + } + } +}); +</script> diff --git a/src/client/app/common/views/deck/deck.user-column.home.vue b/src/client/app/common/views/deck/deck.user-column.home.vue index 56b117a7dd..9fb50a6672 100644 --- a/src/client/app/common/views/deck/deck.user-column.home.vue +++ b/src/client/app/common/views/deck/deck.user-column.home.vue @@ -1,5 +1,11 @@ <template> <div> + <ui-container v-if="user.pinnedPage" :body-togglable="true"> + <template #header><fa icon="thumbtack"/> {{ $t('pinned-page') }}</template> + <div> + <x-page :page="user.pinnedPage" :key="user.pinnedPage.id" :show-title="!user.pinnedPage.hideTitleWhenPinned"/> + </div> + </ui-container> <ui-container v-if="user.pinnedNotes && user.pinnedNotes.length > 0" :body-togglable="true"> <template #header><fa icon="thumbtack"/> {{ $t('pinned-notes') }}</template> <div> @@ -48,6 +54,7 @@ export default Vue.extend({ components: { XNotes, + XPage: () => import('../../../common/views/components/page/page.vue').then(m => m.default), }, props: { diff --git a/src/client/app/common/views/pages/page-editor/els/page-editor.el.button.vue b/src/client/app/common/views/pages/page-editor/els/page-editor.el.button.vue index 04001d8560..6a82b0eec9 100644 --- a/src/client/app/common/views/pages/page-editor/els/page-editor.el.button.vue +++ b/src/client/app/common/views/pages/page-editor/els/page-editor.el.button.vue @@ -17,6 +17,17 @@ <template v-else-if="value.action === 'pushEvent'"> <ui-input v-model="value.event"><span>{{ $t('blocks._button._action._pushEvent.event') }}</span></ui-input> <ui-input v-model="value.message"><span>{{ $t('blocks._button._action._pushEvent.message') }}</span></ui-input> + <ui-select v-model="value.var"> + <template #label>{{ $t('blocks._button._action._pushEvent.variable') }}</template> + <option :value="null">{{ $t('blocks._button._action._pushEvent.no-variable') }}</option> + <option v-for="v in aiScript.getVarsByType()" :value="v.name">{{ v.name }}</option> + <optgroup :label="$t('script.pageVariables')"> + <option v-for="v in aiScript.getPageVarsByType()" :value="v">{{ v }}</option> + </optgroup> + <optgroup :label="$t('script.enviromentVariables')"> + <option v-for="v in aiScript.getEnvVarsByType()" :value="v">{{ v }}</option> + </optgroup> + </ui-select> </template> </section> </x-container> @@ -39,6 +50,9 @@ export default Vue.extend({ value: { required: true }, + aiScript: { + required: true, + }, }, data() { @@ -53,7 +67,8 @@ export default Vue.extend({ if (this.value.content == null) Vue.set(this.value, 'content', null); if (this.value.event == null) Vue.set(this.value, 'event', null); if (this.value.message == null) Vue.set(this.value, 'message', null); - if (this.value.message == null) Vue.set(this.value, 'primary', false); + if (this.value.primary == null) Vue.set(this.value, 'primary', false); + if (this.value.var == null) Vue.set(this.value, 'var', null); }, }); </script> diff --git a/src/client/app/common/views/pages/page-editor/page-editor.vue b/src/client/app/common/views/pages/page-editor/page-editor.vue index ebe0f4688d..ade7d86991 100644 --- a/src/client/app/common/views/pages/page-editor/page-editor.vue +++ b/src/client/app/common/views/pages/page-editor/page-editor.vue @@ -35,6 +35,8 @@ <option value="sans-serif">{{ $t('fontSansSerif') }}</option> </ui-select> + <ui-switch v-model="hideTitleWhenPinned">{{ $t('hide-title-when-pinned') }}</ui-switch> + <div class="eyeCatch"> <ui-button v-if="eyeCatchingImageId == null && !readonly" @click="setEyeCatchingImage()"><fa :icon="faPlus"/> {{ $t('set-eye-catching-image') }}</ui-button> <div v-else-if="eyeCatchingImage"> @@ -140,6 +142,7 @@ export default Vue.extend({ font: 'sans-serif', content: [], alignCenter: false, + hideTitleWhenPinned: false, variables: [], aiScript: null, showOptions: false, @@ -192,6 +195,7 @@ export default Vue.extend({ this.currentName = this.page.name; this.summary = this.page.summary; this.font = this.page.font; + this.hideTitleWhenPinned = this.page.hideTitleWhenPinned; this.alignCenter = this.page.alignCenter; this.content = this.page.content; this.variables = this.page.variables; @@ -223,6 +227,7 @@ export default Vue.extend({ name: this.name.trim(), summary: this.summary, font: this.font, + hideTitleWhenPinned: this.hideTitleWhenPinned, alignCenter: this.alignCenter, content: this.content, variables: this.variables, @@ -240,6 +245,7 @@ export default Vue.extend({ name: this.name.trim(), summary: this.summary, font: this.font, + hideTitleWhenPinned: this.hideTitleWhenPinned, alignCenter: this.alignCenter, content: this.content, variables: this.variables, diff --git a/src/client/app/common/views/pages/page.vue b/src/client/app/common/views/pages/page.vue new file mode 100644 index 0000000000..d1c4c2be43 --- /dev/null +++ b/src/client/app/common/views/pages/page.vue @@ -0,0 +1,63 @@ +<template> +<x-page v-if="page" :page="page" :key="page.id" :show-footer="true"/> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import { faStickyNote } from '@fortawesome/free-regular-svg-icons'; +import XPage from '../components/page/page.vue'; + +export default Vue.extend({ + components: { + XPage + }, + + props: { + pageName: { + type: String, + required: true + }, + username: { + type: String, + required: true + }, + }, + + data() { + return { + page: null, + }; + }, + + computed: { + path(): string { + return this.username + '/' + this.pageName; + } + }, + + watch: { + path() { + this.fetch(); + } + }, + + created() { + this.fetch(); + }, + + methods: { + fetch() { + this.$root.api('pages/show', { + name: this.pageName, + username: this.username, + }).then(page => { + this.page = page; + this.$emit('init', { + title: this.page.title, + icon: faStickyNote + }); + }); + }, + } +}); +</script> diff --git a/src/client/app/common/views/widgets/post-form.vue b/src/client/app/common/views/widgets/post-form.vue index e180290f95..5e577c9a43 100644 --- a/src/client/app/common/views/widgets/post-form.vue +++ b/src/client/app/common/views/widgets/post-form.vue @@ -122,7 +122,7 @@ export default define({ }, upload(file) { - (this.$refs.uploader as any).upload(file); + (this.$refs.uploader as any).upload(file, this.$store.state.settings.uploadFolder); }, onDragover(e) { diff --git a/src/client/app/desktop/script.ts b/src/client/app/desktop/script.ts index 8065241714..1a4be33020 100644 --- a/src/client/app/desktop/script.ts +++ b/src/client/app/desktop/script.ts @@ -148,6 +148,7 @@ init(async (launch, os) => { { path: '/i/groups', component: DeckColumn, props: route => ({ component: () => import('../common/views/pages/user-groups.vue').then(m => m.default) }) }, { path: '/i/groups/:groupId', component: DeckColumn, props: route => ({ component: () => import('../common/views/pages/user-group-editor.vue').then(m => m.default), groupId: route.params.groupId }) }, { path: '/i/follow-requests', component: DeckColumn, props: route => ({ component: () => import('../common/views/pages/follow-requests.vue').then(m => m.default) }) }, + { path: '/@:username/pages/:pageName', name: 'page', props: true, component: () => import('../common/views/deck/deck.page-column.vue').then(m => m.default) }, ]} : { path: '/', component: MkHome, children: [ { path: '', name: 'index', component: MkHomeTimeline }, @@ -171,12 +172,11 @@ init(async (launch, os) => { { path: '/i/follow-requests', component: () => import('../common/views/pages/follow-requests.vue').then(m => m.default) }, { path: '/i/pages/new', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default) }, { path: '/i/pages/edit/:pageId', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), props: route => ({ initPageId: route.params.pageId }) }, - { path: '/@:user/pages/:page', component: () => import('../common/views/pages/page/page.vue').then(m => m.default), props: route => ({ pageName: route.params.page, username: route.params.user }) }, + { path: '/@:user/pages/:page', component: () => import('../common/views/pages/page.vue').then(m => m.default), props: route => ({ pageName: route.params.page, username: route.params.user }) }, { path: '/@:user/pages/:pageName/view-source', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) }, ]}, { path: '/i/pages/new', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default) }, { path: '/i/pages/edit/:pageId', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), props: route => ({ initPageId: route.params.pageId }) }, - { path: '/@:user/pages/:page', component: () => import('../common/views/pages/page/page.vue').then(m => m.default), props: route => ({ pageName: route.params.page, username: route.params.user }) }, { path: '/@:user/pages/:pageName/view-source', component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), props: route => ({ initUser: route.params.user, initPageName: route.params.pageName }) }, { path: '/i/messaging/group/:group', component: MkMessagingRoom }, { path: '/i/messaging/:user', component: MkMessagingRoom }, diff --git a/src/client/app/desktop/views/components/drive.folder.vue b/src/client/app/desktop/views/components/drive.folder.vue index fd6de5a05e..cf59d51b01 100644 --- a/src/client/app/desktop/views/components/drive.folder.vue +++ b/src/client/app/desktop/views/components/drive.folder.vue @@ -20,6 +20,9 @@ <template v-if="!hover"><fa :icon="['far', 'folder']" fixed-width/></template> {{ folder.name }} </p> + <p class="upload" v-if="$store.state.settings.uploadFolder == folder.id"> + {{ $t('upload-folder') }} + </p> </div> </template> @@ -73,6 +76,14 @@ export default Vue.extend({ text: this.$t('@.delete'), icon: ['far', 'trash-alt'], action: this.deleteFolder + }, null, { + type: 'nest', + text: this.$t('contextmenu.else-folders'), + menu: [{ + type: 'item', + text: this.$t('contextmenu.set-as-upload-folder'), + action: this.setAsUploadFolder + }] }], { closed: () => { this.isContextmenuShowing = false; @@ -213,8 +224,37 @@ export default Vue.extend({ deleteFolder() { this.$root.api('drive/folders/delete', { folderId: this.folder.id + }).then(() => { + if (this.$store.state.settings.uploadFolder === this.folder.id) { + this.$store.dispatch('settings/set', { + key: 'uploadFolder', + value: null + }); + } + }).catch(err => { + switch(err.id) { + case 'b0fc8a17-963c-405d-bfbc-859a487295e1': + this.$root.dialog({ + type: 'error', + title: this.$t('unable-to-delete'), + text: this.$t('has-child-files-or-folders') + }); + break; + default: + this.$root.dialog({ + type: 'error', + text: this.$t('unable-to-delete') + }); + } }); - } + }, + + setAsUploadFolder() { + this.$store.dispatch('settings/set', { + key: 'uploadFolder', + value: this.folder.id + }); + }, } }); </script> @@ -264,4 +304,10 @@ export default Vue.extend({ margin-left 2px text-align left + > .upload + margin 4px 4px + font-size 0.8em + text-align right + color var(--desktopDriveFolderFg) + </style> diff --git a/src/client/app/desktop/views/components/notifications.vue b/src/client/app/desktop/views/components/notifications.vue index aa8b023993..b25f122e0e 100644 --- a/src/client/app/desktop/views/components/notifications.vue +++ b/src/client/app/desktop/views/components/notifications.vue @@ -24,7 +24,7 @@ </p> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note)" :plain="true" :custom-emojis="notification.note.emojis"/> + <mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :custom-emojis="notification.note.emojis"/> <fa icon="quote-right"/> </router-link> </div> @@ -40,7 +40,7 @@ </p> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note.renote)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note.renote)" :plain="true" :custom-emojis="notification.note.renote.emojis"/> + <mfm :text="getNoteSummary(notification.note.renote)" :plain="true" :nowrap="true" :custom-emojis="notification.note.renote.emojis"/> <fa icon="quote-right"/> </router-link> </div> @@ -118,7 +118,7 @@ </router-link></p> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note)" :plain="true" :custom-emojis="notification.note.emojis"/> + <mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :custom-emojis="notification.note.emojis"/> <fa icon="quote-right"/> </router-link> </div> diff --git a/src/client/app/desktop/views/home/user/user.home.vue b/src/client/app/desktop/views/home/user/user.home.vue index ec533efd3e..c47e0a0771 100644 --- a/src/client/app/desktop/views/home/user/user.home.vue +++ b/src/client/app/desktop/views/home/user/user.home.vue @@ -1,5 +1,6 @@ <template> <div class="lnctpgve"> + <x-page v-if="user.pinnedPage" :page="user.pinnedPage" :key="user.pinnedPage.id" :show-title="!user.pinnedPage.hideTitleWhenPinned"/> <mk-note-detail v-for="n in user.pinnedNotes" :key="n.id" :note="n" :compact="true"/> <!--<mk-calendar @chosen="warp" :start="new Date(user.createdAt)"/>--> <div class="activity"> @@ -21,13 +22,15 @@ import i18n from '../../../../i18n'; import XTimeline from './user.timeline.vue'; import XPhotos from './user.photos.vue'; import XActivity from '../../../../common/views/components/activity.vue'; +import XPage from '../../../../common/views/components/page/page.vue'; export default Vue.extend({ i18n: i18n(), components: { XTimeline, XPhotos, - XActivity + XActivity, + XPage, }, props: { user: { diff --git a/src/client/app/mobile/script.ts b/src/client/app/mobile/script.ts index d04662cc1f..6222409931 100644 --- a/src/client/app/mobile/script.ts +++ b/src/client/app/mobile/script.ts @@ -129,6 +129,7 @@ init((launch, os) => { { path: '/i/groups', component: DeckColumn, props: route => ({ component: () => import('../common/views/pages/user-groups.vue').then(m => m.default) }) }, { path: '/i/groups/:groupId', component: DeckColumn, props: route => ({ component: () => import('../common/views/pages/user-group-editor.vue').then(m => m.default), groupId: route.params.groupId }) }, { path: '/i/follow-requests', component: DeckColumn, props: route => ({ component: () => import('../common/views/pages/follow-requests.vue').then(m => m.default) }) }, + { path: '/@:username/pages/:pageName', name: 'page', props: true, component: () => import('../common/views/deck/deck.page-column.vue').then(m => m.default) }, ]}] : [ { path: '/', name: 'index', component: MkIndex }, @@ -163,7 +164,7 @@ init((launch, os) => { { path: 'following', component: () => import('../common/views/pages/following.vue').then(m => m.default) }, { path: 'followers', component: () => import('../common/views/pages/followers.vue').then(m => m.default) }, ]}, - { path: '/@:user/pages/:page', component: UI, props: route => ({ component: () => import('../common/views/pages/page/page.vue').then(m => m.default), pageName: route.params.page, username: route.params.user }) }, + { path: '/@:user/pages/:page', component: UI, props: route => ({ component: () => import('../common/views/pages/page.vue').then(m => m.default), pageName: route.params.page, username: route.params.user }) }, { path: '/@:user/pages/:pageName/view-source', component: UI, props: route => ({ component: () => import('../common/views/pages/page-editor/page-editor.vue').then(m => m.default), initUser: route.params.user, initPageName: route.params.pageName }) }, { path: '/notes/:note', component: MkNote }, { path: '/authorize-follow', component: MkFollow }, diff --git a/src/client/app/mobile/views/components/notification.vue b/src/client/app/mobile/views/components/notification.vue index 7b1030122f..448d22cbe6 100644 --- a/src/client/app/mobile/views/components/notification.vue +++ b/src/client/app/mobile/views/components/notification.vue @@ -10,7 +10,7 @@ </header> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note)" :plain="true" :custom-emojis="notification.note.emojis"/> + <mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :custom-emojis="notification.note.emojis"/> <fa icon="quote-right"/> </router-link> </div> @@ -26,7 +26,7 @@ </header> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note.renote)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note.renote)" :plain="true" :custom-emojis="notification.note.renote.emojis"/> + <mfm :text="getNoteSummary(notification.note.renote)" :plain="true" :nowrap="true" :custom-emojis="notification.note.renote.emojis"/> <fa icon="quote-right"/> </router-link> </div> @@ -64,7 +64,7 @@ </header> <router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> <fa icon="quote-left"/> - <mfm :text="getNoteSummary(notification.note)" :plain="true" :custom-emojis="notification.note.emojis"/> + <mfm :text="getNoteSummary(notification.note)" :plain="true" :nowrap="true" :custom-emojis="notification.note.emojis"/> <fa icon="quote-right"/> </router-link> </div> diff --git a/src/client/app/mobile/views/pages/user/home.vue b/src/client/app/mobile/views/pages/user/home.vue index 1d7b0a4e6d..316b2a12fe 100644 --- a/src/client/app/mobile/views/pages/user/home.vue +++ b/src/client/app/mobile/views/pages/user/home.vue @@ -1,5 +1,6 @@ <template> <div class="wojmldye"> + <x-page class="page" v-if="user.pinnedPage" :page="user.pinnedPage" :key="user.pinnedPage.id" :show-title="!user.pinnedPage.hideTitleWhenPinned"/> <mk-note-detail class="note" v-for="n in user.pinnedNotes" :key="n.id" :note="n" :compact="true"/> <ui-container :body-togglable="true"> <template #header><fa :icon="['far', 'comments']"/>{{ $t('recent-notes') }}</template> @@ -33,6 +34,7 @@ export default Vue.extend({ components: { XNotes, XPhotos, + XPage: () => import('../../../../common/views/components/page/page.vue').then(m => m.default), XActivity: () => import('../../../../common/views/components/activity.vue').then(m => m.default) }, props: ['user'], @@ -53,6 +55,12 @@ export default Vue.extend({ <style lang="stylus" scoped> .wojmldye + > .page + margin 0 0 8px 0 + + @media (min-width 500px) + margin 0 0 16px 0 + > .note margin 0 0 8px 0 diff --git a/src/client/app/store.ts b/src/client/app/store.ts index cca7a5c2ce..252feb3982 100644 --- a/src/client/app/store.ts +++ b/src/client/app/store.ts @@ -38,6 +38,7 @@ const defaultSettings = { homeProfiles: {}, mobileHomeProfiles: {}, deckProfiles: {}, + uploadFolder: null, }; const defaultDeviceSettings = { |