Add tip in threads to inform users what trusted network means
Changelog-Added: Added tip in threads to inform users what trusted network means Signed-off-by: Terry Yiu <git@tyiu.xyz>
This commit is contained in:
@@ -27,6 +27,9 @@
|
|||||||
3A4325A82961E11400BFCD9D /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 3A4325AA2961E11400BFCD9D /* Localizable.stringsdict */; };
|
3A4325A82961E11400BFCD9D /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 3A4325AA2961E11400BFCD9D /* Localizable.stringsdict */; };
|
||||||
3A4647CF2A413ADC00386AD8 /* CondensedProfilePicturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4647CE2A413ADC00386AD8 /* CondensedProfilePicturesView.swift */; };
|
3A4647CF2A413ADC00386AD8 /* CondensedProfilePicturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4647CE2A413ADC00386AD8 /* CondensedProfilePicturesView.swift */; };
|
||||||
3A48E7B029DFBE9D006E787E /* MutedThreadsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A48E7AF29DFBE9D006E787E /* MutedThreadsManager.swift */; };
|
3A48E7B029DFBE9D006E787E /* MutedThreadsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A48E7AF29DFBE9D006E787E /* MutedThreadsManager.swift */; };
|
||||||
|
3A515C502DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C4F2DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift */; };
|
||||||
|
3A515C512DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C4F2DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift */; };
|
||||||
|
3A515C522DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C4F2DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift */; };
|
||||||
3A8CC6CC2A2CFEF900940F5F /* StringUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A8CC6CB2A2CFEF900940F5F /* StringUtil.swift */; };
|
3A8CC6CC2A2CFEF900940F5F /* StringUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A8CC6CB2A2CFEF900940F5F /* StringUtil.swift */; };
|
||||||
3A92C0FE2DE16E9800CEEBAC /* FaviconCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A92C0FD2DE16E9800CEEBAC /* FaviconCache.swift */; };
|
3A92C0FE2DE16E9800CEEBAC /* FaviconCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A92C0FD2DE16E9800CEEBAC /* FaviconCache.swift */; };
|
||||||
3A92C0FF2DE16E9800CEEBAC /* FaviconCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A92C0FD2DE16E9800CEEBAC /* FaviconCache.swift */; };
|
3A92C0FF2DE16E9800CEEBAC /* FaviconCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A92C0FD2DE16E9800CEEBAC /* FaviconCache.swift */; };
|
||||||
@@ -1855,6 +1858,7 @@
|
|||||||
3A47CB782BDA05A200728A7C /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
3A47CB782BDA05A200728A7C /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
3A47CB792BDA05A200728A7C /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fi; path = fi.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
3A47CB792BDA05A200728A7C /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fi; path = fi.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
3A48E7AF29DFBE9D006E787E /* MutedThreadsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutedThreadsManager.swift; sourceTree = "<group>"; };
|
3A48E7AF29DFBE9D006E787E /* MutedThreadsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutedThreadsManager.swift; sourceTree = "<group>"; };
|
||||||
|
3A515C4F2DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustedNetworkRepliesTip.swift; sourceTree = "<group>"; };
|
||||||
3A5C4575296A879E0032D398 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-419"; path = "es-419.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
3A5C4575296A879E0032D398 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-419"; path = "es-419.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||||
3A5CAE1D298DC0DB00B5334F /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
3A5CAE1D298DC0DB00B5334F /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||||
3A5CAE1E298DC0DB00B5334F /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
3A5CAE1E298DC0DB00B5334F /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
@@ -2728,6 +2732,14 @@
|
|||||||
path = "Empty Views";
|
path = "Empty Views";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
3A515C4E2DF4E0E6002D3B34 /* Tips */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3A515C4F2DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift */,
|
||||||
|
);
|
||||||
|
path = Tips;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
3AA24800297E3DAE0090C62D /* Reposts */ = {
|
3AA24800297E3DAE0090C62D /* Reposts */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -3223,6 +3235,7 @@
|
|||||||
4C190F232A547D1700027FD5 /* NostrScript */,
|
4C190F232A547D1700027FD5 /* NostrScript */,
|
||||||
4C7D095A2A098C5C00943473 /* Wallet */,
|
4C7D095A2A098C5C00943473 /* Wallet */,
|
||||||
4C8D1A6D29F31E4100ACDF75 /* Buttons */,
|
4C8D1A6D29F31E4100ACDF75 /* Buttons */,
|
||||||
|
3A515C4E2DF4E0E6002D3B34 /* Tips */,
|
||||||
4C1A9A2829DDF53B00516EAC /* Video */,
|
4C1A9A2829DDF53B00516EAC /* Video */,
|
||||||
4C1A9A1B29DDCF8B00516EAC /* Settings */,
|
4C1A9A1B29DDCF8B00516EAC /* Settings */,
|
||||||
4CFF8F6129CC9A80008DB934 /* Images */,
|
4CFF8F6129CC9A80008DB934 /* Images */,
|
||||||
@@ -4732,6 +4745,7 @@
|
|||||||
D7100C5A2B76FD5100C59298 /* LogoView.swift in Sources */,
|
D7100C5A2B76FD5100C59298 /* LogoView.swift in Sources */,
|
||||||
4C0A3F8F280F640A000448DE /* ThreadModel.swift in Sources */,
|
4C0A3F8F280F640A000448DE /* ThreadModel.swift in Sources */,
|
||||||
4C3AC79F2833115300E1F516 /* FollowButtonView.swift in Sources */,
|
4C3AC79F2833115300E1F516 /* FollowButtonView.swift in Sources */,
|
||||||
|
3A515C502DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift in Sources */,
|
||||||
D7CB5D3B2B112FBB00AD4105 /* NotificationFormatter.swift in Sources */,
|
D7CB5D3B2B112FBB00AD4105 /* NotificationFormatter.swift in Sources */,
|
||||||
4C4E137B2A76D5FB00BDD832 /* MuteThreadNotify.swift in Sources */,
|
4C4E137B2A76D5FB00BDD832 /* MuteThreadNotify.swift in Sources */,
|
||||||
4CC7AAE7297EFA7B00430951 /* Zap.swift in Sources */,
|
4CC7AAE7297EFA7B00430951 /* Zap.swift in Sources */,
|
||||||
@@ -5374,6 +5388,7 @@
|
|||||||
82D6FB9C2CD99F7900C925F4 /* WalletModel.swift in Sources */,
|
82D6FB9C2CD99F7900C925F4 /* WalletModel.swift in Sources */,
|
||||||
82D6FB9D2CD99F7900C925F4 /* ZapButtonModel.swift in Sources */,
|
82D6FB9D2CD99F7900C925F4 /* ZapButtonModel.swift in Sources */,
|
||||||
82D6FB9E2CD99F7900C925F4 /* ContentFilters.swift in Sources */,
|
82D6FB9E2CD99F7900C925F4 /* ContentFilters.swift in Sources */,
|
||||||
|
3A515C512DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift in Sources */,
|
||||||
82D6FB9F2CD99F7900C925F4 /* DamusCacheManager.swift in Sources */,
|
82D6FB9F2CD99F7900C925F4 /* DamusCacheManager.swift in Sources */,
|
||||||
82D6FBA02CD99F7900C925F4 /* NotificationsManager.swift in Sources */,
|
82D6FBA02CD99F7900C925F4 /* NotificationsManager.swift in Sources */,
|
||||||
D755B28E2D3E7D8800BBEEFA /* NIP37Draft.swift in Sources */,
|
D755B28E2D3E7D8800BBEEFA /* NIP37Draft.swift in Sources */,
|
||||||
@@ -5628,6 +5643,7 @@
|
|||||||
D73E5E2B2C6A97F4007EB227 /* PostNotify.swift in Sources */,
|
D73E5E2B2C6A97F4007EB227 /* PostNotify.swift in Sources */,
|
||||||
D73E5E2C2C6A97F4007EB227 /* PresentSheetNotify.swift in Sources */,
|
D73E5E2C2C6A97F4007EB227 /* PresentSheetNotify.swift in Sources */,
|
||||||
D73E5E2D2C6A97F4007EB227 /* ProfileUpdatedNotify.swift in Sources */,
|
D73E5E2D2C6A97F4007EB227 /* ProfileUpdatedNotify.swift in Sources */,
|
||||||
|
3A515C522DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift in Sources */,
|
||||||
D73E5E2E2C6A97F4007EB227 /* ReportNotify.swift in Sources */,
|
D73E5E2E2C6A97F4007EB227 /* ReportNotify.swift in Sources */,
|
||||||
D73E5E2F2C6A97F4007EB227 /* ScrollToTopNotify.swift in Sources */,
|
D73E5E2F2C6A97F4007EB227 /* ScrollToTopNotify.swift in Sources */,
|
||||||
D73E5E302C6A97F4007EB227 /* SwitchedTimelineNotify.swift in Sources */,
|
D73E5E302C6A97F4007EB227 /* SwitchedTimelineNotify.swift in Sources */,
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ import AVKit
|
|||||||
import MediaPlayer
|
import MediaPlayer
|
||||||
import EmojiPicker
|
import EmojiPicker
|
||||||
|
|
||||||
|
#if canImport(TipKit)
|
||||||
|
import TipKit
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ZapSheet {
|
struct ZapSheet {
|
||||||
let target: ZapTarget
|
let target: ZapTarget
|
||||||
let lnurl: String
|
let lnurl: String
|
||||||
@@ -705,6 +709,21 @@ struct ContentView: View {
|
|||||||
|
|
||||||
damus_state.nostrNetwork.pool.register_handler(sub_id: sub_id, handler: home.handle_event)
|
damus_state.nostrNetwork.pool.register_handler(sub_id: sub_id, handler: home.handle_event)
|
||||||
damus_state.nostrNetwork.connect()
|
damus_state.nostrNetwork.connect()
|
||||||
|
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
if damus_state.settings.developer_mode && damus_state.settings.reset_tips_on_launch {
|
||||||
|
do {
|
||||||
|
try Tips.resetDatastore()
|
||||||
|
} catch {
|
||||||
|
Log.error("Failed to reset tips datastore: %s", for: .tips, error.localizedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
try Tips.configure()
|
||||||
|
} catch {
|
||||||
|
Log.error("Failed to configure tips: %s", for: .tips, error.localizedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func music_changed(_ state: MusicState) {
|
func music_changed(_ state: MusicState) {
|
||||||
|
|||||||
@@ -131,6 +131,9 @@ class UserSettingsStore: ObservableObject {
|
|||||||
@Setting(key: "show_trusted_replies_first", default_value: true)
|
@Setting(key: "show_trusted_replies_first", default_value: true)
|
||||||
var show_trusted_replies_first: Bool
|
var show_trusted_replies_first: Bool
|
||||||
|
|
||||||
|
@Setting(key: "reset_tips_on_launch", default_value: false)
|
||||||
|
var reset_tips_on_launch: Bool
|
||||||
|
|
||||||
@Setting(key: "hide_nsfw_tagged_content", default_value: false)
|
@Setting(key: "hide_nsfw_tagged_content", default_value: false)
|
||||||
var hide_nsfw_tagged_content: Bool
|
var hide_nsfw_tagged_content: Bool
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ enum LogCategory: String {
|
|||||||
case damus_purple
|
case damus_purple
|
||||||
case image_uploading
|
case image_uploading
|
||||||
case video_coordination
|
case video_coordination
|
||||||
|
case tips
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Damus structured logger
|
/// Damus structured logger
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SwipeActions
|
import SwipeActions
|
||||||
|
import TipKit
|
||||||
|
|
||||||
struct ChatroomThreadView: View {
|
struct ChatroomThreadView: View {
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
@@ -159,6 +160,12 @@ struct ChatroomThreadView: View {
|
|||||||
|
|
||||||
// MARK: - Children view - outside trusted network
|
// MARK: - Children view - outside trusted network
|
||||||
if !untrusted_events.isEmpty {
|
if !untrusted_events.isEmpty {
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
TipView(TrustedNetworkRepliesTip.shared, arrowEdge: .bottom)
|
||||||
|
.padding(.top, 10)
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
// Track this section's position
|
// Track this section's position
|
||||||
Color.clear
|
Color.clear
|
||||||
@@ -184,6 +191,10 @@ struct ChatroomThreadView: View {
|
|||||||
withAnimation {
|
withAnimation {
|
||||||
untrusted_network_expanded.toggle()
|
untrusted_network_expanded.toggle()
|
||||||
|
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
TrustedNetworkRepliesTip.shared.invalidate(reason: .actionPerformed)
|
||||||
|
}
|
||||||
|
|
||||||
scroll_to_event(scroller: scroller, id: ChatroomThreadView.untrusted_network_section_id, delay: 0.1, animate: true, anchor: ChatroomThreadView.sticky_header_adjusted_anchor)
|
scroll_to_event(scroller: scroller, id: ChatroomThreadView.untrusted_network_section_id, delay: 0.1, animate: true, anchor: ChatroomThreadView.sticky_header_adjusted_anchor)
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
#if canImport(TipKit)
|
||||||
|
import TipKit
|
||||||
|
#endif
|
||||||
|
|
||||||
class NotificationFilter: ObservableObject, Equatable {
|
class NotificationFilter: ObservableObject, Equatable {
|
||||||
@Published var state: NotificationFilterState
|
@Published var state: NotificationFilterState
|
||||||
@Published var friend_filter: FriendFilter
|
@Published var friend_filter: FriendFilter
|
||||||
@@ -76,6 +80,8 @@ struct NotificationsView: View {
|
|||||||
@SceneStorage("NotificationsView.filter_state") var filter_state: NotificationFilterState = .all
|
@SceneStorage("NotificationsView.filter_state") var filter_state: NotificationFilterState = .all
|
||||||
@Binding var subtitle: String?
|
@Binding var subtitle: String?
|
||||||
|
|
||||||
|
@State var showTip: Bool = true
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ struct DeveloperSettingsView: View {
|
|||||||
|
|
||||||
Toggle(NSLocalizedString("Enable experimental Purple In-app purchase support", comment: "Developer mode setting to enable experimental Purple In-app purchase support."), isOn: $settings.enable_experimental_purple_iap_support)
|
Toggle(NSLocalizedString("Enable experimental Purple In-app purchase support", comment: "Developer mode setting to enable experimental Purple In-app purchase support."), isOn: $settings.enable_experimental_purple_iap_support)
|
||||||
.toggleStyle(.switch)
|
.toggleStyle(.switch)
|
||||||
|
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
Toggle(NSLocalizedString("Reset tips on launch", comment: "Developer mode setting to reset tips upon app first launch. Tips are visual contextual hints that highlight new, interesting, or unused features users have not discovered yet."), isOn: $settings.reset_tips_on_launch)
|
||||||
|
.toggleStyle(.switch)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
damus/Views/Tips/TrustedNetworkRepliesTip.swift
Normal file
26
damus/Views/Tips/TrustedNetworkRepliesTip.swift
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// TrustedNetworkRepliesTip.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by Terry Yiu on 6/7/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import TipKit
|
||||||
|
|
||||||
|
@available(iOS 17, *)
|
||||||
|
struct TrustedNetworkRepliesTip: Tip {
|
||||||
|
static let shared = TrustedNetworkRepliesTip()
|
||||||
|
|
||||||
|
var title: Text {
|
||||||
|
Text("Toggle visibility of replies from outside your trusted network", comment: "Title of tip that informs users what trusted network means and that they can toggle the visibility of threaded replies from outside their trusted network.")
|
||||||
|
}
|
||||||
|
|
||||||
|
var message: Text? {
|
||||||
|
Text("Your trusted network is comprised of profiles you follow and profiles that they follow.", comment: "Description of the tip that informs users what trusted network means.")
|
||||||
|
}
|
||||||
|
|
||||||
|
var image: Image? {
|
||||||
|
Image(systemName: "network.badge.shield.half.filled")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user