fix: compact chat subpage typography

This commit is contained in:
AI Bot
2026-06-05 10:53:54 +08:00
parent eb8961fc3f
commit 9807c7a275
10 changed files with 148 additions and 40 deletions

View File

@@ -1145,6 +1145,7 @@ public final class BossUi {
TextView kindView = new TextView(context);
kindView.setText(kindLabel);
kindView.setTextSize(11);
kindView.setIncludeFontPadding(false);
kindView.setTypeface(Typeface.DEFAULT_BOLD);
kindView.setTextColor(context.getColor(outgoing ? R.color.boss_surface : R.color.boss_text_muted));
kindView.setPadding(0, 0, 0, dp(context, 6));
@@ -1154,7 +1155,8 @@ public final class BossUi {
TextView bodyView = new TextView(context);
bodyView.setText(BossMarkdown.render(context, body, outgoing));
bodyView.setTextSize(14);
bodyView.setLineSpacing(0f, 1.34f);
bodyView.setIncludeFontPadding(false);
bodyView.setLineSpacing(0f, 1.26f);
bodyView.setTextColor(context.getColor(outgoing ? R.color.boss_surface : R.color.boss_text_primary));
bodyView.setMaxWidth(maxBubbleWidth);
bodyView.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
@@ -2275,6 +2277,7 @@ public final class BossUi {
String metaText = buildMessageMetaText(senderLabel, meta, outgoing);
metaView.setText(metaText);
metaView.setTextSize(11);
metaView.setIncludeFontPadding(false);
metaView.setTextColor(context.getColor(R.color.boss_text_soft));
metaView.setPadding(dp(context, 6), 0, dp(context, 6), dp(context, 4));
wrapper.addView(metaView);
@@ -2472,6 +2475,7 @@ public final class BossUi {
String metaText = buildMessageMetaText(senderLabel, meta, outgoing);
metaView.setText(metaText);
metaView.setTextSize(11);
metaView.setIncludeFontPadding(false);
metaView.setTextColor(context.getColor(R.color.boss_text_soft));
metaView.setPadding(dp(context, 6), 0, dp(context, 6), dp(context, 4));
wrapper.addView(metaView);

View File

@@ -1333,16 +1333,16 @@ public class ProjectDetailActivity extends BossScreenActivity {
private Button buildQuickActionButton(String label, boolean highlight) {
Button button = new Button(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, BossUi.dp(this, 40), 1f);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, BossUi.dp(this, 36), 1f);
if (quickActionsLayout.getChildCount() > 0) {
params.leftMargin = BossUi.dp(this, 8);
params.leftMargin = BossUi.dp(this, 6);
}
button.setLayoutParams(params);
button.setMinWidth(0);
button.setText(label);
button.setTextSize(14);
button.setTextSize(13);
button.setAllCaps(false);
button.setPadding(BossUi.dp(this, 12), 0, BossUi.dp(this, 12), 0);
button.setPadding(BossUi.dp(this, 10), 0, BossUi.dp(this, 10), 0);
button.setBackgroundResource(highlight ? R.drawable.bg_primary_button : R.drawable.bg_secondary_button);
button.setTextColor(getColor(highlight ? R.color.boss_surface : R.color.boss_text_primary));
return button;

View File

@@ -37,8 +37,11 @@
<TextView
android:id="@+id/screen_title"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="会话信息"
android:textColor="@color/boss_text_primary"
android:textSize="18sp"
@@ -46,9 +49,12 @@
<TextView
android:id="@+id/screen_subtitle"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="单线程会话信息页"
android:textColor="@color/boss_text_muted"
android:textSize="11sp" />

View File

@@ -37,8 +37,11 @@
<TextView
android:id="@+id/screen_title"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="标题"
android:textColor="@color/boss_text_primary"
android:textSize="18sp"
@@ -46,9 +49,12 @@
<TextView
android:id="@+id/screen_subtitle"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="副标题"
android:textColor="@color/boss_text_muted"
android:textSize="11sp" />

View File

@@ -37,8 +37,11 @@
<TextView
android:id="@+id/screen_title"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="发起群聊"
android:textColor="@color/boss_text_primary"
android:textSize="18sp"
@@ -46,9 +49,12 @@
<TextView
android:id="@+id/screen_subtitle"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="从当前会话选择其他线程"
android:textColor="@color/boss_text_muted"
android:textSize="11sp" />

View File

@@ -37,8 +37,11 @@
<TextView
android:id="@+id/screen_title"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="群资料"
android:textColor="@color/boss_text_primary"
android:textSize="18sp"
@@ -46,9 +49,12 @@
<TextView
android:id="@+id/screen_subtitle"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="群聊资料页"
android:textColor="@color/boss_text_muted"
android:textSize="11sp" />

View File

@@ -40,6 +40,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="项目详情"
android:textColor="@color/boss_text_primary"
@@ -48,9 +49,12 @@
<TextView
android:id="@+id/screen_subtitle"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="设备"
android:textColor="@color/boss_text_muted"
android:textSize="11sp" />
@@ -103,9 +107,9 @@
android:background="@color/boss_bg_app"
android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingTop="10dp"
android:paddingTop="8dp"
android:paddingRight="12dp"
android:paddingBottom="12dp">
android:paddingBottom="8dp">
<LinearLayout
android:id="@+id/project_chat_quick_actions"
@@ -137,15 +141,15 @@
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/project_chat_scroll_bottom"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_gravity="bottom|left"
android:layout_marginLeft="12dp"
android:layout_marginBottom="12dp"
android:background="@drawable/bg_chat_scroll_bottom_button"
android:contentDescription="回到底部"
android:elevation="8dp"
android:padding="12dp"
android:padding="11dp"
android:scaleType="center"
android:src="@drawable/ic_boss_arrow_down"
android:tint="@color/boss_text_primary"
@@ -173,18 +177,18 @@
android:gravity="bottom"
android:orientation="horizontal"
android:paddingLeft="12dp"
android:paddingTop="10dp"
android:paddingTop="8dp"
android:paddingRight="12dp"
android:paddingBottom="12dp">
android:paddingBottom="10dp">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/project_chat_attach"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="8dp"
android:background="@drawable/bg_secondary_button"
android:contentDescription="发送附件"
android:padding="12dp"
android:padding="10dp"
android:scaleType="center"
android:src="@drawable/ic_boss_add"
android:tint="@color/boss_text_primary" />
@@ -199,23 +203,25 @@
android:hint="输入消息"
android:inputType="textCapSentences|textMultiLine"
android:maxLines="4"
android:minHeight="44dp"
android:paddingLeft="14dp"
android:paddingTop="10dp"
android:paddingRight="14dp"
android:paddingBottom="10dp"
android:minHeight="40dp"
android:paddingLeft="12dp"
android:paddingTop="8dp"
android:paddingRight="12dp"
android:paddingBottom="8dp"
android:textColor="@color/boss_text_primary"
android:textColorHint="@color/boss_text_muted" />
android:textColorHint="@color/boss_text_muted"
android:textSize="14sp" />
<Button
android:id="@+id/project_chat_send"
android:layout_width="72dp"
android:layout_height="44dp"
android:layout_width="68dp"
android:layout_height="40dp"
android:layout_marginLeft="8dp"
android:background="@drawable/bg_primary_button"
android:text="发送"
android:textAllCaps="false"
android:textColor="@color/boss_surface"
android:textSize="13sp"
android:textStyle="bold" />
</LinearLayout>
@@ -227,32 +233,34 @@
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="12dp"
android:paddingTop="10dp"
android:paddingTop="8dp"
android:paddingRight="12dp"
android:paddingBottom="12dp"
android:paddingBottom="10dp"
android:visibility="gone">
<Button
android:id="@+id/project_chat_multi_copy"
android:layout_width="0dp"
android:layout_height="44dp"
android:layout_height="40dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:background="@drawable/bg_secondary_button"
android:text="复制"
android:textAllCaps="false"
android:textColor="@color/boss_text_primary"
android:textSize="13sp"
android:textStyle="bold" />
<Button
android:id="@+id/project_chat_multi_forward"
android:layout_width="0dp"
android:layout_height="44dp"
android:layout_height="40dp"
android:layout_weight="1"
android:background="@drawable/bg_primary_button"
android:text="转发"
android:textAllCaps="false"
android:textColor="@color/boss_surface"
android:textSize="13sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>

View File

@@ -40,6 +40,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="标题"
android:textColor="@color/boss_text_primary"
@@ -52,6 +53,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:ellipsize="end"
android:includeFontPadding="false"
android:maxLines="1"
android:text="副标题"
android:textColor="@color/boss_text_muted"

View File

@@ -1,5 +1,7 @@
package com.hyzq.boss;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.content.Context;
@@ -38,4 +40,28 @@ public class BossUiMessageBubbleTest {
assertTrue(bodyView.getText().toString().contains("重点"));
assertTrue(bodyView.getText().toString().contains("代码"));
}
@Test
public void buildMessageBubble_usesWechatCompactTextMetrics() {
Context context = RuntimeEnvironment.getApplication();
LinearLayout wrapper = BossUi.buildMessageBubble(
context,
"线程",
"这是一条普通对话内容",
"10:26",
false,
"结果"
);
TextView metaView = (TextView) wrapper.getChildAt(0);
LinearLayout bubble = (LinearLayout) wrapper.getChildAt(1);
TextView kindView = (TextView) bubble.getChildAt(0);
TextView bodyView = (TextView) bubble.getChildAt(1);
assertFalse("消息时间/发送人不应保留默认字体留白", metaView.getIncludeFontPadding());
assertFalse("消息类型标签不应保留默认字体留白", kindView.getIncludeFontPadding());
assertFalse("消息正文不应保留默认字体留白", bodyView.getIncludeFontPadding());
assertEquals("消息正文应对标微信聊天正文", 14f, bodyView.getTextSize() / context.getResources().getDisplayMetrics().scaledDensity, 0.5f);
}
}

View File

@@ -12,6 +12,7 @@ import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.content.res.ColorStateList;
import android.graphics.drawable.GradientDrawable;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -47,6 +48,49 @@ import java.util.function.BooleanSupplier;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 34)
public class ProjectDetailActivityUiTest {
@Test
public void chatSubpageTypographyUsesWechatCompactSizing() {
Intent intent = new Intent()
.putExtra(ProjectDetailActivity.EXTRA_PROJECT_ID, "project-1")
.putExtra(ProjectDetailActivity.EXTRA_PROJECT_NAME, "北区试产线回归");
TestProjectDetailActivity activity = Robolectric
.buildActivity(TestProjectDetailActivity.class, intent)
.setup()
.get();
LinearLayout topBar = activity.findViewById(R.id.screen_top_bar);
TextView title = activity.findViewById(R.id.screen_title);
TextView subtitle = activity.findViewById(R.id.screen_subtitle);
LinearLayout quickActions = activity.findViewById(R.id.project_chat_quick_actions);
ImageButton attachButton = activity.findViewById(R.id.project_chat_attach);
EditText input = activity.findViewById(R.id.project_chat_input);
Button sendButton = activity.findViewById(R.id.project_chat_send);
ReflectionHelpers.callInstanceMethod(activity, "renderQuickActions");
assertEquals("聊天子页面顶部栏左侧留白应和首页一致", BossUi.dp(activity, 16), topBar.getPaddingLeft());
assertFalse("聊天子页面标题不应保留 TextView 默认额外字体留白", title.getIncludeFontPadding());
assertFalse("聊天子页面副标题不应保留 TextView 默认额外字体留白", subtitle.getIncludeFontPadding());
assertEquals("聊天子页面标题不应换行撑高顶部栏", 1, title.getMaxLines());
assertEquals("聊天子页面副标题不应换行撑高顶部栏", 1, subtitle.getMaxLines());
assertEquals("聊天子页面副标题过长时应单行省略", TextUtils.TruncateAt.END, subtitle.getEllipsize());
assertEquals("聊天子页面标题应对标微信页面标题", 18f, title.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
assertEquals("聊天子页面副标题应对标微信辅助说明", 11f, subtitle.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
assertTrue("聊天子页面应渲染项目目标/版本记录按钮", quickActions.getChildCount() >= 2);
Button goalsButton = (Button) quickActions.getChildAt(0);
Button versionsButton = (Button) quickActions.getChildAt(1);
assertEquals("聊天子页面快捷按钮高度不应继续使用旧的大按钮", BossUi.dp(activity, 36), goalsButton.getLayoutParams().height);
assertEquals("聊天子页面快捷按钮文字应对标微信按钮字号", 13f, goalsButton.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
assertEquals("聊天子页面快捷按钮高度应统一", BossUi.dp(activity, 36), versionsButton.getLayoutParams().height);
assertEquals("聊天输入附件按钮不应继续使用 48dp 大图标", BossUi.dp(activity, 40), attachButton.getLayoutParams().width);
assertEquals("聊天输入附件按钮不应继续使用 48dp 大图标", BossUi.dp(activity, 40), attachButton.getLayoutParams().height);
assertTrue("聊天输入框最小高度不应继续撑大底部输入区", input.getMinHeight() <= BossUi.dp(activity, 40));
assertEquals("聊天输入框字号应和微信输入区一致", 14f, input.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
assertEquals("发送按钮高度应和输入框一致", BossUi.dp(activity, 40), sendButton.getLayoutParams().height);
assertEquals("发送按钮字号应对标微信按钮字号", 13f, sendButton.getTextSize() / activity.getResources().getDisplayMetrics().scaledDensity, 0.5f);
}
@Test
public void typingAtInComposerShowsAgentMentionSuggestions() {
Intent intent = new Intent()
@@ -486,8 +530,8 @@ public class ProjectDetailActivityUiTest {
assertTrue(attachView instanceof ImageButton);
ViewGroup.LayoutParams params = attachView.getLayoutParams();
assertTrue(params.width >= BossUi.dp(activity, 46));
assertTrue(params.height >= BossUi.dp(activity, 46));
assertEquals(BossUi.dp(activity, 40), params.width);
assertEquals(BossUi.dp(activity, 40), params.height);
}
@Test
@@ -517,8 +561,8 @@ public class ProjectDetailActivityUiTest {
assertTrue((params.gravity & Gravity.LEFT) == Gravity.LEFT || (params.gravity & Gravity.START) == Gravity.START);
assertEquals(BossUi.dp(activity, 12), params.leftMargin);
assertTrue(params.bottomMargin >= BossUi.dp(activity, 12));
assertEquals(BossUi.dp(activity, 48), params.width);
assertEquals(BossUi.dp(activity, 48), params.height);
assertEquals(BossUi.dp(activity, 44), params.width);
assertEquals(BossUi.dp(activity, 44), params.height);
int baselineScrollCount = activity.scrollChatToBottomCount;
shortcutView.performClick();