Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,34 @@ jobs:
# ./gradlew build
# ./gradlew clean

typecheck-client:
name: "Typecheck Client"
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: pnpm
cache-dependency-path: photon-client/pnpm-lock.yaml
- name: Typecheck Client
working-directory: photon-client
run: |
pnpm install --frozen-lockfile
pnpm type-check
playwright-tests:
name: "Playwright E2E tests"
runs-on: ubuntu-24.04
needs: [validation]
steps:
# Checkout code.
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch tags
run: git fetch --tags --force
- uses: actions/setup-java@v5
with:
java-version: 25
Expand Down Expand Up @@ -136,7 +152,6 @@ jobs:
runs-on: ubuntu-24.04
needs: [validation]
steps:
# Checkout code.
- name: Checkout code
uses: actions/checkout@v6
with:
Expand Down
2 changes: 2 additions & 0 deletions photon-client/env.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
/// <reference types="vite/client" />

declare module "vue3-virtual-scroll-list";
7 changes: 5 additions & 2 deletions photon-client/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import skipFormattingConfig from "@vue/eslint-config-prettier/skip-formatting";

export default defineConfigWithVueTs(
pluginVue.configs["flat/recommended-error"],
vueTsConfigs.recommended,
vueTsConfigs.recommendedTypeChecked,
skipFormattingConfig,
{
ignores: ["**/dist/**", "playwright-report"]
Expand Down Expand Up @@ -42,10 +42,13 @@ export default defineConfigWithVueTs(
"vue/no-use-v-else-with-v-for": "error",
"vue/no-useless-mustaches": "error",
"vue/no-useless-v-bind": "error",
"vue/prefer-use-template-ref": "error",
"vue/require-default-prop": "off",
"vue/require-typed-ref": "error",
"vue/v-for-delimiter-style": "error",
"vue/v-on-event-hyphenation": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-empty-object-type": "error",
"@typescript-eslint/no-explicit-any": "error",
"vue/valid-v-slot": ["error", { allowModifiers: true }]
}
}
Expand Down
5 changes: 3 additions & 2 deletions photon-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"format-ci": "prettier --check src/",
"test": "playwright test",
"test-ui": "playwright test --ui",
"test-setup": "playwright install --with-deps"

"test-setup": "playwright install --with-deps",
"type-check": "vue-tsc --noEmit"
},
"dependencies": {
"@fontsource/prompt": "^5.2.6",
Expand All @@ -40,6 +40,7 @@
"@types/node": "^24.0.0",
"@types/three": "^0.178.0",
"@vitejs/plugin-vue": "^6.0.6",
"vue-tsc": "^3.2.5",
"@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.5.0",
"@vue/tsconfig": "^0.7.0",
Expand Down
69 changes: 69 additions & 0 deletions photon-client/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion photon-client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { useTheme } from "vuetify";
import { restoreThemeConfig } from "@/lib/ThemeManager";

const is_demo = import.meta.env.MODE === "demo";
const backendHost = inject<string>("backendHost");
if (!is_demo) {
const websocket = new AutoReconnectingWebsocket(
`ws://${inject("backendHost")}/websocket_data`,
`ws://${backendHost}/websocket_data`,
() => {
useStateStore().$patch({ backendConnected: true });
},
Expand Down
8 changes: 4 additions & 4 deletions photon-client/src/components/app/photon-3d-visualizer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { PhotonTarget } from "@/types/PhotonTrackingTypes";
// @ts-expect-error Intellisense says these conflict with the dynamic imports below
import type { Mesh, Object3D, PerspectiveCamera, Scene, WebGLRenderer } from "three";
// @ts-expect-error Intellisense says these conflict with the dynamic imports below
import type { TrackballControls } from "three/examples/jsm/controls/TrackballControls";
import type { TrackballControls } from "three/examples/jsm/controls/TrackballControls.js";
import { onBeforeUnmount, onMounted, watchEffect } from "vue";
const {
ArrowHelper,
Expand All @@ -20,7 +20,7 @@ const {
Scene,
WebGLRenderer
} = await import("three");
const { TrackballControls } = await import("three/examples/jsm/controls/TrackballControls");
const { TrackballControls } = await import("three/examples/jsm/controls/TrackballControls.js");

import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
import { createPerspectiveCamera } from "@/lib/ThreeUtils";
Expand Down Expand Up @@ -213,14 +213,14 @@ onMounted(async () => {
renderer.render(scene, camera);
};

drawTargets(props.targets);
await drawTargets(props.targets);
animate();
});
onBeforeUnmount(() => {
window.removeEventListener("resize", onWindowResize);
});
watchEffect(() => {
drawTargets(props.targets);
void drawTargets(props.targets);
});
</script>

Expand Down
33 changes: 21 additions & 12 deletions photon-client/src/components/app/photon-calibration-visualizer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, watch, watchEffect, type Ref } from "vue";
import type {
Scene as SceneType,
PerspectiveCamera as PerspectiveCameraType,
WebGLRenderer as WebGLRendererType,
Group as GroupType,
Object3D
} from "three";
import type { TrackballControls as TrackballControlsType } from "three/examples/jsm/controls/TrackballControls.js";
const {
AmbientLight,
AxesHelper,
Expand All @@ -16,7 +24,7 @@ const {
SphereGeometry,
WebGLRenderer
} = await import("three");
const { TrackballControls } = await import("three/examples/jsm/controls/TrackballControls");
const { TrackballControls } = await import("three/examples/jsm/controls/TrackballControls.js");
import type { BoardObservation, CameraCalibrationResult } from "@/types/SettingTypes";
import axios from "axios";
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
Expand All @@ -31,12 +39,12 @@ const props = defineProps<{
title: string;
}>();

let scene: Scene | undefined;
let camera: PerspectiveCamera | undefined;
let renderer: WebGLRenderer | undefined;
let controls: TrackballControls | undefined;
let scene: SceneType | undefined;
let camera: PerspectiveCameraType | undefined;
let renderer: WebGLRendererType | undefined;
let controls: TrackballControlsType | undefined;

const createChessboard = (obs: BoardObservation, cal: CameraCalibrationResult): Group => {
const createChessboard = (obs: BoardObservation, cal: CameraCalibrationResult): GroupType => {
const group = new Group();

if (obs.locationInImageSpace.length === 0) return group;
Expand Down Expand Up @@ -194,9 +202,6 @@ const resetCamThirdPerson = () => {
let animationFrameId: number | null = null;

onMounted(async () => {
// Grab data first off
fetchCalibrationData();

scene = new Scene();
camera = new PerspectiveCamera(75, 800 / 800, 0.1, 1000);

Expand Down Expand Up @@ -256,6 +261,10 @@ onMounted(async () => {

controls.update();

// Fetch calibration only after the scene is ready so the initial draw
// can happen immediately when the data arrives.
await fetchCalibrationData();

const animate = () => {
if (!scene || !camera || !renderer || !controls) {
return;
Expand Down Expand Up @@ -318,7 +327,7 @@ if (import.meta.hot) {
}

watchEffect(() => {
drawCalibration(calibrationData.value);
void drawCalibration(calibrationData.value);
});

watch(
Expand All @@ -328,9 +337,9 @@ watch(
props.resolution.height,
useCameraSettingsStore().getCalibrationCoeffs(props.resolution)
],
() => {
async () => {
console.log("Camera or resolution changed, refetching calibration");
fetchCalibrationData();
await fetchCalibrationData();
}
);
</script>
Expand Down
Loading
Loading