v1.14: usage history chart + threshold notifications
Add an in-app 7-day history chart and opt-in usage alerts, the two features requested from the macOS Claude-Usage-Tracker that map cleanly to an Android widget app. History: - UsageSnapshot model; PreferencesManager records session/weekly utilization on every refresh (7-day retention, <=600 points, collapses readings under 2 min apart to avoid worker+manual double-logging). - HistoryChartView: dependency-free Canvas line chart (session/weekly, 0/50/100% gridlines), breaks the line across >35-min gaps. - New HISTORY card with chart + legend. Notifications: - Notifier posts when session/weekly crosses a user threshold, at most once per limit window (keyed on reset-epoch, re-arms on rollover). - USAGE ALERTS card: enable switch + session/weekly sliders (50-100%, defaults 90/85). POST_NOTIFICATIONS permission + runtime request. - Wired into the existing 5-min background worker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -229,6 +229,137 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- History card -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/widget_background"
|
||||
android:padding="20dp"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="HISTORY"
|
||||
android:textColor="#888888"
|
||||
android:textSize="11sp"
|
||||
android:letterSpacing="0.1" />
|
||||
|
||||
<me.khodak.claudeusage.HistoryChartView
|
||||
android:id="@+id/historyChart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="140dp"
|
||||
android:layout_marginTop="12dp" />
|
||||
|
||||
<!-- Legend -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="3dp"
|
||||
android:background="#CC785C" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="Session"
|
||||
android:textColor="#AAAAAA"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="3dp"
|
||||
android:background="#7B8FCC" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:text="Weekly"
|
||||
android:textColor="#AAAAAA"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Notifications card -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/widget_background"
|
||||
android:padding="20dp"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="USAGE ALERTS"
|
||||
android:textColor="#888888"
|
||||
android:textSize="11sp"
|
||||
android:letterSpacing="0.1" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/switchNotify"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSessionThreshLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="14dp"
|
||||
android:text="Session alert at 90%"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderSession"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="50"
|
||||
android:valueTo="100"
|
||||
android:stepSize="5"
|
||||
android:value="90" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWeeklyThreshLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="Weekly alert at 85%"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/sliderWeekly"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="50"
|
||||
android:valueTo="100"
|
||||
android:stepSize="5"
|
||||
android:value="85" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnRefresh"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
Reference in New Issue
Block a user