mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-28 12:19:54 +00:00
* ios: fix XCode 16 regressions (tap not working on files, quotes, images, voice messages, etc.), open link previews on tap * fix voice recording * fix video, accepting calls from chat, preference toggles in chat * WIP message and meta * handle links in attributed strings * custom attribute for links to prevent race conditions with default tap handler
151 lines
5.8 KiB
Swift
151 lines
5.8 KiB
Swift
//
|
|
// CIGroupInvitationView.swift
|
|
// SimpleX (iOS)
|
|
//
|
|
// Created by JRoberts on 15.07.2022.
|
|
// Copyright © 2022 SimpleX Chat. All rights reserved.
|
|
//
|
|
|
|
import SwiftUI
|
|
import SimpleXChat
|
|
|
|
struct CIGroupInvitationView: View {
|
|
@EnvironmentObject var chatModel: ChatModel
|
|
@EnvironmentObject var theme: AppTheme
|
|
@Environment(\.showTimestamp) var showTimestamp: Bool
|
|
@ObservedObject var chat: Chat
|
|
var chatItem: ChatItem
|
|
var groupInvitation: CIGroupInvitation
|
|
var memberRole: GroupMemberRole
|
|
var chatIncognito: Bool = false
|
|
@State private var frameWidth: CGFloat = 0
|
|
@State private var inProgress = false
|
|
@State private var progressByTimeout = false
|
|
|
|
@AppStorage(DEFAULT_SHOW_SENT_VIA_RPOXY) private var showSentViaProxy = false
|
|
|
|
var body: some View {
|
|
let action = !chatItem.chatDir.sent && groupInvitation.status == .pending
|
|
let v = ZStack(alignment: .bottomTrailing) {
|
|
ZStack {
|
|
VStack(alignment: .leading) {
|
|
groupInfoView(action)
|
|
.padding(.horizontal, 2)
|
|
.padding(.top, 8)
|
|
.padding(.bottom, 6)
|
|
.overlay(DetermineWidth())
|
|
|
|
Divider().frame(width: frameWidth)
|
|
|
|
if action {
|
|
VStack(alignment: .leading, spacing: 2) {
|
|
groupInvitationText()
|
|
.overlay(DetermineWidth())
|
|
(
|
|
Text(chatIncognito ? "Tap to join incognito" : "Tap to join")
|
|
.foregroundColor(inProgress ? theme.colors.secondary : chatIncognito ? .indigo : theme.colors.primary)
|
|
.font(.callout)
|
|
+ Text(verbatim: " ")
|
|
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, colorMode: .transparent, showStatus: false, showEdited: false, showViaProxy: showSentViaProxy, showTimesamp: showTimestamp)
|
|
)
|
|
.overlay(DetermineWidth())
|
|
}
|
|
} else {
|
|
(
|
|
groupInvitationText()
|
|
+ Text(verbatim: " ")
|
|
+ ciMetaText(chatItem.meta, chatTTL: nil, encrypted: nil, colorMode: .transparent, showStatus: false, showEdited: false, showViaProxy: showSentViaProxy, showTimesamp: showTimestamp)
|
|
)
|
|
.overlay(DetermineWidth())
|
|
}
|
|
}
|
|
.padding(.bottom, 2)
|
|
|
|
if progressByTimeout {
|
|
ProgressView().scaleEffect(2)
|
|
}
|
|
}
|
|
|
|
CIMetaView(chat: chat, chatItem: chatItem, metaColor: theme.colors.secondary, showStatus: false, showEdited: false)
|
|
}
|
|
.padding(.horizontal, 12)
|
|
.padding(.vertical, 6)
|
|
.background { chatItemFrameColor(chatItem, theme).modifier(ChatTailPadding()) }
|
|
.textSelection(.disabled)
|
|
.onPreferenceChange(DetermineWidth.Key.self) { frameWidth = $0 }
|
|
.onChange(of: inProgress) { inProgress in
|
|
if inProgress {
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
progressByTimeout = inProgress
|
|
}
|
|
} else {
|
|
progressByTimeout = false
|
|
}
|
|
}
|
|
|
|
if action {
|
|
v.simultaneousGesture(TapGesture().onEnded {
|
|
inProgress = true
|
|
joinGroup(groupInvitation.groupId) {
|
|
await MainActor.run { inProgress = false }
|
|
}
|
|
})
|
|
.disabled(inProgress)
|
|
} else {
|
|
v
|
|
}
|
|
}
|
|
|
|
private func groupInfoView(_ action: Bool) -> some View {
|
|
var color: Color
|
|
if action && !inProgress {
|
|
color = chatIncognito ? .indigo : theme.colors.primary
|
|
} else {
|
|
color = Color(uiColor: .tertiaryLabel)
|
|
}
|
|
return HStack(alignment: .top) {
|
|
ProfileImage(
|
|
imageStr: groupInvitation.groupProfile.image,
|
|
iconName: "person.2.circle.fill",
|
|
size: 44,
|
|
color: color
|
|
)
|
|
.padding(.trailing, 4)
|
|
VStack(alignment: .leading) {
|
|
let p = groupInvitation.groupProfile
|
|
Text(p.displayName).font(.headline).lineLimit(2)
|
|
if p.fullName != "" && p.displayName != p.fullName {
|
|
Text(p.fullName).font(.subheadline).lineLimit(2)
|
|
}
|
|
}
|
|
.frame(minHeight: 44)
|
|
}
|
|
}
|
|
|
|
private func groupInvitationText() -> Text {
|
|
Text(groupInvitationStr())
|
|
.font(.callout)
|
|
}
|
|
|
|
private func groupInvitationStr() -> LocalizedStringKey {
|
|
if chatItem.chatDir.sent {
|
|
return "You sent group invitation"
|
|
} else {
|
|
switch groupInvitation.status {
|
|
case .pending: return "You are invited to group"
|
|
case .accepted: return "You joined this group"
|
|
case .rejected: return "You rejected group invitation"
|
|
case .expired: return "Group invitation expired"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct CIGroupInvitationView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
Group {
|
|
CIGroupInvitationView(chat: Chat.sampleData, chatItem: ChatItem.getGroupInvitationSample(), groupInvitation: CIGroupInvitation.getSample(groupProfile: GroupProfile(displayName: "team", fullName: "team")), memberRole: .admin)
|
|
CIGroupInvitationView(chat: Chat.sampleData, chatItem: ChatItem.getGroupInvitationSample(), groupInvitation: CIGroupInvitation.getSample(status: .accepted), memberRole: .admin)
|
|
}
|
|
}
|
|
}
|