mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-22 23:08:07 +01:00
FIX: Save the latest successful timeline entry in case of network error
This commit is contained in:
parent
80c1b66604
commit
cd54601fc8
4 changed files with 123 additions and 85 deletions
|
@ -11,8 +11,10 @@ import SwiftUI
|
|||
|
||||
struct WalletInformationWidgetProvider: TimelineProvider {
|
||||
typealias Entry = WalletInformationWidgetEntry
|
||||
static var lastSuccessfulEntry: WalletInformationWidgetEntry?
|
||||
|
||||
func placeholder(in context: Context) -> WalletInformationWidgetEntry {
|
||||
return WalletInformationWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "26", sats: "9 134", price: "$10,000", rate: 10000), allWalletsBalance: WalletData(balance: 1000000, latestTransactionTime: LatestTransaction(isUnconfirmed: false, epochValue: 1568804029000)))
|
||||
return WalletInformationWidgetEntry.placeholder
|
||||
}
|
||||
|
||||
func getSnapshot(in context: Context, completion: @escaping (WalletInformationWidgetEntry) -> ()) {
|
||||
|
@ -27,22 +29,28 @@ struct WalletInformationWidgetProvider: TimelineProvider {
|
|||
|
||||
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
|
||||
var entries: [WalletInformationWidgetEntry] = []
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency();
|
||||
|
||||
let marketDataEntry = MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0)
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency()
|
||||
let allwalletsBalance = WalletData(balance: UserDefaultsGroup.getAllWalletsBalance(), latestTransactionTime: UserDefaultsGroup.getAllWalletsLatestTransactionTime())
|
||||
WidgetAPI.fetchPrice(currency: userPreferredCurrency, completion: { (result, error) in
|
||||
|
||||
WidgetAPI.fetchPrice(currency: userPreferredCurrency) { (result, error) in
|
||||
let entry: WalletInformationWidgetEntry
|
||||
|
||||
if let result = result {
|
||||
entry = WalletInformationWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "", sats: "", price: result.formattedRate ?? "!", rate: result.rateDouble), allWalletsBalance: allwalletsBalance)
|
||||
|
||||
WalletInformationWidgetProvider.lastSuccessfulEntry = entry
|
||||
} else {
|
||||
entry = WalletInformationWidgetEntry(date: Date(), marketData: marketDataEntry, allWalletsBalance: allwalletsBalance)
|
||||
// Use the last successful entry if available
|
||||
if let lastEntry = WalletInformationWidgetProvider.lastSuccessfulEntry {
|
||||
entry = lastEntry
|
||||
} else {
|
||||
// Fallback to a default entry if no successful entry is available
|
||||
entry = WalletInformationWidgetEntry.placeholder
|
||||
}
|
||||
}
|
||||
entries.append(entry)
|
||||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,6 +60,12 @@ struct WalletInformationWidgetEntry: TimelineEntry {
|
|||
var allWalletsBalance: WalletData = WalletData(balance: 0)
|
||||
}
|
||||
|
||||
extension WalletInformationWidgetEntry {
|
||||
static var placeholder: WalletInformationWidgetEntry {
|
||||
WalletInformationWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "26", sats: "9 134", price: "$10,000", rate: 10000), allWalletsBalance: WalletData(balance: 1000000, latestTransactionTime: LatestTransaction(isUnconfirmed: false, epochValue: 1568804029000)))
|
||||
}
|
||||
}
|
||||
|
||||
struct WalletInformationWidgetEntryView : View {
|
||||
let entry: WalletInformationWidgetEntry
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import WidgetKit
|
|||
import SwiftUI
|
||||
|
||||
struct MarketWidgetProvider: TimelineProvider {
|
||||
static var lastSuccessfulEntry: MarketWidgetEntry?
|
||||
|
||||
func placeholder(in context: Context) -> MarketWidgetEntry {
|
||||
return MarketWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "26", sats: "9 134", price: "$10 000", rate: 10000))
|
||||
}
|
||||
|
@ -25,28 +27,34 @@ struct MarketWidgetProvider: TimelineProvider {
|
|||
}
|
||||
|
||||
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
|
||||
var entries: [MarketWidgetEntry] = []
|
||||
if context.isPreview {
|
||||
let entry = MarketWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "26", sats: "9 134", price: "$10 000", rate: 10000))
|
||||
entries.append(entry)
|
||||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
}else {
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency();
|
||||
let marketDataEntry = MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0)
|
||||
WidgetAPI.fetchMarketData(currency: userPreferredCurrency, completion: { (result, error) in
|
||||
let entry: MarketWidgetEntry
|
||||
if let result = result {
|
||||
entry = MarketWidgetEntry(date: Date(), marketData: result)
|
||||
|
||||
} else {
|
||||
entry = MarketWidgetEntry(date: Date(), marketData: marketDataEntry)
|
||||
}
|
||||
var entries: [MarketWidgetEntry] = []
|
||||
if context.isPreview {
|
||||
let entry = MarketWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "26", sats: "9 134", price: "$10 000", rate: 10000))
|
||||
entries.append(entry)
|
||||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency()
|
||||
WidgetAPI.fetchMarketData(currency: userPreferredCurrency) { (result, error) in
|
||||
let entry: MarketWidgetEntry
|
||||
|
||||
if let result = result {
|
||||
entry = MarketWidgetEntry(date: Date(), marketData: result)
|
||||
MarketWidgetProvider.lastSuccessfulEntry = entry
|
||||
} else {
|
||||
// Use the last successful entry if available
|
||||
if let lastEntry = MarketWidgetProvider.lastSuccessfulEntry {
|
||||
entry = lastEntry
|
||||
} else {
|
||||
// Fallback to a default entry if no successful entry is available
|
||||
entry = MarketWidgetEntry(date: Date(), marketData: emptyMarketData)
|
||||
}
|
||||
}
|
||||
entries.append(entry)
|
||||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import SwiftUI
|
|||
var marketData: [MarketDataTimeline: MarketData?] = [ .Current: nil, .Previous: nil]
|
||||
struct PriceWidgetProvider: TimelineProvider {
|
||||
typealias Entry = PriceWidgetEntry
|
||||
static var lastSuccessfulEntry: PriceWidgetEntry?
|
||||
|
||||
func placeholder(in context: Context) -> PriceWidgetEntry {
|
||||
return PriceWidgetEntry(date: Date(), currentMarketData: MarketData(nextBlock: "", sats: "", price: "$10,000", rate: 10000, dateString: "2019-09-18T17:27:00+00:00"))
|
||||
|
@ -35,74 +36,79 @@ struct PriceWidgetProvider: TimelineProvider {
|
|||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
} else {
|
||||
if WidgetAPI.getUserPreferredCurrency() != WidgetAPI.getLastSelectedCurrency() {
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency()
|
||||
if userPreferredCurrency != WidgetAPI.getLastSelectedCurrency() {
|
||||
marketData[.Current] = nil
|
||||
marketData[.Previous] = nil
|
||||
WidgetAPI.saveNewSelectedCurrency()
|
||||
}
|
||||
|
||||
var entryMarketData = marketData[.Current] ?? emptyMarketData
|
||||
WidgetAPI.fetchPrice(currency: WidgetAPI.getUserPreferredCurrency()) { (data, error) in
|
||||
WidgetAPI.fetchPrice(currency: userPreferredCurrency) { (data, error) in
|
||||
let entry: PriceWidgetEntry
|
||||
|
||||
if let data = data, let formattedRate = data.formattedRate {
|
||||
let currentMarketData = MarketData(nextBlock: "", sats: "", price: formattedRate, rate: data.rateDouble, dateString: data.lastUpdate)
|
||||
if let cachedMarketData = marketData[.Current], currentMarketData.dateString != cachedMarketData?.dateString {
|
||||
marketData[.Previous] = marketData[.Current]
|
||||
marketData[.Current] = currentMarketData
|
||||
entryMarketData = currentMarketData
|
||||
entries.append(PriceWidgetEntry(date:Date(), currentMarketData: entryMarketData))
|
||||
marketData[.Previous] = marketData[.Current]
|
||||
marketData[.Current] = currentMarketData
|
||||
entry = PriceWidgetEntry(date: Date(), currentMarketData: currentMarketData)
|
||||
PriceWidgetProvider.lastSuccessfulEntry = entry
|
||||
} else {
|
||||
// Use the last successful entry if available
|
||||
if let lastEntry = PriceWidgetProvider.lastSuccessfulEntry {
|
||||
entry = lastEntry
|
||||
} else {
|
||||
entries.append(PriceWidgetEntry(date:Date(), currentMarketData: currentMarketData))
|
||||
// Fallback to a default entry if no successful entry is available
|
||||
entry = PriceWidgetEntry(date: Date(), currentMarketData: emptyMarketData)
|
||||
}
|
||||
}
|
||||
|
||||
entries.append(entry)
|
||||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PriceWidgetEntry: TimelineEntry {
|
||||
let date: Date
|
||||
let currentMarketData: MarketData?
|
||||
var previousMarketData: MarketData? {
|
||||
return marketData[.Previous] as? MarketData
|
||||
}
|
||||
}
|
||||
|
||||
struct PriceWidgetEntryView : View {
|
||||
let entry: PriceWidgetEntry
|
||||
var priceView: some View {
|
||||
PriceView(currentMarketData: entry.currentMarketData, previousMarketData: marketData[.Previous] ?? emptyMarketData).padding()
|
||||
}}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(content: {
|
||||
priceView
|
||||
}).background(Color.widgetBackground)
|
||||
}
|
||||
}
|
||||
|
||||
struct PriceWidget: Widget {
|
||||
let kind: String = "PriceWidget"
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
if #available(iOSApplicationExtension 16.0, *) {
|
||||
return StaticConfiguration(kind: kind, provider: PriceWidgetProvider()) { entry in
|
||||
PriceWidgetEntryView(entry: entry)
|
||||
}
|
||||
.configurationDisplayName("Price")
|
||||
.description("View the current price of Bitcoin.").supportedFamilies([.systemSmall])
|
||||
} else {
|
||||
return StaticConfiguration(kind: kind, provider: PriceWidgetProvider()) { entry in
|
||||
PriceWidgetEntryView(entry: entry)
|
||||
}
|
||||
.configurationDisplayName("Price")
|
||||
.description("View the current price of Bitcoin.").supportedFamilies([.systemSmall])
|
||||
struct PriceWidgetEntry: TimelineEntry {
|
||||
let date: Date
|
||||
let currentMarketData: MarketData?
|
||||
var previousMarketData: MarketData? {
|
||||
return marketData[.Previous] as? MarketData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct PriceWidgetEntryView : View {
|
||||
let entry: PriceWidgetEntry
|
||||
var priceView: some View {
|
||||
PriceView(currentMarketData: entry.currentMarketData, previousMarketData: marketData[.Previous] ?? emptyMarketData).padding()
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(content: {
|
||||
priceView
|
||||
}).background(Color.widgetBackground)
|
||||
}
|
||||
}
|
||||
|
||||
struct PriceWidget: Widget {
|
||||
let kind: String = "PriceWidget"
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
if #available(iOSApplicationExtension 16.0, *) {
|
||||
return StaticConfiguration(kind: kind, provider: PriceWidgetProvider()) { entry in
|
||||
PriceWidgetEntryView(entry: entry)
|
||||
}
|
||||
.configurationDisplayName("Price")
|
||||
.description("View the current price of Bitcoin.").supportedFamilies([.systemSmall])
|
||||
} else {
|
||||
return StaticConfiguration(kind: kind, provider: PriceWidgetProvider()) { entry in
|
||||
PriceWidgetEntryView(entry: entry)
|
||||
}
|
||||
.configurationDisplayName("Price")
|
||||
.description("View the current price of Bitcoin.").supportedFamilies([.systemSmall])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PriceWidget_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
PriceWidgetEntryView(entry: PriceWidgetEntry(date: Date(), currentMarketData: MarketData(nextBlock: "", sats: "", price: "$10,000", rate: 10000, dateString: "2019-09-18T17:27:00+00:00")))
|
||||
|
|
|
@ -11,8 +11,10 @@ import SwiftUI
|
|||
|
||||
struct WalletInformationAndMarketWidgetProvider: TimelineProvider {
|
||||
typealias Entry = WalletInformationAndMarketWidgetEntry
|
||||
static var lastSuccessfulEntry: WalletInformationAndMarketWidgetEntry?
|
||||
|
||||
func placeholder(in context: Context) -> WalletInformationAndMarketWidgetEntry {
|
||||
return WalletInformationAndMarketWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "26", sats: "9 134", price: "$10,000", rate: 10000), allWalletsBalance: WalletData(balance: 1000000, latestTransactionTime: LatestTransaction(isUnconfirmed: false, epochValue: 1568804029000)))
|
||||
return WalletInformationAndMarketWidgetEntry.placeholder
|
||||
}
|
||||
|
||||
func getSnapshot(in context: Context, completion: @escaping (WalletInformationAndMarketWidgetEntry) -> ()) {
|
||||
|
@ -33,21 +35,28 @@ struct WalletInformationAndMarketWidgetProvider: TimelineProvider {
|
|||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
} else {
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency();
|
||||
let userPreferredCurrency = WidgetAPI.getUserPreferredCurrency()
|
||||
let allwalletsBalance = WalletData(balance: UserDefaultsGroup.getAllWalletsBalance(), latestTransactionTime: UserDefaultsGroup.getAllWalletsLatestTransactionTime())
|
||||
let marketDataEntry = MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0)
|
||||
WidgetAPI.fetchMarketData(currency: userPreferredCurrency, completion: { (result, error) in
|
||||
|
||||
WidgetAPI.fetchMarketData(currency: userPreferredCurrency) { (result, error) in
|
||||
let entry: WalletInformationAndMarketWidgetEntry
|
||||
|
||||
if let result = result {
|
||||
entry = WalletInformationAndMarketWidgetEntry(date: Date(), marketData: result, allWalletsBalance: allwalletsBalance)
|
||||
|
||||
WalletInformationAndMarketWidgetProvider.lastSuccessfulEntry = entry
|
||||
} else {
|
||||
entry = WalletInformationAndMarketWidgetEntry(date: Date(), marketData: marketDataEntry, allWalletsBalance: allwalletsBalance)
|
||||
// Use the last successful entry if available
|
||||
if let lastEntry = WalletInformationAndMarketWidgetProvider.lastSuccessfulEntry {
|
||||
entry = lastEntry
|
||||
} else {
|
||||
// Fallback to a default entry if no successful entry is available
|
||||
entry = WalletInformationAndMarketWidgetEntry.placeholder
|
||||
}
|
||||
}
|
||||
entries.append(entry)
|
||||
let timeline = Timeline(entries: entries, policy: .atEnd)
|
||||
completion(timeline)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +65,7 @@ struct WalletInformationAndMarketWidgetEntry: TimelineEntry {
|
|||
let date: Date
|
||||
let marketData: MarketData
|
||||
var allWalletsBalance: WalletData = WalletData(balance: 0)
|
||||
static var placeholder = WalletInformationAndMarketWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "...", sats: "...", price: "...", rate: 0), allWalletsBalance: WalletData(balance: 0, latestTransactionTime: LatestTransaction(isUnconfirmed: false, epochValue: 1568804029000)))
|
||||
}
|
||||
|
||||
struct WalletInformationAndMarketWidgetEntryView : View {
|
||||
|
|
Loading…
Add table
Reference in a new issue