diff --git a/web/src/features/contacts/AddFriendModal.tsx b/web/src/features/contacts/AddFriendModal.tsx
index 3a58ba96..38325b3a 100644
--- a/web/src/features/contacts/AddFriendModal.tsx
+++ b/web/src/features/contacts/AddFriendModal.tsx
@@ -47,7 +47,7 @@ export function AddFriendModal({ onClose, onSent, initialTarget }: AddFriendModa
// Tracks HOW `selected` was populated so the eventual sendFriendRequest can report the real
// provenance instead of always claiming "search" -- NewFriendsView's own SOURCE_LABEL map has a
// dedicated "扫码添加" entry for the qr case that was otherwise dead/unreachable.
- const [selectedSource, setSelectedSource] = useState<'search' | 'qr'>('search');
+ const [selectedSource, setSelectedSource] = useState<'search' | 'phone' | 'qr'>('search');
const [message, setMessage] = useState('');
const [error, setError] = useState('');
const [sent, setSent] = useState(false);
@@ -194,9 +194,9 @@ export function AddFriendModal({ onClose, onSent, initialTarget }: AddFriendModa
key={action.label}
type="button"
onClick={action.onClick}
- className="flex flex-col items-center gap-1.5 rounded-lg bg-surface-input py-3 text-xs text-text-secondary"
+ className="flex items-center justify-center gap-2 rounded-lg bg-surface-input py-3 text-xs text-text-secondary"
>
-
+
{action.label}
))}
@@ -208,6 +208,13 @@ export function AddFriendModal({ onClose, onSent, initialTarget }: AddFriendModa
{searchQuery.isLoading ? (
搜索中…
+ ) : searchQuery.isError ? (
+
+ 搜索失败,请重试
+
+
) : !searchQuery.data?.items.length ? (
未找到相关用户
) : (
@@ -220,7 +227,12 @@ export function AddFriendModal({ onClose, onSent, initialTarget }: AddFriendModa
type="button"
disabled={!selectable}
onClick={() => {
- setSelectedSource('search');
+ // `searchType` (already computed above from the query itself) is the real
+ // signal for which channel actually found this person -- NewFriendsView's
+ // own SOURCE_LABEL table already has a `phone` entry ("通过手机号搜索")
+ // that this path never reached because every search result was tagged
+ // 'search' regardless of how it was found.
+ setSelectedSource(searchType === 'phone' ? 'phone' : 'search');
setSelected(item);
}}
className="flex items-center gap-3 rounded-lg px-2 py-2 text-left disabled:opacity-70"
@@ -231,7 +243,7 @@ export function AddFriendModal({ onClose, onSent, initialTarget }: AddFriendModa
{item.public_account ?
ID: {item.public_account} : null}
{selectable ? (
-
+
{isSelected ? '已选择' : '选择'}
) : (
diff --git a/web/src/features/contacts/BlocklistView.tsx b/web/src/features/contacts/BlocklistView.tsx
index 544b7658..cce84d6b 100644
--- a/web/src/features/contacts/BlocklistView.tsx
+++ b/web/src/features/contacts/BlocklistView.tsx
@@ -103,6 +103,13 @@ export function BlocklistView() {
{query.isLoading ? (
加载中…
+ ) : query.isError ? (
+
+ 加载失败,请重试
+
+
) : items.length === 0 ? (
黑名单是空的
) : (
diff --git a/web/src/features/contacts/ContactsListColumn.tsx b/web/src/features/contacts/ContactsListColumn.tsx
index 40b6f8d6..20bda27c 100644
--- a/web/src/features/contacts/ContactsListColumn.tsx
+++ b/web/src/features/contacts/ContactsListColumn.tsx
@@ -65,7 +65,7 @@ export function ContactsListColumn() {