ui: Side menu redesign
This PR redesigns the side menu to more closely match Roberto's design Changelog-Changed: Changed side menu design Signed-off-by: ericholguin <ericholguin@apache.org>
This commit is contained in:
@@ -9,6 +9,7 @@ import SwiftUI
|
|||||||
|
|
||||||
struct PubkeyView: View {
|
struct PubkeyView: View {
|
||||||
let pubkey: Pubkey
|
let pubkey: Pubkey
|
||||||
|
var sidemenu: Bool = false
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
|
||||||
@@ -45,20 +46,21 @@ struct PubkeyView: View {
|
|||||||
let bech32 = pubkey.npub
|
let bech32 = pubkey.npub
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Text(verbatim: "\(abbrev_pubkey(bech32, amount: 16))")
|
Text(verbatim: "\(abbrev_pubkey(bech32, amount: sidemenu ? 12 : 16))")
|
||||||
.font(.footnote)
|
.font(sidemenu ? .system(size: 10) : .footnote)
|
||||||
.foregroundColor(keyColor())
|
.foregroundColor(keyColor())
|
||||||
.padding(5)
|
.padding(5)
|
||||||
.padding([.leading], 5)
|
.padding([.leading], 5)
|
||||||
|
.lineLimit(1)
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
if isCopied {
|
if isCopied {
|
||||||
Image("check-circle")
|
Image("check-circle")
|
||||||
.resizable()
|
.resizable()
|
||||||
.foregroundColor(DamusColors.green)
|
.foregroundColor(DamusColors.green)
|
||||||
.frame(width: 20, height: 20)
|
.frame(width: sidemenu ? 15 : 20, height: sidemenu ? 15 : 20)
|
||||||
Text("Copied", comment: "Label indicating that a user's key was copied.")
|
Text("Copied", comment: "Label indicating that a user's key was copied.")
|
||||||
.font(.footnote)
|
.font(sidemenu ? .system(size: 10) : .footnote)
|
||||||
.layoutPriority(1)
|
.layoutPriority(1)
|
||||||
.foregroundColor(DamusColors.green)
|
.foregroundColor(DamusColors.green)
|
||||||
} else {
|
} else {
|
||||||
@@ -72,7 +74,7 @@ struct PubkeyView: View {
|
|||||||
.resizable()
|
.resizable()
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.foregroundColor(colorScheme == .light ? DamusColors.darkGrey : DamusColors.lightGrey)
|
.foregroundColor(colorScheme == .light ? DamusColors.darkGrey : DamusColors.lightGrey)
|
||||||
.frame(width: 20, height: 20)
|
.frame(width: sidemenu ? 15 : 20, height: sidemenu ? 15 : 20)
|
||||||
}
|
}
|
||||||
.labelStyle(IconOnlyLabelStyle())
|
.labelStyle(IconOnlyLabelStyle())
|
||||||
.symbolRenderingMode(.hierarchical)
|
.symbolRenderingMode(.hierarchical)
|
||||||
|
|||||||
@@ -14,21 +14,11 @@ struct SideMenuView: View {
|
|||||||
@Binding var selected: Timeline
|
@Binding var selected: Timeline
|
||||||
@State var confirm_logout: Bool = false
|
@State var confirm_logout: Bool = false
|
||||||
@State private var showQRCode = false
|
@State private var showQRCode = false
|
||||||
|
|
||||||
@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
|
let verticalSpacing: CGFloat = 25
|
||||||
let padding: CGFloat = 30
|
let padding: CGFloat = 30
|
||||||
|
|
||||||
func fillColor() -> Color {
|
|
||||||
colorScheme == .light ? DamusColors.white : DamusColors.black
|
|
||||||
}
|
|
||||||
|
|
||||||
func textColor() -> Color {
|
|
||||||
colorScheme == .light ? DamusColors.black : DamusColors.white
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
GeometryReader { _ in
|
GeometryReader { _ in
|
||||||
@@ -57,7 +47,7 @@ struct SideMenuView: View {
|
|||||||
|
|
||||||
if damus_state.purple.enable_purple {
|
if damus_state.purple.enable_purple {
|
||||||
NavigationLink(destination: DamusPurpleView(damus_state: damus_state)) {
|
NavigationLink(destination: DamusPurpleView(damus_state: damus_state)) {
|
||||||
HStack(spacing: 13) {
|
HStack(spacing: 23) {
|
||||||
Image("nostr-hashtag")
|
Image("nostr-hashtag")
|
||||||
Text("Purple")
|
Text("Purple")
|
||||||
.foregroundColor(DamusColors.purple)
|
.foregroundColor(DamusColors.purple)
|
||||||
@@ -80,12 +70,22 @@ struct SideMenuView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Link(destination: URL(string: "https://store.damus.io/?ref=damus_ios_app")!) {
|
Link(destination: URL(string: "https://store.damus.io/?ref=damus_ios_app")!) {
|
||||||
navLabel(title: NSLocalizedString("Merch", comment: "Sidebar menu label for merch store link."), img: "basket")
|
navLabel(title: NSLocalizedString("Merch", comment: "Sidebar menu label for merch store link."), img: "shop")
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationLink(value: Route.Config) {
|
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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button(action: {
|
||||||
|
if damus_state.keypair.privkey == nil {
|
||||||
|
logout(damus_state)
|
||||||
|
} else {
|
||||||
|
confirm_logout = true
|
||||||
|
}
|
||||||
|
}, label: {
|
||||||
|
navLabel(title: NSLocalizedString("Logout", comment: "Sidebar menu label to sign out of the account."), img: "logout")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,38 +100,68 @@ struct SideMenuView: View {
|
|||||||
display_name = profile?.display_name
|
display_name = profile?.display_name
|
||||||
}
|
}
|
||||||
|
|
||||||
return VStack(alignment: .leading, spacing: verticalSpacing) {
|
return VStack(alignment: .leading) {
|
||||||
HStack {
|
HStack(spacing: 10) {
|
||||||
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: 50, highlight: .none, profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation)
|
||||||
VStack(alignment: .leading) {
|
|
||||||
|
Spacer()
|
||||||
if let display_name {
|
|
||||||
Text(display_name)
|
Button(action: {
|
||||||
.foregroundColor(textColor())
|
present_sheet(.user_status)
|
||||||
.font(.title)
|
isSidebarVisible = false
|
||||||
.lineLimit(1)
|
}, label: {
|
||||||
}
|
Image("add-reaction")
|
||||||
if let name {
|
.resizable()
|
||||||
|
.frame(width: 25, height: 25)
|
||||||
|
.padding(5)
|
||||||
|
.foregroundColor(DamusColors.adaptableBlack)
|
||||||
|
.background {
|
||||||
|
Circle()
|
||||||
|
.foregroundColor(DamusColors.neutral3)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Button(action: {
|
||||||
|
showQRCode.toggle()
|
||||||
|
isSidebarVisible = false
|
||||||
|
}, label: {
|
||||||
|
Image("qr-code")
|
||||||
|
.resizable()
|
||||||
|
.frame(width: 25, height: 25)
|
||||||
|
.padding(5)
|
||||||
|
.foregroundColor(DamusColors.adaptableBlack)
|
||||||
|
.background {
|
||||||
|
Circle()
|
||||||
|
.foregroundColor(DamusColors.neutral3)
|
||||||
|
}
|
||||||
|
}).fullScreenCover(isPresented: $showQRCode) {
|
||||||
|
QRCodeView(damus_state: damus_state, pubkey: damus_state.pubkey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
|
||||||
|
if let display_name {
|
||||||
|
Text(display_name)
|
||||||
|
.font(.title2.weight(.bold))
|
||||||
|
.foregroundColor(DamusColors.adaptableBlack)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.dynamicTypeSize(.xSmall)
|
||||||
|
.lineLimit(1)
|
||||||
|
}
|
||||||
|
if let name {
|
||||||
|
if !name.isEmpty {
|
||||||
Text("@" + name)
|
Text("@" + name)
|
||||||
.foregroundColor(DamusColors.mediumGrey)
|
.foregroundColor(DamusColors.mediumGrey)
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PubkeyView(pubkey: damus_state.pubkey, sidemenu: true)
|
||||||
|
.pubkey_context_menu(pubkey: damus_state.pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
navLabel(title: NSLocalizedString("Set Status", comment: "Sidebar menu label to set user status"), img: "add-reaction")
|
|
||||||
.font(.title2)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
.dynamicTypeSize(.xSmall)
|
|
||||||
.onTapGesture {
|
|
||||||
present_sheet(.user_status)
|
|
||||||
}
|
|
||||||
|
|
||||||
UserStatusView(status: damus_state.profiles.profile_data(damus_state.pubkey).status, show_general: true, show_music: true)
|
|
||||||
.dynamicTypeSize(.xSmall)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,68 +171,28 @@ struct SideMenuView: View {
|
|||||||
let profile_model = ProfileModel(pubkey: damus_state.pubkey, damus: damus_state)
|
let profile_model = ProfileModel(pubkey: damus_state.pubkey, damus: damus_state)
|
||||||
|
|
||||||
NavigationLink(value: Route.Profile(profile: profile_model, followers: followers), label: {
|
NavigationLink(value: Route.Profile(profile: profile_model, followers: followers), label: {
|
||||||
|
|
||||||
TopProfile
|
TopProfile
|
||||||
.padding(.bottom, verticalSpacing)
|
.padding(.bottom, verticalSpacing)
|
||||||
})
|
})
|
||||||
|
|
||||||
Divider()
|
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
SidemenuItems(profile_model: profile_model, followers: followers)
|
SidemenuItems(profile_model: profile_model, followers: followers)
|
||||||
.labelStyle(SideMenuLabelStyle())
|
.simultaneousGesture(TapGesture().onEnded {
|
||||||
.padding([.top, .bottom], verticalSpacing)
|
isSidebarVisible = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
.scrollIndicators(.hidden)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var content: some View {
|
var content: some View {
|
||||||
HStack(alignment: .top) {
|
HStack(alignment: .top) {
|
||||||
ZStack(alignment: .top) {
|
ZStack(alignment: .top) {
|
||||||
fillColor()
|
DamusColors.adaptableWhite
|
||||||
.ignoresSafeArea()
|
.ignoresSafeArea()
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
MainSidemenu
|
||||||
MainSidemenu
|
.padding([.leading, .trailing], padding)
|
||||||
.simultaneousGesture(TapGesture().onEnded {
|
|
||||||
isSidebarVisible = false
|
|
||||||
})
|
|
||||||
|
|
||||||
Divider()
|
|
||||||
|
|
||||||
HStack() {
|
|
||||||
Button(action: {
|
|
||||||
//ConfigView(state: damus_state)
|
|
||||||
if damus_state.keypair.privkey == nil {
|
|
||||||
logout(damus_state)
|
|
||||||
} else {
|
|
||||||
confirm_logout = true
|
|
||||||
}
|
|
||||||
}, label: {
|
|
||||||
Label(NSLocalizedString("Sign out", comment: "Sidebar menu label to sign out of the account."), image: "logout")
|
|
||||||
.font(.title3)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
.dynamicTypeSize(.xSmall)
|
|
||||||
})
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
Button(action: {
|
|
||||||
showQRCode.toggle()
|
|
||||||
}, label: {
|
|
||||||
Image("qr-code")
|
|
||||||
.font(.title)
|
|
||||||
.foregroundColor(textColor())
|
|
||||||
.dynamicTypeSize(.xSmall)
|
|
||||||
}).fullScreenCover(isPresented: $showQRCode) {
|
|
||||||
QRCodeView(damus_state: damus_state, pubkey: damus_state.pubkey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.padding(.top, verticalSpacing)
|
|
||||||
}
|
|
||||||
.padding(.top, selected != .home ? -(padding / 2.0) : 30)
|
|
||||||
.padding([.leading, .trailing, .bottom], padding)
|
|
||||||
}
|
}
|
||||||
.frame(width: sideBarWidth)
|
.frame(width: sideBarWidth)
|
||||||
.offset(x: isSidebarVisible ? 0 : -(sideBarWidth + padding))
|
.offset(x: isSidebarVisible ? 0 : -(sideBarWidth + padding))
|
||||||
@@ -223,28 +213,17 @@ struct SideMenuView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func navLabel(title: String, img: String) -> some View {
|
func navLabel(title: String, img: String) -> some View {
|
||||||
HStack {
|
HStack(spacing: 20) {
|
||||||
Image(img)
|
Image(img)
|
||||||
.tint(DamusColors.adaptableBlack)
|
.tint(DamusColors.adaptableBlack)
|
||||||
|
|
||||||
Text(title)
|
Text(title)
|
||||||
.font(.title2)
|
.font(.title2.weight(.bold))
|
||||||
.foregroundColor(textColor())
|
.foregroundColor(DamusColors.adaptableBlack)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.dynamicTypeSize(.xSmall)
|
.dynamicTypeSize(.xSmall)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SideMenuLabelStyle: LabelStyle {
|
|
||||||
func makeBody(configuration: Configuration) -> some View {
|
|
||||||
HStack(alignment: .center, spacing: 8) {
|
|
||||||
configuration.icon
|
|
||||||
.frame(width: 24, height: 24)
|
|
||||||
.aspectRatio(contentMode: .fit)
|
|
||||||
configuration.title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Previews_SideMenuView_Previews: PreviewProvider {
|
struct Previews_SideMenuView_Previews: PreviewProvider {
|
||||||
|
|||||||
Reference in New Issue
Block a user