From a74299d7160d82267f6a2ebbea2ce9c597ac9645 Mon Sep 17 00:00:00 2001
From: Sakurasan <26715255+Sakurasan@users.noreply.github.com>
Date: Mon, 28 Sep 2026 22:39:06 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BE=A7=E6=A0=8F=E3=80=8C=E6=9C=80=E8=BF=91?=
=?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=80=8D=EF=BC=9A=E7=9F=AD=E6=96=87=E6=98=BE?=
=?UTF-8?q?=E7=A4=BA=E6=AD=A3=E6=96=87=E6=91=98=E5=BD=95=EF=BC=88=E8=B4=B4?=
=?UTF-8?q?=E9=93=BE=E6=8E=A5=E7=9A=84=E5=9B=9E=E9=80=80=E5=88=B0=E5=8D=A1?=
=?UTF-8?q?=E7=89=87=E6=A0=87=E9=A2=98=E3=80=81=E7=BA=AF=E5=9B=BE=E6=98=BE?=
=?UTF-8?q?=E7=A4=BA=E5=8D=A0=E4=BD=8D=EF=BC=89+=20=E9=85=8D=E5=9B=BE?=
=?UTF-8?q?=E7=9F=AD=E6=96=87=E5=B8=A6=2034px=20=E7=BC=A9=E7=95=A5?=
=?UTF-8?q?=E5=9B=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
frontend/src/components/RightRail.vue | 63 ++++++++++++++++++++++++---
1 file changed, 56 insertions(+), 7 deletions(-)
diff --git a/frontend/src/components/RightRail.vue b/frontend/src/components/RightRail.vue
index fc8fb52..71d5a89 100644
--- a/frontend/src/components/RightRail.vue
+++ b/frontend/src/components/RightRail.vue
@@ -3,7 +3,7 @@ import { computed, onMounted, ref } from 'vue'
import { publicApi } from '../api'
import { site } from '../site'
import { socialIcon } from '../socialIcons'
-import { relativeDate } from '../utils'
+import { relativeDate, stripTags, thumbURL } from '../utils'
// vivid 是单栏布局,右栏整体不渲染(省掉 latest/tags 两次请求)。
const isVivid = computed(() => site.ui_id === 'vivid')
@@ -27,6 +27,26 @@ const links = [
const latest = ref([])
const tags = ref([])
+// 短文没有标题,侧栏拿正文开头当标识(flomo/Twitter 的做法),
+// 纯图片短文显示占位;有配图时右侧带一张小缩略图。
+const EXCERPT_LEN = 22
+function excerpt(p) {
+ if (p.kind !== 'short') return p.title || '无题'
+ // 先剥 :贴链接的短文开头是 URL 本身,摘出来没有信息量;
+ // 剥完没字了(纯链接贴)就退到链接卡片的标题
+ const noLinks = (p.content_html || '').replace(/]*>[\s\S]*?<\/a>/gi, ' ')
+ const text = stripTags(noLinks).replace(/\s+/g, ' ').trim()
+ if (text) return text.length > EXCERPT_LEN ? text.slice(0, EXCERPT_LEN) + '…' : text
+ if (p.link_card && p.link_card.title) {
+ const t = p.link_card.title
+ return t.length > EXCERPT_LEN ? t.slice(0, EXCERPT_LEN) + '…' : t
+ }
+ return p.images && p.images.length ? '📷 图片' : '短文'
+}
+function thumbOf(p) {
+ return p.kind === 'short' && p.images && p.images.length ? thumbURL(p.images[0], 160) : ''
+}
+
onMounted(async () => {
if (isVivid.value) return
try {
@@ -52,12 +72,22 @@ onMounted(async () => {
最近更新
-
-
-
- {{ p.kind === 'short' ? '短文' : p.title || '无题' }}
- 短
+
+
+
+ {{ excerpt(p) }}
+ 短
+
+ {{ relativeDate(p.published_at) }}
- {{ relativeDate(p.published_at) }}
+
@@ -152,7 +182,9 @@ onMounted(async () => {
}
.row {
- display: block;
+ display: flex;
+ align-items: center;
+ gap: 10px;
padding: 7px 0;
border-bottom: 1px dashed var(--line-soft);
}
@@ -161,10 +193,27 @@ onMounted(async () => {
border-bottom: 0;
}
+/* 文字列吃满剩余宽度,缩略图固定在右 */
+.row-main {
+ flex: 1;
+ min-width: 0;
+}
+
.title {
display: block;
font-size: 14px;
line-height: 1.7;
+ overflow-wrap: anywhere;
+}
+
+.thumb {
+ flex: 0 0 auto;
+ width: 34px;
+ height: 34px;
+ object-fit: cover;
+ border-radius: 6px;
+ background: var(--card);
+ border: 1px solid var(--line-soft);
}
.badge {