Refactor side menu
Changelog-Fixed: Fix sidebar navigation bugs Closes: #460
This commit is contained in:
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Starscream
|
import Starscream
|
||||||
import Kingfisher
|
|
||||||
|
|
||||||
var BOOTSTRAP_RELAYS = [
|
var BOOTSTRAP_RELAYS = [
|
||||||
"wss://relay.damus.io",
|
"wss://relay.damus.io",
|
||||||
@@ -144,6 +143,29 @@ struct ContentView: View {
|
|||||||
search_open = false
|
search_open = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var timelineNavItem: some View {
|
||||||
|
VStack {
|
||||||
|
switch selected_timeline {
|
||||||
|
case .home:
|
||||||
|
Image("damus-home")
|
||||||
|
.resizable()
|
||||||
|
.frame(width:30,height:30)
|
||||||
|
.shadow(color: Color("DamusPurple"), radius: 2)
|
||||||
|
case .dms:
|
||||||
|
Text("DMs", comment: "Toolbar label for DMs view, where DM is the English abbreviation for Direct Message.")
|
||||||
|
.bold()
|
||||||
|
case .notifications:
|
||||||
|
Text("Notifications", comment: "Toolbar label for Notifications view.")
|
||||||
|
.bold()
|
||||||
|
case .search:
|
||||||
|
Text("Global", comment: "Toolbar label for Global view where posts from all connected relay servers appear.")
|
||||||
|
.bold()
|
||||||
|
case .none:
|
||||||
|
Text("", comment: "Toolbar label for unknown views. This label would be displayed only if a new timeline view is added but a toolbar label was not explicitly assigned to it yet.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func MainContent(damus: DamusState) -> some View {
|
func MainContent(damus: DamusState) -> some View {
|
||||||
VStack {
|
VStack {
|
||||||
NavigationLink(destination: MaybeProfileView, isActive: $profile_open) {
|
NavigationLink(destination: MaybeProfileView, isActive: $profile_open) {
|
||||||
@@ -163,9 +185,10 @@ struct ContentView: View {
|
|||||||
PostingTimelineView
|
PostingTimelineView
|
||||||
|
|
||||||
case .notifications:
|
case .notifications:
|
||||||
TimelineView(events: $home.notifications, loading: $home.loading, damus: damus, show_friend_icon: true, filter: { _ in true })
|
VStack(spacing: 0) {
|
||||||
.navigationTitle(NSLocalizedString("Notifications", comment: "Navigation title for notifications."))
|
Divider()
|
||||||
|
TimelineView(events: $home.notifications, loading: $home.loading, damus: damus, show_friend_icon: true, filter: { _ in true })
|
||||||
|
}
|
||||||
case .dms:
|
case .dms:
|
||||||
DirectMessagesView(damus_state: damus_state!)
|
DirectMessagesView(damus_state: damus_state!)
|
||||||
.environmentObject(home.dms)
|
.environmentObject(home.dms)
|
||||||
@@ -177,24 +200,9 @@ struct ContentView: View {
|
|||||||
.navigationBarTitle(selected_timeline == .home ? NSLocalizedString("Home", comment: "Navigation bar title for Home view where posts and replies appear from those who the user is following.") : NSLocalizedString("Global", comment: "Navigation bar title for Global view where posts from all connected relay servers appear."), displayMode: .inline)
|
.navigationBarTitle(selected_timeline == .home ? NSLocalizedString("Home", comment: "Navigation bar title for Home view where posts and replies appear from those who the user is following.") : NSLocalizedString("Global", comment: "Navigation bar title for Global view where posts from all connected relay servers appear."), displayMode: .inline)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .principal) {
|
ToolbarItem(placement: .principal) {
|
||||||
switch selected_timeline {
|
timelineNavItem
|
||||||
case .home:
|
.opacity(isSideBarOpened ? 0 : 1)
|
||||||
Image("damus-home")
|
.animation(isSideBarOpened ? .none : .default, value: isSideBarOpened)
|
||||||
.resizable()
|
|
||||||
.frame(width:30,height:30)
|
|
||||||
.shadow(color: Color("DamusPurple"), radius: 2)
|
|
||||||
case .dms:
|
|
||||||
Text("DMs", comment: "Toolbar label for DMs view, where DM is the English abbreviation for Direct Message.")
|
|
||||||
.bold()
|
|
||||||
case .notifications:
|
|
||||||
Text("Notifications", comment: "Toolbar label for Notifications view.")
|
|
||||||
.bold()
|
|
||||||
case .search:
|
|
||||||
Text("Global", comment: "Toolbar label for Global view where posts from all connected relay servers appear.")
|
|
||||||
.bold()
|
|
||||||
case .none:
|
|
||||||
Text("", comment: "Toolbar label for unknown views. This label would be displayed only if a new timeline view is added but a toolbar label was not explicitly assigned to it yet.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ignoresSafeArea(.keyboard)
|
.ignoresSafeArea(.keyboard)
|
||||||
@@ -251,7 +259,7 @@ struct ContentView: View {
|
|||||||
if let damus = self.damus_state {
|
if let damus = self.damus_state {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
ZStack {
|
ZStack {
|
||||||
VStack {
|
TabView { // Prevents navbar appearance change on scroll
|
||||||
MainContent(damus: damus)
|
MainContent(damus: damus)
|
||||||
.toolbar() {
|
.toolbar() {
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
ToolbarItem(placement: .navigationBarLeading) {
|
||||||
@@ -259,7 +267,10 @@ struct ContentView: View {
|
|||||||
isSideBarOpened.toggle()
|
isSideBarOpened.toggle()
|
||||||
} label: {
|
} label: {
|
||||||
ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles)
|
ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles)
|
||||||
|
.opacity(isSideBarOpened ? 0 : 1)
|
||||||
|
.animation(isSideBarOpened ? .none : .default, value: isSideBarOpened)
|
||||||
}
|
}
|
||||||
|
.disabled(isSideBarOpened)
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
@@ -275,15 +286,12 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.tabViewStyle(.page(indexDisplayMode: .never))
|
||||||
Color.clear
|
|
||||||
.overlay(
|
|
||||||
SideMenuView(damus_state: damus, isSidebarVisible: $isSideBarOpened)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
.navigationBarHidden(isSideBarOpened ? true: false) // Would prefer a different way of doing this.
|
.overlay(
|
||||||
|
SideMenuView(damus_state: damus, isSidebarVisible: $isSideBarOpened.animation())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
.navigationViewStyle(.stack)
|
.navigationViewStyle(.stack)
|
||||||
|
|
||||||
@@ -293,7 +301,6 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
.onAppear() {
|
.onAppear() {
|
||||||
self.connect()
|
self.connect()
|
||||||
//KingfisherManager.shared.cache.clearDiskCache()
|
|
||||||
setup_notifications()
|
setup_notifications()
|
||||||
}
|
}
|
||||||
.sheet(item: $active_sheet) { item in
|
.sheet(item: $active_sheet) { item in
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ struct SideMenuView: View {
|
|||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
|
||||||
var sideBarWidth = min(UIScreen.main.bounds.size.width * 0.65, 400.0)
|
var sideBarWidth = min(UIScreen.main.bounds.size.width * 0.65, 400.0)
|
||||||
|
let verticalSpacing: CGFloat = 20
|
||||||
|
|
||||||
func fillColor() -> Color {
|
func fillColor() -> Color {
|
||||||
colorScheme == .light ? Color("DamusWhite") : Color("DamusBlack")
|
colorScheme == .light ? Color("DamusWhite") : Color("DamusBlack")
|
||||||
@@ -33,104 +34,86 @@ struct SideMenuView: View {
|
|||||||
}
|
}
|
||||||
.background(Color("DamusDarkGrey").opacity(0.6))
|
.background(Color("DamusDarkGrey").opacity(0.6))
|
||||||
.opacity(isSidebarVisible ? 1 : 0)
|
.opacity(isSidebarVisible ? 1 : 0)
|
||||||
.animation(.easeInOut.delay(0.2), value: isSidebarVisible)
|
.animation(.default, value: isSidebarVisible)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
isSidebarVisible.toggle()
|
isSidebarVisible.toggle()
|
||||||
}
|
}
|
||||||
content
|
content
|
||||||
}
|
}
|
||||||
.edgesIgnoringSafeArea(.all)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var content: some View {
|
var content: some View {
|
||||||
HStack(alignment: .top) {
|
HStack(alignment: .top) {
|
||||||
ZStack(alignment: .top) {
|
ZStack(alignment: .top) {
|
||||||
fillColor()
|
fillColor()
|
||||||
|
.ignoresSafeArea()
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 20) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
let profile = damus_state.profiles.lookup(id: 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)
|
|
||||||
|
|
||||||
NavigationLink(destination: ProfileView(damus_state: damus_state, profile: profile_model, followers: followers)) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
if let picture = damus_state.profiles.lookup(id: damus_state.pubkey)?.picture {
|
let profile = damus_state.profiles.lookup(id: damus_state.pubkey)
|
||||||
ProfilePicView(pubkey: damus_state.pubkey, size: 60, highlight: .none, profiles: damus_state.profiles, picture: picture)
|
let followers = FollowersModel(damus_state: damus_state, target: damus_state.pubkey)
|
||||||
} else {
|
let profile_model = ProfileModel(pubkey: damus_state.pubkey, damus: damus_state)
|
||||||
Image(systemName: "person.fill")
|
|
||||||
|
NavigationLink(destination: ProfileView(damus_state: damus_state, profile: profile_model, followers: followers)) {
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
ProfilePicView(pubkey: damus_state.pubkey, size: 60, highlight: .none, profiles: damus_state.profiles)
|
||||||
|
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
if let display_name = profile?.display_name {
|
||||||
|
Text(display_name)
|
||||||
|
.foregroundColor(textColor())
|
||||||
|
.font(.title)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
if let name = profile?.name {
|
||||||
|
Text("@" + name)
|
||||||
|
.foregroundColor(Color("DamusMediumGrey"))
|
||||||
|
.font(.body)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.bottom, verticalSpacing)
|
||||||
}
|
}
|
||||||
VStack(alignment: .leading) {
|
|
||||||
if let display_name = profile?.display_name {
|
Divider()
|
||||||
Text(display_name)
|
|
||||||
.foregroundColor(textColor())
|
ScrollView {
|
||||||
.font(.title)
|
VStack(spacing: verticalSpacing) {
|
||||||
}
|
NavigationLink(destination: ProfileView(damus_state: damus_state, profile: profile_model, followers: followers)) {
|
||||||
if let name = profile?.name {
|
navLabel(title: NSLocalizedString("Profile", comment: "Sidebar menu label for Profile view."), systemImage: "person")
|
||||||
Text("@" + name)
|
}
|
||||||
.foregroundColor(Color("DamusMediumGrey"))
|
|
||||||
.font(.body)
|
/*
|
||||||
|
NavigationLink(destination: EmptyView()) {
|
||||||
|
navLabel(title: NSLocalizedString("Wallet", comment: "Sidebar menu label for Wallet view."), systemImage: "bolt")
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
NavigationLink(destination: MutelistView(damus_state: damus_state, users: get_mutelist_users(damus_state.contacts.mutelist) )) {
|
||||||
|
navLabel(title: NSLocalizedString("Blocked", comment: "Sidebar menu label for Profile view."), systemImage: "exclamationmark.octagon")
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationLink(destination: RelayConfigView(state: damus_state)) {
|
||||||
|
navLabel(title: NSLocalizedString("Relays", comment: "Sidebar menu label for Relays view."), systemImage: "network")
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationLink(destination: ConfigView(state: damus_state)) {
|
||||||
|
navLabel(title: NSLocalizedString("Settings", comment: "Sidebar menu label for accessing the app settings"), systemImage: "gear")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.padding([.top, .bottom], verticalSpacing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.simultaneousGesture(TapGesture().onEnded {
|
||||||
|
isSidebarVisible = false
|
||||||
|
})
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
.padding(.trailing,40)
|
|
||||||
|
|
||||||
NavigationLink(destination: ProfileView(damus_state: damus_state, profile: profile_model, followers: followers)) {
|
HStack() {
|
||||||
Label(NSLocalizedString("Profile", comment: "Sidebar menu label for Profile view."), systemImage: "person")
|
|
||||||
.font(.title2)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
}
|
|
||||||
.simultaneousGesture(TapGesture().onEnded {
|
|
||||||
isSidebarVisible = false
|
|
||||||
})
|
|
||||||
|
|
||||||
/*
|
|
||||||
NavigationLink(destination: EmptyView()) {
|
|
||||||
Label(NSLocalizedString("Relays", comment: "Sidebar menu label for Relay servers view"), systemImage: "xserve")
|
|
||||||
.font(.title2)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
}
|
|
||||||
.simultaneousGesture(TapGesture().onEnded {
|
|
||||||
isSidebarVisible.toggle()
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
NavigationLink(destination: EmptyView()) {
|
|
||||||
Label(NSLocalizedString("Wallet", comment: "Sidebar menu label for Wallet view."), systemImage: "bolt")
|
|
||||||
.font(.title2)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
}
|
|
||||||
.simultaneousGesture(TapGesture().onEnded {
|
|
||||||
isSidebarVisible.toggle()
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
NavigationLink(destination: MutelistView(damus_state: damus_state, users: get_mutelist_users(damus_state.contacts.mutelist) )) {
|
|
||||||
Label(NSLocalizedString("Blocked", comment: "Sidebar menu label for Profile view."), systemImage: "exclamationmark.octagon")
|
|
||||||
.font(.title2)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
}
|
|
||||||
|
|
||||||
NavigationLink(destination: RelayConfigView(state: damus_state)) {
|
|
||||||
Label(NSLocalizedString("Relays", comment: "Sidebar menu label for Relays view."), systemImage: "network")
|
|
||||||
.font(.title2)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
}
|
|
||||||
|
|
||||||
NavigationLink(destination: ConfigView(state: damus_state)) {
|
|
||||||
Label(NSLocalizedString("Settings", comment: "Sidebar menu label for accessing the app settings"), systemImage: "gear")
|
|
||||||
.font(.title2)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
}
|
|
||||||
.simultaneousGesture(TapGesture().onEnded {
|
|
||||||
isSidebarVisible = false
|
|
||||||
})
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
HStack(alignment: .center) {
|
|
||||||
Button(action: {
|
Button(action: {
|
||||||
//ConfigView(state: damus_state)
|
//ConfigView(state: damus_state)
|
||||||
if damus_state.keypair.privkey == nil {
|
if damus_state.keypair.privkey == nil {
|
||||||
@@ -142,6 +125,7 @@ struct SideMenuView: View {
|
|||||||
Label(NSLocalizedString("Sign out", comment: "Sidebar menu label to sign out of the account."), systemImage: "pip.exit")
|
Label(NSLocalizedString("Sign out", comment: "Sidebar menu label to sign out of the account."), systemImage: "pip.exit")
|
||||||
.font(.title3)
|
.font(.title3)
|
||||||
.foregroundColor(textColor())
|
.foregroundColor(textColor())
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
})
|
})
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
@@ -152,22 +136,18 @@ struct SideMenuView: View {
|
|||||||
Label(NSLocalizedString("", comment: "Sidebar menu label for accessing QRCode view"), systemImage: "qrcode")
|
Label(NSLocalizedString("", comment: "Sidebar menu label for accessing QRCode view"), systemImage: "qrcode")
|
||||||
.font(.title)
|
.font(.title)
|
||||||
.foregroundColor(textColor())
|
.foregroundColor(textColor())
|
||||||
.padding(.trailing, 20)
|
|
||||||
}).fullScreenCover(isPresented: $showQRCode) {
|
}).fullScreenCover(isPresented: $showQRCode) {
|
||||||
QRCodeView(damus_state: damus_state)
|
QRCodeView(damus_state: damus_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.top, verticalSpacing)
|
||||||
}
|
}
|
||||||
.padding(.top, 60)
|
.padding(.top, -15)
|
||||||
.padding(.bottom, 40)
|
.padding([.leading, .trailing, .bottom], 30)
|
||||||
.padding(.leading, 40)
|
|
||||||
}
|
}
|
||||||
.frame(width: sideBarWidth)
|
.frame(width: sideBarWidth)
|
||||||
.offset(x: isSidebarVisible ? 0 : -sideBarWidth)
|
.offset(x: isSidebarVisible ? 0 : -sideBarWidth)
|
||||||
.animation(.default, value: isSidebarVisible)
|
.animation(.default, value: isSidebarVisible)
|
||||||
.onTapGesture {
|
|
||||||
isSidebarVisible.toggle()
|
|
||||||
}
|
|
||||||
.alert("Logout", isPresented: $confirm_logout) {
|
.alert("Logout", isPresented: $confirm_logout) {
|
||||||
Button(NSLocalizedString("Cancel", comment: "Cancel out of logging out the user."), role: .cancel) {
|
Button(NSLocalizedString("Cancel", comment: "Cancel out of logging out the user."), role: .cancel) {
|
||||||
confirm_logout = false
|
confirm_logout = false
|
||||||
@@ -182,6 +162,15 @@ struct SideMenuView: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
func navLabel(title: String, systemImage: String) -> some View {
|
||||||
|
Label(title, systemImage: systemImage)
|
||||||
|
.font(.title2)
|
||||||
|
.foregroundColor(textColor())
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Previews_SideMenuView_Previews: PreviewProvider {
|
struct Previews_SideMenuView_Previews: PreviewProvider {
|
||||||
|
|||||||
Reference in New Issue
Block a user