WIP: Render list of linked items

This commit is contained in:
Satindar Dhillon 2022-08-30 08:06:12 -07:00
parent 2eabc318fe
commit 67d8d95825
3 changed files with 179 additions and 15 deletions

View file

@ -1,25 +1,46 @@
package app.omnivore.omnivore.ui.home
import android.annotation.SuppressLint
import android.net.Uri
import android.util.Log
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import app.omnivore.omnivore.AppleConstants
import app.omnivore.omnivore.ui.auth.AppleAuthDialog
import app.omnivore.omnivore.ui.auth.LoginViewModel
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
@Composable
fun HomeView(loginViewModel: LoginViewModel, homeViewModel: HomeViewModel) {
Column(
val linkedItems: List<LinkedItem> by homeViewModel.itemsLiveData.observeAsState(listOf())
// Fetch items
homeViewModel.load()
LazyColumn(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
@ -27,10 +48,19 @@ fun HomeView(loginViewModel: LoginViewModel, homeViewModel: HomeViewModel) {
.fillMaxSize()
.padding(horizontal = 6.dp)
) {
Text("You have a valid auth token. Nice. Go save something in Chrome!")
LogoutButton { loginViewModel.logout() }
Button(onClick = { homeViewModel.loggo() } ) {
Text("Loggo")
item {
Text("You have a valid auth token. Nice. Go save something in Chrome!")
}
item {
LogoutButton { loginViewModel.logout() }
}
items(linkedItems) { item ->
Text(item.title, modifier = Modifier.clickable {
Log.d("log", "clicked title: ${item.title}")
})
Spacer(modifier = Modifier.height(16.dp))
}
}
}
@ -52,3 +82,63 @@ fun LogoutButton(actionHandler: () -> Unit) {
Text(text = "Logout")
}
}
if (showDialog.value) {
AppleAuthDialog(onDismiss = { token ->
if (token != null ) {
viewModel.handleAppleToken(token)
}
showDialog.value = false
})
}
@Composable
fun ArticleWebViewDialog(onDismiss: (String?) -> Unit) {
Dialog(onDismissRequest = { onDismiss(null) }) {
Surface(
shape = RoundedCornerShape(16.dp),
color = Color.White
) {
AppleAuthWebView(onDismiss)
}
}
}
@SuppressLint("SetJavaScriptEnabled")
@Composable
fun ArticleWebView(onDismiss: (String?) -> Unit) {
val url = AppleConstants.authUrl +
"?client_id=" + AppleConstants.clientId +
"&redirect_uri=" + AppleConstants.redirectURI +
"&response_type=code%20id_token" +
"&scope=" + AppleConstants.scope +
"&response_mode=form_post" +
"&state=android:login"
// Adding a WebView inside AndroidView
// with layout as full screen
AndroidView(factory = {
WebView(it).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
if (request?.url.toString().contains("android-apple-token")) {
val uri = Uri.parse(request!!.url.toString())
val token = uri.getQueryParameter("token")
onDismiss(token)
}
return true
}
}
settings.javaScriptEnabled = true
loadUrl(url)
}
}, update = {
it.loadUrl(url)
})
}

View file

@ -1,10 +1,29 @@
package app.omnivore.omnivore.ui.home
import android.util.Log
import androidx.lifecycle.ViewModel
import android.annotation.SuppressLint
import android.net.Uri
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
import androidx.lifecycle.*
import app.omnivore.omnivore.AppleConstants
import app.omnivore.omnivore.Constants
import app.omnivore.omnivore.DatastoreKeys
import app.omnivore.omnivore.DatastoreRepository
import app.omnivore.omnivore.graphql.generated.SearchQuery
import app.omnivore.omnivore.ui.auth.AppleAuthDialog
import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.api.Optional
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
@ -12,11 +31,68 @@ import javax.inject.Inject
class HomeViewModel @Inject constructor(
private val datastoreRepo: DatastoreRepository
): ViewModel() {
val itemsLiveData = MutableLiveData<List<LinkedItem>>(listOf())
private fun getAuthToken(): String? = runBlocking {
datastoreRepo.getString(DatastoreKeys.omnivoreAuthToken)
}
fun loggo() {
Log.d("TAG", "logging it!")
fun load() {
viewModelScope.launch {
val authToken = getAuthToken()
val apolloClient = ApolloClient.Builder()
.serverUrl("${Constants.apiURL}/api/graphql")
.addHttpHeader("Authorization", value = authToken ?: "")
.build()
val response = apolloClient.query(
SearchQuery(
first = Optional.presentIfNotNull(20),
)
).execute()
val itemList = response.data?.search?.onSearchSuccess?.edges ?: listOf()
val newItems = itemList.map {
LinkedItem(
id = it.node.id,
title = it.node.title,
createdAt = it.node.createdAt,
readAt = it.node.readAt,
readingProgress = it.node.readingProgressPercent,
readingProgressAnchor = it.node.readingProgressAnchorIndex,
imageURLString = it.node.image,
descriptionText = it.node.description,
slug = it.node.slug
)
}
itemsLiveData.value = newItems
}
}
}
public data class LinkedItem(
public val id: String,
public val title: String,
public val createdAt: Any,
// public val savedAt: Any,
public val readAt: Any?,
// public val updatedAt: Any,
public val readingProgress: Double,
public val readingProgressAnchor: Int,
public val imageURLString: String?,
// public val onDeviceImageURLString: String?,
// public val documentDirectoryPath: String?,
// public val pageURLString: String,
public val descriptionText: String?,
// public val publisherURLString: String?,
// public val siteName: String?,
// public val author: String?,
// public val publishDate: Any?,
public val slug: String,
// public val isArchived: Boolean,
// public val contentReader: String?,
// public val originalHtml: String?,
)

View file

@ -40,8 +40,6 @@ class SaveViewModel @Inject constructor(
val authToken = getAuthToken()
Log.d(ContentValues.TAG, "AuthToken: $authToken")
if (authToken == null) {
message = "You are not logged in. Please login before saving."
isLoading = false