收敛玻璃边缘并清理图标库旧界面
This commit is contained in:
1 parent
594f47bf3b
commit
8f5923556d
7 files changed
+65
-217
No files matched your search
@@ -166,7 +166,15 @@ private fun ServerCard(server: EmbyServer, tint: Color, onClick: () -> Unit, onC
|
||||
var clicked by remember { mutableStateOf(false) }
|
||||
val pressBg by animateColorAsState(targetValue = if (clicked) LumaColors.glassHighlight.copy(alpha = 0.24f) else Color.Transparent, animationSpec = tween(durationMillis = if (clicked) 80 else 200), label = "pb")
|
||||
LaunchedEffect(clicked) { if (clicked) { delay(150); clicked = false } }
|
||||
GlassSurface(modifier = Modifier.clickable(interactionSource = remember { MutableInteractionSource() }, indication = null) { clicked = true; onClick() }, cornerRadius = 20.dp, padding = PaddingValues(0.dp)) {
|
||||
GlassSurface(
|
||||
modifier = Modifier.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
role = Role.Button,
|
||||
) { clicked = true; onClick() },
|
||||
cornerRadius = 20.dp,
|
||||
padding = PaddingValues(0.dp),
|
||||
) {
|
||||
Row(modifier = Modifier.fillMaxWidth().background(pressBg).padding(14.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.weight(1f)) {
|
||||
if (server.iconUrl.isNotBlank()) {
|
||||
@@ -204,7 +212,11 @@ private fun ServerCard(server: EmbyServer, tint: Color, onClick: () -> Unit, onC
|
||||
Modifier
|
||||
.size(48.dp)
|
||||
.onGloballyPositioned(onMorePositioned)
|
||||
.clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) { onMoreClick() },
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
role = Role.Button,
|
||||
) { onMoreClick() },
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
LumaIconView(LumaIcon.More, contentDescription = stringResource(Res.string.server_actions), tint = GlassTokens.subtext, modifier = Modifier.size(24.dp))
|
||||
@@ -222,7 +234,15 @@ private fun ServerGridCard(server: EmbyServer, tint: Color, onClick: () -> Unit,
|
||||
var clicked by remember { mutableStateOf(false) }
|
||||
val pressBg by animateColorAsState(targetValue = if (clicked) LumaColors.glassHighlight.copy(alpha = 0.24f) else Color.Transparent, animationSpec = tween(durationMillis = if (clicked) 80 else 200), label = "pb")
|
||||
LaunchedEffect(clicked) { if (clicked) { delay(150); clicked = false } }
|
||||
GlassSurface(modifier = Modifier.clickable(interactionSource = remember { MutableInteractionSource() }, indication = null) { clicked = true; onClick() }, cornerRadius = 20.dp, padding = PaddingValues(0.dp)) {
|
||||
GlassSurface(
|
||||
modifier = Modifier.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
role = Role.Button,
|
||||
) { clicked = true; onClick() },
|
||||
cornerRadius = 20.dp,
|
||||
padding = PaddingValues(0.dp),
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth().background(pressBg).padding(14.dp), horizontalAlignment = Alignment.Start) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
if (server.iconUrl.isNotBlank()) {
|
||||
@@ -265,7 +285,11 @@ private fun ServerGridCard(server: EmbyServer, tint: Color, onClick: () -> Unit,
|
||||
Modifier
|
||||
.size(48.dp)
|
||||
.onGloballyPositioned(onMorePositioned)
|
||||
.clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) { onMoreClick() },
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
role = Role.Button,
|
||||
) { onMoreClick() },
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
LumaIconView(LumaIcon.More, contentDescription = stringResource(Res.string.server_actions), tint = GlassTokens.subtext, modifier = Modifier.size(24.dp))
|
||||
@@ -518,7 +542,11 @@ internal fun IconLibraryManagerScreenContent(
|
||||
Box(Modifier.width(86.dp)) {
|
||||
Box(
|
||||
Modifier.size(48.dp)
|
||||
.clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) { onBack() },
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
role = Role.Button,
|
||||
) { onBack() },
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Box(
|
||||
@@ -538,7 +566,11 @@ internal fun IconLibraryManagerScreenContent(
|
||||
Modifier
|
||||
.heightIn(min = 48.dp)
|
||||
.lumaGlass(radius = 20.dp, level = com.example.myapplication.ui.design.LumaGlassLevel.Interactive)
|
||||
.clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) { showAddDialog = true }
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
role = Role.Button,
|
||||
) { showAddDialog = true }
|
||||
.padding(horizontal = 10.dp, vertical = 7.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(3.dp),
|
||||
@@ -631,7 +663,12 @@ private fun IconLibraryManagerCard(library: IconLibrary, onClick: () -> Unit) {
|
||||
Box(
|
||||
Modifier.fillMaxWidth()
|
||||
.lumaGlass(radius = LumaShapes.large, level = com.example.myapplication.ui.design.LumaGlassLevel.Regular)
|
||||
.clickable(interactionSource = remember { MutableInteractionSource() }, indication = null, onClick = onClick)
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
role = Role.Button,
|
||||
onClick = onClick,
|
||||
)
|
||||
.padding(14.dp),
|
||||
) {
|
||||
Column {
|
||||
@@ -708,204 +745,6 @@ private fun IconLibraryManagerCard(library: IconLibrary, onClick: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun IconLibrarySection(
|
||||
libraries: List<IconLibrary>,
|
||||
isGrid: Boolean,
|
||||
onClick: (IconLibrary) -> Unit,
|
||||
onManage: (IconLibrary) -> Unit,
|
||||
) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(stringResource(Res.string.icon_lib_section_title), fontSize = 15.sp, fontWeight = FontWeight.Bold, color = GlassTokens.text)
|
||||
Text(stringResource(Res.string.icon_count_unit, libraries.size), fontSize = 13.sp, color = GlassTokens.subtext)
|
||||
}
|
||||
if (isGrid) {
|
||||
// Grid layout for icon libraries — use Column+Row to avoid nested scrolling
|
||||
Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
libraries.chunked(2).forEach { row ->
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
row.forEach { lib ->
|
||||
IconLibraryCard(
|
||||
library = lib,
|
||||
modifier = Modifier.weight(1f),
|
||||
onClick = { onClick(lib) },
|
||||
onLongClick = { onManage(lib) },
|
||||
)
|
||||
}
|
||||
// Fill remaining space if odd number
|
||||
if (row.size < 2) {
|
||||
Spacer(Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// List layout for icon libraries — use Row to avoid nested scrolling
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
libraries.forEach { lib ->
|
||||
IconLibraryCard(
|
||||
library = lib,
|
||||
modifier = Modifier.width(140.dp),
|
||||
onClick = { onClick(lib) },
|
||||
onLongClick = { onManage(lib) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun IconLibraryCard(
|
||||
library: IconLibrary,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.lumaGlass(radius = 18.dp, level = LumaGlassLevel.Regular)
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = onClick,
|
||||
)
|
||||
.padding(12.dp),
|
||||
) {
|
||||
Column {
|
||||
// Icon preview row
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy((-6).dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
library.icons.take(3).forEach { icon ->
|
||||
Box(
|
||||
Modifier.size(30.dp).clip(RoundedCornerShape(8.dp))
|
||||
.lumaGlass(radius = 8.dp, level = LumaGlassLevel.Clear, shadowElevation = 0.dp, tint = Color(0xFFFF8A65).copy(alpha = 0.18f)),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
LumaAsyncImage(
|
||||
model = ImageRequest.Builder(LocalContext.current).data(icon.url).crossfade(true).build(),
|
||||
contentDescription = icon.name,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier.size(24.dp).clip(RoundedCornerShape(6.dp)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(library.name, fontSize = 13.sp, fontWeight = FontWeight.SemiBold, color = GlassTokens.text, maxLines = 1, overflow = TextOverflow.Ellipsis)
|
||||
Text(stringResource(Res.string.icon_count_suffix, library.iconCount), fontSize = 11.sp, color = GlassTokens.subtext)
|
||||
Spacer(Modifier.height(6.dp))
|
||||
// Manage button
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.lumaGlass(radius = 10.dp, level = LumaGlassLevel.Interactive, tint = LumaColors.accentSoft, borderColor = GlassTokens.accent.copy(alpha = 0.2f))
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = onLongClick,
|
||||
)
|
||||
.padding(vertical = 6.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Text(stringResource(Res.string.icon_lib_manage), fontSize = 12.sp, fontWeight = FontWeight.Medium, color = GlassTokens.accent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Icon Library Detail Dialog — browse icons */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
@Composable
|
||||
private fun IconLibraryDetailDialog(library: IconLibrary, backdrop: Backdrop? = null, onDismiss: () -> Unit) {
|
||||
GlassDialog(backdrop = backdrop, onDismissRequest = onDismiss, modifier = Modifier.width(340.dp)) {
|
||||
Box(Modifier.fillMaxWidth()) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
// Header
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Box(
|
||||
Modifier.size(36.dp).clip(RoundedCornerShape(10.dp))
|
||||
.background(Brush.linearGradient(listOf(Color(0xFFFF6B9D), Color(0xFFFF8A65)))),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
LumaIconView(LumaIcon.Library, contentDescription = null, tint = Color.White, modifier = Modifier.size(20.dp))
|
||||
}
|
||||
Spacer(Modifier.width(12.dp))
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(library.name, fontWeight = FontWeight.Bold, fontSize = 18.sp, color = GlassTokens.text)
|
||||
Text(stringResource(Res.string.icon_count_suffix, library.iconCount), fontSize = 12.sp, color = GlassTokens.subtext)
|
||||
}
|
||||
}
|
||||
|
||||
if (library.iconCount > 0 && library.icons.isEmpty()) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.lumaGlass(radius = 16.dp, level = LumaGlassLevel.Clear)
|
||||
.padding(vertical = 36.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) { Text(stringResource(Res.string.icon_lib_not_loaded), color = GlassTokens.subtext, fontSize = 14.sp) }
|
||||
} else if (library.icons.isEmpty()) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.lumaGlass(radius = 16.dp, level = LumaGlassLevel.Clear)
|
||||
.padding(vertical = 36.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) { Text(stringResource(Res.string.icon_lib_no_icons), color = GlassTokens.subtext, fontSize = 14.sp) }
|
||||
} else {
|
||||
Box(
|
||||
Modifier.fillMaxWidth()
|
||||
.lumaGlass(radius = 16.dp, level = LumaGlassLevel.Clear)
|
||||
.padding(8.dp)
|
||||
) {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(5),
|
||||
modifier = Modifier.heightIn(min = 120.dp, max = 400.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
items(library.icons) { icon ->
|
||||
Box(
|
||||
modifier = Modifier.aspectRatio(1f)
|
||||
.lumaGlass(radius = 10.dp, level = LumaGlassLevel.Clear, shadowElevation = 0.dp)
|
||||
.padding(4.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
LumaAsyncImage(
|
||||
model = ImageRequest.Builder(LocalContext.current).data(icon.url).crossfade(true).build(),
|
||||
contentDescription = icon.name,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier.fillMaxSize().clip(RoundedCornerShape(8.dp)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close button
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.lumaGlass(radius = 16.dp, level = LumaGlassLevel.Interactive)
|
||||
.clickable { onDismiss() }
|
||||
.padding(vertical = 14.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) { Text(stringResource(Res.string.icon_lib_close), color = GlassTokens.subtext, fontSize = 15.sp, fontWeight = FontWeight.Medium) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Manage Icon Library Dialog — rename, refresh, delete */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
@@ -440,7 +440,7 @@ fun LiquidGlassPopupOverlay(
|
||||
} else {
|
||||
Color.White.copy(alpha = 0.20f)
|
||||
}
|
||||
val border = if (GlassTokens.isDark) Color.White.copy(alpha = 0.24f) else Color.White.copy(alpha = 0.62f)
|
||||
val border = GlassTokens.glassBorder
|
||||
|
||||
Box(modifier.fillMaxSize().zIndex(20f)) {
|
||||
Box(
|
||||
@@ -476,7 +476,7 @@ fun LiquidGlassPopupOverlay(
|
||||
depthEffect = true,
|
||||
)
|
||||
},
|
||||
highlight = { Highlight.Plain },
|
||||
highlight = { Highlight.Plain.copy(alpha = 0.58f) },
|
||||
shadow = { Shadow(alpha = 0.18f) },
|
||||
onDrawSurface = { drawRect(surface) },
|
||||
)
|
||||
|
||||
@@ -129,7 +129,7 @@ object LumaColors {
|
||||
val floatingTint: Color
|
||||
get() = if (isDark) Color(0xFF1B2430).copy(alpha = 0.62f) else Color.White.copy(alpha = 0.30f)
|
||||
val glassBorder: Color
|
||||
get() = if (isDark) Color.White.copy(alpha = 0.16f) else Color(0xFFB7C3D0).copy(alpha = 0.42f)
|
||||
get() = if (isDark) Color.White.copy(alpha = 0.16f) else Color(0xFFB7C3D0).copy(alpha = 0.30f)
|
||||
val glassHighlight: Color
|
||||
get() = if (isDark) Color.White.copy(alpha = 0.07f) else Color.White.copy(alpha = 0.24f)
|
||||
val glassShadow: Color
|
||||
@@ -203,10 +203,10 @@ fun Modifier.lumaFallbackGlass(
|
||||
val edge = if (light) {
|
||||
Color.White.copy(
|
||||
alpha = when {
|
||||
liquidFallback && selected -> 0.86f
|
||||
liquidFallback -> 0.70f
|
||||
selected -> 0.78f
|
||||
else -> 0.64f
|
||||
liquidFallback && selected -> 0.62f
|
||||
liquidFallback -> 0.48f
|
||||
selected -> 0.64f
|
||||
else -> 0.52f
|
||||
},
|
||||
)
|
||||
} else {
|
||||
@@ -222,10 +222,10 @@ fun Modifier.lumaFallbackGlass(
|
||||
val topHighlight = if (light) {
|
||||
Color.White.copy(
|
||||
alpha = when {
|
||||
liquidFallback && selected -> 0.42f
|
||||
liquidFallback -> 0.30f
|
||||
selected -> 0.32f
|
||||
else -> 0.22f
|
||||
liquidFallback && selected -> 0.34f
|
||||
liquidFallback -> 0.24f
|
||||
selected -> 0.28f
|
||||
else -> 0.18f
|
||||
},
|
||||
)
|
||||
} else {
|
||||
@@ -337,7 +337,7 @@ fun Modifier.lumaGlass(
|
||||
)
|
||||
}
|
||||
},
|
||||
highlight = if (highlight) ({ Highlight.Plain.copy(alpha = 0.75f) }) else null,
|
||||
highlight = if (highlight) ({ Highlight.Plain.copy(alpha = 0.58f) }) else null,
|
||||
shadow = { Shadow(alpha = spec.shadowAlpha) },
|
||||
onDrawSurface = { drawRect(surfaceTint) },
|
||||
)
|
||||
|
||||
@@ -21,3 +21,9 @@
|
||||
文件变更: ui/design/LumaDesignSystem.kt、ui/design/LumaComponents.kt、ui/design/LumaIcons.kt、screens/SettingsScreen.kt、screens/SettingsChildScreens.kt、values/strings.xml、values-en/strings.xml。
|
||||
教训: 全局材质状态必须进入 remember key;真实液态玻璃仍需在实体 GPU 上验证。
|
||||
标签: #lumaplayer #glass-mode #design-system #accessibility
|
||||
|
||||
[PROJECT:lumaplayer] 玻璃边缘与资源库遗留 UI 清理
|
||||
结论: 降低原生/降级玻璃的白边和高光强度,删除无引用的旧图标库展示实现,保留当前独立管理页;完整构建和资源库操作回归通过。
|
||||
文件变更: ui/design/LumaDesignSystem.kt、ui/LiquidGlass.kt、screens/LibraryScreen.kt。
|
||||
教训: 清理前以全仓库引用结果确认目标确实未被活动页面使用。
|
||||
标签: #lumaplayer #liquid-glass #library #cleanup
|
||||
@@ -12,3 +12,4 @@
|
||||
- 最新改动:播放器进度条改为自绘可访问 SeekBar,媒体首页、Vision 收藏和搜索加载态改为统一骨架占位;移除未使用的 Material 图标依赖,完整 Debug/Lint/Unit 通过。
|
||||
- 最新校验:修复降级玻璃高光覆盖内容、首页滚动状态恢复与重复详情/播放器导航;Debug/Lint/Unit 和 API35 模拟器启动回归成功。
|
||||
- 最新校验:修复玻璃模式切换后的 Backdrop/source 与材质缓存刷新;设置页行组件、分组标题和子页返回栏统一;Debug/Lint/Unit 与 API35 模拟器液态↔毛玻璃切换回归成功。
|
||||
- 最新收敛:降低统一玻璃边缘高光/白边,清理 `LibraryScreen` 无引用的旧图标库 UI;资源库列表/网格切换回归无崩溃。
|
||||
@@ -22,3 +22,4 @@
|
||||
- 中:降级玻璃的边缘高光应在 `drawContent()` 之前绘制;否则公共玻璃容器中的文字和图标会被高光层洗白。
|
||||
- 高:用户明确要求真实液态玻璃时,不能继续保留设备/模拟器安全门;当前仅保留 API 31+ 能力判断,底栏原生 Backdrop 必须先绘制容器与选中胶囊,再绘制清晰图标/文字,避免内容被二次采样覆盖。该取舍需在实体机 GPU 上继续验证 RenderThread 稳定性。
|
||||
- 中:玻璃模式是全局 Compose 状态;涉及 `rememberLayerBackdrop` 或玻璃规格的缓存必须把 `AppTheme.glassMode` 纳入重建边界,否则设置副标题会变但材质不变。
|
||||
- 低:清理页面遗留实现前必须用全仓库引用检索确认;私有且无调用的旧 UI 可以删除,活动页面保留原数据/弹窗实现。
|
||||
@@ -40,3 +40,4 @@
|
||||
- 2026-08-28:继续收尾降级 UI;修复 fallback 高光绘制顺序,首页接入可保存滚动状态,详情/播放器导航启用 `launchSingleTop` 防重复 Push,详情刷新和剧集加载异常进入已有错误态;`assembleDebug`、`lintDebug`、`testDebugUnitTest` 及 API35 模拟器启动回归成功。
|
||||
- 2026-08-28:按需求取消液态玻璃设备/模拟器安全门,API 31+ 液态模式直接进入 Kyant Backdrop 原生路径;底栏改为玻璃底层、选中胶囊、清晰内容的正确绘制顺序,主图标 40dp、搜索图标 44dp、文字 8sp;补充媒体卡片加载/成功/失败三态和统一按压反馈。`assembleDebug`、`lintDebug`、`testDebugUnitTest` 及 API35 模拟器液态/毛玻璃切换回归成功,未发现 RenderThread 崩溃。
|
||||
- 2026-08-28:修复玻璃模式切换时 `LayerBackdrop` 与 `GlassSpec` 缓存未刷新问题;新增 `LumaSettingRow`、`LumaPageTopBar`、设置分组标题并补齐公共按钮语义。完整 Debug/Lint/Unit 成功,API35 模拟器切换液态→毛玻璃→液态成功且无 RenderThread 崩溃;参考素材仍未提交。
|
||||
- 2026-08-28:收敛原生/降级玻璃边缘高光与白边,清理 `LibraryScreen` 中确认无引用的旧图标库 Section/Card/DetailDialog,并为资源库主要操作补充按钮语义;Debug/Lint/Unit 成功,模拟器资源库列表/网格切换无崩溃。
|
||||
Reference in new issue
Block a user