Merge branch 'improve-local-development' into 'master'

Local development improvements

See merge request openflexure/openflexure-microscope-server!125
This commit is contained in:
Richard Bowman 2021-05-18 10:56:10 +00:00
commit de28b0e2f6
8 changed files with 145 additions and 83 deletions

View file

@ -140,6 +140,8 @@ import loggingContent from "./tabContentComponents/loggingContent.vue";
// Import modal components for device initialisation
import calibrationModal from "./modalComponents/calibrationModal.vue";
import { mapState } from "vuex";
// Export main app
export default {
name: "AppContent",
@ -241,21 +243,21 @@ export default {
currentTabIndex: function() {
return this.tabOrder.indexOf(this.currentTab);
},
// Map the setting for IHI's interface so we can watch it
...mapState(["IHIEnabled"])
},
watch: {
// Update the interface when the IHI interface is enabled/disabled
IHIEnabled: function(newValue) {
this.updateTopTabs(newValue);
}
},
created: function() {
if (this.$store.getters.ready) {
// Detect local connection
if (
["localhost", "0.0.0.0", "127.0.0.1", "[::1]"].includes(
window.location.hostname
)
) {
this.$store.commit("changeDisableStream", true);
this.$store.commit("changeAutoGpuPreview", true);
this.$store.commit("changeTrackWindow", true);
}
// Update top tabs
this.updateTopTabs(this.$store.state.IHIEnabled);
// Update plugins
@ -264,16 +266,6 @@ export default {
this.startModals();
});
}
// Watch for host 'ready', then update status
this.unwatchStoreFunction = this.$store.watch(
state => {
return state.IHIEnabled;
},
IHIEnabled => {
this.updateTopTabs(IHIEnabled);
}
);
},
mounted() {
@ -291,14 +283,6 @@ export default {
});
},
beforeDestroy() {
// Then we call that function here to unwatch
if (this.unwatchStoreFunction) {
this.unwatchStoreFunction();
this.unwatchStoreFunction = null;
}
},
methods: {
updateTopTabs: function(IHIEnabled) {
if (IHIEnabled) {

View file

@ -1,12 +1,36 @@
<template>
<div>
<form class="uk-form-stacked" @submit.prevent="overrideAPIHost">
<form
class="uk-form-stacked"
action=""
method="GET"
@submit="overrideAPIHost"
>
<label class="uk-form-label">Override API origin</label>
<input v-model="newOrigin" class="uk-input" type="text" />
<input
v-model="newOrigin"
name="overrideOrigin"
class="uk-input"
type="text"
/>
<label class="uk-form-label">
<input
v-model="reloadWhenOverridingOrigin"
class="uk-input uk-checkbox"
type="checkbox"
/>
Reload web app with new origin
</label>
<button class="uk-button uk-button-default uk-margin-small">
Apply
</button>
</form>
<form class="uk-form-stacked" @submit.prevent="resetTour">
<label class="uk-form-label">Re-run tour on next load</label>
<button class="uk-button uk-button-default uk-margin-small">
Reset
</button>
</form>
</div>
</template>
@ -19,22 +43,35 @@ export default {
data: function() {
return {
newOrigin: this.$store.state.origin
newOrigin: this.$store.state.origin,
reloadWhenOverridingOrigin: true
};
},
mounted() {
if (localStorage.overrideOrigin){
if (localStorage.overrideOrigin) {
this.newOrigin = localStorage.overrideOrigin;
}else{
} else {
this.newOrigin = "http://microscope.local:5000";
}
},
methods: {
overrideAPIHost: function() {
this.$store.commit("changeOrigin", this.newOrigin);
localStorage.overrideOrigin = this.newOrigin
overrideAPIHost: function(event) {
// Save the origin override, so that if we reload the web app, you can easily
localStorage.overrideOrigin = this.newOrigin;
// If we have elected not to reload the interface, just update the origin
// in the store. Otherwise, the form's default action will do the job for us.
// TODO: preserve other query parameters when reloading
if (!this.reloadWhenOverridingOrigin) {
this.$store.commit("changeOrigin", this.newOrigin);
event.preventDefault();
}
},
resetTour: function() {
// Make the introduction tour run next time the app loads
this.setLocalStorageObj("completedTour", false);
}
}
};

View file

@ -33,7 +33,6 @@ export default {
},
set(value) {
this.$store.commit("changeIHIEnabled", value);
this.$root.$emit("globalSafeTogglePreview", value);
}
}
},

View file

@ -73,8 +73,11 @@ export default {
return this.$store.state.autoGpuPreview;
},
set(value) {
// NB the stream viewer watches the store, and is
// responsible for making the request that switches
// GPU preview on/off
// see streamContent.vue
this.$store.commit("changeAutoGpuPreview", value);
this.$root.$emit("globalSafeTogglePreview", value);
}
},
@ -86,6 +89,51 @@ export default {
this.$store.commit("changeTrackWindow", value);
}
}
},
watch: {
// Cache the stream settings to local storage for persistence
// (the next 3 functions all relate to this)
disableStream: function(newValue) {
console.log(
`disableStream updated to ${newValue} and saved in local storage`
);
this.setLocalStorageObj("disableStream", newValue);
},
autoGpuPreview: function(newValue) {
console.log(
`GPU preview updated to ${newValue} and saved in local storage`
);
this.setLocalStorageObj("autoGpuPreview", newValue);
},
trackWindow: function(newValue) {
console.log(
`trackWindow updated to ${newValue} and saved in local storage`
);
this.setLocalStorageObj("trackWindow", newValue);
}
},
created() {
// Apply sensible defaults for stream settings, depending on
// whether we're connecting locally or remotely, respecting
// the settings that were cached previously.
const localMode = ["localhost", "0.0.0.0", "127.0.0.1", "[::1]"].includes(
window.location.hostname
);
const localDefaults = {
disableStream: true,
autoGpuPreview: true,
trackWindow: true
};
for (let k in localDefaults) {
if (localStorage.getItem(k) !== null) {
this[k] = this.getLocalStorageObj(k);
} else if (localMode) {
console.log(`${k} set to default value for a local connection`);
this[k] = localDefaults[k];
}
}
}
};
</script>

View file

@ -69,6 +69,16 @@ export default {
},
settingsUri: function() {
return `${this.$store.getters.baseUri}/api/v2/instrument/settings`;
},
autoGpuPreview: function() {
return this.$store.state.autoGpuPreview;
}
},
watch: {
autoGpuPreview: function(newValue) {
// When the GPU preview setting in the store changes, update the server
this.safePreviewRequest(newValue);
}
},
@ -77,9 +87,6 @@ export default {
this.$root.$on("globalTogglePreview", state => {
this.previewRequest(state);
});
this.$root.$on("globalSafeTogglePreview", state => {
this.safePreviewRequest(state);
});
// A global signal listener to flash the stream element
this.$root.$on("globalFlashStream", () => {
this.flashStream();
@ -97,7 +104,7 @@ export default {
created: function() {
// Send a request to start/stop GPU preview based on global setting
this.safePreviewRequest(this.$store.state.autoGpuPreview);
this.safePreviewRequest(this.autoGpuPreview);
},
beforeDestroy: function() {

View file

@ -3,9 +3,22 @@ import Vuex from "vuex";
Vue.use(Vuex);
function getOriginFromLocation() {
// This will default to the same origin that's serving
// the web app - but can be overridden by the URL.
// See also devTools.vue which can change the origin.
let url = new URL(window.location.href);
let origin = url.searchParams.get("overrideOrigin");
if (origin) {
return origin;
} else {
return url.origin;
}
}
export default new Vuex.Store({
state: {
origin: window.location.origin,
origin: getOriginFromLocation(),
available: false,
waiting: false,
error: "",