diff --git a/apps/ios/Shared/Assets.xcassets/AccentColor.colorset/Contents.json b/apps/ios/Shared/Assets.xcassets/AccentColor.colorset/Contents.json index eebacd743..481421680 100644 --- a/apps/ios/Shared/Assets.xcassets/AccentColor.colorset/Contents.json +++ b/apps/ios/Shared/Assets.xcassets/AccentColor.colorset/Contents.json @@ -1,6 +1,15 @@ { "colors" : [ { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "0.533", + "red" : "0.000" + } + }, "idiom" : "universal" } ], diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index bdd62accd..34e5fa5bb 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -115,15 +115,15 @@ struct User: Decodable { // self.profile = profile // self.activeUser = activeUser // } -} -let sampleUser = User( - userId: 1, - userContactId: 1, - localDisplayName: "alice", - profile: sampleProfile, - activeUser: true -) + static let sampleData = User( + userId: 1, + userContactId: 1, + localDisplayName: "alice", + profile: Profile.sampleData, + activeUser: true + ) +} typealias ContactName = String @@ -132,12 +132,12 @@ typealias GroupName = String struct Profile: Codable { var displayName: String var fullName: String -} -let sampleProfile = Profile( - displayName: "alice", - fullName: "Alice" -) + static let sampleData = Profile( + displayName: "alice", + fullName: "Alice" + ) +} enum ChatType: String { case direct = "@" @@ -160,6 +160,16 @@ enum ChatInfo: Identifiable, Decodable { } } + var displayName: String { + get { + switch self { + case let .direct(contact): return contact.profile.displayName + case let .group(groupInfo): return groupInfo.groupProfile.displayName + case let .contactRequest(contactRequest): return contactRequest.profile.displayName + } + } + } + var fullName: String { get { switch self { @@ -171,7 +181,7 @@ enum ChatInfo: Identifiable, Decodable { } var chatViewName: String { - get { localDisplayName + (fullName == "" || fullName == localDisplayName ? "" : " / \(fullName)") } + get { displayName + (fullName == "" || fullName == displayName ? "" : " / \(fullName)") } } var id: String { @@ -211,14 +221,20 @@ enum ChatInfo: Identifiable, Decodable { case let .contactRequest(contactRequest): return contactRequest.createdAt } } + + struct SampleData { + var direct: ChatInfo + var group: ChatInfo + var contactRequest: ChatInfo + } + + static var sampleData: ChatInfo.SampleData = SampleData( + direct: ChatInfo.direct(contact: Contact.sampleData), + group: ChatInfo.group(groupInfo: GroupInfo.sampleData), + contactRequest: ChatInfo.contactRequest(contactRequest: UserContactRequest.sampleData) + ) } -let sampleDirectChatInfo = ChatInfo.direct(contact: sampleContact) - -let sampleGroupChatInfo = ChatInfo.group(groupInfo: sampleGroupInfo) - -let sampleContactRequestChatInfo = ChatInfo.contactRequest(contactRequest: sampleContactRequest) - final class Chat: ObservableObject, Identifiable { @Published var chatInfo: ChatInfo @Published var chatItems: [ChatItem] @@ -297,21 +313,21 @@ struct Contact: Identifiable, Decodable { var id: String { get { "@\(contactId)" } } var apiId: Int64 { get { contactId } } var ready: Bool { get { activeConn.connStatus == "ready" || activeConn.connStatus == "snd-ready" } } -} -let sampleContact = Contact( - contactId: 1, - localDisplayName: "alice", - profile: sampleProfile, - activeConn: sampleConnection, - createdAt: .now -) + static let sampleData = Contact( + contactId: 1, + localDisplayName: "alice", + profile: Profile.sampleData, + activeConn: Connection.sampleData, + createdAt: .now + ) +} struct Connection: Decodable { var connStatus: String -} -let sampleConnection = Connection(connStatus: "ready") + static let sampleData = Connection(connStatus: "ready") +} struct UserContactRequest: Decodable { var contactRequestId: Int64 @@ -322,14 +338,14 @@ struct UserContactRequest: Decodable { var id: String { get { "<@\(contactRequestId)" } } var apiId: Int64 { get { contactRequestId } } -} -let sampleContactRequest = UserContactRequest( - contactRequestId: 1, - localDisplayName: "alice", - profile: sampleProfile, - createdAt: .now -) + static let sampleData = UserContactRequest( + contactRequestId: 1, + localDisplayName: "alice", + profile: Profile.sampleData, + createdAt: .now + ) +} struct GroupInfo: Identifiable, Decodable { var groupId: Int64 @@ -340,27 +356,44 @@ struct GroupInfo: Identifiable, Decodable { var id: String { get { "#\(groupId)" } } var apiId: Int64 { get { groupId } } -} -let sampleGroupInfo = GroupInfo( - groupId: 1, - localDisplayName: "team", - groupProfile: sampleGroupProfile, - createdAt: .now -) + static let sampleData = GroupInfo( + groupId: 1, + localDisplayName: "team", + groupProfile: GroupProfile.sampleData, + createdAt: .now + ) +} struct GroupProfile: Codable { var displayName: String var fullName: String + + static let sampleData = GroupProfile( + displayName: "team", + fullName: "My Team" + ) } -let sampleGroupProfile = GroupProfile( - displayName: "team", - fullName: "My Team" -) - struct GroupMember: Decodable { + var groupMemberId: Int64 + var memberId: String +// var memberRole: GroupMemberRole +// var memberCategory: GroupMemberCategory +// var memberStatus: GroupMemberStatus +// var invitedBy: InvitedBy + var localDisplayName: ContactName + var memberProfile: Profile + var memberContactId: Int64? +// var activeConn: Connection? + static let sampleData = GroupMember( + groupMemberId: 1, + memberId: "abcd", + localDisplayName: "alice", + memberProfile: Profile.sampleData, + memberContactId: 1 + ) } struct AChatItem: Decodable { @@ -374,21 +407,21 @@ struct ChatItem: Identifiable, Decodable { var content: CIContent var id: Int64 { get { meta.itemId } } -} -func chatItemSample(_ id: Int64, _ dir: CIDirection, _ ts: Date, _ text: String) -> ChatItem { - ChatItem( - chatDir: dir, - meta: ciMetaSample(id, ts, text), - content: .sndMsgContent(msgContent: .text(text)) - ) + static func getSample (_ id: Int64, _ dir: CIDirection, _ ts: Date, _ text: String) -> ChatItem { + ChatItem( + chatDir: dir, + meta: CIMeta.getSample(id, ts, text), + content: .sndMsgContent(msgContent: .text(text)) + ) + } } enum CIDirection: Decodable { case directSnd case directRcv case groupSnd - case groupRcv(GroupMember) + case groupRcv(groupMember: GroupMember) var sent: Bool { get { @@ -407,6 +440,15 @@ struct CIMeta: Decodable { var itemTs: Date var itemText: String var createdAt: Date + + static func getSample(_ id: Int64, _ ts: Date, _ text: String) -> CIMeta { + CIMeta( + itemId: id, + itemTs: ts, + itemText: text, + createdAt: ts + ) + } } enum CIStatus: Decodable { @@ -418,15 +460,6 @@ enum CIStatus: Decodable { case rcvRead } -func ciMetaSample(_ id: Int64, _ ts: Date, _ text: String) -> CIMeta { - CIMeta( - itemId: id, - itemTs: ts, - itemText: text, - createdAt: ts - ) -} - enum CIContent: Decodable { case sndMsgContent(msgContent: MsgContent) case rcvMsgContent(msgContent: MsgContent) diff --git a/apps/ios/Shared/Views/Chat/ChatInfoView.swift b/apps/ios/Shared/Views/Chat/ChatInfoView.swift index 2932478ee..6d59b1946 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoView.swift @@ -90,10 +90,8 @@ struct ChatInfoView: View { } struct ChatInfoView_Previews: PreviewProvider { - var chatInfo = sampleDirectChatInfo - static var previews: some View { @State var showChatInfo = true - return ChatInfoView(chat: Chat(chatInfo: sampleDirectChatInfo, chatItems: []), showChatInfo: $showChatInfo) + return ChatInfoView(chat: Chat(chatInfo: ChatInfo.sampleData.direct, chatItems: []), showChatInfo: $showChatInfo) } } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift index b474feee1..2ee4a93e2 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift @@ -35,8 +35,8 @@ struct EmojiItemView: View { struct EmojiItemView_Previews: PreviewProvider { static var previews: some View { Group{ - EmojiItemView(chatItem: chatItemSample(1, .directSnd, .now, "🙂")) - EmojiItemView(chatItem: chatItemSample(2, .directRcv, .now, "👍")) + EmojiItemView(chatItem: ChatItem.getSample(1, .directSnd, .now, "🙂")) + EmojiItemView(chatItem: ChatItem.getSample(2, .directRcv, .now, "👍")) } .previewLayout(.fixed(width: 360, height: 70)) } diff --git a/apps/ios/Shared/Views/Chat/ChatItem/TextItemView.swift b/apps/ios/Shared/Views/Chat/ChatItem/TextItemView.swift index 78f875d0e..0a396b16f 100644 --- a/apps/ios/Shared/Views/Chat/ChatItem/TextItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItem/TextItemView.swift @@ -12,54 +12,73 @@ private let emailRegex = try! NSRegularExpression(pattern: "^[a-z0-9.!#$%&'*+/=? private let phoneRegex = try! NSRegularExpression(pattern: "^\\+?[0-9\\.\\(\\)\\-]{7,20}$") +private let sentColorLigth = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.12) +private let sentColorDark = Color(.sRGB, red: 0.27, green: 0.72, blue: 1, opacity: 0.17) +private let linkColor = UIColor(red: 0, green: 0.533, blue: 1, alpha: 1) + struct TextItemView: View { + @Environment(\.colorScheme) var colorScheme var chatItem: ChatItem var width: CGFloat private let codeFont = Font.custom("Courier", size: UIFont.preferredFont(forTextStyle: .body).pointSize) var body: some View { let sent = chatItem.chatDir.sent - let minWidth = min(200, width) - let maxWidth = min(300, width * 0.78) +// let minWidth = min(200, width) + let maxWidth = width * 0.78 let meta = getDateFormatter().string(from: chatItem.meta.itemTs) return ZStack(alignment: .bottomTrailing) { - (messageText(chatItem.content.text, sent: sent) + reserveSpaceForMeta(meta)) + (messageText(chatItem) + reserveSpaceForMeta(meta)) .padding(.top, 6) .padding(.bottom, 7) .padding(.horizontal, 12) - .frame(minWidth: minWidth, maxWidth: maxWidth, alignment: .leading) - .foregroundColor(sent ? .white : .primary) + .frame(minWidth: 0, alignment: .leading) +// .foregroundColor(sent ? .white : .primary) .textSelection(.enabled) + Text(meta) .font(.caption) - .foregroundColor(sent ? Color(uiColor: .secondarySystemBackground) : .secondary) + .foregroundColor(.secondary) +// .foregroundColor(sent ? Color(uiColor: .secondarySystemBackground) : .secondary) .padding(.bottom, 4) .padding(.horizontal, 12) - .frame(minWidth: minWidth, maxWidth: maxWidth, alignment: .bottomTrailing) } - .background(sent ? .blue : Color(uiColor: .tertiarySystemGroupedBackground)) +// .background(sent ? .blue : Color(uiColor: .tertiarySystemGroupedBackground)) + .background( + sent + ? (colorScheme == .light ? sentColorLigth : sentColorDark) + : Color(uiColor: .tertiarySystemGroupedBackground) + ) .cornerRadius(18) .padding(.horizontal) .frame( - minWidth: 200, - maxWidth: .infinity, - minHeight: 0, + maxWidth: maxWidth, maxHeight: .infinity, alignment: sent ? .trailing : .leading ) } - private func messageText(_ s: String, sent: Bool) -> Text { - if s == "" { return Text("") } - let parts = s.split(separator: " ") - var res = wordToText(parts[0], sent) - var i = 1 - while i < parts.count { - res = res + Text(" ") + wordToText(parts[i], sent) - i = i + 1 + private func messageText(_ chatItem: ChatItem) -> Text { + let s = chatItem.content.text + var res: Text + if s == "" { + res = Text("") + } else { + let parts = s.split(separator: " ") + res = wordToText(parts[0]) + var i = 1 + while i < parts.count { + res = res + Text(" ") + wordToText(parts[i]) + i = i + 1 + } + } + if case let .groupRcv(groupMember) = chatItem.chatDir { + let member = Text(groupMember.memberProfile.displayName).font(.headline) + return member + Text(": ") + res + } else { + return res } - return res } private func reserveSpaceForMeta(_ meta: String) -> Text { @@ -69,15 +88,15 @@ struct TextItemView: View { ]))) } - private func wordToText(_ s: String.SubSequence, _ sent: Bool) -> Text { + private func wordToText(_ s: String.SubSequence) -> Text { let str = String(s) switch true { case s.starts(with: "http://") || s.starts(with: "https://"): - return linkText(str, prefix: "", sent: sent) + return linkText(str, prefix: "") case match(str, emailRegex): - return linkText(str, prefix: "mailto:", sent: sent) + return linkText(str, prefix: "mailto:") case match(str, phoneRegex): - return linkText(str, prefix: "tel:", sent: sent) + return linkText(str, prefix: "tel:") default: if (s.count > 1) { switch true { @@ -97,10 +116,10 @@ struct TextItemView: View { regex.firstMatch(in: s, options: [], range: NSRange(location: 0, length: s.count)) != nil } - private func linkText(_ s: String, prefix: String, sent: Bool) -> Text { + private func linkText(_ s: String, prefix: String) -> Text { Text(AttributedString(s, attributes: AttributeContainer([ .link: NSURL(string: prefix + s) as Any, - .foregroundColor: (sent ? UIColor.white : nil) as Any + .foregroundColor: linkColor as Any ]))).underline() } @@ -112,12 +131,13 @@ struct TextItemView: View { struct TextItemView_Previews: PreviewProvider { static var previews: some View { Group{ - TextItemView(chatItem: chatItemSample(1, .directSnd, .now, "hello"), width: 360) - TextItemView(chatItem: chatItemSample(2, .directSnd, .now, "https://simplex.chat"), width: 360) - TextItemView(chatItem: chatItemSample(2, .directRcv, .now, "hello there too!!! this covers -"), width: 360) - TextItemView(chatItem: chatItemSample(2, .directRcv, .now, "hello there too!!! this text has the time on the same line "), width: 360) - TextItemView(chatItem: chatItemSample(2, .directRcv, .now, "https://simplex.chat"), width: 360) - TextItemView(chatItem: chatItemSample(2, .directRcv, .now, "chaT@simplex.chat"), width: 360) + TextItemView(chatItem: ChatItem.getSample(1, .directSnd, .now, "hello"), width: 360) + TextItemView(chatItem: ChatItem.getSample(1, .groupRcv(groupMember: GroupMember.sampleData), .now, "hello"), width: 360) + TextItemView(chatItem: ChatItem.getSample(2, .directSnd, .now, "https://simplex.chat"), width: 360) + TextItemView(chatItem: ChatItem.getSample(2, .directRcv, .now, "hello there too!!! this covers -"), width: 360) + TextItemView(chatItem: ChatItem.getSample(2, .directRcv, .now, "hello there too!!! this text has the time on the same line "), width: 360) + TextItemView(chatItem: ChatItem.getSample(2, .directRcv, .now, "https://simplex.chat"), width: 360) + TextItemView(chatItem: ChatItem.getSample(2, .directRcv, .now, "chaT@simplex.chat"), width: 360) } .previewLayout(.fixed(width: 360, height: 70)) } diff --git a/apps/ios/Shared/Views/Chat/ChatItemView.swift b/apps/ios/Shared/Views/Chat/ChatItemView.swift index 01159d7fd..a2189b597 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemView.swift @@ -34,11 +34,11 @@ func getDateFormatter() -> DateFormatter { struct ChatItemView_Previews: PreviewProvider { static var previews: some View { Group{ - ChatItemView(chatItem: chatItemSample(1, .directSnd, .now, "hello"), width: 360) - ChatItemView(chatItem: chatItemSample(2, .directRcv, .now, "hello there too"), width: 360) - ChatItemView(chatItem: chatItemSample(1, .directSnd, .now, "🙂"), width: 360) - ChatItemView(chatItem: chatItemSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂"), width: 360) - ChatItemView(chatItem: chatItemSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂🙂"), width: 360) + ChatItemView(chatItem: ChatItem.getSample(1, .directSnd, .now, "hello"), width: 360) + ChatItemView(chatItem: ChatItem.getSample(2, .directRcv, .now, "hello there too"), width: 360) + ChatItemView(chatItem: ChatItem.getSample(1, .directSnd, .now, "🙂"), width: 360) + ChatItemView(chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂"), width: 360) + ChatItemView(chatItem: ChatItem.getSample(2, .directRcv, .now, "🙂🙂🙂🙂🙂🙂"), width: 360) } .previewLayout(.fixed(width: 360, height: 70)) } diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 0bfe69d11..864fa39a7 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -8,20 +8,27 @@ import SwiftUI +private let chatImageColorLight = Color(red: 0.9, green: 0.9, blue: 0.9) +private let chatImageColorDark = Color(red: 0.2, green: 0.2, blue: 0.2 ) + struct ChatView: View { @EnvironmentObject var chatModel: ChatModel + @Environment(\.colorScheme) var colorScheme @ObservedObject var chat: Chat @State private var inProgress: Bool = false @State private var showChatInfo = false var body: some View { - VStack { + let cInfo = chat.chatInfo + + return VStack { GeometryReader { g in ScrollViewReader { proxy in ScrollView { VStack(spacing: 5) { ForEach(chatModel.chatItems, id: \.id) { ChatItemView(chatItem: $0, width: g.size.width) + .frame(minWidth: 0, maxWidth: .infinity, alignment: $0.chatDir.sent ? .trailing : .leading) } .onAppear { scrollToBottom(proxy) } .onChange(of: chatModel.chatItems.count) { _ in scrollToBottom(proxy) } @@ -37,7 +44,7 @@ struct ChatView: View { SendMessageView(sendMessage: sendMessage, inProgress: inProgress) } - .navigationTitle(chat.chatInfo.chatViewName) + .navigationTitle(cInfo.chatViewName) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarLeading) { @@ -53,12 +60,19 @@ struct ChatView: View { showChatInfo = true } label: { HStack { - ChatInfoImage(chat: chat) - .frame(width: 32, height: 32) - .padding(.trailing, 4) + ChatInfoImage( + chat: chat, + color: colorScheme == .dark + ? chatImageColorDark + : chatImageColorLight + ) + .frame(width: 32, height: 32) + .padding(.trailing, 4) VStack { - Text(chat.chatInfo.localDisplayName).font(.headline) - Text(chat.chatInfo.fullName).font(.subheadline) + Text(cInfo.displayName).font(.headline) + if cInfo.fullName != "" && cInfo.displayName != cInfo.fullName { + Text(cInfo.fullName).font(.subheadline) + } } } .foregroundColor(.primary) @@ -94,16 +108,16 @@ struct ChatView_Previews: PreviewProvider { let chatModel = ChatModel() chatModel.chatId = "@1" chatModel.chatItems = [ - chatItemSample(1, .directSnd, .now, "hello"), - chatItemSample(2, .directRcv, .now, "hi"), - chatItemSample(3, .directRcv, .now, "hi there"), - chatItemSample(4, .directRcv, .now, "hello again"), - chatItemSample(5, .directSnd, .now, "hi there!!!"), - chatItemSample(6, .directSnd, .now, "how are you?"), - chatItemSample(7, .directSnd, .now, "👍👍👍👍"), - chatItemSample(8, .directSnd, .now, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") + ChatItem.getSample(1, .directSnd, .now, "hello"), + ChatItem.getSample(2, .directRcv, .now, "hi"), + ChatItem.getSample(3, .directRcv, .now, "hi there"), + ChatItem.getSample(4, .directRcv, .now, "hello again"), + ChatItem.getSample(5, .directSnd, .now, "hi there!!!"), + ChatItem.getSample(6, .directSnd, .now, "how are you?"), + ChatItem.getSample(7, .directSnd, .now, "👍👍👍👍"), + ChatItem.getSample(8, .directSnd, .now, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") ] - return ChatView(chat: Chat(chatInfo: sampleDirectChatInfo, chatItems: [])) + return ChatView(chat: Chat(chatInfo: ChatInfo.sampleData.direct, chatItems: [])) .environmentObject(chatModel) } } diff --git a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift index 5f82d44ae..b26ed3f30 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift @@ -175,15 +175,15 @@ struct ChatListNavLink_Previews: PreviewProvider { @State var chatId: String? = "@1" return Group { ChatListNavLink(chat: Chat( - chatInfo: sampleDirectChatInfo, - chatItems: [chatItemSample(1, .directSnd, .now, "hello")] + chatInfo: ChatInfo.sampleData.direct, + chatItems: [ChatItem.getSample(1, .directSnd, .now, "hello")] )) ChatListNavLink(chat: Chat( - chatInfo: sampleDirectChatInfo, - chatItems: [chatItemSample(1, .directSnd, .now, "hello")] + chatInfo: ChatInfo.sampleData.direct, + chatItems: [ChatItem.getSample(1, .directSnd, .now, "hello")] )) ChatListNavLink(chat: Chat( - chatInfo: sampleContactRequestChatInfo, + chatInfo: ChatInfo.sampleData.contactRequest, chatItems: [] )) } diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 5e24ae3b3..ba6082e9c 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -91,20 +91,20 @@ struct ChatListView_Previews: PreviewProvider { let chatModel = ChatModel() chatModel.chats = [ Chat( - chatInfo: sampleDirectChatInfo, - chatItems: [chatItemSample(1, .directSnd, .now, "hello")] + chatInfo: ChatInfo.sampleData.direct, + chatItems: [ChatItem.getSample(1, .directSnd, .now, "hello")] ), Chat( - chatInfo: sampleGroupChatInfo, - chatItems: [chatItemSample(1, .directSnd, .now, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")] + chatInfo: ChatInfo.sampleData.group, + chatItems: [ChatItem.getSample(1, .directSnd, .now, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")] ), Chat( - chatInfo: sampleContactRequestChatInfo, + chatInfo: ChatInfo.sampleData.contactRequest, chatItems: [] ) ] - return ChatListView(user: sampleUser) + return ChatListView(user: User.sampleData) .environmentObject(chatModel) } } diff --git a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift index 8905c99b7..012f57791 100644 --- a/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatPreviewView.swift @@ -46,7 +46,7 @@ struct ChatPreviewView: View { .padding(.horizontal, 8) if let cItem = cItem { - Text(cItem.content.text) + Text(chatItemText(cItem)) .frame(minWidth: 0, maxWidth: .infinity, minHeight: 44, maxHeight: 44, alignment: .topLeading) .padding([.leading, .trailing], 8) .padding(.bottom, 4) @@ -60,22 +60,30 @@ struct ChatPreviewView: View { } } } + + private func chatItemText(_ cItem: ChatItem) -> String { + let t = cItem.content.text + if case let .groupRcv(groupMember) = cItem.chatDir { + return groupMember.memberProfile.displayName + ": " + t + } + return t + } } struct ChatPreviewView_Previews: PreviewProvider { static var previews: some View { Group{ ChatPreviewView(chat: Chat( - chatInfo: sampleDirectChatInfo, + chatInfo: ChatInfo.sampleData.direct, chatItems: [] )) ChatPreviewView(chat: Chat( - chatInfo: sampleDirectChatInfo, - chatItems: [chatItemSample(1, .directSnd, .now, "hello")] + chatInfo: ChatInfo.sampleData.direct, + chatItems: [ChatItem.getSample(1, .directSnd, .now, "hello")] )) ChatPreviewView(chat: Chat( - chatInfo: sampleGroupChatInfo, - chatItems: [chatItemSample(1, .directSnd, .now, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")] + chatInfo: ChatInfo.sampleData.group, + chatItems: [ChatItem.getSample(1, .directSnd, .now, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")] )) } .previewLayout(.fixed(width: 360, height: 78)) diff --git a/apps/ios/Shared/Views/ChatList/ContactRequestView.swift b/apps/ios/Shared/Views/ChatList/ContactRequestView.swift index 8447a253f..2acd47c70 100644 --- a/apps/ios/Shared/Views/ChatList/ContactRequestView.swift +++ b/apps/ios/Shared/Views/ChatList/ContactRequestView.swift @@ -47,7 +47,7 @@ struct ContactRequestView: View { struct ContactRequestView_Previews: PreviewProvider { static var previews: some View { - ContactRequestView(contactRequest: sampleContactRequest) + ContactRequestView(contactRequest: UserContactRequest.sampleData) .previewLayout(.fixed(width: 360, height: 80)) } } diff --git a/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift b/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift index a50158a38..6f95a9be9 100644 --- a/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift +++ b/apps/ios/Shared/Views/Helpers/ChatInfoImage.swift @@ -10,6 +10,7 @@ import SwiftUI struct ChatInfoImage: View { @ObservedObject var chat: Chat + var color = Color(uiColor: .tertiarySystemGroupedBackground) var body: some View { var iconName: String @@ -21,13 +22,16 @@ struct ChatInfoImage: View { return Image(systemName: iconName) .resizable() - .foregroundColor(Color(uiColor: .secondarySystemBackground)) + .foregroundColor(color) } } struct ChatInfoImage_Previews: PreviewProvider { static var previews: some View { - ChatInfoImage(chat: Chat(chatInfo: sampleDirectChatInfo, chatItems: [])) - .previewLayout(.fixed(width: 63, height: 63)) + ChatInfoImage( + chat: Chat(chatInfo: ChatInfo.sampleData.direct, chatItems: []) + , color: Color(red: 0.9, green: 0.9, blue: 0.9) + ) + .previewLayout(.fixed(width: 63, height: 63)) } } diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift index a9b1ed3bd..9d901956e 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift @@ -64,7 +64,7 @@ struct SettingsView: View { struct SettingsView_Previews: PreviewProvider { static var previews: some View { let chatModel = ChatModel() - chatModel.currentUser = sampleUser + chatModel.currentUser = User.sampleData return SettingsView() .environmentObject(chatModel) } diff --git a/apps/ios/Shared/Views/UserSettings/UserProfile.swift b/apps/ios/Shared/Views/UserSettings/UserProfile.swift index 6487e2520..ac252ed83 100644 --- a/apps/ios/Shared/Views/UserSettings/UserProfile.swift +++ b/apps/ios/Shared/Views/UserSettings/UserProfile.swift @@ -77,7 +77,7 @@ struct UserProfile: View { struct UserProfile_Previews: PreviewProvider { static var previews: some View { let chatModel = ChatModel() - chatModel.currentUser = sampleUser + chatModel.currentUser = User.sampleData return UserProfile() .environmentObject(chatModel) } diff --git a/apps/ios/SimpleX--iOS--Info.plist b/apps/ios/SimpleX--iOS--Info.plist index 08407cc1c..b8279472c 100644 --- a/apps/ios/SimpleX--iOS--Info.plist +++ b/apps/ios/SimpleX--iOS--Info.plist @@ -2,6 +2,10 @@ + BGTaskSchedulerPermittedIdentifiers + + chat.simplex.app.receive + CFBundleURLTypes @@ -15,5 +19,9 @@ + UIBackgroundModes + + fetch + diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 05920d4a6..ffd38c356 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -763,7 +763,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_PREVIEWS = YES; @@ -783,7 +783,7 @@ LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Libraries"; "LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = "$(PROJECT_DIR)/Libraries/ios"; "LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(PROJECT_DIR)/Libraries/sim"; - MARKETING_VERSION = 0.2.1; + MARKETING_VERSION = 0.2.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos; @@ -803,7 +803,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_PREVIEWS = YES; @@ -823,7 +823,7 @@ LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/Libraries"; "LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = "$(PROJECT_DIR)/Libraries/ios"; "LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(PROJECT_DIR)/Libraries/sim"; - MARKETING_VERSION = 0.2.1; + MARKETING_VERSION = 0.2.2; PRODUCT_BUNDLE_IDENTIFIER = chat.simplex.app; PRODUCT_NAME = SimpleX; SDKROOT = iphoneos;