FIX: UI fixes for lock screen widgets (#6780)

This commit is contained in:
Marcos Rodriguez Vélez 2024-07-09 20:40:40 -04:00 committed by GitHub
parent 56a409add7
commit f85403573c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 98 additions and 39 deletions

View File

@ -349,7 +349,7 @@ PODS:
- React-Core
- react-native-secure-key-store (2.0.10):
- React-Core
- react-native-tcp-socket (6.1.0):
- react-native-tcp-socket (6.2.0):
- CocoaAsyncSocket
- React-Core
- React-NativeModulesApple (0.72.14):
@ -811,7 +811,7 @@ SPEC CHECKSUMS:
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-safe-area-context: 422017db8bcabbada9ad607d010996c56713234c
react-native-secure-key-store: 910e6df6bc33cb790aba6ee24bc7818df1fe5898
react-native-tcp-socket: ea937a61ee9ff2cb3cceade359290a46ad2b5aab
react-native-tcp-socket: 8c3e8bef909ab06c557eeb95363fe029391ff09d
React-NativeModulesApple: 3107f777453f953906d9ba9dc5f8cbd91a6ef913
React-perflogger: daabc494c6328efc1784a4b49b8b74fca305d11c
React-RCTActionSheet: 0e0e64a7cf6c07f1de73d1f0a92d26a70262b256

View File

@ -14,74 +14,112 @@ struct PriceView: View {
var body: some View {
switch entry.family {
case .accessoryCircular:
accessoryCircularView
case .accessoryInline:
accessoryInlineView
case .accessoryRectangular:
accessoryRectangularView
case .accessoryInline, .accessoryCircular, .accessoryRectangular:
wrappedView(for: getView(for: entry.family), family: entry.family)
default:
defaultView
defaultView.background(Color.widgetBackground)
}
}
private func getView(for family: WidgetFamily) -> some View {
switch family {
case .accessoryCircular:
return AnyView(accessoryCircularView)
case .accessoryInline:
return AnyView(accessoryInlineView)
case .accessoryRectangular:
return AnyView(accessoryRectangularView)
default:
return AnyView(defaultView)
}
}
@ViewBuilder
private func wrappedView<Content: View>(for content: Content, family: WidgetFamily) -> some View {
if #available(iOSApplicationExtension 16.0, *) {
ZStack {
if family == .accessoryRectangular {
AccessoryWidgetBackground()
.background(Color(.systemBackground))
.clipShape(RoundedRectangle(cornerRadius: 10))
} else {
AccessoryWidgetBackground()
}
content
}
} else {
content
}
}
private var accessoryCircularView: some View {
VStack {
let priceString = formattedPriceString(from: entry.currentMarketData?.rate)
let priceChangePercentage = formattedPriceChangePercentage(currentRate: entry.currentMarketData?.rate, previousRate: entry.previousMarketData?.rate)
return VStack(alignment: .center, spacing: 4) {
Text("BTC")
.font(.caption)
.minimumScaleFactor(0.1)
if let preferredFiatCurrencySymbol = fiatUnit(currency: Currency.getUserPreferredCurrency())?.symbol, let rateAbbreviated = entry.currentMarketData?.rate.abbreviated {
Text("\(preferredFiatCurrencySymbol)\(rateAbbreviated)")
.font(.title3)
.minimumScaleFactor(0.1)
} else {
Text("--")
.font(.title)
.fontWeight(.bold)
Text(priceString)
.font(.body)
.minimumScaleFactor(0.1)
.lineLimit(1)
if let priceChangePercentage = priceChangePercentage {
Text(priceChangePercentage)
.font(.caption2)
.foregroundColor(priceChangePercentage.contains("-") ? .red : .green)
}
}
.widgetURL(URL(string: "bluewallet://marketprice"))
}
private var accessoryInlineView: some View {
HStack {
if let preferredFiatCurrencySymbol = fiatUnit(currency: Currency.getUserPreferredCurrency())?.symbol, let rateAbbreviated = entry.currentMarketData?.rate.abbreviated {
Text("BTC \(preferredFiatCurrencySymbol)\(rateAbbreviated)")
.font(.body)
} else {
Text("BTC --")
.font(.body)
let priceString = formattedCurrencyString(from: entry.currentMarketData?.rate)
let priceChangePercentage = formattedPriceChangePercentage(currentRate: entry.currentMarketData?.rate, previousRate: entry.previousMarketData?.rate)
return HStack {
Text(priceString)
.font(.body)
.minimumScaleFactor(0.1)
if let priceChangePercentage = priceChangePercentage {
Image(systemName: priceChangePercentage.contains("-") ? "arrow.down" : "arrow.up")
.foregroundColor(priceChangePercentage.contains("-") ? .red : .green)
}
}
}
private var accessoryRectangularView: some View {
VStack(alignment: .leading, spacing: 4) {
Text("Bitcoin Price")
let currentPrice = formattedCurrencyString(from: entry.currentMarketData?.rate)
return VStack(alignment: .leading, spacing: 4) {
Text("Bitcoin (\(Currency.getUserPreferredCurrency()))")
.font(.caption)
.foregroundColor(.secondary)
HStack {
Text(entry.currentMarketData?.price ?? "--")
.font(.title2)
Text(currentPrice)
.font(.caption)
.fontWeight(.bold)
if let currentMarketDataRate = entry.currentMarketData?.rate, let previousMarketDataRate = entry.previousMarketData?.rate, previousMarketDataRate > 0 {
if let currentMarketDataRate = entry.currentMarketData?.rate,
let previousMarketDataRate = entry.previousMarketData?.rate,
currentMarketDataRate != previousMarketDataRate {
Image(systemName: currentMarketDataRate > previousMarketDataRate ? "arrow.up" : "arrow.down")
.foregroundColor(currentMarketDataRate > previousMarketDataRate ? .green : .red)
}
}
.minimumScaleFactor(0.01)
if let previousMarketDataPrice = entry.previousMarketData?.price {
if let previousMarketDataPrice = entry.previousMarketData?.price, Int(entry.currentMarketData?.rate ?? 0) != Int(entry.previousMarketData?.rate ?? 0) {
Text("From \(previousMarketDataPrice)")
.font(.caption)
.foregroundColor(.secondary)
}
Text("Last Updated: \(entry.currentMarketData?.formattedDate ?? "--")")
Text("at \(entry.currentMarketData?.formattedDate ?? "--")")
.font(.caption2)
.foregroundColor(.secondary)
}
.padding()
.padding(.all, 8)
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(.systemBackground))
.clipShape(RoundedRectangle(cornerRadius: 10))
}
private var defaultView: some View {
@ -105,6 +143,27 @@ struct PriceView: View {
})
}).frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .trailing).padding()
}
private func formattedPriceString(from rate: Double?) -> String {
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
numberFormatter.maximumFractionDigits = 0
return numberFormatter.string(from: NSNumber(value: rate ?? 0)) ?? "--"
}
private func formattedCurrencyString(from rate: Double?) -> String {
let numberFormatter = NumberFormatter()
numberFormatter.maximumFractionDigits = 0
numberFormatter.numberStyle = .currency
numberFormatter.currencySymbol = fiatUnit(currency: Currency.getUserPreferredCurrency())?.symbol
return numberFormatter.string(from: NSNumber(value: rate ?? 0)) ?? "--"
}
private func formattedPriceChangePercentage(currentRate: Double?, previousRate: Double?) -> String? {
guard let currentRate = currentRate, let previousRate = previousRate, previousRate > 0 else { return nil }
let change = ((currentRate - previousRate) / previousRate) * 100
return change == 0 ? nil : String(format: "%+.1f%%", change)
}
}
struct PriceView_Previews: PreviewProvider {
@ -119,7 +178,7 @@ struct PriceView_Previews: PreviewProvider {
.previewContext(WidgetPreviewContext(family: .accessoryInline))
PriceView(entry: PriceWidgetEntry(date: Date(), family: .accessoryRectangular, currentMarketData: MarketData(nextBlock: "", sats: "", price: "$10,000", rate: 10000, dateString: "2019-09-18T17:27:00+00:00"), previousMarketData: emptyMarketData))
.previewContext(WidgetPreviewContext(family: .accessoryRectangular))
}
}
}
}
}
}
}
}