Implement #746
This commit is contained in:
		
							parent
							
								
									61be5c0d10
								
							
						
					
					
						commit
						e7415dd42b
					
				
					 14 changed files with 315 additions and 60 deletions
				
			
		|  | @ -2,6 +2,10 @@ ChangeLog (Release Notes) | ||||||
| ========================= | ========================= | ||||||
| 主に notable な changes を書いていきます | 主に notable な changes を書いていきます | ||||||
| 
 | 
 | ||||||
|  | unreleased | ||||||
|  | ---------- | ||||||
|  | * New: 投稿のピン留め (#746) | ||||||
|  | 
 | ||||||
| 2508 (2017/08/30) | 2508 (2017/08/30) | ||||||
| ----------------- | ----------------- | ||||||
| * New: モバイル版のユーザーページのアクティビティチャートを変更 | * New: モバイル版のユーザーページのアクティビティチャートを変更 | ||||||
|  |  | ||||||
|  | @ -77,6 +77,10 @@ common: | ||||||
|       show-result: "Show result" |       show-result: "Show result" | ||||||
|       voted: "Voted" |       voted: "Voted" | ||||||
| 
 | 
 | ||||||
|  |     mk-post-menu: | ||||||
|  |       pin: "Pin" | ||||||
|  |       pinned: "Pinned" | ||||||
|  | 
 | ||||||
|     mk-reaction-picker: |     mk-reaction-picker: | ||||||
|       choose-reaction: "Pick your reaction" |       choose-reaction: "Pick your reaction" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -77,6 +77,10 @@ common: | ||||||
|       show-result: "結果を見る" |       show-result: "結果を見る" | ||||||
|       voted: "投票済み" |       voted: "投票済み" | ||||||
| 
 | 
 | ||||||
|  |     mk-post-menu: | ||||||
|  |       pin: "ピン留め" | ||||||
|  |       pinned: "ピン留めしました" | ||||||
|  | 
 | ||||||
|     mk-reaction-picker: |     mk-reaction-picker: | ||||||
|       choose-reaction: "リアクションを選択" |       choose-reaction: "リアクションを選択" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -167,6 +167,10 @@ const endpoints: Endpoint[] = [ | ||||||
| 		name: 'i/regenerate_token', | 		name: 'i/regenerate_token', | ||||||
| 		withCredential: true | 		withCredential: true | ||||||
| 	}, | 	}, | ||||||
|  | 	{ | ||||||
|  | 		name: 'i/pin', | ||||||
|  | 		kind: 'account-write' | ||||||
|  | 	}, | ||||||
| 	{ | 	{ | ||||||
| 		name: 'i/appdata/get', | 		name: 'i/appdata/get', | ||||||
| 		withCredential: true | 		withCredential: true | ||||||
|  |  | ||||||
							
								
								
									
										44
									
								
								src/api/endpoints/i/pin.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/api/endpoints/i/pin.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | ||||||
|  | /** | ||||||
|  |  * Module dependencies | ||||||
|  |  */ | ||||||
|  | import $ from 'cafy'; | ||||||
|  | import User from '../../models/user'; | ||||||
|  | import Post from '../../models/post'; | ||||||
|  | import serialize from '../../serializers/user'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Pin post | ||||||
|  |  * | ||||||
|  |  * @param {any} params | ||||||
|  |  * @param {any} user | ||||||
|  |  * @return {Promise<any>} | ||||||
|  |  */ | ||||||
|  | module.exports = async (params, user) => new Promise(async (res, rej) => { | ||||||
|  | 	// Get 'post_id' parameter
 | ||||||
|  | 	const [postId, postIdErr] = $(params.post_id).id().$; | ||||||
|  | 	if (postIdErr) return rej('invalid post_id param'); | ||||||
|  | 
 | ||||||
|  | 	// Fetch pinee
 | ||||||
|  | 	const post = await Post.findOne({ | ||||||
|  | 		_id: postId, | ||||||
|  | 		user_id: user._id | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	if (post === null) { | ||||||
|  | 		return rej('post not found'); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	await User.update(user._id, { | ||||||
|  | 		$set: { | ||||||
|  | 			pinned_post_id: post._id | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// Serialize
 | ||||||
|  | 	const iObj = await serialize(user, user, { | ||||||
|  | 		detail: true | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// Send response
 | ||||||
|  | 	res(iObj); | ||||||
|  | }); | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| import * as mongo from 'mongodb'; | import * as mongo from 'mongodb'; | ||||||
| import deepcopy = require('deepcopy'); | import deepcopy = require('deepcopy'); | ||||||
| import User from '../models/user'; | import User from '../models/user'; | ||||||
|  | import serializePost from './post'; | ||||||
| import Following from '../models/following'; | import Following from '../models/following'; | ||||||
| import getFriends from '../common/get-friends'; | import getFriends from '../common/get-friends'; | ||||||
| import config from '../../conf'; | import config from '../../conf'; | ||||||
|  | @ -116,24 +117,32 @@ export default ( | ||||||
| 		_user.is_followed = follow2 !== null; | 		_user.is_followed = follow2 !== null; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (me && !me.equals(_user.id) && opts.detail) { | 	if (opts.detail) { | ||||||
| 		const myFollowingIds = await getFriends(me); | 		if (_user.pinned_post_id) { | ||||||
|  | 			_user.pinned_post = await serializePost(_user.pinned_post_id, me, { | ||||||
|  | 				detail: true | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		// Get following you know count
 | 		if (me && !me.equals(_user.id)) { | ||||||
| 		const followingYouKnowCount = await Following.count({ | 			const myFollowingIds = await getFriends(me); | ||||||
| 			followee_id: { $in: myFollowingIds }, |  | ||||||
| 			follower_id: _user.id, |  | ||||||
| 			deleted_at: { $exists: false } |  | ||||||
| 		}); |  | ||||||
| 		_user.following_you_know_count = followingYouKnowCount; |  | ||||||
| 
 | 
 | ||||||
| 		// Get followers you know count
 | 			// Get following you know count
 | ||||||
| 		const followersYouKnowCount = await Following.count({ | 			const followingYouKnowCount = await Following.count({ | ||||||
| 			followee_id: _user.id, | 				followee_id: { $in: myFollowingIds }, | ||||||
| 			follower_id: { $in: myFollowingIds }, | 				follower_id: _user.id, | ||||||
| 			deleted_at: { $exists: false } | 				deleted_at: { $exists: false } | ||||||
| 		}); | 			}); | ||||||
| 		_user.followers_you_know_count = followersYouKnowCount; | 			_user.following_you_know_count = followingYouKnowCount; | ||||||
|  | 
 | ||||||
|  | 			// Get followers you know count
 | ||||||
|  | 			const followersYouKnowCount = await Following.count({ | ||||||
|  | 				followee_id: _user.id, | ||||||
|  | 				follower_id: { $in: myFollowingIds }, | ||||||
|  | 				deleted_at: { $exists: false } | ||||||
|  | 			}); | ||||||
|  | 			_user.followers_you_know_count = followersYouKnowCount; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	resolve(_user); | 	resolve(_user); | ||||||
|  |  | ||||||
|  | @ -28,3 +28,4 @@ require('./reaction-picker.tag'); | ||||||
| require('./reactions-viewer.tag'); | require('./reactions-viewer.tag'); | ||||||
| require('./reaction-icon.tag'); | require('./reaction-icon.tag'); | ||||||
| require('./weekly-activity-chart.tag'); | require('./weekly-activity-chart.tag'); | ||||||
|  | require('./post-menu.tag'); | ||||||
|  |  | ||||||
							
								
								
									
										134
									
								
								src/web/app/common/tags/post-menu.tag
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/web/app/common/tags/post-menu.tag
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,134 @@ | ||||||
|  | <mk-post-menu> | ||||||
|  | 	<div class="backdrop" ref="backdrop" onclick={ close }></div> | ||||||
|  | 	<div class="popover { compact: opts.compact }" ref="popover"> | ||||||
|  | 		<button if={ post.user_id === I.id } onclick={ pin }>%i18n:common.tags.mk-post-menu.pin%</button> | ||||||
|  | 	</div> | ||||||
|  | 	<style> | ||||||
|  | 		$border-color = rgba(27, 31, 35, 0.15) | ||||||
|  | 
 | ||||||
|  | 		:scope | ||||||
|  | 			display block | ||||||
|  | 			position initial | ||||||
|  | 
 | ||||||
|  | 			> .backdrop | ||||||
|  | 				position fixed | ||||||
|  | 				top 0 | ||||||
|  | 				left 0 | ||||||
|  | 				z-index 10000 | ||||||
|  | 				width 100% | ||||||
|  | 				height 100% | ||||||
|  | 				background rgba(0, 0, 0, 0.1) | ||||||
|  | 				opacity 0 | ||||||
|  | 
 | ||||||
|  | 			> .popover | ||||||
|  | 				position absolute | ||||||
|  | 				z-index 10001 | ||||||
|  | 				background #fff | ||||||
|  | 				border 1px solid $border-color | ||||||
|  | 				border-radius 4px | ||||||
|  | 				box-shadow 0 3px 12px rgba(27, 31, 35, 0.15) | ||||||
|  | 				transform scale(0.5) | ||||||
|  | 				opacity 0 | ||||||
|  | 
 | ||||||
|  | 				$balloon-size = 16px | ||||||
|  | 
 | ||||||
|  | 				&:not(.compact) | ||||||
|  | 					margin-top $balloon-size | ||||||
|  | 					transform-origin center -($balloon-size) | ||||||
|  | 
 | ||||||
|  | 					&:before | ||||||
|  | 						content "" | ||||||
|  | 						display block | ||||||
|  | 						position absolute | ||||||
|  | 						top -($balloon-size * 2) | ||||||
|  | 						left s('calc(50% - %s)', $balloon-size) | ||||||
|  | 						border-top solid $balloon-size transparent | ||||||
|  | 						border-left solid $balloon-size transparent | ||||||
|  | 						border-right solid $balloon-size transparent | ||||||
|  | 						border-bottom solid $balloon-size $border-color | ||||||
|  | 
 | ||||||
|  | 					&:after | ||||||
|  | 						content "" | ||||||
|  | 						display block | ||||||
|  | 						position absolute | ||||||
|  | 						top -($balloon-size * 2) + 1.5px | ||||||
|  | 						left s('calc(50% - %s)', $balloon-size) | ||||||
|  | 						border-top solid $balloon-size transparent | ||||||
|  | 						border-left solid $balloon-size transparent | ||||||
|  | 						border-right solid $balloon-size transparent | ||||||
|  | 						border-bottom solid $balloon-size #fff | ||||||
|  | 
 | ||||||
|  | 				> button | ||||||
|  | 					display block | ||||||
|  | 
 | ||||||
|  | 	</style> | ||||||
|  | 	<script> | ||||||
|  | 		import anime from 'animejs'; | ||||||
|  | 
 | ||||||
|  | 		this.mixin('i'); | ||||||
|  | 		this.mixin('api'); | ||||||
|  | 
 | ||||||
|  | 		this.post = this.opts.post; | ||||||
|  | 		this.source = this.opts.source; | ||||||
|  | 
 | ||||||
|  | 		this.on('mount', () => { | ||||||
|  | 			const rect = this.source.getBoundingClientRect(); | ||||||
|  | 			const width = this.refs.popover.offsetWidth; | ||||||
|  | 			const height = this.refs.popover.offsetHeight; | ||||||
|  | 			if (this.opts.compact) { | ||||||
|  | 				const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2); | ||||||
|  | 				const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2); | ||||||
|  | 				this.refs.popover.style.left = (x - (width / 2)) + 'px'; | ||||||
|  | 				this.refs.popover.style.top = (y - (height / 2)) + 'px'; | ||||||
|  | 			} else { | ||||||
|  | 				const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2); | ||||||
|  | 				const y = rect.top + window.pageYOffset + this.source.offsetHeight; | ||||||
|  | 				this.refs.popover.style.left = (x - (width / 2)) + 'px'; | ||||||
|  | 				this.refs.popover.style.top = y + 'px'; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			anime({ | ||||||
|  | 				targets: this.refs.backdrop, | ||||||
|  | 				opacity: 1, | ||||||
|  | 				duration: 100, | ||||||
|  | 				easing: 'linear' | ||||||
|  | 			}); | ||||||
|  | 
 | ||||||
|  | 			anime({ | ||||||
|  | 				targets: this.refs.popover, | ||||||
|  | 				opacity: 1, | ||||||
|  | 				scale: [0.5, 1], | ||||||
|  | 				duration: 500 | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 
 | ||||||
|  | 		this.pin = () => { | ||||||
|  | 			this.api('i/pin', { | ||||||
|  | 				post_id: this.post.id | ||||||
|  | 			}).then(() => { | ||||||
|  | 				if (this.opts.cb) this.opts.cb('pinned', '%i18n:common.tags.mk-post-menu.pinned%'); | ||||||
|  | 				this.unmount(); | ||||||
|  | 			}); | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		this.close = () => { | ||||||
|  | 			this.refs.backdrop.style.pointerEvents = 'none'; | ||||||
|  | 			anime({ | ||||||
|  | 				targets: this.refs.backdrop, | ||||||
|  | 				opacity: 0, | ||||||
|  | 				duration: 200, | ||||||
|  | 				easing: 'linear' | ||||||
|  | 			}); | ||||||
|  | 
 | ||||||
|  | 			this.refs.popover.style.pointerEvents = 'none'; | ||||||
|  | 			anime({ | ||||||
|  | 				targets: this.refs.popover, | ||||||
|  | 				opacity: 0, | ||||||
|  | 				scale: 0.5, | ||||||
|  | 				duration: 200, | ||||||
|  | 				easing: 'easeInBack', | ||||||
|  | 				complete: () => this.unmount() | ||||||
|  | 			}); | ||||||
|  | 		}; | ||||||
|  | 	</script> | ||||||
|  | </mk-post-menu> | ||||||
|  | @ -43,16 +43,18 @@ | ||||||
| 			</div> | 			</div> | ||||||
| 			<footer> | 			<footer> | ||||||
| 				<mk-reactions-viewer post={ p }/> | 				<mk-reactions-viewer post={ p }/> | ||||||
| 				<button onclick={ reply } title="返信"><i class="fa fa-reply"></i> | 				<button onclick={ reply } title="返信"> | ||||||
| 					<p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p> | 					<i class="fa fa-reply"></i><p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button onclick={ repost } title="Repost"><i class="fa fa-retweet"></i> | 				<button onclick={ repost } title="Repost"> | ||||||
| 					<p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p> | 					<i class="fa fa-retweet"></i><p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="リアクション"><i class="fa fa-plus"></i> | 				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="リアクション"> | ||||||
| 					<p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p> | 					<i class="fa fa-plus"></i><p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p> | ||||||
|  | 				</button> | ||||||
|  | 				<button onclick={ menu } ref="menuButton"> | ||||||
|  | 					<i class="fa fa-ellipsis-h"></i> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button><i class="fa fa-ellipsis-h"></i></button> |  | ||||||
| 			</footer> | 			</footer> | ||||||
| 		</article> | 		</article> | ||||||
| 		<div class="replies"> | 		<div class="replies"> | ||||||
|  | @ -315,6 +317,13 @@ | ||||||
| 			}); | 			}); | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
|  | 		this.menu = () => { | ||||||
|  | 			riot.mount(document.body.appendChild(document.createElement('mk-post-menu')), { | ||||||
|  | 				source: this.refs.menuButton, | ||||||
|  | 				post: this.p | ||||||
|  | 			}); | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
| 		this.loadContext = () => { | 		this.loadContext = () => { | ||||||
| 			this.contextFetching = true; | 			this.contextFetching = true; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -128,16 +128,16 @@ | ||||||
| 			</div> | 			</div> | ||||||
| 			<footer> | 			<footer> | ||||||
| 				<mk-reactions-viewer post={ p } ref="reactionsViewer"/> | 				<mk-reactions-viewer post={ p } ref="reactionsViewer"/> | ||||||
| 				<button onclick={ reply } title="%i18n:desktop.tags.mk-timeline-post.reply%"><i class="fa fa-reply"></i> | 				<button onclick={ reply } title="%i18n:desktop.tags.mk-timeline-post.reply%"> | ||||||
| 					<p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p> | 					<i class="fa fa-reply"></i><p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button onclick={ repost } title="%i18n:desktop.tags.mk-timeline-post.repost%"><i class="fa fa-retweet"></i> | 				<button onclick={ repost } title="%i18n:desktop.tags.mk-timeline-post.repost%"> | ||||||
| 					<p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p> | 					<i class="fa fa-retweet"></i><p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="%i18n:desktop.tags.mk-timeline-post.add-reaction%"><i class="fa fa-plus"></i> | 				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="%i18n:desktop.tags.mk-timeline-post.add-reaction%"> | ||||||
| 					<p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p> | 					<i class="fa fa-plus"></i><p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button> | 				<button onclick={ menu } ref="menuButton"> | ||||||
| 					<i class="fa fa-ellipsis-h"></i> | 					<i class="fa fa-ellipsis-h"></i> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button onclick={ toggleDetail } title="%i18n:desktop.tags.mk-timeline-post.detail"> | 				<button onclick={ toggleDetail } title="%i18n:desktop.tags.mk-timeline-post.detail"> | ||||||
|  | @ -525,6 +525,13 @@ | ||||||
| 			}); | 			}); | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
|  | 		this.menu = () => { | ||||||
|  | 			riot.mount(document.body.appendChild(document.createElement('mk-post-menu')), { | ||||||
|  | 				source: this.refs.menuButton, | ||||||
|  | 				post: this.p | ||||||
|  | 			}); | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
| 		this.toggleDetail = () => { | 		this.toggleDetail = () => { | ||||||
| 			this.update({ | 			this.update({ | ||||||
| 				isDetailOpened: !this.isDetailOpened | 				isDetailOpened: !this.isDetailOpened | ||||||
|  |  | ||||||
|  | @ -2,7 +2,9 @@ | ||||||
| 	<mk-ui ref="ui"> | 	<mk-ui ref="ui"> | ||||||
| 		<main if={ !parent.fetching }> | 		<main if={ !parent.fetching }> | ||||||
| 			<a if={ parent.post.next } href={ parent.post.next }><i class="fa fa-angle-up"></i>%i18n:mobile.tags.mk-post-page.next%</a> | 			<a if={ parent.post.next } href={ parent.post.next }><i class="fa fa-angle-up"></i>%i18n:mobile.tags.mk-post-page.next%</a> | ||||||
| 			<mk-post-detail ref="post" post={ parent.post }/> | 			<div> | ||||||
|  | 				<mk-post-detail ref="post" post={ parent.post }/> | ||||||
|  | 			</div> | ||||||
| 			<a if={ parent.post.prev } href={ parent.post.prev }><i class="fa fa-angle-down"></i>%i18n:mobile.tags.mk-post-page.prev%</a> | 			<a if={ parent.post.prev } href={ parent.post.prev }><i class="fa fa-angle-down"></i>%i18n:mobile.tags.mk-post-page.prev%</a> | ||||||
| 		</main> | 		</main> | ||||||
| 	</mk-ui> | 	</mk-ui> | ||||||
|  | @ -13,6 +15,16 @@ | ||||||
| 			main | 			main | ||||||
| 				text-align center | 				text-align center | ||||||
| 
 | 
 | ||||||
|  | 				> div | ||||||
|  | 					margin 8px auto | ||||||
|  | 					padding 0 | ||||||
|  | 					max-width 500px | ||||||
|  | 					width calc(100% - 16px) | ||||||
|  | 
 | ||||||
|  | 					@media (min-width 500px) | ||||||
|  | 						margin 16px auto | ||||||
|  | 						width calc(100% - 32px) | ||||||
|  | 
 | ||||||
| 				> a | 				> a | ||||||
| 					display inline-block | 					display inline-block | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -38,24 +38,26 @@ | ||||||
| 			</div> | 			</div> | ||||||
| 			<mk-poll if={ p.poll } post={ p }/> | 			<mk-poll if={ p.poll } post={ p }/> | ||||||
| 		</div> | 		</div> | ||||||
| 		<a class="time" href={ url }> | 		<a class="time" href={ '/' + p.user.username + '/' + p.id }> | ||||||
| 			<mk-time time={ p.created_at } mode="detail"/> | 			<mk-time time={ p.created_at } mode="detail"/> | ||||||
| 		</a> | 		</a> | ||||||
| 		<footer> | 		<footer> | ||||||
| 			<mk-reactions-viewer post={ p }/> | 			<mk-reactions-viewer post={ p }/> | ||||||
| 			<button onclick={ reply } title="%i18n:mobile.tags.mk-post-detail.reply%"><i class="fa fa-reply"></i> | 			<button onclick={ reply } title="%i18n:mobile.tags.mk-post-detail.reply%"> | ||||||
| 				<p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p> | 				<i class="fa fa-reply"></i><p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p> | ||||||
| 			</button> | 			</button> | ||||||
| 			<button onclick={ repost } title="Repost"><i class="fa fa-retweet"></i> | 			<button onclick={ repost } title="Repost"> | ||||||
| 				<p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p> | 				<i class="fa fa-retweet"></i><p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p> | ||||||
| 			</button> | 			</button> | ||||||
| 			<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="%i18n:mobile.tags.mk-post-detail.reaction%"><i class="fa fa-plus"></i> | 			<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton" title="%i18n:mobile.tags.mk-post-detail.reaction%"> | ||||||
| 				<p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p> | 				<i class="fa fa-plus"></i><p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p> | ||||||
|  | 			</button> | ||||||
|  | 			<button onclick={ menu } ref="menuButton"> | ||||||
|  | 				<i class="fa fa-ellipsis-h"></i> | ||||||
| 			</button> | 			</button> | ||||||
| 			<button><i class="fa fa-ellipsis-h"></i></button> |  | ||||||
| 		</footer> | 		</footer> | ||||||
| 	</article> | 	</article> | ||||||
| 	<div class="replies"> | 	<div class="replies" if={ !compact }> | ||||||
| 		<virtual each={ post in replies }> | 		<virtual each={ post in replies }> | ||||||
| 			<mk-post-detail-sub post={ post }/> | 			<mk-post-detail-sub post={ post }/> | ||||||
| 		</virtual> | 		</virtual> | ||||||
|  | @ -64,19 +66,14 @@ | ||||||
| 		:scope | 		:scope | ||||||
| 			display block | 			display block | ||||||
| 			overflow hidden | 			overflow hidden | ||||||
| 			margin 8px auto | 			margin 0 auto | ||||||
| 			padding 0 | 			padding 0 | ||||||
| 			max-width 500px | 			width 100% | ||||||
| 			width calc(100% - 16px) |  | ||||||
| 			text-align left | 			text-align left | ||||||
| 			background #fff | 			background #fff | ||||||
| 			border-radius 8px | 			border-radius 8px | ||||||
| 			box-shadow 0 0 0 1px rgba(0, 0, 0, 0.2) | 			box-shadow 0 0 0 1px rgba(0, 0, 0, 0.2) | ||||||
| 
 | 
 | ||||||
| 			@media (min-width 500px) |  | ||||||
| 				margin 16px auto |  | ||||||
| 				width calc(100% - 32px) |  | ||||||
| 
 |  | ||||||
| 			> .fetching | 			> .fetching | ||||||
| 				padding 64px 0 | 				padding 64px 0 | ||||||
| 
 | 
 | ||||||
|  | @ -269,6 +266,7 @@ | ||||||
| 
 | 
 | ||||||
| 		this.mixin('api'); | 		this.mixin('api'); | ||||||
| 
 | 
 | ||||||
|  | 		this.compact = this.opts.compact; | ||||||
| 		this.post = this.opts.post; | 		this.post = this.opts.post; | ||||||
| 		this.isRepost = this.post.repost != null; | 		this.isRepost = this.post.repost != null; | ||||||
| 		this.p = this.isRepost ? this.post.repost : this.post; | 		this.p = this.isRepost ? this.post.repost : this.post; | ||||||
|  | @ -299,14 +297,16 @@ | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			// Get replies | 			// Get replies | ||||||
| 			this.api('posts/replies', { | 			if (!this.compact) { | ||||||
| 				post_id: this.p.id, | 				this.api('posts/replies', { | ||||||
| 				limit: 8 | 					post_id: this.p.id, | ||||||
| 			}).then(replies => { | 					limit: 8 | ||||||
| 				this.update({ | 				}).then(replies => { | ||||||
| 					replies: replies | 					this.update({ | ||||||
|  | 						replies: replies | ||||||
|  | 					}); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			} | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		this.reply = () => { | 		this.reply = () => { | ||||||
|  | @ -332,6 +332,14 @@ | ||||||
| 			}); | 			}); | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
|  | 		this.menu = () => { | ||||||
|  | 			riot.mount(document.body.appendChild(document.createElement('mk-post-menu')), { | ||||||
|  | 				source: this.refs.menuButton, | ||||||
|  | 				post: this.p, | ||||||
|  | 				compact: true | ||||||
|  | 			}); | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
| 		this.loadContext = () => { | 		this.loadContext = () => { | ||||||
| 			this.contextFetching = true; | 			this.contextFetching = true; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -181,14 +181,17 @@ | ||||||
| 			</div> | 			</div> | ||||||
| 			<footer> | 			<footer> | ||||||
| 				<mk-reactions-viewer post={ p } ref="reactionsViewer"/> | 				<mk-reactions-viewer post={ p } ref="reactionsViewer"/> | ||||||
| 				<button onclick={ reply }><i class="fa fa-reply"></i> | 				<button onclick={ reply }> | ||||||
| 					<p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p> | 					<i class="fa fa-reply"></i><p class="count" if={ p.replies_count > 0 }>{ p.replies_count }</p> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button onclick={ repost } title="Repost"><i class="fa fa-retweet"></i> | 				<button onclick={ repost } title="Repost"> | ||||||
| 					<p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p> | 					<i class="fa fa-retweet"></i><p class="count" if={ p.repost_count > 0 }>{ p.repost_count }</p> | ||||||
| 				</button> | 				</button> | ||||||
| 				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton"><i class="fa fa-plus"></i> | 				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton"> | ||||||
| 					<p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p> | 					<i class="fa fa-plus"></i><p class="count" if={ p.reactions_count > 0 }>{ p.reactions_count }</p> | ||||||
|  | 				</button> | ||||||
|  | 				<button class={ reacted: p.my_reaction != null } onclick={ react } ref="reactButton"> | ||||||
|  | 					<i class="fa fa-ellipsis-h"></i> | ||||||
| 				</button> | 				</button> | ||||||
| 			</footer> | 			</footer> | ||||||
| 		</div> | 		</div> | ||||||
|  | @ -558,6 +561,14 @@ | ||||||
| 				compact: true | 				compact: true | ||||||
| 			}); | 			}); | ||||||
| 		}; | 		}; | ||||||
|  | 
 | ||||||
|  | 		this.menu = () => { | ||||||
|  | 			riot.mount(document.body.appendChild(document.createElement('mk-post-menu')), { | ||||||
|  | 				source: this.refs.menuButton, | ||||||
|  | 				post: this.p, | ||||||
|  | 				compact: true | ||||||
|  | 			}); | ||||||
|  | 		}; | ||||||
| 	</script> | 	</script> | ||||||
| </mk-timeline-post> | </mk-timeline-post> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -215,6 +215,7 @@ | ||||||
| </mk-user> | </mk-user> | ||||||
| 
 | 
 | ||||||
| <mk-user-overview> | <mk-user-overview> | ||||||
|  | 	<mk-post-detail if={ user.pinned_post } post={ user.pinned_post } compact={ true }/> | ||||||
| 	<section class="recent-posts"> | 	<section class="recent-posts"> | ||||||
| 		<h2><i class="fa fa-comments-o"></i>%i18n:mobile.tags.mk-user-overview.recent-posts%</h2> | 		<h2><i class="fa fa-comments-o"></i>%i18n:mobile.tags.mk-user-overview.recent-posts%</h2> | ||||||
| 		<div> | 		<div> | ||||||
|  | @ -240,6 +241,9 @@ | ||||||
| 			max-width 600px | 			max-width 600px | ||||||
| 			margin 0 auto | 			margin 0 auto | ||||||
| 
 | 
 | ||||||
|  | 			> mk-post-detail | ||||||
|  | 				margin 0 0 8px 0 | ||||||
|  | 
 | ||||||
| 			> section | 			> section | ||||||
| 				background #eee | 				background #eee | ||||||
| 				border-radius 8px | 				border-radius 8px | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue