From b1f8fe7752fd14338960de242ebf52aa1fe2a97b Mon Sep 17 00:00:00 2001
From: rinsuki <428rinsuki+git@gmail.com>
Date: Mon, 26 Mar 2018 21:54:38 +0900
Subject: [PATCH] implement mk-media-video

---
 .../common/views/components/media-list.vue    |  3 +-
 src/web/app/desktop/views/components/index.ts |  2 +
 .../views/components/media-video-dialog.vue   | 70 +++++++++++++++++++
 .../desktop/views/components/media-video.vue  | 67 ++++++++++++++++++
 4 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 src/web/app/desktop/views/components/media-video-dialog.vue
 create mode 100644 src/web/app/desktop/views/components/media-video.vue

diff --git a/src/web/app/common/views/components/media-list.vue b/src/web/app/common/views/components/media-list.vue
index d0da584a40..64172ad0b4 100644
--- a/src/web/app/common/views/components/media-list.vue
+++ b/src/web/app/common/views/components/media-list.vue
@@ -1,7 +1,8 @@
 <template>
 <div class="mk-media-list" :data-count="mediaList.length">
 	<template v-for="media in mediaList">
-		<mk-media-image :image="media" :key="media.id"/>
+		<mk-media-video :video="media" :key="media.id" v-if="media.type.startsWith('video')" :inline-playable="mediaList.length === 1"/>
+		<mk-media-image :image="media" :key="media.id" v-else />
 	</template>
 </div>
 </template>
diff --git a/src/web/app/desktop/views/components/index.ts b/src/web/app/desktop/views/components/index.ts
index 9bca603a53..3798bf6d2d 100644
--- a/src/web/app/desktop/views/components/index.ts
+++ b/src/web/app/desktop/views/components/index.ts
@@ -13,6 +13,7 @@ import analogClock from './analog-clock.vue';
 import ellipsisIcon from './ellipsis-icon.vue';
 import mediaImage from './media-image.vue';
 import mediaImageDialog from './media-image-dialog.vue';
+import mediaVideo from './media-video.vue';
 import notifications from './notifications.vue';
 import postForm from './post-form.vue';
 import repostForm from './repost-form.vue';
@@ -42,6 +43,7 @@ Vue.component('mk-analog-clock', analogClock);
 Vue.component('mk-ellipsis-icon', ellipsisIcon);
 Vue.component('mk-media-image', mediaImage);
 Vue.component('mk-media-image-dialog', mediaImageDialog);
+Vue.component('mk-media-video', mediaVideo);
 Vue.component('mk-notifications', notifications);
 Vue.component('mk-post-form', postForm);
 Vue.component('mk-repost-form', repostForm);
diff --git a/src/web/app/desktop/views/components/media-video-dialog.vue b/src/web/app/desktop/views/components/media-video-dialog.vue
new file mode 100644
index 0000000000..cbf862cd1c
--- /dev/null
+++ b/src/web/app/desktop/views/components/media-video-dialog.vue
@@ -0,0 +1,70 @@
+<template>
+<div class="mk-media-video-dialog">
+	<div class="bg" @click="close"></div>
+	<video :src="video.url" :title="video.name" controls autoplay ref="video"/>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import * as anime from 'animejs';
+
+export default Vue.extend({
+	props: ['video', 'start'],
+	mounted() {
+		anime({
+			targets: this.$el,
+			opacity: 1,
+			duration: 100,
+			easing: 'linear'
+		});
+		const videoTag = this.$refs.video as HTMLVideoElement
+		if (this.start) videoTag.currentTime = this.start
+	},
+	methods: {
+		close() {
+			anime({
+				targets: this.$el,
+				opacity: 0,
+				duration: 100,
+				easing: 'linear',
+				complete: () => this.$destroy()
+			});
+		}
+	}
+});
+</script>
+
+<style lang="stylus" scoped>
+.mk-media-video-dialog
+	display block
+	position fixed
+	z-index 2048
+	top 0
+	left 0
+	width 100%
+	height 100%
+	opacity 0
+
+	> .bg
+		display block
+		position fixed
+		z-index 1
+		top 0
+		left 0
+		width 100%
+		height 100%
+		background rgba(0, 0, 0, 0.7)
+
+	> video
+		position fixed
+		z-index 2
+		top 0
+		right 0
+		bottom 0
+		left 0
+		max-width 80vw
+		max-height 80vh
+		margin auto
+
+</style>
diff --git a/src/web/app/desktop/views/components/media-video.vue b/src/web/app/desktop/views/components/media-video.vue
new file mode 100644
index 0000000000..4fd955a821
--- /dev/null
+++ b/src/web/app/desktop/views/components/media-video.vue
@@ -0,0 +1,67 @@
+<template>
+	<video class="mk-media-video"
+		:src="video.url"
+		:title="video.name"
+		controls
+		@dblclick.prevent="onClick"
+		ref="video"
+		v-if="inlinePlayable" />
+	<a class="mk-media-video-thumbnail"
+		:href="video.url"
+		:style="imageStyle"
+		@click.prevent="onClick"
+		:title="video.name"
+		v-else>
+		%fa:R play-circle%
+	</a>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import MkMediaVideoDialog from './media-video-dialog.vue';
+
+export default Vue.extend({
+	props: ['video', 'inlinePlayable'],
+	computed: {
+		imageStyle(): any {
+			return {
+				'background-image': `url(${this.video.url}?thumbnail&size=512)`
+			};
+		}
+	},
+	methods: {
+		onClick() {
+			const videoTag = this.$refs.video as (HTMLVideoElement | null)
+			var start = 0
+			if (videoTag) {
+				start = videoTag.currentTime
+				videoTag.pause()
+			}
+			(this as any).os.new(MkMediaVideoDialog, {
+				video: this.video,
+				start,
+			})
+		}
+	}
+})
+</script>
+
+<style lang="stylus" scoped>
+.mk-media-video
+	display block
+	width 100%
+	height 100%
+	border-radius 4px
+.mk-media-video-thumbnail
+	display flex
+	justify-content center
+	align-items center
+	font-size 3.5em
+
+	cursor zoom-in
+	overflow hidden
+	background-position center
+	background-size cover
+	width 100%
+	height 100%
+</style>