feat(frontend): New /embed route
This commit is contained in:
@@ -45,40 +45,6 @@
|
||||
style="position: absolute; width: 80%; left: 10%; opacity: 0.5"
|
||||
></v-progress-linear>
|
||||
|
||||
<div v-if="embeded" class="top-left ma-2">
|
||||
<v-btn
|
||||
text
|
||||
small
|
||||
color="primary"
|
||||
elevation="0"
|
||||
href="http://speckle.systems"
|
||||
target="blank"
|
||||
>
|
||||
Powered by
|
||||
<img src="@/assets/logo.svg" height="16" />
|
||||
Speckle
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<div v-if="embeded" class="top-right ma-2 d-flex">
|
||||
<ApolloQuery :query="streamQuery" :variables="{ id: $route.params.streamId }" class="">
|
||||
<template v-slot="{ result: { loading, error, data } }">
|
||||
<!-- Loading -->
|
||||
<div v-if="loading" class="loading apollo">Loading...</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-else-if="error" class="error apollo">An error occurred</div>
|
||||
|
||||
<!-- Result -->
|
||||
<div v-else-if="data" class="result apollo">{{ data.stream.name }}</div>
|
||||
|
||||
<!-- No result -->
|
||||
<div v-else class="no-result apollo">No result :(</div>
|
||||
</template>
|
||||
</ApolloQuery>
|
||||
<v-btn color="primary" small :href="url" target="blank">View in Speckle.xyz</v-btn>
|
||||
</div>
|
||||
|
||||
<v-card
|
||||
v-show="hasLoadedModel && loadProgress >= 99"
|
||||
style="position: absolute; bottom: 0px; z-index: 2; width: 100%"
|
||||
@@ -263,6 +229,10 @@ export default {
|
||||
showSelectionHelper: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
embeded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -271,7 +241,6 @@ export default {
|
||||
hasLoadedModel: false,
|
||||
loadProgress: 0,
|
||||
fullScreen: false,
|
||||
embeded: false,
|
||||
showHelp: false,
|
||||
alertMessage: null,
|
||||
showAlert: false,
|
||||
@@ -343,7 +312,6 @@ export default {
|
||||
}
|
||||
if (this.$route.query.embed) {
|
||||
this.fullScreen = true
|
||||
this.embeded = true
|
||||
//TODO: Remove overflow from window
|
||||
document.body.classList.add('no-scrollbar')
|
||||
}
|
||||
@@ -409,7 +377,7 @@ export default {
|
||||
load() {
|
||||
if (!this.objectUrl) return
|
||||
this.hasLoadedModel = true
|
||||
|
||||
console.log('loading model', this.objectUrl)
|
||||
window.__viewer.loadObject(this.objectUrl)
|
||||
window.__viewerLastLoadedUrl = this.objectUrl
|
||||
|
||||
@@ -432,10 +400,6 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.top-left {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
<template lang="html">
|
||||
<div class="fixed-overlay">
|
||||
<img src="@/assets/logo.svg" class="overlay-logo tada" />
|
||||
<div class="fixed-overlay" :class="error ? 'primary' : 'white'">
|
||||
<img v-if="!error" src="@/assets/logo.svg" class="overlay-logo tada" />
|
||||
<div v-else>
|
||||
<v-icon size="120" color="white tada">mdi-alert</v-icon>
|
||||
<h1 class="pt-6 pb-3">Ooops! 😅</h1>
|
||||
<h2>{{ error }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {}
|
||||
export default {
|
||||
name: 'SpeckleLoading',
|
||||
props: {
|
||||
error: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -13,7 +26,6 @@ export default {}
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
font-family: sans-serif !important;
|
||||
background-color: white;
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -24,11 +36,12 @@ export default {}
|
||||
text-align: center;
|
||||
font-weight: 400;
|
||||
font-size: 10px;
|
||||
padding-top: 200px;
|
||||
}
|
||||
|
||||
.overlay-logo {
|
||||
max-width: 50px;
|
||||
position: relative;
|
||||
top: 250px;
|
||||
top: 150px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -159,6 +159,11 @@ const routes = [
|
||||
},
|
||||
component: () => import('../views/GettingStartedView.vue')
|
||||
},
|
||||
{
|
||||
path: '/embed',
|
||||
name: 'Embeded Viewer',
|
||||
component: () => import('../views/EmbedViewer.vue')
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
name: 'notfound',
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
<template lang="html">
|
||||
<v-app class="no-scrollbar">
|
||||
<speckle-loading v-if="$apollo.queries.loading || error" :error="error" style="z-index: 101" />
|
||||
<div v-else class="no-scrollbar embed-view">
|
||||
<div class="top-left ma-2">
|
||||
<v-btn
|
||||
small
|
||||
outlined
|
||||
color="primary"
|
||||
elevation="0"
|
||||
href="http://speckle.systems"
|
||||
target="blank"
|
||||
>
|
||||
Powered by
|
||||
<img src="@/assets/logo.svg" height="16" />
|
||||
Speckle
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<div class="top-right ma-2 d-flex">
|
||||
<v-btn
|
||||
v-if="$apollo.data.stream && $apollo.data.serverInfo"
|
||||
color="primary"
|
||||
small
|
||||
href=""
|
||||
target="blank"
|
||||
>
|
||||
View
|
||||
<em class="pl-1 pr-1">
|
||||
<b>
|
||||
{{ $apollo.data.stream.name }}
|
||||
</b>
|
||||
({{ $apollo.data.stream.id }})
|
||||
</em>
|
||||
in
|
||||
<em>{{ $apollo.data.serverInfo.name }}</em>
|
||||
</v-btn>
|
||||
</div>
|
||||
<renderer
|
||||
v-if="input.stream"
|
||||
:object-url="objectUrl"
|
||||
embeded
|
||||
show-selection-helper
|
||||
></renderer>
|
||||
</div>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import Renderer from '../components/Renderer.vue'
|
||||
import SpeckleLoading from '../components/SpeckleLoading.vue'
|
||||
export default {
|
||||
name: 'EmbedViewer',
|
||||
components: { Renderer, SpeckleLoading },
|
||||
data() {
|
||||
return {
|
||||
error: null,
|
||||
input: {
|
||||
stream: this.$route.query.stream,
|
||||
object: this.$route.query.object,
|
||||
branch: this.$route.query.branch || 'main'
|
||||
}
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
stream: {
|
||||
query: gql`
|
||||
query Stream($id: String!, $branch: String!) {
|
||||
stream(id: $id) {
|
||||
id
|
||||
name
|
||||
description
|
||||
isPublic
|
||||
branch(name: $branch) {
|
||||
commits(limit: 1) {
|
||||
totalCount
|
||||
items {
|
||||
referencedObject
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return {
|
||||
id: this.input.stream,
|
||||
branch: this.input.branch
|
||||
}
|
||||
},
|
||||
error(err) {
|
||||
console.error(err)
|
||||
this.error = err
|
||||
}
|
||||
},
|
||||
serverInfo: {
|
||||
query: gql`
|
||||
query ServerInfo {
|
||||
serverInfo {
|
||||
name
|
||||
}
|
||||
}
|
||||
`,
|
||||
error(err) {
|
||||
console.error(err)
|
||||
this.error = err
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
displayType() {
|
||||
if (!this.input.stream) {
|
||||
return 'error'
|
||||
}
|
||||
if (this.input.object) return 'object'
|
||||
if (this.input.branch) return 'branch'
|
||||
return 'stream'
|
||||
},
|
||||
|
||||
objectUrl() {
|
||||
var objId = this.input.object || this.stream?.branch?.commits?.items[0]?.referencedObject
|
||||
|
||||
return `${window.location.protocol}//${window.location.host}/streams/${this.input.stream}/objects/${objId}`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
displayType(oldVal, newVal) {
|
||||
console.log(oldVal, newVal)
|
||||
if (newVal == 'error') this.error = 'Provided details were invalid'
|
||||
else {
|
||||
this.error = null
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
body::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.embed-view {
|
||||
height: 100vh !important;
|
||||
width: 100vw !important;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.no-scrollbar {
|
||||
overflow: hidden;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -44,6 +44,7 @@
|
||||
<stream-invite-dialog v-if="stream" ref="streamInviteDialog" :stream-id="stream.id" />
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SidebarStream from '../components/SidebarStream'
|
||||
import ErrorBlock from '../components/ErrorBlock'
|
||||
|
||||
Reference in New Issue
Block a user