Commit e570075041d2670c4ac3d0ff990f8962d35c2eaa

Authored by yibo
1 parent adc79e54

refactor(lifelog): 录音/时间轴/声纹/纪要 四 tab 合并到「录音」菜单

删掉底部「纪要」菜单,把它的声纹/纪要两个子页并入「录音」。
录音菜单顶部子 tab 从 2 个(录音/时间轴)扩到 4 个(录音/时间轴/声纹/纪要)。
底部导航 6→5:人物/录音/对话/相册/设置。
跨子页联动保留:声纹点人→时间轴按 TA 筛选;纪要点时间戳→跳时间轴对应段。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lifelog-recorder/app/src/main/kotlin/com/lemon/lifelog/MainActivity.kt
... ... @@ -121,9 +121,8 @@ class MainActivity : ComponentActivity() {
121 121  
122 122 private enum class Tab(val label: String, val icon: String) {
123 123 People("人物", "👤"), // 通讯录 + 联系人档案(CRM 核心,放第一位)
124   - Recording("录音", "⏺"), // 顶部子页:录音 / 时间轴
  124 + Recording("录音", "⏺"), // 顶部子页:录音 / 时间轴 / 声纹 / 纪要
125 125 Chat("对话", "💬"),
126   - Memo("纪要", "✎"), // 顶部子页:声纹 / 纪要
127 126 Album("相册", "🖼"),
128 127 Settings("设置", "⚙"),
129 128 }
... ... @@ -151,9 +150,8 @@ private fun MainScreen() {
151 150 var filterSpeakerId by remember { mutableStateOf<Long?>(null) }
152 151 // Cross-tab jump: a summary bullet sets an absolute timestamp to scroll the timeline to.
153 152 var jumpToTs by remember { mutableStateOf<Long?>(null) }
154   - // 合并页的顶部子 tab:录音页 0=录音 1=时间轴;纪要页 0=声纹 1=纪要。
  153 + // 录音页顶部子 tab:0=录音 1=时间轴 2=声纹 3=纪要(声纹/纪要原是「纪要」菜单,已并入此处)。
155 154 var recordingSub by remember { mutableStateOf(0) }
156   - var memoSub by remember { mutableStateOf(0) }
157 155  
158 156 val speakers by repo.speakers.observeAll().collectAsState(initial = emptyList())
159 157  
... ... @@ -181,14 +179,9 @@ private fun MainScreen() {
181 179 sub = recordingSub, onSub = { recordingSub = it },
182 180 filterSpeakerId = filterSpeakerId, onFilterSpeakerId = { filterSpeakerId = it },
183 181 jumpToTs = jumpToTs, onJumpConsumed = { jumpToTs = null },
  182 + onJumpTo = { ts -> jumpToTs = ts },
184 183 )
185 184 Tab.Chat -> ChatTab(repo)
186   - Tab.Memo -> MemoScreen(
187   - repo = repo, activity = activity, speakers = speakers,
188   - sub = memoSub, onSub = { memoSub = it },
189   - onFilterBySpeaker = { id -> filterSpeakerId = id; recordingSub = 1; tab = Tab.Recording },
190   - onJumpToTime = { ts -> filterSpeakerId = null; jumpToTs = ts; recordingSub = 1; tab = Tab.Recording },
191   - )
192 185 Tab.Album -> AlbumTab(repo)
193 186 Tab.Settings -> SettingsScreen(activity)
194 187 }
... ... @@ -209,17 +202,19 @@ private fun RecordingScreen(
209 202 onFilterSpeakerId: (Long?) -> Unit,
210 203 jumpToTs: Long?,
211 204 onJumpConsumed: () -> Unit,
  205 + onJumpTo: (Long) -> Unit,
212 206 ) {
213 207 Column(modifier = Modifier.fillMaxSize()) {
214 208 androidx.compose.material3.TabRow(selectedTabIndex = sub) {
215 209 androidx.compose.material3.Tab(selected = sub == 0, onClick = { onSub(0) }, text = { Text("录音") })
216 210 androidx.compose.material3.Tab(selected = sub == 1, onClick = { onSub(1) }, text = { Text("时间轴") })
  211 + androidx.compose.material3.Tab(selected = sub == 2, onClick = { onSub(2) }, text = { Text("声纹") })
  212 + androidx.compose.material3.Tab(selected = sub == 3, onClick = { onSub(3) }, text = { Text("纪要") })
217 213 }
218 214 Box(modifier = Modifier.weight(1f)) {
219   - if (sub == 0) {
220   - HomeTab(activity, repo, onOpenTimeline = { onSub(1) })
221   - } else {
222   - TimelineTab(
  215 + when (sub) {
  216 + 0 -> HomeTab(activity, repo, onOpenTimeline = { onSub(1) })
  217 + 1 -> TimelineTab(
223 218 repo = repo,
224 219 speakers = speakers,
225 220 filterSpeakerId = filterSpeakerId,
... ... @@ -227,31 +222,16 @@ private fun RecordingScreen(
227 222 jumpToTs = jumpToTs,
228 223 onJumpConsumed = onJumpConsumed,
229 224 )
230   - }
231   - }
232   - }
233   -}
234   -
235   -@Composable
236   -private fun MemoScreen(
237   - repo: Repository,
238   - activity: Context,
239   - speakers: List<SpeakerProfile>,
240   - sub: Int,
241   - onSub: (Int) -> Unit,
242   - onFilterBySpeaker: (Long) -> Unit,
243   - onJumpToTime: (Long) -> Unit,
244   -) {
245   - Column(modifier = Modifier.fillMaxSize()) {
246   - androidx.compose.material3.TabRow(selectedTabIndex = sub) {
247   - androidx.compose.material3.Tab(selected = sub == 0, onClick = { onSub(0) }, text = { Text("声纹") })
248   - androidx.compose.material3.Tab(selected = sub == 1, onClick = { onSub(1) }, text = { Text("纪要") })
249   - }
250   - Box(modifier = Modifier.weight(1f)) {
251   - if (sub == 0) {
252   - SpeakersTab(repo = repo, speakers = speakers, onFilterBySpeaker = onFilterBySpeaker)
253   - } else {
254   - SummariesTab(repo = repo, activity = activity, onJumpToTime = onJumpToTime)
  225 + 2 -> SpeakersTab(
  226 + repo = repo, speakers = speakers,
  227 + // 点声纹 → 按 TA 筛选时间轴
  228 + onFilterBySpeaker = { id -> onFilterSpeakerId(id); onSub(1) },
  229 + )
  230 + else -> SummariesTab(
  231 + repo = repo, activity = activity,
  232 + // 点纪要时间戳 → 跳时间轴对应段
  233 + onJumpToTime = { ts -> onFilterSpeakerId(null); onJumpTo(ts); onSub(1) },
  234 + )
255 235 }
256 236 }
257 237 }
... ...