feat(frontend): added basic previews to stream page

This commit is contained in:
Dimitrie Stefanescu
2021-05-07 21:55:00 +01:00
parent b2288063de
commit fae853862f
8 changed files with 119 additions and 115 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@@ -1,82 +1,78 @@
<template>
<v-card class="pa-5 " style="transition: all 0.2s" >
<v-row>
<v-col cols="12" sm="8" class="align-self-center">
<p>Hello</p>
</v-col>
<v-col cols="12" sm="8" class="align-self-center">
<div class="subtitle-1 stream-link">
<router-link :to="'/streams/' + stream.id">
{{ stream.name }}
</router-link>
</div>
<div class="caption mb-2 mt-1 text-truncate">
<v-hover v-slot="{ hover }">
<v-card
:to="'/streams/' + stream.id"
color=""
:elevation="hover ? 5 : 1"
style="transition: all 0.2s ease-in-out"
>
<v-img
ref="cover"
:src="currentPreviewImg"
height="150px"
gradient="to bottom left, rgba(100,115,201,.10), rgba(25,32,72,0)"
class="align-end"
>
</v-img>
<v-card-title>{{ stream.name }}</v-card-title>
<v-card-text>
<span class="caption mb-2 font-italic">
Updated
<timeago :datetime="stream.updatedAt"></timeago>
</span>
<v-chip small outlined class="ml-3">
<v-icon small left>mdi-account-key-outline</v-icon>
{{ stream.role.split(':')[1] }}
</v-chip>
<v-btn
v-tooltip="
stream.branches.totalCount + ' branch' + (stream.branches.totalCount === 1 ? '' : 'es')
"
plain
color="primary"
text
class="px-0 ml-3"
small
:to="'/streams/' + stream.id + '/branches'"
>
<v-icon small class="mr-2 float-left">mdi-source-branch</v-icon>
{{ stream.branches.totalCount }}
</v-btn>
<v-btn
v-tooltip="
stream.commits.totalCount + ' commit' + (stream.commits.totalCount === 1 ? '' : 's')
"
plain
color="primary"
text
class="px-0"
small
:to="'/streams/' + stream.id + '/branches/main/commits'"
>
<v-icon small class="mr-2 float-left">mdi-source-commit</v-icon>
{{ stream.commits.totalCount }}
</v-btn>
<!-- <div class="mt-3 caption text-truncate">
{{ stream.description }}
</div>
<div>
<span class="caption mb-2 font-italic">
Updated
<timeago :datetime="stream.updatedAt"></timeago>
</span>
<v-chip small outlined class="ml-3">
<v-icon small left>mdi-account-key-outline</v-icon>
{{ role }}
</v-chip>
<v-btn
v-tooltip="
stream.branches.totalCount +
' branch' +
(stream.branches.totalCount === 1 ? '' : 'es')
"
plain
color="primary"
text
class="px-0 ml-3"
small
:to="'/streams/' + stream.id + '/branches'"
>
<v-icon small class="mr-2 float-left">mdi-source-branch</v-icon>
{{ stream.branches.totalCount }}
</v-btn>
<v-btn
v-tooltip="
stream.commits.totalCount + ' commit' + (stream.commits.totalCount === 1 ? '' : 's')
"
plain
color="primary"
text
class="px-0"
small
:to="'/streams/' + stream.id + '/branches/main/commits'"
>
<v-icon small class="mr-2 float-left">mdi-source-commit</v-icon>
{{ stream.commits.totalCount }}
</v-btn>
</div>
<!-- <v-icon v-if="stream.isPublic" v-tooltip="`Link sharing on`" small>mdi-link</v-icon>
<v-icon v-else v-tooltip="`Link sharing off`" small>mdi-shield-lock</v-icon> -->
</v-col>
<v-col cols="12" sm="4" class="text-sm-center text-md-right align-self-center">
<div>
<user-avatar
v-for="user in collaboratorsSlice"
:id="user.id"
:key="user.id"
:avatar="user.avatar"
:size="30"
:name="user.name"
/>
<div v-if="stream.collaborators.length > collaboratorsSlice.length" class="d-inline">
<v-avatar class="ma-1 grey--text text--darken-2" color="grey lighten-3" size="30">
<b>+{{ stream.collaborators.length - collaboratorsSlice.length }}</b>
</v-avatar>
</div>
</div>
</v-col>
</v-row>
</v-card>
</div> -->
</v-card-text>
<v-card-text class="pt-0">
<user-avatar
v-for="user in stream.collaborators.slice(0, 4)"
:id="user.id"
:key="user.id"
:avatar="user.avatar"
:size="30"
:name="user.name"
/>
<v-avatar v-if="stream.collaborators.length > 4" size="30" color="primary">
<span class="white--text">+{{ stream.collaborators.length - 4 }}</span>
</v-avatar>
</v-card-text>
</v-card>
</v-hover>
</template>
<script>
import UserAvatar from '../components/UserAvatar'
@@ -91,33 +87,32 @@ export default {
}
}
},
computed: {
collaboratorsSlice() {
let limit = 18
switch (this.$vuetify.breakpoint.name) {
case 'xs':
limit = 10
break
case 'sm':
limit = 9
break
case 'md':
limit = 8
break
case 'lg':
limit = 12
break
case 'xl':
limit = 18
break
data() {
return {
previewImgUrls: [],
currentPreviewImg: '/loadingImage.png'
}
},
mounted() {
this.getPreviewImages().then().catch()
},
methods: {
async getPreviewImages() {
if (this.stream.commits.items.length === 0) return
// let angles = [-2, -1, 0, 1, 2]
let angles = [0]
for (let ang of angles) {
let previewUrl = `/preview/${this.stream.id}/objects/${this.stream.commits.items[0].referencedObject}/${ang}`
const res = await fetch(previewUrl, {
headers: localStorage.getItem('AuthToken')
? { Authorization: `Bearer ${localStorage.getItem('AuthToken')}` }
: {}
})
const blob = await res.blob()
const imgUrl = URL.createObjectURL(blob)
this.previewImgUrls.push(imgUrl)
if (ang === 0) this.currentPreviewImg = imgUrl
}
if (this.stream.collaborators.length > limit)
return this.stream.collaborators.slice(0, limit - 1)
return this.stream.collaborators
},
role() {
return this.stream.role.replace('stream:', '')
}
}
}
@@ -270,7 +270,9 @@ export default {
async getPreviewImage(angle) {
angle = angle || 0
let previewUrl = this.objectUrl.replace('streams', 'preview') + '/' + angle
const res = await fetch(previewUrl)
const res = await fetch(previewUrl, {
headers: localStorage.getItem('AuthToken') ? { Authorization: `Bearer ${localStorage.getItem('AuthToken')}` } : {}
})
const blob = await res.blob()
const imgUrl = URL.createObjectURL(blob)
if (this.$refs.cover) this.$refs.cover.style.backgroundImage = `url('${imgUrl}')`
@@ -26,6 +26,7 @@ query Streams($cursor: String) {
authorId
authorName
authorAvatar
referencedObject
}
}
branches {
+5 -1
View File
@@ -20,8 +20,12 @@ query User($id: String!) {
name
avatar
}
commits {
commits(limit: 1) {
totalCount
items{
id
referencedObject
}
}
branches {
totalCount
+2 -2
View File
@@ -77,7 +77,7 @@ const routes = [
// },
{
path: 'streams/:streamId',
name: 'streams',
// name: 'streams',
meta: {
title: 'Stream | Speckle'
},
@@ -214,7 +214,7 @@ router.beforeEach((to, from, next) => {
})
//TODO: include stream name in page title eg `My Cool Stream | Speckle`
router.afterEach((to, from) => {
router.afterEach((to) => {
if (localStorage.getItem('shouldRedirectTo') === to.path)
localStorage.removeItem('shouldRedirectTo')
+5 -3
View File
@@ -9,7 +9,7 @@
<v-col cols="12" sm="12" md="4" lg="3" xl="2">
<user-info-card :user="user"></user-info-card>
</v-col>
<v-col cols="12" sm="12" md="8" lg="9" xl="8" class="pt-10">
<v-col cols="12" sm="12" md="8" lg="9" xl="10" class="pt-10">
<v-card class="mb-3 elevation-0">
<v-card-title>
{{ user.name }} and you share {{ user.streams.totalCount }}
@@ -18,9 +18,11 @@
{{ user.commits.totalCount === 1 ? 'commit' : 'commits' }}.
</v-card-title>
</v-card>
<div v-for="(stream, i) in user.streams.items" :key="i">
<v-row>
<v-col cols="12" sm="12" md="6" lg="6" xl="4" v-for="(stream, i) in user.streams.items" :key="i">
<list-item-stream :stream="stream"></list-item-stream>
</div>
</v-col >
</v-row>
</v-col>
</v-row>
</v-container>
+5 -5
View File
@@ -13,9 +13,9 @@
<stream-new-dialog :open="newStreamDialog" />
</v-dialog>
</v-card>
<div v-if="$apollo.loading" class="mx-5 mt-5">
<div v-if="$apollo.loading" class="pa-3 mx-5 mt-5">
<v-skeleton-loader
type="list-item-avatar, list-item-three-line, list-item-avatar,list-item-three-line"
type="list-item-three-line"
></v-skeleton-loader>
</div>
<v-card
@@ -84,7 +84,7 @@
:message="`Hello there! It seems like you don't have any streams yet. Here's a handful of useful links to help you get started:`"
/>
</div>
<v-card v-if="user && user.streams.totalCount > 0" class="mt-5 mx-4" flat>
<v-card v-if="user && user.streams.totalCount > 0" class="my-5" flat>
<v-card-text class="body-1">
<span>
You have
@@ -98,8 +98,8 @@
</v-card-text>
</v-card>
<v-card elevation="0" color="transparent">
<div v-if="$apollo.loading" class="mx-5">
<v-skeleton-loader type="card, article, article"></v-skeleton-loader>
<div v-if="$apollo.loading" class="my-5">
<v-skeleton-loader type="list-item-three-line"></v-skeleton-loader>
</div>
</v-card>
<v-row v-if="streams && streams.items">