diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2019-04-14 20:38:55 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2019-04-14 20:38:55 +0900 |
| commit | d66e4b7ff97d512e2a2523815e2eef170456b37f (patch) | |
| tree | 59ae1a102d88b5c2c2236b734ea4a584b4f9ba46 /src/client | |
| parent | 10.100.0 (diff) | |
| parent | 11.0.0 (diff) | |
| download | misskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.tar.gz misskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.tar.bz2 misskey-d66e4b7ff97d512e2a2523815e2eef170456b37f.zip | |
Merge branch 'develop'
Diffstat (limited to 'src/client')
90 files changed, 499 insertions, 592 deletions
diff --git a/src/client/app/admin/views/drive.vue b/src/client/app/admin/views/drive.vue index 7812aadaaf..e4565b78fe 100644 --- a/src/client/app/admin/views/drive.vue +++ b/src/client/app/admin/views/drive.vue @@ -38,7 +38,7 @@ <div class="kidvdlkg" v-for="file in files"> <div @click="file._open = !file._open"> <div> - <div class="thumbnail" :style="thumbnail(file)"></div> + <x-file-thumbnail class="thumbnail" :file="file" fit="contain" @click="showFileMenu(file)"/> </div> <div> <header> @@ -48,7 +48,7 @@ <div> <div> <span style="margin-right:16px;">{{ file.type }}</span> - <span>{{ file.datasize | bytes }}</span> + <span>{{ file.size | bytes }}</span> </div> <div><mk-time :time="file.createdAt" mode="detail"/></div> </div> @@ -75,10 +75,15 @@ import Vue from 'vue'; import i18n from '../../i18n'; import { faCloud, faTerminal, faSearch } from '@fortawesome/free-solid-svg-icons'; import { faTrashAlt, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons'; +import XFileThumbnail from '../../common/views/components/drive-file-thumbnail.vue'; export default Vue.extend({ i18n: i18n('admin/views/drive.vue'), + components: { + XFileThumbnail + }, + data() { return { file: null, @@ -151,13 +156,6 @@ export default Vue.extend({ }); }, - thumbnail(file: any): any { - return { - 'background-color': file.properties.avgColor && file.properties.avgColor.length == 3 ? `rgb(${file.properties.avgColor.join(',')})` : 'transparent', - 'background-image': `url(${file.thumbnailUrl})` - }; - }, - async del(file: any) { const process = async () => { await this.$root.api('drive/files/delete', { fileId: file.id }); @@ -179,9 +177,9 @@ export default Vue.extend({ this.$root.api('drive/files/update', { fileId: file.id, isSensitive: !file.isSensitive + }).then(() => { + file.isSensitive = !file.isSensitive; }); - - file.isSensitive = !file.isSensitive; }, async show() { diff --git a/src/client/app/admin/views/hashtags.vue b/src/client/app/admin/views/hashtags.vue index b3190c29c4..e1cc4b494d 100644 --- a/src/client/app/admin/views/hashtags.vue +++ b/src/client/app/admin/views/hashtags.vue @@ -3,7 +3,7 @@ <ui-card> <template #title>{{ $t('hided-tags') }}</template> <section> - <textarea class="jdnqwkzlnxcfftthoybjxrebyolvoucw" v-model="hidedTags"></textarea> + <textarea class="jdnqwkzlnxcfftthoybjxrebyolvoucw" v-model="hiddenTags"></textarea> <ui-button @click="save">{{ $t('save') }}</ui-button> </section> </ui-card> @@ -18,18 +18,18 @@ export default Vue.extend({ i18n: i18n('admin/views/hashtags.vue'), data() { return { - hidedTags: '', + hiddenTags: '', }; }, created() { this.$root.getMeta().then(meta => { - this.hidedTags = meta.hidedTags.join('\n'); + this.hiddenTags = meta.hiddenTags.join('\n'); }); }, methods: { save() { this.$root.api('admin/update-meta', { - hidedTags: this.hidedTags.split('\n') + hiddenTags: this.hiddenTags.split('\n') }).then(() => { //this.$root.os.apis.dialog({ text: `Saved` }); }).catch(e => { diff --git a/src/client/app/admin/views/instance.vue b/src/client/app/admin/views/instance.vue index 2d2a07784b..bc2a5fba85 100644 --- a/src/client/app/admin/views/instance.vue +++ b/src/client/app/admin/views/instance.vue @@ -78,12 +78,6 @@ <ui-input v-model="summalyProxy">URL</ui-input> </section> <section> - <header><fa :icon="faUserPlus"/> {{ $t('user-recommendation-config') }}</header> - <ui-switch v-model="enableExternalUserRecommendation">{{ $t('enable-external-user-recommendation') }}</ui-switch> - <ui-input v-model="externalUserRecommendationEngine" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-engine') }}<template #desc>{{ $t('external-user-recommendation-engine-desc') }}</template></ui-input> - <ui-input v-model="externalUserRecommendationTimeout" type="number" :disabled="!enableExternalUserRecommendation">{{ $t('external-user-recommendation-timeout') }}<template #suffix>ms</template><template #desc>{{ $t('external-user-recommendation-timeout-desc') }}</template></ui-input> - </section> - <section> <ui-button @click="updateMeta">{{ $t('save') }}</ui-button> </section> </ui-card> @@ -184,9 +178,6 @@ export default Vue.extend({ discordClientSecret: null, proxyAccount: null, inviteCode: null, - enableExternalUserRecommendation: false, - externalUserRecommendationEngine: null, - externalUserRecommendationTimeout: null, summalyProxy: null, enableEmail: false, email: null, @@ -205,8 +196,8 @@ export default Vue.extend({ created() { this.$root.getMeta().then(meta => { - this.maintainerName = meta.maintainer.name; - this.maintainerEmail = meta.maintainer.email; + this.maintainerName = meta.maintainerName; + this.maintainerEmail = meta.maintainerEmail; this.disableRegistration = meta.disableRegistration; this.disableLocalTimeline = meta.disableLocalTimeline; this.disableGlobalTimeline = meta.disableGlobalTimeline; @@ -236,9 +227,6 @@ export default Vue.extend({ this.enableDiscordIntegration = meta.enableDiscordIntegration; this.discordClientId = meta.discordClientId; this.discordClientSecret = meta.discordClientSecret; - this.enableExternalUserRecommendation = meta.enableExternalUserRecommendation; - this.externalUserRecommendationEngine = meta.externalUserRecommendationEngine; - this.externalUserRecommendationTimeout = meta.externalUserRecommendationTimeout; this.summalyProxy = meta.summalyProxy; this.enableEmail = meta.enableEmail; this.email = meta.email; @@ -299,9 +287,6 @@ export default Vue.extend({ enableDiscordIntegration: this.enableDiscordIntegration, discordClientId: this.discordClientId, discordClientSecret: this.discordClientSecret, - enableExternalUserRecommendation: this.enableExternalUserRecommendation, - externalUserRecommendationEngine: this.externalUserRecommendationEngine, - externalUserRecommendationTimeout: parseInt(this.externalUserRecommendationTimeout, 10), summalyProxy: this.summalyProxy, enableEmail: this.enableEmail, email: this.email, diff --git a/src/client/app/admin/views/logs.vue b/src/client/app/admin/views/logs.vue index 4a2d957ed7..5c2cfdb396 100644 --- a/src/client/app/admin/views/logs.vue +++ b/src/client/app/admin/views/logs.vue @@ -19,7 +19,7 @@ </ui-horizon-group> <div class="nqjzuvev"> - <code v-for="log in logs" :key="log._id" :class="log.level"> + <code v-for="log in logs" :key="log.id" :class="log.level"> <details> <summary><mk-time :time="log.createdAt"/> [{{ log.domain.join('.') }}] {{ log.message }}</summary> <vue-json-pretty v-if="log.data" :data="log.data"></vue-json-pretty> diff --git a/src/client/app/admin/views/users.vue b/src/client/app/admin/views/users.vue index ff485cec86..0f46b564a9 100644 --- a/src/client/app/admin/views/users.vue +++ b/src/client/app/admin/views/users.vue @@ -165,7 +165,7 @@ export default Vue.extend({ /** 処理対象ユーザーの情報を更新する */ async refreshUser() { - this.$root.api('admin/show-user', { userId: this.user._id }).then(info => { + this.$root.api('admin/show-user', { userId: this.user.id }).then(info => { this.user = info; }); }, @@ -173,7 +173,7 @@ export default Vue.extend({ async resetPassword() { if (!await this.getConfirmed(this.$t('reset-password-confirm'))) return; - this.$root.api('admin/reset-password', { userId: this.user._id }).then(res => { + this.$root.api('admin/reset-password', { userId: this.user.id }).then(res => { this.$root.dialog({ type: 'success', text: this.$t('password-updated', { password: res.password }) @@ -187,7 +187,7 @@ export default Vue.extend({ this.verifying = true; const process = async () => { - await this.$root.api('admin/verify-user', { userId: this.user._id }); + await this.$root.api('admin/verify-user', { userId: this.user.id }); this.$root.dialog({ type: 'success', text: this.$t('verified') @@ -212,7 +212,7 @@ export default Vue.extend({ this.unverifying = true; const process = async () => { - await this.$root.api('admin/unverify-user', { userId: this.user._id }); + await this.$root.api('admin/unverify-user', { userId: this.user.id }); this.$root.dialog({ type: 'success', text: this.$t('unverified') @@ -233,7 +233,7 @@ export default Vue.extend({ async silenceUser() { const process = async () => { - await this.$root.api('admin/silence-user', { userId: this.user._id }); + await this.$root.api('admin/silence-user', { userId: this.user.id }); this.$root.dialog({ type: 'success', splash: true @@ -252,7 +252,7 @@ export default Vue.extend({ async unsilenceUser() { const process = async () => { - await this.$root.api('admin/unsilence-user', { userId: this.user._id }); + await this.$root.api('admin/unsilence-user', { userId: this.user.id }); this.$root.dialog({ type: 'success', splash: true @@ -275,7 +275,7 @@ export default Vue.extend({ this.suspending = true; const process = async () => { - await this.$root.api('admin/suspend-user', { userId: this.user._id }); + await this.$root.api('admin/suspend-user', { userId: this.user.id }); this.$root.dialog({ type: 'success', text: this.$t('suspended') @@ -300,7 +300,7 @@ export default Vue.extend({ this.unsuspending = true; const process = async () => { - await this.$root.api('admin/unsuspend-user', { userId: this.user._id }); + await this.$root.api('admin/unsuspend-user', { userId: this.user.id }); this.$root.dialog({ type: 'success', text: this.$t('unsuspended') @@ -320,7 +320,7 @@ export default Vue.extend({ }, async updateRemoteUser() { - this.$root.api('admin/update-remote-user', { userId: this.user._id }).then(res => { + this.$root.api('admin/update-remote-user', { userId: this.user.id }).then(res => { this.$root.dialog({ type: 'success', text: this.$t('remote-user-updated') diff --git a/src/client/app/auth/views/form.vue b/src/client/app/auth/views/form.vue index 105af375b6..b640a40560 100644 --- a/src/client/app/auth/views/form.vue +++ b/src/client/app/auth/views/form.vue @@ -14,15 +14,7 @@ <h2>{{ $t('permission-ask') }}</h2> <ul> <template v-for="p in app.permission"> - <li v-if="p == 'account-read'">{{ $t('account-read') }}</li> - <li v-if="p == 'account-write'">{{ $t('account-write') }}</li> - <li v-if="p == 'note-write'">{{ $t('note-write') }}</li> - <li v-if="p == 'like-write'">{{ $t('like-write') }}</li> - <li v-if="p == 'following-write'">{{ $t('following-write') }}</li> - <li v-if="p == 'drive-read'">{{ $t('drive-read') }}</li> - <li v-if="p == 'drive-write'">{{ $t('drive-write') }}</li> - <li v-if="p == 'notification-read'">{{ $t('notification-read') }}</li> - <li v-if="p == 'notification-write'">{{ $t('notification-write') }}</li> + <li :key="p">{{ $t(`@.permissions.${p}`) }}</li> </template> </ul> </section> diff --git a/src/client/app/common/define-widget.ts b/src/client/app/common/define-widget.ts index 1efdbb1880..632ddf2ed6 100644 --- a/src/client/app/common/define-widget.ts +++ b/src/client/app/common/define-widget.ts @@ -45,15 +45,9 @@ export default function <T extends object>(data: { this.$watch('props', () => { this.mergeProps(); }); - - this.bakeProps(); }, methods: { - bakeProps() { - this.bakedOldProps = JSON.stringify(this.props); - }, - mergeProps() { if (data.props) { const defaultProps = data.props(); @@ -65,17 +59,10 @@ export default function <T extends object>(data: { }, save() { - if (this.bakedOldProps == JSON.stringify(this.props)) return; - - this.bakeProps(); - if (this.platform == 'deck') { this.$store.commit('device/updateDeckColumn', this.column); } else { - this.$root.api('i/update_widget', { - id: this.id, - data: this.props - }); + this.$store.commit('device/updateWidget', this.widget); } } } diff --git a/src/client/app/common/scripts/note-mixin.ts b/src/client/app/common/scripts/note-mixin.ts index 5707d1bb41..67bbe8c0ae 100644 --- a/src/client/app/common/scripts/note-mixin.ts +++ b/src/client/app/common/scripts/note-mixin.ts @@ -70,8 +70,8 @@ export default (opts: Opts = {}) => ({ }, reactionsCount(): number { - return this.appearNote.reactionCounts - ? sum(Object.values(this.appearNote.reactionCounts)) + return this.appearNote.reactions + ? sum(Object.values(this.appearNote.reactions)) : 0; }, diff --git a/src/client/app/common/scripts/note-subscriber.ts b/src/client/app/common/scripts/note-subscriber.ts index c2b4dd6df9..02d810ded9 100644 --- a/src/client/app/common/scripts/note-subscriber.ts +++ b/src/client/app/common/scripts/note-subscriber.ts @@ -87,16 +87,16 @@ export default prop => ({ case 'reacted': { const reaction = body.reaction; - if (this.$_ns_target.reactionCounts == null) { - Vue.set(this.$_ns_target, 'reactionCounts', {}); + if (this.$_ns_target.reactions == null) { + Vue.set(this.$_ns_target, 'reactions', {}); } - if (this.$_ns_target.reactionCounts[reaction] == null) { - Vue.set(this.$_ns_target.reactionCounts, reaction, 0); + if (this.$_ns_target.reactions[reaction] == null) { + Vue.set(this.$_ns_target.reactions, reaction, 0); } // Increment the count - this.$_ns_target.reactionCounts[reaction]++; + this.$_ns_target.reactions[reaction]++; if (body.userId == this.$store.state.i.id) { Vue.set(this.$_ns_target, 'myReaction', reaction); @@ -107,16 +107,16 @@ export default prop => ({ case 'unreacted': { const reaction = body.reaction; - if (this.$_ns_target.reactionCounts == null) { + if (this.$_ns_target.reactions == null) { return; } - if (this.$_ns_target.reactionCounts[reaction] == null) { + if (this.$_ns_target.reactions[reaction] == null) { return; } // Decrement the count - if (this.$_ns_target.reactionCounts[reaction] > 0) this.$_ns_target.reactionCounts[reaction]--; + if (this.$_ns_target.reactions[reaction] > 0) this.$_ns_target.reactions[reaction]--; if (body.userId == this.$store.state.i.id) { Vue.set(this.$_ns_target, 'myReaction', null); @@ -125,9 +125,11 @@ export default prop => ({ } case 'pollVoted': { - if (body.userId == this.$store.state.i.id) return; const choice = body.choice; - this.$_ns_target.poll.choices.find(c => c.id === choice).votes++; + this.$_ns_target.poll.choices[choice].votes++; + if (body.userId == this.$store.state.i.id) { + Vue.set(this.$_ns_target.poll.choices[choice], 'isVoted', true); + } break; } diff --git a/src/client/app/common/views/components/avatar.vue b/src/client/app/common/views/components/avatar.vue index dce594e702..04f3ed9f78 100644 --- a/src/client/app/common/views/components/avatar.vue +++ b/src/client/app/common/views/components/avatar.vue @@ -55,11 +55,7 @@ export default Vue.extend({ }, icon(): any { return { - backgroundColor: this.lightmode - ? `rgb(${this.user.avatarColor.slice(0, 3).join(',')})` - : this.user.avatarColor && this.user.avatarColor.length == 3 - ? `rgb(${this.user.avatarColor.join(',')})` - : null, + backgroundColor: this.user.avatarColor, backgroundImage: this.lightmode ? null : `url(${this.url})`, borderRadius: this.$store.state.settings.circleIcons ? '100%' : null }; @@ -67,7 +63,7 @@ export default Vue.extend({ }, mounted() { if (this.user.avatarColor) { - this.$el.style.color = `rgb(${this.user.avatarColor.slice(0, 3).join(',')})`; + this.$el.style.color = this.user.avatarColor; } }, methods: { diff --git a/src/client/app/common/views/components/drive-file-thumbnail.vue b/src/client/app/common/views/components/drive-file-thumbnail.vue index faa727f3b6..1a3ef37193 100644 --- a/src/client/app/common/views/components/drive-file-thumbnail.vue +++ b/src/client/app/common/views/components/drive-file-thumbnail.vue @@ -105,15 +105,11 @@ export default Vue.extend({ }, isThumbnailAvailable(): boolean { return this.file.thumbnailUrl - ? this.file.thumbnailUrl.endsWith('?thumbnail') - ? (this.is === 'image' || this.is === 'video') - : true + ? (this.is === 'image' || this.is === 'video') : false; }, background(): string { - return this.file.properties.avgColor && this.file.properties.avgColor.length == 3 - ? `rgb(${this.file.properties.avgColor.join(',')})` - : 'transparent'; + return this.file.properties.avgColor || 'transparent'; } }, mounted() { @@ -122,10 +118,10 @@ export default Vue.extend({ }, methods: { onThumbnailLoaded() { - if (this.file.properties.avgColor && this.file.properties.avgColor.length == 3) { + if (this.file.properties.avgColor) { anime({ targets: this.$refs.thumbnail, - backgroundColor: `rgba(${this.file.properties.avgColor.join(',')}, 0)`, + backgroundColor: this.file.properties.avgColor.replace('255)', '0)'), duration: 100, easing: 'linear' }); diff --git a/src/client/app/common/views/components/games/reversi/reversi.game.vue b/src/client/app/common/views/components/games/reversi/reversi.game.vue index c6fc36db33..bd0401f785 100644 --- a/src/client/app/common/views/components/games/reversi/reversi.game.vue +++ b/src/client/app/common/views/components/games/reversi/reversi.game.vue @@ -24,11 +24,11 @@ <div class="board"> <div class="labels-x" v-if="this.$store.state.settings.games.reversi.showBoardLabels"> - <span v-for="i in game.settings.map[0].length">{{ String.fromCharCode(64 + i) }}</span> + <span v-for="i in game.map[0].length">{{ String.fromCharCode(64 + i) }}</span> </div> <div class="flex"> <div class="labels-y" v-if="this.$store.state.settings.games.reversi.showBoardLabels"> - <div v-for="i in game.settings.map.length">{{ i }}</div> + <div v-for="i in game.map.length">{{ i }}</div> </div> <div class="cells" :style="cellsStyle"> <div v-for="(stone, i) in o.board" @@ -46,11 +46,11 @@ </div> </div> <div class="labels-y" v-if="this.$store.state.settings.games.reversi.showBoardLabels"> - <div v-for="i in game.settings.map.length">{{ i }}</div> + <div v-for="i in game.map.length">{{ i }}</div> </div> </div> <div class="labels-x" v-if="this.$store.state.settings.games.reversi.showBoardLabels"> - <span v-for="i in game.settings.map[0].length">{{ String.fromCharCode(64 + i) }}</span> + <span v-for="i in game.map[0].length">{{ String.fromCharCode(64 + i) }}</span> </div> </div> @@ -71,9 +71,9 @@ </div> <div class="info"> - <p v-if="game.settings.isLlotheo">{{ $t('is-llotheo') }}</p> - <p v-if="game.settings.loopedBoard">{{ $t('looped-map') }}</p> - <p v-if="game.settings.canPutEverywhere">{{ $t('can-put-everywhere') }}</p> + <p v-if="game.isLlotheo">{{ $t('is-llotheo') }}</p> + <p v-if="game.loopedBoard">{{ $t('looped-map') }}</p> + <p v-if="game.canPutEverywhere">{{ $t('can-put-everywhere') }}</p> </div> </div> </template> @@ -160,8 +160,8 @@ export default Vue.extend({ cellsStyle(): any { return { - 'grid-template-rows': `repeat(${this.game.settings.map.length}, 1fr)`, - 'grid-template-columns': `repeat(${this.game.settings.map[0].length}, 1fr)` + 'grid-template-rows': `repeat(${this.game.map.length}, 1fr)`, + 'grid-template-columns': `repeat(${this.game.map[0].length}, 1fr)` }; } }, @@ -169,10 +169,10 @@ export default Vue.extend({ watch: { logPos(v) { if (!this.game.isEnded) return; - this.o = new Reversi(this.game.settings.map, { - isLlotheo: this.game.settings.isLlotheo, - canPutEverywhere: this.game.settings.canPutEverywhere, - loopedBoard: this.game.settings.loopedBoard + this.o = new Reversi(this.game.map, { + isLlotheo: this.game.isLlotheo, + canPutEverywhere: this.game.canPutEverywhere, + loopedBoard: this.game.loopedBoard }); for (const log of this.logs.slice(0, v)) { this.o.put(log.color, log.pos); @@ -184,10 +184,10 @@ export default Vue.extend({ created() { this.game = this.initGame; - this.o = new Reversi(this.game.settings.map, { - isLlotheo: this.game.settings.isLlotheo, - canPutEverywhere: this.game.settings.canPutEverywhere, - loopedBoard: this.game.settings.loopedBoard + this.o = new Reversi(this.game.map, { + isLlotheo: this.game.isLlotheo, + canPutEverywhere: this.game.canPutEverywhere, + loopedBoard: this.game.loopedBoard }); for (const log of this.game.logs) { @@ -286,10 +286,10 @@ export default Vue.extend({ onRescue(game) { this.game = game; - this.o = new Reversi(this.game.settings.map, { - isLlotheo: this.game.settings.isLlotheo, - canPutEverywhere: this.game.settings.canPutEverywhere, - loopedBoard: this.game.settings.loopedBoard + this.o = new Reversi(this.game.map, { + isLlotheo: this.game.isLlotheo, + canPutEverywhere: this.game.canPutEverywhere, + loopedBoard: this.game.loopedBoard }); for (const log of this.game.logs) { diff --git a/src/client/app/common/views/components/games/reversi/reversi.room.vue b/src/client/app/common/views/components/games/reversi/reversi.room.vue index d5d148790c..9ee1a78b86 100644 --- a/src/client/app/common/views/components/games/reversi/reversi.room.vue +++ b/src/client/app/common/views/components/games/reversi/reversi.room.vue @@ -17,9 +17,9 @@ </header> <div> - <div class="random" v-if="game.settings.map == null"><fa icon="dice"/></div> - <div class="board" v-else :style="{ 'grid-template-rows': `repeat(${ game.settings.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map[0].length }, 1fr)` }"> - <div v-for="(x, i) in game.settings.map.join('')" + <div class="random" v-if="game.map == null"><fa icon="dice"/></div> + <div class="board" v-else :style="{ 'grid-template-rows': `repeat(${ game.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.map[0].length }, 1fr)` }"> + <div v-for="(x, i) in game.map.join('')" :data-none="x == ' '" @click="onPixelClick(i, x)"> <fa v-if="x == 'b'" :icon="fasCircle"/> @@ -35,9 +35,9 @@ </header> <div> - <form-radio v-model="game.settings.bw" value="random" @change="updateSettings">{{ $t('random') }}</form-radio> - <form-radio v-model="game.settings.bw" :value="1" @change="updateSettings">{{ this.$t('black-is').split('{}')[0] }}<b><mk-user-name :user="game.user1"/></b>{{ this.$t('black-is').split('{}')[1] }}</form-radio> - <form-radio v-model="game.settings.bw" :value="2" @change="updateSettings">{{ this.$t('black-is').split('{}')[0] }}<b><mk-user-name :user="game.user2"/></b>{{ this.$t('black-is').split('{}')[1] }}</form-radio> + <form-radio v-model="game.bw" value="random" @change="updateSettings('bw')">{{ $t('random') }}</form-radio> + <form-radio v-model="game.bw" :value="1" @change="updateSettings('bw')">{{ this.$t('black-is').split('{}')[0] }}<b><mk-user-name :user="game.user1"/></b>{{ this.$t('black-is').split('{}')[1] }}</form-radio> + <form-radio v-model="game.bw" :value="2" @change="updateSettings('bw')">{{ this.$t('black-is').split('{}')[0] }}<b><mk-user-name :user="game.user2"/></b>{{ this.$t('black-is').split('{}')[1] }}</form-radio> </div> </div> @@ -47,9 +47,9 @@ </header> <div> - <ui-switch v-model="game.settings.isLlotheo" @change="updateSettings">{{ $t('is-llotheo') }}</ui-switch> - <ui-switch v-model="game.settings.loopedBoard" @change="updateSettings">{{ $t('looped-map') }}</ui-switch> - <ui-switch v-model="game.settings.canPutEverywhere" @change="updateSettings">{{ $t('can-put-everywhere') }}</ui-switch> + <ui-switch v-model="game.isLlotheo" @change="updateSettings('isLlotheo')">{{ $t('is-llotheo') }}</ui-switch> + <ui-switch v-model="game.loopedBoard" @change="updateSettings('loopedBoard')">{{ $t('looped-map') }}</ui-switch> + <ui-switch v-model="game.canPutEverywhere" @change="updateSettings('canPutEverywhere')">{{ $t('can-put-everywhere') }}</ui-switch> </div> </div> @@ -159,8 +159,8 @@ export default Vue.extend({ this.connection.on('initForm', this.onInitForm); this.connection.on('message', this.onMessage); - if (this.game.user1Id != this.$store.state.i.id && this.game.settings.form1) this.form = this.game.settings.form1; - if (this.game.user2Id != this.$store.state.i.id && this.game.settings.form2) this.form = this.game.settings.form2; + if (this.game.user1Id != this.$store.state.i.id && this.game.form1) this.form = this.game.form1; + if (this.game.user2Id != this.$store.state.i.id && this.game.form2) this.form = this.game.form2; }, beforeDestroy() { @@ -189,18 +189,19 @@ export default Vue.extend({ this.$forceUpdate(); }, - updateSettings() { + updateSettings(key: string) { this.connection.send('updateSettings', { - settings: this.game.settings + key: key, + value: this.game[key] }); }, - onUpdateSettings(settings) { - this.game.settings = settings; - if (this.game.settings.map == null) { + onUpdateSettings({ key, value }) { + this.game[key] = value; + if (this.game.map == null) { this.mapName = null; } else { - const found = Object.values(maps).find(x => x.data.join('') == this.game.settings.map.join('')); + const found = Object.values(maps).find(x => x.data.join('') == this.game.map.join('')); this.mapName = found ? found.name : '-Custom-'; } }, @@ -224,27 +225,27 @@ export default Vue.extend({ onMapChange() { if (this.mapName == null) { - this.game.settings.map = null; + this.game.map = null; } else { - this.game.settings.map = Object.values(maps).find(x => x.name == this.mapName).data; + this.game.map = Object.values(maps).find(x => x.name == this.mapName).data; } this.$forceUpdate(); this.updateSettings(); }, onPixelClick(pos, pixel) { - const x = pos % this.game.settings.map[0].length; - const y = Math.floor(pos / this.game.settings.map[0].length); + const x = pos % this.game.map[0].length; + const y = Math.floor(pos / this.game.map[0].length); const newPixel = pixel == ' ' ? '-' : pixel == '-' ? 'b' : pixel == 'b' ? 'w' : ' '; - const line = this.game.settings.map[y].split(''); + const line = this.game.map[y].split(''); line[x] = newPixel; - this.$set(this.game.settings.map, y, line.join('')); + this.$set(this.game.map, y, line.join('')); this.$forceUpdate(); - this.updateSettings(); + this.updateSettings('map'); } } }); diff --git a/src/client/app/common/views/components/games/reversi/reversi.vue b/src/client/app/common/views/components/games/reversi/reversi.vue index b6803cd7f7..d33471a049 100644 --- a/src/client/app/common/views/components/games/reversi/reversi.vue +++ b/src/client/app/common/views/components/games/reversi/reversi.vue @@ -106,7 +106,7 @@ export default Vue.extend({ async nav(game, actualNav = true) { if (this.selfNav) { // 受け取ったゲーム情報が省略されたものなら完全な情報を取得する - if (game != null && (game.settings == null || game.settings.map == null)) { + if (game != null && game.map == null) { game = await this.$root.api('games/reversi/games/show', { gameId: game.id }); diff --git a/src/client/app/common/views/components/instance.vue b/src/client/app/common/views/components/instance.vue index 7b8d4f8e0b..497e4976f5 100644 --- a/src/client/app/common/views/components/instance.vue +++ b/src/client/app/common/views/components/instance.vue @@ -2,7 +2,7 @@ <div class="nhasjydimbopojusarffqjyktglcuxjy" v-if="meta"> <div class="banner" :style="{ backgroundImage: meta.bannerUrl ? `url(${meta.bannerUrl})` : null }"></div> - <h1>{{ meta.name }}</h1> + <h1>{{ meta.name || 'Misskey' }}</h1> <p v-html="meta.description || this.$t('@.about')"></p> <router-link to="/">{{ $t('start') }}</router-link> </div> diff --git a/src/client/app/common/views/components/media-image.vue b/src/client/app/common/views/components/media-image.vue index 3947ef5527..2559907512 100644 --- a/src/client/app/common/views/components/media-image.vue +++ b/src/client/app/common/views/components/media-image.vue @@ -52,7 +52,7 @@ export default Vue.extend({ } return { - 'background-color': this.image.properties.avgColor && this.image.properties.avgColor.length == 3 ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent', + 'background-color': this.image.properties.avgColor || 'transparent', 'background-image': url }; } diff --git a/src/client/app/common/views/components/mention.vue b/src/client/app/common/views/components/mention.vue index 11dddbd52a..e1f67282b6 100644 --- a/src/client/app/common/views/components/mention.vue +++ b/src/client/app/common/views/components/mention.vue @@ -33,7 +33,7 @@ export default Vue.extend({ }, computed: { canonical(): string { - return `@${this.username}@${toUnicode(this.host)}`; + return this.host === localHost ? `@${this.username}` : `@${this.username}@${toUnicode(this.host)}`; }, isMe(): boolean { return this.$store.getters.isSignedIn && this.canonical.toLowerCase() === `@${this.$store.state.i.username}@${toUnicode(localHost)}`.toLowerCase(); diff --git a/src/client/app/common/views/components/messaging-room.message.vue b/src/client/app/common/views/components/messaging-room.message.vue index ce76c402f3..256ea760b3 100644 --- a/src/client/app/common/views/components/messaging-room.message.vue +++ b/src/client/app/common/views/components/messaging-room.message.vue @@ -11,7 +11,7 @@ <div class="file" v-if="message.file"> <a :href="message.file.url" target="_blank" :title="message.file.name"> <img v-if="message.file.type.split('/')[0] == 'image'" :src="message.file.url" :alt="message.file.name" - :style="{ backgroundColor: message.file.properties.avgColor && message.file.properties.avgColor.length == 3 ? `rgb(${message.file.properties.avgColor.join(',')})` : 'transparent' }"/> + :style="{ backgroundColor: message.file.properties.avgColor || 'transparent' }"/> <p v-else>{{ message.file.name }}</p> </a> </div> diff --git a/src/client/app/common/views/components/poll.vue b/src/client/app/common/views/components/poll.vue index ba14ba3a44..dc3aaa34f3 100644 --- a/src/client/app/common/views/components/poll.vue +++ b/src/client/app/common/views/components/poll.vue @@ -1,7 +1,7 @@ <template> <div class="mk-poll" :data-done="closed || isVoted"> <ul> - <li v-for="choice in poll.choices" :key="choice.id" @click="vote(choice.id)" :class="{ voted: choice.voted }" :title="!closed && !isVoted ? $t('vote-to').replace('{}', choice.text) : ''"> + <li v-for="(choice, i) in poll.choices" :key="i" @click="vote(i)" :class="{ voted: choice.voted }" :title="!closed && !isVoted ? $t('vote-to').replace('{}', choice.text) : ''"> <div class="backdrop" :style="{ 'width': `${showResult ? (choice.votes / total * 100) : 0}%` }"></div> <span> <template v-if="choice.isVoted"><fa icon="check"/></template> @@ -82,12 +82,6 @@ export default Vue.extend({ noteId: this.note.id, choice: id }).then(() => { - for (const c of this.poll.choices) { - if (c.id == id) { - c.votes++; - Vue.set(c, 'isVoted', true); - } - } if (!this.showResult) this.showResult = !this.poll.multiple; }); } diff --git a/src/client/app/common/views/components/post-form-attaches.vue b/src/client/app/common/views/components/post-form-attaches.vue new file mode 100644 index 0000000000..467e430ccf --- /dev/null +++ b/src/client/app/common/views/components/post-form-attaches.vue @@ -0,0 +1,139 @@ +<template> +<div class="skeikyzd" v-show="files.length != 0"> + <x-draggable class="files" :list="files" :options="{ animation: 150 }"> + <div v-for="file in files" :key="file.id" @click="showFileMenu(file, $event)" @contextmenu.prevent="showFileMenu(file, $event)"> + <x-file-thumbnail :data-id="file.id" class="thumbnail" :file="file" fit="cover"/> + <img class="remove" @click.stop="detachMedia(file.id)" src="/assets/desktop/remove.png" :title="$t('attach-cancel')" alt=""/> + <div class="sensitive" v-if="file.isSensitive"> + <fa class="icon" :icon="faExclamationTriangle"/> + </div> + </div> + </x-draggable> + <p class="remain">{{ 4 - files.length }}/4</p> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import i18n from '../../../i18n'; +import * as XDraggable from 'vuedraggable'; +import XMenu from '../../../common/views/components/menu.vue'; +import { faTimesCircle, faEye, faEyeSlash } from '@fortawesome/free-regular-svg-icons'; +import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; +import XFileThumbnail from './drive-file-thumbnail.vue' + +export default Vue.extend({ + i18n: i18n('common/views/components/post-form-attaches.vue'), + + components: { + XDraggable, + XFileThumbnail + }, + + props: { + files: { + type: Object, + required: true + }, + detachMediaFn: { + type: Object, + required: false + } + }, + + data() { + return { + faExclamationTriangle + }; + }, + + methods: { + detachMedia(id) { + if (this.detachMediaFn) this.detachMediaFn(id) + else if (this.$parent.detachMedia) this.$parent.detachMedia(id) + }, + toggleSensitive(file) { + this.$root.api('drive/files/update', { + fileId: file.id, + isSensitive: !file.isSensitive + }).then(() => { + file.isSensitive = !file.isSensitive; + }); + }, + showFileMenu(file, ev: MouseEvent) { + this.$root.new(XMenu, { + items: [{ + type: 'item', + text: file.isSensitive ? this.$t('unmark-as-sensitive') : this.$t('mark-as-sensitive'), + icon: file.isSensitive ? faEyeSlash : faEye, + action: () => { this.toggleSensitive(file) } + }, { + type: 'item', + text: this.$t('attach-cancel'), + icon: faTimesCircle, + action: () => { this.detachMedia(file.id) } + }], + source: ev.currentTarget || ev.target + }); + } + } +}); +</script> + +<style lang="stylus" scoped> +.skeikyzd + padding 4px + + > .files + display flex + flex-wrap wrap + + > div + width 64px + height 64px + margin 4px + cursor move + + &:hover > .remove + display block + + > .thumbnail + width 100% + height 100% + z-index 1 + color var(--text) + + > .remove + display none + position absolute + top -6px + right -6px + width 16px + height 16px + cursor pointer + z-index 1000 + + > .sensitive + display flex + position absolute + width 64px + height 64px + top 0 + left 0 + z-index 2 + background rgba(17, 17, 17, .7) + color #fff + + > .icon + margin auto + + > .remain + display block + position absolute + top 8px + right 8px + margin 0 + padding 0 + color var(--primaryAlpha04) + +</style> diff --git a/src/client/app/common/views/components/reactions-viewer.vue b/src/client/app/common/views/components/reactions-viewer.vue index cf7f88b2f5..46668054b8 100644 --- a/src/client/app/common/views/components/reactions-viewer.vue +++ b/src/client/app/common/views/components/reactions-viewer.vue @@ -20,7 +20,7 @@ export default Vue.extend({ }, computed: { reactions(): any { - return this.note.reactionCounts; + return this.note.reactions; }, isMe(): boolean { return this.$store.getters.isSignedIn && this.$store.state.i.id === this.note.userId; diff --git a/src/client/app/common/views/components/settings/notification.vue b/src/client/app/common/views/components/settings/notification.vue index b689544d69..2554fe6331 100644 --- a/src/client/app/common/views/components/settings/notification.vue +++ b/src/client/app/common/views/components/settings/notification.vue @@ -2,7 +2,7 @@ <ui-card> <template #title><fa :icon="['far', 'bell']"/> {{ $t('title') }}</template> <section> - <ui-switch v-model="$store.state.i.settings.autoWatch" @change="onChangeAutoWatch"> + <ui-switch v-model="$store.state.i.autoWatch" @change="onChangeAutoWatch"> {{ $t('auto-watch') }}<template #desc>{{ $t('auto-watch-desc') }}</template> </ui-switch> <section> diff --git a/src/client/app/common/views/components/settings/profile.vue b/src/client/app/common/views/components/settings/profile.vue index b9837a6966..fd08f85816 100644 --- a/src/client/app/common/views/components/settings/profile.vue +++ b/src/client/app/common/views/components/settings/profile.vue @@ -158,14 +158,14 @@ export default Vue.extend({ computed: { alwaysMarkNsfw: { - get() { return this.$store.state.i.settings.alwaysMarkNsfw; }, + get() { return this.$store.state.i.alwaysMarkNsfw; }, set(value) { this.$root.api('i/update', { alwaysMarkNsfw: value }); } }, bannerStyle(): any { if (this.$store.state.i.bannerUrl == null) return {}; return { - backgroundColor: this.$store.state.i.bannerColor && this.$store.state.i.bannerColor.length == 3 ? `rgb(${ this.$store.state.i.bannerColor.join(',') })` : null, + backgroundColor: this.$store.state.i.bannerColor, backgroundImage: `url(${ this.$store.state.i.bannerUrl })` }; }, @@ -178,10 +178,10 @@ export default Vue.extend({ this.email = this.$store.state.i.email; this.name = this.$store.state.i.name; this.username = this.$store.state.i.username; - this.location = this.$store.state.i.profile.location; + this.location = this.$store.state.i.location; this.description = this.$store.state.i.description; this.lang = this.$store.state.i.lang; - this.birthday = this.$store.state.i.profile.birthday; + this.birthday = this.$store.state.i.birthday; this.avatarId = this.$store.state.i.avatarId; this.bannerId = this.$store.state.i.bannerId; this.isCat = this.$store.state.i.isCat; diff --git a/src/client/app/common/views/components/settings/theme.vue b/src/client/app/common/views/components/settings/theme.vue index 1dff61e459..3440aacb28 100644 --- a/src/client/app/common/views/components/settings/theme.vue +++ b/src/client/app/common/views/components/settings/theme.vue @@ -130,20 +130,6 @@ import * as tinycolor from 'tinycolor2'; import * as JSON5 from 'json5'; import { faMoon, faSun } from '@fortawesome/free-regular-svg-icons'; -// 後方互換性のため -function convertOldThemedefinition(t) { - const t2 = { - id: t.meta.id, - name: t.meta.name, - author: t.meta.author, - base: t.meta.base, - vars: t.meta.vars, - props: t - }; - delete t2.props.meta; - return t2; -} - export default Vue.extend({ i18n: i18n('common/views/components/theme.vue'), components: { @@ -231,20 +217,6 @@ export default Vue.extend({ } }, - beforeCreate() { - // migrate old theme definitions - // 後方互換性のため - this.$store.commit('device/set', { - key: 'themes', value: this.$store.state.device.themes.map(t => { - if (t.id == null) { - return convertOldThemedefinition(t); - } else { - return t; - } - }) - }); - }, - methods: { install(code) { let theme; @@ -259,11 +231,6 @@ export default Vue.extend({ return; } - // 後方互換性のため - if (theme.id == null && theme.meta != null) { - theme = convertOldThemedefinition(theme); - } - if (theme.id == null) { this.$root.dialog({ type: 'error', diff --git a/src/client/app/common/views/components/signup.vue b/src/client/app/common/views/components/signup.vue index 16e1afaa94..45c2eabd45 100644 --- a/src/client/app/common/views/components/signup.vue +++ b/src/client/app/common/views/components/signup.vue @@ -4,7 +4,7 @@ <ui-input v-if="meta.disableRegistration" v-model="invitationCode" type="text" :autocomplete="Math.random()" spellcheck="false" required styl="fill"> <span>{{ $t('invitation-code') }}</span> <template #prefix><fa icon="id-card-alt"/></template> - <template #desc v-html="this.$t('invitation-info').replace('{}', 'mailto:' + meta.maintainer.email)"></template> + <template #desc v-html="this.$t('invitation-info').replace('{}', 'mailto:' + meta.maintainerEmail)"></template> </ui-input> <ui-input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @input="onChangeUsername" styl="fill"> <span>{{ $t('username') }}</span> diff --git a/src/client/app/common/views/components/user-list-editor.vue b/src/client/app/common/views/components/user-list-editor.vue index 53c945ca0a..8d2e04d045 100644 --- a/src/client/app/common/views/components/user-list-editor.vue +++ b/src/client/app/common/views/components/user-list-editor.vue @@ -1,7 +1,7 @@ <template> <div class="cudqjmnl"> <ui-card> - <template #title><fa :icon="faList"/> {{ list.title }}</template> + <template #title><fa :icon="faList"/> {{ list.name }}</template> <section> <ui-button @click="rename"><fa :icon="faICursor"/> {{ $t('rename') }}</ui-button> @@ -75,7 +75,7 @@ export default Vue.extend({ this.$root.dialog({ title: this.$t('rename'), input: { - default: this.list.title + default: this.list.name } }).then(({ canceled, result: title }) => { if (canceled) return; @@ -89,7 +89,7 @@ export default Vue.extend({ del() { this.$root.dialog({ type: 'warning', - text: this.$t('delete-are-you-sure').replace('$1', this.list.title), + text: this.$t('delete-are-you-sure').replace('$1', this.list.name), showCancelButton: true }).then(({ canceled }) => { if (canceled) return; diff --git a/src/client/app/common/views/components/user-list.vue b/src/client/app/common/views/components/user-list.vue index b56cb13c3e..b8bcc35d82 100644 --- a/src/client/app/common/views/components/user-list.vue +++ b/src/client/app/common/views/components/user-list.vue @@ -51,7 +51,7 @@ export default Vue.extend({ fetchingMoreUsers: false, us: [], inited: false, - cursor: null + more: false }; }, diff --git a/src/client/app/common/views/components/user-menu.vue b/src/client/app/common/views/components/user-menu.vue index 93fd759fd9..a95f7a9225 100644 --- a/src/client/app/common/views/components/user-menu.vue +++ b/src/client/app/common/views/components/user-menu.vue @@ -73,7 +73,7 @@ export default Vue.extend({ title: t, select: { items: lists.map(list => ({ - value: list.id, text: list.title + value: list.id, text: list.name })) }, showCancelButton: true diff --git a/src/client/app/common/views/deck/deck.direct.vue b/src/client/app/common/views/deck/deck.direct.vue index 2618363b14..29db5cb7f3 100644 --- a/src/client/app/common/views/deck/deck.direct.vue +++ b/src/client/app/common/views/deck/deck.direct.vue @@ -28,12 +28,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/common/views/deck/deck.favorites-column.vue b/src/client/app/common/views/deck/deck.favorites-column.vue index 238938594f..526b998f87 100644 --- a/src/client/app/common/views/deck/deck.favorites-column.vue +++ b/src/client/app/common/views/deck/deck.favorites-column.vue @@ -37,12 +37,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/common/views/deck/deck.hashtag-tl.vue b/src/client/app/common/views/deck/deck.hashtag-tl.vue index 07d96f82c4..6f89f6a23d 100644 --- a/src/client/app/common/views/deck/deck.hashtag-tl.vue +++ b/src/client/app/common/views/deck/deck.hashtag-tl.vue @@ -28,7 +28,7 @@ export default Vue.extend({ data() { return { connection: null, - makePromise: cursor => this.$root.api('notes/search_by_tag', { + makePromise: cursor => this.$root.api('notes/search-by-tag', { limit: fetchLimit + 1, untilId: cursor ? cursor : undefined, withFiles: this.mediaOnly, @@ -41,12 +41,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/common/views/deck/deck.list-tl.vue b/src/client/app/common/views/deck/deck.list-tl.vue index d1887990f2..24080ad4ea 100644 --- a/src/client/app/common/views/deck/deck.list-tl.vue +++ b/src/client/app/common/views/deck/deck.list-tl.vue @@ -41,12 +41,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/common/views/deck/deck.mentions.vue b/src/client/app/common/views/deck/deck.mentions.vue index 1efd778226..153b4cd052 100644 --- a/src/client/app/common/views/deck/deck.mentions.vue +++ b/src/client/app/common/views/deck/deck.mentions.vue @@ -27,12 +27,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/common/views/deck/deck.notes.vue b/src/client/app/common/views/deck/deck.notes.vue index 8787a82a1c..15a78bef26 100644 --- a/src/client/app/common/views/deck/deck.notes.vue +++ b/src/client/app/common/views/deck/deck.notes.vue @@ -26,8 +26,8 @@ </template> </component> - <footer v-if="cursor != null"> - <button @click="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> + <footer v-if="more"> + <button @click="fetchMore()" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> <template v-if="!moreFetching">{{ $t('@.load-more') }}</template> <template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template> </button> @@ -61,7 +61,7 @@ export default Vue.extend({ fetching: true, moreFetching: false, inited: false, - cursor: null + more: false }; }, @@ -119,7 +119,7 @@ export default Vue.extend({ this.notes = x; } else { this.notes = x.notes; - this.cursor = x.cursor; + this.more = x.more; } this.inited = true; this.fetching = false; @@ -129,12 +129,12 @@ export default Vue.extend({ }); }, - more() { - if (this.cursor == null || this.moreFetching) return; + fetchMore() { + if (!this.more || this.moreFetching) return; this.moreFetching = true; - this.makePromise(this.cursor).then(x => { + this.makePromise(this.notes[this.notes.length - 1].id).then(x => { this.notes = this.notes.concat(x.notes); - this.cursor = x.cursor; + this.more = x.more; this.moreFetching = false; }, e => { this.moreFetching = false; @@ -157,7 +157,7 @@ export default Vue.extend({ // オーバーフローしたら古い投稿は捨てる if (this.notes.length >= displayLimit) { this.notes = this.notes.slice(0, displayLimit); - this.cursor = this.notes[this.notes.length - 1].id + this.more = true; } } else { this.queue.push(note); @@ -181,7 +181,7 @@ export default Vue.extend({ }, onBottom() { - this.more(); + this.fetchMore(); } } }); diff --git a/src/client/app/common/views/deck/deck.notification.vue b/src/client/app/common/views/deck/deck.notification.vue index 6a116260e5..3ced7b7e23 100644 --- a/src/client/app/common/views/deck/deck.notification.vue +++ b/src/client/app/common/views/deck/deck.notification.vue @@ -62,7 +62,7 @@ </div> </div> - <div class="notification poll_vote" v-if="notification.type == 'poll_vote'"> + <div class="notification pollVote" v-if="notification.type == 'pollVote'"> <mk-avatar class="avatar" :user="notification.user"/> <div> <header> diff --git a/src/client/app/common/views/deck/deck.search-column.vue b/src/client/app/common/views/deck/deck.search-column.vue index fb0ba5f6e4..ab19bdaab6 100644 --- a/src/client/app/common/views/deck/deck.search-column.vue +++ b/src/client/app/common/views/deck/deck.search-column.vue @@ -39,7 +39,7 @@ export default Vue.extend({ } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/common/views/deck/deck.tl-column.vue b/src/client/app/common/views/deck/deck.tl-column.vue index d53aabaea5..5ab8ccb12f 100644 --- a/src/client/app/common/views/deck/deck.tl-column.vue +++ b/src/client/app/common/views/deck/deck.tl-column.vue @@ -82,7 +82,7 @@ export default Vue.extend({ case 'local': return this.$t('@deck.local'); case 'hybrid': return this.$t('@deck.hybrid'); case 'global': return this.$t('@deck.global'); - case 'list': return this.column.list.title; + case 'list': return this.column.list.name; case 'hashtag': return this.$store.state.settings.tagTimelines.find(x => x.id == this.column.tagTlId).title; } } diff --git a/src/client/app/common/views/deck/deck.tl.vue b/src/client/app/common/views/deck/deck.tl.vue index 35cdfa704f..9284f06ee1 100644 --- a/src/client/app/common/views/deck/deck.tl.vue +++ b/src/client/app/common/views/deck/deck.tl.vue @@ -85,12 +85,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }); 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 ee24cad1c5..cf592d031f 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 @@ -95,12 +95,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: new Date(notes[notes.length - 1].createdAt).getTime() + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }); diff --git a/src/client/app/common/views/deck/deck.user-column.vue b/src/client/app/common/views/deck/deck.user-column.vue index 9e9f494b13..fb50d880eb 100644 --- a/src/client/app/common/views/deck/deck.user-column.vue +++ b/src/client/app/common/views/deck/deck.user-column.vue @@ -8,7 +8,7 @@ <div class="is-remote" v-if="user.host != null"> <details> <summary><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}</summary> - <a :href="user.url || user.uri" target="_blank">{{ $t('@.view-on-remote') }}</a> + <a :href="user.url" target="_blank">{{ $t('@.view-on-remote') }}</a> </details> </div> <header :style="bannerStyle"> @@ -88,7 +88,7 @@ export default Vue.extend({ if (this.user == null) return {}; if (this.user.bannerUrl == null) return {}; return { - backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null, + backgroundColor: this.user.bannerColor, backgroundImage: `url(${ this.user.bannerUrl })` }; }, diff --git a/src/client/app/common/views/deck/deck.vue b/src/client/app/common/views/deck/deck.vue index 8ffb3223f9..b46f2167ad 100644 --- a/src/client/app/common/views/deck/deck.vue +++ b/src/client/app/common/views/deck/deck.vue @@ -106,16 +106,6 @@ export default Vue.extend({ value: deck }); } - - // 互換性のため - if (this.$store.state.device.deck != null && this.$store.state.device.deck.layout == null) { - this.$store.commit('device/set', { - key: 'deck', - value: Object.assign({}, this.$store.state.device.deck, { - layout: this.$store.state.device.deck.columns.map(c => [c.id]) - }) - }); - } }, mounted() { @@ -199,7 +189,7 @@ export default Vue.extend({ title: this.$t('@deck.select-list'), select: { items: lists.map(list => ({ - value: list.id, text: list.title + value: list.id, text: list.name })) }, showCancelButton: true diff --git a/src/client/app/common/views/pages/explore.vue b/src/client/app/common/views/pages/explore.vue index 098bf1f4c4..67e92af445 100644 --- a/src/client/app/common/views/pages/explore.vue +++ b/src/client/app/common/views/pages/explore.vue @@ -3,7 +3,7 @@ <ui-container :show-header="false" v-if="meta && stats"> <div class="kpdsmpnk" :style="{ backgroundImage: meta.bannerUrl ? `url(${meta.bannerUrl})` : null }"> <div> - <router-link to="/explore" class="title">{{ $t('explore', { host: meta.name }) }}</router-link> + <router-link to="/explore" class="title">{{ $t('explore', { host: meta.name || 'Misskey' }) }}</router-link> <span>{{ $t('users-info', { users: num(stats.originalUsersCount) }) }}</span> </div> </div> @@ -13,8 +13,8 @@ <template #header><fa :icon="faHashtag" fixed-width/>{{ $t('popular-tags') }}</template> <div class="vxjfqztj"> - <router-link v-for="tag in tagsLocal" :to="`/explore/tags/${tag.tag}`" :key="'local:' + tag.tag" class="local">{{ tag.tag }}</router-link> - <router-link v-for="tag in tagsRemote" :to="`/explore/tags/${tag.tag}`" :key="'remote:' + tag.tag">{{ tag.tag }}</router-link> + <router-link v-for="tag in tagsLocal" :to="`/explore/tags/${tag.name}`" :key="'local:' + tag.name" class="local">{{ tag.name }}</router-link> + <router-link v-for="tag in tagsRemote" :to="`/explore/tags/${tag.name}`" :key="'remote:' + tag.name">{{ tag.name }}</router-link> </div> </ui-container> diff --git a/src/client/app/common/views/pages/follow.vue b/src/client/app/common/views/pages/follow.vue index f8d12a2dca..f6a11a7b4f 100644 --- a/src/client/app/common/views/pages/follow.vue +++ b/src/client/app/common/views/pages/follow.vue @@ -57,7 +57,7 @@ export default Vue.extend({ bannerStyle(): any { if (this.user.bannerUrl == null) return {}; return { - backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null, + backgroundColor: this.user.bannerColor, backgroundImage: `url(${ this.user.bannerUrl })` }; } diff --git a/src/client/app/common/views/pages/followers.vue b/src/client/app/common/views/pages/followers.vue index 94d9c9b13c..1d68d71e80 100644 --- a/src/client/app/common/views/pages/followers.vue +++ b/src/client/app/common/views/pages/followers.vue @@ -9,20 +9,30 @@ import Vue from 'vue'; import parseAcct from '../../../../../misc/acct/parse'; import i18n from '../../../i18n'; +const fetchLimit = 30; + export default Vue.extend({ - i18n: i18n(''), + i18n: i18n(), data() { return { makePromise: cursor => this.$root.api('users/followers', { ...parseAcct(this.$route.params.user), - limit: 30, - cursor: cursor ? cursor : undefined - }).then(x => { - return { - users: x.users, - cursor: x.next - }; + limit: fetchLimit + 1, + untilId: cursor ? cursor : undefined, + }).then(followings => { + if (followings.length == fetchLimit + 1) { + followings.pop(); + return { + users: followings.map(following => following.follower), + cursor: followings[followings.length - 1].id + }; + } else { + return { + users: followings.map(following => following.follower), + more: false + }; + } }), }; }, diff --git a/src/client/app/common/views/pages/following.vue b/src/client/app/common/views/pages/following.vue index 39739fa3da..b65d335314 100644 --- a/src/client/app/common/views/pages/following.vue +++ b/src/client/app/common/views/pages/following.vue @@ -7,19 +7,32 @@ <script lang="ts"> import Vue from 'vue'; import parseAcct from '../../../../../misc/acct/parse'; +import i18n from '../../../i18n'; + +const fetchLimit = 30; export default Vue.extend({ + i18n: i18n(), + data() { return { makePromise: cursor => this.$root.api('users/following', { ...parseAcct(this.$route.params.user), - limit: 30, - cursor: cursor ? cursor : undefined - }).then(x => { - return { - users: x.users, - cursor: x.next - }; + limit: fetchLimit + 1, + untilId: cursor ? cursor : undefined, + }).then(followings => { + if (followings.length == fetchLimit + 1) { + followings.pop(); + return { + users: followings.map(following => following.followee), + cursor: followings[followings.length - 1].id + }; + } else { + return { + users: followings.map(following => following.followee), + more: false + }; + } }), }; }, diff --git a/src/client/app/common/views/pages/share.vue b/src/client/app/common/views/pages/share.vue index 760350b921..0452b25dfc 100644 --- a/src/client/app/common/views/pages/share.vue +++ b/src/client/app/common/views/pages/share.vue @@ -42,7 +42,7 @@ export default Vue.extend({ }, mounted() { this.$root.getMeta().then(meta => { - this.name = meta.name; + this.name = meta.name || 'Misskey'; }); } }); diff --git a/src/client/app/common/views/widgets/post-form.vue b/src/client/app/common/views/widgets/post-form.vue index f1826cc59f..b30168b879 100644 --- a/src/client/app/common/views/widgets/post-form.vue +++ b/src/client/app/common/views/widgets/post-form.vue @@ -21,14 +21,7 @@ <fa :icon="['far', 'laugh']"/> </button> </div> - <div class="files" v-show="files.length != 0"> - <x-draggable :list="files" :options="{ animation: 150 }"> - <div v-for="file in files" :key="file.id"> - <div class="img" :style="{ backgroundImage: `url(${file.thumbnailUrl})` }" :title="file.name"></div> - <img class="remove" @click="detachMedia(file.id)" src="/assets/desktop/remove.png" :title="$t('attach-cancel')" alt=""/> - </div> - </x-draggable> - </div> + <x-post-form-attaches class="files" :files="files" :detachMediaFn="detachMedia"/> <input ref="file" type="file" multiple="multiple" tabindex="-1" @change="onChangeFile"/> <mk-uploader ref="uploader" @uploaded="attachMedia"/> <footer> @@ -45,7 +38,7 @@ import define from '../../../common/define-widget'; import i18n from '../../../i18n'; import insertTextAtCursor from 'insert-text-at-cursor'; -import * as XDraggable from 'vuedraggable'; +import XPostFormAttaches from '../components/post-form-attaches.vue'; export default define({ name: 'post-form', @@ -56,7 +49,7 @@ export default define({ i18n: i18n('desktop/views/widgets/post-form.vue'), components: { - XDraggable + XPostFormAttaches }, data() { @@ -249,38 +242,6 @@ export default define({ & + .emoji opacity 0.7 - > .files - > div - padding 4px - - &:after - content "" - display block - clear both - - > div - float left - border solid 4px transparent - cursor move - - &:hover > .remove - display block - - > .img - width 64px - height 64px - background-size cover - background-position center center - - > .remove - display none - position absolute - top -6px - right -6px - width 16px - height 16px - cursor pointer - > input[type=file] display none diff --git a/src/client/app/common/views/widgets/server.info.vue b/src/client/app/common/views/widgets/server.info.vue index f7efb6fa2a..a97b4ec496 100644 --- a/src/client/app/common/views/widgets/server.info.vue +++ b/src/client/app/common/views/widgets/server.info.vue @@ -1,6 +1,6 @@ <template> <div class="info"> - <p>Maintainer: <b><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></b></p> + <p>Maintainer: <b><a :href="'mailto:' + meta.maintainerEmail" target="_blank">{{ meta.maintainerName }}</a></b></p> <p>Machine: {{ meta.machine }}</p> <p>Node: {{ meta.node }}</p> <p>Version: {{ meta.version }} </p> diff --git a/src/client/app/desktop/views/components/drive.file.vue b/src/client/app/desktop/views/components/drive.file.vue index c560e6d97e..46aae9ad2b 100644 --- a/src/client/app/desktop/views/components/drive.file.vue +++ b/src/client/app/desktop/views/components/drive.file.vue @@ -60,7 +60,7 @@ export default Vue.extend({ return this.browser.selectedFiles.some(f => f.id == this.file.id); }, title(): string { - return `${this.file.name}\n${this.file.type} ${Vue.filter('bytes')(this.file.datasize)}`; + return `${this.file.name}\n${this.file.type} ${Vue.filter('bytes')(this.file.size)}`; } }, methods: { @@ -139,10 +139,10 @@ export default Vue.extend({ }, onThumbnailLoaded() { - if (this.file.properties.avgColor && this.file.properties.avgColor.length == 3) { + if (this.file.properties.avgColor) { anime({ targets: this.$refs.thumbnail, - backgroundColor: `rgba(${this.file.properties.avgColor.join(',')}, 0)`, + backgroundColor: this.file.properties.avgColor.replace('255)', '0)'), duration: 100, easing: 'linear' }); diff --git a/src/client/app/desktop/views/components/drive.vue b/src/client/app/desktop/views/components/drive.vue index 7513f002a7..fcabb4b8eb 100644 --- a/src/client/app/desktop/views/components/drive.vue +++ b/src/client/app/desktop/views/components/drive.vue @@ -769,7 +769,6 @@ export default Vue.extend({ > .mk-uploader height 100px padding 16px - background #fff > input display none diff --git a/src/client/app/desktop/views/components/note.vue b/src/client/app/desktop/views/components/note.vue index 9b36716e83..585294fc89 100644 --- a/src/client/app/desktop/views/components/note.vue +++ b/src/client/app/desktop/views/components/note.vue @@ -54,11 +54,11 @@ </button> <button v-if="!isMyNote && appearNote.myReaction == null" class="reactionButton button" @click="react()" ref="reactButton" :title="$t('add-reaction')"> <fa icon="plus"/> - <p class="count" v-if="Object.values(appearNote.reactionCounts).some(x => x)">{{ Object.values(appearNote.reactionCounts).reduce((a, c) => a + c, 0) }}</p> + <p class="count" v-if="Object.values(appearNote.reactions).some(x => x)">{{ Object.values(appearNote.reactions).reduce((a, c) => a + c, 0) }}</p> </button> <button v-if="!isMyNote && appearNote.myReaction != null" class="reactionButton reacted button" @click="undoReact(appearNote)" ref="reactButton" :title="$t('undo-reaction')"> <fa icon="minus"/> - <p class="count" v-if="Object.values(appearNote.reactionCounts).some(x => x)">{{ Object.values(appearNote.reactionCounts).reduce((a, c) => a + c, 0) }}</p> + <p class="count" v-if="Object.values(appearNote.reactions).some(x => x)">{{ Object.values(appearNote.reactions).reduce((a, c) => a + c, 0) }}</p> </button> <button @click="menu()" ref="menuButton" class="button"> <fa icon="ellipsis-h"/> diff --git a/src/client/app/desktop/views/components/notes.vue b/src/client/app/desktop/views/components/notes.vue index e4df8a4b55..b2c2d9e861 100644 --- a/src/client/app/desktop/views/components/notes.vue +++ b/src/client/app/desktop/views/components/notes.vue @@ -25,8 +25,8 @@ </template> </component> - <footer v-if="cursor != null"> - <button @click="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> + <footer v-if="more"> + <button @click="fetchMore()" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> <template v-if="!moreFetching">{{ $t('@.load-more') }}</template> <template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template> </button> @@ -58,7 +58,7 @@ export default Vue.extend({ fetching: true, moreFetching: false, inited: false, - cursor: null + more: false }; }, @@ -112,7 +112,7 @@ export default Vue.extend({ this.notes = x; } else { this.notes = x.notes; - this.cursor = x.cursor; + this.more = x.more; } this.inited = true; this.fetching = false; @@ -122,12 +122,12 @@ export default Vue.extend({ }); }, - more() { - if (this.cursor == null || this.moreFetching) return; + fetchMore() { + if (!this.more || this.moreFetching) return; this.moreFetching = true; - this.makePromise(this.cursor).then(x => { + this.makePromise(this.notes[this.notes.length - 1].id).then(x => { this.notes = this.notes.concat(x.notes); - this.cursor = x.cursor; + this.more = x.more; this.moreFetching = false; }, e => { this.moreFetching = false; @@ -157,7 +157,7 @@ export default Vue.extend({ // オーバーフローしたら古い投稿は捨てる if (this.notes.length >= displayLimit) { this.notes = this.notes.slice(0, displayLimit); - this.cursor = this.notes[this.notes.length - 1].id + this.more = true; } } else { this.queue.push(note); @@ -183,7 +183,7 @@ export default Vue.extend({ if (this.$store.state.settings.fetchOnScroll !== false) { const current = window.scrollY + window.innerHeight; - if (current > document.body.offsetHeight - 8) this.more(); + if (current > document.body.offsetHeight - 8) this.fetchMore(); } } } diff --git a/src/client/app/desktop/views/components/notifications.vue b/src/client/app/desktop/views/components/notifications.vue index 24b6fc3eba..0bf0132926 100644 --- a/src/client/app/desktop/views/components/notifications.vue +++ b/src/client/app/desktop/views/components/notifications.vue @@ -110,7 +110,7 @@ </div> </template> - <template v-if="notification.type == 'poll_vote'"> + <template v-if="notification.type == 'pollVote'"> <mk-avatar class="avatar" :user="notification.user"/> <div class="text"> <p><fa icon="chart-pie"/><a :href="notification.user | userPage" v-user-preview="notification.user.id"> diff --git a/src/client/app/desktop/views/components/post-form.vue b/src/client/app/desktop/views/components/post-form.vue index 6ba4d47087..fe39a17e67 100644 --- a/src/client/app/desktop/views/components/post-form.vue +++ b/src/client/app/desktop/views/components/post-form.vue @@ -27,15 +27,7 @@ <button class="emoji" @click="emoji" ref="emoji"> <fa :icon="['far', 'laugh']"/> </button> - <div class="files" :class="{ with: poll }" v-show="files.length != 0"> - <x-draggable :list="files" :options="{ animation: 150 }"> - <div v-for="file in files" :key="file.id"> - <div class="img" :style="{ backgroundImage: `url(${file.thumbnailUrl})` }" :title="file.name"></div> - <img class="remove" @click="detachMedia(file.id)" src="/assets/desktop/remove.png" :title="$t('attach-cancel')" alt=""/> - </div> - </x-draggable> - <p class="remain">{{ 4 - files.length }}/4</p> - </div> + <x-post-form-attaches class="files" :class="{ with: poll }" :files="files"/> <mk-poll-editor v-if="poll" ref="poll" @destroyed="poll = false" @updated="onPollUpdate()"/> </div> </div> @@ -65,7 +57,6 @@ import Vue from 'vue'; import i18n from '../../../i18n'; import insertTextAtCursor from 'insert-text-at-cursor'; -import * as XDraggable from 'vuedraggable'; import getFace from '../../../common/scripts/get-face'; import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue'; import { parse } from '../../../../../mfm/parse'; @@ -74,13 +65,14 @@ import { erase, unique } from '../../../../../prelude/array'; import { length } from 'stringz'; import { toASCII } from 'punycode'; import extractMentions from '../../../../../misc/extract-mentions'; +import XPostFormAttaches from '../../../common/views/components/post-form-attaches.vue'; export default Vue.extend({ i18n: i18n('desktop/views/components/post-form.vue'), components: { - XDraggable, - MkVisibilityChooser + MkVisibilityChooser, + XPostFormAttaches }, props: { @@ -513,7 +505,7 @@ export default Vue.extend({ kao() { this.text += getFace(); - } + }, } }); </script> @@ -618,46 +610,6 @@ export default Vue.extend({ border-bottom solid 1px var(--primaryAlpha01) !important border-radius 0 - > .remain - display block - position absolute - top 8px - right 8px - margin 0 - padding 0 - color var(--primaryAlpha04) - - > div - padding 4px - - &:after - content "" - display block - clear both - - > div - float left - border solid 4px transparent - cursor move - - &:hover > .remove - display block - - > .img - width 64px - height 64px - background-size cover - background-position center center - - > .remove - display none - position absolute - top -6px - right -6px - width 16px - height 16px - cursor pointer - > .mk-poll-editor background var(--desktopPostFormTextareaBg) border solid 1px var(--primaryAlpha01) diff --git a/src/client/app/desktop/views/components/user-list-timeline.vue b/src/client/app/desktop/views/components/user-list-timeline.vue index 6fc75d73fc..0cbe5ff05a 100644 --- a/src/client/app/desktop/views/components/user-list-timeline.vue +++ b/src/client/app/desktop/views/components/user-list-timeline.vue @@ -30,12 +30,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/desktop/views/components/user-list-window.vue b/src/client/app/desktop/views/components/user-list-window.vue index afece9fe86..6764579b20 100644 --- a/src/client/app/desktop/views/components/user-list-window.vue +++ b/src/client/app/desktop/views/components/user-list-window.vue @@ -1,6 +1,6 @@ <template> <mk-window ref="window" width="450px" height="500px" @closed="destroyDom"> - <template #header><fa icon="list"/> {{ list.title }}</template> + <template #header><fa icon="list"/> {{ list.name }}</template> <x-editor :list="list"/> </mk-window> 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 4f0af4a278..7afcd6aa3b 100644 --- a/src/client/app/desktop/views/components/user-lists-window.vue +++ b/src/client/app/desktop/views/components/user-lists-window.vue @@ -4,7 +4,7 @@ <div class="xkxvokkjlptzyewouewmceqcxhpgzprp"> <button class="ui" @click="add">{{ $t('create-list') }}</button> - <a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a> + <a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.name }}</a> </div> </mk-window> </template> diff --git a/src/client/app/desktop/views/home/favorites.vue b/src/client/app/desktop/views/home/favorites.vue index 4a4fc9ad8f..951de97498 100644 --- a/src/client/app/desktop/views/home/favorites.vue +++ b/src/client/app/desktop/views/home/favorites.vue @@ -6,7 +6,7 @@ </template> </sequential-entrance> <div class="more" v-if="existMore"> - <ui-button inline @click="more">{{ $t('@.load-more') }}</ui-button> + <ui-button inline @click="fetchMore()">{{ $t('@.load-more') }}</ui-button> </div> </div> </template> @@ -48,7 +48,7 @@ export default Vue.extend({ Progress.done(); }); }, - more() { + fetchMore() { this.moreFetching = true; this.$root.api('i/favorites', { limit: 11, diff --git a/src/client/app/desktop/views/home/home.vue b/src/client/app/desktop/views/home/home.vue index fb7af5a9ad..d0b2fc10bc 100644 --- a/src/client/app/desktop/views/home/home.vue +++ b/src/client/app/desktop/views/home/home.vue @@ -101,7 +101,7 @@ export default Vue.extend({ computed: { home(): any[] { if (this.$store.getters.isSignedIn) { - return this.$store.state.settings.home || []; + return this.$store.state.device.home || []; } else { return [{ name: 'instance', @@ -182,12 +182,8 @@ export default Vue.extend({ } //#endregion - if (this.$store.state.settings.home == null) { - this.$root.api('i/update_home', { - home: _defaultDesktopHomeWidgets - }).then(() => { - this.$store.commit('settings/setHome', _defaultDesktopHomeWidgets); - }); + if (this.$store.state.device.home == null) { + this.$store.commit('device/setHome', _defaultDesktopHomeWidgets); } } }, @@ -226,7 +222,7 @@ export default Vue.extend({ }, addWidget() { - this.$store.dispatch('settings/addHomeWidget', { + this.$store.commit('device/addHomeWidget', { name: this.widgetAdderSelected, id: uuid(), place: 'left', @@ -237,12 +233,9 @@ export default Vue.extend({ saveHome() { const left = this.widgets.left; const right = this.widgets.right; - this.$store.commit('settings/setHome', left.concat(right)); + this.$store.commit('device/setHome', left.concat(right)); for (const w of left) w.place = 'left'; for (const w of right) w.place = 'right'; - this.$root.api('i/update_home', { - home: this.home - }); }, done() { diff --git a/src/client/app/desktop/views/home/search.vue b/src/client/app/desktop/views/home/search.vue index 1632e730d3..84153d18c4 100644 --- a/src/client/app/desktop/views/home/search.vue +++ b/src/client/app/desktop/views/home/search.vue @@ -35,7 +35,7 @@ export default Vue.extend({ } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/desktop/views/home/tag.vue b/src/client/app/desktop/views/home/tag.vue index 4f9bc66e7b..92f5a47528 100644 --- a/src/client/app/desktop/views/home/tag.vue +++ b/src/client/app/desktop/views/home/tag.vue @@ -21,7 +21,7 @@ export default Vue.extend({ i18n: i18n('desktop/views/pages/tag.vue'), data() { return { - makePromise: cursor => this.$root.api('notes/search_by_tag', { + makePromise: cursor => this.$root.api('notes/search-by-tag', { limit: limit + 1, offset: cursor ? cursor : undefined, tag: this.$route.params.tag @@ -35,7 +35,7 @@ export default Vue.extend({ } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/desktop/views/home/timeline.core.vue b/src/client/app/desktop/views/home/timeline.core.vue index e306ac873c..12806365d4 100644 --- a/src/client/app/desktop/views/home/timeline.core.vue +++ b/src/client/app/desktop/views/home/timeline.core.vue @@ -58,7 +58,7 @@ export default Vue.extend({ }; if (this.src == 'tag') { - this.endpoint = 'notes/search_by_tag'; + this.endpoint = 'notes/search-by-tag'; this.query = { query: this.tagTl.query }; @@ -113,12 +113,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }); diff --git a/src/client/app/desktop/views/home/timeline.vue b/src/client/app/desktop/views/home/timeline.vue index 0b8ced4795..f257f1fa97 100644 --- a/src/client/app/desktop/views/home/timeline.vue +++ b/src/client/app/desktop/views/home/timeline.vue @@ -9,7 +9,7 @@ <span :data-active="src == 'hybrid'" @click="src = 'hybrid'" v-if="enableLocalTimeline"><fa icon="share-alt"/> {{ $t('hybrid') }}</span> <span :data-active="src == 'global'" @click="src = 'global'" v-if="enableGlobalTimeline"><fa icon="globe"/> {{ $t('global') }}</span> <span :data-active="src == 'tag'" @click="src = 'tag'" v-if="tagTl"><fa icon="hashtag"/> {{ tagTl.title }}</span> - <span :data-active="src == 'list'" @click="src = 'list'" v-if="list"><fa icon="list"/> {{ list.title }}</span> + <span :data-active="src == 'list'" @click="src = 'list'" v-if="list"><fa icon="list"/> {{ list.name }}</span> <div class="buttons"> <button :data-active="src == 'mentions'" @click="src = 'mentions'" :title="$t('mentions')"><fa icon="at"/><i class="indicator" v-if="$store.state.i.hasUnreadMentions"><fa icon="circle"/></i></button> <button :data-active="src == 'messages'" @click="src = 'messages'" :title="$t('messages')"><fa :icon="['far', 'envelope']"/><i class="indicator" v-if="$store.state.i.hasUnreadSpecifiedNotes"><fa icon="circle"/></i></button> @@ -143,7 +143,7 @@ export default Vue.extend({ menu = menu.concat(lists.map(list => ({ icon: 'list', - text: list.title, + text: list.name, action: () => { this.list = list; this.src = 'list'; diff --git a/src/client/app/desktop/views/home/user/index.vue b/src/client/app/desktop/views/home/user/index.vue index 17a34a30cc..338cd1c59d 100644 --- a/src/client/app/desktop/views/home/user/index.vue +++ b/src/client/app/desktop/views/home/user/index.vue @@ -4,7 +4,7 @@ <fa icon="exclamation-triangle"/> {{ $t('@.user-suspended') }} </div> <div class="is-remote" v-if="user.host != null" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }"> - <fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}<a :href="user.url || user.uri" target="_blank">{{ $t('@.view-on-remote') }}</a> + <fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}<a :href="user.url" target="_blank">{{ $t('@.view-on-remote') }}</a> </div> <div class="main"> <x-header class="header" :user="user"/> diff --git a/src/client/app/desktop/views/home/user/user.header.vue b/src/client/app/desktop/views/home/user/user.header.vue index 85dcd3ddae..e21757ccf9 100644 --- a/src/client/app/desktop/views/home/user/user.header.vue +++ b/src/client/app/desktop/views/home/user/user.header.vue @@ -36,8 +36,8 @@ </dl> </div> <div class="info"> - <span class="location" v-if="user.host === null && user.profile.location"><fa icon="map-marker"/> {{ user.profile.location }}</span> - <span class="birthday" v-if="user.host === null && user.profile.birthday"><fa icon="birthday-cake"/> {{ user.profile.birthday.replace('-', $t('year')).replace('-', $t('month')) + $t('day') }} ({{ $t('years-old', { age }) }})</span> + <span class="location" v-if="user.host === null && user.location"><fa icon="map-marker"/> {{ user.location }}</span> + <span class="birthday" v-if="user.host === null && user.birthday"><fa icon="birthday-cake"/> {{ user.birthday.replace('-', $t('year')).replace('-', $t('month')) + $t('day') }} ({{ $t('years-old', { age }) }})</span> </div> <div class="status"> <router-link :to="user | userPage()" class="notes-count"><b>{{ user.notesCount | number }}</b>{{ $t('posts') }}</router-link> @@ -65,13 +65,13 @@ export default Vue.extend({ style(): any { if (this.user.bannerUrl == null) return {}; return { - backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null, + backgroundColor: this.user.bannerColor, backgroundImage: `url(${ this.user.bannerUrl })` }; }, age(): number { - return age(this.user.profile.birthday); + return age(this.user.birthday); } }, mounted() { diff --git a/src/client/app/desktop/views/home/user/user.timeline.vue b/src/client/app/desktop/views/home/user/user.timeline.vue index 4bdf4b6cdc..eafac4c7fd 100644 --- a/src/client/app/desktop/views/home/user/user.timeline.vue +++ b/src/client/app/desktop/views/home/user/user.timeline.vue @@ -42,12 +42,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: new Date(notes[notes.length - 1].createdAt).getTime() + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/desktop/views/pages/welcome.vue b/src/client/app/desktop/views/pages/welcome.vue index ddffeae408..5a5cd9c8e6 100644 --- a/src/client/app/desktop/views/pages/welcome.vue +++ b/src/client/app/desktop/views/pages/welcome.vue @@ -13,8 +13,8 @@ <div class="body"> <div class="main block"> <div> - <h1 v-if="name != 'Misskey'">{{ name }}</h1> - <h1 v-else><img svg-inline src="../../../../assets/title.svg" :alt="name"></h1> + <h1 v-if="name != null">{{ name }}</h1> + <h1 v-else><img svg-inline src="../../../../assets/title.svg" alt="Misskey"></h1> <div class="info"> <span><b>{{ host }}</b> - <span v-html="$t('powered-by-misskey')"></span></span> @@ -87,7 +87,7 @@ <div> <div v-if="meta" class="body"> <p>Version: <b>{{ meta.version }}</b></p> - <p>Maintainer: <b><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></b></p> + <p>Maintainer: <b><a :href="'mailto:' + meta.maintainerEmail" target="_blank">{{ meta.maintainerName }}</a></b></p> </div> </div> </div> @@ -162,7 +162,7 @@ export default Vue.extend({ banner: null, copyright, host: toUnicode(host), - name: 'Misskey', + name: null, description: '', announcements: [], photos: [] diff --git a/src/client/app/dev/views/new-app.vue b/src/client/app/dev/views/new-app.vue index d8c128904a..00f2ed60d9 100644 --- a/src/client/app/dev/views/new-app.vue +++ b/src/client/app/dev/views/new-app.vue @@ -15,15 +15,21 @@ <b-form-group :description="$t('description')"> <b-alert show variant="warning"><fa icon="exclamation-triangle"/> {{ $t('authority-warning') }}</b-alert> <b-form-checkbox-group v-model="permission" stacked> - <b-form-checkbox value="account-read">{{ $t('account-read') }}</b-form-checkbox> - <b-form-checkbox value="account-write">{{ $t('account-write') }}</b-form-checkbox> - <b-form-checkbox value="note-write">{{ $t('note-write') }}</b-form-checkbox> - <b-form-checkbox value="reaction-write">{{ $t('reaction-write') }}</b-form-checkbox> - <b-form-checkbox value="following-write">{{ $t('following-write') }}</b-form-checkbox> - <b-form-checkbox value="drive-read">{{ $t('drive-read') }}</b-form-checkbox> - <b-form-checkbox value="drive-write">{{ $t('drive-write') }}</b-form-checkbox> - <b-form-checkbox value="notification-read">{{ $t('notification-read') }}</b-form-checkbox> - <b-form-checkbox value="notification-write">{{ $t('notification-write') }}</b-form-checkbox> + <b-form-checkbox value="read:account">{{ $t('read:account') }}</b-form-checkbox> + <b-form-checkbox value="write:account">{{ $t('write:account') }}</b-form-checkbox> + <b-form-checkbox value="write:notes">{{ $t('write:notes') }}</b-form-checkbox> + <b-form-checkbox value="read:reactions">{{ $t('read:reactions') }}</b-form-checkbox> + <b-form-checkbox value="write:reactions">{{ $t('write:reactions') }}</b-form-checkbox> + <b-form-checkbox value="read:following">{{ $t('read:following') }}</b-form-checkbox> + <b-form-checkbox value="write:following">{{ $t('write:following') }}</b-form-checkbox> + <b-form-checkbox value="read:mutes">{{ $t('read:mutes') }}</b-form-checkbox> + <b-form-checkbox value="write:mutes">{{ $t('write:mutes') }}</b-form-checkbox> + <b-form-checkbox value="read:blocks">{{ $t('read:blocks') }}</b-form-checkbox> + <b-form-checkbox value="write:blocks">{{ $t('write:blocks') }}</b-form-checkbox> + <b-form-checkbox value="read:drive">{{ $t('read:drive') }}</b-form-checkbox> + <b-form-checkbox value="write:drive">{{ $t('write:drive') }}</b-form-checkbox> + <b-form-checkbox value="read:notifications">{{ $t('read:notifications') }}</b-form-checkbox> + <b-form-checkbox value="write:notifications">{{ $t('write:notifications') }}</b-form-checkbox> </b-form-checkbox-group> </b-form-group> </b-card> diff --git a/src/client/app/mios.ts b/src/client/app/mios.ts index 9e191bf43c..a3525ed319 100644 --- a/src/client/app/mios.ts +++ b/src/client/app/mios.ts @@ -28,7 +28,7 @@ export default class MiOS extends EventEmitter { }; public get instanceName() { - return this.meta ? this.meta.data.name : 'Misskey'; + return this.meta ? (this.meta.data.name || 'Misskey') : 'Misskey'; } private isMetaFetching = false; @@ -278,21 +278,6 @@ export default class MiOS extends EventEmitter { }); }); - main.on('homeUpdated', x => { - this.store.commit('settings/setHome', x); - }); - - main.on('mobileHomeUpdated', x => { - this.store.commit('settings/setMobileHome', x); - }); - - main.on('widgetUpdated', x => { - this.store.commit('settings/updateWidget', { - id: x.id, - data: x.data - }); - }); - // トークンが再生成されたとき // このままではMisskeyが利用できないので強制的にサインアウトさせる main.on('myTokenRegenerated', () => { diff --git a/src/client/app/mobile/views/components/drive.file-detail.vue b/src/client/app/mobile/views/components/drive.file-detail.vue index 92f5c1fd19..98124354ed 100644 --- a/src/client/app/mobile/views/components/drive.file-detail.vue +++ b/src/client/app/mobile/views/components/drive.file-detail.vue @@ -22,7 +22,7 @@ <div> <span class="type"><mk-file-type-icon :type="file.type"/> {{ file.type }}</span> <span class="separator"></span> - <span class="data-size">{{ file.datasize | bytes }}</span> + <span class="data-size">{{ file.size | bytes }}</span> <span class="separator"></span> <span class="created-at" @click="showCreatedAt"><fa :icon="['far', 'clock']"/><mk-time :time="file.createdAt"/></span> <template v-if="file.isSensitive"> @@ -85,8 +85,8 @@ export default Vue.extend({ }, style(): any { - return this.file.properties.avgColor && this.file.properties.avgColor.length == 3 ? { - 'background-color': `rgb(${ this.file.properties.avgColor.join(',') })` + return this.file.properties.avgColor ? { + 'background-color': this.file.properties.avgColor } : {}; }, diff --git a/src/client/app/mobile/views/components/drive.file.vue b/src/client/app/mobile/views/components/drive.file.vue index feca266ede..ed95537f9c 100644 --- a/src/client/app/mobile/views/components/drive.file.vue +++ b/src/client/app/mobile/views/components/drive.file.vue @@ -10,7 +10,7 @@ <footer> <span class="type"><mk-file-type-icon :type="file.type"/>{{ file.type }}</span> <span class="separator"></span> - <span class="data-size">{{ file.datasize | bytes }}</span> + <span class="data-size">{{ file.size | bytes }}</span> <span class="separator"></span> <span class="created-at"><fa :icon="['far', 'clock']"/><mk-time :time="file.createdAt"/></span> <template v-if="file.isSensitive"> diff --git a/src/client/app/mobile/views/components/notes.vue b/src/client/app/mobile/views/components/notes.vue index 16a1682c2a..5b9652e1e2 100644 --- a/src/client/app/mobile/views/components/notes.vue +++ b/src/client/app/mobile/views/components/notes.vue @@ -21,8 +21,8 @@ </template> </component> - <footer v-if="cursor != null"> - <button @click="more" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> + <footer v-if="more"> + <button @click="fetchMore()" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }"> <template v-if="!moreFetching">{{ $t('@.load-more') }}</template> <template v-if="moreFetching"><fa icon="spinner" pulse fixed-width/></template> </button> @@ -53,7 +53,7 @@ export default Vue.extend({ fetching: true, moreFetching: false, inited: false, - cursor: null + more: false }; }, @@ -113,7 +113,7 @@ export default Vue.extend({ this.notes = x; } else { this.notes = x.notes; - this.cursor = x.cursor; + this.more = x.more; } this.inited = true; this.fetching = false; @@ -123,12 +123,12 @@ export default Vue.extend({ }); }, - more() { - if (this.cursor == null || this.moreFetching) return; + fetchMore() { + if (!this.more || this.moreFetching) return; this.moreFetching = true; - this.makePromise(this.cursor).then(x => { + this.makePromise(this.notes[this.notes.length - 1].id).then(x => { this.notes = this.notes.concat(x.notes); - this.cursor = x.cursor; + this.more = x.more; this.moreFetching = false; }, e => { this.moreFetching = false; @@ -151,7 +151,7 @@ export default Vue.extend({ // オーバーフローしたら古い投稿は捨てる if (this.notes.length >= displayLimit) { this.notes = this.notes.slice(0, displayLimit); - this.cursor = this.notes[this.notes.length - 1].id + this.more = true; } } else { this.queue.push(note); @@ -182,7 +182,7 @@ export default Vue.extend({ if (this.$el.offsetHeight == 0) return; const current = window.scrollY + window.innerHeight; - if (current > document.body.offsetHeight - 8) this.more(); + if (current > document.body.offsetHeight - 8) this.fetchMore(); } } } diff --git a/src/client/app/mobile/views/components/notification-preview.vue b/src/client/app/mobile/views/components/notification-preview.vue index 1b8eceaa6c..8422c73420 100644 --- a/src/client/app/mobile/views/components/notification-preview.vue +++ b/src/client/app/mobile/views/components/notification-preview.vue @@ -54,7 +54,7 @@ </div> </template> - <template v-if="notification.type == 'poll_vote'"> + <template v-if="notification.type == 'pollVote'"> <mk-avatar class="avatar" :user="notification.user"/> <div class="text"> <p><fa icon="chart-pie"/><mk-user-name :user="notification.user"/></p> diff --git a/src/client/app/mobile/views/components/notification.vue b/src/client/app/mobile/views/components/notification.vue index 5308d96533..1128a76000 100644 --- a/src/client/app/mobile/views/components/notification.vue +++ b/src/client/app/mobile/views/components/notification.vue @@ -54,7 +54,7 @@ </div> </div> - <div class="notification poll_vote" v-if="notification.type == 'poll_vote'"> + <div class="notification pollVote" v-if="notification.type == 'pollVote'"> <mk-avatar class="avatar" :user="notification.user"/> <div> <header> diff --git a/src/client/app/mobile/views/components/post-form.vue b/src/client/app/mobile/views/components/post-form.vue index 9c1072b4a3..6b26cdf890 100644 --- a/src/client/app/mobile/views/components/post-form.vue +++ b/src/client/app/mobile/views/components/post-form.vue @@ -21,13 +21,7 @@ </div> <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"> - <div class="img" :style="`background-image: url(${file.thumbnailUrl})`" @click="detachMedia(file)"></div> - </div> - </x-draggable> - </div> + <x-post-form-attaches class="attaches" :files="files"/> <mk-poll-editor v-if="poll" ref="poll" @destroyed="poll = false" @updated="onPollUpdate()"/> <mk-uploader ref="uploader" @uploaded="attachMedia" @change="onChangeUploadings"/> <footer> @@ -57,7 +51,6 @@ import Vue from 'vue'; import i18n from '../../../i18n'; import insertTextAtCursor from 'insert-text-at-cursor'; -import * as XDraggable from 'vuedraggable'; import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue'; import getFace from '../../../common/scripts/get-face'; import { parse } from '../../../../../mfm/parse'; @@ -66,11 +59,12 @@ import { erase, unique } from '../../../../../prelude/array'; import { length } from 'stringz'; import { toASCII } from 'punycode'; import extractMentions from '../../../../../misc/extract-mentions'; +import XPostFormAttaches from '../../../common/views/components/post-form-attaches.vue'; export default Vue.extend({ i18n: i18n('mobile/views/components/post-form.vue'), components: { - XDraggable + XPostFormAttaches }, props: { @@ -264,8 +258,8 @@ export default Vue.extend({ this.$emit('change-attached-files', this.files); }, - detachMedia(file) { - this.files = this.files.filter(x => x.id != file.id); + detachMedia(id) { + this.files = this.files.filter(x => x.id != id); this.$emit('change-attached-files', this.files); }, @@ -481,32 +475,6 @@ export default Vue.extend({ min-width 100% min-height 80px - > .attaches - - > .files - display block - margin 0 - padding 4px - list-style none - - &:after - content "" - display block - clear both - - > .file - display block - float left - margin 0 - padding 0 - border solid 4px transparent - - > .img - width 64px - height 64px - background-size cover - background-position center center - > .mk-uploader margin 8px 0 0 0 padding 8px diff --git a/src/client/app/mobile/views/components/user-list-timeline.vue b/src/client/app/mobile/views/components/user-list-timeline.vue index e67d7931f7..c3f09c9b15 100644 --- a/src/client/app/mobile/views/components/user-list-timeline.vue +++ b/src/client/app/mobile/views/components/user-list-timeline.vue @@ -27,12 +27,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/mobile/views/components/user-timeline.vue b/src/client/app/mobile/views/components/user-timeline.vue index 3ba4011c6c..8ae9794b75 100644 --- a/src/client/app/mobile/views/components/user-timeline.vue +++ b/src/client/app/mobile/views/components/user-timeline.vue @@ -27,12 +27,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: new Date(notes[notes.length - 1].createdAt).getTime() + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/mobile/views/pages/favorites.vue b/src/client/app/mobile/views/pages/favorites.vue index 196bd4b93c..6f175a0053 100644 --- a/src/client/app/mobile/views/pages/favorites.vue +++ b/src/client/app/mobile/views/pages/favorites.vue @@ -8,7 +8,7 @@ <mk-note-detail class="post" :note="favorite.note" :key="favorite.note.id"/> </template> </sequential-entrance> - <ui-button v-if="existMore" @click="more">{{ $t('@.load-more') }}</ui-button> + <ui-button v-if="existMore" @click="fetchMore()">{{ $t('@.load-more') }}</ui-button> </main> </mk-ui> </template> @@ -53,7 +53,7 @@ export default Vue.extend({ Progress.done(); }); }, - more() { + fetchMore() { this.moreFetching = true; this.$root.api('i/favorites', { limit: 11, diff --git a/src/client/app/mobile/views/pages/home.timeline.vue b/src/client/app/mobile/views/pages/home.timeline.vue index 4f9f5119ab..809158dd29 100644 --- a/src/client/app/mobile/views/pages/home.timeline.vue +++ b/src/client/app/mobile/views/pages/home.timeline.vue @@ -59,7 +59,7 @@ export default Vue.extend({ }; if (this.src == 'tag') { - this.endpoint = 'notes/search_by_tag'; + this.endpoint = 'notes/search-by-tag'; this.query = { query: this.tagTl.query }; @@ -114,12 +114,12 @@ export default Vue.extend({ notes.pop(); return { notes: notes, - cursor: notes[notes.length - 1].id + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }); diff --git a/src/client/app/mobile/views/pages/home.vue b/src/client/app/mobile/views/pages/home.vue index 59fae2340b..cf15670f3f 100644 --- a/src/client/app/mobile/views/pages/home.vue +++ b/src/client/app/mobile/views/pages/home.vue @@ -9,7 +9,7 @@ <span v-if="src == 'global'"><fa icon="globe"/>{{ $t('global') }}</span> <span v-if="src == 'mentions'"><fa icon="at"/>{{ $t('mentions') }}</span> <span v-if="src == 'messages'"><fa :icon="['far', 'envelope']"/>{{ $t('messages') }}</span> - <span v-if="src == 'list'"><fa icon="list"/>{{ list.title }}</span> + <span v-if="src == 'list'"><fa icon="list"/>{{ list.name }}</span> <span v-if="src == 'tag'"><fa icon="hashtag"/>{{ tagTl.title }}</span> </span> <span style="margin-left:8px"> diff --git a/src/client/app/mobile/views/pages/search.vue b/src/client/app/mobile/views/pages/search.vue index 9e4be82041..f4b2512809 100644 --- a/src/client/app/mobile/views/pages/search.vue +++ b/src/client/app/mobile/views/pages/search.vue @@ -21,19 +21,19 @@ export default Vue.extend({ return { makePromise: cursor => this.$root.api('notes/search', { limit: limit + 1, - offset: cursor ? cursor : undefined, + untilId: cursor ? cursor : undefined, query: this.q }).then(notes => { if (notes.length == limit + 1) { notes.pop(); return { notes: notes, - cursor: cursor ? cursor + limit : limit + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/mobile/views/pages/tag.vue b/src/client/app/mobile/views/pages/tag.vue index 318e63a473..f41cf1f18c 100644 --- a/src/client/app/mobile/views/pages/tag.vue +++ b/src/client/app/mobile/views/pages/tag.vue @@ -19,21 +19,21 @@ export default Vue.extend({ i18n: i18n('mobile/views/pages/tag.vue'), data() { return { - makePromise: cursor => this.$root.api('notes/search_by_tag', { + makePromise: cursor => this.$root.api('notes/search-by-tag', { limit: limit + 1, - offset: cursor ? cursor : undefined, + untilId: cursor ? cursor : undefined, tag: this.$route.params.tag }).then(notes => { if (notes.length == limit + 1) { notes.pop(); return { notes: notes, - cursor: cursor ? cursor + limit : limit + more: true }; } else { return { notes: notes, - cursor: null + more: false }; } }) diff --git a/src/client/app/mobile/views/pages/user-list.vue b/src/client/app/mobile/views/pages/user-list.vue index 874bae5d18..68fd0358c4 100644 --- a/src/client/app/mobile/views/pages/user-list.vue +++ b/src/client/app/mobile/views/pages/user-list.vue @@ -1,6 +1,6 @@ <template> <mk-ui> - <template #header v-if="!fetching"><fa icon="list"/>{{ list.title }}</template> + <template #header v-if="!fetching"><fa icon="list"/>{{ list.name }}</template> <main v-if="!fetching"> <x-editor :list="list"/> diff --git a/src/client/app/mobile/views/pages/user-lists.vue b/src/client/app/mobile/views/pages/user-lists.vue index fd129339fd..49006f41f6 100644 --- a/src/client/app/mobile/views/pages/user-lists.vue +++ b/src/client/app/mobile/views/pages/user-lists.vue @@ -5,7 +5,7 @@ <main> <ul> - <li v-for="list in lists" :key="list.id"><router-link :to="`/i/lists/${list.id}`">{{ list.title }}</router-link></li> + <li v-for="list in lists" :key="list.id"><router-link :to="`/i/lists/${list.id}`">{{ list.name }}</router-link></li> </ul> </main> </mk-ui> diff --git a/src/client/app/mobile/views/pages/user/home.photos.vue b/src/client/app/mobile/views/pages/user/home.photos.vue index 9c36f1295b..c4f47514d8 100644 --- a/src/client/app/mobile/views/pages/user/home.photos.vue +++ b/src/client/app/mobile/views/pages/user/home.photos.vue @@ -4,7 +4,7 @@ <div class="stream" v-if="!fetching && images.length > 0"> <a v-for="(image, i) in images" :key="i" class="img" - :style="`background-image: url(${thumbnail(image.media)})`" + :style="`background-image: url(${thumbnail(image.file)})`" :href="image.note | notePage" ></a> </div> @@ -40,11 +40,11 @@ export default Vue.extend({ untilDate: new Date().getTime() + 1000 * 86400 * 365 }).then(notes => { for (const note of notes) { - for (const media of note.media) { + for (const file of note.files) { if (this.images.length < 9) { this.images.push({ note, - media + file }); } } diff --git a/src/client/app/mobile/views/pages/user/index.vue b/src/client/app/mobile/views/pages/user/index.vue index fe5ef057e7..cc53ae0cfe 100644 --- a/src/client/app/mobile/views/pages/user/index.vue +++ b/src/client/app/mobile/views/pages/user/index.vue @@ -5,7 +5,7 @@ </template> <div class="wwtwuxyh" v-if="!fetching"> <div class="is-suspended" v-if="user.isSuspended"><p><fa icon="exclamation-triangle"/> {{ $t('@.user-suspended') }}</p></div> - <div class="is-remote" v-if="user.host != null"><p><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}<a :href="user.url || user.uri" target="_blank">{{ $t('@.view-on-remote') }}</a></p></div> + <div class="is-remote" v-if="user.host != null"><p><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}<a :href="user.url" target="_blank">{{ $t('@.view-on-remote') }}</a></p></div> <header> <div class="banner" :style="style"></div> <div class="body"> @@ -36,11 +36,11 @@ </dl> </div> <div class="info"> - <p class="location" v-if="user.host === null && user.profile.location"> - <fa icon="map-marker"/>{{ user.profile.location }} + <p class="location" v-if="user.host === null && user.location"> + <fa icon="map-marker"/>{{ user.location }} </p> - <p class="birthday" v-if="user.host === null && user.profile.birthday"> - <fa icon="birthday-cake"/>{{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ $t('years-old', { age }) }}) + <p class="birthday" v-if="user.host === null && user.birthday"> + <fa icon="birthday-cake"/>{{ user.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ $t('years-old', { age }) }}) </p> </div> <div class="status"> @@ -104,7 +104,7 @@ export default Vue.extend({ }, computed: { age(): number { - return age(this.user.profile.birthday); + return age(this.user.birthday); }, avator(): string { return this.$store.state.device.disableShowingAnimatedImages @@ -114,7 +114,7 @@ export default Vue.extend({ style(): any { if (this.user.bannerUrl == null) return {}; return { - backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null, + backgroundColor: this.user.bannerColor, backgroundImage: `url(${ this.user.bannerUrl })` }; } diff --git a/src/client/app/mobile/views/pages/welcome.vue b/src/client/app/mobile/views/pages/welcome.vue index 1a2b0b6c12..dd71a918db 100644 --- a/src/client/app/mobile/views/pages/welcome.vue +++ b/src/client/app/mobile/views/pages/welcome.vue @@ -3,10 +3,10 @@ <div class="banner" :style="{ backgroundImage: banner ? `url(${banner})` : null }"></div> <div> - <img svg-inline src="../../../../assets/title.svg" :alt="name"> + <img svg-inline src="../../../../assets/title.svg" alt="Misskey"> <p class="host">{{ host }}</p> <div class="about"> - <h2>{{ name }}</h2> + <h2>{{ name || 'Misskey' }}</h2> <p v-html="description || this.$t('@.about')"></p> <router-link class="signup" to="/signup">{{ $t('@.signup') }}</router-link> </div> @@ -62,7 +62,7 @@ </article> <div class="info" v-if="meta"> <p>Version: <b>{{ meta.version }}</b></p> - <p>Maintainer: <b><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></b></p> + <p>Maintainer: <b><a :href="'mailto:' + meta.maintainerEmail" target="_blank">{{ meta.maintainerName }}</a></b></p> </div> <footer> <small>{{ copyright }}</small> @@ -87,7 +87,7 @@ export default Vue.extend({ stats: null, banner: null, host: toUnicode(host), - name: 'Misskey', + name: null, description: '', photos: [], announcements: [] diff --git a/src/client/app/mobile/views/pages/widgets.vue b/src/client/app/mobile/views/pages/widgets.vue index 96dcb977fa..2647f96de2 100644 --- a/src/client/app/mobile/views/pages/widgets.vue +++ b/src/client/app/mobile/views/pages/widgets.vue @@ -119,7 +119,7 @@ export default Vue.extend({ }, addWidget() { - this.$store.dispatch('settings/addMobileHomeWidget', { + this.$store.commit('settings/addMobileHomeWidget', { name: this.widgetAdderSelected, id: uuid(), data: {} @@ -127,14 +127,11 @@ export default Vue.extend({ }, removeWidget(widget) { - this.$store.dispatch('settings/removeMobileHomeWidget', widget); + this.$store.commit('settings/removeMobileHomeWidget', widget); }, saveHome() { this.$store.commit('settings/setMobileHome', this.widgets); - this.$root.api('i/update_mobile_home', { - home: this.widgets - }); } } }); diff --git a/src/client/app/store.ts b/src/client/app/store.ts index e49934fc16..c82981ad24 100644 --- a/src/client/app/store.ts +++ b/src/client/app/store.ts @@ -7,8 +7,6 @@ import { erase } from '../../prelude/array'; import getNoteSummary from '../../misc/get-note-summary'; const defaultSettings = { - home: null, - mobileHome: [], keepCw: false, tagTimelines: [], fetchOnScroll: true, @@ -41,6 +39,8 @@ const defaultSettings = { }; const defaultDeviceSettings = { + home: null, + mobileHome: [], deck: null, deckMode: false, deckColumnAlign: 'center', @@ -120,7 +120,7 @@ export default (os: MiOS) => new Vuex.Store({ actions: { login(ctx, i) { ctx.commit('updateI', i); - ctx.dispatch('settings/merge', i.clientSettings); + ctx.dispatch('settings/merge', i.clientData); }, logout(ctx) { @@ -134,8 +134,8 @@ export default (os: MiOS) => new Vuex.Store({ ctx.commit('updateIKeyValue', { key, value }); } - if (me.clientSettings) { - ctx.dispatch('settings/merge', me.clientSettings); + if (me.clientData) { + ctx.dispatch('settings/merge', me.clientData); } }, }, @@ -162,6 +162,48 @@ export default (os: MiOS) => new Vuex.Store({ state.visibility = visibility; }, + setHome(state, data) { + state.home = data; + }, + + addHomeWidget(state, widget) { + state.home.unshift(widget); + }, + + setMobileHome(state, data) { + state.mobileHome = data; + }, + + updateWidget(state, x) { + let w; + + //#region Desktop home + if (state.home) { + w = state.home.find(w => w.id == x.id); + if (w) { + w.data = x.data; + } + } + //#endregion + + //#region Mobile home + if (state.mobileHome) { + w = state.mobileHome.find(w => w.id == x.id); + if (w) { + w.data = x.data; + } + } + //#endregion + }, + + addMobileHomeWidget(state, widget) { + state.mobileHome.unshift(widget); + }, + + removeMobileHomeWidget(state, widget) { + state.mobileHome = state.mobileHome.filter(w => w.id != widget.id); + }, + addDeckColumn(state, column) { if (column.name == undefined) column.name = null; state.deck.columns.push(column); @@ -301,48 +343,6 @@ export default (os: MiOS) => new Vuex.Store({ set(state, x: { key: string; value: any }) { nestedProperty.set(state, x.key, x.value); }, - - setHome(state, data) { - state.home = data; - }, - - addHomeWidget(state, widget) { - state.home.unshift(widget); - }, - - setMobileHome(state, data) { - state.mobileHome = data; - }, - - updateWidget(state, x) { - let w; - - //#region Desktop home - if (state.home) { - w = state.home.find(w => w.id == x.id); - if (w) { - w.data = x.data; - } - } - //#endregion - - //#region Mobile home - if (state.mobileHome) { - w = state.mobileHome.find(w => w.id == x.id); - if (w) { - w.data = x.data; - } - } - //#endregion - }, - - addMobileHomeWidget(state, widget) { - state.mobileHome.unshift(widget); - }, - - removeMobileHomeWidget(state, widget) { - state.mobileHome = state.mobileHome.filter(w => w.id != widget.id); - }, }, actions: { @@ -363,30 +363,6 @@ export default (os: MiOS) => new Vuex.Store({ }); } }, - - addHomeWidget(ctx, widget) { - ctx.commit('addHomeWidget', widget); - - os.api('i/update_home', { - home: ctx.state.home - }); - }, - - addMobileHomeWidget(ctx, widget) { - ctx.commit('addMobileHomeWidget', widget); - - os.api('i/update_mobile_home', { - home: ctx.state.mobileHome - }); - }, - - removeMobileHomeWidget(ctx, widget) { - ctx.commit('removeMobileHomeWidget', widget); - - os.api('i/update_mobile_home', { - home: ctx.state.mobileHome.filter(w => w.id != widget.id) - }); - } } } } diff --git a/src/client/themes/light.json5 b/src/client/themes/light.json5 index 3bcabddba7..d5680f8f82 100644 --- a/src/client/themes/light.json5 +++ b/src/client/themes/light.json5 @@ -7,7 +7,7 @@ kind: 'light', vars: { - primary: '#fb4e4e', + primary: '#f18570', secondary: '#fff', text: '#666', }, |