ui_migration refactor(store) use pinia stores in components
This commit is contained in:
parent
694a5a690f
commit
3a5a7488dd
25 changed files with 284 additions and 273 deletions
|
|
@ -2,8 +2,8 @@
|
|||
<div id="app" class="uk-height-1-1 uk-margin-remove uk-padding-remove" :class="handleTheme">
|
||||
<!-- this stops the app loading until setConnected is committed in the store, this means
|
||||
other components will not load until we have Thing Descriptions. -->
|
||||
<loadingContent v-if="!$store.getters.ready" />
|
||||
<appContent v-if="$store.getters.ready" />
|
||||
<loadingContent v-if="!ready" />
|
||||
<appContent v-else />
|
||||
<!-- Runtime modals -->
|
||||
<div id="modal-center" ref="keyboardManualModal" class="uk-flex-top" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body uk-margin-auto-vertical">
|
||||
|
|
@ -28,6 +28,9 @@ import appContent from "./components/appContent.vue";
|
|||
import loadingContent from "./components/loadingContent.vue";
|
||||
import Mousetrap from "mousetrap";
|
||||
import { eventBus } from "./eventBus.js";
|
||||
import { mapWritableState, mapState, mapActions } from "pinia";
|
||||
import { useSettingsStore } from "@/stores/settings.js";
|
||||
import { useWotStore } from "@/stores/wot.js";
|
||||
|
||||
const move_keys = ["up", "down", "left", "right", "pageup", "pagedown"];
|
||||
|
||||
|
|
@ -75,6 +78,16 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
...mapWritableState(useSettingsStore, [
|
||||
"appTheme",
|
||||
"navigationStepSize",
|
||||
"navigationInvert",
|
||||
"microscopeHostname",
|
||||
"error",
|
||||
"waiting",
|
||||
]),
|
||||
...mapState(useSettingsStore, ["ready", "baseUri"]),
|
||||
|
||||
isSystemDark: function () {
|
||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
return true;
|
||||
|
|
@ -84,9 +97,9 @@ export default {
|
|||
},
|
||||
handleTheme: function () {
|
||||
var isDark = false;
|
||||
if (this.$store.state.appTheme == "dark") {
|
||||
if (this.appTheme == "dark") {
|
||||
isDark = true;
|
||||
} else if (this.$store.state.appTheme == "system") {
|
||||
} else if (this.appTheme == "system") {
|
||||
if (this.systemDark) {
|
||||
isDark = true;
|
||||
}
|
||||
|
|
@ -98,126 +111,130 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
// watch origin function refactored
|
||||
watch: {
|
||||
baseUri() {
|
||||
this.checkConnection();
|
||||
},
|
||||
// The "Whole App" Wrapper Logic
|
||||
ready(isReady) {
|
||||
if (isReady) {
|
||||
this.bindHardwareInputs(); // Turn keys ON when connected
|
||||
} else {
|
||||
this.unbindHardwareInputs(); // Turn keys OFF if disconnected
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// Query CSS dark theme preference
|
||||
var mql = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
this.mql = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
this.systemDark = this.mql.matches;
|
||||
// Check for system dark theme when mounted
|
||||
if (mql.matches) {
|
||||
if (this.mql.matches) {
|
||||
this.systemDark = true;
|
||||
}
|
||||
// Create a theme observer to watch for changes
|
||||
this.themeObserver = mql.addListener((e) => {
|
||||
if (e.matches) {
|
||||
this.systemDark = true;
|
||||
} else {
|
||||
this.systemDark = false;
|
||||
}
|
||||
});
|
||||
this.themeWatchdog = (e) => {
|
||||
this.systemDark = e.matches;
|
||||
};
|
||||
this.mql.addEventListener("change", this.themeWatchdog);
|
||||
// Check connection to API
|
||||
this.checkConnection();
|
||||
},
|
||||
|
||||
created: function () {
|
||||
window.addEventListener("beforeunload", this.handleExit);
|
||||
// Scrollwheel listener
|
||||
window.addEventListener("wheel", this.wheelMonitor);
|
||||
// Watch for origin changes
|
||||
this.unwatchOriginFunction = this.$store.watch(
|
||||
(state, getters) => {
|
||||
return getters.baseUri;
|
||||
},
|
||||
() => {
|
||||
this.checkConnection();
|
||||
},
|
||||
);
|
||||
|
||||
// Keyboard shortcuts
|
||||
Mousetrap.bind("?", () => {
|
||||
this.toggleModalElement(this.$refs["keyboardManualModal"]); // Calls the mixin
|
||||
});
|
||||
|
||||
Mousetrap.bind(
|
||||
move_keys,
|
||||
(event, key) => {
|
||||
event.preventDefault();
|
||||
this.keysDown.add(key);
|
||||
this.updateJogFromKeys();
|
||||
},
|
||||
"keydown",
|
||||
);
|
||||
|
||||
Mousetrap.bind(
|
||||
move_keys,
|
||||
(event, key) => {
|
||||
event.preventDefault();
|
||||
this.keysDown.delete(key);
|
||||
this.updateJogFromKeys();
|
||||
},
|
||||
"keyup",
|
||||
);
|
||||
|
||||
this.keyboardManual.push({
|
||||
shortcut: "←↑→↓",
|
||||
description: "Move the microscope stage",
|
||||
});
|
||||
|
||||
this.keyboardManual.push({
|
||||
shortcut: "pgup / pgdn",
|
||||
description: "Move the microscope focus",
|
||||
});
|
||||
|
||||
// Capture
|
||||
Mousetrap.bind("c", () => {
|
||||
eventBus.emit("globalCaptureEvent", {});
|
||||
});
|
||||
this.keyboardManual.push({
|
||||
shortcut: "c",
|
||||
description: "Take a capture",
|
||||
});
|
||||
|
||||
// Autofocus
|
||||
Mousetrap.bind("a", () => {
|
||||
eventBus.emit("globalFastAutofocusEvent", {});
|
||||
});
|
||||
this.keyboardManual.push({
|
||||
shortcut: "a",
|
||||
description: "Fast autofocus",
|
||||
});
|
||||
|
||||
// Increment/decrement tab
|
||||
Mousetrap.bind("shift+down", () => {
|
||||
eventBus.emit("globalIncrementTab", {});
|
||||
});
|
||||
Mousetrap.bind("shift+up", () => {
|
||||
eventBus.emit("globalDecrementTab", {});
|
||||
});
|
||||
this.keyboardManual.push({
|
||||
shortcut: "shift+↑ / shift+↓",
|
||||
description: "Switch tab",
|
||||
});
|
||||
},
|
||||
|
||||
beforeUnmount: function () {
|
||||
// Disconnect the theme observer
|
||||
if (this.themeObserver) {
|
||||
this.themeObserver.disconnect();
|
||||
}
|
||||
this.mql.removeEventListener("change", this.themeWatchdog);
|
||||
// Remove scrollwheel listener
|
||||
window.removeEventListener("wheel", this.wheelMonitor);
|
||||
// Remove origin watcher
|
||||
this.unwatchOriginFunction();
|
||||
// Remove key listeners
|
||||
Mousetrap.reset();
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions(useSettingsStore, ["setConnected"]),
|
||||
|
||||
bindHardwareInputs() {
|
||||
window.addEventListener("wheel", this.wheelMonitor);
|
||||
|
||||
Mousetrap.bind("?", () => {
|
||||
this.toggleModalElement(this.$refs["keyboardManualModal"]);
|
||||
});
|
||||
|
||||
Mousetrap.bind(
|
||||
move_keys,
|
||||
(event, key) => {
|
||||
event.preventDefault();
|
||||
this.keysDown.add(key);
|
||||
this.updateJogFromKeys();
|
||||
},
|
||||
"keydown",
|
||||
);
|
||||
|
||||
Mousetrap.bind(
|
||||
move_keys,
|
||||
(event, key) => {
|
||||
event.preventDefault();
|
||||
this.keysDown.delete(key);
|
||||
this.updateJogFromKeys();
|
||||
},
|
||||
"keyup",
|
||||
);
|
||||
|
||||
this.keyboardManual.push({
|
||||
shortcut: "←↑→↓",
|
||||
description: "Move the microscope stage",
|
||||
});
|
||||
|
||||
this.keyboardManual.push({
|
||||
shortcut: "pgup / pgdn",
|
||||
description: "Move the microscope focus",
|
||||
});
|
||||
|
||||
Mousetrap.bind("c", () => {
|
||||
eventBus.emit("globalCaptureEvent", {});
|
||||
});
|
||||
this.keyboardManual.push({
|
||||
shortcut: "c",
|
||||
description: "Take a capture",
|
||||
});
|
||||
|
||||
Mousetrap.bind("a", () => {
|
||||
eventBus.emit("globalFastAutofocusEvent", {});
|
||||
});
|
||||
this.keyboardManual.push({
|
||||
shortcut: "a",
|
||||
description: "Fast autofocus",
|
||||
});
|
||||
|
||||
Mousetrap.bind("shift+down", () => {
|
||||
eventBus.emit("globalIncrementTab", {});
|
||||
});
|
||||
Mousetrap.bind("shift+up", () => {
|
||||
eventBus.emit("globalDecrementTab", {});
|
||||
});
|
||||
this.keyboardManual.push({
|
||||
shortcut: "shift+↑ / shift+↓",
|
||||
description: "Switch tab",
|
||||
});
|
||||
},
|
||||
|
||||
unbindHardwareInputs() {
|
||||
window.removeEventListener("wheel", this.wheelMonitor);
|
||||
Mousetrap.reset();
|
||||
this.keyboardManual = [];
|
||||
},
|
||||
|
||||
async checkConnection() {
|
||||
var baseUri = this.$store.getters.baseUri;
|
||||
this.$store.commit("changeWaiting", true);
|
||||
// TODO: more robust check - e.g. use a microscope Thing
|
||||
// TODO: should we purge existing consumedThings?
|
||||
this.waiting = true;
|
||||
const wotStore = useWotStore();
|
||||
try {
|
||||
await this.$store.dispatch("wot/fetchThingDescriptions", `${baseUri}/thing_descriptions/`);
|
||||
await wotStore.fetchThingDescriptions(`${this.baseUri}/thing_descriptions/`);
|
||||
for (let requiredThing of ["camera", "system"]) {
|
||||
if (!this.thingAvailable(requiredThing)) {
|
||||
throw new Error(`No ${requiredThing} found, the GUI won't work without one.`);
|
||||
|
|
@ -225,74 +242,48 @@ export default {
|
|||
}
|
||||
try {
|
||||
let hostname = await this.readThingProperty("system", "hostname");
|
||||
this.$store.commit("changeMicroscopeHostname", hostname);
|
||||
this.microscopeHostname = hostname;
|
||||
document.title = `OpenFlexure Microscope: ${hostname}`;
|
||||
} catch {
|
||||
this.$store.commit("changeMicroscopeHostname", null);
|
||||
this.microscopeHostname = null;
|
||||
}
|
||||
// start rendering components
|
||||
this.$store.commit("setConnected");
|
||||
this.$store.commit("setErrorMessage", null);
|
||||
this.setConnected();
|
||||
this.error = null;
|
||||
} catch (error) {
|
||||
this.$store.commit("setErrorMessage", error);
|
||||
this.error = error;
|
||||
} finally {
|
||||
this.$store.commit("changeWaiting", false);
|
||||
this.waiting = false;
|
||||
}
|
||||
},
|
||||
handleExit: function () {},
|
||||
|
||||
/**
|
||||
* Handle global mouse wheel events to be associated with navigation
|
||||
*/
|
||||
wheelMonitor: function (event) {
|
||||
// Only capture scroll if the event target's parent contains the "scrollTarget" class
|
||||
handleExit() {},
|
||||
|
||||
wheelMonitor(event) {
|
||||
if (
|
||||
event.target.parentNode.classList.contains("scrollTarget") ||
|
||||
event.target.classList.contains("scrollTarget")
|
||||
) {
|
||||
const z_rel = event.deltaY / 100;
|
||||
// Emit a signal to move, acted on by panelControl.vue
|
||||
const navigationStepSize = this.$store.state.navigationStepSize;
|
||||
const z = z_rel * navigationStepSize.z;
|
||||
// Don't use `jog() due to variable size of jogs here and the rate limiting in
|
||||
// `jog()`. No need to invert on z, as navigationInvert.z isn't exposed.
|
||||
const z = z_rel * this.navigationStepSize.z;
|
||||
this.invokeAction("stage", "jog", { x: 0, y: 0, z: z });
|
||||
eventBus.emit("globalUpdatePositionEvent");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Jog for key-presses.
|
||||
*
|
||||
* This is a similar to the function in stageControlButtons.vue however it uses
|
||||
* uses the key repeat to fire in case a key up is missed. It debounces any
|
||||
* request to jog that is too recent after the last jog.
|
||||
*/
|
||||
jog(x, y, z) {
|
||||
// Manually debounce extra requests from keyboard repeat rate.
|
||||
// This is used rather than an interval in case of missing a repeat.
|
||||
const now = Date.now();
|
||||
const navigationInvert = this.$store.state.navigationInvert;
|
||||
if (now - this.lastJogTime < this.jogTime) {
|
||||
return;
|
||||
}
|
||||
this.lastJogTime = now;
|
||||
|
||||
this.invokeAction("stage", "jog", {
|
||||
x: x * this.jogDistance * (navigationInvert.x ? -1 : 1),
|
||||
y: y * this.jogDistance * (navigationInvert.y ? -1 : 1),
|
||||
x: x * this.jogDistance * (this.navigationInvert.x ? -1 : 1),
|
||||
y: y * this.jogDistance * (this.navigationInvert.y ? -1 : 1),
|
||||
z: z * this.jogDistance,
|
||||
});
|
||||
eventBus.emit("globalUpdatePositionEvent");
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop jogging on key-up
|
||||
*
|
||||
* This is also similar to the function in stageControlButtons.vue. It handles
|
||||
* stopping jogging and resetting the `lastJogTime` so there is no delay when
|
||||
* starting a new jog after an old jog finished.
|
||||
*/
|
||||
jogStop() {
|
||||
this.invokeAction("stage", "jog", { stop: true });
|
||||
this.lastJogTime = 0;
|
||||
|
|
@ -301,9 +292,6 @@ export default {
|
|||
}, 100);
|
||||
},
|
||||
|
||||
/**
|
||||
* Track which keys are still down on keypress (or key repeat).
|
||||
*/
|
||||
updateJogFromKeys() {
|
||||
let x = 0,
|
||||
y = 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue