import API from "@/services/imapAPI"; import { decodeEmojis } from "@/utils/string"; import { AxiosError, AxiosResponse } from "axios"; import { createStore } from "vuex"; import { Room, Account, Address, RoomType, Message, LoadingState } from "./models/model"; interface RoomFromBack { id: number; roomName: string; roomType: RoomType; mailboxId: number; user: string; userId: number; notSeen: number; parent_id?: number; // todo thread } interface AccountFromBack { id: number; email: string; } const buffer: RoomFromBack[] = []; function createRoom(options: RoomFromBack): Room { return { id: options.id, roomName: decodeEmojis(options.roomName), roomType: options.roomType, mailboxId: options.mailboxId, userId: options.userId, members: [], user: options.user, notSeen: options.notSeen, messages: [], messageLoading: LoadingState.notLoaded, threadIds: [], }; } export interface State { rooms: Room[]; accounts: Account[]; activeAccount: number; activeRoom: number; } // // define injection key todo // export const key: InjectionKey> = Symbol() const store = createStore({ state: { rooms: [], //createRoom({ id: 12, userId: 1, user: "user", roomName: "room name", mailboxId: 2, roomType: 1 }) accounts: [{ id: 0, email: "All", fetched: false }], activeAccount: 0, activeRoom: 0, }, mutations: { setActiveAccount(state, payload) { state.activeAccount = payload; const account = state.accounts.find((account) => account.id == payload); store.dispatch("fetchRooms", { accountId: payload, account: account }); }, setActiveRoom(state, payload) { state.activeRoom = payload; // todo load room on load page const room = state.rooms.find((room) => room.id == payload); if (!room) return; store.dispatch("fetchMessages", { roomId: payload, room: room }); }, addAccounts(state, payload) { payload.forEach((account: AccountFromBack) => { state.accounts.push({ id: account.id, email: account.email, fetched: false }); }); }, addRooms(state, payload) { // todo add if not exist payload.rooms.forEach((room: RoomFromBack) => { if (room.roomType == RoomType.THREAD) { buffer.push(room); } state.rooms.push(createRoom(room)); }); buffer.forEach((thread) => { const parentRoom = state.rooms.find((room) => room.id == thread.parent_id); // todo debug parent_id to root_id if (parentRoom) { parentRoom.threadIds.push(thread.id); } else { console.log("yep..."); } }); }, addMessages(state, payload) { // todo add if not exist const room = state.rooms.find((room) => room.id == payload.roomId); if (!room) return; payload.messages.forEach((message: Message) => { room.messages.push(message); }); }, addAddress(state, payload) { // todo add if not exist const room = state.rooms.find((room) => room.id == payload.roomId); if (!room) return; payload.addresses.forEach((address: Address) => { room.members.push(address); }); }, }, getters: { rooms: (state) => (): Room[] => { if (state.activeAccount === 0) return state.rooms; return state.rooms.filter( (room) => room.mailboxId == state.activeAccount && room.roomType != RoomType.THREAD, ); }, room: (state) => (roomId: number): Room | undefined => { const room = state.rooms.find((room) => room.id == roomId); return room; }, address: (state) => (roomId: number, addressId: number): Address | undefined => { const room = state.rooms.find((room) => room.id == roomId); const address = room?.members.find((address) => address.id == addressId); return address; }, messages: (state) => (roomId: number): Message[] => { const room = state.rooms.find((room) => room.id == roomId); if (!room) return []; if (room.messageLoading === LoadingState.notLoaded) { store.dispatch("fetchMessages", { roomId: room.id, room: room }); } return room.messages; }, }, actions: { fetchAccounts: async (context) => { API.getAccounts() .then((res: AxiosResponse) => { context.commit("addAccounts", res.data); }) .catch((err: AxiosError) => { console.log(err); }); }, fetchRooms: async (context, data) => { if (data.account?.fetched == false) { API.getRooms(data.accountId) .then((res: AxiosResponse) => { data.account.fetched = true; context.commit("addRooms", { rooms: res.data }); }) .catch((err: AxiosError) => { console.log(err); }); } }, fetchMessages: async (context, data) => { if (!data.room || data.room.messageLoading === LoadingState.notLoaded) { data.room.messageLoading = LoadingState.loading; store.dispatch("fetchRoomMembers", { roomId: data.roomId }); API.getMessages(data.roomId) .then((res: AxiosResponse) => { data.room.messageLoading = LoadingState.loaded; context.commit("addMessages", { messages: res.data, roomId: data.roomId }); }) .catch((err: AxiosError) => { data.room.messageLoading = LoadingState.notLoaded; console.log(err); }); } }, fetchRoomMembers: async (context, data) => { API.getMembers(data.roomId) .then((res: AxiosResponse) => { context.commit("addAddress", { addresses: res.data, roomId: data.roomId }); }) .catch((err: AxiosError) => { console.log(err); }); }, }, }); export default store;