diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1475dce..e9f14c9 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 = 12 - versionName = "1.5.0-alpha01" + versionCode = 13 + versionName = "1.5.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -62,6 +62,7 @@ android { } buildFeatures { compose = true + buildConfig = true } dependenciesInfo { includeInApk = false diff --git a/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt b/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt index 07de4c2..49012df 100644 --- a/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt +++ b/app/src/main/java/org/nsh07/pomodoro/service/TimerService.kt @@ -102,8 +102,10 @@ class TimerService : Service() { Actions.RESET.toString() -> { if (timerState.value.timerRunning) toggleTimer() - resetTimer() - stopForegroundService() + skipScope.launch { + resetTimer() + stopForegroundService() + } } Actions.SKIP.toString() -> skipTimer(true) @@ -278,27 +280,25 @@ class TimerService : Service() { } } - private fun resetTimer() { + private suspend fun resetTimer() { updateProgressSegments() - skipScope.launch { - saveTimeToDb() - time = timerRepository.focusTime - cycles = 0 - startTime = 0L - pauseTime = 0L - pauseDuration = 0L + saveTimeToDb() + time = timerRepository.focusTime + cycles = 0 + startTime = 0L + pauseTime = 0L + pauseDuration = 0L - _timerState.update { currentState -> - currentState.copy( - timerMode = TimerMode.FOCUS, - timeStr = millisecondsToStr(time), - totalTime = time, - nextTimerMode = if (timerRepository.sessionLength > 1) TimerMode.SHORT_BREAK else TimerMode.LONG_BREAK, - nextTimeStr = millisecondsToStr(if (timerRepository.sessionLength > 1) timerRepository.shortBreakTime else timerRepository.longBreakTime), - currentFocusCount = 1, - totalFocusCount = timerRepository.sessionLength - ) - } + _timerState.update { currentState -> + currentState.copy( + timerMode = TimerMode.FOCUS, + timeStr = millisecondsToStr(time), + totalTime = time, + nextTimerMode = if (timerRepository.sessionLength > 1) TimerMode.SHORT_BREAK else TimerMode.LONG_BREAK, + nextTimeStr = millisecondsToStr(if (timerRepository.sessionLength > 1) timerRepository.shortBreakTime else timerRepository.longBreakTime), + currentFocusCount = 1, + totalFocusCount = timerRepository.sessionLength + ) } } 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 4a261e4..27051d9 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 @@ -19,6 +19,7 @@ import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.text.TextAutoSize @@ -26,6 +27,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.FilledTonalIconToggleButton import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.MaterialTheme @@ -59,6 +61,7 @@ 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.BuildConfig import org.nsh07.pomodoro.R import org.nsh07.pomodoro.data.Stat import org.nsh07.pomodoro.ui.statsScreen.viewModel.StatsViewModel @@ -93,6 +96,7 @@ fun StatsScreenRoot( lastWeekAverageFocusTimes = lastWeekAnalysisValues, lastMonthAverageFocusTimes = lastMonthAnalysisValues, lastYearAverageFocusTimes = lastYearAnalysisValues, + generateSampleData = viewModel::generateSampleData, modifier = modifier ) } @@ -108,6 +112,7 @@ fun StatsScreen( lastWeekAverageFocusTimes: List, lastMonthAverageFocusTimes: List, lastYearAverageFocusTimes: List, + generateSampleData: () -> Unit, modifier: Modifier = Modifier ) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() @@ -152,6 +157,17 @@ fun StatsScreen( .padding(vertical = 14.dp) ) }, + actions = if (BuildConfig.DEBUG) { + { + IconButton( + onClick = generateSampleData + ) { + Spacer(Modifier.size(24.dp)) + } + } + } else { + {} + }, subtitle = {}, titleHorizontalAlignment = Alignment.CenterHorizontally, scrollBehavior = scrollBehavior, @@ -458,7 +474,8 @@ fun StatsScreenPreview() { null, listOf(0, 0, 0, 0), listOf(0, 0, 0, 0), - listOf(0, 0, 0, 0) + listOf(0, 0, 0, 0), + {} ) } } 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 2b907d5..7ed4423 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 @@ -22,14 +22,18 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch +import org.nsh07.pomodoro.BuildConfig import org.nsh07.pomodoro.TomatoApplication +import org.nsh07.pomodoro.data.Stat import org.nsh07.pomodoro.data.StatRepository +import java.time.LocalDate import java.time.format.DateTimeFormatter import java.time.format.TextStyle import java.util.Locale class StatsViewModel( - statRepository: StatRepository + private val statRepository: StatRepository ) : ViewModel() { val todayStat = statRepository.getTodayStat().distinctUntilChanged() @@ -151,6 +155,31 @@ class StatsViewModel( initialValue = listOf(0, 0, 0, 0) ) + fun generateSampleData() { + if (BuildConfig.DEBUG) { + viewModelScope.launch { + val today = LocalDate.now().plusDays(1) + var it = today.minusDays(40) + + while (it.isBefore(today)) { + statRepository.insertStat( + Stat( + it, + (0..30 * 60 * 1000L).random(), + (1 * 60 * 60 * 1000L..3 * 60 * 60 * 1000L).random(), + (0..3 * 60 * 60 * 1000L).random(), + (0..1 * 60 * 60 * 1000L).random(), + 0 + ) + ) + it = it.plusDays(1) + } + + statRepository.addBreakTime((0..30 * 60 * 60 * 1000L).random()) + } + } + } + companion object { val Factory: ViewModelProvider.Factory = viewModelFactory { initializer { 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 6fb988b..bdb563d 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 @@ -138,7 +138,9 @@ fun TimerScreen( targetOffsetY = { (it * 1.25).toInt() } ) ) - } + }, + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxWidth() ) { when (it) { TimerMode.BRAND -> @@ -150,8 +152,7 @@ fun TimerScreen( lineHeight = 32.sp, color = colorScheme.error ), - textAlign = TextAlign.Center, - modifier = Modifier.width(210.dp) + textAlign = TextAlign.Center ) TimerMode.FOCUS -> @@ -163,8 +164,7 @@ fun TimerScreen( lineHeight = 32.sp, color = colorScheme.primary ), - textAlign = TextAlign.Center, - modifier = Modifier.width(210.dp) + textAlign = TextAlign.Center ) TimerMode.SHORT_BREAK -> Text( @@ -175,8 +175,7 @@ fun TimerScreen( lineHeight = 32.sp, color = colorScheme.tertiary ), - textAlign = TextAlign.Center, - modifier = Modifier.width(210.dp) + textAlign = TextAlign.Center ) TimerMode.LONG_BREAK -> Text( @@ -187,8 +186,7 @@ fun TimerScreen( lineHeight = 32.sp, color = colorScheme.tertiary ), - textAlign = TextAlign.Center, - modifier = Modifier.width(210.dp) + textAlign = TextAlign.Center ) } } diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 55344e5..09780a8 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -1,3 +1,60 @@ - \ No newline at end of file + تشغيل + إيقاف + تركيز + استراحة قصيرة + استراحة طويلة + خروج + تخطي + إيقاف المنبه + %1$s دقيقة متبقية + متوقف + انتهي + القادم: %1$s (%2$s) + ابدأ التالي + اختر مجموعة الالوان + حسناً + مجموعة الالوان + ديناميكي + لون + النظام (الافتراضي) + منبه + فاتح + داكن + اختر سمة + تحليل الإنتاجية + مدة التركيز في أوقات مختلفة في اليوم + صوت المنبه + الوضع الاسود + استخدم سمة اسود نقي + التنبيه عند انتهاء المؤقت + اهتزاز + الاهتزاز عندما ينتهي المؤقت + سمة + الاعدادات + طول الجلسة + فترات التركيز في الجلسة الواحدة: %1$d + \"الجلسة\" هي تسلسل فترات بومودورو التي تحتوي علي فترات التركيز، فترة الاستراحة القصيرة و فترة الاستراحة الطويلة. آخر استراحة في الجلسة هي دائما استراحة كبيرة. + الإحصائيات + اليوم + استراحة + الاسبوع الماضي + مدة التركيز في اليوم (المتوسط) + معلومات أكثر + تحليل الإنتاجية الاسبوعي + الشهر الماضي + تحليل الإنتاجية الشهري + إيقاف المنبه؟ + مؤقت الجلسة الحالية انتهي. اضغط في أي مكان لإيقاف المنبه. + %1$d من %2$d + أكثر + إيقاف + أبدا + إعادة التعيين + تخطي الي التالي + القادم + المؤقت + تقدم المؤقت + السنة الماضية + diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index b25d003..f20c905 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -2,10 +2,10 @@ Почати Стоп - Концентрація + Фокус Коротка перерва Довга перерва - Вийти + Завершити Пропустити Колірна схема Аналіз продуктивності @@ -35,7 +35,7 @@ ОК Динамічна Колір - За замовчуванням (система) + Налаштування системи Сигнал Світла Темна @@ -43,17 +43,18 @@ Тривалість концентрації в різні години дня Звук сигналу Використовувати чисту чорну тему - Звуковий сигнал по завершенні таймера + Звуковий сигнал після завершення таймера Увімкнути вібрацію після завершення таймера Інтервали концентрації уваги в одній сесії: %1$d - «Сесія» - це послідовність інтервалів Pomodoro, що містить інтервали концентрації, короткі перерви та довгу перерву. Остання перерва сесії є завжди довгою. + «Сесія» - це послідовність інтервалів Pomodoro, що містить інтервали концентрації, короткі перерви та довгу перерву. Остання перерва сесії завжди є довгою. Перерва Минулого тижня - концентрацій на день (середнє значення) + концентрації на день (сер.) Зупинити сигнал? Поточна сесія таймера завершена. Натисніть будь-де, щоб зупинити сигнал. %1$d з %2$d Більше Пауза Грати + Минулого року diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values-vi/strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml new file mode 100644 index 0000000..6260170 --- /dev/null +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -0,0 +1,60 @@ + + + 開始 + 停止 + 專注 + 短休息 + 長休息 + 退出 + 跳過 + 停止鬧鐘 + 剩餘%1$s + 已暫停 + 已完成 + 下一個: %1$s (%2$s) + 開始下一個 + 選擇配色方案 + 好的 + 配色方案 + 動態 + 顏色 + 系統默認 + 鬧鐘 + 亮色 + 暗色 + 選擇主題 + 生產力分析 + 一天中不同時間的專注持續時間 + 鬧鐘鈴聲 + 純黑主題 + 使用純黑色主題 + 計時器完成時響起鬧鈴 + 振動 + 當計時器完成時震動 + 主题 + 设置 + 会话时长 + 单次专注时间间隔: %1$d + 一个“会话”是由多个番茄钟组成的序列,其中包含专注时间段、短休息和长休息。一个会话中的最后一次休息必然是长休息。 + 统计 + 今天 + 休息 + 上周 + 每天平均專注時間 + 更多資訊 + 每週生產力分析 + 上月 + 每月生产力分析 + 停止鬧鐘? + 當前計時器會話已經完成。 點擊任意位置停止鬧鐘。 + %1$d of %2$d + 更多 + 暂停 + 开始 + 重置 + 跳至下一个 + 接下来 + 计时 + 计时进度 + 上年 + diff --git a/fastlane/metadata/android/ar/full_description.txt b/fastlane/metadata/android/ar/full_description.txt new file mode 100644 index 0000000..18b900d --- /dev/null +++ b/fastlane/metadata/android/ar/full_description.txt @@ -0,0 +1 @@ +

Tomato هو مؤقت بومودورو بسيط (Pomodoro timer) لنظام أندرويد يعتمد على تصميم Material 3 Expressive.


الميزات:

  • واجهة مستخدم بسيطة تعتمد على أحدث إرشادات Material 3 Expressive
  • إحصائيات مفصلة لأوقات العمل/الدراسة بطريقة سهلة الفهم
    • إحصائيات اليوم الحالي مرئية بلمحة سريعة
    • إحصائيات الأسبوع الماضي والشهر الماضي معروضة في رسم بياني نظيف وسهل القراءة
    • إحصائيات إضافية للأسبوع والشهر الماضيين توضح في أي وقت من اليوم تكون أكثر إنتاجية
  • إعدادات المؤقت قابلة للتخصيص
diff --git a/fastlane/metadata/android/ar/short_description.txt b/fastlane/metadata/android/ar/short_description.txt new file mode 100644 index 0000000..7d06a73 --- /dev/null +++ b/fastlane/metadata/android/ar/short_description.txt @@ -0,0 +1 @@ +مؤقت بومودورو بسيط diff --git a/fastlane/metadata/android/cs-CZ/short_description.txt b/fastlane/metadata/android/cs-CZ/short_description.txt new file mode 100644 index 0000000..a3098b6 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/short_description.txt @@ -0,0 +1 @@ +Minimalistický Pomodoro časovač diff --git a/fastlane/metadata/android/en-US/changelogs/13.txt b/fastlane/metadata/android/en-US/changelogs/13.txt new file mode 100644 index 0000000..d1cb604 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/13.txt @@ -0,0 +1,14 @@ +Bug fixes and translation expansion over 1.5.0-alpha01 + +Full changelog for 1.5.0: +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 + +Expanded translations \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 08ad929..b5a1959 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -1 +1,12 @@ -

Tomato is a minimalist Pomodoro timer for Android based on Material 3 Expressive.


Features:

  • Simple, minimalist UI based on the latest Material 3 Expressive guidelines
  • Detailed statistics of work/study times in an easy to understand manner
    • Stats for the current day visible at a glance
    • Stats for the last week and last month shown in an easy to read, clean graph
    • Additional stats for last week and month showing at what time of the day you're the most productive
  • Customizable timer parameters
\ No newline at end of file +Tomato is a minimalist Pomodoro timer for Android based on Material 3 Expressive. + +Tomato is fully free and open-source, forever. You can find the source code and report bugs or suggest features at https://github.com/nsh07/Tomato + +Features: +- Simple, minimalist UI based on the latest Material 3 Expressive guidelines +- Detailed statistics of work/study times in an easy to understand manner + - Stats for the current day visible at a glance + - Stats for the last week and last month shown in an easy to read, clean graph + - Additional stats for last week and month showing at what time of the day you're the most productive +- Customizable timer parameters +- Support for Android 16 Live Updates \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/images/featureGraphic.png b/fastlane/metadata/android/en-US/images/featureGraphic.png index 916999e..a31b206 100644 Binary files a/fastlane/metadata/android/en-US/images/featureGraphic.png and b/fastlane/metadata/android/en-US/images/featureGraphic.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png index 65c74b9..e16947b 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png index e41b904..9c50c63 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png index 3785c3d..6c383a4 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png index 9ce6efb..5fceeba 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png index c5a3722..93ff5e9 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png index dd24621..a3304ea 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png differ