add button to set seen flag on front
This commit is contained in:
@@ -9,7 +9,6 @@ const props = defineProps({
|
||||
|
||||
const iframe = ref<HTMLIFrameElement>();
|
||||
|
||||
// todo dompurify
|
||||
// background vs color
|
||||
const htmlDefault = (html: string) => {
|
||||
return `
|
||||
@@ -33,7 +32,9 @@ function setIframeContent(content: string | undefined) {
|
||||
if (!content) return;
|
||||
const doc = iframe.value.contentDocument || iframe.value.contentWindow?.document;
|
||||
if (!doc) return;
|
||||
const html = DOMPurify.sanitize(content);
|
||||
// todo dompurify for image
|
||||
const html = DOMPurify.sanitize(content, { FORBID_TAGS: ["style"] });
|
||||
|
||||
doc.open();
|
||||
doc.write(htmlDefault(html));
|
||||
doc.close();
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { defineProps, ref, PropType } from "vue";
|
||||
import { defineProps, PropType } from "vue";
|
||||
import { decodeEmojis } from "../../../utils/string";
|
||||
import { removeDuplicates } from "../../../utils/array";
|
||||
import { Address, Message } from "@/store/models/model";
|
||||
import Content from "./Content.vue";
|
||||
import Options from "./Options.vue";
|
||||
import { isSeenFc } from "@/utils/flagsUtils";
|
||||
|
||||
const props = defineProps({
|
||||
msg: Object as PropType<Message>,
|
||||
members: Array as PropType<Address[]>,
|
||||
mailboxId: Number,
|
||||
roomId: Number,
|
||||
});
|
||||
|
||||
const displayAddresses = (addressIds: string[] | undefined): string => {
|
||||
@@ -22,15 +26,13 @@ const displayAddresses = (addressIds: string[] | undefined): string => {
|
||||
};
|
||||
|
||||
const classes = (): string => {
|
||||
const flags = props.msg?.flags?.split(",");
|
||||
|
||||
// not flags implies no seen flag
|
||||
if (!flags) return "msg-notSeen";
|
||||
const flags = props.msg?.flags;
|
||||
|
||||
// Important takes the priority on Seen flag
|
||||
if (flags.includes("\\Important")) {
|
||||
if (flags?.includes("\\Important")) {
|
||||
return "msg-important";
|
||||
} else if (!flags.includes("\\Seen")) {
|
||||
}
|
||||
if (!isSeenFc(flags)) {
|
||||
return "msg-notSeen";
|
||||
}
|
||||
return "msg-basic";
|
||||
@@ -64,7 +66,7 @@ const classes = (): string => {
|
||||
</div>
|
||||
<div class="content" :class="[classes()]">
|
||||
<Content :content="props.msg?.content" />
|
||||
<div class="options">options {{ props?.msg?.flags }}</div>
|
||||
<Options class="options" :mailboxId="props.mailboxId" :roomId="props.roomId" :msg="props.msg" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,23 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
import { defineProps, onMounted, ref, watch, PropType } from "vue";
|
||||
import { decodeEmojis } from "../../../utils/string";
|
||||
import { removeDuplicates } from "../../../utils/array";
|
||||
import DOMPurify from "dompurify";
|
||||
import { Address, Message } from "@/store/models/model";
|
||||
import { defineProps, PropType } from "vue";
|
||||
import { Message } from "@/store/models/model";
|
||||
import API from "@/services/imapAPI";
|
||||
import store from "@/store/store";
|
||||
import { isSeenFc } from "@/utils/flagsUtils";
|
||||
|
||||
const props = defineProps({
|
||||
msg: Object as PropType<Message>,
|
||||
mailboxId: Number,
|
||||
roomId: Number,
|
||||
});
|
||||
|
||||
const setFlag = (flag: string) => {
|
||||
// todo loading
|
||||
if (!props.mailboxId || !props.msg) return;
|
||||
let apiCall = isSeenFc(props.msg?.flags) ? API.removeFlag : API.addFlag;
|
||||
apiCall({
|
||||
mailboxId: props.mailboxId,
|
||||
messageId: props.msg?.id,
|
||||
flag: flag,
|
||||
})
|
||||
.then((res) => {
|
||||
if (isSeenFc(props.msg?.flags)) {
|
||||
store.commit("removeFlag", { roomId: props.roomId, messageId: props.msg?.id, flag: flag });
|
||||
} else {
|
||||
store.commit("addFlag", { roomId: props.roomId, messageId: props.msg?.id, flag: flag });
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div>mark as not read</div>
|
||||
<div class="button" @click="setFlag('\\Seen')">
|
||||
{{ isSeenFc(props.msg?.flags) ? "Mark as not read" : "Mark as read" }}
|
||||
</div>
|
||||
<div>flag favorite</div>
|
||||
<div>reply</div>
|
||||
<div>delete from all</div>
|
||||
<div>delete from remote</div>
|
||||
<div>transfer</div>
|
||||
<div>see source</div>
|
||||
<div>{{ props.msg?.flags }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -25,4 +51,16 @@ const props = defineProps({
|
||||
div {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
border: solid 1px;
|
||||
border-radius: 6px;
|
||||
display: initial;
|
||||
padding: 1px 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: var(--selected);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -16,4 +16,10 @@ export default {
|
||||
getMembers(roomId: number) {
|
||||
return API().get(`/mail/${roomId}/members`);
|
||||
},
|
||||
addFlag(data: { mailboxId: number; messageId: number; flag: string }) {
|
||||
return API().post(`/mail/addFlag`, data);
|
||||
},
|
||||
removeFlag(data: { mailboxId: number; messageId: number; flag: string }) {
|
||||
return API().post(`/mail/removeFlag`, data);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface Message {
|
||||
subject: string;
|
||||
content: string;
|
||||
date: string;
|
||||
flags: string;
|
||||
flags: string[];
|
||||
}
|
||||
|
||||
export enum LoadingState {
|
||||
@@ -23,6 +23,7 @@ export enum LoadingState {
|
||||
loaded = 2,
|
||||
}
|
||||
|
||||
// todo store messages outside of the room
|
||||
export interface Room {
|
||||
id: number;
|
||||
roomName: string;
|
||||
|
||||
@@ -46,6 +46,8 @@ export interface State {
|
||||
activeRoom: number;
|
||||
}
|
||||
|
||||
const roomOnId = (state: State, roomId: number) => state.rooms.find((room: Room) => room.id == roomId);
|
||||
|
||||
// // define injection key todo
|
||||
// export const key: InjectionKey<Store<State>> = Symbol()
|
||||
|
||||
@@ -94,20 +96,33 @@ const store = createStore<State>({
|
||||
},
|
||||
addMessages(state, payload) {
|
||||
// todo add if not exist
|
||||
const room = state.rooms.find((room) => room.id == payload.roomId);
|
||||
const room = roomOnId(state, payload.roomId);
|
||||
if (!room) return;
|
||||
payload.messages.forEach((message: Message) => {
|
||||
payload.messages.forEach((message: any) => {
|
||||
message.flags = message.flags?.split(",") ?? [];
|
||||
room.messages.push(message);
|
||||
});
|
||||
},
|
||||
addAddress(state, payload) {
|
||||
// todo add if not exist
|
||||
const room = state.rooms.find((room) => room.id == payload.roomId);
|
||||
const room = roomOnId(state, payload.roomId);
|
||||
if (!room) return;
|
||||
payload.addresses.forEach((address: Address) => {
|
||||
room.members.push(address);
|
||||
});
|
||||
},
|
||||
addFlag(state, payload) {
|
||||
const msg = roomOnId(state, payload.roomId)?.messages.find((msg) => msg.id == payload.messageId);
|
||||
if (msg) {
|
||||
msg.flags.push(payload.flag);
|
||||
}
|
||||
},
|
||||
removeFlag(state, payload) {
|
||||
const msg = roomOnId(state, payload.roomId)?.messages.find((msg) => msg.id == payload.messageId);
|
||||
if (msg) {
|
||||
msg.flags?.splice(msg.flags?.indexOf(payload.flag), 1);
|
||||
}
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
rooms: (state) => (): Room[] => {
|
||||
@@ -119,20 +134,19 @@ const store = createStore<State>({
|
||||
room:
|
||||
(state) =>
|
||||
(roomId: number): Room | undefined => {
|
||||
const room = state.rooms.find((room) => room.id == roomId);
|
||||
return room;
|
||||
return roomOnId(state, roomId);
|
||||
},
|
||||
address:
|
||||
(state) =>
|
||||
(roomId: number, addressId: number): Address | undefined => {
|
||||
const room = state.rooms.find((room) => room.id == roomId);
|
||||
const room = roomOnId(state, 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);
|
||||
const room = roomOnId(state, roomId);
|
||||
if (!room) return [];
|
||||
if (room.messageLoading === LoadingState.notLoaded) {
|
||||
store.dispatch("fetchMessages", { roomId: room.id, room: room });
|
||||
|
||||
3
front/src/utils/flagsUtils.ts
Normal file
3
front/src/utils/flagsUtils.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function isSeenFc(flags: string[] | undefined): boolean {
|
||||
return flags?.includes("\\Seen") ?? false;
|
||||
}
|
||||
@@ -47,6 +47,8 @@ function openMessageView(id) {
|
||||
:key="index"
|
||||
:msg="message"
|
||||
:members="room?.members"
|
||||
:mailboxId="room.mailboxId"
|
||||
:roomId="room.id"
|
||||
@open-message-view="(id) => openMessageView(id)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user