@@ -4,6 +4,9 @@ import SwiftUI
4
4
public struct LiveTranslationView : View {
5
5
let viewModel : ViewModel
6
6
@State var isSelectedLanguageSheet : Bool = false
7
+ @State var isShowingLastChat : Bool = false
8
+
9
+ private let scrollContentBottomID : String = " atBottom "
7
10
8
11
public init (
9
12
roomNumber: String = ProcessInfo . processInfo. environment [ " LIVE_TRANSLATION_KEY " ]
@@ -16,36 +19,61 @@ public struct LiveTranslationView: View {
16
19
public var body : some View {
17
20
NavigationStack {
18
21
VStack {
19
- ScrollView {
20
- if self . viewModel. roomNumber. isEmpty {
21
- ContentUnavailableView ( " Room is unavailable " , systemImage: " text.page.slash.fill " )
22
- Spacer ( )
23
- } else if viewModel. chatList. isEmpty {
24
- ContentUnavailableView ( " Not started yet " , systemImage: " text.page.slash.fill " )
25
- Spacer ( )
26
- } else {
27
- LazyVStack {
28
- ForEach ( viewModel. chatList) { item in
29
- Text ( item. trItem? . content ?? item. item. text)
30
- . frame ( maxWidth: . infinity, alignment: . leading)
31
- . multilineTextAlignment ( . leading)
32
- . padding ( )
22
+ ScrollViewReader { reader in
23
+ ScrollView {
24
+ if self . viewModel. roomNumber. isEmpty {
25
+ ContentUnavailableView ( " Room is unavailable " , systemImage: " text.page.slash.fill " )
26
+ Spacer ( )
27
+ } else if viewModel. chatList. isEmpty {
28
+ ContentUnavailableView ( " Not started yet " , systemImage: " text.page.slash.fill " )
29
+ Spacer ( )
30
+ } else {
31
+ LazyVStack {
32
+ ForEach ( viewModel. chatList) { item in
33
+ Text ( item. trItem? . content ?? item. item. text)
34
+ . frame ( maxWidth: . infinity, alignment: . leading)
35
+ . multilineTextAlignment ( . leading)
36
+ . padding ( )
37
+ . onAppear {
38
+ guard item == viewModel. chatList. last else { return }
39
+ isShowingLastChat = true
40
+ }
41
+ . onDisappear {
42
+ guard item == viewModel. chatList. last else { return }
43
+ isShowingLastChat = false
44
+ }
45
+ }
33
46
}
34
47
}
48
+
49
+ HStack {
50
+ Spacer ( )
51
+ Text ( " Powered by " , bundle: . module)
52
+ . font ( . caption)
53
+ . foregroundStyle ( Color ( . secondaryLabel) )
54
+ Image ( . flitto)
55
+ . resizable ( )
56
+ . offset ( x: - 10 )
57
+ . aspectRatio ( contentMode: . fit)
58
+ . frame ( maxHeight: 30 )
59
+ Spacer ( )
60
+ }
61
+ . id ( scrollContentBottomID)
62
+ . padding ( . bottom, 16 )
35
63
}
36
- HStack {
37
- Spacer ( )
38
- Text ( " Powered by " , bundle: . module)
39
- . font ( . caption)
40
- . foregroundStyle ( Color ( . secondaryLabel) )
41
- Image ( . flitto)
42
- . resizable ( )
43
- . offset ( x: - 10 )
44
- . aspectRatio ( contentMode: . fit)
45
- . frame ( maxHeight: 30 )
46
- Spacer ( )
64
+ . onChange ( of: viewModel. chatList. last) { old, new in
65
+ guard old != . none else {
66
+ reader. scrollTo ( scrollContentBottomID, anchor: . bottom)
67
+ return
68
+ }
69
+
70
+ guard isShowingLastChat else { return }
71
+
72
+ guard new != . none else { return }
73
+ withAnimation ( . interactiveSpring) {
74
+ reader. scrollTo ( scrollContentBottomID, anchor: . center)
75
+ }
47
76
}
48
- . padding ( . bottom, 16 )
49
77
}
50
78
}
51
79
. task {
0 commit comments