| 1 |
package io.oxygenhub.android.ui.nav |
| 2 |
|
| 3 |
import java.net.URI |
| 4 |
|
| 5 |
/** |
| 6 |
* The app's own screen for a page of the hub (Andy, 2026-10-25: whatever |
| 7 |
* is tapped in the inbox opens natively): an issue, proposal, run, change, |
| 8 |
* file, history, board or repository. Null for a page the app does not |
| 9 |
* show itself, or another site's, which the browser opens. |
| 10 |
*/ |
| 11 |
fun routeFor(url: String, hub: String): Any? { |
| 12 |
val u = runCatching { URI(url) }.getOrNull() ?: return null |
| 13 |
val home = runCatching { URI(hub) }.getOrNull() ?: return null |
| 14 |
if (u.host != null && !u.host.equals(home.host, ignoreCase = true)) return null |
| 15 |
val parts = (u.rawPath ?: "").split('/').filter { it.isNotEmpty() }.map { java.net.URLDecoder.decode(it, "UTF-8") } |
| 16 |
if (parts.size >= 3 && parts[0] == "projects") { |
| 17 |
return parts[2].toLongOrNull()?.let { BoardRoute(parts[1], it) } |
| 18 |
} |
| 19 |
if (parts.size < 2 || parts[0] in HUB_PAGES) return null |
| 20 |
val (owner, name) = parts[0] to parts[1] |
| 21 |
val rest = parts.drop(2) |
| 22 |
return when (rest.firstOrNull()) { |
| 23 |
null -> IssuesRoute(owner, name) |
| 24 |
"issue" -> rest.getOrNull(1)?.toLongOrNull()?.let { IssueRoute(owner, name, it) } |
| 25 |
"proposal" -> rest.getOrNull(1)?.toLongOrNull()?.let { ProposalRoute(owner, name, it) } |
| 26 |
"flow" -> rest.getOrNull(1)?.toLongOrNull()?.let { RunRoute(owner, name, it) } |
| 27 |
"change" -> rest.getOrNull(1)?.let { ChangeRoute(owner, name, it) } |
| 28 |
"file" -> if (rest.size >= 3) FileRoute(owner, name, rest[1], rest.drop(2).joinToString("/")) else null |
| 29 |
"changes" -> rest.getOrNull(1)?.let { HistoryRoute(owner, name, it) } |
| 30 |
else -> null |
| 31 |
} |
| 32 |
} |
| 33 |
|
| 34 |
/** The hub's own top-level pages: never an owner's name. */ |
| 35 |
private val HUB_PAGES = setOf( |
| 36 |
"about", "admin", "api", "apt", "avatar", "device", "drops", "explore", "health", "help", "insights", "live", "log", |
| 37 |
"login", "logout", "metrics", "new", "notifications", "orgs", "register", "search", "security-contact", "settings", |
| 38 |
"sky", "static", "verify", ".well-known", |
| 39 |
) |