From 2ff12de052305e74778bc2ee00276540d6e5f754 Mon Sep 17 00:00:00 2001 From: Vova Ignatov Date: Fri, 12 Jul 2024 15:07:34 +0100 Subject: [PATCH] IOS-3069 Add p2p status support --- Anytype.xcodeproj/project.pbxproj | 4 ++ Anytype/Generated/ImageAssets.swift | 2 + Anytype/Generated/Strings.swift | 10 ++- .../sync_p2p_connected.imageset/Contents.json | 12 ++++ .../sync_p2p_connected.imageset/P2P.pdf | Bin 0 -> 1202 bytes .../sync_p2p_default.imageset/Contents.json | 12 ++++ .../sync_p2p_default.imageset/P2P.pdf | Bin 0 -> 1195 bytes .../Strings/en.lproj/Localizable.strings | 5 +- .../Strings/en.lproj/Localizable.stringsdict | 16 +++++ .../Model/P2PStatusInfoExtension.swift | 58 ++++++++++++++++++ .../SyncStatus/SyncStatusInfoView.swift | 29 +++++++-- .../SyncStatus/SyncStatusInfoViewModel.swift | 8 ++- .../P2PStatus/P2PStatusStorage.swift | 8 ++- Anytype/Sources/ServiceLayer/ServicesDI.swift | 4 ++ .../SyncStatus/SyncStatusStorage.swift | 1 + 15 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_connected.imageset/Contents.json create mode 100644 Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_connected.imageset/P2P.pdf create mode 100644 Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_default.imageset/Contents.json create mode 100644 Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_default.imageset/P2P.pdf create mode 100644 Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/Model/P2PStatusInfoExtension.swift diff --git a/Anytype.xcodeproj/project.pbxproj b/Anytype.xcodeproj/project.pbxproj index de22d6e28e..2e9bada85c 100644 --- a/Anytype.xcodeproj/project.pbxproj +++ b/Anytype.xcodeproj/project.pbxproj @@ -1296,6 +1296,7 @@ 3D929B2B263302160063F1BE /* TypographyExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D929B2A263302160063F1BE /* TypographyExample.swift */; }; 3D929B2F263307700063F1BE /* AnytypeFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D929B2E263307700063F1BE /* AnytypeFont.swift */; }; 3D92E9A52C41219B00A1998C /* P2PStatusStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92E9A42C41219B00A1998C /* P2PStatusStorage.swift */; }; + 3D92E9A72C41334B00A1998C /* P2PStatusInfoExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92E9A62C41334B00A1998C /* P2PStatusInfoExtension.swift */; }; 3D92E9A92C4133A700A1998C /* NetworkIconProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D92E9A82C4133A700A1998C /* NetworkIconProvider.swift */; }; 3D932D5726317EFC00C7D1EA /* CommonViews+Pickers+File+UIKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D932D5326317EFB00C7D1EA /* CommonViews+Pickers+File+UIKit.swift */; }; 3D932D5826317EFC00C7D1EA /* BaseFilePickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D932D5426317EFB00C7D1EA /* BaseFilePickerViewModel.swift */; }; @@ -3119,6 +3120,7 @@ 3D929B2A263302160063F1BE /* TypographyExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypographyExample.swift; sourceTree = ""; }; 3D929B2E263307700063F1BE /* AnytypeFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnytypeFont.swift; sourceTree = ""; }; 3D92E9A42C41219B00A1998C /* P2PStatusStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = P2PStatusStorage.swift; sourceTree = ""; }; + 3D92E9A62C41334B00A1998C /* P2PStatusInfoExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = P2PStatusInfoExtension.swift; sourceTree = ""; }; 3D92E9A82C4133A700A1998C /* NetworkIconProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkIconProvider.swift; sourceTree = ""; }; 3D932D5326317EFB00C7D1EA /* CommonViews+Pickers+File+UIKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CommonViews+Pickers+File+UIKit.swift"; sourceTree = ""; }; 3D932D5426317EFB00C7D1EA /* BaseFilePickerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFilePickerViewModel.swift; sourceTree = ""; }; @@ -9566,6 +9568,7 @@ children = ( 3D92E9A82C4133A700A1998C /* NetworkIconProvider.swift */, 3D2ED6D72C3ECA47003718DE /* SyncStatusInfoExtension.swift */, + 3D92E9A62C41334B00A1998C /* P2PStatusInfoExtension.swift */, 3DD72C2A2C3FEDDA002C5ACC /* Anytype_Event.Space.SyncError+Localizable.swift */, ); path = Model; @@ -11725,6 +11728,7 @@ 2AE276242BD0270000E0244A /* ObjectSettingsCoordinatorView.swift in Sources */, 3DE50F952C130F5C00B92C1F /* SpaceShareUpgradeView.swift in Sources */, 53EDA8802837EC4000887804 /* CreateObjectView.swift in Sources */, + 3D92E9A72C41334B00A1998C /* P2PStatusInfoExtension.swift in Sources */, 1244792227D8A8BE00581174 /* StatusSearchRowView.swift in Sources */, 2A845D752B0D027300AFD252 /* WidgetSwipeActionView.swift in Sources */, 2E1AA7FD2BCEBF180089B136 /* SetLayoutSettingsData.swift in Sources */, diff --git a/Anytype/Generated/ImageAssets.swift b/Anytype/Generated/ImageAssets.swift index 1627d2dea5..29910405f7 100644 --- a/Anytype/Generated/ImageAssets.swift +++ b/Anytype/Generated/ImageAssets.swift @@ -397,6 +397,8 @@ internal extension ImageAsset { static let syncInProgress = ImageAsset.bundle(name: "SyncStatus/sync_in_progress") static let syncLocalonlyDefault = ImageAsset.bundle(name: "SyncStatus/sync_localonly_default") static let syncOffline = ImageAsset.bundle(name: "SyncStatus/sync_offline") + static let syncP2pConnected = ImageAsset.bundle(name: "SyncStatus/sync_p2p_connected") + static let syncP2pDefault = ImageAsset.bundle(name: "SyncStatus/sync_p2p_default") static let syncSelfhostConnected = ImageAsset.bundle(name: "SyncStatus/sync_selfhost_connected") static let syncSelfhostDefault = ImageAsset.bundle(name: "SyncStatus/sync_selfhost_default") static let syncSelfhostError = ImageAsset.bundle(name: "SyncStatus/sync_selfhost_error") diff --git a/Anytype/Generated/Strings.swift b/Anytype/Generated/Strings.swift index de2293b9cb..5f3ce27d19 100644 --- a/Anytype/Generated/Strings.swift +++ b/Anytype/Generated/Strings.swift @@ -76,7 +76,7 @@ internal enum Loc { internal static let color = Loc.tr("Localizable", "Color") internal static let companiesContactsFriendsAndFamily = Loc.tr("Localizable", "Companies, contacts, friends and family") internal static let confirm = Loc.tr("Localizable", "Confirm") - internal static let connecting = Loc.tr("Localizable", "Connecting...") + internal static let connecting = Loc.tr("Localizable", "Connecting") internal static let copied = Loc.tr("Localizable", "Copied") internal static func copiedToClipboard(_ p1: Any) -> String { return Loc.tr("Localizable", "copied to clipboard", String(describing: p1)) @@ -108,6 +108,9 @@ internal enum Loc { internal static let description = Loc.tr("Localizable", "Description") internal static let deselectAll = Loc.tr("Localizable", "Deselect all") internal static let designedToCaptureThoughtsQuickly = Loc.tr("Localizable", "Designed to capture thoughts quickly") + internal static func devicesConnected(_ p1: Int) -> String { + return Loc.tr("Localizable", "Devices connected", p1) + } internal static let done = Loc.tr("Localizable", "Done") internal static let download = Loc.tr("Localizable", "Download") internal static let downloadingOrUploadingDataToSomeNode = Loc.tr("Localizable", "Downloading or uploading data to some node") @@ -219,6 +222,8 @@ internal enum Loc { } internal static let other = Loc.tr("Localizable", "Other") internal static let otherRelations = Loc.tr("Localizable", "Other relations") + internal static let p2PConnecting = Loc.tr("Localizable", "P2P Connecting") + internal static let p2PConnection = Loc.tr("Localizable", "P2P Connection") internal static func paidBy(_ p1: Any) -> String { return Loc.tr("Localizable", "Paid by", String(describing: p1)) } @@ -1709,6 +1714,9 @@ internal enum Loc { internal static let anytypeNetwork = Loc.tr("Localizable", "SyncStatus.Info.AnytypeNetwork") internal static let localOnly = Loc.tr("Localizable", "SyncStatus.Info.localOnly") } + internal enum P2P { + internal static let restricted = Loc.tr("Localizable", "SyncStatus.P2P.Restricted") + } } internal enum TalbeOfContents { internal static let empty = Loc.tr("Localizable", "TalbeOfContents.Empty") diff --git a/Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_connected.imageset/Contents.json b/Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_connected.imageset/Contents.json new file mode 100644 index 0000000000..87285cf7a3 --- /dev/null +++ b/Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_connected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "P2P.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_connected.imageset/P2P.pdf b/Anytype/Resources/Assets.xcassets/SyncStatus/sync_p2p_connected.imageset/P2P.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1e9b62263cbfa2f3cbe1e4716266e2e1ea791948 GIT binary patch literal 1202 zcmY!laBvK;I`dFTEr~!5FAK2q*+Jp}3?dH8Gc~g0XhW!MxiB0xs|WaLwhuBB!j)Bv)|4;cG=`v_Q_K^uPdX}az!pl#ciKH<>Wc<`*)S+`n@il zx!mT-$0^4vHLsrn%B`zS-m;Wi(m_hds>$uewUEDAygN-cdi&Z689Adr8V#TpBWu0vGUDIj$0*|s`+}6Y~Xg5RhPH)2qnCfo^I?^?%lSud*`iN&0(yj z%6&Y+<`1eGSra829cAX%Fg*KfbM9(eR;KBm<9Gb;hX~*LZMFYgjZO87oTj9+m)Bo2 zD3{c_s8=wrOTVOD&pGzYqUS-;3#Mgh(XFnFx1arUqH?j7!|K)b78Cf7Uv+R4 zam&84NM1#;v?PAol*{7$Tc-YIjS5p_-EwFv<0T$`y^1NZye(PYSKU_g-9A!sZVLB& z=3Qy0mN^EW7t}h`w58_3I+oMy3u>SKJL2}8Imnv-UAf=Ys}3u)L|3fiH=NELSaNoX zZ}YNw${{VRFQb3`)!e&8{-yo;2XmW12@IM-U`Y*>b|6X6)YufB08QYcz=Wyqn3tDd zQmhai3r%(*l?AB^`T>dQuyp8~nv$95lwY9`tze*M00sz#u@OuN!Gf6-lvEp8$tO1CK!-d1Qb&+g$g0%7LX7;7wLOvrU0F)0P;bQ0?Z!g z{8FG^Lk#y9Lvjr)Fw9U)0(r0)ZXw8F5RW@2mL%rnr=x1EC`wJ^GEgw*f_NW9Dwvr9 z!&Ct%3vK;I`dFTEr~!5FAK2q*+Jp}3?dH8Gc~g0XhW!M-a70xs|WbwbOu^Zfd^KYw2@fB3oo%ai4A zP5=5;&bcMEOs+;H>HR0Q8}BluP8&Th4Sn|i;OlRbjBZxGyl8vrb4Bd*pL5!6dMjs5 z-xRh?cWvU^#*5SRQW!ElUfeKo+P>^nc=m~2jlb5$ej!{}4X z|E1_D`<#CqnR~|Dbdk=}T^dQ(bsJxq=q_f7sCrQ3_9E}(h7!Z@-QRpyH_Z}sZ(Au{ zu=haIhMofoeg1X~pX=n7XE|@(B6aWk9e@5+oNsIA#;4oOt9_l)lyvs;`fCQ|l3Ew_ zswSBI`)GIJZ18CfkE}8q#_Y0$d;Jdg9vc34s%pFWU*` zKn=fP8tw`4Th#miU_E@L+%MVNptK}p!4>A$y(Wj_%$?Xnm{|iQ)&_Qeo7nQl*lOF= zi?d@lOCBtgIQaAetIyeOT-|Q@2mhR?Tx{jAdUd_U1peb!9UMj6vac+XS5Yi2iJvy* zvN->islQpH);Zm}z;&I?!`NoWgTOLVfmOPpjbXCeI$zGw6t`n9IXlI-dD%SWkQUa= zp9f+&r|~=dKJ~Y=_Z|C^GPyhN=d4=Y7!axz5G$XgCth~ZG}w%HR#jhspxBc9m(Sb3 zOxm|}fBv<(J3%Q6nlxZ(43uafY0uQi0-o|r;G)13sqdJVmtRt>5FHCmZy}WhsS5f5 ziRrKe=$o37ndp>Xp%ATLpl1LE2!^o{ObEe(nG}>-oL^d$oLZ~^$^)Rp3rf$<`FSO& zc|aRM82~02kXQs1Q!s@JA!QSg5Ip9_Rd0pk6}^_ZLI53oJ0q zP)q`Ouo!M3$YBtVJ13ST=H#cNYON?rP2)09Fz14JA4DpcnVK4#DgcF{z|cSe%u>jM z3mF652?7WqGZUaI(1gq^(1k2afB}Z8%F+-R5Ky6#qQuOc)FLiW?0LEXgF~Y@KQ~oV uK_fFo6A~!;LHYS53Lp=I16V&evnmzndT`m1SX2V`j-|N?m#V6(zZ(EKlC4<) literal 0 HcmV?d00001 diff --git a/Anytype/Resources/Strings/en.lproj/Localizable.strings b/Anytype/Resources/Strings/en.lproj/Localizable.strings index 2a13c33dc7..a80a9819ec 100644 --- a/Anytype/Resources/Strings/en.lproj/Localizable.strings +++ b/Anytype/Resources/Strings/en.lproj/Localizable.strings @@ -612,7 +612,9 @@ "Node is not connected" = "Node is not connected"; "Initializing sync" = "Initializing sync"; "Incompatible version" = "Incompatible version"; -"Connecting..." = "Connecting..."; +"Connecting" = "Connecting..."; +"P2P Connecting" = "P2P Connecting..."; +"P2P Connection" = "P2P Connection"; "Anytype Network" = "Anytype Network"; "Self Host" = "Self Host"; "Local Only" = "Local Only"; @@ -1176,6 +1178,7 @@ Please provide specific details of your needs here."; "SyncStatus.Error.incompatibleVersion" = "Incompatible version"; "SyncStatus.Error.networkError" = "No access to the space"; "SyncStatus.Error.UNRECOGNIZED" = "Unrecognized error"; +"SyncStatus.P2P.Restricted" = "Restricted. Check device settings."; // MARK: - Debug diff --git a/Anytype/Resources/Strings/en.lproj/Localizable.stringsdict b/Anytype/Resources/Strings/en.lproj/Localizable.stringsdict index ccca81f903..38b706c895 100644 --- a/Anytype/Resources/Strings/en.lproj/Localizable.stringsdict +++ b/Anytype/Resources/Strings/en.lproj/Localizable.stringsdict @@ -18,6 +18,22 @@ %ld items + Devices connected + + NSStringLocalizedFormatKey + %#@device@ connected + device + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld device + other + %ld devices + + Are you sure you want to delete NSStringLocalizedFormatKey diff --git a/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/Model/P2PStatusInfoExtension.swift b/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/Model/P2PStatusInfoExtension.swift new file mode 100644 index 0000000000..91e4e1b74a --- /dev/null +++ b/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/Model/P2PStatusInfoExtension.swift @@ -0,0 +1,58 @@ +import Services +import SwiftUI + + +extension P2PStatusInfo { + static func `default`(spaceId: String) -> P2PStatusInfo { + var info = P2PStatusInfo() + info.status = .UNRECOGNIZED(1337) + info.spaceID = spaceId + return info + } +} + +// Texts +extension P2PStatusInfo { + var networkTitle: String { + switch status { + case .notConnected, .UNRECOGNIZED: + Loc.p2PConnecting + case .notPossible, .connected: + Loc.p2PConnection + } + } + + var networkSubtitle: String { + switch status { + case .notConnected, .UNRECOGNIZED: + "" + case .notPossible: + Loc.SyncStatus.P2P.restricted + case .connected: + Loc.devicesConnected(Int(devicesCounter)) + } + } +} + +// MARK: - NetworkIconProvider +extension P2PStatusInfo: NetworkIconProvider { + var icon: ImageAsset { + switch self.status { + case .notConnected, .notPossible, .UNRECOGNIZED: + ImageAsset.SyncStatus.syncP2pDefault + case .connected: + ImageAsset.SyncStatus.syncP2pConnected + } + } + + var background: NetworkIconBackground { + switch status { + case .notConnected: + .animation(start: .Light.green, end: .Light.green.opacity(0.5)) + case .notPossible, .UNRECOGNIZED: + .static(.Shape.secondary) + case .connected: + .static(.Light.green) + } + } +} diff --git a/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/SyncStatusInfoView.swift b/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/SyncStatusInfoView.swift index c05b7656fb..e459e835b7 100644 --- a/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/SyncStatusInfoView.swift +++ b/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/SyncStatusInfoView.swift @@ -11,7 +11,8 @@ struct SyncStatusInfoView: View { var body: some View { VStack(spacing: 0) { DragIndicator() - networkInfo + networkInfo.newDivider() + p2pInfo } .padding(8) .cornerRadius(16, style: .continuous) @@ -20,14 +21,34 @@ struct SyncStatusInfoView: View { } var networkInfo: some View { - HStack(spacing: 12) { + HStack(alignment: .center, spacing: 12) { NetworkIconView(iconProvider: $model.syncStatusInfo) VStack(alignment: .leading, spacing: 0) { AnytypeText(model.syncStatusInfo.networkTitle, style: .uxTitle2Regular) .lineLimit(1) - AnytypeText(model.syncStatusInfo.networkSubtitle, style: .relation3Regular) - .foregroundColor(.Text.secondary) + if model.syncStatusInfo.networkSubtitle.isNotEmpty { + AnytypeText(model.syncStatusInfo.networkSubtitle, style: .relation3Regular) + .foregroundColor(.Text.secondary) + .lineLimit(1) + } + } + Spacer() + } + .padding(.horizontal, 16) + .padding(.vertical, 12) + } + + var p2pInfo: some View { + HStack(alignment: .center, spacing: 12) { + NetworkIconView(iconProvider: $model.p2pStatusInfo) + VStack(alignment: .leading, spacing: 0) { + AnytypeText(model.p2pStatusInfo.networkTitle, style: .uxTitle2Regular) .lineLimit(1) + if model.p2pStatusInfo.networkSubtitle.isNotEmpty { + AnytypeText(model.p2pStatusInfo.networkSubtitle, style: .relation3Regular) + .foregroundColor(.Text.secondary) + .lineLimit(1) + } } Spacer() } diff --git a/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/SyncStatusInfoViewModel.swift b/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/SyncStatusInfoViewModel.swift index d2ad857771..61a82b7961 100644 --- a/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/SyncStatusInfoViewModel.swift +++ b/Anytype/Sources/PresentationLayer/Common/SwiftUI/SyncStatus/SyncStatusInfoViewModel.swift @@ -5,13 +5,17 @@ import Services final class SyncStatusInfoViewModel: ObservableObject { @Injected(\.syncStatusStorage) private var syncStatusStorage: SyncStatusStorageProtocol + @Injected(\.p2pStatusStorage) + private var p2pStatusStorage: P2PStatusStorageProtocol @Published var syncStatusInfo: SyncStatusInfo + @Published var p2pStatusInfo: P2PStatusInfo init(spaceId: String) { syncStatusInfo = .default(spaceId: spaceId) + p2pStatusInfo = .default(spaceId: spaceId) Task { await syncStatusStorage.statusPublisher(spaceId: spaceId).assign(to: &$syncStatusInfo) } - } - + Task { await p2pStatusStorage.statusPublisher(spaceId: spaceId).assign(to: &$p2pStatusInfo) } + } } diff --git a/Anytype/Sources/ServiceLayer/P2PStatus/P2PStatusStorage.swift b/Anytype/Sources/ServiceLayer/P2PStatus/P2PStatusStorage.swift index 3e67e5c103..275fb5a925 100644 --- a/Anytype/Sources/ServiceLayer/P2PStatus/P2PStatusStorage.swift +++ b/Anytype/Sources/ServiceLayer/P2PStatus/P2PStatusStorage.swift @@ -5,7 +5,7 @@ import ProtobufMessages protocol P2PStatusStorageProtocol { - func statusPublisher(spaceId: String) async -> AnyPublisher + func statusPublisher(spaceId: String) async -> AnyPublisher func startSubscription() async func stopSubscriptionAndClean() async @@ -20,10 +20,12 @@ actor P2PStatusStorage: P2PStatusStorageProtocol { init() { } - func statusPublisher(spaceId: String) -> AnyPublisher { + func statusPublisher(spaceId: String) -> AnyPublisher { updatePublisher .filter { $0?.spaceID == spaceId} - .merge(with: Just(defaultValues[spaceId])) + .compactMap { $0 } + .merge(with: Just(defaultValues[spaceId] ?? .default(spaceId: spaceId))) + .receiveOnMain() .eraseToAnyPublisher() } diff --git a/Anytype/Sources/ServiceLayer/ServicesDI.swift b/Anytype/Sources/ServiceLayer/ServicesDI.swift index 1364a1dd80..50863d27c6 100644 --- a/Anytype/Sources/ServiceLayer/ServicesDI.swift +++ b/Anytype/Sources/ServiceLayer/ServicesDI.swift @@ -291,4 +291,8 @@ extension Container { var syncStatusStorage: Factory< any SyncStatusStorageProtocol> { self { SyncStatusStorage() }.singleton } + + var p2pStatusStorage: Factory< any P2PStatusStorageProtocol> { + self { P2PStatusStorage() }.singleton + } } diff --git a/Anytype/Sources/ServiceLayer/SyncStatus/SyncStatusStorage.swift b/Anytype/Sources/ServiceLayer/SyncStatus/SyncStatusStorage.swift index 85cd3267df..2031930752 100644 --- a/Anytype/Sources/ServiceLayer/SyncStatus/SyncStatusStorage.swift +++ b/Anytype/Sources/ServiceLayer/SyncStatus/SyncStatusStorage.swift @@ -23,6 +23,7 @@ actor SyncStatusStorage: SyncStatusStorageProtocol { .filter { $0?.id == spaceId} .compactMap { $0 } .merge(with: Just(defaultValues[spaceId] ?? .default(spaceId: spaceId))) + .receiveOnMain() .eraseToAnyPublisher() }