diff --git a/src/web/app/common/views/components/index.ts b/src/web/app/common/views/components/index.ts
index 26213297a8..3d78e7f9c4 100644
--- a/src/web/app/common/views/components/index.ts
+++ b/src/web/app/common/views/components/index.ts
@@ -6,6 +6,7 @@ import forkit from './forkit.vue';
 import nav from './nav.vue';
 import postHtml from './post-html';
 import reactionIcon from './reaction-icon.vue';
+import time from './time.vue';
 
 Vue.component('mk-signin', signin);
 Vue.component('mk-signup', signup);
@@ -13,3 +14,4 @@ Vue.component('mk-forkit', forkit);
 Vue.component('mk-nav', nav);
 Vue.component('mk-post-html', postHtml);
 Vue.component('mk-reaction-icon', reactionIcon);
+Vue.component('mk-time', time);
diff --git a/src/web/app/common/views/components/time.vue b/src/web/app/common/views/components/time.vue
index 7d165fc006..3c856d3f26 100644
--- a/src/web/app/common/views/components/time.vue
+++ b/src/web/app/common/views/components/time.vue
@@ -1,63 +1,76 @@
 <template>
-	<time>
-		<span v-if=" mode == 'relative' ">{{ relative }}</span>
-		<span v-if=" mode == 'absolute' ">{{ absolute }}</span>
-		<span v-if=" mode == 'detail' ">{{ absolute }} ({{ relative }})</span>
-	</time>
+<time>
+	<span v-if=" mode == 'relative' ">{{ relative }}</span>
+	<span v-if=" mode == 'absolute' ">{{ absolute }}</span>
+	<span v-if=" mode == 'detail' ">{{ absolute }} ({{ relative }})</span>
+</time>
 </template>
 
-<script lang="typescript">
-	import Vue from 'vue';
+<script lang="ts">
+import Vue from 'vue';
 
-	export default Vue.extend({
-		props: ['time', 'mode'],
-		data() {
-			return {
-				mode: 'relative',
-				tickId: null,
-				now: new Date()
-			};
+export default Vue.extend({
+	props: {
+		time: {
+			type: [Date, String],
+			required: true
 		},
-		computed: {
-			absolute() {
-				return (
-					this.time.getFullYear()    + '年' +
-					(this.time.getMonth() + 1) + '月' +
-					this.time.getDate()        + '日' +
-					' ' +
-					this.time.getHours()       + '時' +
-					this.time.getMinutes()     + '分');
-			},
-			relative() {
-				const ago = (this.now - this.time) / 1000/*ms*/;
-				return (
-					ago >= 31536000 ? '%i18n:common.time.years_ago%'  .replace('{}', ~~(ago / 31536000)) :
-					ago >= 2592000  ? '%i18n:common.time.months_ago%' .replace('{}', ~~(ago / 2592000)) :
-					ago >= 604800   ? '%i18n:common.time.weeks_ago%'  .replace('{}', ~~(ago / 604800)) :
-					ago >= 86400    ? '%i18n:common.time.days_ago%'   .replace('{}', ~~(ago / 86400)) :
-					ago >= 3600     ? '%i18n:common.time.hours_ago%'  .replace('{}', ~~(ago / 3600)) :
-					ago >= 60       ? '%i18n:common.time.minutes_ago%'.replace('{}', ~~(ago / 60)) :
-					ago >= 10       ? '%i18n:common.time.seconds_ago%'.replace('{}', ~~(ago % 60)) :
-					ago >= 0        ? '%i18n:common.time.just_now%' :
-					ago <  0        ? '%i18n:common.time.future%' :
-					'%i18n:common.time.unknown%');
-			}
-		},
-		created() {
-			if (this.mode == 'relative' || this.mode == 'detail') {
-				this.tick();
-				this.tickId = setInterval(this.tick, 1000);
-			}
-		},
-		destroyed() {
-			if (this.mode === 'relative' || this.mode === 'detail') {
-				clearInterval(this.tickId);
-			}
-		},
-		methods: {
-			tick() {
-				this.now = new Date();
-			}
+		mode: {
+			type: String,
+			default: 'relative'
 		}
-	});
+	},
+	data() {
+		return {
+			tickId: null,
+			now: new Date()
+		};
+	},
+	computed: {
+		_time(): Date {
+			return typeof this.time == 'string' ? new Date(this.time) : this.time;
+		},
+		absolute(): string {
+			const time = this._time;
+			return (
+				time.getFullYear()    + '年' +
+				(time.getMonth() + 1) + '月' +
+				time.getDate()        + '日' +
+				' ' +
+				time.getHours()       + '時' +
+				time.getMinutes()     + '分');
+		},
+		relative(): string {
+			const time = this._time;
+			const ago = (this.now.getTime() - time.getTime()) / 1000/*ms*/;
+			return (
+				ago >= 31536000 ? '%i18n:common.time.years_ago%'  .replace('{}', (~~(ago / 31536000)).toString()) :
+				ago >= 2592000  ? '%i18n:common.time.months_ago%' .replace('{}', (~~(ago / 2592000)).toString()) :
+				ago >= 604800   ? '%i18n:common.time.weeks_ago%'  .replace('{}', (~~(ago / 604800)).toString()) :
+				ago >= 86400    ? '%i18n:common.time.days_ago%'   .replace('{}', (~~(ago / 86400)).toString()) :
+				ago >= 3600     ? '%i18n:common.time.hours_ago%'  .replace('{}', (~~(ago / 3600)).toString()) :
+				ago >= 60       ? '%i18n:common.time.minutes_ago%'.replace('{}', (~~(ago / 60)).toString()) :
+				ago >= 10       ? '%i18n:common.time.seconds_ago%'.replace('{}', (~~(ago % 60)).toString()) :
+				ago >= 0        ? '%i18n:common.time.just_now%' :
+				ago <  0        ? '%i18n:common.time.future%' :
+				'%i18n:common.time.unknown%');
+		}
+	},
+	created() {
+		if (this.mode == 'relative' || this.mode == 'detail') {
+			this.tick();
+			this.tickId = setInterval(this.tick, 1000);
+		}
+	},
+	destroyed() {
+		if (this.mode === 'relative' || this.mode === 'detail') {
+			clearInterval(this.tickId);
+		}
+	},
+	methods: {
+		tick() {
+			this.now = new Date();
+		}
+	}
+});
 </script>
diff --git a/src/web/app/desktop/views/components/images-image.vue b/src/web/app/desktop/views/components/images-image.vue
index 8cb9d5e108..5ef8ffcdae 100644
--- a/src/web/app/desktop/views/components/images-image.vue
+++ b/src/web/app/desktop/views/components/images-image.vue
@@ -4,7 +4,7 @@
 	@mousemove="onMousemove"
 	@mouseleave="onMouseleave"
 	@click.prevent="onClick"
-	:style="styles"
+	:style="style"
 	:title="image.name"></a>
 </template>
 
diff --git a/src/web/app/desktop/views/components/posts-post.vue b/src/web/app/desktop/views/components/posts-post.vue
index 2633a63f28..77a1e882c8 100644
--- a/src/web/app/desktop/views/components/posts-post.vue
+++ b/src/web/app/desktop/views/components/posts-post.vue
@@ -1,5 +1,5 @@
 <template>
-<div class="mk-posts-post" tabindex="-1" :title="title" @keydown="onKeydown" @dblclick="onDblClick">
+<div class="mk-posts-post" tabindex="-1" :title="title" @keydown="onKeydown">
 	<div class="reply-to" v-if="p.reply">
 		<mk-posts-post-sub post="p.reply"/>
 	</div>
@@ -58,7 +58,7 @@
 				<button @click="menu" ref="menuButton">
 					%fa:ellipsis-h%
 				</button>
-				<button @click="toggleDetail" title="%i18n:desktop.tags.mk-timeline-post.detail">
+				<button title="%i18n:desktop.tags.mk-timeline-post.detail">
 					<template v-if="!isDetailOpened">%fa:caret-down%</template>
 					<template v-if="isDetailOpened">%fa:caret-up%</template>
 				</button>
@@ -94,6 +94,7 @@ export default Vue.extend({
 	props: ['post'],
 	data() {
 		return {
+			isDetailOpened: false,
 			connection: null,
 			connectionId: null
 		};
@@ -109,7 +110,11 @@ export default Vue.extend({
 			return this.isRepost ? this.post.repost : this.post;
 		},
 		reactionsCount(): number {
-			return this.p.reaction_counts ? Object.keys(this.p.reaction_counts).map(key => this.p.reaction_counts[key]).reduce((a, b) => a + b) : 0;
+			return this.p.reaction_counts
+				? Object.keys(this.p.reaction_counts)
+					.map(key => this.p.reaction_counts[key])
+					.reduce((a, b) => a + b)
+				: 0;
 		},
 		title(): string {
 			return dateStringify(this.p.created_at);