feat: implement domain models, link health check worker, and feed screen UI components

This commit is contained in:
Bruno Charest 2026-04-23 07:40:58 -04:00
parent 83658cc6c2
commit 2198324c2d
7 changed files with 49 additions and 4 deletions

View File

@ -120,6 +120,8 @@ interface LinkDao {
SELECT * FROM links
WHERE url NOT LIKE 'note://%'
AND url NOT LIKE 'https://shaarit.app/note/%'
AND url NOT LIKE 'https://shaarit.app/config/%'
AND url NOT LIKE 'https://shaarit.app/todo/%'
AND excluded_from_health_check = 0
AND (last_health_check < :timestamp OR last_health_check IS NULL)
ORDER BY last_health_check ASC

View File

@ -41,6 +41,8 @@ class LinkHealthCheckWorker @AssistedInject constructor(
"http://shaare",
"/shaare",
"https://shaarit.app/note/",
"https://shaarit.app/config/",
"https://shaarit.app/todo/",
"file://",
"localhost",
"127.0.0.1",

View File

@ -29,6 +29,8 @@ data class ShaarliLink(
val healthStatus: HealthStatus
get() = when {
(url.startsWith("note://") && !url.startsWith("note://todo-")) || url.startsWith("/shaare/") || url.startsWith("https://shaarit.app/note/") -> HealthStatus.NOTE
url.startsWith("https://shaarit.app/config/") -> HealthStatus.CONFIG
url.startsWith("https://shaarit.app/todo/") || url.startsWith("note://todo-") -> HealthStatus.TODO
lastHealthCheck == 0L -> HealthStatus.UNTESTED
linkCheckStatus == LinkCheckStatus.BROKEN -> HealthStatus.DEAD
linkCheckStatus == LinkCheckStatus.PENDING -> HealthStatus.PENDING
@ -45,6 +47,18 @@ data class ShaarliLink(
url.startsWith("https://shaarit.app/note/") ||
tags.any { it.lowercase() == "note" || it.lowercase() == "#note" }
/**
* Détermine si le bookmark est une configuration app
*/
val isConfig: Boolean
get() = url.startsWith("https://shaarit.app/config/")
/**
* Détermine si le bookmark est un lien interne shaarit.app (note, todo, config, etc.)
*/
val isShaarItInternal: Boolean
get() = url.startsWith("https://shaarit.app/")
/**
* Détermine si le bookmark est une tâche (todo)
*/
@ -77,6 +91,8 @@ data class ShaarliLink(
val displayTitle: String
get() {
val emoji = when {
isConfig -> "⚙️"
isTodo -> ""
isNote -> "📝"
isLocalNetwork -> "🌐"
linkCheckStatus == LinkCheckStatus.BROKEN -> "🔴"
@ -101,6 +117,8 @@ enum class LinkCheckStatus {
enum class HealthStatus {
NOTE, // C'est une note, pas un lien
CONFIG, // Configuration app (https://shaarit.app/config/)
TODO, // Tâche (https://shaarit.app/todo/)
UNTESTED, // Jamais testé
OK, // Testé et fonctionnel
PENDING, // En attente de confirmation

View File

@ -333,6 +333,10 @@ fun FeedScreen(
// For tasks, navigate to task detail screen
onNavigateToTodoDetail(link.id)
}
link.isShaarItInternal -> {
// All shaarit.app/ URLs (config, etc.): show note content
selectedLink = link
}
else -> {
// Regular link: open in browser
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link.url))

View File

@ -249,7 +249,8 @@ class FeedViewModel @Inject constructor(
val links = linkDao.getLinksByIds(selectedIds.toList())
for (link in links) {
if (link.url.startsWith("note://") || link.url.startsWith("https://shaarit.app/note/")) {
if (link.url.startsWith("note://") || link.url.startsWith("https://shaarit.app/note/") ||
link.url.startsWith("https://shaarit.app/config/") || link.url.startsWith("https://shaarit.app/todo/")) {
_linkVerificationResults.value = _linkVerificationResults.value + (link.id to LinkVerificationResult.Skipped)
continue
}

View File

@ -24,6 +24,8 @@ import androidx.compose.material.icons.filled.Warning
import androidx.compose.material.icons.filled.MenuBook
import androidx.compose.material.icons.filled.Alarm
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material.icons.filled.TaskAlt
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.ui.window.DialogProperties
@ -1025,6 +1027,22 @@ fun HealthStatusIcon(
HealthStatus.NOTE -> {
// Pas d'icône pour les notes
}
HealthStatus.CONFIG -> {
Icon(
imageVector = Icons.Default.Settings,
contentDescription = "Configuration",
tint = Color(0xFF8B8B8B),
modifier = modifier
)
}
HealthStatus.TODO -> {
Icon(
imageVector = Icons.Default.TaskAlt,
contentDescription = "Tâche",
tint = Color(0xFF10B981),
modifier = modifier
)
}
HealthStatus.UNTESTED -> {
Icon(
imageVector = Icons.Default.HelpOutline,

View File

@ -1,3 +1,3 @@
#Wed Apr 22 21:45:20 2026
VERSION_NAME=2.9.0
VERSION_CODE=34
#Wed Apr 22 22:23:35 2026
VERSION_NAME=2.10.0
VERSION_CODE=35