Skip to content

Commit

Permalink
BGDIINF_SB-3007: further simplification of camera position URL parsing
Browse files Browse the repository at this point in the history
mimicking what was made for the layers param instead of overriding most of the base class' functions
  • Loading branch information
pakb authored and fredj committed Jul 13, 2023
1 parent 842a8e9 commit da23e27
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 99 deletions.
116 changes: 29 additions & 87 deletions src/router/storeSync/CameraParamConfig.class.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import AbstractParamConfig from '@/router/storeSync/abstractParamConfig.class'

function readValueFromObjectOrReturnNull(object, paramName, type) {
if (object && paramName in object) {
return type(object[paramName])
}
return null
}

/**
* @param query
* Reads the camera position from the single URL param. Returns null if the camera position is not
* defined or not complete
*
* @param urlParamValue
* @returns {CameraPosition | null}
*/
function parseCameraFromQuery(query) {
const camera = readValueFromObjectOrReturnNull(query, 'camera', String)
if (camera) {
let cameraValues = camera.split(',')
export function readCameraFromUrlParam(urlParamValue) {
if (urlParamValue) {
let cameraValues = urlParamValue.split(',')
// the split must have 6 components (x, y, z, pitch, heading and roll)
if (cameraValues.length === 6) {
// parsing to number all values (default to 0 if the value is empty)
Expand All @@ -33,6 +28,26 @@ function parseCameraFromQuery(query) {
return null
}

function dispatchCameraFromUrlIntoStore(store, urlParamValue) {
const promisesForAllDispatch = []
const camera = readCameraFromUrlParam(urlParamValue)
if (camera) {
promisesForAllDispatch.push(store.dispatch('setCameraPosition', camera))
}
return Promise.all(promisesForAllDispatch)
}

function generateCameraUrlParamFromStoreValues(store) {
if (store.state.ui.showIn3d) {
const { x, y, z, pitch, heading, roll } = store.state.position.camera
const valuesAsString = [x, y, z, pitch, heading, roll].map((value) =>
value === 0 ? '' : `${value}`
)
return valuesAsString.join(',')
}
return null
}

/**
* Definition of a set of URL params to store the position camera for the 3D viewer
*
Expand All @@ -46,83 +61,10 @@ export default class CameraParamConfig extends AbstractParamConfig {
super(
'camera',
'setCameraPosition',
() => {},
() => {},
dispatchCameraFromUrlIntoStore,
generateCameraUrlParamFromStoreValues,
false,
String
)
}

/**
* Reads the camera position from the single URL param
*
* @param query
* @returns {CameraPosition | null}
* @override
*/
readValueFromQuery(query) {
return parseCameraFromQuery(query)
}

/**
* Adds the camera URL param if 3D is active, or removes the camera URL param when not active
*
* @param query
* @param store
* @override
*/
populateQueryWithStoreValue(query, store) {
if (store.state.ui.showIn3d) {
const { x, y, z, pitch, heading, roll } = store.state.position.camera
const valuesAsString = [x, y, z, pitch, heading, roll].map((value) =>
value === 0 ? '' : `${value}`
)
query['camera'] = valuesAsString.join(',')
} else {
delete query['camera']
}
}

/**
* Dispatches to the store the camera position from the URL, if 3D is active
*
* @param {Vuex.Store} store
* @param query
* @returns {Promise<Awaited[]>}
* @override
*/
populateStoreWithQueryValue(store, query) {
const promisesSetValuesInStore = []
if (store.state.ui.showIn3d) {
const cameraInQuery = parseCameraFromQuery(query)
if (cameraInQuery) {
promisesSetValuesInStore.push(store.dispatch('setCameraPosition', cameraInQuery))
}
}
return Promise.all(promisesSetValuesInStore)
}

/**
* Checks if the camera in the URL is different from the one in the store, this check happens
* only when 3D is active
*
* @param query
* @param store
* @returns {boolean}
* @override
*/
valuesAreDifferentBetweenQueryAndStore(query, store) {
if (store.state.ui.showIn3d) {
const queryCamera = parseCameraFromQuery(query)
if (!queryCamera) {
return true
}
const camera = store.state.position.camera
let isEqual = true
Object.entries(camera).forEach(([key, value]) => {
isEqual &= value === queryCamera[key]
})
return !isEqual
}
}
}
24 changes: 12 additions & 12 deletions src/router/storeSync/__tests__/CameraParamConfig.class.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import PositionUrlParamConfig from '@/router/storeSync/CameraParamConfig.class'
import PositionUrlParamConfig, {
readCameraFromUrlParam,
} from '@/router/storeSync/CameraParamConfig.class'
import { beforeEach, describe, expect, it, vi } from 'vitest'

describe('CameraParamConfig class test', () => {
Expand Down Expand Up @@ -30,7 +32,7 @@ describe('CameraParamConfig class test', () => {
}
})

describe('reading the query', () => {
describe('reading the query (readCameraFromUrlParam)', () => {
const expectedCamera = {
x: 123,
y: 456,
Expand Down Expand Up @@ -58,25 +60,23 @@ describe('CameraParamConfig class test', () => {
expect(camera.roll).to.eq(expectedCamera.roll)
}
it('reads 3D URL param correctly', () => {
const result = testInstance.readValueFromQuery({
camera: generateCameraString(
const result = readCameraFromUrlParam(
generateCameraString(
expectedCamera.x,
expectedCamera.y,
expectedCamera.z,
expectedCamera.pitch,
expectedCamera.heading,
expectedCamera.roll
),
showIn3d: true,
})
)
)
expect(result).to.be.an('Object')
testCameraValues(result, expectedCamera)
})
it('fills any empty camera value with 0s', () => {
const result = testInstance.readValueFromQuery({
camera: generateCameraString(expectedCamera.x, '', expectedCamera.z, '', '', ''),
showIn3d: true,
})
const result = readCameraFromUrlParam(
generateCameraString(expectedCamera.x, '', expectedCamera.z, '', '', '')
)
expect(result).to.be.an('Object')
testCameraValues(result, {
x: expectedCamera.x,
Expand Down Expand Up @@ -123,7 +123,7 @@ describe('CameraParamConfig class test', () => {
fakeStore.state.ui.showIn3d = true
})
it('dispatches 3D param correctly to the store', () => {
testInstance.populateStoreWithQueryValue(fakeStore, { camera: '1,2,3,4,5,6' })
testInstance.populateStoreWithQueryValue(fakeStore, '1,2,3,4,5,6')
expect(fakeStore.dispatch).toHaveBeenCalledOnce()
expect(fakeStore.dispatch.mock.calls[0]).to.include.members(['setCameraPosition'])
})
Expand Down

0 comments on commit da23e27

Please sign in to comment.