Skip to content

Commit 484e8d4

Browse files
authored
General UI Refinements (#1678)
Does the following: - Adjusts the shade of red buttons and banners to increase readability and reduce eye strain ![image](https://github.com/user-attachments/assets/7f741a9e-dc1e-4394-b87d-580e189245b1) ![image](https://github.com/user-attachments/assets/b23202f1-4cf6-46c1-aca5-2455a09259cd) - Cleans up factory reset and camera deletion modals ![image](https://github.com/user-attachments/assets/e6564732-d578-43da-bc83-729ec6fdbc5e) ![image](https://github.com/user-attachments/assets/9c5a1cba-f4fd-47ea-811c-abbabe5fa3a4) - Removes matchCamerasOnlyByPath as it is no longer used and throws errors in the console ![image](https://github.com/user-attachments/assets/77043993-26a2-4de4-8e98-702e7f285dc6) - Limits the criteria to flag a camera mismatch in Camera Matching to only what is necessary based on camera type and highlights differences in table properties (testing on this is appreciated) ![image](https://github.com/user-attachments/assets/cfbd96c1-09dd-414a-8177-693fc054b26f) - Only displays both saved vs. current info in camera matching if there is a difference between the two ![image](https://github.com/user-attachments/assets/6223ffc8-4cff-464f-8b54-720c3222a5d5) - Some general code cleanup (reduced unnecessary padding/margin/row-col statements, style="display:flex;" -> class="d-flex", etc. - Moves Compact Mode button to the bottom away from all the menu items (cleaner imo, open to thoughts) - Establishes a general spacing format for cards and pages and applies this to existing cards and pages to create a consistent look and feel to the UI (e.g. keeping things in line and less erratic spacing/placement of UI elements) ![image](https://github.com/user-attachments/assets/1ab0ca4b-303e-436d-97b3-da72d46c4fcb) ![image](https://github.com/user-attachments/assets/82ba9e53-f854-4309-bc00-7b5d0bad58b7) ![image](https://github.com/user-attachments/assets/18aa6ca4-e6fa-4125-8a0a-e6a007a0337d) ![image](https://github.com/user-attachments/assets/77043993-26a2-4de4-8e98-702e7f285dc6) - Delete protection for camera matching modules - Anti-backend-spam for activate/deactivate/delete modules to hopefully prevent any odd behavior from button spamming - Enforces a common camera stream size on camera matching view (NEEDS MORE TESTING) ![image](https://github.com/user-attachments/assets/9032783d-1edf-4c6e-ba7b-00e5f20280df) https://private-user-images.githubusercontent.com/29715865/400783758-dc99c151-b8a7-4367-a173-74c2fc5b2666.mp4?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzYyNTc3NzEsIm5iZiI6MTczNjI1NzQ3MSwicGF0aCI6Ii8yOTcxNTg2NS80MDA3ODM3NTgtZGM5OWMxNTEtYjhhNy00MzY3LWExNzMtNzRjMmZjNWIyNjY2Lm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAxMDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMTA3VDEzNDQzMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWMwOWM1MDc2ZTVlOWZhM2MxYjAwZjAyZTc2MTYyZTk1ZTVmOGFhZmVkMzlmODRlZTk1ODVlOTk2ZGQzZmM0Y2EmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.ovtRnObwbkEfljr9d5fqaory0nH91LWJSSkmrUUe_4Y
1 parent fa2034d commit 484e8d4

34 files changed

+1095
-962
lines changed

photon-client/src/components/app/photon-camera-stream.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { UiCameraConfiguration } from "@/types/SettingTypes";
99
const props = defineProps<{
1010
streamType: "Raw" | "Processed";
1111
id: string;
12+
outerId?: string;
1213
cameraSettings: UiCameraConfiguration;
1314
}>();
1415
@@ -90,7 +91,7 @@ onBeforeUnmount(() => {
9091
</script>
9192

9293
<template>
93-
<div class="stream-container" :style="containerStyle">
94+
<div :id="outerId" class="stream-container" :style="containerStyle">
9495
<img :src="loadingImage" class="stream-loading" />
9596
<img
9697
:id="id"

photon-client/src/components/app/photon-sidebar.vue

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,17 @@ const needsCamerasConfigured = computed<boolean>(() => {
8181
<v-list-item-title>Documentation</v-list-item-title>
8282
</v-list-item-content>
8383
</v-list-item>
84-
<v-list-item v-if="mdAndUp" link @click="() => (compact = !compact)">
85-
<v-list-item-icon>
86-
<v-icon v-if="compact || !mdAndUp"> mdi-chevron-right </v-icon>
87-
<v-icon v-else> mdi-chevron-left </v-icon>
88-
</v-list-item-icon>
89-
<v-list-item-content>
90-
<v-list-item-title>Compact Mode</v-list-item-title>
91-
</v-list-item-content>
92-
</v-list-item>
9384

9485
<div style="position: absolute; bottom: 0; left: 0">
86+
<v-list-item v-if="mdAndUp" link @click="() => (compact = !compact)">
87+
<v-list-item-icon>
88+
<v-icon v-if="compact || !mdAndUp"> mdi-chevron-right </v-icon>
89+
<v-icon v-else> mdi-chevron-left </v-icon>
90+
</v-list-item-icon>
91+
<v-list-item-content>
92+
<v-list-item-title>Compact Mode</v-list-item-title>
93+
</v-list-item-content>
94+
</v-list-item>
9595
<v-list-item>
9696
<v-list-item-icon>
9797
<v-icon v-if="useSettingsStore().network.runNTServer"> mdi-server </v-icon>

photon-client/src/components/cameras/CameraCalibrationCard.vue

Lines changed: 246 additions & 275 deletions
Large diffs are not rendered by default.

photon-client/src/components/cameras/CameraControlCard.vue

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,14 @@ const expanded = ref([]);
9191
</script>
9292

9393
<template>
94-
<v-card dark class="pr-6 pb-3" style="background-color: #006492">
94+
<v-card dark style="background-color: #006492">
9595
<v-card-title>Camera Control</v-card-title>
96-
<v-row class="pl-6">
97-
<v-col>
98-
<v-btn color="secondary" @click="fetchSnapshots">
99-
<v-icon left class="open-icon"> mdi-folder </v-icon>
100-
<span class="open-label">Show Saved Snapshots</span>
101-
</v-btn>
102-
</v-col>
103-
</v-row>
96+
<v-card-text>
97+
<v-btn color="secondary" @click="fetchSnapshots">
98+
<v-icon left class="open-icon"> mdi-folder </v-icon>
99+
<span class="open-label">Show Saved Snapshots</span>
100+
</v-btn>
101+
</v-card-text>
104102
<v-dialog v-model="showSnapshotViewerDialog">
105103
<v-card dark class="pt-3 pl-5 pr-5" color="primary" flat>
106104
<v-card-title> View Saved Frame Snapshots </v-card-title>

photon-client/src/components/cameras/CameraSettingsCard.vue

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ const openExportSettingsPrompt = () => {
119119
};
120120
121121
const yesDeleteMySettingsText = ref("");
122+
const deletingCamera = ref(false);
122123
const deleteThisCamera = () => {
124+
if (deletingCamera.value) return;
125+
deletingCamera.value = true;
126+
123127
const payload = {
124128
cameraUniqueName: useStateStore().currentCameraUniqueName
125129
};
@@ -149,8 +153,11 @@ const deleteThisCamera = () => {
149153
color: "error"
150154
});
151155
}
156+
})
157+
.finally(() => {
158+
deletingCamera.value = false;
159+
showDeleteCamera.value = false;
152160
});
153-
showDeleteCamera.value = false;
154161
};
155162
const wrappedCameras = computed<SelectItem[]>(() =>
156163
Object.keys(useCameraSettingsStore().cameras).map((cameraUniqueName) => ({
@@ -161,9 +168,9 @@ const wrappedCameras = computed<SelectItem[]>(() =>
161168
</script>
162169

163170
<template>
164-
<v-card class="mb-3 pr-6 pb-3" color="primary" dark>
165-
<v-card-title>Camera Settings</v-card-title>
166-
<div class="ml-5">
171+
<v-card class="mb-3" color="primary" dark>
172+
<v-card-title class="pa-6 pb-0">Camera Settings</v-card-title>
173+
<v-card-text class="pa-6 pt-3">
167174
<pv-select
168175
v-model="useStateStore().currentCameraUniqueName"
169176
label="Camera"
@@ -193,74 +200,67 @@ const wrappedCameras = computed<SelectItem[]>(() =>
193200
]"
194201
:select-cols="8"
195202
/>
196-
<br />
197-
<v-row>
198-
<v-col cols="6">
199-
<v-btn
200-
class="mt-2 mb-3"
201-
style="width: 100%"
202-
small
203-
color="secondary"
204-
:disabled="!settingsHaveChanged()"
205-
@click="saveCameraSettings"
206-
>
207-
<v-icon left> mdi-content-save </v-icon>
208-
Save Changes
209-
</v-btn>
210-
</v-col>
211-
<v-col cols="6">
212-
<v-btn class="mt-2 mb-3" style="width: 100%" small color="red" @click="() => (showDeleteCamera = true)">
213-
<v-icon left> mdi-bomb </v-icon>
214-
Delete Camera
215-
</v-btn>
216-
</v-col>
217-
</v-row>
218-
</div>
219-
220-
<v-dialog v-model="showDeleteCamera" dark width="1500">
221-
<v-card dark class="dialog-container pa-6" color="primary" flat>
222-
<v-card-title>Delete camera "{{ useCameraSettingsStore().currentCameraName }}"</v-card-title>
223-
<v-row class="pl-3 align-center pa-6">
224-
<v-col cols="12" md="6">
225-
<span class="mt-3"> This will delete ALL OF YOUR SETTINGS and restart PhotonVision. </span>
226-
</v-col>
227-
<v-col cols="12" md="6">
228-
<v-btn color="secondary" style="float: right" @click="openExportSettingsPrompt">
229-
<v-icon left class="open-icon"> mdi-export </v-icon>
230-
<span class="open-label">Backup Settings</span>
231-
<a
232-
ref="exportSettings"
233-
style="color: black; text-decoration: none; display: none"
234-
:href="`http://${address}/api/settings/photonvision_config.zip`"
235-
download="photonvision-settings.zip"
236-
target="_blank"
237-
/>
238-
</v-btn>
239-
</v-col>
240-
</v-row>
241-
242-
<v-divider class="mt-4 mb-4" />
243-
<v-row class="pl-3 align-center pa-6">
244-
<v-col>
245-
<pv-input
246-
v-model="yesDeleteMySettingsText"
247-
:label="'Type &quot;' + useCameraSettingsStore().currentCameraName + '&quot;:'"
248-
:label-cols="12"
249-
:input-cols="12"
250-
/>
251-
</v-col>
203+
</v-card-text>
204+
<v-card-text class="d-flex pa-6 pt-0">
205+
<v-col cols="6" class="pa-0 pr-2">
206+
<v-btn block small color="secondary" :disabled="!settingsHaveChanged()" @click="saveCameraSettings">
207+
<v-icon left> mdi-content-save </v-icon>
208+
Save Changes
209+
</v-btn>
210+
</v-col>
211+
<v-col cols="6" class="pa-0 pl-2">
212+
<v-btn block small color="error" @click="() => (showDeleteCamera = true)">
213+
<v-icon left> mdi-trash-can-outline </v-icon>
214+
Delete Camera
215+
</v-btn>
216+
</v-col>
217+
</v-card-text>
252218

219+
<v-dialog v-model="showDeleteCamera" dark width="800">
220+
<v-card dark class="dialog-container pa-3 pb-2" color="primary" flat>
221+
<v-card-title> Delete {{ useCameraSettingsStore().currentCameraSettings.nickname }}? </v-card-title>
222+
<v-card-text>
223+
<v-row class="align-center pt-6">
224+
<v-col cols="12" md="6">
225+
<span class="white--text"> This will delete ALL OF YOUR SETTINGS and restart PhotonVision. </span>
226+
</v-col>
227+
<v-col cols="12" md="6">
228+
<v-btn color="secondary" block @click="openExportSettingsPrompt">
229+
<v-icon left class="open-icon"> mdi-export </v-icon>
230+
<span class="open-label">Backup Settings</span>
231+
<a
232+
ref="exportSettings"
233+
style="color: black; text-decoration: none; display: none"
234+
:href="`http://${address}/api/settings/photonvision_config.zip`"
235+
download="photonvision-settings.zip"
236+
target="_blank"
237+
/>
238+
</v-btn>
239+
</v-col>
240+
</v-row>
241+
</v-card-text>
242+
<v-card-text>
243+
<pv-input
244+
v-model="yesDeleteMySettingsText"
245+
:label="'Type &quot;' + useCameraSettingsStore().currentCameraName + '&quot;:'"
246+
:label-cols="6"
247+
:input-cols="6"
248+
/>
249+
</v-card-text>
250+
<v-card-text>
253251
<v-btn
254-
color="red"
252+
block
253+
color="error"
255254
:disabled="
256255
yesDeleteMySettingsText.toLowerCase() !== useCameraSettingsStore().currentCameraName.toLowerCase()
257256
"
257+
:loading="deletingCamera"
258258
@click="deleteThisCamera"
259259
>
260-
<v-icon left class="open-icon"> mdi-skull </v-icon>
260+
<v-icon left class="open-icon"> mdi-trash-can-outline </v-icon>
261261
<span class="open-label">DELETE (UNRECOVERABLE)</span>
262262
</v-btn>
263-
</v-row>
263+
</v-card-text>
264264
</v-card>
265265
</v-dialog>
266266
</v-card>

photon-client/src/components/cameras/CamerasView.vue

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,9 @@ const fpsTooLow = computed<boolean>(() => {
4141
</script>
4242

4343
<template>
44-
<v-card
45-
id="camera-settings-camera-view-card"
46-
class="camera-settings-camera-view-card mb-3 pb-3 pa-4"
47-
color="primary"
48-
dark
49-
>
50-
<v-card-title
51-
class="pb-0 mb-2 pl-4 pt-1"
52-
style="min-height: 50px; justify-content: space-between; align-content: center"
53-
>
54-
<div style="display: flex; flex-wrap: wrap">
44+
<v-card id="camera-settings-camera-view-card" class="camera-settings-camera-view-card" color="primary" dark>
45+
<v-card-title class="justify-space-between align-content-center pa-0 pl-6 pr-6">
46+
<div class="d-flex flex-wrap pt-4 pb-4">
5547
<div>
5648
<span class="mr-4" style="white-space: nowrap"> Cameras </span>
5749
</div>
@@ -69,23 +61,23 @@ const fpsTooLow = computed<boolean>(() => {
6961
</span>
7062
</v-chip>
7163
<v-chip v-else label color="transparent" text-color="red" style="font-size: 1rem; padding: 0; margin: 0">
72-
<span class="pr-1"> Camera not connected </span>
64+
<span class="pr-1">Camera not connected</span>
7365
</v-chip>
7466
</div>
7567
</div>
76-
77-
<div>
68+
<div class="d-flex align-center">
7869
<v-switch
7970
v-model="driverMode"
8071
:disabled="useCameraSettingsStore().isCalibrationMode || useCameraSettingsStore().pipelineNames.length === 0"
8172
label="Driver Mode"
8273
style="margin-left: auto"
8374
color="accent"
84-
class="pt-2"
75+
class="pt-2 pb-2"
76+
hide-details="auto"
8577
/>
8678
</div>
8779
</v-card-title>
88-
<div class="stream-container pb-4">
80+
<v-card-text class="stream-container">
8981
<div class="stream">
9082
<photon-camera-stream
9183
v-if="value.includes(0)"
@@ -104,10 +96,8 @@ const fpsTooLow = computed<boolean>(() => {
10496
style="max-width: 100%"
10597
/>
10698
</div>
107-
</div>
108-
<v-divider />
109-
<div class="pt-4">
110-
<p style="color: white">Stream Display</p>
99+
</v-card-text>
100+
<v-card-text class="pt-0">
111101
<v-btn-toggle v-model="localValue" :multiple="true" mandatory dark class="fill" style="width: 100%">
112102
<v-btn
113103
color="secondary"
@@ -126,7 +116,7 @@ const fpsTooLow = computed<boolean>(() => {
126116
<span class="mode-btn-label">Processed</span>
127117
</v-btn>
128118
</v-btn-toggle>
129-
</div>
119+
</v-card-text>
130120
</v-card>
131121
</template>
132122

photon-client/src/components/common/pv-camera-info-card.vue

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
<script setup lang="ts">
22
import { PVCameraInfo } from "@/types/SettingTypes";
33
4-
const { camera, showTitle } = defineProps({
4+
const { camera } = defineProps({
55
camera: {
66
type: PVCameraInfo,
77
required: true
8-
},
9-
showTitle: {
10-
type: Boolean,
11-
required: false,
12-
default: true
138
}
149
});
1510
@@ -29,12 +24,6 @@ const cameraInfoFor: any = (camera: PVCameraInfo) => {
2924

3025
<template>
3126
<div>
32-
<div v-if="showTitle === true">
33-
<h3 v-if="camera.PVUsbCameraInfo" class="mb-3">USB Camera Info</h3>
34-
<h3 v-if="camera.PVCSICameraInfo" class="mb-3">CSI Camera Info</h3>
35-
<h3 v-if="camera.PVFileCameraInfo" class="mb-3">File Camera Info</h3>
36-
</div>
37-
3827
<v-simple-table dense :style="{ backgroundColor: 'var(--v-primary-base)' }">
3928
<tbody>
4029
<tr v-if="cameraInfoFor(camera).dev !== undefined && cameraInfoFor(camera).dev !== null">
@@ -45,6 +34,13 @@ const cameraInfoFor: any = (camera: PVCameraInfo) => {
4534
<td>Name:</td>
4635
<td>{{ cameraInfoFor(camera).name }}</td>
4736
</tr>
37+
<tr>
38+
<td>Type:</td>
39+
<td v-if="camera.PVUsbCameraInfo" class="mb-3">USB Camera</td>
40+
<td v-else-if="camera.PVCSICameraInfo" class="mb-3">CSI Camera</td>
41+
<td v-else-if="camera.PVFileCameraInfo" class="mb-3">File Camera</td>
42+
<td v-else>Unidentified Camera Type</td>
43+
</tr>
4844
<tr v-if="cameraInfoFor(camera).baseName !== undefined && cameraInfoFor(camera).baseName !== null">
4945
<td>Base Name:</td>
5046
<td>{{ cameraInfoFor(camera).baseName }}</td>

0 commit comments

Comments
 (0)