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