diff options
| author | こぴなたみぽ <syuilotan@yahoo.co.jp> | 2018-02-16 17:17:05 +0900 |
|---|---|---|
| committer | こぴなたみぽ <syuilotan@yahoo.co.jp> | 2018-02-16 17:17:05 +0900 |
| commit | 7c30b94cbb4f9374a1b8c7d3aa72e4612b1283a6 (patch) | |
| tree | 0a97d92bab6d0435fc6d98607389967ec4d68cf4 /src/web | |
| parent | wip (diff) | |
| download | misskey-7c30b94cbb4f9374a1b8c7d3aa72e4612b1283a6.tar.gz misskey-7c30b94cbb4f9374a1b8c7d3aa72e4612b1283a6.tar.bz2 misskey-7c30b94cbb4f9374a1b8c7d3aa72e4612b1283a6.zip | |
wip
Diffstat (limited to 'src/web')
| -rw-r--r-- | src/web/app/desktop/-tags/user-timeline.tag | 150 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/user-timeline.vue | 133 |
2 files changed, 133 insertions, 150 deletions
diff --git a/src/web/app/desktop/-tags/user-timeline.tag b/src/web/app/desktop/-tags/user-timeline.tag deleted file mode 100644 index 1071b6e2b4..0000000000 --- a/src/web/app/desktop/-tags/user-timeline.tag +++ /dev/null @@ -1,150 +0,0 @@ -<mk-user-timeline> - <header> - <span data-is-active={ mode == 'default' } @click="setMode.bind(this, 'default')">投稿</span><span data-is-active={ mode == 'with-replies' } @click="setMode.bind(this, 'with-replies')">投稿と返信</span> - </header> - <div class="loading" v-if="isLoading"> - <mk-ellipsis-icon/> - </div> - <p class="empty" v-if="isEmpty">%fa:R comments%このユーザーはまだ何も投稿していないようです。</p> - <mk-timeline ref="timeline"> - <yield to="footer"> - <template v-if="!parent.moreLoading">%fa:moon%</template> - <template v-if="parent.moreLoading">%fa:spinner .pulse .fw%</template> - </yield/> - </mk-timeline> - <style lang="stylus" scoped> - :scope - display block - background #fff - - > header - padding 8px 16px - border-bottom solid 1px #eee - - > span - margin-right 16px - line-height 27px - font-size 18px - color #555 - - &:not([data-is-active]) - color $theme-color - cursor pointer - - &:hover - text-decoration underline - - > .loading - padding 64px 0 - - > .empty - display block - margin 0 auto - padding 32px - max-width 400px - text-align center - color #999 - - > [data-fa] - display block - margin-bottom 16px - font-size 3em - color #ccc - - </style> - <script lang="typescript"> - import isPromise from '../../common/scripts/is-promise'; - - this.mixin('api'); - - this.user = null; - this.userPromise = isPromise(this.opts.user) - ? this.opts.user - : Promise.resolve(this.opts.user); - this.isLoading = true; - this.isEmpty = false; - this.moreLoading = false; - this.unreadCount = 0; - this.mode = 'default'; - - this.on('mount', () => { - document.addEventListener('keydown', this.onDocumentKeydown); - window.addEventListener('scroll', this.onScroll); - - this.userPromise.then(user => { - this.update({ - user: user - }); - - this.fetch(() => this.$emit('loaded')); - }); - }); - - this.on('unmount', () => { - document.removeEventListener('keydown', this.onDocumentKeydown); - window.removeEventListener('scroll', this.onScroll); - }); - - this.onDocumentKeydown = e => { - if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') { - if (e.which == 84) { // [t] - this.$refs.timeline.focus(); - } - } - }; - - this.fetch = cb => { - this.$root.$data.os.api('users/posts', { - user_id: this.user.id, - until_date: this.date ? this.date.getTime() : undefined, - with_replies: this.mode == 'with-replies' - }).then(posts => { - this.update({ - isLoading: false, - isEmpty: posts.length == 0 - }); - this.$refs.timeline.setPosts(posts); - if (cb) cb(); - }); - }; - - this.more = () => { - if (this.moreLoading || this.isLoading || this.$refs.timeline.posts.length == 0) return; - this.update({ - moreLoading: true - }); - this.$root.$data.os.api('users/posts', { - user_id: this.user.id, - with_replies: this.mode == 'with-replies', - until_id: this.$refs.timeline.tail().id - }).then(posts => { - this.update({ - moreLoading: false - }); - this.$refs.timeline.prependPosts(posts); - }); - }; - - this.onScroll = () => { - const current = window.scrollY + window.innerHeight; - if (current > document.body.offsetHeight - 16/*遊び*/) { - this.more(); - } - }; - - this.setMode = mode => { - this.update({ - mode: mode - }); - this.fetch(); - }; - - this.warp = date => { - this.update({ - date: date - }); - - this.fetch(); - }; - </script> -</mk-user-timeline> diff --git a/src/web/app/desktop/views/components/user-timeline.vue b/src/web/app/desktop/views/components/user-timeline.vue new file mode 100644 index 0000000000..bab32fd24e --- /dev/null +++ b/src/web/app/desktop/views/components/user-timeline.vue @@ -0,0 +1,133 @@ +<template> +<div class="mk-user-timeline"> + <header> + <span :data-is-active="mode == 'default'" @click="mode = 'default'">投稿</span> + <span :data-is-active="mode == 'with-replies'" @click="mode = 'with-replies'">投稿と返信</span> + </header> + <div class="loading" v-if="fetching"> + <mk-ellipsis-icon/> + </div> + <p class="empty" v-if="empty">%fa:R comments%このユーザーはまだ何も投稿していないようです。</p> + <mk-posts ref="timeline" :posts="posts"> + <div slot="footer"> + <template v-if="!moreFetching">%fa:moon%</template> + <template v-if="moreFetching">%fa:spinner .pulse .fw%</template> + </div> + </mk-posts> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +export default Vue.extend({ + props: ['user'], + data() { + return { + fetching: true, + moreFetching: false, + mode: 'default', + unreadCount: 0, + posts: [], + date: null + }; + }, + watch: { + mode() { + this.fetch(); + } + }, + computed: { + empty(): boolean { + return this.posts.length == 0; + } + }, + mounted() { + document.addEventListener('keydown', this.onDocumentKeydown); + window.addEventListener('scroll', this.onScroll); + + this.fetch(() => this.$emit('loaded')); + }, + beforeDestroy() { + document.removeEventListener('keydown', this.onDocumentKeydown); + window.removeEventListener('scroll', this.onScroll); + }, + methods: { + onDocumentKeydown(e) { + if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') { + if (e.which == 84) { // [t] + (this.$refs.timeline as any).focus(); + } + } + }, + fetch(cb?) { + this.$root.$data.os.api('users/posts', { + user_id: this.user.id, + until_date: this.date ? this.date.getTime() : undefined, + with_replies: this.mode == 'with-replies' + }).then(posts => { + this.fetching = false; + this.posts = posts; + if (cb) cb(); + }); + }, + more() { + if (this.moreFetching || this.fetching || this.posts.length == 0) return; + this.moreFetching = true; + this.$root.$data.os.api('users/posts', { + user_id: this.user.id, + with_replies: this.mode == 'with-replies', + until_id: this.posts[this.posts.length - 1].id + }).then(posts => { + this.moreFetching = false; + this.posts = this.posts.concat(posts); + }); + }, + onScroll() { + const current = window.scrollY + window.innerHeight; + if (current > document.body.offsetHeight - 16/*遊び*/) { + this.more(); + } + } + } +}); +</script> + +<style lang="stylus" scoped> +.mk-user-timeline + background #fff + + > header + padding 8px 16px + border-bottom solid 1px #eee + + > span + margin-right 16px + line-height 27px + font-size 18px + color #555 + + &:not([data-is-active]) + color $theme-color + cursor pointer + + &:hover + text-decoration underline + + > .loading + padding 64px 0 + + > .empty + display block + margin 0 auto + padding 32px + max-width 400px + text-align center + color #999 + + > [data-fa] + display block + margin-bottom 16px + font-size 3em + color #ccc + +</style> |