Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Claude Code Review

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
# Optional: Only run on specific file changes
# paths:
# - "src/**/*.ts"
# - "src/**/*.tsx"
# - "src/**/*.js"
# - "src/**/*.jsx"

jobs:
claude-review:
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'

runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options

50 changes: 50 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read

# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
# prompt: 'Update the pull request description to include a summary of changes.'

# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr *)'

12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 0.21.0

Special thanks to [@PawiX25](https://github.com/PawiX25) for the new widget!

### New features

* Added summary home screen widget showing monthly income and expenses by [@PawiX25](https://github.com/PawiX25)

### Fixes

* [Android] Two Entry Last now shows the correct buttons, fixed by [@PawiX25](https://github.com/PawiX25)

## 0.20.0

### New features
Expand Down
10 changes: 10 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@
android:name="android.appwidget.provider"
android:resource="@xml/four_entry_widget_info" />
</receiver>
<receiver
android:name=".glance.SummaryReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/summary_widget_info" />
</receiver>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
Expand Down
144 changes: 144 additions & 0 deletions android/app/src/main/kotlin/mn/flow/flow/glance/Summary.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package mn.flow.flow.glance

import es.antonborri.home_widget.HomeWidgetGlanceState
import es.antonborri.home_widget.HomeWidgetGlanceStateDefinition
import android.content.Context
import android.content.Intent
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.GlanceTheme
import androidx.glance.action.clickable
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.SizeMode
import androidx.glance.appwidget.action.actionStartActivity
import androidx.glance.appwidget.cornerRadius
import androidx.glance.appwidget.provideContent
import androidx.glance.background
import androidx.glance.currentState
import androidx.glance.layout.Alignment
import androidx.glance.layout.Box
import androidx.glance.layout.Column
import androidx.glance.layout.Row
import androidx.glance.layout.Spacer
import androidx.glance.layout.fillMaxSize
import androidx.glance.layout.fillMaxWidth
import androidx.glance.layout.height
import androidx.glance.layout.padding
import androidx.glance.layout.width
import androidx.glance.preview.ExperimentalGlancePreviewApi
import androidx.glance.preview.Preview
import androidx.glance.state.GlanceStateDefinition
import androidx.glance.ColorFilter
import androidx.glance.Image
import androidx.glance.ImageProvider
import androidx.glance.text.FontWeight
import androidx.glance.text.Text
import androidx.glance.text.TextStyle
import androidx.glance.unit.ColorProvider
import mn.flow.flow.MainActivity
import mn.flow.flow.R

class Summary : GlanceAppWidget() {
override val sizeMode = SizeMode.Exact

override val stateDefinition: GlanceStateDefinition<*>
get() = HomeWidgetGlanceStateDefinition()

override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
GlanceTheme {
Content(context, currentState())
}
}
}
}

@OptIn(ExperimentalGlancePreviewApi::class)
@Composable
@Preview(widthDp = 200, heightDp = 100)
private fun Content(context: Context, currentState: HomeWidgetGlanceState) {
val income = currentState.preferences.getString("summaryIncome", null) ?: "---"
val expense = currentState.preferences.getString("summaryExpense", null) ?: "---"
val incomeLabel = currentState.preferences.getString("summaryIncomeLabel", null) ?: "Income"
val expenseLabel = currentState.preferences.getString("summaryExpenseLabel", null) ?: "Expense"

Box(
modifier = GlanceModifier
.background(GlanceTheme.colors.widgetBackground)
.fillMaxSize()
.clickable(
onClick = actionStartActivity(
Intent(context, MainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
)
),
contentAlignment = Alignment.Center
) {
Row(
modifier = GlanceModifier.padding(8.dp).fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
) {
Box(modifier = GlanceModifier.defaultWeight()) {
SummaryCard(
label = incomeLabel,
iconRes = R.drawable.ic_arrow_down_forward,
amount = income,
accentColor = ColorProvider(R.color.income_green),
)
}
Spacer(modifier = GlanceModifier.width(8.dp))
Box(modifier = GlanceModifier.defaultWeight()) {
SummaryCard(
label = expenseLabel,
iconRes = R.drawable.ic_arrow_up_forward,
amount = expense,
accentColor = ColorProvider(R.color.expense_red),
)
}
}
}
}

@Composable
private fun SummaryCard(label: String, iconRes: Int, amount: String, accentColor: ColorProvider) {
Box(
modifier = GlanceModifier
.fillMaxWidth()
.background(GlanceTheme.colors.surfaceVariant)
.cornerRadius(16.dp)
.padding(horizontal = 16.dp, vertical = 12.dp),
) {
Column {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = label,
style = TextStyle(
color = GlanceTheme.colors.onSurfaceVariant,
fontSize = 13.sp,
),
)
Spacer(modifier = GlanceModifier.width(4.dp))
Image(
provider = ImageProvider(iconRes),
contentDescription = null,
modifier = GlanceModifier.width(20.dp).height(20.dp),
colorFilter = ColorFilter.tint(accentColor),
)
}
Spacer(modifier = GlanceModifier.height(4.dp))
Text(
text = amount,
style = TextStyle(
color = GlanceTheme.colors.onSurface,
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
),
maxLines = 1,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package mn.flow.flow.glance

import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver

class SummaryReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = Summary()
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class TwoEntryLast : GlanceAppWidget() {
@Composable
@Preview(widthDp = 100, heightDp = 50)
private fun Content(context: Context, currentState: HomeWidgetGlanceState) {
val buttonOrder = FlowWidgetUtils.getButtonOrder(currentState.preferences).subList(0, 2)
val buttonOrder = FlowWidgetUtils.getButtonOrder(currentState.preferences).takeLast(2)

val size = LocalSize.current
val buttonSize = min((size.width / 2 - 24.dp), (size.height - 16.dp))
Expand Down
9 changes: 9 additions & 0 deletions android/app/src/main/res/drawable/ic_arrow_down_forward.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="M480,647 L636,492 Q647,481 663.5,480.5 Q680,480 692,492 Q703,503 703,520 Q703,537 692,548 L537,703 Q514,726 480,726 Q446,726 423,703 L268,548 Q257,537 256.5,520.5 Q256,504 268,492 Q279,481 296,481 Q313,481 324,492 Z M480,407 L636,252 Q647,241 663.5,240.5 Q680,240 692,252 Q703,263 703,280 Q703,297 692,308 L537,463 Q514,486 480,486 Q446,486 423,463 L268,308 Q257,297 256.5,280.5 Q256,264 268,252 Q279,241 296,241 Q313,241 324,252 Z"
android:fillColor="#FFFFFF" />
</vector>
9 changes: 9 additions & 0 deletions android/app/src/main/res/drawable/ic_arrow_up_forward.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="M480,553 L324,708 Q313,719 296.5,719.5 Q280,720 268,708 Q257,697 257,680 Q257,663 268,652 L423,497 Q446,474 480,474 Q514,474 537,497 L692,652 Q703,663 703.5,679.5 Q704,696 692,708 Q681,719 664,719 Q647,719 636,708 Z M480,313 L324,468 Q313,479 296.5,479.5 Q280,480 268,468 Q257,457 257,440 Q257,423 268,412 L423,257 Q446,234 480,234 Q514,234 537,257 L692,412 Q703,423 703.5,439.5 Q704,456 692,468 Q681,479 664,479 Q647,479 636,468 Z"
android:fillColor="#FFFFFF" />
</vector>
5 changes: 5 additions & 0 deletions android/app/src/main/res/values-night/widget_colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="income_green">#FF32CC70</color>
<color name="expense_red">#FFFF4040</color>
</resources>
5 changes: 5 additions & 0 deletions android/app/src/main/res/values/widget_colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="income_green">#FF32CC70</color>
<color name="expense_red">#FFFF4040</color>
</resources>
10 changes: 10 additions & 0 deletions android/app/src/main/res/xml/summary_widget_info.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="Flow Summary"
android:minWidth="180dp"
android:minHeight="55dp"
android:targetCellWidth="3"
android:targetCellHeight="1"
android:resizeMode="horizontal"
android:initialLayout="@layout/glance_default_loading_layout">
</appwidget-provider>
1 change: 1 addition & 0 deletions ios/Flow Widgets/LeBundle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ import SwiftUI
struct LeBundle: WidgetBundle {
var body: some Widget {
FlowTwoEntryWidget()
FlowSummaryWidget()
}
}
Loading
Loading