Since there may be situations where we close and re-open the database,
we need to make sure transactions fail when the database is not open.
Make NdbTxn an init?() constructor and check for ndb.closed. If it's
closed, then fail transaction construction.
This fixes crashes during high database activity when switching from
background to foreground and vice-versa.
Fixes: da2bdad18d ("nostrdb: close database when backgrounded")
205 lines
8.2 KiB
Swift
205 lines
8.2 KiB
Swift
//
|
|
// WalletView.swift
|
|
// damus
|
|
//
|
|
// Created by William Casarin on 2023-05-05.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct WalletView: View {
|
|
let damus_state: DamusState
|
|
@ObservedObject var model: WalletModel
|
|
@ObservedObject var settings: UserSettingsStore
|
|
|
|
init(damus_state: DamusState, model: WalletModel? = nil) {
|
|
self.damus_state = damus_state
|
|
self._model = ObservedObject(wrappedValue: model ?? damus_state.wallet)
|
|
self._settings = ObservedObject(wrappedValue: damus_state.settings)
|
|
}
|
|
|
|
func MainWalletView(nwc: WalletConnectURL) -> some View {
|
|
VStack {
|
|
if !damus_state.settings.nozaps {
|
|
SupportDamus
|
|
|
|
Spacer()
|
|
}
|
|
|
|
Text(verbatim: nwc.relay.id)
|
|
|
|
if let lud16 = nwc.lud16 {
|
|
Text(verbatim: lud16)
|
|
}
|
|
|
|
BigButton(NSLocalizedString("Disconnect Wallet", comment: "Text for button to disconnect from Nostr Wallet Connect lightning wallet.")) {
|
|
self.model.disconnect()
|
|
}
|
|
|
|
}
|
|
.navigationTitle(NSLocalizedString("Wallet", comment: "Navigation title for Wallet view"))
|
|
.navigationBarTitleDisplayMode(.large)
|
|
.padding()
|
|
}
|
|
|
|
func donation_binding() -> Binding<Double> {
|
|
return Binding(get: {
|
|
return Double(model.settings.donation_percent)
|
|
}, set: { v in
|
|
model.settings.donation_percent = Int(v)
|
|
})
|
|
}
|
|
|
|
static let min_donation: Double = 0.0
|
|
static let max_donation: Double = 100.0
|
|
|
|
var percent: Double {
|
|
Double(model.settings.donation_percent) / 100.0
|
|
}
|
|
|
|
var tip_msats: String {
|
|
let msats = Int64(percent * Double(model.settings.default_zap_amount * 1000))
|
|
let s = format_msats_abbrev(msats)
|
|
// TODO: fix formatting and remove this hack
|
|
let parts = s.split(separator: ".")
|
|
if parts.count == 1 {
|
|
return s
|
|
}
|
|
if let end = parts[safe: 1] {
|
|
if end.allSatisfy({ c in c.isNumber }) {
|
|
return String(parts[0])
|
|
} else {
|
|
return s
|
|
}
|
|
}
|
|
return s
|
|
}
|
|
|
|
var SupportDamus: some View {
|
|
ZStack(alignment: .topLeading) {
|
|
RoundedRectangle(cornerRadius: 20)
|
|
.fill(DamusGradient.gradient.opacity(0.5))
|
|
|
|
VStack(alignment: .leading, spacing: 20) {
|
|
HStack {
|
|
Image("logo-nobg")
|
|
.resizable()
|
|
.frame(width: 50, height: 50)
|
|
Text("Support Damus", comment: "Text calling for the user to support Damus through zaps")
|
|
.font(.title.bold())
|
|
.foregroundColor(.white)
|
|
}
|
|
|
|
Text("Help build the future of decentralized communication on the web.", comment: "Text indicating the goal of developing Damus which the user can help with.")
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
.foregroundColor(.white)
|
|
|
|
Text("An additional percentage of each zap will be sent to support Damus development", comment: "Text indicating that they can contribute zaps to support Damus development.")
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
.foregroundColor(.white)
|
|
|
|
let binding = donation_binding()
|
|
|
|
HStack {
|
|
Slider(value: binding,
|
|
in: WalletView.min_donation...WalletView.max_donation,
|
|
label: { })
|
|
Text("\(Int(binding.wrappedValue))%", comment: "Percentage of additional zap that should be sent to support Damus development.")
|
|
.font(.title.bold())
|
|
.foregroundColor(.white)
|
|
.frame(width: 80)
|
|
}
|
|
|
|
HStack{
|
|
Spacer()
|
|
|
|
VStack {
|
|
HStack {
|
|
Text("\(Image("zap.fill")) \(format_msats_abbrev(Int64(model.settings.default_zap_amount) * 1000))")
|
|
.font(.title)
|
|
.foregroundColor(percent == 0 ? .gray : .yellow)
|
|
.frame(width: 120)
|
|
}
|
|
|
|
Text("Zap", comment: "Text underneath the number of sats indicating that it's the amount used for zaps.")
|
|
.foregroundColor(.white)
|
|
}
|
|
Spacer()
|
|
|
|
Text(verbatim: "+")
|
|
.font(.title)
|
|
.foregroundColor(.white)
|
|
Spacer()
|
|
|
|
VStack {
|
|
HStack {
|
|
Text("\(Image("zap.fill")) \(tip_msats)")
|
|
.font(.title)
|
|
.foregroundColor(percent == 0 ? .gray : Color.yellow)
|
|
.frame(width: 120)
|
|
}
|
|
|
|
Text(verbatim: percent == 0 ? "🩶" : "💜")
|
|
.foregroundColor(.white)
|
|
}
|
|
Spacer()
|
|
}
|
|
|
|
EventProfile(damus_state: damus_state, pubkey: damus_state.pubkey, size: .small)
|
|
}
|
|
.padding(25)
|
|
}
|
|
.frame(height: 370)
|
|
}
|
|
|
|
var body: some View {
|
|
switch model.connect_state {
|
|
case .new:
|
|
ConnectWalletView(model: model, nav: damus_state.nav)
|
|
case .none:
|
|
ConnectWalletView(model: model, nav: damus_state.nav)
|
|
case .existing(let nwc):
|
|
MainWalletView(nwc: nwc)
|
|
.onAppear() {
|
|
model.initial_percent = settings.donation_percent
|
|
}
|
|
.onChange(of: settings.donation_percent) { p in
|
|
let profile_txn = damus_state.profiles.lookup(id: damus_state.pubkey)
|
|
guard let profile = profile_txn?.unsafeUnownedValue else {
|
|
return
|
|
}
|
|
|
|
let prof = Profile(name: profile.name, display_name: profile.display_name, about: profile.about, picture: profile.picture, banner: profile.banner, website: profile.website, lud06: profile.lud06, lud16: profile.lud16, nip05: profile.nip05, damus_donation: p, reactions: profile.reactions)
|
|
|
|
notify(.profile_updated(.manual(pubkey: self.damus_state.pubkey, profile: prof)))
|
|
}
|
|
.onDisappear {
|
|
let profile_txn = damus_state.profiles.lookup(id: damus_state.pubkey)
|
|
|
|
guard let keypair = damus_state.keypair.to_full(),
|
|
let profile = profile_txn?.unsafeUnownedValue,
|
|
model.initial_percent != profile.damus_donation
|
|
else {
|
|
return
|
|
}
|
|
|
|
let prof = Profile(name: profile.name, display_name: profile.display_name, about: profile.about, picture: profile.picture, banner: profile.banner, website: profile.website, lud06: profile.lud06, lud16: profile.lud16, nip05: profile.nip05, damus_donation: settings.donation_percent, reactions: profile.reactions)
|
|
|
|
guard let meta = make_metadata_event(keypair: keypair, metadata: prof) else {
|
|
return
|
|
}
|
|
damus_state.postbox.send(meta)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let test_wallet_connect_url = WalletConnectURL(pubkey: test_pubkey, relay: .init("wss://relay.damus.io")!, keypair: test_damus_state.keypair.to_full()!, lud16: "jb55@sendsats.com")
|
|
|
|
struct WalletView_Previews: PreviewProvider {
|
|
static let tds = test_damus_state
|
|
static var previews: some View {
|
|
WalletView(damus_state: tds, model: WalletModel(state: .existing(test_wallet_connect_url), settings: tds.settings))
|
|
}
|
|
}
|