Supporter Badges
This commit is contained in:
@@ -53,6 +53,8 @@
|
|||||||
4C216F34286F5ACD00040376 /* DMView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C216F33286F5ACD00040376 /* DMView.swift */; };
|
4C216F34286F5ACD00040376 /* DMView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C216F33286F5ACD00040376 /* DMView.swift */; };
|
||||||
4C216F362870A9A700040376 /* InputDismissKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C216F352870A9A700040376 /* InputDismissKeyboard.swift */; };
|
4C216F362870A9A700040376 /* InputDismissKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C216F352870A9A700040376 /* InputDismissKeyboard.swift */; };
|
||||||
4C216F382871EDE300040376 /* DirectMessageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C216F372871EDE300040376 /* DirectMessageModel.swift */; };
|
4C216F382871EDE300040376 /* DirectMessageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C216F372871EDE300040376 /* DirectMessageModel.swift */; };
|
||||||
|
4C2859602A12A2BE004746F7 /* SupporterBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C28595F2A12A2BE004746F7 /* SupporterBadge.swift */; };
|
||||||
|
4C2859622A12A7F0004746F7 /* GoldSupportGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C2859612A12A7F0004746F7 /* GoldSupportGradient.swift */; };
|
||||||
4C285C8228385570008A31F1 /* CarouselView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8128385570008A31F1 /* CarouselView.swift */; };
|
4C285C8228385570008A31F1 /* CarouselView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8128385570008A31F1 /* CarouselView.swift */; };
|
||||||
4C285C8428385690008A31F1 /* CreateAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8328385690008A31F1 /* CreateAccountView.swift */; };
|
4C285C8428385690008A31F1 /* CreateAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8328385690008A31F1 /* CreateAccountView.swift */; };
|
||||||
4C285C86283892E7008A31F1 /* CreateAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C85283892E7008A31F1 /* CreateAccountModel.swift */; };
|
4C285C86283892E7008A31F1 /* CreateAccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C85283892E7008A31F1 /* CreateAccountModel.swift */; };
|
||||||
@@ -444,6 +446,8 @@
|
|||||||
4C216F33286F5ACD00040376 /* DMView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMView.swift; sourceTree = "<group>"; };
|
4C216F33286F5ACD00040376 /* DMView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMView.swift; sourceTree = "<group>"; };
|
||||||
4C216F352870A9A700040376 /* InputDismissKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputDismissKeyboard.swift; sourceTree = "<group>"; };
|
4C216F352870A9A700040376 /* InputDismissKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputDismissKeyboard.swift; sourceTree = "<group>"; };
|
||||||
4C216F372871EDE300040376 /* DirectMessageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectMessageModel.swift; sourceTree = "<group>"; };
|
4C216F372871EDE300040376 /* DirectMessageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectMessageModel.swift; sourceTree = "<group>"; };
|
||||||
|
4C28595F2A12A2BE004746F7 /* SupporterBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupporterBadge.swift; sourceTree = "<group>"; };
|
||||||
|
4C2859612A12A7F0004746F7 /* GoldSupportGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoldSupportGradient.swift; sourceTree = "<group>"; };
|
||||||
4C285C8128385570008A31F1 /* CarouselView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselView.swift; sourceTree = "<group>"; };
|
4C285C8128385570008A31F1 /* CarouselView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselView.swift; sourceTree = "<group>"; };
|
||||||
4C285C8328385690008A31F1 /* CreateAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateAccountView.swift; sourceTree = "<group>"; };
|
4C285C8328385690008A31F1 /* CreateAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateAccountView.swift; sourceTree = "<group>"; };
|
||||||
4C285C85283892E7008A31F1 /* CreateAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateAccountModel.swift; sourceTree = "<group>"; };
|
4C285C85283892E7008A31F1 /* CreateAccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateAccountModel.swift; sourceTree = "<group>"; };
|
||||||
@@ -1041,6 +1045,7 @@
|
|||||||
children = (
|
children = (
|
||||||
4C7D09712A0AEF5E00943473 /* DamusGradient.swift */,
|
4C7D09712A0AEF5E00943473 /* DamusGradient.swift */,
|
||||||
4C7D09732A0AEF9000943473 /* AlbyGradient.swift */,
|
4C7D09732A0AEF9000943473 /* AlbyGradient.swift */,
|
||||||
|
4C2859612A12A7F0004746F7 /* GoldSupportGradient.swift */,
|
||||||
);
|
);
|
||||||
path = Gradients;
|
path = Gradients;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1218,6 +1223,7 @@
|
|||||||
4CE4F0F729DB7399005914DB /* ThiccDivider.swift */,
|
4CE4F0F729DB7399005914DB /* ThiccDivider.swift */,
|
||||||
4C1A9A2229DDDB8100516EAC /* IconLabel.swift */,
|
4C1A9A2229DDDB8100516EAC /* IconLabel.swift */,
|
||||||
4C8D00C929DF80350036AF10 /* TruncatedText.swift */,
|
4C8D00C929DF80350036AF10 /* TruncatedText.swift */,
|
||||||
|
4C28595F2A12A2BE004746F7 /* SupporterBadge.swift */,
|
||||||
);
|
);
|
||||||
path = Components;
|
path = Components;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1730,6 +1736,7 @@
|
|||||||
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */,
|
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */,
|
||||||
F79C7FAD29D5E9620000F946 /* EditProfilePictureControl.swift in Sources */,
|
F79C7FAD29D5E9620000F946 /* EditProfilePictureControl.swift in Sources */,
|
||||||
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */,
|
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */,
|
||||||
|
4C2859602A12A2BE004746F7 /* SupporterBadge.swift in Sources */,
|
||||||
4C75EFAF28049D350006080F /* NostrFilter.swift in Sources */,
|
4C75EFAF28049D350006080F /* NostrFilter.swift in Sources */,
|
||||||
4C3EA64C28FF59AC00C48A62 /* bech32_util.c in Sources */,
|
4C3EA64C28FF59AC00C48A62 /* bech32_util.c in Sources */,
|
||||||
4CE1399029F0661A00AC6A0B /* RepostAction.swift in Sources */,
|
4CE1399029F0661A00AC6A0B /* RepostAction.swift in Sources */,
|
||||||
@@ -1837,6 +1844,7 @@
|
|||||||
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */,
|
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */,
|
||||||
4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */,
|
4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */,
|
||||||
4CE4F0F429D779B5005914DB /* PostBox.swift in Sources */,
|
4CE4F0F429D779B5005914DB /* PostBox.swift in Sources */,
|
||||||
|
4C2859622A12A7F0004746F7 /* GoldSupportGradient.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
29
damus/Components/Gradients/GoldSupportGradient.swift
Normal file
29
damus/Components/Gradients/GoldSupportGradient.swift
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// GoldSupportGradient.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by William Casarin on 2023-05-15.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
fileprivate let gold_grad_c1 = hex_col(r: 226, g: 168, b: 0)
|
||||||
|
fileprivate let gold_grad_c2 = hex_col(r: 249, g: 243, b: 100)
|
||||||
|
|
||||||
|
fileprivate let gold_grad = [gold_grad_c2, gold_grad_c1]
|
||||||
|
|
||||||
|
let GoldGradient: LinearGradient =
|
||||||
|
LinearGradient(colors: gold_grad, startPoint: .bottomLeading, endPoint: .topTrailing)
|
||||||
|
|
||||||
|
struct GoldGradientView: View {
|
||||||
|
var body: some View {
|
||||||
|
GoldGradient
|
||||||
|
.edgesIgnoringSafeArea([.top,.bottom])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GoldGradientView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
GoldGradientView()
|
||||||
|
}
|
||||||
|
}
|
||||||
73
damus/Components/SupporterBadge.swift
Normal file
73
damus/Components/SupporterBadge.swift
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
//
|
||||||
|
// SupporterBadge.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by William Casarin on 2023-05-15.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SupporterBadge: View {
|
||||||
|
let percent: Int
|
||||||
|
|
||||||
|
let size: CGFloat = 17
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if percent < 100 {
|
||||||
|
Image("star.fill")
|
||||||
|
.resizable()
|
||||||
|
.frame(width:size, height:size)
|
||||||
|
.foregroundColor(support_level_color(percent))
|
||||||
|
} else {
|
||||||
|
Image("star.fill")
|
||||||
|
.resizable()
|
||||||
|
.frame(width:size, height:size)
|
||||||
|
.foregroundStyle(GoldGradient)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func support_level_color(_ percent: Int) -> Color {
|
||||||
|
if percent == 0 {
|
||||||
|
return .gray
|
||||||
|
}
|
||||||
|
|
||||||
|
let percent_f = Double(percent) / 100.0
|
||||||
|
let cutoff = 0.5
|
||||||
|
let h = cutoff + (percent_f * cutoff); // Hue (note 0.2 = Green, see huge chart below)
|
||||||
|
let s = 0.9; // Saturation
|
||||||
|
let b = 0.9; // Brightness
|
||||||
|
|
||||||
|
return Color(hue: h, saturation: s, brightness: b)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SupporterBadge_Previews: PreviewProvider {
|
||||||
|
static func Level(_ p: Int) -> some View {
|
||||||
|
HStack(alignment: .center) {
|
||||||
|
SupporterBadge(percent: p)
|
||||||
|
.frame(width: 50)
|
||||||
|
Text("\(p)")
|
||||||
|
.frame(width: 50)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
Level(1)
|
||||||
|
Level(10)
|
||||||
|
Level(20)
|
||||||
|
Level(30)
|
||||||
|
Level(40)
|
||||||
|
Level(50)
|
||||||
|
}
|
||||||
|
Level(60)
|
||||||
|
Level(70)
|
||||||
|
Level(80)
|
||||||
|
Level(90)
|
||||||
|
Level(100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ struct ContentView: View {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ds.postbox.send(ev)
|
ds.postbox.send(ev)
|
||||||
if let profile = ds.profiles.profiles[ev.pubkey] {
|
if let profile = ds.profiles.lookup_with_timestamp(id: ev.pubkey) {
|
||||||
ds.postbox.send(profile.event)
|
ds.postbox.send(profile.event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -735,7 +735,7 @@ func process_metadata_profile(our_pubkey: String, profiles: Profiles, profile: P
|
|||||||
var old_nip05: String? = nil
|
var old_nip05: String? = nil
|
||||||
if let mprof = profiles.lookup_with_timestamp(id: ev.pubkey) {
|
if let mprof = profiles.lookup_with_timestamp(id: ev.pubkey) {
|
||||||
old_nip05 = mprof.profile.nip05
|
old_nip05 = mprof.profile.nip05
|
||||||
if mprof.timestamp > ev.created_at {
|
if mprof.event.created_at > ev.created_at {
|
||||||
// skip if we already have an newer profile
|
// skip if we already have an newer profile
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -752,7 +752,7 @@ func process_metadata_profile(our_pubkey: String, profiles: Profiles, profile: P
|
|||||||
print("validated nip05 for '\(nip05)'")
|
print("validated nip05 for '\(nip05)'")
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
Task { @MainActor in
|
||||||
profiles.validated[ev.pubkey] = validated
|
profiles.validated[ev.pubkey] = validated
|
||||||
profiles.nip05_pubkey[nip05] = ev.pubkey
|
profiles.nip05_pubkey[nip05] = ev.pubkey
|
||||||
notify(.profile_updated, ProfileUpdate(pubkey: ev.pubkey, profile: profile))
|
notify(.profile_updated, ProfileUpdate(pubkey: ev.pubkey, profile: profile))
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ func format_msats_abbrev(_ msats: Int64) -> String {
|
|||||||
formatter.positiveSuffix = "m"
|
formatter.positiveSuffix = "m"
|
||||||
formatter.positivePrefix = ""
|
formatter.positivePrefix = ""
|
||||||
formatter.minimumFractionDigits = 0
|
formatter.minimumFractionDigits = 0
|
||||||
formatter.maximumFractionDigits = 2
|
formatter.maximumFractionDigits = 3
|
||||||
formatter.roundingMode = .down
|
formatter.roundingMode = .down
|
||||||
formatter.roundingIncrement = 0.1
|
formatter.roundingIncrement = 0.1
|
||||||
formatter.multiplier = 1
|
formatter.multiplier = 1
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ enum WalletConnectState {
|
|||||||
class WalletModel: ObservableObject {
|
class WalletModel: ObservableObject {
|
||||||
var settings: UserSettingsStore
|
var settings: UserSettingsStore
|
||||||
private(set) var previous_state: WalletConnectState
|
private(set) var previous_state: WalletConnectState
|
||||||
|
var inital_percent: Int
|
||||||
|
|
||||||
@Published private(set) var connect_state: WalletConnectState
|
@Published private(set) var connect_state: WalletConnectState
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ class WalletModel: ObservableObject {
|
|||||||
self.connect_state = state
|
self.connect_state = state
|
||||||
self.previous_state = .none
|
self.previous_state = .none
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
|
self.inital_percent = settings.donation_percent
|
||||||
}
|
}
|
||||||
|
|
||||||
init(settings: UserSettingsStore) {
|
init(settings: UserSettingsStore) {
|
||||||
@@ -35,6 +37,7 @@ class WalletModel: ObservableObject {
|
|||||||
self.previous_state = .none
|
self.previous_state = .none
|
||||||
self.connect_state = .none
|
self.connect_state = .none
|
||||||
}
|
}
|
||||||
|
self.inital_percent = settings.donation_percent
|
||||||
}
|
}
|
||||||
|
|
||||||
func cancel() {
|
func cancel() {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class Profiles {
|
|||||||
qos: .userInteractive,
|
qos: .userInteractive,
|
||||||
attributes: .concurrent)
|
attributes: .concurrent)
|
||||||
|
|
||||||
var profiles: [String: TimestampedProfile] = [:]
|
private var profiles: [String: TimestampedProfile] = [:]
|
||||||
var validated: [String: NIP05] = [:]
|
var validated: [String: NIP05] = [:]
|
||||||
var nip05_pubkey: [String: String] = [:]
|
var nip05_pubkey: [String: String] = [:]
|
||||||
var zappers: [String: String] = [:]
|
var zappers: [String: String] = [:]
|
||||||
@@ -26,6 +26,12 @@ class Profiles {
|
|||||||
return validated[pk]
|
return validated[pk]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func enumerated() -> EnumeratedSequence<[String: TimestampedProfile]> {
|
||||||
|
return queue.sync {
|
||||||
|
return profiles.enumerated()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func lookup_zapper(pubkey: String) -> String? {
|
func lookup_zapper(pubkey: String) -> String? {
|
||||||
if let zapper = zappers[pubkey] {
|
if let zapper = zappers[pubkey] {
|
||||||
return zapper
|
return zapper
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ func search_users_for_autocomplete(profiles: Profiles, tags: [[String]], search
|
|||||||
}
|
}
|
||||||
|
|
||||||
// search profile cache as well
|
// search profile cache as well
|
||||||
for tup in profiles.profiles.enumerated() {
|
for tup in profiles.enumerated() {
|
||||||
let pk = tup.element.key
|
let pk = tup.element.key
|
||||||
let prof = tup.element.value.profile
|
let prof = tup.element.value.profile
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ struct EventProfileName: View {
|
|||||||
|
|
||||||
@State var display_name: DisplayName?
|
@State var display_name: DisplayName?
|
||||||
@State var nip05: NIP05?
|
@State var nip05: NIP05?
|
||||||
|
@State var donation: Int?
|
||||||
|
|
||||||
let size: EventViewKind
|
let size: EventViewKind
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ struct EventProfileName: View {
|
|||||||
self.pubkey = pubkey
|
self.pubkey = pubkey
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
self.size = size
|
self.size = size
|
||||||
|
self._donation = State(wrappedValue: profile?.damus_donation)
|
||||||
}
|
}
|
||||||
|
|
||||||
var friend_type: FriendType? {
|
var friend_type: FriendType? {
|
||||||
@@ -45,6 +47,15 @@ struct EventProfileName: View {
|
|||||||
return profile.reactions == false
|
return profile.reactions == false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var supporter: Int? {
|
||||||
|
guard let donation, donation > 0
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return donation
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(spacing: 2) {
|
HStack(spacing: 2) {
|
||||||
switch current_display_name {
|
switch current_display_name {
|
||||||
@@ -73,6 +84,10 @@ struct EventProfileName: View {
|
|||||||
Image("zap-hashtag")
|
Image("zap-hashtag")
|
||||||
.frame(width: 14, height: 14)
|
.frame(width: 14, height: 14)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let supporter {
|
||||||
|
SupporterBadge(percent: supporter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.onReceive(handle_notify(.profile_updated)) { notif in
|
.onReceive(handle_notify(.profile_updated)) { notif in
|
||||||
let update = notif.object as! ProfileUpdate
|
let update = notif.object as! ProfileUpdate
|
||||||
@@ -81,6 +96,7 @@ struct EventProfileName: View {
|
|||||||
}
|
}
|
||||||
display_name = Profile.displayName(profile: update.profile, pubkey: pubkey)
|
display_name = Profile.displayName(profile: update.profile, pubkey: pubkey)
|
||||||
nip05 = damus_state.profiles.is_validated(pubkey)
|
nip05 = damus_state.profiles.is_validated(pubkey)
|
||||||
|
donation = update.profile.damus_donation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ struct ProfileName: View {
|
|||||||
|
|
||||||
@State var display_name: DisplayName?
|
@State var display_name: DisplayName?
|
||||||
@State var nip05: NIP05?
|
@State var nip05: NIP05?
|
||||||
|
@State var donation: Int?
|
||||||
|
|
||||||
init(pubkey: String, profile: Profile?, damus: DamusState, show_nip5_domain: Bool = true) {
|
init(pubkey: String, profile: Profile?, damus: DamusState, show_nip5_domain: Bool = true) {
|
||||||
self.pubkey = pubkey
|
self.pubkey = pubkey
|
||||||
@@ -75,6 +76,17 @@ struct ProfileName: View {
|
|||||||
return profile.reactions == false
|
return profile.reactions == false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var supporter: Int? {
|
||||||
|
guard let profile,
|
||||||
|
let donation = profile.damus_donation,
|
||||||
|
donation > 0
|
||||||
|
else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return donation
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(spacing: 2) {
|
HStack(spacing: 2) {
|
||||||
Text(verbatim: "\(prefix)\(name_choice)")
|
Text(verbatim: "\(prefix)\(name_choice)")
|
||||||
@@ -90,6 +102,9 @@ struct ProfileName: View {
|
|||||||
Image("zap-hashtag")
|
Image("zap-hashtag")
|
||||||
.frame(width: 14, height: 14)
|
.frame(width: 14, height: 14)
|
||||||
}
|
}
|
||||||
|
if let supporter {
|
||||||
|
SupporterBadge(percent: supporter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.onReceive(handle_notify(.profile_updated)) { notif in
|
.onReceive(handle_notify(.profile_updated)) { notif in
|
||||||
let update = notif.object as! ProfileUpdate
|
let update = notif.object as! ProfileUpdate
|
||||||
@@ -98,6 +113,7 @@ struct ProfileName: View {
|
|||||||
}
|
}
|
||||||
display_name = Profile.displayName(profile: update.profile, pubkey: pubkey)
|
display_name = Profile.displayName(profile: update.profile, pubkey: pubkey)
|
||||||
nip05 = damus_state.profiles.is_validated(pubkey)
|
nip05 = damus_state.profiles.is_validated(pubkey)
|
||||||
|
donation = profile?.damus_donation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -496,6 +496,9 @@ struct ProfileView_Previews: PreviewProvider {
|
|||||||
func test_damus_state() -> DamusState {
|
func test_damus_state() -> DamusState {
|
||||||
let pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
|
let pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
|
||||||
let damus = DamusState.empty
|
let damus = DamusState.empty
|
||||||
|
let settings = UserSettingsStore()
|
||||||
|
settings.donation_percent = 100
|
||||||
|
settings.default_zap_amount = 1971
|
||||||
|
|
||||||
let prof = Profile(name: "damus", display_name: "damus", about: "iOS app!", picture: "https://damus.io/img/logo.png", banner: "", website: "https://damus.io", lud06: nil, lud16: "jb55@sendsats.lol", nip05: "damus.io", damus_donation: nil)
|
let prof = Profile(name: "damus", display_name: "damus", about: "iOS app!", picture: "https://damus.io/img/logo.png", banner: "", website: "https://damus.io", lud06: nil, lud16: "jb55@sendsats.lol", nip05: "damus.io", damus_donation: nil)
|
||||||
let tsprof = TimestampedProfile(profile: prof, timestamp: 0, event: test_event)
|
let tsprof = TimestampedProfile(profile: prof, timestamp: 0, event: test_event)
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ func make_hashtagable(_ str: String) -> String {
|
|||||||
|
|
||||||
func search_profiles(profiles: Profiles, search: String) -> [SearchedUser] {
|
func search_profiles(profiles: Profiles, search: String) -> [SearchedUser] {
|
||||||
let new = search.lowercased()
|
let new = search.lowercased()
|
||||||
return profiles.profiles.enumerated().reduce(into: []) { acc, els in
|
return profiles.enumerated().reduce(into: []) { acc, els in
|
||||||
let pk = els.element.key
|
let pk = els.element.key
|
||||||
let prof = els.element.value.profile
|
let prof = els.element.value.profile
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,19 @@ struct WalletView: View {
|
|||||||
var tip_msats: String {
|
var tip_msats: String {
|
||||||
let msats = Int64(percent * Double(model.settings.default_zap_amount * 1000))
|
let msats = Int64(percent * Double(model.settings.default_zap_amount * 1000))
|
||||||
let s = format_msats_abbrev(msats)
|
let s = format_msats_abbrev(msats)
|
||||||
return s.split(separator: ".").first.map({ x in String(x) }) ?? s
|
// 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 {
|
var SupportDamus: some View {
|
||||||
@@ -93,6 +105,7 @@ struct WalletView: View {
|
|||||||
Text("\(Int(binding.wrappedValue))%")
|
Text("\(Int(binding.wrappedValue))%")
|
||||||
.font(.title.bold())
|
.font(.title.bold())
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
|
.frame(width: 80)
|
||||||
}
|
}
|
||||||
|
|
||||||
HStack{
|
HStack{
|
||||||
@@ -103,7 +116,7 @@ struct WalletView: View {
|
|||||||
Text("\(Image("zap.fill")) \(format_msats_abbrev(Int64(model.settings.default_zap_amount) * 1000))")
|
Text("\(Image("zap.fill")) \(format_msats_abbrev(Int64(model.settings.default_zap_amount) * 1000))")
|
||||||
.font(.title)
|
.font(.title)
|
||||||
.foregroundColor(percent == 0 ? .gray : .yellow)
|
.foregroundColor(percent == 0 ? .gray : .yellow)
|
||||||
.frame(width: 100)
|
.frame(width: 120)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text("Zap")
|
Text("Zap")
|
||||||
@@ -121,9 +134,10 @@ struct WalletView: View {
|
|||||||
Text("\(Image("zap.fill")) \(tip_msats)")
|
Text("\(Image("zap.fill")) \(tip_msats)")
|
||||||
.font(.title)
|
.font(.title)
|
||||||
.foregroundColor(percent == 0 ? .gray : Color.yellow)
|
.foregroundColor(percent == 0 ? .gray : Color.yellow)
|
||||||
.frame(width: 100)
|
.frame(width: 120)
|
||||||
}
|
}
|
||||||
Text("💜")
|
|
||||||
|
Text(percent == 0 ? "🩶" : "💜")
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
@@ -154,16 +168,30 @@ struct WalletView: View {
|
|||||||
ConnectWalletView(model: model)
|
ConnectWalletView(model: model)
|
||||||
case .existing(let nwc):
|
case .existing(let nwc):
|
||||||
MainWalletView(nwc: nwc)
|
MainWalletView(nwc: nwc)
|
||||||
|
.onAppear() {
|
||||||
|
model.inital_percent = settings.donation_percent
|
||||||
|
}
|
||||||
|
.onChange(of: settings.donation_percent) { p in
|
||||||
|
guard let profile = damus_state.profiles.lookup(id: damus_state.pubkey) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.damus_donation = p
|
||||||
|
|
||||||
|
notify(.profile_updated, ProfileUpdate(pubkey: damus_state.pubkey, profile: profile))
|
||||||
|
}
|
||||||
.onDisappear {
|
.onDisappear {
|
||||||
guard let keypair = damus_state.keypair.to_full(),
|
guard let keypair = damus_state.keypair.to_full(),
|
||||||
let profile = damus_state.profiles.lookup(id: damus_state.pubkey),
|
let profile = damus_state.profiles.lookup(id: damus_state.pubkey),
|
||||||
profile.damus_donation != settings.donation_percent
|
model.inital_percent != profile.damus_donation
|
||||||
else {
|
else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.damus_donation = settings.donation_percent
|
profile.damus_donation = settings.donation_percent
|
||||||
let meta = make_metadata_event(keypair: keypair, metadata: profile)
|
let meta = make_metadata_event(keypair: keypair, metadata: profile)
|
||||||
|
let tsprofile = TimestampedProfile(profile: profile, timestamp: meta.created_at, event: meta)
|
||||||
|
damus_state.profiles.add(id: damus_state.pubkey, profile: tsprofile)
|
||||||
damus_state.postbox.send(meta)
|
damus_state.postbox.send(meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user