diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-02-24 02:46:09 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-02-24 02:46:09 +0900 |
| commit | df8a2aea358ca3bcec60c878a6399df46390e3e1 (patch) | |
| tree | 2e187e34a53d9372a797fb9d5882069545f1f03f /src/web/app/mobile | |
| parent | v3840 (diff) | |
| download | sharkey-df8a2aea358ca3bcec60c878a6399df46390e3e1.tar.gz sharkey-df8a2aea358ca3bcec60c878a6399df46390e3e1.tar.bz2 sharkey-df8a2aea358ca3bcec60c878a6399df46390e3e1.zip | |
Implement #1098
Diffstat (limited to 'src/web/app/mobile')
| -rw-r--r-- | src/web/app/mobile/views/components/activity.vue (renamed from src/web/app/mobile/views/pages/user/home.activity.vue) | 4 | ||||
| -rw-r--r-- | src/web/app/mobile/views/components/home.vue | 29 | ||||
| -rw-r--r-- | src/web/app/mobile/views/components/index.ts | 14 | ||||
| -rw-r--r-- | src/web/app/mobile/views/components/ui.header.vue | 4 | ||||
| -rw-r--r-- | src/web/app/mobile/views/components/ui.vue | 6 | ||||
| -rw-r--r-- | src/web/app/mobile/views/components/widget-container.vue | 65 | ||||
| -rw-r--r-- | src/web/app/mobile/views/components/widgets/activity.vue | 23 | ||||
| -rw-r--r-- | src/web/app/mobile/views/pages/drive.vue | 4 | ||||
| -rw-r--r-- | src/web/app/mobile/views/pages/home.vue | 174 | ||||
| -rw-r--r-- | src/web/app/mobile/views/pages/notifications.vue | 4 | ||||
| -rw-r--r-- | src/web/app/mobile/views/pages/user.vue | 1 | ||||
| -rw-r--r-- | src/web/app/mobile/views/pages/user/home.vue | 6 |
12 files changed, 280 insertions, 54 deletions
diff --git a/src/web/app/mobile/views/pages/user/home.activity.vue b/src/web/app/mobile/views/components/activity.vue index 87970795b2..b50044b3de 100644 --- a/src/web/app/mobile/views/pages/user/home.activity.vue +++ b/src/web/app/mobile/views/components/activity.vue @@ -1,5 +1,5 @@ <template> -<div class="root activity"> +<div class="mk-activity"> <svg v-if="data" ref="canvas" viewBox="0 0 30 1" preserveAspectRatio="none"> <g v-for="(d, i) in data"> <rect width="0.8" :height="d.postsH" @@ -47,7 +47,7 @@ export default Vue.extend({ </script> <style lang="stylus" scoped> -.root.activity +.mk-activity max-width 600px margin 0 auto diff --git a/src/web/app/mobile/views/components/home.vue b/src/web/app/mobile/views/components/home.vue deleted file mode 100644 index 3feab581d2..0000000000 --- a/src/web/app/mobile/views/components/home.vue +++ /dev/null @@ -1,29 +0,0 @@ -<template> -<div class="mk-home"> - <mk-timeline @loaded="onTlLoaded"/> -</div> -</template> - -<script lang="ts"> -import Vue from 'vue'; -export default Vue.extend({ - methods: { - onTlLoaded() { - this.$emit('loaded'); - } - } -}); -</script> - -<style lang="stylus" scoped> -.mk-home - - > .mk-timeline - max-width 600px - margin 0 auto - padding 8px - - @media (min-width 500px) - padding 16px - -</style> diff --git a/src/web/app/mobile/views/components/index.ts b/src/web/app/mobile/views/components/index.ts index 905baaf20d..d372f22332 100644 --- a/src/web/app/mobile/views/components/index.ts +++ b/src/web/app/mobile/views/components/index.ts @@ -1,7 +1,6 @@ import Vue from 'vue'; import ui from './ui.vue'; -import home from './home.vue'; import timeline from './timeline.vue'; import posts from './posts.vue'; import imagesImage from './images-image.vue'; @@ -19,9 +18,14 @@ import notificationPreview from './notification-preview.vue'; import usersList from './users-list.vue'; import userPreview from './user-preview.vue'; import userTimeline from './user-timeline.vue'; +import activity from './activity.vue'; +import widgetContainer from './widget-container.vue'; + +//#region widgets +import wActivity from './widgets/activity.vue'; +//#endregion Vue.component('mk-ui', ui); -Vue.component('mk-home', home); Vue.component('mk-timeline', timeline); Vue.component('mk-posts', posts); Vue.component('mk-images-image', imagesImage); @@ -39,3 +43,9 @@ Vue.component('mk-notification-preview', notificationPreview); Vue.component('mk-users-list', usersList); Vue.component('mk-user-preview', userPreview); Vue.component('mk-user-timeline', userTimeline); +Vue.component('mk-activity', activity); +Vue.component('mk-widget-container', widgetContainer); + +//#region widgets +Vue.component('mkw-activity', wActivity); +//#endregion diff --git a/src/web/app/mobile/views/components/ui.header.vue b/src/web/app/mobile/views/components/ui.header.vue index 2df5ea162e..026e7eb1b4 100644 --- a/src/web/app/mobile/views/components/ui.header.vue +++ b/src/web/app/mobile/views/components/ui.header.vue @@ -9,9 +9,7 @@ <h1> <slot>Misskey</slot> </h1> - <button v-if="func" @click="func"> - <slot name="funcIcon"></slot> - </button> + <slot name="func"></slot> </div> </div> </div> diff --git a/src/web/app/mobile/views/components/ui.vue b/src/web/app/mobile/views/components/ui.vue index 91d7ea29b6..325ce9d40e 100644 --- a/src/web/app/mobile/views/components/ui.vue +++ b/src/web/app/mobile/views/components/ui.vue @@ -1,7 +1,7 @@ <template> <div class="mk-ui"> - <x-header :func="func"> - <template slot="funcIcon"><slot name="funcIcon"></slot></template> + <x-header> + <template slot="func"><slot name="func"></slot></template> <slot name="header"></slot> </x-header> <x-nav :is-open="isDrawerOpening"/> @@ -23,7 +23,7 @@ export default Vue.extend({ XHeader, XNav }, - props: ['title', 'func'], + props: ['title'], data() { return { isDrawerOpening: false, diff --git a/src/web/app/mobile/views/components/widget-container.vue b/src/web/app/mobile/views/components/widget-container.vue new file mode 100644 index 0000000000..1775188a93 --- /dev/null +++ b/src/web/app/mobile/views/components/widget-container.vue @@ -0,0 +1,65 @@ +<template> +<div class="mk-widget-container" :class="{ naked }"> + <header v-if="showHeader"> + <div class="title"><slot name="header"></slot></div> + <slot name="func"></slot> + </header> + <slot></slot> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +export default Vue.extend({ + props: { + showHeader: { + type: Boolean, + default: true + }, + naked: { + type: Boolean, + default: false + } + } +}); +</script> + +<style lang="stylus" scoped> +.mk-widget-container + background #eee + border-radius 8px + box-shadow 0 0 0 1px rgba(0, 0, 0, 0.2) + overflow hidden + + &.naked + background transparent !important + border none !important + + > header + > .title + margin 0 + padding 8px 10px + font-size 15px + font-weight normal + color #465258 + background #fff + border-radius 8px 8px 0 0 + + > [data-fa] + margin-right 6px + + &:empty + display none + + > button + position absolute + z-index 2 + top 0 + right 0 + padding 0 + width 42px + height 100% + font-size 15px + color #465258 + +</style> diff --git a/src/web/app/mobile/views/components/widgets/activity.vue b/src/web/app/mobile/views/components/widgets/activity.vue new file mode 100644 index 0000000000..c3fe63f264 --- /dev/null +++ b/src/web/app/mobile/views/components/widgets/activity.vue @@ -0,0 +1,23 @@ +<template> +<div class="mkw-activity"> + <mk-widget-container> + <template slot="header">%fa:chart-bar%アクティビティ</template> + <div :class="$style.body"> + <mk-activity :user="os.i"/> + </div> + </mk-widget-container> +</div> +</template> + +<script lang="ts"> +import define from '../../../../common/define-widget'; + +export default define({ + name: 'activity', +}); +</script> + +<style lang="stylus" module> +.body + padding 8px +</style> diff --git a/src/web/app/mobile/views/pages/drive.vue b/src/web/app/mobile/views/pages/drive.vue index 47aeb52f49..ea61661cf6 100644 --- a/src/web/app/mobile/views/pages/drive.vue +++ b/src/web/app/mobile/views/pages/drive.vue @@ -1,11 +1,11 @@ <template> -<mk-ui :func="fn"> +<mk-ui> <span slot="header"> <template v-if="folder">%fa:R folder-open%{{ folder.name }}</template> <template v-if="file"><mk-file-type-icon class="icon" :type="file.type"/>{{ file.name }}</template> <template v-if="!folder && !file">%fa:cloud%%i18n:mobile.tags.mk-drive-page.drive%</template> </span> - <template slot="funcIcon">%fa:ellipsis-h%</template> + <template slot="func"><button @click="fn">%fa:ellipsis-h%</button></template> <mk-drive ref="browser" :init-folder="initFolder" diff --git a/src/web/app/mobile/views/pages/home.vue b/src/web/app/mobile/views/pages/home.vue index c81cbcadb3..0466fbbbf8 100644 --- a/src/web/app/mobile/views/pages/home.vue +++ b/src/web/app/mobile/views/pages/home.vue @@ -1,24 +1,112 @@ <template> -<mk-ui :func="fn"> - <span slot="header">%fa:home%%i18n:mobile.tags.mk-home.home%</span> - <template slot="funcIcon">%fa:pencil-alt%</template> - <mk-home @loaded="onHomeLoaded"/> +<mk-ui> + <span slot="header" @click="showTl = !showTl"> + <template v-if="showTl">%fa:home%タイムライン</template> + <template v-else>%fa:home%ウィジェット</template> + <span style="margin-left:8px"> + <template v-if="showTl">%fa:angle-down%</template> + <template v-else>%fa:angle-up%</template> + </span> + </span> + <template slot="func"> + <button @click="fn" v-if="showTl">%fa:pencil-alt%</button> + <button @click="customizing = !customizing" v-else>%fa:cog%</button> + </template> + <main> + <div class="tl"> + <mk-timeline @loaded="onLoaded" v-show="showTl"/> + </div> + <div class="widgets" v-if="!showTl"> + <template v-if="customizing"> + <header> + <select v-model="widgetAdderSelected"> + <option value="profile">プロフィール</option> + <option value="calendar">カレンダー</option> + <option value="activity">アクティビティ</option> + <option value="rss">RSSリーダー</option> + <option value="photo-stream">フォトストリーム</option> + <option value="version">バージョン</option> + <option value="access-log">アクセスログ</option> + <option value="server">サーバー情報</option> + <option value="donation">寄付のお願い</option> + <option value="nav">ナビゲーション</option> + <option value="tips">ヒント</option> + </select> + <button @click="addWidget">追加</button> + <p>移動するには「三」をドラッグします。削除するには「x」をタップします。</p> + </header> + <x-draggable + :list="widgets" + :options="{ handle: '.handle', animation: 150 }" + @sort="onWidgetSort" + > + <div v-for="widget in widgets" class="customize-container" :key="widget.id"> + <header> + <span class="handle">%fa:bars%</span>{{ widget.name }}<button class="remove" @click="removeWidget(widget)">%fa:times%</button> + </header> + <div> + <component :is="`mkw-${widget.name}`" :widget="widget" :ref="widget.id" :is-mobile="true"/> + </div> + </div> + </x-draggable> + </template> + <template v-else> + <component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :widget="widget" :is-mobile="true" @chosen="warp"/> + </template> + </div> + </main> </mk-ui> </template> <script lang="ts"> import Vue from 'vue'; +import * as XDraggable from 'vuedraggable'; +import * as uuid from 'uuid'; import Progress from '../../../common/scripts/loading'; import getPostSummary from '../../../../../common/get-post-summary'; export default Vue.extend({ + components: { + XDraggable + }, data() { return { connection: null, connectionId: null, - unreadCount: 0 + unreadCount: 0, + showTl: true, + widgets: [], + customizing: false, + widgetAdderSelected: null }; }, + created() { + if ((this as any).os.i.client_settings.mobile_home == null) { + Vue.set((this as any).os.i.client_settings, 'mobile_home', [{ + name: 'calendar', + id: 'a' + }, { + name: 'activity', + id: 'b' + }, { + name: 'rss', + id: 'c' + }, { + name: 'photo-stream', + id: 'd' + }, { + name: 'donation', + id: 'e' + }, { + name: 'nav', + id: 'f' + }, { + name: 'version', + id: 'g' + }]); + } + this.widgets = (this as any).os.i.client_settings.mobile_home; + }, mounted() { document.title = 'Misskey'; document.documentElement.style.background = '#313a42'; @@ -40,7 +128,7 @@ export default Vue.extend({ fn() { (this as any).apis.post(); }, - onHomeLoaded() { + onLoaded() { Progress.done(); }, onStreamPost(post) { @@ -54,7 +142,81 @@ export default Vue.extend({ this.unreadCount = 0; document.title = 'Misskey'; } + }, + onWidgetSort() { + this.saveHome(); + }, + addWidget() { + const widget = { + 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(); + }, + saveHome() { + (this as any).api('i/update_mobile_home', { + home: this.widgets + }); + }, + warp() { + } } }); </script> + +<style lang="stylus" scoped> +main + + > .tl + > .mk-timeline + max-width 600px + margin 0 auto + padding 8px + + @media (min-width 500px) + padding 16px + + > .widgets + margin 0 auto + max-width 500px + + > header + padding 8px + background #fff + + .widget + margin 8px + + .customize-container + margin 8px + background #fff + + > header + line-height 32px + background #eee + + > .handle + padding 0 8px + + > .remove + position absolute + top 0 + right 0 + padding 0 8px + line-height 32px + + > div + padding 8px + + > * + pointer-events none + +</style> diff --git a/src/web/app/mobile/views/pages/notifications.vue b/src/web/app/mobile/views/pages/notifications.vue index b1243dbc74..3dcfb2f38c 100644 --- a/src/web/app/mobile/views/pages/notifications.vue +++ b/src/web/app/mobile/views/pages/notifications.vue @@ -1,7 +1,7 @@ <template> -<mk-ui :func="fn"> +<mk-ui> <span slot="header">%fa:R bell%%i18n:mobile.tags.mk-notifications-page.notifications%</span> - <span slot="funcIcon">%fa:check%</span> + <template slot="func"><button @click="fn">%fa:check%</button></template> <mk-notifications @fetched="onFetched"/> </mk-ui> </template> diff --git a/src/web/app/mobile/views/pages/user.vue b/src/web/app/mobile/views/pages/user.vue index 27f65e623d..378beeaf13 100644 --- a/src/web/app/mobile/views/pages/user.vue +++ b/src/web/app/mobile/views/pages/user.vue @@ -1,7 +1,6 @@ <template> <mk-ui> <span slot="header" v-if="!fetching">%fa:user% {{ user.name }}</span> - <template slot="funcIcon">%fa:pencil-alt%</template> <main v-if="!fetching"> <header> <div class="banner" :style="user.banner_url ? `background-image: url(${user.banner_url}?thumbnail&size=1024)` : ''"></div> diff --git a/src/web/app/mobile/views/pages/user/home.vue b/src/web/app/mobile/views/pages/user/home.vue index 4c68317879..fdbfd1bf55 100644 --- a/src/web/app/mobile/views/pages/user/home.vue +++ b/src/web/app/mobile/views/pages/user/home.vue @@ -16,7 +16,7 @@ <section class="activity"> <h2>%fa:chart-bar%%i18n:mobile.tags.mk-user-overview.activity%</h2> <div> - <x-activity :user="user"/> + <mk-activity :user="user"/> </div> </section> <section class="frequently-replied-users"> @@ -41,15 +41,13 @@ import XPosts from './home.posts.vue'; import XPhotos from './home.photos.vue'; import XFriends from './home.friends.vue'; import XFollowersYouKnow from './home.followers-you-know.vue'; -import XActivity from './home.activity.vue'; export default Vue.extend({ components: { XPosts, XPhotos, XFriends, - XFollowersYouKnow, - XActivity + XFollowersYouKnow }, props: ['user'] }); |