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