Skip to content
Open
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
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ try {
}

kotlin {
jvmToolchain(21)
jvmToolchain(25)
}

android {
Expand Down
15 changes: 10 additions & 5 deletions app/src/main/java/at/techbee/jtx/ui/list/ListCard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import at.techbee.jtx.ui.reusable.elements.AudioPlaybackElement
import at.techbee.jtx.ui.reusable.elements.DragHandle
import at.techbee.jtx.ui.reusable.elements.ProgressElement
import at.techbee.jtx.ui.reusable.elements.VerticalDateBlock
import at.techbee.jtx.ui.reusable.components.filterCheckedCheckboxes
import at.techbee.jtx.ui.settings.DropdownSettingOption
import at.techbee.jtx.ui.theme.Typography
import at.techbee.jtx.ui.theme.jtxCardBorderStrokeWidth
Expand Down Expand Up @@ -113,6 +114,7 @@ fun ListCard(
markdownEnabled: Boolean,
isSubtaskDragAndDropEnabled: Boolean,
isSubnoteDragAndDropEnabled: Boolean,
hideDoneCheckboxes: Boolean = false,
onClick: (itemId: Long, list: List<ICal4List>, isReadOnly: Boolean) -> Unit,
onLongClick: (itemId: Long, list: List<ICal4List>) -> Unit,
onProgressChanged: (itemId: Long, newPercent: Int) -> Unit,
Expand Down Expand Up @@ -149,16 +151,19 @@ fun ListCard(


@Composable
fun getFormattedDescription() {
fun getFormattedDescription(hideDoneCheckboxes: Boolean = false) {
val descriptionContent = iCalObject.description?.trim() ?: ""
val filteredContent = if (hideDoneCheckboxes) filterCheckedCheckboxes(descriptionContent) else descriptionContent

return if(markdownEnabled && iCalObject.status != Status.CANCELLED.status)
Markdown(
content = iCalObject.description?.trim()?.ellipsize(300) ?: "",
content = filteredContent.ellipsize(300),
imageTransformer = Coil3ImageTransformerImpl,
modifier = Modifier.fillMaxWidth()
)
else
Text(
text = iCalObject.description?.trim() ?: "",
text = descriptionContent.ellipsize(300),
maxLines = 6,
overflow = TextOverflow.Ellipsis,
textDecoration = summaryDescriptionTextDecoration,
Expand Down Expand Up @@ -260,7 +265,7 @@ fun ListCard(
modifier = Modifier.weight(1f)
)
} else if (iCalObject.description?.isNotBlank() == true) {
getFormattedDescription()
getFormattedDescription(hideDoneCheckboxes)
} else {
Spacer(modifier = Modifier.weight(1f))
}
Expand All @@ -280,7 +285,7 @@ fun ListCard(
}

if(iCalObject.summary?.isNotBlank() == true && iCalObject.description?.isNotBlank() == true) {
getFormattedDescription()
getFormattedDescription(hideDoneCheckboxes)
}


Expand Down
7 changes: 6 additions & 1 deletion app/src/main/java/at/techbee/jtx/ui/list/ListCardCompact.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import at.techbee.jtx.database.Status
import at.techbee.jtx.database.locals.ExtendedStatus
import at.techbee.jtx.database.locals.StoredCategory
import at.techbee.jtx.database.views.ICal4List
import at.techbee.jtx.ui.reusable.components.filterCheckedCheckboxes
import at.techbee.jtx.ui.reusable.cards.SubtaskCardCompact
import at.techbee.jtx.ui.reusable.elements.AudioPlaybackElement
import at.techbee.jtx.ui.reusable.elements.DragHandle
Expand All @@ -76,6 +77,7 @@ fun ListCardCompact(
selected: List<Long>,
player: MediaPlayer?,
isSubtaskDragAndDropEnabled: Boolean,
hideDoneCheckboxes: Boolean = false,
modifier: Modifier = Modifier,
isSubtasksExpandedDefault: Boolean,
onProgressChanged: (itemId: Long, newPercent: Int) -> Unit,
Expand Down Expand Up @@ -154,8 +156,11 @@ fun ListCardCompact(
)
}

val summaryDescriptionContent = iCalObject.summary?.trim() ?: iCalObject.description?.trim() ?: ""
val filteredContent = if (hideDoneCheckboxes) filterCheckedCheckboxes(summaryDescriptionContent) else summaryDescriptionContent

Text(
text = iCalObject.summary?.trim() ?: iCalObject.description?.trim() ?: "",
text = filteredContent.trim(),
textDecoration = if (iCalObject.status == Status.CANCELLED.status) TextDecoration.LineThrough else null,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
Expand Down
9 changes: 7 additions & 2 deletions app/src/main/java/at/techbee/jtx/ui/list/ListCardGrid.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import at.techbee.jtx.database.locals.ExtendedStatus
import at.techbee.jtx.database.locals.StoredCategory
import at.techbee.jtx.database.views.ICal4List
import at.techbee.jtx.flavored.BillingManager
import at.techbee.jtx.ui.reusable.components.filterCheckedCheckboxes
import at.techbee.jtx.ui.reusable.elements.AudioPlaybackElement
import at.techbee.jtx.ui.theme.jtxCardBorderStrokeWidth
import at.techbee.jtx.util.UiUtil.ellipsize
Expand All @@ -56,6 +57,7 @@ fun ListCardGrid(
progressUpdateDisabled: Boolean,
markdownEnabled: Boolean,
player: MediaPlayer?,
hideDoneCheckboxes: Boolean = false,
modifier: Modifier = Modifier,
dragHandle:@Composable () -> Unit = { },
onProgressChanged: (itemId: Long, newPercent: Int) -> Unit,
Expand Down Expand Up @@ -142,16 +144,19 @@ fun ListCardGrid(
}

if (iCalObject.description?.isNotBlank() == true) {
val descriptionContent = iCalObject.description?.trim() ?: ""
val filteredContent = if (hideDoneCheckboxes) filterCheckedCheckboxes(descriptionContent) else descriptionContent

if(markdownEnabled && iCalObject.status != Status.CANCELLED.status)
Markdown(
content = iCalObject.description?.trim()?.ellipsize(150) ?: "",
content = filteredContent.ellipsize(150),
modifier = Modifier
.fillMaxWidth()
.padding(end = 8.dp)
)
else
Text(
text = iCalObject.description?.trim() ?: "",
text = descriptionContent.ellipsize(150),
maxLines = 3,
overflow = TextOverflow.Ellipsis,
textDecoration = if (iCalObject.status == Status.CANCELLED.status) TextDecoration.LineThrough else null,
Expand Down
9 changes: 7 additions & 2 deletions app/src/main/java/at/techbee/jtx/ui/list/ListCardKanban.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import at.techbee.jtx.database.locals.ExtendedStatus
import at.techbee.jtx.database.locals.StoredCategory
import at.techbee.jtx.database.views.ICal4List
import at.techbee.jtx.flavored.BillingManager
import at.techbee.jtx.ui.reusable.components.filterCheckedCheckboxes
import at.techbee.jtx.ui.reusable.elements.AudioPlaybackElement
import at.techbee.jtx.ui.theme.jtxCardBorderStrokeWidth
import at.techbee.jtx.util.UiUtil.ellipsize
Expand All @@ -52,6 +53,7 @@ fun ListCardKanban(
markdownEnabled: Boolean,
selected: Boolean,
player: MediaPlayer?,
hideDoneCheckboxes: Boolean = false,
modifier: Modifier = Modifier,
onClick: (itemId: Long, list: List<ICal4List>, isReadOnly: Boolean) -> Unit,
onLongClick: (itemId: Long, list: List<ICal4List>) -> Unit,
Expand Down Expand Up @@ -112,11 +114,14 @@ fun ListCardKanban(
)

if (iCalObject.description?.isNotBlank() == true) {
val descriptionContent = iCalObject.description?.trim() ?: ""
val filteredContent = if (hideDoneCheckboxes) filterCheckedCheckboxes(descriptionContent) else descriptionContent

if(markdownEnabled && iCalObject.status != Status.CANCELLED.status)
Markdown(content = iCalObject.description?.trim()?.ellipsize(100) ?: "",)
Markdown(content = filteredContent.ellipsize(100))
else
Text(
text = iCalObject.description?.trim() ?: "",
text = descriptionContent.ellipsize(100),
maxLines = 4,
textDecoration = if (iCalObject.status == Status.CANCELLED.status) TextDecoration.LineThrough else null,
overflow = TextOverflow.Ellipsis
Expand Down
9 changes: 6 additions & 3 deletions app/src/main/java/at/techbee/jtx/ui/list/ListCardWeek.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import at.techbee.jtx.database.ICalObject
import at.techbee.jtx.database.Module
import at.techbee.jtx.database.Status
import at.techbee.jtx.database.views.ICal4List
import at.techbee.jtx.ui.reusable.components.filterCheckedCheckboxes
import at.techbee.jtx.ui.theme.jtxCardBorderStrokeWidth
import kotlin.time.Duration.Companion.days

Expand All @@ -42,7 +43,8 @@ fun ListCardWeek(
iCalObject: ICal4List,
selected: Boolean,
modifier: Modifier = Modifier,
isDueDate: Boolean = false
isDueDate: Boolean = false,
hideDoneCheckboxes: Boolean = false
) {
Card(
colors = CardDefaults.elevatedCardColors(
Expand All @@ -63,10 +65,11 @@ fun ListCardWeek(
"✔"
else if (isDueDate) "❗"
else ""
text += if(iCalObject.summary?.isNotBlank() == true) iCalObject.summary!!.trim() else iCalObject.description ?: ""
val content = if(iCalObject.summary?.isNotBlank() == true) iCalObject.summary!!.trim() else iCalObject.description ?: ""
text += if (hideDoneCheckboxes) filterCheckedCheckboxes(content) else content

Text(
text = text,
text = text.trim(),
textDecoration = if (iCalObject.status == Status.CANCELLED.status) TextDecoration.LineThrough else null,
maxLines = 3,
overflow = TextOverflow.Ellipsis,
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/at/techbee/jtx/ui/list/ListScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ fun ListScreen(
scrollOnceId = listViewModel.scrollOnceId,
settingLinkProgressToSubtasks = settingsStateHolder.settingLinkProgressToSubtasks.value,
markdownEnabled = listViewModel.listSettings.markdownEnabled.value,
isExcludeDone = listViewModel.listSettings.isExcludeDone.value,
player = listViewModel.mediaPlayer,
onClick = { itemId, ical4list, isReadOnly -> processOnClick(itemId, ical4list, isReadOnly) },
onLongClick = { itemId, ical4list -> processOnLongClick(itemId, ical4list) },
Expand Down Expand Up @@ -181,6 +182,7 @@ fun ListScreen(
scrollOnceId = listViewModel.scrollOnceId,
settingLinkProgressToSubtasks = settingsStateHolder.settingLinkProgressToSubtasks.value,
markdownEnabled = listViewModel.listSettings.markdownEnabled.value,
isExcludeDone = listViewModel.listSettings.isExcludeDone.value,
player = listViewModel.mediaPlayer,
onClick = { itemId, ical4list, isReadOnly -> processOnClick(itemId, ical4list, isReadOnly) },
onLongClick = { itemId, ical4list -> processOnLongClick(itemId, ical4list) },
Expand All @@ -194,6 +196,7 @@ fun ListScreen(
list = sortedList,
selectedEntries = listViewModel.selectedEntries,
scrollOnceId = listViewModel.scrollOnceId,
isExcludeDone = listViewModel.listSettings.isExcludeDone.value,
onClick = { itemId, ical4list, isReadOnly -> processOnClick(itemId, ical4list, isReadOnly) },
onLongClick = { itemId, ical4list -> processOnLongClick(itemId, ical4list) },
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ fun ListScreenCompact(
player = player,
isSubtaskDragAndDropEnabled = isSubtaskDragAndDropEnabled,
isSubtasksExpandedDefault = isSubtasksExpandedDefault,
hideDoneCheckboxes = listSettings.isExcludeDone.value,
dragHandle = {
if(isListDragAndDropEnabled)
DragHandleLazy(this)
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/at/techbee/jtx/ui/list/ListScreenGrid.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ fun ListScreenGrid(
scrollOnceId: MutableLiveData<Long?>,
settingLinkProgressToSubtasks: Boolean,
markdownEnabled: Boolean,
isExcludeDone: Boolean = false,
player: MediaPlayer?,
isListDragAndDropEnabled: Boolean,
onProgressChanged: (itemId: Long, newPercent: Int) -> Unit,
Expand Down Expand Up @@ -138,6 +139,7 @@ fun ListScreenGrid(
selected = selectedEntries.contains(iCal4ListRelObject.iCal4List.id),
progressUpdateDisabled = settingLinkProgressToSubtasks && currentSubtasks.isNotEmpty(),
markdownEnabled = markdownEnabled,
hideDoneCheckboxes = isExcludeDone,
player = player,
modifier = Modifier
.fillMaxWidth()
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/at/techbee/jtx/ui/list/ListScreenKanban.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ fun ListScreenKanban(
scrollOnceId: MutableLiveData<Long?>,
settingLinkProgressToSubtasks: Boolean,
markdownEnabled: Boolean,
isExcludeDone: Boolean = false,
player: MediaPlayer?,
onStatusChanged: (itemid: Long, status: Status, scrollOnce: Boolean) -> Unit,
onXStatusChanged: (itemid: Long, status: ExtendedStatus, scrollOnce: Boolean) -> Unit,
Expand Down Expand Up @@ -183,6 +184,7 @@ fun ListScreenKanban(
storedStatuses = storedStatuses,
selected = selectedEntries.contains(iCal4ListRelObject.iCal4List.id),
markdownEnabled = markdownEnabled,
hideDoneCheckboxes = isExcludeDone,
player = player,
onClick = onClick,
onLongClick = onLongClick,
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/at/techbee/jtx/ui/list/ListScreenList.kt
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ fun ListScreenList(
progressIncrement = settingProgressIncrement.getProgressStepKeyAsInt(),
linkProgressToSubtasks = settingLinkProgressToSubtasks,
markdownEnabled = markdownEnabled,
hideDoneCheckboxes = listSettings.isExcludeDone.value,
onClick = onClick,
onLongClick = onLongClick,
onProgressChanged = onProgressChanged,
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/at/techbee/jtx/ui/list/ListScreenWeek.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ fun ListScreenWeek(
list: List<ICal4ListRel>,
selectedEntries: SnapshotStateList<Long>,
scrollOnceId: MutableLiveData<Long?>,
isExcludeDone: Boolean = false,
onClick: (itemId: Long, list: List<ICal4List>, isReadOnly: Boolean) -> Unit,
onLongClick: (itemId: Long, list: List<ICal4List>) -> Unit,
) {
Expand Down Expand Up @@ -123,6 +124,7 @@ fun ListScreenWeek(
day = day.date,
list = list,
selectedEntries = selectedEntries,
isExcludeDone = isExcludeDone,
onClick = onClick,
onLongClick = onLongClick
)
Expand Down Expand Up @@ -194,6 +196,7 @@ fun Day(
day: LocalDate,
list: List<ICal4ListRel>,
selectedEntries: SnapshotStateList<Long>,
isExcludeDone: Boolean = false,
onClick: (itemId: Long, list: List<ICal4List>, isReadOnly: Boolean) -> Unit,
onLongClick: (itemId: Long, list: List<ICal4List>) -> Unit
) {
Expand Down Expand Up @@ -242,6 +245,7 @@ fun Day(
), DateTimeUtils.requireTzId(iCal4ListRel.iCal4List.dueTimezone)
).atStartOfDay(),
selected = selectedEntries.contains(iCal4ListRel.iCal4List.id),
hideDoneCheckboxes = isExcludeDone,
modifier = Modifier
.combinedClickable(
onClick = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,20 @@ fun InteractiveMarkdown(
}
}

private val checkboxLineRegex = Regex("""^(\s*)-\s*\[([ xX])]\s*(.*)$""")
internal val checkboxLineRegex = Regex("""^(\s*)([-*+])\s*\[([ xX])]\s*(.*?)\r?$""")

/**
* Filters out lines containing checked checkboxes from the given content.
*
* @param content The Markdown content to filter
* @return The filtered content with checked checkbox lines removed
*/
fun filterCheckedCheckboxes(content: String): String {
return content.lines().filter { line ->
val match = checkboxLineRegex.matchEntire(line)
!(match != null && match.groupValues[3].equals("x", ignoreCase = true))
}.joinToString("\n")
}

sealed interface MarkdownSegment {
data class MarkdownText(val content: String) : MarkdownSegment
Expand All @@ -101,15 +114,15 @@ fun parseMarkdownSegments(content: String): List<MarkdownSegment> {
markdownLines.clear()
}

content.split('\n').forEachIndexed { index, line ->
content.lines().forEachIndexed { index, line ->
val match = checkboxLineRegex.matchEntire(line)
if (match != null) {
flushMarkdownLines()
segments.add(
MarkdownSegment.CheckboxItem(
lineIndex = index,
text = match.groupValues[3],
isChecked = match.groupValues[2].equals("x", ignoreCase = true)
text = match.groupValues[4],
isChecked = match.groupValues[3].equals("x", ignoreCase = true)
)
)
} else {
Expand All @@ -127,13 +140,14 @@ fun updateCheckboxState(
lineIndex: Int,
newState: Boolean
): String {
val lines = originalContent.split('\n').toMutableList()
val lines = originalContent.lines().toMutableList()
if (lineIndex !in lines.indices) return originalContent

val match = checkboxLineRegex.matchEntire(lines[lineIndex]) ?: return originalContent
val indentation = match.groupValues[1]
val textContent = match.groupValues[3]
lines[lineIndex] = "$indentation- [${if (newState) "x" else " "}] $textContent"
val marker = match.groupValues[2]
val textContent = match.groupValues[4]
lines[lineIndex] = "$indentation$marker [${if (newState) "x" else " "}] $textContent"

return lines.joinToString("\n")
}
Expand Down
Loading