From a501a3cbc4293fbf5a3558a613ff91e89f9cb28f Mon Sep 17 00:00:00 2001 From: syuilo <syuilotan@yahoo.co.jp> Date: Sat, 25 Mar 2017 23:23:22 +0900 Subject: [PATCH] #322 --- src/api/endpoints.ts | 4 + src/api/endpoints/posts/trend.ts | 76 ++++++++++++ .../app/desktop/tags/home-widgets/trends.tag | 112 ++++++++++++++++++ src/web/app/desktop/tags/home.tag | 1 + src/web/app/desktop/tags/index.js | 1 + 5 files changed, 194 insertions(+) create mode 100644 src/api/endpoints/posts/trend.ts create mode 100644 src/web/app/desktop/tags/home-widgets/trends.tag diff --git a/src/api/endpoints.ts b/src/api/endpoints.ts index f0031b82a2..b72392db64 100644 --- a/src/api/endpoints.ts +++ b/src/api/endpoints.ts @@ -360,6 +360,10 @@ const endpoints: Endpoint[] = [ max: 100 } }, + { + name: 'posts/trend', + withCredential: true + }, { name: 'posts/reactions', withCredential: true diff --git a/src/api/endpoints/posts/trend.ts b/src/api/endpoints/posts/trend.ts new file mode 100644 index 0000000000..0f0ea4876c --- /dev/null +++ b/src/api/endpoints/posts/trend.ts @@ -0,0 +1,76 @@ +/** + * Module dependencies + */ +const ms = require('ms'); +import $ from 'cafy'; +import Post from '../../models/post'; +import serialize from '../../serializers/post'; + +/** + * Get trend posts + * + * @param {any} params + * @param {any} user + * @return {Promise<any>} + */ +module.exports = (params, user) => new Promise(async (res, rej) => { + // Get 'limit' parameter + const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; + if (limitErr) return rej('invalid limit param'); + + // Get 'offset' parameter + const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$; + if (offsetErr) return rej('invalid offset param'); + + // Get 'reply' parameter + const [reply, replyErr] = $(params.reply).optional.boolean().$; + if (replyErr) return rej('invalid reply param'); + + // Get 'repost' parameter + const [repost, repostErr] = $(params.repost).optional.boolean().$; + if (repostErr) return rej('invalid repost param'); + + // Get 'media' parameter + const [media, mediaErr] = $(params.media).optional.boolean().$; + if (mediaErr) return rej('invalid media param'); + + // Get 'poll' parameter + const [poll, pollErr] = $(params.poll).optional.boolean().$; + if (pollErr) return rej('invalid poll param'); + + const query = { + created_at: { + $gte: new Date(Date.now() - ms('1days')) + } + } as any; + + if (reply != undefined) { + query.reply_to_id = reply ? { $exists: true, $ne: null } : null; + } + + if (repost != undefined) { + query.repost_id = repost ? { $exists: true, $ne: null } : null; + } + + if (media != undefined) { + query.media_ids = media ? { $exists: true, $ne: null } : null; + } + + if (poll != undefined) { + query.poll = poll ? { $exists: true, $ne: null } : null; + } + + // Issue query + const posts = await Post + .find(query, { + limit: limit, + skip: offset, + sort: { + repost_count: -1 + } + }); + + // Serialize + res(await Promise.all(posts.map(async post => + await serialize(post, user, { detail: true })))); +}); diff --git a/src/web/app/desktop/tags/home-widgets/trends.tag b/src/web/app/desktop/tags/home-widgets/trends.tag new file mode 100644 index 0000000000..0ad7729abd --- /dev/null +++ b/src/web/app/desktop/tags/home-widgets/trends.tag @@ -0,0 +1,112 @@ +<mk-trends-home-widget> + <p class="title"><i class="fa fa-fire"></i>トレンド</p> + <button onclick={ refresh } title="他を見る"><i class="fa fa-refresh"></i></button> + <div class="post" if={ !loading && post != null }> + <p class="text">{ post.text }</p> + <p class="author">―<a href="/{ post.user.username }">@{ post.user.username }</a></p> + </div> + <p class="empty" if={ !loading && post == null }>ありません!</p> + <p class="loading" if={ loading }><i class="fa fa-spinner fa-pulse fa-fw"></i>読み込んでいます<mk-ellipsis></mk-ellipsis></p> + <style> + :scope + display block + background #fff + + > .title + margin 0 + padding 0 16px + line-height 42px + font-size 0.9em + font-weight bold + color #888 + border-bottom solid 1px #eee + + > i + margin-right 4px + + > button + position absolute + z-index 2 + top 0 + right 0 + padding 0 + width 42px + font-size 0.9em + line-height 42px + color #ccc + + &:hover + color #aaa + + &:active + color #999 + + > .post + padding 16px + font-size 12px + font-style oblique + color #555 + + > p + margin 0 + + > .author + > a + color inherit + + > .empty + margin 0 + padding 16px + text-align center + color #aaa + + > .loading + margin 0 + padding 16px + text-align center + color #aaa + + > i + margin-right 4px + + </style> + <script> + this.mixin('api'); + + this.post = null; + this.loading = true; + + this.offset = 0; + + this.on('mount', () => { + this.fetch(); + }); + + this.fetch = () => { + this.update({ + loading: true, + post: null + }); + this.api('posts/trend', { + limit: 1, + offset: this.offset, + repost: false, + reply: false, + media: false, + poll: false + }).then(posts => { + const post = posts ? posts[0] : null; + if (post == null) this.offset = 0; + this.update({ + loading: false, + post: post + }); + }); + }; + + this.refresh = () => { + this.offset++; + this.fetch(); + }; + </script> +</mk-trends-home-widget> diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag index 93840bdf0e..a913739af6 100644 --- a/src/web/app/desktop/tags/home.tag +++ b/src/web/app/desktop/tags/home.tag @@ -69,6 +69,7 @@ 'profile', 'calendar', 'rss-reader', + 'trends', 'photo-stream', 'version' ], diff --git a/src/web/app/desktop/tags/index.js b/src/web/app/desktop/tags/index.js index 3032c9c544..f92200b3d9 100644 --- a/src/web/app/desktop/tags/index.js +++ b/src/web/app/desktop/tags/index.js @@ -43,6 +43,7 @@ require('./home-widgets/photo-stream.tag'); require('./home-widgets/broadcast.tag'); require('./home-widgets/version.tag'); require('./home-widgets/recommended-polls.tag'); +require('./home-widgets/trends.tag'); require('./timeline.tag'); require('./messaging/window.tag'); require('./messaging/room-window.tag');