From c6a9c529e707156cc0ffecd4f2f29ea71225be5f Mon Sep 17 00:00:00 2001 From: Enes Karaosman Date: Fri, 15 Nov 2024 20:30:00 +0300 Subject: [PATCH] chore(deps): update dependency onevcat/kingfisher to 8.1.0 --- Example/Example/AdvancedExampleView.swift | 27 ++++++++----- Example/Example/BasicExampleView.swift | 38 ++++++++++--------- Example/Example/Extensions.swift | 3 +- Package.resolved | 4 +- Package.swift | 2 +- .../SwiftyChat/ChatMessageViewContainer.swift | 21 +++------- .../SwiftyChat/Core/Extension/Double++.swift | 28 -------------- .../Core/Extension/UIDevice++.swift | 4 +- .../SwiftyChat/Core/Video/PIPVideoCell.swift | 34 ++++++----------- .../Core/Video/PlayerViewModel.swift | 26 +++++++++---- .../Core/Video/VideoPlayerOverlay.swift | 18 +++++---- .../Core/View/LoadingThreeBallsView.swift | 10 ++--- .../Core/ViewModifiers/AvatarModifier.swift | 8 ++-- .../DismissKeyboardModifier.swift | 7 ++-- .../MessageHorizontalAlignmentModifier.swift | 4 +- .../SwiftyChat/InputView/BasicInputView.swift | 8 ++-- .../MessageViews/ContactMessageView.swift | 2 +- .../MessageViews/ImageMessageView.swift | 4 +- 18 files changed, 109 insertions(+), 139 deletions(-) delete mode 100644 Sources/SwiftyChat/Core/Extension/Double++.swift diff --git a/Example/Example/AdvancedExampleView.swift b/Example/Example/AdvancedExampleView.swift index 7a94ff86..1da30f00 100644 --- a/Example/Example/AdvancedExampleView.swift +++ b/Example/Example/AdvancedExampleView.swift @@ -21,7 +21,10 @@ struct AdvancedExampleView: View { } private var chatView: some View { - ChatView(messages: $messages, scrollToBottom: $scrollToBottom) { + ChatView( + messages: $messages, + scrollToBottom: $scrollToBottom + ) { BasicInputView( message: $message, placeholder: "Type something", @@ -44,13 +47,17 @@ struct AdvancedExampleView: View { .messageCellContextMenu { message -> AnyView in switch message.messageKind { case .text: - return Button(action: { - print("Forward Context Menu tapped!!") - // Forward text - }) { - Text("Forward") - Image(systemName: "arrowshape.turn.up.right") - }.embedInAnyView() + return Button( + action: { + print("Forward Context Menu tapped!!") + // Forward text + }, + label: { + Text("Forward") + Image(systemName: "arrowshape.turn.up.right") + } + ) + .embedInAnyView() default: // If you don't want to implement contextMenu action // for a specific case, simply return EmptyView like below; @@ -68,7 +75,7 @@ struct AdvancedExampleView: View { ) } // ▼ Implement in case ChatMessageKind.contact - .contactItemButtons { (contact, message) -> [ContactCellButton] in + .contactItemButtons { (contact, _) -> [ContactCellButton] in return [ .init(title: "Save", action: { print(contact.displayName) @@ -76,7 +83,7 @@ struct AdvancedExampleView: View { ] } // ▼ Optional - .onCarouselItemAction(action: { (button, message) in + .onCarouselItemAction(action: { (_, message) in print(message.messageKind.description) }) // ▼ Required diff --git a/Example/Example/BasicExampleView.swift b/Example/Example/BasicExampleView.swift index cb275cfc..6e25e133 100644 --- a/Example/Example/BasicExampleView.swift +++ b/Example/Example/BasicExampleView.swift @@ -10,15 +10,15 @@ import SwiftyChat import SwiftyChatMock struct BasicExampleView: View { - + @State var messages: [MessageMocker.ChatMessageItem] = MessageMocker.generate(kind: .text, count: 20) - + @State private var message = "" - + var body: some View { chatView } - + private var chatView: some View { ChatView(messages: $messages) { @@ -33,25 +33,27 @@ struct BasicExampleView: View { ) .background(Color.primary.colorInvert()) .embedInAnyView() - + } // ▼ Optional, Present context menu when cell long pressed .messageCellContextMenu { message -> AnyView in switch message.messageKind { case .text(let text): - return Button(action: { - print("Copy Context Menu tapped!!") - #if os(iOS) - UIPasteboard.general.string = text - #endif - - #if os(macOS) - NSPasteboard.general.setString(text, forType: .string) - #endif - }) { - Text("Copy") - Image(systemName: "doc.on.doc") - }.embedInAnyView() + return Button( + action: { + print("Copy Context Menu tapped!!") + #if os(iOS) + UIPasteboard.general.string = text + #endif + #if os(macOS) + NSPasteboard.general.setString(text, forType: .string) + #endif + }, + label: { + Text("Copy") + Image(systemName: "doc.on.doc") + } + ).embedInAnyView() default: // If you don't want to implement contextMenu action // for a specific case, simply return EmptyView like below; diff --git a/Example/Example/Extensions.swift b/Example/Example/Extensions.swift index 2a9a7588..efcb71e3 100644 --- a/Example/Example/Extensions.swift +++ b/Example/Example/Extensions.swift @@ -16,7 +16,7 @@ extension Color { let futuraFont = Font.custom("Futura", size: 17) extension ChatMessageCellStyle { - + static let basicStyle = ChatMessageCellStyle( incomingTextStyle: .init( textStyle: .init(textColor: .black, font: futuraFont), @@ -36,5 +36,4 @@ extension ChatMessageCellStyle { ), incomingAvatarStyle: .init(imageStyle: .init(imageSize: .zero)) ) - } diff --git a/Package.resolved b/Package.resolved index ee4c4516..c891463a 100644 --- a/Package.resolved +++ b/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/onevcat/Kingfisher.git", "state" : { - "revision" : "3340001633525fd68c53d3a359e3c118797ad08e", - "version" : "8.0.2" + "revision" : "c0940e241945e6378c01fbd45fd3815579d47ef5", + "version" : "8.1.0" } }, { diff --git a/Package.swift b/Package.swift index 15059247..55c61e33 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,7 @@ let package = Package( ), ], dependencies: [ - .package(url: "https://github.com/onevcat/Kingfisher.git", from: "8.0.2"), + .package(url: "https://github.com/onevcat/Kingfisher.git", from: "8.1.0"), .package(url: "https://github.com/EnesKaraosman/SwiftUIEKtensions.git", from: "0.4.0"), .package(url: "https://github.com/dkk/WrappingHStack.git", from: "2.2.11") ], diff --git a/Sources/SwiftyChat/ChatMessageViewContainer.swift b/Sources/SwiftyChat/ChatMessageViewContainer.swift index f784e346..62153c4a 100644 --- a/Sources/SwiftyChat/ChatMessageViewContainer.swift +++ b/Sources/SwiftyChat/ChatMessageViewContainer.swift @@ -16,22 +16,15 @@ struct ChatMessageViewContainer: View { let contactFooterSection: (ContactItem, Message) -> [ContactCellButton] let onCarouselItemAction: (CarouselItemButton, Message) -> Void - @ViewBuilder private func messageCell() -> some View { + @ViewBuilder + private func messageCell() -> some View { switch message.messageKind { case .text(let text): - TextMessageView( - text: text, - message: message, - size: size - ) + TextMessageView(text: text, message: message, size: size) case .location(let location): - LocationMessageView( - location: location, - message: message, - size: size - ) + LocationMessageView(location: location, message: message, size: size) case .imageText(let imageLoadingType, let text): ImageTextMessageView( @@ -71,11 +64,7 @@ struct ChatMessageViewContainer: View { ) case .video(let videoItem): - VideoMessageView( - media: videoItem, - message: message, - size: size - ) + VideoMessageView(media: videoItem, message: message, size: size) case .loading: LoadingMessageView(message: message, size: size) diff --git a/Sources/SwiftyChat/Core/Extension/Double++.swift b/Sources/SwiftyChat/Core/Extension/Double++.swift deleted file mode 100644 index 608309fc..00000000 --- a/Sources/SwiftyChat/Core/Extension/Double++.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// Double++.swift -// -// -// Created by Enes Karaosman on 11.11.2020. -// - -import Foundation - -extension Double { - - private static var timeHMSFormatter: DateComponentsFormatter = { - let formatter = DateComponentsFormatter() - formatter.unitsStyle = .positional - formatter.allowedUnits = [.minute, .second] - formatter.zeroFormattingBehavior = [.pad] - return formatter - }() - - func formatSecondsToHMS() -> String { - guard !self.isNaN, - let text = Double.timeHMSFormatter.string(from: self) else { - return "00:00" - } - - return text - } -} diff --git a/Sources/SwiftyChat/Core/Extension/UIDevice++.swift b/Sources/SwiftyChat/Core/Extension/UIDevice++.swift index 126f5a2d..295bc73e 100644 --- a/Sources/SwiftyChat/Core/Extension/UIDevice++.swift +++ b/Sources/SwiftyChat/Core/Extension/UIDevice++.swift @@ -16,8 +16,8 @@ public struct Device { let orientation = UIDevice.current.orientation return orientation == .landscapeLeft || orientation == .landscapeRight - #endif - + #else return false + #endif } } diff --git a/Sources/SwiftyChat/Core/Video/PIPVideoCell.swift b/Sources/SwiftyChat/Core/Video/PIPVideoCell.swift index 793683db..19127d75 100644 --- a/Sources/SwiftyChat/Core/Video/PIPVideoCell.swift +++ b/Sources/SwiftyChat/Core/Video/PIPVideoCell.swift @@ -69,29 +69,21 @@ struct PIPVideoCell: View { let inputViewOffset: CGFloat = videoManager.isFullScreen ? 0 : 60 let hPadding = videoManager.isFullScreen ? 0 : horizontalPadding withAnimation(.easeIn) { - switch toCorner { - case .center: - location = .init( - x: size.width / 2, - y: size.height / 2 - ) - case .leftTop: - location = .init( + location = switch toCorner { + case .center: .init(x: size.width / 2, y: size.height / 2) + case .leftTop: .init( x: (videoFrameWidth(in: size) / 2) + (hPadding / 2), y: videoFrameHeight(in: size) / 2 ) - case .leftBottom: - location = .init( + case .leftBottom: .init( x: (videoFrameWidth(in: size) / 2) + (hPadding / 2), y: size.height - videoFrameHeight(in: size) / 2 - inputViewOffset ) - case .rightTop: - location = .init( + case .rightTop: .init( x: size.width - (videoFrameWidth(in: size) / 2) - (hPadding / 2), y: videoFrameHeight(in: size) / 2 ) - case .rightBottom: - location = .init( + case .rightBottom: .init( x: size.width - (videoFrameWidth(in: size) / 2) - (hPadding / 2), y: size.height - videoFrameHeight(in: size) / 2 - inputViewOffset ) @@ -117,9 +109,8 @@ struct PIPVideoCell: View { .gesture(simpleDrag(in: geometry.size)) .animation(.linear(duration: 0.1)) .onAppear { rePositionVideoFrame(toCorner: .rightTop, in: geometry.size) } - .onAppear { - - videoManager.$isFullScreen + .onAppear { [weak videoManager] in + videoManager?.$isFullScreen .removeDuplicates() .sink { _ in DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { @@ -141,7 +132,6 @@ struct PIPVideoCell: View { } .onDisappear { cancellables.forEach { $0.cancel() } - print("☠️ pip disappeared..") } } } @@ -166,20 +156,20 @@ struct PIPVideoCell: View { var newLocation = startLocation ?? location newLocation.x += value.translation.width newLocation.y += value.translation.height - self.location = newLocation + location = newLocation } .updating($startLocation) { _, startLocation, _ in startLocation = startLocation ?? location } .onEnded { _ in - if self.location.y > size.midY { - if self.location.x > size.midX { + if location.y > size.midY { + if location.x > size.midX { rePositionVideoFrame(toCorner: .rightBottom, in: size) } else { rePositionVideoFrame(toCorner: .leftBottom, in: size) } } else { - if self.location.x > size.midX { + if location.x > size.midX { rePositionVideoFrame(toCorner: .rightTop, in: size) } else { rePositionVideoFrame(toCorner: .leftTop, in: size) diff --git a/Sources/SwiftyChat/Core/Video/PlayerViewModel.swift b/Sources/SwiftyChat/Core/Video/PlayerViewModel.swift index c38b7a66..46746f69 100644 --- a/Sources/SwiftyChat/Core/Video/PlayerViewModel.swift +++ b/Sources/SwiftyChat/Core/Video/PlayerViewModel.swift @@ -2,23 +2,35 @@ import AVFoundation import Combine final class PlayerViewModel: ObservableObject { - let player = AVPlayer() - @Published var isInPipMode: Bool = false - @Published var isPlaying = false - @Published var isEditingCurrentTime = false - @Published var currentTime: Double = .zero - @Published var duration: Double? + let player: AVPlayer + + @Published + var isEditingCurrentTime = false + + @Published + var currentTime: Double = .zero + + @Published + var isInPipMode: Bool = false + + @Published + private(set) var isPlaying = false + + @Published + private(set) var duration: Double? private var subscriptions: Set = [] private var timeObserver: Any? deinit { - if let timeObserver = timeObserver { + if let timeObserver { player.removeTimeObserver(timeObserver) } } init() { + player = AVPlayer() + $isEditingCurrentTime .dropFirst() .filter({ $0 == false }) diff --git a/Sources/SwiftyChat/Core/Video/VideoPlayerOverlay.swift b/Sources/SwiftyChat/Core/Video/VideoPlayerOverlay.swift index e96081d4..02df6d52 100644 --- a/Sources/SwiftyChat/Core/Video/VideoPlayerOverlay.swift +++ b/Sources/SwiftyChat/Core/Video/VideoPlayerOverlay.swift @@ -1,8 +1,11 @@ import SwiftUI struct VideoPlayerOverlay: View { - @ObservedObject var playerVM: PlayerViewModel - @EnvironmentObject var videoManager: VideoManager + @ObservedObject + var playerVM: PlayerViewModel + + @EnvironmentObject + var videoManager: VideoManager init(for playerViewModel: PlayerViewModel) { self.playerVM = playerViewModel @@ -61,16 +64,15 @@ struct VideoPlayerOverlay: View { .overlay( Image( systemName: videoManager.isFullScreen ? - "arrow.down.right.and.arrow.up.left" : - "arrow.up.left.and.arrow.down.right" + "arrow.down.right.and.arrow.up.left" : "arrow.up.left.and.arrow.down.right" ) .font(Font.body.weight(.semibold)) .foregroundColor(Color.white) .padding() ) - .onTapGesture { + .onTapGesture { [weak videoManager] in withAnimation { - videoManager.isFullScreen.toggle() + videoManager?.isFullScreen.toggle() } } } @@ -85,8 +87,8 @@ struct VideoPlayerOverlay: View { .foregroundColor(Color.white) .padding() ) - .onTapGesture { - self.videoManager.flushState() + .onTapGesture { [weak videoManager] in + videoManager?.flushState() } } } diff --git a/Sources/SwiftyChat/Core/View/LoadingThreeBallsView.swift b/Sources/SwiftyChat/Core/View/LoadingThreeBallsView.swift index 6310c674..1db52524 100644 --- a/Sources/SwiftyChat/Core/View/LoadingThreeBallsView.swift +++ b/Sources/SwiftyChat/Core/View/LoadingThreeBallsView.swift @@ -14,7 +14,7 @@ struct LoadingThreeBalls: View { let timing: Double let maxCounter = 3 - @State var counter = 0 + @State private var counter = 0 let frame: CGSize let primaryColor: Color @@ -44,9 +44,9 @@ struct LoadingThreeBalls: View { } #if DEBUG -struct LoadingThreeBalls_Previews: PreviewProvider { - static var previews: some View { - LoadingThreeBalls() - } +@available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *) +#Preview(traits: .sizeThatFitsLayout) { + LoadingThreeBalls() + .padding() } #endif diff --git a/Sources/SwiftyChat/Core/ViewModifiers/AvatarModifier.swift b/Sources/SwiftyChat/Core/ViewModifiers/AvatarModifier.swift index aaac8c39..858807f8 100644 --- a/Sources/SwiftyChat/Core/ViewModifiers/AvatarModifier.swift +++ b/Sources/SwiftyChat/Core/ViewModifiers/AvatarModifier.swift @@ -103,10 +103,10 @@ struct AvatarModifier: ViewModifier { } private var avatarSpacing: CGFloat { - switch currentAvatarPosition { - case .alignToMessageTop(let spacing): return spacing - case .alignToMessageCenter(let spacing): return spacing - case .alignToMessageBottom(let spacing): return spacing + return switch currentAvatarPosition { + case .alignToMessageTop(let spacing): spacing + case .alignToMessageCenter(let spacing): spacing + case .alignToMessageBottom(let spacing): spacing } } diff --git a/Sources/SwiftyChat/Core/ViewModifiers/DismissKeyboardModifier.swift b/Sources/SwiftyChat/Core/ViewModifiers/DismissKeyboardModifier.swift index 0a882977..dcbba15e 100644 --- a/Sources/SwiftyChat/Core/ViewModifiers/DismissKeyboardModifier.swift +++ b/Sources/SwiftyChat/Core/ViewModifiers/DismissKeyboardModifier.swift @@ -19,11 +19,10 @@ struct DismissKeyboardOnTappingOutside: ViewModifier { .onTapGesture { #if os(iOS) let keyWindow = UIApplication.shared.connectedScenes - .filter({$0.activationState == .foregroundActive}) - .map({$0 as? UIWindowScene}) - .compactMap({$0}) + .filter({ $0.activationState == .foregroundActive }) + .compactMap({ $0 as? UIWindowScene }) .first?.windows - .filter({$0.isKeyWindow}).first + .filter(\.isKeyWindow).first keyWindow?.endEditing(true) #endif } diff --git a/Sources/SwiftyChat/Core/ViewModifiers/MessageHorizontalAlignmentModifier.swift b/Sources/SwiftyChat/Core/ViewModifiers/MessageHorizontalAlignmentModifier.swift index d5f792ee..7b7086c0 100644 --- a/Sources/SwiftyChat/Core/ViewModifiers/MessageHorizontalAlignmentModifier.swift +++ b/Sources/SwiftyChat/Core/ViewModifiers/MessageHorizontalAlignmentModifier.swift @@ -9,8 +9,8 @@ import SwiftUI struct MessageHorizontalAlignmentModifier: ViewModifier { - var messageKind: ChatMessageKind - var isSender: Bool + let messageKind: ChatMessageKind + let isSender: Bool private var isSpaceFreeMessageKind: Bool { if case ChatMessageKind.carousel = messageKind { diff --git a/Sources/SwiftyChat/InputView/BasicInputView.swift b/Sources/SwiftyChat/InputView/BasicInputView.swift index 10444312..fd831270 100644 --- a/Sources/SwiftyChat/InputView/BasicInputView.swift +++ b/Sources/SwiftyChat/InputView/BasicInputView.swift @@ -37,8 +37,8 @@ public struct BasicInputView: View { private var sendButton: some View { Button(action: { - self.onCommit?(.text(message)) - self.message.removeAll() + onCommit?(.text(message)) + message.removeAll() }, label: { Circle().fill(Color(.systemBlue)) .frame(width: 36, height: 36) @@ -57,8 +57,8 @@ public struct BasicInputView: View { VStack(spacing: .zero) { Divider().padding(.bottom, 8) HStack { - self.messageEditorView - self.sendButton + messageEditorView + sendButton } } .padding(.horizontal, 8) diff --git a/Sources/SwiftyChat/MessageViews/ContactMessageView.swift b/Sources/SwiftyChat/MessageViews/ContactMessageView.swift index 0c1cd917..3e591304 100644 --- a/Sources/SwiftyChat/MessageViews/ContactMessageView.swift +++ b/Sources/SwiftyChat/MessageViews/ContactMessageView.swift @@ -65,7 +65,7 @@ struct ContactMessageView: View { } private var buttons: [ContactCellButton] { - return footerSection(contact, message) + footerSection(contact, message) } private var buttonActionFooter: some View { diff --git a/Sources/SwiftyChat/MessageViews/ImageMessageView.swift b/Sources/SwiftyChat/MessageViews/ImageMessageView.swift index 87cdb8d7..71aa2d6f 100644 --- a/Sources/SwiftyChat/MessageViews/ImageMessageView.swift +++ b/Sources/SwiftyChat/MessageViews/ImageMessageView.swift @@ -33,7 +33,6 @@ struct ImageLoadingKindCell: View { imageView } - @MainActor @ViewBuilder private var imageView: some View { switch imageLoadingType { @@ -54,9 +53,8 @@ struct ImageLoadingKindCell: View { .frame(width: width, height: height) } - @MainActor private func remoteImage(url: URL) -> some View { - KFAnimatedImage(url) + KFImage.url(url) .cacheOriginalImage() .fade(duration: 0.2) .forceTransition()