mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-03-31 07:35:55 +00:00
large emojis, full contact names, contact createdAt, process profile updates, etc. (#268)
This commit is contained in:
committed by
GitHub
parent
214ecf605b
commit
e424e9328b
@@ -126,12 +126,26 @@ enum ChatInfo: Identifiable, Decodable {
|
||||
var localDisplayName: String {
|
||||
get {
|
||||
switch self {
|
||||
case let .direct(contact): return "@\(contact.localDisplayName)"
|
||||
case let .group(groupInfo): return "#\(groupInfo.localDisplayName)"
|
||||
case let .contactRequest(contactRequest): return "< @\(contactRequest.localDisplayName)"
|
||||
case let .direct(contact): return contact.localDisplayName
|
||||
case let .group(groupInfo): return groupInfo.localDisplayName
|
||||
case let .contactRequest(contactRequest): return contactRequest.localDisplayName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fullName: String {
|
||||
get {
|
||||
switch self {
|
||||
case let .direct(contact): return contact.profile.fullName
|
||||
case let .group(groupInfo): return groupInfo.groupProfile.fullName
|
||||
case let .contactRequest(contactRequest): return contactRequest.profile.fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var chatViewName: String {
|
||||
get { localDisplayName + (fullName == "" || fullName == localDisplayName ? "" : " / \(fullName)") }
|
||||
}
|
||||
|
||||
var id: String {
|
||||
get {
|
||||
@@ -162,6 +176,14 @@ enum ChatInfo: Identifiable, Decodable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var createdAt: Date {
|
||||
switch self {
|
||||
case let .direct(contact): return contact.createdAt
|
||||
case let .group(groupInfo): return groupInfo.createdAt
|
||||
case let .contactRequest(contactRequest): return contactRequest.createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let sampleDirectChatInfo = ChatInfo.direct(contact: sampleContact)
|
||||
@@ -200,6 +222,7 @@ struct Contact: Identifiable, Decodable {
|
||||
var profile: Profile
|
||||
var activeConn: Connection
|
||||
var viaGroup: Int64?
|
||||
var createdAt: Date
|
||||
|
||||
var id: String { get { "@\(contactId)" } }
|
||||
var apiId: Int64 { get { contactId } }
|
||||
@@ -210,7 +233,8 @@ let sampleContact = Contact(
|
||||
contactId: 1,
|
||||
localDisplayName: "alice",
|
||||
profile: sampleProfile,
|
||||
activeConn: sampleConnection
|
||||
activeConn: sampleConnection,
|
||||
createdAt: .now
|
||||
)
|
||||
|
||||
struct Connection: Decodable {
|
||||
@@ -223,6 +247,7 @@ struct UserContactRequest: Decodable {
|
||||
var contactRequestId: Int64
|
||||
var localDisplayName: ContactName
|
||||
var profile: Profile
|
||||
var createdAt: Date
|
||||
|
||||
var id: String { get { "<@\(contactRequestId)" } }
|
||||
|
||||
@@ -232,13 +257,15 @@ struct UserContactRequest: Decodable {
|
||||
let sampleContactRequest = UserContactRequest(
|
||||
contactRequestId: 1,
|
||||
localDisplayName: "alice",
|
||||
profile: sampleProfile
|
||||
profile: sampleProfile,
|
||||
createdAt: .now
|
||||
)
|
||||
|
||||
struct GroupInfo: Identifiable, Decodable {
|
||||
var groupId: Int64
|
||||
var localDisplayName: GroupName
|
||||
var groupProfile: GroupProfile
|
||||
var createdAt: Date
|
||||
|
||||
var id: String { get { "#\(groupId)" } }
|
||||
|
||||
@@ -248,7 +275,8 @@ struct GroupInfo: Identifiable, Decodable {
|
||||
let sampleGroupInfo = GroupInfo(
|
||||
groupId: 1,
|
||||
localDisplayName: "team",
|
||||
groupProfile: sampleGroupProfile
|
||||
groupProfile: sampleGroupProfile,
|
||||
createdAt: .now
|
||||
)
|
||||
|
||||
struct GroupProfile: Codable {
|
||||
|
||||
@@ -84,6 +84,7 @@ enum ChatResponse: Decodable, Error {
|
||||
case receivedContactRequest(contactRequest: UserContactRequest)
|
||||
case acceptingContactRequest(contact: Contact)
|
||||
case contactRequestRejected
|
||||
case contactUpdated(toContact: Contact)
|
||||
case newChatItem(chatItem: AChatItem)
|
||||
case chatCmdError(chatError: ChatError)
|
||||
|
||||
@@ -106,6 +107,7 @@ enum ChatResponse: Decodable, Error {
|
||||
case .receivedContactRequest: return "receivedContactRequest"
|
||||
case .acceptingContactRequest: return "acceptingContactRequest"
|
||||
case .contactRequestRejected: return "contactRequestRejected"
|
||||
case .contactUpdated: return "contactUpdated"
|
||||
case .newChatItem: return "newChatItem"
|
||||
case .chatCmdError: return "chatCmdError"
|
||||
}
|
||||
@@ -131,6 +133,7 @@ enum ChatResponse: Decodable, Error {
|
||||
case let .receivedContactRequest(contactRequest): return String(describing: contactRequest)
|
||||
case let .acceptingContactRequest(contact): return String(describing: contact)
|
||||
case .contactRequestRejected: return noDetails
|
||||
case let .contactUpdated(toContact): return String(describing: toContact)
|
||||
case let .newChatItem(chatItem): return String(describing: chatItem)
|
||||
case let .chatCmdError(chatError): return String(describing: chatError)
|
||||
}
|
||||
@@ -293,7 +296,7 @@ func apiRejectContactRequest(contactReqId: Int64) throws {
|
||||
|
||||
func processReceivedMsg(_ chatModel: ChatModel, _ res: ChatResponse) {
|
||||
DispatchQueue.main.async {
|
||||
chatModel.terminalItems.append(.resp(Date.now, res))
|
||||
chatModel.terminalItems.append(.resp(.now, res))
|
||||
switch res {
|
||||
case let .contactConnected(contact):
|
||||
let cInfo = ChatInfo.direct(contact: contact)
|
||||
@@ -307,6 +310,11 @@ func processReceivedMsg(_ chatModel: ChatModel, _ res: ChatResponse) {
|
||||
chatInfo: ChatInfo.contactRequest(contactRequest: contactRequest),
|
||||
chatItems: []
|
||||
))
|
||||
case let .contactUpdated(toContact):
|
||||
let cInfo = ChatInfo.direct(contact: toContact)
|
||||
if chatModel.hasChat(toContact.id) {
|
||||
chatModel.updateChatInfo(cInfo)
|
||||
}
|
||||
case let .newChatItem(aChatItem):
|
||||
chatModel.addChatItem(aChatItem.chatInfo, aChatItem.chatItem)
|
||||
default:
|
||||
|
||||
43
apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift
Normal file
43
apps/ios/Shared/Views/Chat/ChatItem/EmojiItemView.swift
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// EmojiItemView.swift
|
||||
// SimpleX
|
||||
//
|
||||
// Created by Evgeny Poberezkin on 04/02/2022.
|
||||
// Copyright © 2022 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct EmojiItemView: View {
|
||||
var chatItem: ChatItem
|
||||
|
||||
var body: some View {
|
||||
let sent = chatItem.chatDir.sent
|
||||
|
||||
VStack {
|
||||
Text(chatItem.content.text)
|
||||
.font(Font.custom("Emoji", size: 48, relativeTo: .largeTitle))
|
||||
.padding(.top, 8)
|
||||
.padding(.horizontal, 6)
|
||||
.frame(maxWidth: .infinity, alignment: sent ? .trailing : .leading)
|
||||
Text(getDateFormatter().string(from: chatItem.meta.itemTs))
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
.padding(.bottom, 8)
|
||||
.padding(.horizontal, 12)
|
||||
.frame(maxWidth: .infinity, alignment: sent ? .trailing : .leading)
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.frame(maxWidth: .infinity, alignment: sent ? .trailing : .leading)
|
||||
}
|
||||
}
|
||||
|
||||
struct EmojiItemView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group{
|
||||
EmojiItemView(chatItem: chatItemSample(1, .directSnd, .now, "🙂"))
|
||||
EmojiItemView(chatItem: chatItemSample(2, .directRcv, .now, "👍"))
|
||||
}
|
||||
.previewLayout(.fixed(width: 360, height: 70))
|
||||
}
|
||||
}
|
||||
55
apps/ios/Shared/Views/Chat/ChatItem/TextItemView.swift
Normal file
55
apps/ios/Shared/Views/Chat/ChatItem/TextItemView.swift
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// TextItemView.swift
|
||||
// SimpleX
|
||||
//
|
||||
// Created by Evgeny Poberezkin on 04/02/2022.
|
||||
// Copyright © 2022 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct TextItemView: View {
|
||||
var chatItem: ChatItem
|
||||
var width: CGFloat
|
||||
|
||||
var body: some View {
|
||||
let sent = chatItem.chatDir.sent
|
||||
let minWidth = min(200, width)
|
||||
let maxWidth = min(300, width * 0.78)
|
||||
|
||||
return VStack {
|
||||
Text(chatItem.content.text)
|
||||
.padding(.top, 8)
|
||||
.padding(.horizontal, 12)
|
||||
.frame(minWidth: minWidth, maxWidth: maxWidth, alignment: .leading)
|
||||
.foregroundColor(sent ? .white : .primary)
|
||||
.textSelection(.enabled)
|
||||
Text(getDateFormatter().string(from: chatItem.meta.itemTs))
|
||||
.font(.caption)
|
||||
.foregroundColor(sent ? .white : .secondary)
|
||||
.padding(.bottom, 8)
|
||||
.padding(.horizontal, 12)
|
||||
.frame(minWidth: minWidth, maxWidth: maxWidth, alignment: .trailing)
|
||||
}
|
||||
.background(sent ? .blue : Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.cornerRadius(10)
|
||||
.padding(.horizontal)
|
||||
.frame(
|
||||
minWidth: 200,
|
||||
maxWidth: .infinity,
|
||||
minHeight: 0,
|
||||
maxHeight: .infinity,
|
||||
alignment: sent ? .trailing : .leading
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct TextItemView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group{
|
||||
TextItemView(chatItem: chatItemSample(1, .directSnd, .now, "hello"), width: 360)
|
||||
TextItemView(chatItem: chatItemSample(2, .directRcv, .now, "hello there too"), width: 360)
|
||||
}
|
||||
.previewLayout(.fixed(width: 360, height: 70))
|
||||
}
|
||||
}
|
||||
@@ -12,36 +12,14 @@ private var dateFormatter: DateFormatter?
|
||||
|
||||
struct ChatItemView: View {
|
||||
var chatItem: ChatItem
|
||||
var width: CGFloat
|
||||
|
||||
var body: some View {
|
||||
let sent = chatItem.chatDir.sent
|
||||
|
||||
return VStack {
|
||||
Group {
|
||||
Text(chatItem.content.text)
|
||||
.padding(.top, 8)
|
||||
.padding(.horizontal, 12)
|
||||
.frame(minWidth: 200, maxWidth: 300, alignment: .leading)
|
||||
.foregroundColor(sent ? .white : .primary)
|
||||
.textSelection(.enabled)
|
||||
Text(getDateFormatter().string(from: chatItem.meta.itemTs))
|
||||
.font(.subheadline)
|
||||
.foregroundColor(sent ? .white : .secondary)
|
||||
.padding(.bottom, 8)
|
||||
.padding(.horizontal, 12)
|
||||
.frame(minWidth: 200, maxWidth: 300, alignment: .trailing)
|
||||
}
|
||||
if (isShortEmoji(chatItem.content.text)) {
|
||||
EmojiItemView(chatItem: chatItem)
|
||||
} else {
|
||||
TextItemView(chatItem: chatItem, width: width)
|
||||
}
|
||||
.background(sent ? .blue : Color(uiColor: .tertiarySystemGroupedBackground))
|
||||
.cornerRadius(10)
|
||||
.padding(.horizontal)
|
||||
.frame(
|
||||
minWidth: 200,
|
||||
maxWidth: .infinity,
|
||||
minHeight: 0,
|
||||
maxHeight: .infinity,
|
||||
alignment: sent ? .trailing : .leading
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,9 +34,12 @@ func getDateFormatter() -> DateFormatter {
|
||||
struct ChatItemView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
Group{
|
||||
ChatItemView(chatItem: chatItemSample(1, .directSnd, Date.now, "hello"))
|
||||
ChatItemView(chatItem: chatItemSample(2, .directRcv, Date.now, "hello there too"))
|
||||
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)
|
||||
}
|
||||
.previewLayout(.fixed(width: 300, height: 70))
|
||||
.previewLayout(.fixed(width: 360, height: 70))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,16 @@ struct ChatView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
ScrollViewReader { proxy in
|
||||
ScrollView {
|
||||
VStack(spacing: 5) {
|
||||
ForEach(chatModel.chatItems, id: \.id) {
|
||||
ChatItemView(chatItem: $0)
|
||||
GeometryReader { g in
|
||||
ScrollViewReader { proxy in
|
||||
ScrollView {
|
||||
VStack(spacing: 5) {
|
||||
ForEach(chatModel.chatItems, id: \.id) {
|
||||
ChatItemView(chatItem: $0, width: g.size.width)
|
||||
}
|
||||
.onAppear { scrollToBottom(proxy) }
|
||||
.onChange(of: chatModel.chatItems.count) { _ in scrollToBottom(proxy) }
|
||||
}
|
||||
.onAppear { scrollToBottom(proxy) }
|
||||
.onChange(of: chatModel.chatItems.count) { _ in scrollToBottom(proxy) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +33,7 @@ struct ChatView: View {
|
||||
|
||||
SendMessageView(sendMessage: sendMessage, inProgress: inProgress)
|
||||
}
|
||||
.navigationTitle(chatInfo.localDisplayName)
|
||||
.navigationTitle(chatInfo.chatViewName)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button { chatModel.chatId = nil } label: {
|
||||
@@ -68,13 +70,13 @@ struct ChatView_Previews: PreviewProvider {
|
||||
let chatModel = ChatModel()
|
||||
chatModel.chatId = "@1"
|
||||
chatModel.chatItems = [
|
||||
chatItemSample(1, .directSnd, Date.now, "hello"),
|
||||
chatItemSample(2, .directRcv, Date.now, "hi"),
|
||||
chatItemSample(3, .directRcv, Date.now, "hi there"),
|
||||
chatItemSample(4, .directRcv, Date.now, "hello again"),
|
||||
chatItemSample(5, .directSnd, Date.now, "hi there!!!"),
|
||||
chatItemSample(6, .directSnd, Date.now, "how are you?"),
|
||||
chatItemSample(7, .directSnd, Date.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.")
|
||||
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, "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(chatInfo: sampleDirectChatInfo)
|
||||
.environmentObject(chatModel)
|
||||
|
||||
27
apps/ios/Shared/Views/Chat/Emoji.swift
Normal file
27
apps/ios/Shared/Views/Chat/Emoji.swift
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Emoji.swift
|
||||
// SimpleX
|
||||
//
|
||||
// Created by Evgeny Poberezkin on 04/02/2022.
|
||||
// Copyright © 2022 SimpleX Chat. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
private func isSimpleEmoji(_ c: Character) -> Bool {
|
||||
guard let firstScalar = c.unicodeScalars.first else { return false }
|
||||
return firstScalar.properties.isEmoji && firstScalar.value > 0x238C
|
||||
}
|
||||
|
||||
private func isCombinedIntoEmoji(_ c: Character) -> Bool {
|
||||
c.unicodeScalars.count > 1 && c.unicodeScalars.first?.properties.isEmoji ?? false
|
||||
}
|
||||
|
||||
func isEmoji(_ c: Character) -> Bool {
|
||||
isSimpleEmoji(c) || isCombinedIntoEmoji(c)
|
||||
}
|
||||
|
||||
func isShortEmoji(_ str: String) -> Bool {
|
||||
let s = str.trimmingCharacters(in: .whitespaces)
|
||||
return s.count <= 3 && s.allSatisfy(isEmoji)
|
||||
}
|
||||
@@ -176,11 +176,11 @@ struct ChatListNavLink_Previews: PreviewProvider {
|
||||
return Group {
|
||||
ChatListNavLink(chat: Chat(
|
||||
chatInfo: sampleDirectChatInfo,
|
||||
chatItems: [chatItemSample(1, .directSnd, Date.now, "hello")]
|
||||
chatItems: [chatItemSample(1, .directSnd, .now, "hello")]
|
||||
))
|
||||
ChatListNavLink(chat: Chat(
|
||||
chatInfo: sampleDirectChatInfo,
|
||||
chatItems: [chatItemSample(1, .directSnd, Date.now, "hello")]
|
||||
chatItems: [chatItemSample(1, .directSnd, .now, "hello")]
|
||||
))
|
||||
ChatListNavLink(chat: Chat(
|
||||
chatInfo: sampleContactRequestChatInfo,
|
||||
|
||||
@@ -92,11 +92,11 @@ struct ChatListView_Previews: PreviewProvider {
|
||||
chatModel.chats = [
|
||||
Chat(
|
||||
chatInfo: sampleDirectChatInfo,
|
||||
chatItems: [chatItemSample(1, .directSnd, Date.now, "hello")]
|
||||
chatItems: [chatItemSample(1, .directSnd, .now, "hello")]
|
||||
),
|
||||
Chat(
|
||||
chatInfo: sampleGroupChatInfo,
|
||||
chatItems: [chatItemSample(1, .directSnd, Date.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.")]
|
||||
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.")]
|
||||
),
|
||||
Chat(
|
||||
chatInfo: sampleContactRequestChatInfo,
|
||||
|
||||
@@ -13,38 +13,46 @@ struct ChatPreviewView: View {
|
||||
|
||||
var body: some View {
|
||||
let cItem = chat.chatItems.last
|
||||
return VStack(spacing: 4) {
|
||||
HStack(alignment: .top) {
|
||||
Text(chat.chatInfo.localDisplayName)
|
||||
.font(.title3)
|
||||
.fontWeight(.bold)
|
||||
.padding(.leading, 8)
|
||||
.padding(.top, 4)
|
||||
.frame(maxHeight: .infinity, alignment: .topLeading)
|
||||
Spacer()
|
||||
if let cItem = cItem {
|
||||
Text(getDateFormatter().string(from: cItem.meta.itemTs))
|
||||
var iconName: String
|
||||
switch chat.chatInfo {
|
||||
case .direct: iconName = "person.crop.circle.fill"
|
||||
case .group: iconName = "person.2.circle.fill"
|
||||
default: iconName = "circle.fill"
|
||||
}
|
||||
return HStack(spacing: 8) {
|
||||
Image(systemName: iconName)
|
||||
.resizable()
|
||||
.foregroundColor(Color(uiColor: .secondarySystemBackground))
|
||||
.frame(width: 63, height: 63)
|
||||
.padding(.leading, 4)
|
||||
VStack(spacing: 0) {
|
||||
HStack(alignment: .top) {
|
||||
Text(chat.chatInfo.chatViewName)
|
||||
.font(.title3)
|
||||
.fontWeight(.bold)
|
||||
.frame(maxHeight: .infinity, alignment: .topLeading)
|
||||
Spacer()
|
||||
Text(getDateFormatter().string(from: cItem?.meta.itemTs ?? chat.chatInfo.createdAt))
|
||||
.font(.subheadline)
|
||||
.padding(.trailing, 8)
|
||||
.padding(.top, 4)
|
||||
.frame(minWidth: 60, alignment: .trailing)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.padding(.top, 4)
|
||||
.padding(.horizontal, 8)
|
||||
|
||||
if let cItem = cItem {
|
||||
Text(cItem.content.text)
|
||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 44, maxHeight: 44, alignment: .topLeading)
|
||||
.padding([.leading, .trailing], 8)
|
||||
.padding(.bottom, 4)
|
||||
}
|
||||
else if case let .direct(contact) = chat.chatInfo, !contact.connected {
|
||||
Text("Connecting...")
|
||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 44, maxHeight: 44, alignment: .topLeading)
|
||||
.padding([.leading, .trailing], 8)
|
||||
.padding(.bottom, 4)
|
||||
}
|
||||
}
|
||||
if let cItem = cItem {
|
||||
Text(cItem.content.text)
|
||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 44, maxHeight: 44, alignment: .topLeading)
|
||||
.padding([.leading, .trailing], 8)
|
||||
.padding(.bottom, 4)
|
||||
.padding(.top, 1)
|
||||
}
|
||||
// else if case let .direct(contact) = chatPreview.chatInfo, !contact.connected {
|
||||
// Text("Connecting...")
|
||||
// .frame(minWidth: 0, maxWidth: .infinity, minHeight: 44, maxHeight: 44, alignment: .topLeading)
|
||||
// .padding([.leading, .trailing], 8)
|
||||
// .padding(.bottom, 4)
|
||||
// .padding(.top, 1)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,13 +66,13 @@ struct ChatPreviewView_Previews: PreviewProvider {
|
||||
))
|
||||
ChatPreviewView(chat: Chat(
|
||||
chatInfo: sampleDirectChatInfo,
|
||||
chatItems: [chatItemSample(1, .directSnd, Date.now, "hello")]
|
||||
chatItems: [chatItemSample(1, .directSnd, .now, "hello")]
|
||||
))
|
||||
ChatPreviewView(chat: Chat(
|
||||
chatInfo: sampleGroupChatInfo,
|
||||
chatItems: [chatItemSample(1, .directSnd, Date.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.")]
|
||||
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.")]
|
||||
))
|
||||
}
|
||||
.previewLayout(.fixed(width: 360, height: 80))
|
||||
.previewLayout(.fixed(width: 360, height: 78))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ struct ContactRequestView: View {
|
||||
var body: some View {
|
||||
return VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(alignment: .top) {
|
||||
Text("@\(contactRequest.localDisplayName)")
|
||||
Text(ChatInfo.contactRequest(contactRequest: contactRequest).chatViewName)
|
||||
.font(.title3)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(.blue)
|
||||
@@ -22,7 +22,7 @@ struct ContactRequestView: View {
|
||||
.padding(.top, 4)
|
||||
.frame(maxHeight: .infinity, alignment: .topLeading)
|
||||
Spacer()
|
||||
Text("12:34")// getDateFormatter().string(from: cItem.meta.itemTs))
|
||||
Text(getDateFormatter().string(from: contactRequest.createdAt))
|
||||
.font(.subheadline)
|
||||
.padding(.trailing, 28)
|
||||
.padding(.top, 4)
|
||||
|
||||
@@ -52,14 +52,14 @@ struct TerminalView: View {
|
||||
|
||||
func sendMessage(_ cmdStr: String) {
|
||||
let cmd = ChatCommand.string(cmdStr)
|
||||
chatModel.terminalItems.append(.cmd(Date.now, cmd))
|
||||
chatModel.terminalItems.append(.cmd(.now, cmd))
|
||||
|
||||
DispatchQueue.global().async {
|
||||
inProgress = true
|
||||
do {
|
||||
let r = try chatSendCmd(cmd)
|
||||
DispatchQueue.main.async {
|
||||
chatModel.terminalItems.append(.resp(Date.now, r))
|
||||
chatModel.terminalItems.append(.resp(.now, r))
|
||||
}
|
||||
} catch {
|
||||
print(error)
|
||||
@@ -73,8 +73,8 @@ struct TerminalView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let chatModel = ChatModel()
|
||||
chatModel.terminalItems = [
|
||||
.resp(Date.now, ChatResponse.response(type: "contactSubscribed", json: "{}")),
|
||||
.resp(Date.now, ChatResponse.response(type: "newChatItem", json: "{}"))
|
||||
.resp(.now, ChatResponse.response(type: "contactSubscribed", json: "{}")),
|
||||
.resp(.now, ChatResponse.response(type: "newChatItem", json: "{}"))
|
||||
]
|
||||
return NavigationView {
|
||||
TerminalView()
|
||||
|
||||
@@ -73,6 +73,12 @@
|
||||
5CCD403B27A5F9BE00368C90 /* CreateGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CCD403927A5F9BE00368C90 /* CreateGroupView.swift */; };
|
||||
5CE4406F27AD2648007B033A /* libHSsimplex-chat-1.1.0-1RUev578BUjGkBObUSYLQi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE4406D27AD2648007B033A /* libHSsimplex-chat-1.1.0-1RUev578BUjGkBObUSYLQi.a */; };
|
||||
5CE4407027AD2648007B033A /* libHSsimplex-chat-1.1.0-1RUev578BUjGkBObUSYLQi-ghc8.10.7.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5CE4406E27AD2648007B033A /* libHSsimplex-chat-1.1.0-1RUev578BUjGkBObUSYLQi-ghc8.10.7.a */; };
|
||||
5CE4407227ADB1D0007B033A /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407127ADB1D0007B033A /* Emoji.swift */; };
|
||||
5CE4407327ADB1D0007B033A /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407127ADB1D0007B033A /* Emoji.swift */; };
|
||||
5CE4407627ADB66A007B033A /* TextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407527ADB66A007B033A /* TextItemView.swift */; };
|
||||
5CE4407727ADB66A007B033A /* TextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407527ADB66A007B033A /* TextItemView.swift */; };
|
||||
5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407827ADB701007B033A /* EmojiItemView.swift */; };
|
||||
5CE4407A27ADB701007B033A /* EmojiItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE4407827ADB701007B033A /* EmojiItemView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -138,6 +144,9 @@
|
||||
5CCD403927A5F9BE00368C90 /* CreateGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateGroupView.swift; sourceTree = "<group>"; };
|
||||
5CE4406D27AD2648007B033A /* libHSsimplex-chat-1.1.0-1RUev578BUjGkBObUSYLQi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-1.1.0-1RUev578BUjGkBObUSYLQi.a"; sourceTree = "<group>"; };
|
||||
5CE4406E27AD2648007B033A /* libHSsimplex-chat-1.1.0-1RUev578BUjGkBObUSYLQi-ghc8.10.7.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-1.1.0-1RUev578BUjGkBObUSYLQi-ghc8.10.7.a"; sourceTree = "<group>"; };
|
||||
5CE4407127ADB1D0007B033A /* Emoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Emoji.swift; sourceTree = "<group>"; };
|
||||
5CE4407527ADB66A007B033A /* TextItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextItemView.swift; sourceTree = "<group>"; };
|
||||
5CE4407827ADB701007B033A /* EmojiItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiItemView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -198,9 +207,11 @@
|
||||
5C5F4AC227A5E9AF00B51EF1 /* Chat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5CE4407427ADB657007B033A /* ChatItem */,
|
||||
5C2E260E27A30FDC00F70299 /* ChatView.swift */,
|
||||
5C9FD96D27A5D6ED0075386C /* SendMessageView.swift */,
|
||||
5C1A4C1D27A715B700EAD5AD /* ChatItemView.swift */,
|
||||
5CE4407127ADB1D0007B033A /* Emoji.swift */,
|
||||
);
|
||||
path = Chat;
|
||||
sourceTree = "<group>";
|
||||
@@ -337,6 +348,15 @@
|
||||
path = ChatList;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5CE4407427ADB657007B033A /* ChatItem */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5CE4407527ADB66A007B033A /* TextItemView.swift */,
|
||||
5CE4407827ADB701007B033A /* EmojiItemView.swift */,
|
||||
);
|
||||
path = ChatItem;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -506,7 +526,9 @@
|
||||
files = (
|
||||
5C6AD81327A834E300348BD7 /* NewChatButton.swift in Sources */,
|
||||
5CB924D727A8563F00ACCCDD /* SettingsView.swift in Sources */,
|
||||
5CE4407627ADB66A007B033A /* TextItemView.swift in Sources */,
|
||||
5CB924E127A867BA00ACCCDD /* UserProfile.swift in Sources */,
|
||||
5CE4407927ADB701007B033A /* EmojiItemView.swift in Sources */,
|
||||
5C764E80279C7276000C6508 /* dummy.m in Sources */,
|
||||
5CB924E427A8683A00ACCCDD /* UserAddress.swift in Sources */,
|
||||
5C063D2727A4564100AEC577 /* ChatPreviewView.swift in Sources */,
|
||||
@@ -528,6 +550,7 @@
|
||||
5CC1C99527A6CF7F000D9FF6 /* ShareSheet.swift in Sources */,
|
||||
5C2E260727A2941F00F70299 /* SimpleXAPI.swift in Sources */,
|
||||
5CB924D427A853F100ACCCDD /* SettingsButton.swift in Sources */,
|
||||
5CE4407227ADB1D0007B033A /* Emoji.swift in Sources */,
|
||||
5C1A4C1E27A715B700EAD5AD /* ChatItemView.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -538,7 +561,9 @@
|
||||
files = (
|
||||
5C6AD81427A834E300348BD7 /* NewChatButton.swift in Sources */,
|
||||
5CB924D827A8563F00ACCCDD /* SettingsView.swift in Sources */,
|
||||
5CE4407727ADB66A007B033A /* TextItemView.swift in Sources */,
|
||||
5CB924E227A867BA00ACCCDD /* UserProfile.swift in Sources */,
|
||||
5CE4407A27ADB701007B033A /* EmojiItemView.swift in Sources */,
|
||||
5C764E81279C7276000C6508 /* dummy.m in Sources */,
|
||||
5CB924E527A8683A00ACCCDD /* UserAddress.swift in Sources */,
|
||||
5C063D2827A4564100AEC577 /* ChatPreviewView.swift in Sources */,
|
||||
@@ -560,6 +585,7 @@
|
||||
5CC1C99627A6CF7F000D9FF6 /* ShareSheet.swift in Sources */,
|
||||
5C2E260827A2941F00F70299 /* SimpleXAPI.swift in Sources */,
|
||||
5CB924D527A853F100ACCCDD /* SettingsButton.swift in Sources */,
|
||||
5CE4407327ADB1D0007B033A /* Emoji.swift in Sources */,
|
||||
5C1A4C1F27A715B700EAD5AD /* ChatItemView.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
Reference in New Issue
Block a user