feat(widget): 增强Widget数据同步机制并优化UI设计
- 在useWaterData中统一处理数据变更后的Widget同步逻辑 - 新增数组类型数据存取方法支持更复杂数据结构 - 重构Widget UI为圆形进度条设计,提升视觉体验 - 修复数据同步时可能存在的竞态条件问题 - 优化错误处理,确保Widget同步失败不影响主功能
This commit is contained in:
@@ -84,63 +84,74 @@ struct WaterWidgetEntryView : View {
|
||||
var entry: Provider.Entry
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
VStack(spacing: 8) {
|
||||
// Header with title and add button
|
||||
HStack {
|
||||
Text("喝水")
|
||||
.font(.system(size: 14, weight: .medium))
|
||||
.foregroundColor(Color(red: 0.098, green: 0.129, blue: 0.149))
|
||||
HStack() {
|
||||
Text("饮水")
|
||||
.font(.system(size: 13, weight: .semibold))
|
||||
.foregroundColor(Color(red: 0.2, green: 0.2, blue: 0.2))
|
||||
|
||||
Spacer()
|
||||
|
||||
// Quick add water button
|
||||
Button(intent: AddWaterIntent(amount: entry.waterData.quickAddAmount)) {
|
||||
HStack(spacing: 2) {
|
||||
Text("+")
|
||||
Text("\(entry.waterData.quickAddAmount)ml")
|
||||
}
|
||||
.font(.system(size: 10, weight: .bold))
|
||||
.foregroundColor(Color(red: 0.388, green: 0.4, blue: 0.945))
|
||||
.padding(.horizontal, 6)
|
||||
.padding(.vertical, 5)
|
||||
.background(Color(red: 0.882, green: 0.906, blue: 1.0))
|
||||
.cornerRadius(16)
|
||||
Text("+\(entry.waterData.quickAddAmount)")
|
||||
.font(.system(size: 10, weight: .bold))
|
||||
.foregroundColor(.white)
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 5)
|
||||
.background(
|
||||
LinearGradient(
|
||||
gradient: Gradient(colors: [
|
||||
Color(red: 0.3, green: 0.7, blue: 1.0),
|
||||
Color(red: 0.2, green: 0.6, blue: 0.9)
|
||||
]),
|
||||
startPoint: .topLeading,
|
||||
endPoint: .bottomTrailing
|
||||
)
|
||||
)
|
||||
.cornerRadius(10)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
.padding(.bottom, 8)
|
||||
|
||||
Spacer()
|
||||
|
||||
// Progress visualization - simplified bar chart representation
|
||||
HStack(spacing: 2) {
|
||||
ForEach(0..<12, id: \.self) { index in
|
||||
RoundedRectangle(cornerRadius: 1)
|
||||
.fill(index < Int(entry.waterData.progressPercentage * 12) ?
|
||||
Color(red: 0.49, green: 0.827, blue: 0.988) :
|
||||
Color(red: 0.941, green: 0.976, blue: 1.0))
|
||||
.frame(width: 3, height: 12)
|
||||
// Main content - left right layout
|
||||
HStack(alignment: .center, spacing: 12) {
|
||||
// Left side - Progress circle
|
||||
ZStack {
|
||||
// Background circle
|
||||
Circle()
|
||||
.stroke(Color(red: 0.95, green: 0.95, blue: 0.95), lineWidth: 4)
|
||||
.frame(width: 45, height: 45)
|
||||
|
||||
// Progress circle
|
||||
Circle()
|
||||
.trim(from: 0, to: entry.waterData.progressPercentage)
|
||||
.stroke(
|
||||
LinearGradient(
|
||||
gradient: Gradient(colors: [
|
||||
Color(red: 0.3, green: 0.8, blue: 1.0),
|
||||
Color(red: 0.1, green: 0.6, blue: 0.9)
|
||||
]),
|
||||
startPoint: .topLeading,
|
||||
endPoint: .bottomTrailing
|
||||
),
|
||||
style: StrokeStyle(lineWidth: 4, lineCap: .round)
|
||||
)
|
||||
.frame(width: 45, height: 45)
|
||||
.rotationEffect(.degrees(-90))
|
||||
|
||||
// Progress percentage in center
|
||||
Text("\(Int(entry.waterData.progressPercentage * 100))%")
|
||||
.font(.system(size: 10, weight: .bold))
|
||||
.foregroundColor(Color(red: 0.3, green: 0.7, blue: 1.0))
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 8)
|
||||
|
||||
// Water intake stats
|
||||
HStack(alignment: .firstTextBaseline, spacing: 2) {
|
||||
Text("\(entry.waterData.currentIntake)")
|
||||
.font(.system(size: 14, weight: .semibold))
|
||||
.foregroundColor(Color(red: 0.098, green: 0.129, blue: 0.149))
|
||||
|
||||
Text("ml")
|
||||
.font(.system(size: 14, weight: .semibold))
|
||||
.foregroundColor(Color(red: 0.098, green: 0.129, blue: 0.149))
|
||||
|
||||
Text("/ \(entry.waterData.targetIntake)ml")
|
||||
.font(.system(size: 12))
|
||||
.foregroundColor(Color(red: 0.42, green: 0.447, blue: 0.502))
|
||||
}
|
||||
}
|
||||
.padding(16)
|
||||
.containerBackground(.fill.tertiary, for: .widget)
|
||||
.padding(12)
|
||||
.background(Color.white)
|
||||
.cornerRadius(16)
|
||||
.containerBackground(Color.clear, for: .widget)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user