wip
This commit is contained in:
		| @@ -28,7 +28,6 @@ | |||||||
| 			this.$root.$data.os.api('i/authorized_apps').then(apps => { | 			this.$root.$data.os.api('i/authorized_apps').then(apps => { | ||||||
| 				this.apps = apps; | 				this.apps = apps; | ||||||
| 				this.fetching = false; | 				this.fetching = false; | ||||||
| 				this.update(); |  | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	</script> | 	</script> | ||||||
|   | |||||||
| @@ -78,8 +78,8 @@ export default Vue.extend({ | |||||||
| 		this.connection.on('read', this.onRead); | 		this.connection.on('read', this.onRead); | ||||||
|  |  | ||||||
| 		(this as any).api('messaging/history').then(messages => { | 		(this as any).api('messaging/history').then(messages => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.messages = messages; | 			this.messages = messages; | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
| 	beforeDestroy() { | 	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 | 			default: 0 | ||||||
| 		}, | 		}, | ||||||
| 		start: { | 		start: { | ||||||
| 			type: Object, | 			type: Date, | ||||||
| 			required: false | 			required: false | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| @@ -94,7 +94,7 @@ export default Vue.extend({ | |||||||
| 		isOutOfRange(day) { | 		isOutOfRange(day) { | ||||||
| 			const test = (new Date(this.year, this.month - 1, day)).getTime(); | 			const test = (new Date(this.year, this.month - 1, day)).getTime(); | ||||||
| 			return test > this.today.getTime() || | 			return test > this.today.getTime() || | ||||||
| 				(this.start ? test < this.start.getTime() : false); | 				(this.start ? test < (this.start as any).getTime() : false); | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		isDonichi(day) { | 		isDonichi(day) { | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| <template> | <template> | ||||||
| <mk-window width='400px' height='550px' @closed="$destroy"> | <mk-window width="400px" height="550px" @closed="$destroy"> | ||||||
| 	<span slot="header" :class="$style.header"> | 	<span slot="header" :class="$style.header"> | ||||||
| 		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロワー | 		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロワー | ||||||
| 	</span> | 	</span> | ||||||
| 	<mk-user-followers :user="user"/> | 	<mk-followers-list :user="user"/> | ||||||
| </mk-window> | </mk-window> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| <template> | <template> | ||||||
| <mk-window width='400px' height='550px' @closed="$destroy"> | <mk-window width="400px" height="550px" @closed="$destroy"> | ||||||
| 	<span slot="header" :class="$style.header"> | 	<span slot="header" :class="$style.header"> | ||||||
| 		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロー | 		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロー | ||||||
| 	</span> | 	</span> | ||||||
| 	<mk-user-following :user="user"/> | 	<mk-following-list :user="user"/> | ||||||
| </mk-window> | </mk-window> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -43,8 +43,8 @@ export default Vue.extend({ | |||||||
| 				limit: this.limit, | 				limit: this.limit, | ||||||
| 				offset: this.limit * this.page | 				offset: this.limit * this.page | ||||||
| 			}).then(users => { | 			}).then(users => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.users = users; | 				this.users = users; | ||||||
|  | 				this.fetching = false; | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| 		refresh() { | 		refresh() { | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ import driveNavFolder from './drive-nav-folder.vue'; | |||||||
| import postDetail from './post-detail.vue'; | import postDetail from './post-detail.vue'; | ||||||
| import settings from './settings.vue'; | import settings from './settings.vue'; | ||||||
| import calendar from './calendar.vue'; | import calendar from './calendar.vue'; | ||||||
|  | import activity from './activity.vue'; | ||||||
| import wNav from './widgets/nav.vue'; | import wNav from './widgets/nav.vue'; | ||||||
| import wCalendar from './widgets/calendar.vue'; | import wCalendar from './widgets/calendar.vue'; | ||||||
| import wPhotoStream from './widgets/photo-stream.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-post-detail', postDetail); | ||||||
| Vue.component('mk-settings', settings); | Vue.component('mk-settings', settings); | ||||||
| Vue.component('mk-calendar', calendar); | Vue.component('mk-calendar', calendar); | ||||||
|  | Vue.component('mk-activity', activity); | ||||||
| Vue.component('mkw-nav', wNav); | Vue.component('mkw-nav', wNav); | ||||||
| Vue.component('mkw-calendar', wCalendar); | Vue.component('mkw-calendar', wCalendar); | ||||||
| Vue.component('mkw-photo-stream', wPhotoStream); | Vue.component('mkw-photo-stream', wPhotoStream); | ||||||
|   | |||||||
| @@ -23,8 +23,8 @@ export default Vue.extend({ | |||||||
| 	}, | 	}, | ||||||
| 	mounted() { | 	mounted() { | ||||||
| 		(this as any).api('mute/list').then(x => { | 		(this as any).api('mute/list').then(x => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.users = x.users; | 			this.users = x.users; | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
| 		class="read-more" | 		class="read-more" | ||||||
| 		v-if="p.reply && p.reply.reply_id && context == null" | 		v-if="p.reply && p.reply.reply_id && context == null" | ||||||
| 		title="会話をもっと読み込む" | 		title="会話をもっと読み込む" | ||||||
| 		@click="loadContext" | 		@click="fetchContext" | ||||||
| 		:disabled="contextFetching" | 		:disabled="contextFetching" | ||||||
| 	> | 	> | ||||||
| 		<template v-if="!contextFetching">%fa:ellipsis-v%</template> | 		<template v-if="!contextFetching">%fa:ellipsis-v%</template> | ||||||
|   | |||||||
| @@ -57,8 +57,8 @@ export default Vue.extend({ | |||||||
| 			(this as any).api('posts/timeline', { | 			(this as any).api('posts/timeline', { | ||||||
| 				until_date: this.date ? this.date.getTime() : undefined | 				until_date: this.date ? this.date.getTime() : undefined | ||||||
| 			}).then(posts => { | 			}).then(posts => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.posts = posts; | 				this.posts = posts; | ||||||
|  | 				this.fetching = false; | ||||||
| 				if (cb) cb(); | 				if (cb) cb(); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -45,9 +45,9 @@ export default Vue.extend({ | |||||||
| 		_fetch(cb) { | 		_fetch(cb) { | ||||||
| 			this.fetching = true; | 			this.fetching = true; | ||||||
| 			this.fetch(this.mode == 'iknow', this.limit, null, obj => { | 			this.fetch(this.mode == 'iknow', this.limit, null, obj => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.users = obj.users; | 				this.users = obj.users; | ||||||
| 				this.next = obj.next; | 				this.next = obj.next; | ||||||
|  | 				this.fetching = false; | ||||||
| 				if (cb) cb(); | 				if (cb) cb(); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -46,8 +46,8 @@ export default define({ | |||||||
| 					} | 					} | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.broadcasts = broadcasts; | 			this.broadcasts = broadcasts; | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
| 	methods: { | 	methods: { | ||||||
|   | |||||||
| @@ -35,8 +35,8 @@ export default define({ | |||||||
| 			type: 'image/*', | 			type: 'image/*', | ||||||
| 			limit: 9 | 			limit: 9 | ||||||
| 		}).then(images => { | 		}).then(images => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.images = images; | 			this.images = images; | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
| 	beforeDestroy() { | 	beforeDestroy() { | ||||||
|   | |||||||
| @@ -93,8 +93,8 @@ export default define({ | |||||||
| 				type: 'image/*', | 				type: 'image/*', | ||||||
| 				limit: 100 | 				limit: 100 | ||||||
| 			}).then(images => { | 			}).then(images => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.images = images; | 				this.images = images; | ||||||
|  | 				this.fetching = false; | ||||||
| 				(this.$refs.slideA as any).style.backgroundImage = ''; | 				(this.$refs.slideA as any).style.backgroundImage = ''; | ||||||
| 				(this.$refs.slideB as any).style.backgroundImage = ''; | 				(this.$refs.slideB as any).style.backgroundImage = ''; | ||||||
| 				this.change(); | 				this.change(); | ||||||
|   | |||||||
| @@ -24,8 +24,8 @@ export default Vue.extend({ | |||||||
| 		(this as any).api('users/show', { | 		(this as any).api('users/show', { | ||||||
| 			username: this.username | 			username: this.username | ||||||
| 		}).then(user => { | 		}).then(user => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.user = user; | 			this.user = user; | ||||||
|  | 			this.fetching = false; | ||||||
|  |  | ||||||
| 			document.title = 'メッセージ: ' + this.user.name; | 			document.title = 'メッセージ: ' + this.user.name; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ export default Vue.extend({ | |||||||
| 		(this as any).api('posts/show', { | 		(this as any).api('posts/show', { | ||||||
| 			post_id: this.postId | 			post_id: this.postId | ||||||
| 		}).then(post => { | 		}).then(post => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.post = post; | 			this.post = post; | ||||||
|  | 			this.fetching = false; | ||||||
|  |  | ||||||
| 			Progress.done(); | 			Progress.done(); | ||||||
| 		}); | 		}); | ||||||
|   | |||||||
| @@ -45,8 +45,8 @@ export default Vue.extend({ | |||||||
| 		window.addEventListener('scroll', this.onScroll); | 		window.addEventListener('scroll', this.onScroll); | ||||||
|  |  | ||||||
| 		(this as any).api('posts/search', parse(this.query)).then(posts => { | 		(this as any).api('posts/search', parse(this.query)).then(posts => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.posts = posts; | 			this.posts = posts; | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
| 	beforeDestroy() { | 	beforeDestroy() { | ||||||
|   | |||||||
| @@ -27,8 +27,8 @@ export default Vue.extend({ | |||||||
| 			iknow: true, | 			iknow: true, | ||||||
| 			limit: 16 | 			limit: 16 | ||||||
| 		}).then(x => { | 		}).then(x => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.users = x.users; | 			this.users = x.users; | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -2,16 +2,18 @@ | |||||||
| <div class="mk-user-friends"> | <div class="mk-user-friends"> | ||||||
| 	<p class="title">%fa:users%%i18n:desktop.tags.mk-user.frequently-replied-users.title%</p> | 	<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> | 	<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 }> | 	<template v-if="!fetching && users.length != 0"> | ||||||
| 		<a class="avatar-anchor" href={ '/' + _user.username }> | 		<div class="user" v-for="friend in users"> | ||||||
| 			<img class="avatar" src={ _user.avatar_url + '?thumbnail&size=42' } alt="" v-user-preview={ _user.id }/> | 			<router-link class="avatar-anchor" to="`/${friend.username}`"> | ||||||
| 		</a> | 				<img class="avatar" :src="`${friend.avatar_url}?thumbnail&size=42`" alt="" v-user-preview="friend.id"/> | ||||||
|  | 			</router-link> | ||||||
| 			<div class="body"> | 			<div class="body"> | ||||||
| 			<a class="name" href={ '/' + _user.username } v-user-preview={ _user.id }>{ _user.name }</a> | 				<router-link class="name" to="`/${friend.username}`" v-user-preview="friend.id">{{ friend.name }}</router-link> | ||||||
| 			<p class="username">@{ _user.username }</p> | 				<p class="username">@{{ friend.username }}</p> | ||||||
| 			</div> | 			</div> | ||||||
| 		<mk-follow-button user={ _user }/> | 			<mk-follow-button :user="friend"/> | ||||||
| 		</div> | 		</div> | ||||||
|  | 	</template> | ||||||
| 	<p class="empty" v-if="!fetching && users.length == 0">%i18n:desktop.tags.mk-user.frequently-replied-users.no-users%</p> | 	<p class="empty" v-if="!fetching && users.length == 0">%i18n:desktop.tags.mk-user.frequently-replied-users.no-users%</p> | ||||||
| </div> | </div> | ||||||
| </template> | </template> | ||||||
| @@ -31,8 +33,8 @@ export default Vue.extend({ | |||||||
| 			user_id: this.user.id, | 			user_id: this.user.id, | ||||||
| 			limit: 4 | 			limit: 4 | ||||||
| 		}).then(docs => { | 		}).then(docs => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.users = docs.map(doc => doc.user); | 			this.users = docs.map(doc => doc.user); | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -14,8 +14,8 @@ | |||||||
| 	</main> | 	</main> | ||||||
| 	<div> | 	<div> | ||||||
| 		<div ref="right"> | 		<div ref="right"> | ||||||
| 			<mk-calendar-widget @warp="warp" :start="new Date(user.created_at)"/> | 			<mk-calendar @chosen="warp" :start="new Date(user.created_at)"/> | ||||||
| 			<mk-activity-widget :user="user"/> | 			<mk-activity :user="user"/> | ||||||
| 			<mk-user-friends :user="user"/> | 			<mk-user-friends :user="user"/> | ||||||
| 			<div class="nav"><mk-nav/></div> | 			<div class="nav"><mk-nav/></div> | ||||||
| 		</div> | 		</div> | ||||||
| @@ -25,7 +25,20 @@ | |||||||
|  |  | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import Vue from 'vue'; | 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({ | 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'], | 	props: ['user'], | ||||||
| 	methods: { | 	methods: { | ||||||
| 		warp(date) { | 		warp(date) { | ||||||
|   | |||||||
| @@ -3,8 +3,7 @@ | |||||||
| 	<p class="title">%fa:camera%%i18n:desktop.tags.mk-user.photos.title%</p> | 	<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> | 	<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 class="stream" v-if="!fetching && images.length > 0"> | ||||||
| 		<div v-for="image in images" :key="image.id" | 		<div v-for="image in images" class="img" | ||||||
| 			class="img" |  | ||||||
| 			:style="`background-image: url(${image.url}?thumbnail&size=256)`" | 			:style="`background-image: url(${image.url}?thumbnail&size=256)`" | ||||||
| 		></div> | 		></div> | ||||||
| 	</div> | 	</div> | ||||||
| @@ -28,12 +27,12 @@ export default Vue.extend({ | |||||||
| 			with_media: true, | 			with_media: true, | ||||||
| 			limit: 9 | 			limit: 9 | ||||||
| 		}).then(posts => { | 		}).then(posts => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			posts.forEach(post => { | 			posts.forEach(post => { | ||||||
| 				post.media.forEach(media => { | 				post.media.forEach(media => { | ||||||
| 					if (this.images.length < 9) this.images.push(media); | 					if (this.images.length < 9) this.images.push(media); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -23,7 +23,9 @@ | |||||||
|  |  | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import Vue from 'vue'; | 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({ | export default Vue.extend({ | ||||||
| 	props: ['user'], | 	props: ['user'], | ||||||
| @@ -34,8 +36,7 @@ export default Vue.extend({ | |||||||
| 	}, | 	}, | ||||||
| 	methods: { | 	methods: { | ||||||
| 		showFollowing() { | 		showFollowing() { | ||||||
| 			document.body.appendChild(new MkUserFollowingWindow({ | 			document.body.appendChild(new MkFollowingWindow({ | ||||||
|  |  | ||||||
| 				propsData: { | 				propsData: { | ||||||
| 					user: this.user | 					user: this.user | ||||||
| 				} | 				} | ||||||
| @@ -43,8 +44,7 @@ export default Vue.extend({ | |||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
| 		showFollowers() { | 		showFollowers() { | ||||||
| 			document.body.appendChild(new MkUserFollowersWindow({ | 			document.body.appendChild(new MkFollowersWindow({ | ||||||
|  |  | ||||||
| 				propsData: { | 				propsData: { | ||||||
| 					user: this.user | 					user: this.user | ||||||
| 				} | 				} | ||||||
| @@ -56,7 +56,7 @@ export default Vue.extend({ | |||||||
| 				user_id: this.user.id | 				user_id: this.user.id | ||||||
| 			}).then(() => { | 			}).then(() => { | ||||||
| 				this.user.is_muted = true; | 				this.user.is_muted = true; | ||||||
| 			}, e => { | 			}, () => { | ||||||
| 				alert('error'); | 				alert('error'); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| @@ -66,7 +66,7 @@ export default Vue.extend({ | |||||||
| 				user_id: this.user.id | 				user_id: this.user.id | ||||||
| 			}).then(() => { | 			}).then(() => { | ||||||
| 				this.user.is_muted = false; | 				this.user.is_muted = false; | ||||||
| 			}, e => { | 			}, () => { | ||||||
| 				alert('error'); | 				alert('error'); | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -65,8 +65,8 @@ export default Vue.extend({ | |||||||
| 				until_date: this.date ? this.date.getTime() : undefined, | 				until_date: this.date ? this.date.getTime() : undefined, | ||||||
| 				with_replies: this.mode == 'with-replies' | 				with_replies: this.mode == 'with-replies' | ||||||
| 			}).then(posts => { | 			}).then(posts => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.posts = posts; | 				this.posts = posts; | ||||||
|  | 				this.fetching = false; | ||||||
| 				if (cb) cb(); | 				if (cb) cb(); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| @@ -35,8 +35,8 @@ export default Vue.extend({ | |||||||
| 		(this as any).api('users/show', { | 		(this as any).api('users/show', { | ||||||
| 			username: this.$route.params.user | 			username: this.$route.params.user | ||||||
| 		}).then(user => { | 		}).then(user => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.user = user; | 			this.user = user; | ||||||
|  | 			this.fetching = false; | ||||||
| 			Progress.done(); | 			Progress.done(); | ||||||
| 			document.title = user.name + ' | Misskey'; | 			document.title = user.name + ' | Misskey'; | ||||||
| 		}); | 		}); | ||||||
|   | |||||||
| @@ -351,13 +351,14 @@ export default Vue.extend({ | |||||||
| 			(this as any).api('drive/files/show', { | 			(this as any).api('drive/files/show', { | ||||||
| 				file_id: file | 				file_id: file | ||||||
| 			}).then(file => { | 			}).then(file => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.file = file; | 				this.file = file; | ||||||
| 				this.folder = null; | 				this.folder = null; | ||||||
| 				this.hierarchyFolders = []; | 				this.hierarchyFolders = []; | ||||||
|  |  | ||||||
| 				if (file.folder) this.dive(file.folder); | 				if (file.folder) this.dive(file.folder); | ||||||
|  |  | ||||||
|  | 				this.fetching = false; | ||||||
|  |  | ||||||
| 				this.$emit('open-file', this.file, silent); | 				this.$emit('open-file', this.file, silent); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -36,8 +36,8 @@ export default Vue.extend({ | |||||||
| 				limit: this.limit, | 				limit: this.limit, | ||||||
| 				offset: this.limit * this.page | 				offset: this.limit * this.page | ||||||
| 			}).then(users => { | 			}).then(users => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.users = users; | 				this.users = users; | ||||||
|  | 				this.fetching = false; | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| 		refresh() { | 		refresh() { | ||||||
|   | |||||||
| @@ -63,8 +63,8 @@ export default Vue.extend({ | |||||||
| 			(this as any).api('posts/timeline', { | 			(this as any).api('posts/timeline', { | ||||||
| 				until_date: this.date ? (this.date as any).getTime() : undefined | 				until_date: this.date ? (this.date as any).getTime() : undefined | ||||||
| 			}).then(posts => { | 			}).then(posts => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.posts = posts; | 				this.posts = posts; | ||||||
|  | 				this.fetching = false; | ||||||
| 				if (cb) cb(); | 				if (cb) cb(); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -31,8 +31,8 @@ export default Vue.extend({ | |||||||
| 			user_id: this.user.id, | 			user_id: this.user.id, | ||||||
| 			with_media: this.withMedia | 			with_media: this.withMedia | ||||||
| 		}).then(posts => { | 		}).then(posts => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.posts = posts; | 			this.posts = posts; | ||||||
|  | 			this.fetching = false; | ||||||
| 			this.$emit('loaded'); | 			this.$emit('loaded'); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -41,9 +41,9 @@ export default Vue.extend({ | |||||||
| 		_fetch(cb) { | 		_fetch(cb) { | ||||||
| 			this.fetching = true; | 			this.fetching = true; | ||||||
| 			this.fetch(this.mode == 'iknow', this.limit, null, obj => { | 			this.fetch(this.mode == 'iknow', this.limit, null, obj => { | ||||||
| 				this.fetching = false; |  | ||||||
| 				this.users = obj.users; | 				this.users = obj.users; | ||||||
| 				this.next = obj.next; | 				this.next = obj.next; | ||||||
|  | 				this.fetching = false; | ||||||
| 				if (cb) cb(); | 				if (cb) cb(); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ export default Vue.extend({ | |||||||
| 		(this as any).api('users/show', { | 		(this as any).api('users/show', { | ||||||
| 			username: this.username | 			username: this.username | ||||||
| 		}).then(user => { | 		}).then(user => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.user = user; | 			this.user = user; | ||||||
|  | 			this.fetching = false; | ||||||
|  |  | ||||||
| 			document.title = '%i18n:mobile.tags.mk-user-followers-page.followers-of%'.replace('{}', user.name) + ' | Misskey'; | 			document.title = '%i18n:mobile.tags.mk-user-followers-page.followers-of%'.replace('{}', user.name) + ' | Misskey'; | ||||||
| 			document.documentElement.style.background = '#313a42'; | 			document.documentElement.style.background = '#313a42'; | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ export default Vue.extend({ | |||||||
| 		(this as any).api('users/show', { | 		(this as any).api('users/show', { | ||||||
| 			username: this.username | 			username: this.username | ||||||
| 		}).then(user => { | 		}).then(user => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.user = user; | 			this.user = user; | ||||||
|  | 			this.fetching = false; | ||||||
|  |  | ||||||
| 			document.title = '%i18n:mobile.tags.mk-user-followers-page.followers-of%'.replace('{}', user.name) + ' | Misskey'; | 			document.title = '%i18n:mobile.tags.mk-user-followers-page.followers-of%'.replace('{}', user.name) + ' | Misskey'; | ||||||
| 			document.documentElement.style.background = '#313a42'; | 			document.documentElement.style.background = '#313a42'; | ||||||
|   | |||||||
| @@ -32,8 +32,8 @@ export default Vue.extend({ | |||||||
| 		(this as any).api('posts/show', { | 		(this as any).api('posts/show', { | ||||||
| 			post_id: this.postId | 			post_id: this.postId | ||||||
| 		}).then(post => { | 		}).then(post => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.post = post; | 			this.post = post; | ||||||
|  | 			this.fetching = false; | ||||||
|  |  | ||||||
| 			Progress.done(); | 			Progress.done(); | ||||||
| 		}); | 		}); | ||||||
|   | |||||||
| @@ -88,8 +88,8 @@ export default Vue.extend({ | |||||||
| 		(this as any).api('users/show', { | 		(this as any).api('users/show', { | ||||||
| 			username: this.username | 			username: this.username | ||||||
| 		}).then(user => { | 		}).then(user => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.user = user; | 			this.user = user; | ||||||
|  | 			this.fetching = false; | ||||||
|  |  | ||||||
| 			Progress.done(); | 			Progress.done(); | ||||||
| 			document.title = user.name + ' | Misskey'; | 			document.title = user.name + ' | Misskey'; | ||||||
|   | |||||||
| @@ -22,8 +22,8 @@ export default Vue.extend({ | |||||||
| 		(this as any).api('users/get_frequently_replied_users', { | 		(this as any).api('users/get_frequently_replied_users', { | ||||||
| 			user_id: this.user.id | 			user_id: this.user.id | ||||||
| 		}).then(res => { | 		}).then(res => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.users = res.map(x => x.user); | 			this.users = res.map(x => x.user); | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -28,7 +28,6 @@ export default Vue.extend({ | |||||||
| 			with_media: true, | 			with_media: true, | ||||||
| 			limit: 6 | 			limit: 6 | ||||||
| 		}).then(posts => { | 		}).then(posts => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			posts.forEach(post => { | 			posts.forEach(post => { | ||||||
| 				post.media.forEach(media => { | 				post.media.forEach(media => { | ||||||
| 					if (this.images.length < 9) this.images.push({ | 					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', { | 		(this as any).api('users/posts', { | ||||||
| 			user_id: this.user.id | 			user_id: this.user.id | ||||||
| 		}).then(posts => { | 		}).then(posts => { | ||||||
| 			this.fetching = false; |  | ||||||
| 			this.posts = posts; | 			this.posts = posts; | ||||||
|  | 			this.fetching = false; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo