Compare commits

...

325 Commits

Author SHA1 Message Date
tyiu ae81575386 Add Reposts view 2023-01-24 21:42:25 -05:00
Swift 209a1c3213 Create stretchable profile cover header
Closes: #250
Changelog-Added: Stretchable profile cover header
2023-01-23 12:33:30 -08:00
William Casarin 675903b768 SelectedEventView: use EventProfile 2023-01-23 12:30:29 -08:00
William Casarin 92035e17d3 refactor: move reply_desc to ReplyDescription 2023-01-23 12:20:02 -08:00
William Casarin 8df5bf04ae refactor: Break EventView into 3 separate views
SelectedEventView
EmbeddedEventView
EventView
2023-01-23 12:13:58 -08:00
William Casarin 7e1daf7816 refactor: move Highlight to its own file 2023-01-23 10:58:39 -08:00
William Casarin 0ead583bda refactor: move BuilderEventView to it's own file 2023-01-23 10:58:39 -08:00
William Casarin dd44bd779b EventView: hide extra previews
Getting too busy
2023-01-23 10:58:39 -08:00
William Casarin c31374fc0a build 9 2023-01-23 10:28:36 -08:00
William Casarin f3730630b5 Merge tyiu/string-fixes, transifex/de_AT, transifex/de_DE
More translation stuff from Terry
2023-01-22 19:36:51 -08:00
tyiu d5f2a17249 Import localization for de-AT 2023-01-22 21:57:47 -05:00
tyiu 4526ed01fe Import localization for de-DE 2023-01-22 21:56:35 -05:00
transifex-integration[bot] a590fb099d Apply translations in de_AT
translated for the source file '/damus Localizations/en-US.xcloc/Localized Contents/en-US.xliff'
on the 'de_AT' language.
2023-01-23 02:54:31 +00:00
transifex-integration[bot] 135814737c Apply translations in de_DE
translated for the source file '/damus Localizations/en-US.xcloc/Localized Contents/en-US.xliff'
on the 'de_DE' language.
2023-01-23 02:54:20 +00:00
tyiu e2e60639d9 Remove unused language mapping from transifex.yml 2023-01-22 21:53:30 -05:00
tyiu 83909c8fc9 Change use of DM to be consistent and add missing localization comments 2023-01-22 21:50:28 -05:00
William Casarin 3e4914462b EventDetailBar disappeared. Let's fix that before (8) 2023-01-22 10:37:33 -08:00
William Casarin 7a11433a98 v1.0.0-8 changelog 2023-01-22 10:28:51 -08:00
William Casarin 03e1c1903f v1.0.0-8 2023-01-22 10:27:35 -08:00
William Casarin acdee6a326 Show Website on profiles
Changelog-Added: Show website on profiles
2023-01-22 10:25:12 -08:00
William Casarin f5e03f145c Fix build 2023-01-22 10:10:54 -08:00
Joel Klabo 2a9ddd10c8 Choose Participants on a Thread Reply
Closes: #345
Changelog-Added: Add the ability to choose participants when replying
2023-01-22 10:10:13 -08:00
tyiu 5e9580377d Fix localized string for privacy access description for photos
Closes: #359
2023-01-22 10:00:09 -08:00
William Casarin 9d2ff2fe65 Fix commas and emojis getting included in hashtags
Changelog-Fixed: Fix commands and emojis getting included in hashtags
2023-01-22 09:57:00 -08:00
Joel Klabo 13ea42a2e2 Don't Parse URL with Only Whitespace 2023-01-22 09:49:41 -08:00
William Casarin d9e22ce7bf Add translations for de_AT, de_DE, tr_TR, fr_FR
Changelog-Added: Translations for de_AT, de_DE, tr_TR, fr_FR
2023-01-22 09:43:51 -08:00
William Casarin 2335a65b78 Merge remote-tracking branch 'github/translations_damus-localizations-en-us-xcloc-localized-contents-en-us-xliff--master_fr_FR' 2023-01-22 09:42:57 -08:00
William Casarin 566cd141ce Merge remote-tracking branch 'github/translations_damus-localizations-en-us-xcloc-localized-contents-en-us-xliff--master_tr_TR' 2023-01-22 09:42:06 -08:00
William Casarin 55f7f8c072 Merge remote-tracking branch 'github/translations_damus-localizations-en-us-xcloc-localized-contents-en-us-xliff--master_de_DE' 2023-01-22 09:40:46 -08:00
William Casarin 4b4addd215 Merge remote-tracking branch 'github/translations_damus-localizations-en-us-xcloc-localized-contents-en-us-xliff--master_de_AT' 2023-01-22 09:39:51 -08:00
Joel Klabo 255a0c55ba Update CI Specify Xcode Version
Closes: #360
2023-01-22 09:26:29 -08:00
Thomas Rademaker ced6e2488f Fix duplicate post buttons when swiping tabs
Move the postButtonContainer view to avoid having 2 buttons on screen when swiping tabs

Closes: #366
Changelog-Fixed: Fix duplicate post buttons when swiping tabs
2023-01-22 09:25:16 -08:00
Thomas Rademaker 77c2abc524 fix broken test 2023-01-22 09:25:16 -08:00
Joel Klabo e4ad15ced1 Center PFP in Zoom View
Closes: #357
Changlog-Fixed: Center profile picture in zoom view
2023-01-22 09:23:11 -08:00
Joel Klabo 904a6e960a Cleanup X Padding and Size 2023-01-22 09:23:11 -08:00
tyiu da8a82954a Import localization for fr-FR 2023-01-21 20:59:57 -05:00
tyiu 383f45fe96 Import localization for de-DE 2023-01-21 20:58:21 -05:00
tyiu 9dc0f3baf6 Import localization for de-AT 2023-01-21 20:57:34 -05:00
tyiu abc857582f Import localization for tr-TR 2023-01-21 20:54:33 -05:00
transifex-integration[bot] 4816b57dcd Apply translations in de_AT
translation completed for the source file '/damus Localizations/en-US.xcloc/Localized Contents/en-US.xliff'
on the 'de_AT' language.
2023-01-21 23:34:52 +00:00
transifex-integration[bot] 06b1953b49 Apply translations in de_DE
translation completed for the source file '/damus Localizations/en-US.xcloc/Localized Contents/en-US.xliff'
on the 'de_DE' language.
2023-01-21 23:33:33 +00:00
William Casarin d658d1d987 DM Message Requests
Put strangers in a different tab

Changelog-Added: Add DM Message Requests
2023-01-21 11:13:44 -08:00
William Casarin e14cd99c85 Add first_eref_mention helper to refactor embedded builder 2023-01-21 10:29:40 -08:00
William Casarin 0258ef792f Show embedded note references
This reverts commit 3f3b78f9bc.

Changelog-Fixed: Show embedded note references
2023-01-21 09:57:29 -08:00
transifex-integration[bot] 52524e00a2 Apply translations in tr_TR
translation completed for the source file '/damus Localizations/en-US.xcloc/Localized Contents/en-US.xliff'
on the 'tr_TR' language.
2023-01-21 09:10:29 +00:00
transifex-integration[bot] 342883fbb0 Apply translations in fr_FR
translation completed for the source file '/damus Localizations/en-US.xcloc/Localized Contents/en-US.xliff'
on the 'fr_FR' language.
2023-01-20 22:00:04 +00:00
William Casarin 1e6505abe3 v1.0.0-7 changelog 2023-01-20 09:35:51 -08:00
OlegAba 98c24147e8 Drastically improve image viewer
Changelog-Added: Drastically improved image viewer
Closes: #349
2023-01-20 09:33:22 -08:00
Joel Klabo d1e7de5dcb Add Preview with 999 Everything 2023-01-20 09:23:42 -08:00
Joel Klabo 11e0a87f06 Fix ... when too many likes/reposts
Closes: #351
Changelog-Fixed: Fix ... when too many likes/reposts
2023-01-20 09:23:14 -08:00
Swift 1154cec719 Avoid showing reboost alert for pubkey user
Closes: #337
Changelog-Fixed: Don't show report alert if logged in as a pubkey
2023-01-19 10:10:07 -08:00
Joel Klabo 1ecfb0487e Swipe to Dismiss Images
Closes: #343
2023-01-18 13:36:57 -08:00
Swift 8ffa8446b6 Image Pinch Zooming
Changelog-Added: Added pinch to zoom on images
2023-01-18 10:10:22 -08:00
Ben Weeks fb1f99e728 Fixed Jack's issue with homepage gap at the top.
Closes: #328
Changelog-Fixed: Fix padding issue at top of home timeline
2023-01-18 09:59:26 -08:00
Zach Hendel 031408dec3 Makes both name and @username clickable to go to profile
Changelog-Changed: Makes both name and username clickable in sidebar to go to profile
Closes: #329
2023-01-18 09:54:18 -08:00
Zach Hendel 16b6d029fa Icons for hardclick menu event view
changes copy user id icon to person
changes copy note id icon to note.text
changes copy note json icon to magnifying glass

Closes: #330
2023-01-18 09:48:58 -08:00
Brandon Holm 3e093e8572 Added Blixt Wallet TestFlight link
Closes: #331
2023-01-18 09:48:49 -08:00
John Bethancourt fa11af4b1d Prevent absurdly large sidebar on Mac or iPad
Closes: #338
Changelog-Fixed: Fix absurdly large sidebar on Mac/iPad
2023-01-18 09:39:35 -08:00
William Casarin 91159d70ca Merge remote-tracking branch 'github/translations_damus-localizations-en-us-xcloc-localized-contents-en-us-xliff--master_es_419'
Changelog-Added: Add Latin American Spanish translations
2023-01-18 09:30:53 -08:00
OlegAba a57d654f32 Fix tab views moving after selecting from search result
Closes: #339
Changelog-Fixed: Fix tab views moving after selecting from search result
2023-01-18 09:29:30 -08:00
OlegAba 0313480685 Change navigation title to bold
Closes: #341
2023-01-18 09:29:04 -08:00
OlegAba e07b31e0a1 Consistent follow/unfollow button width
Changelog-Fixed: Make follow/unfollow button a consistent width
2023-01-18 09:28:29 -08:00
tyiu 538a0ae5ea Import es-419 localization files 2023-01-16 20:44:41 -05:00
tyiu 0f82db2440 Delete unused exported es-419 localization 2023-01-16 20:44:11 -05:00
transifex-integration[bot] 92ae2c7754 Apply translations in es_419
translation completed for the source file '/damus Localizations/en-US.xcloc/Localized Contents/en-US.xliff'
on the 'es_419' language.
2023-01-16 16:59:06 +00:00
William Casarin 00c819140b Don't include garbage in notifications
Check to make sure we have our pubkey on events coming into
notifications. Sometimes relays are buggy.

Changelog-Fixed: Don't add events to notifications from buggy relays
2023-01-15 12:53:37 -08:00
OlegAba cbc3c46c9d Fix image crash and support SVG profile pictures
Closes: #310
Changelog-Fixed: Fixed some crashes with large images
Changelog-Added: Added SVG profile picture support
2023-01-14 19:30:54 -08:00
radixrat 4b5c34b4e2 Click pfp in side menu should open profile as well
Closes: #323
Changelog-Changed: Clicking pfp in sidebar opens profile as well
2023-01-14 18:49:36 -08:00
ericholguin 9eb39f7e0a Don't blur images if your friend boosted it
Closes: #322
Changelog-Changed: Don't blur images if your friend boosted it
2023-01-14 18:47:45 -08:00
tyiu 173b22b772 localization: fix string bugs
Closes: #321
2023-01-14 18:44:11 -08:00
William Casarin 18c7cba53c Minor refactor 2023-01-14 17:24:03 -08:00
William Casarin 9a40fd595d Add some DM sorting tests
They didn't help me fix the problem, but maybe they are still useful
somehow
2023-01-14 17:23:35 -08:00
William Casarin a71c35a6b0 Fix DM sorting bug
Changelog-Fixed: Fix DM sorting on incoming messages
2023-01-14 17:21:44 -08:00
William Casarin d69d3cc74e create_dm: allow created_at argument
This is mainly used by tests
2023-01-14 16:28:18 -08:00
William Casarin 6e220ac4c1 dms: extract incoming DM handling into pure functions
So that it will be easier to test
2023-01-14 09:48:31 -08:00
William Casarin bcb40a6ec7 Fix text getting truncated next to link previews
Changelog-Fixed: Fix text getting truncated next to link previews
2023-01-14 09:30:22 -08:00
Swift 2f1063b49f Resolve issue on Roboash not appearing in sidebar pfp
Also works fine with users with profile pic url set

Closes: #315
2023-01-14 09:00:59 -08:00
Swift 73110952e5 Avoid showing wrong alert message for pubkey login user. 2023-01-14 08:58:27 -08:00
tyiu d01e7c0595 Fix localization bugs and export localizations
Changelog-Fixes: Fix some localization bugs
Closes: #320
2023-01-14 08:54:43 -08:00
William Casarin 4f9cef541b v1.0.0-6 changelog 2023-01-13 11:30:20 -08:00
William Casarin 2dfbc4b57e v1.0.0-6 2023-01-13 11:29:06 -08:00
William Casarin b9750dab77 Rename Boost to Repost 2023-01-13 10:18:03 -08:00
William Casarin d59331bc3c Only show EventDetailBar if we have tips/likes/reposts 2023-01-13 10:17:12 -08:00
Jason Jōb abd5856f21 Fix bug where all banner images showed as the current users
Fixes: #313
2023-01-13 09:20:51 -08:00
Joel Klabo 42a475bd72 Purple Shaka icon
Changelog-Changed: Make Shaka button purple when liked
2023-01-12 11:50:57 -08:00
William Casarin 65c1325935 Add some eventbar previews 2023-01-12 11:48:06 -08:00
Joel Klabo db64a73f87 Shaka button improvements
Changelog-Changed: Move counts to right side like Birdsite
Changelog-Changed: Use custom icon for shaka button
Changelog-Fixed: Fixed shaka moving when you press it
2023-01-12 11:40:54 -08:00
Jason Jōb 9d44ed0bfe Profile Banner Images
Changelog-Added: Profile banner images
Closes: #302
2023-01-12 10:51:32 -08:00
William Casarin 33383265c8 Fix horrible reactions view bug 2023-01-12 09:40:28 -08:00
Joel Klabo 76d1ee34d8 Add CI Testing
Closes: #304
2023-01-12 09:32:18 -08:00
punterwantsawhalepass 3b0a84bd43 Update README.md
Closes: #305
2023-01-12 09:32:18 -08:00
William Casarin 5a1daebeca Revert "feat(ci): Publish PR notifications to Nostr"
This reverts commit aee29f145a.
2023-01-12 09:32:18 -08:00
tyiu 08666ff90d Fix spacing on transifex.yml
Closes: #307
2023-01-12 09:32:18 -08:00
William Casarin b2b790a969 Reactions View
Changelog-Added: Added Reactions View
2023-01-11 16:13:09 -08:00
William Casarin 907f0d236f Rename boost to repost and removed nip05 domain from them
Changelog-Changed: Renamed boost to repost
Changelog-Changed: Removed nip05 domain from boosts/reposts
2023-01-11 14:49:14 -08:00
William Casarin 4b8f536a9b Refactor NIP05 badge into its own view
Also only make it clickable in profile view
2023-01-11 14:48:35 -08:00
Joel Klabo c76f92c6ed Move Counts to Right Side Like Twitter 2023-01-10 19:36:25 -08:00
Joel Klabo a165f4281c Use Overlay for Label to Prevent Views Moving 2023-01-10 18:51:22 -08:00
Joel Klabo 5dbf8029da Update Shaka Assets and Use for EventActionBar 2023-01-10 18:51:20 -08:00
Joel Klabo b1885700ca Use A Disabled Version of Shaka to Prevent Size Change 2023-01-10 18:50:15 -08:00
Joel Klabo 9e5209b48d Hide the NIP-05 Domain in Follow List
Changelog-Chaged: Hide the NIP-05 Domain in Follow List
Closes: #267
2023-01-10 11:09:44 -08:00
William Casarin 6bcea13d5a minor cleanup from merge 2023-01-10 10:20:42 -08:00
William Casarin 9944a7bf2a sidebar: rename App settings to Settings
Also localize
2023-01-10 10:20:42 -08:00
Darrell 424fb55343 remove unused packages
Shimmer package was added to package dependencies in #56 but Shimmer.swift in Components was used instead.
2023-01-10 10:11:54 -08:00
Paul 901931443f Update README.md
The backticks around the code  markdown example need escaped with two backticks and a space.
2023-01-10 10:11:32 -08:00
Ben Weeks 40d11ad680 Add a Sidebar
Changlog-Added: Sidebar
Closes: #273
2023-01-10 10:08:20 -08:00
Jonathan Milligan 4d8088d0d0 feat: Add left handed option for post button
Added a left handed toggle in the app configuration section to turn on
left handed mode which moves the post button to the left side. Nearly
done. May just need to fix an initialization bug.

Closes: #282
Changelog-Added: Left hand option for post button
2023-01-10 09:46:23 -08:00
bndw aee29f145a feat(ci): Publish PR notifications to Nostr
Sends pull request notifications to Nostr using Github Workflows and
noscl.

Closes: #297
2023-01-10 09:24:19 -08:00
Jonathan Milligan c9463804a8 style: DMs only take up 80% of screen width
DMs now take up only 80% of the available screen width so it looks much
more like iMessages.

Closes: #286
Changelog-Changed: Make DMs only take up 80% of screen width
2023-01-10 09:24:19 -08:00
Ben Weeks dccaf35410 Uses damus image on the homepage
Closes: #291
Changelog-Added: Damus icon at the top
2023-01-10 09:24:18 -08:00
Joel Klabo 45e64dc42c Hide Recommended Relays Section if Empty
Closes: #293
Changelog-Changed: Hide Recommended Relays Section if Empty
2023-01-10 09:23:44 -08:00
OlegAba 5a32a384c4 Add fallback image url to profile pic view
Closes: #294
Changlog-Changed: Add fallback image url to profile pic view
2023-01-10 09:22:57 -08:00
Fredrik Olofsson 35ae69740a Get event after Add button is pressed to make sure it is up to date.
Closes: #296
Changelog-Fixed: Fixed issue with relays not keeping in sync when adding
2023-01-10 09:22:55 -08:00
Joel Klabo 43cc3b6b6b Make NIP-05 Domain Tappable
Closes: #275
Changelog-Added: Make purple badges on profile page tappable
2023-01-10 09:22:20 -08:00
tyiu b367382aae Export localizations and add Transifex config 2023-01-08 22:01:06 -05:00
tyiu bf1866056c Change development locale to en-US and add es-419 as a target locale 2023-01-08 21:57:38 -05:00
tyiu 016dfa54f3 Internationalize amount formatting for sats 2023-01-08 21:57:38 -05:00
tyiu 887eb902bf Add comments to localized strings 2023-01-08 21:57:28 -05:00
Ben Weeks 966f330317 Added hidden dummy code for future options. 2023-01-08 23:32:35 +00:00
Ben Weeks cb54ac0494 Updated sidebar to close when tab items at the bottom are clicked too. 2023-01-08 01:00:35 +00:00
Ben Weeks fac1911524 Undid change to navigation appearing above the tabView as unfortunately has consequence hadn't spotted of the tab view dropping from profile page and settings page. 2023-01-08 00:38:02 +00:00
tyiu dcf328e7ac Fix localization bugs 2023-01-07 19:36:15 -05:00
Ben Weeks 38211a74f5 Moved the sidebar to above the tab buttons. 2023-01-08 00:26:35 +00:00
Ben Weeks 9b236f9583 Changed opacity to Damus on-brand grey. Removed unnecessary code. 2023-01-08 00:20:43 +00:00
Ben Weeks 4378397c4c Fixed animation. Made menu a touch smaller. 2023-01-07 23:59:35 +00:00
Ben Weeks 392281ca40 Removed unnecessary code. 2023-01-07 23:33:57 +00:00
Ben Weeks 3bf39dc04b Fixed overlay issue (now has faded background) 2023-01-07 23:29:22 +00:00
Ben Weeks 8161d55d05 Updated colors and swapped icons. 2023-01-07 22:31:45 +00:00
Ben Weeks 30151e14fa Merge branch 'damus-io:master' into sidebar 2023-01-07 22:15:11 +00:00
Ben Weeks c6ca0a058e Updated text color to white and swapped icons round 2023-01-07 22:13:44 +00:00
William Casarin c10fcc52e3 dms: always use the other persons pubkey in context menu
The DM view can sometimes show our last message, which means the pubkey
in the context menu would be ours. This is super confusing, so always
use the other persons pubkey when copying the user id in the DMs view.

Changlog-Fixed: Always copy other persons pubkey in DMs context menus
2023-01-07 11:29:24 -08:00
OlegAba 08dd2d5414 Fix picker bug and refactored 2023-01-07 10:22:39 -08:00
Ben Weeks d9b60c0052 Merge branch 'damus-io:master' into sidebar 2023-01-06 23:06:44 +00:00
Ben Weeks fba29d4454 Worked on amending the colors. 2023-01-06 22:41:48 +00:00
William Casarin 421245a2f8 v1.0.0 (5) Changelog 2023-01-06 14:21:23 -08:00
William Casarin ec4790a8fe v1.0.0 (5) 2023-01-06 14:19:23 -08:00
OlegAba 5f22a7691f Fix TabView loading new view on scroll 2023-01-06 14:16:29 -08:00
OlegAba d878ff6fdb Add system background color to profile pics
Changelog-Fixed: Add system background color to profile pics
Closes: #270
2023-01-06 14:14:57 -08:00
William Casarin 7081c4ac69 Profile: make key high-res and reintroduce key color
Changelog-Fixed: High res color pubkey on profile page
2023-01-06 14:09:41 -08:00
William Casarin b03bef2f8b Profile: Add Universal Link share button
Changelog-Added: Added share button to profile
2023-01-06 14:01:57 -08:00
Ben Weeks 5733f782d9 Latest updates to the sidebar. 2023-01-06 20:11:19 +00:00
William Casarin a153515366 Fix compilation 2023-01-06 10:41:56 -08:00
William Casarin d5857325b1 Universal Links: share notes!
Changelog-Added: Added universal link sharing of notes
2023-01-06 10:24:08 -08:00
William Casarin 04e4bc7985 ocd refactor in load_profiles 2023-01-06 10:23:39 -08:00
William Casarin e7d32d9ea7 pool: queue requests if we're disconnected
Changelog-Fixed: Don't spin forever if we're temporarily disconnected
2023-01-06 10:18:31 -08:00
aki-mizu 442a50f9ae update markdown format guides in Formatting Notes
In iOS for strikethrough only one tilde symbol is needed before and after words

Closes: #269
2023-01-06 05:30:30 -08:00
Ben Weeks aba758b143 Fixes damus-io/damus#246 ChangeLog-Changed: Resolved issue with image URLs in uppercase (@npub1jutptdc2m8kgjmudtws095qk2tcale0eemvp4j2xnjnl4nh6669slrf04x) 2023-01-06 00:39:57 +00:00
Ben Weeks b7c7b0b3bf Merge branch 'damus-io:master' into beautify-image-zoom 2023-01-06 00:25:15 +00:00
Ben Weeks 2d10d4592b Fixes damus-io/damus#254 Changes background to Color("DamusDarkGrey") ChangeLog-Changed: Allowed pinch and zoom on profile picture (scoder1747) ChangeLog-Changed: Allowed pinch and zoom to post pictures (@npub1jutptdc2m8kgjmudtws095qk2tcale0eemvp4j2xnjnl4nh6669slrf04x) 2023-01-06 00:16:48 +00:00
Joel Klabo 9f8379cb1e Fix Unassigned Child Image Asset Errors
Closes: #256
2023-01-05 16:11:31 -08:00
Ben Weeks d0eb632ce6 PostButton: Very minor tweak to make it look more natural
Closes: #259
2023-01-05 16:08:00 -08:00
OlegAba cd62418dda Add clear image cache button in settings
Closes: #260
Changelog-Added: Added clear cache button to wipe pfp/image cache
2023-01-05 16:06:05 -08:00
OlegAba ba32d15a49 Refactor large image processor
Changelog-Fixed: Fixed a few issues with avatars not animating
2023-01-05 16:05:01 -08:00
Joel Klabo b688fa98a5 Allow Adding Relay Without wss:// Prefix
Closes: #261
Changelog-Added: Allow Adding Relay Without wss:// Prefix
2023-01-05 16:03:14 -08:00
Joel Klabo 61a451184b Allow Saving Images to Library
Closes: #255
Changelog-Added: Allow Saving Images to Library
2023-01-05 13:12:19 -08:00
Aidan O'Loan 96741af97b Scroll to bottom when new DM received
Closes: #242
Closes: #241
Changelog-Fixed: Scroll to bottom when new DM received
2023-01-05 10:51:42 -08:00
Ben Weeks 553dcb785c Updated the new post button with gradient fill.
Changelog-Changed: Added damus gradient to post button
Closes: #244
2023-01-05 10:42:31 -08:00
Thomas 22008aeabc Center the Post Button
Closes: #245
Changelog-Changed: Center the Post Button
2023-01-05 10:31:29 -08:00
Joel Klabo 64bb28e017 Make Event in Reply View Scrollable
Closes: #248
Changelog-Fixed: Make reply view scrollable
2023-01-05 09:20:49 -08:00
Swift c58c349053 Hide profile edit button for pubkey user
Closes: #249
Changelog-Fixed: Hide profile edit button when logged in with pubkey
2023-01-05 09:19:25 -08:00
William Casarin 4d358415bd nip05: switch yellowcheck to graycheck
Changelog-Changed: Switch yellow nip05 check to gray
2023-01-04 10:16:35 -08:00
William Casarin 5ba5a68628 Switch from bluecheck to purplecheck
This commit also refactors a bunch of crap

Changelog-Changed: Switch from bluecheck to purplecheck
2023-01-04 10:06:19 -08:00
William Casarin 89c857d3e9 v1.0.0-4 changelog 2023-01-04 02:04:00 -08:00
William Casarin 4d3a3184b4 nip05: make hosts searchable 2023-01-04 02:01:57 -08:00
William Casarin 71b1a9d14f nip05: never show full host in event profile names 2023-01-04 02:01:43 -08:00
William Casarin 8785f31834 NIP05 Verification
Changelog-Added: Added NIP05 Verification
2023-01-04 01:30:37 -08:00
William Casarin 104205394f nip05: move nip05 parsing to struct
Going to use this when checking the nip05 identifier
2023-01-04 00:07:08 -08:00
William Casarin 6593c9456d profile: show white circle on buttons in dark mode 2023-01-03 23:49:02 -08:00
William Casarin 186954195d profile: tweak button positioning 2023-01-03 23:42:01 -08:00
William Casarin dba31a9d33 profile: remove redundant pfp border circle 2023-01-03 23:42:01 -08:00
Jonathan Milligan a69fb5306c style: Make the post button purple
Since everything on damus is now purple to match the purple ostrich
mascot I made the background of the post button purple.
2023-01-03 23:42:01 -08:00
William Casarin fb1bcdd31f Revert to old style ln/dm buttons
Until we have high-res icons

Changelog-Changed: Revert to old style ln/dm buttons
2023-01-03 23:42:01 -08:00
William Casarin 2ccc7e9a30 Build 4 2023-01-03 23:08:38 -08:00
Lionello Lunesu e9380c3821 Fix ascii shrug guy
Changelog-Fixed: Fix ascii shrug guy
Closes: #238
2023-01-03 23:05:41 -08:00
OlegAba 39fa973a80 Add KingFisher downsampler processor for large images
Changelog-Added: Downscale images if they are unreasonably large
Closes: #240
2023-01-03 23:04:08 -08:00
William Casarin b70ce53b88 navigation: fix navigation popping issues in threads
Changelog-Fixed: Fix navigation popping in threads
2023-01-03 23:00:22 -08:00
William Casarin 16e3c4e1cf Fix crash with link previews
Changelog-Fixed: Fixed crash with link previews
2023-01-03 11:42:23 -08:00
William Casarin b3b8a708f3 v1.0.0-2 changelog 2023-01-03 11:18:48 -08:00
William Casarin d89e3d32f8 v1.0.0-2 2023-01-03 11:16:41 -08:00
William Casarin b99e9b9acc use muted shaka in EventActionBar 2023-01-03 11:15:10 -08:00
William Casarin 61974ca696 rename nostr-hello to shaka 2023-01-03 11:15:02 -08:00
Lionello Lunesu 42f484bc64 Fix detection of email addresses in profiles
Signed-off-by: Lionello Lunesu <lio+git@lunesu.com>
Changelog-Fixed: Fix detection of email addresses in profiles
Closes: #225
2023-01-03 10:55:25 -08:00
OlegAba 43c6084620 Fix padding on search results view
Changelog-Fixed: Fix padding on search results view
Closes: #232
2023-01-03 10:55:25 -08:00
CutClout 501412e75c Add muted shaka images
Uploading four variations of "🤙" images:
black outline
white outline
solid black
solid white

In three different sizes:
20x20, @2x, and at @3x

Added contents.json imageset file

*They are only the images, I have not changed any code within the app.

Would you please add the images where they are needed? or point me in the right direction? I have much yet to learn.

I hope these are the versions you need. If there are any adjustments, please let me know.

Changelog-Changed: Added muted shaka images instead of thumbs up
Closes: #226
2023-01-03 10:55:25 -08:00
OlegAba 5789cc0097 Fix home view moving after selecting from search result
Changelog-Fixed: Fix home view moving after selecting from search result
Closes: #233
2023-01-03 10:55:25 -08:00
William Casarin d4995aa4bf Tweaks to the new profile page 2023-01-02 19:30:27 -08:00
Ben Weeks 57dbb6a487 Updated the profile look and feel
Closes: #203
Changelog-Changed: Updated profile page look and feel
2023-01-02 19:30:18 -08:00
Joel Klabo 7f71ddce1d Move Relay Add Button to Section Header 2023-01-02 19:06:18 -08:00
William Casarin abf736ec2a Fix bug where boost event is loaded in the thread instead of the boosted event
Changelog-Fixed: Fix bug where boost event is loaded in the thread instead of the boosted event
2023-01-02 18:58:23 -08:00
Nitesh Balusu 2cfcc82b2d Filter out replies from global feed
Closes: #173
Changelog-Changed: Filter replies from global feed
2023-01-02 18:58:23 -08:00
William Casarin aaa21bf1bf misc refactors 2023-01-02 18:58:23 -08:00
William Casarin ba03be5b91 refactor handle_event in SearchHomeModel 2023-01-02 18:58:23 -08:00
William Casarin 3f3b78f9bc EventView: remove weird embedded thing 2023-01-02 18:45:30 -08:00
Swift 2348f64dff Hide Edit Button on Profile Page for the user not logged in w/Private Key
Changelog-Fixed: Hide edit button on profile page when no private key
Closes: #215
2023-01-02 18:33:09 -08:00
tyiu 8428f0af43 Fix relative time test
Closes: #218
2023-01-02 18:30:56 -08:00
hewigovens 8c91ce3e10 Always check SecRandomCopyBytes return value
Closes: #223
2023-01-02 18:30:24 -08:00
William Casarin 5fd5593595 Revert "threadv2: Fix threads sometimes not loading on first click"
This reverts commit 2e99e5acaa.
2023-01-02 18:29:48 -08:00
William Casarin 2e99e5acaa threadv2: Fix threads sometimes not loading on first click
This makes the initial thread open a bit faster

Changelog-Fixed: Fix threads sometimes not loading on first click
2023-01-02 18:00:04 -08:00
William Casarin 0b7a600c67 perf: fix janky linkpreview animation 2023-01-02 15:25:48 -08:00
William Casarin bd5390fbc0 actually add PreviewCache oops 2023-01-02 15:23:13 -08:00
William Casarin 068099c5a7 perf: run more kingfisher stuff in the background 2023-01-02 15:19:57 -08:00
William Casarin 7372c4847d perf: cache link previews
Changelog-Added: Cache link previews
2023-01-02 15:19:57 -08:00
William Casarin b42f0ec5eb Show non-image link inline
Changelog-Changed: Show non-image links inline
2023-01-02 15:19:57 -08:00
William Casarin 0d2ab6aff3 NostrResponse: add sub_id helper
Handy to guard on this
2023-01-02 12:41:28 -08:00
William Casarin e3732b3adc Add filter helper to FilterState
Will be used in upcoming commits
2023-01-02 12:40:49 -08:00
William Casarin ed36a8c062 Add brb.io to recommended relay list
Changelog-Added: Added brb.io to recommended relay list
2023-01-02 08:44:54 -08:00
Thomas Rademaker 2f81a144c1 ContentTimelineView inside a page tabView to get a nice swipe gesture
Changelog-Changed: Add swipe gesture to switch between tabs
Closes: #202
2023-01-02 08:42:03 -08:00
William Casarin 4adb26e784 wallet: refactor a few things 2023-01-02 08:39:39 -08:00
Benjamin Hakes 707f31fca1 Add Blixt & River to Wallet Selector
Changelog-Added: Add Blixt Wallet to Wallet Selector
Changelog-Added: Add River Wallet to Wallet Selector
Closes: #206
2023-01-02 08:38:37 -08:00
tyiu 9e9077bab5 Internationalize all bundled user-facing strings
Enables localization to non-English locales in the future
2023-01-02 08:35:02 -08:00
@RandyMcMillan 7242c0bca3 target: decrement to 15.0
Closes: #207
2023-01-02 08:22:52 -08:00
tyiu badbd8a92e Fix flakey TimeAgo test by anchoring locale to en_US
Closes: #210
2023-01-02 08:22:17 -08:00
Lio李歐 aec61906ae Update CHANGELOG.md
Hey @jb55. I appreciate everything you’re doing for nostr but that
particular change was done by me. Not sure how come your name ended up
besides it. I was a bit bummed when I saw the latest changelog in
TestFlight.

Changelog-Changed: Parse links in profiles (Lionello Lunesu)
Closes: #208
2023-01-02 08:21:25 -08:00
tyiu 4f4557e4b6 Replace deprecated Data.withUnsafeMutableBytes call
Closes: #214
2023-01-02 08:19:47 -08:00
William Casarin 9c6b802f19 Fix follows and relays getting out of sync on profile pages
Fixes: #216
Changelog-Fixed: Fixed follows and relays getting out of sync on profile pages
2023-01-02 08:03:09 -08:00
William Casarin 4c7b8dc10b app category 2023-01-01 11:47:15 -08:00
William Casarin 202f6b1fb9 Update Changelog for App Store Release 2023-01-01 11:38:38 -08:00
William Casarin ab949db651 v1.0.0 2023-01-01 11:36:57 -08:00
William Casarin 2aaa58ada6 Fix relative date tests 2023-01-01 11:32:04 -08:00
William Casarin 5a956248f9 bolt11: fix bug where text not showing after invoice
Changelog-Fixed: Fix but where text was not showing after invoices
2023-01-01 11:31:36 -08:00
William Casarin cf615b82b2 bolt11: fix any amount invoices 2023-01-01 11:02:44 -08:00
William Casarin b65d9a49ff c: silence warnings 2023-01-01 10:30:40 -08:00
William Casarin 9666180db5 threadv2: refactor handle_event logic 2023-01-01 10:27:56 -08:00
William Casarin 3b81592ca2 Load profiles in DMs and notifications
Changelog-Fixed: Load profiles in DMs and notifications
2023-01-01 10:01:48 -08:00
William Casarin 696d341f79 DMs: maybe fix sorting bug
Changlog-Fixed: Potential fix for DM sorting issue
2023-01-01 09:40:32 -08:00
William Casarin 500845f619 likes: make the default like emoji more muted 2022-12-31 18:32:59 -08:00
William Casarin 977ae29949 Fix navigation popping in DM view 2022-12-31 18:10:29 -08:00
William Casarin 52b2407f49 Switch like from ❤️ to 🤙
Actually react with 🤙 at the protocol level as well

Changelog-Changed: Switch like from ❤️  to 🤙
2022-12-31 17:44:56 -08:00
Joel Klabo 9d181fea90 Remove Unused Variable Warning in convert_invoice_block 2022-12-31 16:54:10 -08:00
Joel Klabo 759ba398cc Fix Expanding Profile Picture (nosestr bug)
Changelog-Fixed: Fix expanding profile picture (nosestr bug)
2022-12-31 16:52:06 -08:00
William Casarin 6f5f86114b Parse links in profiles
Changelog-Added: Parse links in profiles
2022-12-31 13:03:52 -08:00
OlegAba d479f7a55a Fix padding on threads and search results view
Closes: #177
Changelog-Fixed: Fix padding on threads and search results views
2022-12-31 12:41:54 -08:00
Joel Klabo 79ea4da2d2 Don't Badge DMs if Sent By You
Closes: #176
Changelog-Fixed: Don't badge DMs if sent by you
2022-12-31 12:37:40 -08:00
Lee Salminen 4781795187 Add Breez & Bitcoin Beach wallets
Closes: #187
Changelog-Added: Added Breez wallet to wallet selector
Changelog-Added: Added Bitcoin Beach wallet to wallet selector
2022-12-31 12:34:52 -08:00
Matt Ward 2c15d22d86 Added copy relay action
Closes: #197
Changelog-Added: Added ability to copy relay urls
2022-12-31 12:33:55 -08:00
gladiusKatana 3d5a098423 SaveKeyView: add spacers to make Text frames invariant upon Copy-tap
Closes: #192
2022-12-31 10:02:40 -08:00
Joel Klabo d0e9e6c03a Reset Relay Add to Placeholder After Addding a Relay
Closes: #175
Changelog-Fixed: Reset relay in Add Relay view after adding
2022-12-31 09:47:29 -08:00
tyiu 0b27a49e32 Internationalize time ago since string
Switches to using standard date component formatting abbreviations and
enables it to be localized to non-English locales

Closes: #194
Changelog-Changed: Internationalize relative dates
2022-12-31 09:46:16 -08:00
Joel Klabo 58b4d57f32 Clean Up Unused Variable Warning in parse_mentions
Closes: #195
2022-12-31 09:45:00 -08:00
William Casarin 6e709058c0 wallet: refactor, make it work with ln tip button
Changelog-Added: Added option to choose default wallet
2022-12-31 09:41:10 -08:00
William Casarin 0384191060 Improved Wallet Selector 2022-12-30 12:41:11 -08:00
William Casarin 7bee8fd0d1 bump to build 12 2022-12-30 12:41:00 -08:00
Suhail Saqan 35fac4a1c3 Merge branch 'master' into improve-wallet-selector 2022-12-30 01:41:05 -06:00
Suhail Saqan dfbeda5e36 Revert "@bhakes: Bh updates to improve wallet selector" (#6) 2022-12-29 23:39:16 -08:00
Suhail Saqan f7b7254b42 Merge pull request #5 from suhailsaqan/revert-4-bh-updates-to-improve-wallet-selector
@bhakes: Bh updates to improve wallet selector
2022-12-30 01:32:01 -06:00
Suhail Saqan 403a22125a Revert "Bh updates to improve wallet selector" 2022-12-29 23:30:56 -08:00
Suhail Saqan 0bcabc8e08 Merge pull request #4 from bhakes/bh-updates-to-improve-wallet-selector
Bh updates to improve wallet selector
2022-12-30 01:27:40 -06:00
William Casarin 1b21a7a7b7 User relays view
Changelog-Added: Added relay list to user profiles
2022-12-29 16:55:36 -08:00
William Casarin 9e6e22fa2d v0.1.8-9 changelog 2022-12-29 16:18:07 -08:00
William Casarin 14a3a352d6 Recommended relay view
Changelog-Changed: Show recommended relays in config. Currently just a fixed set.
2022-12-29 16:08:00 -08:00
William Casarin 3824e95f29 relays: keep in sync with user relay list
Still need to figure out how to ensure new bootstrap relays are added...

Changelog-Changed: Ensure contact relay list is kept in sync with internal relay pool
2022-12-29 15:23:34 -08:00
Benjamin Hakes a2f5bb70d5 revert chgs to dev team 2022-12-29 16:40:07 -06:00
Benjamin Hakes ea7d6e96f9 revert chgs to bundle id 2022-12-29 16:38:44 -06:00
Benjamin Hakes f32c4947e1 make invoice view observed object 2022-12-29 16:25:48 -06:00
Benjamin Hakes fe90d02ea8 fix bug updating default wallet 2022-12-29 16:21:55 -06:00
William Casarin 2867da61ca Fixed issue where contact list would sometimes revert to an older version
Changelog-Fixed: Fixed issue where contact list would sometimes revert to an older version
2022-12-29 13:25:07 -08:00
William Casarin 3ebd562217 add relays.nostr.bg to bootstrap relay list 2022-12-29 13:24:32 -08:00
Benjamin Hakes 79c42544d9 clean up dead code 2022-12-29 15:03:36 -06:00
Benjamin Hakes 429a765d42 finish updates to wallet selector improvements 2022-12-29 14:51:36 -06:00
Joel Klabo 4440f32814 Tweak Boosted Label Layout for Better Alignment 2022-12-29 10:06:58 -08:00
Lio李歐 a94b698e9d Merge branch 'master' into profile-markdown 2022-12-29 09:57:54 -08:00
Thomas 3370ac59d8 Don't show boosts in threads
Changelog-Fixed: Don't show boosts in threads
2022-12-29 09:28:28 -08:00
William Casarin 37189e3862 Re-introduce a small amount of padding under the tab bar 2022-12-29 09:27:29 -08:00
William Casarin 614b48eeae remove extra whitespace on tabbar 2022-12-29 09:21:37 -08:00
Suhail Saqan d10ee72fec add show toggle and default wallet selector 2022-12-29 06:04:58 -06:00
Lionello Lunesu a4eaa50ba7 Make links clickable in follow user view 2022-12-28 23:02:01 -08:00
William Casarin bfae6fcf12 v0.1.8-8
Mostly crash fixes and invoice tweaks
2022-12-28 22:53:39 -08:00
William Casarin b19bc27ead Adjust invoice height 2022-12-28 22:52:28 -08:00
William Casarin 754b47d693 Fix crash when adding relays
Changelog-Fixed: Fix crash when adding relays
2022-12-28 22:39:37 -08:00
William Casarin 69f8bc9779 Disable link previews for iOS <16
Changelog-Fixed: Disabled link previews for iOS 15.* to fix crashing
2022-12-28 22:38:55 -08:00
William Casarin 65d7bbf050 thread: scroll to bottom, less jittery 2022-12-28 14:55:16 -08:00
William Casarin 13516dbc0a Show images from yourself
Changelog-Fixed: Show images from yourself
2022-12-28 14:40:32 -08:00
William Casarin 1a28f8ca94 fix pay button
Changelog-Fixed: Fix pay button
2022-12-28 14:40:06 -08:00
William Casarin 05be94e663 build 7 2022-12-28 14:39:53 -08:00
William Casarin 7692e2bf7e Fix issue with wallet links opening in app store
Changelog-Fixed: Fix issue with wallet links opening in app store
2022-12-28 13:57:56 -08:00
William Casarin 266b1cc0bd actually bump build number =/ 2022-12-28 13:33:23 -08:00
William Casarin 4ecd864963 v0.1.8-6 changelog 2022-12-28 13:32:26 -08:00
William Casarin 54cfdb8dcc Add author to changelog tool 2022-12-28 13:32:17 -08:00
Lionello Lunesu 75c67bc1e9 Make links clickable in profile view 2022-12-28 13:29:18 -08:00
William Casarin 3405742350 Wallet Selector
Closes: #107
Changelog-Added: lightning wallet selector
2022-12-28 13:10:54 -08:00
Pablo Fernandez 205774f684 Fix when calling parse_hex_char out of bounds
Closes: #158
Changelog-Fixed: Fix crash with @ sign in some posts
2022-12-28 12:44:47 -08:00
tyiu 0af8646fd5 Swap order of Logout and Cancel alert buttons
To conform to Apple's Human Interface Guidelines

Closes: #159
Changelog-Fixed: Swapped order of Logout and Cancel alert buttons
2022-12-28 12:40:17 -08:00
Jonathan Milligan 393745f67c feat: Add keyboard shortcuts to switch main views and create posts
I added several keyboard shortcuts so users can switch between the main
views of "Home", "DMs", "Search", and "Notifications" with the shortcuts
"CMD+1", "CMD+2" etc.. Those shortcuts made the most sense to me but
they're definitely up for discussion.

Added a new keyboard shortcut to creat a new post. Unfortunately it had
to be "SHIFT+CMD+N" because "CMD+N" already created a new window.

Closes: #163
Changelog-Added: Cmd-{1,2,3,4} to switch between tabs on MacOS
Changelog-Added: Shift-Cmd-N to create a post on MacOS
2022-12-28 12:38:43 -08:00
William Casarin 7c132675ac images: use clear background color instead of black/white 2022-12-28 12:35:02 -08:00
Sam DuBois e6ab1d16d5 Added padding to the tab bar to fix a layout issue for some devices
Closes: #161
Changelog-Fixed: Fixed padding issue on tabbar on some devices
2022-12-28 12:34:42 -08:00
Amos Elliston 94ad5ad366 Add padding to the followers list
Closes: #162
2022-12-28 12:30:40 -08:00
Sam DuBois cabe3cf791 Show Link Previews
Closes: #170
Changelog-Added: Link Previews!
2022-12-28 12:22:12 -08:00
OlegAba c1c832fab7 Fix post button moving after selecting from search result
Closes: #167
Changelog-Fixed: Fix post button moving after selecting from search result
2022-12-28 11:29:43 -08:00
William Casarin 25b233f586 Images: Don't show white background in dark mode and vice versa
Changelog-Fixed: Don't show white background on images in dark mode
2022-12-28 11:26:40 -08:00
William Casarin fd6173c38c bump package 2022-12-28 11:26:33 -08:00
William Casarin 33b410a4c9 Event Cleanup
Closes: #164
Changelog-Changed: Blur and opaque non-friend images rather than only display the link
Changelog-Changed: Remove URLs in content text when image is displayed
Changelog-Changed: Show non-image URLs as clickable link views
Changelog-Changed: Adjusted Pay button on invoices.
2022-12-28 11:25:16 -08:00
Suhail Saqan c4acebdfee Added paste and delete buttons to add relay field
Closes: #168
Changelog-Added: Added paste and delete buttons to add relay field
2022-12-28 11:07:31 -08:00
Suhail Saqan b5f18da01e Merge pull request #2 from 0xtlt/pr/107-1
"Pay" click : Temporary solution
2022-12-28 02:41:33 -06:00
Thomas 15f6c5bfc2 "Pay" click : Temporary solution 2022-12-28 08:59:42 +01:00
Sam DuBois f04f9dfa33 Added detailed link views using async await 2022-12-27 17:45:19 -07:00
Sam DuBois d7aaca25ee Add Context Menu to copy button 2022-12-27 17:43:37 -07:00
Sam DuBois 702c35382c Merge branch 'master' into event-cleanup 2022-12-27 17:42:37 -07:00
Suhail Saqan 270a29f9c0 Merge branch 'master' into add-wallet-modal 2022-12-27 17:54:51 -06:00
William Casarin b23203825a LNUrl -> LNURL 2022-12-27 15:29:12 -08:00
William Casarin a67cd2a841 v0.1.8-5 changelog 2022-12-27 15:25:58 -08:00
William Casarin 2322186f34 v0.1.8-5 2022-12-27 15:25:15 -08:00
William Casarin d35945258f thread: adjust reply line opacity 2022-12-27 15:23:32 -08:00
William Casarin a6a9d4ed77 images: don't cutoff gifs
Changelog-Fixed: Don't cutoff gifs
2022-12-27 14:41:50 -08:00
William Casarin e3db9954f1 thread: fix fonts up a bit 2022-12-27 14:41:50 -08:00
Thomas d1cbf74840 Improved visual composition for threads
Changelog-Changed: Improve visual composition of threads
2022-12-27 14:41:28 -08:00
William Casarin 538ce45c2c Show npub abbreviations instead of hex
Changelog-Changed: Show npub abbreviations instead of old-style hex
2022-12-27 14:14:49 -08:00
Sam DuBois 33802a0fa3 Cleaned up the way we show images, changed the pay button for invoices, and added a new link view to make links appear a bit more friendly (need to work on this more) 2022-12-27 12:38:52 -07:00
Suhail Saqan 65defd6002 Merge branch 'master' into add-wallet-modal 2022-12-27 00:55:40 -06:00
Suhail Saqan 3a695fb1c1 Merge pull request #1 from suhailsaqan/add-default-button
add default wallet option and phoenix
2022-12-26 03:47:05 -06:00
Suhail Saqan c76e1a39e7 add default wallet option and phoenix 2022-12-26 03:46:08 -06:00
Suhail Saqan a1e634487a fix build errors 2022-12-25 23:51:09 -06:00
Suhail Saqan 067d4d44b3 Merge branch 'master' into add-wallet-modal 2022-12-25 23:44:51 -06:00
Suhail Saqan 6b95195cb8 Merge branch 'master' into add-wallet-modal 2022-12-25 20:41:57 -06:00
Suhail Saqan f74a7c620a cleanup and improve design 2022-12-24 23:05:06 -06:00
Suhail Saqan dd50ffd555 allow opening wallet selector for profile LN button 2022-12-24 20:44:10 -06:00
Suhail Saqan 70756938d7 Update project.pbxproj 2022-12-24 19:33:34 -06:00
Suhail Saqan a8921dc24f add lnlink 2022-12-23 20:35:37 -06:00
Suhail Saqan ef85bb0ca9 Merge branch 'master' into add-wallet-modal 2022-12-23 19:48:43 -06:00
Suhail Saqan 8a62f285a6 remove unneeded changes 2022-12-22 17:15:59 -06:00
Suhail Saqan ed9e60ffb6 make wallet items a List 2022-12-22 16:15:34 -06:00
Suhail Saqan 21db49b6dd fixed alignment 2022-12-22 07:00:31 -06:00
Suhail Saqan 0de7b9dc94 added copy invoice and fixed alignment 2022-12-22 05:31:05 -06:00
Suhail Saqan 2f33a7f761 add title 2022-12-22 05:00:01 -06:00
Suhail Saqan 3a34fd5f46 add images for wallets 2022-12-22 04:34:26 -06:00
Suhail Saqan bb6d1b2522 add wallet modal 2022-12-22 04:20:37 -06:00
211 changed files with 17631 additions and 1110 deletions
+31
View File
@@ -0,0 +1,31 @@
name: Run Test Suite
run-name: Testing ${{ github.ref }} by @${{ github.actor }}
on:
push:
branches:
- "master"
pull_request:
branches:
- "*"
jobs:
run_tests:
runs-on: macos-12
strategy:
matrix:
include:
- xcode: "14.2"
ios: "16.2"
name: Test iOS (${{ matrix.ios }})
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Select Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode }}
- name: Run Tests
run: xcodebuild test -scheme damus -project damus.xcodeproj -destination 'platform=iOS Simulator,name=iPhone 14,OS=${{ matrix.ios }}' | xcpretty && exit ${PIPESTATUS[0]}
+273
View File
@@ -1,3 +1,276 @@
## [1.0.0-8] - 2023-01-22
### Added
- Show website on profiles (William Casarin)
- Add the ability to choose participants when replying (Joel Klabo)
- Translations for de_AT, de_DE, tr_TR, fr_FR (William Casarin)
- Add DM Message Requests (William Casarin)
### Fixed
- Fix commands and emojis getting included in hashtags (William Casarin)
- Fix duplicate post buttons when swiping tabs (Thomas Rademaker)
- Show embedded note references (William Casarin)
[1.0.0-8]: https://github.com/damus-io/damus/releases/tag/v1.0.0-8
## [1.0.0-7] - 2023-01-20
### Added
- Drastically improved image viewer (OlegAba)
- Added pinch to zoom on images (Swift)
- Add Latin American Spanish translations (William Casarin)
- Added SVG profile picture support (OlegAba)
### Changed
- Makes both name and username clickable in sidebar to go to profile (Zach Hendel)
- Clicking pfp in sidebar opens profile as well (radixrat)
- Don't blur images if your friend boosted it (ericholguin)
### Fixed
- Fix ... when too many likes/reposts (Joel Klabo)
- Don't show report alert if logged in as a pubkey (Swift)
- Fix padding issue at top of home timeline (Ben Weeks)
- Fix absurdly large sidebar on Mac/iPad (John Bethancourt)
- Fix tab views moving after selecting from search result (OlegAba)
- Make follow/unfollow button a consistent width (OlegAba)
- Don't add events to notifications from buggy relays (William Casarin)
- Fixed some crashes with large images (OlegAba)
- Fix DM sorting on incoming messages (William Casarin)
- Fix text getting truncated next to link previews (William Casarin)
[1.0.0-7]: https://github.com/damus-io/damus/releases/tag/v1.0.0-7
## [1.0.0-6] - 2023-01-13
### Added
- Profile banner images (Jason Jōb)
- Added Reactions View (William Casarin)
- Left hand option for post button (Jonathan Milligan)
- Damus icon at the top (Ben Weeks)
- Make purple badges on profile page tappable (Joel Klabo)
### Changed
- Make Shaka button purple when liked (Joel Klabo)
- Move counts to right side like Birdsite (Joel Klabo)
- Use custom icon for shaka button (Joel Klabo)
- Renamed boost to repost (William Casarin)
- Removed nip05 domain from boosts/reposts (William Casarin)
- Make DMs only take up 80% of screen width (Jonathan Milligan)
- Hide Recommended Relays Section if Empty (Joel Klabo)
### Fixed
- Fixed shaka moving when you press it (Joel Klabo)
- Fixed issue with relays not keeping in sync when adding (Fredrik Olofsson)
[1.0.0-6]: https://github.com/damus-io/damus/releases/tag/v1.0.0-6
## [1.0.0-5] - 2023-01-06
### Added
- Added share button to profile (William Casarin)
- Added universal link sharing of notes (William Casarin)
- Added clear cache button to wipe pfp/image cache (OlegAba)
- Allow Adding Relay Without wss:// Prefix (Joel Klabo)
- Allow Saving Images to Library (Joel Klabo)
### Changed
- Added damus gradient to post button (Ben Weeks)
- Center the Post Button (Thomas)
- Switch yellow nip05 check to gray (William Casarin)
- Switch from bluecheck to purplecheck (William Casarin)
### Fixed
- Add system background color to profile pics (OlegAba)
- High res color pubkey on profile page (William Casarin)
- Don't spin forever if we're temporarily disconnected (William Casarin)
- Fixed a few issues with avatars not animating (OlegAba)
- Scroll to bottom when new DM received (Aidan O'Loan)
- Make reply view scrollable (Joel Klabo)
- Hide profile edit button when logged in with pubkey (Swift)
[1.0.0-5]: https://github.com/damus-io/damus/releases/tag/v1.0.0-5
## [1.0.0-4] - 2023-01-04
### Added
- Added NIP05 Verification (William Casarin)
- Downscale images if they are unreasonably large (OlegAba)
### Changed
- Revert to old style ln/dm buttons (William Casarin)
### Fixed
- Fix ascii shrug guy (Lionello Lunesu)
- Fix navigation popping in threads (William Casarin)
[1.0.0-4]: https://github.com/damus-io/damus/releases/tag/v1.0.0-4
## [1.0.0-2] - 2023-01-03
### Added
- Cache link previews (William Casarin)
- Added brb.io to recommended relay list (William Casarin)
- Add Blixt Wallet to Wallet Selector (Benjamin Hakes)
- Add River Wallet to Wallet Selector (Benjamin Hakes)
### Changed
- Added muted shaka images instead of thumbs up (CutClout)
- Updated profile page look and feel (Ben Weeks)
- Filter replies from global feed (Nitesh Balusu)
- Show non-image links inline (William Casarin)
- Add swipe gesture to switch between tabs (Thomas Rademaker)
- Parse links in profiles (Lionello Lunesu) (Lio李歐)
### Fixed
- Fix detection of email addresses in profiles (Lionello Lunesu)
- Fix padding on search results view (OlegAba)
- Fix home view moving after selecting from search result (OlegAba)
- Fix bug where boost event is loaded in the thread instead of the boosted event (William Casarin)
- Hide edit button on profile page when no private key (Swift)
- Fixed follows and relays getting out of sync on profile pages (William Casarin)
[1.0.0-2]: https://github.com/damus-io/damus/releases/tag/v1.0.0-2
## [1.0.0] - 2023-01-01
### Added
- Parse links in profiles (Lionello Lunesu)
- Added Breez wallet to wallet selector (Lee Salminen)
- Added Bitcoin Beach wallet to wallet selector (Lee Salminen)
- Added ability to copy relay urls (Matt Ward)
- Added option to choose default wallet (Suhail Saqan)
### Changed
- Switch like from ❤️ to 🤙 (William Casarin)
- Internationalize relative dates (Terry Yiu)
### Fixed
- Fix but where text was not showing after invoices (William Casarin)
- Load profiles in DMs and notifications (William Casarin)
- Fix expanding profile picture (nosestr bug) (Joel Klabo)
- Fix padding on threads and search results views (OlegAba)
- Don't badge DMs if sent by you (Joel Klabo)
- Reset relay in Add Relay view after adding (Joel Klabo)
[1.0.0]: https://github.com/damus-io/damus/releases/tag/v1.0.0
## [0.1.8-9] - 2022-12-29
### Added
- Relay list on user profiles
### Changed
- Show recommended relays in config. Currently just a fixed set. (William Casarin)
- Ensure contact relay list is kept in sync with internal relay pool (William Casarin)
### Fixed
- Fixed issue where contact list would sometimes revert to an older version (William Casarin)
- Don't show boosts in threads (Thomas)
[0.1.8-9]: https://github.com/damus-io/damus/releases/tag/v0.1.8-9
## [0.1.8-6] - 2022-12-28
### Added
- Lightning wallet selector (Suhail Saqan)
- Cmd-{1,2,3,4} to switch between tabs on MacOS (Jonathan Milligan)
- Shift-Cmd-N to create a post on MacOS (Jonathan Milligan)
- Link Previews! (Sam DuBois)
- Added paste and delete buttons to add relay field (Suhail Saqan)
### Changed
- Blur and opaque non-friend images rather than only display the link (Sam DuBois)
- Remove URLs in content text when image is displayed (Sam DuBois)
- Show non-image URLs as clickable link views (Sam DuBois)
- Adjusted Pay button on invoices. (Sam DuBois)
### Fixed
- Fix crash with @ sign in some posts (Pablo Fernandez)
- Swapped order of Logout and Cancel alert buttons (Terry Yiu)
- Fixed padding issue on tabbar on some devices (Sam DuBois)
- Fix post button moving after selecting from search result (OlegAba)
- Don't show white background on images in dark mode (William Casarin)
[0.1.8-6]: https://github.com/damus-io/damus/releases/tag/v0.1.8-6
## [0.1.8-5] - 2022-12-27
### Added
- Added the ability to zoom profile pic on profile page
### Changed
- Improve visual composition of threads
- Show npub abbreviations instead of old-style hex
- Added search placeholder and larger cancel button
- Swap order of Boost and Cancel alert buttons
- Rename "Copy Note" to "Copy Note JSON"
### Fixed
- Don't cutoff gifs
- Fixed bug where booster's names are not displayed
[0.1.8-5]: https://github.com/damus-io/damus/releases/tag/v0.1.8-5
## [0.1.8-4] - 2022-12-26
### Added
+3 -3
View File
@@ -25,7 +25,7 @@ damus implements the following [Nostr Implementation Possibilities][nips]
## Getting Started on Damus
### Damus iOS
1) Get the Damus app on Testflight: https://testflight.apple.com/join/CLwjLxWl
1) Get the Damus app on TestFlight: https://testflight.apple.com/join/CLwjLxWl
#### ⚙️ Settings (gear icon, top right)
- Relays: You can add more relays to send your notes to by tapping the "+".
@@ -56,8 +56,8 @@ damus implements the following [Nostr Implementation Possibilities][nips]
- Formatting Notes (may not format as intended in other web clients)
- Italics: 1 asterisk `*italic*`
- Bold: 2 asterisk `**bold**`
- Strikethrough: 2 tildes `~~strikethrough~~`
- Code: 1 back-tick ``code``
- Strikethrough: 1 tildes `~strikethrough~`
- Code: 1 back-tick `` `code` ``
#### 💬 Encrypted DMs (chat app, bottom navigation)
- Tap the chat icon and you'll notice there's nothing to see at first. Go to a user profile and tap the 💬 chat icon next to the follow button to begin a DM
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,6 @@
/* Bundle display name */
"CFBundleDisplayName" = "Damus";
/* Bundle name */
"CFBundleName" = "damus";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Granting Damus access to your photos allows you to save images.";
@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>collapsed_event_view_other_notes</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>··· %#@NOTES@ ···</string>
<key>NOTES</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>%d other note</string>
<key>other</key>
<string>%d other notes</string>
</dict>
</dict>
<key>followers_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@FOLLOWERS@</string>
<key>FOLLOWERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Follower</string>
<key>other</key>
<string>Followers</string>
</dict>
</dict>
<key>reactions_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@REACTIONS@</string>
<key>REACTIONS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Reaction</string>
<key>other</key>
<string>Reactions</string>
</dict>
</dict>
<key>relays_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@RELAYS@</string>
<key>RELAYS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Relay</string>
<key>other</key>
<string>Relays</string>
</dict>
</dict>
<key>replying_to_one_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Replying to %@%#@OTHERS@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>zero</key>
<string></string>
<key>one</key>
<string> &amp; %d other</string>
<key>other</key>
<string> &amp; %d others</string>
</dict>
</dict>
<key>replying_to_two_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Replying to %@, %@%#@OTHERS@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>zero</key>
<string></string>
<key>one</key>
<string> &amp; %d other</string>
<key>other</key>
<string> &amp; %d others</string>
</dict>
</dict>
<key>reposts_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@REPOSTS@</string>
<key>REPOSTS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Repost</string>
<key>other</key>
<string>Reposts</string>
</dict>
</dict>
<key>sats_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%1$#@SATS@</string>
<key>SATS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>@</string>
<key>one</key>
<string>%2$@ sat</string>
<key>other</key>
<string>%2$@ sats</string>
</dict>
</dict>
<key>tips_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@TIPS@</string>
<key>TIPS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Tip</string>
<key>other</key>
<string>Tips</string>
</dict>
</dict>
</dict>
</plist>
@@ -0,0 +1,12 @@
{
"developmentRegion" : "en-US",
"project" : "damus.xcodeproj",
"targetLocale" : "en-US",
"toolInfo" : {
"toolBuildNumber" : "14C18",
"toolID" : "com.apple.dt.xcode",
"toolName" : "Xcode",
"toolVersion" : "14.2"
},
"version" : "1.0"
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -151,7 +151,7 @@ static bool from_numbers(u64 *res,
return false;
if (!from_number(&p1, s1, len1, tens_factor)
|| !from_number(&p2, s2, len2, tens_factor - len2))
|| !from_number(&p2, s2, len2, tens_factor - (int)len2))
return false;
if (add_overflows_u64(p1, p2))
@@ -453,7 +453,7 @@ bool amount_msat_to_u32(struct amount_msat msat, u32 *millisatoshis)
{
if (amount_msat_greater_eq(msat, AMOUNT_MSAT(0x100000000)))
return false;
*millisatoshis = msat.millisatoshis;
*millisatoshis = (u32)msat.millisatoshis;
return true;
}
+1 -1
View File
@@ -297,7 +297,7 @@ static char *decode_c(struct bolt11 *b11,
if (!pull_uint(hu5, data, data_len, &c, data_length * 5))
return tal_fmt(b11, "c: length %zu chars is excessive",
*data_len);
b11->min_final_cltv_expiry = c;
b11->min_final_cltv_expiry = (u32)c;
/* Can overflow, since c is 64 bits but value must be < 32 bits */
if (b11->min_final_cltv_expiry != c)
return tal_fmt(b11, "c: %"PRIu64" is too large", c);
+25 -4
View File
@@ -22,6 +22,10 @@ static inline int is_whitespace(char c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r';
}
static inline int is_boundary(char c) {
return !isalnum(c);
}
static void make_cursor(struct cursor *c, const u8 *content, size_t len)
{
c->start = content;
@@ -29,18 +33,35 @@ static void make_cursor(struct cursor *c, const u8 *content, size_t len)
c->p = content;
}
static int consume_until_whitespace(struct cursor *cur, int or_end) {
static int consume_until_boundary(struct cursor *cur) {
char c;
while (cur->p < cur->end) {
c = *cur->p;
if (is_whitespace(c))
if (is_boundary(c))
return 1;
cur->p++;
}
return 1;
}
static int consume_until_whitespace(struct cursor *cur, int or_end) {
char c;
bool consumedAtLeastOne = false;
while (cur->p < cur->end) {
c = *cur->p;
if (is_whitespace(c) && consumedAtLeastOne)
return 1;
cur->p++;
consumedAtLeastOne = true;
}
return or_end;
}
@@ -145,7 +166,7 @@ static int parse_hashtag(struct cursor *cur, struct block *block) {
return 0;
}
consume_until_whitespace(cur, 1);
consume_until_boundary(cur);
block->type = BLOCK_HASHTAG;
block->block.str.start = (const char*)(start + 1);
@@ -241,7 +262,7 @@ static int parse_invoice(struct cursor *cur, struct block *block) {
block->block.invoice.invstr.end = (const char*)end;
block->block.invoice.bolt11 = bolt11;
cur->p += end - start;
cur->p = end;
return 1;
}
+2 -2
View File
@@ -30,7 +30,7 @@ void hash_u5(struct hash_u5 *hu5, const u8 *u5, size_t len)
u5++;
if (hu5->num_bits >= 32) {
be32 be32 = cpu_to_be32(hu5->buf >> (hu5->num_bits-32));
be32 be32 = cpu_to_be32((u32)(hu5->buf >> (hu5->num_bits-32)));
sha256_update(&hu5->hash, &be32, sizeof(be32));
hu5->num_bits -= 32;
}
@@ -40,7 +40,7 @@ void hash_u5(struct hash_u5 *hu5, const u8 *u5, size_t len)
void hash_u5_done(struct hash_u5 *hu5, struct sha256 *res)
{
if (hu5->num_bits) {
be32 be32 = cpu_to_be32(hu5->buf << (32 - hu5->num_bits));
be32 be32 = cpu_to_be32((u32)(hu5->buf << (32 - hu5->num_bits)));
sha256_update(&hu5->hash, &be32, (hu5->num_bits + 7) / 8);
}
+1 -1
View File
@@ -37,7 +37,7 @@ static inline bool assign_overflow_u16(u16 *dst, uint64_t v)
static inline bool assign_overflow_u32(u32 *dst, uint64_t v)
{
*dst = v;
*dst = (u32)v;
return *dst == v;
}
#endif /* LIGHTNING_COMMON_OVERFLOWS_H */
+331 -49
View File
@@ -7,9 +7,17 @@
objects = {
/* Begin PBXBuildFile section */
3165648B295B70D500C64604 /* LinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3165648A295B70D500C64604 /* LinkView.swift */; };
3169CAE6294E69C000EE4006 /* EmptyTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3169CAE5294E69C000EE4006 /* EmptyTimelineView.swift */; };
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3169CAEC294FCCFC00EE4006 /* Constants.swift */; };
31D2E847295218AF006D67F8 /* Shimmer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D2E846295218AF006D67F8 /* Shimmer.swift */; };
3A4325A82961E11400BFCD9D /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 3A4325AA2961E11400BFCD9D /* Localizable.stringsdict */; };
3AA247FD297E3CFF0090C62D /* RepostsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA247FC297E3CFF0090C62D /* RepostsModel.swift */; };
3AA247FF297E3D900090C62D /* RepostsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA247FE297E3D900090C62D /* RepostsView.swift */; };
3AA24802297E3DC20090C62D /* RepostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AA24801297E3DC20090C62D /* RepostView.swift */; };
3ACB685C297633BC00C46468 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3ACB685A297633BC00C46468 /* InfoPlist.strings */; };
3ACB685F297633BC00C46468 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3ACB685D297633BC00C46468 /* Localizable.strings */; };
3ACBCB78295FE5C70037388A /* TimeAgoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ACBCB77295FE5C70037388A /* TimeAgoTests.swift */; };
4C06670128FC7C5900038D2A /* RelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670028FC7C5900038D2A /* RelayView.swift */; };
4C06670428FC7EC500038D2A /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 4C06670328FC7EC500038D2A /* Kingfisher */; };
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670528FCB08600038D2A /* ImageCarousel.swift */; };
@@ -47,6 +55,8 @@
4C363AA228296A7E006E126D /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363AA128296A7E006E126D /* SearchView.swift */; };
4C363AA428296DEE006E126D /* SearchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363AA328296DEE006E126D /* SearchModel.swift */; };
4C363AA828297703006E126D /* InsertSort.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363AA728297703006E126D /* InsertSort.swift */; };
4C3A1D332960DB0500558C0F /* Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3A1D322960DB0500558C0F /* Markdown.swift */; };
4C3A1D3729637E0500558C0F /* PreviewCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3A1D3629637E0500558C0F /* PreviewCache.swift */; };
4C3AC79B28306D7B00E1F516 /* Contacts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3AC79A28306D7B00E1F516 /* Contacts.swift */; };
4C3AC79D2833036D00E1F516 /* FollowingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3AC79C2833036D00E1F516 /* FollowingView.swift */; };
4C3AC79F2833115300E1F516 /* FollowButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3AC79E2833115300E1F516 /* FollowButtonView.swift */; };
@@ -108,6 +118,24 @@
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */; };
4CACA9D5280C31E100D9BBE8 /* ReplyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */; };
4CACA9DC280C38C000D9BBE8 /* Profiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CACA9DB280C38C000D9BBE8 /* Profiles.swift */; };
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */; };
4CB55EF5295E679D007FD187 /* UserRelaysView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB55EF4295E679D007FD187 /* UserRelaysView.swift */; };
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838529656C8B00DC99E7 /* NIP05.swift */; };
4CB88389296AF99A00DC99E7 /* EventDetailBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB88388296AF99A00DC99E7 /* EventDetailBar.swift */; };
4CB8838B296F6E1E00DC99E7 /* NIP05Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838A296F6E1E00DC99E7 /* NIP05Badge.swift */; };
4CB8838D296F710400DC99E7 /* Reposted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838C296F710400DC99E7 /* Reposted.swift */; };
4CB8838F296F781C00DC99E7 /* ReactionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8838E296F781C00DC99E7 /* ReactionsView.swift */; };
4CB88393296F798300DC99E7 /* ReactionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB88392296F798300DC99E7 /* ReactionsModel.swift */; };
4CB88396296F7F8B00DC99E7 /* ReactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB88395296F7F8B00DC99E7 /* ReactionView.swift */; };
4CB8839A297322D200DC99E7 /* DMTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB88399297322D200DC99E7 /* DMTests.swift */; };
4CBCA930297DB57F00EC6B2F /* WebsiteLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */; };
4CC7AAEB297F0AEC00430951 /* BuilderEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */; };
4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEC297F0B9E00430951 /* Highlight.swift */; };
4CC7AAF0297F11C700430951 /* SelectedEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAEF297F11C700430951 /* SelectedEventView.swift */; };
4CC7AAF2297F129C00430951 /* EmbeddedEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF1297F129C00430951 /* EmbeddedEventView.swift */; };
4CC7AAF4297F18B400430951 /* ReplyDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF3297F18B400430951 /* ReplyDescription.swift */; };
4CC7AAF6297F1A6A00430951 /* EventBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF5297F1A6A00430951 /* EventBody.swift */; };
4CC7AAF8297F1CEE00430951 /* EventProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF7297F1CEE00430951 /* EventProfile.swift */; };
4CD7641B28A1641400B6928F /* EndBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD7641A28A1641400B6928F /* EndBlock.swift */; };
4CE4F8CD281352B30009DFBB /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F8CC281352B30009DFBB /* Notifications.swift */; };
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */; };
@@ -129,8 +157,22 @@
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 */; };
4FE60CDD295E1C5E00105A1F /* Wallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE60CDC295E1C5E00105A1F /* Wallet.swift */; };
6439E014296790CF0020672B /* ProfileZoomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6439E013296790CF0020672B /* ProfileZoomView.swift */; };
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647D9A8C2968520300A295DE /* SideMenuView.swift */; };
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FBD06E296255C400D9D3B2 /* Theme.swift */; };
6C7DE41F2955169800E66263 /* Vault in Frameworks */ = {isa = PBXBuildFile; productRef = 6C7DE41E2955169800E66263 /* Vault */; };
7C45AE6D297352F90031D7BC /* SVGKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7C45AE6C297352F90031D7BC /* SVGKit */; };
7C45AE6F297352F90031D7BC /* SVGKitSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 7C45AE6E297352F90031D7BC /* SVGKitSwift */; };
7C45AE71297353390031D7BC /* KFImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C45AE70297353390031D7BC /* KFImageModel.swift */; };
9609F058296E220800069BF3 /* BannerImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9609F057296E220800069BF3 /* BannerImageView.swift */; };
BA693074295D649800ADDB87 /* UserSettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA693073295D649800ADDB87 /* UserSettingsStore.swift */; };
BAB68BED29543FA3007BA466 /* SelectWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */; };
DD597CBD2963D85A00C64D32 /* MarkdownTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD597CBC2963D85A00C64D32 /* MarkdownTests.swift */; };
E990020F2955F837003BBC5A /* EditMetadataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E990020E2955F837003BBC5A /* EditMetadataView.swift */; };
E9E4ED0B295867B900DD7078 /* ThreadV2View.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */; };
F7F0BA25297892BD009531F3 /* SwipeToDismiss.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F0BA24297892BD009531F3 /* SwipeToDismiss.swift */; };
F7F0BA272978E54D009531F3 /* ParicipantsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F0BA262978E54D009531F3 /* ParicipantsView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -151,9 +193,30 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
3165648A295B70D500C64604 /* LinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkView.swift; sourceTree = "<group>"; };
3169CAE5294E69C000EE4006 /* EmptyTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyTimelineView.swift; sourceTree = "<group>"; };
3169CAEC294FCCFC00EE4006 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Constants.swift; path = damus/Util/Constants.swift; sourceTree = SOURCE_ROOT; };
31D2E846295218AF006D67F8 /* Shimmer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shimmer.swift; sourceTree = "<group>"; };
3A2B8B0A296A8982009CC16D /* en-US */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "en-US"; path = "en-US.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
3A4F3320297CCFEE004B5F72 /* fr-FR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-FR"; path = "fr-FR.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
3A4F3321297CCFEE004B5F72 /* fr-FR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-FR"; path = "fr-FR.lproj/Localizable.strings"; sourceTree = "<group>"; };
3A4F3322297CCFEE004B5F72 /* fr-FR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "fr-FR"; path = "fr-FR.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
3A5C4575296A879E0032D398 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-419"; path = "es-419.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
3A5EA10F297CCF6C00569477 /* de-AT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "de-AT"; path = "de-AT.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
3A5EA110297CCF6C00569477 /* de-AT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "de-AT"; path = "de-AT.lproj/Localizable.strings"; sourceTree = "<group>"; };
3A5EA111297CCF6C00569477 /* de-AT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "de-AT"; path = "de-AT.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
3AA247FC297E3CFF0090C62D /* RepostsModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepostsModel.swift; sourceTree = "<group>"; };
3AA247FE297E3D900090C62D /* RepostsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepostsView.swift; sourceTree = "<group>"; };
3AA24801297E3DC20090C62D /* RepostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepostView.swift; sourceTree = "<group>"; };
3ACB685B297633BC00C46468 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
3ACB685E297633BC00C46468 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Localizable.strings"; sourceTree = "<group>"; };
3ACBCB77295FE5C70037388A /* TimeAgoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeAgoTests.swift; sourceTree = "<group>"; };
3AEABD20297CCFA8003F2975 /* de-DE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "de-DE"; path = "de-DE.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
3AEABD21297CCFA8003F2975 /* de-DE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "de-DE"; path = "de-DE.lproj/Localizable.strings"; sourceTree = "<group>"; };
3AEABD22297CCFA8003F2975 /* de-DE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "de-DE"; path = "de-DE.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
3AEB8003297CCEA800713A25 /* tr-TR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "tr-TR"; path = "tr-TR.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
3AEB8004297CCEA800713A25 /* tr-TR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "tr-TR"; path = "tr-TR.lproj/Localizable.strings"; sourceTree = "<group>"; };
3AEB8005297CCEA900713A25 /* tr-TR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "tr-TR"; path = "tr-TR.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
4C06670028FC7C5900038D2A /* RelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayView.swift; sourceTree = "<group>"; };
4C06670528FCB08600038D2A /* ImageCarousel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCarousel.swift; sourceTree = "<group>"; };
4C06670828FDE64700038D2A /* damus-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "damus-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -193,6 +256,8 @@
4C363AA128296A7E006E126D /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = "<group>"; };
4C363AA328296DEE006E126D /* SearchModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchModel.swift; sourceTree = "<group>"; };
4C363AA728297703006E126D /* InsertSort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsertSort.swift; sourceTree = "<group>"; };
4C3A1D322960DB0500558C0F /* Markdown.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Markdown.swift; sourceTree = "<group>"; };
4C3A1D3629637E0500558C0F /* PreviewCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewCache.swift; sourceTree = "<group>"; };
4C3AC79A28306D7B00E1F516 /* Contacts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contacts.swift; sourceTree = "<group>"; };
4C3AC79C2833036D00E1F516 /* FollowingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingView.swift; sourceTree = "<group>"; };
4C3AC79E2833115300E1F516 /* FollowButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowButtonView.swift; sourceTree = "<group>"; };
@@ -284,6 +349,24 @@
4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineView.swift; sourceTree = "<group>"; };
4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyView.swift; sourceTree = "<group>"; };
4CACA9DB280C38C000D9BBE8 /* Profiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Profiles.swift; sourceTree = "<group>"; };
4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendedRelayView.swift; sourceTree = "<group>"; };
4CB55EF4295E679D007FD187 /* UserRelaysView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRelaysView.swift; sourceTree = "<group>"; };
4CB8838529656C8B00DC99E7 /* NIP05.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP05.swift; sourceTree = "<group>"; };
4CB88388296AF99A00DC99E7 /* EventDetailBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventDetailBar.swift; sourceTree = "<group>"; };
4CB8838A296F6E1E00DC99E7 /* NIP05Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP05Badge.swift; sourceTree = "<group>"; };
4CB8838C296F710400DC99E7 /* Reposted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reposted.swift; sourceTree = "<group>"; };
4CB8838E296F781C00DC99E7 /* ReactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionsView.swift; sourceTree = "<group>"; };
4CB88392296F798300DC99E7 /* ReactionsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionsModel.swift; sourceTree = "<group>"; };
4CB88395296F7F8B00DC99E7 /* ReactionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionView.swift; sourceTree = "<group>"; };
4CB88399297322D200DC99E7 /* DMTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMTests.swift; sourceTree = "<group>"; };
4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebsiteLink.swift; sourceTree = "<group>"; };
4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuilderEventView.swift; sourceTree = "<group>"; };
4CC7AAEC297F0B9E00430951 /* Highlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Highlight.swift; sourceTree = "<group>"; };
4CC7AAEF297F11C700430951 /* SelectedEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedEventView.swift; sourceTree = "<group>"; };
4CC7AAF1297F129C00430951 /* EmbeddedEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmbeddedEventView.swift; sourceTree = "<group>"; };
4CC7AAF3297F18B400430951 /* ReplyDescription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplyDescription.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>"; };
4CD7641A28A1641400B6928F /* EndBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EndBlock.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>"; };
@@ -308,7 +391,19 @@
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>"; };
4FE60CDC295E1C5E00105A1F /* Wallet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wallet.swift; sourceTree = "<group>"; };
6439E013296790CF0020672B /* ProfileZoomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileZoomView.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>"; };
7C45AE70297353390031D7BC /* KFImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KFImageModel.swift; sourceTree = "<group>"; };
9609F057296E220800069BF3 /* BannerImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BannerImageView.swift; sourceTree = "<group>"; };
BA693073295D649800ADDB87 /* UserSettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsStore.swift; sourceTree = "<group>"; };
BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectWalletView.swift; sourceTree = "<group>"; };
DD597CBC2963D85A00C64D32 /* MarkdownTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkdownTests.swift; sourceTree = "<group>"; };
E990020E2955F837003BBC5A /* EditMetadataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditMetadataView.swift; sourceTree = "<group>"; };
E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadV2View.swift; sourceTree = "<group>"; };
F7F0BA24297892BD009531F3 /* SwipeToDismiss.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeToDismiss.swift; sourceTree = "<group>"; };
F7F0BA262978E54D009531F3 /* ParicipantsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParicipantsView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -316,6 +411,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7C45AE6F297352F90031D7BC /* SVGKitSwift in Frameworks */,
7C45AE6D297352F90031D7BC /* SVGKit in Frameworks */,
4C06670428FC7EC500038D2A /* Kingfisher in Frameworks */,
6C7DE41F2955169800E66263 /* Vault in Frameworks */,
4CE6DF1227F7A2B300C66700 /* Starscream in Frameworks */,
@@ -348,6 +445,14 @@
path = "Empty Views";
sourceTree = "<group>";
};
3AA24800297E3DAE0090C62D /* Reposts */ = {
isa = PBXGroup;
children = (
3AA24801297E3DC20090C62D /* RepostView.swift */,
);
path = Reposts;
sourceTree = "<group>";
};
4C06670728FDE62900038D2A /* damus-c */ = {
isa = PBXGroup;
children = (
@@ -405,6 +510,7 @@
4C0A3F8D280F63FF000448DE /* Models */ = {
isa = PBXGroup;
children = (
3AA247FC297E3CFF0090C62D /* RepostsModel.swift */,
4C0A3F8E280F640A000448DE /* ThreadModel.swift */,
4C0A3F92280F66F5000448DE /* ReplyMap.swift */,
4C3BEFD12819DB9B00B3DE84 /* ProfileModel.swift */,
@@ -432,6 +538,10 @@
4C64987D286D082C00EAE2B3 /* DirectMessagesModel.swift */,
4C216F372871EDE300040376 /* DirectMessageModel.swift */,
4C99737A28C92A9200E53835 /* ChatroomMetadata.swift */,
BA693073295D649800ADDB87 /* UserSettingsStore.swift */,
4FE60CDC295E1C5E00105A1F /* Wallet.swift */,
4CB88392296F798300DC99E7 /* ReactionsModel.swift */,
7C45AE70297353390031D7BC /* KFImageModel.swift */,
);
path = Models;
sourceTree = "<group>";
@@ -439,45 +549,58 @@
4C75EFA227FA576C0006080F /* Views */ = {
isa = PBXGroup;
children = (
3169CAE4294E699400EE4006 /* Empty Views */,
4C75EFA327FA577B0006080F /* PostView.swift */,
4C75EFAC28049CFB0006080F /* PostButton.swift */,
4C75EFB82804A2740006080F /* EventView.swift */,
4CEE2AF0280B216B00AB5EEF /* EventDetailView.swift */,
4CEE2AF2280B25C500AB5EEF /* ProfilePicView.swift */,
4CEE2AF6280B2DEA00AB5EEF /* ProfileName.swift */,
4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */,
4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */,
4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */,
4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */,
4CC7AAEE297F11B300430951 /* Events */,
3AA24800297E3DAE0090C62D /* Reposts */,
4CB88394296F7F8100DC99E7 /* Reactions */,
4CB88387296AF97C00DC99E7 /* ActionBar */,
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */,
4C363A8728236948006E126D /* BlocksView.swift */,
4C285C8128385570008A31F1 /* CarouselView.swift */,
4C0A3F8B280F5FCA000448DE /* ChatroomView.swift */,
4C0A3F90280F6528000448DE /* ChatView.swift */,
4C0A3F94280F6C78000448DE /* ReplyQuoteView.swift */,
4C0A3F96280F8E02000448DE /* ThreadView.swift */,
4C8682862814DE470026224F /* ProfileView.swift */,
4C363A8728236948006E126D /* BlocksView.swift */,
4C363A8928236B57006E126D /* MentionView.swift */,
4C363A8B28236B92006E126D /* PubkeyView.swift */,
4C363A8D28236FE4006E126D /* NoteContentView.swift */,
4C363AA128296A7E006E126D /* SearchView.swift */,
4C3AC79C2833036D00E1F516 /* FollowingView.swift */,
4C3AC79E2833115300E1F516 /* FollowButtonView.swift */,
4C3AC7A02835A81400E1F516 /* SetupView.swift */,
4C3AC7A42836987600E1F516 /* MainTabView.swift */,
4C3AC7A628369BA200E1F516 /* SearchHomeView.swift */,
4C285C8128385570008A31F1 /* CarouselView.swift */,
4C285C8328385690008A31F1 /* CreateAccountView.swift */,
4C285C892838B985008A31F1 /* ProfilePictureSelector.swift */,
4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */,
4C90BD17283A9EE5008EE7EF /* LoginView.swift */,
4C5C7E69284EDE2E00A22DF5 /* SearchResultsView.swift */,
4CE4F9DD2852768D00C00DD9 /* ConfigView.swift */,
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */,
4C285C8328385690008A31F1 /* CreateAccountView.swift */,
4C64987B286D03E000EAE2B3 /* DirectMessagesView.swift */,
4C216F31286E388800040376 /* DMChatView.swift */,
4C216F33286F5ACD00040376 /* DMView.swift */,
4C06670028FC7C5900038D2A /* RelayView.swift */,
E990020E2955F837003BBC5A /* EditMetadataView.swift */,
3169CAE4294E699400EE4006 /* Empty Views */,
4C75EFB82804A2740006080F /* EventView.swift */,
4CEE2AF0280B216B00AB5EEF /* EventDetailView.swift */,
4C3AC79E2833115300E1F516 /* FollowButtonView.swift */,
4C3AC79C2833036D00E1F516 /* FollowingView.swift */,
4C90BD17283A9EE5008EE7EF /* LoginView.swift */,
4C363A8928236B57006E126D /* MentionView.swift */,
4C363A8D28236FE4006E126D /* NoteContentView.swift */,
4C75EFAC28049CFB0006080F /* PostButton.swift */,
4C75EFA327FA577B0006080F /* PostView.swift */,
4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */,
4CEE2AF6280B2DEA00AB5EEF /* ProfileName.swift */,
4C285C892838B985008A31F1 /* ProfilePictureSelector.swift */,
4CEE2AF2280B25C500AB5EEF /* ProfilePicView.swift */,
4C8682862814DE470026224F /* ProfileView.swift */,
4C3AC7A42836987600E1F516 /* MainTabView.swift */,
4C363A8B28236B92006E126D /* PubkeyView.swift */,
4CB55EF2295E5D59007FD187 /* RecommendedRelayView.swift */,
4C06670028FC7C5900038D2A /* RelayView.swift */,
4C0A3F94280F6C78000448DE /* ReplyQuoteView.swift */,
4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */,
F7F0BA262978E54D009531F3 /* ParicipantsView.swift */,
4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */,
4C3AC7A628369BA200E1F516 /* SearchHomeView.swift */,
4C5C7E69284EDE2E00A22DF5 /* SearchResultsView.swift */,
4C363AA128296A7E006E126D /* SearchView.swift */,
BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */,
4C3AC7A02835A81400E1F516 /* SetupView.swift */,
E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */,
4C0A3F96280F8E02000448DE /* ThreadView.swift */,
4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */,
4CB55EF4295E679D007FD187 /* UserRelaysView.swift */,
647D9A8C2968520300A295DE /* SideMenuView.swift */,
9609F057296E220800069BF3 /* BannerImageView.swift */,
4CB8838E296F781C00DC99E7 /* ReactionsView.swift */,
6439E013296790CF0020672B /* ProfileZoomView.swift */,
3AA247FE297E3D900090C62D /* RepostsView.swift */,
);
path = Views;
sourceTree = "<group>";
@@ -505,6 +628,7 @@
4C7FF7D628233637009601DB /* Util */ = {
isa = PBXGroup;
children = (
4C3A1D322960DB0500558C0F /* Markdown.swift */,
4CEE2AF4280B29E600AB5EEF /* TimeAgo.swift */,
4CE4F8CC281352B30009DFBB /* Notifications.swift */,
4C363A8328233689006E126D /* Parser.swift */,
@@ -514,10 +638,44 @@
4C90BD19283AA67F008EE7EF /* Bech32.swift */,
4C216F352870A9A700040376 /* InputDismissKeyboard.swift */,
3169CAEC294FCCFC00EE4006 /* Constants.swift */,
3165648A295B70D500C64604 /* LinkView.swift */,
4C3A1D3629637E0500558C0F /* PreviewCache.swift */,
64FBD06E296255C400D9D3B2 /* Theme.swift */,
4CB8838529656C8B00DC99E7 /* NIP05.swift */,
);
path = Util;
sourceTree = "<group>";
};
4CB88387296AF97C00DC99E7 /* ActionBar */ = {
isa = PBXGroup;
children = (
4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */,
4CB88388296AF99A00DC99E7 /* EventDetailBar.swift */,
);
path = ActionBar;
sourceTree = "<group>";
};
4CB88394296F7F8100DC99E7 /* Reactions */ = {
isa = PBXGroup;
children = (
4CB88395296F7F8B00DC99E7 /* ReactionView.swift */,
);
path = Reactions;
sourceTree = "<group>";
};
4CC7AAEE297F11B300430951 /* Events */ = {
isa = PBXGroup;
children = (
4CC7AAEF297F11C700430951 /* SelectedEventView.swift */,
4CC7AAF1297F129C00430951 /* EmbeddedEventView.swift */,
4CC7AAF3297F18B400430951 /* ReplyDescription.swift */,
4CC7AAF5297F1A6A00430951 /* EventBody.swift */,
4CC7AAEA297F0AEC00430951 /* BuilderEventView.swift */,
4CC7AAF7297F1CEE00430951 /* EventProfile.swift */,
);
path = Events;
sourceTree = "<group>";
};
4CE4F9DF285287A000C00DD9 /* Components */ = {
isa = PBXGroup;
children = (
@@ -527,6 +685,10 @@
4C06670528FCB08600038D2A /* ImageCarousel.swift */,
4C3EA67C28FFBBA200C48A62 /* InvoicesView.swift */,
4C3EA67E28FFC01D00C48A62 /* InvoiceView.swift */,
4CB8838A296F6E1E00DC99E7 /* NIP05Badge.swift */,
4CB8838C296F710400DC99E7 /* Reposted.swift */,
4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */,
4CC7AAEC297F0B9E00430951 /* Highlight.swift */,
);
path = Components;
sourceTree = "<group>";
@@ -556,17 +718,21 @@
4CE6DEE527F7A08100C66700 /* damus */ = {
isa = PBXGroup;
children = (
F7F0BA23297892AE009531F3 /* Modifiers */,
4C4A3A5A288A1B2200453788 /* damus.entitlements */,
4CE4F9DF285287A000C00DD9 /* Components */,
4C7FF7D628233637009601DB /* Util */,
4C0A3F8D280F63FF000448DE /* Models */,
4C75EFAB28049CC80006080F /* Nostr */,
4C75EFA72804823E0006080F /* Info.plist */,
3ACB685D297633BC00C46468 /* Localizable.strings */,
3ACB685A297633BC00C46468 /* InfoPlist.strings */,
4C75EFA227FA576C0006080F /* Views */,
4CE6DEE627F7A08100C66700 /* damusApp.swift */,
4CE6DEE827F7A08100C66700 /* ContentView.swift */,
4CE6DEEA27F7A08200C66700 /* Assets.xcassets */,
4CE6DEEC27F7A08200C66700 /* Preview Content */,
3A4325AA2961E11400BFCD9D /* Localizable.stringsdict */,
);
path = damus;
sourceTree = "<group>";
@@ -582,11 +748,14 @@
4CE6DEF627F7A08200C66700 /* damusTests */ = {
isa = PBXGroup;
children = (
DD597CBC2963D85A00C64D32 /* MarkdownTests.swift */,
4C90BD1B283AC38E008EE7EF /* Bech32Tests.swift */,
4C363A9F2828A8DD006E126D /* LikeTests.swift */,
4C363A9D2828A822006E126D /* ReplyTests.swift */,
4CE6DEF727F7A08200C66700 /* damusTests.swift */,
4C3EA67A28FF7B3900C48A62 /* InvoiceTests.swift */,
3ACBCB77295FE5C70037388A /* TimeAgoTests.swift */,
4CB88399297322D200DC99E7 /* DMTests.swift */,
);
path = damusTests;
sourceTree = "<group>";
@@ -608,6 +777,14 @@
name = Frameworks;
sourceTree = "<group>";
};
F7F0BA23297892AE009531F3 /* Modifiers */ = {
isa = PBXGroup;
children = (
F7F0BA24297892BD009531F3 /* SwipeToDismiss.swift */,
);
path = Modifiers;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -629,6 +806,8 @@
4C649880286E0EE300EAE2B3 /* secp256k1 */,
4C06670328FC7EC500038D2A /* Kingfisher */,
6C7DE41E2955169800E66263 /* Vault */,
7C45AE6C297352F90031D7BC /* SVGKit */,
7C45AE6E297352F90031D7BC /* SVGKitSwift */,
);
productName = damus;
productReference = 4CE6DEE327F7A08100C66700 /* damus.app */;
@@ -696,19 +875,24 @@
};
buildConfigurationList = 4CE6DEDE27F7A08100C66700 /* Build configuration list for PBXProject "damus" */;
compatibilityVersion = "Xcode 13.0";
developmentRegion = en;
developmentRegion = "en-US";
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
"es-419",
"en-US",
"de-AT",
"de-DE",
"tr-TR",
"fr-FR",
);
mainGroup = 4CE6DEDA27F7A08100C66700;
packageReferences = (
4CE6DF1027F7A2B300C66700 /* XCRemoteSwiftPackageReference "Starscream" */,
4C64987F286E0EE300EAE2B3 /* XCRemoteSwiftPackageReference "secp256k1" */,
4C06670228FC7EC500038D2A /* XCRemoteSwiftPackageReference "Kingfisher" */,
3169CAE9294FCABA00EE4006 /* XCRemoteSwiftPackageReference "Shimmer" */,
6C7DE41D2955169800E66263 /* XCRemoteSwiftPackageReference "Vault" */,
7C45AE6B297352F90031D7BC /* XCRemoteSwiftPackageReference "SVGKit" */,
);
productRefGroup = 4CE6DEE427F7A08100C66700 /* Products */;
projectDirPath = "";
@@ -726,8 +910,11 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3ACB685F297633BC00C46468 /* Localizable.strings in Resources */,
4CE6DEEE27F7A08200C66700 /* Preview Assets.xcassets in Resources */,
3ACB685C297633BC00C46468 /* InfoPlist.strings in Resources */,
4CE6DEEB27F7A08200C66700 /* Assets.xcassets in Resources */,
3A4325A82961E11400BFCD9D /* Localizable.stringsdict in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -765,54 +952,74 @@
4C363A8C28236B92006E126D /* PubkeyView.swift in Sources */,
4C5C7E68284ED36500A22DF5 /* SearchHomeModel.swift in Sources */,
4C75EFB728049D990006080F /* RelayPool.swift in Sources */,
4CB8838D296F710400DC99E7 /* Reposted.swift in Sources */,
4C3EA67728FF7A9800C48A62 /* talstr.c in Sources */,
4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */,
4CEE2AF5280B29E600AB5EEF /* TimeAgo.swift in Sources */,
4C75EFAD28049CFB0006080F /* PostButton.swift in Sources */,
4CB55EF5295E679D007FD187 /* UserRelaysView.swift in Sources */,
4C363AA228296A7E006E126D /* SearchView.swift in Sources */,
4CC7AAED297F0B9E00430951 /* Highlight.swift in Sources */,
4C285C8A2838B985008A31F1 /* ProfilePictureSelector.swift in Sources */,
4C75EFB92804A2740006080F /* EventView.swift in Sources */,
3AA247FD297E3CFF0090C62D /* RepostsModel.swift in Sources */,
4C7FF7D52823313F009601DB /* Mentions.swift in Sources */,
4C633350283D40E500B1C9C3 /* HomeModel.swift in Sources */,
4C987B57283FD07F0042CE38 /* FollowersModel.swift in Sources */,
4C363A9028247A1D006E126D /* NostrLink.swift in Sources */,
4C0A3F8C280F5FCA000448DE /* ChatroomView.swift in Sources */,
4C477C9E282C3A4800033AA3 /* TipCounter.swift in Sources */,
647D9A8D2968520300A295DE /* SideMenuView.swift in Sources */,
F7F0BA272978E54D009531F3 /* ParicipantsView.swift in Sources */,
4C0A3F91280F6528000448DE /* ChatView.swift in Sources */,
4C216F362870A9A700040376 /* InputDismissKeyboard.swift in Sources */,
4C216F382871EDE300040376 /* DirectMessageModel.swift in Sources */,
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */,
4CE4F9DE2852768D00C00DD9 /* ConfigView.swift in Sources */,
4C285C8E28399BFE008A31F1 /* SaveKeysView.swift in Sources */,
F7F0BA25297892BD009531F3 /* SwipeToDismiss.swift in Sources */,
4CB8838F296F781C00DC99E7 /* ReactionsView.swift in Sources */,
4C649844285A952100EAE2B3 /* LocalUserConfig.swift in Sources */,
4C75EFB328049D640006080F /* NostrEvent.swift in Sources */,
4CA2EFA0280E37AC0044ACD8 /* TimelineView.swift in Sources */,
4C363A8428233689006E126D /* Parser.swift in Sources */,
4CE4F9E328528C5200C00DD9 /* AddRelayView.swift in Sources */,
4C363A9A28283854006E126D /* Reply.swift in Sources */,
BA693074295D649800ADDB87 /* UserSettingsStore.swift in Sources */,
4C90BD18283A9EE5008EE7EF /* LoginView.swift in Sources */,
4CB8838B296F6E1E00DC99E7 /* NIP05Badge.swift in Sources */,
4C3EA66828FF5F9900C48A62 /* hex.c in Sources */,
E9E4ED0B295867B900DD7078 /* ThreadV2View.swift in Sources */,
4C3BEFDC281DCE6100B3DE84 /* Liked.swift in Sources */,
4C75EFB128049D510006080F /* NostrResponse.swift in Sources */,
4CEE2AF7280B2DEA00AB5EEF /* ProfileName.swift in Sources */,
4CC7AAEB297F0AEC00430951 /* BuilderEventView.swift in Sources */,
31D2E847295218AF006D67F8 /* Shimmer.swift in Sources */,
4C285C8228385570008A31F1 /* CarouselView.swift in Sources */,
4C3EA67F28FFC01D00C48A62 /* InvoiceView.swift in Sources */,
4CEE2B02280B39E800AB5EEF /* EventActionBar.swift in Sources */,
4C3BEFE0281DE1ED00B3DE84 /* DamusState.swift in Sources */,
7C45AE71297353390031D7BC /* KFImageModel.swift in Sources */,
4C0A3F8F280F640A000448DE /* ThreadModel.swift in Sources */,
4CC7AAF2297F129C00430951 /* EmbeddedEventView.swift in Sources */,
4C3AC79F2833115300E1F516 /* FollowButtonView.swift in Sources */,
4C3BEFD22819DB9B00B3DE84 /* ProfileModel.swift in Sources */,
4C0A3F93280F66F5000448DE /* ReplyMap.swift in Sources */,
BAB68BED29543FA3007BA466 /* SelectWalletView.swift in Sources */,
3169CAE6294E69C000EE4006 /* EmptyTimelineView.swift in Sources */,
4CC7AAF0297F11C700430951 /* SelectedEventView.swift in Sources */,
4CC7AAF8297F1CEE00430951 /* EventProfile.swift in Sources */,
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */,
4C3EA64928FF597700C48A62 /* bech32.c in Sources */,
4C90BD162839DB54008EE7EF /* NostrMetadata.swift in Sources */,
4C3A1D3729637E0500558C0F /* PreviewCache.swift in Sources */,
4C3EA67528FF7A5A00C48A62 /* take.c in Sources */,
4C3AC7A12835A81400E1F516 /* SetupView.swift in Sources */,
4C06670128FC7C5900038D2A /* RelayView.swift in Sources */,
4C285C8C28398BC7008A31F1 /* Keys.swift in Sources */,
4CACA9DC280C38C000D9BBE8 /* Profiles.swift in Sources */,
4C633352283D419F00B1C9C3 /* SignalModel.swift in Sources */,
9609F058296E220800069BF3 /* BannerImageView.swift in Sources */,
4C363A94282704FA006E126D /* Post.swift in Sources */,
4C216F32286E388800040376 /* DMChatView.swift in Sources */,
4C3EA67928FF7ABF00C48A62 /* list.c in Sources */,
@@ -822,18 +1029,26 @@
4C75EFAF28049D350006080F /* NostrFilter.swift in Sources */,
4C3EA64C28FF59AC00C48A62 /* bech32_util.c in Sources */,
4C363A9C282838B9006E126D /* EventRef.swift in Sources */,
3AA24802297E3DC20090C62D /* RepostView.swift in Sources */,
4CD7641B28A1641400B6928F /* EndBlock.swift in Sources */,
4C3EA66528FF5F6800C48A62 /* mem.c in Sources */,
4CBCA930297DB57F00EC6B2F /* WebsiteLink.swift in Sources */,
4C3EA64128FF553900C48A62 /* hash_u5.c in Sources */,
4C3EA64F28FF59F200C48A62 /* tal.c in Sources */,
4CB88393296F798300DC99E7 /* ReactionsModel.swift in Sources */,
4CB88396296F7F8B00DC99E7 /* ReactionView.swift in Sources */,
4C8682872814DE470026224F /* ProfileView.swift in Sources */,
4C5F9114283D694D0052CD1C /* FollowTarget.swift in Sources */,
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */,
4C5C7E6A284EDE2E00A22DF5 /* SearchResultsView.swift in Sources */,
6439E014296790CF0020672B /* ProfileZoomView.swift in Sources */,
4CE6DF1627F8DEBF00C66700 /* RelayConnection.swift in Sources */,
4C3BEFD6281D995700B3DE84 /* ActionBarModel.swift in Sources */,
4C363AA428296DEE006E126D /* SearchModel.swift in Sources */,
4CEE2AF3280B25C500AB5EEF /* ProfilePicView.swift in Sources */,
4CC7AAF6297F1A6A00430951 /* EventBody.swift in Sources */,
4CEE2AF9280B2EAC00AB5EEF /* PowView.swift in Sources */,
3165648B295B70D500C64604 /* LinkView.swift in Sources */,
4C3BEFD42819DE8F00B3DE84 /* NostrKind.swift in Sources */,
4C3EA66028FF5E7700C48A62 /* node_id.c in Sources */,
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */,
@@ -846,17 +1061,23 @@
4C363A922825FCF2006E126D /* ProfileUpdate.swift in Sources */,
4C0A3F95280F6C78000448DE /* ReplyQuoteView.swift in Sources */,
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */,
4CB88389296AF99A00DC99E7 /* EventDetailBar.swift in Sources */,
4C3AC79B28306D7B00E1F516 /* Contacts.swift in Sources */,
4C3EA63D28FF52D600C48A62 /* bolt11.c in Sources */,
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */,
4C5F9118283D88E40052CD1C /* FollowingModel.swift in Sources */,
4C3EA67D28FFBBA300C48A62 /* InvoicesView.swift in Sources */,
4C363A8E28236FE4006E126D /* NoteContentView.swift in Sources */,
4C90BD1A283AA67F008EE7EF /* Bech32.swift in Sources */,
E990020F2955F837003BBC5A /* EditMetadataView.swift in Sources */,
4CACA9D5280C31E100D9BBE8 /* ReplyView.swift in Sources */,
4C3A1D332960DB0500558C0F /* Markdown.swift in Sources */,
4C0A3F97280F8E02000448DE /* ThreadView.swift in Sources */,
4C06670B28FDE64700038D2A /* damus.c in Sources */,
4FE60CDD295E1C5E00105A1F /* Wallet.swift in Sources */,
3AA247FF297E3D900090C62D /* RepostsView.swift in Sources */,
4C99737B28C92A9200E53835 /* ChatroomMetadata.swift in Sources */,
4CC7AAF4297F18B400430951 /* ReplyDescription.swift in Sources */,
4C75EFA427FA577B0006080F /* PostView.swift in Sources */,
4C75EFB528049D790006080F /* Relay.swift in Sources */,
4CEE2AF1280B216B00AB5EEF /* EventDetailView.swift in Sources */,
@@ -870,8 +1091,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3ACBCB78295FE5C70037388A /* TimeAgoTests.swift in Sources */,
DD597CBD2963D85A00C64D32 /* MarkdownTests.swift in Sources */,
4C3EA67B28FF7B3900C48A62 /* InvoiceTests.swift in Sources */,
4C363A9E2828A822006E126D /* ReplyTests.swift in Sources */,
4CB8839A297322D200DC99E7 /* DMTests.swift in Sources */,
4C363AA02828A8DD006E126D /* LikeTests.swift in Sources */,
4C90BD1C283AC38E008EE7EF /* Bech32Tests.swift in Sources */,
4CE6DEF827F7A08200C66700 /* damusTests.swift in Sources */,
@@ -902,11 +1126,52 @@
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
3A4325AA2961E11400BFCD9D /* Localizable.stringsdict */ = {
isa = PBXVariantGroup;
children = (
3A5C4575296A879E0032D398 /* es-419 */,
3A2B8B0A296A8982009CC16D /* en-US */,
3A5EA111297CCF6C00569477 /* de-AT */,
3AEABD22297CCFA8003F2975 /* de-DE */,
3AEB8005297CCEA900713A25 /* tr-TR */,
3A4F3322297CCFEE004B5F72 /* fr-FR */,
);
name = Localizable.stringsdict;
sourceTree = "<group>";
};
3ACB685A297633BC00C46468 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
3ACB685B297633BC00C46468 /* es-419 */,
3A5EA10F297CCF6C00569477 /* de-AT */,
3AEABD20297CCFA8003F2975 /* de-DE */,
3AEB8003297CCEA800713A25 /* tr-TR */,
3A4F3320297CCFEE004B5F72 /* fr-FR */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
3ACB685D297633BC00C46468 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
3ACB685E297633BC00C46468 /* es-419 */,
3A5EA110297CCF6C00569477 /* de-AT */,
3AEABD21297CCFA8003F2975 /* de-DE */,
3AEB8004297CCEA800713A25 /* tr-TR */,
3A4F3321297CCFEE004B5F72 /* fr-FR */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
4CE6DF0527F7A08200C66700 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
@@ -953,13 +1218,14 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MACOSX_DEPLOYMENT_TARGET = 12.3;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
@@ -968,6 +1234,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
@@ -1008,12 +1275,13 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.3;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MACOSX_DEPLOYMENT_TARGET = 12.3;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
@@ -1027,13 +1295,15 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = damus/damus.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 9;
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
DEVELOPMENT_TEAM = XK7H4JAB3D;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = damus/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Damus;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Granting Damus access to your photos allows you to save images.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@@ -1047,7 +1317,7 @@
"$(inherited)",
"$(PROJECT_DIR)",
);
MARKETING_VERSION = 0.1.8;
MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.jb55.damus2;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -1066,13 +1336,15 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = damus/damus.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 4;
CURRENT_PROJECT_VERSION = 9;
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
DEVELOPMENT_TEAM = XK7H4JAB3D;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = damus/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Damus;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Granting Damus access to your photos allows you to save images.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@@ -1086,7 +1358,7 @@
"$(inherited)",
"$(PROJECT_DIR)",
);
MARKETING_VERSION = 0.1.8;
MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.jb55.damus2;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -1214,14 +1486,6 @@
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
3169CAE9294FCABA00EE4006 /* XCRemoteSwiftPackageReference "Shimmer" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/joshuajhomann/Shimmer";
requirement = {
branch = master;
kind = branch;
};
};
4C06670228FC7EC500038D2A /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/onevcat/Kingfisher";
@@ -1254,6 +1518,14 @@
minimumVersion = 1.0.0;
};
};
7C45AE6B297352F90031D7BC /* XCRemoteSwiftPackageReference "SVGKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SVGKit/SVGKit";
requirement = {
kind = revision;
revision = e1f13e27b1e4c0ffe20e7d8d3984bf49c2a584d0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@@ -1277,6 +1549,16 @@
package = 6C7DE41D2955169800E66263 /* XCRemoteSwiftPackageReference "Vault" */;
productName = Vault;
};
7C45AE6C297352F90031D7BC /* SVGKit */ = {
isa = XCSwiftPackageProductDependency;
package = 7C45AE6B297352F90031D7BC /* XCRemoteSwiftPackageReference "SVGKit" */;
productName = SVGKit;
};
7C45AE6E297352F90031D7BC /* SVGKitSwift */ = {
isa = XCSwiftPackageProductDependency;
package = 7C45AE6B297352F90031D7BC /* XCRemoteSwiftPackageReference "SVGKit" */;
productName = SVGKitSwift;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 4CE6DEDB27F7A08100C66700 /* Project object */;
@@ -17,15 +17,6 @@
"revision" : "40b4b38b3b1c83f7088c76189a742870e0ca06a9"
}
},
{
"identity" : "shimmer",
"kind" : "remoteSourceControl",
"location" : "https://github.com/joshuajhomann/Shimmer",
"state" : {
"branch" : "master",
"revision" : "2fde687b3f1d9c5409c53da095d3686361e41343"
}
},
{
"identity" : "starscream",
"kind" : "remoteSourceControl",
@@ -35,13 +26,21 @@
"version" : "4.0.4"
}
},
{
"identity" : "svgkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SVGKit/SVGKit",
"state" : {
"revision" : "e1f13e27b1e4c0ffe20e7d8d3984bf49c2a584d0"
}
},
{
"identity" : "vault",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SparrowTek/Vault",
"state" : {
"revision" : "f5707fac23f4a17b3e5ed32dd444f502773615ae",
"version" : "1.0.2"
"revision" : "87db56c3c8b6421c65b0745f73e08b0dc56f79d4",
"version" : "1.0.3"
}
}
],
@@ -1,6 +1,33 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xC5",
"green" : "0x43",
"red" : "0xCC"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xC5",
"green" : "0x43",
"red" : "0xCC"
}
},
"idiom" : "universal"
}
],
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x00",
"green" : "0x00",
"red" : "0x00"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x00",
"green" : "0x00",
"red" : "0x00"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xFF",
"green" : "0x4D",
"red" : "0x4B"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xFF",
"green" : "0x4D",
"red" : "0x4B"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x1E",
"green" : "0x1C",
"red" : "0x1C"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x1E",
"green" : "0x1C",
"red" : "0x1C"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x4F",
"green" : "0xC3",
"red" : "0x66"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x4F",
"green" : "0xC3",
"red" : "0x66"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xF4",
"green" : "0xEE",
"red" : "0xEE"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xF4",
"green" : "0xEE",
"red" : "0xEE"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x5F",
"green" : "0x5F",
"red" : "0x5F"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x5F",
"green" : "0x5F",
"red" : "0x5F"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xC5",
"green" : "0x43",
"red" : "0xCC"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xC5",
"green" : "0x43",
"red" : "0xCC"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xFF",
"green" : "0xFF",
"red" : "0xFF"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xFF",
"green" : "0xFF",
"red" : "0xFF"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ic-copy.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ic-key.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

@@ -0,0 +1,52 @@
{
"images" : [
{
"filename" : "ic-message-black.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "ic-message-white 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ic-nipverified.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 950 B

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ic-qr.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "profile-banner.jpeg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "bbw.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "blixt-wallet.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "bluewallet.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "breez.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "cashapp.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

+23
View File
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "damus-home@1x.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "damus-home@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "damus-home@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ic-lightning.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "ic-tick.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "lnlink.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "muun.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "phoenix.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "river.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+15
View File
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "shaka-full.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
@@ -0,0 +1,88 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 0.000000 -0.073975 cm
1.000000 1.000000 1.000000 scn
1.295334 8.661732 m
3.613694 8.367855 l
4.475733 8.733568 5.268113 9.771931 5.474915 10.327032 c
6.083156 11.959681 5.507567 14.604573 5.474915 15.061715 c
5.448792 15.427428 6.008246 15.693006 6.291239 15.780080 c
7.571236 15.858447 8.508359 14.876789 8.642253 13.984165 c
8.740212 13.331103 8.576948 11.752880 8.381030 10.849482 c
8.979668 10.936556 10.980525 10.901726 11.868687 10.849482 c
12.756847 10.797236 13.474895 10.196423 14.193260 9.412750 c
14.767952 8.237244 13.953805 7.725680 13.474895 7.616838 c
13.834077 7.257654 l
14.781013 5.918882 13.649043 5.178749 13.115711 5.004600 c
13.474895 4.743376 l
14.487136 3.763786 13.246323 2.751544 13.017752 2.882155 c
11.058574 3.176033 l
15.499378 1.673996 l
16.054478 0.400530 15.074889 0.073999 14.781013 0.073999 c
8.576947 1.673996 l
6.291239 1.673996 5.311650 1.869914 4.299407 2.163791 c
4.157911 2.131138 3.659409 1.987464 2.797370 1.673996 c
1.935332 1.360527 1.219143 2.087601 0.968804 2.490320 c
-0.285071 4.083785 -0.467927 7.257655 1.295334 8.661732 c
h
f
n
Q
endstream
endobj
3 0 obj
1149
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 15.666626 15.710510 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000001239 00000 n
0000001262 00000 n
0000001435 00000 n
0000001509 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
1568
%%EOF
+15
View File
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "shaka-line.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
+323
View File
@@ -0,0 +1,323 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 0.474731 -0.563965 cm
1.000000 1.000000 1.000000 scn
3.613694 9.332577 m
3.553993 8.861599 l
3.637261 8.851044 3.721838 8.862753 3.799107 8.895533 c
3.613694 9.332577 l
h
1.295334 9.626453 m
1.355035 10.097433 l
1.227973 10.113539 1.099794 10.077623 0.999601 9.997839 c
1.295334 9.626453 l
h
0.968804 3.455042 m
1.372000 3.705677 l
1.362764 3.720535 1.352713 3.734872 1.341894 3.748621 c
0.968804 3.455042 l
h
4.299407 3.128512 m
4.431771 3.584435 l
4.353942 3.607030 4.271623 3.609325 4.192656 3.591103 c
4.299407 3.128512 l
h
8.576947 2.638718 m
8.695503 3.098424 l
8.656776 3.108411 8.616942 3.113465 8.576947 3.113465 c
8.576947 2.638718 l
h
14.781013 1.038721 m
14.662457 0.579016 l
14.701184 0.569027 14.741018 0.563974 14.781013 0.563974 c
14.781013 1.038721 l
h
15.499378 2.638718 m
15.934578 2.828420 l
15.881091 2.951125 15.778289 3.045548 15.651489 3.088437 c
15.499378 2.638718 l
h
11.058574 4.140755 m
11.128998 4.610250 l
10.885809 4.646729 10.655017 4.491467 10.597156 4.252461 c
10.539293 4.013455 10.673516 3.769826 10.906463 3.691035 c
11.058574 4.140755 l
h
13.017752 3.846877 m
13.253292 4.259073 l
13.202273 4.288227 13.146286 4.307655 13.088176 4.316372 c
13.017752 3.846877 l
h
13.474895 5.708097 m
13.805044 6.049252 l
13.789093 6.064689 13.772079 6.078987 13.754128 6.092043 c
13.474895 5.708097 l
h
13.115711 5.969321 m
12.968349 6.420619 l
12.798800 6.365256 12.674588 6.219535 12.646772 6.043359 c
12.618958 5.867183 12.692234 5.690281 12.836478 5.585376 c
13.115711 5.969321 l
h
13.834077 8.222376 m
14.221668 8.496526 l
14.206144 8.518474 14.188784 8.539063 14.169774 8.558073 c
13.834077 8.222376 l
h
13.474895 8.581559 m
13.369680 9.044500 l
13.201114 9.006190 13.066693 8.879284 13.018762 8.713197 c
12.970830 8.547110 13.016963 8.368095 13.139197 8.245862 c
13.474895 8.581559 l
h
14.193260 10.377472 m
14.619765 10.585986 l
14.599768 10.626891 14.573989 10.664707 14.543221 10.698271 c
14.193260 10.377472 l
h
8.381030 11.814203 m
7.917068 11.914822 l
7.884080 11.762714 7.927746 11.604099 8.033934 11.490305 c
8.140121 11.376513 8.295343 11.321997 8.449365 11.344399 c
8.381030 11.814203 l
h
8.642253 14.948887 m
9.111748 15.019311 l
8.642253 14.948887 l
h
6.291239 16.744801 m
6.262227 17.218662 l
6.224693 17.216364 6.187564 17.209614 6.151623 17.198555 c
6.291239 16.744801 l
h
5.474915 16.026436 m
5.948456 16.060261 l
5.474915 16.026436 l
h
5.474915 11.291754 m
5.030037 11.457493 l
5.474915 11.291754 l
h
3.673396 9.803555 m
1.355035 10.097433 l
1.235632 9.155476 l
3.553993 8.861599 l
3.673396 9.803555 l
h
0.999601 9.997839 m
-0.029049 9.178730 -0.454726 7.875908 -0.474048 6.619066 c
-0.493367 5.362488 -0.110331 4.058727 0.595713 3.161463 c
1.341894 3.748621 l
0.794064 4.444821 0.458734 5.524729 0.475334 6.604470 c
0.491930 7.683949 0.856455 8.670100 1.591066 9.255068 c
0.999601 9.997839 l
h
0.565608 3.204407 m
0.721970 2.952868 1.013515 2.611341 1.407507 2.372385 c
1.811404 2.127421 2.357187 1.973489 2.959612 2.192553 c
2.635129 3.084882 l
2.375515 2.990478 2.132184 3.043347 1.899893 3.184233 c
1.657696 3.331126 1.465977 3.554496 1.372000 3.705677 c
0.565608 3.204407 l
h
2.959612 2.192553 m
3.816493 2.504146 4.293336 2.639887 4.406158 2.665923 c
4.192656 3.591103 l
4.022485 3.551832 3.502325 3.400227 2.635129 3.084882 c
2.959612 2.192553 l
h
4.167043 2.672591 m
5.229115 2.364247 6.254152 2.163970 8.576947 2.163970 c
8.576947 3.113465 l
6.328326 3.113465 5.394184 3.305025 4.431771 3.584435 c
4.167043 2.672591 l
h
8.458392 2.179011 m
14.662457 0.579016 l
14.899569 1.498427 l
8.695503 3.098424 l
8.458392 2.179011 l
h
14.781013 0.563974 m
15.036198 0.563974 15.495326 0.684875 15.814721 1.047266 c
16.180891 1.462728 16.264221 2.072176 15.934578 2.828420 c
15.064179 2.449016 l
15.289635 1.931793 15.160722 1.741243 15.102402 1.675073 c
15.055794 1.622190 14.990156 1.579316 14.916806 1.549556 c
14.881134 1.535082 14.847747 1.525430 14.820526 1.519657 c
14.791491 1.513498 14.777695 1.513469 14.781013 1.513469 c
14.781013 0.563974 l
h
15.651489 3.088437 m
11.210685 4.590474 l
10.906463 3.691035 l
15.347267 2.188998 l
15.651489 3.088437 l
h
10.988150 3.671260 m
12.947328 3.377382 l
13.088176 4.316372 l
11.128998 4.610250 l
10.988150 3.671260 l
h
12.782211 3.434681 m
12.991495 3.315090 13.204453 3.370091 13.288217 3.396689 c
13.400116 3.432221 13.506123 3.490767 13.598186 3.554502 c
13.783985 3.683133 13.977411 3.877748 14.120350 4.119644 c
14.264680 4.363894 14.369576 4.678114 14.335162 5.031647 c
14.300108 5.391746 14.125634 5.739002 13.805044 6.049252 c
13.144745 5.366943 l
13.330275 5.187398 13.380290 5.040778 13.390134 4.939653 c
13.400617 4.831963 13.370820 4.717613 13.302905 4.602680 c
13.233600 4.485394 13.137231 4.390213 13.057724 4.335170 c
13.017135 4.307070 12.996612 4.300308 13.000857 4.301657 c
13.003194 4.302399 13.024761 4.309311 13.061064 4.310122 c
13.095938 4.310902 13.170414 4.306433 13.253292 4.259073 c
12.782211 3.434681 l
h
13.754128 6.092043 m
13.394944 6.353267 l
12.836478 5.585376 l
13.195662 5.324152 l
13.754128 6.092043 l
h
13.263074 5.518023 m
13.593105 5.625790 14.123367 5.907292 14.433812 6.409482 c
14.595931 6.671733 14.696482 6.993351 14.669847 7.364054 c
14.643518 7.730516 14.495621 8.109214 14.221668 8.496526 c
13.446486 7.948226 l
13.646002 7.666152 13.711709 7.450294 13.722795 7.296009 c
13.733575 7.145966 13.695351 7.020646 13.626177 6.908748 c
13.474038 6.662641 13.171650 6.487002 12.968349 6.420619 c
13.263074 5.518023 l
h
14.169774 8.558073 m
13.810592 8.917255 l
13.139197 8.245862 l
13.498380 7.886679 l
14.169774 8.558073 l
h
13.580109 8.118617 m
13.896242 8.190466 14.344993 8.395787 14.624650 8.816864 c
14.929440 9.275781 14.963785 9.882310 14.619765 10.585986 c
13.766754 10.168959 l
13.997427 9.697128 13.912044 9.460121 13.833706 9.342171 c
13.730235 9.186377 13.532457 9.081495 13.369680 9.044500 c
13.580109 8.118617 l
h
14.543221 10.698271 m
13.820906 11.486253 12.989320 12.223852 11.896564 12.288132 c
11.840808 11.340275 l
12.524374 11.300065 13.128883 10.836036 13.843298 10.056674 c
14.543221 10.698271 l
h
11.896564 12.288132 m
11.441970 12.314873 10.711069 12.336796 10.019300 12.341186 c
9.341933 12.345484 8.654247 12.333687 8.312695 12.284006 c
8.449365 11.344399 l
8.706450 11.381794 9.318512 11.396118 10.013274 11.391710 c
10.693633 11.387392 11.407242 11.365778 11.840808 11.340275 c
11.896564 12.288132 l
h
8.844993 11.713585 m
8.948084 12.188952 9.040332 12.829445 9.094679 13.432834 c
9.147870 14.023395 9.169946 14.631327 9.111748 15.019311 c
8.172758 14.878462 l
8.212520 14.613384 8.201942 14.105675 8.149012 13.518009 c
8.097237 12.943172 8.009893 12.342852 7.917068 11.914822 c
8.844993 11.713585 l
h
9.111748 15.019311 m
8.944062 16.137217 7.805658 17.313158 6.262227 17.218662 c
6.320251 16.270941 l
7.336813 16.333179 8.072657 15.545805 8.172758 14.878462 c
9.111748 15.019311 l
h
6.151623 17.198555 m
5.976391 17.144638 5.715709 17.036982 5.490986 16.876261 c
5.292936 16.734617 4.969444 16.439627 5.001374 15.992612 c
5.948456 16.060261 l
5.951383 16.019283 5.934667 15.999795 5.943361 16.012491 c
5.954769 16.029152 5.984430 16.061831 6.043331 16.103956 c
6.162553 16.189222 6.323094 16.257891 6.430855 16.291048 c
6.151623 17.198555 l
h
5.001374 15.992612 m
5.011176 15.855374 5.059216 15.566318 5.104405 15.255149 c
5.152757 14.922197 5.207128 14.509316 5.241940 14.062993 c
5.312967 13.152368 5.295928 12.171200 5.030037 11.457493 c
5.919792 11.126015 l
6.262142 12.044956 6.261431 13.202559 6.188560 14.136827 c
6.151423 14.612950 6.093790 15.049047 6.044043 15.391605 c
5.991133 15.755945 5.954979 15.968927 5.948456 16.060261 c
5.001374 15.992612 l
h
5.030037 11.457493 m
4.953650 11.252455 4.742510 10.903708 4.434547 10.555828 c
4.127778 10.209298 3.769400 9.914337 3.428282 9.769621 c
3.799107 8.895533 l
4.320028 9.116529 4.788858 9.523607 5.145489 9.926461 c
5.500926 10.327968 5.789377 10.775953 5.919792 11.126015 c
5.030037 11.457493 l
h
f
n
Q
endstream
endobj
3 0 obj
7995
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 16.615845 16.660034 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000008085 00000 n
0000008108 00000 n
0000008281 00000 n
0000008355 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
8414
%%EOF
+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "strike.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "walletofsatoshi.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "zebedee.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

+21
View File
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "zeus.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

+39
View File
@@ -0,0 +1,39 @@
//
// Highlight.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import Foundation
import SwiftUI
enum Highlight {
case none
case main
case reply
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
}
}
}
+205 -46
View File
@@ -12,14 +12,14 @@ import Kingfisher
struct ShareSheet: UIViewControllerRepresentable {
typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void
let activityItems: [URL]
let activityItems: [URL?]
let callback: Callback? = nil
let applicationActivities: [UIActivity]? = nil
let excludedActivityTypes: [UIActivity.ActivityType]? = nil
func makeUIViewController(context: Context) -> UIActivityViewController {
let controller = UIActivityViewController(
activityItems: activityItems,
activityItems: activityItems as [Any],
applicationActivities: applicationActivities)
controller.excludedActivityTypes = excludedActivityTypes
controller.completionWithItemsHandler = callback
@@ -32,7 +32,7 @@ struct ShareSheet: UIViewControllerRepresentable {
}
struct ImageContextMenuModifier: ViewModifier {
let url: URL
let url: URL?
let image: UIImage?
@Binding var showShareSheet: Bool
@@ -41,26 +41,44 @@ struct ImageContextMenuModifier: ViewModifier {
Button {
UIPasteboard.general.url = url
} label: {
Label("Copy Image URL", systemImage: "doc.on.doc")
Label(NSLocalizedString("Copy Image URL", comment: "Context menu option to copy the URL of an image into clipboard."), systemImage: "doc.on.doc")
}
if let someImage = image {
Button {
UIPasteboard.general.image = someImage
} label: {
Label("Copy Image", systemImage: "photo.on.rectangle")
Label(NSLocalizedString("Copy Image", comment: "Context menu option to copy an image into clipboard."), systemImage: "photo.on.rectangle")
}
Button {
UIImageWriteToSavedPhotosAlbum(someImage, nil, nil, nil)
} label: {
Label(NSLocalizedString("Save Image", comment: "Context menu option to save an image."), systemImage: "square.and.arrow.down")
}
}
Button {
showShareSheet = true
} label: {
Label("Share", systemImage: "square.and.arrow.up")
Label(NSLocalizedString("Share", comment: "Button to share an image."), systemImage: "square.and.arrow.up")
}
}
}
}
struct ImageViewer: View {
let urls: [URL]
private struct ImageContainerView: View {
@ObservedObject var imageModel: KFImageModel
@State private var image: UIImage?
@State private var showShareSheet = false
init(url: URL?) {
self.imageModel = KFImageModel(
url: url,
fallbackUrl: nil,
maxByteSize: 2000000, // 2 MB
downsampleSize: CGSize(width: 400, height: 400)
)
}
private struct ImageHandler: ImageModifier {
@Binding var handler: UIImage?
@@ -70,45 +88,178 @@ struct ImageViewer: View {
return image
}
}
@State private var image: UIImage?
@State private var showShareSheet = false
func onShared(completed: Bool) -> Void {
if (completed) {
showShareSheet = false
var body: some View {
KFAnimatedImage(imageModel.url)
.callbackQueue(.dispatch(.global(qos: .background)))
.processingQueue(.dispatch(.global(qos: .background)))
.cacheOriginalImage()
.configure { view in
view.framePreloadCount = 1
}
.scaleFactor(UIScreen.main.scale)
.loadDiskFileSynchronously()
.fade(duration: 0.1)
.imageModifier(ImageHandler(handler: $image))
.onFailure { _ in
imageModel.downloadFailed()
}
.id(imageModel.refreshID)
.clipped()
.modifier(ImageContextMenuModifier(url: imageModel.url, image: image, showShareSheet: $showShareSheet))
.sheet(isPresented: $showShareSheet) {
ShareSheet(activityItems: [imageModel.url])
}
// TODO: Update ImageCarousel with serializer and processor
// .serialize(by: imageModel.serializer)
// .setProcessor(imageModel.processor)
}
}
struct ZoomableScrollView<Content: View>: UIViewRepresentable {
private var content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
func makeUIView(context: Context) -> UIScrollView {
let scrollView = UIScrollView()
scrollView.delegate = context.coordinator
scrollView.maximumZoomScale = 20
scrollView.minimumZoomScale = 1
scrollView.bouncesZoom = true
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
let hostedView = context.coordinator.hostingController.view!
hostedView.translatesAutoresizingMaskIntoConstraints = true
hostedView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
hostedView.frame = scrollView.bounds
hostedView.backgroundColor = .clear
scrollView.addSubview(hostedView)
return scrollView
}
func makeCoordinator() -> Coordinator {
return Coordinator(hostingController: UIHostingController(rootView: self.content))
}
func updateUIView(_ uiView: UIScrollView, context: Context) {
context.coordinator.hostingController.rootView = self.content
assert(context.coordinator.hostingController.view.superview == uiView)
}
class Coordinator: NSObject, UIScrollViewDelegate {
var hostingController: UIHostingController<Content>
init(hostingController: UIHostingController<Content>) {
self.hostingController = hostingController
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return hostingController.view
}
}
}
struct ImageView: View {
let urls: [URL?]
@Environment(\.presentationMode) var presentationMode
@State private var selectedIndex = 0
@State var showMenu = true
var navBarView: some View {
VStack {
HStack {
Text(urls[selectedIndex]?.lastPathComponent ?? "")
.bold()
Spacer()
Button(action: {
presentationMode.wrappedValue.dismiss()
}, label: {
Image(systemName: "xmark")
})
}
.padding()
Divider()
.ignoresSafeArea()
}
.background(.regularMaterial)
}
var tabViewIndicator: some View {
HStack(spacing: 10) {
ForEach(urls.indices, id: \.self) { index in
Capsule()
.fill(index == selectedIndex ? Color(UIColor.label) : Color.secondary)
.frame(width: 7, height: 7)
}
}
.padding()
.background(.regularMaterial)
.clipShape(Capsule())
}
var body: some View {
TabView {
ForEach(urls, id: \.absoluteString) { url in
VStack{
Text(url.lastPathComponent)
KFAnimatedImage(url)
.configure { view in
view.framePreloadCount = 3
}
.cacheOriginalImage()
.imageModifier(ImageHandler(handler: $image))
.loadDiskFileSynchronously()
.scaleFactor(UIScreen.main.scale)
.fade(duration: 0.1)
.aspectRatio(contentMode: .fit)
.tabItem {
Text(url.absoluteString)
}
.id(url.absoluteString)
.modifier(ImageContextMenuModifier(url: url, image: image, showShareSheet: $showShareSheet))
.sheet(isPresented: $showShareSheet) {
ShareSheet(activityItems: [url])
}
ZStack {
Color(.systemBackground)
.ignoresSafeArea()
TabView(selection: $selectedIndex) {
ForEach(urls.indices, id: \.self) { index in
ZoomableScrollView {
ImageContainerView(url: urls[index])
.aspectRatio(contentMode: .fit)
}
.ignoresSafeArea()
.tag(index)
.modifier(SwipeToDismissModifier(minDistance: 50, onDismiss: {
presentationMode.wrappedValue.dismiss()
}))
}
}
.ignoresSafeArea()
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.onChange(of: selectedIndex, perform: { _ in
showMenu = true
})
.onTapGesture {
showMenu.toggle()
}
.overlay(
VStack {
if showMenu {
navBarView
Spacer()
if (urls.count > 1) {
tabViewIndicator
}
}
}
.animation(.easeInOut, value: showMenu)
.padding(
.bottom,
UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.first { $0.isKeyWindow }?.safeAreaInsets.bottom
)
)
}
.tabViewStyle(PageTabViewStyle())
}
}
@@ -122,26 +273,34 @@ struct ImageCarousel: View {
TabView {
ForEach(urls, id: \.absoluteString) { url in
Rectangle()
.foregroundColor(Color.clear)
.overlay {
KFAnimatedImage(url)
.configure { view in
view.framePreloadCount = 3
}
.callbackQueue(.dispatch(.global(qos: .background)))
.processingQueue(.dispatch(.global(qos: .background)))
.cacheOriginalImage()
.loadDiskFileSynchronously()
.scaleFactor(UIScreen.main.scale)
.fade(duration: 0.1)
.aspectRatio(contentMode: .fill)
.configure { view in
view.framePreloadCount = 3
}
.aspectRatio(contentMode: .fit)
.tabItem {
Text(url.absoluteString)
}
.id(url.absoluteString)
.contextMenu {
Button(NSLocalizedString("Copy Image", comment: "Context menu option to copy an image to clipboard.")) {
UIPasteboard.general.string = url.absoluteString
}
}
}
}
}
.cornerRadius(10)
.sheet(isPresented: $open_sheet) {
ImageViewer(urls: urls)
.fullScreenCover(isPresented: $open_sheet) {
ImageView(urls: urls)
}
.frame(height: 200)
.onTapGesture {
@@ -153,6 +312,6 @@ struct ImageCarousel: View {
struct ImageCarousel_Previews: PreviewProvider {
static var previews: some View {
ImageCarousel(urls: [URL(string: "https://jb55.com/red-me.jpg")!])
ImageCarousel(urls: [URL(string: "https://jb55.com/red-me.jpg")!,URL(string: "https://jb55.com/red-me.jpg")!])
}
}
+54 -12
View File
@@ -7,43 +7,85 @@
import SwiftUI
func open_with_wallet(wallet: Wallet.Model, invoice: String) {
if let url = URL(string: "\(wallet.link)\(invoice)"), UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
} else {
guard let store_link = wallet.appStoreLink else {
// TODO: do something here if we don't have an appstore link
return
}
guard let url = URL(string: store_link) else {
return
}
guard UIApplication.shared.canOpenURL(url) else {
return
}
UIApplication.shared.open(url)
}
}
struct InvoiceView: View {
@Environment(\.colorScheme) var colorScheme
@Environment(\.openURL) private var openURL
let invoice: Invoice
@State var showing_select_wallet: Bool = false
@ObservedObject var user_settings = UserSettingsStore()
var PayButton: some View {
Button("Pay") {
guard let url = URL(string: "lightning:" + invoice.string) else {
return
Button {
if user_settings.show_wallet_selector {
showing_select_wallet = true
} else {
open_with_wallet(wallet: user_settings.default_wallet.model, invoice: invoice.string)
}
UIApplication.shared.open(url)
} label: {
RoundedRectangle(cornerRadius: 20)
.foregroundColor(colorScheme == .light ? .black : .white)
.overlay {
Text("Pay", comment: "Button to pay a Lightning invoice.")
.fontWeight(.medium)
.foregroundColor(colorScheme == .light ? .white : .black)
}
}
//.buttonStyle(.bordered)
.onTapGesture {
// Temporary solution so that the "pay" button can be clicked (Yes we need an empty tap gesture)
}
.buttonStyle(.bordered)
}
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 20)
RoundedRectangle(cornerRadius: 10)
.foregroundColor(.secondary.opacity(0.1))
VStack(alignment: .trailing, spacing: 12) {
VStack(alignment: .leading, spacing: 12) {
HStack {
Label("", systemImage: "bolt.fill")
.foregroundColor(.orange)
Text("Lightning Invoice")
Text("Lightning Invoice", comment: "Indicates that the view is for paying a Lightning invoice.")
}
Divider()
Text(invoice.description)
Text("\(invoice.amount / 1000) sats")
Text(invoice.amount.amount_sats_str())
.font(.title)
PayButton
.zIndex(5.0)
.frame(height: 50)
.zIndex(10.0)
}
.padding()
.padding(30)
}
.sheet(isPresented: $showing_select_wallet, onDismiss: {showing_select_wallet = false}) {
SelectWalletView(showingSelectWallet: $showing_select_wallet, invoice: invoice.string).environmentObject(user_settings)
}
}
}
let test_invoice = Invoice(description: "this is a description", amount: 10000, string: "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r", expiry: 604800, payment_hash: Data(), created_at: 1666139119)
let test_invoice = Invoice(description: "this is a description", amount: .specific(10000), string: "lnbc100n1p357sl0sp5t9n56wdztun39lgdqlr30xqwksg3k69q4q2rkr52aplujw0esn0qpp5mrqgljk62z20q4nvgr6lzcyn6fhylzccwdvu4k77apg3zmrkujjqdpzw35xjueqd9ejqcfqv3jhxcmjd9c8g6t0dcxqyjw5qcqpjrzjqt56h4gvp5yx36u2uzqa6qwcsk3e2duunfxppzj9vhypc3wfe2wswz607uqq3xqqqsqqqqqqqqqqqlqqyg9qyysgqagx5h20aeulj3gdwx3kxs8u9f4mcakdkwuakasamm9562ffyr9en8yg20lg0ygnr9zpwp68524kmda0t5xp2wytex35pu8hapyjajxqpsql29r", expiry: 604800, payment_hash: Data(), created_at: 1666139119)
struct InvoiceView_Previews: PreviewProvider {
static var previews: some View {
+3 -2
View File
@@ -23,13 +23,14 @@ struct InvoicesView: View {
.id(invoice.string)
}
}
.frame(height: 200)
.frame(height: 240)
.tabViewStyle(PageTabViewStyle())
}
}
struct InvoicesView_Previews: PreviewProvider {
static var previews: some View {
InvoicesView(invoices: [Invoice.init(description: "description", amount: 10000, string: "invstr", expiry: 100000, payment_hash: Data(), created_at: 1000000)])
InvoicesView(invoices: [Invoice.init(description: "description", amount: .specific(10000), string: "invstr", expiry: 100000, payment_hash: Data(), created_at: 1000000)])
.frame(width: 300)
}
}
+65
View File
@@ -0,0 +1,65 @@
//
// NIP05Badge.swift
// damus
//
// Created by William Casarin on 2023-01-11.
//
import SwiftUI
struct NIP05Badge: View {
let nip05: NIP05
let pubkey: String
let contacts: Contacts
let show_domain: Bool
let clickable: Bool
@Environment(\.openURL) var openURL
init (nip05: NIP05, pubkey: String, contacts: Contacts, show_domain: Bool, clickable: Bool) {
self.nip05 = nip05
self.pubkey = pubkey
self.contacts = contacts
self.show_domain = show_domain
self.clickable = clickable
}
var nip05_color: Color {
return get_nip05_color(pubkey: pubkey, contacts: contacts)
}
var body: some View {
HStack(spacing: 2) {
Image(systemName: "checkmark.seal.fill")
.font(.footnote)
.foregroundColor(nip05_color)
if show_domain {
if clickable {
Text(nip05.host)
.foregroundColor(nip05_color)
.onTapGesture {
if let nip5url = nip05.siteUrl {
openURL(nip5url)
}
}
} else {
Text(nip05.host)
.foregroundColor(nip05_color)
}
}
}
}
}
func get_nip05_color(pubkey: String, contacts: Contacts) -> Color {
return contacts.is_friend_or_self(pubkey) ? .accentColor : .gray
}
struct NIP05Badge_Previews: PreviewProvider {
static var previews: some View {
let test_state = test_damus_state()
NIP05Badge(nip05: NIP05(username: "jb55", host: "jb55.com"), pubkey: test_state.pubkey, contacts: test_state.contacts, show_domain: true, clickable: false)
}
}
+34
View File
@@ -0,0 +1,34 @@
//
// Reposted.swift
// damus
//
// Created by William Casarin on 2023-01-11.
//
import SwiftUI
struct Reposted: View {
let damus: DamusState
let pubkey: String
let profile: Profile?
var body: some View {
HStack(alignment: .center) {
Image(systemName: "arrow.2.squarepath")
.font(.footnote)
.foregroundColor(Color.gray)
ProfileName(pubkey: pubkey, profile: profile, damus: damus, show_friend_confirmed: true, show_nip5_domain: false)
.foregroundColor(Color.gray)
Text("Reposted", comment: "Text indicating that the post was reposted (i.e. re-shared).")
.font(.footnote)
.foregroundColor(Color.gray)
}
}
}
struct Reposted_Previews: PreviewProvider {
static var previews: some View {
let test_state = test_damus_state()
Reposted(damus: test_state, pubkey: test_state.pubkey, profile: make_test_profile())
}
}
+2 -2
View File
@@ -20,7 +20,7 @@ struct TextFieldAlert<Presenting>: View where Presenting: View {
.disabled(isShowing)
VStack {
Text(self.title)
TextField("Relay", text: self.$text)
TextField(NSLocalizedString("Relay", comment: "Text field for relay server. Used for testing purposes."), text: self.$text)
Divider()
HStack {
Button(action: {
@@ -28,7 +28,7 @@ struct TextFieldAlert<Presenting>: View where Presenting: View {
self.isShowing.toggle()
}
}) {
Text("Dismiss")
Text("Dismiss", comment: "Button to dismiss a text field alert.")
}
}
}
+38
View File
@@ -0,0 +1,38 @@
//
// WebsiteLink.swift
// damus
//
// Created by William Casarin on 2023-01-22.
//
import SwiftUI
struct WebsiteLink: View {
let url: URL
@Environment(\.openURL) var openURL
var body: some View {
HStack {
Image(systemName: "link")
.foregroundColor(.gray)
.font(.footnote)
Button(action: {
openURL(url)
}, label: {
Text(link_text)
.font(.footnote)
})
}
}
var link_text: String {
url.host ?? url.absoluteString
}
}
struct WebsiteLink_Previews: PreviewProvider {
static var previews: some View {
WebsiteLink(url: URL(string: "https://jb55.com")!)
}
}
+105 -64
View File
@@ -13,7 +13,10 @@ var BOOTSTRAP_RELAYS = [
"wss://relay.damus.io",
"wss://nostr-relay.wlvs.space",
"wss://nostr.fmt.wiz.biz",
"wss://relay.nostr.bg",
"wss://nostr.oxtr.dev",
"wss://nostr.v0l.io",
"wss://brb.io",
]
struct TimestampedProfile {
@@ -41,6 +44,15 @@ enum ThreadState {
enum FilterState : Int {
case posts_and_replies = 1
case posts = 0
func filter(ev: NostrEvent) -> Bool {
switch self {
case .posts:
return !ev.is_reply(nil)
case .posts_and_replies:
return true
}
}
}
struct ContentView: View {
@@ -68,7 +80,9 @@ struct ContentView: View {
@State var thread_open: Bool = false
@State var search_open: Bool = false
@State var filter_state : FilterState = .posts_and_replies
@State private var isSideBarOpened = false
@StateObject var home: HomeModel = HomeModel()
@StateObject var user_settings = UserSettingsStore()
// connect retry timer
let timer = Timer.publish(every: 4, on: .main, in: .common).autoconnect()
@@ -78,19 +92,26 @@ struct ContentView: View {
@Environment(\.colorScheme) var colorScheme
var PostingTimelineView: some View {
VStack{
VStack {
ZStack {
if let damus = self.damus_state {
TimelineView(events: $home.events, loading: $home.loading, damus: damus, show_friend_icon: false, filter: filter_event)
TabView(selection: $filter_state) {
contentTimelineView(filter: FilterState.posts.filter)
.tag(FilterState.posts)
.id(FilterState.posts)
contentTimelineView(filter: FilterState.posts_and_replies.filter)
.tag(FilterState.posts_and_replies)
.id(FilterState.posts_and_replies)
}
.tabViewStyle(.page(indexDisplayMode: .never))
if privkey != nil {
PostButtonContainer {
PostButtonContainer(userSettings: user_settings) {
self.active_sheet = .post
}
}
}
}
.safeAreaInset(edge: .top) {
.safeAreaInset(edge: .top, spacing: 0) {
VStack(spacing: 0) {
FiltersView
//.frame(maxWidth: 275)
@@ -102,22 +123,22 @@ struct ContentView: View {
}
}
var FiltersView: some View {
VStack{
Picker("Filter State", selection: $filter_state) {
Text("Posts").tag(FilterState.posts)
Text("Posts & Replies").tag(FilterState.posts_and_replies)
func contentTimelineView(filter: (@escaping (NostrEvent) -> Bool)) -> some View {
ZStack {
if let damus = self.damus_state {
TimelineView(events: $home.events, loading: $home.loading, damus: damus, show_friend_icon: false, filter: filter)
}
.pickerStyle(.segmented)
}
}
func filter_event(_ ev: NostrEvent) -> Bool {
if self.filter_state == .posts {
return !ev.is_reply(nil)
var FiltersView: some View {
VStack{
Picker(NSLocalizedString("Filter State", comment: "Filter state for seeing either only posts, or posts & replies."), selection: $filter_state) {
Text("Posts", comment: "Label for filter for seeing only posts (instead of posts and replies).").tag(FilterState.posts)
Text("Posts & Replies", comment: "Label for filter for seeing posts and replies (instead of only posts).").tag(FilterState.posts_and_replies)
}
.pickerStyle(.segmented)
}
return true
}
func MainContent(damus: DamusState) -> some View {
@@ -140,7 +161,7 @@ struct ContentView: View {
case .notifications:
TimelineView(events: $home.notifications, loading: $home.loading, damus: damus, show_friend_icon: true, filter: { _ in true })
.navigationTitle("Notifications")
.navigationTitle(NSLocalizedString("Notifications", comment: "Navigation title for notifications."))
case .dms:
DirectMessagesView(damus_state: damus_state!)
@@ -150,7 +171,30 @@ struct ContentView: View {
EmptyView()
}
}
.navigationBarTitle(selected_timeline == .home ? "Home" : "Global", displayMode: .inline)
.navigationBarTitle(selected_timeline == .home ? NSLocalizedString("Home", comment: "Navigation bar title for Home view where posts and replies appear from those who the user is following.") : NSLocalizedString("Global", comment: "Navigation bar title for Global view where posts from all connected relay servers appear."), displayMode: .inline)
.toolbar {
ToolbarItem(placement: .principal) {
switch selected_timeline {
case .home:
Image("damus-home")
.resizable()
.frame(width:30,height:30)
.shadow(color: Color("DamusPurple"), radius: 2)
case .dms:
Text("DMs", comment: "Toolbar label for DMs view, where DM is the English abbreviation for Direct Message.")
.bold()
case .notifications:
Text("Notifications", comment: "Toolbar label for Notifications view.")
.bold()
case .search:
Text("Global", comment: "Toolbar label for Global view where posts from all connected relay servers appear.")
.bold()
case .none:
Text("", comment: "Toolbar label for unknown views. This label would be displayed only if a new timeline view is added but a toolbar label was not explicitly assigned to it yet.")
}
}
}
.ignoresSafeArea(.keyboard)
}
var MaybeSearchView: some View {
@@ -166,8 +210,7 @@ struct ContentView: View {
var MaybeThreadView: some View {
Group {
if let evid = self.active_event_id {
let thread_model = ThreadModel(evid: evid, damus_state: damus_state!)
ThreadView(thread: thread_model, damus: damus_state!, is_chatroom: false)
BuildThreadV2View(damus: damus_state!, event_id: evid)
} else {
EmptyView()
}
@@ -185,50 +228,49 @@ struct ContentView: View {
}
}
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
if let damus = self.damus_state {
NavigationView {
MainContent(damus: damus)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
let profile_model = ProfileModel(pubkey: damus_state!.pubkey, damus: damus_state!)
let followers_model = FollowersModel(damus_state: damus_state!, target: damus_state!.pubkey)
let prof_dest = ProfileView(damus_state: damus_state!, profile: profile_model, followers: followers_model)
ZStack {
VStack {
MainContent(damus: damus)
.toolbar() {
ToolbarItem(placement: .navigationBarLeading) {
Button {
isSideBarOpened.toggle()
} label: {
ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles)
}
}
ToolbarItem(placement: .navigationBarTrailing) {
HStack(alignment: .center) {
if home.signal.signal != home.signal.max_signal {
Text("\(home.signal.signal)/\(home.signal.max_signal)", comment: "Fraction of how many of the user's relay servers that are operational.")
.font(.callout)
.foregroundColor(.gray)
}
NavigationLink(destination: prof_dest) {
/// Verify that the user has a profile picture, if not display a generic SF Symbol
/// (Resolves an in-app error where ``Robohash`` pictures are not generated so the button dissapears
if let picture = damus_state?.profiles.lookup(id: pubkey)?.picture {
ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles, picture: picture)
} else {
Image(systemName: "person.fill")
}
}
}
.buttonStyle(PlainButtonStyle())
}
ToolbarItem(placement: .navigationBarTrailing) {
HStack(alignment: .center) {
if home.signal.signal != home.signal.max_signal {
Text("\(home.signal.signal)/\(home.signal.max_signal)")
.font(.callout)
.foregroundColor(.gray)
}
NavigationLink(destination: ConfigView(state: damus_state!)) {
Label("", systemImage: "gear")
}
.buttonStyle(PlainButtonStyle())
}
}
}
Color.clear
.overlay(
SideMenuView(damus_state: damus, isSidebarVisible: $isSideBarOpened)
)
}
.navigationBarHidden(isSideBarOpened ? true: false) // Would prefer a different way of doing this.
}
.navigationViewStyle(.stack)
TabBar(new_events: $home.new_events, selected: $selected_timeline, isSidebarVisible: $isSideBarOpened, action: switch_timeline)
.padding([.bottom], 8)
}
TabBar(new_events: $home.new_events, selected: $selected_timeline, action: switch_timeline)
}
.onAppear() {
self.connect()
@@ -269,7 +311,6 @@ struct ContentView: View {
guard let privkey = self.privkey else {
return
}
let ev = notif.object as! NostrEvent
let boost = make_boost_event(pubkey: pubkey, privkey: privkey, boosted: ev)
self.damus_state?.pool.send(.event(boost))
@@ -302,10 +343,10 @@ struct ContentView: View {
let pk = target.pubkey
if let ev = unfollow_user(pool: damus.pool,
our_contacts: damus.contacts.event,
pubkey: damus.pubkey,
privkey: privkey,
unfollow: pk) {
our_contacts: damus.contacts.event,
pubkey: damus.pubkey,
privkey: privkey,
unfollow: pk) {
notify(.unfollowed, pk)
damus.contacts.event = ev
@@ -324,10 +365,10 @@ struct ContentView: View {
}
if let ev = follow_user(pool: damus.pool,
our_contacts: damus.contacts.event,
pubkey: damus.pubkey,
privkey: privkey,
follow: ReferencedId(ref_id: fnotify.pubkey, relay_id: nil, key: "p")) {
our_contacts: damus.contacts.event,
pubkey: damus.pubkey,
privkey: privkey,
follow: ReferencedId(ref_id: fnotify.pubkey, relay_id: nil, key: "p")) {
notify(.followed, fnotify.pubkey)
damus_state?.contacts.event = ev
@@ -397,10 +438,11 @@ struct ContentView: View {
self.damus_state = DamusState(pool: pool, keypair: keypair,
likes: EventCounter(our_pubkey: pubkey),
boosts: EventCounter(our_pubkey: pubkey),
contacts: Contacts(),
contacts: Contacts(our_pubkey: pubkey),
tips: TipCounter(our_pubkey: pubkey),
profiles: Profiles(),
dms: home.dms
dms: home.dms,
previews: PreviewCache()
)
home.damus_state = self.damus_state!
@@ -416,7 +458,6 @@ struct ContentView_Previews: PreviewProvider {
}
}
func get_since_time(last_event: NostrEvent?) -> Int64? {
if let last_event = last_event {
return last_event.created_at - 60 * 10
+17
View File
@@ -15,6 +15,23 @@
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>river</string>
<string>bitcoinbeach</string>
<string>breez</string>
<string>muun</string>
<string>zeusln</string>
<string>zebedee</string>
<string>lightning</string>
<string>squarecash</string>
<string>phoenix</string>
<string>lnlink</string>
<string>strike</string>
<string>bluewallet</string>
<string>walletofsatoshi</string>
<string>blixtwallet</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
+8
View File
@@ -16,6 +16,10 @@ class ActionBarModel: ObservableObject {
@Published var boosts: Int
@Published var tips: Int64
static func empty() -> ActionBarModel {
return ActionBarModel(likes: 0, boosts: 0, tips: 0, our_like: nil, our_boost: nil, our_tip: nil)
}
init(likes: Int, boosts: Int, tips: Int64, our_like: NostrEvent?, our_boost: NostrEvent?, our_tip: NostrEvent?) {
self.likes = likes
self.boosts = boosts
@@ -25,6 +29,10 @@ class ActionBarModel: ObservableObject {
self.our_tip = our_tip
}
var is_empty: Bool {
return likes == 0 && boosts == 0 && tips == 0
}
var tipped: Bool {
return our_tip != nil
}
+14 -10
View File
@@ -11,8 +11,13 @@ import Foundation
class Contacts {
private var friends: Set<String> = Set()
private var friend_of_friends: Set<String> = Set()
let our_pubkey: String
var event: NostrEvent?
init(our_pubkey: String) {
self.our_pubkey = our_pubkey
}
func get_friendosphere() -> [String] {
var fs = get_friend_list()
fs.append(contentsOf: get_friend_of_friend_list())
@@ -56,6 +61,10 @@ class Contacts {
return friends.contains(pubkey)
}
func is_friend_or_self(_ pubkey: String) -> Bool {
return pubkey == our_pubkey || is_friend(pubkey)
}
func follow_state(_ pubkey: String) -> FollowState {
return is_friend(pubkey) ? .follows : .unfollows
}
@@ -139,16 +148,12 @@ func decode_json_relays(_ content: String) -> [String: RelayInfo]? {
return decode_json(content)
}
func remove_relay(ev: NostrEvent, privkey: String, relay: String) -> NostrEvent? {
let damus_relay = RelayDescriptor(url: URL(string: "wss://relay.damus.io")!, info: .rw)
var relays = ensure_relay_info(relays: [damus_relay], content: ev.content)
guard relays.index(forKey: relay) != nil else {
return nil
}
func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], privkey: String, relay: String) -> NostrEvent? {
var relays = ensure_relay_info(relays: current_relays, content: ev.content)
relays.removeValue(forKey: relay)
print("remove_relay \(relays)")
guard let content = encode_json(relays) else {
return nil
}
@@ -159,10 +164,9 @@ func remove_relay(ev: NostrEvent, privkey: String, relay: String) -> NostrEvent?
return new_ev
}
func add_relay(ev: NostrEvent, privkey: String, relay: String, info: RelayInfo) -> NostrEvent? {
let damus_relay = RelayDescriptor(url: URL(string: "wss://relay.damus.io")!, info: .rw)
func add_relay(ev: NostrEvent, privkey: String, current_relays: [RelayDescriptor], relay: String, info: RelayInfo) -> NostrEvent? {
var relays = ensure_relay_info(relays: current_relays, content: ev.content)
var relays = ensure_relay_info(relays: [damus_relay], content: ev.content)
guard relays.index(forKey: relay) == nil else {
return nil
}
+8 -1
View File
@@ -6,6 +6,7 @@
//
import Foundation
import LinkPresentation
struct DamusState {
let pool: RelayPool
@@ -16,12 +17,18 @@ struct DamusState {
let tips: TipCounter
let profiles: Profiles
let dms: DirectMessagesModel
let previews: PreviewCache
var pubkey: String {
return keypair.pubkey
}
var is_privkey_user: Bool {
keypair.privkey != nil
}
static var empty: DamusState {
return DamusState.init(pool: RelayPool(), keypair: Keypair(pubkey: "", privkey: ""), likes: EventCounter(our_pubkey: ""), boosts: EventCounter(our_pubkey: ""), contacts: Contacts(), tips: TipCounter(our_pubkey: ""), profiles: Profiles(), dms: DirectMessagesModel())
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())
}
}
+26 -5
View File
@@ -8,13 +8,34 @@
import Foundation
class DirectMessageModel: ObservableObject {
@Published var events: [NostrEvent]
init(events: [NostrEvent]) {
self.events = events
@Published var events: [NostrEvent] {
didSet {
is_request = determine_is_request()
}
}
init() {
var is_request: Bool
var our_pubkey: String
func determine_is_request() -> Bool {
for event in events {
if event.pubkey == our_pubkey {
return false
}
}
return true
}
init(events: [NostrEvent], our_pubkey: String) {
self.events = events
self.is_request = false
self.our_pubkey = our_pubkey
}
init(our_pubkey: String) {
self.events = []
self.is_request = false
self.our_pubkey = our_pubkey
}
}
+14 -1
View File
@@ -10,13 +10,26 @@ import Foundation
class DirectMessagesModel: ObservableObject {
@Published var dms: [(String, DirectMessageModel)] = []
@Published var loading: Bool = false
let our_pubkey: String
init(our_pubkey: String) {
self.our_pubkey = our_pubkey
}
var message_requests: [(String, DirectMessageModel)] {
return dms.filter { dm in dm.1.is_request }
}
var friend_dms: [(String, DirectMessageModel)] {
return dms.filter { dm in !dm.1.is_request }
}
func lookup_or_create(_ pubkey: String) -> DirectMessageModel {
if let dm = lookup(pubkey) {
return dm
}
let new = DirectMessageModel()
let new = DirectMessageModel(our_pubkey: our_pubkey)
dms.append((pubkey, new))
return new
}
+27 -28
View File
@@ -18,11 +18,11 @@ class FollowersModel: ObservableObject {
let sub_id: String = UUID().description
let profiles_id: String = UUID().description
var count_display: String {
var count: Int? {
guard let contacts = self.contacts else {
return "?"
return nil
}
return "\(contacts.count)";
return contacts.count
}
init(damus_state: DamusState, target: String) {
@@ -73,31 +73,30 @@ class FollowersModel: ObservableObject {
}
func handle_event(relay_id: String, ev: NostrConnectionEvent) {
switch ev {
case .ws_event:
break
case .nostr_event(let nev):
switch nev {
case .event(let sub_id, let ev):
guard sub_id == self.sub_id || sub_id == self.profiles_id else {
return
}
if ev.known_kind == .contacts {
handle_contact_event(ev)
} else if ev.known_kind == .metadata {
process_metadata_event(profiles: damus_state.profiles, ev: ev)
}
case .notice(let msg):
print("followingmodel notice: \(msg)")
case .eose(let sub_id):
if sub_id == self.sub_id {
load_profiles(relay_id: relay_id)
} else if sub_id == self.profiles_id {
damus_state.pool.unsubscribe(sub_id: profiles_id, to: [relay_id])
}
guard case .nostr_event(let nev) = ev else {
return
}
switch nev {
case .event(let sub_id, let ev):
guard sub_id == self.sub_id || sub_id == self.profiles_id else {
return
}
if ev.known_kind == .contacts {
handle_contact_event(ev)
} else if ev.known_kind == .metadata {
process_metadata_event(profiles: damus_state.profiles, ev: ev)
}
case .notice(let msg):
print("followingmodel notice: \(msg)")
case .eose(let sub_id):
if sub_id == self.sub_id {
load_profiles(relay_id: relay_id)
} else if sub_id == self.profiles_id {
damus_state.pool.unsubscribe(sub_id: profiles_id, to: [relay_id])
}
}
}
+194 -94
View File
@@ -44,20 +44,23 @@ class HomeModel: ObservableObject {
let notifications_subid = UUID().description
let dms_subid = UUID().description
let init_subid = UUID().description
let profiles_subid = UUID().description
@Published var new_events: NewEventsBits = NewEventsBits()
@Published var notifications: [NostrEvent] = []
@Published var dms: DirectMessagesModel = DirectMessagesModel()
@Published var dms: DirectMessagesModel
@Published var events: [NostrEvent] = []
@Published var loading: Bool = false
@Published var signal: SignalModel = SignalModel()
init() {
self.damus_state = DamusState.empty
self.dms = DirectMessagesModel(our_pubkey: damus_state.pubkey)
}
init(damus_state: DamusState) {
self.damus_state = damus_state
self.dms = DirectMessagesModel(our_pubkey: damus_state.pubkey)
}
var pool: RelayPool {
@@ -234,7 +237,15 @@ class HomeModel: ObservableObject {
//self.events.insert(NostrEvent(content: "NOTICE from \(relay_id): \(msg)", pubkey: "system"), at: 0)
print(msg)
case .eose:
case .eose(let sub_id):
if sub_id == dms_subid {
let dms = dms.dms.flatMap { $0.1.events }
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, events: dms, damus_state: damus_state)
} else if sub_id == notifications_subid {
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, events: notifications, damus_state: damus_state)
}
self.loading = false
break
}
@@ -260,6 +271,9 @@ class HomeModel: ObservableObject {
var contacts_filter = NostrFilter.filter_kinds([0])
contacts_filter.authors = friends
var our_contacts_filter = NostrFilter.filter_kinds([3, 0])
our_contacts_filter.authors = [damus_state.pubkey]
var dms_filter = NostrFilter.filter_kinds([
NostrKind.dm.rawValue,
@@ -297,7 +311,7 @@ class HomeModel: ObservableObject {
var home_filters = [home_filter]
var notifications_filters = [notifications_filter]
var contacts_filters = [contacts_filter]
var contacts_filters = [contacts_filter, our_contacts_filter]
var dms_filters = [dms_filter, our_dms_filter]
let last_of_kind = relay_id.flatMap { last_event_of_kind[$0] } ?? [:]
@@ -335,22 +349,23 @@ class HomeModel: ObservableObject {
return m[kind]
}
func handle_last_event(ev: NostrEvent, timeline: Timeline) {
let last_ev = get_last_event(timeline)
if last_ev == nil || last_ev!.created_at < ev.created_at {
save_last_event(ev, timeline: timeline)
new_events = NewEventsBits(prev: new_events, setting: timeline)
}
}
func handle_notification(ev: NostrEvent) {
guard event_has_our_pubkey(ev, our_pubkey: self.damus_state.pubkey) else {
return
}
if !insert_uniq_sorted_event(events: &notifications, new_ev: ev, cmp: { $0.created_at > $1.created_at }) {
return
}
handle_last_event(ev: ev, timeline: .notifications)
}
func handle_last_event(ev: NostrEvent, timeline: Timeline, shouldNotify: Bool = true) {
if let new_bits = handle_last_events(new_events: self.new_events, ev: ev, timeline: timeline, shouldNotify: shouldNotify) {
new_events = new_bits
}
}
func insert_home_event(_ ev: NostrEvent) -> Bool {
let ok = insert_uniq_sorted_event(events: &self.events, new_ev: ev, cmp: { $0.created_at > $1.created_at })
@@ -377,49 +392,8 @@ class HomeModel: ObservableObject {
}
func handle_dm(_ ev: NostrEvent) {
var inserted = false
var found = false
let ours = ev.pubkey == self.damus_state.pubkey
var i = 0
var the_pk = ev.pubkey
if ours {
if let ref_pk = ev.referenced_pubkeys.first {
the_pk = ref_pk.ref_id
} else {
// self dm!?
print("TODO: handle self dm?")
}
}
for (pk, _) in dms.dms {
if pk == the_pk {
found = true
inserted = insert_uniq_sorted_event(events: &(dms.dms[i].1.events), new_ev: ev) {
$0.created_at < $1.created_at
}
break
}
i += 1
}
if !found {
inserted = true
let model = DirectMessageModel(events: [ev])
dms.dms.append((the_pk, model))
}
if inserted {
handle_last_event(ev: ev, timeline: .dms)
dms.dms = dms.dms.sorted { a, b in
if a.1.events.count > 0 && b.1.events.count > 0 {
return a.1.events.last!.created_at > b.1.events.last!.created_at
}
return true
}
if let notifs = handle_incoming_dm(prev_events: self.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, ev: ev) {
self.new_events = notifs
}
}
}
@@ -443,18 +417,33 @@ func add_contact_if_friend(contacts: Contacts, ev: NostrEvent) {
contacts.add_friend_contact(ev)
}
func load_our_contacts(contacts: Contacts, our_pubkey: String, ev: NostrEvent) {
guard ev.pubkey == our_pubkey else {
return
}
contacts.event = ev
func load_our_contacts(contacts: Contacts, our_pubkey: String, m_old_ev: NostrEvent?, ev: NostrEvent) {
var new_pks = Set<String>()
// our contacts
for tag in ev.tags {
if tag.count > 1 && tag[0] == "p" {
// TODO: validate pubkey?
contacts.add_friend_pubkey(tag[1])
if tag.count >= 2 && tag[0] == "p" {
new_pks.insert(tag[1])
}
}
var old_pks = Set<String>()
// find removed contacts
if let old_ev = m_old_ev {
for tag in old_ev.tags {
if tag.count >= 2 && tag[0] == "p" {
old_pks.insert(tag[1])
}
}
}
let diff = new_pks.symmetricDifference(old_pks)
for pk in diff {
if new_pks.contains(pk) {
notify(.followed, pk)
contacts.add_friend_pubkey(pk)
} else {
notify(.unfollowed, pk)
contacts.remove_friend(pk)
}
}
}
@@ -515,7 +504,9 @@ func process_metadata_event(profiles: Profiles, ev: NostrEvent) {
return
}
var old_nip05: String? = nil
if let mprof = profiles.lookup_with_timestamp(id: ev.pubkey) {
old_nip05 = mprof.profile.nip05
if mprof.timestamp > ev.created_at {
// skip if we already have an newer profile
return
@@ -525,6 +516,20 @@ func process_metadata_event(profiles: Profiles, ev: NostrEvent) {
let tprof = TimestampedProfile(profile: profile, timestamp: ev.created_at)
profiles.add(id: ev.pubkey, profile: tprof)
if let nip05 = profile.nip05, old_nip05 != profile.nip05 {
Task.detached(priority: .background) {
let validated = await validate_nip05(pubkey: ev.pubkey, nip05_str: nip05)
if validated != nil {
print("validated nip05 for '\(nip05)'")
}
DispatchQueue.main.async {
profiles.validated[ev.pubkey] = validated
notify(.profile_updated, ProfileUpdate(pubkey: ev.pubkey, profile: profile))
}
}
}
// load pfps asap
let picture = tprof.profile.picture ?? robohash(ev.pubkey)
if let _ = URL(string: picture) {
@@ -533,6 +538,13 @@ func process_metadata_event(profiles: Profiles, ev: NostrEvent) {
}
}
let banner = tprof.profile.banner ?? ""
if let _ = URL(string: banner) {
DispatchQueue.main.async {
notify(.profile_updated, ProfileUpdate(pubkey: ev.pubkey, profile: profile))
}
}
notify(.profile_updated, ProfileUpdate(pubkey: ev.pubkey, profile: profile))
}
@@ -540,51 +552,139 @@ func robohash(_ pk: String) -> String {
return "https://robohash.org/" + pk
}
func load_our_stuff(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
guard ev.pubkey == pubkey else {
return
}
// only use new stuff
if let current_ev = contacts.event {
guard ev.created_at > current_ev.created_at else {
return
}
}
let m_old_ev = contacts.event
contacts.event = ev
load_our_contacts(contacts: contacts, our_pubkey: pubkey, m_old_ev: m_old_ev, ev: ev)
load_our_relays(contacts: contacts, our_pubkey: pubkey, pool: pool, m_old_ev: m_old_ev, ev: ev)
}
func process_contact_event(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
load_our_contacts(contacts: contacts, our_pubkey: pubkey, ev: ev)
load_our_relays(our_pubkey: pubkey, pool: pool, ev: ev)
load_our_stuff(pool: pool, contacts: contacts, pubkey: pubkey, ev: ev)
add_contact_if_friend(contacts: contacts, ev: ev)
}
func load_our_relays(our_pubkey: String, pool: RelayPool, ev: NostrEvent) {
guard ev.pubkey == our_pubkey else {
return
func load_our_relays(contacts: Contacts, our_pubkey: String, pool: RelayPool, m_old_ev: NostrEvent?, ev: NostrEvent) {
let bootstrap_dict: [String: RelayInfo] = [:]
let old_decoded = m_old_ev.flatMap { decode_json_relays($0.content) } ?? BOOTSTRAP_RELAYS.reduce(into: bootstrap_dict) { (d, r) in
d[r] = .rw
}
guard let decoded = decode_json_relays(ev.content) else {
return
}
var changed = false
var new = Set<String>()
for key in decoded.keys {
if let url = URL(string: key) {
if let _ = try? pool.add_relay(url, info: decoded[key]!) {
pool.connect(to: [key])
new.insert(key)
}
var old = Set<String>()
for key in old_decoded.keys {
old.insert(key)
}
let diff = old.symmetricDifference(new)
for d in diff {
changed = true
if new.contains(d) {
if let url = URL(string: d) {
try? pool.add_relay(url, info: decoded[d] ?? .rw)
}
} else {
pool.remove_relay(d)
}
}
if changed {
notify(.relays_changed, ())
}
}
func handle_incoming_dm(prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: String, ev: NostrEvent) -> NewEventsBits? {
var inserted = false
var found = false
let ours = ev.pubkey == our_pubkey
var i = 0
func remove_bootstrap_nodes(_ damus_state: DamusState) {
guard let contacts = damus_state.contacts.event else {
return
}
guard let relays = decode_json_relays(contacts.content) else {
return
}
let descriptors = relays.reduce(into: []) { arr, kv in
guard let url = URL(string: kv.key) else {
return
}
arr.append(RelayDescriptor(url: url, info: kv.value))
}
for relay in BOOTSTRAP_RELAYS {
if !(descriptors.contains { ($0 as! RelayDescriptor).url.absoluteString == relay }) {
damus_state.pool.remove_relay(relay)
var the_pk = ev.pubkey
if ours {
if let ref_pk = ev.referenced_pubkeys.first {
the_pk = ref_pk.ref_id
} else {
// self dm!?
print("TODO: handle self dm?")
}
}
for (pk, _) in dms.dms {
if pk == the_pk {
found = true
inserted = insert_uniq_sorted_event(events: &(dms.dms[i].1.events), new_ev: ev) {
$0.created_at < $1.created_at
}
break
}
i += 1
}
if !found {
inserted = true
let model = DirectMessageModel(events: [ev], our_pubkey: our_pubkey)
dms.dms.append((the_pk, model))
}
var new_events: NewEventsBits? = nil
if inserted {
new_events = handle_last_events(new_events: prev_events, ev: ev, timeline: .dms, shouldNotify: !ours)
dms.dms = dms.dms.filter({ $0.1.events.count > 0 }).sorted { a, b in
return a.1.events.last!.created_at > b.1.events.last!.created_at
}
}
return new_events
}
/// A helper to determine if we need to notify the user of new events
func handle_last_events(new_events: NewEventsBits, ev: NostrEvent, timeline: Timeline, shouldNotify: Bool = true) -> NewEventsBits? {
let last_ev = get_last_event(timeline)
if last_ev == nil || last_ev!.created_at < ev.created_at {
save_last_event(ev, timeline: timeline)
if shouldNotify {
return NewEventsBits(prev: new_events, setting: timeline)
}
}
return nil
}
/// Sometimes we get garbage in our notifications. Ensure we have our pubkey on this event
func event_has_our_pubkey(_ ev: NostrEvent, our_pubkey: String) -> Bool {
for tag in ev.tags {
if tag.count >= 2 && tag[0] == "p" && tag[1] == our_pubkey {
return true
}
}
return false
}
+108
View File
@@ -0,0 +1,108 @@
//
// KFImageModel.swift
// damus
//
// Created by Oleg Abalonski on 1/11/23.
//
import Foundation
import Kingfisher
import SVGKit
class KFImageModel: ObservableObject {
let url: URL?
let fallbackUrl: URL?
let processor: ImageProcessor
let serializer: CacheSerializer
@Published var refreshID = ""
init(url: URL?, fallbackUrl: URL?, maxByteSize: Int, downsampleSize: CGSize) {
self.url = url
self.fallbackUrl = fallbackUrl
self.processor = CustomImageProcessor(maxSize: maxByteSize, downsampleSize: downsampleSize)
self.serializer = CustomCacheSerializer(maxSize: maxByteSize, downsampleSize: downsampleSize)
}
func refresh() -> Void {
DispatchQueue.main.async {
self.refreshID = UUID().uuidString
}
}
func cache(_ image: UIImage, forKey key: String) -> Void {
KingfisherManager.shared.cache.store(image, forKey: key, processorIdentifier: processor.identifier) { _ in
self.refresh()
}
}
func downloadFailed() -> Void {
guard let url = url, let fallbackUrl = fallbackUrl else { return }
DispatchQueue.global(qos: .background).async {
KingfisherManager.shared.downloader.downloadImage(with: fallbackUrl) { result in
var fallbackImage: UIImage {
switch result {
case .success(let imageLoadingResult):
return imageLoadingResult.image
case .failure(let error):
print(error)
return UIImage()
}
}
self.cache(fallbackImage, forKey: url.absoluteString)
}
}
}
}
struct CustomImageProcessor: ImageProcessor {
let maxSize: Int
let downsampleSize: CGSize
let identifier = "com.damus.customimageprocessor"
func process(item: ImageProcessItem, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? {
switch item {
case .image(_):
// This case will never run
return DefaultImageProcessor.default.process(item: item, options: options)
case .data(let data):
// Handle large image size
if data.count > maxSize {
return KingfisherWrapper.downsampledImage(data: data, to: downsampleSize, scale: options.scaleFactor)
}
// Handle SVG image
if let svgImage = SVGKImage(data: data), let image = svgImage.uiImage {
return image.kf.scaled(to: options.scaleFactor)
}
return DefaultImageProcessor.default.process(item: item, options: options)
}
}
}
struct CustomCacheSerializer: CacheSerializer {
let maxSize: Int
let downsampleSize: CGSize
func data(with image: Kingfisher.KFCrossPlatformImage, original: Data?) -> Data? {
return DefaultCacheSerializer.default.data(with: image, original: original)
}
func image(with data: Data, options: Kingfisher.KingfisherParsedOptionsInfo) -> Kingfisher.KFCrossPlatformImage? {
if data.count > maxSize {
return KingfisherWrapper.downsampledImage(data: data, to: downsampleSize, scale: options.scaleFactor)
}
return DefaultCacheSerializer.default.image(with: data, options: options)
}
}

Some files were not shown because too many files have changed in this diff Show More