Vue and Vuex Instance Across Tabs

887 Views Asked by At

I'm about one month learning Vue. It might be a silly question, but I'm really confused.

I'm creating a cs livechat app with five state and "component is". Welcome -> identity -> wait for queue -> Chat -> end.

The user progress is stored in Vuex. The state changes by listening to "next" event fired by currently active component.

However, when I created three different browser windows (including incognito), things get weird. I've opened the first instance till it in waiting state. Then, I do the same for the other two instances. When I checked the first one, it was suddenly in end state and the second one is in chat state. I tried to check it's history and found that the first two vue instance listen to next event fired by the other. I thought like this because time interval when the event was fired was wide.

Where am I going wrong? It works fine in one tab.

Additional info: I've tried in development and production build but the result still the same.

App.vue

<template>
  <div class="mx-auto pt-6" style="width: 480px; height: 550px">
    <transition name="component-fade" mode="out-in">
      <component
        :is="currentProgressComponent"
        @next="nextProgress"
        @home="home"
      ></component>
    </transition>
  </div>
</template>

store.js

import { createStore } from 'vuex'
import { sendMessage } from '../services/socket'

export default createStore({
  state: {
    identity: { name: '', email: '' },
    target: { name: '', email: '' },
    role: '',
    progress: {
      list: ["welcome", "identity", "wait", "box", "ended"],
      current: 'welcome'
    },
    chats: []
  },
  mutations: {
    SET_IDENTITY(state, data) {
      state.identity = data
    },
    SET_ROLE(state, data) {
      state.role = data
    },
    SET_PROGRESS(state, newProgressIndex) {
      state.progress.current = state.progress.list[newProgressIndex]
    }
  },
  actions: {
    ....,
    nextProgress(store) {
      const next = store.state.progress.list.indexOf(store.state.progress.current) + 1
      if (next === store.state.progress.list.length) {
        throw new Error('Invalid next progress state')
      }
      store.commit('SET_PROGRESS', next)
    },
    home(store) {
      store.commit('SET_PROGRESS', 0)
    }
  },
})

ChatWait.vue

export default {
  components: { LoadingSpinner, ExclamationCircleIcon },
  setup(props, { emit }) {
    const state = ref("registering");
    const queue = ref(-1);
    const errorMessage = ref("");
    const store = useStore();
    const next = ref(false);
    if (store.state.role === "customer") {
      queueUp();
    } else if (store.state.role === "admin") {
      setAdminAvailability();
    } else {
      throw new Error("Invalid role");
    }
    const queuedCallback = ({ error, message }) => {
      if (error) {
        state.value = "error";
        errorMessage.value = message;
      } else {
        if (store.state.role === "customer") {
          state.value = "queued";
          getQueueNumber();
        } else if (store.state.role === "admin") {
          state.value = "waiting";
        }
      }
    };
    const queueNumberCallback = (number) => {
      queue.value = number;
      if (number < 2 && number >= 0) {
        joinConversation();
      } else if (number > 10) {
        setTimeout(() => {
          getQueueNumber();
        }, 10000);
      } else if (number > 5) {
        setTimeout(() => {
          getQueueNumber();
        }, 5000);
      } else {
        setTimeout(() => {
          getQueueNumber();
        }, 1000);
      }
    };
    registerWaitingCallbacks(queuedCallback, queueNumberCallback);
    registerChatCallbacks(() => {
      next.value = true;
    }, store);
    watchEffect(() => {
      if (next.value) {
        console.log("I am from chat wait");
        emit("next");
      }
    });
    return {
      state,
      queue,
      errorMessage,
    };
  },
  computed: {
    ...
  },
};

Note: it doesnt log 'I am from chat wait' when the component changed

0

There are 0 best solutions below