Convert more NavigationLinks to router

This commit is contained in:
Scott Penrose
2023-05-26 16:58:24 -04:00
committed by William Casarin
parent f0b0eade37
commit 242455410e
19 changed files with 274 additions and 193 deletions

View File

@@ -11,21 +11,10 @@ struct UserViewRow: View {
let damus_state: DamusState let damus_state: DamusState
let pubkey: String let pubkey: String
@State var navigating: Bool = false
var body: some View { var body: some View {
let dest = ProfileView(damus_state: damus_state, pubkey: pubkey)
UserView(damus_state: damus_state, pubkey: pubkey) UserView(damus_state: damus_state, pubkey: pubkey)
.contentShape(Rectangle()) .contentShape(Rectangle())
.background( .background(.clear)
NavigationLink(destination: dest, isActive: $navigating) {
EmptyView()
}
)
.onTapGesture {
navigating = true
}
} }
} }

View File

@@ -329,7 +329,7 @@ struct ContentView: View {
SideMenuView(damus_state: damus, isSidebarVisible: $isSideBarOpened.animation()) SideMenuView(damus_state: damus, isSidebarVisible: $isSideBarOpened.animation())
) )
.navigationDestination(for: Route.self) { route in .navigationDestination(for: Route.self) { route in
route.view(navigationCordinator: navigationCoordinator) route.view(navigationCordinator: navigationCoordinator, damusState: damus_state!)
} }
.onReceive(handle_notify(.switched_timeline)) { _ in .onReceive(handle_notify(.switched_timeline)) { _ in
navigationCoordinator.popToRoot() navigationCoordinator.popToRoot()

View File

@@ -8,71 +8,131 @@
import SwiftUI import SwiftUI
enum Route: Hashable { enum Route: Hashable {
case Profile(damusSate: DamusState, profile: ProfileModel, followers: FollowersModel) case ProfileByKey(pubkey: String)
case Followers(damusState: DamusState, environmentObject: FollowersModel) case Profile(profile: ProfileModel, followers: FollowersModel)
case Relay(damusState: DamusState, relay: String, showActionButtons: Binding<Bool>) case Followers(environmentObject: FollowersModel)
case Following(damusState: DamusState, following: FollowingModel) case Relay(relay: String, showActionButtons: Binding<Bool>)
case MuteList(damusState: DamusState, users: [String]) case RelayDetail(relay: String, metadata: RelayMetadata)
case RelayConfig(damusState: DamusState) case Following(following: FollowingModel)
case Bookmarks(damusState: DamusState) case MuteList(users: [String])
case Config(damusState: DamusState) case RelayConfig
case EditMetadata(damusState: DamusState) case Bookmarks
case DMChat(damusState: DamusState, dms: DirectMessageModel) case Config
case UserRelays(damusState: DamusState, relays: [String]) case EditMetadata
case DMChat(dms: DirectMessageModel)
case UserRelays(relays: [String])
case KeySettings(keypair: Keypair)
case AppearanceSettings(settings: UserSettingsStore) // Observed object.. is this an issue?
case NotificationSettings(settings: UserSettingsStore) // Observed object.. is this an issue?
case ZapSettings(settings: UserSettingsStore) // Observed object.. is this an issue?
case TranslationSettings(settings: UserSettingsStore) // Observed object.. is this an issue?
case Thread(thread: ThreadModel)
case Reposts(reposts: RepostsModel)
case Reactions(reactions: ReactionsModel)
case Zaps(target: ZapTarget)
case Search(search: SearchModel)
@ViewBuilder @ViewBuilder
func view(navigationCordinator: NavigationCoordinator) -> some View { func view(navigationCordinator: NavigationCoordinator, damusState: DamusState) -> some View {
switch self { switch self {
case .Profile (let damusState, let profile, let followers): case .ProfileByKey(let pubkey):
ProfileView(damus_state: damusState, pubkey: pubkey)
case .Profile(let profile, let followers):
ProfileView(damus_state: damusState, profile: profile, followers: followers) ProfileView(damus_state: damusState, profile: profile, followers: followers)
case .Followers (let damusState, let environmentObject): case .Followers(let environmentObject):
FollowersView(damus_state: damusState) FollowersView(damus_state: damusState)
.environmentObject(environmentObject) .environmentObject(environmentObject)
case .Relay (let damusState, let relay, let showActionButtons): case .Relay(let relay, let showActionButtons):
RelayView(state: damusState, relay: relay, showActionButtons: showActionButtons) RelayView(state: damusState, relay: relay, showActionButtons: showActionButtons)
case .Following(let damusState, let following): case .RelayDetail(let relay, let metadata):
RelayDetailView(state: damusState, relay: relay, nip11: metadata)
case .Following(let following):
FollowingView(damus_state: damusState, following: following) FollowingView(damus_state: damusState, following: following)
case .MuteList(let damusState, let users): case .MuteList(let users):
MutelistView(damus_state: damusState, users: users) MutelistView(damus_state: damusState, users: users)
case .RelayConfig(let damusState): case .RelayConfig:
RelayConfigView(state: damusState) RelayConfigView(state: damusState)
case .Bookmarks(let damusState): case .Bookmarks:
BookmarksView(state: damusState) BookmarksView(state: damusState)
case .Config(let damusState): case .Config:
ConfigView(state: damusState) ConfigView(state: damusState)
case .EditMetadata(let damusState): case .EditMetadata:
EditMetadataView(damus_state: damusState) EditMetadataView(damus_state: damusState)
case .DMChat(let damusState, let dms): case .DMChat(let dms):
DMChatView(damus_state: damusState, dms: dms) DMChatView(damus_state: damusState, dms: dms)
case .UserRelays(let damusState, let relays): case .UserRelays(let relays):
UserRelaysView(state: damusState, relays: relays) UserRelaysView(state: damusState, relays: relays)
case .KeySettings(let keypair):
KeySettingsView(keypair: keypair)
case .AppearanceSettings(let settings):
AppearanceSettingsView(settings: settings)
case .NotificationSettings(let settings):
NotificationSettingsView(settings: settings)
case .ZapSettings(let settings):
ZapSettingsView(settings: settings)
case .TranslationSettings(let settings):
NotificationSettingsView(settings: settings)
case .Thread(let thread):
ThreadView(state: damusState, thread: thread)
case .Reposts(let reposts):
RepostsView(damus_state: damusState, model: reposts)
case .Reactions(let reactions):
ReactionsView(damus_state: damusState, model: reactions)
case .Zaps(let target):
ZapsView(state: damusState, target: target)
case .Search(let search):
SearchView(appstate: damusState, search: search)
} }
} }
static func == (lhs: Route, rhs: Route) -> Bool { static func == (lhs: Route, rhs: Route) -> Bool {
switch (lhs, rhs) { switch (lhs, rhs) {
case (.Profile (_, let lhs_profile, _), .Profile(_, let rhs_profile, _)): case (.ProfileByKey (let lhs_pubkey), .ProfileByKey(let rhs_pubkey)):
return lhs_pubkey == rhs_pubkey
case (.Profile (let lhs_profile, _), .Profile(let rhs_profile, _)):
return lhs_profile == rhs_profile return lhs_profile == rhs_profile
case (.Followers (_, _), .Followers (_, _)): case (.Followers (_), .Followers (_)):
return true return true
case (.Relay (_, let lhs_relay, _), .Relay (_, let rhs_relay, _)): case (.Relay (let lhs_relay, _), .Relay (let rhs_relay, _)):
return lhs_relay == rhs_relay return lhs_relay == rhs_relay
case (.Following(_, _), .Following(_, _)): case (.RelayDetail(let lhs_relay, _), .RelayDetail(let rhs_relay, _)):
return lhs_relay == rhs_relay
case (.Following(_), .Following(_)):
return true return true
case (.MuteList(_, let lhs_users), .MuteList(_, let rhs_users)): case (.MuteList(let lhs_users), .MuteList(let rhs_users)):
return lhs_users == rhs_users return lhs_users == rhs_users
case (.RelayConfig(_), .RelayConfig(_)): case (.RelayConfig, .RelayConfig):
return true return true
case (.Bookmarks(_), .Bookmarks(_)): case (.Bookmarks, .Bookmarks):
return true return true
case (.Config(_), .Config(_)): case (.Config, .Config):
return true return true
case (.EditMetadata(_), .EditMetadata(_)): case (.EditMetadata, .EditMetadata):
return true return true
case (.DMChat(_, let lhs_dms), .DMChat(_, let rhs_dms)): case (.DMChat(let lhs_dms), .DMChat(let rhs_dms)):
return lhs_dms.our_pubkey == rhs_dms.our_pubkey return lhs_dms.our_pubkey == rhs_dms.our_pubkey
case (.UserRelays(_, let lhs_relays), .UserRelays(_, let rhs_relays)): case (.UserRelays(let lhs_relays), .UserRelays(let rhs_relays)):
return lhs_relays == rhs_relays return lhs_relays == rhs_relays
case (.KeySettings(let lhs_keypair), .KeySettings(let rhs_keypair)):
return lhs_keypair.pubkey == rhs_keypair.pubkey
case (.AppearanceSettings(_), .AppearanceSettings(_)):
return true
case (.NotificationSettings(_), .NotificationSettings(_)):
return true
case (.ZapSettings(_), .ZapSettings(_)):
return true
case (.TranslationSettings(_), .TranslationSettings(_)):
return true
case (.Thread(let lhs_threadModel), .Thread(thread: let rhs_threadModel)):
return lhs_threadModel.event.id == rhs_threadModel.event.id
case (.Reposts(let lhs_reposts), .Reposts(let rhs_reposts)):
return lhs_reposts.target == rhs_reposts.target
case (.Reactions(let lhs_reactions), .Reactions(let rhs_reactions)):
return lhs_reactions.target == rhs_reactions.target
case (.Zaps(let lhs_target), .Zaps(let rhs_target)):
return lhs_target == rhs_target
case (.Search(let lhs_search), .Search(let rhs_search)):
return lhs_search.sub_id == rhs_search.sub_id && lhs_search.profiles_subid == rhs_search.profiles_subid
default: default:
return false return false
} }
@@ -80,28 +140,67 @@ enum Route: Hashable {
func hash(into hasher: inout Hasher) { func hash(into hasher: inout Hasher) {
switch self { switch self {
case .Profile(_, let profile, _): case .ProfileByKey(let pubkey):
hasher.combine("profilebykey")
hasher.combine(pubkey)
case .Profile(let profile, _):
hasher.combine("profile")
hasher.combine(profile.pubkey) hasher.combine(profile.pubkey)
case .Followers(_, _): case .Followers(_):
hasher.combine("followers") hasher.combine("followers")
case .Relay(_, let relay, _): case .Relay(let relay, _):
hasher.combine("relay")
hasher.combine(relay) hasher.combine(relay)
case .Following(_, _): case .RelayDetail(let relay, _):
hasher.combine("relayDetail")
hasher.combine(relay)
case .Following(_):
hasher.combine("following") hasher.combine("following")
case .MuteList(_, let users): case .MuteList(let users):
hasher.combine("muteList")
hasher.combine(users) hasher.combine(users)
case .RelayConfig(_): case .RelayConfig:
hasher.combine("relayConfig") hasher.combine("relayConfig")
case .Bookmarks(_): case .Bookmarks:
hasher.combine("bookmarks") hasher.combine("bookmarks")
case .Config(_): case .Config:
hasher.combine("config") hasher.combine("config")
case .EditMetadata(_): case .EditMetadata:
hasher.combine("editMetadata") hasher.combine("editMetadata")
case .DMChat(_, let dms): case .DMChat(let dms):
hasher.combine("dms")
hasher.combine(dms.our_pubkey) hasher.combine(dms.our_pubkey)
case .UserRelays(_, let relays): case .UserRelays(let relays):
hasher.combine("userRelays")
hasher.combine(relays) hasher.combine(relays)
case .KeySettings(let keypair):
hasher.combine("keySettings")
hasher.combine(keypair.pubkey)
case .AppearanceSettings(_):
hasher.combine("appearanceSettings")
case .NotificationSettings(_):
hasher.combine("notificationSettings")
case .ZapSettings(_):
hasher.combine("zapSettings")
case .TranslationSettings(_):
hasher.combine("translationSettings")
case .Thread(let threadModel):
hasher.combine("thread")
hasher.combine(threadModel.event.id)
case .Reposts(let reposts):
hasher.combine("reposts")
hasher.combine(reposts.target)
case .Zaps(let target):
hasher.combine("zaps")
hasher.combine(target.id)
hasher.combine(target.pubkey)
case .Reactions(let reactions):
hasher.combine("reactions")
hasher.combine(reactions.target)
case .Search(let search):
hasher.combine("search")
hasher.combine(search.sub_id)
hasher.combine(search.profiles_subid)
} }
} }
} }

View File

@@ -25,7 +25,7 @@ struct EventDetailBar: View {
var body: some View { var body: some View {
HStack { HStack {
if bar.boosts > 0 { if bar.boosts > 0 {
NavigationLink(destination: RepostsView(damus_state: state, model: RepostsModel(state: state, target: target))) { NavigationLink(value: Route.Reposts(reposts: RepostsModel(state: state, target: target))) {
let noun = Text(verbatim: repostsCountString(bar.boosts)).foregroundColor(.gray) let noun = Text(verbatim: repostsCountString(bar.boosts)).foregroundColor(.gray)
Text("\(Text(verbatim: bar.boosts.formatted()).font(.body.bold())) \(noun)", comment: "Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.") Text("\(Text(verbatim: bar.boosts.formatted()).font(.body.bold())) \(noun)", comment: "Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.")
} }
@@ -33,7 +33,7 @@ struct EventDetailBar: View {
} }
if bar.likes > 0 && !state.settings.onlyzaps_mode { if bar.likes > 0 && !state.settings.onlyzaps_mode {
NavigationLink(destination: ReactionsView(damus_state: state, model: ReactionsModel(state: state, target: target))) { NavigationLink(value: Route.Reactions(reactions: ReactionsModel(state: state, target: target))) {
let noun = Text(verbatim: reactionsCountString(bar.likes)).foregroundColor(.gray) let noun = Text(verbatim: reactionsCountString(bar.likes)).foregroundColor(.gray)
Text("\(Text(verbatim: bar.likes.formatted()).font(.body.bold())) \(noun)", comment: "Sentence composed of 2 variables to describe how many reactions there are on a post. In source English, the first variable is the number of reactions, and the second variable is 'Reaction' or 'Reactions'.") Text("\(Text(verbatim: bar.likes.formatted()).font(.body.bold())) \(noun)", comment: "Sentence composed of 2 variables to describe how many reactions there are on a post. In source English, the first variable is the number of reactions, and the second variable is 'Reaction' or 'Reactions'.")
} }
@@ -41,8 +41,7 @@ struct EventDetailBar: View {
} }
if bar.zaps > 0 { if bar.zaps > 0 {
let dst = ZapsView(state: state, target: .note(id: target, author: target_pk)) NavigationLink(value: Route.Zaps(target: .note(id: target, author: target_pk))) {
NavigationLink(destination: dst) {
let noun = Text(verbatim: zapsCountString(bar.zaps)).foregroundColor(.gray) let noun = Text(verbatim: zapsCountString(bar.zaps)).foregroundColor(.gray)
Text("\(Text(verbatim: bar.zaps.formatted()).font(.body.bold())) \(noun)", comment: "Sentence composed of 2 variables to describe how many zap payments there are on a post. In source English, the first variable is the number of zap payments, and the second variable is 'Zap' or 'Zaps'.") Text("\(Text(verbatim: bar.zaps.formatted()).font(.body.bold())) \(noun)", comment: "Sentence composed of 2 variables to describe how many zap payments there are on a post. In source English, the first variable is the number of zap payments, and the second variable is 'Zap' or 'Zaps'.")
} }

View File

@@ -36,11 +36,11 @@ struct ConfigView: View {
ZStack(alignment: .leading) { ZStack(alignment: .leading) {
Form { Form {
Section { Section {
NavigationLink(destination: KeySettingsView(keypair: state.keypair)) { NavigationLink(value: Route.KeySettings(keypair: state.keypair)) {
IconLabel(NSLocalizedString("Keys", comment: "Settings section for managing keys"), img_name: "key", color: .purple) IconLabel(NSLocalizedString("Keys", comment: "Settings section for managing keys"), img_name: "key", color: .purple)
} }
NavigationLink(destination: AppearanceSettingsView(settings: settings)) { NavigationLink(value: Route.AppearanceSettings(settings: settings)) {
IconLabel(NSLocalizedString("Appearance", comment: "Section header for text and appearance settings"), img_name: "eye", color: .red) IconLabel(NSLocalizedString("Appearance", comment: "Section header for text and appearance settings"), img_name: "eye", color: .red)
} }
@@ -48,20 +48,19 @@ struct ConfigView: View {
IconLabel(NSLocalizedString("Search/Universe", comment: "Section header for search/universe settings"), img_name: "magnifyingglass", color: .red) IconLabel(NSLocalizedString("Search/Universe", comment: "Section header for search/universe settings"), img_name: "magnifyingglass", color: .red)
} }
NavigationLink(destination: NotificationSettingsView(settings: settings)) { NavigationLink(value: Route.NotificationSettings(settings: settings)) {
IconLabel(NSLocalizedString("Notifications", comment: "Section header for Damus notifications"), img_name: "notification-bell-on", color: .blue) IconLabel(NSLocalizedString("Notifications", comment: "Section header for Damus notifications"), img_name: "notification-bell-on", color: .blue)
} }
NavigationLink(destination: ZapSettingsView(settings: settings)) { NavigationLink(value: Route.ZapSettings(settings: settings)) {
IconLabel(NSLocalizedString("Zaps", comment: "Section header for zap settings"), img_name: "zap.fill", color: .orange) IconLabel(NSLocalizedString("Zaps", comment: "Section header for zap settings"), img_name: "zap.fill", color: .orange)
} }
NavigationLink(destination: TranslationSettingsView(settings: settings)) { NavigationLink(value: Route.TranslationSettings(settings: settings)) {
IconLabel(NSLocalizedString("Translation", comment: "Section header for text and appearance settings"), img_name: "globe", color: .green) IconLabel(NSLocalizedString("Translation", comment: "Section header for text and appearance settings"), img_name: "globe", color: .green)
} }
} }
Section(NSLocalizedString("Sign Out", comment: "Section title for signing out")) { Section(NSLocalizedString("Sign Out", comment: "Section title for signing out")) {
Button(action: { Button(action: {
if state.keypair.privkey == nil { if state.keypair.privkey == nil {

View File

@@ -61,8 +61,7 @@ struct DMChatView: View, KeyboardReadable {
var Header: some View { var Header: some View {
let profile = damus_state.profiles.lookup(id: pubkey) let profile = damus_state.profiles.lookup(id: pubkey)
let profile_page = ProfileView(damus_state: damus_state, pubkey: pubkey) return NavigationLink(value: Route.ProfileByKey(pubkey: pubkey)) {
return NavigationLink(destination: profile_page) {
HStack { HStack {
ProfilePicView(pubkey: pubkey, size: 24, highlight: .none, profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation) ProfilePicView(pubkey: pubkey, size: 24, highlight: .none, profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation)

View File

@@ -72,8 +72,7 @@ struct BuilderEventView: View {
if let event { if let event {
let ev = event.get_inner_event(cache: damus.events) ?? event let ev = event.get_inner_event(cache: damus.events) ?? event
let thread = ThreadModel(event: ev, damus_state: damus) let thread = ThreadModel(event: ev, damus_state: damus)
let dest = ThreadView(state: damus, thread: thread) NavigationLink(value: Route.Thread(thread: thread)) {
NavigationLink(destination: dest) {
EventView(damus: damus, event: event, options: .embedded) EventView(damus: damus, event: event, options: .embedded)
.padding([.top, .bottom], 8) .padding([.top, .bottom], 8)
}.buttonStyle(.plain) }.buttonStyle(.plain)

View File

@@ -37,7 +37,7 @@ struct EventProfile: View {
var body: some View { var body: some View {
HStack(alignment: .center) { HStack(alignment: .center) {
VStack { VStack {
NavigationLink(destination: ProfileView(damus_state: damus_state, pubkey: pubkey)) { NavigationLink(value: Route.ProfileByKey(pubkey: pubkey)) {
ProfilePicView(pubkey: pubkey, size: pfp_size, highlight: .none, profiles: damus_state.profiles, disable_animation: disable_animation) ProfilePicView(pubkey: pubkey, size: pfp_size, highlight: .none, profiles: damus_state.profiles, disable_animation: disable_animation)
} }
} }

View File

@@ -240,8 +240,7 @@ struct EventGroupView: View {
if let event { if let event {
let thread = ThreadModel(event: event, damus_state: state) let thread = ThreadModel(event: event, damus_state: state)
let dest = ThreadView(state: state, thread: thread) NavigationLink(value: Route.Thread(thread: thread)) {
NavigationLink(destination: dest) {
VStack(alignment: .leading) { VStack(alignment: .leading) {
GroupDescription(unique_pubkeys) GroupDescription(unique_pubkeys)
EventBody(damus_state: state, event: event, size: .normal, options: [.truncate_content]) EventBody(damus_state: state, event: event, size: .normal, options: [.truncate_content])

View File

@@ -59,7 +59,7 @@ struct NotificationItemView: View {
EventGroupView(state: state, event: ev, group: .reaction(evgrp)) EventGroupView(state: state, event: ev, group: .reaction(evgrp))
case .reply(let ev): case .reply(let ev):
NavigationLink(destination: ThreadView(state: state, thread: ThreadModel(event: ev, damus_state: state))) { NavigationLink(value: Route.Thread(thread: ThreadModel(event: ev, damus_state: state))) {
EventView(damus: state, event: ev, options: options) EventView(damus: state, event: ev, options: options)
} }
.buttonStyle(.plain) .buttonStyle(.plain)

View File

@@ -28,7 +28,7 @@ struct MaybeAnonPfpView: View {
.font(.largeTitle) .font(.largeTitle)
.frame(width: size, height: size) .frame(width: size, height: size)
} else { } else {
NavigationLink(destination: ProfileView(damus_state: state, pubkey: pubkey)) { NavigationLink(value: Route.ProfileByKey(pubkey: pubkey)) {
ProfilePicView(pubkey: pubkey, size: size, highlight: .none, profiles: state.profiles, disable_animation: state.settings.disable_animation) ProfilePicView(pubkey: pubkey, size: size, highlight: .none, profiles: state.profiles, disable_animation: state.settings.disable_animation)
} }
} }

View File

@@ -77,7 +77,7 @@ struct EditButton: View {
@Environment(\.colorScheme) var colorScheme @Environment(\.colorScheme) var colorScheme
var body: some View { var body: some View {
NavigationLink(value: Route.EditMetadata(damusState: damus_state)) { NavigationLink(value: Route.EditMetadata) {
Text("Edit", comment: "Button to edit user's profile.") Text("Edit", comment: "Button to edit user's profile.")
.frame(height: 30) .frame(height: 30)
.padding(.horizontal,25) .padding(.horizontal,25)
@@ -300,7 +300,7 @@ struct ProfileView: View {
var dmButton: some View { var dmButton: some View {
let dm_model = damus_state.dms.lookup_or_create(profile.pubkey) let dm_model = damus_state.dms.lookup_or_create(profile.pubkey)
return NavigationLink(value: Route.DMChat(damusState: damus_state, dms: dm_model)) { return NavigationLink(value: Route.DMChat(dms: dm_model)) {
Image("messages") Image("messages")
.profile_button_style(scheme: colorScheme) .profile_button_style(scheme: colorScheme)
} }
@@ -324,7 +324,7 @@ struct ProfileView: View {
follow_state: damus_state.contacts.follow_state(profile.pubkey) follow_state: damus_state.contacts.follow_state(profile.pubkey)
) )
} else if damus_state.keypair.privkey != nil { } else if damus_state.keypair.privkey != nil {
NavigationLink(value: Route.EditMetadata(damusState: damus_state)) { NavigationLink(value: Route.EditMetadata) {
EditButton(damus_state: damus_state) EditButton(damus_state: damus_state)
} }
} }
@@ -403,7 +403,7 @@ struct ProfileView: View {
if let contact = profile.contacts { if let contact = profile.contacts {
let contacts = contact.referenced_pubkeys.map { $0.ref_id } let contacts = contact.referenced_pubkeys.map { $0.ref_id }
let following_model = FollowingModel(damus_state: damus_state, contacts: contacts) let following_model = FollowingModel(damus_state: damus_state, contacts: contacts)
NavigationLink(value: Route.Following(damusState: damus_state, following: following_model)) { NavigationLink(value: Route.Following(following: following_model)) {
HStack { HStack {
let noun_text = Text(verbatim: "\(followingCountString(profile.following))").font(.subheadline).foregroundColor(.gray) let noun_text = Text(verbatim: "\(followingCountString(profile.following))").font(.subheadline).foregroundColor(.gray)
Text("\(Text(verbatim: profile.following.formatted()).font(.subheadline.weight(.medium))) \(noun_text)", comment: "Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'.") Text("\(Text(verbatim: profile.following.formatted()).font(.subheadline.weight(.medium))) \(noun_text)", comment: "Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'.")
@@ -413,7 +413,7 @@ struct ProfileView: View {
} }
if followers.contacts != nil { if followers.contacts != nil {
NavigationLink(value: Route.Followers(damusState: damus_state, environmentObject: followers)) { NavigationLink(value: Route.Followers(environmentObject: followers)) {
followersCount followersCount
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())
@@ -431,12 +431,12 @@ struct ProfileView: View {
let noun_text = Text(verbatim: relaysCountString(relays.keys.count)).font(.subheadline).foregroundColor(.gray) let noun_text = Text(verbatim: relaysCountString(relays.keys.count)).font(.subheadline).foregroundColor(.gray)
let relay_text = Text("\(Text(verbatim: relays.keys.count.formatted()).font(.subheadline.weight(.medium))) \(noun_text)", comment: "Sentence composed of 2 variables to describe how many relay servers a user is connected. In source English, the first variable is the number of relay servers, and the second variable is 'Relay' or 'Relays'.") let relay_text = Text("\(Text(verbatim: relays.keys.count.formatted()).font(.subheadline.weight(.medium))) \(noun_text)", comment: "Sentence composed of 2 variables to describe how many relay servers a user is connected. In source English, the first variable is the number of relay servers, and the second variable is 'Relay' or 'Relays'.")
if profile.pubkey == damus_state.pubkey && damus_state.is_privkey_user { if profile.pubkey == damus_state.pubkey && damus_state.is_privkey_user {
NavigationLink(value: Route.RelayConfig(damusState: damus_state)) { NavigationLink(value: Route.RelayConfig) {
relay_text relay_text
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())
} else { } else {
NavigationLink(value: Route.UserRelays(damusState: damus_state, relays: Array(relays.keys).sorted())) { NavigationLink(value: Route.UserRelays(relays: Array(relays.keys).sorted())) {
relay_text relay_text
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())

View File

@@ -72,7 +72,9 @@ struct RelayDetailView: View {
if let pubkey = nip11.pubkey { if let pubkey = nip11.pubkey {
Section(NSLocalizedString("Admin", comment: "Label to display relay contact user.")) { Section(NSLocalizedString("Admin", comment: "Label to display relay contact user.")) {
NavigationLink(value: Route.ProfileByKey(pubkey: pubkey), label: {
UserViewRow(damus_state: state, pubkey: pubkey) UserViewRow(damus_state: state, pubkey: pubkey)
})
} }
} }
if let relay_connection { if let relay_connection {

View File

@@ -30,8 +30,9 @@ struct RelayView: View {
if let meta = state.relay_metadata.lookup(relay_id: relay) { if let meta = state.relay_metadata.lookup(relay_id: relay) {
Text(relay) Text(relay)
.background( .background(
NavigationLink("", destination: RelayDetailView(state: state, relay: relay, nip11: meta)).opacity(0.0) NavigationLink(value: Route.RelayDetail(relay: relay, metadata: meta), label: {
.disabled(showActionButtons) EmptyView()
}).opacity(0.0).disabled(showActionButtons)
) )
Spacer() Spacer()

View File

@@ -14,7 +14,7 @@ struct SignalView: View {
var body: some View { var body: some View {
Group { Group {
if signal.signal != signal.max_signal { if signal.signal != signal.max_signal {
NavigationLink(destination: RelayConfigView(state: state)) { NavigationLink(value: Route.RelayConfig) {
Text("\(signal.signal)/\(signal.max_signal)", comment: "Fraction of how many of the user's relay servers that are operational.") Text("\(signal.signal)/\(signal.max_signal)", comment: "Fraction of how many of the user's relay servers that are operational.")
.font(.callout) .font(.callout)
.foregroundColor(.gray) .foregroundColor(.gray)

View File

@@ -16,9 +16,8 @@ struct RepostedEvent: View {
var body: some View { var body: some View {
VStack(alignment: .leading) { VStack(alignment: .leading) {
let prof = damus.profiles.lookup(id: event.pubkey) let prof = damus.profiles.lookup(id: event.pubkey)
let booster_profile = ProfileView(damus_state: damus, pubkey: event.pubkey)
NavigationLink(destination: booster_profile) { NavigationLink(value: Route.ProfileByKey(pubkey: event.pubkey)) {
Reposted(damus: damus, pubkey: event.pubkey, profile: prof) Reposted(damus: damus, pubkey: event.pubkey, profile: prof)
.padding(.horizontal) .padding(.horizontal)
} }

View File

@@ -100,14 +100,12 @@ struct SearchingEventView: View {
.progressViewStyle(.circular) .progressViewStyle(.circular)
} }
case .found(let ev): case .found(let ev):
NavigationLink(destination: ThreadView(state: state, thread: ThreadModel(event: ev, damus_state: state))) { NavigationLink(value: Route.Thread(thread: ThreadModel(event: ev, damus_state: state))) {
EventView(damus: state, event: ev) EventView(damus: state, event: ev)
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())
case .found_profile(let pk): case .found_profile(let pk):
NavigationLink(destination: ProfileView(damus_state: state, pubkey: pk)) { NavigationLink(value: Route.ProfileByKey(pubkey: pk)) {
FollowUserView(target: .pubkey(pk), damus_state: state) FollowUserView(target: .pubkey(pk), damus_state: state)
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())

View File

@@ -44,8 +44,7 @@ struct InnerSearchResults: View {
func HashtagSearch(_ ht: String) -> some View { func HashtagSearch(_ ht: String) -> some View {
let search_model = SearchModel(state: damus_state, search: .filter_hashtag([ht])) let search_model = SearchModel(state: damus_state, search: .filter_hashtag([ht]))
let dst = SearchView(appstate: damus_state, search: search_model) return NavigationLink(value: Route.Search(search: search_model)) {
return NavigationLink(destination: dst) {
Text("Search hashtag: #\(ht)", comment: "Navigation link to search hashtag.") Text("Search hashtag: #\(ht)", comment: "Navigation link to search hashtag.")
} }
} }

View File

@@ -45,7 +45,7 @@ struct SideMenuView: View {
func SidemenuItems(profile_model: ProfileModel, followers: FollowersModel) -> some View { func SidemenuItems(profile_model: ProfileModel, followers: FollowersModel) -> some View {
return VStack(spacing: verticalSpacing) { return VStack(spacing: verticalSpacing) {
NavigationLink(value: Route.Profile(damusSate: damus_state, profile: profile_model, followers: followers)) { NavigationLink(value: Route.Profile(profile: profile_model, followers: followers)) {
navLabel(title: NSLocalizedString("Profile", comment: "Sidebar menu label for Profile view."), img: "user") navLabel(title: NSLocalizedString("Profile", comment: "Sidebar menu label for Profile view."), img: "user")
} }
@@ -64,19 +64,19 @@ struct SideMenuView: View {
}*/ }*/
} }
NavigationLink(value: Route.MuteList(damusState: damus_state, users: get_mutelist_users(damus_state.contacts.mutelist))) { NavigationLink(value: Route.MuteList(users: get_mutelist_users(damus_state.contacts.mutelist))) {
navLabel(title: NSLocalizedString("Muted", comment: "Sidebar menu label for muted users view."), img: "mute") navLabel(title: NSLocalizedString("Muted", comment: "Sidebar menu label for muted users view."), img: "mute")
} }
NavigationLink(value: Route.RelayConfig(damusState: damus_state)) { NavigationLink(value: Route.RelayConfig) {
navLabel(title: NSLocalizedString("Relays", comment: "Sidebar menu label for Relays view."), img: "world-relays") navLabel(title: NSLocalizedString("Relays", comment: "Sidebar menu label for Relays view."), img: "world-relays")
} }
NavigationLink(value: Route.Bookmarks(damusState: damus_state)) { NavigationLink(value: Route.Bookmarks) {
navLabel(title: NSLocalizedString("Bookmarks", comment: "Sidebar menu label for Bookmarks view."), img: "bookmark") navLabel(title: NSLocalizedString("Bookmarks", comment: "Sidebar menu label for Bookmarks view."), img: "bookmark")
} }
NavigationLink(value: Route.Config(damusState: damus_state)) { NavigationLink(value: Route.Config) {
navLabel(title: NSLocalizedString("Settings", comment: "Sidebar menu label for accessing the app settings"), img: "settings") navLabel(title: NSLocalizedString("Settings", comment: "Sidebar menu label for accessing the app settings"), img: "settings")
} }
} }
@@ -88,8 +88,7 @@ struct SideMenuView: View {
let followers = FollowersModel(damus_state: damus_state, target: damus_state.pubkey) let followers = FollowersModel(damus_state: damus_state, target: damus_state.pubkey)
let profile_model = ProfileModel(pubkey: damus_state.pubkey, damus: damus_state) let profile_model = ProfileModel(pubkey: damus_state.pubkey, damus: damus_state)
NavigationLink(destination: ProfileView(damus_state: damus_state, profile: profile_model, followers: followers)) { NavigationLink(value: Route.Profile(profile: profile_model, followers: followers), label: {
HStack { HStack {
ProfilePicView(pubkey: damus_state.pubkey, size: 60, highlight: .none, profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation) ProfilePicView(pubkey: damus_state.pubkey, size: 60, highlight: .none, profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation)
@@ -109,7 +108,7 @@ struct SideMenuView: View {
} }
} }
.padding(.bottom, verticalSpacing) .padding(.bottom, verticalSpacing)
} })
Divider() Divider()