Skip to content

Commit

Permalink
Add timetable detail screen Base (#102)
Browse files Browse the repository at this point in the history
* add timetableDetail transition

* add Coil

* add Timetable Detail Screen

* Format

* Put Japanese into English in comment

* Use fake method

* Fix spotless

* Fix test

* Fix test

Co-authored-by: taijionishi <69178389+taijionishifc@users.noreply.github.com>
Co-authored-by: takahirom <takam.dev@gmail.com>
  • Loading branch information
3 people authored Sep 3, 2022
1 parent 6e17b80 commit 90729dd
Show file tree
Hide file tree
Showing 10 changed files with 413 additions and 59 deletions.
1 change: 1 addition & 0 deletions app-android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ dependencies {
implementation(projects.coreData)
implementation(projects.coreDesignsystem)
implementation(projects.coreUi)
implementation(projects.coreModel)

implementation(libs.composeMaterial3WindowSizeClass)
implementation(libs.androidxNavigationCompose)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import io.github.droidkaigi.confsched2022.feature.contributors.ContributorsNavGr
import io.github.droidkaigi.confsched2022.feature.contributors.contributorsNavGraph
import io.github.droidkaigi.confsched2022.feature.sessions.SessionsNavGraph
import io.github.droidkaigi.confsched2022.feature.sessions.sessionsNavGraph
import io.github.droidkaigi.confsched2022.model.TimetableItemId
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

Expand All @@ -57,7 +58,10 @@ fun KaigiApp(
navController = kaigiAppScaffoldState.navController,
startDestination = SessionsNavGraph.sessionRoute,
) {
sessionsNavGraph(kaigiAppScaffoldState::onNavigationClick)
sessionsNavGraph(
kaigiAppScaffoldState::onNavigationClick,
kaigiAppScaffoldState::onTimeTableClick,
)
contributorsNavGraph(kaigiAppScaffoldState::onNavigationClick)
}
}
Expand Down Expand Up @@ -118,6 +122,12 @@ class KaigiAppScaffoldState @OptIn(ExperimentalMaterial3Api::class) constructor(
}
}

fun onTimeTableClick(timetableId: TimetableItemId) {
navController.navigate(
route = SessionsNavGraph.sessionDetail + timetableId.value
)
}

fun onNavigationClick() {
coroutineScope.launch {
drawerState.open()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,54 +101,21 @@ fun Timetable.Companion.fake(): Timetable {
TimeZone.of("UTC+9")
)

val fake = TimetableItem.Session.fake()
add(
TimetableItem.Session(
id = TimetableItemId("2$index"),
title = MultiLangText(
"DroidKaigiのアプリのアーキテクチャ$index ${day + 2}",
"DroidKaigi App Architecture$index ${day + 2}"
),
startsAt = start
.toInstant(TimeZone.of("UTC+9")),
endsAt = end
.toInstant(TimeZone.of("UTC+9")),
category = TimetableCategory(
id = 28654,
fake
.copy(
id = TimetableItemId("2$index"),
title = MultiLangText(
"Android FrameworkとJetpack",
"Android Framework and Jetpack",
jaTitle = "${fake.title.jaTitle} $day $index",
enTitle = "${fake.title.enTitle} $day $index"
),
),
room = roomsIterator.next(),
targetAudience = "For App developer アプリ開発者向け",
language = "JAPANESE",
asset = TimetableAsset(
videoUrl = "https://www.youtube.com/watch?v=hFdKCyJ-Z9A",
slideUrl = "https://droidkaigi.jp/2021/",
),
levels = persistentListOf(
"INTERMEDIATE",
),
description = "これはディスクリプションです。\n" +
"これはディスクリプションです。\n" +
"これはディスクリプションです。\n" +
"これはディスクリプションです。",
speakers = persistentListOf(
TimetableSpeaker(
name = "taka",
iconUrl = "https://github.com/takahirom.png",
bio = "Likes Android",
tagLine = "Android Engineer"
),
TimetableSpeaker(
name = "ry",
iconUrl = "https://github.com/ry-itto.png",
bio = "Likes iOS",
tagLine = "iOS Engineer",
),
),
message = null,
)
room = roomsIterator.next(),
startsAt = start
.toInstant(TimeZone.of("UTC+9")),
endsAt = end
.toInstant(TimeZone.of("UTC+9")),
)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@

package io.github.droidkaigi.confsched2022.model

import io.github.droidkaigi.confsched2022.model.TimetableItem.Session
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
Expand Down Expand Up @@ -41,7 +45,9 @@ sealed class TimetableItem {
val description: String,
val speakers: PersistentList<TimetableSpeaker>,
val message: MultiLangText?,
) : TimetableItem()
) : TimetableItem() {
companion object
}

@Serializable
data class Special(
Expand Down Expand Up @@ -69,3 +75,51 @@ sealed class TimetableItem {
"${minutes}min"
}
}

fun TimetableItem.Session.Companion.fake(): Session {
return Session(
id = TimetableItemId("2"),
title = MultiLangText("DroidKaigiのアプリのアーキテクチャ", "DroidKaigi App Architecture"),
startsAt = LocalDateTime.parse("2021-10-20T10:30:00")
.toInstant(TimeZone.of("UTC+9")),
endsAt = LocalDateTime.parse("2021-10-20T10:50:00")
.toInstant(TimeZone.of("UTC+9")),
category = TimetableCategory(
id = 28654,
title = MultiLangText(
"Android FrameworkとJetpack",
"Android Framework and Jetpack",
),
),
room = TimetableRoom(
id = 2,
name = MultiLangText("Room1", "Room2"),
sort = 1
),
targetAudience = "For App developer アプリ開発者向け",
language = "JAPANESE",
asset = TimetableAsset(
videoUrl = "https://www.youtube.com/watch?v=hFdKCyJ-Z9A",
slideUrl = "https://droidkaigi.jp/2021/",
),
speakers = listOf(
TimetableSpeaker(
name = "taka",
iconUrl = "https://github.com/takahirom.png",
bio = "Likes Android",
tagLine = "Android Engineer"
),
TimetableSpeaker(
name = "ry",
iconUrl = "https://github.com/ry-itto.png",
bio = "Likes iOS",
tagLine = "iOS Engineer",
),
).toPersistentList(),
description = "これはディスクリプションです。\nこれはディスクリプションです。\nこれはディスクリプションです。\nこれはディスクリプションです。",
message = null,
levels = listOf(
"INTERMEDIATE",
).toPersistentList(),
)
}
1 change: 1 addition & 0 deletions feature-sessions/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies {
implementation(libs.androidxLifecycleLifecycleRuntimeKtx)
implementation(libs.androidxActivityCompose)
implementation(libs.accompanistPager)
implementation(libs.coilCompose)
testImplementation(libs.kluentAndroid)
androidTestImplementation(libs.composeUiTestJunit4)
debugImplementation(libs.composeUiTooling)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ import kotlinx.coroutines.launch
@Composable
fun SessionsScreenRoot(
modifier: Modifier = Modifier,
onNavigationIconClick: () -> Unit = {}
onNavigationIconClick: () -> Unit = {},
onTimetableClick: (TimetableItemId) -> Unit = {},
) {
val viewModel = hiltViewModel<SessionsViewModel>()
val state: SessionsUiModel by viewModel.uiModel

Sessions(
uiModel = state,
modifier = modifier,
onTimetableClick = {},
onTimetableClick = { onTimetableClick(it) },
onToggleFilter = { viewModel.onToggleFilter() },
onFavoriteClick = { timetableItemId, isFavorite ->
viewModel.onFavoriteToggle(timetableItemId, isFavorite)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,40 @@
package io.github.droidkaigi.confsched2022.feature.sessions

import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavType
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import io.github.droidkaigi.confsched2022.model.TimetableItemId

fun NavGraphBuilder.sessionsNavGraph(onNavigationIconClick: () -> Unit) {
fun NavGraphBuilder.sessionsNavGraph(
onNavigationIconClick: () -> Unit,
onTimetableClick: (TimetableItemId) -> Unit,
) {
composable(route = SessionsNavGraph.sessionRoute) {
SessionsScreenRoot(onNavigationIconClick = onNavigationIconClick)
SessionsScreenRoot(
onNavigationIconClick = onNavigationIconClick,
onTimetableClick = onTimetableClick,
)
}

composable(
route = "${SessionsNavGraph.sessionDetail}{id}",
arguments = listOf(
navArgument("id") {
type = NavType.StringType
}
)
) {
// TODO make it savable
val id = it.arguments?.getString("id") ?: ""
TimetableDetailScreenRoot(
timetableItemId = TimetableItemId(id),
onNavigationIconClick = onNavigationIconClick,
)
}
}

object SessionsNavGraph {
const val sessionRoute = "sessions"
const val sessionDetail = "session/detail/"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.github.droidkaigi.confsched2022.feature.sessions

import io.github.droidkaigi.confsched2022.model.TimetableItem
import io.github.droidkaigi.confsched2022.ui.Result

data class TimeTableDetailUiModel(
val timetableDetailState: TimetableDetailState,
) {
sealed interface TimetableDetailState {

data class Loaded(val timetableItem: TimetableItem) : TimetableDetailState

object Loading : TimetableDetailState

companion object {
fun of(timetableItemResult: Result<TimetableItem>): TimetableDetailState {
return when (timetableItemResult) {
Result.Loading -> {
Loading
}
is Result.Success -> {
Loaded(timetableItemResult.data)
}
else -> {
// TODO
// SessionsState.Error
Loading
}
}
}
}
}
}
Loading

0 comments on commit 90729dd

Please sign in to comment.