From 74b62e985741958b2328d244a75c2e072207d60d Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Thu, 2 Nov 2023 16:50:09 +1100 Subject: [PATCH] fix link preview with swift ui --- .../SwiftUI/LinkPreviewView_SwiftUI.swift | 48 ++++--- .../SwiftUI/VoiceMessageView_SwiftUI.swift | 18 ++- .../MessageInfoView.swift | 132 +++++++++--------- Session/Shared/LoadingIndicatorView.swift | 18 ++- 4 files changed, 128 insertions(+), 88 deletions(-) diff --git a/Session/Conversations/Message Cells/Content Views/SwiftUI/LinkPreviewView_SwiftUI.swift b/Session/Conversations/Message Cells/Content Views/SwiftUI/LinkPreviewView_SwiftUI.swift index c762e0c35..0cf86a5fb 100644 --- a/Session/Conversations/Message Cells/Content Views/SwiftUI/LinkPreviewView_SwiftUI.swift +++ b/Session/Conversations/Message Cells/Content Views/SwiftUI/LinkPreviewView_SwiftUI.swift @@ -35,10 +35,17 @@ public struct LinkPreviewView_SwiftUI: View { } public var body: some View { - VStack( - alignment: .leading, - spacing: Values.mediumSpacing + ZStack( + alignment: .leading ) { + if state is LinkPreview.SentState { + if #available(iOS 14.0, *) { + ThemeManager.currentTheme.colorSwiftUI(for: .messageBubble_overlay).ignoresSafeArea() + } else { + ThemeManager.currentTheme.colorSwiftUI(for: .messageBubble_overlay) + } + } + HStack( alignment: .center, spacing: Values.mediumSpacing @@ -63,20 +70,27 @@ public struct LinkPreviewView_SwiftUI: View { state is LinkPreview.DraftState || state is LinkPreview.SentState, let defaultImage: UIImage = UIImage(named: "Link")?.withRenderingMode(.alwaysTemplate) { - Image(uiImage: defaultImage) - .foregroundColor( - themeColor: isOutgoing ? - .messageBubble_outgoingText : - .messageBubble_incomingText - ) - .frame( - width: imageSize, - height: imageSize - ) - .cornerRadius(state is LinkPreview.SentState ? 0 : 8) + ZStack { + if #available(iOS 14.0, *) { + ThemeManager.currentTheme.colorSwiftUI(for: .messageBubble_overlay).ignoresSafeArea() + } else { + ThemeManager.currentTheme.colorSwiftUI(for: .messageBubble_overlay) + } + + Image(uiImage: defaultImage) + .foregroundColor( + themeColor: isOutgoing ? + .messageBubble_outgoingText : + .messageBubble_incomingText + ) + .cornerRadius(state is LinkPreview.SentState ? 0 : 8) + } + .frame( + width: imageSize, + height: imageSize + ) } else { - ActivityIndicator() - .foregroundColor(.black) + ActivityIndicator(themeColor: .borderSeparator, width: 2) .frame( width: Self.loaderSize, height: Self.loaderSize @@ -94,6 +108,8 @@ public struct LinkPreviewView_SwiftUI: View { .messageBubble_outgoingText : .messageBubble_incomingText ) + .fixedSize(horizontal: false, vertical: true) + .padding(.trailing, Values.mediumSpacing) } // Cancel button diff --git a/Session/Conversations/Message Cells/Content Views/SwiftUI/VoiceMessageView_SwiftUI.swift b/Session/Conversations/Message Cells/Content Views/SwiftUI/VoiceMessageView_SwiftUI.swift index 00bd2dd2e..919997a58 100644 --- a/Session/Conversations/Message Cells/Content Views/SwiftUI/VoiceMessageView_SwiftUI.swift +++ b/Session/Conversations/Message Cells/Content Views/SwiftUI/VoiceMessageView_SwiftUI.swift @@ -8,11 +8,17 @@ struct VoiceMessageView_SwiftUI: View { @State var isPlaying: Bool = false @State var time: String = "0:00" @State var speed: String = "1.5×" - @State var progress: Double = 1.0 + @State var progress: Double = 0.0 private static let width: CGFloat = 160 private static let toggleContainerSize: CGFloat = 20 + private var attachment: Attachment + + public init(attachment: Attachment) { + self.attachment = attachment + } + var body: some View { ZStack(alignment: .leading) { Rectangle() @@ -40,6 +46,12 @@ struct VoiceMessageView_SwiftUI: View { height: 8 ) } + +// ActivityIndicator(themeColor: .textPrimary, width: 2) +// .frame( +// width: Self.toggleContainerSize, +// height: Self.toggleContainerSize +// ) } Rectangle() @@ -59,7 +71,7 @@ struct VoiceMessageView_SwiftUI: View { .font(.system(size: Values.smallFontSize)) } } - .padding(.horizontal, Values.smallSpacing) + .padding(.all, Values.smallSpacing) } .frame( width: Self.width @@ -69,7 +81,7 @@ struct VoiceMessageView_SwiftUI: View { struct VoiceMessageView_SwiftUI_Previews: PreviewProvider { static var previews: some View { - VoiceMessageView_SwiftUI() + VoiceMessageView_SwiftUI(attachment: Attachment(variant: .voiceMessage, contentType: "mp4", byteCount: 100)) .frame(height: 58) } } diff --git a/Session/Media Viewing & Editing/MessageInfoView.swift b/Session/Media Viewing & Editing/MessageInfoView.swift index c2f75b882..f0811a006 100644 --- a/Session/Media Viewing & Editing/MessageInfoView.swift +++ b/Session/Media Viewing & Editing/MessageInfoView.swift @@ -384,68 +384,73 @@ struct MessageBubble: View { ZStack { switch messageViewModel.cellType { case .textOnlyMessage: - let maxWidth: CGFloat = (VisibleMessageCell.getMaxWidth(for: messageViewModel) - 2 * Self.inset) + let maxWidth: CGFloat = (VisibleMessageCell.getMaxWidth(for: messageViewModel) - 2 * Self.inset) - if let linkPreview: LinkPreview = messageViewModel.linkPreview { - switch linkPreview.variant { - case .standard: - LinkPreviewView_SwiftUI( - state: LinkPreview.SentState( - linkPreview: linkPreview, - imageAttachment: messageViewModel.linkPreviewAttachment - ), - isOutgoing: (messageViewModel.variant == .standardOutgoing), - maxWidth: maxWidth, - messageViewModel: messageViewModel, - bodyLabelTextColor: bodyLabelTextColor, - lastSearchText: nil - ) - - case .openGroupInvitation: - OpenGroupInvitationView_SwiftUI( - name: (linkPreview.title ?? ""), - url: linkPreview.url, - textColor: bodyLabelTextColor, - isOutgoing: (messageViewModel.variant == .standardOutgoing)) - } - } - // else { - // // Stack view - // let stackView = UIStackView(arrangedSubviews: []) - // stackView.axis = .vertical - // stackView.spacing = 2 - // - // // Quote view - // if let quote: Quote = messageViewModel.quote { - // let hInset: CGFloat = 2 - // let quoteView: QuoteView = QuoteView( - // for: .regular, - // authorId: quote.authorId, - // quotedText: quote.body, - // threadVariant: cellViewModel.threadVariant, - // currentUserPublicKey: cellViewModel.currentUserPublicKey, - // currentUserBlinded15PublicKey: cellViewModel.currentUserBlinded15PublicKey, - // currentUserBlinded25PublicKey: cellViewModel.currentUserBlinded25PublicKey, - // direction: (cellViewModel.variant == .standardOutgoing ? - // .outgoing : - // .incoming - // ), - // attachment: cellViewModel.quoteAttachment, - // hInset: hInset, - // maxWidth: maxWidth - // ) - // let quoteViewContainer = UIView(wrapping: quoteView, withInsets: UIEdgeInsets(top: 0, leading: hInset, bottom: 0, trailing: hInset)) - // stackView.addArrangedSubview(quoteViewContainer) - // } - if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText( - for: messageViewModel, - theme: ThemeManager.currentTheme, - primaryColor: ThemeManager.primaryColor, - textColor: bodyLabelTextColor, - searchText: nil + VStack( + alignment: .leading, + spacing: 0 ) { - AttributedText(bodyText) - .padding(.all, Self.inset) + if let linkPreview: LinkPreview = messageViewModel.linkPreview { + switch linkPreview.variant { + case .standard: + LinkPreviewView_SwiftUI( + state: LinkPreview.SentState( + linkPreview: linkPreview, + imageAttachment: messageViewModel.linkPreviewAttachment + ), + isOutgoing: (messageViewModel.variant == .standardOutgoing), + maxWidth: maxWidth, + messageViewModel: messageViewModel, + bodyLabelTextColor: bodyLabelTextColor, + lastSearchText: nil + ) + + case .openGroupInvitation: + OpenGroupInvitationView_SwiftUI( + name: (linkPreview.title ?? ""), + url: linkPreview.url, + textColor: bodyLabelTextColor, + isOutgoing: (messageViewModel.variant == .standardOutgoing)) + } + } + // else { + // // Stack view + // let stackView = UIStackView(arrangedSubviews: []) + // stackView.axis = .vertical + // stackView.spacing = 2 + // + // // Quote view + // if let quote: Quote = messageViewModel.quote { + // let hInset: CGFloat = 2 + // let quoteView: QuoteView = QuoteView( + // for: .regular, + // authorId: quote.authorId, + // quotedText: quote.body, + // threadVariant: cellViewModel.threadVariant, + // currentUserPublicKey: cellViewModel.currentUserPublicKey, + // currentUserBlinded15PublicKey: cellViewModel.currentUserBlinded15PublicKey, + // currentUserBlinded25PublicKey: cellViewModel.currentUserBlinded25PublicKey, + // direction: (cellViewModel.variant == .standardOutgoing ? + // .outgoing : + // .incoming + // ), + // attachment: cellViewModel.quoteAttachment, + // hInset: hInset, + // maxWidth: maxWidth + // ) + // let quoteViewContainer = UIView(wrapping: quoteView, withInsets: UIEdgeInsets(top: 0, leading: hInset, bottom: 0, trailing: hInset)) + // stackView.addArrangedSubview(quoteViewContainer) + // } + if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText( + for: messageViewModel, + theme: ThemeManager.currentTheme, + primaryColor: ThemeManager.primaryColor, + textColor: bodyLabelTextColor, + searchText: nil + ) { + AttributedText(bodyText) + .padding(.all, Self.inset) + } } case .mediaMessage: if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText( @@ -458,13 +463,12 @@ struct MessageBubble: View { AttributedText(bodyText) .padding(.all, Self.inset) } - case .audio: + case .voiceMessage: if let attachment: Attachment = messageViewModel.attachments?.first(where: { $0.isAudio }){ // TODO: Playback Info and check if playing function is needed - VoiceMessageView_SwiftUI() - .padding(.all, Self.inset) + VoiceMessageView_SwiftUI(attachment: attachment) } - case .genericAttachment: + case .audio, .genericAttachment: if let attachment: Attachment = messageViewModel.attachments?.first { VStack(spacing: Values.smallSpacing) { DocumentView_SwiftUI(attachment: attachment, textColor: bodyLabelTextColor) diff --git a/Session/Shared/LoadingIndicatorView.swift b/Session/Shared/LoadingIndicatorView.swift index a2c95d538..e4e384e55 100644 --- a/Session/Shared/LoadingIndicatorView.swift +++ b/Session/Shared/LoadingIndicatorView.swift @@ -1,21 +1,30 @@ // Copyright © 2023 Rangeproof Pty Ltd. All rights reserved. import SwiftUI +import SessionUIKit public struct ActivityIndicator: View { @State private var strokeStart: Double = 0.95 @State private var strokeEnd: Double = 1.0 @State private var shorten: Bool = false @State private var isRotating: Bool = false + + private var themeColor: ThemeValue + private var width: CGFloat + + public init(themeColor: ThemeValue, width: CGFloat) { + self.themeColor = themeColor + self.width = width + } public var body: some View { GeometryReader { (geometry: GeometryProxy) in Circle() .trim(from: strokeStart, to: strokeEnd) .stroke( - themeColor: .borderSeparator, + themeColor: themeColor, style: StrokeStyle( - lineWidth: 2, + lineWidth: width, lineCap: .round ) ) @@ -36,7 +45,7 @@ public struct ActivityIndicator: View { } self.trimStroke() - Timer.scheduledTimerOnMainThread(withTimeInterval: 1.5, repeats: true) { _ in + Timer.scheduledTimer(withTimeInterval: 1.5, repeats: true) { _ in self.trimStroke() } } @@ -65,8 +74,7 @@ public struct ActivityIndicator: View { struct ActivityIndicator_Previews: PreviewProvider { static var previews: some View { - ActivityIndicator() - .foregroundColor(.black) + ActivityIndicator(themeColor: .textPrimary, width: 2) .frame( width: 40, height: 40