<template> <div> <div v-if="loading" class="container"> <div class="d-flex justify-content-center align-items-center" style="height: 100vh;"> <b-spinner /> </div> </div> <div v-else> <div class="container mb-5"> <div class="row mt-3"> <div class="col-12 mb-4"> <div class="d-flex justify-content-center"> <img :src="post.media_attachments[0].url" class="img-fluid mb-4" style="max-height: 80vh;object-fit: contain;"> </div> </div> <div class="col-12 mb-4"> <p v-if="settings.show_captions && post.content_text">{{ post.content_text }}</p> <div class="d-md-flex justify-content-between align-items-center"> <p class="small">by <a :href="profileUrl()" class="font-weight-bold link-color">@{{profile.username}}</a></p> <p v-if="settings.show_license && post.media_attachments[0].license" class="small">Licensed under {{ post.media_attachments[0].license.title }}</p> <p v-if="settings.show_location && post.place" class="small text-muted">{{ post.place.name }}, {{ post.place.country }}</p> <p v-if="settings.show_timestamp" class="small"> <a v-if="settings.show_link" :href="post.url" class="font-weight-bold link-color" style="z-index: 2"> {{ formatDate(post.created_at) }} </a> <span v-else class="user-select-none"> {{ formatDate(post.created_at) }} </span> </p> </div> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-12"> <div class="d-flex fixed-bottom p-3 justify-content-between align-items-center"> <a v-if="user" class="logo-mark logo-mark-sm mb-0 p-1" href="/"> <span class="text-gradient-primary">portfolio</span> </a> <span v-else class="logo-mark logo-mark-sm mb-0 p-1"> <span class="text-gradient-primary">portfolio</span> </span> <p v-if="user && user.id === profile.id" class="text-center mb-0"> <a :href="settingsUrl" class="text-muted"><i class="far fa-cog fa-lg"></i></a> </p> </div> </div> </div> </div> </div> </div> </template> <script type="text/javascript"> export default { props: [ 'initialData' ], data() { return { loading: true, isAuthed: undefined, user: undefined, settings: undefined, post: undefined, profile: undefined, settingsUrl: window._portfolio.path + '/settings' } }, mounted() { const initialData = JSON.parse(this.initialData); this.post = initialData.post; this.profile = initialData.profile; this.isAuthed = initialData.authed; this.fetchUser(); }, methods: { async fetchUser() { if(this.isAuthed) { await axios.get('/api/v1/accounts/verify_credentials') .then(res => { this.user = res.data; }) .catch(err => { }); } await axios.get('/api/portfolio/account/settings.json', { params: { id: this.profile.id } }) .then(res => { this.settings = res.data; if(res.data.hasOwnProperty('background_color')) { this.updateCssVariable('--body-bg', res.data.background_color); } if(res.data.hasOwnProperty('text_color')) { this.updateCssVariable('--text-color', res.data.text_color); this.updateCssVariable('--link-color', res.data.text_color); } }) .then(() => { setTimeout(() => { this.loading = false; }, 500); }) }, profileUrl() { return `https://${window._portfolio.domain}${window._portfolio.path}/${this.profile.username}`; }, postUrl(res) { return `/${this.profile.username}/${res.id}`; }, formatDate(ts) { const dts = new Date(ts); return dts.toLocaleDateString(undefined, { weekday: 'short', year: 'numeric', month: 'long', day: 'numeric' }); }, updateCssVariable(k, v) { let rs = document.querySelector(':root'); rs.style.setProperty(k, v); } } } </script>