Skip to content

Commit

Permalink
Merge pull request #994 from novasamatech/develop
Browse files Browse the repository at this point in the history
v7.9.3
  • Loading branch information
ERussel committed Feb 28, 2024
2 parents b18ba50 + 83f4b2f commit 0893b81
Show file tree
Hide file tree
Showing 54 changed files with 1,301 additions and 112 deletions.
2 changes: 1 addition & 1 deletion Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ abstract_target 'novawalletAll' do
pod 'SwiftLint'
pod 'R.swift', :inhibit_warnings => true
pod 'SoraKeystore', '~> 1.0.0'
pod 'SoraUI', :git => 'https://github.com/ERussel/UIkit-iOS.git', :tag => '1.12.0'
pod 'SoraUI', :git => 'https://github.com/ERussel/UIkit-iOS.git', :tag => '1.13.0'
pod 'RobinHood', '~> 2.6.0'
pod 'SoraFoundation', :git => 'https://github.com/ERussel/Foundation-iOS.git', :tag => '1.1.0'
pod 'SwiftyBeaver'
Expand Down
62 changes: 31 additions & 31 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -61,38 +61,38 @@ PODS:
- SoraFoundation/NotificationHandlers
- SoraFoundation/ViewModel (1.1.0)
- SoraKeystore (1.0.0)
- SoraUI (1.12.0):
- SoraUI/AdaptiveDesign (= 1.12.0)
- SoraUI/Animator (= 1.12.0)
- SoraUI/Camera (= 1.12.0)
- SoraUI/Controls (= 1.12.0)
- SoraUI/DetailsView (= 1.12.0)
- SoraUI/EmptyState (= 1.12.0)
- SoraUI/Helpers (= 1.12.0)
- SoraUI/LoadingView (= 1.12.0)
- SoraUI/ModalPresentation (= 1.12.0)
- SoraUI/PageLoader (= 1.12.0)
- SoraUI/PinView (= 1.12.0)
- SoraUI/Skrull (= 1.12.0)
- SoraUI/AdaptiveDesign (1.12.0)
- SoraUI/Animator (1.12.0)
- SoraUI/Camera (1.12.0)
- SoraUI/Controls (1.12.0):
- SoraUI (1.13.0):
- SoraUI/AdaptiveDesign (= 1.13.0)
- SoraUI/Animator (= 1.13.0)
- SoraUI/Camera (= 1.13.0)
- SoraUI/Controls (= 1.13.0)
- SoraUI/DetailsView (= 1.13.0)
- SoraUI/EmptyState (= 1.13.0)
- SoraUI/Helpers (= 1.13.0)
- SoraUI/LoadingView (= 1.13.0)
- SoraUI/ModalPresentation (= 1.13.0)
- SoraUI/PageLoader (= 1.13.0)
- SoraUI/PinView (= 1.13.0)
- SoraUI/Skrull (= 1.13.0)
- SoraUI/AdaptiveDesign (1.13.0)
- SoraUI/Animator (1.13.0)
- SoraUI/Camera (1.13.0)
- SoraUI/Controls (1.13.0):
- SoraUI/Animator
- SoraUI/DetailsView (1.12.0):
- SoraUI/DetailsView (1.13.0):
- SoraUI/Controls
- SoraUI/EmptyState (1.12.0):
- SoraUI/EmptyState (1.13.0):
- SoraUI/Animator
- SoraUI/Helpers (1.12.0)
- SoraUI/LoadingView (1.12.0):
- SoraUI/Helpers (1.13.0)
- SoraUI/LoadingView (1.13.0):
- SoraUI/Controls
- SoraUI/ModalPresentation (1.12.0):
- SoraUI/ModalPresentation (1.13.0):
- SoraUI/Animator
- SoraUI/Controls
- SoraUI/PageLoader (1.12.0)
- SoraUI/PinView (1.12.0):
- SoraUI/PageLoader (1.13.0)
- SoraUI/PinView (1.13.0):
- SoraUI/Controls
- SoraUI/Skrull (1.12.0)
- SoraUI/Skrull (1.13.0)
- Sourcery (1.4.1)
- Starscream (4.0.8)
- SubstrateSdk (1.17.0):
Expand Down Expand Up @@ -161,7 +161,7 @@ DEPENDENCIES:
- SnapKit (~> 5.0.0)
- SoraFoundation (from `https://github.com/ERussel/Foundation-iOS.git`, tag `1.1.0`)
- SoraKeystore (~> 1.0.0)
- SoraUI (from `https://github.com/ERussel/UIkit-iOS.git`, tag `1.12.0`)
- SoraUI (from `https://github.com/ERussel/UIkit-iOS.git`, tag `1.13.0`)
- Sourcery (~> 1.4)
- Starscream (from `https://github.com/ERussel/Starscream.git`, tag `4.0.8`)
- SubstrateSdk (from `https://github.com/nova-wallet/substrate-sdk-ios.git`, tag `1.17.0`)
Expand Down Expand Up @@ -219,7 +219,7 @@ EXTERNAL SOURCES:
:tag: 1.1.0
SoraUI:
:git: https://github.com/ERussel/UIkit-iOS.git
:tag: 1.12.0
:tag: 1.13.0
Starscream:
:git: https://github.com/ERussel/Starscream.git
:tag: 4.0.8
Expand Down Expand Up @@ -253,7 +253,7 @@ CHECKOUT OPTIONS:
:tag: 1.1.0
SoraUI:
:git: https://github.com/ERussel/UIkit-iOS.git
:tag: 1.12.0
:tag: 1.13.0
Starscream:
:git: https://github.com/ERussel/Starscream.git
:tag: 4.0.8
Expand Down Expand Up @@ -294,7 +294,7 @@ SPEC CHECKSUMS:
SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
SoraFoundation: 5b9d3c82d602150d2c2e65481c5eca5f5987c12c
SoraKeystore: 92cff6e2a12f212dd64ed089970ff7c365247b1c
SoraUI: a3c1163a95c9dd1b6758ca90eb5bda2f4639d634
SoraUI: 1d1a25881d1d597f19bc55f82c99ee236cc1ab11
Sourcery: db66600e8b285c427701821598d07cf3c7e6c476
Starscream: b676ee89781677a2d8d36029a78c970710e2d3eb
SubstrateSdk: a67e5c58fc9a7b31f24e1dc43e7dd44568018c83
Expand All @@ -312,6 +312,6 @@ SPEC CHECKSUMS:
ZMarkupParser: a92d31ba40695b790f1da5fec98c3d4505341aff
ZNSTextAttachment: 1ddd53660a8d3c42dbb716bf6866ffce22c44181

PODFILE CHECKSUM: aa3fb53d81d4ec88f1cc632534e55682e7632451
PODFILE CHECKSUM: 798bed5133df90a8c4cc6f210493388b77dcda3f

COCOAPODS: 1.13.0
COCOAPODS: 1.15.2
50 changes: 49 additions & 1 deletion novawallet.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions novawallet/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
) -> Bool {
URLHandlingService.shared.handle(url: url)
}

func application(_: UIApplication, supportedInterfaceOrientationsFor _: UIWindow?) -> UIInterfaceOrientationMask {
DeviceOrientationManager.shared.enabledOrientations
}
}
59 changes: 56 additions & 3 deletions novawallet/Common/DataProvider/NftLocalSubscriptionFactory.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation
import RobinHood
import SubstrateSdk

protocol NftLocalSubscriptionFactoryProtocol {
func getNftProvider(for wallet: MetaAccountModel, chains: [ChainModel]) -> StreamableProvider<NftModel>
Expand Down Expand Up @@ -42,7 +43,7 @@ final class NftLocalSubscriptionFactory: SubstrateLocalSubscriptionFactory,
type: NftType
) -> AnyDataProviderRepository<NftModel> {
let mapper = AnyCoreDataMapper(NftModelMapper())
let filter = NSPredicate.nfts(for: [(chain.chainId, ownerId)], type: type.rawValue)
let filter = NSPredicate.nfts(for: [(chain.chainId, ownerId)], type: type)
let sortDescriptor = NSSortDescriptor.nftsByCreationDesc
let repository = storageFacade.createRepository(
filter: filter,
Expand All @@ -53,6 +54,29 @@ final class NftLocalSubscriptionFactory: SubstrateLocalSubscriptionFactory,
return AnyDataProviderRepository(repository)
}

private func createClearService() -> NftSyncServiceProtocol? {
let excludedTypes = NftType.excludedTypes

guard !excludedTypes.isEmpty else {
return nil
}

let mapper = AnyCoreDataMapper(NftModelMapper())
let filter = NSPredicate.nftsForTypes(excludedTypes)
let repository = storageFacade.createRepository(
filter: filter,
sortDescriptors: [],
mapper: mapper
)

return NFTClearService(
repository: AnyDataProviderRepository(repository),
operationQueue: operationQueue,
retryStrategy: ExponentialReconnection(),
logger: logger
)
}

private func createUniquesService(
for chain: ChainModel,
ownerId: AccountId
Expand Down Expand Up @@ -107,11 +131,27 @@ final class NftLocalSubscriptionFactory: SubstrateLocalSubscriptionFactory,
)
}

private func createKodaDotService(for chain: ChainModel, ownerId: AccountId) -> NftSyncServiceProtocol? {
guard let apiUrl = KodaDotAssetHubApi.apiForChain(chain.chainId) else {
return nil
}

let repository = createSyncRepository(for: chain, ownerId: ownerId, type: .kodadot)

return KodaDotNftSyncService(
api: apiUrl,
ownerId: ownerId,
chain: chain,
repository: repository,
operationQueue: operationQueue
)
}

private func createService(
for chain: ChainModel,
ownerId: AccountId,
type: NftType
) -> NftSyncServiceProtocol {
) -> NftSyncServiceProtocol? {
switch type {
case .uniques:
return createUniquesService(for: chain, ownerId: ownerId)
Expand All @@ -121,6 +161,8 @@ final class NftLocalSubscriptionFactory: SubstrateLocalSubscriptionFactory,
return createRMRKV2Service(for: chain, ownerId: ownerId)
case .pdc20:
return createPdc20Service(for: chain, ownerId: ownerId)
case .kodadot:
return createKodaDotService(for: chain, ownerId: ownerId)
}
}

Expand Down Expand Up @@ -154,12 +196,23 @@ final class NftLocalSubscriptionFactory: SubstrateLocalSubscriptionFactory,

let nftOptions = createNftOptions(for: wallet, chains: chains)

let syncServices = nftOptions.map { option in
var syncServices = nftOptions.compactMap { option in
createService(for: option.chain, ownerId: option.ownerId, type: option.type)
}

if let clearService = createClearService() {
syncServices.insert(clearService, at: 0)
}

let dataSource = NftStreamableSource(syncServices: syncServices)

/**
* We can now have cases:
* 1) When we don't sync nfts (don't have source for it) but want to display it from cache (rmrk v1).
* 2) Don't have source for nfts and don't want to display them from cache (uniques).
* Probably we want to remove such nfts from cache and don't provide source for them in future.
*/

let mapper = AnyCoreDataMapper(NftModelMapper())
let observable = CoreDataContextObservable(
service: storageFacade.databaseService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,16 +217,28 @@ extension NSPredicate {
return NSCompoundPredicate(andPredicateWithSubpredicates: [chainPredicate, ownerPredicate])
}

static func nfts(for type: UInt16) -> NSPredicate {
NSPredicate(format: "%K == %d", #keyPath(CDNft.type), type)
}

static func nfts(for chainAccounts: [(ChainModel.Id, AccountId)]) -> NSPredicate {
let predicates = chainAccounts.map { nfts(for: $0.0, ownerId: $0.1) }
return NSCompoundPredicate(orPredicateWithSubpredicates: predicates)
}

static func nfts(for chainAccounts: [(ChainModel.Id, AccountId)], type: UInt16) -> NSPredicate {
static func nfts(for type: NftType) -> NSPredicate {
NSPredicate(format: "%K == %d", #keyPath(CDNft.type), type.rawValue)
}

static func nftsForTypes(_ types: Set<NftType>) -> NSPredicate {
let orPredicates = types.map { nfts(for: $0) }
return NSCompoundPredicate(orPredicateWithSubpredicates: orPredicates)
}

static func nfts(for chainAccounts: [(ChainModel.Id, AccountId)], types: Set<NftType>) -> NSPredicate {
let chainAccountPredicate = nfts(for: chainAccounts)
let orPredicates = types.map { nfts(for: $0) }
let typesPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: orPredicates)
return NSCompoundPredicate(andPredicateWithSubpredicates: [chainAccountPredicate, typesPredicate])
}

static func nfts(for chainAccounts: [(ChainModel.Id, AccountId)], type: NftType) -> NSPredicate {
let chainAccountPredicate = nfts(for: chainAccounts)
let typePredicate = nfts(for: type)
return NSCompoundPredicate(andPredicateWithSubpredicates: [chainAccountPredicate, typePredicate])
Expand Down
7 changes: 7 additions & 0 deletions novawallet/Common/Extension/Foundation/String+Search.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Foundation

extension String {
func contains(substring: String) -> Bool {
range(of: substring) != nil
}
}
36 changes: 36 additions & 0 deletions novawallet/Common/Helpers/DeviceOrientationManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import UIKit

protocol DeviceOrientationManaging {
var enabledOrientations: UIInterfaceOrientationMask { get }

func enableLandscape()
func disableLandscape()
}

final class DeviceOrientationManager {
static let shared = DeviceOrientationManager(isLandscapeEnabled: false)

private var isLandscapeEnabled: Bool

init(isLandscapeEnabled: Bool) {
self.isLandscapeEnabled = isLandscapeEnabled
}
}

extension DeviceOrientationManager: DeviceOrientationManaging {
var enabledOrientations: UIInterfaceOrientationMask {
if isLandscapeEnabled {
return [.portrait, .landscapeLeft, .landscapeRight]
} else {
return .portrait
}
}

func enableLandscape() {
isLandscapeEnabled = true
}

func disableLandscape() {
isLandscapeEnabled = false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ final class DistributedUrlParser: DistributedUrlParserProtocol {

switch DistributedStorageScheme(rawValue: scheme) {
case .ipfs:
return .ipfs(hash: urlComponents.path)
if let host = urlComponents.host, host != "ipfs" {
return .ipfs(hash: (host as NSString).appendingPathComponent(urlComponents.path))
} else {
return .ipfs(hash: urlComponents.path)
}
case .none:
return nil
}
Expand Down
12 changes: 11 additions & 1 deletion novawallet/Common/Network/Files/FileDownloadOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,17 @@ final class FileDownloadOperation: BaseOperation<URLResponse> {
let dataTask = networkSession.downloadTask(with: remoteUrl) { tempUrl, response, networkError in
do {
if let tempUrl = tempUrl {
if !currentFileManager.fileExists(atPath: directoryUrl.path) {
var isDirectory: ObjCBool = false
let parentExists = currentFileManager.fileExists(
atPath: directoryUrl.path,
isDirectory: &isDirectory
)

if !parentExists || !isDirectory.boolValue {
if parentExists {
try currentFileManager.removeItem(at: directoryUrl)
}

try currentFileManager.createDirectory(
at: directoryUrl,
withIntermediateDirectories: true,
Expand Down
4 changes: 2 additions & 2 deletions novawallet/Common/Services/ServiceCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ extension ServiceCoordinator: ServiceCoordinatorProtocol {

extension ServiceCoordinator {
// swiftlint:disable:next function_body_length
static func createDefault() -> ServiceCoordinatorProtocol {
static func createDefault(for urlHandlingFacade: URLHandlingServiceFacadeProtocol) -> ServiceCoordinatorProtocol {
let githubPhishingAPIService = GitHubPhishingServiceFactory.createService()

let chainRegistry = ChainRegistryFacade.sharedRegistry
Expand Down Expand Up @@ -232,7 +232,7 @@ extension ServiceCoordinator {
githubPhishingService: githubPhishingAPIService,
equilibriumService: equilibriumService,
proxySyncService: proxySyncService,
dappMediator: DAppInteractionFactory.createMediator(),
dappMediator: DAppInteractionFactory.createMediator(for: urlHandlingFacade),
walletNotificationService: walletNotificationService,
syncModeUpdateService: syncModeUpdateService
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import Foundation

struct WalletConnectMetadata {
struct Redirect {
let native: String?
let universal: String?
}

let projectId: String
let name: String
let description: String
let website: String
let icon: String
let redirect: Redirect
}

extension WalletConnectMetadata {
Expand All @@ -15,7 +21,11 @@ extension WalletConnectMetadata {
name: "Nova wallet",
description: "Next-gen wallet for Polkadot and Kusama ecosystem",
website: "https://novawallet.io",
icon: "https://raw.githubusercontent.com/novasamatech/branding/master/logos/Nova_Wallet_Star_Color.png"
icon: "https://raw.githubusercontent.com/novasamatech/branding/master/logos/Nova_Wallet_Star_Color.png",
redirect: .init(
native: "novawallet://request",
universal: nil
)
)
}
}

0 comments on commit 0893b81

Please sign in to comment.