Commit f8ea7522 authored by Joel Collins's avatar Joel Collins
Browse files

Connection handled by component, not store

parent fe397e5e
Loading
Loading
Loading
Loading
+52 −19
Original line number Diff line number Diff line
@@ -138,6 +138,8 @@ if (isElectron()) {
  var mdns = require("mdns-js");
}

import axios from "axios";

import hostCard from "./connectComponents/hostCard.vue";

// Export main app
@@ -262,18 +264,37 @@ export default {
      this.port = host.port;

      // Commit the hostname and port to store
      this.$store.commit("resetState");
      this.$store.commit("changeHost", [host.hostname, host.port]);
      // Try to get config and state JSON from the newly submitted host
      this.$store
        .dispatch("firstConnect")
        .then(() => {
          console.log("Connected!");
      this.$store.commit("changeWaiting", true);
      // Try to get list of available routes
      axios
        .get(`${this.$store.getters.baseUri}/routes`)
        .then(response => {
          console.log(response.data);
          // If the /api/v2 route is available
          if (Object.keys(response.data).includes("/api/v2/")) {
            console.log("API v2 available");
            // Tell Vuex store that we're connected
            this.$store.commit("setConnected");
            // Check client and server match
            this.checkServerVersion();
            // Switch to live view tab
            // TODO: Not working for some reason?
            this.$root.$emit("globalTogglePanelRightTab", "preview");
          } else {
            // Error and no-connect if API v2 is missing
            var ApiVersionError = Error(`Your microscope is running an old API version.\
            You must update your microscope software to continue.\
            <br><br> \n
            For API upgrades, burning the latest Raspbian-OpenFlexure is often easiest.\
            <br><br> \n
            Alternatively, you can run 'ofm upgrade' on your microscope.`);
            this.modalError(ApiVersionError);
          }
        })
        .catch(error => {
          this.$store.commit("setError");
          this.modalError(error); // Let mixin handle error
        });
    },
@@ -307,14 +328,15 @@ export default {
    },

    checkServerVersion: function() {
      this.$store
        .dispatch("updateState")
        .then(() => {
      var versionUri = `${this.$store.getters.baseUri}/api/v2/status/version`;
      axios
        .get(versionUri)
        .then(response => {
          var serverVersion = response.data;
          var clientVersion = process.env.PACKAGE.version;
          var clientVersionMajor = clientVersion.substring(0, 3);
          console.log(clientVersionMajor);

          var serverVersion = this.$store.state.apiState.version;
          if (serverVersion != undefined) {
            var serverVersionMajor = serverVersion.substring(0, 3);
          }
@@ -362,12 +384,23 @@ export default {
    },

    saveHost: function() {
      // URI to get hostname directly from settings
      var hostnameUri = `${this.$store.getters.baseUri}/api/v2/settings/name`;
      axios
        .get(hostnameUri)
        .then(response => {
          // Get device name from response
          var deviceName = response.data;
          // We use unshift instead of push to add the entry to the beginning of the array
          this.savedHosts.unshift({
        name: this.$store.state.apiConfig.name,
            name: deviceName,
            hostname: this.$store.state.host,
            port: this.$store.state.port
          });
        })
        .catch(error => {
          this.modalError(error); // Let mixin handle error
        });
    }
  }
};
+5 −154
Original line number Diff line number Diff line
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";

Vue.use(Vuex);

@@ -8,13 +7,9 @@ export default new Vuex.Store({
  state: {
    host: "",
    port: 5000,
    apiVer: "v1",
    available: true,
    available: false,
    waiting: false,
    error: "",
    apiConfig: {},
    apiState: {},
    apiPlugins: [],
    globalSettings: {
      disableStream: false,
      autoGpuPreview: false,
@@ -24,33 +19,20 @@ export default new Vuex.Store({
  },

  mutations: {
    changeHost(state, [host, port, apiVer = "v1"]) {
    changeHost(state, [host, port]) {
      state.host = host;
      state.port = port;
      state.apiVer = apiVer;
    },
    changeWaiting(state, waiting) {
      state.waiting = waiting;
    },
    commitConfig(state, configData) {
      state.apiConfig = configData;
    },
    commitState(state, stateData) {
      state.apiState = stateData;
    },
    commitPlugins(state, pluginData) {
      state.apiPlugins = pluginData;
    },
    changeSetting(state, [key, value]) {
      state.globalSettings[key] = value;
    },
    resetState(state) {
      state.waiting = false;
      state.available = true;
      state.available = false;
      state.error = null;
      state.apiConfig = {};
      state.apiState = {};
      state.apiPlugins = [];
    },
    setConnected(state) {
      state.waiting = false;
@@ -62,142 +44,11 @@ export default new Vuex.Store({
    }
  },

  actions: {
    firstConnect(context) {
      // Reset the state when reconnecting starts
      context.commit("resetState");
      // Mark as loading
      context.commit("changeWaiting", true);

      var sendRequest = function(resolve, reject) {
        // Do requests
        context
          .dispatch("updateConfig")
          .then(() => context.dispatch("updateState"))
          .then(() => context.dispatch("updatePlugins"))
          .then(() => {
            console.log("Finished first connect");
            resolve();
          })
          .catch(error => {
            reject(error);
          });
      };
      return new Promise(sendRequest);
    },

    updateConfig(context, uri = `${context.getters.uri}/config`) {
      console.log("Updating config");
      context.commit("changeWaiting", true);

      var sendRequest = function(resolve, reject) {
        axios
          .get(uri)
          .then(response => {
            context.commit("commitConfig", response.data);
            context.commit("setConnected");
            console.log("Updating config finished");
            resolve();
          })
          .catch(error => {
            reject(new Error(error));
          });
      };
      return new Promise(sendRequest);
    },

    updateState(context, uri = `${context.getters.uri}/state`) {
      console.log("Updating state");
      context.commit("changeWaiting", true);

      var sendRequest = function(resolve, reject) {
        axios
          .get(uri)
          .then(response => {
            context.commit("commitState", response.data);
            context.commit("setConnected");
            console.log("Updating state finished");
            resolve();
          })
          .catch(error => {
            reject(new Error(error));
          });
      };
      return new Promise(sendRequest);
    },

    updatePlugins(context, uri = `${context.getters.uri}/plugin`) {
      console.log("Updating plugins");
      context.commit("changeWaiting", true);

      var sendRequest = function(resolve, reject) {
        axios
          .get(uri)
          .then(response => {
            console.log("PLUGINS");
            console.log(response.data);
            context.commit("commitPlugins", response.data);
            context.commit("setConnected");
            console.log("Updating plugins finished");
            resolve();
          })
          .catch(error => {
            reject(new Error(error));
          });
      };
      return new Promise(sendRequest);
    },

    pollTask(context, [taskId, timeout, interval]) {
      var endTime = Number(new Date()) + (timeout * 1000 || 30000);
      interval = interval * 1000 || 500;

      var checkCondition = function(resolve, reject) {
        // If the condition is met, we're done!
        axios.get(`${context.getters.uri}/task/${taskId}`).then(response => {
          console.log(response.data.status);
          var result = response.data.status;
          // If the task ends with success
          if (result == "success") {
            resolve(response.data);
          }
          // If task ends with an error
          else if (result == "error") {
            // Pass the error string back with reject
            reject(new Error(response.data.return));
          }
          // If task ends with termination
          else if (result == "terminated") {
            // Pass a generic termination error back with reject
            reject(new Error("Task terminated"));
          }
          // If task ends in any other way
          else if (result != "running") {
            // Pass status string as error
            reject(new Error(result));
          }
          // If the condition isn't met but the timeout hasn't elapsed, go again
          else if (Number(new Date()) < endTime) {
            setTimeout(checkCondition, interval, resolve, reject);
          }
          // Didn't match and too much time, reject!
          else {
            reject(new Error("Polling timed out"));
          }
        });
      };

      return new Promise(checkCondition);
    }
  },
  actions: {},

  getters: {
    uri: state => `http://${state.host}:${state.port}/api/${state.apiVer}`,
    uriV2: state => `http://${state.host}:${state.port}/api/v2`,
    baseUri: state => `http://${state.host}:${state.port}`,
    ready: state =>
      state.available &&
      Object.keys(state.apiConfig).length !== 0 &&
      Object.keys(state.apiState).length !== 0
    ready: state => state.available
  }
});