committed by
William Casarin
parent
0da10eb716
commit
9847f12c95
@@ -35,16 +35,13 @@
|
|||||||
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670528FCB08600038D2A /* ImageCarousel.swift */; };
|
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670528FCB08600038D2A /* ImageCarousel.swift */; };
|
||||||
4C06670B28FDE64700038D2A /* damus.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670A28FDE64700038D2A /* damus.c */; };
|
4C06670B28FDE64700038D2A /* damus.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670A28FDE64700038D2A /* damus.c */; };
|
||||||
4C06670E28FDEAA000038D2A /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670D28FDEAA000038D2A /* utf8.c */; };
|
4C06670E28FDEAA000038D2A /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670D28FDEAA000038D2A /* utf8.c */; };
|
||||||
4C0A3F8C280F5FCA000448DE /* ChatroomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A3F8B280F5FCA000448DE /* ChatroomView.swift */; };
|
|
||||||
4C0A3F8F280F640A000448DE /* ThreadModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A3F8E280F640A000448DE /* ThreadModel.swift */; };
|
4C0A3F8F280F640A000448DE /* ThreadModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A3F8E280F640A000448DE /* ThreadModel.swift */; };
|
||||||
4C0A3F91280F6528000448DE /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A3F90280F6528000448DE /* ChatView.swift */; };
|
|
||||||
4C0A3F93280F66F5000448DE /* ReplyMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A3F92280F66F5000448DE /* ReplyMap.swift */; };
|
4C0A3F93280F66F5000448DE /* ReplyMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A3F92280F66F5000448DE /* ReplyMap.swift */; };
|
||||||
4C198DEF29F88C6B004C165C /* BlurHashEncode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C198DEB29F88C6B004C165C /* BlurHashEncode.swift */; };
|
4C198DEF29F88C6B004C165C /* BlurHashEncode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C198DEB29F88C6B004C165C /* BlurHashEncode.swift */; };
|
||||||
4C198DF029F88C6B004C165C /* Readme.md in Resources */ = {isa = PBXBuildFile; fileRef = 4C198DEC29F88C6B004C165C /* Readme.md */; };
|
4C198DF029F88C6B004C165C /* Readme.md in Resources */ = {isa = PBXBuildFile; fileRef = 4C198DEC29F88C6B004C165C /* Readme.md */; };
|
||||||
4C198DF129F88C6B004C165C /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 4C198DED29F88C6B004C165C /* License.txt */; };
|
4C198DF129F88C6B004C165C /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 4C198DED29F88C6B004C165C /* License.txt */; };
|
||||||
4C198DF229F88C6B004C165C /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C198DEE29F88C6B004C165C /* BlurHashDecode.swift */; };
|
4C198DF229F88C6B004C165C /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C198DEE29F88C6B004C165C /* BlurHashDecode.swift */; };
|
||||||
4C198DF529F88D2E004C165C /* ImageMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C198DF429F88D2E004C165C /* ImageMetadata.swift */; };
|
4C198DF529F88D2E004C165C /* ImageMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C198DF429F88D2E004C165C /* ImageMetadata.swift */; };
|
||||||
4C198DF829F89323004C165C /* BinaryParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C198DF729F89323004C165C /* BinaryParser.swift */; };
|
|
||||||
4C1A9A1A29DCA17E00516EAC /* ReplyCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A1929DCA17E00516EAC /* ReplyCounter.swift */; };
|
4C1A9A1A29DCA17E00516EAC /* ReplyCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A1929DCA17E00516EAC /* ReplyCounter.swift */; };
|
||||||
4C1A9A1D29DDCF9B00516EAC /* NotificationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A1C29DDCF9B00516EAC /* NotificationSettingsView.swift */; };
|
4C1A9A1D29DDCF9B00516EAC /* NotificationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A1C29DDCF9B00516EAC /* NotificationSettingsView.swift */; };
|
||||||
4C1A9A1F29DDD24B00516EAC /* AppearanceSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A1E29DDD24B00516EAC /* AppearanceSettingsView.swift */; };
|
4C1A9A1F29DDD24B00516EAC /* AppearanceSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A1E29DDD24B00516EAC /* AppearanceSettingsView.swift */; };
|
||||||
@@ -70,7 +67,6 @@
|
|||||||
4C30AC8029A6A53F00E2BD5A /* ProfilePicturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C30AC7F29A6A53F00E2BD5A /* ProfilePicturesView.swift */; };
|
4C30AC8029A6A53F00E2BD5A /* ProfilePicturesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C30AC7F29A6A53F00E2BD5A /* ProfilePicturesView.swift */; };
|
||||||
4C363A8428233689006E126D /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8328233689006E126D /* Parser.swift */; };
|
4C363A8428233689006E126D /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8328233689006E126D /* Parser.swift */; };
|
||||||
4C363A8828236948006E126D /* BlocksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8728236948006E126D /* BlocksView.swift */; };
|
4C363A8828236948006E126D /* BlocksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8728236948006E126D /* BlocksView.swift */; };
|
||||||
4C363A8A28236B57006E126D /* MentionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8928236B57006E126D /* MentionView.swift */; };
|
|
||||||
4C363A8C28236B92006E126D /* PubkeyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8B28236B92006E126D /* PubkeyView.swift */; };
|
4C363A8C28236B92006E126D /* PubkeyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8B28236B92006E126D /* PubkeyView.swift */; };
|
||||||
4C363A8E28236FE4006E126D /* NoteContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8D28236FE4006E126D /* NoteContentView.swift */; };
|
4C363A8E28236FE4006E126D /* NoteContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8D28236FE4006E126D /* NoteContentView.swift */; };
|
||||||
4C363A9028247A1D006E126D /* NostrLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8F28247A1D006E126D /* NostrLink.swift */; };
|
4C363A9028247A1D006E126D /* NostrLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8F28247A1D006E126D /* NostrLink.swift */; };
|
||||||
@@ -117,7 +113,6 @@
|
|||||||
4C3EA67D28FFBBA300C48A62 /* InvoicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA67C28FFBBA200C48A62 /* InvoicesView.swift */; };
|
4C3EA67D28FFBBA300C48A62 /* InvoicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA67C28FFBBA200C48A62 /* InvoicesView.swift */; };
|
||||||
4C3EA67F28FFC01D00C48A62 /* InvoiceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA67E28FFC01D00C48A62 /* InvoiceView.swift */; };
|
4C3EA67F28FFC01D00C48A62 /* InvoiceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3EA67E28FFC01D00C48A62 /* InvoiceView.swift */; };
|
||||||
4C42812C298C848200DBF26F /* TranslateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C42812B298C848200DBF26F /* TranslateView.swift */; };
|
4C42812C298C848200DBF26F /* TranslateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C42812B298C848200DBF26F /* TranslateView.swift */; };
|
||||||
4C477C9E282C3A4800033AA3 /* TipCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C477C9D282C3A4800033AA3 /* TipCounter.swift */; };
|
|
||||||
4C54AA0729A540BA003E4487 /* NotificationsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C54AA0629A540BA003E4487 /* NotificationsModel.swift */; };
|
4C54AA0729A540BA003E4487 /* NotificationsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C54AA0629A540BA003E4487 /* NotificationsModel.swift */; };
|
||||||
4C54AA0A29A55429003E4487 /* EventGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C54AA0929A55429003E4487 /* EventGroup.swift */; };
|
4C54AA0A29A55429003E4487 /* EventGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C54AA0929A55429003E4487 /* EventGroup.swift */; };
|
||||||
4C54AA0C29A5543C003E4487 /* ZapGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C54AA0B29A5543C003E4487 /* ZapGroup.swift */; };
|
4C54AA0C29A5543C003E4487 /* ZapGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C54AA0B29A5543C003E4487 /* ZapGroup.swift */; };
|
||||||
@@ -156,7 +151,6 @@
|
|||||||
4C90BD1A283AA67F008EE7EF /* Bech32.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C90BD19283AA67F008EE7EF /* Bech32.swift */; };
|
4C90BD1A283AA67F008EE7EF /* Bech32.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C90BD19283AA67F008EE7EF /* Bech32.swift */; };
|
||||||
4C90BD1C283AC38E008EE7EF /* Bech32Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C90BD1B283AC38E008EE7EF /* Bech32Tests.swift */; };
|
4C90BD1C283AC38E008EE7EF /* Bech32Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C90BD1B283AC38E008EE7EF /* Bech32Tests.swift */; };
|
||||||
4C987B57283FD07F0042CE38 /* FollowersModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C987B56283FD07F0042CE38 /* FollowersModel.swift */; };
|
4C987B57283FD07F0042CE38 /* FollowersModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C987B56283FD07F0042CE38 /* FollowersModel.swift */; };
|
||||||
4C99737B28C92A9200E53835 /* ChatroomMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C99737A28C92A9200E53835 /* ChatroomMetadata.swift */; };
|
|
||||||
4C9BB83129C0ED4F00FC4E37 /* DisplayName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */; };
|
4C9BB83129C0ED4F00FC4E37 /* DisplayName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */; };
|
||||||
4C9BB83429C12D9900FC4E37 /* EventProfileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */; };
|
4C9BB83429C12D9900FC4E37 /* EventProfileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */; };
|
||||||
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9F18E129AA9B6C008C55EC /* CustomizeZapView.swift */; };
|
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9F18E129AA9B6C008C55EC /* CustomizeZapView.swift */; };
|
||||||
@@ -196,7 +190,6 @@
|
|||||||
4CC7AAF6297F1A6A00430951 /* EventBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF5297F1A6A00430951 /* EventBody.swift */; };
|
4CC7AAF6297F1A6A00430951 /* EventBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF5297F1A6A00430951 /* EventBody.swift */; };
|
||||||
4CC7AAF8297F1CEE00430951 /* EventProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF7297F1CEE00430951 /* EventProfile.swift */; };
|
4CC7AAF8297F1CEE00430951 /* EventProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF7297F1CEE00430951 /* EventProfile.swift */; };
|
||||||
4CC7AAFA297F64AC00430951 /* EventMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF9297F64AC00430951 /* EventMenu.swift */; };
|
4CC7AAFA297F64AC00430951 /* EventMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF9297F64AC00430951 /* EventMenu.swift */; };
|
||||||
4CCEB7A929B29DD50078AA28 /* SearchResultsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEB7A829B29DD50078AA28 /* SearchResultsModel.swift */; };
|
|
||||||
4CCEB7AE29B53D260078AA28 /* SearchingEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEB7AD29B53D260078AA28 /* SearchingEventView.swift */; };
|
4CCEB7AE29B53D260078AA28 /* SearchingEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEB7AD29B53D260078AA28 /* SearchingEventView.swift */; };
|
||||||
4CCEB7B029B5415A0078AA28 /* SearchingProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEB7AF29B5415A0078AA28 /* SearchingProfileView.swift */; };
|
4CCEB7B029B5415A0078AA28 /* SearchingProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CCEB7AF29B5415A0078AA28 /* SearchingProfileView.swift */; };
|
||||||
4CD348EF29C3659D00497EB2 /* ImageUploadModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD348EE29C3659D00497EB2 /* ImageUploadModel.swift */; };
|
4CD348EF29C3659D00497EB2 /* ImageUploadModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD348EE29C3659D00497EB2 /* ImageUploadModel.swift */; };
|
||||||
@@ -214,7 +207,6 @@
|
|||||||
4CE4F0F829DB7399005914DB /* ThiccDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F0F729DB7399005914DB /* ThiccDivider.swift */; };
|
4CE4F0F829DB7399005914DB /* ThiccDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F0F729DB7399005914DB /* ThiccDivider.swift */; };
|
||||||
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F8CC281352B30009DFBB /* Notifications.swift */; };
|
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F8CC281352B30009DFBB /* Notifications.swift */; };
|
||||||
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */; };
|
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */; };
|
||||||
4CE4F9E1285287B800C00DD9 /* TextFieldAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9E0285287B800C00DD9 /* TextFieldAlert.swift */; };
|
|
||||||
4CE4F9E328528C5200C00DD9 /* AddRelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */; };
|
4CE4F9E328528C5200C00DD9 /* AddRelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */; };
|
||||||
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE627F7A08100C66700 /* damusApp.swift */; };
|
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE627F7A08100C66700 /* damusApp.swift */; };
|
||||||
4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE827F7A08100C66700 /* ContentView.swift */; };
|
4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE827F7A08100C66700 /* ContentView.swift */; };
|
||||||
@@ -237,13 +229,11 @@
|
|||||||
4CEE2AF3280B25C500AB5EEF /* ProfilePicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF2280B25C500AB5EEF /* ProfilePicView.swift */; };
|
4CEE2AF3280B25C500AB5EEF /* ProfilePicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF2280B25C500AB5EEF /* ProfilePicView.swift */; };
|
||||||
4CEE2AF5280B29E600AB5EEF /* TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF4280B29E600AB5EEF /* TimeAgo.swift */; };
|
4CEE2AF5280B29E600AB5EEF /* TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF4280B29E600AB5EEF /* TimeAgo.swift */; };
|
||||||
4CEE2AF7280B2DEA00AB5EEF /* ProfileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF6280B2DEA00AB5EEF /* ProfileName.swift */; };
|
4CEE2AF7280B2DEA00AB5EEF /* ProfileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF6280B2DEA00AB5EEF /* ProfileName.swift */; };
|
||||||
4CEE2AF9280B2EAC00AB5EEF /* PowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */; };
|
|
||||||
4CEE2B02280B39E800AB5EEF /* EventActionBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */; };
|
4CEE2B02280B39E800AB5EEF /* EventActionBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */; };
|
||||||
4CF0ABD42980996B00D66079 /* Report.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD32980996B00D66079 /* Report.swift */; };
|
4CF0ABD42980996B00D66079 /* Report.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD32980996B00D66079 /* Report.swift */; };
|
||||||
4CF0ABD629817F5B00D66079 /* ReportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD529817F5B00D66079 /* ReportView.swift */; };
|
4CF0ABD629817F5B00D66079 /* ReportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD529817F5B00D66079 /* ReportView.swift */; };
|
||||||
4CF0ABD82981980C00D66079 /* Lists.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD72981980C00D66079 /* Lists.swift */; };
|
4CF0ABD82981980C00D66079 /* Lists.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD72981980C00D66079 /* Lists.swift */; };
|
||||||
4CF0ABDC2981A19E00D66079 /* ListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABDB2981A19E00D66079 /* ListTests.swift */; };
|
4CF0ABDC2981A19E00D66079 /* ListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABDB2981A19E00D66079 /* ListTests.swift */; };
|
||||||
4CF0ABDE2981A69500D66079 /* MutelistModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABDD2981A69500D66079 /* MutelistModel.swift */; };
|
|
||||||
4CF0ABE12981A83900D66079 /* MutelistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE02981A83900D66079 /* MutelistView.swift */; };
|
4CF0ABE12981A83900D66079 /* MutelistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE02981A83900D66079 /* MutelistView.swift */; };
|
||||||
4CF0ABE32981BC7D00D66079 /* UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE22981BC7D00D66079 /* UserView.swift */; };
|
4CF0ABE32981BC7D00D66079 /* UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE22981BC7D00D66079 /* UserView.swift */; };
|
||||||
4CF0ABE52981EE0C00D66079 /* EULAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE42981EE0C00D66079 /* EULAView.swift */; };
|
4CF0ABE52981EE0C00D66079 /* EULAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE42981EE0C00D66079 /* EULAView.swift */; };
|
||||||
@@ -272,7 +262,6 @@
|
|||||||
643EA5C8296B764E005081BB /* RelayFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643EA5C7296B764E005081BB /* RelayFilterView.swift */; };
|
643EA5C8296B764E005081BB /* RelayFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643EA5C7296B764E005081BB /* RelayFilterView.swift */; };
|
||||||
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647D9A8C2968520300A295DE /* SideMenuView.swift */; };
|
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647D9A8C2968520300A295DE /* SideMenuView.swift */; };
|
||||||
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FBD06E296255C400D9D3B2 /* Theme.swift */; };
|
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FBD06E296255C400D9D3B2 /* Theme.swift */; };
|
||||||
7C0F392F29B57CAF0039859C /* Binding+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C0F392E29B57CAF0039859C /* Binding+.swift */; };
|
|
||||||
7C60CAEF298471A1009C80D6 /* CoreSVG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C60CAEE298471A1009C80D6 /* CoreSVG.swift */; };
|
7C60CAEF298471A1009C80D6 /* CoreSVG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C60CAEE298471A1009C80D6 /* CoreSVG.swift */; };
|
||||||
7C902AE32981D55B002AB16E /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */; };
|
7C902AE32981D55B002AB16E /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */; };
|
||||||
7C95CAEE299DCEF1009DCB67 /* KFOptionSetter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */; };
|
7C95CAEE299DCEF1009DCB67 /* KFOptionSetter+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */; };
|
||||||
@@ -424,16 +413,13 @@
|
|||||||
4C06670A28FDE64700038D2A /* damus.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = damus.c; sourceTree = "<group>"; };
|
4C06670A28FDE64700038D2A /* damus.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = damus.c; sourceTree = "<group>"; };
|
||||||
4C06670C28FDEAA000038D2A /* utf8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = "<group>"; };
|
4C06670C28FDEAA000038D2A /* utf8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = "<group>"; };
|
||||||
4C06670D28FDEAA000038D2A /* utf8.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = utf8.c; sourceTree = "<group>"; };
|
4C06670D28FDEAA000038D2A /* utf8.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = utf8.c; sourceTree = "<group>"; };
|
||||||
4C0A3F8B280F5FCA000448DE /* ChatroomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatroomView.swift; sourceTree = "<group>"; };
|
|
||||||
4C0A3F8E280F640A000448DE /* ThreadModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadModel.swift; sourceTree = "<group>"; };
|
4C0A3F8E280F640A000448DE /* ThreadModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadModel.swift; sourceTree = "<group>"; };
|
||||||
4C0A3F90280F6528000448DE /* ChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatView.swift; sourceTree = "<group>"; };
|
|
||||||
4C0A3F92280F66F5000448DE /* ReplyMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyMap.swift; sourceTree = "<group>"; };
|
4C0A3F92280F66F5000448DE /* ReplyMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyMap.swift; sourceTree = "<group>"; };
|
||||||
4C198DEB29F88C6B004C165C /* BlurHashEncode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashEncode.swift; sourceTree = "<group>"; };
|
4C198DEB29F88C6B004C165C /* BlurHashEncode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashEncode.swift; sourceTree = "<group>"; };
|
||||||
4C198DEC29F88C6B004C165C /* Readme.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Readme.md; sourceTree = "<group>"; };
|
4C198DEC29F88C6B004C165C /* Readme.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Readme.md; sourceTree = "<group>"; };
|
||||||
4C198DED29F88C6B004C165C /* License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = License.txt; sourceTree = "<group>"; };
|
4C198DED29F88C6B004C165C /* License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = License.txt; sourceTree = "<group>"; };
|
||||||
4C198DEE29F88C6B004C165C /* BlurHashDecode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
|
4C198DEE29F88C6B004C165C /* BlurHashDecode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
|
||||||
4C198DF429F88D2E004C165C /* ImageMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageMetadata.swift; sourceTree = "<group>"; };
|
4C198DF429F88D2E004C165C /* ImageMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageMetadata.swift; sourceTree = "<group>"; };
|
||||||
4C198DF729F89323004C165C /* BinaryParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryParser.swift; sourceTree = "<group>"; };
|
|
||||||
4C1A9A1929DCA17E00516EAC /* ReplyCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyCounter.swift; sourceTree = "<group>"; };
|
4C1A9A1929DCA17E00516EAC /* ReplyCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyCounter.swift; sourceTree = "<group>"; };
|
||||||
4C1A9A1C29DDCF9B00516EAC /* NotificationSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsView.swift; sourceTree = "<group>"; };
|
4C1A9A1C29DDCF9B00516EAC /* NotificationSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsView.swift; sourceTree = "<group>"; };
|
||||||
4C1A9A1E29DDD24B00516EAC /* AppearanceSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceSettingsView.swift; sourceTree = "<group>"; };
|
4C1A9A1E29DDD24B00516EAC /* AppearanceSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceSettingsView.swift; sourceTree = "<group>"; };
|
||||||
@@ -459,7 +445,6 @@
|
|||||||
4C30AC7F29A6A53F00E2BD5A /* ProfilePicturesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePicturesView.swift; sourceTree = "<group>"; };
|
4C30AC7F29A6A53F00E2BD5A /* ProfilePicturesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePicturesView.swift; sourceTree = "<group>"; };
|
||||||
4C363A8328233689006E126D /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
|
4C363A8328233689006E126D /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
|
||||||
4C363A8728236948006E126D /* BlocksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlocksView.swift; sourceTree = "<group>"; };
|
4C363A8728236948006E126D /* BlocksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlocksView.swift; sourceTree = "<group>"; };
|
||||||
4C363A8928236B57006E126D /* MentionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionView.swift; sourceTree = "<group>"; };
|
|
||||||
4C363A8B28236B92006E126D /* PubkeyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PubkeyView.swift; sourceTree = "<group>"; };
|
4C363A8B28236B92006E126D /* PubkeyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PubkeyView.swift; sourceTree = "<group>"; };
|
||||||
4C363A8D28236FE4006E126D /* NoteContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContentView.swift; sourceTree = "<group>"; };
|
4C363A8D28236FE4006E126D /* NoteContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContentView.swift; sourceTree = "<group>"; };
|
||||||
4C363A8F28247A1D006E126D /* NostrLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NostrLink.swift; sourceTree = "<group>"; };
|
4C363A8F28247A1D006E126D /* NostrLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NostrLink.swift; sourceTree = "<group>"; };
|
||||||
@@ -535,7 +520,6 @@
|
|||||||
4C3EA67C28FFBBA200C48A62 /* InvoicesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvoicesView.swift; sourceTree = "<group>"; };
|
4C3EA67C28FFBBA200C48A62 /* InvoicesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvoicesView.swift; sourceTree = "<group>"; };
|
||||||
4C3EA67E28FFC01D00C48A62 /* InvoiceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvoiceView.swift; sourceTree = "<group>"; };
|
4C3EA67E28FFC01D00C48A62 /* InvoiceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvoiceView.swift; sourceTree = "<group>"; };
|
||||||
4C42812B298C848200DBF26F /* TranslateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslateView.swift; sourceTree = "<group>"; };
|
4C42812B298C848200DBF26F /* TranslateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslateView.swift; sourceTree = "<group>"; };
|
||||||
4C477C9D282C3A4800033AA3 /* TipCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipCounter.swift; sourceTree = "<group>"; };
|
|
||||||
4C4A3A5A288A1B2200453788 /* damus.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = damus.entitlements; sourceTree = "<group>"; };
|
4C4A3A5A288A1B2200453788 /* damus.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = damus.entitlements; sourceTree = "<group>"; };
|
||||||
4C54AA0629A540BA003E4487 /* NotificationsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsModel.swift; sourceTree = "<group>"; };
|
4C54AA0629A540BA003E4487 /* NotificationsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsModel.swift; sourceTree = "<group>"; };
|
||||||
4C54AA0929A55429003E4487 /* EventGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventGroup.swift; sourceTree = "<group>"; };
|
4C54AA0929A55429003E4487 /* EventGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventGroup.swift; sourceTree = "<group>"; };
|
||||||
@@ -579,7 +563,6 @@
|
|||||||
4C90BD19283AA67F008EE7EF /* Bech32.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bech32.swift; sourceTree = "<group>"; };
|
4C90BD19283AA67F008EE7EF /* Bech32.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bech32.swift; sourceTree = "<group>"; };
|
||||||
4C90BD1B283AC38E008EE7EF /* Bech32Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bech32Tests.swift; sourceTree = "<group>"; };
|
4C90BD1B283AC38E008EE7EF /* Bech32Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bech32Tests.swift; sourceTree = "<group>"; };
|
||||||
4C987B56283FD07F0042CE38 /* FollowersModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowersModel.swift; sourceTree = "<group>"; };
|
4C987B56283FD07F0042CE38 /* FollowersModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowersModel.swift; sourceTree = "<group>"; };
|
||||||
4C99737A28C92A9200E53835 /* ChatroomMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatroomMetadata.swift; sourceTree = "<group>"; };
|
|
||||||
4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayName.swift; sourceTree = "<group>"; };
|
4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayName.swift; sourceTree = "<group>"; };
|
||||||
4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventProfileName.swift; sourceTree = "<group>"; };
|
4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventProfileName.swift; sourceTree = "<group>"; };
|
||||||
4C9F18E129AA9B6C008C55EC /* CustomizeZapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomizeZapView.swift; sourceTree = "<group>"; };
|
4C9F18E129AA9B6C008C55EC /* CustomizeZapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomizeZapView.swift; sourceTree = "<group>"; };
|
||||||
@@ -619,7 +602,6 @@
|
|||||||
4CC7AAF5297F1A6A00430951 /* EventBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBody.swift; sourceTree = "<group>"; };
|
4CC7AAF5297F1A6A00430951 /* EventBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBody.swift; sourceTree = "<group>"; };
|
||||||
4CC7AAF7297F1CEE00430951 /* EventProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventProfile.swift; sourceTree = "<group>"; };
|
4CC7AAF7297F1CEE00430951 /* EventProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventProfile.swift; sourceTree = "<group>"; };
|
||||||
4CC7AAF9297F64AC00430951 /* EventMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMenu.swift; sourceTree = "<group>"; };
|
4CC7AAF9297F64AC00430951 /* EventMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMenu.swift; sourceTree = "<group>"; };
|
||||||
4CCEB7A829B29DD50078AA28 /* SearchResultsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsModel.swift; sourceTree = "<group>"; };
|
|
||||||
4CCEB7AD29B53D260078AA28 /* SearchingEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingEventView.swift; sourceTree = "<group>"; };
|
4CCEB7AD29B53D260078AA28 /* SearchingEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingEventView.swift; sourceTree = "<group>"; };
|
||||||
4CCEB7AF29B5415A0078AA28 /* SearchingProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingProfileView.swift; sourceTree = "<group>"; };
|
4CCEB7AF29B5415A0078AA28 /* SearchingProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingProfileView.swift; sourceTree = "<group>"; };
|
||||||
4CD348EE29C3659D00497EB2 /* ImageUploadModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageUploadModel.swift; sourceTree = "<group>"; };
|
4CD348EE29C3659D00497EB2 /* ImageUploadModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageUploadModel.swift; sourceTree = "<group>"; };
|
||||||
@@ -637,7 +619,6 @@
|
|||||||
4CE4F0F729DB7399005914DB /* ThiccDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThiccDivider.swift; sourceTree = "<group>"; };
|
4CE4F0F729DB7399005914DB /* ThiccDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThiccDivider.swift; sourceTree = "<group>"; };
|
||||||
4CE4F8CC281352B30009DFBB /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
|
4CE4F8CC281352B30009DFBB /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
|
||||||
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigView.swift; sourceTree = "<group>"; };
|
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigView.swift; sourceTree = "<group>"; };
|
||||||
4CE4F9E0285287B800C00DD9 /* TextFieldAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldAlert.swift; sourceTree = "<group>"; };
|
|
||||||
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRelayView.swift; sourceTree = "<group>"; };
|
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRelayView.swift; sourceTree = "<group>"; };
|
||||||
4CE6DEE327F7A08100C66700 /* damus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = damus.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
4CE6DEE327F7A08100C66700 /* damus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = damus.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4CE6DEE627F7A08100C66700 /* damusApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = damusApp.swift; sourceTree = "<group>"; };
|
4CE6DEE627F7A08100C66700 /* damusApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = damusApp.swift; sourceTree = "<group>"; };
|
||||||
@@ -664,13 +645,11 @@
|
|||||||
4CEE2AF2280B25C500AB5EEF /* ProfilePicView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePicView.swift; sourceTree = "<group>"; };
|
4CEE2AF2280B25C500AB5EEF /* ProfilePicView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePicView.swift; sourceTree = "<group>"; };
|
||||||
4CEE2AF4280B29E600AB5EEF /* TimeAgo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeAgo.swift; sourceTree = "<group>"; };
|
4CEE2AF4280B29E600AB5EEF /* TimeAgo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeAgo.swift; sourceTree = "<group>"; };
|
||||||
4CEE2AF6280B2DEA00AB5EEF /* ProfileName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileName.swift; sourceTree = "<group>"; };
|
4CEE2AF6280B2DEA00AB5EEF /* ProfileName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileName.swift; sourceTree = "<group>"; };
|
||||||
4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PowView.swift; sourceTree = "<group>"; };
|
|
||||||
4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventActionBar.swift; sourceTree = "<group>"; };
|
4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventActionBar.swift; sourceTree = "<group>"; };
|
||||||
4CF0ABD32980996B00D66079 /* Report.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Report.swift; sourceTree = "<group>"; };
|
4CF0ABD32980996B00D66079 /* Report.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Report.swift; sourceTree = "<group>"; };
|
||||||
4CF0ABD529817F5B00D66079 /* ReportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportView.swift; sourceTree = "<group>"; };
|
4CF0ABD529817F5B00D66079 /* ReportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportView.swift; sourceTree = "<group>"; };
|
||||||
4CF0ABD72981980C00D66079 /* Lists.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lists.swift; sourceTree = "<group>"; };
|
4CF0ABD72981980C00D66079 /* Lists.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lists.swift; sourceTree = "<group>"; };
|
||||||
4CF0ABDB2981A19E00D66079 /* ListTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTests.swift; sourceTree = "<group>"; };
|
4CF0ABDB2981A19E00D66079 /* ListTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTests.swift; sourceTree = "<group>"; };
|
||||||
4CF0ABDD2981A69500D66079 /* MutelistModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutelistModel.swift; sourceTree = "<group>"; };
|
|
||||||
4CF0ABE02981A83900D66079 /* MutelistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutelistView.swift; sourceTree = "<group>"; };
|
4CF0ABE02981A83900D66079 /* MutelistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutelistView.swift; sourceTree = "<group>"; };
|
||||||
4CF0ABE22981BC7D00D66079 /* UserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserView.swift; sourceTree = "<group>"; };
|
4CF0ABE22981BC7D00D66079 /* UserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserView.swift; sourceTree = "<group>"; };
|
||||||
4CF0ABE42981EE0C00D66079 /* EULAView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EULAView.swift; sourceTree = "<group>"; };
|
4CF0ABE42981EE0C00D66079 /* EULAView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EULAView.swift; sourceTree = "<group>"; };
|
||||||
@@ -699,7 +678,6 @@
|
|||||||
643EA5C7296B764E005081BB /* RelayFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterView.swift; sourceTree = "<group>"; };
|
643EA5C7296B764E005081BB /* RelayFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterView.swift; sourceTree = "<group>"; };
|
||||||
647D9A8C2968520300A295DE /* SideMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuView.swift; sourceTree = "<group>"; };
|
647D9A8C2968520300A295DE /* SideMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideMenuView.swift; sourceTree = "<group>"; };
|
||||||
64FBD06E296255C400D9D3B2 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
64FBD06E296255C400D9D3B2 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
||||||
7C0F392E29B57CAF0039859C /* Binding+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Binding+.swift"; sourceTree = "<group>"; };
|
|
||||||
7C60CAEE298471A1009C80D6 /* CoreSVG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreSVG.swift; sourceTree = "<group>"; };
|
7C60CAEE298471A1009C80D6 /* CoreSVG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreSVG.swift; sourceTree = "<group>"; };
|
||||||
7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableScrollView.swift; sourceTree = "<group>"; };
|
7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableScrollView.swift; sourceTree = "<group>"; };
|
||||||
7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KFOptionSetter+.swift"; sourceTree = "<group>"; };
|
7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KFOptionSetter+.swift"; sourceTree = "<group>"; };
|
||||||
@@ -830,7 +808,6 @@
|
|||||||
4C0A3F8D280F63FF000448DE /* Models */ = {
|
4C0A3F8D280F63FF000448DE /* Models */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4CCEB7A729B29DC90078AA28 /* Search */,
|
|
||||||
4C54AA0829A55416003E4487 /* Notifications */,
|
4C54AA0829A55416003E4487 /* Notifications */,
|
||||||
3AA247FC297E3CFF0090C62D /* RepostsModel.swift */,
|
3AA247FC297E3CFF0090C62D /* RepostsModel.swift */,
|
||||||
4C0A3F8E280F640A000448DE /* ThreadModel.swift */,
|
4C0A3F8E280F640A000448DE /* ThreadModel.swift */,
|
||||||
@@ -859,12 +836,10 @@
|
|||||||
4C5C7E67284ED36500A22DF5 /* SearchHomeModel.swift */,
|
4C5C7E67284ED36500A22DF5 /* SearchHomeModel.swift */,
|
||||||
4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */,
|
4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */,
|
||||||
4C216F372871EDE300040376 /* DirectMessageModel.swift */,
|
4C216F372871EDE300040376 /* DirectMessageModel.swift */,
|
||||||
4C99737A28C92A9200E53835 /* ChatroomMetadata.swift */,
|
|
||||||
BA693073295D649800ADDB87 /* UserSettingsStore.swift */,
|
BA693073295D649800ADDB87 /* UserSettingsStore.swift */,
|
||||||
4FE60CDC295E1C5E00105A1F /* Wallet.swift */,
|
4FE60CDC295E1C5E00105A1F /* Wallet.swift */,
|
||||||
4CB88392296F798300DC99E7 /* ReactionsModel.swift */,
|
4CB88392296F798300DC99E7 /* ReactionsModel.swift */,
|
||||||
4CF0ABD32980996B00D66079 /* Report.swift */,
|
4CF0ABD32980996B00D66079 /* Report.swift */,
|
||||||
4CF0ABDD2981A69500D66079 /* MutelistModel.swift */,
|
|
||||||
3AE45AF5297BB2E700C1D842 /* LibreTranslateServer.swift */,
|
3AE45AF5297BB2E700C1D842 /* LibreTranslateServer.swift */,
|
||||||
3AAA95C9298DF87B00F3D526 /* TranslationService.swift */,
|
3AAA95C9298DF87B00F3D526 /* TranslationService.swift */,
|
||||||
3AAA95CB298E07E900F3D526 /* DeepLPlan.swift */,
|
3AAA95CB298E07E900F3D526 /* DeepLPlan.swift */,
|
||||||
@@ -896,14 +871,6 @@
|
|||||||
path = Images;
|
path = Images;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
4C198DF629F89317004C165C /* Parser */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
4C198DF729F89323004C165C /* BinaryParser.swift */,
|
|
||||||
);
|
|
||||||
path = Parser;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
4C1A9A1B29DDCF8B00516EAC /* Settings */ = {
|
4C1A9A1B29DDCF8B00516EAC /* Settings */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -958,8 +925,6 @@
|
|||||||
4C363A8728236948006E126D /* BlocksView.swift */,
|
4C363A8728236948006E126D /* BlocksView.swift */,
|
||||||
F75BA12E29A18EF500E10810 /* BookmarksView.swift */,
|
F75BA12E29A18EF500E10810 /* BookmarksView.swift */,
|
||||||
4C285C8128385570008A31F1 /* CarouselView.swift */,
|
4C285C8128385570008A31F1 /* CarouselView.swift */,
|
||||||
4C0A3F8B280F5FCA000448DE /* ChatroomView.swift */,
|
|
||||||
4C0A3F90280F6528000448DE /* ChatView.swift */,
|
|
||||||
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */,
|
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */,
|
||||||
4C285C8328385690008A31F1 /* CreateAccountView.swift */,
|
4C285C8328385690008A31F1 /* CreateAccountView.swift */,
|
||||||
4C64987B286D03E000EAE2B3 /* DirectMessagesView.swift */,
|
4C64987B286D03E000EAE2B3 /* DirectMessagesView.swift */,
|
||||||
@@ -971,14 +936,12 @@
|
|||||||
4C3AC79E2833115300E1F516 /* FollowButtonView.swift */,
|
4C3AC79E2833115300E1F516 /* FollowButtonView.swift */,
|
||||||
4C3AC79C2833036D00E1F516 /* FollowingView.swift */,
|
4C3AC79C2833036D00E1F516 /* FollowingView.swift */,
|
||||||
4C90BD17283A9EE5008EE7EF /* LoginView.swift */,
|
4C90BD17283A9EE5008EE7EF /* LoginView.swift */,
|
||||||
4C363A8928236B57006E126D /* MentionView.swift */,
|
|
||||||
4C363A8D28236FE4006E126D /* NoteContentView.swift */,
|
4C363A8D28236FE4006E126D /* NoteContentView.swift */,
|
||||||
4C75EFAC28049CFB0006080F /* PostButton.swift */,
|
4C75EFAC28049CFB0006080F /* PostButton.swift */,
|
||||||
4C75EFA327FA577B0006080F /* PostView.swift */,
|
4C75EFA327FA577B0006080F /* PostView.swift */,
|
||||||
9CA876E129A00CE90003B9A3 /* AttachMediaUtility.swift */,
|
9CA876E129A00CE90003B9A3 /* AttachMediaUtility.swift */,
|
||||||
F757933929D7AECD007DEAC1 /* ImagePicker.swift */,
|
F757933929D7AECD007DEAC1 /* ImagePicker.swift */,
|
||||||
9C83F89229A937B900136C08 /* TextViewWrapper.swift */,
|
9C83F89229A937B900136C08 /* TextViewWrapper.swift */,
|
||||||
4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */,
|
|
||||||
4C3AC7A42836987600E1F516 /* MainTabView.swift */,
|
4C3AC7A42836987600E1F516 /* MainTabView.swift */,
|
||||||
4C363A8B28236B92006E126D /* PubkeyView.swift */,
|
4C363A8B28236B92006E126D /* PubkeyView.swift */,
|
||||||
4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */,
|
4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */,
|
||||||
@@ -1027,7 +990,6 @@
|
|||||||
4C7FF7D628233637009601DB /* Util */ = {
|
4C7FF7D628233637009601DB /* Util */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4C198DF629F89317004C165C /* Parser */,
|
|
||||||
4C198DF329F88D23004C165C /* Images */,
|
4C198DF329F88D23004C165C /* Images */,
|
||||||
4C198DEA29F88C6B004C165C /* BlurHash */,
|
4C198DEA29F88C6B004C165C /* BlurHash */,
|
||||||
4CE4F0F329D779B5005914DB /* PostBox.swift */,
|
4CE4F0F329D779B5005914DB /* PostBox.swift */,
|
||||||
@@ -1041,7 +1003,6 @@
|
|||||||
4CE4F8CC281352B30009DFBB /* Notifications.swift */,
|
4CE4F8CC281352B30009DFBB /* Notifications.swift */,
|
||||||
4C363A8328233689006E126D /* Parser.swift */,
|
4C363A8328233689006E126D /* Parser.swift */,
|
||||||
4C363AA728297703006E126D /* InsertSort.swift */,
|
4C363AA728297703006E126D /* InsertSort.swift */,
|
||||||
4C477C9D282C3A4800033AA3 /* TipCounter.swift */,
|
|
||||||
4C285C8B28398BC6008A31F1 /* Keys.swift */,
|
4C285C8B28398BC6008A31F1 /* Keys.swift */,
|
||||||
501F8C7F2A0220E1001AFC1D /* KeychainStorage.swift */,
|
501F8C7F2A0220E1001AFC1D /* KeychainStorage.swift */,
|
||||||
4C90BD19283AA67F008EE7EF /* Bech32.swift */,
|
4C90BD19283AA67F008EE7EF /* Bech32.swift */,
|
||||||
@@ -1156,14 +1117,6 @@
|
|||||||
path = Events;
|
path = Events;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
4CCEB7A729B29DC90078AA28 /* Search */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
4CCEB7A829B29DD50078AA28 /* SearchResultsModel.swift */,
|
|
||||||
);
|
|
||||||
path = Search;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
4CCEB7AC29B53D180078AA28 /* Search */ = {
|
4CCEB7AC29B53D180078AA28 /* Search */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1186,7 +1139,6 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
31D2E846295218AF006D67F8 /* Shimmer.swift */,
|
31D2E846295218AF006D67F8 /* Shimmer.swift */,
|
||||||
4CE4F9E0285287B800C00DD9 /* TextFieldAlert.swift */,
|
|
||||||
4CD7641A28A1641400B6928F /* EndBlock.swift */,
|
4CD7641A28A1641400B6928F /* EndBlock.swift */,
|
||||||
4C06670528FCB08600038D2A /* ImageCarousel.swift */,
|
4C06670528FCB08600038D2A /* ImageCarousel.swift */,
|
||||||
4C3EA67C28FFBBA200C48A62 /* InvoicesView.swift */,
|
4C3EA67C28FFBBA200C48A62 /* InvoicesView.swift */,
|
||||||
@@ -1374,7 +1326,6 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */,
|
7C95CAED299DCEF1009DCB67 /* KFOptionSetter+.swift */,
|
||||||
7C0F392E29B57CAF0039859C /* Binding+.swift */,
|
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1568,14 +1519,12 @@
|
|||||||
files = (
|
files = (
|
||||||
4C3AC79D2833036D00E1F516 /* FollowingView.swift in Sources */,
|
4C3AC79D2833036D00E1F516 /* FollowingView.swift in Sources */,
|
||||||
5CF72FC229B9142F00124A13 /* ShareAction.swift in Sources */,
|
5CF72FC229B9142F00124A13 /* ShareAction.swift in Sources */,
|
||||||
4C363A8A28236B57006E126D /* MentionView.swift in Sources */,
|
|
||||||
4C8D1A6C29F1DFC200ACDF75 /* FriendIcon.swift in Sources */,
|
4C8D1A6C29F1DFC200ACDF75 /* FriendIcon.swift in Sources */,
|
||||||
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */,
|
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */,
|
||||||
4C30AC7829A577AB00E2BD5A /* EventCache.swift in Sources */,
|
4C30AC7829A577AB00E2BD5A /* EventCache.swift in Sources */,
|
||||||
4C285C8428385690008A31F1 /* CreateAccountView.swift in Sources */,
|
4C285C8428385690008A31F1 /* CreateAccountView.swift in Sources */,
|
||||||
4C216F34286F5ACD00040376 /* DMView.swift in Sources */,
|
4C216F34286F5ACD00040376 /* DMView.swift in Sources */,
|
||||||
4C3EA64428FF558100C48A62 /* sha256.c in Sources */,
|
4C3EA64428FF558100C48A62 /* sha256.c in Sources */,
|
||||||
4CE4F9E1285287B800C00DD9 /* TextFieldAlert.swift in Sources */,
|
|
||||||
4CF0ABF62985CD5500D66079 /* UserSearch.swift in Sources */,
|
4CF0ABF62985CD5500D66079 /* UserSearch.swift in Sources */,
|
||||||
4C363AA828297703006E126D /* InsertSort.swift in Sources */,
|
4C363AA828297703006E126D /* InsertSort.swift in Sources */,
|
||||||
4C285C86283892E7008A31F1 /* CreateAccountModel.swift in Sources */,
|
4C285C86283892E7008A31F1 /* CreateAccountModel.swift in Sources */,
|
||||||
@@ -1590,7 +1539,6 @@
|
|||||||
F757933A29D7AECD007DEAC1 /* ImagePicker.swift in Sources */,
|
F757933A29D7AECD007DEAC1 /* ImagePicker.swift in Sources */,
|
||||||
4CF0ABEE29844B5500D66079 /* AnyEncodable.swift in Sources */,
|
4CF0ABEE29844B5500D66079 /* AnyEncodable.swift in Sources */,
|
||||||
4CB8838D296F710400DC99E7 /* Reposted.swift in Sources */,
|
4CB8838D296F710400DC99E7 /* Reposted.swift in Sources */,
|
||||||
4CCEB7A929B29DD50078AA28 /* SearchResultsModel.swift in Sources */,
|
|
||||||
4C3EA67728FF7A9800C48A62 /* talstr.c in Sources */,
|
4C3EA67728FF7A9800C48A62 /* talstr.c in Sources */,
|
||||||
4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */,
|
4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */,
|
||||||
4CEE2AF5280B29E600AB5EEF /* TimeAgo.swift in Sources */,
|
4CEE2AF5280B29E600AB5EEF /* TimeAgo.swift in Sources */,
|
||||||
@@ -1613,12 +1561,9 @@
|
|||||||
4C987B57283FD07F0042CE38 /* FollowersModel.swift in Sources */,
|
4C987B57283FD07F0042CE38 /* FollowersModel.swift in Sources */,
|
||||||
3AB72AB9298ECF30004BB58C /* Translator.swift in Sources */,
|
3AB72AB9298ECF30004BB58C /* Translator.swift in Sources */,
|
||||||
4C363A9028247A1D006E126D /* NostrLink.swift in Sources */,
|
4C363A9028247A1D006E126D /* NostrLink.swift in Sources */,
|
||||||
4C0A3F8C280F5FCA000448DE /* ChatroomView.swift in Sources */,
|
|
||||||
4C477C9E282C3A4800033AA3 /* TipCounter.swift in Sources */,
|
|
||||||
4C3D52B6298DB4E6001C5831 /* ZapEvent.swift in Sources */,
|
4C3D52B6298DB4E6001C5831 /* ZapEvent.swift in Sources */,
|
||||||
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */,
|
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */,
|
||||||
F7F0BA272978E54D009531F3 /* ParticipantsView.swift in Sources */,
|
F7F0BA272978E54D009531F3 /* ParticipantsView.swift in Sources */,
|
||||||
4C0A3F91280F6528000448DE /* ChatView.swift in Sources */,
|
|
||||||
4CF0ABE32981BC7D00D66079 /* UserView.swift in Sources */,
|
4CF0ABE32981BC7D00D66079 /* UserView.swift in Sources */,
|
||||||
4CE0E2AF29A2E82100DB4CA2 /* EventHolder.swift in Sources */,
|
4CE0E2AF29A2E82100DB4CA2 /* EventHolder.swift in Sources */,
|
||||||
4CE0E2B229A3DF6900DB4CA2 /* LoadMoreButton.swift in Sources */,
|
4CE0E2B229A3DF6900DB4CA2 /* LoadMoreButton.swift in Sources */,
|
||||||
@@ -1713,7 +1658,6 @@
|
|||||||
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */,
|
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */,
|
||||||
F79C7FAD29D5E9620000F946 /* EditProfilePictureControl.swift in Sources */,
|
F79C7FAD29D5E9620000F946 /* EditProfilePictureControl.swift in Sources */,
|
||||||
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */,
|
4C9F18E229AA9B6C008C55EC /* CustomizeZapView.swift in Sources */,
|
||||||
4C198DF829F89323004C165C /* BinaryParser.swift in Sources */,
|
|
||||||
4C75EFAF28049D350006080F /* NostrFilter.swift in Sources */,
|
4C75EFAF28049D350006080F /* NostrFilter.swift in Sources */,
|
||||||
4C3EA64C28FF59AC00C48A62 /* bech32_util.c in Sources */,
|
4C3EA64C28FF59AC00C48A62 /* bech32_util.c in Sources */,
|
||||||
4CE1399029F0661A00AC6A0B /* RepostAction.swift in Sources */,
|
4CE1399029F0661A00AC6A0B /* RepostAction.swift in Sources */,
|
||||||
@@ -1754,7 +1698,6 @@
|
|||||||
4C8D00CC29DF92DF0036AF10 /* Hashtags.swift in Sources */,
|
4C8D00CC29DF92DF0036AF10 /* Hashtags.swift in Sources */,
|
||||||
4CEE2AF3280B25C500AB5EEF /* ProfilePicView.swift in Sources */,
|
4CEE2AF3280B25C500AB5EEF /* ProfilePicView.swift in Sources */,
|
||||||
4CC7AAF6297F1A6A00430951 /* EventBody.swift in Sources */,
|
4CC7AAF6297F1A6A00430951 /* EventBody.swift in Sources */,
|
||||||
4CEE2AF9280B2EAC00AB5EEF /* PowView.swift in Sources */,
|
|
||||||
3165648B295B70D500C64604 /* LinkView.swift in Sources */,
|
3165648B295B70D500C64604 /* LinkView.swift in Sources */,
|
||||||
4C8D00CF29E38B950036AF10 /* nostr_bech32.c in Sources */,
|
4C8D00CF29E38B950036AF10 /* nostr_bech32.c in Sources */,
|
||||||
4C3BEFD42819DE8F00B3DE84 /* NostrKind.swift in Sources */,
|
4C3BEFD42819DE8F00B3DE84 /* NostrKind.swift in Sources */,
|
||||||
@@ -1771,7 +1714,6 @@
|
|||||||
4CB9D4A92992D2F400A9A7E4 /* FollowsYou.swift in Sources */,
|
4CB9D4A92992D2F400A9A7E4 /* FollowsYou.swift in Sources */,
|
||||||
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */,
|
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */,
|
||||||
4CB88389296AF99A00DC99E7 /* EventDetailBar.swift in Sources */,
|
4CB88389296AF99A00DC99E7 /* EventDetailBar.swift in Sources */,
|
||||||
4CF0ABDE2981A69500D66079 /* MutelistModel.swift in Sources */,
|
|
||||||
4CE8794E2996B16A00F758CC /* RelayToggle.swift in Sources */,
|
4CE8794E2996B16A00F758CC /* RelayToggle.swift in Sources */,
|
||||||
4C3AC79B28306D7B00E1F516 /* Contacts.swift in Sources */,
|
4C3AC79B28306D7B00E1F516 /* Contacts.swift in Sources */,
|
||||||
4C3EA63D28FF52D600C48A62 /* bolt11.c in Sources */,
|
4C3EA63D28FF52D600C48A62 /* bolt11.c in Sources */,
|
||||||
@@ -1804,7 +1746,6 @@
|
|||||||
3AA247FF297E3D900090C62D /* RepostsView.swift in Sources */,
|
3AA247FF297E3D900090C62D /* RepostsView.swift in Sources */,
|
||||||
3AE45AF6297BB2E700C1D842 /* LibreTranslateServer.swift in Sources */,
|
3AE45AF6297BB2E700C1D842 /* LibreTranslateServer.swift in Sources */,
|
||||||
4CE879502996B2BD00F758CC /* RelayStatus.swift in Sources */,
|
4CE879502996B2BD00F758CC /* RelayStatus.swift in Sources */,
|
||||||
4C99737B28C92A9200E53835 /* ChatroomMetadata.swift in Sources */,
|
|
||||||
4CC7AAF4297F18B400430951 /* ReplyDescription.swift in Sources */,
|
4CC7AAF4297F18B400430951 /* ReplyDescription.swift in Sources */,
|
||||||
4C75EFA427FA577B0006080F /* PostView.swift in Sources */,
|
4C75EFA427FA577B0006080F /* PostView.swift in Sources */,
|
||||||
4C30AC7229A5677A00E2BD5A /* NotificationsView.swift in Sources */,
|
4C30AC7229A5677A00E2BD5A /* NotificationsView.swift in Sources */,
|
||||||
@@ -1816,7 +1757,6 @@
|
|||||||
4CC7AAFA297F64AC00430951 /* EventMenu.swift in Sources */,
|
4CC7AAFA297F64AC00430951 /* EventMenu.swift in Sources */,
|
||||||
4C75EFBB2804A34C0006080F /* ProofOfWork.swift in Sources */,
|
4C75EFBB2804A34C0006080F /* ProofOfWork.swift in Sources */,
|
||||||
4C3AC7A52836987600E1F516 /* MainTabView.swift in Sources */,
|
4C3AC7A52836987600E1F516 /* MainTabView.swift in Sources */,
|
||||||
7C0F392F29B57CAF0039859C /* Binding+.swift in Sources */,
|
|
||||||
4C1A9A1F29DDD24B00516EAC /* AppearanceSettingsView.swift in Sources */,
|
4C1A9A1F29DDD24B00516EAC /* AppearanceSettingsView.swift in Sources */,
|
||||||
3AA59D1D2999B0400061C48E /* DraftsModel.swift in Sources */,
|
3AA59D1D2999B0400061C48E /* DraftsModel.swift in Sources */,
|
||||||
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */,
|
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */,
|
||||||
|
|||||||
@@ -14,26 +14,5 @@ enum Highlight {
|
|||||||
case main
|
case main
|
||||||
case reply
|
case reply
|
||||||
case custom(Color, Float)
|
case custom(Color, Float)
|
||||||
|
|
||||||
var is_main: Bool {
|
|
||||||
if case .main = self {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var is_none: Bool {
|
|
||||||
if case .none = self {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var is_replied_to: Bool {
|
|
||||||
switch self {
|
|
||||||
case .reply: return true
|
|
||||||
default: return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,17 +52,6 @@ enum ImageShape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try either calculated imagefill from the real image or from metadata hints in tags
|
|
||||||
func lookup_imgmeta_size_hint(events: EventCache, url: URL?) -> CGSize? {
|
|
||||||
guard let url,
|
|
||||||
let meta = events.lookup_img_metadata(url: url),
|
|
||||||
let img_size = meta.meta.dim?.size else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return img_size
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ImageCarousel: View {
|
struct ImageCarousel: View {
|
||||||
var urls: [URL]
|
var urls: [URL]
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import SwiftUI
|
|||||||
|
|
||||||
struct InvoiceView: View {
|
struct InvoiceView: View {
|
||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
@Environment(\.openURL) private var openURL
|
|
||||||
let our_pubkey: String
|
let our_pubkey: String
|
||||||
let invoice: Invoice
|
let invoice: Invoice
|
||||||
@State var showing_select_wallet: Bool = false
|
@State var showing_select_wallet: Bool = false
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ struct InvoicesView: View {
|
|||||||
var invoices: [Invoice]
|
var invoices: [Invoice]
|
||||||
let settings: UserSettingsStore
|
let settings: UserSettingsStore
|
||||||
|
|
||||||
@State var open_sheet: Bool = false
|
|
||||||
@State var current_invoice: Invoice? = nil
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
TabView {
|
TabView {
|
||||||
ForEach(invoices, id: \.string) { invoice in
|
ForEach(invoices, id: \.string) { invoice in
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct Reposted: View {
|
|||||||
HStack(alignment: .center) {
|
HStack(alignment: .center) {
|
||||||
Image(systemName: "arrow.2.squarepath")
|
Image(systemName: "arrow.2.squarepath")
|
||||||
.foregroundColor(Color.gray)
|
.foregroundColor(Color.gray)
|
||||||
ProfileName(pubkey: pubkey, profile: profile, damus: damus, show_friend_confirmed: true, show_nip5_domain: false)
|
ProfileName(pubkey: pubkey, profile: profile, damus: damus, show_nip5_domain: false)
|
||||||
.foregroundColor(Color.gray)
|
.foregroundColor(Color.gray)
|
||||||
Text("Reposted", comment: "Text indicating that the post was reposted (i.e. re-shared).")
|
Text("Reposted", comment: "Text indicating that the post was reposted (i.e. re-shared).")
|
||||||
.foregroundColor(Color.gray)
|
.foregroundColor(Color.gray)
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import SwiftUI
|
|||||||
|
|
||||||
public struct ShimmerConfiguration {
|
public struct ShimmerConfiguration {
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
|
||||||
|
|
||||||
public let gradient: Gradient
|
public let gradient: Gradient
|
||||||
public let initialLocation: (start: UnitPoint, end: UnitPoint)
|
public let initialLocation: (start: UnitPoint, end: UnitPoint)
|
||||||
public let finalLocation: (start: UnitPoint, end: UnitPoint)
|
public let finalLocation: (start: UnitPoint, end: UnitPoint)
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
//
|
|
||||||
// TextFieldAlert.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2022-06-09.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct TextFieldAlert<Presenting>: View where Presenting: View {
|
|
||||||
@Binding var isShowing: Bool
|
|
||||||
@Binding var text: String
|
|
||||||
let presenting: Presenting
|
|
||||||
let title: String
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
GeometryReader { (deviceSize: GeometryProxy) in
|
|
||||||
ZStack {
|
|
||||||
self.presenting
|
|
||||||
.disabled(isShowing)
|
|
||||||
VStack {
|
|
||||||
Text(self.title)
|
|
||||||
TextField(NSLocalizedString("Relay", comment: "Text field for relay server. Used for testing purposes."), text: self.$text)
|
|
||||||
Divider()
|
|
||||||
HStack {
|
|
||||||
Button(action: {
|
|
||||||
withAnimation {
|
|
||||||
self.isShowing.toggle()
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
Text("Dismiss", comment: "Button to dismiss a text field alert.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.padding()
|
|
||||||
.background(Color.white)
|
|
||||||
.frame(
|
|
||||||
width: deviceSize.size.width*0.7,
|
|
||||||
height: deviceSize.size.height*0.7
|
|
||||||
)
|
|
||||||
.shadow(radius: 1)
|
|
||||||
.opacity(self.isShowing ? 1 : 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extension View {
|
|
||||||
|
|
||||||
func textFieldAlert(isShowing: Binding<Bool>,
|
|
||||||
text: Binding<String>,
|
|
||||||
title: String) -> some View {
|
|
||||||
TextFieldAlert(isShowing: isShowing,
|
|
||||||
text: text,
|
|
||||||
presenting: self,
|
|
||||||
title: title)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -143,7 +143,7 @@ func translate_note(profiles: Profiles, privkey: String?, event: NostrEvent, set
|
|||||||
|
|
||||||
// Render translated note
|
// Render translated note
|
||||||
let translated_blocks = event.get_blocks(content: translated_note)
|
let translated_blocks = event.get_blocks(content: translated_note)
|
||||||
let artifacts = render_blocks(blocks: translated_blocks, profiles: profiles, privkey: privkey)
|
let artifacts = render_blocks(blocks: translated_blocks, profiles: profiles)
|
||||||
|
|
||||||
// and cache it
|
// and cache it
|
||||||
return .translated(Translated(artifacts: artifacts, language: note_lang))
|
return .translated(Translated(artifacts: artifacts, language: note_lang))
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ struct UserView: View {
|
|||||||
|
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
let profile = damus_state.profiles.lookup(id: pubkey)
|
let profile = damus_state.profiles.lookup(id: pubkey)
|
||||||
ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: false, show_nip5_domain: false)
|
ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_nip5_domain: false)
|
||||||
if let about = profile?.about {
|
if let about = profile?.about {
|
||||||
Text(about)
|
Text(about)
|
||||||
.lineLimit(3)
|
.lineLimit(3)
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ struct ZapButton: View {
|
|||||||
|
|
||||||
@State var zapping: Bool = false
|
@State var zapping: Bool = false
|
||||||
@State var invoice: String = ""
|
@State var invoice: String = ""
|
||||||
@State var slider_value: Double = 0.0
|
|
||||||
@State var slider_visible: Bool = false
|
|
||||||
@State var showing_select_wallet: Bool = false
|
@State var showing_select_wallet: Bool = false
|
||||||
@State var showing_zap_customizer: Bool = false
|
@State var showing_zap_customizer: Bool = false
|
||||||
@State var is_charging: Bool = false
|
@State var is_charging: Bool = false
|
||||||
|
|||||||
@@ -29,11 +29,6 @@ enum Sheets: Identifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ThreadState {
|
|
||||||
case event_details
|
|
||||||
case chatroom
|
|
||||||
}
|
|
||||||
|
|
||||||
enum FilterState : Int {
|
enum FilterState : Int {
|
||||||
case posts_and_replies = 1
|
case posts_and_replies = 1
|
||||||
case posts = 0
|
case posts = 0
|
||||||
@@ -61,13 +56,10 @@ struct ContentView: View {
|
|||||||
|
|
||||||
@Environment(\.scenePhase) var scenePhase
|
@Environment(\.scenePhase) var scenePhase
|
||||||
|
|
||||||
@State var status: String = "Not connected"
|
|
||||||
@State var active_sheet: Sheets? = nil
|
@State var active_sheet: Sheets? = nil
|
||||||
@State var damus_state: DamusState? = nil
|
@State var damus_state: DamusState? = nil
|
||||||
@SceneStorage("ContentView.selected_timeline") var selected_timeline: Timeline = .home
|
@SceneStorage("ContentView.selected_timeline") var selected_timeline: Timeline = .home
|
||||||
@State var is_deleted_account: Bool = false
|
@State var is_deleted_account: Bool = false
|
||||||
@State var is_profile_open: Bool = false
|
|
||||||
@State var event: NostrEvent? = nil
|
|
||||||
@State var active_profile: String? = nil
|
@State var active_profile: String? = nil
|
||||||
@State var active_search: NostrFilter? = nil
|
@State var active_search: NostrFilter? = nil
|
||||||
@State var active_event: NostrEvent? = nil
|
@State var active_event: NostrEvent? = nil
|
||||||
@@ -551,19 +543,6 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.selected_timeline = timeline
|
self.selected_timeline = timeline
|
||||||
//NotificationCenter.default.post(name: .switched_timeline, object: timeline)
|
|
||||||
//self.selected_timeline = timeline
|
|
||||||
}
|
|
||||||
|
|
||||||
func add_relay(_ pool: RelayPool, _ relay: String) {
|
|
||||||
//add_rw_relay(pool, "wss://nostr-pub.wellorder.net")
|
|
||||||
add_rw_relay(pool, relay)
|
|
||||||
/*
|
|
||||||
let profile = Profile(name: relay, about: nil, picture: nil)
|
|
||||||
let ts = Int64(Date().timeIntervalSince1970)
|
|
||||||
let tsprofile = TimestampedProfile(profile: profile, timestamp: ts)
|
|
||||||
damus!.profiles.add(id: relay, profile: tsprofile)
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect() {
|
func connect() {
|
||||||
@@ -591,7 +570,6 @@ struct ContentView: View {
|
|||||||
likes: EventCounter(our_pubkey: pubkey),
|
likes: EventCounter(our_pubkey: pubkey),
|
||||||
boosts: EventCounter(our_pubkey: pubkey),
|
boosts: EventCounter(our_pubkey: pubkey),
|
||||||
contacts: Contacts(our_pubkey: pubkey),
|
contacts: Contacts(our_pubkey: pubkey),
|
||||||
tips: TipCounter(our_pubkey: pubkey),
|
|
||||||
profiles: Profiles(),
|
profiles: Profiles(),
|
||||||
dms: home.dms,
|
dms: home.dms,
|
||||||
previews: PreviewCache(),
|
previews: PreviewCache(),
|
||||||
@@ -630,14 +608,6 @@ func get_since_time(last_event: NostrEvent?) -> Int64? {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func is_notification(ev: NostrEvent, pubkey: String) -> Bool {
|
|
||||||
if ev.pubkey == pubkey {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return ev.references(id: pubkey, key: "p")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extension UINavigationController: UIGestureRecognizerDelegate {
|
extension UINavigationController: UIGestureRecognizerDelegate {
|
||||||
override open func viewDidLoad() {
|
override open func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
@@ -673,12 +643,6 @@ func save_last_event(_ ev: NostrEvent, timeline: Timeline) {
|
|||||||
UserDefaults.standard.set(String(ev.created_at), forKey: "last_\(str)_time")
|
UserDefaults.standard.set(String(ev.created_at), forKey: "last_\(str)_time")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func get_like_pow() -> [String] {
|
|
||||||
return ["00000"] // 20 bits
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func update_filters_with_since(last_of_kind: [Int: NostrEvent], filters: [NostrFilter]) -> [NostrFilter] {
|
func update_filters_with_since(last_of_kind: [Int: NostrEvent], filters: [NostrFilter]) -> [NostrFilter] {
|
||||||
|
|
||||||
return filters.map { filter in
|
return filters.map { filter in
|
||||||
@@ -713,7 +677,6 @@ func update_filters_with_since(last_of_kind: [Int: NostrEvent], filters: [NostrF
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func setup_notifications() {
|
func setup_notifications() {
|
||||||
|
|
||||||
UIApplication.shared.registerForRemoteNotifications()
|
UIApplication.shared.registerForRemoteNotifications()
|
||||||
@@ -788,7 +751,6 @@ func find_event(state: DamusState, evid: String, search_type: SearchType, find_f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func timeline_name(_ timeline: Timeline?) -> String {
|
func timeline_name(_ timeline: Timeline?) -> String {
|
||||||
guard let timeline else {
|
guard let timeline else {
|
||||||
return ""
|
return ""
|
||||||
@@ -872,5 +834,3 @@ func handle_post_notification(keypair: FullKeypair, postbox: PostBox, events: Ev
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ func save_bookmarks(pubkey: String, current_value: [NostrEvent], value: [NostrEv
|
|||||||
|
|
||||||
class BookmarksManager: ObservableObject {
|
class BookmarksManager: ObservableObject {
|
||||||
|
|
||||||
private let userDefaults = UserDefaults.standard
|
|
||||||
private let pubkey: String
|
private let pubkey: String
|
||||||
|
|
||||||
private var _bookmarks: [NostrEvent]
|
private var _bookmarks: [NostrEvent]
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
//
|
|
||||||
// ChatroomMetadata.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2022-09-07.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
|
|
||||||
struct ChatroomMetadata: Decodable {
|
|
||||||
let name: String?
|
|
||||||
let about: String?
|
|
||||||
let picture: String?
|
|
||||||
}
|
|
||||||
@@ -56,12 +56,6 @@ class Contacts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_friendosphere() -> [String] {
|
|
||||||
var fs = get_friend_list()
|
|
||||||
fs.append(contentsOf: get_friend_of_friend_list())
|
|
||||||
return fs
|
|
||||||
}
|
|
||||||
|
|
||||||
func remove_friend(_ pubkey: String) {
|
func remove_friend(_ pubkey: String) {
|
||||||
friends.remove(pubkey)
|
friends.remove(pubkey)
|
||||||
}
|
}
|
||||||
@@ -70,10 +64,6 @@ class Contacts {
|
|||||||
return Array(friends)
|
return Array(friends)
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_friend_of_friend_list() -> [String] {
|
|
||||||
return Array(friend_of_friends)
|
|
||||||
}
|
|
||||||
|
|
||||||
func add_friend_pubkey(_ pubkey: String) {
|
func add_friend_pubkey(_ pubkey: String) {
|
||||||
friends.insert(pubkey)
|
friends.insert(pubkey)
|
||||||
}
|
}
|
||||||
@@ -108,24 +98,6 @@ class Contacts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func create_contacts(relays: [RelayDescriptor], our_pubkey: String, follow: ReferencedId) -> NostrEvent {
|
|
||||||
let kind = NostrKind.contacts.rawValue
|
|
||||||
let content = create_contacts_content(relays) ?? "{}"
|
|
||||||
let tags = [refid_to_tag(follow)]
|
|
||||||
return NostrEvent(content: content, pubkey: our_pubkey, kind: kind, tags: tags)
|
|
||||||
}
|
|
||||||
|
|
||||||
func create_contacts_content(_ relays: [RelayDescriptor]) -> String? {
|
|
||||||
// TODO: just create a new one of this is corrupted?
|
|
||||||
let crelays = make_contact_relays(relays)
|
|
||||||
guard let encoded = encode_json(crelays) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return encoded
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func follow_user(pool: RelayPool, our_contacts: NostrEvent?, pubkey: String, privkey: String, follow: ReferencedId) -> NostrEvent? {
|
func follow_user(pool: RelayPool, our_contacts: NostrEvent?, pubkey: String, privkey: String, follow: ReferencedId) -> NostrEvent? {
|
||||||
guard let ev = follow_user_event(our_contacts: our_contacts, our_pubkey: pubkey, follow: follow) else {
|
guard let ev = follow_user_event(our_contacts: our_contacts, our_pubkey: pubkey, follow: follow) else {
|
||||||
return nil
|
return nil
|
||||||
@@ -245,37 +217,3 @@ func make_contact_relays(_ relays: [RelayDescriptor]) -> [String: RelayInfo] {
|
|||||||
acc[relay.url.url.absoluteString] = relay.info
|
acc[relay.url.url.absoluteString] = relay.info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: tests for this
|
|
||||||
func is_friend_event(_ ev: NostrEvent, keypair: Keypair, contacts: Contacts) -> Bool
|
|
||||||
{
|
|
||||||
if !contacts.is_friend(ev.pubkey) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if ev.is_reply(keypair.privkey) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
let pks = get_referenced_id_set(tags: ev.tags, key: "p")
|
|
||||||
|
|
||||||
// reply to self
|
|
||||||
if pks.count == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow reply-to-self-or-friend case
|
|
||||||
if pks.count == 1 && contacts.is_friend(pks.first!.ref_id) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// show our replies?
|
|
||||||
for pk in pks {
|
|
||||||
// don't count self mentions here
|
|
||||||
if pk.ref_id != ev.pubkey && contacts.is_friend(pk.ref_id) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ struct DamusState {
|
|||||||
let likes: EventCounter
|
let likes: EventCounter
|
||||||
let boosts: EventCounter
|
let boosts: EventCounter
|
||||||
let contacts: Contacts
|
let contacts: Contacts
|
||||||
let tips: TipCounter
|
|
||||||
let profiles: Profiles
|
let profiles: Profiles
|
||||||
let dms: DirectMessagesModel
|
let dms: DirectMessagesModel
|
||||||
let previews: PreviewCache
|
let previews: PreviewCache
|
||||||
@@ -47,8 +46,6 @@ struct DamusState {
|
|||||||
keypair.privkey != nil
|
keypair.privkey != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static var settings_pubkey: String? = nil
|
|
||||||
|
|
||||||
static var empty: DamusState {
|
static var empty: DamusState {
|
||||||
return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(our_pubkey: ""), tips: TipCounter(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel(our_pubkey: ""), previews: PreviewCache(), zaps: Zaps(our_pubkey: ""), lnurls: LNUrls(), settings: UserSettingsStore(), relay_filters: RelayFilters(our_pubkey: ""), relay_metadata: RelayMetadatas(), drafts: Drafts(), events: EventCache(), bookmarks: BookmarksManager(pubkey: ""), postbox: PostBox(pool: RelayPool()), bootstrap_relays: [], replies: ReplyCounter(our_pubkey: ""), muted_threads: MutedThreadsManager(keypair: Keypair(pubkey: "", privkey: nil))) }
|
return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel(our_pubkey: ""), previews: PreviewCache(), zaps: Zaps(our_pubkey: ""), lnurls: LNUrls(), settings: UserSettingsStore(), relay_filters: RelayFilters(our_pubkey: ""), relay_metadata: RelayMetadatas(), drafts: Drafts(), events: EventCache(), bookmarks: BookmarksManager(pubkey: ""), postbox: PostBox(pool: RelayPool()), bootstrap_relays: [], replies: ReplyCounter(our_pubkey: ""), muted_threads: MutedThreadsManager(keypair: Keypair(pubkey: "", privkey: nil))) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,4 @@ enum DeepLPlan: String, CaseIterable, Identifiable, StringCodable {
|
|||||||
return .init(tag: self.rawValue, displayName: NSLocalizedString("Pro", comment: "Dropdown option for selecting Pro plan for DeepL translation service."), url: "https://api.deepl.com")
|
return .init(tag: self.rawValue, displayName: NSLocalizedString("Pro", comment: "Dropdown option for selecting Pro plan for DeepL translation service."), url: "https://api.deepl.com")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static var allModels: [Model] {
|
|
||||||
return Self.allCases.map { $0.model }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,15 +60,6 @@ enum EventRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func has_any_e_refs(_ tags: [[String]]) -> Bool {
|
|
||||||
for tag in tags {
|
|
||||||
if tag.count >= 2 && tag[0] == "e" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func build_mention_indices(_ blocks: [Block], type: MentionType) -> Set<Int> {
|
func build_mention_indices(_ blocks: [Block], type: MentionType) -> Set<Int> {
|
||||||
return blocks.reduce(into: []) { acc, block in
|
return blocks.reduce(into: []) { acc, block in
|
||||||
switch block {
|
switch block {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import Foundation
|
|||||||
class FollowersModel: ObservableObject {
|
class FollowersModel: ObservableObject {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
let target: String
|
let target: String
|
||||||
var needs_sub: Bool = true
|
|
||||||
|
|
||||||
@Published var contacts: [String]? = nil
|
@Published var contacts: [String]? = nil
|
||||||
var has_contact: Set<String> = Set()
|
var has_contact: Set<String> = Set()
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ class FollowingModel {
|
|||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
var needs_sub: Bool = true
|
var needs_sub: Bool = true
|
||||||
|
|
||||||
var has_contact: Set<String> = Set()
|
|
||||||
let contacts: [String]
|
let contacts: [String]
|
||||||
|
|
||||||
let sub_id: String = UUID().description
|
let sub_id: String = UUID().description
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class HomeModel: ObservableObject {
|
|||||||
case .channel_create:
|
case .channel_create:
|
||||||
handle_channel_create(ev)
|
handle_channel_create(ev)
|
||||||
case .channel_meta:
|
case .channel_meta:
|
||||||
handle_channel_meta(ev)
|
break
|
||||||
case .zap:
|
case .zap:
|
||||||
handle_zap_event(ev)
|
handle_zap_event(ev)
|
||||||
case .zap_request:
|
case .zap_request:
|
||||||
@@ -140,7 +140,7 @@ class HomeModel: ObservableObject {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !notifications.insert_zap(zap, damus_state: damus_state) {
|
if !notifications.insert_zap(zap) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,9 +195,6 @@ class HomeModel: ObservableObject {
|
|||||||
self.channels[ev.id] = ev
|
self.channels[ev.id] = ev
|
||||||
}
|
}
|
||||||
|
|
||||||
func handle_channel_meta(_ ev: NostrEvent) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func filter_events() {
|
func filter_events() {
|
||||||
events.filter { ev in
|
events.filter { ev in
|
||||||
!damus_state.contacts.is_muted(ev.pubkey)
|
!damus_state.contacts.is_muted(ev.pubkey)
|
||||||
@@ -327,7 +324,6 @@ class HomeModel: ObservableObject {
|
|||||||
|
|
||||||
self.process_event(sub_id: sub_id, relay_id: relay_id, ev: ev)
|
self.process_event(sub_id: sub_id, relay_id: relay_id, ev: ev)
|
||||||
case .notice(let msg):
|
case .notice(let msg):
|
||||||
//self.events.insert(NostrEvent(content: "NOTICE from \(relay_id): \(msg)", pubkey: "system"), at: 0)
|
|
||||||
print(msg)
|
print(msg)
|
||||||
|
|
||||||
case .eose(let sub_id):
|
case .eose(let sub_id):
|
||||||
@@ -600,7 +596,7 @@ func add_contact_if_friend(contacts: Contacts, ev: NostrEvent) {
|
|||||||
contacts.add_friend_contact(ev)
|
contacts.add_friend_contact(ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
func load_our_contacts(contacts: Contacts, our_pubkey: String, m_old_ev: NostrEvent?, ev: NostrEvent) {
|
func load_our_contacts(contacts: Contacts, m_old_ev: NostrEvent?, ev: NostrEvent) {
|
||||||
var new_pks = Set<String>()
|
var new_pks = Set<String>()
|
||||||
// our contacts
|
// our contacts
|
||||||
for tag in ev.tags {
|
for tag in ev.tags {
|
||||||
@@ -798,7 +794,7 @@ func load_our_stuff(state: DamusState, ev: NostrEvent) {
|
|||||||
let m_old_ev = state.contacts.event
|
let m_old_ev = state.contacts.event
|
||||||
state.contacts.event = ev
|
state.contacts.event = ev
|
||||||
|
|
||||||
load_our_contacts(contacts: state.contacts, our_pubkey: state.pubkey, m_old_ev: m_old_ev, ev: ev)
|
load_our_contacts(contacts: state.contacts, m_old_ev: m_old_ev, ev: ev)
|
||||||
load_our_relays(state: state, m_old_ev: m_old_ev, ev: ev)
|
load_our_relays(state: state, m_old_ev: m_old_ev, ev: ev)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,9 +892,6 @@ func fetch_relay_metadata(relay_id: String) async throws -> RelayMetadata? {
|
|||||||
return nip11
|
return nip11
|
||||||
}
|
}
|
||||||
|
|
||||||
func process_relay_metadata() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, dms: DirectMessagesModel, prev_events: NewEventsBits) -> (Bool, NewEventsBits?) {
|
func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, dms: DirectMessagesModel, prev_events: NewEventsBits) -> (Bool, NewEventsBits?) {
|
||||||
var inserted = false
|
var inserted = false
|
||||||
|
|||||||
@@ -42,8 +42,4 @@ enum LibreTranslateServer: String, CaseIterable, Identifiable, StringCodable {
|
|||||||
return .init(tag: self.rawValue, displayName: NSLocalizedString("Custom", comment: "Dropdown option for selecting a custom translation server."), url: nil)
|
return .init(tag: self.rawValue, displayName: NSLocalizedString("Custom", comment: "Dropdown option for selecting a custom translation server."), url: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static var allModels: [Model] {
|
|
||||||
return Self.allCases.map { $0.model }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,3 @@ struct Counted {
|
|||||||
let id: String
|
let id: String
|
||||||
let total: Int
|
let total: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LikeRefs {
|
|
||||||
let thread_id: String?
|
|
||||||
let like_id: String
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -27,11 +27,6 @@ struct Mention: Equatable {
|
|||||||
let ref: ReferencedId
|
let ref: ReferencedId
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IdBlock: Identifiable {
|
|
||||||
let id: String = UUID().description
|
|
||||||
let block: Block
|
|
||||||
}
|
|
||||||
|
|
||||||
typealias Invoice = LightningInvoice<Amount>
|
typealias Invoice = LightningInvoice<Amount>
|
||||||
typealias ZapInvoice = LightningInvoice<Int64>
|
typealias ZapInvoice = LightningInvoice<Int64>
|
||||||
|
|
||||||
@@ -155,10 +150,6 @@ func render_blocks(blocks: [Block]) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse_textblock(str: String, from: Int, to: Int) -> Block {
|
|
||||||
return .text(String(substring(str, start: from, end: to)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func parse_mentions(content: String, tags: [[String]]) -> [Block] {
|
func parse_mentions(content: String, tags: [[String]]) -> [Block] {
|
||||||
var out: [Block] = []
|
var out: [Block] = []
|
||||||
|
|
||||||
@@ -249,32 +240,6 @@ enum Amount: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func format_actions_abbrev(_ actions: Int) -> String {
|
|
||||||
let formatter = NumberFormatter()
|
|
||||||
formatter.numberStyle = .decimal
|
|
||||||
formatter.positiveSuffix = "m"
|
|
||||||
formatter.positivePrefix = ""
|
|
||||||
formatter.minimumFractionDigits = 0
|
|
||||||
formatter.maximumFractionDigits = 3
|
|
||||||
formatter.roundingMode = .down
|
|
||||||
formatter.roundingIncrement = 0.1
|
|
||||||
formatter.multiplier = 1
|
|
||||||
|
|
||||||
if actions >= 1_000_000 {
|
|
||||||
formatter.positiveSuffix = "m"
|
|
||||||
formatter.multiplier = 0.000001
|
|
||||||
} else if actions >= 1000 {
|
|
||||||
formatter.positiveSuffix = "k"
|
|
||||||
formatter.multiplier = 0.001
|
|
||||||
} else {
|
|
||||||
return "\(actions)"
|
|
||||||
}
|
|
||||||
|
|
||||||
let actions = NSNumber(value: actions)
|
|
||||||
|
|
||||||
return formatter.string(from: actions) ?? "\(actions)"
|
|
||||||
}
|
|
||||||
|
|
||||||
func format_msats_abbrev(_ msats: Int64) -> String {
|
func format_msats_abbrev(_ msats: Int64) -> String {
|
||||||
let formatter = NumberFormatter()
|
let formatter = NumberFormatter()
|
||||||
formatter.numberStyle = .decimal
|
formatter.numberStyle = .decimal
|
||||||
@@ -423,59 +388,6 @@ func convert_mention_index_block(ind: Int32, tags: [[String]]) -> Block?
|
|||||||
return .mention(Mention(index: ind, type: mention_type, ref: ref))
|
return .mention(Mention(index: ind, type: mention_type, ref: ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse_mentions_old(content: String, tags: [[String]]) -> [Block] {
|
|
||||||
let p = Parser(pos: 0, str: content)
|
|
||||||
var blocks: [Block] = []
|
|
||||||
var starting_from: Int = 0
|
|
||||||
|
|
||||||
while p.pos < content.count {
|
|
||||||
if !consume_until(p, match: { !$0.isWhitespace}) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
let pre_mention = p.pos
|
|
||||||
|
|
||||||
let c = peek_char(p, 0)
|
|
||||||
let pr = peek_char(p, -1)
|
|
||||||
|
|
||||||
if c == "#" {
|
|
||||||
if let mention = parse_mention(p, tags: tags) {
|
|
||||||
blocks.append(parse_textblock(str: p.str, from: starting_from, to: pre_mention))
|
|
||||||
blocks.append(.mention(mention))
|
|
||||||
starting_from = p.pos
|
|
||||||
} else if let hashtag = parse_hashtag(p) {
|
|
||||||
blocks.append(parse_textblock(str: p.str, from: starting_from, to: pre_mention))
|
|
||||||
blocks.append(.hashtag(hashtag))
|
|
||||||
starting_from = p.pos
|
|
||||||
} else {
|
|
||||||
if !consume_until(p, match: { $0.isWhitespace }) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if c == "h" && (pr == nil || pr!.isWhitespace) {
|
|
||||||
if let url = parse_url(p) {
|
|
||||||
blocks.append(parse_textblock(str: p.str, from: starting_from, to: pre_mention))
|
|
||||||
blocks.append(.url(url))
|
|
||||||
starting_from = p.pos
|
|
||||||
} else {
|
|
||||||
if !consume_until(p, match: { $0.isWhitespace }) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !consume_until(p, match: { $0.isWhitespace }) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.str.count - starting_from > 0 {
|
|
||||||
blocks.append(parse_textblock(str: p.str, from: starting_from, to: p.str.count))
|
|
||||||
}
|
|
||||||
|
|
||||||
return blocks
|
|
||||||
}
|
|
||||||
|
|
||||||
func parse_while(_ p: Parser, match: (Character) -> Bool) -> String? {
|
func parse_while(_ p: Parser, match: (Character) -> Bool) -> String? {
|
||||||
var i: Int = 0
|
var i: Int = 0
|
||||||
let sub = substring(p.str, start: p.pos, end: p.str.count)
|
let sub = substring(p.str, start: p.pos, end: p.str.count)
|
||||||
@@ -513,37 +425,6 @@ func is_punctuation(_ c: Character) -> Bool {
|
|||||||
return c.isWhitespace || c.isPunctuation
|
return c.isWhitespace || c.isPunctuation
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse_url(_ p: Parser) -> URL? {
|
|
||||||
let start = p.pos
|
|
||||||
|
|
||||||
if !parse_str(p, "http") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if parse_char(p, "s") {
|
|
||||||
if !parse_str(p, "://") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !parse_str(p, "://") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !consume_until(p, match: { c in c.isWhitespace }, end_ok: true) {
|
|
||||||
p.pos = start
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
let url_str = String(substring(p.str, start: start, end: p.pos))
|
|
||||||
guard let url = URL(string: url_str) else {
|
|
||||||
p.pos = start
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
|
|
||||||
func parse_hashtag(_ p: Parser) -> String? {
|
func parse_hashtag(_ p: Parser) -> String? {
|
||||||
let start = p.pos
|
let start = p.pos
|
||||||
|
|
||||||
@@ -566,51 +447,6 @@ func parse_hashtag(_ p: Parser) -> String? {
|
|||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse_mention(_ p: Parser, tags: [[String]]) -> Mention? {
|
|
||||||
let start = p.pos
|
|
||||||
|
|
||||||
if !parse_str(p, "#[") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let digit = parse_digit(p) else {
|
|
||||||
p.pos = start
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var ind = digit
|
|
||||||
|
|
||||||
if let d2 = parse_digit(p) {
|
|
||||||
ind = digit * 10
|
|
||||||
ind += d2
|
|
||||||
}
|
|
||||||
|
|
||||||
if !parse_char(p, "]") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var kind: MentionType = .pubkey
|
|
||||||
if ind > tags.count - 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if tags[ind].count == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch tags[ind][0] {
|
|
||||||
case "e": kind = .event
|
|
||||||
case "p": kind = .pubkey
|
|
||||||
default: return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let ref = tag_to_refid(tags[ind]) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return Mention(index: ind, type: kind, ref: ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
func find_tag_ref(type: String, id: String, tags: [[String]]) -> Int? {
|
func find_tag_ref(type: String, id: String, tags: [[String]]) -> Int? {
|
||||||
var i: Int = 0
|
var i: Int = 0
|
||||||
for tag in tags {
|
for tag in tags {
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ func saveMutedThreads(pubkey: String, currentValue: [String], value: [String]) -
|
|||||||
|
|
||||||
class MutedThreadsManager: ObservableObject {
|
class MutedThreadsManager: ObservableObject {
|
||||||
|
|
||||||
private let userDefaults = UserDefaults.standard
|
|
||||||
private let keypair: Keypair
|
private let keypair: Keypair
|
||||||
|
|
||||||
private var _mutedThreadsSet: Set<String>
|
private var _mutedThreadsSet: Set<String>
|
||||||
@@ -68,9 +67,4 @@ class MutedThreadsManager: ObservableObject {
|
|||||||
notify(.mute_thread, ev)
|
notify(.mute_thread, ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearAll() {
|
|
||||||
mutedThreads = []
|
|
||||||
_mutedThreadsSet.removeAll()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
//
|
|
||||||
// ListModel.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2023-01-25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
class MutelistModel: ObservableObject {
|
|
||||||
let contacts: Contacts
|
|
||||||
|
|
||||||
@Published var users: [String]
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -285,7 +285,7 @@ class NotificationsModel: ObservableObject, ScrollQueue {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func insert_zap(_ zap: Zap, damus_state: DamusState) -> Bool {
|
func insert_zap(_ zap: Zap) -> Bool {
|
||||||
if should_queue {
|
if should_queue {
|
||||||
return insert_uniq_sorted_zap_by_created(zaps: &incoming_zaps, new_zap: zap)
|
return insert_uniq_sorted_zap_by_created(zaps: &incoming_zaps, new_zap: zap)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,6 @@ struct NostrPost {
|
|||||||
self.kind = kind
|
self.kind = kind
|
||||||
self.tags = tags
|
self.tags = tags
|
||||||
}
|
}
|
||||||
|
|
||||||
func to_event(keypair: FullKeypair) -> NostrEvent {
|
|
||||||
return post_to_event(post: self, privkey: keypair.privkey, pubkey: keypair.pubkey)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parse nostr:{e,p}:pubkey uris as well
|
// TODO: parse nostr:{e,p}:pubkey uris as well
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
//
|
|
||||||
// SearchResultsModel.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2023-03-03.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
|
|
||||||
class SearchResultsModel: ObservableObject {
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,6 @@ class SearchModel: ObservableObject {
|
|||||||
let state: DamusState
|
let state: DamusState
|
||||||
var events: EventHolder
|
var events: EventHolder
|
||||||
@Published var loading: Bool = false
|
@Published var loading: Bool = false
|
||||||
@Published var channel_name: String? = nil
|
|
||||||
|
|
||||||
var search: NostrFilter
|
var search: NostrFilter
|
||||||
let sub_id = UUID().description
|
let sub_id = UUID().description
|
||||||
@@ -65,24 +64,14 @@ class SearchModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handle_channel_create(_ ev: NostrEvent) {
|
|
||||||
self.channel_name = ev.content
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func handle_channel_meta(_ ev: NostrEvent) {
|
|
||||||
self.channel_name = ev.content
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func handle_event(relay_id: String, ev: NostrConnectionEvent) {
|
func handle_event(relay_id: String, ev: NostrConnectionEvent) {
|
||||||
let (sub_id, done) = handle_subid_event(pool: state.pool, relay_id: relay_id, ev: ev) { sub_id, ev in
|
let (sub_id, done) = handle_subid_event(pool: state.pool, relay_id: relay_id, ev: ev) { sub_id, ev in
|
||||||
if ev.is_textlike && ev.should_show_event {
|
if ev.is_textlike && ev.should_show_event {
|
||||||
self.add_event(ev)
|
self.add_event(ev)
|
||||||
} else if ev.known_kind == .channel_create {
|
} else if ev.known_kind == .channel_create {
|
||||||
handle_channel_create(ev)
|
// unimplemented
|
||||||
} else if ev.known_kind == .channel_meta {
|
} else if ev.known_kind == .channel_meta {
|
||||||
handle_channel_meta(ev)
|
// unimplemented
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,16 +101,6 @@ func tag_is_hashtag(_ tag: [String]) -> Bool {
|
|||||||
return tag.count >= 2 && (tag[0] == "hashtag" || tag[0] == "t")
|
return tag.count >= 2 && (tag[0] == "hashtag" || tag[0] == "t")
|
||||||
}
|
}
|
||||||
|
|
||||||
func has_hashtag(_ tags: [[String]], hashtag: String) -> Bool {
|
|
||||||
for tag in tags {
|
|
||||||
if tag_is_hashtag(tag) && tag[1] == hashtag {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func event_matches_filter(_ ev: NostrEvent, filter: NostrFilter) -> Bool {
|
func event_matches_filter(_ ev: NostrEvent, filter: NostrFilter) -> Bool {
|
||||||
if let hashtags = filter.hashtag {
|
if let hashtags = filter.hashtag {
|
||||||
return event_matches_hashtag(ev, hashtags: hashtags)
|
return event_matches_hashtag(ev, hashtags: hashtags)
|
||||||
|
|||||||
@@ -12,14 +12,6 @@ class SignalModel: ObservableObject {
|
|||||||
@Published var signal: Int
|
@Published var signal: Int
|
||||||
@Published var max_signal: Int
|
@Published var max_signal: Int
|
||||||
|
|
||||||
var percentage: Double {
|
|
||||||
if max_signal == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return Double(signal) / Double(max_signal)
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
self.signal = 0
|
self.signal = 0
|
||||||
self.max_signal = 0
|
self.max_signal = 0
|
||||||
|
|||||||
@@ -7,41 +7,16 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum InitialEvent {
|
|
||||||
case event(NostrEvent)
|
|
||||||
case event_id(String)
|
|
||||||
|
|
||||||
var is_event_id: String? {
|
|
||||||
if case .event_id(let evid) = self {
|
|
||||||
return evid
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var id: String {
|
|
||||||
switch self {
|
|
||||||
case .event(let ev):
|
|
||||||
return ev.id
|
|
||||||
case .event_id(let evid):
|
|
||||||
return evid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// manages the lifetime of a thread
|
/// manages the lifetime of a thread
|
||||||
class ThreadModel: ObservableObject {
|
class ThreadModel: ObservableObject {
|
||||||
@Published var event: NostrEvent
|
@Published var event: NostrEvent
|
||||||
var event_map: Set<NostrEvent>
|
var event_map: Set<NostrEvent>
|
||||||
|
|
||||||
@Published var loading: Bool = false
|
|
||||||
|
|
||||||
var replies: ReplyMap = ReplyMap()
|
|
||||||
|
|
||||||
init(event: NostrEvent, damus_state: DamusState) {
|
init(event: NostrEvent, damus_state: DamusState) {
|
||||||
self.damus_state = damus_state
|
self.damus_state = damus_state
|
||||||
self.event_map = Set()
|
self.event_map = Set()
|
||||||
self.event = event
|
self.event = event
|
||||||
add_event(event, privkey: nil)
|
add_event(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
@@ -65,9 +40,9 @@ class ThreadModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func set_active_event(_ ev: NostrEvent, privkey: String?) -> Bool {
|
func set_active_event(_ ev: NostrEvent) -> Bool {
|
||||||
self.event = ev
|
self.event = ev
|
||||||
add_event(ev, privkey: privkey)
|
add_event(ev)
|
||||||
|
|
||||||
//self.objectWillChange.send()
|
//self.objectWillChange.send()
|
||||||
return false
|
return false
|
||||||
@@ -96,24 +71,15 @@ class ThreadModel: ObservableObject {
|
|||||||
|
|
||||||
meta_events.limit = 1000
|
meta_events.limit = 1000
|
||||||
|
|
||||||
/*
|
|
||||||
if let last_ev = self.events.last {
|
|
||||||
if last_ev.created_at <= Int64(Date().timeIntervalSince1970) {
|
|
||||||
ref_events.since = last_ev.created_at
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
let base_filters = [event_filter, ref_events]
|
let base_filters = [event_filter, ref_events]
|
||||||
let meta_filters = [meta_events]
|
let meta_filters = [meta_events]
|
||||||
|
|
||||||
print("subscribing to thread \(event.id) with sub_id \(base_subid)")
|
print("subscribing to thread \(event.id) with sub_id \(base_subid)")
|
||||||
loading = true
|
|
||||||
damus_state.pool.subscribe(sub_id: base_subid, filters: base_filters, handler: handle_event)
|
damus_state.pool.subscribe(sub_id: base_subid, filters: base_filters, handler: handle_event)
|
||||||
damus_state.pool.subscribe(sub_id: meta_subid, filters: meta_filters, handler: handle_event)
|
damus_state.pool.subscribe(sub_id: meta_subid, filters: meta_filters, handler: handle_event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func add_event(_ ev: NostrEvent, privkey: String?) {
|
func add_event(_ ev: NostrEvent) {
|
||||||
if event_map.contains(ev) {
|
if event_map.contains(ev) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -136,7 +102,7 @@ class ThreadModel: ObservableObject {
|
|||||||
if ev.known_kind == .metadata {
|
if ev.known_kind == .metadata {
|
||||||
process_metadata_event(events: damus_state.events, our_pubkey: damus_state.pubkey, profiles: damus_state.profiles, ev: ev)
|
process_metadata_event(events: damus_state.events, our_pubkey: damus_state.pubkey, profiles: damus_state.profiles, ev: ev)
|
||||||
} else if ev.is_textlike {
|
} else if ev.is_textlike {
|
||||||
self.add_event(ev, privkey: self.damus_state.keypair.privkey)
|
self.add_event(ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,10 +110,6 @@ class ThreadModel: ObservableObject {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if event_map.contains(event) {
|
|
||||||
loading = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if sub_id == self.base_subid {
|
if sub_id == self.base_subid {
|
||||||
load_profiles(profiles_subid: self.profiles_subid, relay_id: relay_id, load: .from_events(Array(event_map)), damus_state: damus_state)
|
load_profiles(profiles_subid: self.profiles_subid, relay_id: relay_id, load: .from_events(Array(event_map)), damus_state: damus_state)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,4 @@ enum TranslationService: String, CaseIterable, Identifiable, StringCodable {
|
|||||||
return .init(tag: self.rawValue, displayName: NSLocalizedString("NoKYCTranslate.com (Prepay with BTC)", comment: "Dropdown option for selecting NoKYCTranslate.com as the translation service."))
|
return .init(tag: self.rawValue, displayName: NSLocalizedString("NoKYCTranslate.com (Prepay with BTC)", comment: "Dropdown option for selecting NoKYCTranslate.com as the translation service."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static var allModels: [Model] {
|
|
||||||
return Self.allCases.map { $0.model }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,11 +187,6 @@ func make_ln_url(_ str: String?) -> URL? {
|
|||||||
return str.flatMap { URL(string: "lightning:" + $0) }
|
return str.flatMap { URL(string: "lightning:" + $0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NostrSubscription {
|
|
||||||
let sub_id: String
|
|
||||||
let filter: NostrFilter
|
|
||||||
}
|
|
||||||
|
|
||||||
func lnaddress_to_lnurl(_ lnaddr: String) -> String? {
|
func lnaddress_to_lnurl(_ lnaddr: String) -> String? {
|
||||||
let parts = lnaddr.split(separator: "@")
|
let parts = lnaddr.split(separator: "@")
|
||||||
guard parts.count == 2 else {
|
guard parts.count == 2 else {
|
||||||
|
|||||||
@@ -18,20 +18,6 @@ enum ValidationResult: Decodable {
|
|||||||
case ok
|
case ok
|
||||||
case bad_id
|
case bad_id
|
||||||
case bad_sig
|
case bad_sig
|
||||||
|
|
||||||
var is_bad: Bool {
|
|
||||||
return self == .bad_id || self == .bad_sig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct OtherEvent {
|
|
||||||
let event_id: String
|
|
||||||
let relay_url: String
|
|
||||||
}
|
|
||||||
|
|
||||||
struct KeyEvent {
|
|
||||||
let key: String
|
|
||||||
let relay_url: String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ReferencedId: Identifiable, Hashable, Equatable {
|
struct ReferencedId: Identifiable, Hashable, Equatable {
|
||||||
@@ -50,18 +36,6 @@ struct ReferencedId: Identifiable, Hashable, Equatable {
|
|||||||
static func e(_ id: String, relay_id: String? = nil) -> ReferencedId {
|
static func e(_ id: String, relay_id: String? = nil) -> ReferencedId {
|
||||||
return ReferencedId(ref_id: id, relay_id: relay_id, key: "e")
|
return ReferencedId(ref_id: id, relay_id: relay_id, key: "e")
|
||||||
}
|
}
|
||||||
|
|
||||||
static func p(_ id: String, relay_id: String? = nil) -> ReferencedId {
|
|
||||||
return ReferencedId(ref_id: id, relay_id: relay_id, key: "p")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EventId: Identifiable, CustomStringConvertible {
|
|
||||||
let id: String
|
|
||||||
|
|
||||||
var description: String {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class NostrEvent: Codable, Identifiable, CustomStringConvertible, Equatable, Hashable, Comparable {
|
class NostrEvent: Codable, Identifiable, CustomStringConvertible, Equatable, Hashable, Comparable {
|
||||||
@@ -186,21 +160,9 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible, Equatable, Has
|
|||||||
}
|
}
|
||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
/*
|
|
||||||
switch validity {
|
|
||||||
case .ok:
|
|
||||||
return content
|
|
||||||
case .bad_id:
|
|
||||||
return content + "\n\n*WARNING: invalid note id, could be forged!*"
|
|
||||||
case .bad_sig:
|
|
||||||
return content + "\n\n*WARNING: invalid signature, could be forged!*"
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var description: String {
|
var description: String {
|
||||||
//let p = pow.map { String($0) } ?? "?"
|
|
||||||
return "NostrEvent { id: \(id) pubkey \(pubkey) kind \(kind) tags \(tags) content '\(content)' }"
|
return "NostrEvent { id: \(id) pubkey \(pubkey) kind \(kind) tags \(tags) content '\(content)' }"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,15 +178,6 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible, Equatable, Has
|
|||||||
return damus.get_referenced_ids(tags: self.tags, key: key)
|
return damus.get_referenced_ids(tags: self.tags, key: key)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func is_root_event() -> Bool {
|
|
||||||
for tag in tags {
|
|
||||||
if tag.count >= 1 && tag[0] == "e" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
public func direct_replies(_ privkey: String?) -> [ReferencedId] {
|
public func direct_replies(_ privkey: String?) -> [ReferencedId] {
|
||||||
return event_refs(privkey).reduce(into: []) { acc, evref in
|
return event_refs(privkey).reduce(into: []) { acc, evref in
|
||||||
if let direct_reply = evref.is_direct_reply {
|
if let direct_reply = evref.is_direct_reply {
|
||||||
@@ -299,31 +252,10 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible, Equatable, Has
|
|||||||
return get_referenced_ids(key: "e")
|
return get_referenced_ids(key: "e")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func count_ids() -> Int {
|
|
||||||
return count_refs("e")
|
|
||||||
}
|
|
||||||
|
|
||||||
public func count_refs(_ type: String) -> Int {
|
|
||||||
var count: Int = 0
|
|
||||||
for tag in tags {
|
|
||||||
if tag.count >= 2 && tag[0] == "e" {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
|
|
||||||
public var referenced_pubkeys: [ReferencedId] {
|
public var referenced_pubkeys: [ReferencedId] {
|
||||||
return get_referenced_ids(key: "p")
|
return get_referenced_ids(key: "p")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a local event
|
|
||||||
public static func local(content: String, pubkey: String) -> NostrEvent {
|
|
||||||
let ev = NostrEvent(content: content, pubkey: pubkey)
|
|
||||||
ev.flags |= 1
|
|
||||||
return ev
|
|
||||||
}
|
|
||||||
|
|
||||||
public var is_local: Bool {
|
public var is_local: Bool {
|
||||||
return (self.flags & 1) != 0
|
return (self.flags & 1) != 0
|
||||||
}
|
}
|
||||||
@@ -339,45 +271,8 @@ class NostrEvent: Codable, Identifiable, CustomStringConvertible, Equatable, Has
|
|||||||
self.created_at = createdAt
|
self.created_at = createdAt
|
||||||
}
|
}
|
||||||
|
|
||||||
init(from: NostrEvent, content: String? = nil) {
|
|
||||||
self.id = from.id
|
|
||||||
self.sig = from.sig
|
|
||||||
|
|
||||||
self.content = content ?? from.content
|
|
||||||
self.pubkey = from.pubkey
|
|
||||||
self.kind = from.kind
|
|
||||||
self.tags = from.tags
|
|
||||||
self.created_at = from.created_at
|
|
||||||
}
|
|
||||||
|
|
||||||
func calculate_id() {
|
func calculate_id() {
|
||||||
self.id = calculate_event_id(ev: self)
|
self.id = calculate_event_id(ev: self)
|
||||||
//self.pow = count_hash_leading_zero_bits(self.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: timeout
|
|
||||||
/*
|
|
||||||
func mine_id(pow: Int, done: @escaping (String) -> ()) {
|
|
||||||
let nonce_ind = self.ensure_nonce_tag()
|
|
||||||
let nonce: Int64 = 0
|
|
||||||
|
|
||||||
DispatchQueue.global(qos: .background).async {
|
|
||||||
while
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private func ensure_nonce_tag() -> Int {
|
|
||||||
for (i, tags) in self.tags.enumerated() {
|
|
||||||
for tag in tags {
|
|
||||||
if tags.count == 2 && tag == "nonce" {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.tags.append(["nonce", "0"])
|
|
||||||
return self.tags.count - 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sign(privkey: String) {
|
func sign(privkey: String) {
|
||||||
@@ -538,18 +433,6 @@ func get_referenced_ids(tags: [[String]], key: String) -> [ReferencedId] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_referenced_id_set(tags: [[String]], key: String) -> Set<ReferencedId> {
|
|
||||||
return tags.reduce(into: Set()) { (acc, tag) in
|
|
||||||
if tag.count >= 2 && tag[0] == key {
|
|
||||||
var relay_id: String? = nil
|
|
||||||
if tag.count >= 3 {
|
|
||||||
relay_id = tag[2]
|
|
||||||
}
|
|
||||||
acc.insert(ReferencedId(ref_id: tag[1], relay_id: relay_id, key: key))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func make_first_contact_event(keypair: Keypair) -> NostrEvent? {
|
func make_first_contact_event(keypair: Keypair) -> NostrEvent? {
|
||||||
guard let privkey = keypair.privkey else {
|
guard let privkey = keypair.privkey else {
|
||||||
return nil
|
return nil
|
||||||
@@ -1018,14 +901,6 @@ func last_etag(tags: [[String]]) -> String? {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func inner_event_or_self(ev: NostrEvent, cache: EventCache) -> NostrEvent {
|
|
||||||
guard let inner_ev = ev.get_inner_event(cache: cache) else {
|
|
||||||
return ev
|
|
||||||
}
|
|
||||||
|
|
||||||
return inner_ev
|
|
||||||
}
|
|
||||||
|
|
||||||
func first_eref_mention(ev: NostrEvent, privkey: String?) -> Mention? {
|
func first_eref_mention(ev: NostrEvent, privkey: String?) -> Mention? {
|
||||||
let blocks = ev.blocks(privkey).filter { block in
|
let blocks = ev.blocks(privkey).filter { block in
|
||||||
guard case .mention(let mention) = block else {
|
guard case .mention(let mention) = block else {
|
||||||
|
|||||||
@@ -40,10 +40,6 @@ struct NostrFilter: Codable, Equatable {
|
|||||||
return NostrFilter(ids: nil, kinds: nil, referenced_ids: nil, pubkeys: nil, since: nil, until: nil, authors: nil, hashtag: htags.map { $0.lowercased() })
|
return NostrFilter(ids: nil, kinds: nil, referenced_ids: nil, pubkeys: nil, since: nil, until: nil, authors: nil, hashtag: htags.map { $0.lowercased() })
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var filter_text: NostrFilter {
|
|
||||||
return filter_kinds([NostrKind.text.rawValue])
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func filter_ids(_ ids: [String]) -> NostrFilter {
|
public static func filter_ids(_ ids: [String]) -> NostrFilter {
|
||||||
return NostrFilter(ids: ids, kinds: nil, referenced_ids: nil, pubkeys: nil, since: nil, until: nil, authors: nil, hashtag: nil)
|
return NostrFilter(ids: ids, kinds: nil, referenced_ids: nil, pubkeys: nil, since: nil, until: nil, authors: nil, hashtag: nil)
|
||||||
}
|
}
|
||||||
@@ -63,8 +59,4 @@ struct NostrFilter: Codable, Equatable {
|
|||||||
public static func filter_kinds(_ kinds: [Int]) -> NostrFilter {
|
public static func filter_kinds(_ kinds: [Int]) -> NostrFilter {
|
||||||
return NostrFilter(ids: nil, kinds: kinds, referenced_ids: nil, pubkeys: nil, since: nil, until: nil, authors: nil)
|
return NostrFilter(ids: nil, kinds: kinds, referenced_ids: nil, pubkeys: nil, since: nil, until: nil, authors: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func filter_since(_ val: Int64) -> NostrFilter {
|
|
||||||
return NostrFilter(ids: nil, kinds: nil, referenced_ids: nil, pubkeys: nil, since: val, until: nil, authors: nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,54 +7,6 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
func zero_bits(_ argb: UInt8) -> Int
|
|
||||||
{
|
|
||||||
var b = argb
|
|
||||||
var n: Int = 0;
|
|
||||||
|
|
||||||
if b == 0 {
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
while true {
|
|
||||||
b >>= 1;
|
|
||||||
if b != 0 {
|
|
||||||
n += 1;
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 7-n;
|
|
||||||
}
|
|
||||||
|
|
||||||
func count_hash_leading_zero_bits(_ hash: String) -> Int?
|
|
||||||
{
|
|
||||||
guard let decoded = hex_decode(hash) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return count_leading_zero_bits(decoded)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the number of leading zero bits in a hash */
|
|
||||||
func count_leading_zero_bits(_ hash: [UInt8]) -> Int
|
|
||||||
{
|
|
||||||
var bits: Int = 0
|
|
||||||
var total: Int = 0
|
|
||||||
|
|
||||||
for c in hash {
|
|
||||||
bits = zero_bits(c)
|
|
||||||
total += bits
|
|
||||||
if (bits != 8) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return total
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func char_to_hex(_ c: UInt8) -> UInt8?
|
func char_to_hex(_ c: UInt8) -> UInt8?
|
||||||
{
|
{
|
||||||
// 0 && 9
|
// 0 && 9
|
||||||
|
|||||||
@@ -60,10 +60,6 @@ class Relay: Identifiable {
|
|||||||
self.connection = connection
|
self.connection = connection
|
||||||
}
|
}
|
||||||
|
|
||||||
func mark_broken() {
|
|
||||||
flags |= RelayFlags.broken.rawValue
|
|
||||||
}
|
|
||||||
|
|
||||||
var is_broken: Bool {
|
var is_broken: Bool {
|
||||||
return (flags & RelayFlags.broken.rawValue) == RelayFlags.broken.rawValue
|
return (flags & RelayFlags.broken.rawValue) == RelayFlags.broken.rawValue
|
||||||
}
|
}
|
||||||
@@ -76,7 +72,6 @@ class Relay: Identifiable {
|
|||||||
|
|
||||||
enum RelayError: Error {
|
enum RelayError: Error {
|
||||||
case RelayAlreadyExists
|
case RelayAlreadyExists
|
||||||
case RelayNotFound
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_relay_id(_ url: RelayURL) -> String {
|
func get_relay_id(_ url: RelayURL) -> String {
|
||||||
|
|||||||
@@ -8,22 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Network
|
import Network
|
||||||
|
|
||||||
struct SubscriptionId: Identifiable, CustomStringConvertible {
|
|
||||||
let id: String
|
|
||||||
|
|
||||||
var description: String {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RelayId: Identifiable, CustomStringConvertible {
|
|
||||||
let id: String
|
|
||||||
|
|
||||||
var description: String {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RelayHandler {
|
struct RelayHandler {
|
||||||
let sub_id: String
|
let sub_id: String
|
||||||
let callback: (String, NostrConnectionEvent) -> ()
|
let callback: (String, NostrConnectionEvent) -> ()
|
||||||
@@ -34,11 +18,6 @@ struct QueuedRequest {
|
|||||||
let relay: String
|
let relay: String
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NostrRequestId: Equatable, Hashable {
|
|
||||||
let relay: String?
|
|
||||||
let sub_id: String
|
|
||||||
}
|
|
||||||
|
|
||||||
class RelayPool {
|
class RelayPool {
|
||||||
var relays: [Relay] = []
|
var relays: [Relay] = []
|
||||||
var handlers: [RelayHandler] = []
|
var handlers: [RelayHandler] = []
|
||||||
@@ -67,10 +46,6 @@ class RelayPool {
|
|||||||
relays.map { $0.descriptor }
|
relays.map { $0.descriptor }
|
||||||
}
|
}
|
||||||
|
|
||||||
var num_connecting: Int {
|
|
||||||
return relays.reduce(0) { n, r in n + (r.connection.isConnecting ? 1 : 0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
var num_connected: Int {
|
var num_connected: Int {
|
||||||
return relays.reduce(0) { n, r in n + (r.connection.isConnected ? 1 : 0) }
|
return relays.reduce(0) { n, r in n + (r.connection.isConnected ? 1 : 0) }
|
||||||
}
|
}
|
||||||
@@ -152,12 +127,6 @@ class RelayPool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mark_broken(_ relay_id: String) {
|
|
||||||
for relay in relays {
|
|
||||||
relay.mark_broken()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func connect(to: [String]? = nil) {
|
func connect(to: [String]? = nil) {
|
||||||
let relays = to.map{ get_relays($0) } ?? self.relays
|
let relays = to.map{ get_relays($0) } ?? self.relays
|
||||||
for relay in relays {
|
for relay in relays {
|
||||||
|
|||||||
@@ -7,21 +7,6 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class Constants {
|
class Constants {
|
||||||
|
|
||||||
static let PUB_KEY = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
|
|
||||||
|
|
||||||
static let EXAMPLE_DEMOS: DamusState = .empty
|
static let EXAMPLE_DEMOS: DamusState = .empty
|
||||||
|
|
||||||
static let EXAMPLE_EVENTS = [
|
|
||||||
NostrEvent(id: UUID().description, content: "Nostr - Damus... Haha get it? Bonjour Le Monde mon Ami! C'est la tres importante", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
NostrEvent(id: UUID().description, content: "This is a test for a really long note that somebody sent because they thought they were super cool or maybe they were just really excited to share something with the world.", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
NostrEvent(id: UUID().description, content: "Bonjour Le Monde", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
NostrEvent(id: UUID().description, content: "Why am I helping on this app? Because it's fun!", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
NostrEvent(id: UUID().description, content: "Pizza and Icecream! Pizza and Icecream! Testing Testing! 1 .. 2.. 3..", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
NostrEvent(id: UUID().description, content: "Hello World! This is so cool!", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
NostrEvent(id: UUID().description, content: "Nostr - Damus... Haha get it?", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
NostrEvent(id: UUID().description, content: "Hello World! This is so cool!", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
NostrEvent(id: UUID().description, content: "Bonjour Le Monde", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,12 +48,6 @@ public class SVG {
|
|||||||
CGSVGDocumentGetCanvasSize(document)
|
CGSVGDocumentGetCanvasSize(document)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func image() -> UIImage? {
|
|
||||||
let ImageWithCGSVGDocument = unsafeBitCast(UIImage.self.method(for: ImageWithCGSVGDocumentSEL), to: ImageWithCGSVGDocument.self)
|
|
||||||
let image = ImageWithCGSVGDocument(UIImage.self, ImageWithCGSVGDocumentSEL, document)
|
|
||||||
return image
|
|
||||||
}
|
|
||||||
|
|
||||||
public func draw(in context: CGContext) {
|
public func draw(in context: CGContext) {
|
||||||
draw(in: context, size: size)
|
draw(in: context, size: size)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,15 +26,6 @@ enum ImageMetaProcessState {
|
|||||||
case failed
|
case failed
|
||||||
case processed(UIImage)
|
case processed(UIImage)
|
||||||
case not_needed
|
case not_needed
|
||||||
|
|
||||||
var img: UIImage? {
|
|
||||||
switch self {
|
|
||||||
case .processed(let img):
|
|
||||||
return img
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TranslationModel: ObservableObject {
|
class TranslationModel: ObservableObject {
|
||||||
@@ -58,10 +49,6 @@ class NoteArtifactsModel: ObservableObject {
|
|||||||
class PreviewModel: ObservableObject {
|
class PreviewModel: ObservableObject {
|
||||||
@Published var state: PreviewState
|
@Published var state: PreviewState
|
||||||
|
|
||||||
func store(preview: LPLinkMetadata?) {
|
|
||||||
state = .loaded(Preview(meta: preview))
|
|
||||||
}
|
|
||||||
|
|
||||||
init(state: PreviewState) {
|
init(state: PreviewState) {
|
||||||
self.state = state
|
self.state = state
|
||||||
}
|
}
|
||||||
@@ -76,17 +63,7 @@ class ZapsDataModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RelativeTimeModel: ObservableObject {
|
class RelativeTimeModel: ObservableObject {
|
||||||
private(set) var last_update: Int64
|
@Published var value: String = ""
|
||||||
@Published var value: String {
|
|
||||||
didSet {
|
|
||||||
self.last_update = Int64(Date().timeIntervalSince1970)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init(value: String) {
|
|
||||||
self.last_update = 0
|
|
||||||
self.value = ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventData {
|
class EventData {
|
||||||
@@ -94,7 +71,7 @@ class EventData {
|
|||||||
var artifacts_model: NoteArtifactsModel
|
var artifacts_model: NoteArtifactsModel
|
||||||
var preview_model: PreviewModel
|
var preview_model: PreviewModel
|
||||||
var zaps_model : ZapsDataModel
|
var zaps_model : ZapsDataModel
|
||||||
var relative_time: RelativeTimeModel
|
var relative_time: RelativeTimeModel = RelativeTimeModel()
|
||||||
var validated: ValidationResult
|
var validated: ValidationResult
|
||||||
|
|
||||||
var translations: TranslateStatus {
|
var translations: TranslateStatus {
|
||||||
@@ -109,17 +86,12 @@ class EventData {
|
|||||||
return preview_model.state
|
return preview_model.state
|
||||||
}
|
}
|
||||||
|
|
||||||
var zaps: [Zap] {
|
|
||||||
return zaps_model.zaps
|
|
||||||
}
|
|
||||||
|
|
||||||
init(zaps: [Zap] = []) {
|
init(zaps: [Zap] = []) {
|
||||||
self.translations_model = .init(state: .havent_tried)
|
self.translations_model = .init(state: .havent_tried)
|
||||||
self.artifacts_model = .init(state: .not_loaded)
|
self.artifacts_model = .init(state: .not_loaded)
|
||||||
self.zaps_model = .init(zaps)
|
self.zaps_model = .init(zaps)
|
||||||
self.validated = .unknown
|
self.validated = .unknown
|
||||||
self.preview_model = .init(state: .not_loaded)
|
self.preview_model = .init(state: .not_loaded)
|
||||||
self.relative_time = .init(value: "")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,14 +130,6 @@ class EventCache {
|
|||||||
get_cache_data(evid).validated = validated
|
get_cache_data(evid).validated = validated
|
||||||
}
|
}
|
||||||
|
|
||||||
func store_translation_artifacts(evid: String, translated: TranslateStatus) {
|
|
||||||
get_cache_data(evid).translations_model.state = translated
|
|
||||||
}
|
|
||||||
|
|
||||||
func store_artifacts(evid: String, artifacts: NoteArtifacts) {
|
|
||||||
get_cache_data(evid).artifacts_model.state = .loaded(artifacts)
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func store_zap(zap: Zap) -> Bool {
|
func store_zap(zap: Zap) -> Bool {
|
||||||
let data = get_cache_data(zap.target.id).zaps_model
|
let data = get_cache_data(zap.target.id).zaps_model
|
||||||
@@ -180,18 +144,10 @@ class EventCache {
|
|||||||
self.image_metadata[url.absoluteString.lowercased()] = meta
|
self.image_metadata[url.absoluteString.lowercased()] = meta
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookup_artifacts(evid: String) -> NoteArtifactState {
|
|
||||||
return get_cache_data(evid).artifacts_model.state
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookup_img_metadata(url: URL) -> ImageMetadataState? {
|
func lookup_img_metadata(url: URL) -> ImageMetadataState? {
|
||||||
return image_metadata[url.absoluteString.lowercased()]
|
return image_metadata[url.absoluteString.lowercased()]
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookup_translated_artifacts(evid: String) -> TranslateStatus? {
|
|
||||||
return get_cache_data(evid).translations_model.state
|
|
||||||
}
|
|
||||||
|
|
||||||
func parent_events(event: NostrEvent) -> [NostrEvent] {
|
func parent_events(event: NostrEvent) -> [NostrEvent] {
|
||||||
var parents: [NostrEvent] = []
|
var parents: [NostrEvent] = []
|
||||||
|
|
||||||
@@ -368,15 +324,6 @@ func preload_image(url: URL) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func preload_pfp(profiles: Profiles, pubkey: String) {
|
|
||||||
// preload pfp
|
|
||||||
if let profile = profiles.lookup(id: pubkey),
|
|
||||||
let picture = profile.picture,
|
|
||||||
let url = URL(string: picture) {
|
|
||||||
preload_image(url: url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func preload_event(plan: PreloadPlan, state: DamusState) async {
|
func preload_event(plan: PreloadPlan, state: DamusState) async {
|
||||||
var artifacts: NoteArtifacts? = plan.data.artifacts.artifacts
|
var artifacts: NoteArtifacts? = plan.data.artifacts.artifacts
|
||||||
let settings = state.settings
|
let settings = state.settings
|
||||||
@@ -385,13 +332,6 @@ func preload_event(plan: PreloadPlan, state: DamusState) async {
|
|||||||
|
|
||||||
print("Preloading event \(plan.event.content)")
|
print("Preloading event \(plan.event.content)")
|
||||||
|
|
||||||
/*
|
|
||||||
preload_pfp(profiles: profiles, pubkey: plan.event.pubkey)
|
|
||||||
if let inner_ev = plan.event.get_inner_event(cache: state.events), inner_ev.pubkey != plan.event.pubkey {
|
|
||||||
preload_pfp(profiles: profiles, pubkey: inner_ev.pubkey)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if artifacts == nil && plan.load_artifacts {
|
if artifacts == nil && plan.load_artifacts {
|
||||||
let arts = render_note_content(ev: plan.event, profiles: profiles, privkey: our_keypair.privkey)
|
let arts = render_note_content(ev: plan.event, profiles: profiles, privkey: our_keypair.privkey)
|
||||||
artifacts = arts
|
artifacts = arts
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ class EventHolder: ObservableObject, ScrollQueue {
|
|||||||
return incoming.count
|
return incoming.count
|
||||||
}
|
}
|
||||||
|
|
||||||
var has_incoming: Bool {
|
|
||||||
return queued > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var all_events: [NostrEvent] {
|
var all_events: [NostrEvent] {
|
||||||
events + incoming
|
events + incoming
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
//
|
|
||||||
// Binding+.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by Oleg Abalonski on 3/5/23.
|
|
||||||
// Ref: https://josephduffy.co.uk/posts/mapping-optional-binding-to-bool
|
|
||||||
|
|
||||||
import os.log
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
extension Binding where Value == Bool {
|
|
||||||
/// Creates a binding by mapping an optional value to a `Bool` that is
|
|
||||||
/// `true` when the value is non-`nil` and `false` when the value is `nil`.
|
|
||||||
///
|
|
||||||
/// When the value of the produced binding is set to `false` the value
|
|
||||||
/// of `bindingToOptional`'s `wrappedValue` is set to `nil`.
|
|
||||||
///
|
|
||||||
/// Setting the value of the produce binding to `true` does nothing and
|
|
||||||
/// will log an error.
|
|
||||||
///
|
|
||||||
/// - parameter bindingToOptional: A `Binding` to an optional value, used to calculate the `wrappedValue`.
|
|
||||||
public init<Wrapped>(mappedTo bindingToOptional: Binding<Wrapped?>) {
|
|
||||||
self.init(
|
|
||||||
get: { bindingToOptional.wrappedValue != nil },
|
|
||||||
set: { newValue in
|
|
||||||
if !newValue {
|
|
||||||
bindingToOptional.wrappedValue = nil
|
|
||||||
} else {
|
|
||||||
os_log(
|
|
||||||
.error,
|
|
||||||
"Optional binding mapped to optional has been set to `true`, which will have no effect. Current value: %@",
|
|
||||||
String(describing: bindingToOptional.wrappedValue)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Binding {
|
|
||||||
/// Returns a binding by mapping this binding's value to a `Bool` that is
|
|
||||||
/// `true` when the value is non-`nil` and `false` when the value is `nil`.
|
|
||||||
///
|
|
||||||
/// When the value of the produced binding is set to `false` this binding's value
|
|
||||||
/// is set to `nil`.
|
|
||||||
public func mappedToBool<Wrapped>() -> Binding<Bool> where Value == Wrapped? {
|
|
||||||
return Binding<Bool>(mappedTo: self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -34,11 +34,6 @@ struct ImageMetaDim: Equatable, StringCodable {
|
|||||||
let height: Int
|
let height: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProcessedImageMetadata {
|
|
||||||
let blurhash: UIImage?
|
|
||||||
let dim: ImageMetaDim?
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ImageMetadata: Equatable {
|
struct ImageMetadata: Equatable {
|
||||||
let url: URL
|
let url: URL
|
||||||
let blurhash: String?
|
let blurhash: String?
|
||||||
|
|||||||
@@ -7,37 +7,6 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
func insert_uniq<T: Equatable>(xs: inout [T], new_x: T) -> Bool {
|
|
||||||
for x in xs {
|
|
||||||
if x == new_x {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xs.append(new_x)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func insert_uniq_by_pubkey(events: inout [NostrEvent], new_ev: NostrEvent, cmp: (NostrEvent, NostrEvent) -> Bool) -> Bool {
|
|
||||||
var i: Int = 0
|
|
||||||
|
|
||||||
for event in events {
|
|
||||||
// don't insert duplicate events
|
|
||||||
if new_ev.pubkey == event.pubkey {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if cmp(new_ev, event) {
|
|
||||||
events.insert(new_ev, at: i)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
i += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
events.append(new_ev)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func insert_uniq_sorted_zap(zaps: inout [Zap], new_zap: Zap, cmp: (Zap, Zap) -> Bool) -> Bool {
|
func insert_uniq_sorted_zap(zaps: inout [Zap], new_zap: Zap, cmp: (Zap, Zap) -> Bool) -> Bool {
|
||||||
var i: Int = 0
|
var i: Int = 0
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import Foundation
|
|||||||
import secp256k1
|
import secp256k1
|
||||||
|
|
||||||
let PUBKEY_HRP = "npub"
|
let PUBKEY_HRP = "npub"
|
||||||
let PRIVKEY_HRP = "nsec"
|
|
||||||
|
|
||||||
struct FullKeypair {
|
struct FullKeypair {
|
||||||
let pubkey: String
|
let pubkey: String
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ struct LNUrlPayRequest: Decodable {
|
|||||||
let commentAllowed: Int?
|
let commentAllowed: Int?
|
||||||
let nostrPubkey: String?
|
let nostrPubkey: String?
|
||||||
|
|
||||||
let metadata: String?
|
|
||||||
let minSendable: Int64?
|
|
||||||
let maxSendable: Int64?
|
|
||||||
let status: String?
|
|
||||||
let callback: String?
|
let callback: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,25 +31,6 @@ struct NIP05 {
|
|||||||
|
|
||||||
struct NIP05Response: Decodable {
|
struct NIP05Response: Decodable {
|
||||||
let names: [String: String]
|
let names: [String: String]
|
||||||
let relays: [String: [String]]?
|
|
||||||
}
|
|
||||||
|
|
||||||
enum NIP05Validation {
|
|
||||||
case invalid
|
|
||||||
case valid
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FetchedNIP05 {
|
|
||||||
let response: NIP05Response
|
|
||||||
let nip05: NIP05Response
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetch_nip05_str(nip05_str: String) async -> NIP05Response? {
|
|
||||||
guard let nip05 = NIP05.parse(nip05_str) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return await fetch_nip05(nip05: nip05)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetch_nip05(nip05: NIP05) async -> NIP05Response? {
|
func fetch_nip05(nip05: NIP05) async -> NIP05Response? {
|
||||||
|
|||||||
@@ -8,18 +8,9 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension Notification.Name {
|
extension Notification.Name {
|
||||||
static var thread_focus: Notification.Name {
|
|
||||||
return Notification.Name("thread focus")
|
|
||||||
}
|
|
||||||
static var relays_changed: Notification.Name {
|
static var relays_changed: Notification.Name {
|
||||||
return Notification.Name("relays_changed")
|
return Notification.Name("relays_changed")
|
||||||
}
|
}
|
||||||
static var select_event: Notification.Name {
|
|
||||||
return Notification.Name("select_event")
|
|
||||||
}
|
|
||||||
static var select_quote: Notification.Name {
|
|
||||||
return Notification.Name("select quote")
|
|
||||||
}
|
|
||||||
static var profile_updated: Notification.Name {
|
static var profile_updated: Notification.Name {
|
||||||
return Notification.Name("profile_updated")
|
return Notification.Name("profile_updated")
|
||||||
}
|
}
|
||||||
@@ -29,24 +20,15 @@ extension Notification.Name {
|
|||||||
static var liked: Notification.Name {
|
static var liked: Notification.Name {
|
||||||
return Notification.Name("liked")
|
return Notification.Name("liked")
|
||||||
}
|
}
|
||||||
static var open_profile: Notification.Name {
|
|
||||||
return Notification.Name("open_profile")
|
|
||||||
}
|
|
||||||
static var scroll_to_top: Notification.Name {
|
static var scroll_to_top: Notification.Name {
|
||||||
return Notification.Name("scroll_to_to")
|
return Notification.Name("scroll_to_to")
|
||||||
}
|
}
|
||||||
static var broadcast_event: Notification.Name {
|
static var broadcast_event: Notification.Name {
|
||||||
return Notification.Name("broadcast event")
|
return Notification.Name("broadcast event")
|
||||||
}
|
}
|
||||||
static var open_thread: Notification.Name {
|
|
||||||
return Notification.Name("open thread")
|
|
||||||
}
|
|
||||||
static var notice: Notification.Name {
|
static var notice: Notification.Name {
|
||||||
return Notification.Name("notice")
|
return Notification.Name("notice")
|
||||||
}
|
}
|
||||||
static var like: Notification.Name {
|
|
||||||
return Notification.Name("like note")
|
|
||||||
}
|
|
||||||
static var delete: Notification.Name {
|
static var delete: Notification.Name {
|
||||||
return Notification.Name("delete note")
|
return Notification.Name("delete note")
|
||||||
}
|
}
|
||||||
@@ -56,9 +38,6 @@ extension Notification.Name {
|
|||||||
static var compose: Notification.Name {
|
static var compose: Notification.Name {
|
||||||
return Notification.Name("compose")
|
return Notification.Name("compose")
|
||||||
}
|
}
|
||||||
static var boost: Notification.Name {
|
|
||||||
return Notification.Name("boost")
|
|
||||||
}
|
|
||||||
static var boosted: Notification.Name {
|
static var boosted: Notification.Name {
|
||||||
return Notification.Name("boosted")
|
return Notification.Name("boosted")
|
||||||
}
|
}
|
||||||
@@ -77,9 +56,6 @@ extension Notification.Name {
|
|||||||
static var followed: Notification.Name {
|
static var followed: Notification.Name {
|
||||||
return Notification.Name("followed")
|
return Notification.Name("followed")
|
||||||
}
|
}
|
||||||
static var chatroom_meta: Notification.Name {
|
|
||||||
return Notification.Name("chatroom_meta")
|
|
||||||
}
|
|
||||||
static var unfollowed: Notification.Name {
|
static var unfollowed: Notification.Name {
|
||||||
return Notification.Name("unfollowed")
|
return Notification.Name("unfollowed")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,15 +55,6 @@ func parse_str(_ p: Parser, _ s: String) -> Bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func peek_char(_ p: Parser, _ i: Int) -> Character? {
|
|
||||||
let offset = p.pos + i
|
|
||||||
if offset < 0 || offset > p.str.count {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
let ind = p.str.index(p.str.startIndex, offsetBy: offset)
|
|
||||||
return p.str[ind]
|
|
||||||
}
|
|
||||||
|
|
||||||
func parse_char(_ p: Parser, _ c: Character) -> Bool {
|
func parse_char(_ p: Parser, _ c: Character) -> Bool {
|
||||||
if p.pos >= p.str.count {
|
if p.pos >= p.str.count {
|
||||||
return false
|
return false
|
||||||
@@ -79,21 +70,6 @@ func parse_char(_ p: Parser, _ c: Character) -> Bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse_digit(_ p: Parser) -> Int? {
|
|
||||||
let ind = p.str.index(p.str.startIndex, offsetBy: p.pos)
|
|
||||||
|
|
||||||
if let c = p.str[ind].unicodeScalars.first {
|
|
||||||
let d = Int(c.value) - 48
|
|
||||||
if d >= 0 && d < 10 {
|
|
||||||
p.pos += 1
|
|
||||||
return Int(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func parse_hex_char(_ p: Parser) -> Character? {
|
func parse_hex_char(_ p: Parser) -> Character? {
|
||||||
let ind = p.str.index(p.str.startIndex, offsetBy: p.pos)
|
let ind = p.str.index(p.str.startIndex, offsetBy: p.pos)
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
//
|
|
||||||
// BinaryParser.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2023-04-25.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
class BinaryParser {
|
|
||||||
var pos: Int
|
|
||||||
var buf: [UInt8]
|
|
||||||
|
|
||||||
init(buf: [UInt8], pos: Int = 0) {
|
|
||||||
self.pos = pos
|
|
||||||
self.buf = buf
|
|
||||||
}
|
|
||||||
|
|
||||||
func read_byte() -> UInt8? {
|
|
||||||
guard pos < buf.count else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
let v = buf[pos]
|
|
||||||
pos += 1
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func read_bytes(_ n: Int) -> [UInt8]? {
|
|
||||||
guard pos + n < buf.count else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
let v = [UInt8](self.buf[pos...pos+n])
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func read_u16() -> UInt16? {
|
|
||||||
let start = self.pos
|
|
||||||
|
|
||||||
guard let b1 = read_byte(), let b2 = read_byte() else {
|
|
||||||
self.pos = start
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return (UInt16(b1) << 8) | UInt16(b2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -97,12 +97,6 @@ class PostBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func flush() {
|
|
||||||
for event in events {
|
|
||||||
flush_event(event.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func send(_ event: NostrEvent) {
|
func send(_ event: NostrEvent) {
|
||||||
// Don't add event if we already have it
|
// Don't add event if we already have it
|
||||||
if events[event.id] != nil {
|
if events[event.id] != nil {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ struct RelayFilter: Hashable {
|
|||||||
let timeline: Timeline
|
let timeline: Timeline
|
||||||
let relay_id: String
|
let relay_id: String
|
||||||
|
|
||||||
init(timeline: Timeline, relay_id: String, on: Bool = false) {
|
init(timeline: Timeline, relay_id: String) {
|
||||||
self.timeline = timeline
|
self.timeline = timeline
|
||||||
self.relay_id = relay_id
|
self.relay_id = relay_id
|
||||||
}
|
}
|
||||||
@@ -63,11 +63,6 @@ func relay_filter_setting_key(_ pubkey: String) -> String {
|
|||||||
return pk_setting_key(pubkey, key: "relay_filters")
|
return pk_setting_key(pubkey, key: "relay_filters")
|
||||||
}
|
}
|
||||||
|
|
||||||
func clear_relay_filters(_ pubkey: String) {
|
|
||||||
let key = relay_filter_setting_key(pubkey)
|
|
||||||
UserDefaults.standard.removeObject(forKey: key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func load_relay_filters(_ pubkey: String) -> Set<RelayFilter>? {
|
func load_relay_filters(_ pubkey: String) -> Set<RelayFilter>? {
|
||||||
let key = relay_filter_setting_key(pubkey)
|
let key = relay_filter_setting_key(pubkey)
|
||||||
guard let filters = UserDefaults.standard.stringArray(forKey: key) else {
|
guard let filters = UserDefaults.standard.stringArray(forKey: key) else {
|
||||||
|
|||||||
@@ -9,22 +9,6 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class Theme {
|
class Theme {
|
||||||
static func navigationBarColors(background : UIColor?,
|
|
||||||
titleColor : UIColor? = nil, tintColor : UIColor? = nil ){
|
|
||||||
|
|
||||||
let navigationAppearance = UINavigationBarAppearance()
|
|
||||||
navigationAppearance.configureWithOpaqueBackground()
|
|
||||||
navigationAppearance.backgroundColor = background ?? .clear
|
|
||||||
|
|
||||||
navigationAppearance.titleTextAttributes = [.foregroundColor: titleColor ?? .black]
|
|
||||||
navigationAppearance.largeTitleTextAttributes = [.foregroundColor: titleColor ?? .black]
|
|
||||||
|
|
||||||
UINavigationBar.appearance().standardAppearance = navigationAppearance
|
|
||||||
UINavigationBar.appearance().compactAppearance = navigationAppearance
|
|
||||||
UINavigationBar.appearance().scrollEdgeAppearance = navigationAppearance
|
|
||||||
|
|
||||||
UINavigationBar.appearance().tintColor = tintColor ?? titleColor ?? .black
|
|
||||||
}
|
|
||||||
|
|
||||||
static var safeAreaInsets: UIEdgeInsets? {
|
static var safeAreaInsets: UIEdgeInsets? {
|
||||||
return UIApplication
|
return UIApplication
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
//
|
|
||||||
// TipCounter.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2022-05-11.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
class TipCounter {
|
|
||||||
var tips: [String: Int64] = [:]
|
|
||||||
var user_tips: [String: Set<String>] = [:]
|
|
||||||
var our_tips: [String: NostrEvent] = [:]
|
|
||||||
var our_pubkey: String
|
|
||||||
|
|
||||||
enum CountResult {
|
|
||||||
case already_tipped
|
|
||||||
case success(Int64)
|
|
||||||
}
|
|
||||||
|
|
||||||
init (our_pubkey: String) {
|
|
||||||
self.our_pubkey = our_pubkey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -134,16 +134,6 @@ func invoice_to_zap_invoice(_ invoice: Invoice) -> ZapInvoice? {
|
|||||||
return ZapInvoice(description: invoice.description, amount: amt, string: invoice.string, expiry: invoice.expiry, payment_hash: invoice.payment_hash, created_at: invoice.created_at)
|
return ZapInvoice(description: invoice.description, amount: amt, string: invoice.string, expiry: invoice.expiry, payment_hash: invoice.payment_hash, created_at: invoice.created_at)
|
||||||
}
|
}
|
||||||
|
|
||||||
func preimage_matches_invoice<T>(_ preimage: String, inv: LightningInvoice<T>) -> Bool {
|
|
||||||
guard let raw_preimage = hex_decode(preimage) else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
let hashed = sha256(Data(raw_preimage))
|
|
||||||
|
|
||||||
return inv.payment_hash == hashed
|
|
||||||
}
|
|
||||||
|
|
||||||
func determine_zap_target(_ ev: NostrEvent) -> ZapTarget? {
|
func determine_zap_target(_ ev: NostrEvent) -> ZapTarget? {
|
||||||
guard let ptag = event_tag(ev, name: "p") else {
|
guard let ptag = event_tag(ev, name: "p") else {
|
||||||
return nil
|
return nil
|
||||||
@@ -209,47 +199,6 @@ func decode_nostr_event_json(_ desc: String) -> NostrEvent? {
|
|||||||
return ev
|
return ev
|
||||||
}
|
}
|
||||||
|
|
||||||
func decode_zap_request(_ desc: String) -> ZapRequest? {
|
|
||||||
let decoder = JSONDecoder()
|
|
||||||
guard let jsonData = desc.data(using: .utf8) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
guard let jsonArray = try? JSONSerialization.jsonObject(with: jsonData) as? [[Any]] else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for array in jsonArray {
|
|
||||||
guard array.count == 2 else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
let mkey = array.first.flatMap { $0 as? String }
|
|
||||||
if let key = mkey, key == "application/nostr" {
|
|
||||||
guard let dat = try? JSONSerialization.data(withJSONObject: array[1], options: []) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let zap_req = try? decoder.decode(NostrEvent.self, from: dat) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
guard zap_req.kind == 9734 else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ensure the signature on the zap request is correct
|
|
||||||
guard case .ok = validate_event(ev: zap_req) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return ZapRequest(ev: zap_req)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func fetch_zapper_from_lnurl(_ lnurl: String) async -> String? {
|
func fetch_zapper_from_lnurl(_ lnurl: String) async -> String? {
|
||||||
guard let endpoint = await fetch_static_payreq(lnurl) else {
|
guard let endpoint = await fetch_static_payreq(lnurl) else {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ struct EventActionBar: View {
|
|||||||
_bar = ObservedObject(wrappedValue: bar ?? make_actionbar_model(ev: event.id, damus: damus_state))
|
_bar = ObservedObject(wrappedValue: bar ?? make_actionbar_model(ev: event.id, damus: damus_state))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
|
||||||
|
|
||||||
var lnurl: String? {
|
var lnurl: String? {
|
||||||
damus_state.profiles.lookup(id: event.pubkey)?.lnurl
|
damus_state.profiles.lookup(id: event.pubkey)?.lnurl
|
||||||
}
|
}
|
||||||
@@ -173,8 +171,6 @@ struct LikeButton: View {
|
|||||||
let liked: Bool
|
let liked: Bool
|
||||||
let action: () -> ()
|
let action: () -> ()
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
|
||||||
|
|
||||||
// Following four are Shaka animation properties
|
// Following four are Shaka animation properties
|
||||||
let timer = Timer.publish(every: 0.10, on: .main, in: .common).autoconnect()
|
let timer = Timer.publish(every: 0.10, on: .main, in: .common).autoconnect()
|
||||||
@State private var shouldAnimate = false
|
@State private var shouldAnimate = false
|
||||||
@@ -232,7 +228,6 @@ struct EventActionBar_Previews: PreviewProvider {
|
|||||||
let maxed_bar = ActionBarModel(likes: 999, boosts: 999, zaps: 999, zap_total: 99999999, replies: 999, our_like: test_event, our_boost: test_event, our_zap: nil, our_reply: nil)
|
let maxed_bar = ActionBarModel(likes: 999, boosts: 999, zaps: 999, zap_total: 99999999, replies: 999, our_like: test_event, our_boost: test_event, our_zap: nil, our_reply: nil)
|
||||||
let extra_max_bar = ActionBarModel(likes: 9999, boosts: 9999, zaps: 9999, zap_total: 99999999, replies: 9999, our_like: test_event, our_boost: test_event, our_zap: nil, our_reply: test_event)
|
let extra_max_bar = ActionBarModel(likes: 9999, boosts: 9999, zaps: 9999, zap_total: 99999999, replies: 9999, our_like: test_event, our_boost: test_event, our_zap: nil, our_reply: test_event)
|
||||||
let mega_max_bar = ActionBarModel(likes: 9999999, boosts: 99999, zaps: 9999, zap_total: 99999999, replies: 9999999, our_like: test_event, our_boost: test_event, our_zap: test_zap, our_reply: test_event)
|
let mega_max_bar = ActionBarModel(likes: 9999999, boosts: 99999, zaps: 9999, zap_total: 99999999, replies: 9999999, our_like: test_event, our_boost: test_event, our_zap: test_zap, our_reply: test_event)
|
||||||
let zapbar = ActionBarModel(likes: 0, boosts: 0, zaps: 5, zap_total: 10000000, replies: 0, our_like: nil, our_boost: nil, our_zap: nil, our_reply: nil)
|
|
||||||
|
|
||||||
VStack(spacing: 50) {
|
VStack(spacing: 50) {
|
||||||
EventActionBar(damus_state: ds, event: ev, bar: bar)
|
EventActionBar(damus_state: ds, event: ev, bar: bar)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ struct ShareAction: View {
|
|||||||
|
|
||||||
@Binding var show_share: Bool
|
@Binding var show_share: Bool
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
||||||
init(event: NostrEvent, bookmarks: BookmarksManager, show_share: Binding<Bool>) {
|
init(event: NostrEvent, bookmarks: BookmarksManager, show_share: Binding<Bool>) {
|
||||||
@@ -44,8 +43,7 @@ struct ShareAction: View {
|
|||||||
|
|
||||||
let bookmarkImg = isBookmarked ? "bookmark.slash" : "bookmark"
|
let bookmarkImg = isBookmarked ? "bookmark.slash" : "bookmark"
|
||||||
let bookmarkTxt = isBookmarked ? NSLocalizedString("Remove Bookmark", comment: "Button text to remove bookmark from a note.") : NSLocalizedString("Add Bookmark", comment: "Button text to add bookmark to a note.")
|
let bookmarkTxt = isBookmarked ? NSLocalizedString("Remove Bookmark", comment: "Button text to remove bookmark from a note.") : NSLocalizedString("Add Bookmark", comment: "Button text to add bookmark to a note.")
|
||||||
let boomarkCol = isBookmarked ? Color(.red) : nil
|
ShareActionButton(img: bookmarkImg, text: bookmarkTxt) {
|
||||||
ShareActionButton(img: bookmarkImg, text: bookmarkTxt, col: boomarkCol) {
|
|
||||||
dismiss()
|
dismiss()
|
||||||
self.bookmarks.updateBookmark(event)
|
self.bookmarks.updateBookmark(event)
|
||||||
isBookmarked = self.bookmarks.isBookmarked(event)
|
isBookmarked = self.bookmarks.isBookmarked(event)
|
||||||
|
|||||||
@@ -10,21 +10,12 @@ import SwiftUI
|
|||||||
struct ShareActionButton: View {
|
struct ShareActionButton: View {
|
||||||
let img: String
|
let img: String
|
||||||
let text: String
|
let text: String
|
||||||
let color: Color?
|
|
||||||
let action: () -> ()
|
let action: () -> ()
|
||||||
|
|
||||||
init(img: String, text: String, col: Color?, action: @escaping () -> ()) {
|
|
||||||
self.img = img
|
|
||||||
self.text = text
|
|
||||||
self.color = col
|
|
||||||
self.action = action
|
|
||||||
}
|
|
||||||
|
|
||||||
init(img: String, text: String, action: @escaping () -> ()) {
|
init(img: String, text: String, action: @escaping () -> ()) {
|
||||||
self.img = img
|
self.img = img
|
||||||
self.text = text
|
self.text = text
|
||||||
self.action = action
|
self.action = action
|
||||||
self.color = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var col: Color {
|
var col: Color {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ struct BookmarksView: View {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
InnerTimelineView(events: EventHolder(events: bookmarks, incoming: []), damus: state, show_friend_icon: true, filter: noneFilter)
|
InnerTimelineView(events: EventHolder(events: bookmarks, incoming: []), damus: state, filter: noneFilter)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,6 @@ struct CarouselView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CarouselText(_ txt: String) -> some View {
|
|
||||||
return Text(txt)
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CarouselItemView: View {
|
struct CarouselItemView: View {
|
||||||
let item: CarouselItem
|
let item: CarouselItem
|
||||||
|
|
||||||
|
|||||||
@@ -1,175 +0,0 @@
|
|||||||
//
|
|
||||||
// ChatView.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2022-04-19.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct ChatView: View {
|
|
||||||
let event: NostrEvent
|
|
||||||
let prev_ev: NostrEvent?
|
|
||||||
let next_ev: NostrEvent?
|
|
||||||
|
|
||||||
let damus_state: DamusState
|
|
||||||
|
|
||||||
@State var expand_reply: Bool = false
|
|
||||||
@EnvironmentObject var thread: ThreadModel
|
|
||||||
|
|
||||||
var just_started: Bool {
|
|
||||||
return prev_ev == nil || prev_ev!.pubkey != event.pubkey
|
|
||||||
}
|
|
||||||
|
|
||||||
func next_replies_to_this() -> Bool {
|
|
||||||
guard let next = next_ev else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return thread.replies.lookup(next.id) != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func is_reply_to_prev() -> Bool {
|
|
||||||
guard let prev = prev_ev else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if let rep = thread.replies.lookup(event.id) {
|
|
||||||
return rep.contains(prev.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var is_active: Bool {
|
|
||||||
return thread.event.id == event.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func prev_reply_is_same() -> String? {
|
|
||||||
return damus.prev_reply_is_same(event: event, prev_ev: prev_ev, replies: thread.replies)
|
|
||||||
}
|
|
||||||
|
|
||||||
func reply_is_new() -> String? {
|
|
||||||
guard let prev = self.prev_ev else {
|
|
||||||
// if they are both null they are the same?
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if thread.replies.lookup(prev.id) != thread.replies.lookup(event.id) {
|
|
||||||
return prev.id
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var ReplyDescription: some View {
|
|
||||||
Text(verbatim: "\(reply_desc(profiles: damus_state.profiles, event: event))")
|
|
||||||
.font(.footnote)
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
.frame(alignment: .leading)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
|
||||||
|
|
||||||
var disable_animation: Bool {
|
|
||||||
self.damus_state.settings.disable_animation
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
HStack {
|
|
||||||
VStack {
|
|
||||||
if is_active || just_started {
|
|
||||||
ProfilePicView(pubkey: event.pubkey, size: 32, highlight: is_active ? .main : .none, profiles: damus_state.profiles, disable_animation: disable_animation)
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
.frame(maxWidth: 32)
|
|
||||||
|
|
||||||
Group {
|
|
||||||
VStack(alignment: .leading) {
|
|
||||||
if just_started {
|
|
||||||
HStack {
|
|
||||||
ProfileName(pubkey: event.pubkey, profile: damus_state.profiles.lookup(id: event.pubkey), damus: damus_state, show_friend_confirmed: true)
|
|
||||||
.foregroundColor(colorScheme == .dark ? id_to_color(event.pubkey) : Color.black)
|
|
||||||
//.shadow(color: Color.black, radius: 2)
|
|
||||||
Text(verbatim: "\(format_relative_time(event.created_at))")
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let _ = thread.replies.lookup(event.id) {
|
|
||||||
if !is_reply_to_prev() {
|
|
||||||
/*
|
|
||||||
ReplyQuoteView(keypair: damus_state.keypair, quoter: event, event_id: ref_id, profiles: damus_state.profiles, previews: damus_state.previews)
|
|
||||||
.frame(maxHeight: expand_reply ? nil : 100)
|
|
||||||
.environmentObject(thread)
|
|
||||||
.onTapGesture {
|
|
||||||
expand_reply = !expand_reply
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
ReplyDescription
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let show_images = should_show_images(settings: damus_state.settings, contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey)
|
|
||||||
NoteContentView(damus_state: damus_state,
|
|
||||||
event: event,
|
|
||||||
show_images: show_images,
|
|
||||||
size: .normal,
|
|
||||||
artifacts: .just_content(event.content),
|
|
||||||
options: [])
|
|
||||||
|
|
||||||
if is_active || next_ev == nil || next_ev!.pubkey != event.pubkey {
|
|
||||||
let bar = make_actionbar_model(ev: event.id, damus: damus_state)
|
|
||||||
EventActionBar(damus_state: damus_state, event: event, bar: bar)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Spacer()
|
|
||||||
}
|
|
||||||
.padding(6)
|
|
||||||
}
|
|
||||||
.background(Color.secondary.opacity(0.1))
|
|
||||||
.cornerRadius(8.0)
|
|
||||||
|
|
||||||
//.border(Color.red)
|
|
||||||
}
|
|
||||||
.contentShape(Rectangle())
|
|
||||||
.id(event.id)
|
|
||||||
//.frame(minHeight: just_started ? PFP_SIZE : 0)
|
|
||||||
.padding([.bottom], 6)
|
|
||||||
//.border(Color.green)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Notification.Name {
|
|
||||||
static var toggle_thread_view: Notification.Name {
|
|
||||||
return Notification.Name("convert_to_thread")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct ChatView_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
|
||||||
ChatView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
func prev_reply_is_same(event: NostrEvent, prev_ev: NostrEvent?, replies: ReplyMap) -> String? {
|
|
||||||
if let prev = prev_ev {
|
|
||||||
if let prev_reply_id = replies.lookup(prev.id) {
|
|
||||||
if let cur_reply_id = replies.lookup(event.id) {
|
|
||||||
if prev_reply_id != cur_reply_id {
|
|
||||||
return cur_reply_id.first
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
//
|
|
||||||
// ChatroomView.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2022-04-19.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct ChatroomView: View {
|
|
||||||
@EnvironmentObject var thread: ThreadModel
|
|
||||||
@Environment(\.dismiss) var dismiss
|
|
||||||
@State var once: Bool = false
|
|
||||||
let damus: DamusState
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
ScrollViewReader { scroller in
|
|
||||||
ScrollView(.vertical) {
|
|
||||||
VStack(alignment: .leading) {
|
|
||||||
let count = thread.events.count
|
|
||||||
ForEach(Array(zip(thread.events, thread.events.indices)), id: \.0.id) { (ev, ind) in
|
|
||||||
ChatView(event: thread.events[ind],
|
|
||||||
prev_ev: ind > 0 ? thread.events[ind-1] : nil,
|
|
||||||
next_ev: ind == count-1 ? nil : thread.events[ind+1],
|
|
||||||
damus_state: damus
|
|
||||||
)
|
|
||||||
.contextMenu{MenuItems(event: ev, keypair: damus.keypair, target_pubkey: ev.pubkey, bookmarks: damus.bookmarks)}
|
|
||||||
.onTapGesture {
|
|
||||||
if thread.event.id == ev.id {
|
|
||||||
//dismiss()
|
|
||||||
toggle_thread_view()
|
|
||||||
} else {
|
|
||||||
thread.set_active_event(ev, privkey: damus.keypair.privkey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.environmentObject(thread)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
.padding(.horizontal)
|
|
||||||
.padding(.top)
|
|
||||||
|
|
||||||
EndBlock()
|
|
||||||
}
|
|
||||||
.onReceive(NotificationCenter.default.publisher(for: .select_quote)) { notif in
|
|
||||||
let ev = notif.object as! NostrEvent
|
|
||||||
if ev.id != thread.event.id {
|
|
||||||
thread.set_active_event(ev, privkey: damus.keypair.privkey)
|
|
||||||
}
|
|
||||||
scroll_to_event(scroller: scroller, id: ev.id, delay: 0, animate: true)
|
|
||||||
}
|
|
||||||
.onChange(of: thread.loading) { _ in
|
|
||||||
guard !thread.loading && !once else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
scroll_after_load(thread: thread, proxy: scroller)
|
|
||||||
once = true
|
|
||||||
}
|
|
||||||
.onAppear() {
|
|
||||||
scroll_to_event(scroller: scroller, id: thread.event.id, delay: 0.1, animate: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toggle_thread_view() {
|
|
||||||
NotificationCenter.default.post(name: .toggle_thread_view, object: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ChatroomView_Previews: PreviewProvider {
|
|
||||||
@State var events = [NostrEvent(content: "hello", pubkey: "pubkey")]
|
|
||||||
|
|
||||||
static var previews: some View {
|
|
||||||
let state = test_damus_state()
|
|
||||||
ChatroomView(damus: state)
|
|
||||||
.environmentObject(ThreadModel(event: test_event, damus_state: state))
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
@@ -48,7 +48,7 @@ struct ConfigView: View {
|
|||||||
IconLabel(NSLocalizedString("Notifications", comment: "Section header for Damus notifications"), img_name: "bell.fill", color: .blue)
|
IconLabel(NSLocalizedString("Notifications", comment: "Section header for Damus notifications"), img_name: "bell.fill", color: .blue)
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationLink(destination: ZapSettingsView(pubkey: state.pubkey, settings: settings)) {
|
NavigationLink(destination: ZapSettingsView(settings: settings)) {
|
||||||
IconLabel(NSLocalizedString("Zaps", comment: "Section header for zap settings"), img_name: "bolt.fill", color: .orange)
|
IconLabel(NSLocalizedString("Zaps", comment: "Section header for zap settings"), img_name: "bolt.fill", color: .orange)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,7 @@ struct CreateAccountView: View {
|
|||||||
@StateObject var account: CreateAccountModel = CreateAccountModel()
|
@StateObject var account: CreateAccountModel = CreateAccountModel()
|
||||||
@StateObject var profileUploadViewModel = ProfileUploadingViewModel()
|
@StateObject var profileUploadViewModel = ProfileUploadingViewModel()
|
||||||
|
|
||||||
@State var is_light: Bool = false
|
|
||||||
@State var is_done: Bool = false
|
@State var is_done: Bool = false
|
||||||
@State var reading_eula: Bool = false
|
|
||||||
@State var profile_image: URL? = nil
|
|
||||||
|
|
||||||
func SignupForm<FormContent: View>(@ViewBuilder content: () -> FormContent) -> some View {
|
func SignupForm<FormContent: View>(@ViewBuilder content: () -> FormContent) -> some View {
|
||||||
return VStack(alignment: .leading, spacing: 10.0, content: content)
|
return VStack(alignment: .leading, spacing: 10.0, content: content)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ struct DMChatView: View, KeyboardReadable {
|
|||||||
HStack {
|
HStack {
|
||||||
ProfilePicView(pubkey: pubkey, size: 24, highlight: .none, profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation)
|
ProfilePicView(pubkey: pubkey, size: 24, highlight: .none, profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation)
|
||||||
|
|
||||||
ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: true)
|
ProfileName(pubkey: pubkey, profile: profile, damus: damus_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
@@ -99,14 +99,6 @@ struct DMChatView: View, KeyboardReadable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BackgroundColor() -> some View {
|
|
||||||
if colorScheme == .dark {
|
|
||||||
return Color.black.opacity(0.9)
|
|
||||||
} else {
|
|
||||||
return Color.white.opacity(0.9)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var Footer: some View {
|
var Footer: some View {
|
||||||
|
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ struct DMView: View {
|
|||||||
|
|
||||||
let should_show_img = should_show_images(settings: damus_state.settings, contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey)
|
let should_show_img = should_show_images(settings: damus_state.settings, contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey)
|
||||||
|
|
||||||
NoteContentView(damus_state: damus_state, event: event, show_images: should_show_img, size: .normal, artifacts: .just_content(event.get_content(damus_state.keypair.privkey)), options: dm_options)
|
NoteContentView(damus_state: damus_state, event: event, show_images: should_show_img, size: .normal, options: dm_options)
|
||||||
.padding([.top, .leading, .trailing], 10)
|
.padding([.top, .leading, .trailing], 10)
|
||||||
.padding([.bottom], 25)
|
.padding([.bottom], 25)
|
||||||
.background(VisualEffectView(effect: UIBlurEffect(style: .prominent))
|
.background(VisualEffectView(effect: UIBlurEffect(style: .prominent))
|
||||||
|
|||||||
@@ -110,10 +110,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 ev = NostrEvent(content: "encrypted stuff",
|
|
||||||
pubkey: "pubkey",
|
|
||||||
kind: 4,
|
|
||||||
tags: [])
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,6 @@ struct EventDetailView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func scroll_after_load(thread: ThreadModel, proxy: ScrollViewProxy) {
|
|
||||||
if !thread.loading {
|
|
||||||
let id = thread.event.id
|
|
||||||
scroll_to_event(scroller: proxy, id: id, delay: 0.1, animate: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EventDetailView_Previews: PreviewProvider {
|
struct EventDetailView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let _ = test_damus_state()
|
let _ = test_damus_state()
|
||||||
@@ -28,11 +21,6 @@ struct EventDetailView_Previews: PreviewProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func print_event(_ ev: NostrEvent) {
|
|
||||||
print(ev.description)
|
|
||||||
}
|
|
||||||
|
|
||||||
func scroll_to_event(scroller: ScrollViewProxy, id: String, delay: Double, animate: Bool, anchor: UnitPoint = .bottom) {
|
func scroll_to_event(scroller: ScrollViewProxy, id: String, delay: Double, animate: Bool, anchor: UnitPoint = .bottom) {
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
||||||
if animate {
|
if animate {
|
||||||
|
|||||||
@@ -20,8 +20,6 @@ struct EventView: View {
|
|||||||
let damus: DamusState
|
let damus: DamusState
|
||||||
let pubkey: String
|
let pubkey: String
|
||||||
|
|
||||||
@EnvironmentObject var action_bar: ActionBarModel
|
|
||||||
|
|
||||||
init(damus: DamusState, event: NostrEvent, pubkey: String? = nil, options: EventViewOptions = []) {
|
init(damus: DamusState, event: NostrEvent, pubkey: String? = nil, options: EventViewOptions = []) {
|
||||||
self.event = event
|
self.event = event
|
||||||
self.options = options
|
self.options = options
|
||||||
@@ -79,13 +77,6 @@ extension View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func event_context_menu(_ event: NostrEvent, keypair: Keypair, target_pubkey: String, bookmarks: BookmarksManager, muted_threads: MutedThreadsManager) -> some View {
|
|
||||||
return self.contextMenu {
|
|
||||||
EventMenuContext(event: event, keypair: keypair, target_pubkey: target_pubkey, bookmarks: bookmarks, muted_threads: muted_threads)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func format_relative_time(_ created_at: Int64) -> String
|
func format_relative_time(_ created_at: Int64) -> String
|
||||||
|
|||||||
@@ -22,12 +22,8 @@ struct EventBody: View {
|
|||||||
self.should_show_img = should_show_img ?? should_show_images(settings: damus_state.settings, contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey)
|
self.should_show_img = should_show_img ?? should_show_images(settings: damus_state.settings, contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
var content: String {
|
|
||||||
event.get_content(damus_state.keypair.privkey)
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NoteContentView(damus_state: damus_state, event: event, show_images: should_show_img, size: size, artifacts: .just_content(content), options: options)
|
NoteContentView(damus_state: damus_state, event: event, show_images: should_show_img, size: size, options: options)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ struct EventMenuContext: View {
|
|||||||
let bookmarks: BookmarksManager
|
let bookmarks: BookmarksManager
|
||||||
let muted_threads: MutedThreadsManager
|
let muted_threads: MutedThreadsManager
|
||||||
|
|
||||||
@Environment(\.colorScheme) var colorScheme
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
Menu {
|
Menu {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ struct EventProfile: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EventProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: true, size: size)
|
EventProfileName(pubkey: pubkey, profile: profile, damus: damus_state, size: size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,8 +82,6 @@ struct MutedEventView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct MutedEventView_Previews: PreviewProvider {
|
struct MutedEventView_Previews: PreviewProvider {
|
||||||
@State static var nav_target: NostrEvent = test_event
|
|
||||||
@State static var navigating: Bool = false
|
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ struct EventViewOptions: OptionSet {
|
|||||||
|
|
||||||
static let no_action_bar = EventViewOptions(rawValue: 1 << 0)
|
static let no_action_bar = EventViewOptions(rawValue: 1 << 0)
|
||||||
static let no_replying_to = EventViewOptions(rawValue: 1 << 1)
|
static let no_replying_to = EventViewOptions(rawValue: 1 << 1)
|
||||||
static let no_images = EventViewOptions(rawValue: 1 << 2)
|
|
||||||
static let wide = EventViewOptions(rawValue: 1 << 3)
|
static let wide = EventViewOptions(rawValue: 1 << 3)
|
||||||
static let truncate_content = EventViewOptions(rawValue: 1 << 4)
|
static let truncate_content = EventViewOptions(rawValue: 1 << 4)
|
||||||
static let pad_content = EventViewOptions(rawValue: 1 << 5)
|
static let pad_content = EventViewOptions(rawValue: 1 << 5)
|
||||||
@@ -133,18 +132,16 @@ struct TextEvent: View {
|
|||||||
func ProfileName(is_anon: Bool) -> some View {
|
func ProfileName(is_anon: Bool) -> some View {
|
||||||
let profile = damus.profiles.lookup(id: pubkey)
|
let profile = damus.profiles.lookup(id: pubkey)
|
||||||
let pk = is_anon ? "anon" : pubkey
|
let pk = is_anon ? "anon" : pubkey
|
||||||
return EventProfileName(pubkey: pk, profile: profile, damus: damus, show_friend_confirmed: true, size: .normal)
|
return EventProfileName(pubkey: pk, profile: profile, damus: damus, size: .normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EvBody(options: EventViewOptions) -> some View {
|
func EvBody(options: EventViewOptions) -> some View {
|
||||||
let show_imgs = should_show_images(settings: damus.settings, contacts: damus.contacts, ev: event, our_pubkey: damus.pubkey)
|
let show_imgs = should_show_images(settings: damus.settings, contacts: damus.contacts, ev: event, our_pubkey: damus.pubkey)
|
||||||
let artifacts = damus.events.get_cache_data(event.id).artifacts.artifacts ?? .just_content(event.get_content(damus.keypair.privkey))
|
|
||||||
return NoteContentView(
|
return NoteContentView(
|
||||||
damus_state: damus,
|
damus_state: damus,
|
||||||
event: event,
|
event: event,
|
||||||
show_images: show_imgs,
|
show_images: show_imgs,
|
||||||
size: .normal,
|
size: .normal,
|
||||||
artifacts: artifacts,
|
|
||||||
options: options
|
options: options
|
||||||
)
|
)
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
|||||||
@@ -23,18 +23,15 @@ struct ImagePicker: UIViewControllerRepresentable {
|
|||||||
|
|
||||||
final class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
|
final class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
|
||||||
@Binding private var presentationMode: PresentationMode
|
@Binding private var presentationMode: PresentationMode
|
||||||
private let sourceType: UIImagePickerController.SourceType
|
|
||||||
private let onImagePicked: (URL) -> Void
|
private let onImagePicked: (URL) -> Void
|
||||||
private let onVideoPicked: (URL) -> Void
|
private let onVideoPicked: (URL) -> Void
|
||||||
@Binding var image_upload_confirm: Bool
|
@Binding var image_upload_confirm: Bool
|
||||||
|
|
||||||
init(presentationMode: Binding<PresentationMode>,
|
init(presentationMode: Binding<PresentationMode>,
|
||||||
sourceType: UIImagePickerController.SourceType,
|
|
||||||
onImagePicked: @escaping (URL) -> Void,
|
onImagePicked: @escaping (URL) -> Void,
|
||||||
onVideoPicked: @escaping (URL) -> Void,
|
onVideoPicked: @escaping (URL) -> Void,
|
||||||
image_upload_confirm: Binding<Bool>) {
|
image_upload_confirm: Binding<Bool>) {
|
||||||
_presentationMode = presentationMode
|
_presentationMode = presentationMode
|
||||||
self.sourceType = sourceType
|
|
||||||
self.onImagePicked = onImagePicked
|
self.onImagePicked = onImagePicked
|
||||||
self.onVideoPicked = onVideoPicked
|
self.onVideoPicked = onVideoPicked
|
||||||
self._image_upload_confirm = image_upload_confirm
|
self._image_upload_confirm = image_upload_confirm
|
||||||
@@ -95,7 +92,6 @@ struct ImagePicker: UIViewControllerRepresentable {
|
|||||||
|
|
||||||
func makeCoordinator() -> Coordinator {
|
func makeCoordinator() -> Coordinator {
|
||||||
return Coordinator(presentationMode: presentationMode,
|
return Coordinator(presentationMode: presentationMode,
|
||||||
sourceType: sourceType,
|
|
||||||
onImagePicked: { url in
|
onImagePicked: { url in
|
||||||
// Handle the selected image URL
|
// Handle the selected image URL
|
||||||
onImagePicked(url)
|
onImagePicked(url)
|
||||||
|
|||||||
@@ -18,15 +18,6 @@ enum Timeline: String, CustomStringConvertible, Hashable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func timeline_bit(_ timeline: Timeline) -> Int {
|
|
||||||
switch timeline {
|
|
||||||
case .home: return 1 << 0
|
|
||||||
case .notifications: return 1 << 1
|
|
||||||
case .search: return 1 << 2
|
|
||||||
case .dms: return 1 << 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func show_indicator(timeline: Timeline, current: NewEventsBits, indicator_setting: Int) -> Bool {
|
func show_indicator(timeline: Timeline, current: NewEventsBits, indicator_setting: Int) -> Bool {
|
||||||
if timeline == .notifications {
|
if timeline == .notifications {
|
||||||
return (current.rawValue & indicator_setting & NewEventsBits.notifications.rawValue) > 0
|
return (current.rawValue & indicator_setting & NewEventsBits.notifications.rawValue) > 0
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
//
|
|
||||||
// MentionView.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2022-05-04.
|
|
||||||
//
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct MentionView: View {
|
|
||||||
let mention: Mention
|
|
||||||
let profiles: Profiles
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
switch mention.type {
|
|
||||||
case .pubkey:
|
|
||||||
let pk = bech32_pubkey(mention.ref.ref_id) ?? mention.ref.ref_id
|
|
||||||
PubkeyView(pubkey: pk, relay: mention.ref.relay_id)
|
|
||||||
case .event:
|
|
||||||
Text(verbatim: "< e >")
|
|
||||||
//EventBlockView(pubkey: mention.ref.ref_id, relay: mention.ref.relay_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct MentionView_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
|
||||||
MentionView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -37,7 +37,7 @@ struct NoteContentView: View {
|
|||||||
return self.artifacts_model.state.artifacts ?? .just_content(event.get_content(damus_state.keypair.privkey))
|
return self.artifacts_model.state.artifacts ?? .just_content(event.get_content(damus_state.keypair.privkey))
|
||||||
}
|
}
|
||||||
|
|
||||||
init(damus_state: DamusState, event: NostrEvent, show_images: Bool, size: EventViewKind, artifacts: NoteArtifacts, options: EventViewOptions) {
|
init(damus_state: DamusState, event: NostrEvent, show_images: Bool, size: EventViewKind, options: EventViewOptions) {
|
||||||
self.damus_state = damus_state
|
self.damus_state = damus_state
|
||||||
self.event = event
|
self.event = event
|
||||||
self.show_images = show_images
|
self.show_images = show_images
|
||||||
@@ -210,11 +210,6 @@ struct NoteContentView: View {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ImageName {
|
|
||||||
case systemImage(String)
|
|
||||||
case image(String)
|
|
||||||
}
|
|
||||||
|
|
||||||
func attributed_string_attach_icon(_ astr: inout AttributedString, img: UIImage) {
|
func attributed_string_attach_icon(_ astr: inout AttributedString, img: UIImage) {
|
||||||
let attachment = NSTextAttachment()
|
let attachment = NSTextAttachment()
|
||||||
attachment.image = img
|
attachment.image = img
|
||||||
@@ -256,9 +251,7 @@ struct NoteContentView_Previews: PreviewProvider {
|
|||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let state = test_damus_state()
|
let state = test_damus_state()
|
||||||
let content = "hi there ¯\\_(ツ)_/¯ https://jb55.com/s/Oct12-150217.png 5739a762ef6124dd.jpg"
|
let content = "hi there ¯\\_(ツ)_/¯ https://jb55.com/s/Oct12-150217.png 5739a762ef6124dd.jpg"
|
||||||
let txt = CompatibleText(attributed: AttributedString(stringLiteral: content))
|
NoteContentView(damus_state: state, event: NostrEvent(content: content, pubkey: "pk"), show_images: true, size: .normal, options: [])
|
||||||
let artifacts = NoteArtifacts(content: txt, images: [], invoices: [], links: [])
|
|
||||||
NoteContentView(damus_state: state, event: NostrEvent(content: content, pubkey: "pk"), show_images: true, size: .normal, artifacts: artifacts, options: [])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,17 +284,6 @@ enum NoteArtifactState {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var is_loaded: Bool {
|
|
||||||
switch self {
|
|
||||||
case .not_loaded:
|
|
||||||
return false
|
|
||||||
case .loading:
|
|
||||||
return false
|
|
||||||
case .loaded:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var should_preload: Bool {
|
var should_preload: Bool {
|
||||||
switch self {
|
switch self {
|
||||||
case .loaded:
|
case .loaded:
|
||||||
@@ -317,10 +299,10 @@ enum NoteArtifactState {
|
|||||||
func render_note_content(ev: NostrEvent, profiles: Profiles, privkey: String?) -> NoteArtifacts {
|
func render_note_content(ev: NostrEvent, profiles: Profiles, privkey: String?) -> NoteArtifacts {
|
||||||
let blocks = ev.blocks(privkey)
|
let blocks = ev.blocks(privkey)
|
||||||
|
|
||||||
return render_blocks(blocks: blocks, profiles: profiles, privkey: privkey)
|
return render_blocks(blocks: blocks, profiles: profiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
func render_blocks(blocks: [Block], profiles: Profiles, privkey: String?) -> NoteArtifacts {
|
func render_blocks(blocks: [Block], profiles: Profiles) -> NoteArtifacts {
|
||||||
var invoices: [Invoice] = []
|
var invoices: [Invoice] = []
|
||||||
var img_urls: [URL] = []
|
var img_urls: [URL] = []
|
||||||
var link_urls: [URL] = []
|
var link_urls: [URL] = []
|
||||||
@@ -396,16 +378,6 @@ func lookup_cached_preview_size(previews: PreviewCache, evid: String) -> CGFloat
|
|||||||
return height
|
return height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func load_cached_preview(previews: PreviewCache, evid: String) -> LinkViewRepresentable? {
|
|
||||||
guard case .value(let meta) = previews.lookup(evid) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return LinkViewRepresentable(meta: .linkmeta(meta))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// trim suffix whitespace and newlines
|
// trim suffix whitespace and newlines
|
||||||
func trim_suffix(_ str: String) -> String {
|
func trim_suffix(_ str: String) -> String {
|
||||||
return str.replacingOccurrences(of: "\\s+$", with: "", options: .regularExpression)
|
return str.replacingOccurrences(of: "\\s+$", with: "", options: .regularExpression)
|
||||||
|
|||||||
@@ -51,15 +51,6 @@ class NotificationFilter: ObservableObject, Equatable {
|
|||||||
self.fine_filter = fine_filter
|
self.fine_filter = fine_filter
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggle_fine_filter() {
|
|
||||||
switch self.fine_filter {
|
|
||||||
case .all:
|
|
||||||
self.fine_filter = .friends
|
|
||||||
case .friends:
|
|
||||||
self.fine_filter = .all
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func filter(contacts: Contacts, items: [NotificationItem]) -> [NotificationItem] {
|
func filter(contacts: Contacts, items: [NotificationItem]) -> [NotificationItem] {
|
||||||
|
|
||||||
return items.reduce(into: []) { acc, item in
|
return items.reduce(into: []) { acc, item in
|
||||||
@@ -79,10 +70,6 @@ enum NotificationFilterState: String {
|
|||||||
case zaps
|
case zaps
|
||||||
case replies
|
case replies
|
||||||
|
|
||||||
func is_other( item: NotificationItem) -> Bool {
|
|
||||||
item.is_zap == nil && item.is_reply == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func filter(_ item: NotificationItem) -> Bool {
|
func filter(_ item: NotificationItem) -> Bool {
|
||||||
switch self {
|
switch self {
|
||||||
case .all:
|
case .all:
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ struct ParticipantsView: View {
|
|||||||
|
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
let profile = damus_state.profiles.lookup(id: pubkey)
|
let profile = damus_state.profiles.lookup(id: pubkey)
|
||||||
ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: false, show_nip5_domain: false)
|
ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_nip5_domain: false)
|
||||||
if let about = profile?.about {
|
if let about = profile?.about {
|
||||||
Text(FollowUserView.markdown.process(about))
|
Text(FollowUserView.markdown.process(about))
|
||||||
.lineLimit(3)
|
.lineLimit(3)
|
||||||
|
|||||||
@@ -55,10 +55,6 @@ struct PostView: View {
|
|||||||
|
|
||||||
@Environment(\.presentationMode) var presentationMode
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
|
||||||
enum FocusField: Hashable {
|
|
||||||
case post
|
|
||||||
}
|
|
||||||
|
|
||||||
func cancel() {
|
func cancel() {
|
||||||
NotificationCenter.default.post(name: .post, object: NostrPostResult.cancel)
|
NotificationCenter.default.post(name: .post, object: NostrPostResult.cancel)
|
||||||
dismiss()
|
dismiss()
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
//
|
|
||||||
// PowView.swift
|
|
||||||
// damus
|
|
||||||
//
|
|
||||||
// Created by William Casarin on 2022-04-16.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
func PowView(_ mpow: Int?) -> some View
|
|
||||||
{
|
|
||||||
let pow = mpow ?? 0
|
|
||||||
return Text(verbatim: "\(pow)")
|
|
||||||
.font(.callout)
|
|
||||||
.foregroundColor(calculate_pow_color(pow))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: make this less saturated on white theme
|
|
||||||
func calculate_pow_color(_ pow: Int) -> Color
|
|
||||||
{
|
|
||||||
let x = Double(pow) / 30.0;
|
|
||||||
return Color(.sRGB, red: 2.0 * (1.0 - x), green: 2.0 * x, blue: 0, opacity: 0.5)
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -8,51 +8,8 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
let PPM_SIZE: CGFloat = 80.0
|
|
||||||
let BANNER_HEIGHT: CGFloat = 150.0;
|
let BANNER_HEIGHT: CGFloat = 150.0;
|
||||||
|
|
||||||
func isHttpsUrl(_ string: String) -> Bool {
|
|
||||||
let urlRegEx = "^https://.*$"
|
|
||||||
let urlTest = NSPredicate(format:"SELF MATCHES %@", urlRegEx)
|
|
||||||
return urlTest.evaluate(with: string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isImage(_ urlString: String) -> Bool {
|
|
||||||
let imageTypes = ["image/jpg", "image/jpeg", "image/png", "image/gif", "image/tiff", "image/bmp", "image/webp"]
|
|
||||||
|
|
||||||
guard let url = URL(string: urlString) else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = false
|
|
||||||
let semaphore = DispatchSemaphore(value: 0)
|
|
||||||
|
|
||||||
let task = URLSession.shared.dataTask(with: url) { data, response, error in
|
|
||||||
if let error = error {
|
|
||||||
print(error)
|
|
||||||
semaphore.signal()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let httpResponse = response as? HTTPURLResponse,
|
|
||||||
let contentType = httpResponse.allHeaderFields["Content-Type"] as? String else {
|
|
||||||
semaphore.signal()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if imageTypes.contains(contentType.lowercased()) {
|
|
||||||
result = true
|
|
||||||
}
|
|
||||||
|
|
||||||
semaphore.signal()
|
|
||||||
}
|
|
||||||
|
|
||||||
task.resume()
|
|
||||||
semaphore.wait()
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EditMetadataView: View {
|
struct EditMetadataView: View {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
@State var display_name: String
|
@State var display_name: String
|
||||||
@@ -66,7 +23,6 @@ struct EditMetadataView: View {
|
|||||||
let profile: Profile?
|
let profile: Profile?
|
||||||
|
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
@Environment(\.colorScheme) var colorScheme
|
|
||||||
|
|
||||||
@State var confirm_ln_address: Bool = false
|
@State var confirm_ln_address: Bool = false
|
||||||
@StateObject var profileUploadViewModel = ProfileUploadingViewModel()
|
@StateObject var profileUploadViewModel = ProfileUploadingViewModel()
|
||||||
@@ -86,10 +42,6 @@ struct EditMetadataView: View {
|
|||||||
_ln = State(initialValue: data?.lud16 ?? data?.lud06 ?? "")
|
_ln = State(initialValue: data?.lud16 ?? data?.lud06 ?? "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func imageBorderColor() -> Color {
|
|
||||||
colorScheme == .light ? DamusColors.white : DamusColors.black
|
|
||||||
}
|
|
||||||
|
|
||||||
func to_profile() -> Profile {
|
func to_profile() -> Profile {
|
||||||
let profile = self.profile ?? Profile()
|
let profile = self.profile ?? Profile()
|
||||||
|
|
||||||
|
|||||||
@@ -12,30 +12,16 @@ struct EventProfileName: View {
|
|||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
let pubkey: String
|
let pubkey: String
|
||||||
let profile: Profile?
|
let profile: Profile?
|
||||||
let prefix: String
|
|
||||||
|
|
||||||
let show_friend_confirmed: Bool
|
|
||||||
|
|
||||||
@State var display_name: DisplayName?
|
@State var display_name: DisplayName?
|
||||||
@State var nip05: NIP05?
|
@State var nip05: NIP05?
|
||||||
|
|
||||||
let size: EventViewKind
|
let size: EventViewKind
|
||||||
|
|
||||||
init(pubkey: String, profile: Profile?, damus: DamusState, show_friend_confirmed: Bool, size: EventViewKind = .normal) {
|
init(pubkey: String, profile: Profile?, damus: DamusState, size: EventViewKind = .normal) {
|
||||||
self.damus_state = damus
|
self.damus_state = damus
|
||||||
self.pubkey = pubkey
|
self.pubkey = pubkey
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
self.prefix = ""
|
|
||||||
self.show_friend_confirmed = show_friend_confirmed
|
|
||||||
self.size = size
|
|
||||||
}
|
|
||||||
|
|
||||||
init(pubkey: String, profile: Profile?, prefix: String, damus: DamusState, show_friend_confirmed: Bool, size: EventViewKind = .normal) {
|
|
||||||
self.damus_state = damus
|
|
||||||
self.pubkey = pubkey
|
|
||||||
self.profile = profile
|
|
||||||
self.prefix = prefix
|
|
||||||
self.show_friend_confirmed = show_friend_confirmed
|
|
||||||
self.size = size
|
self.size = size
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +88,6 @@ struct EventProfileName: View {
|
|||||||
|
|
||||||
struct EventProfileName_Previews: PreviewProvider {
|
struct EventProfileName_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
EventProfileName(pubkey: "pk", profile: nil, damus: test_damus_state(), show_friend_confirmed: true)
|
EventProfileName(pubkey: "pk", profile: nil, damus: test_damus_state())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,13 +13,6 @@ struct MaybeAnonPfpView: View {
|
|||||||
let pubkey: String
|
let pubkey: String
|
||||||
let size: CGFloat
|
let size: CGFloat
|
||||||
|
|
||||||
init(state: DamusState, event: NostrEvent, pubkey: String, size: CGFloat) {
|
|
||||||
self.state = state
|
|
||||||
self.is_anon = event_is_anonymous(ev: event)
|
|
||||||
self.pubkey = pubkey
|
|
||||||
self.size = size
|
|
||||||
}
|
|
||||||
|
|
||||||
init(state: DamusState, is_anon: Bool, pubkey: String, size: CGFloat) {
|
init(state: DamusState, is_anon: Bool, pubkey: String, size: CGFloat) {
|
||||||
self.state = state
|
self.state = state
|
||||||
self.is_anon = is_anon
|
self.is_anon = is_anon
|
||||||
|
|||||||
@@ -30,27 +30,24 @@ struct ProfileName: View {
|
|||||||
let profile: Profile?
|
let profile: Profile?
|
||||||
let prefix: String
|
let prefix: String
|
||||||
|
|
||||||
let show_friend_confirmed: Bool
|
|
||||||
let show_nip5_domain: Bool
|
let show_nip5_domain: Bool
|
||||||
|
|
||||||
@State var display_name: DisplayName?
|
@State var display_name: DisplayName?
|
||||||
@State var nip05: NIP05?
|
@State var nip05: NIP05?
|
||||||
|
|
||||||
init(pubkey: String, profile: Profile?, damus: DamusState, show_friend_confirmed: Bool, show_nip5_domain: Bool = true) {
|
init(pubkey: String, profile: Profile?, damus: DamusState, show_nip5_domain: Bool = true) {
|
||||||
self.pubkey = pubkey
|
self.pubkey = pubkey
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
self.prefix = ""
|
self.prefix = ""
|
||||||
self.show_friend_confirmed = show_friend_confirmed
|
|
||||||
self.show_nip5_domain = show_nip5_domain
|
self.show_nip5_domain = show_nip5_domain
|
||||||
self.damus_state = damus
|
self.damus_state = damus
|
||||||
}
|
}
|
||||||
|
|
||||||
init(pubkey: String, profile: Profile?, prefix: String, damus: DamusState, show_friend_confirmed: Bool, show_nip5_domain: Bool = true) {
|
init(pubkey: String, profile: Profile?, prefix: String, damus: DamusState, show_nip5_domain: Bool = true) {
|
||||||
self.pubkey = pubkey
|
self.pubkey = pubkey
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
self.damus_state = damus
|
self.damus_state = damus
|
||||||
self.show_friend_confirmed = show_friend_confirmed
|
|
||||||
self.show_nip5_domain = show_nip5_domain
|
self.show_nip5_domain = show_nip5_domain
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +105,6 @@ struct ProfileName: View {
|
|||||||
struct ProfileName_Previews: PreviewProvider {
|
struct ProfileName_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ProfileName(pubkey:
|
ProfileName(pubkey:
|
||||||
test_damus_state().pubkey, profile: make_test_profile(), damus: test_damus_state(), show_friend_confirmed: true)
|
test_damus_state().pubkey, profile: make_test_profile(), damus: test_damus_state())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ struct ProfileNameView: View {
|
|||||||
switch Profile.displayName(profile: profile, pubkey: pubkey) {
|
switch Profile.displayName(profile: profile, pubkey: pubkey) {
|
||||||
case .one:
|
case .one:
|
||||||
HStack(alignment: .center, spacing: spacing) {
|
HStack(alignment: .center, spacing: spacing) {
|
||||||
ProfileName(pubkey: pubkey, profile: profile, damus: damus, show_friend_confirmed: true)
|
ProfileName(pubkey: pubkey, profile: profile, damus: damus)
|
||||||
.font(.title3.weight(.bold))
|
.font(.title3.weight(.bold))
|
||||||
if follows_you {
|
if follows_you {
|
||||||
FollowsYou()
|
FollowsYou()
|
||||||
@@ -32,7 +32,7 @@ struct ProfileNameView: View {
|
|||||||
.font(.title3.weight(.bold))
|
.font(.title3.weight(.bold))
|
||||||
|
|
||||||
HStack(alignment: .center, spacing: spacing) {
|
HStack(alignment: .center, spacing: spacing) {
|
||||||
ProfileName(pubkey: pubkey, profile: profile, prefix: "@", damus: damus, show_friend_confirmed: true)
|
ProfileName(pubkey: pubkey, profile: profile, prefix: "@", damus: damus)
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,6 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
enum ProfileTab: Hashable {
|
|
||||||
case posts
|
|
||||||
case following
|
|
||||||
}
|
|
||||||
|
|
||||||
enum FollowState {
|
enum FollowState {
|
||||||
case follows
|
case follows
|
||||||
case following
|
case following
|
||||||
@@ -36,19 +31,6 @@ func follow_btn_txt(_ fs: FollowState, follows_you: Bool) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func follow_btn_enabled_state(_ fs: FollowState) -> Bool {
|
|
||||||
switch fs {
|
|
||||||
case .follows:
|
|
||||||
return true
|
|
||||||
case .following:
|
|
||||||
return false
|
|
||||||
case .unfollowing:
|
|
||||||
return false
|
|
||||||
case .unfollows:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func followersCountString(_ count: Int, locale: Locale = Locale.current) -> String {
|
func followersCountString(_ count: Int, locale: Locale = Locale.current) -> String {
|
||||||
let format = localizedStringFormat(key: "followers_count", locale: locale)
|
let format = localizedStringFormat(key: "followers_count", locale: locale)
|
||||||
return String(format: format, locale: locale, count)
|
return String(format: format, locale: locale, count)
|
||||||
@@ -114,8 +96,6 @@ struct ProfileView: View {
|
|||||||
|
|
||||||
static let markdown = Markdown()
|
static let markdown = Markdown()
|
||||||
|
|
||||||
@State private var selected_tab: ProfileTab = .posts
|
|
||||||
@State private var showingEditProfile = false
|
|
||||||
@State var showing_select_wallet: Bool = false
|
@State var showing_select_wallet: Bool = false
|
||||||
@State var is_zoomed: Bool = false
|
@State var is_zoomed: Bool = false
|
||||||
@State var show_share_sheet: Bool = false
|
@State var show_share_sheet: Bool = false
|
||||||
@@ -141,7 +121,6 @@ struct ProfileView: View {
|
|||||||
|
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
@Environment(\.openURL) var openURL
|
|
||||||
@Environment(\.presentationMode) var presentationMode
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
|
||||||
func imageBorderColor() -> Color {
|
func imageBorderColor() -> Color {
|
||||||
@@ -419,7 +398,7 @@ struct ProfileView: View {
|
|||||||
}
|
}
|
||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
} else {
|
} else {
|
||||||
NavigationLink(destination: UserRelaysView(state: damus_state, pubkey: profile.pubkey, relays: Array(relays.keys).sorted())) {
|
NavigationLink(destination: UserRelaysView(state: damus_state, relays: Array(relays.keys).sorted())) {
|
||||||
relay_text
|
relay_text
|
||||||
}
|
}
|
||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
@@ -450,10 +429,10 @@ struct ProfileView: View {
|
|||||||
.background(colorScheme == .dark ? Color.black : Color.white)
|
.background(colorScheme == .dark ? Color.black : Color.white)
|
||||||
|
|
||||||
if filter_state == FilterState.posts {
|
if filter_state == FilterState.posts {
|
||||||
InnerTimelineView(events: profile.events, damus: damus_state, show_friend_icon: false, filter: FilterState.posts.filter)
|
InnerTimelineView(events: profile.events, damus: damus_state, filter: FilterState.posts.filter)
|
||||||
}
|
}
|
||||||
if filter_state == FilterState.posts_and_replies {
|
if filter_state == FilterState.posts_and_replies {
|
||||||
InnerTimelineView(events: profile.events, damus: damus_state, show_friend_icon: false, filter: FilterState.posts_and_replies.filter)
|
InnerTimelineView(events: profile.events, damus: damus_state, filter: FilterState.posts_and_replies.filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal, Theme.safeAreaInsets?.left)
|
.padding(.horizontal, Theme.safeAreaInsets?.left)
|
||||||
|
|||||||
@@ -7,27 +7,6 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct PubkeyView: View {
|
|
||||||
let pubkey: String
|
|
||||||
let relay: String?
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
let color: Color = id_to_color(pubkey)
|
|
||||||
ZStack {
|
|
||||||
Text(verbatim: abbrev_pubkey(pubkey))
|
|
||||||
.foregroundColor(color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func abbrev_pubkey(_ pubkey: String, amount: Int = 8) -> String {
|
func abbrev_pubkey(_ pubkey: String, amount: Int = 8) -> String {
|
||||||
return pubkey.prefix(amount) + ":" + pubkey.suffix(amount)
|
return pubkey.prefix(amount) + ":" + pubkey.suffix(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
struct PubkeyView_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
|
||||||
PubkeyView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ struct QRCodeView: View {
|
|||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
@State var pubkey: String
|
@State var pubkey: String
|
||||||
|
|
||||||
@Environment(\.dismiss) var dismiss
|
|
||||||
@Environment(\.presentationMode) var presentationMode
|
@Environment(\.presentationMode) var presentationMode
|
||||||
|
|
||||||
var maybe_key: String? {
|
var maybe_key: String? {
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ struct RelayDetailView: View {
|
|||||||
let relay: String
|
let relay: String
|
||||||
let nip11: RelayMetadata
|
let nip11: RelayMetadata
|
||||||
|
|
||||||
@State private var errorString: String?
|
|
||||||
|
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
||||||
func check_connection() -> Bool {
|
func check_connection() -> Bool {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import Security
|
|||||||
struct SaveKeysView: View {
|
struct SaveKeysView: View {
|
||||||
let account: CreateAccountModel
|
let account: CreateAccountModel
|
||||||
let pool: RelayPool = RelayPool()
|
let pool: RelayPool = RelayPool()
|
||||||
@State var is_done: Bool = false
|
|
||||||
@State var pub_copied: Bool = false
|
@State var pub_copied: Bool = false
|
||||||
@State var priv_copied: Bool = false
|
@State var priv_copied: Bool = false
|
||||||
@State var loading: Bool = false
|
@State var loading: Bool = false
|
||||||
|
|||||||
@@ -27,14 +27,6 @@ struct SearchingEventView: View {
|
|||||||
|
|
||||||
@State var search_state: SearchState = .searching
|
@State var search_state: SearchState = .searching
|
||||||
|
|
||||||
var bech32_evid: String {
|
|
||||||
guard let bytes = hex_decode(evid) else {
|
|
||||||
return evid
|
|
||||||
}
|
|
||||||
let noteid = bech32_encode(hrp: "note", bytes)
|
|
||||||
return abbrev_pubkey(noteid)
|
|
||||||
}
|
|
||||||
|
|
||||||
var search_name: String {
|
var search_name: String {
|
||||||
switch search_type {
|
switch search_type {
|
||||||
case .nip05:
|
case .nip05:
|
||||||
@@ -142,12 +134,3 @@ struct SearchingEventView_Previews: PreviewProvider {
|
|||||||
SearchingEventView(state: state, evid: test_event.id, search_type: .event)
|
SearchingEventView(state: state, evid: test_event.id, search_type: .event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum EventSearchState {
|
|
||||||
case searching
|
|
||||||
case not_found
|
|
||||||
case found(NostrEvent)
|
|
||||||
case found_profile(String)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,19 +34,6 @@ enum Search: Identifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnySearchResultsView: View {
|
|
||||||
let damus_state: DamusState
|
|
||||||
let searches: [Search]
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
VStack {
|
|
||||||
ForEach(searches) { r in
|
|
||||||
InnerSearchResults(damus_state: damus_state, search: r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct InnerSearchResults: View {
|
struct InnerSearchResults: View {
|
||||||
let damus_state: DamusState
|
let damus_state: DamusState
|
||||||
let search: Search?
|
let search: Search?
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ struct SelectWalletView: View {
|
|||||||
@Binding var showingSelectWallet: Bool
|
@Binding var showingSelectWallet: Bool
|
||||||
let our_pubkey: String
|
let our_pubkey: String
|
||||||
let invoice: String
|
let invoice: String
|
||||||
@Environment(\.openURL) private var openURL
|
|
||||||
@State var invoice_copied: Bool = false
|
@State var invoice_copied: Bool = false
|
||||||
|
|
||||||
@State var allWalletModels: [Wallet.Model] = Wallet.allModels
|
@State var allWalletModels: [Wallet.Model] = Wallet.allModels
|
||||||
@@ -70,7 +69,6 @@ struct SelectWalletView: View {
|
|||||||
|
|
||||||
struct SelectWalletView_Previews: PreviewProvider {
|
struct SelectWalletView_Previews: PreviewProvider {
|
||||||
@State static var show: Bool = true
|
@State static var show: Bool = true
|
||||||
@State static var invoice: String = ""
|
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
SelectWalletView(default_wallet: .lnlink, showingSelectWallet: $show, our_pubkey: "", invoice: "")
|
SelectWalletView(default_wallet: .lnlink, showingSelectWallet: $show, our_pubkey: "", invoice: "")
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import SwiftUI
|
|||||||
struct TranslationSettingsView: View {
|
struct TranslationSettingsView: View {
|
||||||
@ObservedObject var settings: UserSettingsStore
|
@ObservedObject var settings: UserSettingsStore
|
||||||
|
|
||||||
@State var show_api_key: Bool = false
|
|
||||||
|
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|||||||
@@ -9,14 +9,12 @@ import SwiftUI
|
|||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
struct ZapSettingsView: View {
|
struct ZapSettingsView: View {
|
||||||
let pubkey: String
|
|
||||||
@ObservedObject var settings: UserSettingsStore
|
@ObservedObject var settings: UserSettingsStore
|
||||||
|
|
||||||
@State var default_zap_amount: String
|
@State var default_zap_amount: String
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
||||||
init(pubkey: String, settings: UserSettingsStore) {
|
init(settings: UserSettingsStore) {
|
||||||
self.pubkey = pubkey
|
|
||||||
_default_zap_amount = State(initialValue: settings.default_zap_amount.formatted())
|
_default_zap_amount = State(initialValue: settings.default_zap_amount.formatted())
|
||||||
self._settings = ObservedObject(initialValue: settings)
|
self._settings = ObservedObject(initialValue: settings)
|
||||||
}
|
}
|
||||||
@@ -75,6 +73,6 @@ struct ZapSettingsView: View {
|
|||||||
|
|
||||||
struct WalletSettingsView_Previews: PreviewProvider {
|
struct WalletSettingsView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ZapSettingsView(pubkey: "pubkey", settings: UserSettingsStore())
|
ZapSettingsView(settings: UserSettingsStore())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ struct ThreadView: View {
|
|||||||
selected: false)
|
selected: false)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
thread.set_active_event(parent_event, privkey: state.keypair.privkey)
|
thread.set_active_event(parent_event)
|
||||||
scroll_to_event(scroller: reader, id: parent_event.id, delay: 0.1, animate: false)
|
scroll_to_event(scroller: reader, id: parent_event.id, delay: 0.1, animate: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ struct ThreadView: View {
|
|||||||
)
|
)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
thread.set_active_event(child_event, privkey: state.keypair.privkey)
|
thread.set_active_event(child_event)
|
||||||
scroll_to_event(scroller: reader, id: child_event.id, delay: 0.1, animate: false)
|
scroll_to_event(scroller: reader, id: child_event.id, delay: 0.1, animate: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user