diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj index 7a4488d8..b02738b7 100644 --- a/damus.xcodeproj/project.pbxproj +++ b/damus.xcodeproj/project.pbxproj @@ -543,6 +543,18 @@ 5CB017312D4422DB00A9ED05 /* NWCSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB017302D4422D600A9ED05 /* NWCSettings.swift */; }; 5CB017322D4422DB00A9ED05 /* NWCSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB017302D4422D600A9ED05 /* NWCSettings.swift */; }; 5CB017332D4422DB00A9ED05 /* NWCSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB017302D4422D600A9ED05 /* NWCSettings.swift */; }; + 5CB645982EA317D20018BD91 /* DamusLabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645972EA317CC0018BD91 /* DamusLabs.swift */; }; + 5CB645992EA317D20018BD91 /* DamusLabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645972EA317CC0018BD91 /* DamusLabs.swift */; }; + 5CB6459A2EA317D20018BD91 /* DamusLabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645972EA317CC0018BD91 /* DamusLabs.swift */; }; + 5CB6459C2EA31D8E0018BD91 /* LabsIntroduction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB6459B2EA31D750018BD91 /* LabsIntroduction.swift */; }; + 5CB6459D2EA31D8E0018BD91 /* LabsIntroduction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB6459B2EA31D750018BD91 /* LabsIntroduction.swift */; }; + 5CB6459E2EA31D8E0018BD91 /* LabsIntroduction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB6459B2EA31D750018BD91 /* LabsIntroduction.swift */; }; + 5CB645A12EA31E410018BD91 /* LabsLogoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645A02EA31E3D0018BD91 /* LabsLogoView.swift */; }; + 5CB645A22EA31E410018BD91 /* LabsLogoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645A02EA31E3D0018BD91 /* LabsLogoView.swift */; }; + 5CB645A32EA31E410018BD91 /* LabsLogoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645A02EA31E3D0018BD91 /* LabsLogoView.swift */; }; + 5CB645A92EAC01430018BD91 /* DamusLabsExpirements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645A82EAC013A0018BD91 /* DamusLabsExpirements.swift */; }; + 5CB645AA2EAC01430018BD91 /* DamusLabsExpirements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645A82EAC013A0018BD91 /* DamusLabsExpirements.swift */; }; + 5CB645AB2EAC01430018BD91 /* DamusLabsExpirements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB645A82EAC013A0018BD91 /* DamusLabsExpirements.swift */; }; 5CC8529D2BD741CD0039FFC5 /* HighlightEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CC8529C2BD741CD0039FFC5 /* HighlightEvent.swift */; }; 5CC8529F2BD744F60039FFC5 /* HighlightView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CC8529E2BD744F60039FFC5 /* HighlightView.swift */; }; 5CC852A22BDED9B90039FFC5 /* HighlightDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CC852A12BDED9B90039FFC5 /* HighlightDescription.swift */; }; @@ -2551,6 +2563,10 @@ 5CB017242D42C5BD00A9ED05 /* TransactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionsView.swift; sourceTree = ""; }; 5CB0172C2D42C76600A9ED05 /* BalanceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceView.swift; sourceTree = ""; }; 5CB017302D4422D600A9ED05 /* NWCSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NWCSettings.swift; sourceTree = ""; }; + 5CB645972EA317CC0018BD91 /* DamusLabs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusLabs.swift; sourceTree = ""; }; + 5CB6459B2EA31D750018BD91 /* LabsIntroduction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabsIntroduction.swift; sourceTree = ""; }; + 5CB645A02EA31E3D0018BD91 /* LabsLogoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabsLogoView.swift; sourceTree = ""; }; + 5CB645A82EAC013A0018BD91 /* DamusLabsExpirements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusLabsExpirements.swift; sourceTree = ""; }; 5CC8529C2BD741CD0039FFC5 /* HighlightEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HighlightEvent.swift; sourceTree = ""; }; 5CC8529E2BD744F60039FFC5 /* HighlightView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HighlightView.swift; sourceTree = ""; }; 5CC852A12BDED9B90039FFC5 /* HighlightDescription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HighlightDescription.swift; sourceTree = ""; }; @@ -4021,6 +4037,7 @@ 5C78A7872E30345900CF177D /* Longform */, 5C78A7842E30340E00CF177D /* FollowPack */, 4CFF8F5729C9FD07008DB934 /* Purple */, + 5CB645962EA3106A0018BD91 /* Labs */, 4CE879562996C44A00F758CC /* Zaps */, 4C7D095A2A098C5C00943473 /* Wallet */, 4CCEB7AC29B53D180078AA28 /* Search */, @@ -4841,6 +4858,33 @@ path = Views; sourceTree = ""; }; + 5CB645952EA3106A0018BD91 /* Views */ = { + isa = PBXGroup; + children = ( + 5CB645A82EAC013A0018BD91 /* DamusLabsExpirements.swift */, + 5CB6459B2EA31D750018BD91 /* LabsIntroduction.swift */, + 5CB645972EA317CC0018BD91 /* DamusLabs.swift */, + ); + path = Views; + sourceTree = ""; + }; + 5CB645962EA3106A0018BD91 /* Labs */ = { + isa = PBXGroup; + children = ( + 5CB6459F2EA31E2C0018BD91 /* Detail */, + 5CB645952EA3106A0018BD91 /* Views */, + ); + path = Labs; + sourceTree = ""; + }; + 5CB6459F2EA31E2C0018BD91 /* Detail */ = { + isa = PBXGroup; + children = ( + 5CB645A02EA31E3D0018BD91 /* LabsLogoView.swift */, + ); + path = Detail; + sourceTree = ""; + }; 7C0F392D29B57C8F0039859C /* Extensions */ = { isa = PBXGroup; children = ( @@ -5500,6 +5544,7 @@ 4CB8838D296F710400DC99E7 /* Reposted.swift in Sources */, 4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */, 2710433D2E6BFE340005C3B0 /* PostingTimelineSwitcherView.swift in Sources */, + 5CB6459A2EA317D20018BD91 /* DamusLabs.swift in Sources */, 4CEE2AF5280B29E600AB5EEF /* TimeAgo.swift in Sources */, 4CC14FF12A73FCDB007AEB17 /* Pubkey.swift in Sources */, 5C8711DE2C460C06007879C2 /* PostingTimelineView.swift in Sources */, @@ -5877,6 +5922,7 @@ 4C9BB83129C0ED4F00FC4E37 /* DisplayName.swift in Sources */, 7CFF6317299FEFE5005D382A /* SelectableText.swift in Sources */, D5C1AFD42E5EE2820092F72F /* FavoriteButtonView.swift in Sources */, + 5CB645AB2EAC01430018BD91 /* DamusLabsExpirements.swift in Sources */, D5C1AFCA2E5EE12B0092F72F /* ContactCardNotify.swift in Sources */, 4CA352A82A76B37E003BB08B /* NewMutesNotify.swift in Sources */, 4CFF8F6929CC9ED1008DB934 /* ImageContainerView.swift in Sources */, @@ -5934,6 +5980,7 @@ 4C73C5142A4437C10062CAC0 /* ZapUserView.swift in Sources */, 501F8C802A0220E1001AFC1D /* KeychainStorage.swift in Sources */, 3A92C0FE2DE16E9800CEEBAC /* FaviconCache.swift in Sources */, + 5CB645A22EA31E410018BD91 /* LabsLogoView.swift in Sources */, 4C1A9A1D29DDCF9B00516EAC /* NotificationSettingsView.swift in Sources */, 5CC868DD2AA29B3200FB22BA /* NeutralButtonStyle.swift in Sources */, 4C75EFB528049D790006080F /* Relay.swift in Sources */, @@ -5956,6 +6003,7 @@ D7100C5C2B77016700C59298 /* IAPProductStateView.swift in Sources */, 4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */, D733F9E82D92C76100317B11 /* UnownedNdbNote.swift in Sources */, + 5CB6459C2EA31D8E0018BD91 /* LabsIntroduction.swift in Sources */, D77135D42E7B766B00E7639F /* DataExtensions.swift in Sources */, D74EA0902D2E271E002290DD /* ErrorView.swift in Sources */, 4CE4F0F429D779B5005914DB /* PostBox.swift in Sources */, @@ -6040,6 +6088,7 @@ 5C4FA7FB2DC29C3800CE658C /* FollowPackView.swift in Sources */, 4C3624722D5EA18E00DD066E /* amount.c in Sources */, 4C3624712D5EA18300DD066E /* error.c in Sources */, + 5CB645A92EAC01430018BD91 /* DamusLabsExpirements.swift in Sources */, 4C3624702D5EA17700DD066E /* utf8.c in Sources */, 4C36246F2D5EA16A00DD066E /* str.c in Sources */, 4C36246E2D5EA10400DD066E /* hash_u5.c in Sources */, @@ -6191,6 +6240,7 @@ 82D6FB2C2CD99F7900C925F4 /* ImageMetadata.swift in Sources */, D71527FF2E0A3D6900C893D6 /* InterestList.swift in Sources */, 82D6FB2D2CD99F7900C925F4 /* ImageProcessing.swift in Sources */, + 5CB6459D2EA31D8E0018BD91 /* LabsIntroduction.swift in Sources */, 82D6FB2E2CD99F7900C925F4 /* BlurHashEncode.swift in Sources */, 82D6FB2F2CD99F7900C925F4 /* BlurHashDecode.swift in Sources */, 82D6FB302CD99F7900C925F4 /* PostBox.swift in Sources */, @@ -6427,6 +6477,7 @@ D71AD8FE2CEC176A002E2C3C /* AppAccessibilityIdentifiers.swift in Sources */, 82D6FC092CD99F7900C925F4 /* AboutView.swift in Sources */, 82D6FC0A2CD99F7900C925F4 /* ProfileName.swift in Sources */, + 5CB645982EA317D20018BD91 /* DamusLabs.swift in Sources */, 82D6FC0B2CD99F7900C925F4 /* ProfilePictureSelector.swift in Sources */, 82D6FC0C2CD99F7900C925F4 /* EditMetadataView.swift in Sources */, 82D6FC0D2CD99F7900C925F4 /* EditPictureControl.swift in Sources */, @@ -6438,6 +6489,7 @@ 82D6FC122CD99F7900C925F4 /* EventProfileName.swift in Sources */, 82D6FC132CD99F7900C925F4 /* FriendIcon.swift in Sources */, 82D6FC142CD99F7900C925F4 /* CondensedProfilePicturesView.swift in Sources */, + 5CB645A32EA31E410018BD91 /* LabsLogoView.swift in Sources */, 82D6FC152CD99F7900C925F4 /* ProfileEditButton.swift in Sources */, D73BDB102D6FF5F600D69970 /* NostrNetworkManager.swift in Sources */, 82D6FC162CD99F7900C925F4 /* RelayPaidDetail.swift in Sources */, @@ -6690,6 +6742,7 @@ D73E5E872C6A97F4007EB227 /* DamusPurple.swift in Sources */, D73E5F992C6AA864007EB227 /* InvoicesView.swift in Sources */, D73E5E882C6A97F4007EB227 /* StoreObserver.swift in Sources */, + 5CB645992EA317D20018BD91 /* DamusLabs.swift in Sources */, D73E5E892C6A97F4007EB227 /* DamusPurpleURL.swift in Sources */, D73E5E8A2C6A97F4007EB227 /* PurpleStoreKitManager.swift in Sources */, D733F9E72D92C76100317B11 /* UnownedNdbNote.swift in Sources */, @@ -6853,6 +6906,7 @@ D73E5F0E2C6A97F4007EB227 /* FriendIcon.swift in Sources */, D73E5F0F2C6A97F4007EB227 /* CondensedProfilePicturesView.swift in Sources */, D73E5F102C6A97F4007EB227 /* ProfileEditButton.swift in Sources */, + 5CB6459E2EA31D8E0018BD91 /* LabsIntroduction.swift in Sources */, D73E5F112C6A97F4007EB227 /* RelayPaidDetail.swift in Sources */, D7AACFFF2E0387B800FB7699 /* LnurlAmountView.swift in Sources */, D73E5F122C6A97F4007EB227 /* RelayAuthenticationDetail.swift in Sources */, @@ -7002,6 +7056,7 @@ D703D7A52C670E3E00A400EA /* mdb.c in Sources */, D703D76B2C670B3100A400EA /* Referenced.swift in Sources */, D73BDB192D71311900D69970 /* UserRelayListErrors.swift in Sources */, + 5CB645A12EA31E410018BD91 /* LabsLogoView.swift in Sources */, D703D7582C670A6000A400EA /* Id.swift in Sources */, 5C05675A2C8FBDE70073F23A /* NDBSearchView.swift in Sources */, D703D76E2C670B4900A400EA /* NdbTagsIterator.swift in Sources */, @@ -7045,6 +7100,7 @@ D73E5E162C6A9619007EB227 /* PostView.swift in Sources */, D703D7872C670C7E00A400EA /* DamusPurpleEnvironment.swift in Sources */, D703D7892C670C8600A400EA /* DeepLPlan.swift in Sources */, + 5CB645AA2EAC01430018BD91 /* DamusLabsExpirements.swift in Sources */, D73E5E182C6A963D007EB227 /* AttachMediaUtility.swift in Sources */, D73E5F852C6AA628007EB227 /* LoadScript.swift in Sources */, D703D74E2C6709DA00A400EA /* Pubkey.swift in Sources */, diff --git a/damus/Assets.xcassets/Illustrations/damooseLabs.imageset/Contents.json b/damus/Assets.xcassets/Illustrations/damooseLabs.imageset/Contents.json new file mode 100644 index 00000000..92ff9f55 --- /dev/null +++ b/damus/Assets.xcassets/Illustrations/damooseLabs.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "damooseLabs.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/damus/Assets.xcassets/Illustrations/damooseLabs.imageset/damooseLabs.png b/damus/Assets.xcassets/Illustrations/damooseLabs.imageset/damooseLabs.png new file mode 100644 index 00000000..6b8ac7ad Binary files /dev/null and b/damus/Assets.xcassets/Illustrations/damooseLabs.imageset/damooseLabs.png differ diff --git a/damus/ContentView.swift b/damus/ContentView.swift index 95c4e9bc..dee644ac 100644 --- a/damus/ContentView.swift +++ b/damus/ContentView.swift @@ -195,6 +195,9 @@ struct ContentView: View { } } } + .onAppear { + notify(.display_tabbar(true)) + } } func MaybeReportView(target: ReportTarget) -> some View { diff --git a/damus/Features/Labs/Detail/LabsLogoView.swift b/damus/Features/Labs/Detail/LabsLogoView.swift new file mode 100644 index 00000000..44e10e71 --- /dev/null +++ b/damus/Features/Labs/Detail/LabsLogoView.swift @@ -0,0 +1,62 @@ +// +// LabsLogoView.swift +// damus +// +// Created by eric on 10/17/25. +// + +import SwiftUI + +struct LabsLogoView: View { + var body: some View { + HStack(spacing: 20) { + Image("damus-dark-logo") + .resizable() + .frame(width: 60, height: 60) + .clipShape(RoundedRectangle(cornerRadius: 15.0)) + .overlay( + RoundedRectangle(cornerRadius: 15) + .stroke(LinearGradient( + colors: [DamusColors.lighterPink.opacity(0.8), .white.opacity(0), DamusColors.deepPurple.opacity(0.6)], + startPoint: .topLeading, + endPoint: .bottomTrailing), lineWidth: 1) + ) + .shadow(radius: 5) + + VStack(alignment: .leading) { + HStack(spacing: 0) { + Text("Labs ", comment: "Feature name") + .font(.system(size: 60.0).weight(.bold)) + .foregroundColor(.white) + .tracking(-2) + Image(systemName: "flask.fill") + .padding(.top, 25) + .foregroundStyle( + LinearGradient( + colors: [DamusColors.deepPurple, DamusColors.lighterPink], + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + ) + Image(systemName: "testtube.2") + .padding(.top, 25) + .foregroundStyle( + LinearGradient( + colors: [DamusColors.lighterPink, DamusColors.deepPurple], + startPoint: .bottomLeading, + endPoint: .topTrailing + ) + ) + } + } + } + .padding(.bottom, 30) + } +} + + +#Preview { + PurpleBackdrop { + LabsLogoView() + } +} diff --git a/damus/Features/Labs/Views/DamusLabs.swift b/damus/Features/Labs/Views/DamusLabs.swift new file mode 100644 index 00000000..1249bf69 --- /dev/null +++ b/damus/Features/Labs/Views/DamusLabs.swift @@ -0,0 +1,71 @@ +// +// DamusLabs.swift +// damus +// +// Created by eric on 10/17/25. +// + +import SwiftUI +import StoreKit + +struct DamusLabsView: View { + let damus_state: DamusState + @State var purple_account: DamusPurple.Account? + + @State var show_intro_sheet: Bool = true + @State private var shouldDismissView = false + + @Environment(\.dismiss) var dismiss + + init(damus_state: DamusState) { + self.damus_state = damus_state + self.purple_account = nil + } + + var body: some View { + NavigationView { + PurpleBackdrop { + VStack { + MainContent + .padding(.top, 125) + } + } + .navigationBarHidden(true) + .navigationBarTitleDisplayMode(.inline) + .navigationBarBackButtonHidden(true) + .navigationBarItems(leading: BackNav()) + } + .onReceive(handle_notify(.switched_timeline)) { _ in + dismiss() + } + .onAppear { + notify(.display_tabbar(false)) + } + .task { + if damus_state.purple.enable_purple { + self.purple_account = try? await damus_state.purple.get_maybe_cached_account(pubkey: damus_state.pubkey) + } + } + .ignoresSafeArea(.all) + } + + var MainContent: some View { + VStack { + LabsLogoView() + + if let purple_account, purple_account.active == true { + DamusLabsExpirements(damus_state: damus_state) + } else { + LabsIntroductionView(damus_state: damus_state) + } + + Spacer() + } + } +} + +struct DamusLabsView_Previews: PreviewProvider { + static var previews: some View { + DamusLabsView(damus_state: test_damus_state) + } +} diff --git a/damus/Features/Labs/Views/DamusLabsExpirements.swift b/damus/Features/Labs/Views/DamusLabsExpirements.swift new file mode 100644 index 00000000..97f40b01 --- /dev/null +++ b/damus/Features/Labs/Views/DamusLabsExpirements.swift @@ -0,0 +1,52 @@ +// +// DamusLabsExpirements.swift +// damus +// +// Created by eric on 10/24/25. +// + +import SwiftUI + + +struct DamusLabsExpirements: View { + + let damus_state: DamusState + + var body: some View { + VStack { + VStack(alignment: .leading, spacing: 30) { + PurpleViewPrimitives.SubtitleView(text: NSLocalizedString("As a subscriber, you’re getting an early look at new and innovative tools. These are beta features — still being tested and tuned. Try them out, share your thoughts, and help us perfect what’s next.", comment: "Damus Labs explainer")) + .multilineTextAlignment(.center) + + + HStack { + Spacer() + Text("Features coming soon!") + .font(.title2) + .foregroundColor(.white) + .fontWeight(.bold) + .padding(.bottom, 2) + Spacer() + } + .padding(15) + .background(DamusColors.neutral6) + .cornerRadius(15) + .padding(.top, 10) + + } + .padding([.trailing, .leading], 30) + .padding(.bottom, 20) + + Image("damooseLabs") + .resizable() + .aspectRatio(contentMode: .fill) + } + } +} + + +#Preview { + PurpleBackdrop { + DamusLabsExpirements(damus_state: test_damus_state) + } +} diff --git a/damus/Features/Labs/Views/LabsIntroduction.swift b/damus/Features/Labs/Views/LabsIntroduction.swift new file mode 100644 index 00000000..0eef5bff --- /dev/null +++ b/damus/Features/Labs/Views/LabsIntroduction.swift @@ -0,0 +1,53 @@ +// +// LabsIntroduction.swift +// damus +// +// Created by eric on 10/17/25. +// + +import SwiftUI + + +struct LabsIntroductionView: View { + + let damus_state: DamusState + + var body: some View { + VStack { + VStack(alignment: .leading, spacing: 30) { + PurpleViewPrimitives.SubtitleView(text: NSLocalizedString("Purple subscribers get first access to new and experimental features — fresh ideas straight from the lab.", comment: "Damus purple subscription pitch")) + .multilineTextAlignment(.center) + + HStack { + NavigationLink(destination: DamusPurpleView(damus_state: damus_state)) { + HStack(spacing: 10) { + Spacer() + Text("Learn more about Purple") + .foregroundColor(Color.white) + Spacer() + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding() + .background { + RoundedRectangle(cornerRadius: 12) + .fill(PinkGradient) + } + } + } + } + .padding([.trailing, .leading], 30) + .padding(.bottom, 20) + + Image("damooseLabs") + .resizable() + .aspectRatio(contentMode: .fill) + } + } +} + + +#Preview { + PurpleBackdrop { + LabsIntroductionView(damus_state: test_damus_state) + } +} diff --git a/damus/Features/Purple/Views/DamusPurpleView.swift b/damus/Features/Purple/Views/DamusPurpleView.swift index c1c95658..dae4804b 100644 --- a/damus/Features/Purple/Views/DamusPurpleView.swift +++ b/damus/Features/Purple/Views/DamusPurpleView.swift @@ -68,9 +68,6 @@ struct DamusPurpleView: View, DamusPurpleStoreKitManagerDelegate { self.account_uuid = try await damus_state.purple.get_maybe_cached_uuid_for_account() } } - .onDisappear { - notify(.display_tabbar(true)) - } .onReceive(handle_notify(.purple_account_update), perform: { account in self.my_account_info_state = .loaded(account: account) }) diff --git a/damus/Features/Timeline/Views/SideMenuView.swift b/damus/Features/Timeline/Views/SideMenuView.swift index a6cbe8dc..44e0b3ab 100644 --- a/damus/Features/Timeline/Views/SideMenuView.swift +++ b/damus/Features/Timeline/Views/SideMenuView.swift @@ -57,6 +57,22 @@ struct SideMenuView: View { .frame(maxWidth: .infinity, alignment: .leading) } } + + NavigationLink(destination: DamusLabsView(damus_state: damus_state)) { + HStack(spacing: 23) { + Image(systemName: "flask") + .fontWeight(.bold) + .tint(DamusColors.adaptableBlack) + Text("Labs") + .font(.title2.weight(.semibold)) + .foregroundColor(DamusColors.adaptableBlack) + .frame(maxWidth: .infinity, alignment: .leading) + .dynamicTypeSize(.xSmall) + .minimumScaleFactor(0.5) + .lineLimit(1) + } + .frame(maxWidth: .infinity, alignment: .leading) + } NavigationLink(value: Route.MuteList) { navLabel(title: NSLocalizedString("Muted", comment: "Sidebar menu label for muted users view."), img: "mute")