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