mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-02 00:56:50 +01:00
feat: change favorites from navigation drawer (#993)
This commit is contained in:
parent
98ad71100a
commit
005b2cbdbc
@ -416,4 +416,5 @@ internal val ArStrings =
|
||||
override val noticeBannedUser = "تم حظر المستخدم الحالي من هذا المجتمع"
|
||||
override val settingsHiddenPosts = "المشاركات المخفية"
|
||||
override val settingsMediaList = "تحميلات الوسائط"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer = "إضافة/إزالة المفضلة في درج التنقل"
|
||||
}
|
||||
|
@ -424,4 +424,6 @@ internal val BgStrings =
|
||||
override val noticeBannedUser = "Настоящият потребител е забранен от тази общност"
|
||||
override val settingsHiddenPosts = "Скрити публикации"
|
||||
override val settingsMediaList = "Качване на мултимедия"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Добавяне/премахване на любими в чекмеджето за навигация"
|
||||
}
|
||||
|
@ -420,4 +420,6 @@ internal val CsStrings =
|
||||
override val noticeBannedUser = "Aktuálnímu uživateli byl zakázán přístup do této komunity"
|
||||
override val settingsHiddenPosts = "Skryté příspěvky"
|
||||
override val settingsMediaList = "Nahrávání médií"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Přidat/odebrat oblíbené položky v navigační zásuvce"
|
||||
}
|
||||
|
@ -420,4 +420,6 @@ internal val DaStrings =
|
||||
"Den nuværende bruger er blevet udelukket fra dette fællesskab"
|
||||
override val settingsHiddenPosts = "Skjulte indlæg"
|
||||
override val settingsMediaList = "Medieuploads"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Tilføj/fjern favoritter i navigationsskuffen"
|
||||
}
|
||||
|
@ -423,4 +423,6 @@ internal val DeStrings =
|
||||
override val contentScaleFit = "Angepasste Größe"
|
||||
override val contentScaleFillWidth = "Breite füllen"
|
||||
override val settingsMediaList = "Medien-Uploads"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Favoriten in der Navigationsleiste hinzufügen/entfernen"
|
||||
}
|
||||
|
@ -427,4 +427,6 @@ internal val ElStrings =
|
||||
override val noticeBannedUser = "Ο τρέχων χρήστης έχει αποκλειστεί από αυτήν την κοινότητα"
|
||||
override val settingsHiddenPosts = "Κρυφές αναρτήσεις"
|
||||
override val settingsMediaList = "Μεταφορτώσεις πολυμέσων"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Προσθήκη/αφαίρεση αγαπημένων στο συρτάρι πλοήγησης"
|
||||
}
|
||||
|
@ -417,4 +417,5 @@ internal val EnStrings =
|
||||
override val noticeBannedUser = "The current user has been banned from this community"
|
||||
override val settingsHiddenPosts = "Hidden posts"
|
||||
override val settingsMediaList = "Media uploads"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer = "Add/remove favorites in navigation drawer"
|
||||
}
|
||||
|
@ -416,4 +416,5 @@ internal val EoStrings =
|
||||
override val noticeBannedUser = "La nuna uzanto estas malpermesita de ĉi tiu komunumo"
|
||||
override val settingsHiddenPosts = "Kaŝitaj afiŝoj"
|
||||
override val settingsMediaList = "Amaskomunikiloj alŝutoj"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer = "Aldoni/forigi plej ŝatatajn en navigada tirkesto"
|
||||
}
|
||||
|
@ -421,4 +421,6 @@ internal val EsStrings =
|
||||
override val noticeBannedUser = "El usuario actual ha sido baneado de esta comunidad"
|
||||
override val settingsHiddenPosts = "Publicaciones escondidas"
|
||||
override val settingsMediaList = "Cargas de medios"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Agregar/eliminar favoritos en el cajón de navegación"
|
||||
}
|
||||
|
@ -422,4 +422,6 @@ internal val EtStrings =
|
||||
override val noticeBannedUser = "Praegune kasutaja on sellest kogukonnast keelatud"
|
||||
override val settingsHiddenPosts = "Peidetud postitused"
|
||||
override val settingsMediaList = "Meedia üleslaadimine"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Lemmikute lisamine/eemaldamine navigeerimissahtlis"
|
||||
}
|
||||
|
@ -417,4 +417,6 @@ internal val FiStrings =
|
||||
override val noticeBannedUser = "Nykyinen käyttäjä on estetty tästä yhteisöstä"
|
||||
override val settingsHiddenPosts = "Piilotetut viestit"
|
||||
override val settingsMediaList = "Median lataukset"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Lisää/poista suosikkeja navigointipaneelissa"
|
||||
}
|
||||
|
@ -426,4 +426,6 @@ internal val FrStrings =
|
||||
override val noticeBannedUser = "L\'utilisateur actuel a été banni de cette communauté"
|
||||
override val settingsHiddenPosts = "Messages masqués"
|
||||
override val settingsMediaList = "Téléchargements de médias"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Ajouter/supprimer des favoris dans le tiroir de navigation"
|
||||
}
|
||||
|
@ -421,4 +421,6 @@ internal val GaStrings =
|
||||
override val noticeBannedUser = "Tá cosc ar an úsáideoir reatha ón bpobal seo"
|
||||
override val settingsHiddenPosts = "Poist i bhfolach"
|
||||
override val settingsMediaList = "Uaslódálacha meáin"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Cuir leis/bain na ceanáin sa tarraiceán nascleanúna"
|
||||
}
|
||||
|
@ -421,4 +421,6 @@ internal val HrStrings =
|
||||
override val noticeBannedUser = "Trenutačni korisnik je zabranjen iz ove zajednice"
|
||||
override val settingsHiddenPosts = "Skriveni postovi"
|
||||
override val settingsMediaList = "Prijenos medija"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Dodajte/uklonite favorite u ladici za navigaciju"
|
||||
}
|
||||
|
@ -425,4 +425,6 @@ internal val HuStrings =
|
||||
override val noticeBannedUser = "A jelenlegi felhasználót kitiltották a közösségből"
|
||||
override val settingsHiddenPosts = "Rejtett bejegyzések"
|
||||
override val settingsMediaList = "Médiafeltöltések"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Kedvencek hozzáadása/eltávolítása a navigációs fiókban"
|
||||
}
|
||||
|
@ -422,4 +422,5 @@ internal val ItStrings =
|
||||
override val noticeBannedUser = "L\'utente corrente è stato bannato da questa comunità"
|
||||
override val settingsHiddenPosts = "Post nascosti"
|
||||
override val settingsMediaList = "Caricamenti multimediali"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer = "Aggiungi/rimuovi preferiti in menu laterale"
|
||||
}
|
||||
|
@ -420,4 +420,6 @@ internal val LtStrings =
|
||||
"Dabartinis vartotojas buvo uždraustas dalyvauti šioje bendruomenėje"
|
||||
override val settingsHiddenPosts = "Paslėpti įrašai"
|
||||
override val settingsMediaList = "Žiniasklaidos įkėlimai"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Pridėti / pašalinti mėgstamiausius naršymo skydelyje"
|
||||
}
|
||||
|
@ -419,4 +419,6 @@ internal val LvStrings =
|
||||
override val noticeBannedUser = "Pašreizējais lietotājs ir bloķēts no šīs kopienas"
|
||||
override val settingsHiddenPosts = "Slēptās ziņas"
|
||||
override val settingsMediaList = "Multivides augšupielādes"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Pievienojiet/noņemiet izlasi navigācijas atvilktnē"
|
||||
}
|
||||
|
@ -421,4 +421,6 @@ internal val MtStrings =
|
||||
override val noticeBannedUser = "L-utent attwali ġie pprojbit minn din il-komunità"
|
||||
override val settingsHiddenPosts = "Postijiet moħbija"
|
||||
override val settingsMediaList = "Uploads tal-midja"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Żid/neħħi l-favoriti fil-kexxun tan-navigazzjoni"
|
||||
}
|
||||
|
@ -422,4 +422,6 @@ internal val NlStrings =
|
||||
override val noticeBannedUser = "De huidige gebruiker is uitgesloten van deze community"
|
||||
override val settingsHiddenPosts = "Verborgen berichten"
|
||||
override val settingsMediaList = "Media-uploads"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Favorieten toevoegen/verwijderen in de navigatielade"
|
||||
}
|
||||
|
@ -419,4 +419,6 @@ internal val NoStrings =
|
||||
"Den nåværende brukeren har blitt utestengt fra dette fellesskapet"
|
||||
override val settingsHiddenPosts = "Skjulte innlegg"
|
||||
override val settingsMediaList = "Medieopplastinger"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Legg til/fjern favoritter i navigasjonsskuffen"
|
||||
}
|
||||
|
@ -421,4 +421,5 @@ internal val PlStrings =
|
||||
override val noticeBannedUser = "Bieżący użytkownik został zablokowany w tej społeczności"
|
||||
override val settingsHiddenPosts = "Ukryte posty"
|
||||
override val settingsMediaList = "Przesyłanie multimediów"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer = "Dodaj/usuń ulubione w szufladzie nawigacji"
|
||||
}
|
||||
|
@ -419,4 +419,6 @@ internal val PtBrStrings =
|
||||
override val noticeBannedUser = "O usuário atual foi banido desta comunidade"
|
||||
override val settingsHiddenPosts = "Posts escondidos"
|
||||
override val settingsMediaList = "Carregamentos de mídia"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Adicionar/remover favoritos na gaveta de navegação"
|
||||
}
|
||||
|
@ -420,4 +420,6 @@ internal val PtStrings =
|
||||
override val noticeBannedUser = "O usuário atual foi banido desta comunidade"
|
||||
override val settingsHiddenPosts = "Postagens ocultadas"
|
||||
override val settingsMediaList = "Carregamentos de mídia"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Adicionar/remover favoritos na gaveta de navegação"
|
||||
}
|
||||
|
@ -420,4 +420,6 @@ internal val RoStrings =
|
||||
override val noticeBannedUser = "Utilizatorul actual a fost exclus din această comunitate"
|
||||
override val settingsHiddenPosts = "Postări ascunse"
|
||||
override val settingsMediaList = "Încărcări media"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Adăugă/elimină favoritele din sertarul de navigare"
|
||||
}
|
||||
|
@ -422,4 +422,6 @@ internal val RuStrings =
|
||||
override val noticeBannedUser = "Текущий пользователь заблокирован в этом сообществе"
|
||||
override val settingsHiddenPosts = "Скрытые сообщения"
|
||||
override val settingsMediaList = "Загрузка мультимедиа"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Добавить/удалить избранное в панели навигации"
|
||||
}
|
||||
|
@ -420,4 +420,6 @@ internal val SeStrings =
|
||||
override val noticeBannedUser = "Den nuvarande användaren har blockerats från denna grupp"
|
||||
override val settingsHiddenPosts = "Dolda inlägg"
|
||||
override val settingsMediaList = "Mediauppladdningar"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Lägg till/ta bort favoriter i navigeringslådan"
|
||||
}
|
||||
|
@ -422,4 +422,6 @@ internal val SkStrings =
|
||||
override val noticeBannedUser = "Aktuálny používateľ má zakázaný prístup do tejto komunity"
|
||||
override val settingsHiddenPosts = "Skryté príspevky"
|
||||
override val settingsMediaList = "Nahrávanie médií"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Pridať/odstrániť obľúbené položky v navigačnej zásuvke"
|
||||
}
|
||||
|
@ -420,4 +420,6 @@ internal val SlStrings =
|
||||
override val noticeBannedUser = "Trenutni uporabnik je bil izključen iz te skupnosti"
|
||||
override val settingsHiddenPosts = "Skrite objave"
|
||||
override val settingsMediaList = "Nalaganje medijev"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Dodajte/odstranite priljubljene v predalu za krmarjenje"
|
||||
}
|
||||
|
@ -422,4 +422,6 @@ internal val SqStrings =
|
||||
override val noticeBannedUser = "Përdoruesi aktual është përjashtuar nga ky komunitet"
|
||||
override val settingsHiddenPosts = "Postimet e fshehura"
|
||||
override val settingsMediaList = "Ngarkimet e mediave"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Shto/hiq të preferuarat në sirtarin e navigimit"
|
||||
}
|
||||
|
@ -422,4 +422,6 @@ internal val SrStrings =
|
||||
override val noticeBannedUser = "Тренутном кориснику је забрањен приступ овој заједници"
|
||||
override val settingsHiddenPosts = "Скривени постови"
|
||||
override val settingsMediaList = "Учитавање медија"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Додајте/уклоните фаворите у фиоци за навигацију"
|
||||
}
|
||||
|
@ -415,6 +415,7 @@ interface Strings {
|
||||
val noticeBannedUser: String
|
||||
val settingsHiddenPosts: String
|
||||
val settingsMediaList: String
|
||||
val settingsEnableToggleFavoriteInNavDrawer: String
|
||||
}
|
||||
|
||||
object Locales {
|
||||
|
@ -416,4 +416,6 @@ internal val TokStrings =
|
||||
override val noticeBannedUser = "sina ken lukin ala e lipu mute pi kulupu ni"
|
||||
override val settingsHiddenPosts = "lipu pi lukin ala"
|
||||
override val settingsMediaList = "sitelen linluwi"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"o sin/o weka e ijo pona lon leko luka"
|
||||
}
|
||||
|
@ -421,4 +421,6 @@ internal val TrStrings =
|
||||
override val noticeBannedUser = "Mevcut kullanıcı bu topluluktan yasaklandı"
|
||||
override val settingsHiddenPosts = "Gizli gönderiler"
|
||||
override val settingsMediaList = "Medya yüklemeleri"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Gezinme çekmecesinde favorileri ekle/kaldır"
|
||||
}
|
||||
|
@ -422,4 +422,6 @@ internal val UkStrings =
|
||||
override val noticeBannedUser = "Поточний користувач був забанений у цій спільноті"
|
||||
override val settingsHiddenPosts = "Приховані пости"
|
||||
override val settingsMediaList = "Завантаження медіа"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Додати/видалити вибране в панелі навігації"
|
||||
}
|
||||
|
@ -411,4 +411,6 @@ internal val ZhHkStrings =
|
||||
override val noticeBannedUser = "呢個用戶已被呢個社區禁止"
|
||||
override val settingsHiddenPosts = "隱藏帖子"
|
||||
override val settingsMediaList = "媒體上傳"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Add/remove favorites in navigation drawer"
|
||||
}
|
||||
|
@ -411,4 +411,6 @@ internal val ZhTwStrings =
|
||||
override val settingsAboutLicences = "授權"
|
||||
override val never = "從不"
|
||||
override val appIconDefault = "默認"
|
||||
override val settingsEnableToggleFavoriteInNavDrawer =
|
||||
"Add/remove favorites in navigation drawer"
|
||||
}
|
||||
|
@ -162,4 +162,6 @@ sealed interface NotificationCenterEvent {
|
||||
|
||||
data class ChangeCommunityVisibility(val value: CommunityVisibilityType) :
|
||||
NotificationCenterEvent
|
||||
|
||||
data object FavoritesUpdated : NotificationCenterEvent
|
||||
}
|
||||
|
@ -155,6 +155,7 @@ class DefaultSettingsRepositoryTest {
|
||||
fullWidthImages = if (model.fullWidthImages) 1 else 0,
|
||||
showUnreadComments = if (model.showUnreadComments) 1 else 0,
|
||||
commentIndentAmount = model.commentIndentAmount.toLong(),
|
||||
enableToggleFavoriteInNavDrawer = if (model.enableToggleFavoriteInNavDrawer) 1 else 0,
|
||||
account_id = 1,
|
||||
)
|
||||
}
|
||||
@ -226,6 +227,7 @@ class DefaultSettingsRepositoryTest {
|
||||
fullWidthImages = if (model.fullWidthImages) 1 else 0,
|
||||
showUnreadComments = if (model.showUnreadComments) 1 else 0,
|
||||
commentIndentAmount = model.commentIndentAmount.toLong(),
|
||||
enableToggleFavoriteInNavDrawer = if (model.enableToggleFavoriteInNavDrawer) 1 else 0,
|
||||
account_id = 1,
|
||||
)
|
||||
}
|
||||
@ -293,6 +295,7 @@ class DefaultSettingsRepositoryTest {
|
||||
fullWidthImages: Boolean = false,
|
||||
showUnreadComments: Boolean = true,
|
||||
commentIndentAmount: Int = 2,
|
||||
enableToggleFavoriteInNavDrawer: Boolean = false,
|
||||
) = GetBy(
|
||||
id = id,
|
||||
theme = theme,
|
||||
@ -353,5 +356,6 @@ class DefaultSettingsRepositoryTest {
|
||||
fullWidthImages = if (fullWidthImages) 1 else 0,
|
||||
showUnreadComments = if (showUnreadComments) 1 else 0,
|
||||
commentIndentAmount = commentIndentAmount.toLong(),
|
||||
enableToggleFavoriteInNavDrawer = if (enableToggleFavoriteInNavDrawer) 1 else 0,
|
||||
)
|
||||
}
|
||||
|
@ -62,4 +62,5 @@ data class SettingsModel(
|
||||
val showUnreadComments: Boolean = false,
|
||||
val enableButtonsToScrollBetweenComments: Boolean = false,
|
||||
val commentIndentAmount: Int = 2,
|
||||
val enableToggleFavoriteInNavDrawer: Boolean = false,
|
||||
)
|
||||
|
@ -120,22 +120,28 @@ internal class DefaultSettingsRepository(
|
||||
postBodyMaxLines = settings.postBodyMaxLines?.toLong(),
|
||||
infiniteScrollEnabled = if (settings.infiniteScrollEnabled) 1 else 0,
|
||||
actionsOnSwipeToStartPosts =
|
||||
settings.actionsOnSwipeToStartPosts.map { it.toInt() }
|
||||
settings.actionsOnSwipeToStartPosts
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToEndPosts =
|
||||
settings.actionsOnSwipeToEndPosts.map { it.toInt() }
|
||||
settings.actionsOnSwipeToEndPosts
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToStartComments =
|
||||
settings.actionsOnSwipeToStartComments.map { it.toInt() }
|
||||
settings.actionsOnSwipeToStartComments
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToEndComments =
|
||||
settings.actionsOnSwipeToEndComments.map { it.toInt() }
|
||||
settings.actionsOnSwipeToEndComments
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToStartInbox =
|
||||
settings.actionsOnSwipeToStartInbox.map { it.toInt() }
|
||||
settings.actionsOnSwipeToStartInbox
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToEndInbox =
|
||||
settings.actionsOnSwipeToEndInbox.map { it.toInt() }
|
||||
settings.actionsOnSwipeToEndInbox
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
opaqueSystemBars = if (settings.opaqueSystemBars) 1L else 0L,
|
||||
showScores = if (settings.showScores) 1L else 0L,
|
||||
@ -150,6 +156,7 @@ internal class DefaultSettingsRepository(
|
||||
showUnreadComments = if (settings.showUnreadComments) 1L else 0L,
|
||||
enableButtonsToScrollBetweenComments = if (settings.enableButtonsToScrollBetweenComments) 1L else 0L,
|
||||
fullWidthImages = if (settings.fullWidthImages) 1L else 0L,
|
||||
enableToggleFavoriteInNavDrawer = if (settings.enableToggleFavoriteInNavDrawer) 1L else 0L,
|
||||
)
|
||||
}
|
||||
|
||||
@ -387,22 +394,28 @@ internal class DefaultSettingsRepository(
|
||||
postBodyMaxLines = settings.postBodyMaxLines?.toLong(),
|
||||
infiniteScrollEnabled = if (settings.infiniteScrollEnabled) 1L else 0L,
|
||||
actionsOnSwipeToStartPosts =
|
||||
settings.actionsOnSwipeToStartPosts.map { it.toInt() }
|
||||
settings.actionsOnSwipeToStartPosts
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToEndPosts =
|
||||
settings.actionsOnSwipeToEndPosts.map { it.toInt() }
|
||||
settings.actionsOnSwipeToEndPosts
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToStartComments =
|
||||
settings.actionsOnSwipeToStartComments.map { it.toInt() }
|
||||
settings.actionsOnSwipeToStartComments
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToEndComments =
|
||||
settings.actionsOnSwipeToEndComments.map { it.toInt() }
|
||||
settings.actionsOnSwipeToEndComments
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToStartInbox =
|
||||
settings.actionsOnSwipeToStartInbox.map { it.toInt() }
|
||||
settings.actionsOnSwipeToStartInbox
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
actionsOnSwipeToEndInbox =
|
||||
settings.actionsOnSwipeToEndInbox.map { it.toInt() }
|
||||
settings.actionsOnSwipeToEndInbox
|
||||
.map { it.toInt() }
|
||||
.joinToString(","),
|
||||
opaqueSystemBars = if (settings.opaqueSystemBars) 1L else 0L,
|
||||
showScores = if (settings.showScores) 1L else 0L,
|
||||
@ -417,6 +430,7 @@ internal class DefaultSettingsRepository(
|
||||
showUnreadComments = if (settings.showUnreadComments) 1L else 0L,
|
||||
enableButtonsToScrollBetweenComments = if (settings.enableButtonsToScrollBetweenComments) 1L else 0L,
|
||||
fullWidthImages = if (settings.fullWidthImages) 1L else 0L,
|
||||
enableToggleFavoriteInNavDrawer = if (settings.enableToggleFavoriteInNavDrawer) 1L else 0L,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -472,27 +486,33 @@ private fun GetBy.toModel() =
|
||||
postBodyMaxLines = postBodyMaxLines?.toInt(),
|
||||
infiniteScrollEnabled = infiniteScrollEnabled != 0L,
|
||||
actionsOnSwipeToStartPosts =
|
||||
actionsOnSwipeToStartPosts?.split(",")
|
||||
actionsOnSwipeToStartPosts
|
||||
?.split(",")
|
||||
?.mapNotNull { it.toIntOrNull()?.toActionOnSwipe() }
|
||||
?: ActionOnSwipe.DEFAULT_SWIPE_TO_START_POSTS,
|
||||
actionsOnSwipeToEndPosts =
|
||||
actionsOnSwipeToEndPosts?.split(",")
|
||||
actionsOnSwipeToEndPosts
|
||||
?.split(",")
|
||||
?.mapNotNull { it.toIntOrNull()?.toActionOnSwipe() }
|
||||
?: ActionOnSwipe.DEFAULT_SWIPE_TO_END_POSTS,
|
||||
actionsOnSwipeToStartComments =
|
||||
actionsOnSwipeToStartComments?.split(",")
|
||||
actionsOnSwipeToStartComments
|
||||
?.split(",")
|
||||
?.mapNotNull { it.toIntOrNull()?.toActionOnSwipe() }
|
||||
?: ActionOnSwipe.DEFAULT_SWIPE_TO_START_COMMENTS,
|
||||
actionsOnSwipeToEndComments =
|
||||
actionsOnSwipeToEndComments?.split(",")
|
||||
actionsOnSwipeToEndComments
|
||||
?.split(",")
|
||||
?.mapNotNull { it.toIntOrNull()?.toActionOnSwipe() }
|
||||
?: ActionOnSwipe.DEFAULT_SWIPE_TO_END_COMMENTS,
|
||||
actionsOnSwipeToStartInbox =
|
||||
actionsOnSwipeToStartInbox?.split(",")
|
||||
actionsOnSwipeToStartInbox
|
||||
?.split(",")
|
||||
?.mapNotNull { it.toIntOrNull()?.toActionOnSwipe() }
|
||||
?: ActionOnSwipe.DEFAULT_SWIPE_TO_START_INBOX,
|
||||
actionsOnSwipeToEndInbox =
|
||||
actionsOnSwipeToEndInbox?.split(",")
|
||||
actionsOnSwipeToEndInbox
|
||||
?.split(",")
|
||||
?.mapNotNull { it.toIntOrNull()?.toActionOnSwipe() }
|
||||
?: ActionOnSwipe.DEFAULT_SWIPE_TO_END_INBOX,
|
||||
opaqueSystemBars = opaqueSystemBars == 1L,
|
||||
@ -508,4 +528,5 @@ private fun GetBy.toModel() =
|
||||
showUnreadComments = showUnreadComments == 1L,
|
||||
enableButtonsToScrollBetweenComments = enableButtonsToScrollBetweenComments == 1L,
|
||||
fullWidthImages = fullWidthImages == 1L,
|
||||
enableToggleFavoriteInNavDrawer = enableToggleFavoriteInNavDrawer == 1L,
|
||||
)
|
||||
|
@ -74,6 +74,7 @@ internal data class SerializableSettings(
|
||||
val showUnreadComments: Boolean = false,
|
||||
val enableButtonsToScrollBetweenComments: Boolean = false,
|
||||
val fullWidthImages: Boolean = false,
|
||||
val enableToggleFavoriteInNavDrawer: Boolean = false,
|
||||
)
|
||||
|
||||
internal fun SerializableSettings.toModel() =
|
||||
@ -139,6 +140,7 @@ internal fun SerializableSettings.toModel() =
|
||||
showUnreadComments = showUnreadComments,
|
||||
enableButtonsToScrollBetweenComments = enableButtonsToScrollBetweenComments,
|
||||
fullWidthImages = fullWidthImages,
|
||||
enableToggleFavoriteInNavDrawer = enableToggleFavoriteInNavDrawer,
|
||||
)
|
||||
|
||||
internal fun SettingsModel.toData() =
|
||||
@ -198,4 +200,5 @@ internal fun SettingsModel.toData() =
|
||||
showUnreadComments = showUnreadComments,
|
||||
enableButtonsToScrollBetweenComments = enableButtonsToScrollBetweenComments,
|
||||
fullWidthImages = fullWidthImages,
|
||||
enableToggleFavoriteInNavDrawer = enableToggleFavoriteInNavDrawer,
|
||||
)
|
||||
|
@ -59,6 +59,7 @@ CREATE TABLE SettingsEntity (
|
||||
enableButtonsToScrollBetweenComments INTEGER NOT NULL DEFAULT 0,
|
||||
fullWidthImages INTEGER NOT NULL DEFAULT 0,
|
||||
commentIndentAmount INTEGER NOT NULL DEFAULT 2,
|
||||
enableToggleFavoriteInNavDrawer INTEGER NOT NULL DEFAULT 0,
|
||||
FOREIGN KEY (account_id) REFERENCES AccountEntity(id) ON DELETE CASCADE,
|
||||
UNIQUE(account_id)
|
||||
);
|
||||
@ -123,6 +124,7 @@ INSERT OR IGNORE INTO SettingsEntity (
|
||||
enableButtonsToScrollBetweenComments,
|
||||
fullWidthImages,
|
||||
commentIndentAmount,
|
||||
enableToggleFavoriteInNavDrawer,
|
||||
account_id
|
||||
) VALUES (
|
||||
?,
|
||||
@ -183,6 +185,7 @@ INSERT OR IGNORE INTO SettingsEntity (
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?
|
||||
);
|
||||
|
||||
@ -245,7 +248,8 @@ SET theme = ?,
|
||||
showUnreadComments = ?,
|
||||
enableButtonsToScrollBetweenComments = ?,
|
||||
fullWidthImages = ?,
|
||||
commentIndentAmount = ?
|
||||
commentIndentAmount = ?,
|
||||
enableToggleFavoriteInNavDrawer = ?
|
||||
WHERE account_id = ?;
|
||||
|
||||
getBy:
|
||||
@ -308,6 +312,7 @@ SELECT
|
||||
showUnreadComments,
|
||||
enableButtonsToScrollBetweenComments,
|
||||
fullWidthImages,
|
||||
commentIndentAmount
|
||||
commentIndentAmount,
|
||||
enableToggleFavoriteInNavDrawer
|
||||
FROM SettingsEntity
|
||||
WHERE account_id = ?;
|
||||
|
@ -0,0 +1,2 @@
|
||||
ALTER TABLE SettingsEntity
|
||||
ADD COLUMN enableToggleFavoriteInNavDrawer INTEGER NOT NULL DEFAULT 0;
|
@ -14,7 +14,7 @@
|
||||
{
|
||||
"title": "NicKoehler",
|
||||
"avatar": "https://avatars.githubusercontent.com/u/53040044?v=4",
|
||||
"subtitle": "App icon and artwork",
|
||||
"subtitle": "App icon designer, Code contributor",
|
||||
"url": "https://github.com/NicKoehler"
|
||||
},
|
||||
{
|
||||
|
@ -11,37 +11,71 @@ interface AdvancedSettingsMviModel :
|
||||
ScreenModel,
|
||||
MviModel<AdvancedSettingsMviModel.Intent, AdvancedSettingsMviModel.UiState, AdvancedSettingsMviModel.Effect> {
|
||||
sealed interface Intent {
|
||||
data class ChangeEnableDoubleTapAction(val value: Boolean) : Intent
|
||||
data class ChangeEnableDoubleTapAction(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeAutoLoadImages(val value: Boolean) : Intent
|
||||
data class ChangeAutoLoadImages(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeAutoExpandComments(val value: Boolean) : Intent
|
||||
data class ChangeAutoExpandComments(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeHideNavigationBarWhileScrolling(val value: Boolean) : Intent
|
||||
data class ChangeHideNavigationBarWhileScrolling(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeMarkAsReadWhileScrolling(val value: Boolean) : Intent
|
||||
data class ChangeMarkAsReadWhileScrolling(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeNavBarTitlesVisible(val value: Boolean) : Intent
|
||||
data class ChangeNavBarTitlesVisible(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeSearchPostTitleOnly(val value: Boolean) : Intent
|
||||
data class ChangeSearchPostTitleOnly(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeEdgeToEdge(val value: Boolean) : Intent
|
||||
data class ChangeEdgeToEdge(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeInfiniteScrollDisabled(val value: Boolean) : Intent
|
||||
data class ChangeInfiniteScrollDisabled(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeImageSourcePath(val value: Boolean) : Intent
|
||||
data class ChangeImageSourcePath(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeDefaultLanguage(val value: Long?) : Intent
|
||||
data class ChangeDefaultLanguage(
|
||||
val value: Long?,
|
||||
) : Intent
|
||||
|
||||
data class ChangeFadeReadPosts(val value: Boolean) : Intent
|
||||
data class ChangeFadeReadPosts(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeShowUnreadComments(val value: Boolean) : Intent
|
||||
data class ChangeShowUnreadComments(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data object ExportSettings : Intent
|
||||
|
||||
data class ImportSettings(val content: String) : Intent
|
||||
data class ImportSettings(
|
||||
val content: String,
|
||||
) : Intent
|
||||
|
||||
data class ChangeEnableButtonsToScrollBetweenComments(val value: Boolean) : Intent
|
||||
data class ChangeEnableButtonsToScrollBetweenComments(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
|
||||
data class ChangeEnableToggleFavoriteInNavDrawer(
|
||||
val value: Boolean,
|
||||
) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
@ -71,9 +105,12 @@ interface AdvancedSettingsMviModel :
|
||||
val supportSettingsImportExport: Boolean = true,
|
||||
val loading: Boolean = false,
|
||||
val enableButtonsToScrollBetweenComments: Boolean = false,
|
||||
val enableToggleFavoriteInNavDrawer: Boolean = false,
|
||||
)
|
||||
|
||||
sealed interface Effect {
|
||||
data class SaveSettings(val content: String) : Effect
|
||||
data class SaveSettings(
|
||||
val content: String,
|
||||
) : Effect
|
||||
}
|
||||
}
|
||||
|
@ -97,13 +97,14 @@ class AdvancedSettingsScreen : Screen {
|
||||
var settingsContent by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach { evt ->
|
||||
when (evt) {
|
||||
is AdvancedSettingsMviModel.Effect.SaveSettings -> {
|
||||
settingsContent = evt.content
|
||||
model.effects
|
||||
.onEach { evt ->
|
||||
when (evt) {
|
||||
is AdvancedSettingsMviModel.Effect.SaveSettings -> {
|
||||
settingsContent = evt.content
|
||||
}
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
@ -155,8 +156,7 @@ class AdvancedSettingsScreen : Screen {
|
||||
Modifier
|
||||
.padding(
|
||||
top = padding.calculateTopPadding(),
|
||||
)
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
).nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().verticalScroll(scrollState),
|
||||
@ -287,11 +287,12 @@ class AdvancedSettingsScreen : Screen {
|
||||
|
||||
// default language
|
||||
val languageValue =
|
||||
uiState.availableLanguages.firstOrNull { l ->
|
||||
l.id == uiState.defaultLanguageId
|
||||
}?.takeIf { l ->
|
||||
l.id > 0 // undetermined language
|
||||
}?.name ?: LocalStrings.current.undetermined
|
||||
uiState.availableLanguages
|
||||
.firstOrNull { l ->
|
||||
l.id == uiState.defaultLanguageId
|
||||
}?.takeIf { l ->
|
||||
l.id > 0 // undetermined language
|
||||
}?.name ?: LocalStrings.current.undetermined
|
||||
SettingsRow(
|
||||
title = LocalStrings.current.advancedSettingsDefaultLanguage,
|
||||
value = languageValue,
|
||||
@ -365,7 +366,11 @@ class AdvancedSettingsScreen : Screen {
|
||||
title = LocalStrings.current.settingsZombieModeScrollAmount,
|
||||
value =
|
||||
buildString {
|
||||
val pt = uiState.zombieModeScrollAmount.toLocalDp().value.roundToInt()
|
||||
val pt =
|
||||
uiState.zombieModeScrollAmount
|
||||
.toLocalDp()
|
||||
.value
|
||||
.roundToInt()
|
||||
append(pt)
|
||||
append(LocalStrings.current.settingsPointsShort)
|
||||
},
|
||||
@ -429,6 +434,20 @@ class AdvancedSettingsScreen : Screen {
|
||||
icon = Icons.Default.Science,
|
||||
)
|
||||
if (uiState.isLogged) {
|
||||
// edit favorites in navigation drawer
|
||||
SettingsSwitchRow(
|
||||
title = LocalStrings.current.settingsEnableToggleFavoriteInNavDrawer,
|
||||
value = uiState.enableToggleFavoriteInNavDrawer,
|
||||
onValueChanged =
|
||||
rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
AdvancedSettingsMviModel.Intent.ChangeEnableToggleFavoriteInNavDrawer(
|
||||
value,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
// double tap
|
||||
SettingsSwitchRow(
|
||||
title = LocalStrings.current.settingsEnableDoubleTap,
|
||||
|
@ -40,44 +40,59 @@ class AdvancedSettingsViewModel(
|
||||
private val fileSystemManager: FileSystemManager,
|
||||
private val importSettings: ImportSettingsUseCase,
|
||||
private val exportSettings: ExportSettingsUseCase,
|
||||
) : AdvancedSettingsMviModel,
|
||||
DefaultMviModel<AdvancedSettingsMviModel.Intent, AdvancedSettingsMviModel.UiState, AdvancedSettingsMviModel.Effect>(
|
||||
) : DefaultMviModel<AdvancedSettingsMviModel.Intent, AdvancedSettingsMviModel.UiState, AdvancedSettingsMviModel.Effect>(
|
||||
initialState = AdvancedSettingsMviModel.UiState(),
|
||||
) {
|
||||
),
|
||||
AdvancedSettingsMviModel {
|
||||
init {
|
||||
screenModelScope.launch {
|
||||
themeRepository.navItemTitles.onEach { value ->
|
||||
updateState { it.copy(navBarTitlesVisible = value) }
|
||||
}.launchIn(this)
|
||||
themeRepository.navItemTitles
|
||||
.onEach { value ->
|
||||
updateState { it.copy(navBarTitlesVisible = value) }
|
||||
}.launchIn(this)
|
||||
|
||||
identityRepository.isLogged.onEach { logged ->
|
||||
updateState { it.copy(isLogged = logged ?: false) }
|
||||
}.launchIn(this)
|
||||
identityRepository.isLogged
|
||||
.onEach { logged ->
|
||||
updateState { it.copy(isLogged = logged ?: false) }
|
||||
}.launchIn(this)
|
||||
|
||||
notificationCenter.subscribe(NotificationCenterEvent.ChangeZombieInterval::class).onEach { evt ->
|
||||
changeZombieModeInterval(evt.value)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.ChangeFeedType::class).onEach { evt ->
|
||||
if (evt.screenKey == "advancedSettings") {
|
||||
changeExploreType(evt.value)
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.ChangeZombieScrollAmount::class).onEach { evt ->
|
||||
changeZombieModeScrollAmount(evt.value)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.ChangeInboxType::class).onEach { evt ->
|
||||
changeDefaultInboxUnreadOnly(evt.unreadOnly)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.ChangeSystemBarTheme::class).onEach { evt ->
|
||||
changeSystemBarTheme(evt.value)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.ChangeInboxBackgroundCheckPeriod::class)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.ChangeZombieInterval::class)
|
||||
.onEach { evt ->
|
||||
changeZombieModeInterval(evt.value)
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.ChangeFeedType::class)
|
||||
.onEach { evt ->
|
||||
if (evt.screenKey == "advancedSettings") {
|
||||
changeExploreType(evt.value)
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.ChangeZombieScrollAmount::class)
|
||||
.onEach { evt ->
|
||||
changeZombieModeScrollAmount(evt.value)
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.ChangeInboxType::class)
|
||||
.onEach { evt ->
|
||||
changeDefaultInboxUnreadOnly(evt.unreadOnly)
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.ChangeSystemBarTheme::class)
|
||||
.onEach { evt ->
|
||||
changeSystemBarTheme(evt.value)
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.ChangeInboxBackgroundCheckPeriod::class)
|
||||
.onEach { evt ->
|
||||
changeInboxBackgroundCheckPeriod(evt.value)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.AppIconVariantSelected::class).onEach { evt ->
|
||||
changeAppIconVariant(evt.value.toAppIconVariant())
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.AppIconVariantSelected::class)
|
||||
.onEach { evt ->
|
||||
changeAppIconVariant(evt.value.toAppIconVariant())
|
||||
}.launchIn(this)
|
||||
|
||||
updateAvailableLanguages()
|
||||
|
||||
@ -106,6 +121,7 @@ class AdvancedSettingsViewModel(
|
||||
inboxBackgroundCheckPeriod = settings.inboxBackgroundCheckPeriod,
|
||||
supportSettingsImportExport = fileSystemManager.isSupported,
|
||||
enableButtonsToScrollBetweenComments = settings.enableButtonsToScrollBetweenComments,
|
||||
enableToggleFavoriteInNavDrawer = settings.enableToggleFavoriteInNavDrawer,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -129,26 +145,44 @@ class AdvancedSettingsViewModel(
|
||||
is AdvancedSettingsMviModel.Intent.ChangeMarkAsReadWhileScrolling ->
|
||||
changeMarkAsReadWhileScrolling(intent.value)
|
||||
|
||||
is AdvancedSettingsMviModel.Intent.ChangeSearchPostTitleOnly -> changeSearchPostTitleOnly(intent.value)
|
||||
is AdvancedSettingsMviModel.Intent.ChangeSearchPostTitleOnly ->
|
||||
changeSearchPostTitleOnly(
|
||||
intent.value,
|
||||
)
|
||||
|
||||
is AdvancedSettingsMviModel.Intent.ChangeEdgeToEdge -> changeEdgeToEdge(intent.value)
|
||||
is AdvancedSettingsMviModel.Intent.ChangeInfiniteScrollDisabled ->
|
||||
changeInfiniteScrollDisabled(intent.value)
|
||||
|
||||
is AdvancedSettingsMviModel.Intent.ChangeImageSourcePath -> changeImageSourcePath(intent.value)
|
||||
is AdvancedSettingsMviModel.Intent.ChangeDefaultLanguage -> changeDefaultLanguageId(intent.value)
|
||||
is AdvancedSettingsMviModel.Intent.ChangeDefaultLanguage ->
|
||||
changeDefaultLanguageId(
|
||||
intent.value,
|
||||
)
|
||||
|
||||
is AdvancedSettingsMviModel.Intent.ChangeFadeReadPosts -> changeFadeReadPosts(intent.value)
|
||||
is AdvancedSettingsMviModel.Intent.ChangeShowUnreadComments -> changeShowUnreadPosts(intent.value)
|
||||
is AdvancedSettingsMviModel.Intent.ChangeShowUnreadComments ->
|
||||
changeShowUnreadPosts(
|
||||
intent.value,
|
||||
)
|
||||
|
||||
is AdvancedSettingsMviModel.Intent.ExportSettings -> handleExportSettings()
|
||||
is AdvancedSettingsMviModel.Intent.ImportSettings -> handleImportSettings(intent.content)
|
||||
is AdvancedSettingsMviModel.Intent.ChangeEnableButtonsToScrollBetweenComments ->
|
||||
changeEnableButtonsToScrollBetweenComments(intent.value)
|
||||
|
||||
is AdvancedSettingsMviModel.Intent.ChangeEnableToggleFavoriteInNavDrawer ->
|
||||
changeEnableToggleFavoriteInNavDrawer(
|
||||
intent.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeNavBarTitlesVisible(value: Boolean) {
|
||||
themeRepository.changeNavItemTitles(value)
|
||||
screenModelScope.launch {
|
||||
val settings = settingsRepository.currentSettings.value.copy(navigationTitlesVisible = value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(navigationTitlesVisible = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -156,7 +190,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeEnableDoubleTapAction(value: Boolean) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(enableDoubleTapAction = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(enableDoubleTapAction = value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(enableDoubleTapAction = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -180,7 +215,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeHideNavigationBarWhileScrolling(value: Boolean) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(hideNavigationBarWhileScrolling = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(hideNavigationBarWhileScrolling = value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(hideNavigationBarWhileScrolling = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -188,7 +224,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeMarkAsReadWhileScrolling(value: Boolean) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(markAsReadWhileScrolling = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(markAsReadWhileScrolling = value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(markAsReadWhileScrolling = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -204,7 +241,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeZombieModeScrollAmount(value: Float) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(zombieModeScrollAmount = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(zombieModeScrollAmount = value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(zombieModeScrollAmount = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -212,7 +250,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeDefaultInboxUnreadOnly(value: Boolean) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(defaultInboxUnreadOnly = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(defaultInboxType = value.toInboxDefaultType())
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(defaultInboxType = value.toInboxDefaultType())
|
||||
saveSettings(settings)
|
||||
notificationCenter.send(NotificationCenterEvent.ResetInbox)
|
||||
}
|
||||
@ -221,7 +260,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeSearchPostTitleOnly(value: Boolean) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(searchPostTitleOnly = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(searchPostTitleOnly = value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(searchPostTitleOnly = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -229,7 +269,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeExploreType(value: ListingType) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(defaultExploreType = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(defaultExploreType = value.toInt())
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(defaultExploreType = value.toInt())
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -245,7 +286,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeInfiniteScrollDisabled(value: Boolean) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(infiniteScrollDisabled = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(infiniteScrollEnabled = !value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(infiniteScrollEnabled = !value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -290,7 +332,8 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeInboxBackgroundCheckPeriod(value: Duration) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(inboxBackgroundCheckPeriod = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(inboxBackgroundCheckPeriod = value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(inboxBackgroundCheckPeriod = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
@ -314,7 +357,17 @@ class AdvancedSettingsViewModel(
|
||||
private fun changeEnableButtonsToScrollBetweenComments(value: Boolean) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(enableButtonsToScrollBetweenComments = value) }
|
||||
val settings = settingsRepository.currentSettings.value.copy(enableButtonsToScrollBetweenComments = value)
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(enableButtonsToScrollBetweenComments = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeEnableToggleFavoriteInNavDrawer(value: Boolean) {
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(enableToggleFavoriteInNavDrawer = value) }
|
||||
val settings =
|
||||
settingsRepository.currentSettings.value.copy(enableToggleFavoriteInNavDrawer = value)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
|
@ -67,10 +67,10 @@ class CommunityDetailViewModel(
|
||||
private val communitySortRepository: CommunitySortRepository,
|
||||
private val postNavigationManager: PostNavigationManager,
|
||||
private val communityPreferredLanguageRepository: CommunityPreferredLanguageRepository,
|
||||
) : CommunityDetailMviModel,
|
||||
DefaultMviModel<CommunityDetailMviModel.Intent, CommunityDetailMviModel.UiState, CommunityDetailMviModel.Effect>(
|
||||
) : DefaultMviModel<CommunityDetailMviModel.Intent, CommunityDetailMviModel.UiState, CommunityDetailMviModel.Effect>(
|
||||
initialState = CommunityDetailMviModel.UiState(),
|
||||
) {
|
||||
),
|
||||
CommunityDetailMviModel {
|
||||
private var hideReadPosts = false
|
||||
private val searchEventChannel = Channel<Unit>()
|
||||
|
||||
@ -88,47 +88,56 @@ class CommunityDetailViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
themeRepository.postLayout.onEach { layout ->
|
||||
updateState { it.copy(postLayout = layout) }
|
||||
}.launchIn(this)
|
||||
identityRepository.isLogged.onEach { logged ->
|
||||
updateState { it.copy(isLogged = logged ?: false) }
|
||||
updateAvailableSortTypes()
|
||||
}.launchIn(this)
|
||||
themeRepository.postLayout
|
||||
.onEach { layout ->
|
||||
updateState { it.copy(postLayout = layout) }
|
||||
}.launchIn(this)
|
||||
identityRepository.isLogged
|
||||
.onEach { logged ->
|
||||
updateState { it.copy(isLogged = logged ?: false) }
|
||||
updateAvailableSortTypes()
|
||||
}.launchIn(this)
|
||||
|
||||
settingsRepository.currentSettings.onEach { settings ->
|
||||
updateState {
|
||||
it.copy(
|
||||
blurNsfw = settings.blurNsfw,
|
||||
swipeActionsEnabled = settings.enableSwipeActions,
|
||||
doubleTapActionEnabled = settings.enableDoubleTapAction,
|
||||
fullHeightImages = settings.fullHeightImages,
|
||||
fullWidthImages = settings.fullWidthImages,
|
||||
voteFormat = settings.voteFormat,
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
preferNicknames = settings.preferUserNicknames,
|
||||
actionsOnSwipeToStartPosts = settings.actionsOnSwipeToStartPosts,
|
||||
actionsOnSwipeToEndPosts = settings.actionsOnSwipeToEndPosts,
|
||||
showScores = settings.showScores,
|
||||
fadeReadPosts = settings.fadeReadPosts,
|
||||
showUnreadComments = settings.showUnreadComments,
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
settingsRepository.currentSettings
|
||||
.onEach { settings ->
|
||||
updateState {
|
||||
it.copy(
|
||||
blurNsfw = settings.blurNsfw,
|
||||
swipeActionsEnabled = settings.enableSwipeActions,
|
||||
doubleTapActionEnabled = settings.enableDoubleTapAction,
|
||||
fullHeightImages = settings.fullHeightImages,
|
||||
fullWidthImages = settings.fullWidthImages,
|
||||
voteFormat = settings.voteFormat,
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
preferNicknames = settings.preferUserNicknames,
|
||||
actionsOnSwipeToStartPosts = settings.actionsOnSwipeToStartPosts,
|
||||
actionsOnSwipeToEndPosts = settings.actionsOnSwipeToEndPosts,
|
||||
showScores = settings.showScores,
|
||||
fadeReadPosts = settings.fadeReadPosts,
|
||||
showUnreadComments = settings.showUnreadComments,
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
|
||||
zombieModeHelper.index.onEach { index ->
|
||||
if (uiState.value.zombieModeActive) {
|
||||
emitEffect(CommunityDetailMviModel.Effect.ZombieModeTick(index))
|
||||
}
|
||||
}.launchIn(this)
|
||||
zombieModeHelper.index
|
||||
.onEach { index ->
|
||||
if (uiState.value.zombieModeActive) {
|
||||
emitEffect(CommunityDetailMviModel.Effect.ZombieModeTick(index))
|
||||
}
|
||||
}.launchIn(this)
|
||||
|
||||
notificationCenter.subscribe(NotificationCenterEvent.PostUpdated::class).onEach { evt ->
|
||||
handlePostUpdate(evt.model)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.PostRemoved::class).onEach { evt ->
|
||||
handlePostDelete(evt.model.id)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.UserBannedPost::class)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.PostUpdated::class)
|
||||
.onEach { evt ->
|
||||
handlePostUpdate(evt.model)
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.PostRemoved::class)
|
||||
.onEach { evt ->
|
||||
handlePostDelete(evt.model.id)
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.UserBannedPost::class)
|
||||
.onEach { evt ->
|
||||
val postId = evt.postId
|
||||
val newUser = evt.user
|
||||
@ -148,7 +157,8 @@ class CommunityDetailViewModel(
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.CommentRemoved::class)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.CommentRemoved::class)
|
||||
.onEach { evt ->
|
||||
val postId = evt.model.postId
|
||||
uiState.value.posts.firstOrNull { it.id == postId }?.also {
|
||||
@ -157,7 +167,8 @@ class CommunityDetailViewModel(
|
||||
}
|
||||
}.launchIn(this)
|
||||
val communityHandle = uiState.value.community.readableHandle
|
||||
notificationCenter.subscribe(NotificationCenterEvent.ChangeSortType::class)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.ChangeSortType::class)
|
||||
.onEach { evt ->
|
||||
if (evt.screenKey == communityHandle) {
|
||||
if (evt.defaultForCommunity) {
|
||||
@ -166,19 +177,26 @@ class CommunityDetailViewModel(
|
||||
applySortType(evt.value)
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.Share::class).onEach { evt ->
|
||||
shareHelper.share(evt.url)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.CopyText::class).onEach {
|
||||
emitEffect(CommunityDetailMviModel.Effect.TriggerCopy(it.value))
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.Share::class)
|
||||
.onEach { evt ->
|
||||
shareHelper.share(evt.url)
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.CopyText::class)
|
||||
.onEach {
|
||||
emitEffect(CommunityDetailMviModel.Effect.TriggerCopy(it.value))
|
||||
}.launchIn(this)
|
||||
|
||||
searchEventChannel.receiveAsFlow().debounce(1_000).onEach {
|
||||
updateState { it.copy(loading = false) }
|
||||
emitEffect(CommunityDetailMviModel.Effect.BackToTop)
|
||||
delay(50)
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
searchEventChannel
|
||||
.receiveAsFlow()
|
||||
.debounce(1_000)
|
||||
.onEach {
|
||||
updateState { it.copy(loading = false) }
|
||||
emitEffect(CommunityDetailMviModel.Effect.BackToTop)
|
||||
delay(50)
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
|
||||
if (uiState.value.currentUserId == null) {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
@ -194,7 +212,8 @@ class CommunityDetailViewModel(
|
||||
}
|
||||
if (uiState.value.initial) {
|
||||
val defaultPostSortType =
|
||||
settingsRepository.currentSettings.value.defaultPostSortType.toSortType()
|
||||
settingsRepository.currentSettings.value.defaultPostSortType
|
||||
.toSortType()
|
||||
val customPostSortType =
|
||||
communitySortRepository.get(communityHandle)?.toSortType()
|
||||
val preferredLanguageId = communityPreferredLanguageRepository.get(communityHandle)
|
||||
@ -296,19 +315,22 @@ class CommunityDetailViewModel(
|
||||
}
|
||||
|
||||
is CommunityDetailMviModel.Intent.ModFeaturePost ->
|
||||
uiState.value.posts.firstOrNull { it.id == intent.id }
|
||||
uiState.value.posts
|
||||
.firstOrNull { it.id == intent.id }
|
||||
?.also { post ->
|
||||
feature(post = post)
|
||||
}
|
||||
|
||||
is CommunityDetailMviModel.Intent.AdminFeaturePost ->
|
||||
uiState.value.posts.firstOrNull { it.id == intent.id }
|
||||
uiState.value.posts
|
||||
.firstOrNull { it.id == intent.id }
|
||||
?.also { post ->
|
||||
featureLocal(post = post)
|
||||
}
|
||||
|
||||
is CommunityDetailMviModel.Intent.ModLockPost ->
|
||||
uiState.value.posts.firstOrNull { it.id == intent.id }
|
||||
uiState.value.posts
|
||||
.firstOrNull { it.id == intent.id }
|
||||
?.also { post ->
|
||||
lock(post = post)
|
||||
}
|
||||
@ -381,12 +403,13 @@ class CommunityDetailViewModel(
|
||||
val isFavorite =
|
||||
favoriteCommunityRepository.getBy(accountId, currentState.community.id) != null
|
||||
val refreshedCommunity =
|
||||
communityRepository.get(
|
||||
auth = auth,
|
||||
name = currentState.community.name,
|
||||
id = currentState.community.id,
|
||||
instance = otherInstance,
|
||||
)?.copy(favorite = isFavorite)
|
||||
communityRepository
|
||||
.get(
|
||||
auth = auth,
|
||||
name = currentState.community.name,
|
||||
id = currentState.community.id,
|
||||
instance = otherInstance,
|
||||
)?.copy(favorite = isFavorite)
|
||||
val moderators =
|
||||
communityRepository.getModerators(
|
||||
auth = auth,
|
||||
@ -436,26 +459,28 @@ class CommunityDetailViewModel(
|
||||
}
|
||||
updateState { it.copy(loading = true) }
|
||||
val posts =
|
||||
postPaginationManager.loadNextPage().let {
|
||||
if (!hideReadPosts) {
|
||||
it
|
||||
} else {
|
||||
it.filter { post -> !post.read }
|
||||
}
|
||||
}.let {
|
||||
if (currentState.searching) {
|
||||
it.filter { post ->
|
||||
listOf(post.title, post.text).any { s ->
|
||||
s.contains(
|
||||
other = currentState.searchText,
|
||||
ignoreCase = true,
|
||||
)
|
||||
}
|
||||
postPaginationManager
|
||||
.loadNextPage()
|
||||
.let {
|
||||
if (!hideReadPosts) {
|
||||
it
|
||||
} else {
|
||||
it.filter { post -> !post.read }
|
||||
}
|
||||
}.let {
|
||||
if (currentState.searching) {
|
||||
it.filter { post ->
|
||||
listOf(post.title, post.text).any { s ->
|
||||
s.contains(
|
||||
other = currentState.searchText,
|
||||
ignoreCase = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
it
|
||||
}
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
if (uiState.value.autoLoadImages) {
|
||||
posts.forEach { post ->
|
||||
post.imageUrl.takeIf { i -> i.isNotEmpty() }?.also { url ->
|
||||
@ -775,9 +800,11 @@ class CommunityDetailViewModel(
|
||||
if (newValue) {
|
||||
val model = FavoriteCommunityModel(communityId = communityId)
|
||||
favoriteCommunityRepository.create(model, accountId)
|
||||
notificationCenter.send(NotificationCenterEvent.FavoritesUpdated)
|
||||
} else {
|
||||
favoriteCommunityRepository.getBy(accountId, communityId)?.also { toDelete ->
|
||||
favoriteCommunityRepository.delete(accountId, toDelete)
|
||||
notificationCenter.send(NotificationCenterEvent.FavoritesUpdated)
|
||||
}
|
||||
}
|
||||
val newCommunity = uiState.value.community.copy(favorite = newValue)
|
||||
|
@ -103,20 +103,24 @@ object ModalDrawerContent : Tab {
|
||||
|
||||
var uiFontSizeWorkaround by remember { mutableStateOf(true) }
|
||||
LaunchedEffect(themeRepository) {
|
||||
themeRepository.uiFontScale.drop(1).onEach {
|
||||
uiFontSizeWorkaround = false
|
||||
delay(50)
|
||||
uiFontSizeWorkaround = true
|
||||
}.launchIn(this)
|
||||
themeRepository.uiFontScale
|
||||
.drop(1)
|
||||
.onEach {
|
||||
uiFontSizeWorkaround = false
|
||||
delay(50)
|
||||
uiFontSizeWorkaround = true
|
||||
}.launchIn(this)
|
||||
}
|
||||
if (!uiFontSizeWorkaround) {
|
||||
return
|
||||
}
|
||||
LaunchedEffect(notificationCenter) {
|
||||
notificationCenter.subscribe(NotificationCenterEvent.InstanceSelected::class).onEach {
|
||||
// closes the navigation drawer after instance change
|
||||
coordinator.closeDrawer()
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.InstanceSelected::class)
|
||||
.onEach {
|
||||
// closes the navigation drawer after instance change
|
||||
coordinator.closeDrawer()
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
ModalDrawerSheet {
|
||||
@ -125,21 +129,22 @@ object ModalDrawerContent : Tab {
|
||||
instance = uiState.instance,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
onOpenChangeInstance =
|
||||
rememberCallback(model) {
|
||||
navigationCoordinator.showBottomSheet(SelectInstanceBottomSheet())
|
||||
},
|
||||
onOpenSwitchAccount = {
|
||||
navigationCoordinator.showBottomSheet(ManageAccountsScreen())
|
||||
},
|
||||
rememberCallback(model) {
|
||||
navigationCoordinator.showBottomSheet(SelectInstanceBottomSheet())
|
||||
},
|
||||
onOpenSwitchAccount =
|
||||
rememberCallback {
|
||||
navigationCoordinator.showBottomSheet(ManageAccountsScreen())
|
||||
},
|
||||
)
|
||||
|
||||
HorizontalDivider(
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(
|
||||
top = Spacing.s,
|
||||
bottom = Spacing.s,
|
||||
),
|
||||
Modifier
|
||||
.padding(
|
||||
top = Spacing.s,
|
||||
bottom = Spacing.s,
|
||||
),
|
||||
)
|
||||
|
||||
if (uiState.user != null) {
|
||||
@ -147,16 +152,16 @@ object ModalDrawerContent : Tab {
|
||||
rememberPullRefreshState(
|
||||
refreshing = uiState.refreshing,
|
||||
onRefresh =
|
||||
rememberCallback(model) {
|
||||
model.reduce(ModalDrawerMviModel.Intent.Refresh)
|
||||
},
|
||||
rememberCallback(model) {
|
||||
model.reduce(ModalDrawerMviModel.Intent.Refresh)
|
||||
},
|
||||
)
|
||||
Box(
|
||||
modifier =
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.nestedScroll(keyboardScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.nestedScroll(keyboardScrollConnection)
|
||||
.pullRefresh(pullRefreshState),
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize().padding(horizontal = Spacing.xxs),
|
||||
@ -165,45 +170,45 @@ object ModalDrawerContent : Tab {
|
||||
item {
|
||||
TextField(
|
||||
modifier =
|
||||
Modifier
|
||||
.scale(0.95f)
|
||||
.padding(
|
||||
horizontal = Spacing.xxs,
|
||||
vertical = Spacing.xxs,
|
||||
).fillMaxWidth(),
|
||||
Modifier
|
||||
.scale(0.95f)
|
||||
.padding(
|
||||
horizontal = Spacing.xxs,
|
||||
vertical = Spacing.xxs,
|
||||
).fillMaxWidth(),
|
||||
label = {
|
||||
Text(text = LocalStrings.current.exploreSearchPlaceholder)
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.searchText,
|
||||
keyboardOptions =
|
||||
KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
imeAction = ImeAction.Search,
|
||||
),
|
||||
KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
imeAction = ImeAction.Search,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(ModalDrawerMviModel.Intent.SetSearch(value))
|
||||
},
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
modifier =
|
||||
Modifier.onClick(
|
||||
onClick = {
|
||||
if (uiState.searchText.isNotEmpty()) {
|
||||
model.reduce(
|
||||
ModalDrawerMviModel.Intent.SetSearch(
|
||||
"",
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
Modifier.onClick(
|
||||
onClick = {
|
||||
if (uiState.searchText.isNotEmpty()) {
|
||||
model.reduce(
|
||||
ModalDrawerMviModel.Intent.SetSearch(
|
||||
"",
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
imageVector =
|
||||
if (uiState.searchText.isEmpty()) {
|
||||
Icons.Default.Search
|
||||
} else {
|
||||
Icons.Default.Clear
|
||||
},
|
||||
if (uiState.searchText.isEmpty()) {
|
||||
Icons.Default.Search
|
||||
} else {
|
||||
Icons.Default.Clear
|
||||
},
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
@ -223,15 +228,15 @@ object ModalDrawerContent : Tab {
|
||||
title = listingType.toReadableName(),
|
||||
icon = listingType.toIcon(),
|
||||
onSelected =
|
||||
rememberCallback(coordinator) {
|
||||
scope.launch {
|
||||
focusManager.clearFocus()
|
||||
coordinator.toggleDrawer()
|
||||
coordinator.sendEvent(
|
||||
DrawerEvent.ChangeListingType(listingType),
|
||||
)
|
||||
}
|
||||
},
|
||||
rememberCallback(coordinator) {
|
||||
scope.launch {
|
||||
focusManager.clearFocus()
|
||||
coordinator.toggleDrawer()
|
||||
coordinator.sendEvent(
|
||||
DrawerEvent.ChangeListingType(listingType),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -259,7 +264,7 @@ object ModalDrawerContent : Tab {
|
||||
|
||||
items(
|
||||
items = uiState.favorites,
|
||||
key = { it.id.toString() },
|
||||
key = { "${it.id}-favorite" },
|
||||
) { community ->
|
||||
DrawerCommunityItem(
|
||||
title = community.readableName(uiState.preferNicknames),
|
||||
@ -276,17 +281,28 @@ object ModalDrawerContent : Tab {
|
||||
)
|
||||
}
|
||||
},
|
||||
onToggleFavorite =
|
||||
if (!uiState.enableToggleFavorite) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
ModalDrawerMviModel.Intent.ToggleFavorite(community.id),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
items(
|
||||
items = uiState.communities,
|
||||
key = { it.id.toString() },
|
||||
key = { "${it.id}-community" },
|
||||
) { community ->
|
||||
DrawerCommunityItem(
|
||||
title = community.readableName(uiState.preferNicknames),
|
||||
subtitle = community.readableHandle,
|
||||
url = community.icon,
|
||||
favorite = false,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
onSelected = {
|
||||
scope.launch {
|
||||
@ -297,6 +313,16 @@ object ModalDrawerContent : Tab {
|
||||
)
|
||||
}
|
||||
},
|
||||
onToggleFavorite =
|
||||
if (!uiState.enableToggleFavorite) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
ModalDrawerMviModel.Intent.ToggleFavorite(community.id),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,15 @@ interface ModalDrawerMviModel :
|
||||
sealed interface Intent {
|
||||
data object Refresh : Intent
|
||||
|
||||
data class SetSearch(val value: String) : Intent
|
||||
data class SetSearch(
|
||||
val value: String,
|
||||
) : Intent
|
||||
|
||||
data object LoadNextPage : Intent
|
||||
|
||||
data class ToggleFavorite(
|
||||
val id: Long,
|
||||
) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
@ -31,6 +38,7 @@ interface ModalDrawerMviModel :
|
||||
val favorites: List<CommunityModel> = emptyList(),
|
||||
val searchText: String = "",
|
||||
val isFiltering: Boolean = false,
|
||||
val enableToggleFavorite: Boolean = false,
|
||||
)
|
||||
|
||||
sealed interface Effect
|
||||
|
@ -4,6 +4,7 @@ import cafe.adriel.voyager.core.model.screenModelScope
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.FavoriteCommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.AccountRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.FavoriteCommunityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.MultiCommunityRepository
|
||||
@ -12,21 +13,15 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.ApiCo
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flatMapConcat
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import kotlinx.coroutines.yield
|
||||
@ -41,47 +36,60 @@ class ModalDrawerViewModel(
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val favoriteCommunityRepository: FavoriteCommunityRepository,
|
||||
private val notificationCenter: NotificationCenter,
|
||||
) : ModalDrawerMviModel,
|
||||
DefaultMviModel<ModalDrawerMviModel.Intent, ModalDrawerMviModel.UiState, ModalDrawerMviModel.Effect>(
|
||||
) : DefaultMviModel<ModalDrawerMviModel.Intent, ModalDrawerMviModel.UiState, ModalDrawerMviModel.Effect>(
|
||||
initialState = ModalDrawerMviModel.UiState(),
|
||||
) {
|
||||
),
|
||||
ModalDrawerMviModel {
|
||||
private var currentPage = 1
|
||||
private val searchEventChannel = Channel<Unit>()
|
||||
|
||||
init {
|
||||
screenModelScope.launch {
|
||||
apiConfigurationRepository.instance.onEach { instance ->
|
||||
updateState {
|
||||
it.copy(instance = instance)
|
||||
}
|
||||
}.launchIn(this)
|
||||
apiConfigurationRepository.instance
|
||||
.onEach { instance ->
|
||||
updateState {
|
||||
it.copy(instance = instance)
|
||||
}
|
||||
}.launchIn(this)
|
||||
|
||||
identityRepository.isLogged.onEach { _ ->
|
||||
refreshUser()
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
identityRepository.isLogged
|
||||
.onEach { _ ->
|
||||
refreshUser()
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
|
||||
notificationCenter.subscribe(NotificationCenterEvent.Logout::class).onEach {
|
||||
delay(250)
|
||||
refreshUser()
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.Logout::class)
|
||||
.onEach {
|
||||
delay(250)
|
||||
refreshUser()
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
|
||||
settingsRepository.currentSettings.onEach { settings ->
|
||||
updateState {
|
||||
it.copy(
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
preferNicknames = settings.preferUserNicknames,
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.FavoritesUpdated::class)
|
||||
.onEach {
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
|
||||
settingsRepository.currentSettings
|
||||
.onEach { settings ->
|
||||
updateState {
|
||||
it.copy(
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
preferNicknames = settings.preferUserNicknames,
|
||||
enableToggleFavorite = settings.enableToggleFavoriteInNavDrawer,
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
searchEventChannel.receiveAsFlow().debounce(1000).onEach {
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
|
||||
observeChangesInFavoriteCommunities()
|
||||
searchEventChannel
|
||||
.receiveAsFlow()
|
||||
.debounce(1000)
|
||||
.onEach {
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
|
||||
delay(250)
|
||||
refreshUser()
|
||||
@ -89,53 +97,25 @@ class ModalDrawerViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun CoroutineScope.observeChangesInFavoriteCommunities() {
|
||||
channelFlow {
|
||||
while (isActive) {
|
||||
val accountId = accountRepository.getActive()?.id
|
||||
trySend(accountId)
|
||||
delay(1000)
|
||||
}
|
||||
}.distinctUntilChanged().flatMapConcat { accountId ->
|
||||
channelFlow {
|
||||
while (isActive) {
|
||||
val communityIds =
|
||||
favoriteCommunityRepository.getAll(accountId).map { it.communityId }
|
||||
trySend(communityIds)
|
||||
delay(1000)
|
||||
}
|
||||
}.distinctUntilChanged()
|
||||
}.onEach { favoriteCommunityIds ->
|
||||
val currentState = uiState.value
|
||||
val newFavorites =
|
||||
currentState.favorites.filter { it.id in favoriteCommunityIds } + currentState.communities.filter { it.id in favoriteCommunityIds }
|
||||
val newCommunities =
|
||||
(currentState.communities.filter { it.id !in favoriteCommunityIds } + currentState.favorites.filter { it.id !in favoriteCommunityIds })
|
||||
updateState {
|
||||
it.copy(
|
||||
favorites = newFavorites,
|
||||
communities = newCommunities,
|
||||
)
|
||||
}
|
||||
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
override fun reduce(intent: ModalDrawerMviModel.Intent) {
|
||||
when (intent) {
|
||||
ModalDrawerMviModel.Intent.Refresh -> screenModelScope.launch {
|
||||
refresh()
|
||||
}
|
||||
ModalDrawerMviModel.Intent.Refresh ->
|
||||
screenModelScope.launch {
|
||||
refresh()
|
||||
}
|
||||
|
||||
is ModalDrawerMviModel.Intent.SetSearch -> screenModelScope.launch {
|
||||
updateState { it.copy(searchText = intent.value) }
|
||||
searchEventChannel.send(Unit)
|
||||
}
|
||||
is ModalDrawerMviModel.Intent.SetSearch ->
|
||||
screenModelScope.launch {
|
||||
updateState { it.copy(searchText = intent.value) }
|
||||
searchEventChannel.send(Unit)
|
||||
}
|
||||
|
||||
ModalDrawerMviModel.Intent.LoadNextPage -> screenModelScope.launch {
|
||||
loadNextPage()
|
||||
}
|
||||
ModalDrawerMviModel.Intent.LoadNextPage ->
|
||||
screenModelScope.launch {
|
||||
loadNextPage()
|
||||
}
|
||||
|
||||
is ModalDrawerMviModel.Intent.ToggleFavorite -> toggleFavorite(intent.id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,46 +155,48 @@ class ModalDrawerViewModel(
|
||||
val accountId = accountRepository.getActive()?.id
|
||||
val searchText = uiState.value.searchText
|
||||
val multiCommunities =
|
||||
accountId?.let {
|
||||
multiCommunityRepository.getAll(it)
|
||||
.let { communities ->
|
||||
if (searchText.isEmpty()) {
|
||||
communities
|
||||
} else {
|
||||
communities.filter { c ->
|
||||
c.name.contains(
|
||||
other = searchText,
|
||||
ignoreCase = true
|
||||
)
|
||||
accountId
|
||||
?.let {
|
||||
multiCommunityRepository
|
||||
.getAll(it)
|
||||
.let { communities ->
|
||||
if (searchText.isEmpty()) {
|
||||
communities
|
||||
} else {
|
||||
communities.filter { c ->
|
||||
c.name.contains(
|
||||
other = searchText,
|
||||
ignoreCase = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.sortedBy { e -> e.name }
|
||||
}.orEmpty()
|
||||
}.sortedBy { e -> e.name }
|
||||
}.orEmpty()
|
||||
|
||||
val favorites = coroutineScope {
|
||||
val auth = identityRepository.authToken.value
|
||||
favoriteCommunityRepository.getAll(accountId).mapNotNull { favorite ->
|
||||
val communityId = favorite.communityId
|
||||
async {
|
||||
communityRepository.get(
|
||||
auth = auth,
|
||||
id = communityId,
|
||||
)
|
||||
}.await()
|
||||
}
|
||||
}.let { communities ->
|
||||
if (searchText.isEmpty()) {
|
||||
communities
|
||||
} else {
|
||||
communities.filter { c ->
|
||||
c.name.contains(
|
||||
other = searchText,
|
||||
ignoreCase = true
|
||||
)
|
||||
val favorites =
|
||||
coroutineScope {
|
||||
val auth = identityRepository.authToken.value
|
||||
favoriteCommunityRepository.getAll(accountId).mapNotNull { favorite ->
|
||||
val communityId = favorite.communityId
|
||||
async {
|
||||
communityRepository.get(
|
||||
auth = auth,
|
||||
id = communityId,
|
||||
)
|
||||
}.await()
|
||||
}
|
||||
}.let { communities ->
|
||||
if (searchText.isEmpty()) {
|
||||
communities
|
||||
} else {
|
||||
communities.filter { c ->
|
||||
c.name.contains(
|
||||
other = searchText,
|
||||
ignoreCase = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateState {
|
||||
it.copy(
|
||||
@ -234,21 +216,23 @@ class ModalDrawerViewModel(
|
||||
}
|
||||
val auth = identityRepository.authToken.value
|
||||
val searchText = uiState.value.searchText
|
||||
val itemsToAdd = communityRepository.getSubscribed(
|
||||
auth = auth,
|
||||
page = currentPage,
|
||||
query = searchText,
|
||||
).filter { c1 ->
|
||||
// exclude items already included in favorites
|
||||
currentState.favorites.none { c2 -> c2.id == c1.id }
|
||||
}.filter { c1 ->
|
||||
// prevents accidental duplication
|
||||
if (!currentState.refreshing) {
|
||||
currentState.communities.none { c2 -> c2.id == c1.id }
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
val itemsToAdd =
|
||||
communityRepository
|
||||
.getSubscribed(
|
||||
auth = auth,
|
||||
page = currentPage,
|
||||
query = searchText,
|
||||
).filter { c1 ->
|
||||
// exclude items already included in favorites
|
||||
currentState.favorites.none { c2 -> c2.id == c1.id }
|
||||
}.filter { c1 ->
|
||||
// prevents accidental duplication
|
||||
if (!currentState.refreshing) {
|
||||
currentState.communities.none { c2 -> c2.id == c1.id }
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
if (itemsToAdd.isNotEmpty()) {
|
||||
currentPage++
|
||||
}
|
||||
@ -256,14 +240,49 @@ class ModalDrawerViewModel(
|
||||
it.copy(
|
||||
isFiltering = searchText.isNotEmpty(),
|
||||
refreshing = false,
|
||||
communities = if (currentState.refreshing) {
|
||||
itemsToAdd
|
||||
} else {
|
||||
currentState.communities + itemsToAdd
|
||||
},
|
||||
communities =
|
||||
if (currentState.refreshing) {
|
||||
itemsToAdd
|
||||
} else {
|
||||
currentState.communities + itemsToAdd
|
||||
},
|
||||
canFetchMore = itemsToAdd.isNotEmpty(),
|
||||
loading = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleFavorite(communityId: Long) {
|
||||
screenModelScope.launch {
|
||||
val currentState = uiState.value
|
||||
val accountId = accountRepository.getActive()?.id ?: 0L
|
||||
val isCurrentlyFavorite = currentState.favorites.any { it.id == communityId }
|
||||
if (isCurrentlyFavorite) {
|
||||
val community = currentState.favorites.first { it.id == communityId }
|
||||
favoriteCommunityRepository.getBy(accountId, communityId)?.also { toDelete ->
|
||||
favoriteCommunityRepository.delete(accountId, toDelete)
|
||||
}
|
||||
val newFavorites = currentState.favorites.filter { it.id != communityId }
|
||||
val newCommunities = currentState.communities + community
|
||||
updateState {
|
||||
it.copy(
|
||||
favorites = newFavorites,
|
||||
communities = newCommunities,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val model = FavoriteCommunityModel(communityId = communityId)
|
||||
favoriteCommunityRepository.create(model, accountId)
|
||||
val community = currentState.communities.first { it.id == communityId }
|
||||
val newFavorites = currentState.favorites + community
|
||||
val newCommunities = currentState.communities.filter { it.id != communityId }
|
||||
updateState {
|
||||
it.copy(
|
||||
favorites = newFavorites,
|
||||
communities = newCommunities,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.unit.drawer.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Star
|
||||
import androidx.compose.material.icons.filled.StarBorder
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationDrawerItem
|
||||
@ -13,10 +15,12 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.ancillaryTextAlpha
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomImage
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PlaceholderImage
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
|
||||
@Composable
|
||||
internal fun DrawerCommunityItem(
|
||||
@ -27,6 +31,7 @@ internal fun DrawerCommunityItem(
|
||||
favorite: Boolean = false,
|
||||
autoLoadImages: Boolean = true,
|
||||
onSelected: (() -> Unit)? = null,
|
||||
onToggleFavorite: (() -> Unit)? = null,
|
||||
) {
|
||||
NavigationDrawerItem(
|
||||
modifier = modifier,
|
||||
@ -51,7 +56,8 @@ internal fun DrawerCommunityItem(
|
||||
},
|
||||
label = {
|
||||
val fullColor = MaterialTheme.colorScheme.onBackground
|
||||
val ancillaryColor = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha)
|
||||
val ancillaryColor =
|
||||
MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha)
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
@ -70,13 +76,24 @@ internal fun DrawerCommunityItem(
|
||||
}
|
||||
},
|
||||
badge =
|
||||
if (favorite) {
|
||||
if (onToggleFavorite != null || favorite) {
|
||||
@Composable {
|
||||
Icon(
|
||||
modifier = Modifier.size(IconSize.s),
|
||||
imageVector = Icons.Default.Star,
|
||||
modifier =
|
||||
Modifier
|
||||
.size(IconSize.s)
|
||||
.padding(start = 1.dp)
|
||||
.onClick(onClick = { onToggleFavorite?.invoke() }),
|
||||
imageVector = if (favorite) Icons.Default.Star else Icons.Default.StarBorder,
|
||||
contentDescription = "",
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
tint =
|
||||
MaterialTheme.colorScheme.onBackground.let {
|
||||
if (favorite) {
|
||||
it
|
||||
} else {
|
||||
it.copy(alpha = 0.25f)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
@ -34,36 +34,42 @@ class ManageSubscriptionsViewModel(
|
||||
private val siteRepository: SiteRepository,
|
||||
private val hapticFeedback: HapticFeedback,
|
||||
private val notificationCenter: NotificationCenter,
|
||||
) : ManageSubscriptionsMviModel,
|
||||
DefaultMviModel<ManageSubscriptionsMviModel.Intent, ManageSubscriptionsMviModel.UiState, ManageSubscriptionsMviModel.Effect>(
|
||||
) : DefaultMviModel<ManageSubscriptionsMviModel.Intent, ManageSubscriptionsMviModel.UiState, ManageSubscriptionsMviModel.Effect>(
|
||||
initialState = ManageSubscriptionsMviModel.UiState(),
|
||||
) {
|
||||
),
|
||||
ManageSubscriptionsMviModel {
|
||||
private var currentPage = 1
|
||||
private val searchEventChannel = Channel<Unit>()
|
||||
|
||||
init {
|
||||
screenModelScope.launch {
|
||||
settingsRepository.currentSettings.onEach { settings ->
|
||||
updateState {
|
||||
it.copy(
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
preferNicknames = settings.preferUserNicknames,
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.MultiCommunityCreated::class)
|
||||
settingsRepository.currentSettings
|
||||
.onEach { settings ->
|
||||
updateState {
|
||||
it.copy(
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
preferNicknames = settings.preferUserNicknames,
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.MultiCommunityCreated::class)
|
||||
.onEach { evt ->
|
||||
handleMultiCommunityCreated(evt.model)
|
||||
}.launchIn(this)
|
||||
notificationCenter.subscribe(NotificationCenterEvent.CommunitySubscriptionChanged::class)
|
||||
notificationCenter
|
||||
.subscribe(NotificationCenterEvent.CommunitySubscriptionChanged::class)
|
||||
.onEach { evt ->
|
||||
handleCommunityUpdate(evt.value)
|
||||
}.launchIn(this)
|
||||
|
||||
searchEventChannel.receiveAsFlow().debounce(1000).onEach {
|
||||
emitEffect(ManageSubscriptionsMviModel.Effect.BackToTop)
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
searchEventChannel
|
||||
.receiveAsFlow()
|
||||
.debounce(1000)
|
||||
.onEach {
|
||||
emitEffect(ManageSubscriptionsMviModel.Effect.BackToTop)
|
||||
refresh()
|
||||
}.launchIn(this)
|
||||
if (uiState.value.communities.isEmpty()) {
|
||||
// determine whether community creation is allowed
|
||||
val isAdmin = identityRepository.cachedUser?.admin ?: false
|
||||
@ -89,11 +95,12 @@ class ManageSubscriptionsViewModel(
|
||||
}
|
||||
|
||||
is ManageSubscriptionsMviModel.Intent.DeleteMultiCommunity -> {
|
||||
uiState.value.multiCommunities.firstOrNull {
|
||||
(it.id ?: 0L) == intent.id
|
||||
}?.also { community ->
|
||||
deleteMultiCommunity(community)
|
||||
}
|
||||
uiState.value.multiCommunities
|
||||
.firstOrNull {
|
||||
(it.id ?: 0L) == intent.id
|
||||
}?.also { community ->
|
||||
deleteMultiCommunity(community)
|
||||
}
|
||||
}
|
||||
|
||||
is ManageSubscriptionsMviModel.Intent.ToggleFavorite -> {
|
||||
@ -122,7 +129,8 @@ class ManageSubscriptionsViewModel(
|
||||
currentPage = 1
|
||||
val accountId = accountRepository.getActive()?.id ?: 0L
|
||||
val multiCommunitites =
|
||||
multiCommunityRepository.getAll(accountId)
|
||||
multiCommunityRepository
|
||||
.getAll(accountId)
|
||||
.let {
|
||||
val searchText = uiState.value.searchText
|
||||
if (searchText.isNotEmpty()) {
|
||||
@ -132,8 +140,7 @@ class ManageSubscriptionsViewModel(
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
.sortedBy { it.name }
|
||||
}.sortedBy { it.name }
|
||||
|
||||
updateState {
|
||||
it.copy(
|
||||
@ -193,9 +200,11 @@ class ManageSubscriptionsViewModel(
|
||||
if (newValue) {
|
||||
val model = FavoriteCommunityModel(communityId = communityId)
|
||||
favoriteCommunityRepository.create(model, accountId)
|
||||
notificationCenter.send(NotificationCenterEvent.FavoritesUpdated)
|
||||
} else {
|
||||
favoriteCommunityRepository.getBy(accountId, communityId)?.also { toDelete ->
|
||||
favoriteCommunityRepository.delete(accountId, toDelete)
|
||||
notificationCenter.send(NotificationCenterEvent.FavoritesUpdated)
|
||||
}
|
||||
}
|
||||
val newCommunity = community.copy(favorite = newValue)
|
||||
@ -240,17 +249,19 @@ class ManageSubscriptionsViewModel(
|
||||
val favoriteCommunityIds =
|
||||
favoriteCommunityRepository.getAll(accountId).map { it.communityId }
|
||||
val itemsToAdd =
|
||||
communityRepository.getSubscribed(
|
||||
auth = auth,
|
||||
page = currentPage,
|
||||
query = searchText,
|
||||
).map { community ->
|
||||
community.copy(favorite = community.id in favoriteCommunityIds)
|
||||
}.sortedBy { it.name }.let {
|
||||
val favorites = it.filter { e -> e.favorite }
|
||||
val res = it - favorites.toSet()
|
||||
favorites + res
|
||||
}
|
||||
communityRepository
|
||||
.getSubscribed(
|
||||
auth = auth,
|
||||
page = currentPage,
|
||||
query = searchText,
|
||||
).map { community ->
|
||||
community.copy(favorite = community.id in favoriteCommunityIds)
|
||||
}.sortedBy { it.name }
|
||||
.let {
|
||||
val favorites = it.filter { e -> e.favorite }
|
||||
val res = it - favorites.toSet()
|
||||
favorites + res
|
||||
}
|
||||
if (itemsToAdd.isNotEmpty()) {
|
||||
currentPage++
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user