Skip to content

Commit

Permalink
Record Store Integration
Browse files Browse the repository at this point in the history
  • Loading branch information
cristhianescobar committed Oct 11, 2024
1 parent 646297a commit ec0e3d8
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 10 deletions.
17 changes: 17 additions & 0 deletions android/app-newm/src/main/java/io/newm/HomeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import io.newm.screens.library.NFTLibraryState
import io.newm.screens.profile.edit.ProfileEditPresenter
import io.newm.screens.profile.edit.ProfileEditUi
import io.newm.screens.profile.edit.ProfileEditUiState
import io.newm.screens.recordstore.RecordStorePresenter
import io.newm.screens.recordstore.RecordStoreScreenUi
import io.newm.screens.recordstore.RecordStoreState
import io.newm.shared.NewmAppLogger
import io.newm.shared.public.analytics.NewmAppEventLogger
import io.newm.shared.public.analytics.events.AppScreens
Expand Down Expand Up @@ -86,6 +89,14 @@ class HomeActivity : ComponentActivity() {
)
}

is Screen.RecordStore -> ui<RecordStoreState> { state, modifier ->
RecordStoreScreenUi(
state = state,
modifier = modifier,
eventLogger = eventLogger
)
}

is NFTLibrary -> ui<NFTLibraryState> { state, modifier ->
NFTLibraryScreenUi(
state = state,
Expand Down Expand Up @@ -131,6 +142,12 @@ class HomeActivity : ComponentActivity() {
)
}.value

is Screen.RecordStore -> inject<RecordStorePresenter> {
parametersOf(
navigator
)
}.value

is Screen.EditProfile -> inject<ProfileEditPresenter> {
parametersOf(
navigator
Expand Down
17 changes: 17 additions & 0 deletions android/app-newm/src/main/java/io/newm/NewmAppComposable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ val initialScreen = Screen.NFTLibrary
internal fun NewmApp(
logger: NewmAppLogger,
eventLogger: NewmAppEventLogger,
showRecordStore: Boolean = false //update once backend supports special access
) {
val context = LocalContext.current
val backstack = rememberSaveableBackStack {
Expand Down Expand Up @@ -166,6 +167,7 @@ internal fun NewmApp(
NewmBottomNavigation(
currentRootScreen = currentRootScreen,
eventLogger = eventLogger,
showRecordStore = showRecordStore,
onNavigationSelected = {
circuitNavigator.resetRoot(it)
}
Expand All @@ -188,6 +190,7 @@ internal fun NewmApp(
internal fun NewmBottomNavigation(
currentRootScreen: CircuitScreen?,
eventLogger: NewmAppEventLogger,
showRecordStore: Boolean = false,
onNavigationSelected: (Screen) -> Unit
) {
Column(Modifier.height(76.dp)) {
Expand All @@ -209,6 +212,20 @@ internal fun NewmBottomNavigation(
onNavigationSelected(Screen.NFTLibrary)
},
)
if (showRecordStore) {
HomeBottomNavigationItem(
selected = currentRootScreen == Screen.RecordStore,
iconResId = R.drawable.ic_recordstore_active,
labelResId = R.string.record_store,
selectedIconBrush = AccountIconGradient,
selectedLabelColor = DarkPink,
onClick = {
eventLogger.logClickEvent(AppScreens.RecordStoreScreen.RECORD_STORE_BUTTON)
eventLogger.logPageLoad(AppScreens.RecordStoreScreen.name)
onNavigationSelected(Screen.RecordStore)
},
)
}
HomeBottomNavigationItem(
selected = currentRootScreen == Screen.UserAccount,
iconResId = R.drawable.ic_profile,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import io.newm.screens.forceupdate.ForceAppUpdatePresenter
import io.newm.screens.library.NFTLibraryPresenter
import io.newm.screens.profile.edit.ProfileEditPresenter
import io.newm.screens.profile.view.ProfilePresenter
import io.newm.screens.recordstore.RecordStorePresenter
import io.newm.shared.config.NewmSharedBuildConfig
import io.newm.utils.ForceAppUpdateViewModel
import org.koin.android.ext.koin.androidContext
Expand Down Expand Up @@ -85,6 +86,12 @@ val viewModule = module {
get()
)
}
factory { params ->
RecordStorePresenter(
params.get(),
get(),
)
}
factory { params ->
ProfileEditPresenter(
params.get(),
Expand Down
2 changes: 2 additions & 0 deletions android/app-newm/src/main/java/io/newm/screens/Screen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ sealed class Screen(val screenName: String) : CircuitScreen {

data object UserAccount : Screen(screenName = AppScreens.AccountScreen.name)

data object RecordStore : Screen(screenName = AppScreens.RecordStoreScreen.name)

data object NFTLibrary : Screen(screenName = AppScreens.NFTLibraryScreen.name)

data object Welcome : Screen(screenName = AppScreens.WelcomeScreen.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ fun NFTLibraryScreenUi(
LaunchedEffect(Unit) {
eventLogger.logPageLoad(AppScreens.ErrorScreen.name)
}
ErrorScreen(state.message)
ErrorScreen(
title = "Oops, something went wrong!",
message =state.message)
}

is NFTLibraryState.Content -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.slack.circuit.runtime.CircuitUiEvent

sealed interface ProfileUiEvent : CircuitUiEvent
sealed interface ProfileEditUiEvent : CircuitUiEvent

sealed interface RecordStoreUiEvent : CircuitUiEvent
/** Profile UI Events */
data object OnDisconnectWallet : ProfileUiEvent
data object OnEditProfile : ProfileUiEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private val disconnectWalletButtonTextGradient =
fun ProfileUi(
state: ProfileUiState,
modifier: Modifier = Modifier,
eventLogger : NewmAppEventLogger
eventLogger: NewmAppEventLogger
) {
when (state) {
ProfileUiState.Loading -> LoadingScreen()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.newm.screens.recordstore

import android.content.Context
import android.net.ConnectivityManager
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.platform.LocalContext
import com.slack.circuit.runtime.Navigator
import com.slack.circuit.runtime.presenter.Presenter
import io.newm.screens.profile.view.ProfileUiState
import io.newm.shared.public.analytics.NewmAppEventLogger
import io.newm.shared.public.analytics.events.AppScreens
import io.newm.shared.public.usecases.HasWalletConnectionsUseCase
import io.newm.shared.public.usecases.UserDetailsUseCase
import kotlinx.coroutines.flow.distinctUntilChanged

class RecordStorePresenter(
private val navigator: Navigator,
private val eventLogger: NewmAppEventLogger
) : Presenter<RecordStoreState> {
@Composable
override fun present(): RecordStoreState {
val context = LocalContext.current
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val isNetworkAvailable by remember {
mutableStateOf(connectivityManager.activeNetwork != null)
}
return when {
!isNetworkAvailable -> RecordStoreState.Error
else -> {
eventLogger.logPageLoad(AppScreens.RecordStoreScreen.name)
RecordStoreState.Content(
eventSink = {}
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.newm.screens.recordstore

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import io.newm.core.ui.LoadingScreen
import io.newm.core.ui.utils.ErrorScreen
import io.newm.core.ui.webview.FullScreenWebView
import io.newm.screens.library.TAG_NFT_LIBRARY_SCREEN
import io.newm.shared.public.analytics.NewmAppEventLogger
import io.newm.shared.public.analytics.events.AppScreens

private const val RECORD_STORE_URL = "https://recordstore.newm.io/"

@Composable
fun RecordStoreScreenUi(
modifier: Modifier = Modifier,
state: RecordStoreState,
eventLogger: NewmAppEventLogger
) {
val context = LocalContext.current
Column(
modifier = modifier
.fillMaxSize()
.statusBarsPadding()
.testTag(TAG_NFT_LIBRARY_SCREEN),
) {
when (state) {
is RecordStoreState.Content -> {
FullScreenWebView(context, RECORD_STORE_URL)
}

RecordStoreState.Loading -> {
LaunchedEffect(Unit) {
eventLogger.logPageLoad(AppScreens.LoadingScreen.name)
}
LoadingScreen()
}

RecordStoreState.Error -> {
ErrorScreen(
title = "Connection Lost",
message = "It looks like you're not connected to the internet. Please check your connection and try again."
)
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.newm.screens.recordstore

import com.slack.circuit.runtime.CircuitUiState
import io.newm.screens.profile.RecordStoreUiEvent

sealed class RecordStoreState : CircuitUiState {
data object Loading : RecordStoreState()
data class Content(
val eventSink: (RecordStoreUiEvent) -> Unit,
) : RecordStoreState()
data object Error : RecordStoreState()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android" android:alpha="0.9" android:autoMirrored="true" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<group>

<clip-path android:pathData="M0,0h24v24h-24z"/>

<path android:pathData="M4,3H20C20.265,3 20.52,3.105 20.707,3.293C20.895,3.48 21,3.735 21,4V20C21,20.265 20.895,20.52 20.707,20.707C20.52,20.895 20.265,21 20,21H4C3.735,21 3.48,20.895 3.293,20.707C3.105,20.52 3,20.265 3,20V4C3,3.735 3.105,3.48 3.293,3.293C3.48,3.105 3.735,3 4,3ZM12,17C10.674,17 9.402,16.473 8.464,15.535C7.527,14.598 7,13.326 7,12C7,10.674 7.527,9.402 8.464,8.464C9.402,7.527 10.674,7 12,7C13.326,7 14.598,7.527 15.535,8.464C16.473,9.402 17,10.674 17,12C17,13.326 16.473,14.598 15.535,15.535C14.598,16.473 13.326,17 12,17ZM12,19C12.919,19 13.83,18.819 14.679,18.467C15.528,18.115 16.3,17.6 16.95,16.95C17.6,16.3 18.115,15.528 18.467,14.679C18.819,13.83 19,12.919 19,12C19,11.081 18.819,10.17 18.467,9.321C18.115,8.472 17.6,7.7 16.95,7.05C16.3,6.4 15.528,5.885 14.679,5.533C13.83,5.181 12.919,5 12,5C10.144,5 8.363,5.738 7.05,7.05C5.738,8.363 5,10.144 5,12C5,13.856 5.738,15.637 7.05,16.95C8.363,18.263 10.144,19 12,19ZM12,14C12.53,14 13.039,13.789 13.414,13.414C13.789,13.039 14,12.53 14,12C14,11.47 13.789,10.961 13.414,10.586C13.039,10.211 12.53,10 12,10C11.47,10 10.961,10.211 10.586,10.586C10.211,10.961 10,11.47 10,12C10,12.53 10.211,13.039 10.586,13.414C10.961,13.789 11.47,14 12,14Z">

<aapt:attr name="android:fillColor">

<gradient android:endX="23.235" android:endY="6.018" android:startX="3" android:startY="21" android:type="linear">

<item android:color="#FFF53C69" android:offset="0"/>

<item android:color="#FFFF6E32" android:offset="1"/>

</gradient>

</aapt:attr>

</path>

</group>

</vector>
1 change: 1 addition & 0 deletions android/core/resources/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<resources>
<string name="account">Account</string>
<string name="record_store">RecordStore</string>
<string name="app_name">NEWM</string>
<string name="artist_list_songs">%s Songs</string>
<string name="barcode_help_text">How can I connect a wallet?</string>
Expand Down
3 changes: 2 additions & 1 deletion android/core/ui-utils/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ android {
dependencies {
api(project(Modules.coreResources))

implementation(libs.androidx.browser)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.material)
implementation(libs.androidx.material.icons.extended)
implementation(project(Modules.coreTheme))
implementation(project(":shared"))
implementation(project(Modules.coreTheme))
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,32 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import io.newm.shared.public.analytics.NewmAppEventLogger

@Composable
fun ErrorScreen(
errorMessage: String
title: String,
message: String
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(
text = "Oops, something went wrong!",
style = MaterialTheme.typography.h6,
text = title,
style = MaterialTheme.typography.h4,
textAlign = TextAlign.Center,
modifier = Modifier.padding(16.dp)
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = errorMessage,
text = message,
style = MaterialTheme.typography.body1,
textAlign = TextAlign.Center,
modifier = Modifier.padding(horizontal = 16.dp)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.newm.core.ui.webview

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView

@SuppressLint("SetJavaScriptEnabled")
@Composable
fun FullScreenWebView(context: Context, url: String) {
AndroidView(
factory = { ctx ->
WebView(ctx).apply {
webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
val currentUrl = request?.url.toString()
return if (currentUrl.startsWith("https://newm.io/")) {
// Load the URL in the current WebView
false
} else {
// Open URLs that don't start with "https://newm.io/" in an external browser or another WebView
launchExternalUrl(context, currentUrl)
true
}
}
}

settings.javaScriptEnabled = true

loadUrl(url)
}
},
modifier = Modifier.fillMaxSize()
)
}

fun launchExternalUrl(context: Context, url: String) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
context.startActivity(intent)
}
Loading

0 comments on commit ec0e3d8

Please sign in to comment.