mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
WIP: Render list of linked items
This commit is contained in:
parent
2eabc318fe
commit
67d8d95825
3 changed files with 179 additions and 15 deletions
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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?,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue