mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-08 17:48:42 +01:00
feat: show unread comments with different background in post detail (#286)
* add String to timestamp conversion utils * refactor: key generation in sort serializer * add long to long map serializer * add post last seen date repository * update login/logout use cases * update post detail screen * update DI
This commit is contained in:
parent
65dea9c9a6
commit
d5702e31d3
@ -0,0 +1,44 @@
|
||||
package com.livefast.eattrash.raccoonforlemmy.core.persistence.repository
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class DefaultLongToLongMapSerializerTest {
|
||||
private val sut = DefaultLongToLongMapSerializer()
|
||||
|
||||
@Test
|
||||
fun givenEmpty_whenSerializeMap_thenResultIsAsExpected() {
|
||||
val map = mapOf<Long, Long>()
|
||||
|
||||
val res = sut.serializeMap(map)
|
||||
|
||||
assertEquals(emptyList(), res)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSerializeMap_thenResultIsAsExpected() {
|
||||
val map = mapOf(1L to 2L)
|
||||
|
||||
val res = sut.serializeMap(map)
|
||||
|
||||
assertEquals(listOf("1:2"), res)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEmpty_whenDeserializeMap_thenResultIsAsExpected() {
|
||||
val list = listOf<String>()
|
||||
|
||||
val res = sut.deserializeMap(list)
|
||||
|
||||
assertEquals(mapOf(), res)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenDeserializeMap_thenResultIsAsExpected() {
|
||||
val list = listOf("1:2")
|
||||
|
||||
val res = sut.deserializeMap(list)
|
||||
|
||||
assertEquals(mapOf(1L to 2L), res)
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.livefast.eattrash.raccoonforlemmy.core.persistence.repository
|
||||
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.preferences.store.TemporaryKeyStore
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.testutils.DispatcherTestRule
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import junit.framework.TestCase.assertNull
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class DefaultPostLastSeenDateRepositoryTest {
|
||||
@get:Rule
|
||||
val dispatcherTestRule = DispatcherTestRule()
|
||||
|
||||
private val keyStore = mockk<TemporaryKeyStore>(relaxUnitFun = true)
|
||||
private val serializer =
|
||||
mockk<LongToLongMapSerializer> {
|
||||
every { deserializeMap(any()) } answers {
|
||||
firstArg<List<String>>()
|
||||
.associate { s ->
|
||||
val tokens = s.split(":").map { it.trim() }
|
||||
tokens[0].toLong() to tokens[1].toLong()
|
||||
}.toMutableMap()
|
||||
}
|
||||
every { serializeMap(any()) } answers {
|
||||
firstArg<Map<String, Int>>()
|
||||
.map { entry ->
|
||||
"${entry.key}:${entry.value}"
|
||||
}.toList()
|
||||
}
|
||||
}
|
||||
|
||||
private val sut =
|
||||
DefaultPostLastSeenDateRepository(
|
||||
keyStore = keyStore,
|
||||
serializer = serializer,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun givenEmptyInitialState_whenSave_thenValueIsStored() =
|
||||
runTest {
|
||||
every { keyStore.get(KEY, listOf()) } returns listOf()
|
||||
sut.save(1L, 2L)
|
||||
|
||||
verify {
|
||||
keyStore.save(KEY, listOf("1:2"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEntryAlreadyExisting_whenSave_thenValueIsStored() =
|
||||
runTest {
|
||||
every { keyStore.get(KEY, listOf()) } returns listOf("1:2")
|
||||
|
||||
sut.save(1, 3)
|
||||
|
||||
verify {
|
||||
keyStore.save(KEY, listOf("1:3"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenOtherEntryAlreadyExisting_whenSave_thenBothValuesAreStored() =
|
||||
runTest {
|
||||
every { keyStore.get(KEY, listOf()) } returns listOf("1:2")
|
||||
|
||||
sut.save(3, 4)
|
||||
|
||||
verify {
|
||||
keyStore.save(KEY, listOf("1:2", "3:4"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenEmptyInitialState_whenGet_thenResultIsAsExpected() =
|
||||
runTest {
|
||||
every { keyStore.get(KEY, listOf()) } returns listOf()
|
||||
|
||||
val res = sut.get(1L)
|
||||
|
||||
assertNull(res)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenCommunityExists_whenGet_thenResultIsAsExpected() =
|
||||
runTest {
|
||||
every { keyStore.get(KEY, listOf()) } returns listOf("1:2")
|
||||
|
||||
val res = sut.get(1L)
|
||||
|
||||
assertEquals(2, res)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenCommunityDoesNotExist_whenGet_thenResultIsAsExpected() =
|
||||
runTest {
|
||||
every { keyStore.get(KEY, listOf()) } returns listOf("1:2")
|
||||
|
||||
val res = sut.get(3L)
|
||||
|
||||
assertNull(res)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY = "postLastSeenDate"
|
||||
}
|
||||
}
|
@ -12,7 +12,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.Default
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultDraftRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultFavoriteCommunityRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultInstanceSelectionRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultLongToLongMapSerializer
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultMultiCommunityRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultPostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultSettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultSortSerializer
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DefaultStopWordRepository
|
||||
@ -22,7 +24,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DomainB
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.DraftRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.FavoriteCommunityRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.InstanceSelectionRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.LongToLongMapSerializer
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.MultiCommunityRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.PostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SortSerializer
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.StopWordRepository
|
||||
@ -164,4 +168,17 @@ val persistenceModule =
|
||||
)
|
||||
}
|
||||
}
|
||||
bind<LongToLongMapSerializer> {
|
||||
singleton {
|
||||
DefaultLongToLongMapSerializer()
|
||||
}
|
||||
}
|
||||
bind<PostLastSeenDateRepository> {
|
||||
singleton {
|
||||
DefaultPostLastSeenDateRepository(
|
||||
keyStore = instance(),
|
||||
serializer = instance(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
package com.livefast.eattrash.raccoonforlemmy.core.persistence.repository
|
||||
|
||||
internal class DefaultLongToLongMapSerializer : LongToLongMapSerializer {
|
||||
override fun deserializeMap(list: List<String>): MutableMap<Long, Long> =
|
||||
list
|
||||
.mapNotNull {
|
||||
it.split(":").takeIf { e -> e.size == 2 }?.let { e -> e[0] to e[1] }
|
||||
}.let { pairs ->
|
||||
val res = mutableMapOf<Long, Long>()
|
||||
for (pair in pairs) {
|
||||
res[pair.first.toLong()] = pair.second.toLong()
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
override fun serializeMap(map: Map<Long, Long>): List<String> =
|
||||
map.map { e ->
|
||||
buildString {
|
||||
append("")
|
||||
append(e.key)
|
||||
append(":")
|
||||
append(e.value)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.livefast.eattrash.raccoonforlemmy.core.persistence.repository
|
||||
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.preferences.store.TemporaryKeyStore
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
internal class DefaultPostLastSeenDateRepository(
|
||||
private val keyStore: TemporaryKeyStore,
|
||||
private val serializer: LongToLongMapSerializer,
|
||||
) : PostLastSeenDateRepository {
|
||||
override suspend fun get(postId: Long): Long? =
|
||||
withContext(Dispatchers.IO) {
|
||||
val map =
|
||||
keyStore.get(SETTINGS_KEY, listOf()).let {
|
||||
serializer.deserializeMap(it)
|
||||
}
|
||||
map[postId]
|
||||
}
|
||||
|
||||
override suspend fun save(
|
||||
postId: Long,
|
||||
timestamp: Long,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
val map =
|
||||
keyStore.get(SETTINGS_KEY, listOf()).let {
|
||||
serializer.deserializeMap(it)
|
||||
}
|
||||
map[postId] = timestamp
|
||||
val newValue = serializer.serializeMap(map)
|
||||
keyStore.save(SETTINGS_KEY, newValue)
|
||||
}
|
||||
|
||||
override suspend fun clear() =
|
||||
withContext(Dispatchers.IO) {
|
||||
keyStore.remove(SETTINGS_KEY)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SETTINGS_KEY = "postLastSeenDate"
|
||||
}
|
||||
}
|
@ -15,6 +15,10 @@ internal class DefaultSortSerializer : SortSerializer {
|
||||
|
||||
override fun serializeMap(map: Map<String, Int>): List<String> =
|
||||
map.map { e ->
|
||||
e.key + ":" + e.value
|
||||
buildString {
|
||||
append(e.key)
|
||||
append(":")
|
||||
append(e.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.livefast.eattrash.raccoonforlemmy.core.persistence.repository
|
||||
|
||||
internal interface LongToLongMapSerializer {
|
||||
fun deserializeMap(list: List<String>): MutableMap<Long, Long>
|
||||
|
||||
fun serializeMap(map: Map<Long, Long>): List<String>
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.livefast.eattrash.raccoonforlemmy.core.persistence.repository
|
||||
|
||||
interface PostLastSeenDateRepository {
|
||||
suspend fun get(postId: Long): Long?
|
||||
|
||||
suspend fun save(
|
||||
postId: Long,
|
||||
timestamp: Long,
|
||||
)
|
||||
|
||||
suspend fun clear()
|
||||
}
|
@ -25,6 +25,11 @@ actual fun Long.toIso8601Timestamp(): String? {
|
||||
return safeFormatter.format(date)
|
||||
}
|
||||
|
||||
actual fun String.toTimestamp(): Long {
|
||||
val date = getDateFromIso8601Timestamp(this)
|
||||
return date.toInstant().toEpochMilli()
|
||||
}
|
||||
|
||||
actual fun getFormattedDate(
|
||||
iso8601Timestamp: String,
|
||||
format: String,
|
||||
|
@ -4,6 +4,8 @@ expect fun epochMillis(): Long
|
||||
|
||||
expect fun Long.toIso8601Timestamp(): String?
|
||||
|
||||
expect fun String.toTimestamp(): Long
|
||||
|
||||
expect fun getFormattedDate(
|
||||
iso8601Timestamp: String,
|
||||
format: String,
|
||||
|
@ -16,6 +16,7 @@ import platform.Foundation.NSTimeZone
|
||||
import platform.Foundation.autoupdatingCurrentLocale
|
||||
import platform.Foundation.localTimeZone
|
||||
import platform.Foundation.timeIntervalSince1970
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
actual fun epochMillis(): Long = (NSDate().timeIntervalSince1970 * 1000).toLong()
|
||||
|
||||
@ -28,6 +29,11 @@ actual fun Long.toIso8601Timestamp(): String? {
|
||||
return dateFormatter.stringFromDate(date)
|
||||
}
|
||||
|
||||
actual fun String.toTimestamp(): Long {
|
||||
val date = getDateFromIso8601Timestamp(this)
|
||||
return date?.timeIntervalSince1970?.let { (it * 1000).roundToLong() } ?: 0
|
||||
}
|
||||
|
||||
actual fun getFormattedDate(
|
||||
iso8601Timestamp: String,
|
||||
format: String,
|
||||
|
@ -7,7 +7,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.SettingsModel
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.AccountRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunityPreferredLanguageRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunitySortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.PostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.UserSortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.usecase.CreateSpecialTagsUseCase
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.testutils.DispatcherTestRule
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository
|
||||
@ -42,6 +44,8 @@ class DefaultLoginUseCaseTest {
|
||||
private val communitySortRepository = mockk<CommunitySortRepository>(relaxUnitFun = true)
|
||||
private val communityPreferredLanguageRepository =
|
||||
mockk<CommunityPreferredLanguageRepository>(relaxUnitFun = true)
|
||||
private val userSortRepository = mockk<UserSortRepository>(relaxUnitFun = true)
|
||||
private val postLastSeenDateRepository = mockk<PostLastSeenDateRepository>(relaxUnitFun = true)
|
||||
private val bottomNavItemsRepository =
|
||||
mockk<BottomNavItemsRepository>(relaxUnitFun = true) {
|
||||
coEvery { get(accountId = any()) } returns BottomNavItemsRepository.DEFAULT_ITEMS
|
||||
@ -61,6 +65,8 @@ class DefaultLoginUseCaseTest {
|
||||
bottomNavItemsRepository = bottomNavItemsRepository,
|
||||
lemmyValueCache = lemmyValueCache,
|
||||
createSpecialTagsUseCase = createSpecialTagsUseCase,
|
||||
userSortRepository = userSortRepository,
|
||||
postLastSeenDateRepository = postLastSeenDateRepository,
|
||||
)
|
||||
|
||||
@Test
|
||||
@ -104,6 +110,8 @@ class DefaultLoginUseCaseTest {
|
||||
settingsRepository.createSettings(anonymousSettings, accountId)
|
||||
settingsRepository.changeCurrentSettings(anonymousSettings)
|
||||
communitySortRepository.clear()
|
||||
userSortRepository.clear()
|
||||
postLastSeenDateRepository.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,6 +164,8 @@ class DefaultLoginUseCaseTest {
|
||||
settingsRepository.createSettings(anonymousSettings, accountId)
|
||||
settingsRepository.changeCurrentSettings(anonymousSettings)
|
||||
communitySortRepository.clear()
|
||||
userSortRepository.clear()
|
||||
postLastSeenDateRepository.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,6 +211,8 @@ class DefaultLoginUseCaseTest {
|
||||
settingsRepository.changeCurrentSettings(oldSettings)
|
||||
communitySortRepository.clear()
|
||||
communityPreferredLanguageRepository.clear()
|
||||
userSortRepository.clear()
|
||||
postLastSeenDateRepository.clear()
|
||||
}
|
||||
coVerify(inverse = true) {
|
||||
accountRepository.createAccount(any())
|
||||
|
@ -7,7 +7,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.AccountModel
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.SettingsModel
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.AccountRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunitySortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.PostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.UserSortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.testutils.DispatcherTestRule
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.repository.LemmyValueCache
|
||||
@ -29,6 +31,8 @@ class DefaultLogoutUseCaseTest {
|
||||
private val notificationCenter = mockk<NotificationCenter>(relaxUnitFun = true)
|
||||
private val communitySortRepository = mockk<CommunitySortRepository>(relaxUnitFun = true)
|
||||
private val lemmyValueCache = mockk<LemmyValueCache>(relaxUnitFun = true)
|
||||
private val userSortRepository = mockk<UserSortRepository>(relaxUnitFun = true)
|
||||
private val postLastSeenDateRepository = mockk<PostLastSeenDateRepository>(relaxUnitFun = true)
|
||||
private val bottomNavItemsRepository =
|
||||
mockk<BottomNavItemsRepository>(relaxUnitFun = true) {
|
||||
coEvery { get(accountId = any()) } returns BottomNavItemsRepository.DEFAULT_ITEMS
|
||||
@ -44,6 +48,8 @@ class DefaultLogoutUseCaseTest {
|
||||
bottomNavItemsRepository = bottomNavItemsRepository,
|
||||
lemmyValueCache = lemmyValueCache,
|
||||
userTagHelper = userTagHelper,
|
||||
userSortRepository = userSortRepository,
|
||||
postLastSeenDateRepository = postLastSeenDateRepository,
|
||||
)
|
||||
|
||||
@Test
|
||||
@ -74,6 +80,8 @@ class DefaultLogoutUseCaseTest {
|
||||
accountRepository.setActive(accountId, false)
|
||||
settingsRepository.changeCurrentSettings(anonymousSettings)
|
||||
userTagHelper.clear()
|
||||
userSortRepository.clear()
|
||||
postLastSeenDateRepository.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.SettingsModel
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.AccountRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunityPreferredLanguageRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunitySortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.PostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.UserSortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.testutils.DispatcherTestRule
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.repository.LemmyValueCache
|
||||
@ -33,6 +35,8 @@ class DefaultSwitchAccountUseCaseTest {
|
||||
private val communitySortRepository = mockk<CommunitySortRepository>(relaxUnitFun = true)
|
||||
private val communityPreferredLanguageRepository =
|
||||
mockk<CommunityPreferredLanguageRepository>(relaxUnitFun = true)
|
||||
private val userSortRepository = mockk<UserSortRepository>(relaxUnitFun = true)
|
||||
private val postLastSeenDateRepository = mockk<PostLastSeenDateRepository>(relaxUnitFun = true)
|
||||
private val lemmyValueCache = mockk<LemmyValueCache>(relaxUnitFun = true)
|
||||
private val bottomNavItemsRepository =
|
||||
mockk<BottomNavItemsRepository>(relaxUnitFun = true) {
|
||||
@ -51,6 +55,8 @@ class DefaultSwitchAccountUseCaseTest {
|
||||
bottomNavItemsRepository = bottomNavItemsRepository,
|
||||
lemmyValueCache = lemmyValueCache,
|
||||
userTagHelper = userTagHelper,
|
||||
userSortRepository = userSortRepository,
|
||||
postLastSeenDateRepository = postLastSeenDateRepository,
|
||||
)
|
||||
|
||||
@Test
|
||||
@ -101,6 +107,8 @@ class DefaultSwitchAccountUseCaseTest {
|
||||
identityRepository.refreshLoggedState()
|
||||
serviceProvider.changeInstance("new-instance")
|
||||
userTagHelper.clear()
|
||||
userSortRepository.clear()
|
||||
postLastSeenDateRepository.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +139,8 @@ val identityModule =
|
||||
bottomNavItemsRepository = instance(),
|
||||
lemmyValueCache = instance(),
|
||||
createSpecialTagsUseCase = instance(),
|
||||
userSortRepository = instance(),
|
||||
postLastSeenDateRepository = instance(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -153,6 +155,8 @@ val identityModule =
|
||||
bottomNavItemsRepository = instance(),
|
||||
userTagHelper = instance(),
|
||||
lemmyValueCache = instance(),
|
||||
userSortRepository = instance(),
|
||||
postLastSeenDateRepository = instance(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -169,6 +173,8 @@ val identityModule =
|
||||
bottomNavItemsRepository = instance(),
|
||||
userTagHelper = instance(),
|
||||
lemmyValueCache = instance(),
|
||||
userSortRepository = instance(),
|
||||
postLastSeenDateRepository = instance(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.AccountModel
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.AccountRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunityPreferredLanguageRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunitySortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.PostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.UserSortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.usecase.CreateSpecialTagsUseCase
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.identity.repository.AuthRepository
|
||||
@ -27,6 +29,8 @@ internal class DefaultLoginUseCase(
|
||||
private val bottomNavItemsRepository: BottomNavItemsRepository,
|
||||
private val lemmyValueCache: LemmyValueCache,
|
||||
private val createSpecialTagsUseCase: CreateSpecialTagsUseCase,
|
||||
private val userSortRepository: UserSortRepository,
|
||||
private val postLastSeenDateRepository: PostLastSeenDateRepository,
|
||||
) : LoginUseCase {
|
||||
override suspend operator fun invoke(
|
||||
instance: String,
|
||||
@ -108,6 +112,8 @@ internal class DefaultLoginUseCase(
|
||||
|
||||
communitySortRepository.clear()
|
||||
communityPreferredLanguageRepository.clear()
|
||||
userSortRepository.clear()
|
||||
postLastSeenDateRepository.clear()
|
||||
|
||||
val newSettings = settingsRepository.getSettings(accountId)
|
||||
settingsRepository.changeCurrentSettings(newSettings)
|
||||
|
@ -6,7 +6,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCent
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.AccountRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunitySortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.PostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.UserSortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.repository.LemmyValueCache
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.repository.UserTagHelper
|
||||
@ -20,6 +22,8 @@ internal class DefaultLogoutUseCase(
|
||||
private val bottomNavItemsRepository: BottomNavItemsRepository,
|
||||
private val lemmyValueCache: LemmyValueCache,
|
||||
private val userTagHelper: UserTagHelper,
|
||||
private val userSortRepository: UserSortRepository,
|
||||
private val postLastSeenDateRepository: PostLastSeenDateRepository,
|
||||
) : LogoutUseCase {
|
||||
override suspend operator fun invoke() {
|
||||
notificationCenter.send(NotificationCenterEvent.ResetExplore)
|
||||
@ -27,6 +31,8 @@ internal class DefaultLogoutUseCase(
|
||||
|
||||
identityRepository.clearToken()
|
||||
communitySortRepository.clear()
|
||||
userSortRepository.clear()
|
||||
postLastSeenDateRepository.clear()
|
||||
lemmyValueCache.refresh()
|
||||
notificationCenter.send(NotificationCenterEvent.Logout)
|
||||
|
||||
|
@ -9,7 +9,9 @@ import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.AccountModel
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.AccountRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunityPreferredLanguageRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.CommunitySortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.PostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.UserSortRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.repository.LemmyValueCache
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.lemmy.repository.UserTagHelper
|
||||
@ -25,6 +27,8 @@ internal class DefaultSwitchAccountUseCase(
|
||||
private val bottomNavItemsRepository: BottomNavItemsRepository,
|
||||
private val lemmyValueCache: LemmyValueCache,
|
||||
private val userTagHelper: UserTagHelper,
|
||||
private val userSortRepository: UserSortRepository,
|
||||
private val postLastSeenDateRepository: PostLastSeenDateRepository,
|
||||
) : SwitchAccountUseCase {
|
||||
override suspend fun invoke(account: AccountModel) {
|
||||
val accountId = account.id ?: return
|
||||
@ -39,6 +43,8 @@ internal class DefaultSwitchAccountUseCase(
|
||||
notificationCenter.send(NotificationCenterEvent.Logout)
|
||||
|
||||
communitySortRepository.clear()
|
||||
userSortRepository.clear()
|
||||
postLastSeenDateRepository.clear()
|
||||
communityPreferredLanguageRepository.clear()
|
||||
|
||||
serviceProvider.changeInstance(instance)
|
||||
|
@ -150,6 +150,7 @@ interface PostDetailMviModel :
|
||||
val meTagColor: Int? = null,
|
||||
val modTagColor: Int? = null,
|
||||
val opTagColor: Int? = null,
|
||||
val lastSeenTimestamp: Long? = null,
|
||||
)
|
||||
|
||||
sealed interface Effect {
|
||||
|
@ -120,6 +120,7 @@ import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.ActionOnSwipe
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.VoteAction
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.datetime.toTimestamp
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.toIcon
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.toLocalDp
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.toModifier
|
||||
@ -1063,22 +1064,33 @@ class PostDetailScreen(
|
||||
emptyList()
|
||||
},
|
||||
content = {
|
||||
val commentTs =
|
||||
with(comment) {
|
||||
updateDate ?: publishDate
|
||||
}?.toTimestamp()
|
||||
val lastSeenTs = uiState.lastSeenTimestamp
|
||||
val isAfterLastSeenTs = commentTs != null &&
|
||||
lastSeenTs != null &&
|
||||
commentTs > lastSeenTs
|
||||
val backgroundModifier =
|
||||
when {
|
||||
commentIdToHighlight == comment.id ||
|
||||
(commentIdToHighlight == null && isAfterLastSeenTs)
|
||||
->
|
||||
Modifier.background(
|
||||
MaterialTheme.colorScheme
|
||||
.surfaceColorAtElevation(
|
||||
5.dp,
|
||||
).copy(alpha = 0.75f),
|
||||
)
|
||||
|
||||
else -> Modifier
|
||||
}
|
||||
CommentCard(
|
||||
modifier =
|
||||
Modifier
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.then(
|
||||
if (comment.id == commentIdToHighlight) {
|
||||
Modifier.background(
|
||||
MaterialTheme.colorScheme
|
||||
.surfaceColorAtElevation(
|
||||
5.dp,
|
||||
).copy(alpha = 0.75f),
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
},
|
||||
),
|
||||
.then(backgroundModifier),
|
||||
comment = comment,
|
||||
isOp = comment.creator?.id == uiState.post.creator?.id,
|
||||
showBot = true,
|
||||
|
@ -7,8 +7,10 @@ import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCent
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.data.UserTagType
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.AccountRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.PostLastSeenDateRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.persistence.repository.UserTagRepository
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.datetime.epochMillis
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.share.ShareHelper
|
||||
import com.livefast.eattrash.raccoonforlemmy.core.utils.vibrate.HapticFeedback
|
||||
import com.livefast.eattrash.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository
|
||||
@ -60,6 +62,7 @@ class PostDetailViewModel(
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val accountRepository: AccountRepository,
|
||||
private val userTagRepository: UserTagRepository,
|
||||
private val postLastSeenDateRepository: PostLastSeenDateRepository,
|
||||
private val userTagHelper: UserTagHelper,
|
||||
private val shareHelper: ShareHelper,
|
||||
private val notificationCenter: NotificationCenter,
|
||||
@ -95,14 +98,20 @@ class PostDetailViewModel(
|
||||
}
|
||||
if (uiState.value.post.id == 0L) {
|
||||
val post = itemCache.getPost(postId) ?: PostModel()
|
||||
val lastSeenTimestamp = postLastSeenDateRepository.get(postId)
|
||||
updateState {
|
||||
it.copy(
|
||||
post = post,
|
||||
isModerator = isModerator,
|
||||
currentUserId = identityRepository.cachedUser?.id,
|
||||
canFetchMore = it.comments.size < post.comments,
|
||||
lastSeenTimestamp = lastSeenTimestamp,
|
||||
)
|
||||
}
|
||||
if (identityRepository.isLogged.value == true) {
|
||||
val now = epochMillis()
|
||||
postLastSeenDateRepository.save(postId = postId, timestamp = now)
|
||||
}
|
||||
}
|
||||
|
||||
themeRepository.postLayout
|
||||
|
@ -35,6 +35,7 @@ val postDetailModule =
|
||||
accountRepository = instance(),
|
||||
userTagRepository = instance(),
|
||||
userTagHelper = instance(),
|
||||
postLastSeenDateRepository = instance(),
|
||||
shareHelper = instance(),
|
||||
notificationCenter = instance(),
|
||||
hapticFeedback = instance(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user