Merge branch 'main' into settings-page

This commit is contained in:
JustTemmie 2025-06-02 12:36:20 +02:00
commit 8a3bb89f8a
Signed by: justtemmie
SSH key fingerprint: SHA256:nBO+OwpTkd8LYhe38PIqdxmDvkIg9Vw2EbrRZM97dkU
7 changed files with 76 additions and 56 deletions

View file

@ -1,11 +1,11 @@
<template>
<div v-if="isCurrentChannel" class="channel-list-link-container rounded-corners current-channel">
<NuxtLink class="channel-list-link" :href="props.href">
<div v-if="isCurrentChannel" class="channel-list-link-container rounded-corners current-channel" tabindex="0">
<NuxtLink class="channel-list-link" :href="props.href" tabindex="-1">
# {{ props.name }}
</NuxtLink>
</div>
<div v-else class="channel-list-link-container rounded-corners">
<NuxtLink class="channel-list-link" :href="props.href">
<div v-else class="channel-list-link-container rounded-corners" tabindex="0">
<NuxtLink class="channel-list-link" :href="props.href" tabindex="-1">
# {{ props.name }}
</NuxtLink>
</div>

View file

@ -1,5 +1,5 @@
<template>
<div v-if="props.type == 'normal'" :id="props.last ? 'last-message' : undefined" class="message normal-message" :class="{ 'message-margin-bottom': props.marginBottom }">
<div v-if="props.type == 'normal'" :id="props.last ? 'last-message' : undefined" class="message normal-message" :class="{ 'message-margin-bottom': props.marginBottom }" tabindex="0">
<div class="left-column">
<img v-if="props.img" class="message-author-avatar" :src="props.img" :alt="username">
<Icon v-else name="lucide:user" class="message-author-avatar" />
@ -13,12 +13,10 @@
{{ messageDate }}
</span>
</div>
<div class="message-text">
{{ text }}
</div>
<div class="message-text" v-html="sanitized"></div>
</div>
</div>
<div v-else ref="messageElement" :id="props.last ? 'last-message' : undefined" class="message grouped-message">
<div v-else ref="messageElement" :id="props.last ? 'last-message' : undefined" class="message grouped-message" tabindex="0">
<div class="left-column">
<div>
<span :class="{ 'invisible': dateHidden }" class="message-date" :title="date.toString()">
@ -27,14 +25,15 @@
</div>
</div>
<div class="message-data">
<div class="message-text">
{{ text }}
</div>
<div class="message-text" v-html="sanitized"></div>
</div>
</div>
</template>
<script lang="ts" setup>
import DOMPurify from 'dompurify';
import { parseInline } from 'marked';
const props = defineProps<{
class?: string,
img?: string | null,
@ -74,7 +73,11 @@ if (props.format == "12") {
console.log("message:", props.text);
console.log("author:", props.username);
const sanitized = ref<string>();
onMounted(async () => {
const parsed = await parseInline(props.text, {gfm: true });
sanitized.value = DOMPurify.sanitize(parsed, { ALLOWED_TAGS: ["strong", "em", "br", "blockquote", "code", "ul", "ol", "li", "a"] });
console.log("adding listeners")
await nextTick();
messageElement.value?.addEventListener("mouseenter", (e: Event) => {
@ -102,8 +105,8 @@ onMounted(async () => {
align-items: center;
}
.message-margin-bottom {
margin-bottom: 1dvh;
.normal-message {
margin-top: 1dvh;
}
#last-message {

View file

@ -185,6 +185,7 @@ onMounted(async () => {
olderMessages.reverse();
console.log("older messages:", olderMessages);
if (olderMessages.length == 0) return;
olderMessages.reverse();
for (const [i, oldMessage] of olderMessages.entries()) {
console.log("old message:", oldMessage);
messages.value.unshift(oldMessage);

View file

@ -123,30 +123,6 @@ const members = [
grid-row: 1;
}
#test {
grid-column: 3;
grid-row: 1;
}
.member-item {
display: flex;
justify-content: center;
align-items: center;
}
#message-history,
#members-list {
padding-top: 3dvh;
}
#message-history {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 3dvw;
padding-right: 3dvw;
}
#left-column {
display: flex;
flex-direction: column;

View file

@ -14,6 +14,8 @@
"@nuxt/icon": "1.13.0",
"@nuxt/image": "1.10.0",
"@pinia/nuxt": "0.11.0",
"dompurify": "^3.2.6",
"marked": "^15.0.12",
"nuxt": "^3.17.0",
"pinia": "^3.0.2",
"pinia-plugin-persistedstate": "^4.2.0",

View file

@ -24,11 +24,13 @@
</div>
</div>
<MessageArea :channel-url="channelUrlPath" />
<div id="members-list">
<div class="member-item" v-for="member of members">
<img v-if="member.user.avatar" class="member-avatar" :src="member.user.avatar" :alt="member.user.display_name ?? member.user.username" />
<Icon v-else class="member-avatar" name="lucide:user" />
<span class="member-display-name">{{ member.user.display_name ?? member.user.username }}</span>
<div id="members-container">
<div id="members-list">
<div class="member-item" v-for="member of members" tabindex="0">
<img v-if="member.user.avatar" class="member-avatar" :src="member.user.avatar" :alt="member.user.display_name ?? member.user.username" />
<Icon v-else class="member-avatar" name="lucide:user" />
<span class="member-display-name">{{ member.user.display_name ?? member.user.username }}</span>
</div>
</div>
</div>
</NuxtLayout>
@ -79,18 +81,6 @@ function toggleInvitePopup(e: Event) {
</script>
<style>
.member-item {
display: flex;
justify-content: center;
align-items: center;
margin-top: .5em;
margin-bottom: .5em;
gap: .5em;
}
#members-list {
padding-top: 3dvh;
}
#middle-left-column {
padding-left: 1dvw;
@ -98,12 +88,29 @@ function toggleInvitePopup(e: Event) {
border-right: 1px solid rgb(70, 70, 70);
}
#members-list {
#members-container {
padding-top: 1dvh;
padding-left: 1dvw;
padding-right: 1dvw;
border-left: 1px solid rgb(70, 70, 70);
}
#members-list {
display: grid;
grid-template-columns: auto;
}
.member-item {
display: grid;
grid-template-columns: 2dvw auto;
margin-top: .5em;
margin-bottom: .5em;
gap: 1em;
align-items: center;
text-align: left;
}
#channels-list {
display: flex;
flex-direction: column;
@ -116,4 +123,9 @@ function toggleInvitePopup(e: Event) {
border-radius: 50%;
}
.member-display-name {
overflow: hidden;
text-overflow: ellipsis;
}
</style>

26
pnpm-lock.yaml generated
View file

@ -20,6 +20,12 @@ importers:
'@pinia/nuxt':
specifier: 0.11.0
version: 0.11.0(magicast@0.3.5)(pinia@3.0.2(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)))
dompurify:
specifier: ^3.2.6
version: 3.2.6
marked:
specifier: ^15.0.12
version: 15.0.12
nuxt:
specifier: ^3.17.0
version: 3.17.0(@netlify/blobs@8.2.0)(@parcel/watcher@2.5.1)(@types/node@22.15.3)(db0@0.3.2)(eslint@9.25.1(jiti@2.4.2))(ioredis@5.6.1)(lightningcss@1.29.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.1)(terser@5.39.0)(typescript@5.8.3)(vite@6.3.3(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.39.0)(yaml@2.7.1))(yaml@2.7.1)
@ -1199,6 +1205,9 @@ packages:
'@types/triple-beam@1.3.5':
resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==}
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
'@types/yauzl@2.10.3':
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
@ -2113,6 +2122,9 @@ packages:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'}
dompurify@3.2.6:
resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==}
domutils@3.2.2:
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
@ -3092,6 +3104,11 @@ packages:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
marked@15.0.12:
resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
engines: {node: '>= 18'}
hasBin: true
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
@ -6094,6 +6111,9 @@ snapshots:
'@types/triple-beam@1.3.5': {}
'@types/trusted-types@2.0.7':
optional: true
'@types/yauzl@2.10.3':
dependencies:
'@types/node': 22.15.3
@ -7082,6 +7102,10 @@ snapshots:
dependencies:
domelementtype: 2.3.0
dompurify@3.2.6:
optionalDependencies:
'@types/trusted-types': 2.0.7
domutils@3.2.2:
dependencies:
dom-serializer: 2.0.0
@ -8170,6 +8194,8 @@ snapshots:
dependencies:
semver: 6.3.1
marked@15.0.12: {}
math-intrinsics@1.1.0: {}
mdn-data@2.0.28: {}