美化pagetype详情页评论活动时间线
This commit is contained in:
parent
40fd8e1ed3
commit
013f899f75
@ -28,16 +28,6 @@
|
||||
:disabled="submitting"
|
||||
@keydown.enter.exact="handleAddComment"
|
||||
/>
|
||||
<n-button
|
||||
size="small"
|
||||
type="primary"
|
||||
:disabled="!commentText.trim() || submitting"
|
||||
:loading="submitting"
|
||||
@click="handleAddComment"
|
||||
class="comment-submit-btn"
|
||||
>
|
||||
{{ t('Send') }}
|
||||
</n-button>
|
||||
</div>
|
||||
|
||||
<!-- Timeline 列表 -->
|
||||
@ -53,8 +43,8 @@
|
||||
</div>
|
||||
<div class="timeline-dot" v-else></div>
|
||||
<div class="timeline-content" :class="{ 'is-card': item.isCard }">
|
||||
<span v-html="item.content"></span>
|
||||
<span v-if="!item.hideTimestamp" class="timeline-time">{{ relativeTime(item.creation) }}</span>
|
||||
<div class="timeline-content-text" v-html="item.content"></div>
|
||||
<div v-if="!item.hideTimestamp" class="timeline-time">{{ relativeTime(item.creation) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -234,7 +224,9 @@ function buildTimelineItems() {
|
||||
for (const a of info.attachment_logs || []) {
|
||||
const isUpload = a.comment_type === 'Attachment'
|
||||
const isSelf = a.owner === currentUser.value
|
||||
const fileName = a.content || ''
|
||||
const rawContent = a.content || ''
|
||||
// 后端 content 可能自带"已移除"/"Added"等前缀,只提取文件名部分
|
||||
const fileName = rawContent.replace(/^(已移除|Added|Removed)\s*/i, '')
|
||||
const uploadMsg = isSelf ? t('You attached {0}', [fileName]) : `<strong>${a.owner}</strong> ${t('attached {0}', [fileName])}`
|
||||
const removeMsg = isSelf ? t('You removed attachment {0}', [fileName]) : `<strong>${a.owner}</strong> ${t('removed attachment {0}', [fileName])}`
|
||||
items.push({
|
||||
@ -382,45 +374,49 @@ watch(() => [props.entity, props.id], () => {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Comment input */
|
||||
/* Comment input - 无发送按钮,Enter 发送 */
|
||||
.comment-input-area {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.comment-input-area :deep(.n-input) {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.comment-submit-btn {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Timeline */
|
||||
/* ===== Timeline 时间线 - 现代风格 ===== */
|
||||
.timeline-items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
/* 时间线串联竖线 - 参考旧版 timeline.scss .new-timeline:before */
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
.timeline-items::before {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
left: 13px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border-left: 2px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
padding: 8px 0;
|
||||
padding: 6px 0;
|
||||
position: relative;
|
||||
/* 竖线通过每个 item 的伪元素实现,更精确控制起止 */
|
||||
}
|
||||
|
||||
/* 时间线串联竖线 - 每个 item 左侧有一条竖线连接上下 */
|
||||
.timeline-item::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 13px; /* 28px badge 中心 = 14px,稍微偏移留出视觉间隙 */
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 2px;
|
||||
background: #e5e7eb;
|
||||
}
|
||||
|
||||
/* 第一个 item:竖线从图标中心开始 */
|
||||
.timeline-item:first-child::before {
|
||||
top: 20px; /* 从 badge 中心向下 */
|
||||
}
|
||||
|
||||
/* 最后一个 item:竖线到图标中心结束 */
|
||||
.timeline-item:last-child::before {
|
||||
bottom: calc(100% - 20px); /* 到 badge 中心向上 */
|
||||
}
|
||||
|
||||
.timeline-badge {
|
||||
@ -435,6 +431,8 @@ watch(() => [props.entity, props.id], () => {
|
||||
color: #6b7280;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
/* 微妙的阴影增加层次感 */
|
||||
box-shadow: 0 0 0 2px #fff;
|
||||
}
|
||||
|
||||
.timeline-dot {
|
||||
@ -454,13 +452,20 @@ watch(() => [props.entity, props.id], () => {
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #d1d5db;
|
||||
box-shadow: 0 0 0 2px #fff;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
flex: 1;
|
||||
font-size: 13px;
|
||||
color: #374151;
|
||||
line-height: 1.5;
|
||||
line-height: 1.6;
|
||||
padding: 2px 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.timeline-content-text {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.timeline-content.is-card {
|
||||
@ -470,10 +475,22 @@ watch(() => [props.entity, props.id], () => {
|
||||
padding: 10px 14px;
|
||||
}
|
||||
|
||||
.timeline-content.is-card .timeline-content-text {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
color: #9ca3af;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
margin-top: 2px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.timeline-content.is-card .timeline-time {
|
||||
margin-top: 4px;
|
||||
border-top: 1px solid #f3f4f6;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.timeline-empty {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user