Skip to content

Commit

Permalink
enhancement: change open circle behaviour (#537)
Browse files Browse the repository at this point in the history
* update l10n

* update build scripts

* add utility to get notification center

* update user service

* update user repository

* rename CircleDetail to CircleMembers

* allow opening timeline from circles screen

* implement circle timeline screen

* add method to detail opener

* refactor timeline view model

to isolate changeTimelineType operation

* update DI modules

* update user manual
  • Loading branch information
AkesiSeli authored Nov 18, 2024
1 parent cb9d701 commit 4a96973
Show file tree
Hide file tree
Showing 33 changed files with 1,276 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ internal val sharedModule =
settingsRepository = get(),
entryCache = get(),
eventCache = get(),
circleCache = get(),
)
}
single<AuthManager> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.livefast.eattrash.feature.userdetail.forum.ForumListScreen
import com.livefast.eattrash.raccoonforfriendica.core.commonui.content.WebViewScreen
import com.livefast.eattrash.raccoonforfriendica.core.navigation.DetailOpener
import com.livefast.eattrash.raccoonforfriendica.core.navigation.NavigationCoordinator
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.CircleModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.EventModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.FavoritesType
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.TimelineEntryModel
Expand All @@ -17,8 +18,9 @@ import com.livefast.eattrash.raccoonforfriendica.domain.identity.repository.Iden
import com.livefast.eattrash.raccoonforfriendica.domain.identity.repository.SettingsRepository
import com.livefast.eattrash.raccoonforfriendica.feature.calendar.detail.EventDetailScreen
import com.livefast.eattrash.raccoonforfriendica.feature.calendar.list.CalendarScreen
import com.livefast.eattrash.raccoonforfriendica.feature.circles.detail.CircleDetailScreen
import com.livefast.eattrash.raccoonforfriendica.feature.circles.editmembers.CircleMembersScreen
import com.livefast.eattrash.raccoonforfriendica.feature.circles.list.CirclesScreen
import com.livefast.eattrash.raccoonforfriendica.feature.circles.timeline.CircleTimelineScreen
import com.livefast.eattrash.raccoonforfriendica.feature.composer.ComposerScreen
import com.livefast.eattrash.raccoonforfriendica.feature.directmessages.detail.ConversationScreen
import com.livefast.eattrash.raccoonforfriendica.feature.directmessages.list.DirectMessageListScreen
Expand Down Expand Up @@ -55,6 +57,7 @@ class DefaultDetailOpener(
private val userCache: LocalItemCache<UserModel>,
private val entryCache: LocalItemCache<TimelineEntryModel>,
private val eventCache: LocalItemCache<EventModel>,
private val circleCache: LocalItemCache<CircleModel>,
dispatcher: CoroutineDispatcher = Dispatchers.IO,
) : DetailOpener {
private val currentUserId: String? get() = identityRepository.currentUser.value?.id
Expand Down Expand Up @@ -116,7 +119,8 @@ class DefaultDetailOpener(

override fun openFollowers(
user: UserModel,
enableExport: Boolean) {
enableExport: Boolean,
) {
scope.launch {
userCache.put(user.id, user)
val screen =
Expand All @@ -131,7 +135,8 @@ class DefaultDetailOpener(

override fun openFollowing(
user: UserModel,
enableExport: Boolean) {
enableExport: Boolean,
) {
scope.launch {
userCache.put(user.id, user)
val screen =
Expand Down Expand Up @@ -285,11 +290,19 @@ class DefaultDetailOpener(
navigationCoordinator.push(screen)
}

override fun openCircle(groupId: String) {
val screen = CircleDetailScreen(groupId)
override fun openCircleEditMembers(groupId: String) {
val screen = CircleMembersScreen(groupId)
navigationCoordinator.push(screen)
}

override fun openCircleTimeline(circle: CircleModel) {
scope.launch {
circleCache.put(circle.id, circle)
val screen = CircleTimelineScreen(circle.id)
navigationCoordinator.push(screen)
}
}

override fun openFollowRequests() {
val screen = FollowRequestsScreen()
navigationCoordinator.push(screen)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.livefast.eattrash.feature.userdetail.classic.UserDetailScreen
import com.livefast.eattrash.feature.userdetail.forum.ForumListScreen
import com.livefast.eattrash.raccoonforfriendica.core.commonui.content.WebViewScreen
import com.livefast.eattrash.raccoonforfriendica.core.navigation.NavigationCoordinator
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.CircleModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.EventModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.TimelineEntryModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.UnpublishedType
Expand All @@ -14,8 +15,9 @@ import com.livefast.eattrash.raccoonforfriendica.domain.identity.repository.Iden
import com.livefast.eattrash.raccoonforfriendica.domain.identity.repository.SettingsRepository
import com.livefast.eattrash.raccoonforfriendica.feature.calendar.detail.EventDetailScreen
import com.livefast.eattrash.raccoonforfriendica.feature.calendar.list.CalendarScreen
import com.livefast.eattrash.raccoonforfriendica.feature.circles.detail.CircleDetailScreen
import com.livefast.eattrash.raccoonforfriendica.feature.circles.editmembers.CircleMembersScreen
import com.livefast.eattrash.raccoonforfriendica.feature.circles.list.CirclesScreen
import com.livefast.eattrash.raccoonforfriendica.feature.circles.timeline.CircleTimelineScreen
import com.livefast.eattrash.raccoonforfriendica.feature.composer.ComposerScreen
import com.livefast.eattrash.raccoonforfriendica.feature.directmessages.detail.ConversationScreen
import com.livefast.eattrash.raccoonforfriendica.feature.directmessages.list.DirectMessageListScreen
Expand Down Expand Up @@ -65,6 +67,7 @@ class DefaultDetailOpenerTest {
private val userCache = mock<LocalItemCache<UserModel>>(mode = MockMode.autoUnit)
private val entryCache = mock<LocalItemCache<TimelineEntryModel>>(mode = MockMode.autoUnit)
private val eventCache = mock<LocalItemCache<EventModel>>(mode = MockMode.autoUnit)
private val circleCache = mock<LocalItemCache<CircleModel>>(mode = MockMode.autoUnit)
private val sut =
DefaultDetailOpener(
navigationCoordinator = navigationCoordinator,
Expand All @@ -73,6 +76,7 @@ class DefaultDetailOpenerTest {
userCache = userCache,
entryCache = entryCache,
eventCache = eventCache,
circleCache = circleCache,
dispatcher = UnconfinedTestDispatcher(),
)

Expand Down Expand Up @@ -316,11 +320,22 @@ class DefaultDetailOpenerTest {
}

@Test
fun `when openCircle then interactions are as expected`() {
sut.openCircle(groupId = "1")
fun `when openCircleEditMembers then interactions are as expected`() {
sut.openCircleEditMembers(groupId = "1")

verify {
navigationCoordinator.push(any<CircleDetailScreen>())
navigationCoordinator.push(any<CircleMembersScreen>())
}
}

@Test
fun `when openCircleTimeline then interactions are as expected`() {
val circle = CircleModel(id = "id")
sut.openCircleTimeline(circle)

verifySuspend {
circleCache.put(circle.id, circle)
navigationCoordinator.push(any<CircleTimelineScreen>())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface UserService {
@Query("q") query: String = "",
@Query("offset") offset: Int = 0,
@Query("resolve") resolve: Boolean = false,
@Query("following") following: Boolean = false,
): List<Account>

@GET("v1/accounts/{id}/statuses")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,5 @@ internal val DeStrings =
override val actionChangeMarkupMode = "Auszeichnungsart ändern"
override val confirmChangeMarkupMode =
"Wenn Sie den Markup-Typ ändern, gehen alle Formatierungen verloren. Trotzdem weitermachen?"
override val actionEditMembers = "Mitglieder bearbeiten"
}
Original file line number Diff line number Diff line change
Expand Up @@ -450,4 +450,5 @@ internal open class DefaultStrings : Strings {
override val actionChangeMarkupMode = "Change markup type"
override val confirmChangeMarkupMode =
"If you change the markup type, all the formatting will be lost. Proceed anyway?"
override val actionEditMembers = "Edit members"
}
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,5 @@ internal val EsStrings =
override val actionChangeMarkupMode = "Cambiar tipo de marcado"
override val confirmChangeMarkupMode =
"Si cambia el tipo de marcado, se perderá todo el formato. ¿Proceder de todos modos?"
override val actionEditMembers = "Editar miembros"
}
Original file line number Diff line number Diff line change
Expand Up @@ -460,4 +460,5 @@ internal val FrStrings =
override val actionChangeMarkupMode = "Modifier type de balisage"
override val confirmChangeMarkupMode =
"Si vous modifiez le type de balisage, toutes les mises en forme seront perdues. Poursuivre quand même ?"
override val actionEditMembers = "Modifier les membres"
}
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,5 @@ internal val ItStrings =
override val actionChangeMarkupMode = "Cambia il tipo di markup"
override val confirmChangeMarkupMode =
"Se si cambia il tipo di markup, tutta la formattazione andrà persa. Procedere comunque?"
override val actionEditMembers = "Modifica membri"
}
Original file line number Diff line number Diff line change
Expand Up @@ -453,4 +453,5 @@ internal val PlStrings =
override val actionChangeMarkupMode = "Zmiana typu znaczników"
override val confirmChangeMarkupMode =
"Jeśli zmienisz typ znaczników, całe formatowanie zostanie utracone. Kontynuować mimo to?"
override val actionEditMembers = "Edytuj członków"
}
Original file line number Diff line number Diff line change
Expand Up @@ -459,4 +459,5 @@ internal val PtStrings =
override val actionChangeMarkupMode = "Alterar tipo de marcação"
override val confirmChangeMarkupMode =
"Se alterar o tipo de marcação, toda a formatação se perderá. Continuar na mesma?"
override val actionEditMembers = "Editar membros"
}
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ interface Strings {
val actionExport: String
val actionChangeMarkupMode: String
val confirmChangeMarkupMode: String
val actionEditMembers: String
}

object Locales {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.livefast.eattrash.raccoonforfriendica.core.navigation

import androidx.compose.runtime.Stable
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.CircleModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.EventModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.TimelineEntryModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.UnpublishedType
Expand Down Expand Up @@ -30,7 +31,8 @@ interface DetailOpener {

fun openFollowing(
user: UserModel,
enableExport: Boolean = false)
enableExport: Boolean = false,
)

fun openFavorites()

Expand Down Expand Up @@ -77,7 +79,9 @@ interface DetailOpener {

fun openCircles()

fun openCircle(groupId: String)
fun openCircleEditMembers(groupId: String)

fun openCircleTimeline(circle: CircleModel)

fun openFollowRequests()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.livefast.eattrash.raccoonforfriendica.core.notifications.di

import com.livefast.eattrash.raccoonforfriendica.core.notifications.NotificationCenter
import org.koin.java.KoinJavaComponent

actual fun getNotificationCenter(): NotificationCenter {
val res by KoinJavaComponent.inject<NotificationCenter>(NotificationCenter::class.java)
return res
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.livefast.eattrash.raccoonforfriendica.core.notifications.di

import com.livefast.eattrash.raccoonforfriendica.core.notifications.NotificationCenter

expect fun getNotificationCenter(): NotificationCenter
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.livefast.eattrash.raccoonforfriendica.core.notifications.di

import com.livefast.eattrash.raccoonforfriendica.core.notifications.NotificationCenter
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject

actual fun getNotificationCenter(): NotificationCenter = CoreNotificationsDiHelper.notificationCenter

internal object CoreNotificationsDiHelper : KoinComponent {
val notificationCenter by inject<NotificationCenter>()
}
22 changes: 14 additions & 8 deletions docs/manual/it/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -837,16 +837,22 @@ Al fine di rendere la consultazione più facile, Raccoon suddivide in sezioni la
un'intestazione di sezione che specifica il tipo dei contenuti sottostanti.

Tra queste tre categorie, l'unica che consente di essere modificata è la prima, per la quale è
possibile:
possibile utilizzare il pulsante "⋮" per:

- utilizzare il pulsante "⋮" per modificare il nome o eliminarle;
- entrare nella schermata di dettaglio cerchia, visualizzare i contatti che ne fanno parte e
aggiungerne di nuovi (con il pulsante "+") o rimuovere quelli esistenti.
- modificare il nome;
- eliminare la cerchia;
- visualizzare i contatti che ne fanno parte e aggiungerne di nuovi (con il pulsante "+") o
rimuovere quelli esistenti.

Ricorda che in Friendica, come impostazione predefinita, tutti i contatti che non sono di tipo
gruppo vengono aggiunti alla cerchia "Amici" mentre tutti i contatti di tipo gruppo vengono aggiunti
alla cerchia "Gruppi". Pur essendo create in automatico dal sistema, "Amici" e "Gruppi" sono
cerchie normalissime che possono essere modificate o eliminate.
Va tenuto presente che in Friendica, come impostazione predefinita, tutti i contatti che non sono di
tipo gruppo vengono aggiunti alla cerchia "Amici" mentre tutti i contatti di tipo gruppo vengono
aggiunti alla cerchia "Gruppi". Pur essendo create in automatico dal sistema, "Amici" e "Gruppi"
sono cerchie normalissime che possono essere modificate o eliminate.

Facendo tap su ogni voce della lista cerchie, verrà aperta la lista dei post corrispondenti, ovvero:

- la [modalità forum](#modalità-forum) per i gruppi;
- una timeline dedicata per tutte le altre cerchie.

<div align="center">
<img width="310" alt="circle list screen" src="../images/circles_list.png" />
Expand Down
14 changes: 10 additions & 4 deletions docs/manual/main.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,16 +776,22 @@ This screens contains all the custom feeds that can be used in the timeline, whi
To make it easier to browse and understand this list, Raccoon divides the list in sections, each
with its header specifying the type of the following items.

Among these three categories, the only one which allow to be modified is the first one, for which:
Among these three categories, the only one which allow to be modified is the first one, for which
you can use the "⋮" button to:

- you can use the "⋮" button to edit the name or delete it;
- you can enter a circle detail screen to see the contacts that belong to it and add new ones (with
the "+" button) or remove existing ones.
- edit the circle name;
- delete the circle;
- see the circle members and add new ones (with the "+" button) or remove existing ones.

Please remember that in Friendica by default all non-group contacts are added to the "Friends"
circle and all group contacts are added to "Group". Albeit being created by the system, "Friends"
and "Groups" are regulars circles that can be changed or deleted.

By tapping on each item in the circle list, you will open the corresponding post list, i.e.:

- the [forum mode](#forum-mode) for groups;
- a dedicated timeline, for all other circles.

<div align="center">
<img width="310" alt="circle list screen" src="images/circles_list.png" />
<img width="310" alt="circle detail screen" src="images/circle_detail.png" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ internal class DefaultUserRepository(
override suspend fun search(
query: String,
offset: Int,
following: Boolean,
): List<UserModel>? =
withContext(Dispatchers.IO) {
runCatching {
Expand All @@ -47,6 +48,7 @@ internal class DefaultUserRepository(
query = query,
offset = offset,
resolve = true,
following = following,
).map { it.toModel() }
}
}.getOrNull()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface UserRepository {
suspend fun search(
query: String,
offset: Int,
following: Boolean = false,
): List<UserModel>?

suspend fun getByHandle(handle: String): UserModel?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.livefast.eattrash.raccoonforfriendica.domain.content.repository.di

import com.livefast.eattrash.raccoonforfriendica.domain.content.data.CircleModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.EventModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.TimelineEntryModel
import com.livefast.eattrash.raccoonforfriendica.domain.content.data.UserModel
Expand Down Expand Up @@ -133,6 +134,9 @@ val domainContentRepositoryModule =
single<LocalItemCache<EventModel>> {
DefaultLocalItemCache()
}
single<LocalItemCache<CircleModel>> {
DefaultLocalItemCache()
}
single<ScheduledEntryRepository> {
DefaultScheduledEntryRepository(
provider = get(named("default")),
Expand Down
2 changes: 2 additions & 0 deletions feature/circles/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ kotlin {
implementation(projects.core.commonui.content)
implementation(projects.core.l10n)
implementation(projects.core.navigation)
implementation(projects.core.notifications)
implementation(projects.core.utils)

implementation(projects.domain.content.data)
implementation(projects.domain.content.pagination)
implementation(projects.domain.content.repository)
implementation(projects.domain.identity.data)
implementation(projects.domain.identity.repository)
implementation(projects.domain.identity.usecase)
}
}
}
Expand Down
Loading

0 comments on commit 4a96973

Please sign in to comment.