feat: implement domain models, link health check worker, and feed screen UI components
This commit is contained in:
parent
83658cc6c2
commit
2198324c2d
@ -120,6 +120,8 @@ interface LinkDao {
|
|||||||
SELECT * FROM links
|
SELECT * FROM links
|
||||||
WHERE url NOT LIKE 'note://%'
|
WHERE url NOT LIKE 'note://%'
|
||||||
AND url NOT LIKE 'https://shaarit.app/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 excluded_from_health_check = 0
|
||||||
AND (last_health_check < :timestamp OR last_health_check IS NULL)
|
AND (last_health_check < :timestamp OR last_health_check IS NULL)
|
||||||
ORDER BY last_health_check ASC
|
ORDER BY last_health_check ASC
|
||||||
|
|||||||
@ -41,6 +41,8 @@ class LinkHealthCheckWorker @AssistedInject constructor(
|
|||||||
"http://shaare",
|
"http://shaare",
|
||||||
"/shaare",
|
"/shaare",
|
||||||
"https://shaarit.app/note/",
|
"https://shaarit.app/note/",
|
||||||
|
"https://shaarit.app/config/",
|
||||||
|
"https://shaarit.app/todo/",
|
||||||
"file://",
|
"file://",
|
||||||
"localhost",
|
"localhost",
|
||||||
"127.0.0.1",
|
"127.0.0.1",
|
||||||
|
|||||||
@ -29,6 +29,8 @@ data class ShaarliLink(
|
|||||||
val healthStatus: HealthStatus
|
val healthStatus: HealthStatus
|
||||||
get() = when {
|
get() = when {
|
||||||
(url.startsWith("note://") && !url.startsWith("note://todo-")) || url.startsWith("/shaare/") || url.startsWith("https://shaarit.app/note/") -> HealthStatus.NOTE
|
(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
|
lastHealthCheck == 0L -> HealthStatus.UNTESTED
|
||||||
linkCheckStatus == LinkCheckStatus.BROKEN -> HealthStatus.DEAD
|
linkCheckStatus == LinkCheckStatus.BROKEN -> HealthStatus.DEAD
|
||||||
linkCheckStatus == LinkCheckStatus.PENDING -> HealthStatus.PENDING
|
linkCheckStatus == LinkCheckStatus.PENDING -> HealthStatus.PENDING
|
||||||
@ -45,6 +47,18 @@ data class ShaarliLink(
|
|||||||
url.startsWith("https://shaarit.app/note/") ||
|
url.startsWith("https://shaarit.app/note/") ||
|
||||||
tags.any { it.lowercase() == "note" || it.lowercase() == "#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)
|
* Détermine si le bookmark est une tâche (todo)
|
||||||
*/
|
*/
|
||||||
@ -77,6 +91,8 @@ data class ShaarliLink(
|
|||||||
val displayTitle: String
|
val displayTitle: String
|
||||||
get() {
|
get() {
|
||||||
val emoji = when {
|
val emoji = when {
|
||||||
|
isConfig -> "⚙️"
|
||||||
|
isTodo -> "✅"
|
||||||
isNote -> "📝"
|
isNote -> "📝"
|
||||||
isLocalNetwork -> "🌐"
|
isLocalNetwork -> "🌐"
|
||||||
linkCheckStatus == LinkCheckStatus.BROKEN -> "🔴"
|
linkCheckStatus == LinkCheckStatus.BROKEN -> "🔴"
|
||||||
@ -101,6 +117,8 @@ enum class LinkCheckStatus {
|
|||||||
|
|
||||||
enum class HealthStatus {
|
enum class HealthStatus {
|
||||||
NOTE, // C'est une note, pas un lien
|
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é
|
UNTESTED, // Jamais testé
|
||||||
OK, // Testé et fonctionnel
|
OK, // Testé et fonctionnel
|
||||||
PENDING, // En attente de confirmation
|
PENDING, // En attente de confirmation
|
||||||
|
|||||||
@ -333,6 +333,10 @@ fun FeedScreen(
|
|||||||
// For tasks, navigate to task detail screen
|
// For tasks, navigate to task detail screen
|
||||||
onNavigateToTodoDetail(link.id)
|
onNavigateToTodoDetail(link.id)
|
||||||
}
|
}
|
||||||
|
link.isShaarItInternal -> {
|
||||||
|
// All shaarit.app/ URLs (config, etc.): show note content
|
||||||
|
selectedLink = link
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// Regular link: open in browser
|
// Regular link: open in browser
|
||||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link.url))
|
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link.url))
|
||||||
|
|||||||
@ -249,7 +249,8 @@ class FeedViewModel @Inject constructor(
|
|||||||
|
|
||||||
val links = linkDao.getLinksByIds(selectedIds.toList())
|
val links = linkDao.getLinksByIds(selectedIds.toList())
|
||||||
for (link in links) {
|
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)
|
_linkVerificationResults.value = _linkVerificationResults.value + (link.id to LinkVerificationResult.Skipped)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,8 @@ import androidx.compose.material.icons.filled.Warning
|
|||||||
import androidx.compose.material.icons.filled.MenuBook
|
import androidx.compose.material.icons.filled.MenuBook
|
||||||
import androidx.compose.material.icons.filled.Alarm
|
import androidx.compose.material.icons.filled.Alarm
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
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.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
@ -1025,6 +1027,22 @@ fun HealthStatusIcon(
|
|||||||
HealthStatus.NOTE -> {
|
HealthStatus.NOTE -> {
|
||||||
// Pas d'icône pour les notes
|
// 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 -> {
|
HealthStatus.UNTESTED -> {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.HelpOutline,
|
imageVector = Icons.Default.HelpOutline,
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
#Wed Apr 22 21:45:20 2026
|
#Wed Apr 22 22:23:35 2026
|
||||||
VERSION_NAME=2.9.0
|
VERSION_NAME=2.10.0
|
||||||
VERSION_CODE=34
|
VERSION_CODE=35
|
||||||
Loading…
x
Reference in New Issue
Block a user