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
8 changes: 6 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ android {
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = (100000000 + Instant.now().toEpochMilli() / 1000).toInt()
versionName = "1.9"
versionName = "1.9.1"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -68,6 +68,11 @@ android {
}
namespace = "ru.beryukhov.coffeegram"

configurations.configureEach {
exclude(group = "androidx.appcompat", module = "appcompat")
exclude(group = "androidx.appcompat", module = "appcompat-resources")
}

experimentalProperties["android.experimental.enableScreenshotTest"] = true

testOptions {
Expand All @@ -92,7 +97,6 @@ dependencies {
implementation(projects.dateTimeUtils)

implementation(libs.core.coreKtx)
implementation(libs.material)

implementation(libs.cmp.ui)
implementation(libs.cmp.material3)
Expand Down
4 changes: 1 addition & 3 deletions app/src/main/java/ru/beryukhov/coffeegram/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ import ru.beryukhov.coffeegram.model.ThemeStore
import ru.beryukhov.coffeegram.pages.LandingPage
import ru.beryukhov.coffeegram.screens.RootScreen
import ru.beryukhov.coffeegram.wearable.WearableSyncService
import kotlin.time.ExperimentalTime

@OptIn(ExperimentalTime::class)
class MainActivity : ComponentActivity() {

private val wearableSyncService by lazy { WearableSyncService(this) }
Expand All @@ -48,7 +46,7 @@ class MainActivity : ComponentActivity() {
themeStore = themeStore,
daysCoffeesStore = daysCoffeesStore,
showMap = showMap,
onAndroidStartWearableActivity = ::startWearableActivity,
onAndroidStartWearableActivity = if (BuildConfig.DEBUG) ::startWearableActivity else null,
onAndroidIconChange = { isSummer -> changeIcon(this, isSummer) },
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import ru.beryukhov.coffeegram.data.withEmpty
import ru.beryukhov.coffeegram.model.DaysCoffeesIntent
import ru.beryukhov.coffeegram.model.DaysCoffeesStore
import kotlin.time.Clock
import kotlin.time.ExperimentalTime

/**
* Bridge between Glance widget and Store pattern.
Expand All @@ -32,7 +31,6 @@ class DefaultWidgetDataBridge(
private val daysCoffeesStore: DaysCoffeesStore,
) : WidgetDataBridge {

@OptIn(ExperimentalTime::class)
private fun getCurrentDay() = Clock.System.todayIn(TimeZone.currentSystemDefault())

override fun getCurrentDayCupsCount(): Flow<Int> =
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/res/layout/widget_preview_row.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
android:layout_gravity="center_vertical"
android:text="@string/widget_preview_latte"
android:layout_marginStart="16dp"
android:textColor="?colorPrimary"
android:textColor="?android:attr/colorPrimary"
android:textSize="16sp"
android:layout_weight="1"
/>
Expand All @@ -33,7 +33,7 @@
android:padding="0dp"
android:text="-"
android:layout_marginStart="16dp"
android:textColor="?colorPrimary"
android:textColor="?android:attr/colorPrimary"
tools:ignore="HardcodedText" />

<TextView
Expand All @@ -44,7 +44,7 @@
android:textSize="20sp"
android:textStyle="bold"
android:layout_marginStart="16dp"
android:textColor="?colorSecondary"
android:textColor="?android:attr/colorAccent"
tools:ignore="HardcodedText" />

<Button
Expand All @@ -55,6 +55,6 @@
android:padding="0dp"
android:text="+"
android:layout_marginStart="16dp"
android:textColor="?colorPrimary"
android:textColor="?android:attr/colorPrimary"
tools:ignore="HardcodedText" />
</LinearLayout>
8 changes: 8 additions & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Kaffegram</string>
<string name="app_widget_title">Heutiger Kaffeekonsum</string>
<string name="app_widget_description">Schneller Zugriff auf die Kaffee-Nachverfolgung</string>
<string name="loading_widget">Widget wird geladen</string>
<string name="widget_preview_latte">Latte</string>
</resources>
8 changes: 8 additions & 0 deletions app/src/main/res/values-el/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Καφεγράμ</string>
<string name="app_widget_title">Σημερινή κατανάλωση καφέ</string>
<string name="app_widget_description">Γρήγορη πρόσβαση στην παρακολούθηση καφέ</string>
<string name="loading_widget">Φόρτωση widget</string>
<string name="widget_preview_latte">Λάτε</string>
</resources>
8 changes: 8 additions & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Cafégrаm</string>
<string name="app_widget_title">Consumo de café de hoy</string>
<string name="app_widget_description">Acceso rápido al seguimiento del café</string>
<string name="loading_widget">Widget de carga</string>
<string name="widget_preview_latte">Latte</string>
</resources>
10 changes: 1 addition & 9 deletions app/src/main/res/values-night/themes.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Coffeegram" parent="Theme.Material3.DayNight">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/brown_200</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
</style>
<style name="Theme.Coffeegram" parent="android:Theme.Material.NoActionBar" />
</resources>
8 changes: 8 additions & 0 deletions app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Кофеграм</string>
<string name="app_widget_title">Потребление кофе сегодня</string>
<string name="app_widget_description">Быстрый доступ к отслеживанию кофе</string>
<string name="loading_widget">Загрузка виджета</string>
<string name="widget_preview_latte">Латте</string>
</resources>
2 changes: 0 additions & 2 deletions app/src/main/res/values-v31/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@
<item name="android:windowSplashScreenBackground">@color/brown_500</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_splashscreen_logo_animated</item>
<item name="android:windowSplashScreenAnimationDuration">2147483647</item><!--Integer.MAX_VALUE-->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>
15 changes: 2 additions & 13 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
<resources>
<string name="app_name">Coffeegram</string>
<string name="calendar">Calendar</string>
<string name="stats">Stats</string>
<string name="settings">Settings</string>
<string name="map_short">Specialty</string>
<string name="add_drink">Drinks</string>
<string name="app_theme">App theme</string>
<string name="app_theme_system">System</string>
<string name="app_theme_light">Light</string>
<string name="app_theme_dark">Dark</string>
<string name="app_theme_dynamic">Dynamic</string>
<string name="app_theme_summer">Summer</string>

<string name="app_widget_title">Today\'s coffee consumption</string>
<string name="app_widget_description">Quick access to coffee tracking</string>
<string name="loading_widget">Loading widget</string>
<string name="stats_tab_all">All</string>
<string name="stats_tab_weekly">Weekly</string>
<string name="widget_preview_latte">Latte</string>
</resources>
10 changes: 5 additions & 5 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Widget.AppWidget.AppWidget.Container" parent="Theme.Material3.DynamicColors.DayNight">
<style name="Widget.AppWidget.AppWidget.Container" parent="android:Widget">
<item name="android:id">@android:id/background</item>
<item name="android:background">?colorSurface</item>
<item name="android:background">?android:attr/colorBackground</item>
<item name="android:padding">@dimen/appWidgetPadding</item>
</style>

<dimen name="appWidgetPadding">16dp</dimen>
<dimen name="appWidgetRadius">16dp</dimen>

<color name="appwidget_background">?colorSurface</color>
<color name="appwidget_background">?android:attr/colorBackground</color>

<!-- The themes below are only used for the preview layouts -->
<style name="Theme.AppWidget.AppWidgetContainer" parent="Theme.Material3.DynamicColors.DayNight"/>
<style name="Theme.AppWidget.AppWidgetContainer" parent="android:Theme.Material.Light"/>

</resources>
</resources>
12 changes: 1 addition & 11 deletions app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Coffeegram" parent="Theme.Material3.DayNight">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/brown_500</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
</style>
<style name="Theme.Coffeegram" parent="android:Theme.Material.Light.NoActionBar" />

<style name="Theme.Coffeegram.NoActionBar">
<item name="android:windowBackground">@drawable/background_splash</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>

</resources>
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
package ru.beryukhov.coffeegram.app_ui

import android.os.Build
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext

actual fun isCupertinoDefault(): Boolean = false

@Composable
actual fun dynamicColorSchemeOrNull(darkTheme: Boolean): ColorScheme? =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
} else {
null
}
4 changes: 0 additions & 4 deletions cmp-common/src/androidMain/res/values/strings.xml

This file was deleted.

Binary file not shown.
131 changes: 131 additions & 0 deletions cmp-common/src/commonMain/composeResources/font/FONTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Fonts

The four `.ttf` files in this directory are **merged builds**: each combines a brand
font (Fraunces / Plus Jakarta Sans / DM Mono) with a script-coverage donor for
Cyrillic and Greek. Compose Resources auto-generates `Res.font.<name>` for every file
here, so donor files are removed after merging — see [Reproducing the merges](#reproducing-the-merges).

## Files in use (referenced from `Theme.kt`)

| File | Family | Style | Weight | Size (B) | Glyphs | Latin¹ | Cyrillic² | Greek³ | Role |
|---|---|---|---:|---:|---:|---:|---:|---:|---|
| `Fraunces.ttf` | Fraunces | Regular | 900 | 455 072 | 1 475 | 388 | 132 | 322 | display serif (headlines, titles) |
| `Fraunces-Italic.ttf` | Fraunces | Italic | 900 | 479 528 | 1 475 | 388 | 132 | 322 | display serif italic |
| `PlusJakartaSans.ttf` | Plus Jakarta Sans | Regular | 400 | 191 076 | 908 | 380 | 104 | 75 | body / UI sans |
| `DMMono-Regular.ttf` | DM Mono | Regular | 400 | 163 728 | 978 | 343 | 98 | 77 | small body / numeric mono |

¹ codepoints `U+0000..U+024F` ² `U+0400..U+052F` ³ `U+0370..U+03FF` and `U+1F00..U+1FFF`

To restore a pre-merge original, fetch from git: `git log -- <path>` then
`git cat-file -p <blob>` (filenames matching pre-merge state may have been deleted, so
use `git rev-list --all --objects | grep <name>` to find the blob hash).

## Donors used in current merges

| File | Family | Style | Glyphs | Latin | Cyrillic | Greek | Weight | Paired with |
|---|---|---|---:|---:|---:|---:|---:|---|
| `Spectral-ExtraBold.ttf` | Spectral | ExtraBold | 878 | 381 | 128 | 3 | 800 | Fraunces |
| `Spectral-ExtraBoldItalic.ttf` | Spectral | ExtraBold Italic | 878 | 381 | 128 | 3 | 800 | Fraunces-Italic |
| `GFSDidot-Regular.ttf` | GFS Didot | Regular | 1104 | 332 | 4 | 322 | 400 | Fraunces (Greek)¹ |
| `Manrope-Regular.ttf` | Manrope | Regular | 678 | 316 | 104 | 75 | 400 | Plus Jakarta Sans |
| `JetBrainsMono-Regular.ttf` | JetBrains Mono | Regular | 976 | 343 | 98 | 77 | 400 | DM Mono |

Donor files are removed from this directory after merging (Compose Resources auto-packages
every `.ttf` here). Redownload from Google Fonts when re-merging.

¹ GFS Didot only ships in Regular (weight 400). Fraunces is pinned at weight 900 (Black)
so Greek letters render lighter than Latin/Cyrillic. Acceptable trade-off for the `el`
locale; to fix later, swap to a heavier Greek serif (e.g. GFS Bodoni Black or a Noto
Serif Greek heavy weight) and re-merge.

## Sources & licenses

All seven families are redistributed under the SIL Open Font License 1.1 (OFL). Merging
with `pyftmerge` and shipping the merged binary in this app is permitted; per OFL the
copyright/license notices must be preserved (kept inside each `.ttf`'s `name` table).
Do **not** rename the resulting family to imply it's an unmodified original.

- **Fraunces** — Undercase Type (Phaedra Charles, David Jonathan Ross). https://fonts.google.com/specimen/Fraunces
- **Plus Jakarta Sans** — Tokotype. https://fonts.google.com/specimen/Plus+Jakarta+Sans
- **DM Mono** — Colophon Foundry / Google. https://fonts.google.com/specimen/DM+Mono
- **Spectral** — Production Type. https://fonts.google.com/specimen/Spectral
- **GFS Didot** — Greek Font Society. https://fonts.google.com/specimen/GFS+Didot
- **Manrope** — Mikhail Sharanda. https://fonts.google.com/specimen/Manrope
- **JetBrains Mono** — JetBrains. https://www.jetbrains.com/lp/mono/

## Known caveats

1. **Variable fonts must be flattened first.** The original `Fraunces`, `Fraunces-Italic`,
and `PlusJakartaSans` upstream files are variable fonts; `pyftmerge` errors on VFs
(`VarStore has no attribute mergeMap`). Use `fontTools.varLib.instancer.instantiateVariableFont`
to bake them at the desired axis values first.
2. **UPEM mismatches must be reconciled.** `pyftmerge` requires identical
`head.unitsPerEm` across all inputs. Fraunces is 2000 UPEM; PT Serif / GFS Didot /
Spectral / Plus Jakarta Sans are 1000 UPEM; Manrope is 2000 UPEM. Use
`fontTools.ttLib.scaleUpem.scale_upem` on the donor before merging.
3. **Weight matching matters.** Fraunces is pinned at `wght=900` (Black), so its
Cyrillic donor must also be heavy or the scripts render at visibly different
weights. Spectral ExtraBold (800) is the closest available match. The Greek donor
GFS Didot is only Regular (400) — Greek currently renders lighter than Latin/Cyrillic;
acceptable for the small `el` locale audience, swap to a heavier Greek serif later
if it becomes a problem.
4. **First font wins on overlapping codepoints** — always list the brand font first.
`pyftmerge` keeps the GPOS/GSUB tables of the first font only, so donor-specific
kerning/ligatures for Cyrillic/Greek are dropped (usually invisible at body sizes).
5. **`U+2126` (Ohm sign) and `U+2206` (Increment)** were dropped from the Fraunces merges
because both Fraunces and GFS Didot define glyphs named `Omega`/`Delta`. The real
Greek letters Ω (`U+03A9`) and Δ (`U+0394`) are unaffected.

## Reproducing the merges

From inside this directory, with `fonttools` installed (`pip install fonttools`).
Donor files are needed in the working directory but should be deleted after merging.

```bash
PY=python3 # adjust if fonttools isn't on system python
PYFT=pyftmerge

# 1) Flatten Fraunces / PJS VFs to static instances at their current axis defaults.
$PY -c "
from fontTools.ttLib import TTFont
from fontTools.varLib.instancer import instantiateVariableFont
for fn, axes in [
('Fraunces.ttf', {'opsz': 9, 'wght': 900, 'SOFT': 0, 'WONK': 1}),
('Fraunces-Italic.ttf',{'opsz': 9, 'wght': 900, 'SOFT': 0, 'WONK': 1}),
('PlusJakartaSans.ttf',{'wght': 400}),
]:
instantiateVariableFont(TTFont(fn), axes).save(fn.replace('.ttf','-static.ttf'))
"

# 2) Rescale donors so they share UPEM with their base.
$PY -c "
from fontTools.ttLib import TTFont, scaleUpem
for fn, upem in [
('Spectral-ExtraBold.ttf', 2000),
('Spectral-ExtraBoldItalic.ttf', 2000),
('GFSDidot-Regular.ttf', 2000),
('Manrope-Regular.ttf', 1000),
]:
f = TTFont(fn); scaleUpem.scale_upem(f, upem); f.save(fn.replace('.ttf', f'-u{upem}.ttf'))
"

# 3) Merge. Brand font always first.
$PYFT Fraunces-static.ttf Spectral-ExtraBold-u2000.ttf GFSDidot-Regular-u2000.ttf && mv merged.ttf Fraunces.ttf
$PYFT Fraunces-Italic-static.ttf Spectral-ExtraBoldItalic-u2000.ttf GFSDidot-Regular-u2000.ttf && mv merged.ttf Fraunces-Italic.ttf
$PYFT PlusJakartaSans-static.ttf Manrope-Regular-u1000.ttf && mv merged.ttf PlusJakartaSans.ttf
$PYFT DMMono-Regular.ttf JetBrainsMono-Regular.ttf && mv merged.ttf DMMono-Regular.ttf

# 4) Clean up.
rm -f *-static.ttf *-u1000.ttf *-u2000.ttf \
Spectral-ExtraBold.ttf Spectral-ExtraBoldItalic.ttf \
GFSDidot-Regular.ttf Manrope-Regular.ttf JetBrainsMono-Regular.ttf
```

Sanity-check coverage after each merge:

```bash
python3 -c "from fontTools.ttLib import TTFont; \
f=TTFont('Fraunces.ttf'); cps=set(f.getBestCmap()); \
print('Cyr:', any(0x0400<=c<=0x04FF for c in cps), \
'Greek:', any(0x0370<=c<=0x03FF for c in cps))"
```
Binary file not shown.
Binary file modified cmp-common/src/commonMain/composeResources/font/Fraunces.ttf
Binary file not shown.
Binary file not shown.
Loading