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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.appoutlet.foliary.data.authentication

import eu.anifantakis.lib.ksafe.KSafe
import kotlin.io.path.createTempDirectory

actual fun platformKSafe(): KSafe = error("")
1 change: 1 addition & 0 deletions foliary/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<string name="create_task_description_placeholder">Add description...</string>
<string name="create_task_save">Save</string>
<string name="create_task_title_required">Title is required</string>
<string name="create_task_priority_label">Priority</string>
<string name="create_task_due_date_label">Due date</string>
<string name="create_task_due_date_placeholder">Add due date</string>
<string name="create_task_due_date_clear_a11y">Clear due date</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,24 @@ package dev.appoutlet.foliary.core.ui.component.pill

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Flag
import com.composables.icons.lucide.Lucide
import dev.appoutlet.foliary.core.ui.priority.viewData
import dev.appoutlet.foliary.core.ui.theme.FoliaryTheme
import dev.appoutlet.foliary.data.task.database.entity.Priority
import foliary.foliary.generated.resources.Res
import foliary.foliary.generated.resources.priority_pill_blocker
import foliary.foliary.generated.resources.priority_pill_high
import foliary.foliary.generated.resources.priority_pill_highest
import foliary.foliary.generated.resources.priority_pill_low
import foliary.foliary.generated.resources.priority_pill_lowest
import foliary.foliary.generated.resources.priority_pill_medium
import org.jetbrains.compose.resources.stringResource

private val HighContentColor = Color(0xFFC4A319)
private val HighestContentColor = Color(0xFFAD5203)

@Composable
fun PriorityPill(priority: Priority, modifier: Modifier = Modifier) {
val defaultContentColor = MaterialTheme.colorScheme.onSurface
val blockerContentColor = MaterialTheme.colorScheme.error

val (text, contentColor) = when (priority) {
Priority.LOWEST -> Res.string.priority_pill_lowest to defaultContentColor
Priority.LOW -> Res.string.priority_pill_low to defaultContentColor
Priority.MEDIUM -> Res.string.priority_pill_medium to defaultContentColor
Priority.HIGH -> Res.string.priority_pill_high to HighContentColor
Priority.HIGHEST -> Res.string.priority_pill_highest to HighestContentColor
Priority.BLOCKER -> Res.string.priority_pill_blocker to blockerContentColor
}
val priorityViewData = priority.viewData()

FoliaryPill(
modifier = modifier.testTag("PriorityPill"),
icon = Lucide.Flag,
text = stringResource(text),
contentColor = contentColor
icon = priorityViewData.icon,
text = priorityViewData.text,
contentColor = priorityViewData.color
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package dev.appoutlet.foliary.core.ui.priority

import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import com.composables.icons.lucide.ChevronDown
import com.composables.icons.lucide.ChevronUp
import com.composables.icons.lucide.ChevronsDown
import com.composables.icons.lucide.ChevronsUp
import com.composables.icons.lucide.ChevronsUpDown
import com.composables.icons.lucide.CircleMinus
import com.composables.icons.lucide.Lucide
import dev.appoutlet.foliary.core.ui.theme.LocalIsDarkTheme
import dev.appoutlet.foliary.data.task.database.entity.Priority
import foliary.foliary.generated.resources.Res
import foliary.foliary.generated.resources.priority_pill_blocker
import foliary.foliary.generated.resources.priority_pill_high
import foliary.foliary.generated.resources.priority_pill_highest
import foliary.foliary.generated.resources.priority_pill_low
import foliary.foliary.generated.resources.priority_pill_lowest
import foliary.foliary.generated.resources.priority_pill_medium
import org.jetbrains.compose.resources.stringResource

data class PriorityViewData(
val text: String,
val color: Color,
val icon: ImageVector,
)

val PriorityHighLight = Color(0xFFBD8100)
val PriorityHighestLight = Color(0xFFA65200)
val PriorityBlockerLight = Color(0xFF93000A)

val PriorityHighDark = Color(0xFFFFAA5C)
val PriorityHighestDark = Color(0xFFFF8080)
val PriorityBlockerDark = Color(0xFFFF5449)

private data class PriorityColors(
val high: Color,
val highest: Color,
val blocker: Color
)

@Composable
fun Priority.viewData(): PriorityViewData {
val isDarkTheme = LocalIsDarkTheme.current

val colors = remember(isDarkTheme) {
if (isDarkTheme) {
PriorityColors(PriorityHighDark, PriorityHighestDark, PriorityBlockerDark)
} else {
PriorityColors(PriorityHighLight, PriorityHighestLight, PriorityBlockerLight)
}
}

return when (this) {
Priority.LOWEST -> PriorityViewData(
text = stringResource(Res.string.priority_pill_lowest),
color = MaterialTheme.colorScheme.onSurface.copy(alpha = .4f),
icon = Lucide.ChevronsDown,
)

Priority.LOW -> PriorityViewData(
text = stringResource(Res.string.priority_pill_low),
color = MaterialTheme.colorScheme.onSurface.copy(alpha = .7f),
icon = Lucide.ChevronDown,
)

Priority.MEDIUM -> PriorityViewData(
text = stringResource(Res.string.priority_pill_medium),
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 1f),
icon = Lucide.ChevronsUpDown,
)

Priority.HIGH -> PriorityViewData(
text = stringResource(Res.string.priority_pill_high),
color = colors.high,
icon = Lucide.ChevronUp,
)

Priority.HIGHEST -> PriorityViewData(
text = stringResource(Res.string.priority_pill_highest),
color = colors.highest,
icon = Lucide.ChevronsUp,
)

Priority.BLOCKER -> PriorityViewData(
text = stringResource(Res.string.priority_pill_blocker),
color = colors.blocker,
icon = Lucide.CircleMinus,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package dev.appoutlet.foliary.core.ui.theme
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.graphics.Color

val primaryLight = Color(0xFF1A4D3E)
Expand Down Expand Up @@ -72,3 +73,5 @@ val surfaceContainerLowDark = Color(0xFF22261E)
val surfaceContainerDark = Color(0xFF272B22)
val surfaceContainerHighDark = Color(0xFF32372B)
val surfaceContainerHighestDark = Color(0xFF3D4235)

val LocalIsDarkTheme = compositionLocalOf { false }
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider

private val lightScheme = lightColorScheme(
primary = primaryLight,
Expand Down Expand Up @@ -91,12 +92,14 @@ fun FoliaryTheme(

val colorScheme = if (isDarkTheme) darkScheme else lightScheme

MaterialTheme(
colorScheme = colorScheme,
typography = getTypography(colorScheme),
content = content,
shapes = shapes
)
CompositionLocalProvider(LocalIsDarkTheme provides isDarkTheme) {
MaterialTheme(
colorScheme = colorScheme,
typography = getTypography(colorScheme),
content = content,
shapes = shapes
)
}
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package dev.appoutlet.foliary.data.task.database.entity

enum class Priority {
LOWEST, LOW, MEDIUM, HIGH, HIGHEST, BLOCKER
BLOCKER, HIGHEST, HIGH, MEDIUM, LOW, LOWEST
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import foliary.foliary.generated.resources.create_task_description_label
import foliary.foliary.generated.resources.create_task_description_placeholder
import foliary.foliary.generated.resources.create_task_due_date_label
import foliary.foliary.generated.resources.create_task_due_date_placeholder
import foliary.foliary.generated.resources.create_task_priority_label
import foliary.foliary.generated.resources.create_task_save
import foliary.foliary.generated.resources.create_task_title
import foliary.foliary.generated.resources.create_task_title_label
Expand All @@ -57,6 +58,15 @@ fun CreateTaskScreen(viewData: CreateTaskViewData, onEvent: (CreateTaskEvent) ->
Spacer(Modifier.size(16.dp))
TitleField(viewData.title, onEvent)
DescriptionField(viewData.description, onEvent)
FoliaryPriorityPicker(
modifier = Modifier.widthInCompact()
.fillMaxWidth()
.padding(horizontal = 16.dp)
.testTag("CreateTaskScreen:PriorityPicker"),
label = stringResource(Res.string.create_task_priority_label),
selectedPriority = viewData.priority,
onPrioritySelected = { onEvent(CreateTaskEvent.PriorityChanged(it)) },
)
FoliaryDatePicker(
modifier = Modifier.widthInCompact()
.fillMaxWidth()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class CreateTaskViewModel(
id = task.id.toString(),
title = task.title,
description = task.description,
priority = task.priority,
dueDate = task.dueDate?.let { dueDate ->
CreateTaskViewData.DueDateViewData(
selectedDateMillis = dueDate.toEpochMilliseconds(),
Expand All @@ -54,12 +55,17 @@ class CreateTaskViewModel(
when (event) {
is CreateTaskEvent.TitleChanged -> onTitleChange(event.title)
is CreateTaskEvent.DescriptionChanged -> onDescriptionChange(event.description)
is CreateTaskEvent.PriorityChanged -> onPriorityChange(event.priority)
is CreateTaskEvent.DueDateChanged -> onDueDateChange(event.dueDateMillis)
CreateTaskEvent.SaveClicked -> onSaveClick()
CreateTaskEvent.BackClicked -> onBackClick()
}
}

private fun onPriorityChange(priority: Priority) = intent {
reduce { state.copy(priority = priority) }
}

private fun onDueDateChange(dueDateMillis: Long?) = intent {
reduce {
state.copy(
Expand Down Expand Up @@ -100,7 +106,7 @@ class CreateTaskViewModel(
timeProvider.endOfDay(it)
},
completionDate = null,
priority = Priority.MEDIUM,
priority = state.priority,
url = null,
location = null,
)
Expand All @@ -121,6 +127,7 @@ data class CreateTaskViewData(
val id: String? = null,
val title: String = "",
val description: String? = null,
val priority: Priority = Priority.MEDIUM,
val dueDate: DueDateViewData? = null,
val minDueDateMillis: Long,
val saveButtonEnabled: Boolean = false,
Expand All @@ -138,6 +145,7 @@ data class CreateTaskViewData(
sealed interface CreateTaskEvent {
data class TitleChanged(val title: String) : CreateTaskEvent
data class DescriptionChanged(val description: String?) : CreateTaskEvent
data class PriorityChanged(val priority: Priority) : CreateTaskEvent
data class DueDateChanged(val dueDateMillis: Long?) : CreateTaskEvent
data object SaveClicked : CreateTaskEvent
data object BackClicked : CreateTaskEvent
Expand Down
Loading
Loading