Browse Source

Extract subviews of chat and chat list views

Sergey 2 years ago
parent
commit
d736f599f7

+ 8 - 0
Chat.xcodeproj/project.pbxproj

@@ -21,6 +21,8 @@
 		2F6045B3288EA0E6008F005E /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6045B2288EA0E6008F005E /* LoginView.swift */; };
 		2F6045B6288EA10B008F005E /* LoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6045B5288EA10B008F005E /* LoginViewModel.swift */; };
 		2F6E936828F8714600FAF0E5 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6E936728F8714600FAF0E5 /* Message.swift */; };
+		2F6E936A28F8D63600FAF0E5 /* ChatListCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6E936928F8D63600FAF0E5 /* ChatListCellView.swift */; };
+		2F6E936C28F8D74600FAF0E5 /* MessageTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F6E936B28F8D74600FAF0E5 /* MessageTextField.swift */; };
 		2F81974828ACEDC8008D8C45 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F81974728ACEDC8008D8C45 /* User.swift */; };
 		2F81974C28ACFDEA008D8C45 /* Room.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F81974B28ACFDEA008D8C45 /* Room.swift */; };
 		2FCB75E728A425580097BD1D /* RoomsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FCB75E628A425580097BD1D /* RoomsListView.swift */; };
@@ -44,6 +46,8 @@
 		2F6045B2288EA0E6008F005E /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
 		2F6045B5288EA10B008F005E /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = "<group>"; };
 		2F6E936728F8714600FAF0E5 /* Message.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = "<group>"; };
+		2F6E936928F8D63600FAF0E5 /* ChatListCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListCellView.swift; sourceTree = "<group>"; };
+		2F6E936B28F8D74600FAF0E5 /* MessageTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageTextField.swift; sourceTree = "<group>"; };
 		2F81974728ACEDC8008D8C45 /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
 		2F81974B28ACFDEA008D8C45 /* Room.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Room.swift; sourceTree = "<group>"; };
 		2FCB75E628A425580097BD1D /* RoomsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomsListView.swift; sourceTree = "<group>"; };
@@ -95,6 +99,7 @@
 			isa = PBXGroup;
 			children = (
 				2F604598288D7E00008F005E /* ChatView.swift */,
+				2F6E936B28F8D74600FAF0E5 /* MessageTextField.swift */,
 				2FCB75EC28A42B1E0097BD1D /* ChatViewModel.swift */,
 			);
 			path = Chat;
@@ -159,6 +164,7 @@
 			isa = PBXGroup;
 			children = (
 				2F60459E288D869B008F005E /* ChatListView.swift */,
+				2F6E936928F8D63600FAF0E5 /* ChatListCellView.swift */,
 				2F6045AF288E9D3E008F005E /* ChatListViewModel.swift */,
 			);
 			path = ChatList;
@@ -253,6 +259,7 @@
 				2FCB75ED28A42B1E0097BD1D /* ChatViewModel.swift in Sources */,
 				2F24E94828F2FC8A007ECE97 /* AppDelegate.swift in Sources */,
 				2F81974C28ACFDEA008D8C45 /* Room.swift in Sources */,
+				2F6E936C28F8D74600FAF0E5 /* MessageTextField.swift in Sources */,
 				2F60459C288D8000008F005E /* MessageView.swift in Sources */,
 				2F6E936828F8714600FAF0E5 /* Message.swift in Sources */,
 				2F6045B0288E9D3E008F005E /* ChatListViewModel.swift in Sources */,
@@ -265,6 +272,7 @@
 				2F60458C288D787F008F005E /* ContentView.swift in Sources */,
 				2F604599288D7E00008F005E /* ChatView.swift in Sources */,
 				2F6045B6288EA10B008F005E /* LoginViewModel.swift in Sources */,
+				2F6E936A28F8D63600FAF0E5 /* ChatListCellView.swift in Sources */,
 				2F60458A288D787F008F005E /* ChatApp.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 6 - 29
Chat/UI/Chat/ChatView.swift

@@ -56,24 +56,7 @@ struct ChatView: View, KeyboardReadable {
                 }
             }
             Divider()
-            HStack {
-                TextField("Сообщение", text: $viewModel.messageText)
-                    .textFieldStyle(.automatic)
-                    .padding(.vertical, 6)
-                    .padding(.horizontal, 12)
-                    .background(.background)
-                Button {
-                    viewModel.sendMessage()
-                } label: {
-                    Image(systemName: "arrow.up.circle.fill")
-                        .font(.title)
-                        .foregroundColor(viewModel.messageText.isEmpty ? .gray : .accentColor)
-                }
-                .disabled(viewModel.messageText.isEmpty)
-            }
-            .padding(.horizontal, .sidePadding)
-            .padding(.vertical, 6)
-            .background()
+			MessageTextField(message: $viewModel.messageText, action: viewModel.sendMessage)
         }
         .navigationTitle(viewModel.room.roomJID.user ?? "Room")
         .navigationBarTitleDisplayMode(.inline)
@@ -86,23 +69,17 @@ struct ChatView: View, KeyboardReadable {
                 }
             }
         }
-        .onAppear {
-            viewModel.fetchMessages()
-        }
     }
 }
 
 struct ChatView_Previews: PreviewProvider {
-    static var viewModel: ChatViewModel = ChatViewModel(with: "")
+    static var viewModel: ChatViewModel = ChatViewModel(with: "jid")
+
     static var previews: some View {
         Group {
-            NavigationView {
-                ChatView(viewModel: viewModel)
-            }
-            NavigationView {
-                ChatView(viewModel: viewModel)
-                    .preferredColorScheme(.dark)
-            }
+			NavigationView {
+				ChatView(viewModel: viewModel)
+			}
         }
     }
 }

+ 52 - 0
Chat/UI/Chat/MessageTextField.swift

@@ -0,0 +1,52 @@
+//
+//  MessageTextField.swift
+//  Chat (iOS)
+//
+//  Created by Sergey Tarasov on 14.10.2022.
+//
+
+import SwiftUI
+
+struct MessageTextField: View {
+	@Binding var message: String
+	let action: () -> Void
+
+	var body: some View {
+		HStack {
+			TextField("Сообщение", text: $message)
+				.textFieldStyle(.automatic)
+				.padding(.vertical, 6)
+				.padding(.horizontal, 12)
+				.background(.background)
+			Button {
+				action()
+			} label: {
+				Image(systemName: "arrow.up.circle.fill")
+					.font(.title)
+					.foregroundColor(message.isEmpty ? .gray : .accentColor)
+			}
+			.disabled(message.isEmpty)
+		}
+		.padding(.horizontal, .sidePadding)
+		.padding(.vertical, 6)
+		.background()
+	}
+}
+
+struct MessageTextField_Previews: PreviewProvider {
+    static var previews: some View {
+		MessageTestTextField()
+    }
+
+	struct MessageTestTextField: View {
+		@State var messageText: String = ""
+		@State var lastMessage: String = ""
+
+		var body: some View {
+			VStack {
+				MessageTextField(message: $messageText, action: { lastMessage = messageText })
+				Text("Last message: " + lastMessage)
+			}
+		}
+	}
+}

+ 42 - 0
Chat/UI/ChatList/ChatListCellView.swift

@@ -0,0 +1,42 @@
+//
+//  ChatListCellView.swift
+//  Chat (iOS)
+//
+//  Created by Sergey Tarasov on 14.10.2022.
+//
+
+import SwiftUI
+
+struct ChatListCellView: View {
+	let nickname: String
+	let jid: String
+
+	var body: some View {
+		ZStack {
+			HStack {
+				Image(systemName: "person.crop.circle")
+					.resizable()
+					.scaledToFit()
+					.foregroundColor(.secondary.opacity(0.5))
+				Text(nickname)
+				Spacer()
+			}
+			.foregroundColor(.primary)
+			.frame(height: 30)
+			NavigationLink {
+				ChatView(viewModel: ChatViewModel(with: jid))
+			} label: {
+				EmptyView()
+			}
+			.opacity(0.0)
+		}
+	}
+}
+
+struct ChatListCellView_Previews: PreviewProvider {
+    static var previews: some View {
+		ChatListCellView(nickname: "Nickname", jid: "user@domain.com")
+			.padding()
+			.previewLayout(.sizeThatFits)
+    }
+}

+ 13 - 34
Chat/UI/ChatList/ChatListView.swift

@@ -16,31 +16,15 @@ struct ChatListView: View {
 
     var body: some View {
         Group {
-            if viewModel.users.isEmpty {
-                ProgressView()
-            } else {
-                List {
-                    ForEach(viewModel.users.indices, id: \.self) { index in
-                        ZStack {
-                            HStack {
-                                Image(systemName: "person.crop.circle")
-                                    .resizable()
-                                    .scaledToFit()
-                                    .foregroundColor(.secondary.opacity(0.5))
-                                Text(viewModel.nicknames[index])
-                                Spacer()
-                            }
-                            .foregroundColor(.primary)
-                            .frame(height: 30)
-                            NavigationLink {
-                                ChatView(viewModel: ChatViewModel(with: viewModel.users[index].jidString))
-                            } label: {
-                                EmptyView()
-                            }
-                                .opacity(0.0)
-                        }
-                    }
-                }
+			if viewModel.users.isEmpty {
+				ProgressView()
+			} else {
+				List(viewModel.users.indices, id: \.self) { index in
+					ChatListCellView(
+						nickname: viewModel.nicknames[index],
+						jid: viewModel.users[index].jidString
+					)
+				}
 				.listStyle(.plain)
 			}
 		}
@@ -53,15 +37,10 @@ struct ChatListView: View {
 
 struct ChatListView_Previews: PreviewProvider {
     static var viewModel: ChatListViewModel = ChatListViewModel()
+
     static var previews: some View {
-        Group {
-            NavigationView {
-                ChatListView()
-            }
-            NavigationView {
-                ChatListView()
-            }
-            .preferredColorScheme(.dark)
-        }
+		NavigationView {
+			ChatListView()
+		}
     }
 }

+ 3 - 1
Chat/UI/ChatList/ChatListViewModel.swift

@@ -22,7 +22,9 @@ final class ChatListViewModel: NSObject, ObservableObject {
 
     public func fetchChatList() {
 		let xmppUsers = XMPPController.shared.xmppRosterStorage.sortedUsersByAvailabilityName() as? [XMPPUser]
-		guard let users = xmppUsers?.compactMap({ User(jidString: $0.jid.bare, nickname: $0.nickname) }) else {
+		guard let users = xmppUsers?.compactMap({
+			User(jidString: $0.jid.bare, nickname: $0.nickname.isEmpty ? $0.jid.bare : $0.nickname)
+		}) else {
 			return
 		}
 		self.users = users