This commit is contained in:
syuilo 2017-08-28 00:03:57 +09:00
parent f228788fcb
commit 3b77bc8299
6 changed files with 132 additions and 83 deletions

View file

@ -2,6 +2,10 @@ ChangeLog
========= =========
主に notable な changes を書いていきます 主に notable な changes を書いていきます
unreleased
----------
* 投稿ページに次の投稿/前の投稿リンクを作成 (#734)
2380 2380
---- ----
アプリケーションが作れない問題を修正 アプリケーションが作れない問題を修正

View file

@ -231,6 +231,10 @@ desktop:
attaches: "{} media attached" attaches: "{} media attached"
uploading-media: "Uploading {} media" uploading-media: "Uploading {} media"
mk-post-page:
prev: "Previous post"
next: "Next post"
mk-timeline-post: mk-timeline-post:
reposted-by: "Reposted by {}" reposted-by: "Reposted by {}"
reply: "Reply" reply: "Reply"

View file

@ -231,6 +231,10 @@ desktop:
attaches: "添付: {}メディア" attaches: "添付: {}メディア"
uploading-media: "{}個のメディアをアップロード中" uploading-media: "{}個のメディアをアップロード中"
mk-post-page:
prev: "前の投稿"
next: "次の投稿"
mk-timeline-post: mk-timeline-post:
reposted-by: "{}がRepost" reposted-by: "{}がRepost"
reply: "返信" reply: "返信"

View file

@ -73,44 +73,79 @@ const self = (
)); ));
} }
if (_post.reply_to_id && opts.detail) { // When requested a detailed post data
// Populate reply to post if (opts.detail) {
_post.reply_to = await self(_post.reply_to_id, me, { // Get previous post info
detail: false const prev = await Post.findOne({
user_id: _post.user_id,
_id: {
$lt: id
}
}, {
fields: {
_id: true
},
sort: {
_id: -1
}
}); });
} _post.prev = prev ? prev._id : null;
if (_post.repost_id && opts.detail) { // Get next post info
// Populate repost const next = await Post.findOne({
_post.repost = await self(_post.repost_id, me, { user_id: _post.user_id,
detail: _post.text == null _id: {
$gt: id
}
}, {
fields: {
_id: true
},
sort: {
_id: 1
}
}); });
} _post.next = next ? next._id : null;
// Poll if (_post.reply_to_id) {
if (me && _post.poll && opts.detail) { // Populate reply to post
const vote = await Vote _post.reply_to = await self(_post.reply_to_id, me, {
.findOne({ detail: false
user_id: me._id,
post_id: id
}); });
if (vote != null) {
_post.poll.choices.filter(c => c.id == vote.choice)[0].is_voted = true;
} }
}
// Fetch my reaction if (_post.repost_id) {
if (me && opts.detail) { // Populate repost
const reaction = await Reaction _post.repost = await self(_post.repost_id, me, {
.findOne({ detail: _post.text == null
user_id: me._id,
post_id: id,
deleted_at: { $exists: false }
}); });
}
if (reaction) { // Poll
_post.my_reaction = reaction.reaction; if (me && _post.poll) {
const vote = await Vote
.findOne({
user_id: me._id,
post_id: id
});
if (vote != null) {
_post.poll.choices.filter(c => c.id == vote.choice)[0].is_voted = true;
}
}
// Fetch my reaction
if (me) {
const reaction = await Reaction
.findOne({
user_id: me._id,
post_id: id,
deleted_at: { $exists: false }
});
if (reaction) {
_post.my_reaction = reaction.reaction;
}
} }
} }

View file

@ -1,7 +1,9 @@
<mk-post-page> <mk-post-page>
<mk-ui ref="ui"> <mk-ui ref="ui">
<main> <main if={ !parent.fetching }>
<a if={ parent.post.next } href={ parent.post.next }><i class="fa fa-angle-up"></i>%i18n:desktop.tags.mk-post-page.next%</a>
<mk-post-detail ref="detail" post={ parent.post }/> <mk-post-detail ref="detail" post={ parent.post }/>
<a if={ parent.post.prev } href={ parent.post.prev }><i class="fa fa-angle-down"></i>%i18n:desktop.tags.mk-post-page.prev%</a>
</main> </main>
</mk-ui> </mk-ui>
<style> <style>
@ -10,6 +12,19 @@
main main
padding 16px padding 16px
text-align center
> a
display inline-block
&:first-child
margin-bottom 4px
&:last-child
margin-top 4px
> i
margin-right 4px
> mk-post-detail > mk-post-detail
margin 0 auto margin 0 auto
@ -18,16 +33,23 @@
<script> <script>
import Progress from '../../../common/scripts/loading'; import Progress from '../../../common/scripts/loading';
this.post = this.opts.post; this.mixin('api');
this.fetching = true;
this.post = null;
this.on('mount', () => { this.on('mount', () => {
Progress.start(); Progress.start();
this.refs.ui.refs.detail.on('post-fetched', () => { this.api('posts/show', {
Progress.set(0.5); post_id: this.opts.post
}); }).then(post => {
this.update({
fetching: false,
post: post
});
this.refs.ui.refs.detail.on('loaded', () => {
Progress.done(); Progress.done();
}); });
}); });

View file

@ -1,8 +1,5 @@
<mk-post-detail title={ title }> <mk-post-detail title={ title }>
<div class="fetching" if={ fetching }> <div class="main">
<mk-ellipsis-icon/>
</div>
<div class="main" if={ !fetching }>
<button class="read-more" if={ p.reply_to && p.reply_to.reply_to_id && context == null } title="会話をもっと読み込む" onclick={ loadContext } disabled={ contextFetching }> <button class="read-more" if={ p.reply_to && p.reply_to.reply_to_id && context == null } title="会話をもっと読み込む" onclick={ loadContext } disabled={ contextFetching }>
<i class="fa fa-ellipsis-v" if={ !contextFetching }></i> <i class="fa fa-ellipsis-v" if={ !contextFetching }></i>
<i class="fa fa-spinner fa-pulse" if={ contextFetching }></i> <i class="fa fa-spinner fa-pulse" if={ contextFetching }></i>
@ -71,13 +68,11 @@
padding 0 padding 0
width 640px width 640px
overflow hidden overflow hidden
text-align left
background #fff background #fff
border solid 1px rgba(0, 0, 0, 0.1) border solid 1px rgba(0, 0, 0, 0.1)
border-radius 8px border-radius 8px
> .fetching
padding 64px 0
> .main > .main
> .read-more > .read-more
@ -262,56 +257,41 @@
this.mixin('api'); this.mixin('api');
this.mixin('user-preview'); this.mixin('user-preview');
this.fetching = true;
this.contextFetching = false; this.contextFetching = false;
this.context = null; this.context = null;
this.post = null; this.post = this.opts.post;
this.isRepost = this.post.repost != null;
this.p = this.isRepost ? this.post.repost : this.post;
this.p.reactions_count = this.p.reaction_counts ? Object.keys(this.p.reaction_counts).map(key => this.p.reaction_counts[key]).reduce((a, b) => a + b) : 0;
this.title = dateStringify(this.p.created_at);
this.on('mount', () => { this.on('mount', () => {
this.api('posts/show', { if (this.p.text) {
post_id: this.opts.post const tokens = this.p.ast;
}).then(post => {
const isRepost = post.repost != null;
const p = isRepost ? post.repost : post;
p.reactions_count = p.reaction_counts ? Object.keys(p.reaction_counts).map(key => p.reaction_counts[key]).reduce((a, b) => a + b) : 0;
this.update({ this.refs.text.innerHTML = compile(tokens);
fetching: false,
post: post, this.refs.text.children.forEach(e => {
isRepost: isRepost, if (e.tagName == 'MK-URL') riot.mount(e);
p: p,
title: dateStringify(p.created_at)
}); });
this.trigger('loaded'); // URLをプレビュー
tokens
if (this.p.text) { .filter(t => (t.type == 'url' || t.type == 'link') && !t.silent)
const tokens = this.p.ast; .map(t => {
riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), {
this.refs.text.innerHTML = compile(tokens); url: t.url
this.refs.text.children.forEach(e => {
if (e.tagName == 'MK-URL') riot.mount(e);
}); });
});
}
// URLをプレビュー // Get replies
tokens this.api('posts/replies', {
.filter(t => (t.type == 'url' || t.type == 'link') && !t.silent) post_id: this.p.id,
.map(t => { limit: 8
riot.mount(this.refs.text.appendChild(document.createElement('mk-url-preview')), { }).then(replies => {
url: t.url this.update({
}); replies: replies
});
}
// Get replies
this.api('posts/replies', {
post_id: this.p.id,
limit: 8
}).then(replies => {
this.update({
replies: replies
});
}); });
}); });
}); });