wip
This commit is contained in:
		
							parent
							
								
									43d9d81b53
								
							
						
					
					
						commit
						4980b86d64
					
				
					 18 changed files with 761 additions and 771 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<mk-index>
 | 
			
		||||
	<main v-if="SIGNIN">
 | 
			
		||||
	<main v-if="$root.$data.os.isSignedIn">
 | 
			
		||||
		<p class="fetching" v-if="fetching">読み込み中<mk-ellipsis/></p>
 | 
			
		||||
		<mk-form ref="form" v-if="state == 'waiting'" session={ session }/>
 | 
			
		||||
		<div class="denied" v-if="state == 'denied'">
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,7 @@
 | 
			
		|||
			<p>セッションが存在しません。</p>
 | 
			
		||||
		</div>
 | 
			
		||||
	</main>
 | 
			
		||||
	<main class="signin" v-if="!SIGNIN">
 | 
			
		||||
	<main class="signin" v-if="!$root.$data.os.isSignedIn">
 | 
			
		||||
		<h1>サインインしてください</h1>
 | 
			
		||||
		<mk-signin/>
 | 
			
		||||
	</main>
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +93,7 @@
 | 
			
		|||
		this.token = window.location.href.split('/').pop();
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			if (!this.SIGNIN) return;
 | 
			
		||||
			if (!this.$root.$data.os.isSignedIn) return;
 | 
			
		||||
 | 
			
		||||
			// Fetch session
 | 
			
		||||
			this.$root.$data.os.api('auth/session/show', {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
	<main v-if="!fetching">
 | 
			
		||||
		<h1>{ channel.title }</h1>
 | 
			
		||||
 | 
			
		||||
		<div v-if="SIGNIN">
 | 
			
		||||
		<div v-if="$root.$data.os.isSignedIn">
 | 
			
		||||
			<p v-if="channel.is_watching">このチャンネルをウォッチしています <a @click="unwatch">ウォッチ解除</a></p>
 | 
			
		||||
			<p v-if="!channel.is_watching"><a @click="watch">このチャンネルをウォッチする</a></p>
 | 
			
		||||
		</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -24,8 +24,8 @@
 | 
			
		|||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<hr>
 | 
			
		||||
		<mk-channel-form v-if="SIGNIN" channel={ channel } ref="form"/>
 | 
			
		||||
		<div v-if="!SIGNIN">
 | 
			
		||||
		<mk-channel-form v-if="$root.$data.os.isSignedIn" channel={ channel } ref="form"/>
 | 
			
		||||
		<div v-if="!$root.$data.os.isSignedIn">
 | 
			
		||||
			<p>参加するには<a href={ _URL_ }>ログインまたは新規登録</a>してください</p>
 | 
			
		||||
		</div>
 | 
			
		||||
		<hr>
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +125,7 @@
 | 
			
		|||
			this.posts.unshift(post);
 | 
			
		||||
			this.update();
 | 
			
		||||
 | 
			
		||||
			if (document.hidden && this.SIGNIN && post.user_id !== this.$root.$data.os.i.id) {
 | 
			
		||||
			if (document.hidden && this.$root.$data.os.isSignedIn && post.user_id !== this.$root.$data.os.i.id) {
 | 
			
		||||
				this.unreadCount++;
 | 
			
		||||
				document.title = `(${this.unreadCount}) ${this.channel.title} | Misskey`;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,8 @@
 | 
			
		|||
		<a href={ _CH_URL_ }>Index</a> | <a href={ _URL_ }>Misskey</a>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div>
 | 
			
		||||
		<a v-if="!SIGNIN" href={ _URL_ }>ログイン(新規登録)</a>
 | 
			
		||||
		<a v-if="SIGNIN" href={ _URL_ + '/' + I.username }>{ I.username }</a>
 | 
			
		||||
		<a v-if="!$root.$data.os.isSignedIn" href={ _URL_ }>ログイン(新規登録)</a>
 | 
			
		||||
		<a v-if="$root.$data.os.isSignedIn" href={ _URL_ + '/' + I.username }>{ I.username }</a>
 | 
			
		||||
	</div>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
				<p>フォロワー</p><a>{ user.followers_count }</a>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<mk-follow-button v-if="SIGNIN && user.id != I.id" user={ userPromise }/>
 | 
			
		||||
		<mk-follow-button v-if="$root.$data.os.isSignedIn && user.id != I.id" user={ userPromise }/>
 | 
			
		||||
	</template>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
	<nav>
 | 
			
		||||
		<div>
 | 
			
		||||
			<span data-is-active={ mode == 'all' } @click="setMode.bind(this, 'all')">すべて<span>{ opts.count }</span></span>
 | 
			
		||||
			<span v-if="SIGNIN && opts.youKnowCount" data-is-active={ mode == 'iknow' } @click="setMode.bind(this, 'iknow')">知り合い<span>{ opts.youKnowCount }</span></span>
 | 
			
		||||
			<span v-if="$root.$data.os.isSignedIn && opts.youKnowCount" data-is-active={ mode == 'iknow' } @click="setMode.bind(this, 'iknow')">知り合い<span>{ opts.youKnowCount }</span></span>
 | 
			
		||||
		</div>
 | 
			
		||||
	</nav>
 | 
			
		||||
	<div class="users" v-if="!fetching && users.length != 0">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,23 +0,0 @@
 | 
			
		|||
<mk-home>
 | 
			
		||||
	<mk-home-timeline ref="tl"/>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> mk-home-timeline
 | 
			
		||||
				max-width 600px
 | 
			
		||||
				margin 0 auto
 | 
			
		||||
				padding 8px
 | 
			
		||||
 | 
			
		||||
			@media (min-width 500px)
 | 
			
		||||
				padding 16px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.$refs.tl.on('loaded', () => {
 | 
			
		||||
				this.$emit('loaded');
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-home>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,735 +0,0 @@
 | 
			
		|||
<mk-user>
 | 
			
		||||
	<div class="user" v-if="!fetching">
 | 
			
		||||
		<header>
 | 
			
		||||
			<div class="banner" style={ user.banner_url ? 'background-image: url(' + user.banner_url + '?thumbnail&size=1024)' : '' }></div>
 | 
			
		||||
			<div class="body">
 | 
			
		||||
				<div class="top">
 | 
			
		||||
					<a class="avatar">
 | 
			
		||||
						<img src={ user.avatar_url + '?thumbnail&size=200' } alt="avatar"/>
 | 
			
		||||
					</a>
 | 
			
		||||
					<mk-follow-button v-if="SIGNIN && I.id != user.id" user={ user }/>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="title">
 | 
			
		||||
					<h1>{ user.name }</h1>
 | 
			
		||||
					<span class="username">@{ user.username }</span>
 | 
			
		||||
					<span class="followed" v-if="user.is_followed">%i18n:mobile.tags.mk-user.follows-you%</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="description">{ user.description }</div>
 | 
			
		||||
				<div class="info">
 | 
			
		||||
					<p class="location" v-if="user.profile.location">
 | 
			
		||||
						%fa:map-marker%{ user.profile.location }
 | 
			
		||||
					</p>
 | 
			
		||||
					<p class="birthday" v-if="user.profile.birthday">
 | 
			
		||||
						%fa:birthday-cake%{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' } ({ age(user.profile.birthday) }歳)
 | 
			
		||||
					</p>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="status">
 | 
			
		||||
				  <a>
 | 
			
		||||
				    <b>{ user.posts_count }</b>
 | 
			
		||||
						<i>%i18n:mobile.tags.mk-user.posts%</i>
 | 
			
		||||
					</a>
 | 
			
		||||
					<a href="{ user.username }/following">
 | 
			
		||||
						<b>{ user.following_count }</b>
 | 
			
		||||
						<i>%i18n:mobile.tags.mk-user.following%</i>
 | 
			
		||||
					</a>
 | 
			
		||||
					<a href="{ user.username }/followers">
 | 
			
		||||
						<b>{ user.followers_count }</b>
 | 
			
		||||
						<i>%i18n:mobile.tags.mk-user.followers%</i>
 | 
			
		||||
					</a>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<nav>
 | 
			
		||||
				<a data-is-active={ page == 'overview' } @click="go.bind(null, 'overview')">%i18n:mobile.tags.mk-user.overview%</a>
 | 
			
		||||
				<a data-is-active={ page == 'posts' } @click="go.bind(null, 'posts')">%i18n:mobile.tags.mk-user.timeline%</a>
 | 
			
		||||
				<a data-is-active={ page == 'media' } @click="go.bind(null, 'media')">%i18n:mobile.tags.mk-user.media%</a>
 | 
			
		||||
			</nav>
 | 
			
		||||
		</header>
 | 
			
		||||
		<div class="body">
 | 
			
		||||
			<mk-user-overview v-if="page == 'overview'" user={ user }/>
 | 
			
		||||
			<mk-user-timeline v-if="page == 'posts'" user={ user }/>
 | 
			
		||||
			<mk-user-timeline v-if="page == 'media'" user={ user } with-media={ true }/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> .user
 | 
			
		||||
				> header
 | 
			
		||||
					box-shadow 0 4px 4px rgba(0, 0, 0, 0.3)
 | 
			
		||||
 | 
			
		||||
					> .banner
 | 
			
		||||
						padding-bottom 33.3%
 | 
			
		||||
						background-color #1b1b1b
 | 
			
		||||
						background-size cover
 | 
			
		||||
						background-position center
 | 
			
		||||
 | 
			
		||||
					> .body
 | 
			
		||||
						padding 12px
 | 
			
		||||
						margin 0 auto
 | 
			
		||||
						max-width 600px
 | 
			
		||||
 | 
			
		||||
						> .top
 | 
			
		||||
							&:after
 | 
			
		||||
								content ''
 | 
			
		||||
								display block
 | 
			
		||||
								clear both
 | 
			
		||||
 | 
			
		||||
							> .avatar
 | 
			
		||||
								display block
 | 
			
		||||
								float left
 | 
			
		||||
								width 25%
 | 
			
		||||
								height 40px
 | 
			
		||||
 | 
			
		||||
								> img
 | 
			
		||||
									display block
 | 
			
		||||
									position absolute
 | 
			
		||||
									left -2px
 | 
			
		||||
									bottom -2px
 | 
			
		||||
									width 100%
 | 
			
		||||
									border 2px solid #313a42
 | 
			
		||||
									border-radius 6px
 | 
			
		||||
 | 
			
		||||
									@media (min-width 500px)
 | 
			
		||||
										left -4px
 | 
			
		||||
										bottom -4px
 | 
			
		||||
										border 4px solid #313a42
 | 
			
		||||
										border-radius 12px
 | 
			
		||||
 | 
			
		||||
							> mk-follow-button
 | 
			
		||||
								float right
 | 
			
		||||
								height 40px
 | 
			
		||||
 | 
			
		||||
						> .title
 | 
			
		||||
							margin 8px 0
 | 
			
		||||
 | 
			
		||||
							> h1
 | 
			
		||||
								margin 0
 | 
			
		||||
								line-height 22px
 | 
			
		||||
								font-size 20px
 | 
			
		||||
								color #fff
 | 
			
		||||
 | 
			
		||||
							> .username
 | 
			
		||||
								display inline-block
 | 
			
		||||
								line-height 20px
 | 
			
		||||
								font-size 16px
 | 
			
		||||
								font-weight bold
 | 
			
		||||
								color #657786
 | 
			
		||||
 | 
			
		||||
							> .followed
 | 
			
		||||
								margin-left 8px
 | 
			
		||||
								padding 2px 4px
 | 
			
		||||
								font-size 12px
 | 
			
		||||
								color #657786
 | 
			
		||||
								background #f8f8f8
 | 
			
		||||
								border-radius 4px
 | 
			
		||||
 | 
			
		||||
						> .description
 | 
			
		||||
							margin 8px 0
 | 
			
		||||
							color #fff
 | 
			
		||||
 | 
			
		||||
						> .info
 | 
			
		||||
							margin 8px 0
 | 
			
		||||
 | 
			
		||||
							> p
 | 
			
		||||
								display inline
 | 
			
		||||
								margin 0 16px 0 0
 | 
			
		||||
								color #a9b9c1
 | 
			
		||||
 | 
			
		||||
								> i
 | 
			
		||||
									margin-right 4px
 | 
			
		||||
 | 
			
		||||
						> .status
 | 
			
		||||
							> a
 | 
			
		||||
								color #657786
 | 
			
		||||
 | 
			
		||||
								&:not(:last-child)
 | 
			
		||||
									margin-right 16px
 | 
			
		||||
 | 
			
		||||
								> b
 | 
			
		||||
									margin-right 4px
 | 
			
		||||
									font-size 16px
 | 
			
		||||
									color #fff
 | 
			
		||||
 | 
			
		||||
								> i
 | 
			
		||||
									font-size 14px
 | 
			
		||||
 | 
			
		||||
						> mk-activity-table
 | 
			
		||||
							margin 12px 0 0 0
 | 
			
		||||
 | 
			
		||||
					> nav
 | 
			
		||||
						display flex
 | 
			
		||||
						justify-content center
 | 
			
		||||
						margin 0 auto
 | 
			
		||||
						max-width 600px
 | 
			
		||||
 | 
			
		||||
						> a
 | 
			
		||||
							display block
 | 
			
		||||
							flex 1 1
 | 
			
		||||
							text-align center
 | 
			
		||||
							line-height 52px
 | 
			
		||||
							font-size 14px
 | 
			
		||||
							text-decoration none
 | 
			
		||||
							color #657786
 | 
			
		||||
							border-bottom solid 2px transparent
 | 
			
		||||
 | 
			
		||||
							&[data-is-active]
 | 
			
		||||
								font-weight bold
 | 
			
		||||
								color $theme-color
 | 
			
		||||
								border-color $theme-color
 | 
			
		||||
 | 
			
		||||
				> .body
 | 
			
		||||
					padding 8px
 | 
			
		||||
 | 
			
		||||
					@media (min-width 500px)
 | 
			
		||||
						padding 16px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.age = require('s-age');
 | 
			
		||||
 | 
			
		||||
		this.mixin('i');
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		this.username = this.opts.user;
 | 
			
		||||
		this.page = this.opts.page ? this.opts.page : 'overview';
 | 
			
		||||
		this.fetching = true;
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.$root.$data.os.api('users/show', {
 | 
			
		||||
				username: this.username
 | 
			
		||||
			}).then(user => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.user = user;
 | 
			
		||||
				this.$emit('loaded', user);
 | 
			
		||||
				this.update();
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.go = page => {
 | 
			
		||||
			this.update({
 | 
			
		||||
				page: page
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview>
 | 
			
		||||
	<mk-post-detail v-if="user.pinned_post" post={ user.pinned_post } compact={ true }/>
 | 
			
		||||
	<section class="recent-posts">
 | 
			
		||||
		<h2>%fa:R comments%%i18n:mobile.tags.mk-user-overview.recent-posts%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-overview-posts user={ user }/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="images">
 | 
			
		||||
		<h2>%fa:image%%i18n:mobile.tags.mk-user-overview.images%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-overview-photos user={ user }/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="activity">
 | 
			
		||||
		<h2>%fa:chart-bar%%i18n:mobile.tags.mk-user-overview.activity%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-overview-activity-chart user={ user }/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="keywords">
 | 
			
		||||
		<h2>%fa:R comment%%i18n:mobile.tags.mk-user-overview.keywords%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-overview-keywords user={ user }/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="domains">
 | 
			
		||||
		<h2>%fa:globe%%i18n:mobile.tags.mk-user-overview.domains%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-overview-domains user={ user }/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="frequently-replied-users">
 | 
			
		||||
		<h2>%fa:users%%i18n:mobile.tags.mk-user-overview.frequently-replied-users%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-overview-frequently-replied-users user={ user }/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="followers-you-know" v-if="SIGNIN && I.id !== user.id">
 | 
			
		||||
		<h2>%fa:users%%i18n:mobile.tags.mk-user-overview.followers-you-know%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-overview-followers-you-know user={ user }/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<p>%i18n:mobile.tags.mk-user-overview.last-used-at%: <b><mk-time time={ user.last_used_at }/></b></p>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
			max-width 600px
 | 
			
		||||
			margin 0 auto
 | 
			
		||||
 | 
			
		||||
			> mk-post-detail
 | 
			
		||||
				margin 0 0 8px 0
 | 
			
		||||
 | 
			
		||||
			> section
 | 
			
		||||
				background #eee
 | 
			
		||||
				border-radius 8px
 | 
			
		||||
				box-shadow 0 0 0 1px rgba(0, 0, 0, 0.2)
 | 
			
		||||
 | 
			
		||||
				&:not(:last-child)
 | 
			
		||||
					margin-bottom 8px
 | 
			
		||||
 | 
			
		||||
				> h2
 | 
			
		||||
					margin 0
 | 
			
		||||
					padding 8px 10px
 | 
			
		||||
					font-size 15px
 | 
			
		||||
					font-weight normal
 | 
			
		||||
					color #465258
 | 
			
		||||
					background #fff
 | 
			
		||||
					border-radius 8px 8px 0 0
 | 
			
		||||
 | 
			
		||||
					> i
 | 
			
		||||
						margin-right 6px
 | 
			
		||||
 | 
			
		||||
			> .activity
 | 
			
		||||
				> div
 | 
			
		||||
					padding 8px
 | 
			
		||||
 | 
			
		||||
			> p
 | 
			
		||||
				display block
 | 
			
		||||
				margin 16px
 | 
			
		||||
				text-align center
 | 
			
		||||
				color #cad2da
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.mixin('i');
 | 
			
		||||
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview-posts>
 | 
			
		||||
	<p class="initializing" v-if="initializing">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-posts.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div v-if="!initializing && posts.length > 0">
 | 
			
		||||
		<template each={ posts }>
 | 
			
		||||
			<mk-user-overview-posts-post-card post={ this }/>
 | 
			
		||||
		</template>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!initializing && posts.length == 0">%i18n:mobile.tags.mk-user-overview-posts.no-posts%</p>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> div
 | 
			
		||||
				overflow-x scroll
 | 
			
		||||
				-webkit-overflow-scrolling touch
 | 
			
		||||
				white-space nowrap
 | 
			
		||||
				padding 8px
 | 
			
		||||
 | 
			
		||||
				> *
 | 
			
		||||
					vertical-align top
 | 
			
		||||
 | 
			
		||||
					&:not(:last-child)
 | 
			
		||||
						margin-right 8px
 | 
			
		||||
 | 
			
		||||
			> .initializing
 | 
			
		||||
			> .empty
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 16px
 | 
			
		||||
				text-align center
 | 
			
		||||
				color #aaa
 | 
			
		||||
 | 
			
		||||
				> i
 | 
			
		||||
					margin-right 4px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
		this.initializing = true;
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.$root.$data.os.api('users/posts', {
 | 
			
		||||
				user_id: this.user.id
 | 
			
		||||
			}).then(posts => {
 | 
			
		||||
				this.update({
 | 
			
		||||
					posts: posts,
 | 
			
		||||
					initializing: false
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview-posts>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview-posts-post-card>
 | 
			
		||||
	<a href={ '/' + post.user.username + '/' + post.id }>
 | 
			
		||||
		<header>
 | 
			
		||||
			<img src={ post.user.avatar_url + '?thumbnail&size=64' } alt="avatar"/><h3>{ post.user.name }</h3>
 | 
			
		||||
		</header>
 | 
			
		||||
		<div>
 | 
			
		||||
			{ text }
 | 
			
		||||
		</div>
 | 
			
		||||
		<mk-time time={ post.created_at }/>
 | 
			
		||||
	</a>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display inline-block
 | 
			
		||||
			width 150px
 | 
			
		||||
			//height 120px
 | 
			
		||||
			font-size 12px
 | 
			
		||||
			background #fff
 | 
			
		||||
			border-radius 4px
 | 
			
		||||
 | 
			
		||||
			> a
 | 
			
		||||
				display block
 | 
			
		||||
				color #2c3940
 | 
			
		||||
 | 
			
		||||
				&:hover
 | 
			
		||||
					text-decoration none
 | 
			
		||||
 | 
			
		||||
				> header
 | 
			
		||||
					> img
 | 
			
		||||
						position absolute
 | 
			
		||||
						top 8px
 | 
			
		||||
						left 8px
 | 
			
		||||
						width 28px
 | 
			
		||||
						height 28px
 | 
			
		||||
						border-radius 6px
 | 
			
		||||
 | 
			
		||||
					> h3
 | 
			
		||||
						display inline-block
 | 
			
		||||
						overflow hidden
 | 
			
		||||
						width calc(100% - 45px)
 | 
			
		||||
						margin 8px 0 0 42px
 | 
			
		||||
						line-height 28px
 | 
			
		||||
						white-space nowrap
 | 
			
		||||
						text-overflow ellipsis
 | 
			
		||||
						font-size 12px
 | 
			
		||||
 | 
			
		||||
				> div
 | 
			
		||||
					padding 2px 8px 8px 8px
 | 
			
		||||
					height 60px
 | 
			
		||||
					overflow hidden
 | 
			
		||||
					white-space normal
 | 
			
		||||
 | 
			
		||||
					&:after
 | 
			
		||||
						content ""
 | 
			
		||||
						display block
 | 
			
		||||
						position absolute
 | 
			
		||||
						top 40px
 | 
			
		||||
						left 0
 | 
			
		||||
						width 100%
 | 
			
		||||
						height 20px
 | 
			
		||||
						background linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 100%)
 | 
			
		||||
 | 
			
		||||
				> mk-time
 | 
			
		||||
					display inline-block
 | 
			
		||||
					padding 8px
 | 
			
		||||
					color #aaa
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		import summary from '../../../../common/get-post-summary.ts';
 | 
			
		||||
 | 
			
		||||
		this.post = this.opts.post;
 | 
			
		||||
		this.text = summary(this.post);
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview-posts-post-card>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview-photos>
 | 
			
		||||
	<p class="initializing" v-if="initializing">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-photos.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div class="stream" v-if="!initializing && images.length > 0">
 | 
			
		||||
		<template each={ image in images }>
 | 
			
		||||
			<a class="img" style={ 'background-image: url(' + image.media.url + '?thumbnail&size=256)' } href={ '/' + image.post.user.username + '/' + image.post.id }></a>
 | 
			
		||||
		</template>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!initializing && images.length == 0">%i18n:mobile.tags.mk-user-overview-photos.no-photos%</p>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> .stream
 | 
			
		||||
				display -webkit-flex
 | 
			
		||||
				display -moz-flex
 | 
			
		||||
				display -ms-flex
 | 
			
		||||
				display flex
 | 
			
		||||
				justify-content center
 | 
			
		||||
				flex-wrap wrap
 | 
			
		||||
				padding 8px
 | 
			
		||||
 | 
			
		||||
				> .img
 | 
			
		||||
					flex 1 1 33%
 | 
			
		||||
					width 33%
 | 
			
		||||
					height 80px
 | 
			
		||||
					background-position center center
 | 
			
		||||
					background-size cover
 | 
			
		||||
					background-clip content-box
 | 
			
		||||
					border solid 2px transparent
 | 
			
		||||
					border-radius 4px
 | 
			
		||||
 | 
			
		||||
			> .initializing
 | 
			
		||||
			> .empty
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 16px
 | 
			
		||||
				text-align center
 | 
			
		||||
				color #aaa
 | 
			
		||||
 | 
			
		||||
				> i
 | 
			
		||||
					margin-right 4px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		this.images = [];
 | 
			
		||||
		this.initializing = true;
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.$root.$data.os.api('users/posts', {
 | 
			
		||||
				user_id: this.user.id,
 | 
			
		||||
				with_media: true,
 | 
			
		||||
				limit: 6
 | 
			
		||||
			}).then(posts => {
 | 
			
		||||
				this.initializing = false;
 | 
			
		||||
				posts.forEach(post => {
 | 
			
		||||
					post.media.forEach(media => {
 | 
			
		||||
						if (this.images.length < 9) this.images.push({
 | 
			
		||||
							post,
 | 
			
		||||
							media
 | 
			
		||||
						});
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
				this.update();
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview-photos>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview-activity-chart>
 | 
			
		||||
	<svg v-if="data" ref="canvas" viewBox="0 0 30 1" preserveAspectRatio="none">
 | 
			
		||||
		<g each={ d, i in data.reverse() }>
 | 
			
		||||
			<rect width="0.8" riot-height={ d.postsH }
 | 
			
		||||
				riot-x={ i + 0.1 } riot-y={ 1 - d.postsH - d.repliesH - d.repostsH }
 | 
			
		||||
				fill="#41ddde"/>
 | 
			
		||||
			<rect width="0.8" riot-height={ d.repliesH }
 | 
			
		||||
				riot-x={ i + 0.1 } riot-y={ 1 - d.repliesH - d.repostsH }
 | 
			
		||||
				fill="#f7796c"/>
 | 
			
		||||
			<rect width="0.8" riot-height={ d.repostsH }
 | 
			
		||||
				riot-x={ i + 0.1 } riot-y={ 1 - d.repostsH }
 | 
			
		||||
				fill="#a1de41"/>
 | 
			
		||||
			</g>
 | 
			
		||||
	</svg>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
			max-width 600px
 | 
			
		||||
			margin 0 auto
 | 
			
		||||
 | 
			
		||||
			> svg
 | 
			
		||||
				display block
 | 
			
		||||
				width 100%
 | 
			
		||||
				height 80px
 | 
			
		||||
 | 
			
		||||
				> rect
 | 
			
		||||
					transform-origin center
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.$root.$data.os.api('aggregation/users/activity', {
 | 
			
		||||
				user_id: this.user.id,
 | 
			
		||||
				limit: 30
 | 
			
		||||
			}).then(data => {
 | 
			
		||||
				data.forEach(d => d.total = d.posts + d.replies + d.reposts);
 | 
			
		||||
				this.peak = Math.max.apply(null, data.map(d => d.total));
 | 
			
		||||
				data.forEach(d => {
 | 
			
		||||
					d.postsH = d.posts / this.peak;
 | 
			
		||||
					d.repliesH = d.replies / this.peak;
 | 
			
		||||
					d.repostsH = d.reposts / this.peak;
 | 
			
		||||
				});
 | 
			
		||||
				this.update({ data });
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview-activity-chart>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview-keywords>
 | 
			
		||||
	<div v-if="user.keywords != null && user.keywords.length > 1">
 | 
			
		||||
		<template each={ keyword in user.keywords }>
 | 
			
		||||
			<a>{ keyword }</a>
 | 
			
		||||
		</template>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="user.keywords == null || user.keywords.length == 0">%i18n:mobile.tags.mk-user-overview-keywords.no-keywords%</p>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> div
 | 
			
		||||
				padding 4px
 | 
			
		||||
 | 
			
		||||
				> a
 | 
			
		||||
					display inline-block
 | 
			
		||||
					margin 4px
 | 
			
		||||
					color #555
 | 
			
		||||
 | 
			
		||||
			> .empty
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 16px
 | 
			
		||||
				text-align center
 | 
			
		||||
				color #aaa
 | 
			
		||||
 | 
			
		||||
				> i
 | 
			
		||||
					margin-right 4px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview-keywords>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview-domains>
 | 
			
		||||
	<div v-if="user.domains != null && user.domains.length > 1">
 | 
			
		||||
		<template each={ domain in user.domains }>
 | 
			
		||||
			<a style="opacity: { 0.5 + (domain.weight / 2) }">{ domain.domain }</a>
 | 
			
		||||
		</template>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="user.domains == null || user.domains.length == 0">%i18n:mobile.tags.mk-user-overview-domains.no-domains%</p>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> div
 | 
			
		||||
				padding 4px
 | 
			
		||||
 | 
			
		||||
				> a
 | 
			
		||||
					display inline-block
 | 
			
		||||
					margin 4px
 | 
			
		||||
					color #555
 | 
			
		||||
 | 
			
		||||
			> .empty
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 16px
 | 
			
		||||
				text-align center
 | 
			
		||||
				color #aaa
 | 
			
		||||
 | 
			
		||||
				> i
 | 
			
		||||
					margin-right 4px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview-domains>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview-frequently-replied-users>
 | 
			
		||||
	<p class="initializing" v-if="initializing">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-frequently-replied-users.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div v-if="!initializing && users.length > 0">
 | 
			
		||||
		<template each={ users }>
 | 
			
		||||
			<mk-user-card user={ this.user }/>
 | 
			
		||||
		</template>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!initializing && users.length == 0">%i18n:mobile.tags.mk-user-overview-frequently-replied-users.no-users%</p>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> div
 | 
			
		||||
				overflow-x scroll
 | 
			
		||||
				-webkit-overflow-scrolling touch
 | 
			
		||||
				white-space nowrap
 | 
			
		||||
				padding 8px
 | 
			
		||||
 | 
			
		||||
				> mk-user-card
 | 
			
		||||
					&:not(:last-child)
 | 
			
		||||
						margin-right 8px
 | 
			
		||||
 | 
			
		||||
			> .initializing
 | 
			
		||||
			> .empty
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 16px
 | 
			
		||||
				text-align center
 | 
			
		||||
				color #aaa
 | 
			
		||||
 | 
			
		||||
				> i
 | 
			
		||||
					margin-right 4px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
		this.initializing = true;
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.$root.$data.os.api('users/get_frequently_replied_users', {
 | 
			
		||||
				user_id: this.user.id
 | 
			
		||||
			}).then(x => {
 | 
			
		||||
				this.update({
 | 
			
		||||
					users: x,
 | 
			
		||||
					initializing: false
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview-frequently-replied-users>
 | 
			
		||||
 | 
			
		||||
<mk-user-overview-followers-you-know>
 | 
			
		||||
	<p class="initializing" v-if="initializing">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-followers-you-know.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div v-if="!initializing && users.length > 0">
 | 
			
		||||
		<template each={ user in users }>
 | 
			
		||||
			<a href={ '/' + user.username }><img src={ user.avatar_url + '?thumbnail&size=64' } alt={ user.name }/></a>
 | 
			
		||||
		</template>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!initializing && users.length == 0">%i18n:mobile.tags.mk-user-overview-followers-you-know.no-users%</p>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> div
 | 
			
		||||
				padding 4px
 | 
			
		||||
 | 
			
		||||
				> a
 | 
			
		||||
					display inline-block
 | 
			
		||||
					margin 4px
 | 
			
		||||
 | 
			
		||||
					> img
 | 
			
		||||
						width 48px
 | 
			
		||||
						height 48px
 | 
			
		||||
						vertical-align bottom
 | 
			
		||||
						border-radius 100%
 | 
			
		||||
 | 
			
		||||
			> .initializing
 | 
			
		||||
			> .empty
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 16px
 | 
			
		||||
				text-align center
 | 
			
		||||
				color #aaa
 | 
			
		||||
 | 
			
		||||
				> i
 | 
			
		||||
					margin-right 4px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
		this.initializing = true;
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.$root.$data.os.api('users/followers', {
 | 
			
		||||
				user_id: this.user.id,
 | 
			
		||||
				iknow: true,
 | 
			
		||||
				limit: 30
 | 
			
		||||
			}).then(x => {
 | 
			
		||||
				this.update({
 | 
			
		||||
					users: x.users,
 | 
			
		||||
					initializing: false
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-user-overview-followers-you-know>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<mk-users-list>
 | 
			
		||||
	<nav>
 | 
			
		||||
		<span data-is-active={ mode == 'all' } @click="setMode.bind(this, 'all')">%i18n:mobile.tags.mk-users-list.all%<span>{ opts.count }</span></span>
 | 
			
		||||
		<span v-if="SIGNIN && opts.youKnowCount" data-is-active={ mode == 'iknow' } @click="setMode.bind(this, 'iknow')">%i18n:mobile.tags.mk-users-list.known%<span>{ opts.youKnowCount }</span></span>
 | 
			
		||||
		<span v-if="$root.$data.os.isSignedIn && opts.youKnowCount" data-is-active={ mode == 'iknow' } @click="setMode.bind(this, 'iknow')">%i18n:mobile.tags.mk-users-list.known%<span>{ opts.youKnowCount }</span></span>
 | 
			
		||||
	</nav>
 | 
			
		||||
	<div class="users" v-if="!fetching && users.length != 0">
 | 
			
		||||
		<mk-user-preview each={ users } user={ this }/>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								src/web/app/mobile/views/components/home.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/web/app/mobile/views/components/home.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mk-home">
 | 
			
		||||
	<mk-timeline @loaded="onTlLoaded"/>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	methods: {
 | 
			
		||||
		onTlLoaded() {
 | 
			
		||||
			this.$emit('loaded');
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-home
 | 
			
		||||
 | 
			
		||||
	> .mk-timeline
 | 
			
		||||
		max-width 600px
 | 
			
		||||
		margin 0 auto
 | 
			
		||||
		padding 8px
 | 
			
		||||
 | 
			
		||||
	@media (min-width 500px)
 | 
			
		||||
		padding 16px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										85
									
								
								src/web/app/mobile/views/components/post-card.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/web/app/mobile/views/components/post-card.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mk-post-card">
 | 
			
		||||
	<a :href="`/${post.user.username}/${post.id}`">
 | 
			
		||||
		<header>
 | 
			
		||||
			<img :src="`${post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/><h3>{{ post.user.name }}</h3>
 | 
			
		||||
		</header>
 | 
			
		||||
		<div>
 | 
			
		||||
			{{ text }}
 | 
			
		||||
		</div>
 | 
			
		||||
		<mk-time :time="post.created_at"/>
 | 
			
		||||
	</a>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import summary from '../../../../../common/get-post-summary';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['post'],
 | 
			
		||||
	computed: {
 | 
			
		||||
		text(): string {
 | 
			
		||||
			return summary(this.post);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-post-card
 | 
			
		||||
	display inline-block
 | 
			
		||||
	width 150px
 | 
			
		||||
	//height 120px
 | 
			
		||||
	font-size 12px
 | 
			
		||||
	background #fff
 | 
			
		||||
	border-radius 4px
 | 
			
		||||
 | 
			
		||||
	> a
 | 
			
		||||
		display block
 | 
			
		||||
		color #2c3940
 | 
			
		||||
 | 
			
		||||
		&:hover
 | 
			
		||||
			text-decoration none
 | 
			
		||||
 | 
			
		||||
		> header
 | 
			
		||||
			> img
 | 
			
		||||
				position absolute
 | 
			
		||||
				top 8px
 | 
			
		||||
				left 8px
 | 
			
		||||
				width 28px
 | 
			
		||||
				height 28px
 | 
			
		||||
				border-radius 6px
 | 
			
		||||
 | 
			
		||||
			> h3
 | 
			
		||||
				display inline-block
 | 
			
		||||
				overflow hidden
 | 
			
		||||
				width calc(100% - 45px)
 | 
			
		||||
				margin 8px 0 0 42px
 | 
			
		||||
				line-height 28px
 | 
			
		||||
				white-space nowrap
 | 
			
		||||
				text-overflow ellipsis
 | 
			
		||||
				font-size 12px
 | 
			
		||||
 | 
			
		||||
		> div
 | 
			
		||||
			padding 2px 8px 8px 8px
 | 
			
		||||
			height 60px
 | 
			
		||||
			overflow hidden
 | 
			
		||||
			white-space normal
 | 
			
		||||
 | 
			
		||||
			&:after
 | 
			
		||||
				content ""
 | 
			
		||||
				display block
 | 
			
		||||
				position absolute
 | 
			
		||||
				top 40px
 | 
			
		||||
				left 0
 | 
			
		||||
				width 100%
 | 
			
		||||
				height 20px
 | 
			
		||||
				background linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 100%)
 | 
			
		||||
 | 
			
		||||
		> mk-time
 | 
			
		||||
			display inline-block
 | 
			
		||||
			padding 8px
 | 
			
		||||
			color #aaa
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
<div class="mk-ui-nav" :style="{ display: isOpen ? 'block' : 'none' }">
 | 
			
		||||
	<div class="backdrop" @click="parent.toggleDrawer"></div>
 | 
			
		||||
	<div class="body">
 | 
			
		||||
		<a class="me" v-if="SIGNIN" href={ '/' + I.username }>
 | 
			
		||||
		<a class="me" v-if="$root.$data.os.isSignedIn" href={ '/' + I.username }>
 | 
			
		||||
			<img class="avatar" src={ I.avatar_url + '?thumbnail&size=128' } alt="avatar"/>
 | 
			
		||||
			<p class="name">{ I.name }</p>
 | 
			
		||||
		</a>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										226
									
								
								src/web/app/mobile/views/pages/user.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								src/web/app/mobile/views/pages/user.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,226 @@
 | 
			
		|||
<template>
 | 
			
		||||
<mk-ui :func="fn" func-icon="%fa:pencil-alt%">
 | 
			
		||||
	<span slot="header">%fa:user% {{user.name}}</span>
 | 
			
		||||
	<div v-if="!fetching" :class="$style.user">
 | 
			
		||||
		<header>
 | 
			
		||||
			<div class="banner" :style="user.banner_url ? `background-image: url(${user.banner_url}?thumbnail&size=1024)` : ''"></div>
 | 
			
		||||
			<div class="body">
 | 
			
		||||
				<div class="top">
 | 
			
		||||
					<a class="avatar">
 | 
			
		||||
						<img :src="`${user.avatar_url}?thumbnail&size=200`" alt="avatar"/>
 | 
			
		||||
					</a>
 | 
			
		||||
					<mk-follow-button v-if="$root.$data.os.isSignedIn && $root.$data.os.i.id != user.id" :user="user"/>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="title">
 | 
			
		||||
					<h1>{{ user.name }}</h1>
 | 
			
		||||
					<span class="username">@{{ user.username }}</span>
 | 
			
		||||
					<span class="followed" v-if="user.is_followed">%i18n:mobile.tags.mk-user.follows-you%</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="description">{{ user.description }}</div>
 | 
			
		||||
				<div class="info">
 | 
			
		||||
					<p class="location" v-if="user.profile.location">
 | 
			
		||||
						%fa:map-marker%{{ user.profile.location }}
 | 
			
		||||
					</p>
 | 
			
		||||
					<p class="birthday" v-if="user.profile.birthday">
 | 
			
		||||
						%fa:birthday-cake%{{ user.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ age }}歳)
 | 
			
		||||
					</p>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="status">
 | 
			
		||||
				  <a>
 | 
			
		||||
				    <b>{{ user.posts_count }}</b>
 | 
			
		||||
						<i>%i18n:mobile.tags.mk-user.posts%</i>
 | 
			
		||||
					</a>
 | 
			
		||||
					<a :href="`${user.username}/following`">
 | 
			
		||||
						<b>{{ user.following_count }}</b>
 | 
			
		||||
						<i>%i18n:mobile.tags.mk-user.following%</i>
 | 
			
		||||
					</a>
 | 
			
		||||
					<a :href="`${user.username}/followers`">
 | 
			
		||||
						<b>{{ user.followers_count }}</b>
 | 
			
		||||
						<i>%i18n:mobile.tags.mk-user.followers%</i>
 | 
			
		||||
					</a>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<nav>
 | 
			
		||||
				<a :data-is-active=" page == 'home' " @click="page = 'home'">%i18n:mobile.tags.mk-user.overview%</a>
 | 
			
		||||
				<a :data-is-active=" page == 'posts' " @click="page = 'posts'">%i18n:mobile.tags.mk-user.timeline%</a>
 | 
			
		||||
				<a :data-is-active=" page == 'media' " @click="page = 'media'">%i18n:mobile.tags.mk-user.media%</a>
 | 
			
		||||
			</nav>
 | 
			
		||||
		</header>
 | 
			
		||||
		<div class="body">
 | 
			
		||||
			<mk-user-home v-if="page == 'home'" :user="user"/>
 | 
			
		||||
			<mk-user-timeline v-if="page == 'posts'" :user="user"/>
 | 
			
		||||
			<mk-user-timeline v-if="page == 'media'" :user="user" with-media/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</mk-ui>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
const age = require('s-age');
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: {
 | 
			
		||||
		username: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: true
 | 
			
		||||
		},
 | 
			
		||||
		page: {
 | 
			
		||||
			default: 'home'
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			user: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	computed: {
 | 
			
		||||
		age(): number {
 | 
			
		||||
			return age(this.user.profile.birthday);
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$root.$data.os.api('users/show', {
 | 
			
		||||
			username: this.username
 | 
			
		||||
		}).then(user => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.user = user;
 | 
			
		||||
			this.$emit('loaded', user);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" module>
 | 
			
		||||
.user
 | 
			
		||||
	> header
 | 
			
		||||
		box-shadow 0 4px 4px rgba(0, 0, 0, 0.3)
 | 
			
		||||
 | 
			
		||||
		> .banner
 | 
			
		||||
			padding-bottom 33.3%
 | 
			
		||||
			background-color #1b1b1b
 | 
			
		||||
			background-size cover
 | 
			
		||||
			background-position center
 | 
			
		||||
 | 
			
		||||
		> .body
 | 
			
		||||
			padding 12px
 | 
			
		||||
			margin 0 auto
 | 
			
		||||
			max-width 600px
 | 
			
		||||
 | 
			
		||||
			> .top
 | 
			
		||||
				&:after
 | 
			
		||||
					content ''
 | 
			
		||||
					display block
 | 
			
		||||
					clear both
 | 
			
		||||
 | 
			
		||||
				> .avatar
 | 
			
		||||
					display block
 | 
			
		||||
					float left
 | 
			
		||||
					width 25%
 | 
			
		||||
					height 40px
 | 
			
		||||
 | 
			
		||||
					> img
 | 
			
		||||
						display block
 | 
			
		||||
						position absolute
 | 
			
		||||
						left -2px
 | 
			
		||||
						bottom -2px
 | 
			
		||||
						width 100%
 | 
			
		||||
						border 2px solid #313a42
 | 
			
		||||
						border-radius 6px
 | 
			
		||||
 | 
			
		||||
						@media (min-width 500px)
 | 
			
		||||
							left -4px
 | 
			
		||||
							bottom -4px
 | 
			
		||||
							border 4px solid #313a42
 | 
			
		||||
							border-radius 12px
 | 
			
		||||
 | 
			
		||||
				> mk-follow-button
 | 
			
		||||
					float right
 | 
			
		||||
					height 40px
 | 
			
		||||
 | 
			
		||||
			> .title
 | 
			
		||||
				margin 8px 0
 | 
			
		||||
 | 
			
		||||
				> h1
 | 
			
		||||
					margin 0
 | 
			
		||||
					line-height 22px
 | 
			
		||||
					font-size 20px
 | 
			
		||||
					color #fff
 | 
			
		||||
 | 
			
		||||
				> .username
 | 
			
		||||
					display inline-block
 | 
			
		||||
					line-height 20px
 | 
			
		||||
					font-size 16px
 | 
			
		||||
					font-weight bold
 | 
			
		||||
					color #657786
 | 
			
		||||
 | 
			
		||||
				> .followed
 | 
			
		||||
					margin-left 8px
 | 
			
		||||
					padding 2px 4px
 | 
			
		||||
					font-size 12px
 | 
			
		||||
					color #657786
 | 
			
		||||
					background #f8f8f8
 | 
			
		||||
					border-radius 4px
 | 
			
		||||
 | 
			
		||||
			> .description
 | 
			
		||||
				margin 8px 0
 | 
			
		||||
				color #fff
 | 
			
		||||
 | 
			
		||||
			> .info
 | 
			
		||||
				margin 8px 0
 | 
			
		||||
 | 
			
		||||
				> p
 | 
			
		||||
					display inline
 | 
			
		||||
					margin 0 16px 0 0
 | 
			
		||||
					color #a9b9c1
 | 
			
		||||
 | 
			
		||||
					> i
 | 
			
		||||
						margin-right 4px
 | 
			
		||||
 | 
			
		||||
			> .status
 | 
			
		||||
				> a
 | 
			
		||||
					color #657786
 | 
			
		||||
 | 
			
		||||
					&:not(:last-child)
 | 
			
		||||
						margin-right 16px
 | 
			
		||||
 | 
			
		||||
					> b
 | 
			
		||||
						margin-right 4px
 | 
			
		||||
						font-size 16px
 | 
			
		||||
						color #fff
 | 
			
		||||
 | 
			
		||||
					> i
 | 
			
		||||
						font-size 14px
 | 
			
		||||
 | 
			
		||||
			> mk-activity-table
 | 
			
		||||
				margin 12px 0 0 0
 | 
			
		||||
 | 
			
		||||
		> nav
 | 
			
		||||
			display flex
 | 
			
		||||
			justify-content center
 | 
			
		||||
			margin 0 auto
 | 
			
		||||
			max-width 600px
 | 
			
		||||
 | 
			
		||||
			> a
 | 
			
		||||
				display block
 | 
			
		||||
				flex 1 1
 | 
			
		||||
				text-align center
 | 
			
		||||
				line-height 52px
 | 
			
		||||
				font-size 14px
 | 
			
		||||
				text-decoration none
 | 
			
		||||
				color #657786
 | 
			
		||||
				border-bottom solid 2px transparent
 | 
			
		||||
 | 
			
		||||
				&[data-is-active]
 | 
			
		||||
					font-weight bold
 | 
			
		||||
					color $theme-color
 | 
			
		||||
					border-color $theme-color
 | 
			
		||||
 | 
			
		||||
	> .body
 | 
			
		||||
		padding 8px
 | 
			
		||||
 | 
			
		||||
		@media (min-width 500px)
 | 
			
		||||
			padding 16px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										62
									
								
								src/web/app/mobile/views/pages/user/followers-you-know.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/web/app/mobile/views/pages/user/followers-you-know.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mk-user-home-followers-you-know">
 | 
			
		||||
	<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-followers-you-know.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div v-if="!fetching && users.length > 0">
 | 
			
		||||
		<a v-for="user in users" :key="user.id" :href="`/${user.username}`">
 | 
			
		||||
			<img :src="`${user.avatar_url}?thumbnail&size=64`" :alt="user.name"/>
 | 
			
		||||
		</a>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!fetching && users.length == 0">%i18n:mobile.tags.mk-user-overview-followers-you-know.no-users%</p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			users: []
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$root.$data.os.api('users/followers', {
 | 
			
		||||
			user_id: this.user.id,
 | 
			
		||||
			iknow: true,
 | 
			
		||||
			limit: 30
 | 
			
		||||
		}).then(res => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.users = res.users;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-user-home-followers-you-know
 | 
			
		||||
 | 
			
		||||
	> div
 | 
			
		||||
		padding 4px
 | 
			
		||||
 | 
			
		||||
		> a
 | 
			
		||||
			display inline-block
 | 
			
		||||
			margin 4px
 | 
			
		||||
 | 
			
		||||
			> img
 | 
			
		||||
				width 48px
 | 
			
		||||
				height 48px
 | 
			
		||||
				vertical-align bottom
 | 
			
		||||
				border-radius 100%
 | 
			
		||||
 | 
			
		||||
	> .initializing
 | 
			
		||||
	> .empty
 | 
			
		||||
		margin 0
 | 
			
		||||
		padding 16px
 | 
			
		||||
		text-align center
 | 
			
		||||
		color #aaa
 | 
			
		||||
 | 
			
		||||
		> i
 | 
			
		||||
			margin-right 4px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										62
									
								
								src/web/app/mobile/views/pages/user/home-activity.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/web/app/mobile/views/pages/user/home-activity.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mk-user-home-activity">
 | 
			
		||||
	<svg v-if="data" ref="canvas" viewBox="0 0 30 1" preserveAspectRatio="none">
 | 
			
		||||
		<g v-for="(d, i) in data.reverse()" :key="i">
 | 
			
		||||
			<rect width="0.8" :height="d.postsH"
 | 
			
		||||
				:x="i + 0.1" :y="1 - d.postsH - d.repliesH - d.repostsH"
 | 
			
		||||
				fill="#41ddde"/>
 | 
			
		||||
			<rect width="0.8" :height="d.repliesH"
 | 
			
		||||
				:x="i + 0.1" :y="1 - d.repliesH - d.repostsH"
 | 
			
		||||
				fill="#f7796c"/>
 | 
			
		||||
			<rect width="0.8" :height="d.repostsH"
 | 
			
		||||
				:x="i + 0.1" :y="1 - d.repostsH"
 | 
			
		||||
				fill="#a1de41"/>
 | 
			
		||||
			</g>
 | 
			
		||||
	</svg>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			data: [],
 | 
			
		||||
			peak: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$root.$data.os.api('aggregation/users/activity', {
 | 
			
		||||
			user_id: this.user.id,
 | 
			
		||||
			limit: 30
 | 
			
		||||
		}).then(data => {
 | 
			
		||||
			data.forEach(d => d.total = d.posts + d.replies + d.reposts);
 | 
			
		||||
			this.peak = Math.max.apply(null, data.map(d => d.total));
 | 
			
		||||
			data.forEach(d => {
 | 
			
		||||
				d.postsH = d.posts / this.peak;
 | 
			
		||||
				d.repliesH = d.replies / this.peak;
 | 
			
		||||
				d.repostsH = d.reposts / this.peak;
 | 
			
		||||
			});
 | 
			
		||||
			this.data = data;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-user-home-activity
 | 
			
		||||
	display block
 | 
			
		||||
	max-width 600px
 | 
			
		||||
	margin 0 auto
 | 
			
		||||
 | 
			
		||||
	> svg
 | 
			
		||||
		display block
 | 
			
		||||
		width 100%
 | 
			
		||||
		height 80px
 | 
			
		||||
 | 
			
		||||
		> rect
 | 
			
		||||
			transform-origin center
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										54
									
								
								src/web/app/mobile/views/pages/user/home-friends.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/web/app/mobile/views/pages/user/home-friends.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mk-user-home-friends">
 | 
			
		||||
	<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-frequently-replied-users.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div v-if="!fetching && users.length > 0">
 | 
			
		||||
		<mk-user-card v-for="user in users" :key="user.id" :user="user"/>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!fetching && users.length == 0">%i18n:mobile.tags.mk-user-overview-frequently-replied-users.no-users%</p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			users: []
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$root.$data.os.api('users/get_frequently_replied_users', {
 | 
			
		||||
			user_id: this.user.id
 | 
			
		||||
		}).then(res => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.users = res.map(x => x.user);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-user-home-friends
 | 
			
		||||
	> div
 | 
			
		||||
		overflow-x scroll
 | 
			
		||||
		-webkit-overflow-scrolling touch
 | 
			
		||||
		white-space nowrap
 | 
			
		||||
		padding 8px
 | 
			
		||||
 | 
			
		||||
		> mk-user-card
 | 
			
		||||
			&:not(:last-child)
 | 
			
		||||
				margin-right 8px
 | 
			
		||||
 | 
			
		||||
	> .initializing
 | 
			
		||||
	> .empty
 | 
			
		||||
		margin 0
 | 
			
		||||
		padding 16px
 | 
			
		||||
		text-align center
 | 
			
		||||
		color #aaa
 | 
			
		||||
 | 
			
		||||
		> i
 | 
			
		||||
			margin-right 4px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										78
									
								
								src/web/app/mobile/views/pages/user/home-photos.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/web/app/mobile/views/pages/user/home-photos.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mk-user-home-photos">
 | 
			
		||||
	<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-photos.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div class="stream" v-if="!fetching && images.length > 0">
 | 
			
		||||
		<a v-for="image in images" :key="image.id"
 | 
			
		||||
			class="img"
 | 
			
		||||
			:style="`background-image: url(${image.media.url}?thumbnail&size=256)`"
 | 
			
		||||
			:href="`/${image.post.user.username}/${image.post.id}`"
 | 
			
		||||
		></a>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!fetching && images.length == 0">%i18n:mobile.tags.mk-user-overview-photos.no-photos%</p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			images: []
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$root.$data.os.api('users/posts', {
 | 
			
		||||
			user_id: this.user.id,
 | 
			
		||||
			with_media: true,
 | 
			
		||||
			limit: 6
 | 
			
		||||
		}).then(posts => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			posts.forEach(post => {
 | 
			
		||||
				post.media.forEach(media => {
 | 
			
		||||
					if (this.images.length < 9) this.images.push({
 | 
			
		||||
						post,
 | 
			
		||||
						media
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-user-home-photos
 | 
			
		||||
 | 
			
		||||
	> .stream
 | 
			
		||||
		display -webkit-flex
 | 
			
		||||
		display -moz-flex
 | 
			
		||||
		display -ms-flex
 | 
			
		||||
		display flex
 | 
			
		||||
		justify-content center
 | 
			
		||||
		flex-wrap wrap
 | 
			
		||||
		padding 8px
 | 
			
		||||
 | 
			
		||||
		> .img
 | 
			
		||||
			flex 1 1 33%
 | 
			
		||||
			width 33%
 | 
			
		||||
			height 80px
 | 
			
		||||
			background-position center center
 | 
			
		||||
			background-size cover
 | 
			
		||||
			background-clip content-box
 | 
			
		||||
			border solid 2px transparent
 | 
			
		||||
			border-radius 4px
 | 
			
		||||
 | 
			
		||||
	> .initializing
 | 
			
		||||
	> .empty
 | 
			
		||||
		margin 0
 | 
			
		||||
		padding 16px
 | 
			
		||||
		text-align center
 | 
			
		||||
		color #aaa
 | 
			
		||||
 | 
			
		||||
		> i
 | 
			
		||||
			margin-right 4px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										57
									
								
								src/web/app/mobile/views/pages/user/home-posts.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/web/app/mobile/views/pages/user/home-posts.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mk-user-home-posts">
 | 
			
		||||
	<p class="initializing" v-if="initializing">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-posts.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div v-if="!initializing && posts.length > 0">
 | 
			
		||||
		<mk-post-card v-for="post in posts" :key="post.id" :post="post"/>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!initializing && posts.length == 0">%i18n:mobile.tags.mk-user-overview-posts.no-posts%</p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			posts: []
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$root.$data.os.api('users/posts', {
 | 
			
		||||
			user_id: this.user.id
 | 
			
		||||
		}).then(posts => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.posts = posts;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-user-home-posts
 | 
			
		||||
 | 
			
		||||
	> div
 | 
			
		||||
		overflow-x scroll
 | 
			
		||||
		-webkit-overflow-scrolling touch
 | 
			
		||||
		white-space nowrap
 | 
			
		||||
		padding 8px
 | 
			
		||||
 | 
			
		||||
		> *
 | 
			
		||||
			vertical-align top
 | 
			
		||||
 | 
			
		||||
			&:not(:last-child)
 | 
			
		||||
				margin-right 8px
 | 
			
		||||
 | 
			
		||||
	> .initializing
 | 
			
		||||
	> .empty
 | 
			
		||||
		margin 0
 | 
			
		||||
		padding 16px
 | 
			
		||||
		text-align center
 | 
			
		||||
		color #aaa
 | 
			
		||||
 | 
			
		||||
		> i
 | 
			
		||||
			margin-right 4px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										95
									
								
								src/web/app/mobile/views/pages/user/home.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/web/app/mobile/views/pages/user/home.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="mk-user-home">
 | 
			
		||||
	<mk-post-detail v-if="user.pinned_post" :post="user.pinned_post" compact/>
 | 
			
		||||
	<section class="recent-posts">
 | 
			
		||||
		<h2>%fa:R comments%%i18n:mobile.tags.mk-user-overview.recent-posts%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-home-posts :user="user"/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="images">
 | 
			
		||||
		<h2>%fa:image%%i18n:mobile.tags.mk-user-overview.images%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-home-photos :user="user"/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="activity">
 | 
			
		||||
		<h2>%fa:chart-bar%%i18n:mobile.tags.mk-user-overview.activity%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-home-activity-chart :user="user"/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="keywords">
 | 
			
		||||
		<h2>%fa:R comment%%i18n:mobile.tags.mk-user-overview.keywords%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-home-keywords :user="user"/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="domains">
 | 
			
		||||
		<h2>%fa:globe%%i18n:mobile.tags.mk-user-overview.domains%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-home-domains :user="user"/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="frequently-replied-users">
 | 
			
		||||
		<h2>%fa:users%%i18n:mobile.tags.mk-user-overview.frequently-replied-users%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-home-frequently-replied-users :user="user"/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<section class="followers-you-know" v-if="$root.$data.os.isSignedIn && $root.$data.os.i.id !== user.id">
 | 
			
		||||
		<h2>%fa:users%%i18n:mobile.tags.mk-user-overview.followers-you-know%</h2>
 | 
			
		||||
		<div>
 | 
			
		||||
			<mk-user-home-followers-you-know :user="user"/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
	<p>%i18n:mobile.tags.mk-user-overview.last-used-at%: <b><mk-time :time="user.last_used_at"/></b></p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['user']
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-user-home
 | 
			
		||||
	max-width 600px
 | 
			
		||||
	margin 0 auto
 | 
			
		||||
 | 
			
		||||
	> mk-post-detail
 | 
			
		||||
		margin 0 0 8px 0
 | 
			
		||||
 | 
			
		||||
	> section
 | 
			
		||||
		background #eee
 | 
			
		||||
		border-radius 8px
 | 
			
		||||
		box-shadow 0 0 0 1px rgba(0, 0, 0, 0.2)
 | 
			
		||||
 | 
			
		||||
		&:not(:last-child)
 | 
			
		||||
			margin-bottom 8px
 | 
			
		||||
 | 
			
		||||
		> h2
 | 
			
		||||
			margin 0
 | 
			
		||||
			padding 8px 10px
 | 
			
		||||
			font-size 15px
 | 
			
		||||
			font-weight normal
 | 
			
		||||
			color #465258
 | 
			
		||||
			background #fff
 | 
			
		||||
			border-radius 8px 8px 0 0
 | 
			
		||||
 | 
			
		||||
			> i
 | 
			
		||||
				margin-right 6px
 | 
			
		||||
 | 
			
		||||
	> .activity
 | 
			
		||||
		> div
 | 
			
		||||
			padding 8px
 | 
			
		||||
 | 
			
		||||
	> p
 | 
			
		||||
		display block
 | 
			
		||||
		margin 16px
 | 
			
		||||
		text-align center
 | 
			
		||||
		color #cad2da
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue