Add StoryViewer Component

This commit is contained in:
Daniel Supernault 2020-01-02 15:13:47 -07:00
parent 504694d495
commit e8b30ed898
No known key found for this signature in database
GPG key ID: 0DEF1C662C9033F7
2 changed files with 142 additions and 3 deletions

View file

@ -35,7 +35,12 @@
<div class="d-block d-md-none mt-n3 mb-3"> <div class="d-block d-md-none mt-n3 mb-3">
<div class="row"> <div class="row">
<div class="col-4"> <div class="col-4">
<img :alt="profileUsername + '\'s profile picture'" class="rounded-circle border mr-2" :src="profile.avatar" width="77px" height="77px"> <div v-if="hasStory" class="has-story cursor-pointer shadow-sm" @click="storyRedirect()">
<img :alt="profileUsername + '\'s profile picture'" class="rounded-circle" :src="profile.avatar" width="77px" height="77px">
</div>
<div v-else>
<img :alt="profileUsername + '\'s profile picture'" class="rounded-circle border" :src="profile.avatar" width="77px" height="77px">
</div>
</div> </div>
<div class="col-8"> <div class="col-8">
<div class="d-block d-md-none mt-3 py-2"> <div class="d-block d-md-none mt-3 py-2">
@ -72,7 +77,12 @@
<!-- DESKTOP PROFILE PICTURE --> <!-- DESKTOP PROFILE PICTURE -->
<div class="d-none d-md-block pb-5"> <div class="d-none d-md-block pb-5">
<img :alt="profileUsername + '\'s profile picture'" class="rounded-circle box-shadow" :src="profile.avatar" width="150px" height="150px"> <div v-if="hasStory" class="has-story-lg cursor-pointer shadow-sm" @click="storyRedirect()">
<img :alt="profileUsername + '\'s profile picture'" class="rounded-circle box-shadow" :src="profile.avatar" width="150px" height="150px">
</div>
<div v-else>
<img :alt="profileUsername + '\'s profile picture'" class="rounded-circle box-shadow" :src="profile.avatar" width="150px" height="150px">
</div>
<p v-if="sponsorList.patreon || sponsorList.liberapay || sponsorList.opencollective" class="text-center mt-3"> <p v-if="sponsorList.patreon || sponsorList.liberapay || sponsorList.opencollective" class="text-center mt-3">
<button type="button" @click="showSponsorModal" class="btn btn-outline-secondary font-weight-bold py-0"> <button type="button" @click="showSponsorModal" class="btn btn-outline-secondary font-weight-bold py-0">
<i class="fas fa-heart text-danger"></i> <i class="fas fa-heart text-danger"></i>
@ -523,6 +533,20 @@
.nav-topbar .nav-link .small { .nav-topbar .nav-link .small {
font-weight: 600; font-weight: 600;
} }
.has-story {
width: 83px;
height: 83px;
border-radius: 50%;
padding: 3px;
background: radial-gradient(ellipse at 70% 70%, #ee583f 8%, #d92d77 42%, #bd3381 58%);
}
.has-story-lg {
width: 156px;
height: 156px;
border-radius: 50%;
padding: 3px;
background: radial-gradient(ellipse at 70% 70%, #ee583f 8%, #d92d77 42%, #bd3381 58%);
}
</style> </style>
<script type="text/javascript"> <script type="text/javascript">
import VueMasonry from 'vue-masonry-css' import VueMasonry from 'vue-masonry-css'
@ -565,7 +589,8 @@
collectionsPage: 2, collectionsPage: 2,
isMobile: false, isMobile: false,
ctxEmbedPayload: null, ctxEmbedPayload: null,
copiedEmbed: false copiedEmbed: false,
hasStory: null
} }
}, },
beforeMount() { beforeMount() {
@ -620,6 +645,10 @@
this.profile = res.data; this.profile = res.data;
}).then(res => { }).then(res => {
this.fetchPosts(); this.fetchPosts();
axios.get('/api/stories/v1/exists/' + this.profileId)
.then(res => {
this.hasStory = res.data == true;
})
}); });
}, },
@ -1133,6 +1162,10 @@
this.$refs.embedModal.hide(); this.$refs.embedModal.hide();
this.$refs.visitorContextMenu.hide(); this.$refs.visitorContextMenu.hide();
}, },
storyRedirect() {
window.location.href = '/stories/' + this.profileUsername;
}
} }
} }
</script> </script>

View file

@ -0,0 +1,106 @@
<template>
<div class="container">
<div v-if="loading" class="row">
<div class="col-12 mt-5 pt-5">
<div class="text-center">
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</div>
</div>
<div v-if="stories.length != 0">
<div id="storyContainer" class="d-none m-3"></div>
</div>
</div>
</template>
<style type="text/css" scoped>
#storyContainer > .story {
margin-right: 3rem;
}
</style>
<script type="text/javascript">
import 'zuck.js/dist/zuck.css';
import 'zuck.js/dist/skins/snapgram.css';
window.Zuck = require('zuck.js');
export default {
props: ['pid'],
data() {
return {
loading: true,
stories: {},
}
},
beforeMount() {
this.fetchStories();
},
methods: {
fetchStories() {
axios.get('/api/stories/v1/profile/' + this.pid)
.then(res => {
let data = res.data;
if(data.length == 0) {
window.location.href = '/';
return;
}
window._storyData = data;
window.stories = new Zuck('storyContainer', {
stories: data,
localStorage: true,
callbacks: {
onOpen (storyId, callback) {
document.body.style.overflow = "hidden";
callback()
},
onEnd (storyId, callback) {
axios.post('/i/stories/viewed', {
id: storyId
});
callback();
},
onClose (storyId, callback) {
document.body.style.overflow = "auto";
callback();
window.location.href = '/';
},
}
});
this.loading = false;
document.querySelectorAll('#storyContainer .story')[0].click()
})
.catch(err => {
window.location.href = '/';
return;
});
}
}
}
</script>
<style type="text/css">
#storyContainer .story {
margin-right: 2rem;
width: 100%;
max-width: 64px;
}
.stories.carousel .story > .item-link > .item-preview {
height: 64px;
}
#zuck-modal.with-effects {
width: 100%;
}
.stories.carousel .story > .item-link > .info .name {
font-weight: 600;
font-size: 12px;
}
.stories.carousel .story > .item-link > .info {
}
</style>