mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-12 09:13:23 +00:00
feat: Extract Card interface and CardFeedState to commons (B1)
- Create commons/ui/notifications/CardFeedState.kt with: - Card interface (createdAt, id) - CardFeedState sealed class (Loading, Loaded, Empty, FeedError) - DefaultCardComparator for sorting - Update Android imports to use commons Card/CardFeedState: - DefaultFeedOrder.kt - AccountViewModel.kt - CardFeedContentState.kt - CardFeedState.kt (now only contains concrete card types) - CardFeedView.kt Part of Phase B (Notifications Feed Extraction) for #1648 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
45207857c6
commit
ec629ac3fe
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.dal
|
||||
|
||||
import com.vitorpamplona.amethyst.commons.ui.notifications.Card
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.Card
|
||||
|
||||
val DefaultFeedOrder: Comparator<Note> =
|
||||
compareByDescending<Note> { it.createdAt() }.thenBy { it.idHex }
|
||||
|
||||
+1
-1
@@ -42,6 +42,7 @@ import com.vitorpamplona.amethyst.commons.compose.GenericBaseCache
|
||||
import com.vitorpamplona.amethyst.commons.compose.GenericBaseCacheAsync
|
||||
import com.vitorpamplona.amethyst.commons.model.LiveHiddenUsers
|
||||
import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState
|
||||
import com.vitorpamplona.amethyst.commons.ui.notifications.CardFeedState
|
||||
import com.vitorpamplona.amethyst.logTime
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
@@ -82,7 +83,6 @@ import com.vitorpamplona.amethyst.ui.note.ZapraiserStatus
|
||||
import com.vitorpamplona.amethyst.ui.note.showAmount
|
||||
import com.vitorpamplona.amethyst.ui.note.showAmountInteger
|
||||
import com.vitorpamplona.amethyst.ui.screen.UiSettingsState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.CardFeedState
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.CombinedZap
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.tor.TorSettingsFlow
|
||||
|
||||
+2
@@ -26,6 +26,8 @@ import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.vitorpamplona.amethyst.commons.ui.feeds.InvalidatableContent
|
||||
import com.vitorpamplona.amethyst.commons.ui.feeds.LoadedFeedState
|
||||
import com.vitorpamplona.amethyst.commons.ui.notifications.Card
|
||||
import com.vitorpamplona.amethyst.commons.ui.notifications.CardFeedState
|
||||
import com.vitorpamplona.amethyst.logTime
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
|
||||
+1
-26
@@ -21,8 +21,7 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.vitorpamplona.amethyst.commons.ui.feeds.LoadedFeedState
|
||||
import com.vitorpamplona.amethyst.commons.ui.notifications.Card
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.firstFullCharOrEmoji
|
||||
@@ -30,14 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.core.ImmutableListOfLists
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableMap
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
@Immutable
|
||||
interface Card {
|
||||
fun createdAt(): Long
|
||||
|
||||
fun id(): String
|
||||
}
|
||||
|
||||
@Immutable
|
||||
class BadgeCard(
|
||||
@@ -113,19 +104,3 @@ class MessageSetCard(
|
||||
|
||||
override fun id() = note.idHex
|
||||
}
|
||||
|
||||
@Immutable
|
||||
sealed class CardFeedState {
|
||||
@Immutable object Loading : CardFeedState()
|
||||
|
||||
@Stable
|
||||
class Loaded(
|
||||
val feed: MutableStateFlow<LoadedFeedState<Card>>,
|
||||
) : CardFeedState()
|
||||
|
||||
@Immutable object Empty : CardFeedState()
|
||||
|
||||
@Immutable class FeedError(
|
||||
val errorMessage: String,
|
||||
) : CardFeedState()
|
||||
}
|
||||
|
||||
+2
@@ -43,6 +43,8 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.commons.ui.notifications.Card
|
||||
import com.vitorpamplona.amethyst.commons.ui.notifications.CardFeedState
|
||||
import com.vitorpamplona.amethyst.logTime
|
||||
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||
import com.vitorpamplona.amethyst.ui.feeds.FeedError
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.ui.notifications
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.vitorpamplona.amethyst.commons.ui.feeds.LoadedFeedState
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
/**
|
||||
* Base interface for notification cards.
|
||||
*
|
||||
* Cards represent grouped or individual notification items in the feed.
|
||||
* Platform implementations provide concrete card types (NoteCard, MultiSetCard, etc.).
|
||||
*/
|
||||
@Immutable
|
||||
interface Card {
|
||||
/**
|
||||
* Returns the creation timestamp of this card.
|
||||
* Used for sorting cards in chronological order.
|
||||
*/
|
||||
fun createdAt(): Long
|
||||
|
||||
/**
|
||||
* Returns a unique identifier for this card.
|
||||
* Used for list diffing and deduplication.
|
||||
*/
|
||||
fun id(): String
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed state for notification cards.
|
||||
*
|
||||
* Mirrors FeedState but specifically typed for Card content.
|
||||
*/
|
||||
@Stable
|
||||
sealed class CardFeedState {
|
||||
@Immutable
|
||||
object Loading : CardFeedState()
|
||||
|
||||
@Stable
|
||||
class Loaded(
|
||||
val feed: MutableStateFlow<LoadedFeedState<Card>>,
|
||||
) : CardFeedState()
|
||||
|
||||
@Immutable
|
||||
object Empty : CardFeedState()
|
||||
|
||||
@Immutable
|
||||
class FeedError(
|
||||
val errorMessage: String,
|
||||
) : CardFeedState()
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator for sorting cards by creation time (newest first).
|
||||
*/
|
||||
val DefaultCardComparator: Comparator<Card> =
|
||||
compareByDescending<Card> { it.createdAt() }
|
||||
.thenByDescending { it.id() }
|
||||
Reference in New Issue
Block a user