feat: integrate accessible journey world and controls
This commit is contained in:
64
src/components/DriveControls.vue
Normal file
64
src/components/DriveControls.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import type { MotionPolicy, QualityTier } from '@/journey/motion-policy';
|
||||
|
||||
const props = defineProps<{
|
||||
policy: MotionPolicy;
|
||||
maximumQuality: QualityTier;
|
||||
sceneStatus: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
pause: [];
|
||||
resume: [];
|
||||
enable: [];
|
||||
qualityChange: [quality: QualityTier];
|
||||
}>();
|
||||
|
||||
const action = computed(() => {
|
||||
if (props.policy.reason === 'visitor-pause') return { label: 'Resume motion', event: 'resume' as const };
|
||||
if (props.policy.reason === 'saved-static') return { label: 'Enable motion', event: 'enable' as const };
|
||||
if (props.policy.reason === 'full') return { label: 'Pause motion', event: 'pause' as const };
|
||||
return null;
|
||||
});
|
||||
|
||||
const statusText = computed(() => {
|
||||
if (props.policy.reason === 'system-reduce') return 'Motion: static — reduced motion requested';
|
||||
if (props.policy.reason === 'data-saver') return 'Motion: static — data saver is active';
|
||||
if (props.policy.reason === 'visitor-pause') return 'Motion: paused';
|
||||
if (props.policy.reason === 'saved-static') return 'Motion: static';
|
||||
if (props.sceneStatus === 'failed' || props.sceneStatus === 'static') return 'Motion: static — scene unavailable';
|
||||
if (props.sceneStatus === 'loading' || props.sceneStatus === 'idle') return 'Motion: preparing';
|
||||
return 'Motion: active';
|
||||
});
|
||||
|
||||
const runAction = (): void => {
|
||||
const event = action.value?.event;
|
||||
if (event === 'pause') emit('pause');
|
||||
else if (event === 'resume') emit('resume');
|
||||
else if (event === 'enable') emit('enable');
|
||||
};
|
||||
|
||||
const changeQuality = (event: Event): void => {
|
||||
const value = (event.currentTarget as HTMLSelectElement).value;
|
||||
if (value === 'high' || value === 'medium' || value === 'low' || value === 'static') {
|
||||
emit('qualityChange', value);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="drive-controls">
|
||||
<button v-if="action" type="button" @click="runAction">{{ action.label }}</button>
|
||||
<label>
|
||||
<span>Quality</span>
|
||||
<select :value="maximumQuality" aria-label="Quality control" @change="changeQuality">
|
||||
<option value="high">High</option>
|
||||
<option value="medium">Medium</option>
|
||||
<option value="low">Low</option>
|
||||
<option value="static">Static</option>
|
||||
</select>
|
||||
</label>
|
||||
<p class="drive-controls__status" role="status">{{ statusText }}</p>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user