Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/main/kotlin/chatroom/users/Users.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
package chatroom.users

import chatroom.ChatroomWindow
import chatroom.LEFT_WIDTH
import org.koin.dsl.module

val usersModule =
module {
scope<ChatroomWindow> {
scoped { UsersPanel(presenter = get()) }
scoped { UsersListUseCase() }
scoped { UsersListPresenter(users = get(), scope = get<ChatroomWindow>().windowScope, dispatchers = get()) }
scoped {
UsersListPresenter(
users = get(),
truncate = get(),
scope = get<ChatroomWindow>().windowScope,
dispatchers = get(),
)
}
}
factory { UsersListTruncation(LEFT_WIDTH - 3) }
}
17 changes: 13 additions & 4 deletions src/main/kotlin/chatroom/users/UsersListPresenter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,27 @@ import arch.Presenter
import arch.RokyDispatchers
import chatroom.users.UsersViewState.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class UsersListPresenter(
private val users: UsersListUseCase,
private val truncate: UsersListTruncation,
private val scope: CoroutineScope,
dispatchers: RokyDispatchers,
) : Presenter<UsersListView>(dispatchers) {
override fun onAttach(view: UsersListView) {
view.show(Empty)
scope.launch(dispatchers.io) {
users().map(::Users).collect { state ->
withContext(dispatchers.main) {
show(state)
users()
.truncateUsernames()
.map(::Users).collect { state ->
withContext(dispatchers.main) {
show(state)
}
}
}
}
}

Expand All @@ -31,4 +35,9 @@ class UsersListPresenter(
override fun onDetach(view: UsersListView) {
// Deliberately empty
}

private fun Flow<List<String>>.truncateUsernames() =
map { username ->
username.map(truncate::invoke)
}
}
7 changes: 7 additions & 0 deletions src/main/kotlin/chatroom/users/UsersListTruncation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package chatroom.users

import utils.cutOff

class UsersListTruncation(private val width: Int) {
operator fun invoke(input: String): String = input.cutOff(width)
}
20 changes: 19 additions & 1 deletion src/test/kotlin/chatroom/users/UsersListPresenterTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class UsersListPresenterTest {
every { io } returns dispatcher
}
scope = CoroutineScope(dispatcher)
presenter = UsersListPresenter(listUsers, scope, dispatchers)
presenter = UsersListPresenter(listUsers, UsersListTruncation(10), scope, dispatchers)
}

@Test
Expand Down Expand Up @@ -78,6 +78,24 @@ class UsersListPresenterTest {
}
}

@Test
fun `when users list contains very long usernames, then truncate long usernames only`() =
runTest(dispatcher) {
val userList = listOf("Allie", "Kai", "A very very long username")
coEvery { listUsers() } coAnswersDelayed { flowOf(userList) }
presenter.attach(view)
advanceUntilIdle()
verifyOrder {
view.show(Empty)
view.show(
withArg {
assertTrue { it is Users }
assertTrue { (it as Users).users == listOf("Allie", "Kai", "A very ve…") }
},
)
}
}

companion object {
private val dispatcher = StandardTestDispatcher()
}
Expand Down
Loading