feat: Add file sharing support and collections configuration management
- Add intent filters for markdown and text file sharing (text/*, application/octet-stream) - Implement file content reading with filename extraction and automatic tagging - Enable edge-to-edge mode with proper IME insets handling for keyboard - Add collections configuration dirty flag and bookmark ID tracking to TokenManager - Create CollectionsConfigDto and CollectionConfigDto for JSON serialization - Add collection query methods
This commit is contained in:
@@ -16,9 +16,21 @@ import java.net.URLEncoder
|
||||
|
||||
sealed class Screen(val route: String) {
|
||||
object Login : Screen("login")
|
||||
object Feed : Screen("feed?tag={tag}") {
|
||||
fun createRoute(tag: String? = null): String {
|
||||
return if (tag != null) "feed?tag=$tag" else "feed"
|
||||
object Feed : Screen("feed?tag={tag}&collectionId={collectionId}") {
|
||||
fun createRoute(tag: String? = null, collectionId: Long? = null): String {
|
||||
val params = mutableListOf<String>()
|
||||
if (tag != null) {
|
||||
val encoded = URLEncoder.encode(tag, "UTF-8")
|
||||
params.add("tag=$encoded")
|
||||
}
|
||||
if (collectionId != null) {
|
||||
params.add("collectionId=$collectionId")
|
||||
}
|
||||
return if (params.isEmpty()) {
|
||||
"feed"
|
||||
} else {
|
||||
"feed?" + params.joinToString("&")
|
||||
}
|
||||
}
|
||||
}
|
||||
object Add : Screen("add?url={url}&title={title}&isShare={isShare}")
|
||||
@@ -36,6 +48,9 @@ fun AppNavGraph(
|
||||
startDestination: String = Screen.Login.route,
|
||||
shareUrl: String? = null,
|
||||
shareTitle: String? = null,
|
||||
shareDescription: String? = null,
|
||||
shareTags: List<String>? = null,
|
||||
isFileShare: Boolean = false,
|
||||
initialDeepLink: String? = null
|
||||
) {
|
||||
val navController = rememberNavController()
|
||||
@@ -45,14 +60,22 @@ fun AppNavGraph(
|
||||
composable(Screen.Login.route) {
|
||||
com.shaarit.presentation.auth.LoginScreen(
|
||||
onLoginSuccess = {
|
||||
if (shareUrl != null) {
|
||||
if (isFileShare && shareTitle != null) {
|
||||
// File share - navigate to add screen with file data
|
||||
val encodedTitle = URLEncoder.encode(shareTitle, "UTF-8")
|
||||
val encodedDesc = if (shareDescription != null) URLEncoder.encode(shareDescription, "UTF-8") else ""
|
||||
val encodedTags = shareTags?.joinToString(",") { URLEncoder.encode(it, "UTF-8") } ?: ""
|
||||
navController.navigate("add?url=&title=$encodedTitle&isShare=true&isFileShare=true&description=$encodedDesc&tags=$encodedTags") {
|
||||
popUpTo(Screen.Login.route) { inclusive = true }
|
||||
}
|
||||
} else if (shareUrl != null) {
|
||||
// Use proper URL encoding that handles spaces correctly
|
||||
val encodedUrl = URLEncoder.encode(shareUrl, "UTF-8")
|
||||
val encodedTitle =
|
||||
if (shareTitle != null) {
|
||||
URLEncoder.encode(shareTitle, "UTF-8")
|
||||
} else ""
|
||||
navController.navigate("add?url=$encodedUrl&title=$encodedTitle&isShare=true") {
|
||||
navController.navigate("add?url=$encodedUrl&title=$encodedTitle&isShare=true&isFileShare=false&description=&tags=") {
|
||||
popUpTo(Screen.Login.route) { inclusive = true }
|
||||
}
|
||||
} else if (initialDeepLink != null) {
|
||||
@@ -70,12 +93,16 @@ fun AppNavGraph(
|
||||
}
|
||||
|
||||
composable(
|
||||
route = "feed?tag={tag}",
|
||||
route = "feed?tag={tag}&collectionId={collectionId}",
|
||||
arguments = listOf(
|
||||
navArgument("tag") {
|
||||
type = NavType.StringType
|
||||
nullable = true
|
||||
defaultValue = null
|
||||
},
|
||||
navArgument("collectionId") {
|
||||
type = NavType.LongType
|
||||
defaultValue = -1L
|
||||
}
|
||||
),
|
||||
deepLinks = listOf(
|
||||
@@ -84,6 +111,9 @@ fun AppNavGraph(
|
||||
)
|
||||
) { backStackEntry ->
|
||||
val tag = backStackEntry.arguments?.getString("tag")
|
||||
val collectionId = backStackEntry.arguments
|
||||
?.getLong("collectionId")
|
||||
?.takeIf { it != -1L }
|
||||
com.shaarit.presentation.feed.FeedScreen(
|
||||
onNavigateToAdd = { navController.navigate("add?url=&title=&isShare=false") },
|
||||
onNavigateToEdit = { linkId ->
|
||||
@@ -93,12 +123,13 @@ fun AppNavGraph(
|
||||
onNavigateToCollections = { navController.navigate(Screen.Collections.route) },
|
||||
onNavigateToSettings = { navController.navigate(Screen.Settings.route) },
|
||||
onNavigateToRandom = { },
|
||||
initialTagFilter = tag
|
||||
initialTagFilter = tag,
|
||||
initialCollectionId = collectionId
|
||||
)
|
||||
}
|
||||
|
||||
composable(
|
||||
route = "add?url={url}&title={title}&isShare={isShare}",
|
||||
route = "add?url={url}&title={title}&isShare={isShare}&isFileShare={isFileShare}&description={description}&tags={tags}",
|
||||
arguments = listOf(
|
||||
navArgument("url") {
|
||||
type = NavType.StringType
|
||||
@@ -113,6 +144,20 @@ fun AppNavGraph(
|
||||
navArgument("isShare") {
|
||||
type = NavType.BoolType
|
||||
defaultValue = false
|
||||
},
|
||||
navArgument("isFileShare") {
|
||||
type = NavType.BoolType
|
||||
defaultValue = false
|
||||
},
|
||||
navArgument("description") {
|
||||
type = NavType.StringType
|
||||
defaultValue = ""
|
||||
nullable = true
|
||||
},
|
||||
navArgument("tags") {
|
||||
type = NavType.StringType
|
||||
defaultValue = ""
|
||||
nullable = true
|
||||
}
|
||||
),
|
||||
deepLinks = listOf(
|
||||
@@ -165,9 +210,14 @@ fun AppNavGraph(
|
||||
) {
|
||||
com.shaarit.presentation.collections.CollectionsScreen(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onCollectionClick = { collectionId ->
|
||||
// Naviguer vers le feed avec le filtre de collection
|
||||
navController.navigate(Screen.Feed.createRoute()) {
|
||||
onCollectionClick = { collectionId, isSmart, query ->
|
||||
navController.navigate(
|
||||
if (isSmart) {
|
||||
Screen.Feed.createRoute(tag = query)
|
||||
} else {
|
||||
Screen.Feed.createRoute(collectionId = collectionId)
|
||||
}
|
||||
) {
|
||||
popUpTo(Screen.Collections.route) { inclusive = true }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user