Compare commits

..

2 Commits

Author SHA1 Message Date
grimhilt
c3374a612e compact mode for messages 2023-05-06 14:14:32 +02:00
grimhilt
686e6a4911 set loading of deletions 2023-05-06 13:30:50 +02:00
7 changed files with 86 additions and 35 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5.79297 5.20718L12.0001 11.4143L18.2072 5.20718L16.793 3.79297L12.0001 8.58586L7.20718 3.79297L5.79297 5.20718Z M18.2073 18.7928L12.0002 12.5857L5.79312 18.7928L7.20733 20.207L12.0002 15.4141L16.7931 20.207L18.2073 18.7928Z"></path></svg>

After

Width:  |  Height:  |  Size: 308 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.2073 9.04304L12.0002 2.83594L5.79312 9.04304L7.20733 10.4573L12.0002 5.66436L16.7931 10.4573L18.2073 9.04304Z M5.79297 14.9574L12.0001 21.1646L18.2072 14.9574L16.793 13.5432L12.0001 18.3361L7.20718 13.5432L5.79297 14.9574Z"></path></svg>

After

Width:  |  Height:  |  Size: 310 B

View File

@ -281,6 +281,7 @@ function sendMessage() {
display: flex;
flex-direction: row;
padding: 0 10px 10px 10px;
min-height: 90px;
max-height: 500px;
overflow: auto;
}
@ -296,7 +297,7 @@ function sendMessage() {
border-radius: 10px;
padding: 0 10px;
overflow: auto;
min-height: 150px;
min-height: 80px;
}
.bubble-menu,

View File

@ -1,17 +1,25 @@
<script setup lang="ts">
import { defineProps, PropType } from "vue";
import { defineProps, withDefaults, ref } 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";
import SvgLoader from "@/components/utils/SvgLoader.vue";
const props = defineProps({
msg: Object as PropType<Message>,
members: Array as PropType<Address[]>,
export interface Props {
msg: Message;
members: Address[];
compact: boolean;
}
const props = withDefaults(defineProps<Props>(), {
compact: () => true,
});
const compact = ref(props.compact);
const displayAddresses = (addressIds: string[] | undefined): string => {
if (!addressIds) return "";
addressIds = removeDuplicates(addressIds);
@ -63,7 +71,14 @@ const classes = (): string => {
</div>
</div>
<div class="content" :class="[classes()]">
<Content :content="props.msg?.content" />
<Content v-if="!compact" :content="props.msg?.content" />
<SvgLoader
v-if="compact"
classes="selectable"
class="expand-contract"
svg="expand-up-down-line"
@click="compact = false"
/>
<Options class="options" :msg="props.msg" />
</div>
</div>
@ -101,6 +116,10 @@ const classes = (): string => {
flex-direction: row;
}
.expand-contract {
margin: 0 50px;
}
.msg-important {
background-color: #ec7a4342;
}

View File

@ -14,6 +14,7 @@ const room: any = inject("room");
const seenLoading = ref(false);
const flaggedLoading = ref(false);
const deletionLoading = ref(false);
const setReadFlag = () => setFlag("\\Seen", seenLoading);
const setFlaggedFlag = () => setFlag("\\Flagged", flaggedLoading);
@ -44,26 +45,34 @@ const setFlag = (flag: string, loadingState: Ref<boolean>) => {
};
const deleteEverywhere = () => {
if (deletionLoading.value) return;
if (!room?.value || !props.msg) return;
deletionLoading.value = true;
API.deleteEverywhere({ mailboxId: room.value?.mailboxId, messageId: props.msg?.id })
.then((res) => {
store.commit("removeMsg", { roomId: room.value?.id, messageId: props.msg?.id });
deletionLoading.value = false;
})
.catch((err) => {
console.log(err);
deletionLoading.value = false;
});
};
const deleteRemoteOnly = () => {
if (deletionLoading.value) return;
if (!room?.value || !props.msg) return;
deletionLoading.value = true;
API.deleteRemoteOnly({ mailboxId: room.value?.mailboxId, messageId: props.msg?.id })
.then((res) => {
if (!hasFlag(props.msg?.flags, "\\Deleted")) {
store.commit("addFlag", { roomId: room.value?.id, messageId: props.msg?.id, flag: "\\Deleted" });
}
deletionLoading.value = false;
})
.catch((err) => {
console.log(err);
deletionLoading.value = false;
});
};
</script>
@ -75,14 +84,14 @@ const deleteRemoteOnly = () => {
<SvgLoader
v-if="isSeenFc(props.msg?.flags)"
svg="mail-check-line"
class="option"
classes="selectable"
v-tooltip="'Mark unread'"
:loading="seenLoading"
/>
<SvgLoader
v-if="!isSeenFc(props.msg?.flags)"
svg="mail-unread-line"
class="option"
classes="selectable"
v-tooltip="'Mark as read'"
:loading="seenLoading"
/>
@ -90,26 +99,33 @@ const deleteRemoteOnly = () => {
<span @click="setFlaggedFlag()">
<SvgLoader
svg="flag-line"
class="option"
:loading="flaggedLoading"
:classes="hasFlag(props.msg?.flags, '\\Flagged') ? 'warn' : ''"
:classes="(hasFlag(props.msg?.flags, '\\Flagged') ? 'warn' : '') + ',selectable'"
v-tooltip="hasFlag(props.msg?.flags, '\\Flagged') ? 'Unflag' : 'Flag'"
/>
</span>
<SvgLoader svg="reply-line" class="option" />
<SvgLoader svg="reply-line" classes="selectable" />
<span @click="deleteRemoteOnly()">
<SvgLoader svg="delete-bin-4-line" class="option" classes="danger" v-tooltip="'Delete from remote'" />
<SvgLoader
svg="delete-bin-4-line"
:loading="deletionLoading"
classes="danger,selectable"
v-tooltip="'Delete from remote'"
/>
</span>
<span @click="deleteEverywhere()">
<SvgLoader svg="delete-bin-6-line" class="option" classes="danger" v-tooltip="'Delete everywhere'" />
<SvgLoader
svg="delete-bin-6-line"
:loading="deletionLoading"
classes="danger,selectable"
v-tooltip="'Delete everywhere'"
/>
</span>
<SvgLoader svg="share-forward-line" class="option" />
<SvgLoader svg="reply-all-line" class="option" />
<SvgLoader svg="share-forward-line" classes="selectable" />
<SvgLoader svg="reply-all-line" classes="selectable" />
<div>{{ props.msg?.flags }}</div>
</div>
<div>reply</div>
<div>transfer</div>
<div>see source</div>
<div>{{ props.msg?.flags }}</div>
<!-- <div>see source</div> -->
</div>
</template>
@ -122,6 +138,7 @@ const deleteRemoteOnly = () => {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.button {
@ -135,14 +152,4 @@ const deleteRemoteOnly = () => {
background-color: var(--selected);
}
}
.option {
border-radius: 6px;
cursor: pointer;
&:hover,
&.is-active {
background-color: var(--selected);
}
}
</style>

View File

@ -5,23 +5,34 @@ const props = defineProps({
svg: { type: String, required: true },
isDisabled: Boolean,
classes: String,
loading: { type: Boolean, default: false },
loading: { type: Boolean },
});
console.log(props.loading);
const pathSvg = () => require(`@/assets/svg/${props.svg}.svg`);
const classes = () => props.classes?.split(",") ?? "";
</script>
<template>
<div class="mainSvg">
<div class="mainSvg" :class="classes()">
<div class="lds-dual-ring" v-if="loading"></div>
<img v-if="!loading" :disabled="props.isDisabled" :src="pathSvg()" :class="props.classes" />
<img v-if="!loading" :disabled="props.isDisabled" :src="pathSvg()" :class="classes()" />
</div>
</template>
<style lang="scss" scoped>
.mainSvg {
display: inherit;
min-width: 26px;
min-height: 26px;
}
.mainSvg.selectable {
border-radius: 6px;
cursor: pointer;
&:hover,
&.is-active {
background-color: var(--selected);
}
}
img {
@ -37,7 +48,7 @@ img {
}
.lds-dual-ring {
display: inline-block;
display: flex;
width: 26px;
height: 26px;
}

View File

@ -12,12 +12,14 @@ const store = useStore();
const route = useRoute();
const messageIdView = ref(-1);
const message = ref(undefined);
const messages = ref([]);
const id = ref(parseInt(route.params.id));
let room = ref();
onBeforeMount(async () => {
store.commit("setActiveRoom", id.value);
room.value = store.getters.room(id.value);
messages.value = store.getters.messages(room.value?.id);
console.log(room.value);
});
@ -26,6 +28,8 @@ onBeforeRouteUpdate(async (to, from) => {
id.value = parseInt(to.params.id);
store.commit("setActiveRoom", id.value);
room.value = await store.getters.room(id.value);
messages.value = store.getters.messages(room.value?.id);
console.log(room.value);
}
});
@ -45,6 +49,12 @@ function openMessageView(messageId) {
message.value = store.getters.message(room.value.id, messageId);
}
const shouldBeCompact = (index) => {
// show last three messages
if (messages.value?.length - 4 < index) return false;
return true;
};
provide("room", room);
</script>
@ -53,10 +63,11 @@ provide("room", room);
<Header :id="id" :room="room"></Header>
<div class="messages">
<Message
v-for="(message, index) in store.getters.messages(room?.id)"
v-for="(message, index) in messages"
:key="index"
:msg="message"
:members="room?.members"
:compact="shouldBeCompact(index)"
@open-message-view="(id) => openMessageView(id)"
/>
</div>