git-subtree-dir: frontend git-subtree-mainline:205a3bd14bgit-subtree-split:c070c0315d
187 lines
5.4 KiB
Vue
187 lines
5.4 KiB
Vue
<template>
|
|
<div class="flex flex-column py-2">
|
|
<div class="flex flex-row full">
|
|
<div class="w-full">
|
|
<div class="flex justify-between items-center">
|
|
<div>
|
|
<div>
|
|
<div class="content-center flex flex-row">
|
|
<img
|
|
:src="message.createdByPortraitUrl ?? '/images/usersmedia/anonyme/profilepictures/profileAnonymeSquare.png'"
|
|
alt="Profile Image"
|
|
class="rounded-full"
|
|
width="32px"
|
|
height="32px"
|
|
/>
|
|
<span class="font-semibold font-sans mr-2 capitalize ml-2">
|
|
{{ message.createdByName }}
|
|
</span>
|
|
|
|
<v-tooltip :text="new Date(message.createdAt).toLocaleString()">
|
|
<template v-slot:activator="{ props }">
|
|
<span v-bind="props" class="text-sm-caption text-gray-700 mt-1 ">
|
|
{{ time_ago(message.createdAt) }}
|
|
</span>
|
|
|
|
</template>
|
|
</v-tooltip>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<v-menu class="ml-auto" v-if="messageAuthorIsCurrentUser">
|
|
<template v-slot:activator="{ props }">
|
|
<v-btn variant="plain" icon v-bind="props">
|
|
<v-icon>mdi-dots-vertical</v-icon>
|
|
</v-btn>
|
|
</template>
|
|
<v-list>
|
|
<v-list-item @click="editMessage(message)">
|
|
<v-list-item-title>{{ $t('message.edit') }}</v-list-item-title>
|
|
</v-list-item>
|
|
<v-list-item @click="deleteMessage()">
|
|
<v-list-item-title>{{ $t('message.delete') }}</v-list-item-title>
|
|
</v-list-item>
|
|
</v-list>
|
|
</v-menu>
|
|
</div>
|
|
|
|
<div class="font-sans message-content">
|
|
<p class="pb-2" v-if="!isEditMessage"> {{ message.value }}</p>
|
|
|
|
<div v-if="isEditMessage" class="flex flex-row">
|
|
<v-textarea
|
|
variant="outlined"
|
|
v-model="editMessageValue"
|
|
rows="1"
|
|
auto-grow
|
|
class="flex-1 mt-3"
|
|
@keyup.enter="acceptChanges"
|
|
></v-textarea>
|
|
|
|
<div class="flex flex-row px-2 space-y-1 align-center">
|
|
<v-btn variant="plain" @click="cancel">
|
|
<v-icon class="rounded-full">mdi-cancel</v-icon>
|
|
</v-btn>
|
|
<v-btn variant="plain" @click="acceptChanges">
|
|
<v-icon>mdi-check</v-icon>
|
|
</v-btn>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<must-be-logged v-model="loginModal"
|
|
message="Vous devez être connecté pour supprimer ou modifier un commentaire."></must-be-logged>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {ref, watch, onMounted, onBeforeUnmount, computed} from "vue";
|
|
import {time_ago} from "@/internal_time_ago.js";
|
|
import MustBeLogged from "@/views/MustBeLogged.vue";
|
|
import {useAuthStore} from "@/stores/authStore.js";
|
|
import {useClient} from "@/plugins/api.js";
|
|
|
|
const isEditMessage = ref(false);
|
|
const editMessageValue = ref("");
|
|
const originalMessageValue = ref("");
|
|
const loginModal = ref(false);
|
|
const authStore = useAuthStore();
|
|
const client = useClient();
|
|
const messageAuthorId = computed(() => props.message.createdBy)
|
|
const messageAuthorIsCurrentUser = computed(() => authStore.isAuthenticated && authStore.userId === messageAuthorId.value)
|
|
|
|
const props = defineProps({
|
|
message: {
|
|
type: Object,
|
|
required: true
|
|
}
|
|
});
|
|
|
|
const emits = defineEmits(['message-deleted']);
|
|
|
|
function editMessage(message) {
|
|
isEditMessage.value = true;
|
|
originalMessageValue.value = message.value;
|
|
editMessageValue.value = message.value;
|
|
}
|
|
|
|
const acceptChanges = async () => {
|
|
props.message.value = editMessageValue.value;
|
|
isEditMessage.value = false;
|
|
|
|
console.log('Update message', props.message.value);
|
|
if (!authStore.isAuthenticated) {
|
|
loginModal.value = true;
|
|
} else {
|
|
try {
|
|
await client.post(`/api/messages/update`, {
|
|
"id": props.message.id,
|
|
"subjectId": props.message.subjectId,
|
|
"message": props.message.value
|
|
})
|
|
} catch (error) {
|
|
console.error(`post api/message/update : ${error}`)
|
|
}
|
|
}
|
|
}
|
|
|
|
function cancel() {
|
|
editMessageValue.value = originalMessageValue.value;
|
|
isEditMessage.value = false;
|
|
}
|
|
|
|
const deleteMessage = async () => {
|
|
console.log('Delete message', props.message);
|
|
if (!authStore.isAuthenticated) {
|
|
loginModal.value = true;
|
|
} else {
|
|
try {
|
|
await client.delete(`/api/messages/${props.message.id}`)
|
|
emits('message-deleted', {
|
|
"id": props.message.id
|
|
})
|
|
} catch (error) {
|
|
console.error(`delete api/message : ${error}`)
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleKeydown(event) {
|
|
if (event.key === "Escape") {
|
|
cancel();
|
|
}
|
|
}
|
|
|
|
watch(isEditMessage, (newValue) => {
|
|
if (newValue) {
|
|
window.addEventListener('keydown', handleKeydown);
|
|
} else {
|
|
window.removeEventListener('keydown', handleKeydown);
|
|
}
|
|
});
|
|
|
|
onMounted(() => {
|
|
if (isEditMessage.value) {
|
|
window.addEventListener('keydown', handleKeydown);
|
|
}
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
window.removeEventListener('keydown', handleKeydown);
|
|
});
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
.content-center {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.message-content {
|
|
word-wrap: break-word;
|
|
word-break: break-word;
|
|
}
|
|
</style>
|