feat: paginate, sync, and display branched sessions (#563)
* mobile: 以 Desktop Sessions 作为聊天历史源 * mobile: 修复快速连接崩溃与无标题会话隐藏 * mobile: 对齐 Desktop 标题并恢复完整历史 * mobile: 分离 Desktop 存储 ID 与运行 Session ID * mobile: 将新对话持久化为 Desktop Session * mobile: 渲染 Desktop 本地媒体 * feat: 分页加载并同步当前会话 * fix: 显示分支会话名称与层级 * fix: align PR with upstream app contract * fix: preserve upstream session RPC lifecycle
This commit is contained in:
1 parent
306861a222
commit
3052db7d65
8 files changed
+405
-79
No files matched your search
@@ -19,6 +19,8 @@ data class SessionInfo(
|
||||
val preview: String? = null,
|
||||
val started_at: Double? = null,
|
||||
val source: String? = null,
|
||||
val parent_session_id: String? = null,
|
||||
val display_name: String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.m57.hermescontrol.data.model
|
||||
|
||||
data class SessionTreeItem(
|
||||
val session: SessionInfo,
|
||||
val depth: Int,
|
||||
val branchStem: String?,
|
||||
val displayTitle: String,
|
||||
)
|
||||
|
||||
fun flattenSessionTree(sessions: List<SessionInfo>): List<SessionTreeItem> {
|
||||
val ids = sessions.mapTo(mutableSetOf()) { it.id }
|
||||
val children = sessions.groupBy { it.parent_session_id?.takeIf(ids::contains) }
|
||||
val result = mutableListOf<SessionTreeItem>()
|
||||
val visited = mutableSetOf<String>()
|
||||
|
||||
fun append(
|
||||
session: SessionInfo,
|
||||
depth: Int,
|
||||
branchStem: String?,
|
||||
siblingIndex: Int,
|
||||
) {
|
||||
if (!visited.add(session.id)) return
|
||||
val isBranch = session.parent_session_id?.takeIf(ids::contains) != null
|
||||
val title =
|
||||
session.title?.takeIf(String::isNotBlank)
|
||||
?: session.display_name?.takeIf(String::isNotBlank)
|
||||
?: if (isBranch) {
|
||||
"branch ${siblingIndex + 1}"
|
||||
} else {
|
||||
session.preview?.takeIf(String::isNotBlank)?.take(80) ?: "Untitled"
|
||||
}
|
||||
result += SessionTreeItem(session, depth, branchStem, title)
|
||||
val descendants = children[session.id].orEmpty()
|
||||
descendants.forEachIndexed { index, child ->
|
||||
append(
|
||||
session = child,
|
||||
depth = depth + 1,
|
||||
branchStem = if (index == descendants.lastIndex) "└─" else "├─",
|
||||
siblingIndex = index,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
children[null].orEmpty().forEachIndexed { index, root ->
|
||||
append(root, depth = 0, branchStem = null, siblingIndex = index)
|
||||
}
|
||||
sessions.filterNot { it.id in visited }.forEachIndexed { index, orphan ->
|
||||
append(orphan, depth = 0, branchStem = null, siblingIndex = index)
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in new issue
Block a user