bde148f286
* wip * some extra fixes * stuff kinda works? * need to figure out mocks * need to figure out mocks * fix db listener * gqlgen fix * minor gqlgen watch adjustment * lint fixes * delete old codegen file * converting migrations to ESM * getModuleDIrectory * vitest sort of works * added back ts-vitest * resolve gql double load * fixing test timeout configs * TSC lint fix * fix automate tests * moar debugging * debugging * more debugging * codegen update * server works * yargs migrated * chore(server): getting rid of global mocks for Server ESM (#5046) * got rid of email mock * got rid of comment mocks * got rid of multi region mocks * got rid of stripe mock * admin override mock updated * removed final mock * fixing import.meta.resolve calls * another import.meta.resolve fix * added requested test * nyc ESM fix * removed unneeded deps + linting * yarn lock forgot to commit * tryna fix flakyness * email capture util fix * sendEmail fix * fix TSX check * sender transporter fix + CR comments * merge main fix * test fixx * circleci fix * gqlgen bigint fix * error formatter fix * more error formatting improvements * esmloader added to Dockerfile * more dockerfile fixes * bg jobs fix
200 lines
5.8 KiB
TypeScript
200 lines
5.8 KiB
TypeScript
import {
|
|
ConvertLegacyDataToState,
|
|
GetViewerResourcesForComments
|
|
} from '@/modules/comments/domain/operations'
|
|
import { LegacyCommentViewerData } from '@/modules/core/graph/generated/graphql'
|
|
import { viewerResourcesToString } from '@/modules/core/services/commit/viewerResources'
|
|
import { Nullable, SpeckleViewer } from '@speckle/shared'
|
|
import { has, get, intersection, isObjectLike } from 'lodash-es'
|
|
|
|
type SerializedViewerState = SpeckleViewer.ViewerState.SerializedViewerState
|
|
|
|
export type LegacyData = Partial<LegacyCommentViewerData>
|
|
|
|
export type DataStruct = {
|
|
version: number
|
|
state: SerializedViewerState
|
|
}
|
|
|
|
export function inputToDataStruct(
|
|
inputSerializedViewerState: unknown
|
|
): Nullable<DataStruct> {
|
|
const state = SpeckleViewer.ViewerState.isSerializedViewerState(
|
|
inputSerializedViewerState
|
|
)
|
|
? inputSerializedViewerState
|
|
: null
|
|
if (!state) return null
|
|
|
|
return {
|
|
version: SpeckleViewer.ViewerState.SERIALIZED_VIEWER_STATE_VERSION,
|
|
state
|
|
}
|
|
}
|
|
|
|
export function isDataStruct(data: unknown): data is DataStruct {
|
|
if (!data) return false
|
|
if (!has(data, 'version')) return false
|
|
const stateRaw = get(data, 'state')
|
|
return SpeckleViewer.ViewerState.isSerializedViewerState(stateRaw)
|
|
}
|
|
|
|
export const formatSerializedViewerState =
|
|
SpeckleViewer.ViewerState.formatSerializedViewerState
|
|
|
|
export function isLegacyData(data: unknown): data is LegacyData {
|
|
if (!data) return false
|
|
const keys: Array<keyof LegacyData> = [
|
|
'camPos',
|
|
'filters',
|
|
'location',
|
|
'sectionBox',
|
|
'selection'
|
|
]
|
|
if (!isObjectLike(data)) return false
|
|
|
|
const valKeys = Object.keys(data as Record<string, unknown>)
|
|
if (intersection(valKeys, keys).length !== keys.length) return false
|
|
|
|
return true
|
|
}
|
|
|
|
export function convertStateToLegacyData(state: SerializedViewerState): LegacyData {
|
|
const camPos = state.ui.camera.position
|
|
const camTarget = state.ui.camera.target
|
|
const zoom = state.ui.camera.zoom
|
|
const isOrtho = state.ui.camera.isOrthoProjection
|
|
const selection = state.ui.selection
|
|
const selectionLocation = selection || camTarget
|
|
|
|
const ret: LegacyData = {
|
|
camPos: [
|
|
camPos[0] || 0,
|
|
camPos[1] || 0,
|
|
camPos[2] || 0,
|
|
camTarget[0] || 0,
|
|
camTarget[1] || 0,
|
|
camTarget[2] || 0,
|
|
zoom || 1,
|
|
isOrtho ? 1 : 0
|
|
],
|
|
filters: {
|
|
passMin: state.viewer.metadata.filteringState?.passMin || null,
|
|
passMax: state.viewer.metadata.filteringState?.passMax || null,
|
|
hiddenIds: state.ui.filters.hiddenObjectIds.slice(),
|
|
isolatedIds: state.ui.filters.isolatedObjectIds.slice(),
|
|
sectionBox: {
|
|
min: (state.ui?.sectionBox?.min as number[]) || [0, 0, 0],
|
|
max: (state.ui?.sectionBox?.max as number[]) || [0, 0, 0],
|
|
rotation: (state.ui?.sectionBox?.rotation as number[]) || [
|
|
1, 0, 0, 0, 1, 0, 0, 0, 1
|
|
]
|
|
},
|
|
propertyInfoKey: state.ui.filters.propertyFilter.key
|
|
},
|
|
location: {
|
|
x: selectionLocation[0] || 0,
|
|
y: selectionLocation[1] || 0,
|
|
z: selectionLocation[2] || 0
|
|
},
|
|
sectionBox: {
|
|
min: (state.ui?.sectionBox?.min as number[]) || [0, 0, 0],
|
|
max: (state.ui?.sectionBox?.max as number[]) || [0, 0, 0],
|
|
rotation: (state.ui?.sectionBox?.rotation as number[]) || [
|
|
1, 0, 0, 0, 1, 0, 0, 0, 1
|
|
]
|
|
},
|
|
selection: null
|
|
}
|
|
return ret
|
|
}
|
|
|
|
export const convertLegacyDataToStateFactory =
|
|
(deps: {
|
|
getViewerResourcesForComments: GetViewerResourcesForComments
|
|
}): ConvertLegacyDataToState =>
|
|
async (data, comment) => {
|
|
const resources = await deps.getViewerResourcesForComments(comment.streamId, [
|
|
comment.id
|
|
])
|
|
const sectionBox = data.filters?.sectionBox || data.sectionBox
|
|
|
|
const ret: SerializedViewerState = {
|
|
projectId: comment.streamId,
|
|
sessionId: 'legacy-sessionId',
|
|
viewer: {
|
|
metadata: {
|
|
filteringState: {
|
|
passMax: data.filters?.passMax,
|
|
passMin: data.filters?.passMin
|
|
}
|
|
}
|
|
},
|
|
resources: {
|
|
request: {
|
|
resourceIdString: viewerResourcesToString(resources),
|
|
threadFilters: {
|
|
includeArchived: false,
|
|
loadedVersionsOnly: false
|
|
}
|
|
}
|
|
},
|
|
ui: {
|
|
threads: {
|
|
openThread: {
|
|
threadId: null,
|
|
isTyping: false,
|
|
newThreadEditor: true
|
|
}
|
|
},
|
|
spotlightUserSessionId: null,
|
|
explodeFactor: 0,
|
|
filters: {
|
|
isolatedObjectIds: data.filters?.isolatedIds || [],
|
|
hiddenObjectIds: data.filters?.hiddenIds || [],
|
|
selectedObjectApplicationIds: {},
|
|
propertyFilter: {
|
|
key: data.filters?.propertyInfoKey || null,
|
|
isApplied: true
|
|
}
|
|
},
|
|
camera: {
|
|
position: [
|
|
data.camPos?.[0] || 0,
|
|
data.camPos?.[1] || 0,
|
|
data.camPos?.[2] || 0
|
|
],
|
|
target: [data.camPos?.[3] || 0, data.camPos?.[4] || 0, data.camPos?.[5] || 0],
|
|
isOrthoProjection: !!data.camPos?.[6],
|
|
zoom: data.camPos?.[7] || 1
|
|
},
|
|
viewMode: 0,
|
|
sectionBox: sectionBox
|
|
? {
|
|
min: (sectionBox.min as number[]) || [0, 0, 0],
|
|
max: (sectionBox.max as number[]) || [0, 0, 0],
|
|
rotation: (sectionBox.rotation as number[]) || [1, 0, 0, 0, 1, 0, 0, 0, 1]
|
|
}
|
|
: null,
|
|
lightConfig: {},
|
|
selection: data.location
|
|
? [
|
|
data.location.x as number,
|
|
data.location.y as number,
|
|
data.location.z as number
|
|
]
|
|
: null,
|
|
diff: {
|
|
command: null,
|
|
mode: 1,
|
|
time: 0.5
|
|
},
|
|
measurement: {
|
|
enabled: false,
|
|
options: null
|
|
}
|
|
}
|
|
}
|
|
return ret
|
|
}
|