Skip to content

Commit

Permalink
Merge pull request #55 from DroidKaigi/takahirom/add-empty-eventmap-m…
Browse files Browse the repository at this point in the history
…odule/2024-06-15

Add empty eventmap module
  • Loading branch information
takahirom authored Jun 18, 2024
2 parents 6b65723 + 6b04a11 commit 90a587f
Show file tree
Hide file tree
Showing 27 changed files with 608 additions and 18 deletions.
1 change: 1 addition & 0 deletions app-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ dependencies {
implementation(projects.feature.main)
implementation(projects.feature.contributors)
implementation(projects.feature.sessions)
implementation(projects.feature.eventmap)
implementation(projects.core.model)
implementation(projects.core.data)
implementation(projects.core.designsystem)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import io.github.droidkaigi.confsched.contributors.contributorsScreenRoute
import io.github.droidkaigi.confsched.contributors.contributorsScreens
import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
import io.github.droidkaigi.confsched.eventmap.eventMapScreens
import io.github.droidkaigi.confsched.eventmap.navigateEventMapScreen
import io.github.droidkaigi.confsched.main.MainNestedGraphStateHolder
import io.github.droidkaigi.confsched.main.MainScreenTab
import io.github.droidkaigi.confsched.main.MainScreenTab.About
import io.github.droidkaigi.confsched.main.MainScreenTab.Achievements
import io.github.droidkaigi.confsched.main.MainScreenTab.FloorMap
import io.github.droidkaigi.confsched.main.MainScreenTab.EventMap
import io.github.droidkaigi.confsched.main.MainScreenTab.ProfileCard
import io.github.droidkaigi.confsched.main.MainScreenTab.Timetable
import io.github.droidkaigi.confsched.main.mainScreen
import io.github.droidkaigi.confsched.main.mainScreenRoute
Expand Down Expand Up @@ -109,6 +111,10 @@ private fun NavGraphBuilder.mainScreen(
onTimetableItemClick = navController::navigateToTimetableItemDetailScreen,
contentPadding = contentPadding,
)
eventMapScreens(
onNavigationIconClick = navController::popBackStack,
onEventMapItemClick = externalNavController::navigate,
)
},
)
}
Expand All @@ -129,9 +135,9 @@ class KaigiAppMainNestedGraphStateHolder : MainNestedGraphStateHolder {
) {
when (tab) {
Timetable -> mainNestedNavController.navigateTimetableScreen()
EventMap -> mainNestedNavController.navigateEventMapScreen()
About -> TODO()
FloorMap -> TODO()
Achievements -> TODO()
ProfileCard -> TODO()
}
}
}
Expand Down
1 change: 1 addition & 0 deletions app-ios-shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ kotlin {
api(projects.core.ui)
api(projects.feature.main)
api(projects.feature.sessions)
api(projects.feature.eventmap)
api(projects.feature.contributors)
implementation(libs.kotlinxCoroutinesCore)
implementation(libs.skieAnnotation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import io.github.droidkaigi.confsched.contributors.ContributorsScreen
import io.github.droidkaigi.confsched.contributors.contributorsScreenRoute
import io.github.droidkaigi.confsched.data.Repositories
import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
import io.github.droidkaigi.confsched.eventmap.navigateEventMapScreen
import io.github.droidkaigi.confsched.main.MainNestedGraphStateHolder
import io.github.droidkaigi.confsched.main.MainScreenTab
import io.github.droidkaigi.confsched.main.MainScreenTab.About
import io.github.droidkaigi.confsched.main.MainScreenTab.Achievements
import io.github.droidkaigi.confsched.main.MainScreenTab.FloorMap
import io.github.droidkaigi.confsched.main.MainScreenTab.EventMap
import io.github.droidkaigi.confsched.main.MainScreenTab.ProfileCard
import io.github.droidkaigi.confsched.main.MainScreenTab.Timetable
import io.github.droidkaigi.confsched.main.mainScreen
import io.github.droidkaigi.confsched.main.mainScreenRoute
Expand Down Expand Up @@ -138,9 +139,9 @@ class KaigiAppMainNestedGraphStateHolder : MainNestedGraphStateHolder {
) {
when (tab) {
Timetable -> mainNestedNavController.navigateTimetableScreen()
EventMap -> mainNestedNavController.navigateEventMapScreen()
About -> TODO()
FloorMap -> TODO()
Achievements -> TODO()
ProfileCard -> TODO()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.github.droidkaigi.confsched.data.eventmap

import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent

@Module
@InstallIn(SingletonComponent::class)
public class EventMapApiModule {
@Provides
public fun provideEventMapApi(): EventMapApiClient {
return FakeEventMapApiClient()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.github.droidkaigi.confsched.data.eventmap

import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import io.github.droidkaigi.confsched.data.di.RepositoryQualifier
import io.github.droidkaigi.confsched.model.EventMapRepository
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
public abstract class EventMapRepositoryModule {
@Binds
@RepositoryQualifier
@IntoMap
@ClassKey(EventMapRepository::class)
public abstract fun bind(repository: EventMapRepository): Any

public companion object {
@Provides
@Singleton
public fun provideEventMapRepository(
eventMapApi: EventMapApiClient,
): EventMapRepository {
return DefaultEventMapRepository(
eventMapApi = eventMapApi,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.github.droidkaigi.confsched.data.eventmap

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import io.github.droidkaigi.confsched.compose.SafeLaunchedEffect
import io.github.droidkaigi.confsched.compose.safeCollectAsState
import io.github.droidkaigi.confsched.model.EventMapEvent
import io.github.droidkaigi.confsched.model.EventMapRepository
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.flow.MutableStateFlow

public class DefaultEventMapRepository(
private val eventMapApi: EventMapApiClient,
) : EventMapRepository {
private val eventMapStateFlow =
MutableStateFlow<PersistentList<EventMapEvent>>(persistentListOf())

@Composable
override fun eventMapEvents(): PersistentList<EventMapEvent> {
val eventMap by eventMapStateFlow.safeCollectAsState()
SafeLaunchedEffect(Unit) {
if (eventMap.isEmpty()) {
refresh()
}
}
return eventMap
}

override suspend fun refresh() {
eventMapApi
.eventMapEvents()
.toPersistentList().also { eventMapStateFlow.value = it }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.github.droidkaigi.confsched.data.eventmap

import de.jensklingenberg.ktorfit.http.GET
import io.github.droidkaigi.confsched.data.eventmap.response.EventMapResponse
import io.github.droidkaigi.confsched.model.EventMapEvent
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.toPersistentList

internal interface EventMapApi {
@GET("/events/droidkaigi2023/eventmap")
suspend fun getEventMap(): EventMapResponse
}

public interface EventMapApiClient {

public suspend fun eventMapEvents(): PersistentList<EventMapEvent>
}

public fun EventMapResponse.toEventMapList(): PersistentList<EventMapEvent> {
return listOf(EventMapEvent()).toPersistentList()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.github.droidkaigi.confsched.data.eventmap

import io.github.droidkaigi.confsched.data.eventmap.response.EventMapResponse
import io.github.droidkaigi.confsched.model.EventMapEvent
import kotlinx.collections.immutable.PersistentList
import okio.IOException

public class FakeEventMapApiClient : EventMapApiClient {

public sealed class Status : EventMapApiClient {
public data object Operational : Status() {
override suspend fun eventMapEvents(): PersistentList<EventMapEvent> {
return EventMapResponse().toEventMapList()
}
}

public data object Error : Status() {
override suspend fun eventMapEvents(): PersistentList<EventMapEvent> {
throw IOException("Fake IO Exception")
}
}
}

private var status: Status = Status.Operational

public fun setup(status: Status) {
this.status = status
}

override suspend fun eventMapEvents(): PersistentList<EventMapEvent> {
return status.eventMapEvents()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.github.droidkaigi.confsched.data.eventmap.response

public class EventMapResponse
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.github.droidkaigi.confsched.model

class EventMapEvent
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.github.droidkaigi.confsched.model

import androidx.compose.runtime.Composable
import io.github.droidkaigi.confsched.model.compositionlocal.LocalRepositories
import kotlinx.collections.immutable.PersistentList

interface EventMapRepository {

suspend fun refresh()

@Composable
fun eventMapEvents(): PersistentList<EventMapEvent>
}

@Composable
fun localEventMapRepository(): EventMapRepository {
return LocalRepositories.current[EventMapRepository::class] as EventMapRepository
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package io.github.droidkaigi.confsched.testing
import androidx.compose.ui.test.junit4.ComposeTestRule
import io.github.droidkaigi.confsched.data.contributors.ContributorsApiClient
import io.github.droidkaigi.confsched.data.contributors.FakeContributorsApiClient
import io.github.droidkaigi.confsched.data.eventmap.EventMapApiClient
import io.github.droidkaigi.confsched.data.eventmap.FakeEventMapApiClient
import io.github.droidkaigi.confsched.data.sessions.FakeSessionsApiClient
import io.github.droidkaigi.confsched.data.sessions.SessionsApiClient
import io.github.droidkaigi.confsched.testing.coroutines.runTestWithLogging
Expand Down Expand Up @@ -136,3 +138,25 @@ class DefaultContributorsServerRobot @Inject constructor(contributorsApiClient:
)
}
}

interface EventMapServerRobot {
enum class ServerStatus {
Operational,
Error,
}

fun setupContributorServer(serverStatus: ServerStatus)
}

class DefaultEventMapServerRobot @Inject constructor(contributorsApiClient: EventMapApiClient) :
EventMapServerRobot {
private val fakeEventMapApiClient = contributorsApiClient as FakeEventMapApiClient
override fun setupContributorServer(serverStatus: EventMapServerRobot.ServerStatus) {
fakeEventMapApiClient.setup(
when (serverStatus) {
EventMapServerRobot.ServerStatus.Operational -> FakeEventMapApiClient.Status.Operational
EventMapServerRobot.ServerStatus.Error -> FakeEventMapApiClient.Status.Error
},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ class KaigiAppRobot @Inject constructor(

fun goToFloorMap() {
composeTestRule
.onNode(hasTestTag(MainScreenTab.FloorMap.testTag))
.onNode(hasTestTag(MainScreenTab.About.testTag))
.performClick()
waitUntilIdle()
}

fun goToAchievements() {
composeTestRule
.onAllNodes(
matcher = hasTestTag(MainScreenTab.Achievements.testTag),
matcher = hasTestTag(MainScreenTab.ProfileCard.testTag),
useUnmergedTree = true,
)
.onFirst()
Expand Down
1 change: 1 addition & 0 deletions feature/eventmap/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
23 changes: 23 additions & 0 deletions feature/eventmap/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
plugins {
id("droidkaigi.convention.kmpfeature")
}

android.namespace = "io.github.droidkaigi.confsched.feature.eventMap"
kotlin {
sourceSets {
commonMain {
dependencies {
implementation(projects.core.model)
implementation(projects.core.ui)
implementation(libs.kotlinxCoroutinesCore)
implementation(projects.core.designsystem)
implementation(libs.moleculeRuntime)
}
}
androidUnitTest {
dependencies {
implementation(projects.core.testing)
}
}
}
}
21 changes: 21 additions & 0 deletions feature/eventmap/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Loading

0 comments on commit 90a587f

Please sign in to comment.