Added some stuff.
This commit is contained in:
parent
a92f970aaf
commit
c5f06a9db9
7 changed files with 124 additions and 177 deletions
|
@ -16,10 +16,9 @@ object DriveRequester {
|
|||
builderModifier: (HttpUrl.Builder) -> Unit,
|
||||
callback: (String?, Exception?) -> Unit
|
||||
) {
|
||||
val authPersistence = AuthStatePersistence
|
||||
val authState = authPersistence.retrieveAuthState(context)
|
||||
val authState = AuthStatePersistence.retrieveAuthState(context)
|
||||
makeDriveApiCall(context, authState, url, builderModifier, callback)
|
||||
authPersistence.putAuthState(context, authState)
|
||||
AuthStatePersistence.putAuthState(context, authState)
|
||||
}
|
||||
|
||||
fun populateTree(
|
||||
|
|
|
@ -80,7 +80,8 @@ class HomeNotAuthActivity : ComponentActivity() {
|
|||
.setScopes(
|
||||
listOf(
|
||||
"https://www.googleapis.com/auth/drive",
|
||||
"https://www.googleapis.com/auth/drive.apps"
|
||||
"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/userinfo.email",
|
||||
)
|
||||
)
|
||||
.build()
|
||||
|
|
|
@ -13,32 +13,24 @@ You should have received a copy of the GNU General Public License along with DeN
|
|||
If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file contains the MainActivity activity.
|
||||
* The activity is responsible for the everyday usage of the app.
|
||||
* It provides a UI to do all sort of operations
|
||||
*/
|
||||
|
||||
package com.bbc.denadrive
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.bbc.denadrive.apihandlers.DriveResponseBody
|
||||
import com.bbc.denadrive.apihandlers.MyFile
|
||||
import com.bbc.denadrive.apihandlers.ResponsesHandler
|
||||
import com.bbc.denadrive.apihandlers.ResponsesViewer
|
||||
import com.bbc.denadrive.apihandlers.makeDriveApiCall
|
||||
import com.bbc.denadrive.filehandling.FileDownloader
|
||||
import com.bbc.denadrive.home.ScaffoldWithSidebar
|
||||
import com.bbc.denadrive.oauth.AuthStatePersistence
|
||||
import com.bbc.denadrive.ui.theme.DeNaDriveTheme
|
||||
import net.openid.appauth.AuthorizationException
|
||||
import net.openid.appauth.AuthorizationResponse
|
||||
import okhttp3.HttpUrl
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
|
@ -57,10 +49,7 @@ class MainActivity : ComponentActivity() {
|
|||
|
||||
DriveRequester.populateTree(this, responsesViewer.folderTree)
|
||||
|
||||
// onBackPressedDispatcher.addCallback(this) {
|
||||
// if (currentPath != "root") goToFolder("", false)
|
||||
// else finish()
|
||||
// }
|
||||
Log.e("vediamo", AuthStatePersistence.retrieveAuthState(this).jsonSerializeString())
|
||||
|
||||
onBackPressedDispatcher.addCallback(this) {
|
||||
if (responsesViewer.currentFolderTree.value.parent != null) {
|
||||
|
@ -72,7 +61,6 @@ class MainActivity : ComponentActivity() {
|
|||
}
|
||||
val fileDownloader = FileDownloader(this)
|
||||
|
||||
// goToFolder(parentFolder = "root", forward = true, isFirstRequest = true)
|
||||
|
||||
setContent {
|
||||
// val navController = rememberNavController()
|
||||
|
@ -84,10 +72,11 @@ class MainActivity : ComponentActivity() {
|
|||
"You pressed the file ${file.name}",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
if (file.mimeType.substringAfterLast(".") in exportSupportedFiles) {
|
||||
/*if (file.mimeType.substringAfterLast(".") in exportSupportedFiles) {
|
||||
Log.e("MYTAG", "Supported!", )
|
||||
fileDownloader.downloadFile(
|
||||
"https://www.googleapis.com/drive/v3/files/${file.id}/export",
|
||||
"application/pdf"
|
||||
file,
|
||||
exported = true
|
||||
)
|
||||
} else {
|
||||
Toast.makeText(
|
||||
|
@ -95,109 +84,31 @@ class MainActivity : ComponentActivity() {
|
|||
"This file has no default action. Download support coming soon",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}*/
|
||||
fileDownloader.downloadFile(
|
||||
file,
|
||||
exported = file.mimeType.substringAfterLast(".") in exportSupportedFiles
|
||||
)
|
||||
},
|
||||
{ folder ->
|
||||
responsesViewer.currentFolderTree.value =
|
||||
responsesViewer.currentFolderTree.value.stepForward(folder.id)
|
||||
// responsesViewer.currentFolderTree.value =
|
||||
// responsesViewer.currentFolderTree.value.goToPath("$folder/")
|
||||
// parent ->
|
||||
// goToFolder(parent, true)
|
||||
}
|
||||
) {
|
||||
responsesViewer.toggleUpdaters()
|
||||
// getApps()
|
||||
DriveRequester.makeNewRequest(
|
||||
this,
|
||||
"https://people.googleapis.com/v1/people/me?personFields=emailAddresses",
|
||||
{}) { resp, ex ->
|
||||
if (ex != null) {
|
||||
Log.e("noGood", "$ex")
|
||||
} else {
|
||||
Log.e("good", "$resp")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getApps() {
|
||||
val myUrl = "https://www.googleapis.com/drive/v3/apps"
|
||||
DriveRequester.makeNewRequest(this, myUrl, { }) {
|
||||
response, exception ->
|
||||
if (exception != null) {
|
||||
Log.e("notGood", "getApps: $exception", )
|
||||
} else {
|
||||
Log.e("GOOD", "getApps: $response", )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private fun askForFolder(folderId: String) {
|
||||
// val myUrl = "https://www.googleapis.com/drive/v3/files"
|
||||
// makeNewRequest(myUrl, { builder ->
|
||||
// builder.addQueryParameter("q", "'$folderId' in parents")
|
||||
// }) { response, exception ->
|
||||
// if (exception != null) {
|
||||
// Log.e("TAG", "askForFolder: Something went wrong")
|
||||
// } else {
|
||||
// // fai quel che ti pare
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun goToFolder(
|
||||
// parentFolder: String, forward: Boolean, isFirstRequest: Boolean = false
|
||||
// ) {
|
||||
// responsesViewer.lastResponseBody.value = null
|
||||
// val actualFolder: String
|
||||
// if (!isFirstRequest) {
|
||||
// if (forward) {
|
||||
// currentPath += "/$parentFolder"
|
||||
// actualFolder = parentFolder
|
||||
// } else {
|
||||
// currentPath = currentPath.substringBeforeLast("/")
|
||||
// actualFolder =
|
||||
// if (currentPath != "root") currentPath.substringAfterLast("/")
|
||||
// else "root"
|
||||
// }
|
||||
// } else actualFolder = parentFolder
|
||||
//
|
||||
// val myUrl = "https://www.googleapis.com/drive/v3/files?trashed=false&orderBy=folder"
|
||||
// makeNewRequest(myUrl, { builder ->
|
||||
// builder.addQueryParameter("q", "'$actualFolder' in parents")
|
||||
// }) { response, exception ->
|
||||
// if (exception != null) {
|
||||
// Log.e("ECCOLO", "${exception.cause}")
|
||||
// Log.e("ECCOLO", "${exception.message}")
|
||||
// } else {
|
||||
// Log.e("UOOOO", "$response")
|
||||
// responsesViewer.newResponseArrived(response)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun makeNewRequest(
|
||||
// url: String,
|
||||
// builderModifier: (HttpUrl.Builder) -> Unit,
|
||||
// callback: (String?, Exception?) -> Unit
|
||||
// ) {
|
||||
// val authPersistence = AuthStatePersistence
|
||||
// val authState = authPersistence.retrieveAuthState(this)
|
||||
// makeDriveApiCall(this, authState, url, builderModifier, callback)
|
||||
// authPersistence.putAuthState(this, authState)
|
||||
// }
|
||||
|
||||
// override fun onNewIntent(intent: Intent) {
|
||||
// super.onNewIntent(intent)
|
||||
// val resp = AuthorizationResponse.fromIntent(intent)
|
||||
// val ex = AuthorizationException.fromIntent(intent)
|
||||
// if (resp != null) {
|
||||
// Toast.makeText(this, "YES", Toast.LENGTH_SHORT).show()
|
||||
// } else {
|
||||
// if (ex != null) {
|
||||
// Toast.makeText(this, "NOPE ${ex.error}", Toast.LENGTH_SHORT).show()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// setContent {
|
||||
//// val navController = rememberNavController()
|
||||
//// ScaffoldWithSidebar(navController) { }
|
||||
// Greeting("bah")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
//@Composable
|
||||
|
|
|
@ -23,7 +23,7 @@ import com.bbc.denadrive.FolderTree
|
|||
|
||||
class ResponsesViewer: ViewModel() {
|
||||
|
||||
val rootFolder: MyFile = MyFile(
|
||||
private val rootFolder: MyFile = MyFile(
|
||||
kind = "drive#file",
|
||||
mimeType = "application/vnd.google-apps.folder",
|
||||
id = "root",
|
||||
|
@ -42,31 +42,26 @@ class ResponsesViewer: ViewModel() {
|
|||
updater2.value = !updater2.value
|
||||
}
|
||||
|
||||
// private var lastResponse: String = ""
|
||||
// private var isComplete: Boolean = true
|
||||
// private lateinit var respBuilder: StringBuilder
|
||||
|
||||
fun newResponseArrived(response: String?) {
|
||||
if (response == null) return
|
||||
lastResponseBody.value = ResponsesHandler.newResponseArrived<DriveResponseBody>(response)
|
||||
/*private var lastResponse: String = ""
|
||||
private var isComplete: Boolean = true
|
||||
private lateinit var respBuilder: StringBuilder
|
||||
|
||||
|
||||
private fun checkForCompleteness(): Pair<Boolean, DriveResponseBody?> {
|
||||
return try {
|
||||
Pair(true, Json.decodeFromString<DriveResponseBody>(respBuilder.toString()))
|
||||
} catch (e: SerializationException) {
|
||||
Pair(false, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// private fun checkForCompleteness(): Pair<Boolean, DriveResponseBody?> {
|
||||
// return try {
|
||||
// Pair(true, Json.decodeFromString<DriveResponseBody>(respBuilder.toString()))
|
||||
// } catch (e: SerializationException) {
|
||||
// Pair(false, null)
|
||||
// }
|
||||
// }
|
||||
|
||||
// private fun updateCompleteness() {
|
||||
// val pair = checkForCompleteness()
|
||||
// isComplete = pair.first
|
||||
// if (isComplete) {
|
||||
// lastResponse = respBuilder.toString()
|
||||
// lastResponseBody.value = pair.second
|
||||
// }
|
||||
// }
|
||||
private fun updateCompleteness() {
|
||||
val pair = checkForCompleteness()
|
||||
isComplete = pair.first
|
||||
if (isComplete) {
|
||||
lastResponse = respBuilder.toString()
|
||||
lastResponseBody.value = pair.second
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@ import android.content.Intent
|
|||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.core.content.FileProvider
|
||||
import com.bbc.denadrive.apihandlers.MyFile
|
||||
import com.bbc.denadrive.oauth.AuthStatePersistence
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -18,40 +19,33 @@ import java.net.URL
|
|||
|
||||
class FileDownloader(private val context: Context) {
|
||||
|
||||
fun downloadFile(fileUrl: String, mimeType: String) {
|
||||
fun downloadFile(file: MyFile, exported: Boolean) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val tempFile = downloadIt(fileUrl, mimeType)
|
||||
val tempFile = downloadIt(file, exported)
|
||||
withContext(Dispatchers.Main) {
|
||||
tempFile?.let {
|
||||
openFile(it)
|
||||
openFile(it, exported)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadIt(fileUrl: String, mimeType: String): File? {
|
||||
private fun downloadIt(file: MyFile, exported: Boolean): File? {
|
||||
var tempFile: File? = null
|
||||
val authState = AuthStatePersistence.retrieveAuthState(context)
|
||||
val query = if (exported) "export?mimeType=application/pdf" else "download"
|
||||
val fileUrl = "https://www.googleapis.com/drive/v3/files/${file.id}/$query"
|
||||
Log.e("SEE", fileUrl, )
|
||||
|
||||
try {
|
||||
tempFile = File.createTempFile("tempFile", ".pdf", context.cacheDir)
|
||||
// val builder = fileUrl.toHttpUrl().newBuilder()
|
||||
// builder.addQueryParameter("mimeType", mimeType)
|
||||
// val urlConnection = builder.build().toUrl().openConnection() as HttpURLConnection
|
||||
val urlConnection = URL("$fileUrl?mimeType=application/pdf").openConnection() as HttpURLConnection
|
||||
tempFile =
|
||||
File.createTempFile(file.name, if (exported) ".pdf" else "", context.cacheDir)
|
||||
val urlConnection = URL(fileUrl).openConnection() as HttpURLConnection
|
||||
urlConnection.setRequestProperty("Authorization", "Bearer ${authState.accessToken}")
|
||||
urlConnection.connect()
|
||||
|
||||
// val inputStream1 = urlConnection.inputStream
|
||||
// val buffer1 = ByteArray(4)
|
||||
// inputStream1.read(buffer1)
|
||||
// val header = String(buffer1)
|
||||
// if (!header.startsWith("%PDF")) {
|
||||
// Log.e("FileDownloader", "Downloaded file is not a valid PDF")
|
||||
// }
|
||||
|
||||
if (urlConnection.responseCode == HttpURLConnection.HTTP_OK) {
|
||||
Log.e("MA", "downloadIt: andato", )
|
||||
val inputStream = urlConnection.inputStream
|
||||
val outputStream = FileOutputStream(tempFile)
|
||||
|
||||
|
@ -65,7 +59,10 @@ class FileDownloader(private val context: Context) {
|
|||
inputStream.close()
|
||||
urlConnection.disconnect()
|
||||
} else {
|
||||
Log.e("FileDownloader", "Error: ${urlConnection.responseCode} - ${urlConnection.responseMessage}")
|
||||
Log.e(
|
||||
"FileDownloader",
|
||||
"Error: ${urlConnection.responseCode} - ${urlConnection.responseMessage}"
|
||||
)
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
|
@ -76,10 +73,12 @@ class FileDownloader(private val context: Context) {
|
|||
}
|
||||
|
||||
|
||||
private fun openFile(file: File) {
|
||||
val uri: Uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
|
||||
private fun openFile(file: File, exported: Boolean) {
|
||||
val uri: Uri =
|
||||
FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)
|
||||
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||||
setDataAndType(uri, "application/pdf")
|
||||
if (exported) setDataAndType(uri, "application/pdf")
|
||||
else setData(uri)
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
|
|
|
@ -41,6 +41,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
@ -182,7 +184,7 @@ fun MyListVisualizer(
|
|||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.TopCenter) {
|
||||
LazyColumn {
|
||||
items(fileList) { file ->
|
||||
val logo = painterResource(id = getId(file.mimeType))
|
||||
val logo = painterResource(id = getLogoId(file.mimeType))
|
||||
val isFolder = file.mimeType.endsWith("folder")
|
||||
val onClick = if (isFolder) onFolderClick
|
||||
else onFileClick
|
||||
|
@ -252,7 +254,7 @@ fun AnotherVisualizer(
|
|||
val updater1 = responsesViewer.updater1.value
|
||||
val updater2 = responsesViewer.updater2.value
|
||||
if (currentFolderTree.isLeaf() && (updater1 || updater2)) {
|
||||
Log.e("Visualizer", "AnotherVisualizer: ${currentFolderTree.value}", )
|
||||
Log.e("Visualizer", "AnotherVisualizer: ${currentFolderTree.value}")
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Text(text = "How did you get here? You're inside a file...")
|
||||
}
|
||||
|
@ -263,29 +265,49 @@ fun AnotherVisualizer(
|
|||
} else if (currentFolderTree.getChildren().isEmpty()) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Text("Empty folder")
|
||||
// Loading()
|
||||
}
|
||||
} else {
|
||||
val state = rememberLazyListState()
|
||||
val fileList = currentFolderTree.getChildren().map { tree -> tree.value }
|
||||
// Log.e("Visualizer", "AnotherVisualizer: ${currentFolderTree.value}", )
|
||||
// Log.e("Visualizer", "AnotherVisualizer: ${currentFolderTree.getChildren()}", )
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.TopCenter) {
|
||||
LazyColumn {
|
||||
items(fileList) { file ->
|
||||
val logo = painterResource(id = getId(file.mimeType))
|
||||
LazyColumn (
|
||||
state = state
|
||||
) {
|
||||
itemsIndexed(fileList) { index, file ->
|
||||
val logo = painterResource(id = getLogoId(file.mimeType))
|
||||
val isFolder = file.mimeType.endsWith("folder")
|
||||
val onClick = if (isFolder) onFolderClick
|
||||
else onFileClick
|
||||
LogoTextBox(logo, file.name) {
|
||||
onClick(file)
|
||||
|
||||
var mod = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(color = MaterialTheme.colorScheme.onBackground)
|
||||
// .padding(horizontal = 1.dp)
|
||||
|
||||
mod = if (index == 0) {
|
||||
mod.padding(vertical = 1.dp)
|
||||
} else {
|
||||
mod.padding(bottom = 1.dp)
|
||||
}
|
||||
|
||||
mod = mod
|
||||
.background(color = MaterialTheme.colorScheme.background)
|
||||
.clickable {
|
||||
onClick(file)
|
||||
}
|
||||
|
||||
FileVisualizer(
|
||||
logo,
|
||||
file.name,
|
||||
mod
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getId(mimeType: String): Int {
|
||||
fun getLogoId(mimeType: String): Int {
|
||||
val extracted = mimeType.substringAfterLast(".")
|
||||
return when (extracted) {
|
||||
"document" -> R.drawable.docslogo_ok
|
||||
|
@ -295,6 +317,24 @@ fun getId(mimeType: String): Int {
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FileVisualizer(
|
||||
logoPainter: Painter,
|
||||
text: String,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = modifier
|
||||
) {
|
||||
Image(
|
||||
painter = logoPainter,
|
||||
contentDescription = "Item logo"
|
||||
)
|
||||
Text(text = text, style = MaterialTheme.typography.titleLarge)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LogoTextBox(
|
||||
logoPainter: Painter,
|
||||
|
@ -335,3 +375,4 @@ fun LogoTextBox(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class LoadingActivity : ComponentActivity() {
|
|||
setContent {
|
||||
DeNaDriveTheme {
|
||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||
LoadingScreen(modifier = Modifier.padding(innerPadding))
|
||||
LoadingScreen(text = "Loading...", modifier = Modifier.padding(innerPadding))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ class LoadingActivity : ComponentActivity() {
|
|||
|
||||
@Composable
|
||||
fun LoadingScreen(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
// State to control the rotation animation
|
||||
|
|
Loading…
Add table
Reference in a new issue