diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2018-05-18 15:34:38 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-05-18 15:34:38 +0900 |
| commit | 0d0c45a4cfa541c2d2d4abc2a332ee06ff8e89ef (patch) | |
| tree | bb848206ce941fdf784418ad18060522d51eec18 /src/client/app/mobile | |
| parent | New translations ja.yml (Korean) (diff) | |
| parent | 2.10.0 (diff) | |
| download | misskey-0d0c45a4cfa541c2d2d4abc2a332ee06ff8e89ef.tar.gz misskey-0d0c45a4cfa541c2d2d4abc2a332ee06ff8e89ef.tar.bz2 misskey-0d0c45a4cfa541c2d2d4abc2a332ee06ff8e89ef.zip | |
Merge branch 'master' into l10n_master
Diffstat (limited to 'src/client/app/mobile')
| -rw-r--r-- | src/client/app/mobile/api/post.ts | 49 | ||||
| -rw-r--r-- | src/client/app/mobile/script.ts | 2 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/drive.file-detail.vue | 2 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/drive.file.vue | 2 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/media-image.vue | 2 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/note-preview.vue | 3 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/note.vue | 16 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/notes.vue | 19 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/post-form.vue | 12 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/ui.header.vue | 5 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/ui.nav.vue | 1 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/widget-container.vue | 22 | ||||
| -rw-r--r-- | src/client/app/mobile/views/pages/user.vue | 2 | ||||
| -rw-r--r-- | src/client/app/mobile/views/pages/widgets.vue (renamed from src/client/app/mobile/views/pages/dashboard.vue) | 69 |
14 files changed, 108 insertions, 98 deletions
diff --git a/src/client/app/mobile/api/post.ts b/src/client/app/mobile/api/post.ts index 72919c6505..0634c52642 100644 --- a/src/client/app/mobile/api/post.ts +++ b/src/client/app/mobile/api/post.ts @@ -1,43 +1,24 @@ import PostForm from '../views/components/post-form.vue'; -//import RenoteForm from '../views/components/renote-form.vue'; -import getNoteSummary from '../../../../renderers/get-note-summary'; export default (os) => (opts) => { const o = opts || {}; - if (o.renote) { - /*const vm = new RenoteForm({ - propsData: { - renote: o.renote - } - }).$mount(); - vm.$once('cancel', recover); - vm.$once('note', recover); - document.body.appendChild(vm.$el);*/ + const app = document.getElementById('app'); + app.style.display = 'none'; - const text = window.prompt(`「${getNoteSummary(o.renote)}」をRenote`); - if (text == null) return; - os.api('notes/create', { - renoteId: o.renote.id, - text: text == '' ? undefined : text - }); - } else { - const app = document.getElementById('app'); - app.style.display = 'none'; + function recover() { + app.style.display = 'block'; + } - function recover() { - app.style.display = 'block'; + const vm = new PostForm({ + parent: os.app, + propsData: { + reply: o.reply, + renote: o.renote } - - const vm = new PostForm({ - parent: os.app, - propsData: { - reply: o.reply - } - }).$mount(); - vm.$once('cancel', recover); - vm.$once('note', recover); - document.body.appendChild(vm.$el); - (vm as any).focus(); - } + }).$mount(); + vm.$once('cancel', recover); + vm.$once('note', recover); + document.body.appendChild(vm.$el); + (vm as any).focus(); }; diff --git a/src/client/app/mobile/script.ts b/src/client/app/mobile/script.ts index 2e9805e0d0..1405139be6 100644 --- a/src/client/app/mobile/script.ts +++ b/src/client/app/mobile/script.ts @@ -23,6 +23,7 @@ import MkUser from './views/pages/user.vue'; import MkSelectDrive from './views/pages/selectdrive.vue'; import MkDrive from './views/pages/drive.vue'; import MkNotifications from './views/pages/notifications.vue'; +import MkWidgets from './views/pages/widgets.vue'; import MkMessaging from './views/pages/messaging.vue'; import MkMessagingRoom from './views/pages/messaging-room.vue'; import MkNote from './views/pages/note.vue'; @@ -56,6 +57,7 @@ init((launch) => { { path: '/i/settings', component: MkSettings }, { path: '/i/settings/profile', component: MkProfileSetting }, { path: '/i/notifications', name: 'notifications', component: MkNotifications }, + { path: '/i/widgets', name: 'widgets', component: MkWidgets }, { path: '/i/messaging', name: 'messaging', component: MkMessaging }, { path: '/i/messaging/:user', component: MkMessagingRoom }, { path: '/i/drive', name: 'drive', component: MkDrive }, 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 764822e98c..ddf17d2723 100644 --- a/src/client/app/mobile/views/components/drive.file-detail.vue +++ b/src/client/app/mobile/views/components/drive.file-detail.vue @@ -86,7 +86,7 @@ export default Vue.extend({ return this.file.type.split('/')[0]; }, style(): any { - return this.file.properties.avgColor ? { + return this.file.properties.avgColor && this.file.properties.avgColor.length == 3 ? { 'background-color': `rgb(${ this.file.properties.avgColor.join(',') })` } : {}; } diff --git a/src/client/app/mobile/views/components/drive.file.vue b/src/client/app/mobile/views/components/drive.file.vue index 7d1957042b..94c8ae3535 100644 --- a/src/client/app/mobile/views/components/drive.file.vue +++ b/src/client/app/mobile/views/components/drive.file.vue @@ -42,7 +42,7 @@ export default Vue.extend({ }, thumbnail(): any { return { - 'background-color': this.file.properties.avgColor ? `rgb(${this.file.properties.avgColor.join(',')})` : 'transparent', + 'background-color': this.file.properties.avgColor && this.file.properties.avgColor.length == 3 ? `rgb(${this.file.properties.avgColor.join(',')})` : 'transparent', 'background-image': `url(${this.file.url}?thumbnail&size=128)` }; } diff --git a/src/client/app/mobile/views/components/media-image.vue b/src/client/app/mobile/views/components/media-image.vue index 92d1cdc6f5..9e0f8e5f7e 100644 --- a/src/client/app/mobile/views/components/media-image.vue +++ b/src/client/app/mobile/views/components/media-image.vue @@ -18,7 +18,7 @@ export default Vue.extend({ computed: { style(): any { return { - 'background-color': this.image.properties.avgColor ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent', + 'background-color': this.image.properties.avgColor && this.image.properties.avgColor.length == 3 ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent', 'background-image': this.raw ? `url(${this.image.url})` : `url(${this.image.url}?thumbnail&size=512)` }; } diff --git a/src/client/app/mobile/views/components/note-preview.vue b/src/client/app/mobile/views/components/note-preview.vue index ec11f23315..b3ab088ffe 100644 --- a/src/client/app/mobile/views/components/note-preview.vue +++ b/src/client/app/mobile/views/components/note-preview.vue @@ -69,8 +69,9 @@ root(isDark) text-decoration underline > .username - text-align left margin 0 .5em 0 0 + overflow hidden + text-overflow ellipsis color isDark ? #606984 : #d1d8da > .time diff --git a/src/client/app/mobile/views/components/note.vue b/src/client/app/mobile/views/components/note.vue index d66f5a1016..77a766f327 100644 --- a/src/client/app/mobile/views/components/note.vue +++ b/src/client/app/mobile/views/components/note.vue @@ -41,7 +41,7 @@ <div class="text"> <span v-if="p.isHidden" style="opacity: 0.5">(この投稿は非公開です)</span> <a class="reply" v-if="p.reply">%fa:reply%</a> - <mk-note-html v-if="p.text" :text="p.text" :i="os.i" :class="$style.text"/> + <mk-note-html v-if="p.text && !canHideText(p)" :text="p.text" :i="os.i" :class="$style.text"/> <a class="rp" v-if="p.renote != null">RP:</a> </div> <div class="media" v-if="p.media.length > 0"> @@ -85,6 +85,7 @@ <script lang="ts"> import Vue from 'vue'; import parse from '../../../../../text/parse'; +import canHideText from '../../../common/scripts/can-hide-text'; import MkNoteMenu from '../../../common/views/components/note-menu.vue'; import MkReactionPicker from '../../../common/views/components/reaction-picker.vue'; @@ -112,9 +113,11 @@ export default Vue.extend({ this.note.mediaIds.length == 0 && this.note.poll == null); }, + p(): any { return this.isRenote ? this.note.renote : this.note; }, + reactionsCount(): number { return this.p.reactionCounts ? Object.keys(this.p.reactionCounts) @@ -122,6 +125,7 @@ export default Vue.extend({ .reduce((a, b) => a + b) : 0; }, + urls(): string[] { if (this.p.text) { const ast = parse(this.p.text); @@ -177,6 +181,8 @@ export default Vue.extend({ }, methods: { + canHideText, + capture(withHandler = false) { if ((this as any).os.isSignedIn) { this.connection.send({ @@ -186,6 +192,7 @@ export default Vue.extend({ if (withHandler) this.connection.on('note-updated', this.onStreamNoteUpdated); } }, + decapture(withHandler = false) { if ((this as any).os.isSignedIn) { this.connection.send({ @@ -195,9 +202,11 @@ export default Vue.extend({ if (withHandler) this.connection.off('note-updated', this.onStreamNoteUpdated); } }, + onStreamConnected() { this.capture(); }, + onStreamNoteUpdated(data) { const note = data.note; if (note.id == this.note.id) { @@ -206,16 +215,19 @@ export default Vue.extend({ this.note.renote = note; } }, + reply() { (this as any).apis.post({ reply: this.p }); }, + renote() { (this as any).apis.post({ renote: this.p }); }, + react() { (this as any).os.new(MkReactionPicker, { source: this.$refs.reactButton, @@ -223,6 +235,7 @@ export default Vue.extend({ compact: true }); }, + menu() { (this as any).os.new(MkNoteMenu, { source: this.$refs.menuButton, @@ -255,6 +268,7 @@ root(isDark) align-items center padding 8px 16px line-height 28px + white-space pre color #9dbb00 background isDark ? linear-gradient(to bottom, #314027 0%, #282c37 100%) : linear-gradient(to bottom, #edfde2 0%, #fff 100%) diff --git a/src/client/app/mobile/views/components/notes.vue b/src/client/app/mobile/views/components/notes.vue index 53e232e521..e77698dea9 100644 --- a/src/client/app/mobile/views/components/notes.vue +++ b/src/client/app/mobile/views/components/notes.vue @@ -1,7 +1,5 @@ <template> <div class="mk-notes"> - <div class="newer-indicator" :style="{ top: $store.state.uiHeaderHeight + 'px' }" v-show="queue.length > 0"></div> - <slot name="head"></slot> <slot name="empty" v-if="notes.length == 0 && !fetching && requestInitPromise == null"></slot> @@ -71,6 +69,16 @@ export default Vue.extend({ } }, + watch: { + queue(x) { + if (x.length > 0) { + this.$store.commit('indicate', true); + } else { + this.$store.commit('indicate', false); + } + } + }, + mounted() { document.addEventListener('visibilitychange', this.onVisibilitychange, false); window.addEventListener('scroll', this.onScroll); @@ -238,13 +246,6 @@ root(isDark) [data-fa] margin-right 8px - > .newer-indicator - position -webkit-sticky - position sticky - z-index 100 - height 3px - background $theme-color - > .init padding 64px 0 text-align center diff --git a/src/client/app/mobile/views/components/post-form.vue b/src/client/app/mobile/views/components/post-form.vue index 6d80b3046b..0bb498e5d7 100644 --- a/src/client/app/mobile/views/components/post-form.vue +++ b/src/client/app/mobile/views/components/post-form.vue @@ -5,17 +5,22 @@ <div> <span class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</span> <span class="geo" v-if="geo">%fa:map-marker-alt%</span> - <button class="submit" :disabled="posting" @click="post">{{ reply ? '返信' : '%i18n:!@submit%' }}</button> + <button class="submit" :disabled="posting" @click="post"> + <template v-if="reply">%i18n:@reply%</template> + <template v-else-if="renote">%i18n:@renote%</template> + <template v-else>%i18n:@submit%</template> + </button> </div> </header> <div class="form"> <mk-note-preview v-if="reply" :note="reply"/> + <mk-note-preview v-if="renote" :note="renote"/> <div v-if="visibility == 'specified'" class="visibleUsers"> <span v-for="u in visibleUsers">{{ u | userName }}<a @click="removeVisibleUser(u)">[x]</a></span> <a @click="addVisibleUser">+ユーザーを追加</a> </div> <input v-show="useCw" v-model="cw" placeholder="内容への注釈 (オプション)"> - <textarea v-model="text" ref="text" :disabled="posting" :placeholder="reply ? '%i18n:!@reply-placeholder%' : '%i18n:!@note-placeholder%'"></textarea> + <textarea v-model="text" ref="text" :disabled="posting" :placeholder="reply ? '%i18n:!@reply-placeholder%' : renote ? '%i18n:!@renote-placeholder%' : '%i18n:!@note-placeholder%'"></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"> @@ -51,7 +56,7 @@ export default Vue.extend({ MkVisibilityChooser }, - props: ['reply'], + props: ['reply', 'renote'], data() { return { @@ -177,6 +182,7 @@ export default Vue.extend({ text: this.text == '' ? undefined : this.text, mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined, replyId: this.reply ? this.reply.id : undefined, + renoteId: this.renote ? this.renote.id : undefined, poll: this.poll ? (this.$refs.poll as any).get() : undefined, cw: this.useCw ? this.cw || '' : undefined, geo: this.geo ? { diff --git a/src/client/app/mobile/views/components/ui.header.vue b/src/client/app/mobile/views/components/ui.header.vue index 509463333d..a49462b159 100644 --- a/src/client/app/mobile/views/components/ui.header.vue +++ b/src/client/app/mobile/views/components/ui.header.vue @@ -13,6 +13,7 @@ <slot name="func"></slot> </div> </div> + <div class="indicator" v-show="$store.state.indicate"></div> </div> </template> @@ -156,6 +157,10 @@ root(isDark) &, * user-select none + > .indicator + height 3px + background $theme-color + > .main color rgba(#fff, 0.9) diff --git a/src/client/app/mobile/views/components/ui.nav.vue b/src/client/app/mobile/views/components/ui.nav.vue index 5c65d52237..ec42dbc99d 100644 --- a/src/client/app/mobile/views/components/ui.nav.vue +++ b/src/client/app/mobile/views/components/ui.nav.vue @@ -21,6 +21,7 @@ <li><router-link to="/othello" :data-active="$route.name == 'othello'">%fa:gamepad%ゲーム<template v-if="hasGameInvitations">%fa:circle%</template>%fa:angle-right%</router-link></li> </ul> <ul> + <li><router-link to="/i/widgets" :data-active="$route.name == 'widgets'">%fa:quidditch%%i18n:@widgets%%fa:angle-right%</router-link></li> <li><router-link to="/i/drive" :data-active="$route.name == 'drive'">%fa:cloud%%i18n:@drive%%fa:angle-right%</router-link></li> </ul> <ul> diff --git a/src/client/app/mobile/views/components/widget-container.vue b/src/client/app/mobile/views/components/widget-container.vue index 1bdc875763..a713a10621 100644 --- a/src/client/app/mobile/views/components/widget-container.vue +++ b/src/client/app/mobile/views/components/widget-container.vue @@ -25,27 +25,27 @@ export default Vue.extend({ </script> <style lang="stylus" scoped> -.mk-widget-container - background #eee +root(isDark) + background isDark ? #21242f : #eee border-radius 8px - box-shadow 0 0 0 1px rgba(#000, 0.2) + box-shadow 0 4px 16px rgba(#000, 0.1) overflow hidden - &.hideHeader - background #fff - &.naked background transparent !important box-shadow none !important + &.hideHeader + background isDark ? #21242f : #fff + > header > .title margin 0 padding 8px 10px font-size 15px font-weight normal - color #465258 - background #fff + color isDark ? #b8c5cc : #465258 + background isDark ? #282c37 : #fff border-radius 8px 8px 0 0 > [data-fa] @@ -65,4 +65,10 @@ export default Vue.extend({ font-size 15px color #465258 +.mk-widget-container[data-darkmode] + root(true) + +.mk-widget-container:not([data-darkmode]) + root(false) + </style> diff --git a/src/client/app/mobile/views/pages/user.vue b/src/client/app/mobile/views/pages/user.vue index 27482dc215..f43454f9db 100644 --- a/src/client/app/mobile/views/pages/user.vue +++ b/src/client/app/mobile/views/pages/user.vue @@ -84,7 +84,7 @@ export default Vue.extend({ style(): any { if (this.user.bannerUrl == null) return {}; return { - backgroundColor: this.user.bannerColor ? `rgb(${ this.user.bannerColor.join(',') })` : null, + backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null, backgroundImage: `url(${ this.user.bannerUrl })` }; } diff --git a/src/client/app/mobile/views/pages/dashboard.vue b/src/client/app/mobile/views/pages/widgets.vue index a5ca6cb4a2..509ce16eef 100644 --- a/src/client/app/mobile/views/pages/dashboard.vue +++ b/src/client/app/mobile/views/pages/widgets.vue @@ -40,7 +40,7 @@ </x-draggable> </template> <template v-else> - <component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" :is-mobile="true" @chosen="warp"/> + <component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" :is-mobile="true"/> </template> </main> </mk-ui> @@ -55,17 +55,24 @@ export default Vue.extend({ components: { XDraggable }, + data() { return { showNav: false, - widgets: [], customizing: false, widgetAdderSelected: null }; }, + + computed: { + widgets(): any[] { + return this.$store.state.settings.data.mobileHome; + } + }, + created() { - if ((this as any).clientSettings.mobileHome == null) { - Vue.set((this as any).clientSettings, 'mobileHome', [{ + if (this.widgets.length == 0) { + this.widgets = [{ name: 'calendar', id: 'a', data: {} }, { @@ -86,18 +93,9 @@ export default Vue.extend({ }, { name: 'version', id: 'g', data: {} - }]); - this.widgets = (this as any).clientSettings.mobileHome; + }]; this.saveHome(); - } else { - this.widgets = (this as any).clientSettings.mobileHome; } - - this.$watch('clientSettings', i => { - this.widgets = (this as any).clientSettings.mobileHome; - }, { - deep: true - }); }, mounted() { @@ -105,46 +103,33 @@ export default Vue.extend({ }, methods: { - onHomeUpdated(data) { - if (data.home) { - (this as any).clientSettings.mobileHome = data.home; - this.widgets = data.home; - } else { - const w = (this as any).clientSettings.mobileHome.find(w => w.id == data.id); - if (w != null) { - w.data = data.data; - this.$refs[w.id][0].preventSave = true; - this.$refs[w.id][0].props = w.data; - this.widgets = (this as any).clientSettings.mobileHome; - } - } - }, hint() { alert('ウィジェットを追加/削除したり並べ替えたりできます。ウィジェットを移動するには「三」をドラッグします。ウィジェットを削除するには「x」をタップします。いくつかのウィジェットはタップすることで表示を変更できます。'); }, + widgetFunc(id) { const w = this.$refs[id][0]; if (w.func) w.func(); }, + onWidgetSort() { this.saveHome(); }, + addWidget() { - const widget = { + this.$store.dispatch('settings/addMobileHomeWidget', { name: this.widgetAdderSelected, id: uuid(), data: {} - }; - - this.widgets.unshift(widget); - this.saveHome(); + }); }, + removeWidget(widget) { - this.widgets = this.widgets.filter(w => w.id != widget.id); - this.saveHome(); + this.$store.dispatch('settings/removeMobileHomeWidget', widget); }, + saveHome() { - (this as any).clientSettings.mobileHome = this.widgets; + this.$store.commit('settings/setMobileHome', this.widgets); (this as any).api('i/update_mobile_home', { home: this.widgets }); @@ -156,17 +141,25 @@ export default Vue.extend({ <style lang="stylus" scoped> main margin 0 auto + padding 8px max-width 500px + width 100% @media (min-width 500px) - padding 8px + padding 16px 8px + + @media (min-width 600px) + padding 32px 8px > header padding 8px background #fff .widget - margin 8px + margin-bottom 8px + + @media (min-width 600px) + margin-bottom 16px .customize-container margin 8px |