Skip to content

Commit b991c96

Browse files
committed
更新:添加 v5.9 发布说明,包含 UI 升级、体验优化及问题修复
1 parent a80930e commit b991c96

7 files changed

Lines changed: 156 additions & 29 deletions

File tree

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
workflow_dispatch:
88
inputs:
99
version_tag:
10-
description: '版本标签 (例如: v5.2)'
10+
description: '版本标签 (例如: v5.9)'
1111
required: true
1212
type: string
1313

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
- **项目管理**:查看、创建、删除 Pages 项目
3232
- **部署管理**:查看部署历史和状态
3333
- **自定义域名**:管理 Pages 项目的自定义域名
34-
- **OkHttp 4.12.0**:+自签名 S3 API (R2) # 纯自实现,已移除 AWS SDK
3534

3635
### 🌐 路由和域管理
3736
- **路由绑定**:将 Worker 脚本绑定到指定域名路径
@@ -91,7 +90,7 @@ Jetpack 组件:
9190
网络层:
9291
├── Retrofit 2.9.0 # HTTP 客户端
9392
├── OkHttp 4.12.0 # 网络层 + 自签名 S3 API (R2)
94-
└──Gson 2.10.1 # JSON 解析
93+
└── Gson 2.10.1 # JSON 解析
9594
9695
依赖注入:
9796
└── Hilt 2.48 # 依赖注入框架

RELEASE_NOTES_v5.8.md

Lines changed: 0 additions & 18 deletions
This file was deleted.

RELEASE_NOTES_v5.9.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
### ✨ 新特性
2+
- **UI 升级**: 主界面标题栏全面适配 Material Design 3 风格,采用动态取色和胶囊样式账号选择器。
3+
- **体验优化**: 优化了深色模式下的文本显示,解决了部分界面文字看不清的问题。
4+
- **信息展示**: 标题栏现在支持同时显示当前账号和选中的域名信息。
5+
6+
### 🐛 问题修复
7+
- 修复了主界面编译错误。
8+
- 修复了首次启动时域名可能不显示的问题。
9+
- 修复了部分界面在深色模式下的适配问题。
10+
- 优化了账号切换时的交互体验。

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ android {
2020
applicationId = "com.muort.upworker"
2121
minSdk = 26
2222
targetSdk = 34
23-
versionCode = 2025122101
24-
versionName = "5.8"
23+
versionCode = 2025122201
24+
versionName = "5.9"
2525

2626
vectorDrawables {
2727
useSupportLibrary = true

app/src/main/java/com/muort/upworker/MainActivity.kt

Lines changed: 138 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
package com.muort.upworker
22

3+
import android.content.res.Configuration
4+
import android.graphics.PorterDuff
5+
import android.graphics.PorterDuffColorFilter
6+
import android.text.SpannableString
7+
import android.text.Spanned
8+
import android.text.style.RelativeSizeSpan
9+
import android.text.style.StyleSpan
310
import android.os.Bundle
11+
import android.util.TypedValue
412
import android.view.LayoutInflater
513
import androidx.activity.viewModels
614
import androidx.appcompat.app.AppCompatActivity
15+
import androidx.core.view.WindowCompat
716
import androidx.lifecycle.Lifecycle
817
import androidx.lifecycle.lifecycleScope
918
import androidx.lifecycle.repeatOnLifecycle
@@ -13,13 +22,15 @@ import androidx.navigation.ui.setupActionBarWithNavController
1322
import androidx.recyclerview.widget.LinearLayoutManager
1423
import com.google.android.material.dialog.MaterialAlertDialogBuilder
1524
import com.muort.upworker.core.model.Account
25+
import com.muort.upworker.core.model.Zone
1626
import com.muort.upworker.core.util.DataMigrationHelper
1727
import com.muort.upworker.core.util.MigrationResult
1828
import com.muort.upworker.core.util.showToast
1929
import com.muort.upworker.databinding.ActivityMainBinding
2030
import com.muort.upworker.databinding.DialogAccountSelectionBinding
2131
import com.muort.upworker.feature.account.AccountViewModel
2232
import dagger.hilt.android.AndroidEntryPoint
33+
import kotlinx.coroutines.flow.combine
2334
import kotlinx.coroutines.launch
2435
import timber.log.Timber
2536
import javax.inject.Inject
@@ -39,11 +50,92 @@ class MainActivity : AppCompatActivity() {
3950
setContentView(binding.root)
4051

4152
setupNavigation()
53+
configureSystemBars()
4254
setupAccountSelector()
4355
observeViewModel()
4456
performMigrationIfNeeded()
4557
}
4658

59+
private fun configureSystemBars() {
60+
// 1. 获取 MD3 颜色定义
61+
val typedValueContainer = TypedValue()
62+
// Surface Container (用于 Toolbar 背景)
63+
val hasContainer = theme.resolveAttribute(com.google.android.material.R.attr.colorSurfaceContainer, typedValueContainer, true)
64+
val colorSurfaceContainer = if (hasContainer) typedValueContainer.data else {
65+
val typedValueSurface = TypedValue()
66+
theme.resolveAttribute(com.google.android.material.R.attr.colorSurface, typedValueSurface, true)
67+
typedValueSurface.data
68+
}
69+
70+
// Secondary Container (用于账号选择器背景 - 胶囊样式)
71+
val typedValueSecContainer = TypedValue()
72+
theme.resolveAttribute(com.google.android.material.R.attr.colorSecondaryContainer, typedValueSecContainer, true)
73+
val colorSecondaryContainer = typedValueSecContainer.data
74+
75+
// On Secondary Container (用于账号选择器前景)
76+
val typedValueOnSecContainer = TypedValue()
77+
theme.resolveAttribute(com.google.android.material.R.attr.colorOnSecondaryContainer, typedValueOnSecContainer, true)
78+
val colorOnSecondaryContainer = typedValueOnSecContainer.data
79+
80+
// On Surface (用于 Toolbar 上的通用图标)
81+
val typedValueOnSurface = TypedValue()
82+
theme.resolveAttribute(com.google.android.material.R.attr.colorOnSurface, typedValueOnSurface, true)
83+
val colorOnSurface = typedValueOnSurface.data
84+
85+
// 2. 设置状态栏和 Toolbar 背景
86+
window.statusBarColor = colorSurfaceContainer
87+
binding.toolbar.setBackgroundColor(colorSurfaceContainer)
88+
binding.toolbar.setTitleTextColor(colorOnSurface)
89+
90+
// 3. Toolbar 样式调整:去阴影、居中
91+
(binding.toolbar as? com.google.android.material.appbar.MaterialToolbar)?.isTitleCentered = true
92+
binding.toolbar.elevation = 0f
93+
94+
// 4. 打造 "胶囊" (Chip) 样式的账号选择器
95+
// 创建圆角背景
96+
val chipBackground = android.graphics.drawable.GradientDrawable().apply {
97+
shape = android.graphics.drawable.GradientDrawable.RECTANGLE
98+
setColor(colorSecondaryContainer)
99+
cornerRadius = 100f // 大圆角
100+
}
101+
binding.selectAccountButton.background = chipBackground
102+
103+
// 增加内边距 (8dp vertical, 16dp horizontal)
104+
val density = resources.displayMetrics.density
105+
val paddingH = (16 * density).toInt()
106+
val paddingV = (6 * density).toInt()
107+
binding.selectAccountButton.setPadding(paddingH, paddingV, paddingH, paddingV)
108+
109+
// 5. 设置选择器内容颜色 (OnSecondaryContainer)
110+
val contentColorFilter = PorterDuffColorFilter(colorOnSecondaryContainer, PorterDuff.Mode.SRC_IN)
111+
112+
binding.currentAccountText.typeface = android.graphics.Typeface.DEFAULT_BOLD
113+
binding.currentAccountText.setTextColor(colorOnSecondaryContainer)
114+
binding.currentAccountText.isSingleLine = false
115+
binding.currentAccountText.maxLines = 2
116+
binding.currentAccountText.ellipsize = android.text.TextUtils.TruncateAt.END
117+
binding.currentAccountText.compoundDrawables.forEach { it?.mutate()?.colorFilter = contentColorFilter }
118+
binding.currentAccountText.compoundDrawablesRelative.forEach { it?.mutate()?.colorFilter = contentColorFilter }
119+
120+
(binding.selectAccountButton as? android.widget.TextView)?.let { textView ->
121+
textView.text = ""
122+
val icon = getDrawable(android.R.drawable.ic_menu_more)
123+
textView.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, icon, null)
124+
textView.setTextColor(colorOnSecondaryContainer)
125+
textView.compoundDrawables.forEach { it?.mutate()?.colorFilter = contentColorFilter }
126+
textView.compoundDrawablesRelative.forEach { it?.mutate()?.colorFilter = contentColorFilter }
127+
}
128+
129+
// 6. 设置 Toolbar 导航图标颜色 (OnSurface)
130+
val navColorFilter = PorterDuffColorFilter(colorOnSurface, PorterDuff.Mode.SRC_IN)
131+
binding.toolbar.navigationIcon?.mutate()?.colorFilter = navColorFilter
132+
binding.toolbar.overflowIcon?.mutate()?.colorFilter = navColorFilter
133+
134+
val isNightMode = (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) ==
135+
Configuration.UI_MODE_NIGHT_YES
136+
WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = !isNightMode
137+
}
138+
47139
private fun setupAccountSelector() {
48140
binding.selectAccountButton.setOnClickListener {
49141
showAccountSelectionDialog()
@@ -110,6 +202,14 @@ class MainActivity : AppCompatActivity() {
110202
)
111203

112204
setupActionBarWithNavController(navController, appBarConfiguration)
205+
206+
// 监听导航变化,确保返回按钮/菜单图标颜色在页面切换后依然正确
207+
navController.addOnDestinationChangedListener { _, _, _ ->
208+
val typedValue = TypedValue()
209+
theme.resolveAttribute(com.google.android.material.R.attr.colorOnSurface, typedValue, true)
210+
val colorOnSurface = typedValue.data
211+
binding.toolbar.navigationIcon?.mutate()?.colorFilter = PorterDuffColorFilter(colorOnSurface, PorterDuff.Mode.SRC_IN)
212+
}
113213
}
114214

115215
override fun onSupportNavigateUp(): Boolean {
@@ -122,12 +222,21 @@ class MainActivity : AppCompatActivity() {
122222
private fun observeViewModel() {
123223
lifecycleScope.launch {
124224
repeatOnLifecycle(Lifecycle.State.STARTED) {
225+
launch {
226+
combine(
227+
accountViewModel.defaultAccount,
228+
accountViewModel.selectedZone
229+
) { account, zone ->
230+
Pair(account, zone)
231+
}.collect { (account, zone) ->
232+
updateTitleBar(account, zone)
233+
}
234+
}
235+
125236
launch {
126237
accountViewModel.defaultAccount.collect { account ->
127238
account?.let {
128-
binding.currentAccountText.text = it.name
129-
} ?: run {
130-
binding.currentAccountText.text = "未选择账号"
239+
accountViewModel.loadZonesForAccount(it.id)
131240
}
132241
}
133242
}
@@ -141,6 +250,32 @@ class MainActivity : AppCompatActivity() {
141250
}
142251
}
143252

253+
private fun updateTitleBar(account: Account?, zone: Zone?) {
254+
if (account == null) {
255+
binding.currentAccountText.text = "未选择账号"
256+
return
257+
}
258+
259+
val accountName = account.name
260+
val zoneName = zone?.name
261+
262+
if (zoneName.isNullOrEmpty()) {
263+
binding.currentAccountText.text = accountName
264+
} else {
265+
val text = "$accountName\n$zoneName"
266+
val spannable = SpannableString(text)
267+
268+
// 设置域名部分为正常字体(非粗体)和小字号 (75%)
269+
val start = accountName.length + 1
270+
val end = text.length
271+
272+
spannable.setSpan(StyleSpan(android.graphics.Typeface.NORMAL), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
273+
spannable.setSpan(RelativeSizeSpan(0.75f), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
274+
275+
binding.currentAccountText.text = spannable
276+
}
277+
}
278+
144279
private fun showZoneSelectionDialog(account: Account) {
145280
val zones = accountViewModel.zones.value
146281
val selectedZone = accountViewModel.selectedZone.value

app/src/main/java/com/muort/upworker/feature/pages/PagesFragment.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.Intent
55
import android.graphics.Typeface
66
import android.net.Uri
77
import android.os.Bundle
8+
import android.util.TypedValue
89
import android.view.LayoutInflater
910
import android.view.View
1011
import android.view.ViewGroup
@@ -1351,9 +1352,9 @@ class PagesVariablesAndSecretsAdapter(
13511352
} else {
13521353
binding.variableValueText.text = value
13531354
binding.variableValueText.setTypeface(null, Typeface.NORMAL)
1354-
binding.variableValueText.setTextColor(
1355-
binding.root.context.getColor(android.R.color.black)
1356-
)
1355+
val typedValue = TypedValue()
1356+
binding.root.context.theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true)
1357+
binding.variableValueText.setTextColor(typedValue.data)
13571358
}
13581359

13591360
// Show type label

0 commit comments

Comments
 (0)