From 8969d7f8491323f2f72b6fbb17cf96e8373f2614 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Thu, 9 Oct 2025 12:40:58 +0200 Subject: [PATCH 01/25] Added translation using Weblate (Japanese) Co-authored-by: daiman --- app/src/main/res/values-ja/strings.xml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/src/main/res/values-ja/strings.xml diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-ja/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file From 7a6a2463ec76e4037348427d3956011026679f63 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Thu, 9 Oct 2025 21:26:37 +0200 Subject: [PATCH 02/25] Added translation using Weblate (Portuguese (Brazil)) Translated using Weblate (Japanese) Currently translated at 98.2% (56 of 57 strings) Translated using Weblate (Japanese) Currently translated at 100.0% (11 of 11 strings) Co-authored-by: Hosted Weblate Co-authored-by: Thiago Co-authored-by: daiman Translate-URL: https://hosted.weblate.org/projects/tomato/store-descriptions/ja/ Translate-URL: https://hosted.weblate.org/projects/tomato/strings/ja/ Translation: Tomato/Store descriptions Translation: Tomato/Strings --- app/src/main/res/values-ja/strings.xml | 58 ++++++++++++++++++- app/src/main/res/values-pt-rBR/strings.xml | 3 + .../android/ja-JP/full_description.txt | 1 + .../android/ja-JP/short_description.txt | 1 + 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/values-pt-rBR/strings.xml create mode 100644 fastlane/metadata/android/ja-JP/full_description.txt create mode 100644 fastlane/metadata/android/ja-JP/short_description.txt diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 55344e5..93ee360 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1,3 +1,59 @@ - \ No newline at end of file + 開始 + 停止 + 集中 + 短い休憩 + 長い休憩 + 終了 + スキップ + アラームを停止 + 残り%1$s分 + 中断 + 完了 + 次の予定: %1$s (%2$s) + 開始 + カラースキームを選んでください + OK + カラースキーム + ダイナミック + + 初期設定 + アラーム + ライト + ダーク + テーマ選択 + 生産性の分析 + 時間帯別の集中した時間 + アラームサウンド + ブラックテーマ + 漆黒テーマを使用 + 終了時にアラームを鳴らす + 振動 + 終了時に振動します + テーマ + 設定 + セッションの長さ + %1$dに一度長い休憩を行う + 「セッション」とは、集中時間・短い休憩・長い休憩を含む一連のポモドーロ間隔のことです。セッションの最後の休憩は必ず長い休憩になります。 + 統計 + 今日 + 休憩 + 先週 + 平均時間 + 詳細 + 一週間の生産性の分析 + 先月 + 先月の生産性の分析 + アラームを停止しますか? + 現在のタイマーセッションは終了しました。アラームを停止するには、任意の場所をタップしてください。 + %1$dの%2$d + 追加 + 一時停止 + 再開 + やり直し + スキップ + 次は + タイマー + タイマーの進行状況 + diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fastlane/metadata/android/ja-JP/full_description.txt b/fastlane/metadata/android/ja-JP/full_description.txt new file mode 100644 index 0000000..b959733 --- /dev/null +++ b/fastlane/metadata/android/ja-JP/full_description.txt @@ -0,0 +1 @@ +

Tomato は、Material 3 Expressive をベースにしたミニマルな Android 向けポモドーロ・タイマーです。


主な機能:

  • 最新の Material 3 Expressive ガイドラインに基づいたシンプルでミニマルなUI
  • 作業・学習時間をわかりやすく可視化した詳細な統計
    • 当日の統計をひと目で確認可能
    • 過去1週間・1か月分の統計を見やすく整理されたグラフで表示
    • さらに、先週・先月の統計から一日のうち最も集中できる時間帯を確認可能
  • タイマー設定を自由にカスタマイズ可能
diff --git a/fastlane/metadata/android/ja-JP/short_description.txt b/fastlane/metadata/android/ja-JP/short_description.txt new file mode 100644 index 0000000..d761598 --- /dev/null +++ b/fastlane/metadata/android/ja-JP/short_description.txt @@ -0,0 +1 @@ +シンプルなポモドーロタイマー From 08152ccfcd2d87a370ecf82089b08520990580ae Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 10 Oct 2025 06:40:29 +0200 Subject: [PATCH 03/25] Added translation using Weblate (German) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (57 of 57 strings) Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (11 of 11 strings) Co-authored-by: Elias Frey Co-authored-by: Hosted Weblate Co-authored-by: Thiago Translate-URL: https://hosted.weblate.org/projects/tomato/store-descriptions/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/tomato/strings/pt_BR/ Translation: Tomato/Store descriptions Translation: Tomato/Strings --- app/src/main/res/values-de/strings.xml | 3 + app/src/main/res/values-pt-rBR/strings.xml | 58 ++++++++++++++++++- .../android/pt-BR/full_description.txt | 1 + .../android/pt-BR/short_description.txt | 1 + 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/values-de/strings.xml create mode 100644 fastlane/metadata/android/pt-BR/full_description.txt create mode 100644 fastlane/metadata/android/pt-BR/short_description.txt diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-de/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 55344e5..e857b72 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1,3 +1,59 @@ - \ No newline at end of file + Começar + Parar + Focar + Pausa curta + Pausa longa + Sair + Pular + Parar alarme + %1$s minutos restantes + Pausado + Concluído + A seguir: %1$s (%2$s) + Começar o próximo + Escolha o esquema de cores + OK + Esquema de cores + Dinâmico + Cor + Padrão do sistema + Alarme + Claro + Escuro + Escolher tema + Análise de produtividade + Duração do foco em diferentes horas do dia + Som de alarme + Tema escuro + Use um tema preto escuro puro + Tocar o alarme quando um timer for concluído + Vibrar + Vibrar quanto um timer for concluído + Tema + Configurações + Duração da sessão + Intervalos de foco em uma sessão: %1$d + Uma \"sessão\" é uma sequência de intervalos Pomodoro que contém intervalos de foco, intervalos de pausa curta e um intervalo de pausa longa. A última pausa de uma sessão é sempre uma pausa longa. + Estatísticas + Hoje + Pausa + Última semana + foco por dia (média) + Mais informações + Análise de produtividade semanal + Último mês + Análise de produtividade mensal + Parar Alarme? + A sessão atual do timer foi concluída. Toque em qualquer lugar para interromper o alarme. + %1$d de %2$d + Mais + Pausar + Começar + Reiniciar + Pular para o próximo + Próximo + Timer + Progresso do timer + diff --git a/fastlane/metadata/android/pt-BR/full_description.txt b/fastlane/metadata/android/pt-BR/full_description.txt new file mode 100644 index 0000000..b9e7b5b --- /dev/null +++ b/fastlane/metadata/android/pt-BR/full_description.txt @@ -0,0 +1 @@ +

Tomato é um timer Pomodoro minimalista para Android baseado em Material 3 Expressive.


Funções:

  • Simples, interface minimalista baseada nas últimas diretrizes do Material 3 Expressive
  • Estatísticas detalhadas de tempo de trabalho/estudo de um jeito fácil de entender
    • Estatísticas do dia atual visíveis num relance
    • Estatísticas da última semana e do último mês mostrados de um jeito fácil de ler em um gráfico limpo
    • Estatísticas adicionais da última semana e mês mostrando que hora do dia você é mais produtivo
  • Parâmetros do timer customizáveis
diff --git a/fastlane/metadata/android/pt-BR/short_description.txt b/fastlane/metadata/android/pt-BR/short_description.txt new file mode 100644 index 0000000..8846b7b --- /dev/null +++ b/fastlane/metadata/android/pt-BR/short_description.txt @@ -0,0 +1 @@ +Timer minimalista Pomodoro From 020bc5c8da3eae419fc9f43020f55dd484982a36 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sat, 11 Oct 2025 07:07:27 +0200 Subject: [PATCH 04/25] Translated using Weblate (German) Currently translated at 100.0% (57 of 57 strings) Translated using Weblate (German) Currently translated at 100.0% (11 of 11 strings) Co-authored-by: Elias Frey Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/tomato/store-descriptions/de/ Translate-URL: https://hosted.weblate.org/projects/tomato/strings/de/ Translation: Tomato/Store descriptions Translation: Tomato/Strings --- app/src/main/res/values-de/strings.xml | 58 ++++++++++++++++++- .../android/de-DE/full_description.txt | 1 + .../android/de-DE/short_description.txt | 1 + 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/de-DE/full_description.txt create mode 100644 fastlane/metadata/android/de-DE/short_description.txt diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 55344e5..3c08f8f 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1,3 +1,59 @@ - \ No newline at end of file + Start + Stop + Fokus + Kurze Pause + Lange Pause + Abbrechen + Überspringen + Alarm beenden + %1$s min verbleibend + Pausiert + Abgeschlossen + Als nächstes: %1$s (%2$s) + Weiter + Farbschema auswählen + OK + Farbschema + Dynamisch + Farbe + Systemstandard + Alarm + Hell + Dunkel + Erscheinungsbild wählen + Produktivitätsanalyse + Fokusdauer zu verschiedenen Tageszeiten + Alarmton + Schwarzes Design + Echten Schwarzmodus verwenden + Alarmton bei Ablauf des Timers + Vibration + Vibrieren, wenn ein Timer abgelaufen ist + Design + Einstellungen + Fokusphasen + Fokusintervalle pro Sitzung:%1$d + Eine „Sitzung“ ist eine Abfolge von Pomodoro-Intervallen, die Fokusintervalle, kurze Pausenintervalle und ein langes Pausenintervall enthalten. Die letzte Pause einer Sitzung ist immer eine lange Pause. + Statistik + Heute + Pause + Letzte Woche + Fokus pro Tag (⌀) + Weitere Infos + Wöchentliche Produktivität + Letzter Monat + Monatliche Produktivität + Alarm stoppen? + Die aktuelle Timer-Sitzung ist beendet. Tippen Sie auf eine beliebige Stelle, um den Alarm zu stoppen. + %1$d von %2$d + Mehr + Pausieren + Fortsetzen + Neustarten + Zum nächsten springen + Als nächstes + Timer + Timer-Fortschritt + diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt new file mode 100644 index 0000000..1c1fcad --- /dev/null +++ b/fastlane/metadata/android/de-DE/full_description.txt @@ -0,0 +1 @@ +

Tomato ist ein minimalistischer Pomodoro-Timer für Android, der auf Material 3 Expressive basiert.


Funktionen:

  • Einfache, minimalistische Benutzeroberfläche, die auf den neuesten Material 3 Expressive-Richtlinien basiert
  • Detaillierte Statistiken zu Arbeits-/Lernzeiten in leicht verständlicher Form
    • Statistiken für den aktuellen Tag auf einen Blick sichtbar
    • Statistiken für die letzte Woche und den letzten Monat in einer übersichtlichen und sauberen Grafik dargestellt
    • Zusätzliche Statistiken für die letzte Woche und den letzten Monat zeigen, zu welcher Tageszeit Sie am produktivsten sind
  • Anpassbare Timer Voreinstellungen
diff --git a/fastlane/metadata/android/de-DE/short_description.txt b/fastlane/metadata/android/de-DE/short_description.txt new file mode 100644 index 0000000..fbf59f3 --- /dev/null +++ b/fastlane/metadata/android/de-DE/short_description.txt @@ -0,0 +1 @@ +Minimalistischer Pomodoro-Timer From 662ba1321497dfb1f03800958ae84a4d14f6fdb7 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sat, 11 Oct 2025 17:20:23 +0200 Subject: [PATCH 05/25] Added translation using Weblate (Czech) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michal Bedáň --- app/src/main/res/values-cs/strings.xml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/src/main/res/values-cs/strings.xml diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-cs/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file From dbd4a6902536f5d7e556be826d07622ec4f6b69d Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 12 Oct 2025 20:07:27 +0200 Subject: [PATCH 06/25] Translated using Weblate (Czech) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 5.2% (3 of 57 strings) Co-authored-by: Michal Bedáň Translate-URL: https://hosted.weblate.org/projects/tomato/strings/cs/ Translation: Tomato/Strings --- app/src/main/res/values-cs/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 55344e5..9050dd5 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1,3 +1,5 @@ - \ No newline at end of file + Zapnout + Zastavit + From 6451a3bdd1a09f9c30d2c123510d92430cd93522 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 13 Oct 2025 02:11:59 +0200 Subject: [PATCH 07/25] Added translation using Weblate (Italian) Co-authored-by: Matteo Ventura --- app/src/main/res/values-it/strings.xml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/src/main/res/values-it/strings.xml diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-it/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file From 33e7086bca44da5f9450f186543755bb50f55896 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 13 Oct 2025 10:54:01 +0200 Subject: [PATCH 08/25] Added translation using Weblate (Spanish) Translated using Weblate (Italian) Currently translated at 100.0% (57 of 57 strings) Translated using Weblate (Italian) Currently translated at 100.0% (11 of 11 strings) Co-authored-by: Hosted Weblate Co-authored-by: Profono Co-authored-by: matteventu Translate-URL: https://hosted.weblate.org/projects/tomato/store-descriptions/it/ Translate-URL: https://hosted.weblate.org/projects/tomato/strings/it/ Translation: Tomato/Store descriptions Translation: Tomato/Strings --- app/src/main/res/values-es/strings.xml | 3 + app/src/main/res/values-it/strings.xml | 58 ++++++++++++++++++- .../android/it-IT/full_description.txt | 1 + .../android/it-IT/short_description.txt | 1 + 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/values-es/strings.xml create mode 100644 fastlane/metadata/android/it-IT/full_description.txt create mode 100644 fastlane/metadata/android/it-IT/short_description.txt diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-es/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 55344e5..1f13090 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -1,3 +1,59 @@ - \ No newline at end of file + Inizia + Ferma + Concentrati + Pausa breve + Pausa lunga + Esci + Salta + Ferma sveglia + %1$s min rimanenti + In pausa + Completato + Prossimo: %1$s (%2$s) + Inizia il prossimo + Scegli schema colori + OK + Schema colori + Dinamico + Colore + Segui sistema + Sveglia + Chiaro + Scuro + Scegli tema + Analisi produttività + Durata della concentrazione in diverse ore del giorno + Suono sveglia + Tema nero + Tema scuro completamente nero + Suona la sveglia quando il timer scade + Vibrazione + Vibra il telefono quando il timer scade + Tema + Impostazioni + Lunghezza sessione + Intervalli di concentrazione per sessione: %1$d + Una \"sessione\" è una sequenza di intervalli \"pomodoro\" che include intervalli di concentrazione, di pausa breve, e di pausa lunga. L\'ultima pausa di una sessione è sempre una pausa lunga. + Statistiche + Oggi + Pausa + Ultima settimana + concentrazione al giorno (media) + Più informazioni + Analisi produttività settimanale + Ultimo mese + Analisi produttività mensile + Ferma allarme? + Il timer per la sessione corrente è scaduto. Tocca in qualsiasi punto per fermare la sveglia. + %1$d di %2$d + Altro + Pausa + Inizia + Reinizia + Salta al prossimo + Prossimo + Timer + Progresso timer + diff --git a/fastlane/metadata/android/it-IT/full_description.txt b/fastlane/metadata/android/it-IT/full_description.txt new file mode 100644 index 0000000..c15cbd1 --- /dev/null +++ b/fastlane/metadata/android/it-IT/full_description.txt @@ -0,0 +1 @@ +

Tomato è un timer Pomodoro minimalista per Android con design Material 3 Expressive.


Features:

  • UI semplice e minimalista basata sulle ultime linee guida Material 3 Expressive
  • Statistiche dettagliate dei tempi di studio/lavoro in modo semplice da comprendere
    • Statistiche per il giorno attuale visibili a colpo d'occhio
    • Statistiche per l'ultima settimana e ultimo mese visibili in un chiaro grafico di semplice lettura
    • Statistiche aggiuntive per l'ultima settimana e ultimo mese che mostrano a quale ora del giorno sei più produttivo
  • Parametri del timer personalizzabili
diff --git a/fastlane/metadata/android/it-IT/short_description.txt b/fastlane/metadata/android/it-IT/short_description.txt new file mode 100644 index 0000000..1704e13 --- /dev/null +++ b/fastlane/metadata/android/it-IT/short_description.txt @@ -0,0 +1 @@ +Timer Pomodoro Minimalista From 4b6035a17c77c7daa6feaa4afeab2205a5983249 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 14 Oct 2025 11:07:35 +0200 Subject: [PATCH 09/25] Translated using Weblate (Spanish) Currently translated at 82.4% (47 of 57 strings) Translated using Weblate (Spanish) Currently translated at 90.9% (10 of 11 strings) Co-authored-by: Hosted Weblate Co-authored-by: Profono Translate-URL: https://hosted.weblate.org/projects/tomato/store-descriptions/es/ Translate-URL: https://hosted.weblate.org/projects/tomato/strings/es/ Translation: Tomato/Store descriptions Translation: Tomato/Strings --- app/src/main/res/values-es/strings.xml | 58 ++++++++++++++++++- .../android/es-ES/full_description.txt | 1 + .../android/es-ES/short_description.txt | 1 + 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/es-ES/full_description.txt create mode 100644 fastlane/metadata/android/es-ES/short_description.txt diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 55344e5..5a729c0 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1,3 +1,59 @@ - \ No newline at end of file + Iniciar + Detener + Concentración + Pequeño descanso + Descanso extenso + Salir + Omitir + Parar alarma + En pausa + Predeterminado del sistema + Alarma + Elige tema + Análisis de productividad + Duración de la concentración en diferentes momentos del día + Sonido de la alarma + Tema negro + Utiliza un tema oscuro negro puro + Sonar alarma cuando el temporizador finalice + Vibrar + Vibrar cuando el temporizador finalice + Tema + Configuración + Duración de la sesión + Intervalos de concentración en una sesión: %1$d + Una \"sesión\" es una secuencia de intervalos Pomodoro que contiene intervalos de concentración, intervalos de descanso cortos y un intervalo de descanso largo. El último descanso de una sesión es siempre un descanso largo. + Estadísticas + Hoy + Descanso + Semana pasada + concentración por día (avg) + Más informes + Análisis de productividad semanal + Mes pasado + Análisis de productividad mensual + Parar alarma? + La sesión actual del temporizador ha finalizado. Toque en cualquier lugar para detener la alarma. + %1$d de %2$d + Más + Pausa + Empezar + Reiniciar + Pasar al siguiente + A continuación + Temporizador + Pregreso del temporizador + %1$s minutos restantes + Completado + A continuación: %1$s (%2$s) + Empezar siguiente + Elige la combinación de colores + Ok + Esquema de colores + Dinámica + Color + Luz + Oscuro + diff --git a/fastlane/metadata/android/es-ES/full_description.txt b/fastlane/metadata/android/es-ES/full_description.txt new file mode 100644 index 0000000..4feacf8 --- /dev/null +++ b/fastlane/metadata/android/es-ES/full_description.txt @@ -0,0 +1 @@ +

Tomato es un temporizador Pomodoro minimalista para Android basado en "Material 3 Expressive".


Características:

  • Interfaz de usuario sencilla y minimalista basada en las últimas directrices de "Material 3 Expressive".
  • Estadísticas detalladas e intuitivas en los tiempos de trabajo/estudio.
    • Estadísticas simples y accesibles del día en curso.
    • Estadísticas de la última semana y del último mes mostradas en un gráfico sencillo.
    • Estadísticas adicionales de la última semana y del último mes que muestran a qué hora del día eres más productivo.
  • Parámetros de temporizador personalizables.
diff --git a/fastlane/metadata/android/es-ES/short_description.txt b/fastlane/metadata/android/es-ES/short_description.txt new file mode 100644 index 0000000..ba57514 --- /dev/null +++ b/fastlane/metadata/android/es-ES/short_description.txt @@ -0,0 +1 @@ +Temporizador Pomodoro minimalista From 7b2fa614ad36635eb4cbf23922b9afc8008f5877 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 14 Oct 2025 20:16:54 +0200 Subject: [PATCH 10/25] Added translation using Weblate (Kurdish (Central)) Co-authored-by: mastawbeqezwan --- app/src/main/res/values-ckb/strings.xml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/src/main/res/values-ckb/strings.xml diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-ckb/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file From cbede43ff9464dbba8305da33ff1da0b2d94df60 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 15 Oct 2025 07:10:45 +0200 Subject: [PATCH 11/25] Added translation using Weblate (Minnan (Traditional Han script)) Translated using Weblate (Kurdish (Central)) Currently translated at 64.9% (37 of 57 strings) Translated using Weblate (Kurdish (Central)) Currently translated at 90.9% (10 of 11 strings) Co-authored-by: Hosted Weblate Co-authored-by: SweetPotato Yee (SweetPotatoYee) Co-authored-by: mastawbeqezwan Translate-URL: https://hosted.weblate.org/projects/tomato/store-descriptions/ckb/ Translate-URL: https://hosted.weblate.org/projects/tomato/strings/ckb/ Translation: Tomato/Store descriptions Translation: Tomato/Strings --- .../main/res/values-b+nan+Hant/strings.xml | 3 ++ app/src/main/res/values-ckb/strings.xml | 38 ++++++++++++++++++- .../android/ckb/short_description.txt | 1 + 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/values-b+nan+Hant/strings.xml create mode 100644 fastlane/metadata/android/ckb/short_description.txt diff --git a/app/src/main/res/values-b+nan+Hant/strings.xml b/app/src/main/res/values-b+nan+Hant/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-b+nan+Hant/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values-ckb/strings.xml b/app/src/main/res/values-ckb/strings.xml index 55344e5..b5a25e8 100644 --- a/app/src/main/res/values-ckb/strings.xml +++ b/app/src/main/res/values-ckb/strings.xml @@ -1,3 +1,39 @@ - \ No newline at end of file + دەستپێکردن + وەستاندن + سەرنجدان + پشوویەکی کورت + پشوویەکی درێژ + دەرچوون + پەڕاندن + وەستاندنی زەنگی ئاگادار کردنەوە + %1$s خولەک ماوە + باشە + ڕەنگی رووکار + داینامیکی + ڕەنگ + ڕەنگی ڕووکار هەڵبژێرە + وەک سیستەم + زەنگی ئاگادارکردنەوە + تاریک + ڕووکارێک هەلبژێرە + شرۆڤەی بە بەرهەمی + ماوەی سەرنجدان لە کاتە جیاوازەکانی ڕۆژ + زەنگی ئاگادارکردنەوە + ڕووکاری ڕەش + بەکارهێنانی ڕووکاری تەواو ڕەش + زەنگی ئاگادارکردنەوە لێبدە لە کاتی تەواوبوونی کاتگرەوە + لەرینەوە + لەرینەوە لە کاتی تەواوبوونی کاتگرەوە + ڕووناک + ڕووکار + ڕێکخستنەکان + ئەمڕۆ + پشوو + هەفتەی ڕابردوو + زیاتر + ئامار + زانیاری زیاتر + وەستاندن + diff --git a/fastlane/metadata/android/ckb/short_description.txt b/fastlane/metadata/android/ckb/short_description.txt new file mode 100644 index 0000000..4edb81f --- /dev/null +++ b/fastlane/metadata/android/ckb/short_description.txt @@ -0,0 +1 @@ +کاتگرەوەیەکی چکۆلانەی پۆمۆدۆرە From 78bdf27d22771882295ae4035514ac763edaf794 Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Wed, 15 Oct 2025 20:36:57 +0530 Subject: [PATCH 12/25] feat: implement a time line chart composable --- .../pomodoro/ui/statsScreen/TimeLineChart.kt | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt new file mode 100644 index 0000000..00855dd --- /dev/null +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025 Nishant Mishra + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.nsh07.pomodoro.ui.statsScreen + +import androidx.compose.animation.core.AnimationSpec +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.material3.MaterialTheme.motionScheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost +import com.patrykandpatrick.vico.compose.cartesian.axis.rememberBottom +import com.patrykandpatrick.vico.compose.cartesian.axis.rememberStart +import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLine +import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer +import com.patrykandpatrick.vico.compose.cartesian.rememberCartesianChart +import com.patrykandpatrick.vico.compose.cartesian.rememberVicoZoomState +import com.patrykandpatrick.vico.compose.common.ProvideVicoTheme +import com.patrykandpatrick.vico.compose.common.component.rememberLineComponent +import com.patrykandpatrick.vico.compose.common.fill +import com.patrykandpatrick.vico.compose.common.vicoTheme +import com.patrykandpatrick.vico.compose.m3.common.rememberM3VicoTheme +import com.patrykandpatrick.vico.core.cartesian.FadingEdges +import com.patrykandpatrick.vico.core.cartesian.Zoom +import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis +import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis +import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer +import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter +import com.patrykandpatrick.vico.core.cartesian.data.lineSeries +import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer +import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer.LineFill.Companion.single +import com.patrykandpatrick.vico.core.common.Fill +import com.patrykandpatrick.vico.core.common.shader.ShaderProvider +import org.nsh07.pomodoro.ui.theme.TomatoTheme +import org.nsh07.pomodoro.utils.millisecondsToHours +import org.nsh07.pomodoro.utils.millisecondsToMinutes + +@OptIn(ExperimentalMaterial3ExpressiveApi::class) +@Composable +internal fun TimeLineChart( + modelProducer: CartesianChartModelProducer, + modifier: Modifier = Modifier, + thickness: Float = 2f, + pointSpacing: Dp = 12.dp, + xValueFormatter: CartesianValueFormatter = CartesianValueFormatter.Default, + yValueFormatter: CartesianValueFormatter = CartesianValueFormatter { _, value, _ -> + if (value >= 60 * 60 * 1000) { + millisecondsToHours(value.toLong()) + } else { + millisecondsToMinutes(value.toLong()) + } + }, + animationSpec: AnimationSpec? = motionScheme.slowEffectsSpec() +) { + ProvideVicoTheme(rememberM3VicoTheme()) { + CartesianChartHost( + chart = + rememberCartesianChart( + rememberLineCartesianLayer( + LineCartesianLayer.LineProvider.series( + vicoTheme.lineCartesianLayerColors.map { color -> + LineCartesianLayer.rememberLine( + fill = single(fill(color)), + stroke = LineCartesianLayer.LineStroke.Continuous( + thicknessDp = thickness, + ), + areaFill = LineCartesianLayer.AreaFill.single( + fill( + ShaderProvider.verticalGradient( + color.toArgb(), + Color.Transparent.toArgb() + ) + ) + ), + pointConnector = LineCartesianLayer.PointConnector.cubic(0.5f) + ) + } + ), + pointSpacing = pointSpacing + ), + startAxis = VerticalAxis.rememberStart( + line = rememberLineComponent(Fill.Transparent), + tick = rememberLineComponent(Fill.Transparent), + guideline = rememberLineComponent(Fill.Transparent), + valueFormatter = yValueFormatter + ), + bottomAxis = HorizontalAxis.rememberBottom( + rememberLineComponent(Fill.Transparent), + tick = rememberLineComponent(Fill.Transparent), + guideline = rememberLineComponent(Fill.Transparent), + valueFormatter = xValueFormatter + ), + fadingEdges = FadingEdges() + ), + modelProducer = modelProducer, + zoomState = rememberVicoZoomState( + zoomEnabled = true, + initialZoom = Zoom.fixed(), + minZoom = Zoom.min(Zoom.Content, Zoom.fixed()) + ), + animationSpec = animationSpec, + modifier = modifier, + ) + } +} + +@OptIn(ExperimentalMaterial3ExpressiveApi::class) +@Preview +@Composable +private fun TimeLineChartPreview() { + val modelProducer = remember { CartesianChartModelProducer() } + val values = mutableListOf() + LaunchedEffect(Unit) { + repeat(365) { + values.add((0..120).random() * 60 * 1000) + } + modelProducer.runTransaction { + lineSeries { + series(values) + } + } + } + TomatoTheme { + Surface { + TimeLineChart(modelProducer = modelProducer) + } + } +} From 5717a0f27471877c7a87fc9a7cd1e9e5a8af256b Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Wed, 15 Oct 2025 20:40:25 +0530 Subject: [PATCH 13/25] feat: add fading edges to time column chart --- .../ui/statsScreen/TimeColumnChart.kt | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeColumnChart.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeColumnChart.kt index 497e553..ef5c563 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeColumnChart.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeColumnChart.kt @@ -10,8 +10,12 @@ package org.nsh07.pomodoro.ui.statsScreen import androidx.compose.animation.core.AnimationSpec import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.MaterialTheme.motionScheme +import androidx.compose.material3.Surface import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost @@ -25,20 +29,23 @@ import com.patrykandpatrick.vico.compose.common.component.rememberLineComponent import com.patrykandpatrick.vico.compose.common.fill import com.patrykandpatrick.vico.compose.common.vicoTheme import com.patrykandpatrick.vico.compose.m3.common.rememberM3VicoTheme +import com.patrykandpatrick.vico.core.cartesian.FadingEdges import com.patrykandpatrick.vico.core.cartesian.Zoom import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter +import com.patrykandpatrick.vico.core.cartesian.data.columnSeries import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer import com.patrykandpatrick.vico.core.common.Fill import com.patrykandpatrick.vico.core.common.shape.CorneredShape +import org.nsh07.pomodoro.ui.theme.TomatoTheme import org.nsh07.pomodoro.utils.millisecondsToHours import org.nsh07.pomodoro.utils.millisecondsToMinutes @OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable -internal fun TimeColumnChart( +fun TimeColumnChart( modelProducer: CartesianChartModelProducer, modifier: Modifier = Modifier, thickness: Dp = 40.dp, @@ -80,7 +87,8 @@ internal fun TimeColumnChart( tick = rememberLineComponent(Fill.Transparent), guideline = rememberLineComponent(Fill.Transparent), valueFormatter = xValueFormatter - ) + ), + fadingEdges = FadingEdges() ), modelProducer = modelProducer, zoomState = rememberVicoZoomState( @@ -92,4 +100,26 @@ internal fun TimeColumnChart( modifier = modifier, ) } -} \ No newline at end of file +} + +@Preview +@Composable +private fun TimeColumnChartPreview() { + val modelProducer = remember { CartesianChartModelProducer() } + val values = mutableListOf() + LaunchedEffect(Unit) { + repeat(30) { + values.add((0..120).random() * 60 * 1000) + } + modelProducer.runTransaction { + columnSeries { + series(values) + } + } + } + TomatoTheme { + Surface { + TimeColumnChart(thickness = 8.dp, modelProducer = modelProducer) + } + } +} From a26b0eac7403d9945e5ca615c4346322a7a17a91 Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Wed, 15 Oct 2025 23:25:29 +0530 Subject: [PATCH 14/25] refactor(stats): refactor flow collection to improve performance --- .../pomodoro/ui/statsScreen/StatsScreen.kt | 74 ++++++--- .../statsScreen/viewModel/StatsViewModel.kt | 147 +++++++++--------- 2 files changed, 128 insertions(+), 93 deletions(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt index e40a0b2..3af64e8 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt @@ -35,6 +35,7 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -56,10 +57,8 @@ import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter import com.patrykandpatrick.vico.core.cartesian.data.columnSeries import com.patrykandpatrick.vico.core.common.data.ExtraStore -import kotlinx.coroutines.runBlocking import org.nsh07.pomodoro.R import org.nsh07.pomodoro.data.Stat -import org.nsh07.pomodoro.data.StatFocusTime import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar @@ -72,20 +71,41 @@ fun StatsScreenRoot( viewModel: StatsViewModel = viewModel(factory = StatsViewModel.Factory) ) { val todayStat by viewModel.todayStat.collectAsStateWithLifecycle(null) - val lastWeekAverageFocusTimes by viewModel - .lastWeekAverageFocusTimes.collectAsStateWithLifecycle(null) - val lastMonthAverageFocusTimes by viewModel - .lastMonthAverageFocusTimes.collectAsStateWithLifecycle(null) + + val lastWeekSummaryChartData by viewModel.lastWeekSummaryChartData.collectAsStateWithLifecycle() + val lastWeekAnalysisValues by viewModel.lastWeekAverageFocusTimes.collectAsStateWithLifecycle() + + val lastMonthSummaryChartData by viewModel.lastMonthSummaryChartData.collectAsStateWithLifecycle() + val lastMonthAnalysisValues by viewModel.lastMonthAverageFocusTimes.collectAsStateWithLifecycle() + + val lastWeekSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() } + val lastMonthSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() } + + LaunchedEffect(lastWeekAnalysisValues) { + lastWeekSummaryAnalysisModelProducer.runTransaction { + columnSeries { + series(lastWeekAnalysisValues) + } + } + } + + LaunchedEffect(lastMonthAnalysisValues) { + lastMonthSummaryAnalysisModelProducer.runTransaction { + columnSeries { + series(lastMonthAnalysisValues) + } + } + } StatsScreen( contentPadding = contentPadding, - lastWeekSummaryChartData = remember { viewModel.lastWeekSummaryChartData }, - lastWeekSummaryAnalysisModelProducer = remember { viewModel.lastWeekSummaryAnalysisModelProducer }, - lastMonthSummaryChartData = remember { viewModel.lastMonthSummaryChartData }, - lastMonthSummaryAnalysisModelProducer = remember { viewModel.lastMonthSummaryAnalysisModelProducer }, + lastWeekSummaryChartData = lastWeekSummaryChartData, + lastWeekSummaryAnalysisModelProducer = lastWeekSummaryAnalysisModelProducer, + lastMonthSummaryChartData = lastMonthSummaryChartData, + lastMonthSummaryAnalysisModelProducer = lastMonthSummaryAnalysisModelProducer, todayStat = todayStat, - lastWeekAverageFocusTimes = lastWeekAverageFocusTimes, - lastMonthAverageFocusTimes = lastMonthAverageFocusTimes, + lastWeekAverageFocusTimes = lastWeekAnalysisValues, + lastMonthAverageFocusTimes = lastMonthAnalysisValues, modifier = modifier ) } @@ -99,8 +119,8 @@ fun StatsScreen( lastMonthSummaryChartData: Pair>>, lastMonthSummaryAnalysisModelProducer: CartesianChartModelProducer, todayStat: Stat?, - lastWeekAverageFocusTimes: StatFocusTime?, - lastMonthAverageFocusTimes: StatFocusTime?, + lastWeekAverageFocusTimes: List, + lastMonthAverageFocusTimes: List, modifier: Modifier = Modifier ) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() @@ -218,7 +238,11 @@ fun StatsScreen( .padding(horizontal = 16.dp) ) { Text( - millisecondsToHoursMinutes(lastWeekAverageFocusTimes?.total() ?: 0), + millisecondsToHoursMinutes( + remember(lastWeekAverageFocusTimes) { + lastWeekAverageFocusTimes.sum().toLong() + } + ), style = typography.displaySmall, fontFamily = openRundeClock ) @@ -290,7 +314,11 @@ fun StatsScreen( .padding(horizontal = 16.dp) ) { Text( - millisecondsToHoursMinutes(lastMonthAverageFocusTimes?.total() ?: 0), + millisecondsToHoursMinutes( + remember(lastMonthAverageFocusTimes) { + lastMonthAverageFocusTimes.sum().toLong() + } + ), style = typography.displaySmall, fontFamily = openRundeClock ) @@ -356,23 +384,25 @@ fun StatsScreen( @Composable fun StatsScreenPreview() { val modelProducer = remember { CartesianChartModelProducer() } + val keys = remember { ExtraStore.Key>() } - runBlocking { + LaunchedEffect(Unit) { modelProducer.runTransaction { columnSeries { series(5, 6, 5, 2, 11, 8, 5, 2, 15, 11, 8, 13, 12, 10, 2, 7) } + extras { it[keys] = listOf("M", "T", "W", "T", "F", "S", "S") } } } StatsScreen( PaddingValues(), - Pair(modelProducer, ExtraStore.Key()), + Pair(modelProducer, keys), modelProducer, - Pair(modelProducer, ExtraStore.Key()), + Pair(modelProducer, keys), modelProducer, null, - null, - null + listOf(0, 0, 0, 0), + listOf(0, 0, 0, 0) ) -} +} \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/viewModel/StatsViewModel.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/viewModel/StatsViewModel.kt index 73f4f8e..9f0e553 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/viewModel/StatsViewModel.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/viewModel/StatsViewModel.kt @@ -16,9 +16,11 @@ import androidx.lifecycle.viewmodel.viewModelFactory import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.columnSeries import com.patrykandpatrick.vico.core.common.data.ExtraStore -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn import org.nsh07.pomodoro.TomatoApplication import org.nsh07.pomodoro.data.StatRepository import java.time.format.TextStyle @@ -29,83 +31,86 @@ class StatsViewModel( ) : ViewModel() { val todayStat = statRepository.getTodayStat().distinctUntilChanged() - private val lastWeekStatsSummary = statRepository.getLastNDaysStatsSummary(7) - val lastWeekAverageFocusTimes = - statRepository.getLastNDaysAverageFocusTimes(7).distinctUntilChanged() - private val lastMonthStatsSummary = statRepository.getLastNDaysStatsSummary(30) - val lastMonthAverageFocusTimes = - statRepository.getLastNDaysAverageFocusTimes(30).distinctUntilChanged() - val lastWeekSummaryChartData = + private val lastWeekSummary = Pair(CartesianChartModelProducer(), ExtraStore.Key>()) - val lastWeekSummaryAnalysisModelProducer = CartesianChartModelProducer() - val lastMonthSummaryChartData = + private val lastMonthSummary = Pair(CartesianChartModelProducer(), ExtraStore.Key>()) - val lastMonthSummaryAnalysisModelProducer = CartesianChartModelProducer() - init { - viewModelScope.launch(Dispatchers.IO) { - lastWeekStatsSummary - .collect { list -> - // reversing is required because we need ascending order while the DB returns descending order - val reversed = list.reversed() - val keys = reversed.map { - it.date.dayOfWeek.getDisplayName( - TextStyle.NARROW, - Locale.getDefault() - ) - } - val values = reversed.map { it.focusTime } - lastWeekSummaryChartData.first.runTransaction { - columnSeries { series(values) } - extras { it[lastWeekSummaryChartData.second] = keys } - } + val lastWeekSummaryChartData: StateFlow>>> = + statRepository.getLastNDaysStatsSummary(7) + .map { list -> + // reversing is required because we need ascending order while the DB returns descending order + val reversed = list.reversed() + val keys = reversed.map { + it.date.dayOfWeek.getDisplayName( + TextStyle.NARROW, + Locale.getDefault() + ) } - } - viewModelScope.launch(Dispatchers.IO) { - lastWeekAverageFocusTimes - .collect { - lastWeekSummaryAnalysisModelProducer.runTransaction { - columnSeries { - series( - it?.focusTimeQ1 ?: 0, - it?.focusTimeQ2 ?: 0, - it?.focusTimeQ3 ?: 0, - it?.focusTimeQ4 ?: 0 - ) - } - } + val values = reversed.map { it.focusTime } + lastWeekSummary.first.runTransaction { + columnSeries { series(values) } + extras { it[lastWeekSummary.second] = keys } } - } - viewModelScope.launch(Dispatchers.IO) { - lastMonthStatsSummary - .collect { list -> - val reversed = list.reversed() - val keys = reversed.map { it.date.dayOfMonth.toString() } - val values = reversed.map { it.focusTime } - lastMonthSummaryChartData.first.runTransaction { - columnSeries { series(values) } - extras { it[lastMonthSummaryChartData.second] = keys } - } + lastWeekSummary + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = lastWeekSummary + ) + + val lastWeekAverageFocusTimes: StateFlow> = + statRepository.getLastNDaysAverageFocusTimes(7) + .map { + listOf( + it?.focusTimeQ1?.toInt() ?: 0, + it?.focusTimeQ2?.toInt() ?: 0, + it?.focusTimeQ3?.toInt() ?: 0, + it?.focusTimeQ4?.toInt() ?: 0 + ) + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = listOf(0, 0, 0, 0) + ) + + val lastMonthSummaryChartData: StateFlow>>> = + statRepository.getLastNDaysStatsSummary(30) + .map { list -> + val reversed = list.reversed() + val keys = reversed.map { it.date.dayOfMonth.toString() } + val values = reversed.map { it.focusTime } + lastMonthSummary.first.runTransaction { + columnSeries { series(values) } + extras { it[lastMonthSummary.second] = keys } } - } - viewModelScope.launch(Dispatchers.IO) { - lastMonthAverageFocusTimes - .collect { - lastMonthSummaryAnalysisModelProducer.runTransaction { - columnSeries { - series( - it?.focusTimeQ1 ?: 0, - it?.focusTimeQ2 ?: 0, - it?.focusTimeQ3 ?: 0, - it?.focusTimeQ4 ?: 0 - ) - } - } - } - } - } + lastMonthSummary + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = lastMonthSummary + ) + + val lastMonthAverageFocusTimes: StateFlow> = + statRepository.getLastNDaysAverageFocusTimes(30) + .map { + listOf( + it?.focusTimeQ1?.toInt() ?: 0, + it?.focusTimeQ2?.toInt() ?: 0, + it?.focusTimeQ3?.toInt() ?: 0, + it?.focusTimeQ4?.toInt() ?: 0 + ) + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = listOf(0, 0, 0, 0) + ) companion object { val Factory: ViewModelProvider.Factory = viewModelFactory { From 567e6f09215061a8e6b400c6c680548d8043837a Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 15 Oct 2025 20:08:25 +0200 Subject: [PATCH 15/25] Added translation using Weblate (Hungarian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translated using Weblate (Minnan (Traditional Han script)) Currently translated at 61.4% (35 of 57 strings) Translated using Weblate (Minnan (Traditional Han script)) Currently translated at 100.0% (11 of 11 strings) Co-authored-by: Godó Egyházi Co-authored-by: Hosted Weblate Co-authored-by: SweetPotato Yee (SweetPotatoYee) Translate-URL: https://hosted.weblate.org/projects/tomato/store-descriptions/nan_Hant/ Translate-URL: https://hosted.weblate.org/projects/tomato/strings/nan_Hant/ Translation: Tomato/Store descriptions Translation: Tomato/Strings --- .../main/res/values-b+nan+Hant/strings.xml | 37 ++++++++++++++++++- app/src/main/res/values-hu/strings.xml | 3 ++ .../android/nan-Hant/full_description.txt | 9 +++++ .../android/nan-Hant/short_description.txt | 1 + 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/values-hu/strings.xml create mode 100644 fastlane/metadata/android/nan-Hant/full_description.txt create mode 100644 fastlane/metadata/android/nan-Hant/short_description.txt diff --git a/app/src/main/res/values-b+nan+Hant/strings.xml b/app/src/main/res/values-b+nan+Hant/strings.xml index 55344e5..5815af7 100644 --- a/app/src/main/res/values-b+nan+Hant/strings.xml +++ b/app/src/main/res/values-b+nan+Hant/strings.xml @@ -1,3 +1,38 @@ - \ No newline at end of file + 開始 + 停止 + 專注 + 小歇 + 系統預設 + 亂鐘 + 淺色 + 深色 + 選擇主題 + 工課效率分析 + 無仝時段的專注連紲時間 + 亂鐘聲音 + 烏色的主題 + 使用專烏色的主題 + 計時結束時喨喨仔 + 震動 + 計時結束時震動 + 主題 + 設定 + 小節長度 + 一个小節的專注時段:%1$d + 長歇 + 離開 + 跳過 + 止喨 + 閣賰 %1$s 分鐘 + 已暫停 + 已完成 + 紲落來:%1$s (%2$s) + 開始後一個 + 選擇配色方案 + 確認 + 配色方案 + 動態 + 色彩 + diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-hu/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fastlane/metadata/android/nan-Hant/full_description.txt b/fastlane/metadata/android/nan-Hant/full_description.txt new file mode 100644 index 0000000..36ae7dc --- /dev/null +++ b/fastlane/metadata/android/nan-Hant/full_description.txt @@ -0,0 +1,9 @@ +

Tomato 是一个簡單的柑仔蜜鐘計時器,設計的風格是根據 Material 3 Expressive。


功能:

    +
  • 簡單、極簡的使用介面,遵照最新的 Material 3 Expressive 指引
  • +
  • 提供詳細的工作/讀書時間統計,容易看懂
      +
    • 當日的統計一目了然
    • +
    • 上禮拜佮上個月的統計,以簡潔 ê 圖表呈現
    • +
    • 閣有額外 ê 統計,顯示你上生產力的時段(上禮拜佮上個月)
    • +
  • +
  • 計時參數會當自由調整
  • +
diff --git a/fastlane/metadata/android/nan-Hant/short_description.txt b/fastlane/metadata/android/nan-Hant/short_description.txt new file mode 100644 index 0000000..935f8ab --- /dev/null +++ b/fastlane/metadata/android/nan-Hant/short_description.txt @@ -0,0 +1 @@ +簡潔柑仔蜜計時器 From 09c7ca45594ee254f9dec4920317f3ce9132bc7e Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Thu, 16 Oct 2025 00:04:33 +0530 Subject: [PATCH 16/25] feat(stats): implement showing last year stats in a line chart --- .../pomodoro/ui/statsScreen/StatsScreen.kt | 96 ++++++++++++++----- .../pomodoro/ui/statsScreen/TimeLineChart.kt | 2 +- .../statsScreen/viewModel/StatsViewModel.kt | 41 +++++++- app/src/main/res/values/strings.xml | 1 + 4 files changed, 113 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt index 3af64e8..1f7c8c3 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt @@ -78,34 +78,18 @@ fun StatsScreenRoot( val lastMonthSummaryChartData by viewModel.lastMonthSummaryChartData.collectAsStateWithLifecycle() val lastMonthAnalysisValues by viewModel.lastMonthAverageFocusTimes.collectAsStateWithLifecycle() - val lastWeekSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() } - val lastMonthSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() } - - LaunchedEffect(lastWeekAnalysisValues) { - lastWeekSummaryAnalysisModelProducer.runTransaction { - columnSeries { - series(lastWeekAnalysisValues) - } - } - } - - LaunchedEffect(lastMonthAnalysisValues) { - lastMonthSummaryAnalysisModelProducer.runTransaction { - columnSeries { - series(lastMonthAnalysisValues) - } - } - } + val lastYearSummaryChartData by viewModel.lastYearSummaryChartData.collectAsStateWithLifecycle() + val lastYearAnalysisValues by viewModel.lastYearAverageFocusTimes.collectAsStateWithLifecycle() StatsScreen( contentPadding = contentPadding, lastWeekSummaryChartData = lastWeekSummaryChartData, - lastWeekSummaryAnalysisModelProducer = lastWeekSummaryAnalysisModelProducer, lastMonthSummaryChartData = lastMonthSummaryChartData, - lastMonthSummaryAnalysisModelProducer = lastMonthSummaryAnalysisModelProducer, + lastYearSummaryChartData = lastYearSummaryChartData, todayStat = todayStat, lastWeekAverageFocusTimes = lastWeekAnalysisValues, lastMonthAverageFocusTimes = lastMonthAnalysisValues, + lastYearAverageFocusTimes = lastYearAnalysisValues, modifier = modifier ) } @@ -115,12 +99,12 @@ fun StatsScreenRoot( fun StatsScreen( contentPadding: PaddingValues, lastWeekSummaryChartData: Pair>>, - lastWeekSummaryAnalysisModelProducer: CartesianChartModelProducer, lastMonthSummaryChartData: Pair>>, - lastMonthSummaryAnalysisModelProducer: CartesianChartModelProducer, + lastYearSummaryChartData: Pair>>, todayStat: Stat?, lastWeekAverageFocusTimes: List, lastMonthAverageFocusTimes: List, + lastYearAverageFocusTimes: List, modifier: Modifier = Modifier ) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() @@ -128,6 +112,25 @@ fun StatsScreen( var lastWeekStatExpanded by rememberSaveable { mutableStateOf(false) } var lastMonthStatExpanded by rememberSaveable { mutableStateOf(false) } + val lastWeekSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() } + val lastMonthSummaryAnalysisModelProducer = remember { CartesianChartModelProducer() } + + LaunchedEffect(lastWeekAverageFocusTimes) { + lastWeekSummaryAnalysisModelProducer.runTransaction { + columnSeries { + series(lastWeekAverageFocusTimes) + } + } + } + + LaunchedEffect(lastMonthAverageFocusTimes) { + lastMonthSummaryAnalysisModelProducer.runTransaction { + columnSeries { + series(lastMonthAverageFocusTimes) + } + } + } + Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection) @@ -371,8 +374,51 @@ fun StatsScreen( modifier = Modifier.padding(horizontal = 32.dp) ) } - Spacer(Modifier.height(16.dp)) } + item { Spacer(Modifier) } + item { + Text( + stringResource(R.string.last_year), + style = typography.headlineSmall, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) + } + item { + Row( + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) { + Text( + millisecondsToHoursMinutes( + remember(lastYearAverageFocusTimes) { + lastYearAverageFocusTimes.sum().toLong() + } + ), + style = typography.displaySmall, + fontFamily = openRundeClock + ) + Text( + text = stringResource(R.string.focus_per_day_avg), + style = typography.titleSmall, + modifier = Modifier.padding(bottom = 6.3.dp) + ) + } + } + item { + TimeLineChart( + lastYearSummaryChartData.first, + modifier = Modifier.padding(start = 16.dp), + xValueFormatter = CartesianValueFormatter { context, x, _ -> + context.model.extraStore[lastYearSummaryChartData.second][x.toInt()] + } + ) + } + item { Spacer(Modifier.height(16.dp)) } } } } @@ -398,11 +444,11 @@ fun StatsScreenPreview() { StatsScreen( PaddingValues(), Pair(modelProducer, keys), - modelProducer, Pair(modelProducer, keys), - modelProducer, + Pair(modelProducer, keys), null, listOf(0, 0, 0, 0), + listOf(0, 0, 0, 0), listOf(0, 0, 0, 0) ) } \ No newline at end of file diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt index 00855dd..73485f9 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt @@ -49,7 +49,7 @@ import org.nsh07.pomodoro.utils.millisecondsToMinutes @OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable -internal fun TimeLineChart( +fun TimeLineChart( modelProducer: CartesianChartModelProducer, modifier: Modifier = Modifier, thickness: Float = 2f, diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/viewModel/StatsViewModel.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/viewModel/StatsViewModel.kt index 9f0e553..2b907d5 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/viewModel/StatsViewModel.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/viewModel/StatsViewModel.kt @@ -15,6 +15,7 @@ import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.viewModelFactory import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.columnSeries +import com.patrykandpatrick.vico.core.cartesian.data.lineSeries import com.patrykandpatrick.vico.core.common.data.ExtraStore import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -23,6 +24,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import org.nsh07.pomodoro.TomatoApplication import org.nsh07.pomodoro.data.StatRepository +import java.time.format.DateTimeFormatter import java.time.format.TextStyle import java.util.Locale @@ -34,9 +36,12 @@ class StatsViewModel( private val lastWeekSummary = Pair(CartesianChartModelProducer(), ExtraStore.Key>()) - private val lastMonthSummary = Pair(CartesianChartModelProducer(), ExtraStore.Key>()) + private val lastYearSummary = + Pair(CartesianChartModelProducer(), ExtraStore.Key>()) + + private val yearDayFormatter = DateTimeFormatter.ofPattern("d MMM") val lastWeekSummaryChartData: StateFlow>>> = statRepository.getLastNDaysStatsSummary(7) @@ -112,6 +117,40 @@ class StatsViewModel( initialValue = listOf(0, 0, 0, 0) ) + val lastYearSummaryChartData: StateFlow>>> = + statRepository.getLastNDaysStatsSummary(365) + .map { list -> + val reversed = list.reversed() + val keys = reversed.map { it.date.format(yearDayFormatter) } + val values = reversed.map { it.focusTime } + lastYearSummary.first.runTransaction { + lineSeries { series(values) } + extras { it[lastYearSummary.second] = keys } + } + lastYearSummary + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = lastYearSummary + ) + + val lastYearAverageFocusTimes: StateFlow> = + statRepository.getLastNDaysAverageFocusTimes(365) + .map { + listOf( + it?.focusTimeQ1?.toInt() ?: 0, + it?.focusTimeQ2?.toInt() ?: 0, + it?.focusTimeQ3?.toInt() ?: 0, + it?.focusTimeQ4?.toInt() ?: 0 + ) + } + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = listOf(0, 0, 0, 0) + ) + companion object { val Factory: ViewModelProvider.Factory = viewModelFactory { initializer { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0d55c21..067cff5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -56,4 +56,5 @@ Up next Timer Timer progress + Last year \ No newline at end of file From dc4c498371f747135105926abb5da117af1d71de Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Thu, 16 Oct 2025 00:18:21 +0530 Subject: [PATCH 17/25] fix(notification): reduce importance level to disable heads-up notif --- app/src/main/java/org/nsh07/pomodoro/TomatoApplication.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/TomatoApplication.kt b/app/src/main/java/org/nsh07/pomodoro/TomatoApplication.kt index 7b0da79..87be588 100644 --- a/app/src/main/java/org/nsh07/pomodoro/TomatoApplication.kt +++ b/app/src/main/java/org/nsh07/pomodoro/TomatoApplication.kt @@ -15,7 +15,7 @@ class TomatoApplication : Application() { val notificationChannel = NotificationChannel( "timer", getString(R.string.timer_progress), - NotificationManager.IMPORTANCE_HIGH + NotificationManager.IMPORTANCE_DEFAULT ) container.notificationManager.createNotificationChannel(notificationChannel) From 1000727004bc21b119a46ae89e619257a6aa32e8 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 15 Oct 2025 20:40:59 +0200 Subject: [PATCH 18/25] Translated using Weblate (Hungarian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (57 of 57 strings) Translated using Weblate (Hungarian) Currently translated at 100.0% (11 of 11 strings) Co-authored-by: Godó Egyházi Co-authored-by: Hosted Weblate Translate-URL: https://hosted.weblate.org/projects/tomato/store-descriptions/hu/ Translate-URL: https://hosted.weblate.org/projects/tomato/strings/hu/ Translation: Tomato/Store descriptions Translation: Tomato/Strings --- app/src/main/res/values-hu/strings.xml | 58 ++++++++++++++++++- .../android/hu-HU/full_description.txt | 1 + .../android/hu-HU/short_description.txt | 1 + 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/hu-HU/full_description.txt create mode 100644 fastlane/metadata/android/hu-HU/short_description.txt diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 55344e5..8955466 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -1,3 +1,59 @@ - \ No newline at end of file + Indít + Leállít + Fókuszálás + Rövid szünet + Hosszú szünet + Kilépés + Átugrás + Jelzés leállítása + %1$s perc van hátra + Megállítva + Befejezve + Következő: %1$s (%2$s) + Következő indítása + Válassz színsémát + OK + Színséma + Dinamikus + Szín + Rendszer alapértelmezés + Jelzés + Világos + Sötét + Válassz témát + Produktivitás elemzése + Fókuszálás időtartama a nap különböző szakaszaiban + Jelzés hangja + Fekete téma + Használjon teljesen fekete sötét témát + Csengőhang, amikor az időzítő lejár + Rezgés + Rezgés, amikor az időzítő lejár + Téma + Beállítások + Munkamenet hossza + Fókusz-intervallumok száma: %1$d + Egy „munkamenet” egy sor pomodoro-intervallumból áll, amely fókusz-intervallumokat, rövid szüneteket és egy hosszú szünetet tartalmaz. A munkamenet utolsó szünete mindig hosszú szünet. + Statisztikák + Ma + Szünet + Múlt hét + naponta átlagosan fókuszált idő + További információk + Heti produktivitás elemzés + Múlt hónap + Havi produktivitás elemzés + Jelzés leállítása? + A jelenlegi időzítő munkamenet befejeződött. Érintse meg a képernyőt bárhol, hogy leállítsa a jelzést. + %1$d a %2$d-ből + Több + Megállít + Indítás + Újraindítás + Ugrás a következőre + Következik + Időzítő + Időzítő állása + diff --git a/fastlane/metadata/android/hu-HU/full_description.txt b/fastlane/metadata/android/hu-HU/full_description.txt new file mode 100644 index 0000000..247aaa2 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/full_description.txt @@ -0,0 +1 @@ +

A Tomato egy minimalista Pomodoro időzítő Androidra, ami Material 3 Expressive alapú.


Funkciók:

  • Egyszerű, minimalista felhasználói felület, a legújabb Material 3 Expressive irányelvek alapján.
  • Részletes statisztikák a munka/tanulási időkről, könnyen érthető módon
    • A mai nap statisztikái egy pillanat alatt áttekinthetők
    • Az elmúlt hét és hónap statisztikái könnyen olvasható, letisztult grafikonon
    • A múlt hét és hónap további statisztikái, amelyekből kiderül, hogy a nap melyik szakaszában vagy a legproduktívabb
  • Testreszabható időzítő paraméterek
diff --git a/fastlane/metadata/android/hu-HU/short_description.txt b/fastlane/metadata/android/hu-HU/short_description.txt new file mode 100644 index 0000000..6e775e7 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/short_description.txt @@ -0,0 +1 @@ +Minimalista Pomodoro időzítő From bb23f975b331896fec4a4590ae2bde0f2858bfb0 Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Thu, 16 Oct 2025 00:25:50 +0530 Subject: [PATCH 19/25] fix(timer): fix low top bar text contrast with 2025 color spec Closes: #68 --- .../java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt index e608cdc..515b73d 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt @@ -140,7 +140,7 @@ fun TimerScreen( fontFamily = robotoFlexTopBar, fontSize = 32.sp, lineHeight = 32.sp, - color = colorScheme.onErrorContainer + color = colorScheme.error ), textAlign = TextAlign.Center, modifier = Modifier.width(210.dp) @@ -153,7 +153,7 @@ fun TimerScreen( fontFamily = robotoFlexTopBar, fontSize = 32.sp, lineHeight = 32.sp, - color = colorScheme.onPrimaryContainer + color = colorScheme.primary ), textAlign = TextAlign.Center, modifier = Modifier.width(210.dp) @@ -165,7 +165,7 @@ fun TimerScreen( fontFamily = robotoFlexTopBar, fontSize = 32.sp, lineHeight = 32.sp, - color = colorScheme.onTertiaryContainer + color = colorScheme.tertiary ), textAlign = TextAlign.Center, modifier = Modifier.width(210.dp) @@ -177,7 +177,7 @@ fun TimerScreen( fontFamily = robotoFlexTopBar, fontSize = 32.sp, lineHeight = 32.sp, - color = colorScheme.onTertiaryContainer + color = colorScheme.tertiary ), textAlign = TextAlign.Center, modifier = Modifier.width(210.dp) From 8c629403a7c05397db3dba547f511fe32127b1d7 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 15 Oct 2025 23:40:50 +0200 Subject: [PATCH 20/25] Added translation using Weblate (Arabic) Co-authored-by: K-MAX --- app/src/main/res/values-ar/strings.xml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/src/main/res/values-ar/strings.xml diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-ar/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file From 47bb70181f68354f30b04c644ad87a35b68ccc23 Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Thu, 16 Oct 2025 08:12:54 +0530 Subject: [PATCH 21/25] fix(timer): make timer screen scrollable --- .../pomodoro/ui/timerScreen/TimerScreen.kt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt index 515b73d..629bc1b 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt @@ -35,6 +35,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ButtonGroup import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularWavyProgressIndicator @@ -51,6 +53,7 @@ import androidx.compose.material3.MaterialTheme.shapes import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -64,6 +67,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.res.painterResource @@ -115,7 +119,9 @@ fun TimerScreen( onResult = {} ) - Column(modifier = modifier) { + val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() + + Column(modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) { TopAppBar( title = { AnimatedContent( @@ -186,13 +192,16 @@ fun TimerScreen( } }, subtitle = {}, - titleHorizontalAlignment = CenterHorizontally + titleHorizontalAlignment = CenterHorizontally, + scrollBehavior = scrollBehavior ) Column( verticalArrangement = Arrangement.Center, horizontalAlignment = CenterHorizontally, - modifier = Modifier.fillMaxSize() + modifier = Modifier + .fillMaxSize() + .verticalScroll(rememberScrollState()) ) { Column(horizontalAlignment = CenterHorizontally) { Box(contentAlignment = Alignment.Center) { @@ -509,6 +518,8 @@ fun TimerScreen( ) } } + + Spacer(Modifier.height(16.dp)) } } } From c2c74c12d1bd43702a447b51acbf9f8846120601 Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Thu, 16 Oct 2025 08:26:43 +0530 Subject: [PATCH 22/25] fix(stats): auto resize text to better support narrow screens --- .../pomodoro/ui/statsScreen/StatsScreen.kt | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt index 1f7c8c3..4a261e4 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/StatsScreen.kt @@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.text.TextAutoSize import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.FilledTonalIconToggleButton @@ -31,6 +32,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.motionScheme import androidx.compose.material3.MaterialTheme.typography +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -47,7 +49,6 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -56,12 +57,14 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter import com.patrykandpatrick.vico.core.cartesian.data.columnSeries +import com.patrykandpatrick.vico.core.cartesian.data.lineSeries import com.patrykandpatrick.vico.core.common.data.ExtraStore import org.nsh07.pomodoro.R import org.nsh07.pomodoro.data.Stat import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel import org.nsh07.pomodoro.ui.theme.AppFonts.openRundeClock import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar +import org.nsh07.pomodoro.ui.theme.TomatoTheme import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes @Composable @@ -191,7 +194,9 @@ fun StatsScreen( }, style = typography.displaySmall, fontFamily = openRundeClock, - color = colorScheme.onPrimaryContainer + color = colorScheme.onPrimaryContainer, + maxLines = 1, + autoSize = TextAutoSize.StepBased(maxFontSize = typography.displaySmall.fontSize) ) } } @@ -216,7 +221,9 @@ fun StatsScreen( }, style = typography.displaySmall, fontFamily = openRundeClock, - color = colorScheme.onTertiaryContainer + color = colorScheme.onTertiaryContainer, + maxLines = 1, + autoSize = TextAutoSize.StepBased(maxFontSize = typography.displaySmall.fontSize) ) } } @@ -424,8 +431,7 @@ fun StatsScreen( } @Preview( - showSystemUi = true, - device = Devices.PIXEL_9_PRO + widthDp = 400 ) @Composable fun StatsScreenPreview() { @@ -435,20 +441,25 @@ fun StatsScreenPreview() { LaunchedEffect(Unit) { modelProducer.runTransaction { columnSeries { - series(5, 6, 5, 2, 11, 8, 5, 2, 15, 11, 8, 13, 12, 10, 2, 7) + series(5, 6, 5, 2, 11, 8, 5) } + lineSeries {} extras { it[keys] = listOf("M", "T", "W", "T", "F", "S", "S") } } } - StatsScreen( - PaddingValues(), - Pair(modelProducer, keys), - Pair(modelProducer, keys), - Pair(modelProducer, keys), - null, - listOf(0, 0, 0, 0), - listOf(0, 0, 0, 0), - listOf(0, 0, 0, 0) - ) + TomatoTheme { + Surface { + StatsScreen( + PaddingValues(), + Pair(modelProducer, keys), + Pair(modelProducer, keys), + Pair(modelProducer, keys), + null, + listOf(0, 0, 0, 0), + listOf(0, 0, 0, 0), + listOf(0, 0, 0, 0) + ) + } + } } \ No newline at end of file From de3dec970c9953eafdeb3250817f81d971973cd9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 09:44:59 +0000 Subject: [PATCH 23/25] fix(deps): update all non-major dependencies --- gradle/libs.versions.toml | 12 ++++++------ gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 3 --- gradlew.bat | 3 +-- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ed4870e..31fb247 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,19 +1,19 @@ [versions] activityCompose = "1.11.0" adaptive = "1.1.0" -agp = "8.11.2" -composeBom = "2025.09.01" +agp = "8.13.0" +composeBom = "2025.10.00" coreKtx = "1.17.0" espressoCore = "3.7.0" junit = "4.13.2" junitVersion = "1.3.0" kotlin = "2.2.20" -ksp = "2.2.20-2.0.3" +ksp = "2.2.20-2.0.4" lifecycleRuntimeKtx = "2.9.4" materialKolor = "3.0.1" -navigation3 = "1.0.0-alpha10" -room = "2.8.1" -vico = "2.2.0" +navigation3 = "1.0.0-alpha11" +room = "2.8.2" +vico = "2.2.1" [libraries] androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2a84e18..2e11132 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index ef07e01..adff685 100755 --- a/gradlew +++ b/gradlew @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/gradlew.bat b/gradlew.bat index 5eed7ee..e509b2d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell From acf2ad7448e0599797f9069e71fb6b528df1b601 Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Thu, 16 Oct 2025 08:52:25 +0530 Subject: [PATCH 24/25] fix(build): fix failing build due to API changes --- .../java/org/nsh07/pomodoro/ui/AppScreen.kt | 2 +- .../pomodoro/ui/timerScreen/TimerScreen.kt | 40 +++++++------------ 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/AppScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/AppScreen.kt index 8e84a98..59390fd 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/AppScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/AppScreen.kt @@ -68,7 +68,7 @@ fun AppScreen( val motionScheme = motionScheme val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass - val backStack = rememberNavBackStack(Screen.Timer) + val backStack = rememberNavBackStack(Screen.Timer) if (uiState.alarmRinging) AlarmDialog { diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt index 629bc1b..6fb988b 100644 --- a/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt +++ b/app/src/main/java/org/nsh07/pomodoro/ui/timerScreen/TimerScreen.kt @@ -38,6 +38,7 @@ import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ButtonGroup +import androidx.compose.material3.ButtonGroupDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularWavyProgressIndicator import androidx.compose.material3.DropdownMenuItem @@ -51,6 +52,7 @@ import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.MaterialTheme.motionScheme import androidx.compose.material3.MaterialTheme.shapes import androidx.compose.material3.MaterialTheme.typography +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -286,27 +288,11 @@ fun TimerScreen( val interactionSources = remember { List(3) { MutableInteractionSource() } } ButtonGroup( overflowIndicator = { state -> - FilledTonalIconButton( - onClick = { - if (state.isExpanded) { - state.dismiss() - } else { - state.show() - } - }, - colors = IconButtonDefaults.filledTonalIconButtonColors( - containerColor = colorContainer - ), - shapes = IconButtonDefaults.shapes(), - modifier = Modifier - .size(64.dp, 96.dp) - ) { - Icon( - painterResource(R.drawable.more_vert_large), - contentDescription = stringResource(R.string.more), - modifier = Modifier.size(32.dp) - ) - } + ButtonGroupDefaults.OverflowIndicator( + state, + colors = IconButtonDefaults.filledTonalIconButtonColors(), + modifier = Modifier.size(64.dp, 96.dp) + ) }, modifier = Modifier.padding(16.dp) ) { @@ -534,10 +520,12 @@ fun TimerScreenPreview() { timeStr = "03:34", nextTimeStr = "5:00", timerMode = TimerMode.FOCUS, timerRunning = true ) TomatoTheme { - TimerScreen( - timerState, - { 0.3f }, - {} - ) + Surface { + TimerScreen( + timerState, + { 0.3f }, + {} + ) + } } } From bd71b55baf18e12e0b91353b3af7ffef227a657a Mon Sep 17 00:00:00 2001 From: Nishant Mishra Date: Thu, 16 Oct 2025 12:40:55 +0530 Subject: [PATCH 25/25] chore(release): Bump version string, update changelog --- app/build.gradle.kts | 4 ++-- fastlane/metadata/android/en-US/changelogs/12.txt | 12 ++++++++++++ gradle/libs.versions.toml | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/12.txt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 77e1df8..1475dce 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -33,8 +33,8 @@ android { applicationId = "org.nsh07.pomodoro" minSdk = 26 targetSdk = 36 - versionCode = 11 - versionName = "1.4.3" + versionCode = 12 + versionName = "1.5.0-alpha01" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/fastlane/metadata/android/en-US/changelogs/12.txt b/fastlane/metadata/android/en-US/changelogs/12.txt new file mode 100644 index 0000000..01a6a5e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/12.txt @@ -0,0 +1,12 @@ +New features: +- The Stats screen now contains the data for the past year +- Charts now have fading edges to indicate scrollable content + +Fixes: +- Improved Stats screen performance +- Notification now does not pop up on your screen +- Fixed low contrast on the Timer screen heading +- Improve app usability on smaller screens + +Translators on Weblate added support for: +Arabic, Czech, German, Hungarian, Italian, Japanese, Kurdish (Central), Minnan (Traditional), Portuguese (Brazil), Spanish \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 31fb247..0e776d2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] activityCompose = "1.11.0" adaptive = "1.1.0" -agp = "8.13.0" +agp = "8.11.2" composeBom = "2025.10.00" coreKtx = "1.17.0" espressoCore = "3.7.0"