feat: Compose 浏览器跳转 App

This commit is contained in:
HuanCheng65 2024-01-30 15:02:08 +08:00
parent 0c5c11a88d
commit 28a4e379a7
No known key found for this signature in database
GPG Key ID: 5EC9DD60A32C7360
2 changed files with 77 additions and 43 deletions

View File

@ -170,6 +170,17 @@
<data android:scheme="tblite" /> <data android:scheme="tblite" />
</intent-filter> </intent-filter>
<intent-filter android:autoVerify="true">
<data
android:host="unidispatch"
android:scheme="com.baidu.tieba" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<meta-data <meta-data
android:name="android.app.shortcuts" android:name="android.app.shortcuts"
android:resource="@xml/shortcut_new" /> android:resource="@xml/shortcut_new" />
@ -269,42 +280,7 @@
android:windowSoftInputMode="adjustResize" /> android:windowSoftInputMode="adjustResize" />
<activity <activity
android:name=".activities.DispatchActivity" android:name=".activities.DispatchActivity"
android:exported="true"> android:exported="true" />
<intent-filter android:autoVerify="true">
<data
android:host="tieba.baidu.com"
android:scheme="tbfrs" />
<data
android:host="tieba.baidu.com"
android:scheme="tbpb" />
<data
android:host="tieba.baidu.com"
android:scheme="http" />
<data
android:host="tieba.baidu.com"
android:scheme="https" />
<data
android:host="unidispatch"
android:scheme="com.baidu.tieba" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<intent-filter>
<data
android:host="tieba.baidu.com"
android:scheme="http" />
<data
android:host="tieba.baidu.com"
android:scheme="https" />
<action android:name="com.huanchengfly.tieba.post.ACTION_JUMP" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity <activity
android:name=".activities.PreferencesActivity" android:name=".activities.PreferencesActivity"
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden" android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize|keyboardHidden"

View File

@ -80,6 +80,8 @@ import com.huanchengfly.tieba.post.components.ClipBoardThreadLink
import com.huanchengfly.tieba.post.services.NotifyJobService import com.huanchengfly.tieba.post.services.NotifyJobService
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
import com.huanchengfly.tieba.post.ui.page.NavGraphs import com.huanchengfly.tieba.post.ui.page.NavGraphs
import com.huanchengfly.tieba.post.ui.page.destinations.ForumPageDestination
import com.huanchengfly.tieba.post.ui.page.destinations.ThreadPageDestination
import com.huanchengfly.tieba.post.ui.utils.DevicePosture import com.huanchengfly.tieba.post.ui.utils.DevicePosture
import com.huanchengfly.tieba.post.ui.utils.isBookPosture import com.huanchengfly.tieba.post.ui.utils.isBookPosture
import com.huanchengfly.tieba.post.ui.utils.isSeparating import com.huanchengfly.tieba.post.ui.utils.isSeparating
@ -111,8 +113,11 @@ import com.microsoft.appcenter.analytics.Analytics
import com.ramcosta.composedestinations.DestinationsNavHost import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations
import com.ramcosta.composedestinations.animations.rememberAnimatedNavHostEngine import com.ramcosta.composedestinations.animations.rememberAnimatedNavHostEngine
import com.ramcosta.composedestinations.navigation.navigate
import com.ramcosta.composedestinations.spec.DestinationSpec import com.ramcosta.composedestinations.spec.DestinationSpec
import com.ramcosta.composedestinations.spec.Direction
import com.ramcosta.composedestinations.utils.currentDestinationAsState import com.ramcosta.composedestinations.utils.currentDestinationAsState
import com.ramcosta.composedestinations.utils.currentDestinationFlow
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
@ -125,7 +130,9 @@ import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.concurrent.atomic.AtomicBoolean
val LocalNotificationCountFlow = val LocalNotificationCountFlow =
staticCompositionLocalOf<Flow<Int>> { throw IllegalStateException("not allowed here!") } staticCompositionLocalOf<Flow<Int>> { throw IllegalStateException("not allowed here!") }
@ -194,12 +201,61 @@ class MainActivityV2 : BaseComposeActivity() {
) )
} }
private var myNavCollector: NavHostController? = null private var direction: Direction? = null
private var waitingNavCollectorToNavigate = AtomicBoolean(false)
private var myNavController: NavHostController? = null
set(value) {
field = value
if (value != null && waitingNavCollectorToNavigate.get() && direction != null) {
launch {
value.currentDestinationFlow
.take(1)
.collect {
if (waitingNavCollectorToNavigate.get() && direction != null) {
value.navigate(direction!!)
waitingNavCollectorToNavigate.set(false)
direction = null
}
}
}
}
}
private fun navigate(direction: Direction) {
if (myNavController == null) {
waitingNavCollectorToNavigate.set(true)
this.direction = direction
} else {
myNavController?.navigate(direction)
}
}
private fun checkIntent(intent: Intent): Boolean {
return if (intent.data?.scheme == "com.baidu.tieba" && intent.data?.host == "unidispatch") {
val uri = intent.data!!
when (uri.path.orEmpty().lowercase()) {
"/frs" -> {
val forumName = uri.getQueryParameter("kw") ?: return true
navigate(ForumPageDestination(forumName))
}
"/pb" -> {
val threadId = uri.getQueryParameter("tid")?.toLongOrNull() ?: return true
navigate(ThreadPageDestination(threadId))
}
}
true
} else {
false
}
}
override fun onNewIntent(intent: Intent?) { override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent) super.onNewIntent(intent)
intent?.let { intent?.let {
myNavCollector?.handleDeepLink(it) if (!checkIntent(it)) {
myNavController?.handleDeepLink(it)
}
} }
} }
@ -265,6 +321,7 @@ class MainActivityV2 : BaseComposeActivity() {
launch { launch {
ClientUtils.setActiveTimestamp() ClientUtils.setActiveTimestamp()
} }
intent?.let { checkIntent(it) }
} }
override fun onCreateContent(systemUiController: SystemUiController) { override fun onCreateContent(systemUiController: SystemUiController) {
@ -276,11 +333,11 @@ class MainActivityV2 : BaseComposeActivity() {
private fun openClipBoardLink(link: ClipBoardLink) { private fun openClipBoardLink(link: ClipBoardLink) {
when (link) { when (link) {
is ClipBoardThreadLink -> { is ClipBoardThreadLink -> {
myNavCollector?.navigate(Uri.parse("tblite://thread/${link.threadId}")) myNavController?.navigate(Uri.parse("tblite://thread/${link.threadId}"))
} }
is ClipBoardForumLink -> { is ClipBoardForumLink -> {
myNavCollector?.navigate(Uri.parse("tblite://forum/${link.forumName}")) myNavController?.navigate(Uri.parse("tblite://forum/${link.forumName}"))
} }
else -> { else -> {
@ -409,9 +466,6 @@ class MainActivityV2 : BaseComposeActivity() {
TiebaLiteLocalProvider { TiebaLiteLocalProvider {
TranslucentThemeBackground { TranslucentThemeBackground {
val navController = rememberNavController() val navController = rememberNavController()
SideEffect {
myNavCollector = navController
}
val engine = TiebaNavHostDefaults.rememberNavHostEngine() val engine = TiebaNavHostDefaults.rememberNavHostEngine()
val navigator = TiebaNavHostDefaults.rememberBottomSheetNavigator() val navigator = TiebaNavHostDefaults.rememberBottomSheetNavigator()
val currentDestination by navController.currentDestinationAsState() val currentDestination by navController.currentDestinationAsState()
@ -447,6 +501,10 @@ class MainActivityV2 : BaseComposeActivity() {
) )
} }
} }
SideEffect {
myNavController = navController
}
} }
} }
} }