Added UI controls to enable ImJoy and gallery

There are now tick boxes in "features" settings to
enable/disable ImJoy and the gallery.
These persist in local storage.
This commit is contained in:
Richard 2021-05-29 13:06:13 +01:00
parent dac1c9a748
commit 6a353ccbd3
3 changed files with 133 additions and 81 deletions

View file

@ -28,7 +28,14 @@
:class="item.class"
@set-tab="setTab"
>
<i class="material-icons">{{ item.icon }}</i>
<img
v-if="item.iconURL"
style="filter: grayscale(100%);width: 22px;margin-top: 5px;margin-bottom: 8px;"
:src="item.iconURL"
/>
<i v-if="!item.iconURL" class="material-icons">
{{ item.icon }}
</i>
</tabIcon>
<!-- Add a divider if item.divide is true -->
<hr v-if="item.divide" :key="'tab-divider-' + index" />
@ -48,20 +55,6 @@
<i class="material-icons">{{ plugin.icon || "extension" }}</i>
</tabIcon>
<tabIcon
v-if="imjoyEnabled"
tab-i-d="ImJoy"
title="ImJoy"
:require-connection="false"
:current-tab="currentTab"
@set-tab="setTab"
>
<img
style="filter: grayscale(100%);width: 22px;margin-top: 5px;margin-bottom: 8px;"
src="https://imjoy.io/static/img/imjoy-icon.svg"
/>
</tabIcon>
<tabIcon
v-for="imjoyTab in imjoyTabs"
:key="imjoyTab.id"
@ -137,15 +130,6 @@
/>
</tabContent>
<tabContent
v-if="imjoyEnabled"
tab-i-d="ImJoy"
:require-connection="false"
:current-tab="currentTab"
>
<ImJoyContent />
</tabContent>
<tabContent
v-for="imjoyTab in imjoyTabs"
:key="imjoyTab.id"
@ -185,17 +169,23 @@ import captureContent from "./tabContentComponents/captureContent.vue";
import slideScanContent from "./tabContentComponents/slideScanContent.vue";
import viewContent from "./tabContentComponents/viewContent.vue";
import settingsContent from "./tabContentComponents/settingsContent.vue";
import galleryContent from "./tabContentComponents/galleryContent.vue";
import extensionContent from "./tabContentComponents/extensionContent.vue";
import aboutContent from "./tabContentComponents/aboutContent.vue";
import loggingContent from "./tabContentComponents/loggingContent.vue";
// ImJoy and the gallery are loaded asynchronously to allow them to be disabled if needed
const galleryContent = () =>
import(
/* webpackChunkName: "gallery") */ "./tabContentComponents/galleryContent.vue"
);
const imjoyContent = () =>
import(
/* webpackChunkName: "imjoy" */ "./tabContentComponents/imjoyContent.vue"
);
// Import modal components for device initialisation
import calibrationModal from "./modalComponents/calibrationModal.vue";
import TabIcon from "./genericComponents/tabIcon.vue";
import { mapState } from "vuex";
// Export main app
export default {
name: "AppContent",
@ -214,37 +204,12 @@ export default {
aboutContent,
loggingContent,
TabIcon,
ImJoyContent: () => import(/* webpackChunkName: "imjoy" */"./tabContentComponents/imjoyContent.vue")
imjoyContent
},
data: function() {
return {
plugins: [],
currentTab: "view",
unwatchStoreFunction: null,
topTabs: [
{
id: "view",
icon: "visibility",
component: viewContent
},
{
id: "gallery",
icon: "photo_library",
component: galleryContent,
divide: true // Add a divider after this tab icon
},
{
id: "navigate",
icon: "gamepad",
component: navigateContent
},
{
id: "capture",
icon: "camera_alt",
component: captureContent,
divide: true // Add a divider after this tab icon
}
],
bottomTabs: [
{
id: "settings",
@ -296,32 +261,76 @@ export default {
return ind;
},
topTabs: function() {
let tabs = [
{
id: "view",
icon: "visibility",
component: viewContent
},
{
id: "gallery",
icon: "photo_library",
component: galleryContent,
divide: true // Add a divider after this tab icon
},
{
id: "navigate",
icon: "gamepad",
component: navigateContent
},
{
id: "capture",
icon: "camera_alt",
component: captureContent,
divide: true // Add a divider after this tab icon
}
];
if (!this.$store.state.galleryEnabled) {
tabs = tabs.filter(tab => tab.id != "gallery");
}
if (this.$store.state.IHIEnabled) {
tabs.push({
id: "slidescan",
icon: "settings_overscan",
component: slideScanContent,
divide: true
});
}
if (this.$store.state.imjoyEnabled) {
tabs.push({
id: "imjoy",
iconURL: "https://imjoy.io/static/img/imjoy-icon.svg",
component: imjoyContent,
divide: true
});
}
return tabs;
},
currentTabIndex: function() {
return this.tabOrder.indexOf(this.currentTab);
},
imjoyEnabled: function() {
return process.env.VUE_APP_ENABLE_IMJOY === "true";
// Enable the ImJoy tab (and associated code) only if it is
// enabled client-side, and at build time.
// This means that the medical version of the microscope can
// disable the plugin architecture by setting the environment
// variable VUE_APP_ENABLE_IMJOY=false
if (process.env.VUE_APP_ENABLE_IMJOY === "true") {
return this.$store.state.imjoyEnabled;
} else {
return false;
}
},
// Map the tabs from ImJoy's store module so we can display them
...mapState("imjoy", { imjoyTabs: "tabs" }),
// 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);
}
...mapState("imjoy", { imjoyTabs: "tabs" })
},
created: function() {
if (this.$store.getters.ready) {
// Update top tabs
this.updateTopTabs(this.$store.state.IHIEnabled);
// Update plugins
this.updatePlugins().then(() => {
// Start initialisation modals
@ -346,19 +355,6 @@ export default {
},
methods: {
updateTopTabs: function(IHIEnabled) {
if (IHIEnabled) {
this.topTabs.push({
id: "slidescan",
icon: "settings_overscan",
component: slideScanContent,
divide: true
});
} else {
// If the connection is now disconnected, empty capture list
this.topTabs = this.topTabs.filter(tab => tab.id != "slidescan");
}
},
updatePlugins: function() {
return axios
.get(this.pluginsUri)

View file

@ -14,6 +14,28 @@
for use in clinics acquiring blood smear samples using a 100x
oil-immersion objective, with a Raspberry Pi Camera v2.
</p>
<p class="uk-margin-small">
<label
><input v-model="imjoyEnabled" class="uk-checkbox" type="checkbox" />
Enable ImJoy plugin engine</label
>
</p>
<p class="uk-margin-small">
<a href="https://imjoy.io/">ImJoy</a> enables integration with a wide
variety of microscopy and image analysis applications, including ImageJ.JS
and Kaibu. Support for ImJoy within the OFM software is currently
experimental, and it may slow down loading of the application.
</p>
<p class="uk-margin-small">
<label
><input v-model="galleryEnabled" class="uk-checkbox" type="checkbox" />
Enable Gallery</label
>
</p>
<p class="uk-margin-small">
The "gallery" tab can cause performance issues; un-tick the box above to
disable it.
</p>
</div>
</template>
@ -34,18 +56,44 @@ export default {
set(value) {
this.$store.commit("changeIHIEnabled", value);
}
},
imjoyEnabled: {
get() {
return this.$store.state.imjoyEnabled;
},
set(value) {
this.$store.commit("changeImjoyEnabled", value);
}
},
galleryEnabled: {
get() {
return this.$store.state.galleryEnabled;
},
set(value) {
this.$store.commit("changeGalleryEnabled", value);
}
}
},
watch: {
IHIEnabled: function() {
this.setLocalStorageObj("IHIEnabled", this.IHIEnabled);
},
imjoyEnabled: function() {
this.setLocalStorageObj("imjoyEnabled", this.imjoyEnabled);
},
galleryEnabled: function() {
this.setLocalStorageObj("galleryEnabled", this.galleryEnabled);
}
},
mounted() {
// Try loading settings from localStorage. If null, don't change.
this.IHIEnabled = this.getLocalStorageObj("IHIEnabled") || this.IHIEnabled;
this.imjoyEnabled =
this.getLocalStorageObj("imjoyEnabled") || this.imjoyEnabled;
this.galleryEnabled =
this.getLocalStorageObj("galleryEnabled") || this.galleryEnabled;
}
};
</script>

View file

@ -39,7 +39,7 @@ const moduleImjoy = {
},
/**
* Set a parameter on the tab with a given id
*
*
* Payload should contain:
* tab: ID of the tab to modify (not window_id)
* key: name of the property to add/change
@ -87,6 +87,8 @@ export default new Vuex.Store({
autoGpuPreview: false,
trackWindow: true,
IHIEnabled: false,
imjoyEnabled: false,
galleryEnabled: true,
appTheme: "system",
activeStreams: {}
},
@ -113,6 +115,12 @@ export default new Vuex.Store({
changeIHIEnabled(state, enabled) {
state.IHIEnabled = enabled;
},
changeImjoyEnabled(state, enabled) {
state.imjoyEnabled = enabled;
},
changeGalleryEnabled(state, enabled) {
state.galleryEnabled = enabled;
},
resetState(state) {
state.waiting = false;
state.available = false;