Skip to content

Commit

Permalink
Merge pull request #8 from SphericalKat/refactor-welcome-auth
Browse files Browse the repository at this point in the history
  • Loading branch information
SphericalKat authored Aug 4, 2021
2 parents cc477f3 + 5ef6e0a commit 02d4e7a
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 122 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ dependencies {
implementation "androidx.browser:browser:1.3.0"

// navigation
implementation "androidx.navigation:navigation-compose:2.4.0-alpha05"
implementation "androidx.navigation:navigation-compose:2.4.0-alpha04"

// accompanist
implementation "com.google.accompanist:accompanist-insets:0.13.0"
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

</activity>
<activity
android:name=".AuthActivity"
android:theme="@style/Theme.Transparent"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

Expand All @@ -33,6 +37,7 @@
android:scheme="gimmick" />
</intent-filter>
</activity>

</application>

</manifest>
44 changes: 44 additions & 0 deletions app/src/main/java/at/sphericalk/gidget/AuthActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package at.sphericalk.gidget

import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import at.sphericalk.gidget.utils.Constants

class AuthActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val authIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Constants.OAUTH_URL))
startActivity(authIntent)
return
}

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)

if (intent == null) {
setResult(Activity.RESULT_CANCELED)
finish()
return
}

val uri = intent.data
val returnIntent = Intent().apply { data = intent.data }

if (uri.toString().startsWith(Constants.REDIRECT_URI)) {
setResult(Activity.RESULT_OK, returnIntent)
} else {
setResult(Activity.RESULT_CANCELED, returnIntent)
}

finish()
}

override fun onDestroy() {
super.onDestroy()
}
}
63 changes: 19 additions & 44 deletions app/src/main/java/at/sphericalk/gidget/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.core.view.WindowCompat
import androidx.datastore.preferences.core.edit
Expand All @@ -19,6 +16,8 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import at.sphericalk.gidget.navigation.AppActions
import at.sphericalk.gidget.navigation.Destination
import at.sphericalk.gidget.ui.routes.Feed
import at.sphericalk.gidget.ui.routes.FeedViewModel
import at.sphericalk.gidget.ui.routes.Release
Expand Down Expand Up @@ -75,47 +74,23 @@ class MainActivity : ComponentActivity() {
WindowCompat.setDecorFitsSystemWindows(window, false)
}

override fun onResume() {
super.onResume()
val uri = intent.data
@Composable
fun Home(
viewModel: FeedViewModel,
navController: NavHostController,
languageColors: LanguageColors
) {
val dataStore = LocalActivity.current.dataStore

if (uri.toString().startsWith(Constants.REDIRECT_URI)) {
viewModel.getAccessToken(
BuildConfig.CLIENT_ID,
BuildConfig.CLIENT_SECRET,
uri?.getQueryParameter("code").toString(),
Constants.REDIRECT_URI
).observe(this) {
if (it != null) {
runBlocking {
dataStore.edit { prefs ->
prefs[Constants.API_KEY] = it.first
prefs[Constants.USERNAME] = it.second
}
}
navController.navigate("feed") {
popUpTo("welcome") { inclusive = true }
}
}
}
}
}
}

@Composable
fun Home(
viewModel: FeedViewModel,
navController: NavHostController,
languageColors: LanguageColors
) {
val dataStore = LocalActivity.current.dataStore
val token = runBlocking { dataStore.data.first()[Constants.API_KEY] }
val startDestination =
if (token == null) Destination.Welcome.route else Destination.Feed.route
val appActions = remember(navController) { AppActions(navController) }

val token = runBlocking { dataStore.data.first()[Constants.API_KEY] }
val startDestination = if (token == null) "welcome" else "feed"

NavHost(navController = navController, startDestination = startDestination) {
composable("welcome") { Welcome(navController) }
composable("feed") { Feed(navController, viewModel, languageColors) }
composable("release") { Release(navController, viewModel) }
NavHost(navController = navController, startDestination = startDestination) {
composable(Destination.Welcome.route) { Welcome(viewModel, appActions.navigateToFeed) }
composable(Destination.Feed.route) { Feed(navController, viewModel, languageColors) }
composable(Destination.Release.route) { Release(navController, viewModel) }
}
}
}
17 changes: 17 additions & 0 deletions app/src/main/java/at/sphericalk/gidget/navigation/Destination.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package at.sphericalk.gidget.navigation

import androidx.navigation.NavController

sealed class Destination(val route: String) {
object Welcome : Destination("welcome")
object Feed : Destination("feed")
object Release : Destination("release")
}

class AppActions(navController: NavController) {
val navigateToFeed: () -> Unit = {
navController.navigate(Destination.Feed.route) {
popUpTo(Destination.Welcome.route) { inclusive = true }
}
}
}
45 changes: 27 additions & 18 deletions app/src/main/java/at/sphericalk/gidget/ui/routes/FeedViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import android.app.Application
import android.util.Log
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import at.sphericalk.gidget.dataStore
import at.sphericalk.gidget.model.ApiResult
import at.sphericalk.gidget.model.Event
import at.sphericalk.gidget.repo.GithubRepository
import at.sphericalk.gidget.utils.Constants
Expand Down Expand Up @@ -78,26 +82,31 @@ class FeedViewModel @Inject constructor(
clientId: String,
clientSecret: String,
code: String,
redirectUrl: String
) = liveData {
try {
repository.getAccessToken(
clientId,
clientSecret,
code,
redirectUrl
).catch { e ->
Log.e("VIEWMODEL", "Something went wrong fetching the auth token", e)
}.collect {
if (it.error != null || it.access_token == null) {
Log.e("VIEWMODEL", "Could not fetch access token")
} else {
val user = repository.getUser(it.access_token)
emit(Pair(it.access_token, user.login))
redirectUrl: String,
dataStore: DataStore<Preferences>
) = liveData<ApiResult<Unit>> {
emit(ApiResult.Loading)

repository.getAccessToken(
clientId,
clientSecret,
code,
redirectUrl
).catch { e ->
Log.e("VIEWMODEL", "Something went wrong fetching the auth token", e)
emit(ApiResult.Error("Something went wrong fetching the auth token"))
}.collect {
if (it.error != null || it.access_token == null) {
Log.e("VIEWMODEL", "Could not fetch access token")
emit(ApiResult.Error("Something went wrong fetching the auth token"))
} else {
val user = repository.getUser(it.access_token)
dataStore.edit { prefs ->
prefs[Constants.API_KEY] = it.access_token
prefs[Constants.USERNAME] = user.login
}
emit(ApiResult.Success(Unit))
}
} catch (e: Exception) {
Log.e("VIEWMODEL", "Something went wrong fetching the auth token", e)
}
}
}
Loading

0 comments on commit 02d4e7a

Please sign in to comment.