Main.kt (4460B)
1 package pages 2 3 import androidx.compose.runtime.Composable 4 import androidx.compose.runtime.collectAsState 5 import androidx.compose.runtime.getValue 6 import com.arkivanov.decompose.extensions.compose.jetbrains.subscribeAsState 7 import com.varabyte.kobweb.compose.css.Overflow 8 import com.varabyte.kobweb.compose.css.borderRight 9 import com.varabyte.kobweb.compose.css.overflowX 10 import com.varabyte.kobweb.compose.css.overflowY 11 import com.varabyte.kobweb.silk.components.forms.Button 12 import de.connect2x.trixnity.messenger.viewmodel.MainViewModel 13 import de.connect2x.trixnity.messenger.viewmodel.room.RoomRouter 14 import de.connect2x.trixnity.messenger.viewmodel.room.RoomViewModel 15 import de.connect2x.trixnity.messenger.viewmodel.room.timeline.RoomHeaderViewModel 16 import de.connect2x.trixnity.messenger.viewmodel.room.timeline.TimelineRouter 17 import de.connect2x.trixnity.messenger.viewmodel.roomlist.RoomListElementViewModel 18 import de.connect2x.trixnity.messenger.viewmodel.roomlist.RoomListRouter 19 import de.connect2x.trixnity.messenger.viewmodel.roomlist.RoomListViewModel 20 import net.folivo.trixnity.core.model.RoomId 21 import org.jetbrains.compose.web.css.* 22 import org.jetbrains.compose.web.dom.Div 23 import org.jetbrains.compose.web.dom.Text 24 25 @Composable 26 fun Main(mainViewModel: MainViewModel) { 27 suspend { 28 mainViewModel.start() 29 } 30 val roomListData by mainViewModel.roomListRouterStack.subscribeAsState() 31 val roomData by mainViewModel.roomRouterStack.subscribeAsState() 32 val room = roomData.active.instance 33 val roomList = roomListData.active.instance 34 35 36 Div({ 37 style { 38 display(DisplayStyle.Flex) 39 flexDirection(FlexDirection.Row) 40 gap(2.px) 41 height(100.vh) 42 } 43 }) { 44 Div({ 45 style { 46 width(25.em) 47 display(DisplayStyle.Flex) 48 flexDirection(FlexDirection.Column) 49 gap(2.px) 50 borderRight(width = 1.px, style = LineStyle.Solid, color = Color("black")) 51 padding(4.px) 52 overflowX(Overflow.Hidden) 53 overflowY(Overflow.Auto) 54 } 55 }) { 56 if (roomList is RoomListRouter.RoomListWrapper.List) { 57 RoomList(roomList.roomListViewModel) 58 } 59 } 60 61 Div({ 62 style { 63 display(DisplayStyle.Flex) 64 flexDirection(FlexDirection.Column) 65 gap(2.px) 66 width(100.percent) 67 padding(4.px) 68 } 69 }) { 70 when (room) { 71 is RoomRouter.RoomWrapper.None -> { 72 Text("Room") 73 } 74 75 is RoomRouter.RoomWrapper.View -> { 76 Room(room.roomViewModel) 77 } 78 } 79 } 80 } 81 } 82 83 @Composable 84 fun RoomList(roomListViewModel: RoomListViewModel) { 85 val initialSyncFinished by roomListViewModel.initialSyncFinished.collectAsState() 86 val selectedRoomId by roomListViewModel.selectedRoomId.collectAsState() 87 val rooms by roomListViewModel.sortedRoomListElementViewModels.collectAsState() 88 89 if (!initialSyncFinished) { 90 Div({ 91 classes("lds-dual-ring") 92 }) 93 } else { 94 rooms.forEach { room -> 95 RoomListItem(room.second, room.first == selectedRoomId) { roomID -> 96 roomListViewModel.selectRoom(roomID) 97 } 98 } 99 } 100 } 101 102 @Composable 103 fun RoomListItem(roomViewModel: RoomListElementViewModel, selected: Boolean, selectRoom: (RoomId) -> Unit) { 104 val roomName by roomViewModel.roomName.collectAsState() 105 val roomId = roomViewModel.roomId 106 val roomNameReal = roomName ?: roomId.full 107 Button(onClick = { 108 if (!selected) { 109 // Geht das eleganter? 110 selectRoom(roomId) 111 } 112 }) { 113 Text(roomNameReal) 114 } 115 } 116 117 @Composable 118 fun Room(roomViewModel: RoomViewModel) { 119 val timelineStack by roomViewModel.timelineStack.subscribeAsState() 120 val timeline = timelineStack.active.instance 121 if (timeline is TimelineRouter.TimelineWrapper.View) { 122 val roomHeaderViewModel = timeline.timelineViewModel.roomHeaderViewModel 123 124 RoomHeaderElement(roomHeaderViewModel) 125 } 126 } 127 128 129 @Composable 130 fun RoomHeaderElement(roomHeaderViewModel: RoomHeaderViewModel) { 131 val roomHeaderElement by roomHeaderViewModel.roomHeaderElement.collectAsState() 132 Text(roomHeaderElement.roomName) 133 }