Merge 'ios18-fixes-round1' into 'release_1.10'
Merge some additional ios18 fixes
Daniel D’Aquino (1):
Fix unclickable elements
William Casarin (3):
relays: add some ping/pong and connection logs
relay: don't reconnect when we don't have to
This commit is contained in:
@@ -1111,6 +1111,8 @@
|
||||
D7CE1B482B0BE719002EDAD4 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93D2A9AD44700DC3548 /* Message.swift */; };
|
||||
D7CE1B492B0BE729002EDAD4 /* DisplayName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */; };
|
||||
D7D2A3812BF815D000E4B42B /* PushNotificationClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D2A3802BF815D000E4B42B /* PushNotificationClient.swift */; };
|
||||
D7D68FF92C9E01BE0015A515 /* KFClickable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D68FF82C9E01B60015A515 /* KFClickable.swift */; };
|
||||
D7D68FFA2C9E01BE0015A515 /* KFClickable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D68FF82C9E01B60015A515 /* KFClickable.swift */; };
|
||||
D7DBD41F2B02F15E002A6197 /* NostrKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFD32819DE8F00B3DE84 /* NostrKind.swift */; };
|
||||
D7DEEF2F2A8C021E00E0C99F /* NostrEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DEEF2E2A8C021E00E0C99F /* NostrEventTests.swift */; };
|
||||
D7EDED152B11776B0018B19C /* LibreTranslateServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE45AF5297BB2E700C1D842 /* LibreTranslateServer.swift */; };
|
||||
@@ -1959,6 +1961,7 @@
|
||||
D7CBD1D32B8D21DC00BFD889 /* DamusPurpleNotificationManagement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleNotificationManagement.swift; sourceTree = "<group>"; };
|
||||
D7CBD1D52B8D509800BFD889 /* DamusPurpleImpendingExpirationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleImpendingExpirationTests.swift; sourceTree = "<group>"; };
|
||||
D7D2A3802BF815D000E4B42B /* PushNotificationClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationClient.swift; sourceTree = "<group>"; };
|
||||
D7D68FF82C9E01B60015A515 /* KFClickable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KFClickable.swift; sourceTree = "<group>"; };
|
||||
D7DEEF2E2A8C021E00E0C99F /* NostrEventTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NostrEventTests.swift; sourceTree = "<group>"; };
|
||||
D7EDED1B2B1178FE0018B19C /* NoteContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContent.swift; sourceTree = "<group>"; };
|
||||
D7EDED1D2B11797D0018B19C /* LongformEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongformEvent.swift; sourceTree = "<group>"; };
|
||||
@@ -2540,6 +2543,7 @@
|
||||
4C75EFA227FA576C0006080F /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D7D68FF72C9E01A80015A515 /* Utils */,
|
||||
D78DB85D2C20FE9E00F0AB12 /* Chat */,
|
||||
D71AC4CA2BA8E3320076268E /* Extensions */,
|
||||
BA3759952ABCCF360018D73B /* Camera */,
|
||||
@@ -3368,6 +3372,14 @@
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D7D68FF72C9E01A80015A515 /* Utils */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D7D68FF82C9E01B60015A515 /* KFClickable.swift */,
|
||||
);
|
||||
path = Utils;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E06336A72B7582D600A88E6B /* Assets */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -3803,6 +3815,7 @@
|
||||
B51C1CEA2B55A60A00E312A9 /* AddMuteItemView.swift in Sources */,
|
||||
4C5D5C992A6AF8F80024563C /* NdbNote.swift in Sources */,
|
||||
4CF0ABF029857E9200D66079 /* Bech32Object.swift in Sources */,
|
||||
D7D68FFA2C9E01BE0015A515 /* KFClickable.swift in Sources */,
|
||||
4C3D52B8298DB5C6001C5831 /* TextEvent.swift in Sources */,
|
||||
4C216F362870A9A700040376 /* InputDismissKeyboard.swift in Sources */,
|
||||
D74AAFCF2B155D8C006CF0F4 /* ZapDataModel.swift in Sources */,
|
||||
@@ -4517,6 +4530,7 @@
|
||||
D73E5F332C6A97F4007EB227 /* ZapEvent.swift in Sources */,
|
||||
D73E5F342C6A97F4007EB227 /* TextEvent.swift in Sources */,
|
||||
D73E5F352C6A97F4007EB227 /* WideEventView.swift in Sources */,
|
||||
D7D68FF92C9E01BE0015A515 /* KFClickable.swift in Sources */,
|
||||
D73E5F8A2C6AA69C007EB227 /* SideMenuView.swift in Sources */,
|
||||
D73E5F362C6A97F4007EB227 /* LongformView.swift in Sources */,
|
||||
D73E5F372C6A97F4007EB227 /* LongformPreview.swift in Sources */,
|
||||
|
||||
@@ -236,6 +236,7 @@ struct ImageCarousel<Content: View>: View {
|
||||
Placeholder(url: url, geo_size: geo.size, num_urls: urls.count)
|
||||
}
|
||||
.aspectRatio(contentMode: filling ? .fill : .fit)
|
||||
.kfClickable()
|
||||
.position(x: geo.size.width / 2, y: geo.size.height / 2)
|
||||
.tabItem {
|
||||
Text(url.absoluteString)
|
||||
@@ -274,8 +275,14 @@ struct ImageCarousel<Content: View>: View {
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Medias
|
||||
.onTapGesture { }
|
||||
if #available(iOS 18.0, *) {
|
||||
Medias
|
||||
} else {
|
||||
// An empty tap gesture recognizer is needed on iOS 17 and below to suppress other overlapping tap recognizers
|
||||
// Otherwise it will both open the carousel and go to a note at the same time
|
||||
Medias.onTapGesture { }
|
||||
}
|
||||
|
||||
|
||||
if urls.count > 1 {
|
||||
PageControlView(currentPage: $model.selectedIndex, numberOfPages: urls.count)
|
||||
|
||||
@@ -46,9 +46,10 @@ final class RelayConnection: ObservableObject {
|
||||
|
||||
if err == nil {
|
||||
self.last_pong = .now
|
||||
Log.info("Got pong from '%s'", for: .networking, self.relay_url.absoluteString)
|
||||
self.log?.add("Successful ping")
|
||||
} else {
|
||||
print("pong failed, reconnecting \(self.relay_url.id)")
|
||||
Log.info("Ping failed, reconnecting to '%s'", for: .networking, self.relay_url.absoluteString)
|
||||
self.isConnected = false
|
||||
self.isConnecting = false
|
||||
self.reconnect_with_backoff()
|
||||
@@ -126,7 +127,7 @@ final class RelayConnection: ObservableObject {
|
||||
self.receive(message: message)
|
||||
case .disconnected(let closeCode, let reason):
|
||||
if closeCode != .normalClosure {
|
||||
print("⚠️ Warning: RelayConnection (\(self.relay_url)) closed with code \(closeCode), reason: \(String(describing: reason))")
|
||||
Log.error("⚠️ Warning: RelayConnection (%d) closed with code: %s", for: .networking, String(describing: closeCode), String(describing: reason))
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self.isConnected = false
|
||||
@@ -134,12 +135,16 @@ final class RelayConnection: ObservableObject {
|
||||
self.reconnect()
|
||||
}
|
||||
case .error(let error):
|
||||
print("⚠️ Warning: RelayConnection (\(self.relay_url)) error: \(error)")
|
||||
Log.error("⚠️ Warning: RelayConnection (%s) error: %s", for: .networking, self.relay_url.absoluteString, error.localizedDescription)
|
||||
let nserr = error as NSError
|
||||
if nserr.domain == NSPOSIXErrorDomain && nserr.code == 57 {
|
||||
// ignore socket not connected?
|
||||
return
|
||||
}
|
||||
if nserr.domain == NSURLErrorDomain && nserr.code == -999 {
|
||||
// these aren't real error, it just means task was cancelled
|
||||
return
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self.isConnected = false
|
||||
self.isConnecting = false
|
||||
@@ -156,14 +161,21 @@ final class RelayConnection: ObservableObject {
|
||||
}
|
||||
|
||||
func reconnect_with_backoff() {
|
||||
self.backoff *= 1.5
|
||||
self.backoff *= 2.0
|
||||
self.reconnect_in(after: self.backoff)
|
||||
}
|
||||
|
||||
func reconnect() {
|
||||
guard !isConnecting && !isDisabled else {
|
||||
self.log?.add("Cancelling reconnect, already connecting")
|
||||
return // we're already trying to connect or we're disabled
|
||||
}
|
||||
|
||||
guard !self.isConnected else {
|
||||
self.log?.add("Cancelling reconnect, already connected")
|
||||
return
|
||||
}
|
||||
|
||||
disconnect()
|
||||
connect()
|
||||
log?.add("Reconnecting...")
|
||||
|
||||
@@ -89,6 +89,7 @@ class RelayPool {
|
||||
}
|
||||
|
||||
func ping() {
|
||||
Log.info("Pinging %d relays", for: .networking, relays.count)
|
||||
for relay in relays {
|
||||
relay.connection.ping()
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ enum LogCategory: String {
|
||||
case nav
|
||||
case render
|
||||
case storage
|
||||
case networking
|
||||
case push_notifications
|
||||
case damus_purple
|
||||
case image_uploading
|
||||
|
||||
@@ -29,6 +29,7 @@ struct EditBannerImageView: View {
|
||||
Color(uiColor: .secondarySystemBackground)
|
||||
}
|
||||
.onFailureImage(defaultImage)
|
||||
.kfClickable()
|
||||
|
||||
EditPictureControl(uploader: damus_state.settings.default_media_uploader, pubkey: damus_state.pubkey, image_url: $banner_image, uploadObserver: viewModel, callback: callback)
|
||||
}
|
||||
@@ -54,6 +55,7 @@ struct InnerBannerImageView: View {
|
||||
Color(uiColor: .secondarySystemBackground)
|
||||
}
|
||||
.onFailureImage(defaultImage)
|
||||
.kfClickable()
|
||||
} else {
|
||||
Image(uiImage: defaultImage).resizable()
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ struct HighlightEventRef: View {
|
||||
FailedImage()
|
||||
}
|
||||
.frame(width: 35, height: 35)
|
||||
.kfClickable()
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
.overlay(RoundedRectangle(cornerRadius: 10).stroke(.gray.opacity(0.5), lineWidth: 0.5))
|
||||
.scaledToFit()
|
||||
|
||||
@@ -61,6 +61,7 @@ struct HighlightLink: View {
|
||||
.background(DamusColors.adaptableWhite)
|
||||
}
|
||||
.frame(width: 35, height: 35)
|
||||
.kfClickable()
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
.scaledToFit()
|
||||
} else {
|
||||
|
||||
@@ -98,6 +98,7 @@ struct LongformPreviewBody: View {
|
||||
}
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(maxWidth: .infinity, maxHeight: header ? .infinity : 150)
|
||||
.kfClickable()
|
||||
.cornerRadius(1)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ struct ImageContainerView: View {
|
||||
view.framePreloadCount = 3
|
||||
}
|
||||
.imageModifier(ImageHandler(handler: $image))
|
||||
.kfClickable()
|
||||
.clipped()
|
||||
.modifier(ImageContextMenuModifier(url: url, image: image, settings: settings, showShareSheet: $showShareSheet))
|
||||
.sheet(isPresented: $showShareSheet) {
|
||||
|
||||
@@ -33,6 +33,7 @@ struct ProfileImageContainerView: View {
|
||||
.imageModifier(ImageHandler(handler: $image))
|
||||
.clipShape(Circle())
|
||||
.modifier(ImageContextMenuModifier(url: url, image: image, settings: settings, showShareSheet: $showShareSheet))
|
||||
.kfClickable()
|
||||
.sheet(isPresented: $showShareSheet) {
|
||||
ShareSheet(activityItems: [url])
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ struct EditPictureControl: View {
|
||||
}
|
||||
.scaledToFill()
|
||||
.frame(width: (size ?? 25) + 10, height: (size ?? 25) + 10)
|
||||
.kfClickable()
|
||||
.foregroundColor(DamusColors.white)
|
||||
.clipShape(Circle())
|
||||
.overlay(Circle().stroke(.white, lineWidth: 4))
|
||||
|
||||
@@ -57,6 +57,7 @@ struct InnerProfilePicView: View {
|
||||
}
|
||||
.scaledToFill()
|
||||
.frame(width: size, height: size)
|
||||
.kfClickable()
|
||||
.clipShape(Circle())
|
||||
.overlay(Circle().stroke(highlight_color(highlight), lineWidth: pfp_line_width(highlight)))
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ struct EditProfilePictureView: View {
|
||||
view.framePreloadCount = 3
|
||||
}
|
||||
.scaledToFill()
|
||||
.kfClickable()
|
||||
|
||||
EditPictureControl(uploader: damus_state?.settings.default_media_uploader ?? .nostrBuild, pubkey: pubkey, image_url: $profile_url, uploadObserver: uploadObserver, callback: callback)
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ struct InnerRelayPicView: View {
|
||||
Placeholder(url: url)
|
||||
}
|
||||
.scaledToFit()
|
||||
.kfClickable()
|
||||
} else {
|
||||
FailedRelayImage(url: nil)
|
||||
}
|
||||
|
||||
23
damus/Views/Utils/KFClickable.swift
Normal file
23
damus/Views/Utils/KFClickable.swift
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// ClickableOverlay.swift
|
||||
// damus
|
||||
//
|
||||
// Created by Daniel D’Aquino on 2024-09-20.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
/// Applies a property that makes `KFAnimatedImage` clickable again on iOS 18+
|
||||
fileprivate struct KFClickable: ViewModifier {
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
}
|
||||
|
||||
extension View {
|
||||
/// Applies a property that makes `KFAnimatedImage` clickable again on iOS 18+
|
||||
func kfClickable() -> some View {
|
||||
return self.modifier(KFClickable())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user