Skip to content

Commit

Permalink
[Platform] Add desktop support (#3)
Browse files Browse the repository at this point in the history
* feat: adjust UI and uses shimmer for loader

* feat: add desktop app support

* feat: add desktop for jvm linux target build on github workflows
  • Loading branch information
isfaaghyth committed Aug 29, 2024
1 parent 232d342 commit 3a94a0b
Show file tree
Hide file tree
Showing 25 changed files with 242 additions and 85 deletions.
19 changes: 0 additions & 19 deletions .fleet/receipt.json

This file was deleted.

1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
config: [
{ target: android, os: ubuntu-latest, tasks: testDebugUnitTest testReleaseUnitTest, continueOnError: false },
{ target: apple, os: macos-latest, tasks: iosX64Test iosSimulatorArm64Test, continueOnError: false },
{ target: desktop, os: ubuntu-latest, tasks: desktopTest, continueOnError: false },
]
runs-on: ${{ matrix.config.os }}
name: Build ${{ matrix.config.target }}
Expand Down
21 changes: 20 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ kotlin {
}
}
jvmToolchain(17)
jvm("desktop")

listOf(
iosX64(),
Expand All @@ -33,7 +34,8 @@ kotlin {
}

sourceSets {

val desktopMain by getting

androidMain.dependencies {
implementation(compose.preview)
implementation(libs.androidx.activity.compose)
Expand All @@ -42,6 +44,11 @@ kotlin {
implementation(libs.androidx.compose.windowsizeclass)
}

desktopMain.dependencies {
implementation(libs.kotlinx.coroutines.swing)
implementation(compose.desktop.currentOs)
}

commonMain.dependencies {
// Libraries
implementation(project(":gdg-ui"))
Expand All @@ -68,6 +75,7 @@ kotlin {
implementation(libs.common.koin)
implementation(libs.util.constraintlayout)
}

commonTest.dependencies {
implementation(kotlin("test"))
implementation(libs.common.koin.test)
Expand Down Expand Up @@ -128,3 +136,14 @@ android {
}
}

compose.desktop {
application {
mainClass = "id.gdg.app.MainKt"

nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "id.gdg.app"
packageVersion = "1.0.0"
}
}
}
1 change: 0 additions & 1 deletion app/src/androidMain/kotlin/id/gdg/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import id.gdg.app.ui.AppContent
import id.gdg.ui.DarkColorPalette
import id.gdg.ui.LightColorPalette
import id.gdg.ui.androidx.compose.material3.windowsizeclass.CommonWindowSizeClass
Expand Down
15 changes: 0 additions & 15 deletions app/src/commonMain/kotlin/id/gdg/app/App.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package id.gdg.app.ui
package id.gdg.app

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
Expand All @@ -11,8 +11,9 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import id.gdg.app.AppViewModel
import id.gdg.app.di.ViewModelFactory
import id.gdg.app.ui.AppEvent
import id.gdg.app.ui.AppRouter
import id.gdg.app.ui.screen.EventDetailScreen
import id.gdg.app.ui.screen.MainScreen
import id.gdg.app.ui.screen.OnboardingScreen
Expand Down
2 changes: 1 addition & 1 deletion app/src/commonMain/kotlin/id/gdg/app/AppViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AppViewModel(
_upcomingEvent,
_previousEvents
) { upcoming, previous ->
ChapterUiModel(upcoming, previous, true)
ChapterUiModel(upcoming, previous)
}.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
Expand Down
30 changes: 11 additions & 19 deletions app/src/commonMain/kotlin/id/gdg/app/ui/screen/MainScreen.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package id.gdg.app.ui.screen

import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
Expand Down Expand Up @@ -32,29 +30,23 @@ fun MainScreen(
var selectedEventId by rememberSaveable { mutableStateOf("") }

val windowSizeClazz: CommonWindowSizeClass = LocalWindowSizeClass.current
var hasDetailOpened: Boolean? by rememberSaveable { mutableStateOf(null) }
var showSidePanel by rememberSaveable {
mutableStateOf(hasDetailOpened != null).also {
println("showsidepanel: ${it.value}")
}
}
var shouldPanelOpened: Boolean? by rememberSaveable { mutableStateOf(null) }
var panelVisibility by rememberSaveable { mutableStateOf(shouldPanelOpened != null) }

LaunchedEffect(!chapterUiState.isInitiated) {
LaunchedEffect(Unit) {
viewModel.sendEvent(AppEvent.InitialContent)
}

LaunchedEffect(windowSizeClazz) {
hasDetailOpened =
hasDetailOpened.takeIf { windowSizeClazz.widthSizeClass != CommonWindowWidthSizeClass.Compact }
println("hasdetail: $hasDetailOpened")
println("apaini: ${windowSizeClazz.widthSizeClass != CommonWindowWidthSizeClass.Compact}")
showSidePanel = hasDetailOpened != null
shouldPanelOpened =
shouldPanelOpened.takeIf { windowSizeClazz.widthSizeClass != CommonWindowWidthSizeClass.Compact }
panelVisibility = shouldPanelOpened != null
}

TwoPanelScaffold(
panelVisibility = showSidePanel,
panelVisibility = panelVisibility,
animationSpec = TwoPanelScaffoldAnimationSpec(
finishedListener = { fraction -> if (fraction == 1f) hasDetailOpened = null }
finishedListener = { fraction -> if (fraction == 1f) shouldPanelOpened = null }
),
body = {
MainScreenContent(
Expand All @@ -68,8 +60,8 @@ fun MainScreen(
}

selectedEventId = it
hasDetailOpened = true
showSidePanel = true
shouldPanelOpened = true
panelVisibility = true
},
onRefreshPreviousContentClicked = {
viewModel.sendEvent(AppEvent.FetchPreviousEvent)
Expand All @@ -78,7 +70,7 @@ fun MainScreen(
},
panel = {
Surface(tonalElevation = 1.dp) {
if (hasDetailOpened != null) {
if (shouldPanelOpened != null) {
EventDetailScreen(
viewModel = viewModel,
eventId = selectedEventId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,27 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import id.gdg.app.ui.screen.uimodel.toEventContent
import id.gdg.app.ui.state.partial.PreviousEventsUiModel
import id.gdg.ui.component.EventContent
import id.gdg.ui.component.EventSimpleCard
import id.gdg.ui.component.HeadlineSection
import id.gdg.ui.component.shimmer.EventSimpleCardShimmerList

@Composable
fun PreviousEventContent(
data: PreviousEventsUiModel,
onRefreshContent: () -> Unit,
onEventClicked: (String) -> Unit,
) {
Box {
Box(
modifier = Modifier
.padding(12.dp)
) {
AnimatedVisibility(data.state.isLoading) {
CircularProgressIndicator()
EventSimpleCardShimmerList()
}

when {
Expand All @@ -37,16 +37,12 @@ fun PreviousEventContent(
modifier = Modifier
.fillMaxWidth(),
) {
item {
Text(
text = "Previous Events",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
}
item { HeadlineSection("Previous Events") }

items(data.previousEvents.map { it.toEventContent() }) {
EventSimpleCard(it) { onEventClicked(it) }
items(data.toEventContent()) {
EventSimpleCard(it) { eventId ->
onEventClicked(eventId)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ fun EventModel.toEventContent(): EventContent {
bannerUrl = eventImageUrl,
eventName = title,
date = startDate,
type = audienceType
type = audienceType.toString()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ import id.gdg.app.ui.state.partial.UpcomingEventUiModel

data class ChapterUiModel(
val upcomingEvent: UpcomingEventUiModel,
val previousEvents: PreviousEventsUiModel,
val isInitiated: Boolean
val previousEvents: PreviousEventsUiModel
) {

companion object {
val Default get() = ChapterUiModel(
upcomingEvent = UpcomingEventUiModel.Empty,
previousEvents = PreviousEventsUiModel.Empty,
isInitiated = false
previousEvents = PreviousEventsUiModel.Empty
)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package id.gdg.app.ui.state.partial

import id.gdg.app.ui.screen.uimodel.toEventContent
import id.gdg.app.ui.state.common.UiState
import id.gdg.event.model.EventModel

Expand All @@ -8,6 +9,8 @@ data class PreviousEventsUiModel(
val previousEvents: List<EventModel>,
) {

fun toEventContent() = previousEvents.map { it.toEventContent() }

companion object {
val Empty get() = PreviousEventsUiModel(
state = UiState.Loading,
Expand Down
10 changes: 7 additions & 3 deletions app/src/commonTest/kotlin/id/gdg/app/robot/AppViewModelRobot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import id.gdg.app.stub.GetPreviousEventUseCaseStub
import id.gdg.app.stub.GetUpcomingEventUseCaseStub
import id.gdg.chapter.domain.GetChapterIdUseCaseImpl
import id.gdg.chapter.domain.SetChapterIdUseCaseImpl
import id.gdg.event.domain.mapper.AudienceType
import id.gdg.event.model.EventModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
Expand Down Expand Up @@ -84,7 +85,8 @@ object AppViewModelRobot : KoinTest {
descriptionShort = "Loren Ipsum",
eventImageUrl = "https://sample.com/image.png",
startDate = "",
timezoneAbbreviation = "WIB"
timezoneAbbreviation = "WIB",
audienceType = AudienceType("hybrid")
),
EventModel(
id = 1,
Expand All @@ -93,7 +95,8 @@ object AppViewModelRobot : KoinTest {
descriptionShort = "Loren Ipsum",
eventImageUrl = "https://sample.com/image.png",
startDate = "",
timezoneAbbreviation = "WIB"
timezoneAbbreviation = "WIB",
audienceType = AudienceType("in person")
),
EventModel(
id = 2,
Expand All @@ -102,7 +105,8 @@ object AppViewModelRobot : KoinTest {
descriptionShort = "Loren Ipsum",
eventImageUrl = "https://sample.com/image.png",
startDate = "",
timezoneAbbreviation = "WIB"
timezoneAbbreviation = "WIB",
audienceType = AudienceType("online")
)
)
}
Loading

0 comments on commit 3a94a0b

Please sign in to comment.