Skip to content

Commit

Permalink
Merge pull request #1628 from planetary-social/welcome-to-feed-tip
Browse files Browse the repository at this point in the history
#1602: Welcome to Your Feed tip
  • Loading branch information
joshuatbrown authored Oct 16, 2024
2 parents 8979e9c + 39abfef commit 4a03936
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 25 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Release Notes
- Added a tip to the Feed to welcome first-time users and explain how the Feed works. [#1602](https://github.com/planetary-social/nos/issues/1602)

## [0.2.2] - 2024-10-11Z

### Release Notes
Expand Down
8 changes: 8 additions & 0 deletions Nos.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@
03C49AC22C938DE100502321 /* SoupOpenGraphParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03C49AC12C938DE100502321 /* SoupOpenGraphParser.swift */; };
03C49AC32C938DE100502321 /* SoupOpenGraphParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03C49AC12C938DE100502321 /* SoupOpenGraphParser.swift */; };
03C68C522C94D8400037DC59 /* SwiftSoup in Frameworks */ = {isa = PBXBuildFile; productRef = 03C68C512C94D8400037DC59 /* SwiftSoup */; };
03C7E7922CB9C0B30054624C /* WelcomeToFeedTip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03C7E7912CB9C0AF0054624C /* WelcomeToFeedTip.swift */; };
03C7E7982CB9C16C0054624C /* InlineTipViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03C7E7972CB9C1600054624C /* InlineTipViewStyle.swift */; };
03C8B4962C6D065900A07CCD /* ImageViewer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03C8B4952C6D065900A07CCD /* ImageViewer.swift */; };
03D1B4282C3C1A5D001778CD /* NostrIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D1B4272C3C1A5D001778CD /* NostrIdentifier.swift */; };
03D1B4292C3C1AC9001778CD /* NostrIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03D1B4272C3C1A5D001778CD /* NostrIdentifier.swift */; };
Expand Down Expand Up @@ -659,6 +661,8 @@
03B4E6AB2C125D13006E5F59 /* FileStorageUploadResponseJSONTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileStorageUploadResponseJSONTests.swift; sourceTree = "<group>"; };
03B4E6AD2C125D61006E5F59 /* FileStorageUploadResponseJSON.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileStorageUploadResponseJSON.swift; sourceTree = "<group>"; };
03C49AC12C938DE100502321 /* SoupOpenGraphParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoupOpenGraphParser.swift; sourceTree = "<group>"; };
03C7E7912CB9C0AF0054624C /* WelcomeToFeedTip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeToFeedTip.swift; sourceTree = "<group>"; };
03C7E7972CB9C1600054624C /* InlineTipViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineTipViewStyle.swift; sourceTree = "<group>"; };
03C8B4952C6D065900A07CCD /* ImageViewer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewer.swift; sourceTree = "<group>"; };
03D1B4272C3C1A5D001778CD /* NostrIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NostrIdentifier.swift; sourceTree = "<group>"; };
03D1B42B2C3C1B0D001778CD /* TLVElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TLVElement.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1647,6 +1651,7 @@
children = (
C9DEBFD8298941000078B43A /* HomeFeedView.swift */,
5BE281C92AE2CCEB00880466 /* HomeTab.swift */,
03C7E7912CB9C0AF0054624C /* WelcomeToFeedTip.swift */,
);
path = Home;
sourceTree = "<group>";
Expand Down Expand Up @@ -1745,6 +1750,7 @@
C9CFF6D02AB241EB00D4B368 /* Modifiers */ = {
isa = PBXGroup;
children = (
03C7E7972CB9C1600054624C /* InlineTipViewStyle.swift */,
5B0D99022A94090A0039F0C5 /* DoubleTapToPopModifier.swift */,
C95D68A8299E709800429F86 /* LinearGradient+Planetary.swift */,
C95D68A4299E6E1E00429F86 /* PlaceholderModifier.swift */,
Expand Down Expand Up @@ -2440,6 +2446,7 @@
030FECAB2CB5E0B900820014 /* BuildYourNetworkView.swift in Sources */,
A3B943CF299AE00100A15A08 /* Keychain.swift in Sources */,
C9671D73298DB94C00EE7E12 /* Data+Encoding.swift in Sources */,
03C7E7922CB9C0B30054624C /* WelcomeToFeedTip.swift in Sources */,
C9646EA129B7A22C007239A4 /* Analytics.swift in Sources */,
C9A6C74B2AD866A7001F9500 /* UNSSuccessView.swift in Sources */,
5045540D2C81E10C0044ECAE /* EditableAvatarView.swift in Sources */,
Expand All @@ -2463,6 +2470,7 @@
3F43C47629A9625700E896A0 /* AuthorReference+CoreDataClass.swift in Sources */,
C9A6C7492AD86271001F9500 /* UNSNewNameView.swift in Sources */,
5B6136382C2F408E00ADD9C3 /* RepliesLabel.swift in Sources */,
03C7E7982CB9C16C0054624C /* InlineTipViewStyle.swift in Sources */,
C9ADB13D29929B540075E7F8 /* Bech32.swift in Sources */,
C95D68A1299E6D3E00429F86 /* BioView.swift in Sources */,
5BE281CA2AE2CCEB00880466 /* HomeTab.swift in Sources */,
Expand Down
22 changes: 22 additions & 0 deletions Nos/Assets/Localization/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -12937,6 +12937,17 @@
}
}
},
"nosDoesNotUseAlgorithms" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nos does not use algorithms to populate your feed. Notes appear in reverse chronological order based on publish time and date."
}
}
}
},
"nosIsOpenSource" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -21571,6 +21582,17 @@
}
}
},
"welcomeToYourFeed" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Welcome to your feed!"
}
}
}
},
"xNewFollowers" : {
"extractionState" : "manual",
"localizations" : {
Expand Down
2 changes: 2 additions & 0 deletions Nos/NosApp.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import SwiftUI
import Logger
import Dependencies
import TipKit

@main
struct NosApp: App {
Expand All @@ -22,6 +23,7 @@ struct NosApp: App {
// https://github.com/planetary-social/nos/issues/1064
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = .systemBlue
persistenceController.scheduleBackgroundCleanupTask()
try? Tips.configure()
}

var body: some Scene {
Expand Down
49 changes: 31 additions & 18 deletions Nos/Views/Home/HomeFeedView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import SwiftUI
import CoreData
import Combine
import Dependencies
import TipKit

struct HomeFeedView: View {

Expand All @@ -21,6 +22,9 @@ struct HomeFeedView: View {
static let staticLoadTime: TimeInterval = 2

let user: Author

/// A tip to display at the top of the feed.
let welcomeTip = WelcomeToFeedTip()

@State private var showRelayPicker = false
@State private var selectedRelay: Relay?
Expand Down Expand Up @@ -63,25 +67,34 @@ struct HomeFeedView: View {

var body: some View {
ZStack {
PagedNoteListView(
refreshController: $refreshController,
databaseFilter: homeFeedFetchRequest,
relayFilter: homeFeedFilter,
relay: selectedRelay,
managedObjectContext: viewContext,
tab: .home,
header: {
EmptyView()
},
emptyPlaceholder: {
VStack {
Text(.localizable.noEvents)
.padding()
VStack(spacing: 8) {
TipView(welcomeTip)
.padding(.top, 20)
.padding(.horizontal, 16)
.readabilityPadding()
.tipBackground(LinearGradient.horizontalAccentReversed)
.tipViewStyle(.inline)

PagedNoteListView(
refreshController: $refreshController,
databaseFilter: homeFeedFetchRequest,
relayFilter: homeFeedFilter,
relay: selectedRelay,
managedObjectContext: viewContext,
tab: .home,
header: {
EmptyView()
},
emptyPlaceholder: {
VStack {
Text(.localizable.noEvents)
.padding()
}
.frame(minHeight: 300)
}
.frame(minHeight: 300)
}
)
.padding(0)
)
.padding(0)
}

NewNotesButton(fetchRequest: FetchRequest(fetchRequest: newNotesRequest)) {
refreshController.startRefresh = true
Expand Down
12 changes: 12 additions & 0 deletions Nos/Views/Home/WelcomeToFeedTip.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import TipKit

/// A tip that's displayed on the Feed view, also known as the Home view.
struct WelcomeToFeedTip: Tip {
var title: Text {
Text("welcomeToYourFeed")
}

var message: Text? {
Text("nosDoesNotUseAlgorithms")
}
}
33 changes: 33 additions & 0 deletions Nos/Views/Modifiers/InlineTipViewStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import TipKit

/// An inline tip view style with a styled title, message, and close button.
struct InlineTipViewStyle: TipViewStyle {
func makeBody(configuration: TipViewStyle.Configuration) -> some View {
VStack(alignment: .leading, spacing: 10) {
HStack(alignment: .top) {
configuration.title
.font(.title2.bold())
.foregroundStyle(Color.primaryTxt)
.shadow(color: .lightShadow, radius: 2, x: 0, y: 1)
Spacer()
Button {
configuration.tip.invalidate(reason: .tipClosed)
} label: {
Image(systemName: "xmark").scaledToFit()
.foregroundStyle(Color.primaryTxt)
.font(.system(size: 20).bold())
}
}

configuration.message
.foregroundStyle(Color.primaryTxt)
.shadow(color: .lightShadow, radius: 2, x: 0, y: 1)
}
.padding(.vertical, 20)
.padding(.horizontal, 16)
}
}

extension TipViewStyle where Self == InlineTipViewStyle {
static var inline: Self { Self() }
}
20 changes: 13 additions & 7 deletions Nos/Views/Modifiers/LinearGradient+Planetary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,25 @@ import SwiftUI
extension LinearGradient {

public static let horizontalAccent = LinearGradient(
colors: [ Color.actionPrimaryGradientTop, Color.actionPrimaryGradientBottom],
colors: [.actionPrimaryGradientTop, .actionPrimaryGradientBottom],
startPoint: .leading,
endPoint: .trailing
)

public static let horizontalAccentReversed = LinearGradient(
colors: [.actionPrimaryGradientBottom, .actionPrimaryGradientTop],
startPoint: .leading,
endPoint: .trailing
)

public static let diagonalAccent = LinearGradient(
colors: [ Color.actionPrimaryGradientTop, Color.actionPrimaryGradientBottom],
colors: [.actionPrimaryGradientTop, .actionPrimaryGradientBottom],
startPoint: .topLeading,
endPoint: .bottomTrailing
)

public static let diagonalAccent2 = LinearGradient(
colors: [ Color.actionPrimaryGradientTop, Color.actionPrimaryGradientBottom],
colors: [.actionPrimaryGradientTop, .actionPrimaryGradientBottom],
startPoint: .bottomLeading,
endPoint: .topTrailing
)
Expand All @@ -39,7 +45,7 @@ extension LinearGradient {
)

public static let cardGradient = LinearGradient(
colors: [Color.cardBgTop, Color.cardBgBottom],
colors: [.cardBgTop, .cardBgBottom],
startPoint: .top,
endPoint: .bottom
)
Expand All @@ -51,19 +57,19 @@ extension LinearGradient {
)

public static let gold = LinearGradient(
colors: [Color.goldBgGradientTop, Color.goldBgGradientBottom],
colors: [.goldBgGradientTop, .goldBgGradientBottom],
startPoint: .top,
endPoint: .bottom
)

public static let nip05 = LinearGradient(
colors: [Color.nip05BgGradientTop, Color.nip05BgGradientBottom],
colors: [.nip05BgGradientTop, .nip05BgGradientBottom],
startPoint: .top,
endPoint: .bottom
)

public static let bio = LinearGradient(
colors: [Color.bioBgGradientTop, Color.bioBgGradientBottom],
colors: [.bioBgGradientTop, .bioBgGradientBottom],
startPoint: .top,
endPoint: .bottom
)
Expand Down

0 comments on commit 4a03936

Please sign in to comment.