Compare commits
3 Commits
pinned-not
...
web-of-tru
| Author | SHA1 | Date | |
|---|---|---|---|
|
ac39454a6e
|
|||
|
9eeb00c897
|
|||
|
140da5ba09
|
@@ -27,6 +27,12 @@
|
|||||||
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 */; };
|
||||||
|
3A515C542DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C532DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift */; };
|
||||||
|
3A515C552DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C532DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift */; };
|
||||||
|
3A515C562DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C532DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.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 */; };
|
||||||
@@ -35,6 +41,9 @@
|
|||||||
3A96E3FE2D6BCE3800AE1630 /* RepostedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A96E3FD2D6BCE3800AE1630 /* RepostedTests.swift */; };
|
3A96E3FE2D6BCE3800AE1630 /* RepostedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A96E3FD2D6BCE3800AE1630 /* RepostedTests.swift */; };
|
||||||
3AA247FF297E3D900090C62D /* RepostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA247FE297E3D900090C62D /* RepostsView.swift */; };
|
3AA247FF297E3D900090C62D /* RepostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA247FE297E3D900090C62D /* RepostsView.swift */; };
|
||||||
3AA24802297E3DC20090C62D /* RepostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA24801297E3DC20090C62D /* RepostView.swift */; };
|
3AA24802297E3DC20090C62D /* RepostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA24801297E3DC20090C62D /* RepostView.swift */; };
|
||||||
|
3AA2F4E82DF1467A00B18606 /* TrustedNetworkButtonTip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA2F4E72DF1467A00B18606 /* TrustedNetworkButtonTip.swift */; };
|
||||||
|
3AA2F4E92DF1467A00B18606 /* TrustedNetworkButtonTip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA2F4E72DF1467A00B18606 /* TrustedNetworkButtonTip.swift */; };
|
||||||
|
3AA2F4EA2DF1467A00B18606 /* TrustedNetworkButtonTip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA2F4E72DF1467A00B18606 /* TrustedNetworkButtonTip.swift */; };
|
||||||
3AA59D1D2999B0400061C48E /* DraftsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA59D1C2999B0400061C48E /* DraftsModel.swift */; };
|
3AA59D1D2999B0400061C48E /* DraftsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA59D1C2999B0400061C48E /* DraftsModel.swift */; };
|
||||||
3AAA95CA298DF87B00F3D526 /* TranslationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AAA95C9298DF87B00F3D526 /* TranslationService.swift */; };
|
3AAA95CA298DF87B00F3D526 /* TranslationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AAA95C9298DF87B00F3D526 /* TranslationService.swift */; };
|
||||||
3AAA95CC298E07E900F3D526 /* DeepLPlan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AAA95CB298E07E900F3D526 /* DeepLPlan.swift */; };
|
3AAA95CC298E07E900F3D526 /* DeepLPlan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AAA95CB298E07E900F3D526 /* DeepLPlan.swift */; };
|
||||||
@@ -264,7 +273,7 @@
|
|||||||
4C8D00CF29E38B950036AF10 /* nostr_bech32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D00CE29E38B950036AF10 /* nostr_bech32.c */; };
|
4C8D00CF29E38B950036AF10 /* nostr_bech32.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D00CE29E38B950036AF10 /* nostr_bech32.c */; };
|
||||||
4C8D00D429E3C5D40036AF10 /* NIP19Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D00D329E3C5D40036AF10 /* NIP19Tests.swift */; };
|
4C8D00D429E3C5D40036AF10 /* NIP19Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D00D329E3C5D40036AF10 /* NIP19Tests.swift */; };
|
||||||
4C8D1A6C29F1DFC200ACDF75 /* FriendIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D1A6B29F1DFC200ACDF75 /* FriendIcon.swift */; };
|
4C8D1A6C29F1DFC200ACDF75 /* FriendIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D1A6B29F1DFC200ACDF75 /* FriendIcon.swift */; };
|
||||||
4C8D1A6F29F31E5000ACDF75 /* FriendsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D1A6E29F31E5000ACDF75 /* FriendsButton.swift */; };
|
4C8D1A6F29F31E5000ACDF75 /* TrustedNetworkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D1A6E29F31E5000ACDF75 /* TrustedNetworkButton.swift */; };
|
||||||
4C8EC52529D1FA6C0085D9A8 /* DamusColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8EC52429D1FA6C0085D9A8 /* DamusColors.swift */; };
|
4C8EC52529D1FA6C0085D9A8 /* DamusColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8EC52429D1FA6C0085D9A8 /* DamusColors.swift */; };
|
||||||
4C8FA7242BED58A900798A6A /* ThreadReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C45E5012BED4D000025A428 /* ThreadReply.swift */; };
|
4C8FA7242BED58A900798A6A /* ThreadReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C45E5012BED4D000025A428 /* ThreadReply.swift */; };
|
||||||
4C9054852A6AEAA000811EEC /* NdbTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9054842A6AEAA000811EEC /* NdbTests.swift */; };
|
4C9054852A6AEAA000811EEC /* NdbTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9054842A6AEAA000811EEC /* NdbTests.swift */; };
|
||||||
@@ -763,7 +772,7 @@
|
|||||||
82D6FBD52CD99F7900C925F4 /* ConnectWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D095C2A098C5D00943473 /* ConnectWalletView.swift */; };
|
82D6FBD52CD99F7900C925F4 /* ConnectWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D095C2A098C5D00943473 /* ConnectWalletView.swift */; };
|
||||||
82D6FBD62CD99F7900C925F4 /* WalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D095D2A098C5D00943473 /* WalletView.swift */; };
|
82D6FBD62CD99F7900C925F4 /* WalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D095D2A098C5D00943473 /* WalletView.swift */; };
|
||||||
82D6FBD72CD99F7900C925F4 /* NWCScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09672A0AE9B200943473 /* NWCScannerView.swift */; };
|
82D6FBD72CD99F7900C925F4 /* NWCScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09672A0AE9B200943473 /* NWCScannerView.swift */; };
|
||||||
82D6FBD82CD99F7900C925F4 /* FriendsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D1A6E29F31E5000ACDF75 /* FriendsButton.swift */; };
|
82D6FBD82CD99F7900C925F4 /* TrustedNetworkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D1A6E29F31E5000ACDF75 /* TrustedNetworkButton.swift */; };
|
||||||
82D6FBD92CD99F7900C925F4 /* GradientFollowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694F32A6732B7001F4053 /* GradientFollowButton.swift */; };
|
82D6FBD92CD99F7900C925F4 /* GradientFollowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694F32A6732B7001F4053 /* GradientFollowButton.swift */; };
|
||||||
82D6FBDA2CD99F7900C925F4 /* AlbyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09652A0AE62100943473 /* AlbyButton.swift */; };
|
82D6FBDA2CD99F7900C925F4 /* AlbyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09652A0AE62100943473 /* AlbyButton.swift */; };
|
||||||
82D6FBDC2CD99F7900C925F4 /* DamusVideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A2929DDF54400516EAC /* DamusVideoPlayerView.swift */; };
|
82D6FBDC2CD99F7900C925F4 /* DamusVideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A2929DDF54400516EAC /* DamusVideoPlayerView.swift */; };
|
||||||
@@ -1305,7 +1314,7 @@
|
|||||||
D73E5ECC2C6A97F4007EB227 /* SuggestedUsersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694EB2A662292001F4053 /* SuggestedUsersViewModel.swift */; };
|
D73E5ECC2C6A97F4007EB227 /* SuggestedUsersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694EB2A662292001F4053 /* SuggestedUsersViewModel.swift */; };
|
||||||
D73E5ED22C6A97F4007EB227 /* WalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D095D2A098C5D00943473 /* WalletView.swift */; };
|
D73E5ED22C6A97F4007EB227 /* WalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D095D2A098C5D00943473 /* WalletView.swift */; };
|
||||||
D73E5ED32C6A97F4007EB227 /* NWCScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09672A0AE9B200943473 /* NWCScannerView.swift */; };
|
D73E5ED32C6A97F4007EB227 /* NWCScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09672A0AE9B200943473 /* NWCScannerView.swift */; };
|
||||||
D73E5ED42C6A97F4007EB227 /* FriendsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D1A6E29F31E5000ACDF75 /* FriendsButton.swift */; };
|
D73E5ED42C6A97F4007EB227 /* TrustedNetworkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C8D1A6E29F31E5000ACDF75 /* TrustedNetworkButton.swift */; };
|
||||||
D73E5ED52C6A97F4007EB227 /* GradientFollowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694F32A6732B7001F4053 /* GradientFollowButton.swift */; };
|
D73E5ED52C6A97F4007EB227 /* GradientFollowButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F71694F32A6732B7001F4053 /* GradientFollowButton.swift */; };
|
||||||
D73E5ED62C6A97F4007EB227 /* AlbyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09652A0AE62100943473 /* AlbyButton.swift */; };
|
D73E5ED62C6A97F4007EB227 /* AlbyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09652A0AE62100943473 /* AlbyButton.swift */; };
|
||||||
D73E5ED82C6A97F4007EB227 /* DamusVideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A2929DDF54400516EAC /* DamusVideoPlayerView.swift */; };
|
D73E5ED82C6A97F4007EB227 /* DamusVideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A2929DDF54400516EAC /* DamusVideoPlayerView.swift */; };
|
||||||
@@ -1855,6 +1864,8 @@
|
|||||||
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>"; };
|
||||||
|
3A515C532DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustedNetworkButtonTipViewStyle.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>"; };
|
||||||
@@ -1889,6 +1900,7 @@
|
|||||||
3A994C4E2BE5B9370019F632 /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/Localizable.strings; sourceTree = "<group>"; };
|
3A994C4E2BE5B9370019F632 /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
3AA247FE297E3D900090C62D /* RepostsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepostsView.swift; sourceTree = "<group>"; };
|
3AA247FE297E3D900090C62D /* RepostsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepostsView.swift; sourceTree = "<group>"; };
|
||||||
3AA24801297E3DC20090C62D /* RepostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepostView.swift; sourceTree = "<group>"; };
|
3AA24801297E3DC20090C62D /* RepostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepostView.swift; sourceTree = "<group>"; };
|
||||||
|
3AA2F4E72DF1467A00B18606 /* TrustedNetworkButtonTip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustedNetworkButtonTip.swift; sourceTree = "<group>"; };
|
||||||
3AA59D1C2999B0400061C48E /* DraftsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsModel.swift; sourceTree = "<group>"; };
|
3AA59D1C2999B0400061C48E /* DraftsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsModel.swift; sourceTree = "<group>"; };
|
||||||
3AA5E70229B682A5002701ED /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = "<group>"; };
|
3AA5E70229B682A5002701ED /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
3AA5E70329B682AD002701ED /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
3AA5E70329B682AD002701ED /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
@@ -2276,7 +2288,7 @@
|
|||||||
4C8D00D229E3C19F0036AF10 /* str_block.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = str_block.h; sourceTree = "<group>"; };
|
4C8D00D229E3C19F0036AF10 /* str_block.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = str_block.h; sourceTree = "<group>"; };
|
||||||
4C8D00D329E3C5D40036AF10 /* NIP19Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP19Tests.swift; sourceTree = "<group>"; };
|
4C8D00D329E3C5D40036AF10 /* NIP19Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP19Tests.swift; sourceTree = "<group>"; };
|
||||||
4C8D1A6B29F1DFC200ACDF75 /* FriendIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendIcon.swift; sourceTree = "<group>"; };
|
4C8D1A6B29F1DFC200ACDF75 /* FriendIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendIcon.swift; sourceTree = "<group>"; };
|
||||||
4C8D1A6E29F31E5000ACDF75 /* FriendsButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendsButton.swift; sourceTree = "<group>"; };
|
4C8D1A6E29F31E5000ACDF75 /* TrustedNetworkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustedNetworkButton.swift; sourceTree = "<group>"; };
|
||||||
4C8EC52429D1FA6C0085D9A8 /* DamusColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusColors.swift; sourceTree = "<group>"; };
|
4C8EC52429D1FA6C0085D9A8 /* DamusColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusColors.swift; sourceTree = "<group>"; };
|
||||||
4C9054842A6AEAA000811EEC /* NdbTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NdbTests.swift; sourceTree = "<group>"; };
|
4C9054842A6AEAA000811EEC /* NdbTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NdbTests.swift; sourceTree = "<group>"; };
|
||||||
4C9054882A6AED4700811EEC /* NdbTagIterator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NdbTagIterator.swift; sourceTree = "<group>"; };
|
4C9054882A6AED4700811EEC /* NdbTagIterator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NdbTagIterator.swift; sourceTree = "<group>"; };
|
||||||
@@ -2728,6 +2740,16 @@
|
|||||||
path = "Empty Views";
|
path = "Empty Views";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
3A515C4E2DF4E0E6002D3B34 /* Tips */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3AA2F4E72DF1467A00B18606 /* TrustedNetworkButtonTip.swift */,
|
||||||
|
3A515C532DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift */,
|
||||||
|
3A515C4F2DF4E100002D3B34 /* TrustedNetworkRepliesTip.swift */,
|
||||||
|
);
|
||||||
|
path = Tips;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
3AA24800297E3DAE0090C62D /* Reposts */ = {
|
3AA24800297E3DAE0090C62D /* Reposts */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -3223,6 +3245,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 */,
|
||||||
@@ -3420,7 +3443,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5CB017202D2D985800A9ED05 /* CoinosButton.swift */,
|
5CB017202D2D985800A9ED05 /* CoinosButton.swift */,
|
||||||
4C8D1A6E29F31E5000ACDF75 /* FriendsButton.swift */,
|
4C8D1A6E29F31E5000ACDF75 /* TrustedNetworkButton.swift */,
|
||||||
F71694F32A6732B7001F4053 /* GradientFollowButton.swift */,
|
F71694F32A6732B7001F4053 /* GradientFollowButton.swift */,
|
||||||
4C7D09652A0AE62100943473 /* AlbyButton.swift */,
|
4C7D09652A0AE62100943473 /* AlbyButton.swift */,
|
||||||
);
|
);
|
||||||
@@ -4646,7 +4669,7 @@
|
|||||||
4C3D52B8298DB5C6001C5831 /* TextEvent.swift in Sources */,
|
4C3D52B8298DB5C6001C5831 /* TextEvent.swift in Sources */,
|
||||||
4C216F362870A9A700040376 /* InputDismissKeyboard.swift in Sources */,
|
4C216F362870A9A700040376 /* InputDismissKeyboard.swift in Sources */,
|
||||||
D74AAFCF2B155D8C006CF0F4 /* ZapDataModel.swift in Sources */,
|
D74AAFCF2B155D8C006CF0F4 /* ZapDataModel.swift in Sources */,
|
||||||
4C8D1A6F29F31E5000ACDF75 /* FriendsButton.swift in Sources */,
|
4C8D1A6F29F31E5000ACDF75 /* TrustedNetworkButton.swift in Sources */,
|
||||||
D7100C562B76F8E600C59298 /* PurpleViewPrimitives.swift in Sources */,
|
D7100C562B76F8E600C59298 /* PurpleViewPrimitives.swift in Sources */,
|
||||||
B57B4C642B312BFA00A232C0 /* RelayAuthenticationDetail.swift in Sources */,
|
B57B4C642B312BFA00A232C0 /* RelayAuthenticationDetail.swift in Sources */,
|
||||||
D7EDED2E2B128E8A0018B19C /* CollectionExtension.swift in Sources */,
|
D7EDED2E2B128E8A0018B19C /* CollectionExtension.swift in Sources */,
|
||||||
@@ -4732,6 +4755,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 */,
|
||||||
@@ -4826,6 +4850,7 @@
|
|||||||
4CA352A22A76AEC5003BB08B /* LikedNotify.swift in Sources */,
|
4CA352A22A76AEC5003BB08B /* LikedNotify.swift in Sources */,
|
||||||
5CC8529F2BD744F60039FFC5 /* HighlightView.swift in Sources */,
|
5CC8529F2BD744F60039FFC5 /* HighlightView.swift in Sources */,
|
||||||
BA37598D2ABCCE500018D73B /* PhotoCaptureProcessor.swift in Sources */,
|
BA37598D2ABCCE500018D73B /* PhotoCaptureProcessor.swift in Sources */,
|
||||||
|
3A515C562DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */,
|
||||||
5CC8529D2BD741CD0039FFC5 /* HighlightEvent.swift in Sources */,
|
5CC8529D2BD741CD0039FFC5 /* HighlightEvent.swift in Sources */,
|
||||||
4C9146FD2A2A87C200DDEA40 /* wasm.c in Sources */,
|
4C9146FD2A2A87C200DDEA40 /* wasm.c in Sources */,
|
||||||
4C75EFAF28049D350006080F /* NostrFilter.swift in Sources */,
|
4C75EFAF28049D350006080F /* NostrFilter.swift in Sources */,
|
||||||
@@ -4872,6 +4897,7 @@
|
|||||||
4C1A9A2729DDE31900516EAC /* TranslationSettingsView.swift in Sources */,
|
4C1A9A2729DDE31900516EAC /* TranslationSettingsView.swift in Sources */,
|
||||||
BA3759942ABCCEBA0018D73B /* CameraService.swift in Sources */,
|
BA3759942ABCCEBA0018D73B /* CameraService.swift in Sources */,
|
||||||
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */,
|
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */,
|
||||||
|
3AA2F4E82DF1467A00B18606 /* TrustedNetworkButtonTip.swift in Sources */,
|
||||||
4CF0ABD82981980C00D66079 /* Lists.swift in Sources */,
|
4CF0ABD82981980C00D66079 /* Lists.swift in Sources */,
|
||||||
F71694EA2A662232001F4053 /* OnboardingSuggestionsView.swift in Sources */,
|
F71694EA2A662232001F4053 /* OnboardingSuggestionsView.swift in Sources */,
|
||||||
4C12536A2A76D3850004F4B8 /* RelaysChangedNotify.swift in Sources */,
|
4C12536A2A76D3850004F4B8 /* RelaysChangedNotify.swift in Sources */,
|
||||||
@@ -5125,6 +5151,7 @@
|
|||||||
82D6FAB42CD99F7900C925F4 /* Verifiable.swift in Sources */,
|
82D6FAB42CD99F7900C925F4 /* Verifiable.swift in Sources */,
|
||||||
82D6FAB52CD99F7900C925F4 /* NativeObject.swift in Sources */,
|
82D6FAB52CD99F7900C925F4 /* NativeObject.swift in Sources */,
|
||||||
82D6FAB62CD99F7900C925F4 /* String+extension.swift in Sources */,
|
82D6FAB62CD99F7900C925F4 /* String+extension.swift in Sources */,
|
||||||
|
3A515C552DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */,
|
||||||
82D6FAB72CD99F7900C925F4 /* FlatBufferObject.swift in Sources */,
|
82D6FAB72CD99F7900C925F4 /* FlatBufferObject.swift in Sources */,
|
||||||
82D6FAB82CD99F7900C925F4 /* Enum.swift in Sources */,
|
82D6FAB82CD99F7900C925F4 /* Enum.swift in Sources */,
|
||||||
82D6FAB92CD99F7900C925F4 /* builder.c in Sources */,
|
82D6FAB92CD99F7900C925F4 /* builder.c in Sources */,
|
||||||
@@ -5374,6 +5401,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 */,
|
||||||
@@ -5424,13 +5452,14 @@
|
|||||||
82D6FBCC2CD99F7900C925F4 /* CameraPreview.swift in Sources */,
|
82D6FBCC2CD99F7900C925F4 /* CameraPreview.swift in Sources */,
|
||||||
82D6FBCD2CD99F7900C925F4 /* CameraController.swift in Sources */,
|
82D6FBCD2CD99F7900C925F4 /* CameraController.swift in Sources */,
|
||||||
82D6FBCE2CD99F7900C925F4 /* OnboardingSuggestionsView.swift in Sources */,
|
82D6FBCE2CD99F7900C925F4 /* OnboardingSuggestionsView.swift in Sources */,
|
||||||
|
3AA2F4EA2DF1467A00B18606 /* TrustedNetworkButtonTip.swift in Sources */,
|
||||||
82D6FBCF2CD99F7900C925F4 /* SuggestedUserView.swift in Sources */,
|
82D6FBCF2CD99F7900C925F4 /* SuggestedUserView.swift in Sources */,
|
||||||
82D6FBD02CD99F7900C925F4 /* SuggestedUsersViewModel.swift in Sources */,
|
82D6FBD02CD99F7900C925F4 /* SuggestedUsersViewModel.swift in Sources */,
|
||||||
82D6FBD12CD99F7900C925F4 /* LoadScript.swift in Sources */,
|
82D6FBD12CD99F7900C925F4 /* LoadScript.swift in Sources */,
|
||||||
82D6FBD52CD99F7900C925F4 /* ConnectWalletView.swift in Sources */,
|
82D6FBD52CD99F7900C925F4 /* ConnectWalletView.swift in Sources */,
|
||||||
82D6FBD62CD99F7900C925F4 /* WalletView.swift in Sources */,
|
82D6FBD62CD99F7900C925F4 /* WalletView.swift in Sources */,
|
||||||
82D6FBD72CD99F7900C925F4 /* NWCScannerView.swift in Sources */,
|
82D6FBD72CD99F7900C925F4 /* NWCScannerView.swift in Sources */,
|
||||||
82D6FBD82CD99F7900C925F4 /* FriendsButton.swift in Sources */,
|
82D6FBD82CD99F7900C925F4 /* TrustedNetworkButton.swift in Sources */,
|
||||||
82D6FBD92CD99F7900C925F4 /* GradientFollowButton.swift in Sources */,
|
82D6FBD92CD99F7900C925F4 /* GradientFollowButton.swift in Sources */,
|
||||||
82D6FBDA2CD99F7900C925F4 /* AlbyButton.swift in Sources */,
|
82D6FBDA2CD99F7900C925F4 /* AlbyButton.swift in Sources */,
|
||||||
82D6FBDC2CD99F7900C925F4 /* DamusVideoPlayerView.swift in Sources */,
|
82D6FBDC2CD99F7900C925F4 /* DamusVideoPlayerView.swift in Sources */,
|
||||||
@@ -5628,6 +5657,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 */,
|
||||||
@@ -5734,6 +5764,7 @@
|
|||||||
D73E5E922C6A97F4007EB227 /* EventGroup.swift in Sources */,
|
D73E5E922C6A97F4007EB227 /* EventGroup.swift in Sources */,
|
||||||
D73E5E932C6A97F4007EB227 /* ZapGroup.swift in Sources */,
|
D73E5E932C6A97F4007EB227 /* ZapGroup.swift in Sources */,
|
||||||
D73E5E942C6A97F4007EB227 /* NotificationStatusModel.swift in Sources */,
|
D73E5E942C6A97F4007EB227 /* NotificationStatusModel.swift in Sources */,
|
||||||
|
3A515C542DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */,
|
||||||
D73E5E952C6A97F4007EB227 /* ThreadModel.swift in Sources */,
|
D73E5E952C6A97F4007EB227 /* ThreadModel.swift in Sources */,
|
||||||
D73E5E962C6A97F4007EB227 /* ReplyMap.swift in Sources */,
|
D73E5E962C6A97F4007EB227 /* ReplyMap.swift in Sources */,
|
||||||
D73E5E972C6A97F4007EB227 /* ProfileModel.swift in Sources */,
|
D73E5E972C6A97F4007EB227 /* ProfileModel.swift in Sources */,
|
||||||
@@ -5792,6 +5823,7 @@
|
|||||||
D73E5EC02C6A97F4007EB227 /* NostrEvent+.swift in Sources */,
|
D73E5EC02C6A97F4007EB227 /* NostrEvent+.swift in Sources */,
|
||||||
D73E5EC12C6A97F4007EB227 /* NIP98AuthenticatedRequest.swift in Sources */,
|
D73E5EC12C6A97F4007EB227 /* NIP98AuthenticatedRequest.swift in Sources */,
|
||||||
D73E5EC22C6A97F4007EB227 /* NostrAuth.swift in Sources */,
|
D73E5EC22C6A97F4007EB227 /* NostrAuth.swift in Sources */,
|
||||||
|
3AA2F4E92DF1467A00B18606 /* TrustedNetworkButtonTip.swift in Sources */,
|
||||||
D73E5EC42C6A97F4007EB227 /* ReplyQuoteView.swift in Sources */,
|
D73E5EC42C6A97F4007EB227 /* ReplyQuoteView.swift in Sources */,
|
||||||
D73E5EC62C6A97F4007EB227 /* ChatBubbleView.swift in Sources */,
|
D73E5EC62C6A97F4007EB227 /* ChatBubbleView.swift in Sources */,
|
||||||
D73E5EC72C6A97F4007EB227 /* VisibilityTracker.swift in Sources */,
|
D73E5EC72C6A97F4007EB227 /* VisibilityTracker.swift in Sources */,
|
||||||
@@ -5803,7 +5835,7 @@
|
|||||||
D73E5ED22C6A97F4007EB227 /* WalletView.swift in Sources */,
|
D73E5ED22C6A97F4007EB227 /* WalletView.swift in Sources */,
|
||||||
D73E5ED32C6A97F4007EB227 /* NWCScannerView.swift in Sources */,
|
D73E5ED32C6A97F4007EB227 /* NWCScannerView.swift in Sources */,
|
||||||
D74E64132DC95CC7004C7892 /* HumanReadableErrors.swift in Sources */,
|
D74E64132DC95CC7004C7892 /* HumanReadableErrors.swift in Sources */,
|
||||||
D73E5ED42C6A97F4007EB227 /* FriendsButton.swift in Sources */,
|
D73E5ED42C6A97F4007EB227 /* TrustedNetworkButton.swift in Sources */,
|
||||||
D73E5ED52C6A97F4007EB227 /* GradientFollowButton.swift in Sources */,
|
D73E5ED52C6A97F4007EB227 /* GradientFollowButton.swift in Sources */,
|
||||||
D73E5ED62C6A97F4007EB227 /* AlbyButton.swift in Sources */,
|
D73E5ED62C6A97F4007EB227 /* AlbyButton.swift in Sources */,
|
||||||
D73E5ED82C6A97F4007EB227 /* DamusVideoPlayerView.swift in Sources */,
|
D73E5ED82C6A97F4007EB227 /* DamusVideoPlayerView.swift in Sources */,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import SwiftUI
|
|||||||
import AVKit
|
import AVKit
|
||||||
import MediaPlayer
|
import MediaPlayer
|
||||||
import EmojiPicker
|
import EmojiPicker
|
||||||
|
import TipKit
|
||||||
|
|
||||||
struct ZapSheet {
|
struct ZapSheet {
|
||||||
let target: ZapTarget
|
let target: ZapTarget
|
||||||
@@ -178,7 +179,7 @@ struct ContentView: View {
|
|||||||
NotificationsView(state: damus, notifications: home.notifications, subtitle: $menu_subtitle)
|
NotificationsView(state: damus, notifications: home.notifications, subtitle: $menu_subtitle)
|
||||||
|
|
||||||
case .dms:
|
case .dms:
|
||||||
DirectMessagesView(damus_state: damus_state!, model: damus_state!.dms, settings: damus_state!.settings)
|
DirectMessagesView(damus_state: damus_state!, model: damus_state!.dms, settings: damus_state!.settings, subtitle: $menu_subtitle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.background(DamusColors.adaptableWhite)
|
.background(DamusColors.adaptableWhite)
|
||||||
@@ -705,6 +706,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) {
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ enum FriendFilter: String, StringCodable {
|
|||||||
func description() -> String {
|
func description() -> String {
|
||||||
switch self {
|
switch self {
|
||||||
case .all:
|
case .all:
|
||||||
return NSLocalizedString("All", comment: "Human-readable short description of the 'friends filter' when it is set to 'all'")
|
return NSLocalizedString("All", comment: "Human-readable short description of the 'trusted network filter' when it is disabled, and therefore is showing all content.")
|
||||||
case .friends_of_friends:
|
case .friends_of_friends:
|
||||||
return NSLocalizedString("Friends of friends", comment: "Human-readable short description of the 'friends filter' when it is set to 'friends-of-friends'")
|
return NSLocalizedString("Trusted Network", comment: "Human-readable short description of the 'trusted network filter' when it is enabled, and therefore showing content from only the trusted network.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,12 @@ class UserSettingsStore: ObservableObject {
|
|||||||
@Setting(key: "media_previews", default_value: true)
|
@Setting(key: "media_previews", default_value: true)
|
||||||
var media_previews: Bool
|
var media_previews: Bool
|
||||||
|
|
||||||
|
@Setting(key: "show_trusted_replies_first", default_value: true)
|
||||||
|
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
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
//
|
|
||||||
// FriendsButton.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2023-04-21.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct FriendsButton: View {
|
|
||||||
@Binding var filter: FriendFilter
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
Button(action: {
|
|
||||||
switch self.filter {
|
|
||||||
case .all:
|
|
||||||
self.filter = .friends_of_friends
|
|
||||||
case .friends_of_friends:
|
|
||||||
self.filter = .all
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
if filter == .friends_of_friends {
|
|
||||||
LINEAR_GRADIENT
|
|
||||||
.mask(Image("user-added")
|
|
||||||
.resizable()
|
|
||||||
).frame(width: 28, height: 28)
|
|
||||||
} else {
|
|
||||||
Image("user-added")
|
|
||||||
.resizable()
|
|
||||||
.frame(width: 28, height: 28)
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.buttonStyle(.plain)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FriendsButton_Previews: PreviewProvider {
|
|
||||||
@State static var enabled: FriendFilter = .all
|
|
||||||
|
|
||||||
static var previews: some View {
|
|
||||||
FriendsButton(filter: $enabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
54
damus/Views/Buttons/TrustedNetworkButton.swift
Normal file
54
damus/Views/Buttons/TrustedNetworkButton.swift
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// TrustedNetworkButton.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by William Casarin on 2023-04-21.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct TrustedNetworkButton: View {
|
||||||
|
@Binding var filter: FriendFilter
|
||||||
|
var action: (@MainActor () -> Void)? = nil
|
||||||
|
|
||||||
|
var MainButton: some View {
|
||||||
|
Button(action: {
|
||||||
|
switch self.filter {
|
||||||
|
case .all:
|
||||||
|
self.filter = .friends_of_friends
|
||||||
|
case .friends_of_friends:
|
||||||
|
self.filter = .all
|
||||||
|
}
|
||||||
|
|
||||||
|
if let action {
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
if filter == .friends_of_friends {
|
||||||
|
LINEAR_GRADIENT
|
||||||
|
.mask(Image(systemName: "network.badge.shield.half.filled")
|
||||||
|
.frame(width: 24, height: 24)
|
||||||
|
)
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 24, height: 24)
|
||||||
|
} else {
|
||||||
|
Image(systemName: "network.slash")
|
||||||
|
.frame(width: 24, height: 24)
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
MainButton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TrustedNetworkButton_Previews: PreviewProvider {
|
||||||
|
@State static var enabled: FriendFilter = .all
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
TrustedNetworkButton(filter: $enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -337,12 +337,6 @@ struct ChatEventView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Notification.Name {
|
|
||||||
static var toggle_thread_view: Notification.Name {
|
|
||||||
return Notification.Name("convert_to_thread")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
let bar = make_actionbar_model(ev: test_note.id, damus: test_damus_state)
|
let bar = make_actionbar_model(ev: test_note.id, damus: test_damus_state)
|
||||||
return ChatEventView(event: test_note, selected_event: test_note, prev_ev: nil, next_ev: nil, damus_state: test_damus_state, thread: ThreadModel(event: test_note, damus_state: test_damus_state), scroll_to_event: nil, focus_event: nil, highlight_bubble: false, bar: bar)
|
return ChatEventView(event: test_note, selected_event: test_note, prev_ev: nil, next_ev: nil, damus_state: test_damus_state, thread: ThreadModel(event: test_note, damus_state: test_damus_state), scroll_to_event: nil, focus_event: nil, highlight_bubble: false, bar: bar)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -15,11 +16,20 @@ struct ChatroomThreadView: View {
|
|||||||
@ObservedObject var thread: ThreadModel
|
@ObservedObject var thread: ThreadModel
|
||||||
@State var highlighted_note_id: NoteId? = nil
|
@State var highlighted_note_id: NoteId? = nil
|
||||||
@State var user_just_posted_flag: Bool = false
|
@State var user_just_posted_flag: Bool = false
|
||||||
|
@State var untrusted_network_expanded: Bool = true
|
||||||
@Namespace private var animation
|
@Namespace private var animation
|
||||||
|
|
||||||
|
// Add state for sticky header
|
||||||
|
@State var showStickyHeader: Bool = false
|
||||||
|
@State var untrustedSectionOffset: CGFloat = 0
|
||||||
|
|
||||||
|
private static let untrusted_network_section_id = "untrusted-network-section"
|
||||||
|
private static let sticky_header_adjusted_anchor = UnitPoint(x: UnitPoint.top.x, y: 0.2)
|
||||||
|
|
||||||
func go_to_event(scroller: ScrollViewProxy, note_id: NoteId) {
|
func go_to_event(scroller: ScrollViewProxy, note_id: NoteId) {
|
||||||
scroll_to_event(scroller: scroller, id: note_id, delay: 0, animate: true, anchor: .top)
|
let adjustedAnchor: UnitPoint = showStickyHeader ? ChatroomThreadView.sticky_header_adjusted_anchor : .top
|
||||||
|
|
||||||
|
scroll_to_event(scroller: scroller, id: note_id, delay: 0, animate: true, anchor: adjustedAnchor)
|
||||||
highlighted_note_id = note_id
|
highlighted_note_id = note_id
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
@@ -35,93 +45,202 @@ struct ChatroomThreadView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func trusted_event_filter(_ event: NostrEvent) -> Bool {
|
||||||
|
!damus.settings.show_trusted_replies_first || damus.contacts.is_in_friendosphere(event.pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ThreadedSwipeViewGroup(scroller: ScrollViewProxy, events: [NostrEvent]) -> some View {
|
||||||
|
SwipeViewGroup {
|
||||||
|
ForEach(Array(zip(events, events.indices)), id: \.0.id) { (ev, ind) in
|
||||||
|
ChatEventView(event: events[ind],
|
||||||
|
selected_event: self.thread.selected_event,
|
||||||
|
prev_ev: ind > 0 ? events[ind-1] : nil,
|
||||||
|
next_ev: ind == events.count-1 ? nil : events[ind+1],
|
||||||
|
damus_state: damus,
|
||||||
|
thread: thread,
|
||||||
|
scroll_to_event: { note_id in
|
||||||
|
self.go_to_event(scroller: scroller, note_id: note_id)
|
||||||
|
},
|
||||||
|
focus_event: {
|
||||||
|
self.set_active_event(scroller: scroller, ev: ev)
|
||||||
|
},
|
||||||
|
highlight_bubble: highlighted_note_id == ev.id,
|
||||||
|
bar: make_actionbar_model(ev: ev.id, damus: damus)
|
||||||
|
)
|
||||||
|
.id(ev.id)
|
||||||
|
.matchedGeometryEffect(id: ev.id.hex(), in: animation, anchor: .center)
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var OutsideTrustedNetworkLabel: some View {
|
||||||
|
HStack {
|
||||||
|
Label(
|
||||||
|
NSLocalizedString(
|
||||||
|
"Replies outside your trusted network",
|
||||||
|
comment: "Section title in thread for replies from outside of the current user's trusted network, which is their follows and follows of follows."),
|
||||||
|
systemImage: "network.slash"
|
||||||
|
)
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: "chevron.right")
|
||||||
|
.rotationEffect(.degrees(untrusted_network_expanded ? 90 : 0))
|
||||||
|
.animation(.easeInOut(duration: 0.1), value: untrusted_network_expanded)
|
||||||
|
}
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
|
||||||
|
var StickyHeaderView: some View {
|
||||||
|
OutsideTrustedNetworkLabel
|
||||||
|
.padding(.horizontal)
|
||||||
|
.padding(.vertical, 12)
|
||||||
|
.background(
|
||||||
|
Color(UIColor.systemBackground)
|
||||||
|
.shadow(color: .black.opacity(0.15), radius: 3, x: 0, y: 2)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollViewReader { scroller in
|
ScrollViewReader { scroller in
|
||||||
ScrollView(.vertical) {
|
let sorted_child_events = thread.sorted_child_events
|
||||||
LazyVStack(alignment: .leading, spacing: 8) {
|
|
||||||
// MARK: - Parents events view
|
|
||||||
ForEach(thread.parent_events, id: \.id) { parent_event in
|
|
||||||
EventMutingContainerView(damus_state: damus, event: parent_event) {
|
|
||||||
EventView(damus: damus, event: parent_event)
|
|
||||||
.matchedGeometryEffect(id: parent_event.id.hex(), in: animation, anchor: .center)
|
|
||||||
}
|
|
||||||
.padding(.horizontal)
|
|
||||||
.onTapGesture {
|
|
||||||
self.set_active_event(scroller: scroller, ev: parent_event)
|
|
||||||
}
|
|
||||||
.id(parent_event.id)
|
|
||||||
|
|
||||||
Divider()
|
let untrusted_events = sorted_child_events.filter { !trusted_event_filter($0) }
|
||||||
.padding(.top, 4)
|
let trusted_events = sorted_child_events.filter { trusted_event_filter($0) }
|
||||||
.padding(.leading, 25 * 2)
|
|
||||||
|
|
||||||
}.background(GeometryReader { geometry in
|
ZStack(alignment: .top) {
|
||||||
// get the height and width of the EventView view
|
ScrollView(.vertical) {
|
||||||
let eventHeight = geometry.frame(in: .global).height
|
LazyVStack(alignment: .leading, spacing: 8) {
|
||||||
// let eventWidth = geometry.frame(in: .global).width
|
// MARK: - Parents events view
|
||||||
|
ForEach(thread.parent_events, id: \.id) { parent_event in
|
||||||
// vertical gray line in the background
|
EventMutingContainerView(damus_state: damus, event: parent_event) {
|
||||||
Rectangle()
|
EventView(damus: damus, event: parent_event)
|
||||||
.fill(Color.gray.opacity(0.25))
|
.matchedGeometryEffect(id: parent_event.id.hex(), in: animation, anchor: .center)
|
||||||
.frame(width: 2, height: eventHeight)
|
}
|
||||||
.offset(x: 40, y: 40)
|
|
||||||
})
|
|
||||||
|
|
||||||
// MARK: - Actual event view
|
|
||||||
EventMutingContainerView(
|
|
||||||
damus_state: damus,
|
|
||||||
event: self.thread.selected_event,
|
|
||||||
muteBox: { event_shown, muted_reason in
|
|
||||||
AnyView(
|
|
||||||
EventMutedBoxView(shown: event_shown, reason: muted_reason)
|
|
||||||
.padding(5)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
SelectedEventView(damus: damus, event: self.thread.selected_event, size: .selected)
|
|
||||||
.matchedGeometryEffect(id: self.thread.selected_event.id.hex(), in: animation, anchor: .center)
|
|
||||||
}
|
|
||||||
.id(self.thread.selected_event.id)
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Children view
|
|
||||||
let events = thread.sorted_child_events
|
|
||||||
let count = events.count
|
|
||||||
SwipeViewGroup {
|
|
||||||
ForEach(Array(zip(events, events.indices)), id: \.0.id) { (ev, ind) in
|
|
||||||
ChatEventView(event: events[ind],
|
|
||||||
selected_event: self.thread.selected_event,
|
|
||||||
prev_ev: ind > 0 ? events[ind-1] : nil,
|
|
||||||
next_ev: ind == count-1 ? nil : events[ind+1],
|
|
||||||
damus_state: damus,
|
|
||||||
thread: thread,
|
|
||||||
scroll_to_event: { note_id in
|
|
||||||
self.go_to_event(scroller: scroller, note_id: note_id)
|
|
||||||
},
|
|
||||||
focus_event: {
|
|
||||||
self.set_active_event(scroller: scroller, ev: ev)
|
|
||||||
},
|
|
||||||
highlight_bubble: highlighted_note_id == ev.id,
|
|
||||||
bar: make_actionbar_model(ev: ev.id, damus: damus)
|
|
||||||
)
|
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
.id(ev.id)
|
.onTapGesture {
|
||||||
.matchedGeometryEffect(id: ev.id.hex(), in: animation, anchor: .center)
|
self.set_active_event(scroller: scroller, ev: parent_event)
|
||||||
|
}
|
||||||
|
.id(parent_event.id)
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
.padding(.top, 4)
|
||||||
|
.padding(.leading, 25 * 2)
|
||||||
|
|
||||||
|
}.background(GeometryReader { geometry in
|
||||||
|
let eventHeight = geometry.frame(in: .global).height
|
||||||
|
|
||||||
|
Rectangle()
|
||||||
|
.fill(Color.gray.opacity(0.25))
|
||||||
|
.frame(width: 2, height: eventHeight)
|
||||||
|
.offset(x: 40, y: 40)
|
||||||
|
})
|
||||||
|
|
||||||
|
// MARK: - Actual event view
|
||||||
|
EventMutingContainerView(
|
||||||
|
damus_state: damus,
|
||||||
|
event: self.thread.selected_event,
|
||||||
|
muteBox: { event_shown, muted_reason in
|
||||||
|
AnyView(
|
||||||
|
EventMutedBoxView(shown: event_shown, reason: muted_reason)
|
||||||
|
.padding(5)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
SelectedEventView(damus: damus, event: self.thread.selected_event, size: .selected)
|
||||||
|
.matchedGeometryEffect(id: self.thread.selected_event.id.hex(), in: animation, anchor: .center)
|
||||||
|
}
|
||||||
|
.id(self.thread.selected_event.id)
|
||||||
|
|
||||||
|
// MARK: - Children view - inside trusted network
|
||||||
|
if !trusted_events.isEmpty {
|
||||||
|
ThreadedSwipeViewGroup(scroller: scroller, events: trusted_events)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.padding(.top)
|
||||||
.padding(.top)
|
|
||||||
EndBlock()
|
|
||||||
|
|
||||||
HStack {}
|
// MARK: - Children view - outside trusted network
|
||||||
.frame(height: tabHeight + getSafeAreaBottom())
|
if !untrusted_events.isEmpty {
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
TipView(TrustedNetworkRepliesTip.shared, arrowEdge: .bottom)
|
||||||
|
.padding(.top, 10)
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
// Track this section's position
|
||||||
|
Color.clear
|
||||||
|
.frame(height: 1)
|
||||||
|
.background(
|
||||||
|
GeometryReader { proxy in
|
||||||
|
Color.clear
|
||||||
|
.onAppear {
|
||||||
|
untrustedSectionOffset = proxy.frame(in: .global).minY
|
||||||
|
}
|
||||||
|
.onChange(of: proxy.frame(in: .global).minY) { newY in
|
||||||
|
let shouldShow = newY <= 100 // Adjust this threshold as needed
|
||||||
|
if shouldShow != showStickyHeader {
|
||||||
|
withAnimation(.easeInOut(duration: 0.3)) {
|
||||||
|
showStickyHeader = shouldShow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Button(action: {
|
||||||
|
withAnimation {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
OutsideTrustedNetworkLabel
|
||||||
|
}
|
||||||
|
.id(ChatroomThreadView.untrusted_network_section_id)
|
||||||
|
.buttonStyle(PlainButtonStyle())
|
||||||
|
.padding(.horizontal)
|
||||||
|
|
||||||
|
if untrusted_network_expanded {
|
||||||
|
withAnimation {
|
||||||
|
LazyVStack(alignment: .leading, spacing: 8) {
|
||||||
|
ThreadedSwipeViewGroup(scroller: scroller, events: untrusted_events)
|
||||||
|
}
|
||||||
|
.padding(.top, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EndBlock()
|
||||||
|
|
||||||
|
HStack {}
|
||||||
|
.frame(height: tabHeight + getSafeAreaBottom())
|
||||||
|
}
|
||||||
|
|
||||||
|
if showStickyHeader && !untrusted_events.isEmpty {
|
||||||
|
VStack {
|
||||||
|
StickyHeaderView
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
untrusted_network_expanded.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.transition(.move(edge: .top).combined(with: .opacity))
|
||||||
|
.zIndex(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.onReceive(handle_notify(.post), perform: { notify in
|
.onReceive(handle_notify(.post), perform: { notify in
|
||||||
switch notify {
|
switch notify {
|
||||||
case .post(_):
|
case .post(_):
|
||||||
user_just_posted_flag = true
|
user_just_posted_flag = true
|
||||||
case .cancel:
|
case .cancel:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.onReceive(thread.objectWillChange) {
|
.onReceive(thread.objectWillChange) {
|
||||||
@@ -139,15 +258,8 @@ struct ChatroomThreadView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggle_thread_view() {
|
|
||||||
NotificationCenter.default.post(name: .toggle_thread_view, object: nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ChatroomView_Previews: PreviewProvider {
|
struct ChatroomView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
Group {
|
Group {
|
||||||
@@ -167,8 +279,3 @@ struct ChatroomView_Previews: PreviewProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
|
||||||
func scroll_after_load(thread: ThreadModel, proxy: ScrollViewProxy) {
|
|
||||||
scroll_to_event(scroller: proxy, id: thread.selected_event.id, delay: 0.1, animate: false)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import TipKit
|
||||||
|
|
||||||
enum DMType: Hashable {
|
enum DMType: Hashable {
|
||||||
case rando
|
case rando
|
||||||
@@ -18,6 +19,7 @@ struct DirectMessagesView: View {
|
|||||||
@State var dm_type: DMType = .friend
|
@State var dm_type: DMType = .friend
|
||||||
@ObservedObject var model: DirectMessagesModel
|
@ObservedObject var model: DirectMessagesModel
|
||||||
@ObservedObject var settings: UserSettingsStore
|
@ObservedObject var settings: UserSettingsStore
|
||||||
|
@Binding var subtitle: String?
|
||||||
|
|
||||||
func MainContent(requests: Bool) -> some View {
|
func MainContent(requests: Bool) -> some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
@@ -72,7 +74,15 @@ struct DirectMessagesView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
let showTrustedButton = would_filter_non_friends_from_dms(contacts: damus_state.contacts, dms: self.model.dms)
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
|
if #available(iOS 17, *), showTrustedButton {
|
||||||
|
TipView(TrustedNetworkButtonTip.shared)
|
||||||
|
.tipBackground(.clear)
|
||||||
|
.tipViewStyle(TrustedNetworkButtonTipViewStyle())
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
|
||||||
CustomPicker(tabs: [
|
CustomPicker(tabs: [
|
||||||
(NSLocalizedString("DMs", comment: "Picker option for DM selector for seeing only DMs that have been responded to. DM is the English abbreviation for Direct Message."), DMType.friend),
|
(NSLocalizedString("DMs", comment: "Picker option for DM selector for seeing only DMs that have been responded to. DM is the English abbreviation for Direct Message."), DMType.friend),
|
||||||
(NSLocalizedString("Requests", comment: "Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet"), DMType.rando),
|
(NSLocalizedString("Requests", comment: "Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet"), DMType.rando),
|
||||||
@@ -92,12 +102,22 @@ struct DirectMessagesView: View {
|
|||||||
}
|
}
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
if would_filter_non_friends_from_dms(contacts: damus_state.contacts, dms: self.model.dms) {
|
if showTrustedButton {
|
||||||
|
TrustedNetworkButton(filter: $settings.friend_filter) {
|
||||||
FriendsButton(filter: $settings.friend_filter)
|
if #available(iOS 17, *) {
|
||||||
|
TrustedNetworkButtonTip.shared.invalidate(reason: .actionPerformed)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onAppear {
|
||||||
|
self.subtitle = settings.friend_filter.description()
|
||||||
|
|
||||||
|
}
|
||||||
|
.onChange(of: settings.friend_filter) { val in
|
||||||
|
self.subtitle = val.description()
|
||||||
|
}
|
||||||
.navigationTitle(NSLocalizedString("DMs", comment: "Navigation title for view of DMs, where DM is an English abbreviation for Direct Message."))
|
.navigationTitle(NSLocalizedString("DMs", comment: "Navigation title for view of DMs, where DM is an English abbreviation for Direct Message."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,6 +135,6 @@ func would_filter_non_friends_from_dms(contacts: Contacts, dms: [DirectMessageMo
|
|||||||
struct DirectMessagesView_Previews: PreviewProvider {
|
struct DirectMessagesView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let ds = test_damus_state
|
let ds = test_damus_state
|
||||||
DirectMessagesView(damus_state: ds, model: ds.dms, settings: ds.settings)
|
DirectMessagesView(damus_state: ds, model: ds.dms, settings: ds.settings, subtitle: .constant(nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import TipKit
|
||||||
|
|
||||||
class NotificationFilter: ObservableObject, Equatable {
|
class NotificationFilter: ObservableObject, Equatable {
|
||||||
@Published var state: NotificationFilterState
|
@Published var state: NotificationFilterState
|
||||||
@@ -79,6 +80,7 @@ struct NotificationsView: View {
|
|||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
let showTrustedButton = would_filter_non_friends_from_notifications(contacts: state.contacts, state: filter_state, items: self.notifications.notifications)
|
||||||
TabView(selection: $filter_state) {
|
TabView(selection: $filter_state) {
|
||||||
NotificationTab(
|
NotificationTab(
|
||||||
NotificationFilter(
|
NotificationFilter(
|
||||||
@@ -115,14 +117,19 @@ struct NotificationsView: View {
|
|||||||
Button(
|
Button(
|
||||||
action: { state.nav.push(route: Route.NotificationSettings(settings: state.settings)) },
|
action: { state.nav.push(route: Route.NotificationSettings(settings: state.settings)) },
|
||||||
label: {
|
label: {
|
||||||
Image("settings")
|
Image(systemName: "gearshape")
|
||||||
|
.frame(width: 24, height: 24)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
if would_filter_non_friends_from_notifications(contacts: state.contacts, state: filter_state, items: self.notifications.notifications) {
|
if showTrustedButton {
|
||||||
FriendsButton(filter: $filter.friend_filter)
|
TrustedNetworkButton(filter: $filter.friend_filter) {
|
||||||
|
if #available(iOS 17, *) {
|
||||||
|
TrustedNetworkButtonTip.shared.invalidate(reason: .actionPerformed)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,6 +147,13 @@ struct NotificationsView: View {
|
|||||||
}
|
}
|
||||||
.safeAreaInset(edge: .top, spacing: 0) {
|
.safeAreaInset(edge: .top, spacing: 0) {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
|
if #available(iOS 17, *), showTrustedButton {
|
||||||
|
TipView(TrustedNetworkButtonTip.shared)
|
||||||
|
.tipBackground(.clear)
|
||||||
|
.tipViewStyle(TrustedNetworkButtonTipViewStyle())
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
|
||||||
CustomPicker(tabs: [
|
CustomPicker(tabs: [
|
||||||
(NSLocalizedString("All", comment: "Label for filter for all notifications."), NotificationFilterState.all),
|
(NSLocalizedString("All", comment: "Label for filter for all notifications."), NotificationFilterState.all),
|
||||||
(NSLocalizedString("Zaps", comment: "Label for filter for zap notifications."), NotificationFilterState.zaps),
|
(NSLocalizedString("Zaps", comment: "Label for filter for zap notifications."), NotificationFilterState.zaps),
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ struct AppearanceSettingsView: View {
|
|||||||
header: Text("Content filters", comment: "Section title for content filtering/moderation configuration."),
|
header: Text("Content filters", comment: "Section title for content filtering/moderation configuration."),
|
||||||
footer: Text("Notes with the #nsfw tag usually contains adult content or other \"Not safe for work\" content", comment: "Section footer clarifying what #nsfw (not safe for work) tags mean")
|
footer: Text("Notes with the #nsfw tag usually contains adult content or other \"Not safe for work\" content", comment: "Section footer clarifying what #nsfw (not safe for work) tags mean")
|
||||||
) {
|
) {
|
||||||
|
Toggle(NSLocalizedString("Show replies from your trusted network first", comment: "Setting to show replies in threads from the current user's trusted network first."), isOn: $settings.show_trusted_replies_first)
|
||||||
|
.toggleStyle(.switch)
|
||||||
Toggle(NSLocalizedString("Hide notes with #nsfw tags", comment: "Setting to hide notes with the #nsfw (not safe for work) tags"), isOn: $settings.hide_nsfw_tagged_content)
|
Toggle(NSLocalizedString("Hide notes with #nsfw tags", comment: "Setting to hide notes with the #nsfw (not safe for work) tags"), isOn: $settings.hide_nsfw_tagged_content)
|
||||||
.toggleStyle(.switch)
|
.toggleStyle(.switch)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
damus/Views/Tips/TrustedNetworkButtonTip.swift
Normal file
25
damus/Views/Tips/TrustedNetworkButtonTip.swift
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// TrustedNetworkButtonTip.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by Terry Yiu on 6/4/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import TipKit
|
||||||
|
|
||||||
|
@available(iOS 17, *)
|
||||||
|
struct TrustedNetworkButtonTip: Tip {
|
||||||
|
static let shared = TrustedNetworkButtonTip()
|
||||||
|
|
||||||
|
var title: Text {
|
||||||
|
Text("Toggle visibility of content from outside your trusted network", comment: "Title of tip that informs users what trusted network means and that they can toggle the visibility of content 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
79
damus/Views/Tips/TrustedNetworkButtonTipViewStyle.swift
Normal file
79
damus/Views/Tips/TrustedNetworkButtonTipViewStyle.swift
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// TrustedNetworkButtonTipViewStyle.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by Terry Yiu on 6/7/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import TipKit
|
||||||
|
|
||||||
|
// (tyiu): Apple's native popover tips have a lot of rendering and race condition issues --
|
||||||
|
// text being rendered in the wrong locations or not at all, or the tip gets opened in full screen.
|
||||||
|
//
|
||||||
|
// Instead, we are introducing this custom popover tip view style to emulate a similar look and feel.
|
||||||
|
// The main thing needed from this view style is really just an arrow on the top right corner
|
||||||
|
// to point to the TrustedNetworkButton on the NotificationsView and DirectMessagesview.
|
||||||
|
@available(iOS 17, *)
|
||||||
|
struct TrustedNetworkButtonTipViewStyle: TipViewStyle {
|
||||||
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// Arrow pointing up to the button (positioned at top right)
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
Triangle()
|
||||||
|
.fill(Color(.secondarySystemBackground))
|
||||||
|
.frame(width: 24, height: 14)
|
||||||
|
}
|
||||||
|
|
||||||
|
HStack(alignment: .top, spacing: 12) {
|
||||||
|
// Icon
|
||||||
|
configuration.image
|
||||||
|
.foregroundStyle(.tint)
|
||||||
|
.font(.title2)
|
||||||
|
|
||||||
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
|
configuration.title
|
||||||
|
.font(.headline)
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundStyle(.primary)
|
||||||
|
|
||||||
|
configuration.message
|
||||||
|
.font(.subheadline)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Button(action: { configuration.tip.invalidate(reason: .tipClosed) }) {
|
||||||
|
Image(systemName: "xmark")
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.foregroundStyle(Color(.tertiaryLabel))
|
||||||
|
}
|
||||||
|
.buttonStyle(PlainButtonStyle())
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 14)
|
||||||
|
.padding(.vertical, 14)
|
||||||
|
.background(Color(.secondarySystemBackground))
|
||||||
|
.clipShape(
|
||||||
|
.rect(
|
||||||
|
topLeadingRadius: 20,
|
||||||
|
bottomLeadingRadius: 20,
|
||||||
|
bottomTrailingRadius: 20,
|
||||||
|
topTrailingRadius: 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom triangle shape for the popover arrow
|
||||||
|
struct Triangle: Shape {
|
||||||
|
func path(in rect: CGRect) -> Path {
|
||||||
|
var path = Path()
|
||||||
|
path.move(to: CGPoint(x: rect.midX, y: rect.minY))
|
||||||
|
path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
|
||||||
|
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
|
||||||
|
path.addLine(to: CGPoint(x: rect.midX, y: rect.minY))
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
}
|
||||||
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