KevinnZou / compose-webview-multiplatform

WebView for JetBrains Compose Multiplatform
https://kevinnzou.github.io/compose-webview-multiplatform/
Apache License 2.0
305 stars 39 forks source link

关于WebViewState的设计问题 #143

Open lov3blacksilk opened 3 weeks ago

lov3blacksilk commented 3 weeks ago

WebViewState属于状态持有容器,类似于viewModel的职能, 内部的变量我觉得最好用flow来承载,而不是使用compose体系里mutableStateOf来承载 例如:

class WebViewState(webContent: WebContent) {

    /**
     *  The content being loaded by the WebView
     */
    var content: WebContent by mutableStateOf(webContent)

    /**
     * The last loaded url. This is updated when a new page is loaded.
     */
    private val _lastLoadedUrl = MutableStateFlow("")
    val lastLoadedUrl = _lastLoadedUrl.asStateFlow()
    fun updateLoadedUrl(url: String?) {
        _lastLoadedUrl.value = url ?: ""
    }

    /**
     * Whether the WebView is currently [LoadingState.Loading] data in its main frame (along with
     * progress) or the data loading has [LoadingState.Finished]. See [LoadingState]
     */
    private val _loadingState: MutableStateFlow<LoadingState> = MutableStateFlow(LoadingState.Initializing)
    val loadingState = _loadingState.asStateFlow()
    fun updateLoadingState(state: LoadingState) {
        _loadingState.value = state
    }

    /**
     * Whether the webview is currently loading data in its main frame
     */
    val isLoading: Boolean
        get() = loadingState.value !is LoadingState.Finished

    /**
     * The title received from the loaded content of the current page
     */
    private val _pageTitle = MutableStateFlow("")
    val pageTitle = _pageTitle.asStateFlow()
    fun updatePageTitle(title: String?) {
        _pageTitle.value = title ?: ""
    }

    private val _pagIcon = MutableStateFlow<Bitmap?>(null)
    val pageIcon = _pagIcon.asStateFlow()
    fun updatePageIcon(icon: Bitmap?) {
        _pagIcon.value = icon
    }

    private val _capture: MutableStateFlow<() -> Bitmap?> = MutableStateFlow { null }
    val capture = _capture.asStateFlow()

    fun doCapture(capture: () -> Bitmap?) {
        _capture.value = capture
    }

    /**
     * A list for errors captured in the last load. Reset when a new page is loaded.
     * Errors could be from any resource (iframe, image, etc.), not just for the main page.
     * For more fine grained control use the OnError callback of the WebView.
     */
    val errorsForCurrentRequest: SnapshotStateList<WebViewError> = mutableStateListOf()

    /**
     * Custom Settings for WebView.
     */
    private val _webSettings = MutableStateFlow(WebSettings())
    val webSettings = _webSettings.asStateFlow()
    fun updateWebSettings(settings: WebSettings) {
        _webSettings.value = settings
    }

    // We need access to this in the state saver. An internal DisposableEffect or AndroidView
    // onDestroy is called after the state saver and so can't be used.
    internal var webView by mutableStateOf<IWebView?>(null)
}

我针对这部分逻辑做了部分修改