diff --git a/src/api/endpoints/users.ts b/src/api/endpoints/users.ts index 095b9fe40d..249faed368 100644 --- a/src/api/endpoints/users.ts +++ b/src/api/endpoints/users.ts @@ -16,40 +16,38 @@ module.exports = (params, me) => new Promise(async (res, rej) => { const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; if (limitErr) return rej('invalid limit param'); - // Get 'since_id' parameter - const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$; - if (sinceIdErr) return rej('invalid since_id param'); + // Get 'offset' parameter + const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$; + if (offsetErr) return rej('invalid offset param'); - // Get 'until_id' parameter - const [untilId, untilIdErr] = $(params.until_id).optional.id().$; - if (untilIdErr) return rej('invalid until_id param'); - - // Check if both of since_id and until_id is specified - if (sinceId && untilId) { - return rej('cannot set since_id and until_id'); - } + // Get 'sort' parameter + const [sort, sortError] = $(params.sort).optional.string().or('+follower|-follower').$; + if (sortError) return rej('invalid sort param'); // Construct query - const sort = { - _id: -1 - }; - const query = {} as any; - if (sinceId) { - sort._id = 1; - query._id = { - $gt: sinceId - }; - } else if (untilId) { - query._id = { - $lt: untilId + let _sort; + if (sort) { + if (sort == '+follower') { + _sort = { + followers_count: 1 + }; + } else if (sort == '-follower') { + _sort = { + followers_count: -1 + }; + } + } else { + _sort = { + _id: -1 }; } // Issue query const users = await User - .find(query, { + .find({}, { limit: limit, - sort: sort + sort: _sort, + skip: offset }); // Serialize diff --git a/src/web/app/common/views/components/welcome-timeline.vue b/src/web/app/common/views/components/welcome-timeline.vue index 2ff06e2cc0..7e35e1f71b 100644 --- a/src/web/app/common/views/components/welcome-timeline.vue +++ b/src/web/app/common/views/components/welcome-timeline.vue @@ -1,12 +1,12 @@ <template> <div class="mk-welcome-timeline"> <div v-for="post in posts"> - <router-link class="avatar-anchor" :to="`/${post.user.username}`"> + <router-link class="avatar-anchor" :to="`/${post.user.username}`" v-user-preview="post.user.id"> <img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=96`" alt="avatar"/> </router-link> <div class="body"> <header> - <router-link class="name" :to="`/${post.user.username}`">{{ post.user.name }}</router-link> + <router-link class="name" :to="`/${post.user.username}`" v-user-preview="post.user.id">{{ post.user.name }}</router-link> <span class="username">@{{ post.user.username }}</span> <div class="info"> <router-link class="created-at" :to="`/${post.user.username}/${post.id}`"> @@ -100,6 +100,7 @@ export default Vue.extend({ overflow hidden font-weight bold text-overflow ellipsis + color #627079 > .username margin 0 .5em 0 0 diff --git a/src/web/app/desktop/views/pages/welcome.vue b/src/web/app/desktop/views/pages/welcome.vue index 47068bd937..2ec7f9209c 100644 --- a/src/web/app/desktop/views/pages/welcome.vue +++ b/src/web/app/desktop/views/pages/welcome.vue @@ -5,8 +5,13 @@ <div> <div> <h1>Share<br>Everything!</h1> - <p>ようこそ! <b>Misskey</b>はTwitter風ミニブログSNSです。思ったことや皆と共有したいことを投稿しましょう。タイムラインを見れば、皆の関心事をすぐにチェックすることもできます。<a>詳しく...</a></p> + <p>ようこそ! <b>Misskey</b>はTwitter風ミニブログSNSです。思ったことや皆と共有したいことを投稿しましょう。タイムラインを見れば、皆の関心事をすぐにチェックすることもできます。<a :href="aboutUrl">詳しく...</a></p> <p><button class="signup" @click="signup">はじめる</button><button class="signin" @click="signin">ログイン</button></p> + <div class="users"> + <router-link v-for="user in users" :key="user.id" class="avatar-anchor" :to="`/${user.username}`" v-user-preview="user.id"> + <img class="avatar" :src="`${user.avatar_url}?thumbnail&size=64`" alt="avatar"/> + </router-link> + </div> </div> <div> <div> @@ -37,14 +42,24 @@ <script lang="ts"> import Vue from 'vue'; -import { copyright } from '../../../config'; +import { docsUrl, copyright, lang } from '../../../config'; export default Vue.extend({ data() { return { - copyright + aboutUrl: `${docsUrl}/${lang}/about`, + copyright, + users: [] }; }, + mounted() { + (this as any).api('users', { + sort: '+follower', + limit: 20 + }).then(users => { + this.users = users; + }); + }, methods: { signup() { this.$modal.show('signup'); @@ -139,14 +154,22 @@ export default Vue.extend({ border-color darken($theme-color, 10%) .signin - &:focus - color #444 - &:hover - color #444 + color #fff - &:active - color #333 + > .users + margin 16px 0 0 0 + + > * + display inline-block + margin 4px + + > * + display inline-block + width 38px + height 38px + vertical-align top + border-radius 6px > div:last-child diff --git a/src/web/app/mobile/views/pages/welcome.vue b/src/web/app/mobile/views/pages/welcome.vue index cb8756f3b6..e212d6c786 100644 --- a/src/web/app/mobile/views/pages/welcome.vue +++ b/src/web/app/mobile/views/pages/welcome.vue @@ -1,7 +1,7 @@ <template> <div class="welcome"> <h1><b>Misskey</b>へようこそ</h1> - <p>Twitter風ミニブログSNS、Misskeyへようこそ。思ったことを投稿したり、タイムラインでみんなの投稿を読むこともできます。<a href="/signup">アカウントを作成する</a></p> + <p>Twitter風ミニブログSNS、Misskeyへようこそ。思ったことを投稿したり、タイムラインでみんなの投稿を読むこともできます。<br><a href="/signup">アカウントを作成する</a></p> <div class="form"> <p>%fa:lock% ログイン</p> <div> @@ -20,6 +20,11 @@ <p>%fa:comments R% タイムラインを見てみる</p> <mk-welcome-timeline/> </div> + <div class="users"> + <router-link v-for="user in users" :key="user.id" class="avatar-anchor" :to="`/${user.username}`"> + <img class="avatar" :src="`${user.avatar_url}?thumbnail&size=64`" alt="avatar"/> + </router-link> + </div> <footer> <small>{{ copyright }}</small> </footer> @@ -39,11 +44,17 @@ export default Vue.extend({ password: '', token: '', apiUrl, - copyright + copyright, + users: [] }; }, mounted() { - document.documentElement.style.background = '#293946'; + (this as any).api('users', { + sort: '+follower', + limit: 20 + }).then(users => { + this.users = users; + }); }, methods: { onUsernameChange() { @@ -82,7 +93,7 @@ export default Vue.extend({ padding 8px font-size 1.5em font-weight normal - color #c3c6ca + color #cacac3 & + p margin 0 0 16px 0 @@ -146,7 +157,7 @@ export default Vue.extend({ padding 16px text-align center - .tl + > .tl background #fff border solid 1px rgba(0, 0, 0, 0.2) border-radius 8px @@ -163,12 +174,33 @@ export default Vue.extend({ max-height 300px overflow auto + > .users + margin 12px 0 0 0 + + > * + display inline-block + margin 4px + + > * + display inline-block + width 38px + height 38px + vertical-align top + border-radius 6px + > footer text-align center - color #949fa9 + color #fff > small display block margin 16px 0 0 0 + opacity 0.7 </style> + +<style lang="stylus"> +html +body + background linear-gradient(to bottom, #1e1d65, #bd6659) +</style>