This commit is contained in:
syuilo 2018-03-17 23:01:17 +09:00
parent c10c534d02
commit ab8eefda25
4 changed files with 96 additions and 42 deletions

View File

@ -16,40 +16,38 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$; const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
if (limitErr) return rej('invalid limit param'); if (limitErr) return rej('invalid limit param');
// Get 'since_id' parameter // Get 'offset' parameter
const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$; const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
if (sinceIdErr) return rej('invalid since_id param'); if (offsetErr) return rej('invalid offset param');
// Get 'until_id' parameter // Get 'sort' parameter
const [untilId, untilIdErr] = $(params.until_id).optional.id().$; const [sort, sortError] = $(params.sort).optional.string().or('+follower|-follower').$;
if (untilIdErr) return rej('invalid until_id param'); if (sortError) return rej('invalid sort param');
// Check if both of since_id and until_id is specified
if (sinceId && untilId) {
return rej('cannot set since_id and until_id');
}
// Construct query // Construct query
const sort = { let _sort;
_id: -1 if (sort) {
}; if (sort == '+follower') {
const query = {} as any; _sort = {
if (sinceId) { followers_count: 1
sort._id = 1; };
query._id = { } else if (sort == '-follower') {
$gt: sinceId _sort = {
}; followers_count: -1
} else if (untilId) { };
query._id = { }
$lt: untilId } else {
_sort = {
_id: -1
}; };
} }
// Issue query // Issue query
const users = await User const users = await User
.find(query, { .find({}, {
limit: limit, limit: limit,
sort: sort sort: _sort,
skip: offset
}); });
// Serialize // Serialize

View File

@ -1,12 +1,12 @@
<template> <template>
<div class="mk-welcome-timeline"> <div class="mk-welcome-timeline">
<div v-for="post in posts"> <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"/> <img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=96`" alt="avatar"/>
</router-link> </router-link>
<div class="body"> <div class="body">
<header> <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> <span class="username">@{{ post.user.username }}</span>
<div class="info"> <div class="info">
<router-link class="created-at" :to="`/${post.user.username}/${post.id}`"> <router-link class="created-at" :to="`/${post.user.username}/${post.id}`">
@ -100,6 +100,7 @@ export default Vue.extend({
overflow hidden overflow hidden
font-weight bold font-weight bold
text-overflow ellipsis text-overflow ellipsis
color #627079
> .username > .username
margin 0 .5em 0 0 margin 0 .5em 0 0

View File

@ -5,8 +5,13 @@
<div> <div>
<div> <div>
<h1>Share<br>Everything!</h1> <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> <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> <div>
<div> <div>
@ -37,14 +42,24 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import { copyright } from '../../../config'; import { docsUrl, copyright, lang } from '../../../config';
export default Vue.extend({ export default Vue.extend({
data() { data() {
return { return {
copyright aboutUrl: `${docsUrl}/${lang}/about`,
copyright,
users: []
}; };
}, },
mounted() {
(this as any).api('users', {
sort: '+follower',
limit: 20
}).then(users => {
this.users = users;
});
},
methods: { methods: {
signup() { signup() {
this.$modal.show('signup'); this.$modal.show('signup');
@ -139,14 +154,22 @@ export default Vue.extend({
border-color darken($theme-color, 10%) border-color darken($theme-color, 10%)
.signin .signin
&:focus
color #444
&:hover &:hover
color #444 color #fff
&:active > .users
color #333 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 > div:last-child

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="welcome"> <div class="welcome">
<h1><b>Misskey</b>へようこそ</h1> <h1><b>Misskey</b>へようこそ</h1>
<p>Twitter風ミニブログSNSMisskeyへようこそ思ったことを投稿したりタイムラインでみんなの投稿を読むこともできます<a href="/signup">アカウントを作成する</a></p> <p>Twitter風ミニブログSNSMisskeyへようこそ思ったことを投稿したりタイムラインでみんなの投稿を読むこともできます<br><a href="/signup">アカウントを作成する</a></p>
<div class="form"> <div class="form">
<p>%fa:lock% ログイン</p> <p>%fa:lock% ログイン</p>
<div> <div>
@ -20,6 +20,11 @@
<p>%fa:comments R% タイムラインを見てみる</p> <p>%fa:comments R% タイムラインを見てみる</p>
<mk-welcome-timeline/> <mk-welcome-timeline/>
</div> </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> <footer>
<small>{{ copyright }}</small> <small>{{ copyright }}</small>
</footer> </footer>
@ -39,11 +44,17 @@ export default Vue.extend({
password: '', password: '',
token: '', token: '',
apiUrl, apiUrl,
copyright copyright,
users: []
}; };
}, },
mounted() { mounted() {
document.documentElement.style.background = '#293946'; (this as any).api('users', {
sort: '+follower',
limit: 20
}).then(users => {
this.users = users;
});
}, },
methods: { methods: {
onUsernameChange() { onUsernameChange() {
@ -82,7 +93,7 @@ export default Vue.extend({
padding 8px padding 8px
font-size 1.5em font-size 1.5em
font-weight normal font-weight normal
color #c3c6ca color #cacac3
& + p & + p
margin 0 0 16px 0 margin 0 0 16px 0
@ -146,7 +157,7 @@ export default Vue.extend({
padding 16px padding 16px
text-align center text-align center
.tl > .tl
background #fff background #fff
border solid 1px rgba(0, 0, 0, 0.2) border solid 1px rgba(0, 0, 0, 0.2)
border-radius 8px border-radius 8px
@ -163,12 +174,33 @@ export default Vue.extend({
max-height 300px max-height 300px
overflow auto 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 > footer
text-align center text-align center
color #949fa9 color #fff
> small > small
display block display block
margin 16px 0 0 0 margin 16px 0 0 0
opacity 0.7
</style> </style>
<style lang="stylus">
html
body
background linear-gradient(to bottom, #1e1d65, #bd6659)
</style>