ff6433128a
* Add Dialog * Add options to embed dialog * Min Height of Clipboard Input multiline to 3 lines * Check for visibility * Link to change access of project * Rename to guided mode * Change icon when user clicks copy button * Update Menu styles based on agi feedback * Update graphql.ts * Embed Options as hashState * Auto grow Clipboard Input * embed state and more options * Tidyups * Footer only shows when !embedOptions.isTransparent * Add auto/manual Load * Add Pre setup component * WIP Button Group mobile * Updates around manual load * Viewer Share nav * Add embed dialog to project page * Minor fixes * Check for federated * Responsive Tidyups * Responsive Fixes. Fix console issues * Add Alert to Version Embed * Disable Zoom * GQL updates * Comment Slideshow * GraphQl changes * Fix visibility * Build fix * Revert "Build fix" This reverts commit 0e706cbd9fde78204032bb1ec4421b1742d023ac. * remove unneeded change, revert yarn.lock * Test Commit * Remove commit test * Fix build * Update Tailwind. Add base url env * fix for portal scope issue * useLogger * useLogger * chore(fe2): include NUXT_PUBLIC_BASE_URL in deployment manifests * lazy load optimization * lint fixes * Updates * Re-add guided open Dialog sections * Prevent login popup on embed * Tidy up mobile combined button group * Tidy up embed Dialogs * Small styling issues * Update scrolling in embed dialog * Move selection info when embed * Testing fixes * Discuss in Speckle * Responsive Dialog Changes * Fix bug * WIP Manual Load * Fix nuxt errors * Fix nuxt logger issue * Fix embed dialog overflows * New Dialog layout * Responsive Breakpoint change * Preview Image * Fix bug with dialogSection * Hide selection info on mobile when thread is open * Footer Model Name * Overflow on ClipboardInput * Style fixes * Tidy ups * Responsive updates * Responsive fixes * Update button * Changes from testing * Fix embed height with footer * Fix Dialog Section * Fixes from testing * Move "reset filters" on embed * Small fixes * Updates from CR 1 * CR Comments 2 * Updates from CR * Add deserializeEmbedOptions helper * DialogSection changes * Revert changes in TextArea * Updates from CR * Only check for noscroll in watch * Update useRoute * Comment Slideshow mode * Changes from testing * Fix mobile share button * onMounted warn fixes * Updates from testing * Remove nesting of ManualLoad * Keep Speckle text on mobile * minor cleanup & bugfixes * Add target prop to Logo * navbar flash fix + more cleanup * Fix urls * Footer Logo changes * Remove viewer-transparent from layout * Add Reply in Speckle * Remove Anchored Points from embed * Final changes pre CR * Fix Anchored Points * Update packages/frontend-2/components/project/model-page/dialog/embed/Embed.vue Co-authored-by: Kristaps Fabians Geikins <fabians@speckle.systems> * Fixes from CR * Updates from cr * Changes WIP * Fix for dialog opening * Changes from PR * Updates to check embed in activity * fix(fe2): project settings dialog error * Make Team open section on click of "Manage" * Fixes from merge * Changes from cr * Compare old to new in watch * Fix logo in footer of embed * Fixes from merge * Fix build. Fix lazy load * Updates from Benjamin * Fix transparent bg --------- Co-authored-by: Kristaps Fabians Geikins <fabis94@live.com> Co-authored-by: Iain Sproat <68657+iainsproat@users.noreply.github.com> Co-authored-by: Kristaps Fabians Geikins <fabians@speckle.systems>
130 lines
3.6 KiB
TypeScript
130 lines
3.6 KiB
TypeScript
import { writableAsyncComputed } from '~/lib/common/composables/async'
|
|
import { useScopedState } from '~/lib/common/composables/scopedState'
|
|
import { ViewerHashStateKeys } from '~/lib/viewer/composables/setup/urlHashState'
|
|
import { useConditionalViewerRendering } from '~/lib/viewer/composables/ui'
|
|
import { useRouteHashState } from '~~/lib/common/composables/url'
|
|
|
|
export type EmbedOptions = {
|
|
isEnabled?: boolean
|
|
isTransparent?: boolean
|
|
hideControls?: boolean
|
|
hideSelectionInfo?: boolean
|
|
noScroll?: boolean
|
|
manualLoad?: boolean
|
|
}
|
|
|
|
export function isEmbedOptions(obj: unknown): obj is EmbedOptions {
|
|
if (typeof obj === 'object' && obj !== null) {
|
|
const possibleOptions = obj as Partial<EmbedOptions>
|
|
return Object.keys(possibleOptions).every(
|
|
(key) =>
|
|
[
|
|
'isEnabled',
|
|
'isTransparent',
|
|
'hideControls',
|
|
'hideSelectionInfo',
|
|
'noScroll',
|
|
'manualLoad'
|
|
].includes(key) &&
|
|
typeof possibleOptions[key as keyof EmbedOptions] === 'boolean'
|
|
)
|
|
}
|
|
return false
|
|
}
|
|
|
|
export function deserializeEmbedOptions(embedString: string | null): EmbedOptions {
|
|
const logger = useLogger()
|
|
if (!embedString) {
|
|
return { isEnabled: false }
|
|
}
|
|
|
|
try {
|
|
const parsed: unknown = JSON.parse(embedString)
|
|
if (isEmbedOptions(parsed)) {
|
|
return { ...parsed, isEnabled: true }
|
|
}
|
|
logger.error('Parsed object is not of type EmbedOptions')
|
|
} catch (error) {
|
|
logger.error(error)
|
|
}
|
|
|
|
return { isEnabled: false }
|
|
}
|
|
|
|
export function useEmbedState() {
|
|
const { hashState } = useRouteHashState()
|
|
|
|
const embedOptions = writableAsyncComputed({
|
|
get: () => {
|
|
const embedString = hashState.value[ViewerHashStateKeys.EmbedOptions]
|
|
return deserializeEmbedOptions(embedString)
|
|
},
|
|
set: async (newOptions) => {
|
|
const embedString = newOptions ? JSON.stringify(newOptions) : null
|
|
await hashState.update({
|
|
...hashState.value,
|
|
[ViewerHashStateKeys.EmbedOptions]: embedString
|
|
})
|
|
},
|
|
initialState: null,
|
|
asyncRead: false
|
|
})
|
|
|
|
return { embedOptions }
|
|
}
|
|
|
|
const embedStateScopedKey = Symbol('EmbedStateScopedKey')
|
|
|
|
export function useEmbed() {
|
|
const { embedOptions } = useEmbedState()
|
|
const { showControls } = useConditionalViewerRendering()
|
|
|
|
// useScopedState so that we don't keep creating new computeds
|
|
return useScopedState(embedStateScopedKey, () => {
|
|
const createComputed = <K extends keyof EmbedOptions>(key: K) =>
|
|
writableAsyncComputed({
|
|
get: () => embedOptions.value?.[key],
|
|
set: async (newVal) => {
|
|
await embedOptions.update({
|
|
...(embedOptions.value ?? {}),
|
|
...{
|
|
[key]: newVal
|
|
}
|
|
})
|
|
},
|
|
initialState: null,
|
|
asyncRead: false
|
|
})
|
|
|
|
const isEnabled = createComputed('isEnabled')
|
|
const isTransparent = createComputed('isTransparent')
|
|
|
|
const hideSelectionInfo = createComputed('hideSelectionInfo')
|
|
const noScroll = createComputed('noScroll')
|
|
const manualLoad = createComputed('manualLoad')
|
|
|
|
const showControlsNew = writableAsyncComputed({
|
|
get: () => showControls.value,
|
|
set: async (newVal) =>
|
|
await embedOptions.update({
|
|
...(embedOptions.value ?? {}),
|
|
...{
|
|
hideControls: !(newVal || undefined)
|
|
}
|
|
}),
|
|
initialState: null,
|
|
asyncRead: false
|
|
})
|
|
|
|
return {
|
|
isEnabled,
|
|
isEmbedEnabled: isEnabled,
|
|
isTransparent,
|
|
showControls: showControlsNew,
|
|
hideSelectionInfo,
|
|
noScroll,
|
|
manualLoad
|
|
}
|
|
})
|
|
}
|