Merge pull request #959 from nagisa77/codex/fix-chat-markdown-rendering-issues

feat: enhance chat markdown and editor
This commit is contained in:
Tim
2025-09-09 21:20:49 +08:00
committed by GitHub
3 changed files with 39 additions and 21 deletions

View File

@@ -239,8 +239,16 @@ body {
} }
.info-content-text img { .info-content-text img {
max-width: 100%; max-width: 400px;
max-height: 600px;
height: auto; height: auto;
cursor: pointer;
box-shadow: 4px 12px 48px 0 rgba(0, 0, 0, 0.11);
transition: box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.info-content-text img:hover {
box-shadow: 4px 12px 48px 0 rgba(0, 0, 0, 0.35);
} }
.info-content-text table { .info-content-text table {

View File

@@ -70,23 +70,6 @@ export default {
onMounted(() => { onMounted(() => {
vditorInstance.value = createVditor(editorId.value, { vditorInstance.value = createVditor(editorId.value, {
placeholder: '输入消息...', placeholder: '输入消息...',
height: 150,
toolbar: [
'emoji',
'bold',
'italic',
'strike',
'link',
'|',
'list',
'|',
'line',
'quote',
'code',
'inline-code',
'|',
'upload',
],
preview: { preview: {
actions: [], actions: [],
markdown: { toc: false }, markdown: { toc: false },
@@ -149,11 +132,17 @@ export default {
border-radius: 8px; border-radius: 8px;
} }
.vditor {
min-height: 50px;
max-height: 150px;
}
.message-bottom-container { .message-bottom-container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-end; justify-content: flex-end;
padding: 10px; margin-top: 10px;
margin-bottom: 10px;
background-color: var(--bg-color-soft); background-color: var(--bg-color-soft);
border-top: 1px solid var(--border-color); border-top: 1px solid var(--border-color);
border-bottom-left-radius: 8px; border-bottom-left-radius: 8px;

View File

@@ -1,5 +1,11 @@
<template> <template>
<div class="chat-container" :class="{ float: isFloatMode }"> <div class="chat-container" :class="{ float: isFloatMode }">
<vue-easy-lightbox
:visible="lightboxVisible"
:index="lightboxIndex"
:imgs="lightboxImgs"
@hide="lightboxVisible = false"
/>
<div v-if="!loading" class="chat-header"> <div v-if="!loading" class="chat-header">
<div class="header-main"> <div class="header-main">
<div class="back-button" @click="goBack"> <div class="back-button" @click="goBack">
@@ -14,7 +20,7 @@
</div> </div>
</div> </div>
<div class="messages-list" ref="messagesListEl"> <div class="messages-list" ref="messagesListEl" @click="handleContentClick">
<div v-if="loading" class="loading-container"> <div v-if="loading" class="loading-container">
<l-hatch size="28" stroke="4" speed="3.5" color="var(--primary-color)"></l-hatch> <l-hatch size="28" stroke="4" speed="3.5" color="var(--primary-color)"></l-hatch>
</div> </div>
@@ -101,7 +107,7 @@ import {
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { getToken, fetchCurrentUser } from '~/utils/auth' import { getToken, fetchCurrentUser } from '~/utils/auth'
import { toast } from '~/main' import { toast } from '~/main'
import { renderMarkdown, stripMarkdownLength } from '~/utils/markdown' import { renderMarkdown, stripMarkdownLength, handleMarkdownClick } from '~/utils/markdown'
import MessageEditor from '~/components/MessageEditor.vue' import MessageEditor from '~/components/MessageEditor.vue'
import ReactionsGroup from '~/components/ReactionsGroup.vue' import ReactionsGroup from '~/components/ReactionsGroup.vue'
import { useWebSocket } from '~/composables/useWebSocket' import { useWebSocket } from '~/composables/useWebSocket'
@@ -110,6 +116,7 @@ import { useChannelsUnreadCount } from '~/composables/useChannelsUnreadCount'
import TimeManager from '~/utils/time' import TimeManager from '~/utils/time'
import BaseTimeline from '~/components/BaseTimeline.vue' import BaseTimeline from '~/components/BaseTimeline.vue'
import BasePlaceholder from '~/components/BasePlaceholder.vue' import BasePlaceholder from '~/components/BasePlaceholder.vue'
import VueEasyLightbox from 'vue-easy-lightbox'
const config = useRuntimeConfig() const config = useRuntimeConfig()
const route = useRoute() const route = useRoute()
@@ -135,6 +142,9 @@ const isFloatMode = computed(() => route.query.float !== undefined)
const floatRoute = useState('messageFloatRoute') const floatRoute = useState('messageFloatRoute')
const replyTo = ref(null) const replyTo = ref(null)
const newMessagesCount = ref(0) const newMessagesCount = ref(0)
const lightboxVisible = ref(false)
const lightboxIndex = ref(0)
const lightboxImgs = ref([])
const isUserNearBottom = ref(true) const isUserNearBottom = ref(true)
function updateNearBottom() { function updateNearBottom() {
@@ -451,6 +461,17 @@ function minimize() {
navigateTo('/') navigateTo('/')
} }
function handleContentClick(e) {
handleMarkdownClick(e)
if (e.target.tagName === 'IMG') {
const container = e.target.parentNode
const imgs = [...container.querySelectorAll('img')].map((i) => i.src)
lightboxImgs.value = imgs
lightboxIndex.value = imgs.indexOf(e.target.src)
lightboxVisible.value = true
}
}
function openUser(id) { function openUser(id) {
if (isFloatMode.value) { if (isFloatMode.value) {
// 先不处理... // 先不处理...