Jelajahi Sumber

Update assets, move presenters

Daniel Supernault 1 tahun lalu
induk
melakukan
87ee0633fe

+ 1 - 1
resources/assets/components/partials/post/PostContent.vue

@@ -169,7 +169,7 @@
 <script type="text/javascript">
 	import BigPicture from 'bigpicture';
 	import ReadMore from './ReadMore.vue';
-    import VideoPlayer from './../../presenter/VideoPlayer.vue';
+    import VideoPlayer from '@/presenter/VideoPlayer.vue';
 
 	export default {
 		props: ['status'],

+ 75 - 0
resources/assets/components/presenter/MixedAlbumPresenter.vue

@@ -0,0 +1,75 @@
+<template>
+	<div v-if="status.sensitive == true">
+		<details class="details-animated">
+			<summary>
+				<p class="mb-0 lead font-weight-bold">{{ status.spoiler_text ? status.spoiler_text : 'CW / NSFW / Hidden Media'}}</p>
+				<p class="font-weight-light">(click to show)</p>
+			</summary>
+			<b-carousel :id="status.id + '-carousel'"
+				style="text-shadow: 1px 1px 2px #333; background-color: #000;"
+				controls
+				img-blank
+				background="#ffffff"
+				:interval="0"
+			>
+				<b-carousel-slide v-for="(media, index) in status.media_attachments" :key="media.id + '-media'">
+
+					<video v-if="media.type == 'video'" slot="img" class="embed-responsive-item" preload="none" controls playsinline loop :alt="media.description" width="100%" height="100%">
+						<source :src="media.url" :type="media.mime">
+					</video>
+
+					<div v-else-if="media.type == 'image'" slot="img" :title="media.description">
+						<img :class="media.filter_class + ' d-block img-fluid w-100'" :src="media.url" :alt="media.description" loading="lazy" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
+					</div>
+
+					<p v-else class="text-center p-0 font-weight-bold text-white">Error: Problem rendering preview.</p>
+
+				</b-carousel-slide>
+			</b-carousel>
+		</details>
+	</div>
+	<div v-else class="w-100 h-100 p-0">
+		<!-- <b-carousel :id="status.id + '-carousel'"
+					style="text-shadow: 1px 1px 2px #333; background-color: #000;"
+					controls
+					img-blank
+					background="#ffffff"
+					:interval="0"
+				>
+			<b-carousel-slide v-for="(media, index) in status.media_attachments" :key="media.id + '-media'">
+
+				<video v-if="media.type == 'Video'" slot="img" class="embed-responsive-item" preload="none" controls loop :title="media.description" width="100%" height="100%" :poster="media.preview_url">
+					<source :src="media.url" :type="media.mime">
+				</video>
+
+				<div v-else-if="media.type == 'Image'" slot="img" :title="media.description">
+					<img :class="media.filter_class + ' d-block img-fluid w-100'" :src="media.url" :alt="media.description" loading="lazy">
+				</div>
+
+				<p v-else class="text-center p-0 font-weight-bold text-white">Error: Problem rendering preview.</p>
+
+			</b-carousel-slide>
+		</b-carousel> -->
+		<carousel ref="carousel" :centerMode="true" :loop="false" :per-page="1" :paginationPosition="'bottom-overlay'" paginationActiveColor="#3897f0" paginationColor="#dbdbdb" class="p-0 m-0">
+			<slide v-for="(media, index) in status.media_attachments" :key="'px-carousel-'+media.id + '-' + index" class="w-100 h-100 d-block mx-auto text-center" style="background: #000; display: flex;align-items: center;">
+
+				<video v-if="media.type == 'video'" class="embed-responsive-item" preload="none" controls loop :title="media.description" width="100%" height="100%">
+					<source :src="media.url" :type="media.mime">
+				</video>
+
+				<div v-else-if="media.type == 'image'" :title="media.description">
+					<img :class="media.filter_class + ' img-fluid w-100'" :src="media.url" :alt="media.description" loading="lazy"  onerror="this.onerror=null;this.src='/storage/no-preview.png'">
+				</div>
+
+				<p v-else class="text-center p-0 font-weight-bold text-white">Error: Problem rendering preview.</p>
+
+			</slide>
+		</carousel>
+	</div>
+</template>
+
+<script type="text/javascript">
+	export default {
+		props: ['status']
+	}
+</script>

+ 188 - 0
resources/assets/components/presenter/PhotoAlbumPresenter.vue

@@ -0,0 +1,188 @@
+<template>
+	<div v-if="status.sensitive == true" class="content-label-wrapper">
+		<div class="text-light content-label">
+			<p class="text-center">
+				<i class="far fa-eye-slash fa-2x"></i>
+			</p>
+			<p class="h4 font-weight-bold text-center">
+				Sensitive Content
+			</p>
+			<p class="text-center py-2 content-label-text">
+				{{ status.spoiler_text ? status.spoiler_text : 'This album may contain sensitive content.'}}
+			</p>
+			<p class="mb-0">
+				<button @click="toggleContentWarning()" class="btn btn-outline-light btn-block btn-sm font-weight-bold">See Post</button>
+			</p>
+		</div>
+		<blur-hash-image
+			width="32"
+			height="32"
+			:punch="1"
+			:hash="status.media_attachments[0].blurhash"
+			:alt="altText(status)"/>
+	</div>
+	<div v-else class="w-100 h-100 p-0 album-wrapper">
+		<carousel ref="carousel" :centerMode="true" :loop="false" :per-page="1" :paginationPosition="'bottom-overlay'" paginationActiveColor="#3897f0" paginationColor="#dbdbdb" class="p-0 m-0" :id="'carousel-' + status.id">
+			<slide v-for="(img, index) in status.media_attachments" :key="'px-carousel-'+img.id + '-' + index" class="" style="background: #000; display: flex;align-items: center;" :title="img.description">
+
+				<img
+					class="img-fluid w-100 p-0"
+					:src="img.url"
+					:alt="altText(img)"
+					loading="lazy"
+					:data-bp="img.url"
+					onerror="this.onerror=null;this.src='/storage/no-preview.png'">
+
+			</slide>
+		</carousel>
+		<div class="album-overlay">
+			<p v-if="!status.sensitive && sensitive"
+				@click="status.sensitive = true"
+				style="
+				margin-top: 0;
+				padding: 10px;
+				color: #fff;
+				font-size: 10px;
+				text-align: right;
+				position: absolute;
+				top: 0;
+				right: 0;
+				border-top-left-radius: 5px;
+				cursor: pointer;
+				background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
+			">
+				<i class="fas fa-eye-slash fa-lg"></i>
+			</p>
+
+			<p @click.prevent="toggleLightbox"
+				style="
+				margin-top: 0;
+				padding: 10px;
+				color: #fff;
+				font-size: 10px;
+				text-align: right;
+				position: absolute;
+				left: 0;
+				top: 0;
+				border-bottom-right-radius: 5px;
+				cursor: pointer;
+				background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
+			">
+				<i class="fas fa-expand fa-lg"></i>
+			</p>
+
+			<p
+				v-if="status.media_attachments[0].license"
+				style="
+				margin-bottom: 0;
+				padding: 0 5px;
+				color: #fff;
+				font-size: 10px;
+				text-align: right;
+				position: absolute;
+				bottom: 0;
+				right: 0;
+				border-top-left-radius: 5px;
+				background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
+			">
+				<a :href="status.url" class="font-weight-bold text-light">Photo</a> by <a :href="status.account.url" class="font-weight-bold text-light">&commat;{{status.account.username}}</a> licensed under <a :href="status.media_attachments[0].license.url" class="font-weight-bold text-light">{{status.media_attachments[0].license.title}}</a>
+			</p>
+		</div>
+	</div>
+</template>
+
+
+<script type="text/javascript">
+	import BigPicture from 'bigpicture';
+
+	export default {
+		props: ['status'],
+
+		data() {
+			return {
+				sensitive: this.status.sensitive,
+				cursor: 0
+			}
+		},
+
+		created() {
+			// window.addEventListener("keydown", this.keypressNavigation);
+		},
+
+		beforeDestroy() {
+			// window.removeEventListener("keydown", this.keypressNavigation);
+		},
+
+		methods: {
+			toggleContentWarning(status) {
+				this.$emit('togglecw');
+			},
+
+			toggleLightbox(e) {
+				BigPicture({
+					el: e.target,
+					gallery: '#carousel-' + this.status.id,
+					position: this.$refs.carousel.currentPage
+				})
+			},
+
+			altText(img) {
+				let desc = img.description;
+				if(desc) {
+					return desc;
+				}
+
+				return 'Photo was not tagged with any alt text.';
+			},
+
+			keypressNavigation(e) {
+				let ref = this.$refs.carousel;
+				if (e.keyCode == "37") {
+					e.preventDefault();
+
+					let direction = "backward";
+
+					ref.advancePage(direction);
+					ref.$emit("navigation-click", direction);
+				}
+
+				if (e.keyCode == "39") {
+					e.preventDefault();
+
+					let direction = "forward";
+
+					ref.advancePage(direction);
+					ref.$emit("navigation-click", direction);
+				}
+			}
+		}
+	}
+</script>
+
+<style type="text/css" scoped>
+  .card-img-top {
+	border-top-left-radius: 0 !important;
+	border-top-right-radius: 0 !important;
+  }
+  .content-label-wrapper {
+	position: relative;
+  }
+  .content-label {
+	margin: 0;
+	position: absolute;
+	top:50%;
+	left:50%;
+	transform: translate(-50%, -50%);
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	width: 100%;
+	height: 100%;
+	z-index: 2;
+	background: rgba(0, 0, 0, 0.2)
+  }
+  .album-wrapper {
+	position: relative;
+  }
+</style>

+ 160 - 0
resources/assets/components/presenter/PhotoPresenter.vue

@@ -0,0 +1,160 @@
+<template>
+	<div v-if="status.sensitive == true" class="content-label-wrapper">
+		<div class="text-light content-label">
+			<p class="text-center">
+				<i class="far fa-eye-slash fa-2x"></i>
+			</p>
+			<p class="h4 font-weight-bold text-center">
+				Sensitive Content
+			</p>
+			<p class="text-center py-2 content-label-text">
+				{{ status.spoiler_text ? status.spoiler_text : 'This post may contain sensitive content.'}}
+			</p>
+			<p class="mb-0">
+				<button @click="toggleContentWarning()" class="btn btn-outline-light btn-block btn-sm font-weight-bold">See Post</button>
+			</p>
+		</div>
+		<blur-hash-image
+			width="32"
+			height="32"
+			:punch="1"
+			:hash="status.media_attachments[0].blurhash"
+			:alt="altText(status)"/>
+	</div>
+	<div v-else>
+		<div :title="status.media_attachments[0].description" style="position: relative;">
+			<img class="card-img-top"
+				:src="status.media_attachments[0].url"
+				loading="lazy"
+				:alt="altText(status)"
+				:width="width()"
+				:height="height()"
+				onerror="this.onerror=null;this.src='/storage/no-preview.png'"
+				@click.prevent="toggleLightbox">
+
+				<!-- <blur-hash-image
+					class="card-img-top"
+					width="32"
+					height="32"
+					:punch="1"
+					:hash="status.media_attachments[0].blurhash"
+					:src="status.media_attachments[0].url"
+					:alt="altText(status)"
+					@click.prevent="toggleLightbox"/> -->
+
+				<p v-if="!status.sensitive && sensitive"
+					@click="status.sensitive = true"
+					style="
+					margin-top: 0;
+					padding: 10px;
+					color: #fff;
+					font-size: 10px;
+					text-align: right;
+					position: absolute;
+					top: 0;
+					right: 0;
+					border-top-left-radius: 5px;
+					cursor: pointer;
+					background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
+				">
+					<i class="fas fa-eye-slash fa-lg"></i>
+				</p>
+
+				<p
+					v-if="status.media_attachments[0].license"
+					style="
+					margin-bottom: 0;
+					padding: 0 5px;
+					color: #fff;
+					font-size: 10px;
+					text-align: right;
+					position: absolute;
+					bottom: 0;
+					right: 0;
+					border-top-left-radius: 5px;
+					background: linear-gradient(0deg, rgba(0,0,0,0.5), rgba(0,0,0,0.5));
+				"><a :href="status.url" class="font-weight-bold text-light">Photo</a> by <a :href="status.account.url" class="font-weight-bold text-light">&commat;{{status.account.username}}</a> licensed under <a :href="status.media_attachments[0].license.url" class="font-weight-bold text-light">{{status.media_attachments[0].license.title}}</a></p>
+		</div>
+	</div>
+</template>
+
+<style type="text/css" scoped>
+  .card-img-top {
+    border-top-left-radius: 0 !important;
+    border-top-right-radius: 0 !important;
+  }
+  .content-label-wrapper {
+  	position: relative;
+  }
+  .content-label {
+  	margin: 0;
+  	position: absolute;
+  	top:50%;
+  	left:50%;
+  	transform: translate(-50%, -50%);
+  	display: flex;
+  	flex-direction: column;
+  	align-items: center;
+  	justify-content: center;
+  	width: 100%;
+  	height: 100%;
+  	z-index: 2;
+  	background: rgba(0, 0, 0, 0.2)
+  }
+</style>
+
+<script type="text/javascript">
+	import BigPicture from 'bigpicture';
+
+	export default {
+		props: ['status'],
+
+		data() {
+			return {
+				sensitive: this.status.sensitive
+			}
+		},
+
+		mounted() {
+		},
+
+		methods: {
+			altText(status) {
+				let desc = status.media_attachments[0].description;
+				if(desc) {
+					return desc;
+				}
+
+				return 'Photo was not tagged with any alt text.';
+			},
+
+			toggleContentWarning(status) {
+				this.$emit('togglecw');
+			},
+
+			toggleLightbox(e) {
+				BigPicture({
+					el: e.target
+				})
+			},
+
+			width() {
+				if( !this.status.media_attachments[0].meta ||
+					!this.status.media_attachments[0].meta.original ||
+					!this.status.media_attachments[0].meta.original.width ) {
+					return;
+				}
+				return this.status.media_attachments[0].meta.original.width;
+			},
+
+			height() {
+				if( !this.status.media_attachments[0].meta ||
+					!this.status.media_attachments[0].meta.original ||
+					!this.status.media_attachments[0].meta.original.height ) {
+					return;
+				}
+				return this.status.media_attachments[0].meta.original.height;
+			}
+		}
+	}
+</script>

+ 44 - 0
resources/assets/components/presenter/VideoAlbumPresenter.vue

@@ -0,0 +1,44 @@
+<template>
+	<div v-if="status.sensitive == true">
+		<details class="details-animated">
+			<summary>
+				<p class="mb-0 lead font-weight-bold">{{ status.spoiler_text ? status.spoiler_text : 'CW / NSFW / Hidden Media'}}</p>
+				<p class="font-weight-light">(click to show)</p>
+			</summary>
+			<b-carousel :id="status.id + '-carousel'"
+				style="text-shadow: 1px 1px 2px #333; background-color: #000;"
+				controls
+				img-blank
+				background="#ffffff"
+				:interval="0"
+			>
+				<b-carousel-slide v-for="(vid, index) in status.media_attachments" :key="vid.id + '-media'">
+					<video slot="img" class="embed-responsive-item" preload="none" controls playsinline loop :alt="vid.description" width="100%" height="100%">
+						<source :src="vid.url" :type="vid.mime">
+					</video>
+				</b-carousel-slide>
+			</b-carousel>
+		</details>
+	</div>
+	<div v-else>
+		<b-carousel :id="status.id + '-carousel'"
+			style="text-shadow: 1px 1px 2px #333; background-color: #000;"
+			controls
+			img-blank
+			background="#ffffff"
+			:interval="0"
+		>
+			<b-carousel-slide v-for="(vid, index) in status.media_attachments" :key="vid.id + '-media'">
+				<video slot="img" class="embed-responsive-item" preload="none" controls playsinline loop :alt="vid.description" width="100%" height="100%">
+					<source :src="vid.url" :type="vid.mime">
+				</video>
+			</b-carousel-slide>
+		</b-carousel>
+	</div>
+</template>
+
+<script type="text/javascript">
+	export default {
+		props: ['status']
+	}
+</script>

+ 90 - 0
resources/assets/components/presenter/VideoPresenter.vue

@@ -0,0 +1,90 @@
+<template>
+	<div v-if="status.sensitive == true" class="content-label-wrapper">
+		<div class="text-light content-label">
+			<p class="text-center">
+				<i class="far fa-eye-slash fa-2x"></i>
+			</p>
+			<p class="h4 font-weight-bold text-center">
+				Sensitive Content
+			</p>
+			<p class="text-center py-2 content-label-text">
+				{{ status.spoiler_text ? status.spoiler_text : 'This post may contain sensitive content.'}}
+			</p>
+			<p class="mb-0">
+				<button @click="toggleContentWarning()" class="btn btn-outline-light btn-block btn-sm font-weight-bold">See Post</button>
+			</p>
+		</div>
+		<blur-hash-image
+			width="32"
+			height="32"
+			:punch="1"
+			:hash="status.media_attachments[0].blurhash"
+			:alt="altText(status)"/>
+	</div>
+	<div v-else class="embed-responsive embed-responsive-16by9">
+		<video class="video" controls playsinline webkit-playsinline preload="metadata" loop :data-id="status.id" :poster="poster()">
+			<source :src="status.media_attachments[0].url" :type="status.media_attachments[0].mime">
+		</video>
+	</div>
+</template>
+
+<style type="text/css" scoped>
+  .content-label-wrapper {
+  	position: relative;
+  }
+  .content-label {
+  	margin: 0;
+  	position: absolute;
+  	top:50%;
+  	left:50%;
+  	transform: translate(-50%, -50%);
+  	display: flex;
+  	flex-direction: column;
+  	align-items: center;
+  	justify-content: center;
+  	width: 100%;
+  	height: 100%;
+  	z-index: 2;
+  	background: rgba(0, 0, 0, 0.2)
+  }
+</style>
+
+<script type="text/javascript">
+	export default {
+		props: ['status'],
+
+		methods: {
+			altText(status) {
+				let desc = status.media_attachments[0].description;
+				if(desc) {
+					return desc;
+				}
+
+				return 'Video was not tagged with any alt text.';
+			},
+
+			playOrPause(e) {
+				let el = e.target;
+				if(el.getAttribute('playing') == 1) {
+					el.removeAttribute('playing');
+					el.pause();
+				} else {
+					el.setAttribute('playing', 1);
+					el.play();
+				}
+			},
+
+			toggleContentWarning(status) {
+				this.$emit('togglecw');
+			},
+
+            poster() {
+                let url = this.status.media_attachments[0].preview_url;
+                if(url.endsWith('no-preview.jpg') || url.endsWith('no-preview.png')) {
+                    return;
+                }
+                return url;
+            }
+		}
+	}
+</script>

+ 5 - 5
resources/assets/js/landing.js

@@ -48,27 +48,27 @@ Vue.use(VueTimeago, {
 
 Vue.component(
 	'photo-presenter',
-	require('./components/presenter/PhotoPresenter.vue').default
+	require('./../components/presenter/PhotoPresenter.vue').default
 );
 
 Vue.component(
 	'video-presenter',
-	require('./components/presenter/VideoPresenter.vue').default
+	require('./../components/presenter/VideoPresenter.vue').default
 );
 
 Vue.component(
 	'photo-album-presenter',
-	require('./components/presenter/PhotoAlbumPresenter.vue').default
+	require('./../components/presenter/PhotoAlbumPresenter.vue').default
 );
 
 Vue.component(
 	'video-album-presenter',
-	require('./components/presenter/VideoAlbumPresenter.vue').default
+	require('./../components/presenter/VideoAlbumPresenter.vue').default
 );
 
 Vue.component(
 	'mixed-album-presenter',
-	require('./components/presenter/MixedAlbumPresenter.vue').default
+	require('./../components/presenter/MixedAlbumPresenter.vue').default
 );
 
 Vue.component(

+ 5 - 5
resources/assets/js/profile.js

@@ -1,26 +1,26 @@
 Vue.component(
     'photo-presenter',
-    require('./components/presenter/PhotoPresenter.vue').default
+    require('./../components/presenter/PhotoPresenter.vue').default
 );
 
 Vue.component(
     'video-presenter',
-    require('./components/presenter/VideoPresenter.vue').default
+    require('./../components/presenter/VideoPresenter.vue').default
 );
 
 Vue.component(
     'photo-album-presenter',
-    require('./components/presenter/PhotoAlbumPresenter.vue').default
+    require('./../components/presenter/PhotoAlbumPresenter.vue').default
 );
 
 Vue.component(
     'video-album-presenter',
-    require('./components/presenter/VideoAlbumPresenter.vue').default
+    require('./../components/presenter/VideoAlbumPresenter.vue').default
 );
 
 Vue.component(
     'mixed-album-presenter',
-    require('./components/presenter/MixedAlbumPresenter.vue').default
+    require('./../components/presenter/MixedAlbumPresenter.vue').default
 );
 
 Vue.component(

+ 5 - 5
resources/assets/js/spa.js

@@ -60,27 +60,27 @@ Vue.component(
 
 Vue.component(
 	'photo-presenter',
-	require('./components/presenter/PhotoPresenter.vue').default
+	require('./../components/presenter/PhotoPresenter.vue').default
 );
 
 Vue.component(
 	'video-presenter',
-	require('./components/presenter/VideoPresenter.vue').default
+	require('./../components/presenter/VideoPresenter.vue').default
 );
 
 Vue.component(
 	'photo-album-presenter',
-	require('./components/presenter/PhotoAlbumPresenter.vue').default
+	require('./../components/presenter/PhotoAlbumPresenter.vue').default
 );
 
 Vue.component(
 	'video-album-presenter',
-	require('./components/presenter/VideoAlbumPresenter.vue').default
+	require('./../components/presenter/VideoAlbumPresenter.vue').default
 );
 
 Vue.component(
 	'mixed-album-presenter',
-	require('./components/presenter/MixedAlbumPresenter.vue').default
+	require('./../components/presenter/MixedAlbumPresenter.vue').default
 );
 
 Vue.component(

+ 15 - 5
resources/assets/js/status.js

@@ -1,26 +1,26 @@
 Vue.component(
 	'photo-presenter',
-	require('./components/presenter/PhotoPresenter.vue').default
+	require('./../components/presenter/PhotoPresenter.vue').default
 );
 
 Vue.component(
 	'video-presenter',
-	require('./components/presenter/VideoPresenter.vue').default
+	require('./../components/presenter/VideoPresenter.vue').default
 );
 
 Vue.component(
 	'photo-album-presenter',
-	require('./components/presenter/PhotoAlbumPresenter.vue').default
+	require('./../components/presenter/PhotoAlbumPresenter.vue').default
 );
 
 Vue.component(
 	'video-album-presenter',
-	require('./components/presenter/VideoAlbumPresenter.vue').default
+	require('./../components/presenter/VideoAlbumPresenter.vue').default
 );
 
 Vue.component(
 	'mixed-album-presenter',
-	require('./components/presenter/MixedAlbumPresenter.vue').default
+	require('./../components/presenter/MixedAlbumPresenter.vue').default
 );
 
 Vue.component(
@@ -32,3 +32,13 @@ Vue.component(
 	'post-component',
 	require('./components/PostComponent.vue').default
 );
+
+// Vue.component(
+// 	'post-next',
+// 	require('./components/PostNext.vue').default
+// );
+
+// Vue.component(
+// 	'video-component',
+// 	require('./components/VideoComponent.vue').default
+// );

+ 6 - 6
resources/assets/js/timeline.js

@@ -5,27 +5,27 @@ Vue.component(
 
 Vue.component(
     'photo-presenter',
-    require('./components/presenter/PhotoPresenter.vue').default
+    require('./../components/presenter/PhotoPresenter.vue').default
 );
 
 Vue.component(
     'video-presenter',
-    require('./components/presenter/VideoPresenter.vue').default
+    require('./../components/presenter/VideoPresenter.vue').default
 );
 
 Vue.component(
     'photo-album-presenter',
-    require('./components/presenter/PhotoAlbumPresenter.vue').default
+    require('./../components/presenter/PhotoAlbumPresenter.vue').default
 );
 
 Vue.component(
     'video-album-presenter',
-    require('./components/presenter/VideoAlbumPresenter.vue').default
+    require('./../components/presenter/VideoAlbumPresenter.vue').default
 );
 
 Vue.component(
     'mixed-album-presenter',
-    require('./components/presenter/MixedAlbumPresenter.vue').default
+    require('./../components/presenter/MixedAlbumPresenter.vue').default
 );
 
 Vue.component(
@@ -46,4 +46,4 @@ Vue.component(
 Vue.component(
     'story-component',
     require('./components/StoryTimelineComponent.vue').default
-);
+);