wip
This commit is contained in:
		@@ -28,7 +28,6 @@
 | 
			
		||||
			this.$root.$data.os.api('i/authorized_apps').then(apps => {
 | 
			
		||||
				this.apps = apps;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.update();
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -78,8 +78,8 @@ export default Vue.extend({
 | 
			
		||||
		this.connection.on('read', this.onRead);
 | 
			
		||||
 | 
			
		||||
		(this as any).api('messaging/history').then(messages => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.messages = messages;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,246 +0,0 @@
 | 
			
		||||
<mk-activity-widget data-melt={ design == 2 }>
 | 
			
		||||
	<template v-if="design == 0">
 | 
			
		||||
		<p class="title">%fa:chart-bar%%i18n:desktop.tags.mk-activity-widget.title%</p>
 | 
			
		||||
		<button @click="toggle" title="%i18n:desktop.tags.mk-activity-widget.toggle%">%fa:sort%</button>
 | 
			
		||||
	</template>
 | 
			
		||||
	<p class="initializing" v-if="initializing">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<mk-activity-widget-calender v-if="!initializing && view == 0" data={ [].concat(activity) }/>
 | 
			
		||||
	<mk-activity-widget-chart v-if="!initializing && view == 1" data={ [].concat(activity) }/>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
			background #fff
 | 
			
		||||
			border solid 1px rgba(0, 0, 0, 0.075)
 | 
			
		||||
			border-radius 6px
 | 
			
		||||
 | 
			
		||||
			&[data-melt]
 | 
			
		||||
				background transparent !important
 | 
			
		||||
				border none !important
 | 
			
		||||
 | 
			
		||||
			> .title
 | 
			
		||||
				z-index 1
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 0 16px
 | 
			
		||||
				line-height 42px
 | 
			
		||||
				font-size 0.9em
 | 
			
		||||
				font-weight bold
 | 
			
		||||
				color #888
 | 
			
		||||
				box-shadow 0 1px rgba(0, 0, 0, 0.07)
 | 
			
		||||
 | 
			
		||||
				> [data-fa]
 | 
			
		||||
					margin-right 4px
 | 
			
		||||
 | 
			
		||||
			> button
 | 
			
		||||
				position absolute
 | 
			
		||||
				z-index 2
 | 
			
		||||
				top 0
 | 
			
		||||
				right 0
 | 
			
		||||
				padding 0
 | 
			
		||||
				width 42px
 | 
			
		||||
				font-size 0.9em
 | 
			
		||||
				line-height 42px
 | 
			
		||||
				color #ccc
 | 
			
		||||
 | 
			
		||||
				&:hover
 | 
			
		||||
					color #aaa
 | 
			
		||||
 | 
			
		||||
				&:active
 | 
			
		||||
					color #999
 | 
			
		||||
 | 
			
		||||
			> .initializing
 | 
			
		||||
				margin 0
 | 
			
		||||
				padding 16px
 | 
			
		||||
				text-align center
 | 
			
		||||
				color #aaa
 | 
			
		||||
 | 
			
		||||
				> [data-fa]
 | 
			
		||||
					margin-right 4px
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.mixin('api');
 | 
			
		||||
 | 
			
		||||
		this.design = this.opts.design || 0;
 | 
			
		||||
		this.view = this.opts.view || 0;
 | 
			
		||||
 | 
			
		||||
		this.user = this.opts.user;
 | 
			
		||||
		this.initializing = true;
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.$root.$data.os.api('aggregation/users/activity', {
 | 
			
		||||
				user_id: this.user.id,
 | 
			
		||||
				limit: 20 * 7
 | 
			
		||||
			}).then(activity => {
 | 
			
		||||
				this.update({
 | 
			
		||||
					initializing: false,
 | 
			
		||||
					activity
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.toggle = () => {
 | 
			
		||||
			this.view++;
 | 
			
		||||
			if (this.view == 2) this.view = 0;
 | 
			
		||||
			this.update();
 | 
			
		||||
			this.$emit('view-changed', this.view);
 | 
			
		||||
		};
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-activity-widget>
 | 
			
		||||
 | 
			
		||||
<mk-activity-widget-calender>
 | 
			
		||||
	<svg viewBox="0 0 21 7" preserveAspectRatio="none">
 | 
			
		||||
		<rect each={ data } class="day"
 | 
			
		||||
			width="1" height="1"
 | 
			
		||||
			riot-x={ x } riot-y={ date.weekday }
 | 
			
		||||
			rx="1" ry="1"
 | 
			
		||||
			fill="transparent">
 | 
			
		||||
			<title>{ date.year }/{ date.month }/{ date.day }<br/>Post: { posts }, Reply: { replies }, Repost: { reposts }</title>
 | 
			
		||||
		</rect>
 | 
			
		||||
		<rect each={ data }
 | 
			
		||||
			riot-width={ v } riot-height={ v }
 | 
			
		||||
			riot-x={ x + ((1 - v) / 2) } riot-y={ date.weekday + ((1 - v) / 2) }
 | 
			
		||||
			rx="1" ry="1"
 | 
			
		||||
			fill={ color }
 | 
			
		||||
			style="pointer-events: none;"/>
 | 
			
		||||
		<rect class="today"
 | 
			
		||||
			width="1" height="1"
 | 
			
		||||
			riot-x={ data[data.length - 1].x } riot-y={ data[data.length - 1].date.weekday }
 | 
			
		||||
			rx="1" ry="1"
 | 
			
		||||
			fill="none"
 | 
			
		||||
			stroke-width="0.1"
 | 
			
		||||
			stroke="#f73520"/>
 | 
			
		||||
	</svg>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> svg
 | 
			
		||||
				display block
 | 
			
		||||
				padding 10px
 | 
			
		||||
				width 100%
 | 
			
		||||
 | 
			
		||||
				> rect
 | 
			
		||||
					transform-origin center
 | 
			
		||||
 | 
			
		||||
					&.day
 | 
			
		||||
						&:hover
 | 
			
		||||
							fill rgba(0, 0, 0, 0.05)
 | 
			
		||||
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.data = this.opts.data;
 | 
			
		||||
		this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
 | 
			
		||||
		const peak = Math.max.apply(null, this.data.map(d => d.total));
 | 
			
		||||
 | 
			
		||||
		let x = 0;
 | 
			
		||||
		this.data.reverse().forEach(d => {
 | 
			
		||||
			d.x = x;
 | 
			
		||||
			d.date.weekday = (new Date(d.date.year, d.date.month - 1, d.date.day)).getDay();
 | 
			
		||||
 | 
			
		||||
			d.v = d.total / (peak / 2);
 | 
			
		||||
			if (d.v > 1) d.v = 1;
 | 
			
		||||
			const ch = d.date.weekday == 0 || d.date.weekday == 6 ? 275 : 170;
 | 
			
		||||
			const cs = d.v * 100;
 | 
			
		||||
			const cl = 15 + ((1 - d.v) * 80);
 | 
			
		||||
			d.color = `hsl(${ch}, ${cs}%, ${cl}%)`;
 | 
			
		||||
 | 
			
		||||
			if (d.date.weekday == 6) x++;
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-activity-widget-calender>
 | 
			
		||||
 | 
			
		||||
<mk-activity-widget-chart>
 | 
			
		||||
	<svg riot-viewBox="0 0 { viewBoxX } { viewBoxY }" preserveAspectRatio="none" onmousedown={ onMousedown }>
 | 
			
		||||
		<title>Black ... Total<br/>Blue ... Posts<br/>Red ... Replies<br/>Green ... Reposts</title>
 | 
			
		||||
		<polyline
 | 
			
		||||
			riot-points={ pointsPost }
 | 
			
		||||
			fill="none"
 | 
			
		||||
			stroke-width="1"
 | 
			
		||||
			stroke="#41ddde"/>
 | 
			
		||||
		<polyline
 | 
			
		||||
			riot-points={ pointsReply }
 | 
			
		||||
			fill="none"
 | 
			
		||||
			stroke-width="1"
 | 
			
		||||
			stroke="#f7796c"/>
 | 
			
		||||
		<polyline
 | 
			
		||||
			riot-points={ pointsRepost }
 | 
			
		||||
			fill="none"
 | 
			
		||||
			stroke-width="1"
 | 
			
		||||
			stroke="#a1de41"/>
 | 
			
		||||
		<polyline
 | 
			
		||||
			riot-points={ pointsTotal }
 | 
			
		||||
			fill="none"
 | 
			
		||||
			stroke-width="1"
 | 
			
		||||
			stroke="#555"
 | 
			
		||||
			stroke-dasharray="2 2"/>
 | 
			
		||||
	</svg>
 | 
			
		||||
	<style lang="stylus" scoped>
 | 
			
		||||
		:scope
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> svg
 | 
			
		||||
				display block
 | 
			
		||||
				padding 10px
 | 
			
		||||
				width 100%
 | 
			
		||||
				cursor all-scroll
 | 
			
		||||
	</style>
 | 
			
		||||
	<script lang="typescript">
 | 
			
		||||
		this.viewBoxX = 140;
 | 
			
		||||
		this.viewBoxY = 60;
 | 
			
		||||
		this.zoom = 1;
 | 
			
		||||
		this.pos = 0;
 | 
			
		||||
 | 
			
		||||
		this.data = this.opts.data.reverse();
 | 
			
		||||
		this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
 | 
			
		||||
		const peak = Math.max.apply(null, this.data.map(d => d.total));
 | 
			
		||||
 | 
			
		||||
		this.on('mount', () => {
 | 
			
		||||
			this.render();
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.render = () => {
 | 
			
		||||
			this.update({
 | 
			
		||||
				pointsPost: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.posts / peak)) * this.viewBoxY}`).join(' '),
 | 
			
		||||
				pointsReply: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' '),
 | 
			
		||||
				pointsRepost: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.reposts / peak)) * this.viewBoxY}`).join(' '),
 | 
			
		||||
				pointsTotal: this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ')
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.onMousedown = e => {
 | 
			
		||||
			e.preventDefault();
 | 
			
		||||
 | 
			
		||||
			const clickX = e.clientX;
 | 
			
		||||
			const clickY = e.clientY;
 | 
			
		||||
			const baseZoom = this.zoom;
 | 
			
		||||
			const basePos = this.pos;
 | 
			
		||||
 | 
			
		||||
			// 動かした時
 | 
			
		||||
			dragListen(me => {
 | 
			
		||||
				let moveLeft = me.clientX - clickX;
 | 
			
		||||
				let moveTop = me.clientY - clickY;
 | 
			
		||||
 | 
			
		||||
				this.zoom = baseZoom + (-moveTop / 20);
 | 
			
		||||
				this.pos = basePos + moveLeft;
 | 
			
		||||
				if (this.zoom < 1) this.zoom = 1;
 | 
			
		||||
				if (this.pos > 0) this.pos = 0;
 | 
			
		||||
				if (this.pos < -(((this.data.length - 1) * this.zoom) - this.viewBoxX)) this.pos = -(((this.data.length - 1) * this.zoom) - this.viewBoxX);
 | 
			
		||||
 | 
			
		||||
				this.render();
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		function dragListen(fn) {
 | 
			
		||||
			window.addEventListener('mousemove',  fn);
 | 
			
		||||
			window.addEventListener('mouseleave', dragClear.bind(null, fn));
 | 
			
		||||
			window.addEventListener('mouseup',    dragClear.bind(null, fn));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		function dragClear(fn) {
 | 
			
		||||
			window.removeEventListener('mousemove',  fn);
 | 
			
		||||
			window.removeEventListener('mouseleave', dragClear);
 | 
			
		||||
			window.removeEventListener('mouseup',    dragClear);
 | 
			
		||||
		}
 | 
			
		||||
	</script>
 | 
			
		||||
</mk-activity-widget-chart>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										66
									
								
								src/web/app/desktop/views/components/activity.calendar.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/web/app/desktop/views/components/activity.calendar.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
<template>
 | 
			
		||||
<svg viewBox="0 0 21 7" preserveAspectRatio="none">
 | 
			
		||||
	<rect v-for="record in data" class="day"
 | 
			
		||||
		width="1" height="1"
 | 
			
		||||
		:x="record.x" :y="record.date.weekday"
 | 
			
		||||
		rx="1" ry="1"
 | 
			
		||||
		fill="transparent">
 | 
			
		||||
		<title>{{ record.date.year }}/{{ record.date.month }}/{{ record.date.day }}</title>
 | 
			
		||||
	</rect>
 | 
			
		||||
	<rect v-for="record in data" class="day"
 | 
			
		||||
		:width="record.v" :height="record.v"
 | 
			
		||||
		:x="record.x + ((1 - record.v) / 2)" :y="record.date.weekday + ((1 - record.v) / 2)"
 | 
			
		||||
		rx="1" ry="1"
 | 
			
		||||
		:fill="record.color"
 | 
			
		||||
		style="pointer-events: none;"/>
 | 
			
		||||
	<rect class="today"
 | 
			
		||||
		width="1" height="1"
 | 
			
		||||
		:x="data[data.length - 1].x" :y="data[data.length - 1].date.weekday"
 | 
			
		||||
		rx="1" ry="1"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="0.1"
 | 
			
		||||
		stroke="#f73520"/>
 | 
			
		||||
</svg>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['data'],
 | 
			
		||||
	created() {
 | 
			
		||||
		this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
 | 
			
		||||
		const peak = Math.max.apply(null, this.data.map(d => d.total));
 | 
			
		||||
 | 
			
		||||
		let x = 0;
 | 
			
		||||
		this.data.reverse().forEach(d => {
 | 
			
		||||
			d.x = x;
 | 
			
		||||
			d.date.weekday = (new Date(d.date.year, d.date.month - 1, d.date.day)).getDay();
 | 
			
		||||
 | 
			
		||||
			d.v = d.total / (peak / 2);
 | 
			
		||||
			if (d.v > 1) d.v = 1;
 | 
			
		||||
			const ch = d.date.weekday == 0 || d.date.weekday == 6 ? 275 : 170;
 | 
			
		||||
			const cs = d.v * 100;
 | 
			
		||||
			const cl = 15 + ((1 - d.v) * 80);
 | 
			
		||||
			d.color = `hsl(${ch}, ${cs}%, ${cl}%)`;
 | 
			
		||||
 | 
			
		||||
			if (d.date.weekday == 6) x++;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
svg
 | 
			
		||||
	display block
 | 
			
		||||
	padding 10px
 | 
			
		||||
	width 100%
 | 
			
		||||
 | 
			
		||||
	> rect
 | 
			
		||||
		transform-origin center
 | 
			
		||||
 | 
			
		||||
		&.day
 | 
			
		||||
			&:hover
 | 
			
		||||
				fill rgba(0, 0, 0, 0.05)
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										101
									
								
								src/web/app/desktop/views/components/activity.chart.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/web/app/desktop/views/components/activity.chart.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
<template>
 | 
			
		||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" preserveAspectRatio="none" @mousedown.prevent="onMousedown">
 | 
			
		||||
	<title>Black ... Total<br/>Blue ... Posts<br/>Red ... Replies<br/>Green ... Reposts</title>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsPost"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="1"
 | 
			
		||||
		stroke="#41ddde"/>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsReply"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="1"
 | 
			
		||||
		stroke="#f7796c"/>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsRepost"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="1"
 | 
			
		||||
		stroke="#a1de41"/>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsTotal"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="1"
 | 
			
		||||
		stroke="#555"
 | 
			
		||||
		stroke-dasharray="2 2"/>
 | 
			
		||||
</svg>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
function dragListen(fn) {
 | 
			
		||||
	window.addEventListener('mousemove',  fn);
 | 
			
		||||
	window.addEventListener('mouseleave', dragClear.bind(null, fn));
 | 
			
		||||
	window.addEventListener('mouseup',    dragClear.bind(null, fn));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function dragClear(fn) {
 | 
			
		||||
	window.removeEventListener('mousemove',  fn);
 | 
			
		||||
	window.removeEventListener('mouseleave', dragClear);
 | 
			
		||||
	window.removeEventListener('mouseup',    dragClear);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['data'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			viewBoxX: 140,
 | 
			
		||||
			viewBoxY: 60,
 | 
			
		||||
			zoom: 1,
 | 
			
		||||
			pos: 0,
 | 
			
		||||
			pointsPost: null,
 | 
			
		||||
			pointsReply: null,
 | 
			
		||||
			pointsRepost: null,
 | 
			
		||||
			pointsTotal: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {
 | 
			
		||||
		this.data.reverse();
 | 
			
		||||
		this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
 | 
			
		||||
		this.render();
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		render() {
 | 
			
		||||
			const peak = Math.max.apply(null, this.data.map(d => d.total));
 | 
			
		||||
			this.pointsPost = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.posts / peak)) * this.viewBoxY}`).join(' ');
 | 
			
		||||
			this.pointsReply = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' ');
 | 
			
		||||
			this.pointsRepost = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.reposts / peak)) * this.viewBoxY}`).join(' ');
 | 
			
		||||
			this.pointsTotal = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ');
 | 
			
		||||
		},
 | 
			
		||||
		onMousedown(e) {
 | 
			
		||||
			const clickX = e.clientX;
 | 
			
		||||
			const clickY = e.clientY;
 | 
			
		||||
			const baseZoom = this.zoom;
 | 
			
		||||
			const basePos = this.pos;
 | 
			
		||||
 | 
			
		||||
			// 動かした時
 | 
			
		||||
			dragListen(me => {
 | 
			
		||||
				let moveLeft = me.clientX - clickX;
 | 
			
		||||
				let moveTop = me.clientY - clickY;
 | 
			
		||||
 | 
			
		||||
				this.zoom = baseZoom + (-moveTop / 20);
 | 
			
		||||
				this.pos = basePos + moveLeft;
 | 
			
		||||
				if (this.zoom < 1) this.zoom = 1;
 | 
			
		||||
				if (this.pos > 0) this.pos = 0;
 | 
			
		||||
				if (this.pos < -(((this.data.length - 1) * this.zoom) - this.viewBoxX)) this.pos = -(((this.data.length - 1) * this.zoom) - this.viewBoxX);
 | 
			
		||||
 | 
			
		||||
				this.render();
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
svg
 | 
			
		||||
	display block
 | 
			
		||||
	padding 10px
 | 
			
		||||
	width 100%
 | 
			
		||||
	cursor all-scroll
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										116
									
								
								src/web/app/desktop/views/components/activity.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/web/app/desktop/views/components/activity.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-activity">
 | 
			
		||||
	<template v-if="design == 0">
 | 
			
		||||
		<p class="title">%fa:chart-bar%%i18n:desktop.tags.mk-activity-widget.title%</p>
 | 
			
		||||
		<button @click="toggle" title="%i18n:desktop.tags.mk-activity-widget.toggle%">%fa:sort%</button>
 | 
			
		||||
	</template>
 | 
			
		||||
	<p class="fetching" v-if="fetching">%fa:spinner .pulse .fw%%i18n:common.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<template v-else>
 | 
			
		||||
		<mk-activity-widget-calender v-show="view == 0" :data="[].concat(activity)"/>
 | 
			
		||||
		<mk-activity-widget-chart v-show="view == 1" :data="[].concat(activity)"/>
 | 
			
		||||
	</template>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import Calendar from './activity.calendar.vue';
 | 
			
		||||
import Chart from './activity.chart.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		'mk-activity-widget-calender': Calendar,
 | 
			
		||||
		'mk-activity-widget-chart': Chart
 | 
			
		||||
	},
 | 
			
		||||
	props: {
 | 
			
		||||
		design: {
 | 
			
		||||
			default: 0
 | 
			
		||||
		},
 | 
			
		||||
		initView: {
 | 
			
		||||
			default: 0
 | 
			
		||||
		},
 | 
			
		||||
		user: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			required: true
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			activity: null,
 | 
			
		||||
			view: this.initView
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		(this as any).api('aggregation/users/activity', {
 | 
			
		||||
			user_id: this.user.id,
 | 
			
		||||
			limit: 20 * 7
 | 
			
		||||
		}).then(activity => {
 | 
			
		||||
			this.activity = activity;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		toggle() {
 | 
			
		||||
			if (this.view == 1) {
 | 
			
		||||
				this.view = 0;
 | 
			
		||||
				this.$emit('viewChanged', this.view);
 | 
			
		||||
			} else {
 | 
			
		||||
				this.view++;
 | 
			
		||||
				this.$emit('viewChanged', this.view);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-activity
 | 
			
		||||
	background #fff
 | 
			
		||||
	border solid 1px rgba(0, 0, 0, 0.075)
 | 
			
		||||
	border-radius 6px
 | 
			
		||||
 | 
			
		||||
	&[data-melt]
 | 
			
		||||
		background transparent !important
 | 
			
		||||
		border none !important
 | 
			
		||||
 | 
			
		||||
	> .title
 | 
			
		||||
		z-index 1
 | 
			
		||||
		margin 0
 | 
			
		||||
		padding 0 16px
 | 
			
		||||
		line-height 42px
 | 
			
		||||
		font-size 0.9em
 | 
			
		||||
		font-weight bold
 | 
			
		||||
		color #888
 | 
			
		||||
		box-shadow 0 1px rgba(0, 0, 0, 0.07)
 | 
			
		||||
 | 
			
		||||
		> [data-fa]
 | 
			
		||||
			margin-right 4px
 | 
			
		||||
 | 
			
		||||
	> button
 | 
			
		||||
		position absolute
 | 
			
		||||
		z-index 2
 | 
			
		||||
		top 0
 | 
			
		||||
		right 0
 | 
			
		||||
		padding 0
 | 
			
		||||
		width 42px
 | 
			
		||||
		font-size 0.9em
 | 
			
		||||
		line-height 42px
 | 
			
		||||
		color #ccc
 | 
			
		||||
 | 
			
		||||
		&:hover
 | 
			
		||||
			color #aaa
 | 
			
		||||
 | 
			
		||||
		&:active
 | 
			
		||||
			color #999
 | 
			
		||||
 | 
			
		||||
	> .fetching
 | 
			
		||||
		margin 0
 | 
			
		||||
		padding 16px
 | 
			
		||||
		text-align center
 | 
			
		||||
		color #aaa
 | 
			
		||||
 | 
			
		||||
		> [data-fa]
 | 
			
		||||
			margin-right 4px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -47,7 +47,7 @@ export default Vue.extend({
 | 
			
		||||
			default: 0
 | 
			
		||||
		},
 | 
			
		||||
		start: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			type: Date,
 | 
			
		||||
			required: false
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
@@ -94,7 +94,7 @@ export default Vue.extend({
 | 
			
		||||
		isOutOfRange(day) {
 | 
			
		||||
			const test = (new Date(this.year, this.month - 1, day)).getTime();
 | 
			
		||||
			return test > this.today.getTime() ||
 | 
			
		||||
				(this.start ? test < this.start.getTime() : false);
 | 
			
		||||
				(this.start ? test < (this.start as any).getTime() : false);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		isDonichi(day) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window width='400px' height='550px' @closed="$destroy">
 | 
			
		||||
<mk-window width="400px" height="550px" @closed="$destroy">
 | 
			
		||||
	<span slot="header" :class="$style.header">
 | 
			
		||||
		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロワー
 | 
			
		||||
	</span>
 | 
			
		||||
	<mk-user-followers :user="user"/>
 | 
			
		||||
	<mk-followers-list :user="user"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window width='400px' height='550px' @closed="$destroy">
 | 
			
		||||
<mk-window width="400px" height="550px" @closed="$destroy">
 | 
			
		||||
	<span slot="header" :class="$style.header">
 | 
			
		||||
		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロー
 | 
			
		||||
	</span>
 | 
			
		||||
	<mk-user-following :user="user"/>
 | 
			
		||||
	<mk-following-list :user="user"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -43,8 +43,8 @@ export default Vue.extend({
 | 
			
		||||
				limit: this.limit,
 | 
			
		||||
				offset: this.limit * this.page
 | 
			
		||||
			}).then(users => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.users = users;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		refresh() {
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ import driveNavFolder from './drive-nav-folder.vue';
 | 
			
		||||
import postDetail from './post-detail.vue';
 | 
			
		||||
import settings from './settings.vue';
 | 
			
		||||
import calendar from './calendar.vue';
 | 
			
		||||
import activity from './activity.vue';
 | 
			
		||||
import wNav from './widgets/nav.vue';
 | 
			
		||||
import wCalendar from './widgets/calendar.vue';
 | 
			
		||||
import wPhotoStream from './widgets/photo-stream.vue';
 | 
			
		||||
@@ -78,6 +79,7 @@ Vue.component('mk-drive-nav-folder', driveNavFolder);
 | 
			
		||||
Vue.component('mk-post-detail', postDetail);
 | 
			
		||||
Vue.component('mk-settings', settings);
 | 
			
		||||
Vue.component('mk-calendar', calendar);
 | 
			
		||||
Vue.component('mk-activity', activity);
 | 
			
		||||
Vue.component('mkw-nav', wNav);
 | 
			
		||||
Vue.component('mkw-calendar', wCalendar);
 | 
			
		||||
Vue.component('mkw-photo-stream', wPhotoStream);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,8 @@ export default Vue.extend({
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		(this as any).api('mute/list').then(x => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.users = x.users;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
		class="read-more"
 | 
			
		||||
		v-if="p.reply && p.reply.reply_id && context == null"
 | 
			
		||||
		title="会話をもっと読み込む"
 | 
			
		||||
		@click="loadContext"
 | 
			
		||||
		@click="fetchContext"
 | 
			
		||||
		:disabled="contextFetching"
 | 
			
		||||
	>
 | 
			
		||||
		<template v-if="!contextFetching">%fa:ellipsis-v%</template>
 | 
			
		||||
 
 | 
			
		||||
@@ -57,8 +57,8 @@ export default Vue.extend({
 | 
			
		||||
			(this as any).api('posts/timeline', {
 | 
			
		||||
				until_date: this.date ? this.date.getTime() : undefined
 | 
			
		||||
			}).then(posts => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.posts = posts;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				if (cb) cb();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -45,9 +45,9 @@ export default Vue.extend({
 | 
			
		||||
		_fetch(cb) {
 | 
			
		||||
			this.fetching = true;
 | 
			
		||||
			this.fetch(this.mode == 'iknow', this.limit, null, obj => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.users = obj.users;
 | 
			
		||||
				this.next = obj.next;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				if (cb) cb();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -46,8 +46,8 @@ export default define({
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.broadcasts = broadcasts;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
 
 | 
			
		||||
@@ -35,8 +35,8 @@ export default define({
 | 
			
		||||
			type: 'image/*',
 | 
			
		||||
			limit: 9
 | 
			
		||||
		}).then(images => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.images = images;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
 
 | 
			
		||||
@@ -93,8 +93,8 @@ export default define({
 | 
			
		||||
				type: 'image/*',
 | 
			
		||||
				limit: 100
 | 
			
		||||
			}).then(images => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.images = images;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				(this.$refs.slideA as any).style.backgroundImage = '';
 | 
			
		||||
				(this.$refs.slideB as any).style.backgroundImage = '';
 | 
			
		||||
				this.change();
 | 
			
		||||
 
 | 
			
		||||
@@ -24,8 +24,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('users/show', {
 | 
			
		||||
			username: this.username
 | 
			
		||||
		}).then(user => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.user = user;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
 | 
			
		||||
			document.title = 'メッセージ: ' + this.user.name;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('posts/show', {
 | 
			
		||||
			post_id: this.postId
 | 
			
		||||
		}).then(post => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.post = post;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
 | 
			
		||||
			Progress.done();
 | 
			
		||||
		});
 | 
			
		||||
 
 | 
			
		||||
@@ -45,8 +45,8 @@ export default Vue.extend({
 | 
			
		||||
		window.addEventListener('scroll', this.onScroll);
 | 
			
		||||
 | 
			
		||||
		(this as any).api('posts/search', parse(this.query)).then(posts => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.posts = posts;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
 
 | 
			
		||||
@@ -27,8 +27,8 @@ export default Vue.extend({
 | 
			
		||||
			iknow: true,
 | 
			
		||||
			limit: 16
 | 
			
		||||
		}).then(x => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.users = x.users;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,18 @@
 | 
			
		||||
<div class="mk-user-friends">
 | 
			
		||||
	<p class="title">%fa:users%%i18n:desktop.tags.mk-user.frequently-replied-users.title%</p>
 | 
			
		||||
	<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:desktop.tags.mk-user.frequently-replied-users.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div class="user" v-if="!fetching && users.length != 0" each={ _user in users }>
 | 
			
		||||
		<a class="avatar-anchor" href={ '/' + _user.username }>
 | 
			
		||||
			<img class="avatar" src={ _user.avatar_url + '?thumbnail&size=42' } alt="" v-user-preview={ _user.id }/>
 | 
			
		||||
		</a>
 | 
			
		||||
		<div class="body">
 | 
			
		||||
			<a class="name" href={ '/' + _user.username } v-user-preview={ _user.id }>{ _user.name }</a>
 | 
			
		||||
			<p class="username">@{ _user.username }</p>
 | 
			
		||||
	<template v-if="!fetching && users.length != 0">
 | 
			
		||||
		<div class="user" v-for="friend in users">
 | 
			
		||||
			<router-link class="avatar-anchor" to="`/${friend.username}`">
 | 
			
		||||
				<img class="avatar" :src="`${friend.avatar_url}?thumbnail&size=42`" alt="" v-user-preview="friend.id"/>
 | 
			
		||||
			</router-link>
 | 
			
		||||
			<div class="body">
 | 
			
		||||
				<router-link class="name" to="`/${friend.username}`" v-user-preview="friend.id">{{ friend.name }}</router-link>
 | 
			
		||||
				<p class="username">@{{ friend.username }}</p>
 | 
			
		||||
			</div>
 | 
			
		||||
			<mk-follow-button :user="friend"/>
 | 
			
		||||
		</div>
 | 
			
		||||
		<mk-follow-button user={ _user }/>
 | 
			
		||||
	</div>
 | 
			
		||||
	</template>
 | 
			
		||||
	<p class="empty" v-if="!fetching && users.length == 0">%i18n:desktop.tags.mk-user.frequently-replied-users.no-users%</p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -31,8 +33,8 @@ export default Vue.extend({
 | 
			
		||||
			user_id: this.user.id,
 | 
			
		||||
			limit: 4
 | 
			
		||||
		}).then(docs => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.users = docs.map(doc => doc.user);
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,8 @@
 | 
			
		||||
	</main>
 | 
			
		||||
	<div>
 | 
			
		||||
		<div ref="right">
 | 
			
		||||
			<mk-calendar-widget @warp="warp" :start="new Date(user.created_at)"/>
 | 
			
		||||
			<mk-activity-widget :user="user"/>
 | 
			
		||||
			<mk-calendar @chosen="warp" :start="new Date(user.created_at)"/>
 | 
			
		||||
			<mk-activity :user="user"/>
 | 
			
		||||
			<mk-user-friends :user="user"/>
 | 
			
		||||
			<div class="nav"><mk-nav/></div>
 | 
			
		||||
		</div>
 | 
			
		||||
@@ -25,7 +25,20 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import MkUserTimeline from './user-timeline.vue';
 | 
			
		||||
import MkUserProfile from './user-profile.vue';
 | 
			
		||||
import MkUserPhotos from './user-photos.vue';
 | 
			
		||||
import MkUserFollowersYouKnow from './user-followers-you-know.vue';
 | 
			
		||||
import MkUserFriends from './user-friends.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		'mk-user-timeline': MkUserTimeline,
 | 
			
		||||
		'mk-user-profile': MkUserProfile,
 | 
			
		||||
		'mk-user-photos': MkUserPhotos,
 | 
			
		||||
		'mk-user-followers-you-know': MkUserFollowersYouKnow,
 | 
			
		||||
		'mk-user-friends': MkUserFriends
 | 
			
		||||
	},
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	methods: {
 | 
			
		||||
		warp(date) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,7 @@
 | 
			
		||||
	<p class="title">%fa:camera%%i18n:desktop.tags.mk-user.photos.title%</p>
 | 
			
		||||
	<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:desktop.tags.mk-user.photos.loading%<mk-ellipsis/></p>
 | 
			
		||||
	<div class="stream" v-if="!fetching && images.length > 0">
 | 
			
		||||
		<div v-for="image in images" :key="image.id"
 | 
			
		||||
			class="img"
 | 
			
		||||
		<div v-for="image in images" class="img"
 | 
			
		||||
			:style="`background-image: url(${image.url}?thumbnail&size=256)`"
 | 
			
		||||
		></div>
 | 
			
		||||
	</div>
 | 
			
		||||
@@ -28,12 +27,12 @@ export default Vue.extend({
 | 
			
		||||
			with_media: true,
 | 
			
		||||
			limit: 9
 | 
			
		||||
		}).then(posts => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			posts.forEach(post => {
 | 
			
		||||
				post.media.forEach(media => {
 | 
			
		||||
					if (this.images.length < 9) this.images.push(media);
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
		<p>%fa:B twitter%<a :href="`https://twitter.com/${user.twitter.screen_name}`" target="_blank">@{{ user.twitter.screen_name }}</a></p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="status">
 | 
			
		||||
	  <p class="posts-count">%fa:angle-right%<a>{{ user.posts_count }}</a><b>投稿</b></p>
 | 
			
		||||
		<p class="posts-count">%fa:angle-right%<a>{{ user.posts_count }}</a><b>投稿</b></p>
 | 
			
		||||
		<p class="following">%fa:angle-right%<a @click="showFollowing">{{ user.following_count }}</a>人を<b>フォロー</b></p>
 | 
			
		||||
		<p class="followers">%fa:angle-right%<a @click="showFollowers">{{ user.followers_count }}</a>人の<b>フォロワー</b></p>
 | 
			
		||||
	</div>
 | 
			
		||||
@@ -23,7 +23,9 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
const age = require('s-age');
 | 
			
		||||
import age from 's-age';
 | 
			
		||||
import MkFollowingWindow from '../../components/following-window.vue';
 | 
			
		||||
import MkFollowersWindow from '../../components/followers-window.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
@@ -34,8 +36,7 @@ export default Vue.extend({
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		showFollowing() {
 | 
			
		||||
			document.body.appendChild(new MkUserFollowingWindow({
 | 
			
		||||
 | 
			
		||||
			document.body.appendChild(new MkFollowingWindow({
 | 
			
		||||
				propsData: {
 | 
			
		||||
					user: this.user
 | 
			
		||||
				}
 | 
			
		||||
@@ -43,8 +44,7 @@ export default Vue.extend({
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		showFollowers() {
 | 
			
		||||
			document.body.appendChild(new MkUserFollowersWindow({
 | 
			
		||||
 | 
			
		||||
			document.body.appendChild(new MkFollowersWindow({
 | 
			
		||||
				propsData: {
 | 
			
		||||
					user: this.user
 | 
			
		||||
				}
 | 
			
		||||
@@ -56,7 +56,7 @@ export default Vue.extend({
 | 
			
		||||
				user_id: this.user.id
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				this.user.is_muted = true;
 | 
			
		||||
			}, e => {
 | 
			
		||||
			}, () => {
 | 
			
		||||
				alert('error');
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
@@ -66,7 +66,7 @@ export default Vue.extend({
 | 
			
		||||
				user_id: this.user.id
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				this.user.is_muted = false;
 | 
			
		||||
			}, e => {
 | 
			
		||||
			}, () => {
 | 
			
		||||
				alert('error');
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -65,8 +65,8 @@ export default Vue.extend({
 | 
			
		||||
				until_date: this.date ? this.date.getTime() : undefined,
 | 
			
		||||
				with_replies: this.mode == 'with-replies'
 | 
			
		||||
			}).then(posts => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.posts = posts;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				if (cb) cb();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
@@ -35,8 +35,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('users/show', {
 | 
			
		||||
			username: this.$route.params.user
 | 
			
		||||
		}).then(user => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.user = user;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			Progress.done();
 | 
			
		||||
			document.title = user.name + ' | Misskey';
 | 
			
		||||
		});
 | 
			
		||||
 
 | 
			
		||||
@@ -351,13 +351,14 @@ export default Vue.extend({
 | 
			
		||||
			(this as any).api('drive/files/show', {
 | 
			
		||||
				file_id: file
 | 
			
		||||
			}).then(file => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.file = file;
 | 
			
		||||
				this.folder = null;
 | 
			
		||||
				this.hierarchyFolders = [];
 | 
			
		||||
 | 
			
		||||
				if (file.folder) this.dive(file.folder);
 | 
			
		||||
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
 | 
			
		||||
				this.$emit('open-file', this.file, silent);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -36,8 +36,8 @@ export default Vue.extend({
 | 
			
		||||
				limit: this.limit,
 | 
			
		||||
				offset: this.limit * this.page
 | 
			
		||||
			}).then(users => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.users = users;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		refresh() {
 | 
			
		||||
 
 | 
			
		||||
@@ -63,8 +63,8 @@ export default Vue.extend({
 | 
			
		||||
			(this as any).api('posts/timeline', {
 | 
			
		||||
				until_date: this.date ? (this.date as any).getTime() : undefined
 | 
			
		||||
			}).then(posts => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.posts = posts;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				if (cb) cb();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -31,8 +31,8 @@ export default Vue.extend({
 | 
			
		||||
			user_id: this.user.id,
 | 
			
		||||
			with_media: this.withMedia
 | 
			
		||||
		}).then(posts => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.posts = posts;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.$emit('loaded');
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,9 +41,9 @@ export default Vue.extend({
 | 
			
		||||
		_fetch(cb) {
 | 
			
		||||
			this.fetching = true;
 | 
			
		||||
			this.fetch(this.mode == 'iknow', this.limit, null, obj => {
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				this.users = obj.users;
 | 
			
		||||
				this.next = obj.next;
 | 
			
		||||
				this.fetching = false;
 | 
			
		||||
				if (cb) cb();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('users/show', {
 | 
			
		||||
			username: this.username
 | 
			
		||||
		}).then(user => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.user = user;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
 | 
			
		||||
			document.title = '%i18n:mobile.tags.mk-user-followers-page.followers-of%'.replace('{}', user.name) + ' | Misskey';
 | 
			
		||||
			document.documentElement.style.background = '#313a42';
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('users/show', {
 | 
			
		||||
			username: this.username
 | 
			
		||||
		}).then(user => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.user = user;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
 | 
			
		||||
			document.title = '%i18n:mobile.tags.mk-user-followers-page.followers-of%'.replace('{}', user.name) + ' | Misskey';
 | 
			
		||||
			document.documentElement.style.background = '#313a42';
 | 
			
		||||
 
 | 
			
		||||
@@ -32,8 +32,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('posts/show', {
 | 
			
		||||
			post_id: this.postId
 | 
			
		||||
		}).then(post => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.post = post;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
 | 
			
		||||
			Progress.done();
 | 
			
		||||
		});
 | 
			
		||||
 
 | 
			
		||||
@@ -88,8 +88,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('users/show', {
 | 
			
		||||
			username: this.username
 | 
			
		||||
		}).then(user => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.user = user;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
 | 
			
		||||
			Progress.done();
 | 
			
		||||
			document.title = user.name + ' | Misskey';
 | 
			
		||||
 
 | 
			
		||||
@@ -22,8 +22,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('users/get_frequently_replied_users', {
 | 
			
		||||
			user_id: this.user.id
 | 
			
		||||
		}).then(res => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.users = res.map(x => x.user);
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,6 @@ export default Vue.extend({
 | 
			
		||||
			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({
 | 
			
		||||
@@ -37,6 +36,7 @@ export default Vue.extend({
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -22,8 +22,8 @@ export default Vue.extend({
 | 
			
		||||
		(this as any).api('users/posts', {
 | 
			
		||||
			user_id: this.user.id
 | 
			
		||||
		}).then(posts => {
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
			this.posts = posts;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user