pixelfed/pixelfed

View on GitHub
resources/assets/js/components/PortfolioPost.vue

Summary

Maintainability
Test Coverage
<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">&commat;{{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>