Skip to content

Commit

Permalink
List past events (#1439)
Browse files Browse the repository at this point in the history
Co-authored-by: Ashley Davies <[email protected]>
  • Loading branch information
ashdavies and ashdavies authored Jan 14, 2025
1 parent ac081a9 commit 029ffa6
Show file tree
Hide file tree
Showing 14 changed files with 597 additions and 449 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ public fun AsgService(httpClient: HttpClient): AsgService = object : AsgService
public fun UpcomingConferencesCallable(httpClient: HttpClient): UpcomingConferencesCallable {
return UpcomingConferencesCallable(httpClient, ASG_BASE_URL)
}

public fun PastConferencesCallable(httpClient: HttpClient): PastConferencesCallable {
return PastConferencesCallable(httpClient, ASG_BASE_URL)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.get

internal fun interface PastConferencesCallable : UnaryCallable<Unit, List<AsgConference>>
public fun interface PastConferencesCallable : UnaryCallable<Unit, List<AsgConference>>

internal fun PastConferencesCallable(
httpClient: HttpClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ import com.slack.circuit.runtime.Navigator
import com.slack.circuit.runtime.presenter.Presenter
import com.slack.circuit.runtime.presenter.presenterOf
import com.slack.circuit.runtime.screen.Screen
import io.ashdavies.aggregator.PastConferencesCallable
import io.ashdavies.content.PlatformContext
import io.ashdavies.content.reportFullyDrawn
import io.ashdavies.http.DefaultHttpConfiguration
import io.ashdavies.http.LocalHttpClient
import io.ashdavies.identity.IdentityManager
import io.ashdavies.party.coroutines.rememberRetainedCoroutineScope
import io.ashdavies.party.events.paging.rememberEventPager
import io.ashdavies.party.gallery.File
import io.ashdavies.party.gallery.GalleryPresenter
import io.ashdavies.party.gallery.GalleryScreen
import io.ashdavies.party.gallery.ImageManager
import io.ashdavies.party.gallery.PathProvider
import io.ashdavies.party.gallery.StorageManager
Expand All @@ -26,9 +30,8 @@ import io.ashdavies.party.gallery.inMemoryHttpClientEngine
import io.ashdavies.party.gallery.readChannel
import io.ashdavies.party.home.HomePresenter
import io.ashdavies.party.home.HomeScreen
import io.ashdavies.party.past.GalleryScreen
import io.ashdavies.party.past.PastEventListScreen
import io.ashdavies.party.past.PastEventsPresenter
import io.ashdavies.party.past.PastEventsScreen
import io.ashdavies.party.upcoming.UpcomingEventsPresenter
import io.ashdavies.party.upcoming.UpcomingEventsScreen
import io.ashdavies.playground.PlaygroundDatabase
Expand Down Expand Up @@ -69,10 +72,21 @@ public fun rememberCircuit(
)
.addCircuit<GalleryScreen, GalleryScreen.State>(
presenterFactory = { _, _, _ ->
presenterOf { PastEventsPresenter(imageManager, syncManager) }
presenterOf { GalleryPresenter(imageManager, syncManager) }
},
uiFactory = { state, modifier ->
PastEventListScreen(state, storageManager, modifier)
GalleryScreen(state, storageManager, modifier)
},
)
.addCircuit<PastEventsScreen, PastEventsScreen.State>(
presenterFactory = { _, _, _ ->
presenterOf {
val callable = PastConferencesCallable(LocalHttpClient.current)
PastEventsPresenter(callable)
}
},
uiFactory = { state, modifier ->
PastEventsScreen(state, modifier)
},
)
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import io.ashdavies.config.LocalRemoteConfig
import io.ashdavies.config.RemoteConfig
import io.ashdavies.config.getBoolean

internal suspend fun RemoteConfig.isProfileEnabled() = getBoolean("profile_enabled")

internal suspend fun RemoteConfig.galleryCapture() = getBoolean("gallery_capture")

internal suspend fun RemoteConfig.showPastEvents() = getBoolean("past_events")
internal suspend fun RemoteConfig.isGalleryEnabled() = getBoolean("gallery_enabled")

@Composable
internal fun booleanConfigAsState(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package io.ashdavies.party.gallery

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import com.slack.circuit.retained.produceRetainedState
import com.slack.circuit.retained.rememberRetained
import kotlinx.coroutines.launch

@Composable
internal fun GalleryPresenter(
imageManager: ImageManager,
syncManager: SyncManager,
): GalleryScreen.State {
val itemList by produceRetainedState(emptyList<Image>()) {
imageManager.list.collect { value = it }
}

val syncState by produceRetainedState(emptyMap<String, SyncState>()) {
syncManager.state.collect { value = it }
}

val coroutineScope = rememberCoroutineScope()

var expandedItem by rememberRetained {
mutableStateOf<GalleryScreen.State.ExpandedItem?>(null)
}

var selected by rememberRetained { mutableStateOf(emptyList<Image>()) }
var takePhoto by rememberRetained { mutableStateOf(false) }

return GalleryScreen.State(
itemList = itemList.map {
GalleryScreen.State.StandardItem(
title = it.name,
imageModel = File(it.path),
isSelected = it in selected,
state = syncState[it.name] ?: SyncState.NOT_SYNCED,
)
},
expandedItem = expandedItem,
showCapture = takePhoto,
) { event ->
when (event) {
is GalleryScreen.Event.Capture.Result -> coroutineScope.launch {
imageManager.add(event.value)
takePhoto = false
}

is GalleryScreen.Event.Capture.Cancel -> takePhoto = false
is GalleryScreen.Event.Capture.Request -> takePhoto = true

is GalleryScreen.Event.Selection.Expand -> {
expandedItem = GalleryScreen.State.ExpandedItem(
contentDescription = itemList[event.index].name,
imageModel = File(itemList[event.index].path),
isExpanded = true,
)
}

is GalleryScreen.Event.Selection.Toggle -> itemList[event.index].also {
if (it in selected) selected -= it else selected += it
}

is GalleryScreen.Event.Selection.Collapse -> {
expandedItem = expandedItem?.copy(isExpanded = false)
}

is GalleryScreen.Event.Selection.Delete -> coroutineScope.launch {
selected.forEach { imageManager.remove(it) }
selected = emptyList()
}

is GalleryScreen.Event.Selection.Sync -> coroutineScope.launch {
selected.forEach { syncManager.sync(it.path) }
selected = emptyList()
}
}
}
}
Loading

0 comments on commit 029ffa6

Please sign in to comment.