@@ -10,6 +10,14 @@ struct ClaudeUsageWidget: View {
1010 usageManager. usageData. fiveHourPercentage
1111 }
1212
13+ private var weeklyRemaining : Double {
14+ max ( 0 , min ( 1 , 1 - usageManager. usageData. weeklyPercentage) )
15+ }
16+
17+ private var claudeOrange : Color {
18+ Color ( red: 0.89 , green: 0.45 , blue: 0.29 )
19+ }
20+
1321 private var ringColor : Color {
1422 if percentage >= 0.8 { return . red }
1523 if percentage >= 0.6 { return . orange }
@@ -26,10 +34,7 @@ struct ClaudeUsageWidget: View {
2634 . animation ( . easeOut( duration: 0.3 ) , value: percentage)
2735 }
2836
29- Image ( " ClaudeIcon " )
30- . resizable ( )
31- . scaledToFit ( )
32- . frame ( width: 16 , height: 16 )
37+ drainableIcon
3338 }
3439 . frame ( width: 28 , height: 28 )
3540 . foregroundStyle ( . foregroundOutside)
@@ -58,4 +63,29 @@ struct ClaudeUsageWidget: View {
5863 usageManager. startUpdating ( config: configProvider. config)
5964 }
6065 }
66+
67+ private var drainableIcon : some View {
68+ let iconSize : CGFloat = 16
69+
70+ return ZStack {
71+ Image ( " ClaudeIcon " )
72+ . resizable ( )
73+ . renderingMode ( . template)
74+ . scaledToFit ( )
75+ . foregroundStyle ( . white)
76+ . frame ( width: iconSize, height: iconSize)
77+
78+ Rectangle ( )
79+ . fill ( claudeOrange)
80+ . frame ( width: iconSize, height: iconSize * weeklyRemaining)
81+ . frame ( width: iconSize, height: iconSize, alignment: . bottom)
82+ . animation ( . easeOut( duration: 0.8 ) , value: weeklyRemaining)
83+ . mask (
84+ Image ( " ClaudeIcon " )
85+ . resizable ( )
86+ . scaledToFit ( )
87+ . frame ( width: iconSize, height: iconSize)
88+ )
89+ }
90+ }
6191}
0 commit comments