DONE 🙌
This commit is contained in:
@@ -15,20 +15,18 @@ struct ContentView: View {
|
||||
|
||||
// connect retry timer
|
||||
let timer = Timer.publish(every: 4, on: .main, in: .common).autoconnect()
|
||||
|
||||
let sub_id = UUID().description
|
||||
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
|
||||
var PostingTimelineView: some View {
|
||||
VStack{
|
||||
ZStack {
|
||||
if let damus = self.damus_state {
|
||||
TimelineView(events: viewModel.$home.events, loading: viewModel.$home.loading, damus: damus, show_friend_icon: false, filter: filter_event)
|
||||
if let damus = viewModel.state {
|
||||
TimelineView(events: $viewModel.home.events, loading: $viewModel.home.loading, damus: damus, show_friend_icon: false, filter: filter_event)
|
||||
}
|
||||
if viewModel.privkey != nil {
|
||||
PostButtonContainer {
|
||||
self.active_sheet = .post
|
||||
viewModel.active_sheet = .post
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,32 +72,32 @@ struct ContentView: View {
|
||||
NavigationLink(destination: MaybeSearchView, isActive: $viewModel.search_open) {
|
||||
EmptyView()
|
||||
}
|
||||
switch selected_timeline {
|
||||
switch viewModel.selected_timeline {
|
||||
case .search:
|
||||
SearchHomeView(damus_state: viewModel.state!, model: SearchHomeModel(damus_state: damus_state!))
|
||||
SearchHomeView(damus_state: viewModel.state!, model: SearchHomeModel(damus_state: viewModel.state!))
|
||||
|
||||
case .home:
|
||||
PostingTimelineView
|
||||
|
||||
case .notifications:
|
||||
TimelineView(events: $home.notifications, loading: $home.loading, damus: damus, show_friend_icon: true, filter: { _ in true })
|
||||
TimelineView(events: $viewModel.home.notifications, loading: $viewModel.home.loading, damus: damus, show_friend_icon: true, filter: { _ in true })
|
||||
.navigationTitle("Notifications")
|
||||
|
||||
case .dms:
|
||||
DirectMessagesView(damus_state: damus_state!)
|
||||
.environmentObject(home.dms)
|
||||
DirectMessagesView(damus_state: viewModel.state!)
|
||||
.environmentObject(viewModel.home.dms)
|
||||
|
||||
case .none:
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
.navigationBarTitle(selected_timeline == .home ? "Home" : "Global", displayMode: .inline)
|
||||
.navigationBarTitle(viewModel.selected_timeline == .home ? "Home" : "Global", displayMode: .inline)
|
||||
}
|
||||
|
||||
var MaybeSearchView: some View {
|
||||
Group {
|
||||
if let search = self.active_search {
|
||||
SearchView(appstate: damus_state!, search: SearchModel(pool: damus_state!.pool, search: search))
|
||||
if let search = viewModel.active_search {
|
||||
SearchView(appstate: viewModel.state!, search: SearchModel(pool: viewModel.state!.pool, search: search))
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
@@ -108,9 +106,9 @@ struct ContentView: View {
|
||||
|
||||
var MaybeThreadView: some View {
|
||||
Group {
|
||||
if let evid = self.active_event_id {
|
||||
let thread_model = ThreadModel(evid: evid, damus_state: damus_state!)
|
||||
ThreadView(thread: thread_model, damus: damus_state!, is_chatroom: false)
|
||||
if let evid = viewModel.active_event_id {
|
||||
let thread_model = ThreadModel(evid: evid, damus_state: viewModel.state!)
|
||||
ThreadView(thread: thread_model, damus: viewModel.state!, is_chatroom: false)
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
@@ -119,10 +117,10 @@ struct ContentView: View {
|
||||
|
||||
var MaybeProfileView: some View {
|
||||
Group {
|
||||
if let pk = self.active_profile {
|
||||
let profile_model = ProfileModel(pubkey: pk, damus: damus_state!)
|
||||
let followers = FollowersModel(damus_state: damus_state!, target: pk)
|
||||
ProfileView(damus_state: damus_state!, profile: profile_model, followers: followers)
|
||||
if let pk = viewModel.active_profile {
|
||||
let profile_model = ProfileModel(pubkey: pk, damus: viewModel.state!)
|
||||
let followers = FollowersModel(damus_state: viewModel.state!, target: pk)
|
||||
ProfileView(damus_state: viewModel.state!, profile: profile_model, followers: followers)
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
@@ -131,20 +129,20 @@ struct ContentView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
if let damus = self.damus_state {
|
||||
if let damus = viewModel.state {
|
||||
NavigationView {
|
||||
MainContent(damus: damus)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
let profile_model = ProfileModel(pubkey: damus_state!.pubkey, damus: damus_state!)
|
||||
let followers_model = FollowersModel(damus_state: damus_state!, target: damus_state!.pubkey)
|
||||
let prof_dest = ProfileView(damus_state: damus_state!, profile: profile_model, followers: followers_model)
|
||||
let profile_model = ProfileModel(pubkey: viewModel.state!.pubkey, damus: viewModel.state!)
|
||||
let followers_model = FollowersModel(damus_state: viewModel.state!, target: viewModel.state!.pubkey)
|
||||
let prof_dest = ProfileView(damus_state: viewModel.state!, profile: profile_model, followers: followers_model)
|
||||
|
||||
NavigationLink(destination: prof_dest) {
|
||||
/// Verify that the user has a profile picture, if not display a generic SF Symbol
|
||||
/// (Resolves an in-app error where ``Robohash`` pictures are not generated so the button dissapears
|
||||
if let picture = damus_state?.profiles.lookup(id: pubkey)?.picture {
|
||||
ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles, picture: picture)
|
||||
if let picture = viewModel.state?.profiles.lookup(id: viewModel.pubkey)?.picture {
|
||||
ProfilePicView(pubkey: viewModel.state!.pubkey, size: 32, highlight: .none, profiles: viewModel.state!.profiles, picture: picture)
|
||||
} else {
|
||||
Image(systemName: "person.fill")
|
||||
}
|
||||
@@ -153,9 +151,9 @@ struct ContentView: View {
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
NavigationLink(destination: ConfigView(state: damus_state!)) {
|
||||
NavigationLink(destination: ConfigView(state: viewModel.state!)) {
|
||||
if #available(iOS 16.0, *) {
|
||||
Image(systemName: "chart.bar.fill", variableValue: Double(home.signal.signal) / Double(home.signal.max_signal))
|
||||
Image(systemName: "chart.bar.fill", variableValue: Double(viewModel.home.signal.signal) / Double(viewModel.home.signal.max_signal))
|
||||
.font(.body.weight(.ultraLight))
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
} else {
|
||||
@@ -169,19 +167,19 @@ struct ContentView: View {
|
||||
.navigationViewStyle(.stack)
|
||||
}
|
||||
|
||||
TabBar(new_events: $home.new_events, selected: $selected_timeline, action: switch_timeline)
|
||||
TabBar(new_events: $viewModel.home.new_events, selected: $viewModel.selected_timeline, action: viewModel.switch_timeline)
|
||||
}
|
||||
.onAppear() {
|
||||
self.connect()
|
||||
viewModel.connect()
|
||||
//KingfisherManager.shared.cache.clearDiskCache()
|
||||
setup_notifications()
|
||||
}
|
||||
.sheet(item: $active_sheet) { item in
|
||||
.sheet(item: $viewModel.active_sheet) { item in
|
||||
switch item {
|
||||
case .post:
|
||||
PostView(replying_to: nil, references: [])
|
||||
case .reply(let event):
|
||||
ReplyView(replying_to: event, damus: damus_state!)
|
||||
ReplyView(replying_to: event, damus: viewModel.state!)
|
||||
}
|
||||
}
|
||||
.onOpenURL { url in
|
||||
@@ -192,28 +190,28 @@ struct ContentView: View {
|
||||
switch link {
|
||||
case .ref(let ref):
|
||||
if ref.key == "p" {
|
||||
active_profile = ref.ref_id
|
||||
profile_open = true
|
||||
viewModel.active_profile = ref.ref_id
|
||||
viewModel.profile_open = true
|
||||
} else if ref.key == "e" {
|
||||
active_event_id = ref.ref_id
|
||||
thread_open = true
|
||||
viewModel.active_event_id = ref.ref_id
|
||||
viewModel.thread_open = true
|
||||
}
|
||||
case .filter(let filt):
|
||||
active_search = filt
|
||||
search_open = true
|
||||
viewModel.active_search = filt
|
||||
viewModel.search_open = true
|
||||
break
|
||||
// TODO: handle filter searches?
|
||||
}
|
||||
|
||||
}
|
||||
.onReceive(handle_notify(.boost)) { notif in
|
||||
guard let privkey = self.privkey else {
|
||||
guard let privkey = viewModel.privkey else {
|
||||
return
|
||||
}
|
||||
|
||||
let ev = notif.object as! NostrEvent
|
||||
let boost = make_boost_event(pubkey: pubkey, privkey: privkey, boosted: ev)
|
||||
self.damus_state?.pool.send(.event(boost))
|
||||
let boost = make_boost_event(pubkey: viewModel.pubkey, privkey: privkey, boosted: ev)
|
||||
viewModel.state?.pool.send(.event(boost))
|
||||
}
|
||||
.onReceive(handle_notify(.open_thread)) { obj in
|
||||
//let ev = obj.object as! NostrEvent
|
||||
@@ -222,20 +220,20 @@ struct ContentView: View {
|
||||
}
|
||||
.onReceive(handle_notify(.reply)) { notif in
|
||||
let ev = notif.object as! NostrEvent
|
||||
self.active_sheet = .reply(ev)
|
||||
viewModel.active_sheet = .reply(ev)
|
||||
}
|
||||
.onReceive(handle_notify(.like)) { like in
|
||||
}
|
||||
.onReceive(handle_notify(.broadcast_event)) { obj in
|
||||
let ev = obj.object as! NostrEvent
|
||||
self.damus_state?.pool.send(.event(ev))
|
||||
viewModel.state?.pool.send(.event(ev))
|
||||
}
|
||||
.onReceive(handle_notify(.unfollow)) { notif in
|
||||
guard let privkey = self.privkey else {
|
||||
guard let privkey = viewModel.privkey else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let damus = self.damus_state else {
|
||||
guard let damus = viewModel.state else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -255,12 +253,12 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
.onReceive(handle_notify(.follow)) { notif in
|
||||
guard let privkey = self.privkey else {
|
||||
guard let privkey = viewModel.privkey else {
|
||||
return
|
||||
}
|
||||
|
||||
let fnotify = notif.object as! FollowTarget
|
||||
guard let damus = self.damus_state else {
|
||||
guard let damus = viewModel.state else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -271,7 +269,7 @@ struct ContentView: View {
|
||||
follow: ReferencedId(ref_id: fnotify.pubkey, relay_id: nil, key: "p")) {
|
||||
notify(.followed, fnotify.pubkey)
|
||||
|
||||
damus_state?.contacts.event = ev
|
||||
viewModel.state?.contacts.event = ev
|
||||
|
||||
switch fnotify {
|
||||
case .pubkey(let pk):
|
||||
@@ -282,7 +280,7 @@ struct ContentView: View {
|
||||
}
|
||||
}
|
||||
.onReceive(handle_notify(.post)) { obj in
|
||||
guard let privkey = self.privkey else {
|
||||
guard let privkey = viewModel.privkey else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -290,22 +288,23 @@ struct ContentView: View {
|
||||
switch post_res {
|
||||
case .post(let post):
|
||||
print("post \(post.content)")
|
||||
let new_ev = post_to_event(post: post, privkey: privkey, pubkey: pubkey)
|
||||
self.damus_state?.pool.send(.event(new_ev))
|
||||
let new_ev = post_to_event(post: post, privkey: privkey, pubkey: viewModel.pubkey)
|
||||
viewModel.state?.pool.send(.event(new_ev))
|
||||
case .cancel:
|
||||
active_sheet = nil
|
||||
viewModel.active_sheet = nil
|
||||
print("post cancelled")
|
||||
}
|
||||
}
|
||||
.onReceive(timer) { n in
|
||||
self.damus_state?.pool.connect_to_disconnected()
|
||||
viewModel.state?.pool.connect_to_disconnected()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView(keypair: Keypair(pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681", privkey: nil))
|
||||
ContentView()
|
||||
.environmentObject(DamusViewModel(with: Keypair(pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681", privkey: nil)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,21 @@ import SwiftUI
|
||||
import Starscream
|
||||
import Kingfisher
|
||||
|
||||
/// Default relays to be used when setting up the user's account.
|
||||
var BOOTSTRAP_RELAYS = [
|
||||
"wss://relay.damus.io",
|
||||
"wss://nostr-relay.wlvs.space",
|
||||
"wss://nostr.oxtr.dev",
|
||||
]
|
||||
|
||||
class DamusViewModel: ObservableObject {
|
||||
|
||||
// MARK: Constants and Variables
|
||||
|
||||
let sub_id = UUID().description
|
||||
|
||||
/// User Keypair object
|
||||
let keypair: Keypair
|
||||
var keypair: Keypair
|
||||
|
||||
var pubkey: String {
|
||||
return keypair.pubkey
|
||||
@@ -24,13 +33,6 @@ class DamusViewModel: ObservableObject {
|
||||
return keypair.privkey
|
||||
}
|
||||
|
||||
/// Default relays to be used when setting up the user's account.
|
||||
var BOOTSTRAP_RELAYS = [
|
||||
"wss://relay.damus.io",
|
||||
"wss://nostr-relay.wlvs.space",
|
||||
"wss://nostr.oxtr.dev",
|
||||
]
|
||||
|
||||
@Published var status: String = "Not connected"
|
||||
@Published var state: DamusState? = nil
|
||||
@Published var active_sheet: Sheets? = nil
|
||||
@@ -39,7 +41,7 @@ class DamusViewModel: ObservableObject {
|
||||
@Published var is_profile_open: Bool = false
|
||||
@Published var event: NostrEvent? = nil
|
||||
@Published var active_profile: String? = nil
|
||||
@Published var active_search: String? = nil
|
||||
@Published var active_search: NostrFilter? = nil
|
||||
@Published var active_event_id: String? = nil
|
||||
@Published var profile_open: Bool = false
|
||||
@Published var thread_open: Bool = false
|
||||
@@ -47,6 +49,11 @@ class DamusViewModel: ObservableObject {
|
||||
@Published var filter_state: FilterState = .posts_and_replies
|
||||
@Published var home: HomeModel = HomeModel()
|
||||
|
||||
// MARK: Initializer
|
||||
init(with key: Keypair) {
|
||||
self.keypair = key
|
||||
}
|
||||
|
||||
// MARK: Functionality
|
||||
|
||||
func switch_timeline(_ timeline: Timeline) {
|
||||
|
||||
@@ -35,7 +35,7 @@ struct InnerTimelineView: View {
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.refreshable {
|
||||
<#code#>
|
||||
print("Hello World")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ struct MainView: View {
|
||||
var body: some View {
|
||||
Group {
|
||||
if let kp = keypair, !needs_setup {
|
||||
ContentView(keypair: kp)
|
||||
ContentView()
|
||||
.environmentObject(DamusViewModel(with: kp))
|
||||
} else {
|
||||
SetupView()
|
||||
.onReceive(handle_notify(.login)) { notif in
|
||||
|
||||
Reference in New Issue
Block a user