diff --git a/src/web/app/desktop/-tags/repost-form-window.tag b/src/web/app/desktop/-tags/repost-form-window.tag
deleted file mode 100644
index 25f509c626d2257a952802b8805deb94aadbef62..0000000000000000000000000000000000000000
--- a/src/web/app/desktop/-tags/repost-form-window.tag
+++ /dev/null
@@ -1,47 +0,0 @@
-<mk-repost-form-window>
-	<mk-window ref="window" is-modal={ true }>
-		<yield to="header">
-			%fa:retweet%%i18n:desktop.tags.mk-repost-form-window.title%
-		</yield>
-		<yield to="content">
-			<mk-repost-form ref="form" post={ parent.opts.post }/>
-		</yield>
-	</mk-window>
-	<style lang="stylus" scoped>
-		:scope
-			> mk-window
-				[data-yield='header']
-					> [data-fa]
-						margin-right 4px
-
-	</style>
-	<script lang="typescript">
-		this.onDocumentKeydown = e => {
-			if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
-				if (e.which == 27) { // Esc
-					this.$refs.window.close();
-				}
-			}
-		};
-
-		this.on('mount', () => {
-			this.$refs.window.refs.form.on('cancel', () => {
-				this.$refs.window.close();
-			});
-
-			this.$refs.window.refs.form.on('posted', () => {
-				this.$refs.window.close();
-			});
-
-			document.addEventListener('keydown', this.onDocumentKeydown);
-
-			this.$refs.window.on('closed', () => {
-				this.$destroy();
-			});
-		});
-
-		this.on('unmount', () => {
-			document.removeEventListener('keydown', this.onDocumentKeydown);
-		});
-	</script>
-</mk-repost-form-window>
diff --git a/src/web/app/desktop/views/components/index.ts b/src/web/app/desktop/views/components/index.ts
index b2de82b4d4a70d574bbf5af010146681bfd18e22..9788a27f1a65ea8b13f2287600f0c4c3e6cbb92e 100644
--- a/src/web/app/desktop/views/components/index.ts
+++ b/src/web/app/desktop/views/components/index.ts
@@ -8,6 +8,7 @@ import timelinePostSub from './timeline-post-sub.vue';
 import subPostContent from './sub-post-content.vue';
 import window from './window.vue';
 import postFormWindow from './post-form-window.vue';
+import repostFormWindow from './repost-form-window.vue';
 
 Vue.component('mk-ui', ui);
 Vue.component('mk-home', home);
@@ -17,3 +18,4 @@ Vue.component('mk-timeline-post-sub', timelinePostSub);
 Vue.component('mk-sub-post-content', subPostContent);
 Vue.component('mk-window', window);
 Vue.component('post-form-window', postFormWindow);
+Vue.component('repost-form-window', repostFormWindow);
diff --git a/src/web/app/desktop/views/components/post-form-window.vue b/src/web/app/desktop/views/components/post-form-window.vue
index f488b6c34b4cab572c911eb487e393bf9d23cac8..90e694c922c147ed9d3e39f522cede5e7d06bbf6 100644
--- a/src/web/app/desktop/views/components/post-form-window.vue
+++ b/src/web/app/desktop/views/components/post-form-window.vue
@@ -1,5 +1,5 @@
 <template>
-<mk-window is-modal @closed="$destroy">
+<mk-window ref="window" is-modal @closed="$destroy">
 	<span slot="header">
 		<span v-if="!parent.opts.reply">%i18n:desktop.tags.mk-post-form-window.post%</span>
 		<span v-if="parent.opts.reply">%i18n:desktop.tags.mk-post-form-window.reply%</span>
@@ -10,7 +10,7 @@
 		<mk-post-preview v-if="parent.opts.reply" :class="$style.postPreview" :post="reply"/>
 		<mk-post-form ref="form"
 			:reply="reply"
-			@post="$refs.window.close"
+			@posted="$refs.window.close"
 			@change-uploadings="onChangeUploadings"
 			@change-attached-media="onChangeMedia"/>
 	</div>
diff --git a/src/web/app/desktop/views/components/repost-form-window.vue b/src/web/app/desktop/views/components/repost-form-window.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6f06faaba21968e98f0ce61ba4798964e8005fdd
--- /dev/null
+++ b/src/web/app/desktop/views/components/repost-form-window.vue
@@ -0,0 +1,38 @@
+<template>
+<mk-window ref="window" is-modal @closed="$destroy">
+	<span slot="header" :class="$style.header">%fa:retweet%%i18n:desktop.tags.mk-repost-form-window.title%</span>
+	<div slot="content">
+		<mk-repost-form ref="form" :post="post" @posted="$refs.window.close" @canceled="$refs.window.close"/>
+	</div>
+</mk-window>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+
+export default Vue.extend({
+	props: ['post'],
+	mounted() {
+		document.addEventListener('keydown', this.onDocumentKeydown);
+	},
+	beforeDestroy() {
+		document.removeEventListener('keydown', this.onDocumentKeydown);
+	},
+	methods: {
+		onDocumentKeydown(e) {
+			if (e.target.tagName != 'INPUT' && e.target.tagName != 'TEXTAREA') {
+				if (e.which == 27) { // Esc
+					(this.$refs.window as any).close();
+				}
+			}
+		}
+	}
+});
+</script>
+
+<style lang="stylus" module>
+.header
+	> [data-fa]
+		margin-right 4px
+
+</style>