tangled
alpha
login
or
join now
geesawra.industries
/
jerry-no
8
fork
atom
A cheap attempt at a native Bluesky client for Android
8
fork
atom
overview
issues
pulls
pipelines
ThreadView: better handling of nested threads
geesawra.industries
5 months ago
4ad916e0
e133f306
0/1
build.yaml
timeout
7m 9s
+58
-79
3 changed files
expand all
collapse all
unified
split
app
src
main
java
industries
geesawra
monarch
ThreadView.kt
datalayer
Models.kt
TimelineViewModel.kt
+8
-17
app/src/main/java/industries/geesawra/monarch/ThreadView.kt
···
1
1
package industries.geesawra.monarch
2
2
3
3
-
import android.util.Log
4
3
import androidx.compose.foundation.layout.Column
5
4
import androidx.compose.foundation.layout.fillMaxSize
6
5
import androidx.compose.foundation.layout.padding
7
6
import androidx.compose.material3.ExperimentalMaterial3Api
8
8
-
import androidx.compose.material3.HorizontalDivider
9
7
import androidx.compose.material3.MaterialTheme
10
8
import androidx.compose.material3.Scaffold
11
9
import androidx.compose.material3.Text
···
20
18
import androidx.compose.runtime.remember
21
19
import androidx.compose.ui.Modifier
22
20
import androidx.compose.ui.input.nestedscroll.nestedScroll
23
23
-
import androidx.compose.ui.util.fastForEach
24
21
import industries.geesawra.monarch.datalayer.TimelineViewModel
25
22
import kotlinx.coroutines.CoroutineScope
26
23
···
66
63
) { padding ->
67
64
LaunchedEffect(Unit) {
68
65
timelineViewModel.getThread {
69
69
-
Log.d("ThreadView", "Thread retrieved")
70
66
isRefreshing.value = false
71
67
}
72
68
}
···
74
70
Column(
75
71
modifier = Modifier.padding(padding)
76
72
) {
77
77
-
timelineViewModel.uiState.currentlyShownThread.fastForEach { threadView ->
78
78
-
ShowSkeets(
79
79
-
viewModel = timelineViewModel,
80
80
-
isScrollEnabled = true,
81
81
-
data = threadView,
82
82
-
shouldFetchMoreData = false,
83
83
-
isShowingThread = true,
84
84
-
)
85
85
-
86
86
-
HorizontalDivider()
87
87
-
}
73
73
+
ShowSkeets(
74
74
+
viewModel = timelineViewModel,
75
75
+
isScrollEnabled = true,
76
76
+
data = timelineViewModel.uiState.currentlyShownThread.flatten(),
77
77
+
shouldFetchMoreData = false,
78
78
+
isShowingThread = true,
79
79
+
)
88
80
}
89
81
}
90
82
}
91
91
-
}
92
92
-
83
83
+
}
+13
-3
app/src/main/java/industries/geesawra/monarch/datalayer/Models.kt
···
635
635
)
636
636
637
637
data class ThreadPost(
638
638
-
val post: SkeetData,
639
639
-
val replies: List<ThreadPost>
640
640
-
)
638
638
+
val post: SkeetData = SkeetData(),
639
639
+
val level: Int = 0,
640
640
+
val replies: List<ThreadPost> = listOf()
641
641
+
) {
642
642
+
fun flatten(): List<SkeetData> {
643
643
+
val list = mutableListOf<SkeetData>()
644
644
+
list.add(post.copy(nestingLevel = level))
645
645
+
replies.forEach { reply ->
646
646
+
list.addAll(reply.flatten())
647
647
+
}
648
648
+
return list
649
649
+
}
650
650
+
}
+37
-59
app/src/main/java/industries/geesawra/monarch/datalayer/TimelineViewModel.kt
···
56
56
57
57
val cidInteractedWith: Map<Cid, RKey> = mapOf(),
58
58
59
59
-
val currentlyShownThread: List<List<SkeetData>> = listOf(),
59
59
+
val currentlyShownThread: ThreadPost = ThreadPost(),
60
60
61
61
val loginError: String? = null,
62
62
val error: String? = null,
···
535
535
}
536
536
537
537
fun setThread(tappedElement: SkeetData) {
538
538
-
uiState = uiState.copy(currentlyShownThread = listOf(listOf(tappedElement)))
538
538
+
uiState = uiState.copy(currentlyShownThread = ThreadPost(post = tappedElement))
539
539
}
540
540
541
541
-
private fun getAllThreads(
542
542
-
thread: GetPostThreadResponseThreadUnion,
543
543
-
startingLevel: Int = 0
544
544
-
): List<List<SkeetData>> {
545
545
-
if (thread !is GetPostThreadResponseThreadUnion.ThreadViewPost) {
546
546
-
return when (thread) {
547
547
-
is GetPostThreadResponseThreadUnion.BlockedPost -> listOf(listOf(SkeetData(blocked = true)))
548
548
-
is GetPostThreadResponseThreadUnion.NotFoundPost -> listOf(listOf(SkeetData(notFound = true)))
549
549
-
else -> emptyList()
550
550
-
}
551
551
-
}
552
552
-
553
553
-
val rootSkeet = SkeetData.fromPostView(thread.value.post, thread.value.post.author)
554
554
-
val threads = mutableListOf<List<SkeetData>>()
555
555
-
556
556
-
// fun findPaths(current: ThreadViewPostReplieUnion, currentPath: List<SkeetData>, level: Int) {
557
557
-
// val skeet = when (current) {
558
558
-
// is ThreadViewPostReplieUnion.ThreadViewPost -> SkeetData.fromPostView(
559
559
-
// current.value.post,
560
560
-
// current.value.post.author
561
561
-
// ).copy(nestingLevel = level)
562
562
-
//
563
563
-
// is ThreadViewPostReplieUnion.BlockedPost -> SkeetData(blocked = true)
564
564
-
// is ThreadViewPostReplieUnion.NotFoundPost -> SkeetData(notFound = true)
565
565
-
// else -> null
566
566
-
// }
567
567
-
//
568
568
-
// if (skeet == null) return
569
569
-
//
570
570
-
// val newPath = currentPath + skeet
571
571
-
// val replies = (current as? ThreadViewPostReplieUnion.ThreadViewPost)?.value?.replies
572
572
-
//
573
573
-
// if (replies.isNullOrEmpty()) {
574
574
-
// threads.add(newPath)
575
575
-
// } else {
576
576
-
// replies.forEach { findPaths(it, newPath, level + 1) }
577
577
-
// }
578
578
-
// }
579
579
-
//
580
580
-
581
581
-
val list = mutableListOf<SkeetData>()
541
541
+
private fun readThread(
542
542
+
threadUnion: GetPostThreadResponseThreadUnion,
543
543
+
level: Int = 0
544
544
+
): ThreadPost {
545
545
+
if (threadUnion !is GetPostThreadResponseThreadUnion.ThreadViewPost) {
546
546
+
return when (threadUnion) {
547
547
+
is GetPostThreadResponseThreadUnion.BlockedPost -> ThreadPost(
548
548
+
post = SkeetData(blocked = true),
549
549
+
level = level
550
550
+
)
582
551
583
583
-
thread.value.replies.forEach { reply ->
584
584
-
when (reply) {
585
585
-
is ThreadViewPostReplieUnion.BlockedPost -> listOf(listOf(SkeetData(blocked = true)))
586
586
-
is ThreadViewPostReplieUnion.NotFoundPost -> listOf(listOf(SkeetData(notFound = true)))
587
587
-
is ThreadViewPostReplieUnion.ThreadViewPost -> run {
588
588
-
list.add(SkeetData.fromPostView(reply.value.post, reply.value.post.author))
589
589
-
threads += getAllThreads(
590
590
-
GetPostThreadResponseThreadUnion.ThreadViewPost(reply.value),
591
591
-
startingLevel + 1
592
592
-
)
593
593
-
}
552
552
+
is GetPostThreadResponseThreadUnion.NotFoundPost -> ThreadPost(
553
553
+
post = SkeetData(notFound = true),
554
554
+
level = level
555
555
+
)
594
556
595
595
-
is ThreadViewPostReplieUnion.Unknown -> {}
557
557
+
else -> ThreadPost(level = level) // Default for unknown
596
558
}
597
559
}
598
560
561
561
+
val currentPostSkeetData = SkeetData.fromPostView(threadUnion.value.post, threadUnion.value.post.author)
599
562
600
600
-
threads.add(list)
563
563
+
val replies = threadUnion.value.replies.map { replyUnion ->
564
564
+
readThread(
565
565
+
threadUnion = when (replyUnion) {
566
566
+
is ThreadViewPostReplieUnion.BlockedPost -> GetPostThreadResponseThreadUnion.BlockedPost(replyUnion.value)
567
567
+
is ThreadViewPostReplieUnion.NotFoundPost -> GetPostThreadResponseThreadUnion.NotFoundPost(replyUnion.value)
568
568
+
is ThreadViewPostReplieUnion.ThreadViewPost -> GetPostThreadResponseThreadUnion.ThreadViewPost(replyUnion.value)
569
569
+
is ThreadViewPostReplieUnion.Unknown -> GetPostThreadResponseThreadUnion.Unknown(replyUnion.value)
570
570
+
},
571
571
+
level = level + 1
572
572
+
)
573
573
+
}
601
574
602
602
-
return threads.map { it.sortedBy { skeet -> skeet.createdAt } }
575
575
+
return ThreadPost(
576
576
+
post = currentPostSkeetData,
577
577
+
level = level,
578
578
+
replies = replies
579
579
+
)
603
580
}
604
581
605
582
fun getThread(then: () -> Unit) {
606
583
viewModelScope.launch {
607
607
-
bskyConn.getThread(uiState.currentlyShownThread.first().first().uri).onFailure {
584
584
+
bskyConn.getThread(uiState.currentlyShownThread.post.uri).onFailure {
608
585
uiState = when (it) {
609
586
is LoginException -> uiState.copy(loginError = it.message)
610
587
else -> uiState.copy(error = it.message)
611
588
}
612
589
}.onSuccess {
590
590
+
val asd = readThread(it.thread)
613
591
uiState = uiState.copy(
614
614
-
currentlyShownThread = getAllThreads(it.thread)
592
592
+
currentlyShownThread = asd
615
593
)
616
594
then()
617
595
}