Files
simplex-chat/apps/ios/Shared/Views/Chat/ComposeMessage/ContextItemView.swift
Evgeny f49d985119 ios: sharing channel links/cards (#6821)
* ios: sharing channel links/cards

* update nix shas

* improve

* fix preview

* change condition

* move button for owner

* refactor

* refactor 2

* fix sheets

* MsgChatLink JSON encoding

* correct default icon when editing group profile

* drop link from card

* card layout

* strip link from text

* remove file ref

* share via chat when created

* rename file, do not show text when there is no text

* better card layout

* padding, info string

* add log

* padding

* text layout

* warning emoji if signature verification failed

* chat link preview in chat list

* description

* alert information

* tappable preview

* better

* conditional border color

* sending and forwarding views

* small link icons for forwarding

* strip link in one place

* forwarded context

* quote view for chat links

* reduce diff, remove unnecessary changes

* simplify

* trim description

* diff

---------

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
2026-04-17 21:10:00 +01:00

105 lines
4.1 KiB
Swift

//
// ContextItemView.swift
// SimpleX
//
// Created by JRoberts on 13/03/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
import SimpleXChat
struct ContextItemView: View {
@EnvironmentObject var theme: AppTheme
@ObservedObject var chat: Chat
let contextItems: [ChatItem]
let contextIcon: String
let cancelContextItem: () -> Void
var contextIconForeground: Color? = nil
var showSender: Bool = true
var body: some View {
HStack {
Image(systemName: contextIcon)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
.foregroundColor(contextIconForeground ?? theme.colors.secondary)
if let singleItem = contextItems.first, contextItems.count == 1 {
if showSender, let sender = singleItem.memberDisplayName {
VStack(alignment: .leading, spacing: 4) {
Text(sender).font(.caption).foregroundColor(theme.colors.secondary)
msgContentView(lines: 2, contextItem: singleItem)
}
} else {
msgContentView(lines: 3, contextItem: singleItem)
}
} else {
Text(
chat.chatInfo.chatType == .local
? "Saving \(contextItems.count) messages"
: "Forwarding \(contextItems.count) messages"
)
.italic()
}
Spacer()
Button {
withAnimation {
cancelContextItem()
}
} label: {
Image(systemName: "multiply")
}
.tint(theme.colors.primary)
}
.padding(12)
.frame(minHeight: 54)
.frame(maxWidth: .infinity)
.background(background)
}
private var background: Color {
contextItems.first
.map { chatItemFrameColor($0, theme) }
?? Color(uiColor: .tertiarySystemBackground)
}
private func msgContentView(lines: Int, contextItem: ChatItem) -> some View {
contextMsgPreview(contextItem)
.multilineTextAlignment(isRightToLeft(contextItem.text) ? .trailing : .leading)
.lineLimit(lines)
}
private func contextMsgPreview(_ contextItem: ChatItem) -> some View {
let r = messageText(contextItem.text, contextItem.formattedText, sender: nil, preview: true, mentions: contextItem.mentions, userMemberId: nil, showSecrets: nil, backgroundColor: UIColor(background), stripLink: contextItem.content.msgContent?.chatLinkStr)
let t = attachment() + Text(AttributedString(r.string))
return t.if(r.hasSecrets, transform: hiddenSecretsView)
func attachment() -> Text {
let isFileLoaded = if let fileSource = getLoadedFileSource(contextItem.file) {
FileManager.default.fileExists(atPath: getAppFilePath(fileSource.filePath).path)
} else { false }
switch contextItem.content.msgContent {
case .file: return isFileLoaded ? image("doc.fill") : Text("")
case .image: return image("photo")
case .voice: return isFileLoaded ? image("play.fill") : Text("")
case let .chat(_, chatLink, _):
let hasText = contextItem.text != chatLink.connLinkStr
return image(chatLink.smallIconName) + Text(chatLink.displayName) + Text(verbatim: hasText ? " - " : "")
default: return Text("")
}
}
func image(_ s: String) -> Text {
Text(Image(systemName: s)).foregroundColor(Color(uiColor: .tertiaryLabel)) + textSpace
}
}
}
struct ContextItemView_Previews: PreviewProvider {
static var previews: some View {
let contextItem: ChatItem = ChatItem.getSample(1, .directSnd, .now, "hello")
return ContextItemView(chat: Chat.sampleData, contextItems: [contextItem], contextIcon: "pencil.circle", cancelContextItem: {}, contextIconForeground: Color.red)
}
}