How can I intercept the back and forward navigatio...
# webassembly
o
How can I intercept the back and forward navigation events?
t
In browser?
k
o
So I have found this solution for a while now.
Copy code
external interface JsPageState {
    val id: String
}

class Navigator(private val defaultPage:String = "") {
    private val currentPage = mutableStateOf(defaultPage)
    private val pageHistory = mutableMapOf<String, Any?>()
    private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
    
    init {
        
        // Set up listener for browser back/forward buttons
        
        window.addEventListener("popstate") {
            try {
                val state = window.history.state
                val pageId = if (state != null) {
                    (state as JsPageState).id
                } else {
                    val hash = window.location.hash
                    if (hash.isNotEmpty()) hash.removePrefix("#") else defaultPage
                }
                
                currentPage.value = pageId
            } catch (e: Throwable) {
                currentPage.value = defaultPage
            }
        }
        
    }

    fun getCurrentPage(): String {
        return currentPage.value
    }
    
    fun getCurrentPageState(): MutableState<String> {
        return currentPage
    }
    
    fun navigate(pageId: String, pageData: Any? = null, updateHistory: Boolean = true) {
        scope.launch {
            
            try{// Store any associated data
                
                pageHistory[pageId] = pageData
                
                // Convert pageId to JS value before passing to history API
                val jsPageId = createJsState(pageId)
                
                
                // Update browser history if requested
                if (updateHistory) {
                    // Add new entry to history with hashtag
                    window.history.pushState(jsPageId, "", "#$pageId")
                } else {
                    // Replace current history entry with new pageId
                    window.history.replaceState(jsPageId, "", "#$pageId")
                }
                
                // Update current page state
                withContext(Dispatchers.Main){
                    currentPage.value = pageId
                }
                
            }catch (e:Exception){
                e.printStackTrace()
            }
        }
        
    }
    
    fun getPageData(pageId: String): Any? {
        return pageHistory[pageId]
    }
}
can navigate by calling navigator.navigate(pageId = "home") etc depending on your setup
example setup
Copy code
object Pages {
    const val HOME = "home"
    const val ACCOUNT = "account"
    const val SIGNIN = "signin"
    const val SIGNUP = "signup"
    const val DETAIL = "detail"
    const val DASHBOARD = "dashboard"
}

val currentPage by navigator.getCurrentPageState()
when (currentPage) {
    Pages.HOME -> {
        
        SimpleAnimator(
            modifier = Modifier.matchParentSize(),
                       style = AnimationStyle.LEFT,
                       isVisible = currentPage == Pages.HOME
        ) {
            Home(modifier = Modifier.matchParentSize())
        }
        
    }
   
    Pages.DETAIL -> {
        SimpleAnimator(
            modifier = Modifier.matchParentSize(),
                       style = AnimationStyle.RIGHT,
                       isVisible = currentPage == Pages.DETAIL
        ) {
            Detail(modifier = Modifier.matchParentSize())
        }
    }
    Pages.DASHBOARD-> {
        SimpleAnimator(
            modifier = Modifier.matchParentSize(),
                       style = AnimationStyle.RIGHT,
                       isVisible = currentPage == Pages.DASHBOARD
        ) {
            Dashboard(modifier = Modifier.matchParentSize())
        }
    }
    Pages.SIGNIN -> {
        SimpleAnimator(
            modifier = Modifier.matchParentSize(),
                       style = AnimationStyle.RIGHT,
                       isVisible = currentPage == Pages.SIGNIN
        ) {
            Signin(modifier = Modifier.matchParentSize())
        }
    }
}
👍 1