This commit integrates the Damus Purple translation service: - Automatically handles translation settings change after purchase - Asks for permission to override translation settings if the user already has translation setup - Translation settings can be changed with Damus Purple, if desired - Translation requests working with the Damus API server Testing -------- PASS Device: iPhone 15 simulator iOS: 17.2 Damus: This commit Damus Purple API server: `9397201d7d55ddcec4c18fcd337f759b61dce697` running on Ubuntu 22.04 LTS VM (npm run dev) iOS setting: English set as the only preferred language. Steps: 1. Enable Damus Purple feature flag on developer settings, set purple localhost mode, and restart app 2. Set translation setting to something other than none (e.g. DeepL) 3. Simulate Damus Purple purchase 4. Check that when dismissing welcome view, a confirmation prompt will ask the user whether they want to switch translator to Damus Purple. PASS 5. Click "Yes". 6. Go to translation settings. Check that translation settings are set to "Purple". PASS 7. Go to a non-English profile. Check that translations appear with "Mock translation" (Which is the translation text provided by the mock translation server). PASS 8. Reinstall app 9. Repeat the test, but this time starting with no translation settings. Make sure that translation settings will automatically switch to Damus Purple. PASS Feature flag testing -------------------- PASS Preconditions: Same as above Steps: 1. Turn off translation 2. Turn off Damus Purple feature flag 3. Go to translation settings. Make sure that Damus Purple is not an option. PASS Closes: https://github.com/damus-io/damus/issues/1836 Signed-off-by: Daniel D’Aquino <daniel@daquino.me> Reviewed-by: William Casarin <jb55@jb55.com> Signed-off-by: William Casarin <jb55@jb55.com>
246 lines
9.5 KiB
Swift
246 lines
9.5 KiB
Swift
//
|
|
// SideMenuView.swift
|
|
// damus
|
|
//
|
|
// Created by Ben Weeks on 1/6/23.
|
|
// Ref: https://blog.logrocket.com/create-custom-collapsible-sidebar-swiftui/
|
|
|
|
import SwiftUI
|
|
|
|
@MainActor
|
|
struct SideMenuView: View {
|
|
let damus_state: DamusState
|
|
@Binding var isSidebarVisible: Bool
|
|
@State var confirm_logout: Bool = false
|
|
@State private var showQRCode = false
|
|
|
|
@Environment(\.colorScheme) var colorScheme
|
|
|
|
var sideBarWidth = min(UIScreen.main.bounds.size.width * 0.65, 400.0)
|
|
let verticalSpacing: CGFloat = 20
|
|
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 {
|
|
ZStack {
|
|
GeometryReader { _ in
|
|
EmptyView()
|
|
}
|
|
.background(DamusColors.darkGrey.opacity(0.6))
|
|
.opacity(isSidebarVisible ? 1 : 0)
|
|
.animation(.default, value: isSidebarVisible)
|
|
.onTapGesture {
|
|
isSidebarVisible.toggle()
|
|
}
|
|
|
|
content
|
|
}
|
|
}
|
|
|
|
func SidemenuItems(profile_model: ProfileModel, followers: FollowersModel) -> some View {
|
|
return VStack(spacing: verticalSpacing) {
|
|
NavigationLink(value: Route.Profile(profile: profile_model, followers: followers)) {
|
|
navLabel(title: NSLocalizedString("Profile", comment: "Sidebar menu label for Profile view."), img: "user")
|
|
}
|
|
|
|
NavigationLink(value: Route.Wallet(wallet: damus_state.wallet)) {
|
|
navLabel(title: NSLocalizedString("Wallet", comment: "Sidebar menu label for Wallet view."), img: "wallet")
|
|
}
|
|
|
|
if damus_state.settings.enable_experimental_purple_api {
|
|
NavigationLink(destination: DamusPurpleView(damus_state: damus_state)) {
|
|
HStack(spacing: 13) {
|
|
Image("nostr-hashtag")
|
|
Text("Purple")
|
|
.foregroundColor(DamusColors.purple)
|
|
.font(.title2.weight(.bold))
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
}
|
|
}
|
|
|
|
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")
|
|
}
|
|
|
|
NavigationLink(value: Route.RelayConfig) {
|
|
navLabel(title: NSLocalizedString("Relays", comment: "Sidebar menu label for Relays view."), img: "world-relays")
|
|
}
|
|
|
|
NavigationLink(value: Route.Bookmarks) {
|
|
navLabel(title: NSLocalizedString("Bookmarks", comment: "Sidebar menu label for Bookmarks view."), img: "bookmark")
|
|
}
|
|
|
|
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")
|
|
}
|
|
|
|
NavigationLink(value: Route.Config) {
|
|
navLabel(title: NSLocalizedString("Settings", comment: "Sidebar menu label for accessing the app settings"), img: "settings")
|
|
}
|
|
}
|
|
}
|
|
|
|
var TopProfile: some View {
|
|
let profile_txn = damus_state.profiles.lookup(id: damus_state.pubkey)
|
|
let profile = profile_txn.unsafeUnownedValue
|
|
return VStack(alignment: .leading, spacing: verticalSpacing) {
|
|
HStack {
|
|
ProfilePicView(pubkey: damus_state.pubkey, size: 60, highlight: .none, profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation)
|
|
|
|
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(DamusColors.mediumGrey)
|
|
.font(.body)
|
|
.lineLimit(1)
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
var MainSidemenu: some View {
|
|
VStack(alignment: .leading, spacing: 0) {
|
|
let followers = FollowersModel(damus_state: damus_state, target: damus_state.pubkey)
|
|
let profile_model = ProfileModel(pubkey: damus_state.pubkey, damus: damus_state)
|
|
|
|
NavigationLink(value: Route.Profile(profile: profile_model, followers: followers), label: {
|
|
|
|
TopProfile
|
|
.padding(.bottom, verticalSpacing)
|
|
})
|
|
|
|
Divider()
|
|
|
|
ScrollView {
|
|
SidemenuItems(profile_model: profile_model, followers: followers)
|
|
.labelStyle(SideMenuLabelStyle())
|
|
.padding([.top, .bottom], verticalSpacing)
|
|
}
|
|
}
|
|
}
|
|
|
|
var content: some View {
|
|
HStack(alignment: .top) {
|
|
ZStack(alignment: .top) {
|
|
fillColor()
|
|
.ignoresSafeArea()
|
|
|
|
VStack(alignment: .leading, spacing: 0) {
|
|
MainSidemenu
|
|
.simultaneousGesture(TapGesture().onEnded {
|
|
isSidebarVisible = false
|
|
})
|
|
|
|
Divider()
|
|
|
|
HStack() {
|
|
Button(action: {
|
|
//ConfigView(state: damus_state)
|
|
if damus_state.keypair.privkey == nil {
|
|
notify(.logout)
|
|
} 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, -(padding / 2.0))
|
|
.padding([.leading, .trailing, .bottom], padding)
|
|
}
|
|
.frame(width: sideBarWidth)
|
|
.offset(x: isSidebarVisible ? 0 : -(sideBarWidth + padding))
|
|
.animation(.default, value: isSidebarVisible)
|
|
.alert("Logout", isPresented: $confirm_logout) {
|
|
Button(NSLocalizedString("Cancel", comment: "Cancel out of logging out the user."), role: .cancel) {
|
|
confirm_logout = false
|
|
}
|
|
Button(NSLocalizedString("Logout", comment: "Button for logging out the user."), role: .destructive) {
|
|
notify(.logout)
|
|
}
|
|
} message: {
|
|
Text("Make sure your nsec account key is saved before you logout or you will lose access to this account", comment: "Reminder message in alert to get customer to verify that their private security account key is saved saved before logging out.")
|
|
}
|
|
|
|
Spacer()
|
|
}
|
|
}
|
|
|
|
func navLabel(title: String, img: String) -> some View {
|
|
HStack {
|
|
Image(img)
|
|
.tint(DamusColors.adaptableBlack)
|
|
|
|
Text(title)
|
|
.font(.title2)
|
|
.foregroundColor(textColor())
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.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 {
|
|
static var previews: some View {
|
|
let ds = test_damus_state
|
|
SideMenuView(damus_state: ds, isSidebarVisible: .constant(true))
|
|
}
|
|
}
|