diff --git a/.gitignore b/.gitignore index 710c043d2..7159cda8b 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ TODO.md */Topper-Info.plist */Coinbase-Info.plist */ZenLedger-Info.plist +CLAUDE.md diff --git a/DashWallet.xcodeproj/project.pbxproj b/DashWallet.xcodeproj/project.pbxproj index 364f6be6a..74604c1e5 100644 --- a/DashWallet.xcodeproj/project.pbxproj +++ b/DashWallet.xcodeproj/project.pbxproj @@ -597,6 +597,8 @@ 755049AA2C846299008FA7EB /* DWAboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 755049A72C846299008FA7EB /* DWAboutViewController.m */; }; 755049AC2C846576008FA7EB /* MenuItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755049AB2C846576008FA7EB /* MenuItemModel.swift */; }; 755049AD2C846576008FA7EB /* MenuItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755049AB2C846576008FA7EB /* MenuItemModel.swift */; }; + 7556EE412DF9876B004E8093 /* ExploreSyncBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EE402DF9876B004E8093 /* ExploreSyncBannerView.swift */; }; + 7556EE422DF9876B004E8093 /* ExploreSyncBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7556EE402DF9876B004E8093 /* ExploreSyncBannerView.swift */; }; 755A22BD2B1385FD001F170D /* IconAttributedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755A22BC2B1385FD001F170D /* IconAttributedText.swift */; }; 755B4B222B0C903500B844F0 /* DWDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755B4B212B0C903500B844F0 /* DWDateFormatter.swift */; }; 755B4B232B0C903500B844F0 /* DWDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755B4B212B0C903500B844F0 /* DWDateFormatter.swift */; }; @@ -2491,6 +2493,7 @@ 755049A72C846299008FA7EB /* DWAboutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DWAboutViewController.m; sourceTree = ""; }; 755049A82C846299008FA7EB /* DWAboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWAboutViewController.h; sourceTree = ""; }; 755049AB2C846576008FA7EB /* MenuItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemModel.swift; sourceTree = ""; }; + 7556EE402DF9876B004E8093 /* ExploreSyncBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreSyncBannerView.swift; sourceTree = ""; }; 755A22BC2B1385FD001F170D /* IconAttributedText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconAttributedText.swift; sourceTree = ""; }; 755B4B212B0C903500B844F0 /* DWDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DWDateFormatter.swift; sourceTree = ""; }; 755C32372C358FBD007DA721 /* BackupSeedPhraseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupSeedPhraseViewController.swift; sourceTree = ""; }; @@ -5771,6 +5774,7 @@ 47AE8BD328C1305E00490F5E /* MerchantListViewController.swift */, 47AE8BDD28C1305E00490F5E /* AtmListViewController.swift */, 47AE8BB728C1305E00490F5E /* AllMerchantLocationsViewController.swift */, + 7556EE402DF9876B004E8093 /* ExploreSyncBannerView.swift */, ); path = List; sourceTree = ""; @@ -8811,6 +8815,7 @@ C9F4520B2A1209D100825057 /* HomeHeaderModel.swift in Sources */, 47C6E6E02919578C003FEDF2 /* TerritoryListModel.swift in Sources */, 2AFF01DB243F4559003718DC /* DWDPRegistrationStatus.m in Sources */, + 7556EE412DF9876B004E8093 /* ExploreSyncBannerView.swift in Sources */, 472D13ED299E6579006903F1 /* CurrencyExchanger_Objc.m in Sources */, 471DD1B8290A92CD00E030C8 /* Tools.swift in Sources */, 478A2C7128DC554200AD1420 /* BuySellPortalModel.swift in Sources */, @@ -9468,6 +9473,7 @@ C9D2C76C2A320AA000D15901 /* AccountListController.swift in Sources */, 753261B02CBC11BF003CDE00 /* WelcomeViewController.swift in Sources */, C9D2C76D2A320AA000D15901 /* DWUpholdTransactionObject.m in Sources */, + 7556EE422DF9876B004E8093 /* ExploreSyncBannerView.swift in Sources */, 754C27CD2CC3C15B00BA7B9F /* FeatureSingleItem.swift in Sources */, C943B5052A40A54600AF23C5 /* DWDPIncomingRequestCell.m in Sources */, C9D2C76E2A320AA000D15901 /* DWBaseSeedViewController.m in Sources */, diff --git a/DashWallet/Sources/Models/Explore Dash/ExploreDash.swift b/DashWallet/Sources/Models/Explore Dash/ExploreDash.swift index 5e3399cf8..38bbb5978 100644 --- a/DashWallet/Sources/Models/Explore Dash/ExploreDash.swift +++ b/DashWallet/Sources/Models/Explore Dash/ExploreDash.swift @@ -117,11 +117,27 @@ public class ExploreDash { removeCurrentDatabaseIfNeeded() let isFileExists = FileManager.default.fileExists(atPath: destinationPath.path) - guard !isFileExists else { return } + guard !isFileExists else { + // Check if existing database has old schema and remove it + if ExploreDatabaseConnection.hasOldMerchantIdSchema(at: destinationPath) { + try? FileManager.default.removeItem(at: destinationPath) + // Don't copy bundled database as it also has old schema + // Wait for new database to be downloaded + return + } + return + } guard let dbURL = Bundle.main.url(forResource: "explore", withExtension: "db") else { throw ExploreDatabaseConnectionError.fileNotFound } + + // Check if bundled database has old schema before copying + if ExploreDatabaseConnection.hasOldMerchantIdSchema(at: dbURL) { + // Don't copy bundled database with old schema + // Wait for new database to be downloaded + return + } try FileManager.default.copyItem(at: dbURL, to: destinationPath) diff --git a/DashWallet/Sources/Models/Explore Dash/Infrastructure/Database Connection/ExploreDatabaseConnection.swift b/DashWallet/Sources/Models/Explore Dash/Infrastructure/Database Connection/ExploreDatabaseConnection.swift index 31ff726d5..0a3685dbe 100644 --- a/DashWallet/Sources/Models/Explore Dash/Infrastructure/Database Connection/ExploreDatabaseConnection.swift +++ b/DashWallet/Sources/Models/Explore Dash/Infrastructure/Database Connection/ExploreDatabaseConnection.swift @@ -39,16 +39,42 @@ class ExploreDatabaseConnection { try? self?.connect() } } + + static func hasOldMerchantIdSchema(at url: URL) -> Bool { + do { + let db = try Connection(url.path) + // Query the sqlite_master table to get the schema + let query = "SELECT sql FROM sqlite_master WHERE type='table' AND name='merchant'" + + if let row = try db.prepare(query).makeIterator().next(), + let sql = row[0] as? String { + // Check if merchantId is defined as INTEGER (old schema) + // New schema should have it as TEXT + return sql.contains("merchantId` INTEGER") || sql.contains("merchantId INTEGER") + } + } catch { + // If we can't check, assume it might be old to be safe + return true + } + return false + } func connect() throws { db = nil - guard let dbPath = dbPath() else { throw ExploreDatabaseConnectionError.fileNotFound } + guard let dbPath = dbPath() else { + // No database found - this is expected if we're waiting for v3 download + // Create an in-memory database to prevent crashes + db = try Connection(.inMemory) + return + } do { - db = try Connection(nil ?? dbPath) + db = try Connection(dbPath) } catch { print(error) + // Fallback to in-memory database if connection fails + db = try Connection(.inMemory) } } @@ -59,18 +85,34 @@ class ExploreDatabaseConnection { } func execute(query: QueryType) throws -> [Item] { - let items = try db.prepare(query) + guard db != nil else { return [] } + + do { + let items = try db.prepare(query) - var resultItems: [Item] = [] + var resultItems: [Item] = [] - for item in items { - resultItems.append(Item(row: item)) - } + for item in items { + resultItems.append(Item(row: item)) + } - return resultItems + return resultItems + } catch { + // If query fails (e.g., table doesn't exist in in-memory db), return empty array + print("Database query failed: \(error)") + return [] + } } func execute(query: String) throws -> [Item] { - try db.prepareRowIterator(query).map { Item(row: $0) } + guard db != nil else { return [] } + + do { + return try db.prepareRowIterator(query).map { Item(row: $0) } + } catch { + // If query fails (e.g., table doesn't exist in in-memory db), return empty array + print("Database query failed: \(error)") + return [] + } } } diff --git a/DashWallet/Sources/Models/Explore Dash/Services/ExploreDatabaseSyncManager.swift b/DashWallet/Sources/Models/Explore Dash/Services/ExploreDatabaseSyncManager.swift index 858d6ccda..4d35f58b4 100644 --- a/DashWallet/Sources/Models/Explore Dash/Services/ExploreDatabaseSyncManager.swift +++ b/DashWallet/Sources/Models/Explore Dash/Services/ExploreDatabaseSyncManager.swift @@ -20,7 +20,7 @@ import Foundation import SSZipArchive // TODO: Move it to plist and note in release process -let gsFilePath = "gs://dash-wallet-firebase.appspot.com/explore/explore-v2.db" +let gsFilePath = "gs://dash-wallet-firebase.appspot.com/explore/explore-v3.db" private let fileName = "explore" @@ -136,10 +136,10 @@ extension ExploreDatabaseSyncManager { private func unzipFile(at path: String, password: String) { var error: NSError? - let urlToUnzip = getDocumentsDirectory() + let urlToUnzip = self.getDocumentsDirectory() SSZipArchive.unzipFile(atPath: path, toDestination: urlToUnzip.path, preserveAttributes: true, overwrite: true, - nestedZipLevel: 0, password: password, error: &error, delegate: nil, - progressHandler: nil) { path, _, _ in + nestedZipLevel: 0, password: password, error: &error, delegate: nil, + progressHandler: nil) { path, _, _ in NotificationCenter.default.post(name: ExploreDatabaseSyncManager.databaseHasBeenUpdatedNotification, object: nil) try? FileManager.default.removeItem(at: URL(fileURLWithPath: path)) } diff --git a/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m b/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m index a7f171e16..15830fe78 100644 --- a/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m +++ b/DashWallet/Sources/Models/Uphold/DWUpholdMainnetConstants.m @@ -47,6 +47,7 @@ + (NSString *)transactionURLFormat { + (NSString *)logoutURLString { return @"https://uphold.com/"; + } @end diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExplorePointOfUseListViewController.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExplorePointOfUseListViewController.swift index a81d697a1..0b893cae5 100644 --- a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExplorePointOfUseListViewController.swift +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExplorePointOfUseListViewController.swift @@ -52,6 +52,8 @@ class ExplorePointOfUseListViewController: UIViewController { internal var radius = 20 // In miles //Move to model internal var mapView: ExploreMapView! internal var showMapButton: UIButton! + internal var syncBannerView: ExploreSyncBannerView? + internal var syncBannerHeightConstraint: NSLayoutConstraint? internal var contentViewTopLayoutConstraint: NSLayoutConstraint! internal var contentView: UIView! @@ -136,6 +138,9 @@ class ExplorePointOfUseListViewController: UIViewController { showMapIfNeeded() DWLocationManager.shared.add(observer: self) + + // Check database sync status again in case it changed while navigating + checkDatabaseSyncStatus() } override func viewWillDisappear(_ animated: Bool) { @@ -144,6 +149,7 @@ class ExplorePointOfUseListViewController: UIViewController { super.viewWillDisappear(animated) DWLocationManager.shared.remove(observer: self) + NotificationCenter.default.removeObserver(self, name: ExploreDatabaseSyncManager.databaseHasBeenUpdatedNotification, object: nil) } override func viewDidLoad() { @@ -184,12 +190,76 @@ class ExplorePointOfUseListViewController: UIViewController { } configureHierarchy() + + // Check database sync status + checkDatabaseSyncStatus() + + // Observe database sync notifications + NotificationCenter.default.addObserver(self, selector: #selector(databaseHasBeenUpdated), name: ExploreDatabaseSyncManager.databaseHasBeenUpdatedNotification, object: nil) } } extension ExplorePointOfUseListViewController { @objc internal func configureModel() { } + + private func checkDatabaseSyncStatus() { + // Check if we need to show sync banner + // If database doesn't exist or has old schema, show banner + let documentsPath = FileManager.documentsDirectoryURL.appendingPathComponent(kExploreDashDatabaseName) + let fileExists = FileManager.default.fileExists(atPath: documentsPath.path) + + // If file doesn't exist or has old schema, show sync banner + if !fileExists || ExploreDatabaseConnection.hasOldMerchantIdSchema(at: documentsPath) { + showSyncBanner() + } else { + hideSyncBanner() + } + } + + private func showSyncBanner() { + guard syncBannerView?.isHidden == true else { return } + + syncBannerView?.isHidden = false + syncBannerHeightConstraint?.constant = 30 + + UIView.animate(withDuration: 0.3) { + self.view.layoutIfNeeded() + } + } + + private func hideSyncBanner() { + guard syncBannerView?.isHidden == false else { return } + + syncBannerHeightConstraint?.constant = 0 + + UIView.animate(withDuration: 0.3) { + self.view.layoutIfNeeded() + } completion: { _ in + self.syncBannerView?.isHidden = true + } + } + + @objc private func databaseHasBeenUpdated() { + DispatchQueue.main.async { [weak self] in + // Database has been updated, hide the sync banner + self?.hideSyncBanner() + + // The database connection needs to be re-established after update + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in + guard let self = self else { return } + + self.model.items = [] + if let currentProvider = self.model.currentDataProvider { + currentProvider.items = [] + currentProvider.currentPage = nil + } + + self.model.refreshItems() + self.tableView.reloadData() + } + } + } } // MARK: DWLocationObserver @@ -306,6 +376,12 @@ extension ExplorePointOfUseListViewController { contentView.layer.cornerRadius = 20 contentView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] view.addSubview(contentView) + + // Add sync banner attached to app bar but overlaying content + syncBannerView = ExploreSyncBannerView() + syncBannerView?.translatesAutoresizingMaskIntoConstraints = false + syncBannerView?.isHidden = true + view.addSubview(syncBannerView!) let stackView = UIStackView() stackView.axis = .vertical @@ -364,6 +440,10 @@ extension ExplorePointOfUseListViewController { contentViewTopLayoutConstraint = contentView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: -handlerViewHeight) + + syncBannerHeightConstraint = syncBannerView!.heightAnchor.constraint(equalToConstant: 0) + // Set high z-position to overlay content + syncBannerView!.layer.zPosition = 100 NSLayoutConstraint.activate([ contentViewTopLayoutConstraint, @@ -371,6 +451,12 @@ extension ExplorePointOfUseListViewController { contentView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + + // Sync banner constraints - attached to app bar, overlaying content + syncBannerView!.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + syncBannerView!.leadingAnchor.constraint(equalTo: view.leadingAnchor), + syncBannerView!.trailingAnchor.constraint(equalTo: view.trailingAnchor), + syncBannerHeightConstraint!, handlerView.heightAnchor.constraint(equalToConstant: handlerViewHeight), diff --git a/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExploreSyncBannerView.swift b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExploreSyncBannerView.swift new file mode 100644 index 000000000..cf4dd8d9a --- /dev/null +++ b/DashWallet/Sources/UI/Explore Dash/Merchants & ATMs/List/ExploreSyncBannerView.swift @@ -0,0 +1,54 @@ +// +// Created by Andrei Ashikhmin +// Copyright © 2025 Dash Core Group. All rights reserved. +// +// Licensed under the MIT License (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +class ExploreSyncBannerView: UIView { + + private let label: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.text = NSLocalizedString("Sync in progress… Results may not be complete.", comment: "Explore Dash") + label.textColor = .white + label.font = .dw_font(forTextStyle: .footnote) + label.textAlignment = .center + label.numberOfLines = 1 + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setupView() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setupView() + } + + private func setupView() { + backgroundColor = .dw_dashBlue() + + addSubview(label) + + NSLayoutConstraint.activate([ + label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16), + label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16), + label.topAnchor.constraint(equalTo: topAnchor, constant: 8), + ]) + } +} diff --git a/DashWallet/ar.lproj/Localizable.strings b/DashWallet/ar.lproj/Localizable.strings index 96b70f2a6..7a5286c9c 100644 --- a/DashWallet/ar.lproj/Localizable.strings +++ b/DashWallet/ar.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/bg.lproj/Localizable.strings b/DashWallet/bg.lproj/Localizable.strings index 53eacff5c..45f478c07 100644 --- a/DashWallet/bg.lproj/Localizable.strings +++ b/DashWallet/bg.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Неуспешно синхронизиране"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Синхронизирай сега"; diff --git a/DashWallet/ca.lproj/Localizable.strings b/DashWallet/ca.lproj/Localizable.strings index 2c12d3dac..1508df751 100644 --- a/DashWallet/ca.lproj/Localizable.strings +++ b/DashWallet/ca.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/cs.lproj/Localizable.strings b/DashWallet/cs.lproj/Localizable.strings index ad6b50fdf..6371bea21 100644 --- a/DashWallet/cs.lproj/Localizable.strings +++ b/DashWallet/cs.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Synchronizace selhala"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Synchronizovat"; diff --git a/DashWallet/da.lproj/Localizable.strings b/DashWallet/da.lproj/Localizable.strings index 59036f0ce..58c794512 100644 --- a/DashWallet/da.lproj/Localizable.strings +++ b/DashWallet/da.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/de.lproj/Localizable.strings b/DashWallet/de.lproj/Localizable.strings index 1d1fd761f..fc873c311 100644 --- a/DashWallet/de.lproj/Localizable.strings +++ b/DashWallet/de.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Synchronisierung fehlgeschlagen"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Jetzt synchronisieren"; diff --git a/DashWallet/el.lproj/Localizable.strings b/DashWallet/el.lproj/Localizable.strings index 4a5e81d12..567e9e280 100644 --- a/DashWallet/el.lproj/Localizable.strings +++ b/DashWallet/el.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Ο Συγχρονισμός Απέτυχε!"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Συγχρονισμός Τώρα"; diff --git a/DashWallet/en.lproj/Localizable.strings b/DashWallet/en.lproj/Localizable.strings index 28060be0a..ad11f2224 100644 --- a/DashWallet/en.lproj/Localizable.strings +++ b/DashWallet/en.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/eo.lproj/Localizable.strings b/DashWallet/eo.lproj/Localizable.strings index d6c1d34c9..1645b014f 100644 --- a/DashWallet/eo.lproj/Localizable.strings +++ b/DashWallet/eo.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/es.lproj/Localizable.strings b/DashWallet/es.lproj/Localizable.strings index cae1f3284..60ac2c23d 100644 --- a/DashWallet/es.lproj/Localizable.strings +++ b/DashWallet/es.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Falla en la Sincronizacío"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sincronizar Ahora"; diff --git a/DashWallet/et.lproj/Localizable.strings b/DashWallet/et.lproj/Localizable.strings index 079d092a1..32ab44033 100644 --- a/DashWallet/et.lproj/Localizable.strings +++ b/DashWallet/et.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/fa.lproj/Localizable.strings b/DashWallet/fa.lproj/Localizable.strings index 71625ee63..7b0ab68ac 100644 --- a/DashWallet/fa.lproj/Localizable.strings +++ b/DashWallet/fa.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/fi.lproj/Localizable.strings b/DashWallet/fi.lproj/Localizable.strings index a5cc50593..b10674335 100644 --- a/DashWallet/fi.lproj/Localizable.strings +++ b/DashWallet/fi.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/fil.lproj/Localizable.strings b/DashWallet/fil.lproj/Localizable.strings index 2c729519f..1a186504b 100644 --- a/DashWallet/fil.lproj/Localizable.strings +++ b/DashWallet/fil.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Pumalya ang pag-sync"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "I-sync ngayon"; diff --git a/DashWallet/fr.lproj/Localizable.strings b/DashWallet/fr.lproj/Localizable.strings index f7417734a..48ef0340d 100644 --- a/DashWallet/fr.lproj/Localizable.strings +++ b/DashWallet/fr.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Échec de synchronisation"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Synchroniser maintenant"; diff --git a/DashWallet/hr.lproj/Localizable.strings b/DashWallet/hr.lproj/Localizable.strings index 3ac2444f7..e672f8c6c 100644 --- a/DashWallet/hr.lproj/Localizable.strings +++ b/DashWallet/hr.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/hu.lproj/Localizable.strings b/DashWallet/hu.lproj/Localizable.strings index 99640ec8f..9a556c305 100644 --- a/DashWallet/hu.lproj/Localizable.strings +++ b/DashWallet/hu.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/id.lproj/Localizable.strings b/DashWallet/id.lproj/Localizable.strings index 7ae163407..38ee5f4c1 100644 --- a/DashWallet/id.lproj/Localizable.strings +++ b/DashWallet/id.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sinkronisasi Gagal"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sinkronkan Sekarang"; diff --git a/DashWallet/it.lproj/Localizable.strings b/DashWallet/it.lproj/Localizable.strings index 46531abc6..8c9c8b1d8 100644 --- a/DashWallet/it.lproj/Localizable.strings +++ b/DashWallet/it.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sincronizzazione Fallita"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sincronizza Ora"; diff --git a/DashWallet/ja.lproj/Localizable.strings b/DashWallet/ja.lproj/Localizable.strings index e1902b185..56f30c082 100644 --- a/DashWallet/ja.lproj/Localizable.strings +++ b/DashWallet/ja.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "同期に失敗しました"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "すぐに同期する"; diff --git a/DashWallet/ko.lproj/Localizable.strings b/DashWallet/ko.lproj/Localizable.strings index eaaabb170..ef34f325b 100644 --- a/DashWallet/ko.lproj/Localizable.strings +++ b/DashWallet/ko.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "동기화에 실패하였습니다"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "지금 동기화합니다"; diff --git a/DashWallet/mk.lproj/Localizable.strings b/DashWallet/mk.lproj/Localizable.strings index 598adccad..31b2ea6e2 100644 --- a/DashWallet/mk.lproj/Localizable.strings +++ b/DashWallet/mk.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/ms.lproj/Localizable.strings b/DashWallet/ms.lproj/Localizable.strings index 51e500826..0e8f1559c 100644 --- a/DashWallet/ms.lproj/Localizable.strings +++ b/DashWallet/ms.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/nb.lproj/Localizable.strings b/DashWallet/nb.lproj/Localizable.strings index ae8c6ee5b..41f71a762 100644 --- a/DashWallet/nb.lproj/Localizable.strings +++ b/DashWallet/nb.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/nl.lproj/Localizable.strings b/DashWallet/nl.lproj/Localizable.strings index 6ce328fda..b8cfd9b40 100644 --- a/DashWallet/nl.lproj/Localizable.strings +++ b/DashWallet/nl.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync mislukt"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Nu synchroniseren"; diff --git a/DashWallet/pl.lproj/Localizable.strings b/DashWallet/pl.lproj/Localizable.strings index e098bcb31..c4f1eb27c 100644 --- a/DashWallet/pl.lproj/Localizable.strings +++ b/DashWallet/pl.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Synchronizacja Zawiodła"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Synchronizuj Teraz"; diff --git a/DashWallet/pt.lproj/Localizable.strings b/DashWallet/pt.lproj/Localizable.strings index cc8f934ea..192cf4832 100644 --- a/DashWallet/pt.lproj/Localizable.strings +++ b/DashWallet/pt.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sicronização Falhou"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sincronizar Agora"; diff --git a/DashWallet/ro.lproj/Localizable.strings b/DashWallet/ro.lproj/Localizable.strings index 5b8f24daa..92de57499 100644 --- a/DashWallet/ro.lproj/Localizable.strings +++ b/DashWallet/ro.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/ru.lproj/Localizable.strings b/DashWallet/ru.lproj/Localizable.strings index 2b9c5adf0..3824c9c90 100644 --- a/DashWallet/ru.lproj/Localizable.strings +++ b/DashWallet/ru.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Ошибка синхронизации"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Синхронизировать"; diff --git a/DashWallet/sk.lproj/Localizable.strings b/DashWallet/sk.lproj/Localizable.strings index 86ea90e5d..4b0dbce51 100644 --- a/DashWallet/sk.lproj/Localizable.strings +++ b/DashWallet/sk.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Synchronizácia zlyhala"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Synchronizovať teraz"; diff --git a/DashWallet/sl.lproj/Localizable.strings b/DashWallet/sl.lproj/Localizable.strings index 1efed565a..d339d3e03 100644 --- a/DashWallet/sl.lproj/Localizable.strings +++ b/DashWallet/sl.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/sl_SI.lproj/Localizable.strings b/DashWallet/sl_SI.lproj/Localizable.strings index b251868ec..237eeaa73 100644 --- a/DashWallet/sl_SI.lproj/Localizable.strings +++ b/DashWallet/sl_SI.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/sq.lproj/Localizable.strings b/DashWallet/sq.lproj/Localizable.strings index d2d19265d..f71384460 100644 --- a/DashWallet/sq.lproj/Localizable.strings +++ b/DashWallet/sq.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/sr.lproj/Localizable.strings b/DashWallet/sr.lproj/Localizable.strings index 4e7ea71fa..11ad35791 100644 --- a/DashWallet/sr.lproj/Localizable.strings +++ b/DashWallet/sr.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/sv.lproj/Localizable.strings b/DashWallet/sv.lproj/Localizable.strings index 946088f9e..1326bb7f3 100644 --- a/DashWallet/sv.lproj/Localizable.strings +++ b/DashWallet/sv.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/th.lproj/Localizable.strings b/DashWallet/th.lproj/Localizable.strings index 6db9a898d..f89e4e181 100644 --- a/DashWallet/th.lproj/Localizable.strings +++ b/DashWallet/th.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "ซิงค์ล้มเหลว"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "ซิงค์ตอนนี้"; diff --git a/DashWallet/tr.lproj/Localizable.strings b/DashWallet/tr.lproj/Localizable.strings index 06aa0cd3b..04d3fc5e0 100644 --- a/DashWallet/tr.lproj/Localizable.strings +++ b/DashWallet/tr.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Senkronizasyon Başarısız"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Şimdi Senkronize Et"; diff --git a/DashWallet/uk.lproj/Localizable.strings b/DashWallet/uk.lproj/Localizable.strings index d77759f97..f9905899c 100644 --- a/DashWallet/uk.lproj/Localizable.strings +++ b/DashWallet/uk.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Помилка синхронізації"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Синхронізувати зараз"; diff --git a/DashWallet/vi.lproj/Localizable.strings b/DashWallet/vi.lproj/Localizable.strings index 3a863ccf3..8fefef2f7 100644 --- a/DashWallet/vi.lproj/Localizable.strings +++ b/DashWallet/vi.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Đồng bộ không thành công"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Đồng bộ luôn"; diff --git a/DashWallet/zh-Hans.lproj/Localizable.strings b/DashWallet/zh-Hans.lproj/Localizable.strings index f57315214..c0a014e14 100644 --- a/DashWallet/zh-Hans.lproj/Localizable.strings +++ b/DashWallet/zh-Hans.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/zh-Hant-TW.lproj/Localizable.strings b/DashWallet/zh-Hant-TW.lproj/Localizable.strings index 4e86bd2cb..d950682b0 100644 --- a/DashWallet/zh-Hant-TW.lproj/Localizable.strings +++ b/DashWallet/zh-Hant-TW.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "Sync Failed"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "Sync Now"; diff --git a/DashWallet/zh.lproj/Localizable.strings b/DashWallet/zh.lproj/Localizable.strings index 0c8d79def..f4b445cbe 100644 --- a/DashWallet/zh.lproj/Localizable.strings +++ b/DashWallet/zh.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "同步失败"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "立刻同步"; diff --git a/DashWallet/zh_TW.lproj/Localizable.strings b/DashWallet/zh_TW.lproj/Localizable.strings index 9cf98180e..cafc4c559 100644 --- a/DashWallet/zh_TW.lproj/Localizable.strings +++ b/DashWallet/zh_TW.lproj/Localizable.strings @@ -2374,6 +2374,9 @@ /* No comment provided by engineer. */ "Sync Failed" = "同步失敗"; +/* Explore Dash */ +"Sync in progress… Results may not be complete." = "Sync in progress… Results may not be complete."; + /* Translate it as short as possible! (24 symbols max) */ "Sync Now" = "立即同步";