Merge branch 'dev'
This commit is contained in:
@@ -1,128 +0,0 @@
|
|||||||
# Contributor Covenant Code of Conduct
|
|
||||||
|
|
||||||
## Our Pledge
|
|
||||||
|
|
||||||
We as members, contributors, and leaders pledge to make participation in our
|
|
||||||
community a harassment-free experience for everyone, regardless of age, body
|
|
||||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
||||||
identity and expression, level of experience, education, socio-economic status,
|
|
||||||
nationality, personal appearance, race, religion, or sexual identity
|
|
||||||
and orientation.
|
|
||||||
|
|
||||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
||||||
diverse, inclusive, and healthy community.
|
|
||||||
|
|
||||||
## Our Standards
|
|
||||||
|
|
||||||
Examples of behavior that contributes to a positive environment for our
|
|
||||||
community include:
|
|
||||||
|
|
||||||
* Demonstrating empathy and kindness toward other people
|
|
||||||
* Being respectful of differing opinions, viewpoints, and experiences
|
|
||||||
* Giving and gracefully accepting constructive feedback
|
|
||||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
||||||
and learning from the experience
|
|
||||||
* Focusing on what is best not just for us as individuals, but for the
|
|
||||||
overall community
|
|
||||||
|
|
||||||
Examples of unacceptable behavior include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery, and sexual attention or
|
|
||||||
advances of any kind
|
|
||||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing others' private information, such as a physical or email
|
|
||||||
address, without their explicit permission
|
|
||||||
* Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
## Enforcement Responsibilities
|
|
||||||
|
|
||||||
Community leaders are responsible for clarifying and enforcing our standards of
|
|
||||||
acceptable behavior and will take appropriate and fair corrective action in
|
|
||||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
||||||
or harmful.
|
|
||||||
|
|
||||||
Community leaders have the right and responsibility to remove, edit, or reject
|
|
||||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
||||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
||||||
decisions when appropriate.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
This Code of Conduct applies within all community spaces, and also applies when
|
|
||||||
an individual is officially representing the community in public spaces.
|
|
||||||
Examples of representing our community include using an official e-mail address,
|
|
||||||
posting via an official social media account, or acting as an appointed
|
|
||||||
representative at an online or offline event.
|
|
||||||
|
|
||||||
## Enforcement
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
||||||
reported to the community leaders responsible for enforcement at
|
|
||||||
nishant.28@outlook.com.
|
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the
|
|
||||||
reporter of any incident.
|
|
||||||
|
|
||||||
## Enforcement Guidelines
|
|
||||||
|
|
||||||
Community leaders will follow these Community Impact Guidelines in determining
|
|
||||||
the consequences for any action they deem in violation of this Code of Conduct:
|
|
||||||
|
|
||||||
### 1. Correction
|
|
||||||
|
|
||||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
||||||
unprofessional or unwelcome in the community.
|
|
||||||
|
|
||||||
**Consequence**: A private, written warning from community leaders, providing
|
|
||||||
clarity around the nature of the violation and an explanation of why the
|
|
||||||
behavior was inappropriate. A public apology may be requested.
|
|
||||||
|
|
||||||
### 2. Warning
|
|
||||||
|
|
||||||
**Community Impact**: A violation through a single incident or series
|
|
||||||
of actions.
|
|
||||||
|
|
||||||
**Consequence**: A warning with consequences for continued behavior. No
|
|
||||||
interaction with the people involved, including unsolicited interaction with
|
|
||||||
those enforcing the Code of Conduct, for a specified period of time. This
|
|
||||||
includes avoiding interactions in community spaces as well as external channels
|
|
||||||
like social media. Violating these terms may lead to a temporary or
|
|
||||||
permanent ban.
|
|
||||||
|
|
||||||
### 3. Temporary Ban
|
|
||||||
|
|
||||||
**Community Impact**: A serious violation of community standards, including
|
|
||||||
sustained inappropriate behavior.
|
|
||||||
|
|
||||||
**Consequence**: A temporary ban from any sort of interaction or public
|
|
||||||
communication with the community for a specified period of time. No public or
|
|
||||||
private interaction with the people involved, including unsolicited interaction
|
|
||||||
with those enforcing the Code of Conduct, is allowed during this period.
|
|
||||||
Violating these terms may lead to a permanent ban.
|
|
||||||
|
|
||||||
### 4. Permanent Ban
|
|
||||||
|
|
||||||
**Community Impact**: Demonstrating a pattern of violation of community
|
|
||||||
standards, including sustained inappropriate behavior, harassment of an
|
|
||||||
individual, or aggression toward or disparagement of classes of individuals.
|
|
||||||
|
|
||||||
**Consequence**: A permanent ban from any sort of public interaction within
|
|
||||||
the community.
|
|
||||||
|
|
||||||
## Attribution
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
||||||
version 2.0, available at
|
|
||||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
|
||||||
|
|
||||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
|
||||||
enforcement ladder](https://github.com/mozilla/diversity).
|
|
||||||
|
|
||||||
[homepage]: https://www.contributor-covenant.org
|
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see the FAQ at
|
|
||||||
https://www.contributor-covenant.org/faq. Translations are available at
|
|
||||||
https://www.contributor-covenant.org/translations.
|
|
||||||
@@ -33,8 +33,8 @@ android {
|
|||||||
applicationId = "org.nsh07.pomodoro"
|
applicationId = "org.nsh07.pomodoro"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 10
|
versionCode = 11
|
||||||
versionName = "1.4.2"
|
versionName = "1.4.3"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,11 +42,16 @@ interface StatDao {
|
|||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT " +
|
"SELECT " +
|
||||||
"AVG(NULLIF(focusTimeQ1,0)) AS focusTimeQ1, " +
|
"AVG(focusTimeQ1) AS focusTimeQ1, " +
|
||||||
"AVG(NULLIF(focusTimeQ2,0)) AS focusTimeQ2, " +
|
"AVG(focusTimeQ2) AS focusTimeQ2, " +
|
||||||
"AVG(NULLIF(focusTimeQ3,0)) AS focusTimeQ3, " +
|
"AVG(focusTimeQ3) AS focusTimeQ3, " +
|
||||||
"AVG(NULLIF(focusTimeQ4,0)) AS focusTimeQ4 " +
|
"AVG(focusTimeQ4) AS focusTimeQ4 " +
|
||||||
"FROM (SELECT focusTimeQ1, focusTimeQ2, focusTimeQ3, focusTimeQ4 FROM stat ORDER BY date DESC LIMIT :n)"
|
"FROM (" +
|
||||||
|
"SELECT * FROM (" +
|
||||||
|
"SELECT focusTimeQ1, focusTimeQ2, focusTimeQ3, focusTimeQ4 FROM stat ORDER BY date DESC LIMIT :n" +
|
||||||
|
") " +
|
||||||
|
"WHERE focusTimeQ1 != 0 OR focusTimeQ2 != 0 OR focusTimeQ3 != 0 OR focusTimeQ4 != 0 " +
|
||||||
|
")"
|
||||||
)
|
)
|
||||||
fun getLastNDaysAvgFocusTimes(n: Int): Flow<StatFocusTime?>
|
fun getLastNDaysAvgFocusTimes(n: Int): Flow<StatFocusTime?>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.nsh07.pomodoro.service
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.media.AudioAttributes
|
||||||
import android.media.MediaPlayer
|
import android.media.MediaPlayer
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
@@ -78,7 +79,7 @@ class TimerService : Service() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
timerRepository.serviceRunning = true
|
timerRepository.serviceRunning = true
|
||||||
alarm = MediaPlayer.create(this, timerRepository.alarmSoundUri)
|
alarm = initializeMediaPlayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
@@ -387,9 +388,29 @@ class TimerService : Service() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initializeMediaPlayer(): MediaPlayer? {
|
||||||
|
return try {
|
||||||
|
MediaPlayer().apply {
|
||||||
|
setAudioAttributes(
|
||||||
|
AudioAttributes.Builder()
|
||||||
|
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||||
|
.setUsage(AudioAttributes.USAGE_ALARM)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
timerRepository.alarmSoundUri?.let {
|
||||||
|
setDataSource(applicationContext, it)
|
||||||
|
prepare()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun updateAlarmTone() {
|
fun updateAlarmTone() {
|
||||||
alarm?.release()
|
alarm?.release()
|
||||||
alarm = MediaPlayer.create(this, timerRepository.alarmSoundUri)
|
alarm = initializeMediaPlayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun saveTimeToDb() {
|
suspend fun saveTimeToDb() {
|
||||||
@@ -417,4 +438,4 @@ class TimerService : Service() {
|
|||||||
enum class Actions {
|
enum class Actions {
|
||||||
TOGGLE, SKIP, RESET, STOP_ALARM, UPDATE_ALARM_TONE
|
TOGGLE, SKIP, RESET, STOP_ALARM, UPDATE_ALARM_TONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import org.nsh07.pomodoro.data.TimerRepository
|
|||||||
@OptIn(FlowPreview::class, ExperimentalMaterial3Api::class)
|
@OptIn(FlowPreview::class, ExperimentalMaterial3Api::class)
|
||||||
class SettingsViewModel(
|
class SettingsViewModel(
|
||||||
private val preferenceRepository: AppPreferenceRepository,
|
private val preferenceRepository: AppPreferenceRepository,
|
||||||
private val timerRepository: TimerRepository
|
private val timerRepository: TimerRepository,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _preferencesState = MutableStateFlow(PreferencesState())
|
private val _preferencesState = MutableStateFlow(PreferencesState())
|
||||||
val preferencesState = _preferencesState.asStateFlow()
|
val preferencesState = _preferencesState.asStateFlow()
|
||||||
@@ -50,12 +50,14 @@ class SettingsViewModel(
|
|||||||
TextFieldState((timerRepository.longBreakTime / 60000).toString())
|
TextFieldState((timerRepository.longBreakTime / 60000).toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
val sessionsSliderState = SliderState(
|
val sessionsSliderState by lazy {
|
||||||
value = timerRepository.sessionLength.toFloat(),
|
SliderState(
|
||||||
steps = 4,
|
value = timerRepository.sessionLength.toFloat(),
|
||||||
valueRange = 1f..6f,
|
steps = 4,
|
||||||
onValueChangeFinished = ::updateSessionLength
|
valueRange = 1f..6f,
|
||||||
)
|
onValueChangeFinished = ::updateSessionLength
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val currentAlarmSound = timerRepository.alarmSoundUri.toString()
|
val currentAlarmSound = timerRepository.alarmSoundUri.toString()
|
||||||
|
|
||||||
@@ -203,9 +205,9 @@ class SettingsViewModel(
|
|||||||
|
|
||||||
SettingsViewModel(
|
SettingsViewModel(
|
||||||
preferenceRepository = appPreferenceRepository,
|
preferenceRepository = appPreferenceRepository,
|
||||||
timerRepository = appTimerRepository
|
timerRepository = appTimerRepository,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,11 @@
|
|||||||
|
|
||||||
package org.nsh07.pomodoro.ui.statsScreen
|
package org.nsh07.pomodoro.ui.statsScreen
|
||||||
|
|
||||||
import android.graphics.Path
|
|
||||||
import android.graphics.RectF
|
|
||||||
import androidx.compose.animation.core.AnimationSpec
|
import androidx.compose.animation.core.AnimationSpec
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import androidx.compose.material3.MaterialTheme.motionScheme
|
import androidx.compose.material3.MaterialTheme.motionScheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
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.CartesianChartHost
|
||||||
@@ -35,7 +32,9 @@ import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
|
|||||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
|
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
|
||||||
import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer
|
import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer
|
||||||
import com.patrykandpatrick.vico.core.common.Fill
|
import com.patrykandpatrick.vico.core.common.Fill
|
||||||
|
import com.patrykandpatrick.vico.core.common.shape.CorneredShape
|
||||||
import org.nsh07.pomodoro.utils.millisecondsToHours
|
import org.nsh07.pomodoro.utils.millisecondsToHours
|
||||||
|
import org.nsh07.pomodoro.utils.millisecondsToMinutes
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -45,14 +44,15 @@ internal fun TimeColumnChart(
|
|||||||
thickness: Dp = 40.dp,
|
thickness: Dp = 40.dp,
|
||||||
columnCollectionSpacing: Dp = 4.dp,
|
columnCollectionSpacing: Dp = 4.dp,
|
||||||
xValueFormatter: CartesianValueFormatter = CartesianValueFormatter.Default,
|
xValueFormatter: CartesianValueFormatter = CartesianValueFormatter.Default,
|
||||||
yValueFormatter: CartesianValueFormatter = CartesianValueFormatter { measuringContext, value, _ ->
|
yValueFormatter: CartesianValueFormatter = CartesianValueFormatter { _, value, _ ->
|
||||||
millisecondsToHours(value.toLong())
|
if (value >= 60 * 60 * 1000) {
|
||||||
|
millisecondsToHours(value.toLong())
|
||||||
|
} else {
|
||||||
|
millisecondsToMinutes(value.toLong())
|
||||||
|
}
|
||||||
},
|
},
|
||||||
animationSpec: AnimationSpec<Float>? = motionScheme.slowEffectsSpec()
|
animationSpec: AnimationSpec<Float>? = motionScheme.slowEffectsSpec()
|
||||||
) {
|
) {
|
||||||
val radius = with(LocalDensity.current) {
|
|
||||||
(thickness / 2).toPx()
|
|
||||||
}
|
|
||||||
ProvideVicoTheme(rememberM3VicoTheme()) {
|
ProvideVicoTheme(rememberM3VicoTheme()) {
|
||||||
CartesianChartHost(
|
CartesianChartHost(
|
||||||
chart =
|
chart =
|
||||||
@@ -63,29 +63,7 @@ internal fun TimeColumnChart(
|
|||||||
rememberLineComponent(
|
rememberLineComponent(
|
||||||
fill = fill(color),
|
fill = fill(color),
|
||||||
thickness = thickness,
|
thickness = thickness,
|
||||||
shape = { _, path, left, top, right, bottom ->
|
shape = CorneredShape.Pill
|
||||||
if (top + radius <= bottom - radius) {
|
|
||||||
path.arcTo(
|
|
||||||
RectF(left, top, right, top + 2 * radius),
|
|
||||||
180f,
|
|
||||||
180f
|
|
||||||
)
|
|
||||||
path.lineTo(right, bottom - radius)
|
|
||||||
path.arcTo(
|
|
||||||
RectF(left, bottom - 2 * radius, right, bottom),
|
|
||||||
0f,
|
|
||||||
180f
|
|
||||||
)
|
|
||||||
path.close()
|
|
||||||
} else {
|
|
||||||
path.addCircle(
|
|
||||||
left + radius,
|
|
||||||
bottom - radius,
|
|
||||||
radius,
|
|
||||||
Path.Direction.CW
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -30,6 +30,15 @@ fun millisecondsToHours(t: Long): String {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun millisecondsToMinutes(t: Long): String {
|
||||||
|
require(t >= 0L)
|
||||||
|
return String.format(
|
||||||
|
Locale.getDefault(),
|
||||||
|
"%dm",
|
||||||
|
TimeUnit.MILLISECONDS.toMinutes(t)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun millisecondsToHoursMinutes(t: Long): String {
|
fun millisecondsToHoursMinutes(t: Long): String {
|
||||||
require(t >= 0L)
|
require(t >= 0L)
|
||||||
return String.format(
|
return String.format(
|
||||||
|
|||||||
3
app/src/main/res/values-fa/strings.xml
Normal file
3
app/src/main/res/values-fa/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
</resources>
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
</resources>
|
<string name="start">प्रारंभ करें</string>
|
||||||
|
<string name="stop">विराम करें</string>
|
||||||
|
<string name="focus">ध्यान</string>
|
||||||
|
</resources>
|
||||||
|
|||||||
3
app/src/main/res/values-iw/strings.xml
Normal file
3
app/src/main/res/values-iw/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
</resources>
|
||||||
59
app/src/main/res/values-uk/strings.xml
Normal file
59
app/src/main/res/values-uk/strings.xml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="start">Почати</string>
|
||||||
|
<string name="stop">Стоп</string>
|
||||||
|
<string name="focus">Концентрація</string>
|
||||||
|
<string name="short_break">Коротка перерва</string>
|
||||||
|
<string name="long_break">Довга перерва</string>
|
||||||
|
<string name="exit">Вийти</string>
|
||||||
|
<string name="skip">Пропустити</string>
|
||||||
|
<string name="color_scheme">Колірна схема</string>
|
||||||
|
<string name="productivity_analysis">Аналіз продуктивності</string>
|
||||||
|
<string name="black_theme">Чорна тема</string>
|
||||||
|
<string name="vibrate">Вібрація</string>
|
||||||
|
<string name="theme">Тема</string>
|
||||||
|
<string name="settings">Налаштування</string>
|
||||||
|
<string name="session_length">Тривалість сесії</string>
|
||||||
|
<string name="stats">Статистика</string>
|
||||||
|
<string name="today">Сьогодні</string>
|
||||||
|
<string name="more_info">Більше інформації</string>
|
||||||
|
<string name="weekly_productivity_analysis">Щотижневий аналіз продуктивності</string>
|
||||||
|
<string name="last_month">Минулого місяця</string>
|
||||||
|
<string name="monthly_productivity_analysis">Щомісячний аналіз продуктивності</string>
|
||||||
|
<string name="restart">Перезапустити</string>
|
||||||
|
<string name="skip_to_next">Перейти до наступного</string>
|
||||||
|
<string name="up_next">Далі</string>
|
||||||
|
<string name="timer">Таймер</string>
|
||||||
|
<string name="timer_progress">Прогрес таймера</string>
|
||||||
|
<string name="stop_alarm">Зупинити</string>
|
||||||
|
<string name="min_remaining_notification">%1$s хв залишилося</string>
|
||||||
|
<string name="paused">Призупинено</string>
|
||||||
|
<string name="completed">Завершено</string>
|
||||||
|
<string name="up_next_notification">Далі: %1$s (%2$s)</string>
|
||||||
|
<string name="start_next">Почати наступне</string>
|
||||||
|
<string name="choose_color_scheme">Обрати колірну схему</string>
|
||||||
|
<string name="ok">ОК</string>
|
||||||
|
<string name="dynamic">Динамічна</string>
|
||||||
|
<string name="color">Колір</string>
|
||||||
|
<string name="system_default">За замовчуванням (система)</string>
|
||||||
|
<string name="alarm">Сигнал</string>
|
||||||
|
<string name="light">Світла</string>
|
||||||
|
<string name="dark">Темна</string>
|
||||||
|
<string name="choose_theme">Обрати тему</string>
|
||||||
|
<string name="productivity_analysis_desc">Тривалість концентрації в різні години дня</string>
|
||||||
|
<string name="alarm_sound">Звук сигналу</string>
|
||||||
|
<string name="black_theme_desc">Використовувати чисту чорну тему</string>
|
||||||
|
<string name="alarm_desc">Звуковий сигнал по завершенні таймера</string>
|
||||||
|
<string name="vibrate_desc">Увімкнути вібрацію після завершення таймера</string>
|
||||||
|
<string name="session_length_desc">Інтервали концентрації уваги в одній сесії: %1$d</string>
|
||||||
|
<string name="pomodoro_info">«Сесія» - це послідовність інтервалів Pomodoro, що містить інтервали концентрації, короткі перерви та довгу перерву. Остання перерва сесії є завжди довгою.</string>
|
||||||
|
<string name="break_">Перерва</string>
|
||||||
|
<string name="last_week">Минулого тижня</string>
|
||||||
|
<string name="focus_per_day_avg">концентрацій на день (середнє значення)</string>
|
||||||
|
<string name="stop_alarm_question">Зупинити сигнал?</string>
|
||||||
|
<string name="stop_alarm_dialog_text">Поточна сесія таймера завершена. Натисніть будь-де, щоб зупинити сигнал.</string>
|
||||||
|
<string name="timer_session_count">%1$d з %2$d</string>
|
||||||
|
<string name="more">Більше</string>
|
||||||
|
<string name="pause">Пауза</string>
|
||||||
|
<string name="play">Грати</string>
|
||||||
|
</resources>
|
||||||
59
app/src/main/res/values-zh-rCN/strings.xml
Normal file
59
app/src/main/res/values-zh-rCN/strings.xml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="start">开始</string>
|
||||||
|
<string name="stop">停止</string>
|
||||||
|
<string name="focus">专注</string>
|
||||||
|
<string name="short_break">短休息</string>
|
||||||
|
<string name="long_break">长休息</string>
|
||||||
|
<string name="exit">退出</string>
|
||||||
|
<string name="skip">跳过</string>
|
||||||
|
<string name="stop_alarm">停止响铃</string>
|
||||||
|
<string name="min_remaining_notification">还剩 %1$s 分钟</string>
|
||||||
|
<string name="paused">已暂停</string>
|
||||||
|
<string name="completed">已完成</string>
|
||||||
|
<string name="up_next_notification">下一步: %1$s (%2$s)</string>
|
||||||
|
<string name="start_next">开始下一个</string>
|
||||||
|
<string name="choose_color_scheme">选择配色方案</string>
|
||||||
|
<string name="ok">好的</string>
|
||||||
|
<string name="color_scheme">配色方案</string>
|
||||||
|
<string name="dynamic">动态</string>
|
||||||
|
<string name="color">颜色</string>
|
||||||
|
<string name="system_default">系统默认</string>
|
||||||
|
<string name="alarm">响铃</string>
|
||||||
|
<string name="light">亮色</string>
|
||||||
|
<string name="dark">暗色</string>
|
||||||
|
<string name="choose_theme">选择主题</string>
|
||||||
|
<string name="productivity_analysis">工作效率分析</string>
|
||||||
|
<string name="productivity_analysis_desc">每日不同时间的专注时长</string>
|
||||||
|
<string name="alarm_sound">铃声</string>
|
||||||
|
<string name="black_theme">黑色主题</string>
|
||||||
|
<string name="black_theme_desc">使用纯黑主题</string>
|
||||||
|
<string name="alarm_desc">计时结束时响铃</string>
|
||||||
|
<string name="vibrate">振动</string>
|
||||||
|
<string name="vibrate_desc">计时结束时振动</string>
|
||||||
|
<string name="theme">主题</string>
|
||||||
|
<string name="settings">设置</string>
|
||||||
|
<string name="session_length">小节长度</string>
|
||||||
|
<string name="session_length_desc">一小节内的专注时段: %1$d</string>
|
||||||
|
<string name="pomodoro_info">一个“小节”是一系列包含专注时段、短休息时段和长休息时段的番茄钟时段。一个小节的最后一个休息时段始终是长休息时段。</string>
|
||||||
|
<string name="stats">统计</string>
|
||||||
|
<string name="today">今日</string>
|
||||||
|
<string name="break_">休息</string>
|
||||||
|
<string name="last_week">上周</string>
|
||||||
|
<string name="focus_per_day_avg">每日专注时长 (平均)</string>
|
||||||
|
<string name="more_info">更多信息</string>
|
||||||
|
<string name="weekly_productivity_analysis">周生产力分析</string>
|
||||||
|
<string name="last_month">上月</string>
|
||||||
|
<string name="monthly_productivity_analysis">月生产力分析</string>
|
||||||
|
<string name="stop_alarm_question">要停止响铃吗?</string>
|
||||||
|
<string name="stop_alarm_dialog_text">当前计时小节已完成. 轻触任何位置来停止响铃.</string>
|
||||||
|
<string name="more">更多</string>
|
||||||
|
<string name="pause">暂停</string>
|
||||||
|
<string name="play">开始</string>
|
||||||
|
<string name="restart">重新开始</string>
|
||||||
|
<string name="skip_to_next">跳过到下一个</string>
|
||||||
|
<string name="up_next">接下来是</string>
|
||||||
|
<string name="timer">计时</string>
|
||||||
|
<string name="timer_progress">计时器进度</string>
|
||||||
|
<string name="timer_session_count">%1$d 的 %2$d</string>
|
||||||
|
</resources>
|
||||||
8
fastlane/metadata/android/en-US/changelogs/11.txt
Normal file
8
fastlane/metadata/android/en-US/changelogs/11.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
New features:
|
||||||
|
- The app is now translated into 6 languages (Chinese (Simplified), English, Hebrew, Hindi, Persian, Ukrainian). You can help translate by going to the app's Weblate page!
|
||||||
|
- Alarms now use your phone's alarm volume instead of the media volume
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Fixed incorrect calculation of average durations
|
||||||
|
- Fixed a bug that caused the set session length to not show in the settings slider
|
||||||
|
- Fixed a bug that caused the focus time on graphs show 0 when it was less than an hour
|
||||||
1
fastlane/metadata/android/hi-IN/short_description.txt
Normal file
1
fastlane/metadata/android/hi-IN/short_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
सरल पोमोडोरो टाइमर
|
||||||
1
fastlane/metadata/android/uk/full_description.txt
Normal file
1
fastlane/metadata/android/uk/full_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<p><i>Tomato</i> - мінімалістичний Pomodoro таймер для Android на базі Material 3 Expressive.</p><p><br><b>Особливості:</b></p><ul><li>Простий, мінімалістичний інтерфейс на основі останніх рекомендацій Material 3 Expressive</li><li>Детальна статистика робочого/навчального часу в зрозумілій формі<ul><li>Статистика за поточний день, доступна з одного погляду</li><li>Статистика за останній тиждень і останній місяць, представлена у вигляді зручного для сприйняття чіткого графіку</li><li>Додаткова статистика за останній тиждень і місяць, що показує, в який час дня ви були найбільш продуктивні</li></ul></li><li>Настроювані параметри таймера</li></ul>
|
||||||
1
fastlane/metadata/android/uk/short_description.txt
Normal file
1
fastlane/metadata/android/uk/short_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Мінімалістичний Pomodoro таймер
|
||||||
1
fastlane/metadata/android/uk/title.txt
Normal file
1
fastlane/metadata/android/uk/title.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Tomato
|
||||||
1
fastlane/metadata/android/zh-CN/full_description.txt
Normal file
1
fastlane/metadata/android/zh-CN/full_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<p><i>Tomato</i> 是一个基于Material 3 Expressive的安卓极简主义番茄钟.</p><p><br><b>功能:</b></p><ul><li>基于最新Material 3 Expressive指南的简洁用户界面</li><li>以便于理解的方式提供工作/学习的详细统计数据<ul><li>当日统计数据一目了然</li><li>清楚易读的上周和上月统计图表</li><li>上周和上月的额外统计数据帮您找到一天中最高效的时间段</li></ul></li><li>可自定义的计时器参数</li></ul>
|
||||||
1
fastlane/metadata/android/zh-CN/short_description.txt
Normal file
1
fastlane/metadata/android/zh-CN/short_description.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
极简主义番茄钟
|
||||||
Reference in New Issue
Block a user