Mobile Apps 2023W Lecture 22

From Soma-notes

Code

package carleton.comp2601.webviewcompose

import android.os.Bundle
import android.util.Log
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.viewinterop.AndroidView

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            // Calling the composable function
            // to display element and its contents
            MainContent()
        }
    }
}

// Creating a composable
// function to display Top Bar
@Composable
fun MainContent() {
    var curURL by remember { mutableStateOf("https://news.ycombinator.com") }
    var history = mutableListOf<String>("https://news.ycombinator.com")
    var curURLIndex = 0

    fun updateURL(newURL: String) {
        curURLIndex += 1
        history.add(curURLIndex, newURL)
        val lastIndex = history.lastIndex
        if (lastIndex > curURLIndex) {
            for (i in curURLIndex + 1..lastIndex) {
                history.removeAt(i)
            }
        }
        curURL = newURL
        Log.d("webviewCompose", "updating URL to $curURL")
    }

    fun prevURL() {
        curURLIndex -= 1
        if (curURLIndex < 0) {
            curURLIndex = 0
        }
        curURL = history[curURLIndex]
        Log.d("webviewCompose", "going to previous URL $curURL")
    }

    fun nextURL() {
        curURLIndex += 1
        if (curURLIndex > history.lastIndex) {
            curURLIndex = history.lastIndex
        }
        curURL = history[curURLIndex]
        Log.d("webviewCompose", "going to next URL $curURL")
    }

    Scaffold(
//        topBar = { TopAppBar(title = {Text("COMP 2601")})},
        topBar = {
            Row {
                ClickableText(
                    AnnotatedString(text = "Back"),
                    onClick = {
                        prevURL()
                    }
                )
                ClickableText(
                    AnnotatedString(text = "Forward"),
                    onClick = {
                        nextURL()
                    }
                )
                URLBar(curURL = curURL, updateURL = ::updateURL)
            }
        },
        content = { MyContent(curURL = curURL, updateURL = ::updateURL) }
    )
}

@Composable
fun URLBar(curURL: String, updateURL: (String) -> Unit) {
    var newURL = ""

    TextField(
        value = curURL,
        //onFocusChange = { updateURL(newURL) },
        //onValueChange = { updatedURL: String -> newURL = updatedURL},
        onValueChange = updateURL,
        label = { Text("Enter URL here") }
    )
}

@Composable
fun MyContent(curURL: String, updateURL: (String) -> Unit) {

    class ObservableWebViewClient : WebViewClient() {

        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest): Boolean {
            val url = request.url

            if (!request.isRedirect) {
                updateURL(url.toString())
            }
            return false
        }
    }

    fun logWebViewHistory(view: WebView) {
        val history = view.copyBackForwardList()

        val current = history.currentIndex

        Log.d("webviewCompose", "Current history item: $current")

        Log.d("webviewCompose", "Webview BackForwardList contents:")

        for (i in 0..history.size -1) {
            val item = history.getItemAtIndex(i)

            if (item != null) {
                val u = item.originalUrl
                Log.d("webviewCompose", "  $i: $u")
            }
        }
    }

    // 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 = ObservableWebViewClient()
            loadUrl(curURL)
        }
    }, update = {
        Log.d("webviewCompose", "loading URL $curURL")
        it.loadUrl(curURL)
        //logWebViewHistory(it)
    })
}

// For displaying preview in
// the Android Studio IDE emulator
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    MainContent()
}