diff --git a/back/controllers/messages.js b/back/controllers/messages.js new file mode 100644 index 0000000..8ce445c --- /dev/null +++ b/back/controllers/messages.js @@ -0,0 +1,16 @@ +const statusCode = require("../utils/statusCodes").statusCodes; +const { getMessages } = require("../db/api.js"); + +async function messages(body, res) { + const { roomId } = body; + getMessages(roomId).then((messages) => { + res.status(statusCode.OK).json(messages.data); + }).catch((err) => { + console.log(err) + res.status(statusCode.INTERNAL_SERVER_ERROR); + }); +} + +module.exports = { + messages, +}; diff --git a/back/controllers/rooms.js b/back/controllers/rooms.js index 7d60f69..36b793d 100644 --- a/back/controllers/rooms.js +++ b/back/controllers/rooms.js @@ -4,7 +4,6 @@ const { getRooms } = require("../db/api.js"); async function rooms(body, res) { const { mailboxId, offset, limit } = body; getRooms(mailboxId).then((rooms) => { - console.log(rooms) res.status(statusCode.OK).json(rooms); }).catch((err) => { console.log(err) diff --git a/back/db/api.js b/back/db/api.js index 384916d..ca1f012 100644 --- a/back/db/api.js +++ b/back/db/api.js @@ -44,8 +44,39 @@ async function getRooms(mailboxId) { return await execQueryAsync(query, values); } +async function getMessages(roomId) { + // todo attachements name + const query = ` + SELECT + address_field.address_id, + bodypart.text, + header_field.value + FROM bodypart + INNER JOIN header_field + INNER JOIN address_field + INNER JOIN field_name + WHERE + ( + header_field.field_id = field_name.field_id OR + address_field.field_id = field_name.field_id + ) AND + ( + field_name.field_name = 'html' OR + field_name.field_name = 'text' OR + field_name.field_name = 'textAsHtml' OR + field_name.field_name = 'to' OR + field_name.field_name = 'cc' OR + field_name.field_name = 'subject' + ) + `; + // todo roomID + const values = []; + return await execQueryAsync(query, values); +} + module.exports = { registerMailbox, getMailboxes, - getRooms + getRooms, + getMessages }; diff --git a/back/db/saveMessage.js b/back/db/saveMessage.js index f99525f..e877054 100644 --- a/back/db/saveMessage.js +++ b/back/db/saveMessage.js @@ -16,6 +16,7 @@ function registerMailbox_message(mailboxId, uid, messageId, modseq, seen, delete INSERT IGNORE INTO mailbox_message (mailbox_id, uid, message_id, modseq, seen, deleted) VALUES (1, 19, 10, '12450', 0, 0) `; + // todo const values = [mailboxId, uid, messageId, modseq, seen, deleted]; execQuery(query, values); } @@ -30,7 +31,7 @@ function registerBodypart(messageId, part, bodypartId, bytes, nbLines) { } async function saveBodypart(bytes, hash, text, data) { - const query = `INSERT IGNORE INTO bodypart (bytes, hash, text, data) VALUES (?, ?, ?,)`; + const query = `INSERT IGNORE INTO bodypart (bytes, hash, text, data) VALUES (?, ?, ?, ?)`; const values = [bytes, hash, text, data]; return await execQueryAsyncWithId(query, values); } diff --git a/back/imap/storeMessage.js b/back/imap/storeMessage.js index 7173e41..d2fc0b4 100644 --- a/back/imap/storeMessage.js +++ b/back/imap/storeMessage.js @@ -83,7 +83,7 @@ async function saveFromParsedData(parsed, messageId) { }), ); } else if (["subject", "inReplyTo"].includes(key)) { - // todo : "references" + // todo : "references" (array) promises.push( getFieldId(key).then(async (fieldId) => { await saveHeader_fields(messageId, fieldId, undefined, undefined, parsed[key]); @@ -92,22 +92,22 @@ async function saveFromParsedData(parsed, messageId) { } else if (["html", "text", "textAsHtml"].includes(key)) { const hash = "0"; const size = "0"; - // saveBodypart(size, hash, parsed[key], "").then((bodypartId) => { - // getFieldId(key).then((fieldId) => { - // saveHeader_fields( - // messageId, - // fieldId, - // bodypartId, - // undefined, // todo ? - // undefined - // ); - // }); - // }); + saveBodypart(size, hash, parsed[key], "").then((bodypartId) => { + getFieldId(key).then((fieldId) => { + saveHeader_fields( + messageId, + fieldId, + bodypartId, + undefined, // todo ? + undefined + ); + }); + }); } else if (key == "attachments") { // todo } else if (["date", "messageId", "headers", "headerLines"].includes(key)) { // messageId and date are already saved - // other field are not improted and can be retrieved in source + // other field are not important and can be retrieved in source return; } else { DEBUG.log("doesn't know key: " + key); diff --git a/back/routes/mail.js b/back/routes/mail.js index 0f6bca8..0035add 100644 --- a/back/routes/mail.js +++ b/back/routes/mail.js @@ -10,6 +10,7 @@ const schema_mailbox = require("../schemas/mailbox_schema.json"); const { addMailbox } = require("../controllers/addMailbox.js"); const { getMailboxes } = require("../db/api.js"); const { rooms } = require("../controllers/rooms.js"); +const { messages } = require("../controllers/messages.js"); const validate_mailbox = ajv.compile(schema_mailbox); @@ -37,6 +38,13 @@ router.get("/:mailboxId/rooms", async (req, res) => { }); +router.get("/:roomId/messages", async (req, res) => { + const { roomId } = req.params; + console.log("called") + // todo check token + await messages(req.params, res); +}); + /** * Register a new mailbox inside the app */ diff --git a/front/src/main.js b/front/src/main.js index d80be33..8e57797 100644 --- a/front/src/main.js +++ b/front/src/main.js @@ -1,11 +1,11 @@ import { createApp } from 'vue' import router from './router' import App from './App.vue' -import roomsStore from './store/rooms' +import store from './store/store' const app = createApp(App); app.use(router); -app.use(roomsStore); +app.use(store); app.mount('#app'); \ No newline at end of file diff --git a/front/src/router/index.js b/front/src/router/index.js index 26bf887..4efaa4d 100644 --- a/front/src/router/index.js +++ b/front/src/router/index.js @@ -19,7 +19,6 @@ const routes = [ }, { path: "/:id", - name: "test", component: RoomView } ]; diff --git a/front/src/services/imapAPI.js b/front/src/services/imapAPI.js index a1cc460..587f1a7 100644 --- a/front/src/services/imapAPI.js +++ b/front/src/services/imapAPI.js @@ -9,5 +9,8 @@ export default { }, getRooms(mailboxId) { return API().get(`/mail/${mailboxId}/rooms`); + }, + getMessages(roomId) { + return API().get(`/mail/${roomId}/messages`); } } \ No newline at end of file diff --git a/front/src/store/rooms.js b/front/src/store/store.js similarity index 51% rename from front/src/store/rooms.js rename to front/src/store/store.js index e1c8045..428d87b 100644 --- a/front/src/store/rooms.js +++ b/front/src/store/store.js @@ -1,7 +1,7 @@ import API from "@/services/imapAPI"; import { createStore } from "vuex"; -const roomsStore = createStore({ +const store = createStore({ state() { return { rooms: [ @@ -9,40 +9,50 @@ const roomsStore = createStore({ id: 0, user: "clemnce", userId: 0, - name: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", + roomName: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", mailboxId: 1, }, { + id: 1, user: "juliette", - name: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", + roomName: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", mailboxId: 1, }, { + id: 2, user: "jean", - name: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", + roomName: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", mailboxId: 2, }, { + id: 3, user: "luc", - name: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", + roomName: "Lorem magna minim cillum labore ex eiusmod proident excepteur sint irure ipsum.", mailboxId: 2, }, + ], + messages: [ + ], mailboxes: [], - activeMailbox: -1, + activeMailbox: 0, + activeRoom: 0 }; }, mutations: { setActiveMailbox(state, payload) { state.activeMailbox = payload; + + // todo call actions + // fetch rooms for this mailboxes if not already fetched const mailbox = state.mailboxes.find((mailbox) => mailbox.id == payload); // todo fetched mailbox all if (mailbox?.fetched == false) { - mailbox.fetched = true; - console.log("add messages") API.getRooms(payload).then((res) => { // todo add if not exist + mailbox.fetched = true; res.data.forEach((room) => { + room.fetched = false; state.rooms.push(room); }); }).catch((err) => { @@ -50,6 +60,24 @@ const roomsStore = createStore({ }); } }, + setActiveRoom(state, payload) { + state.activeRoom = payload; + // todo call actions + // fetch messages for this room if not already fetched + const room = state.rooms.find((room) => room.id == payload); + if (!room || room?.fetched == false) { + console.log("add messages") + API.getMessages(payload).then((res) => { + // todo add if not exist + room.fetched = true; + res.data.forEach((msg) => { + state.messages.push(msg); + }); + }).catch((err) => { + console.log(err) + }); + } + }, addMailboxes(state, payload) { payload.forEach((mailbox) => { mailbox.fetched = false; @@ -59,10 +87,16 @@ const roomsStore = createStore({ }, getters: { rooms: (state) => () => { - console.log(state.rooms.length) - if (state.activeMailbox == 0) return state.rooms; + if (state.activeMailbox === 0) return state.rooms; return state.rooms.filter((room) => room.mailboxId == state.activeMailbox); }, + messages: (state) => (roomId) => { + const room = state.rooms.find((room) => room.id === roomId); + if (room?.fetched === false) { + console.log("ok") + } + return [1, 2]; + } }, actions: { async fetchMailboxes(context) { @@ -75,7 +109,10 @@ const roomsStore = createStore({ console.log(err); }); }, + async fetchMessages(context) { + console.log(context) + }, }, }); -export default roomsStore; +export default store; diff --git a/front/src/views/room/Message.vue b/front/src/views/room/Message.vue new file mode 100644 index 0000000..11e5378 --- /dev/null +++ b/front/src/views/room/Message.vue @@ -0,0 +1,30 @@ + + + + + + + + + + + + + diff --git a/front/src/views/room/RoomView.vue b/front/src/views/room/RoomView.vue index 8341174..0ed0c29 100644 --- a/front/src/views/room/RoomView.vue +++ b/front/src/views/room/RoomView.vue @@ -1,35 +1,47 @@ - Room - is thread + {{ id }} + {{ messages.length }} - - diff --git a/front/src/views/sidebar/mailboxes/Mailboxes.vue b/front/src/views/sidebar/mailboxes/Mailboxes.vue index f86b51d..6763d78 100644 --- a/front/src/views/sidebar/mailboxes/Mailboxes.vue +++ b/front/src/views/sidebar/mailboxes/Mailboxes.vue @@ -17,7 +17,7 @@ import { mapState } from 'vuex' import Mailbox from './Mailbox' import AddMailboxModal from '../../modals/AddMailboxModal' -import roomsStore from '@/store/rooms' +import store from '@/store/store' export default { name: 'Mailboxes', @@ -30,7 +30,7 @@ export default { }, created() { console.log("call api get mailboxes"); - roomsStore.dispatch('fetchMailboxes'); + store.dispatch('fetchMailboxes'); } } diff --git a/front/src/views/sidebar/rooms/Room.vue b/front/src/views/sidebar/rooms/Room.vue index 926bacf..91063da 100644 --- a/front/src/views/sidebar/rooms/Room.vue +++ b/front/src/views/sidebar/rooms/Room.vue @@ -1,29 +1,11 @@ - - - - - - - {{ data.user }} - {{ data.roomName }} - - - - - - - + + + + + + {{ props.data.user }} + {{ props.data.roomName }} + + + + + +