Compare commits

..

1 Commits

Author SHA1 Message Date
tyiu a72f964111 Fix localized string for privacy access description for photos 2023-01-21 16:01:31 -05:00
90 changed files with 553 additions and 17138 deletions
+8 -22
View File
@@ -1,6 +1,4 @@
name: Run Test Suite
run-name: Testing ${{ github.ref }} by @${{ github.actor }}
name: Test
on:
push:
branches:
@@ -8,24 +6,12 @@ on:
pull_request:
branches:
- "*"
jobs:
run_tests:
runs-on: macos-12
strategy:
matrix:
include:
- xcode: "14.2"
ios: "16.2"
name: Test iOS (${{ matrix.ios }})
test:
name: Run Tests
runs-on: macos-latest
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]}
- name: Checkout repository
uses: actions/checkout@v1
- name: Running Tests
run: xcodebuild test -scheme damus -project damus.xcodeproj -destination 'platform=iOS Simulator,name=iPhone 14,OS=16.0' | xcpretty && exit ${PIPESTATUS[0]}
-47
View File
@@ -1,50 +1,3 @@
## [1.0.0-11] - 2023-01-25
### Added
- Reposts view (Terry Yiu)
- Translations for it_IT, it_CH, fr_FR, de_DE, de_AT and lv_LV (William Casarin)
- Added ability to block users (William Casarin)
- Added a way to report content (William Casarin)
- Stretchable profile cover header (Swift)
### Changed
- Bump pfp/banner animated fize size limit to 5MiB/20MiB (William Casarin)
- Updated default boostrap relays (Ricardo Arturo Cabral Mejía)
### Fixed
- allow ws:// relays again (Steven Briscoe)
[1.0.0-11]: https://github.com/damus-io/damus/releases/tag/v1.0.0-11
## [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
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
@@ -41,14 +41,9 @@ Abbreviated version of a nostr public key.</note>
<trans-unit id="%@ %@" xml:space="preserve">
<source>%@ %@</source>
<target>%@ %@</target>
<note>Sentence composed of 2 variables to describe how many tip payments there are on a post. In source English, the first variable is the number of tip payments, and the second variable is 'Tip' or 'Tips'.
<note>Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.
Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'.</note>
</trans-unit>
<trans-unit id="%@ has been blocked" xml:space="preserve">
<source>%@ has been blocked</source>
<target>%@ has been blocked</target>
<note>Alert message that informs a user was blocked.</note>
</trans-unit>
<trans-unit id="%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction." xml:space="preserve">
<source>%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction.</source>
<target>%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction.</target>
@@ -67,7 +62,7 @@ Sentence composed of 2 variables to describe how many profiles a user is followi
<trans-unit id="%lld" xml:space="preserve">
<source>%lld</source>
<target>%lld</target>
<note>Number of tip payments on a post.
<note>Number of reposts.
Number of profiles a user is following.</note>
</trans-unit>
<trans-unit id="%lld/%lld" xml:space="preserve">
@@ -120,21 +115,11 @@ Number of profiles a user is following.</note>
<target>Absolute Boss</target>
<note>Placeholder text for About Me description.</note>
</trans-unit>
<trans-unit id="Accept" xml:space="preserve">
<source>Accept</source>
<target>Accept</target>
<note>Button to accept the end user license agreement before being allowed into the app.</note>
</trans-unit>
<trans-unit id="Account ID" xml:space="preserve">
<source>Account ID</source>
<target>Account ID</target>
<note>Label to indicate the public ID of the account.</note>
</trans-unit>
<trans-unit id="Actions" xml:space="preserve">
<source>Actions</source>
<target>Actions</target>
<note>Title for confirmation dialog to either share, report, or block a profile.</note>
</trans-unit>
<trans-unit id="Add" xml:space="preserve">
<source>Add</source>
<target>Add</target>
@@ -146,11 +131,6 @@ Number of profiles a user is following.</note>
<target>Add Relay</target>
<note>Label for section for adding a relay server.</note>
</trans-unit>
<trans-unit id="Add all" xml:space="preserve">
<source>Add all</source>
<target>Add all</target>
<note>Button label to re-add all original participants as profiles to reply to in a note</note>
</trans-unit>
<trans-unit id="Any" xml:space="preserve">
<source>Any</source>
<target>Any</target>
@@ -186,33 +166,6 @@ Number of profiles a user is following.</note>
<target>Blixt Wallet</target>
<note>Dropdown option label for Lightning wallet, Blixt Wallet</note>
</trans-unit>
<trans-unit id="Block" xml:space="preserve">
<source>Block</source>
<target>Block</target>
<note>Alert button to block a user.
Button to block a profile.
Context menu option for blocking users.</note>
</trans-unit>
<trans-unit id="Block %@?" xml:space="preserve">
<source>Block %@?</source>
<target>Block %@?</target>
<note>Alert message prompt to ask if a user should be blocked.</note>
</trans-unit>
<trans-unit id="Block User" xml:space="preserve">
<source>Block User</source>
<target>Block User</target>
<note>Title of alert for blocking a user.</note>
</trans-unit>
<trans-unit id="Blocked" xml:space="preserve">
<source>Blocked</source>
<target>Blocked</target>
<note>Sidebar menu label for Profile view.</note>
</trans-unit>
<trans-unit id="Blocked Users" xml:space="preserve">
<source>Blocked Users</source>
<target>Blocked Users</target>
<note>Navigation title of view to see list of blocked users.</note>
</trans-unit>
<trans-unit id="Blue Wallet" xml:space="preserve">
<source>Blue Wallet</source>
<target>Blue Wallet</target>
@@ -231,9 +184,7 @@ Number of profiles a user is following.</note>
<trans-unit id="Cancel" xml:space="preserve">
<source>Cancel</source>
<target>Cancel</target>
<note>Alert button to cancel out of alert for blocking a user.
Button to cancel out of alert that creates a new mutelist.
Button to cancel out of posting a note.
<note>Button to cancel out of posting a note.
Button to cancel out of reposting a post.
Button to cancel out of view adding user inputted relay.
Cancel out of logging out the user.</note>
@@ -299,19 +250,14 @@ Number of profiles a user is following.</note>
<target>Copy Note JSON</target>
<note>Context menu option for copying the JSON text from the note.</note>
</trans-unit>
<trans-unit id="Copy Report ID" xml:space="preserve">
<source>Copy Report ID</source>
<target>Copy Report ID</target>
<note>Button to copy report ID.</note>
</trans-unit>
<trans-unit id="Copy Text" xml:space="preserve">
<source>Copy Text</source>
<target>Copy Text</target>
<note>Context menu option for copying the text from an note.</note>
</trans-unit>
<trans-unit id="Copy User Pubkey" xml:space="preserve">
<source>Copy User Pubkey</source>
<target>Copy User Pubkey</target>
<trans-unit id="Copy User ID" xml:space="preserve">
<source>Copy User ID</source>
<target>Copy User ID</target>
<note>Context menu option for copying the ID of the user who created the note.</note>
</trans-unit>
<trans-unit id="Copy invoice" xml:space="preserve">
@@ -319,11 +265,6 @@ Number of profiles a user is following.</note>
<target>Copy invoice</target>
<note>Title of section for copying a Lightning invoice identifier.</note>
</trans-unit>
<trans-unit id="Could not find user to block..." xml:space="preserve">
<source>Could not find user to block...</source>
<target>Could not find user to block...</target>
<note>Alert message to indicate that the blocked user could not be found.</note>
</trans-unit>
<trans-unit id="Create" xml:space="preserve">
<source>Create</source>
<target>Create</target>
@@ -334,26 +275,25 @@ Number of profiles a user is following.</note>
<target>Create Account</target>
<note>Button to create an account.</note>
</trans-unit>
<trans-unit id="Create new mutelist" xml:space="preserve">
<source>Create new mutelist</source>
<target>Create new mutelist</target>
<note>Title of alert prompting the user to create a new mutelist.</note>
</trans-unit>
<trans-unit id="Creator(s) of Bitcoin. Absolute legend." xml:space="preserve">
<source>Creator(s) of Bitcoin. Absolute legend.</source>
<target>Creator(s) of Bitcoin. Absolute legend.</target>
<note>Example description about Bitcoin creator(s), Satoshi Nakamoto.</note>
</trans-unit>
<trans-unit id="DM" xml:space="preserve">
<source>DM</source>
<target>DM</target>
<note>Navigation title for DM view, which is the English abbreviation for Direct Message.</note>
</trans-unit>
<trans-unit id="DM Type" xml:space="preserve">
<source>DM Type</source>
<target>DM Type</target>
<note>DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet. DM is the English abbreviation for Direct Message.</note>
<note>DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet.</note>
</trans-unit>
<trans-unit id="DMs" xml:space="preserve">
<source>DMs</source>
<target>DMs</target>
<note>Navigation title for DMs view, where DM is the English abbreviation for Direct Message.
Navigation title for view of DMs, where DM is an English abbreviation for Direct Message.</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Damus" xml:space="preserve">
<source>Damus</source>
@@ -368,8 +308,7 @@ Number of profiles a user is following.</note>
<trans-unit id="Delete" xml:space="preserve">
<source>Delete</source>
<target>Delete</target>
<note>Button to delete a relay server that the user connects to.
Button to remove a user from their blocklist.</note>
<note>Button to delete a relay server that the user connects to.</note>
</trans-unit>
<trans-unit id="Dismiss" xml:space="preserve">
<source>Dismiss</source>
@@ -386,11 +325,6 @@ Number of profiles a user is following.</note>
<target>Done</target>
<note>Button to dismiss wallet selection view for paying Lightning invoice.</note>
</trans-unit>
<trans-unit id="EULA" xml:space="preserve">
<source>EULA</source>
<target>EULA</target>
<note>Label indicating that the below text is the EULA, an acronym for End User License Agreement.</note>
</trans-unit>
<trans-unit id="Earn Money" xml:space="preserve">
<source>Earn Money</source>
<target>Earn Money</target>
@@ -401,16 +335,16 @@ Number of profiles a user is following.</note>
<target>Edit</target>
<note>Button to edit user's profile.</note>
</trans-unit>
<trans-unit id="Edit participants" xml:space="preserve">
<source>Edit participants</source>
<target>Edit participants</target>
<note>Text indicating that the view is used for editing which participants are replied to in a note.</note>
</trans-unit>
<trans-unit id="Encrypted" xml:space="preserve">
<source>Encrypted</source>
<target>Encrypted</target>
<note>Heading indicating that this application keeps private messaging end-to-end encrypted.</note>
</trans-unit>
<trans-unit id="Encrypted DMs" xml:space="preserve">
<source>Encrypted DMs</source>
<target>Encrypted DMs</target>
<note>Navigation title for view of encrypted DMs, where DM is an English abbreviation for Direct Message.</note>
</trans-unit>
<trans-unit id="Enter your account key to login:" xml:space="preserve">
<source>Enter your account key to login:</source>
<target>Enter your account key to login:</target>
@@ -472,21 +406,11 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Home</target>
<note>Navigation bar title for Home view where posts and replies appear from those who the user is following.</note>
</trans-unit>
<trans-unit id="Illegal content" xml:space="preserve">
<source>Illegal content</source>
<target>Illegal content</target>
<note>Button for user to report that the account or content has illegal content.</note>
</trans-unit>
<trans-unit id="Invalid key" xml:space="preserve">
<source>Invalid key</source>
<target>Invalid key</target>
<note>Error message indicating that an invalid account key was entered for login.</note>
</trans-unit>
<trans-unit id="It's spam" xml:space="preserve">
<source>It's spam</source>
<target>It's spam</target>
<note>Button for user to report that the account or content has spam.</note>
</trans-unit>
<trans-unit id="LNLink" xml:space="preserve">
<source>LNLink</source>
<target>LNLink</target>
@@ -545,11 +469,6 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>NIP-05 Verification</target>
<note>Label for NIP-05 Verification section of user profile form.</note>
</trans-unit>
<trans-unit id="No block list found, create a new one? This will overwrite any previous block lists." xml:space="preserve">
<source>No block list found, create a new one? This will overwrite any previous block lists.</source>
<target>No block list found, create a new one? This will overwrite any previous block lists.</target>
<note>Alert message prompt that asks if the user wants to create a new block list, overwriting previous block lists.</note>
</trans-unit>
<trans-unit id="Nothing to see here. Check back later!" xml:space="preserve">
<source>Nothing to see here. Check back later!</source>
<target>Nothing to see here. Check back later!</target>
@@ -560,11 +479,6 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Notifications</target>
<note>Navigation title for notifications.</note>
</trans-unit>
<trans-unit id="Nudity or explicit content" xml:space="preserve">
<source>Nudity or explicit content</source>
<target>Nudity or explicit content</target>
<note>Button for user to report that the account or content has nudity or explicit content.</note>
</trans-unit>
<trans-unit id="Pay" xml:space="preserve">
<source>Pay</source>
<target>Pay</target>
@@ -645,11 +559,6 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Recommended Relays</target>
<note>Section title for recommend relay servers that could be added as part of configuration</note>
</trans-unit>
<trans-unit id="Reject" xml:space="preserve">
<source>Reject</source>
<target>Reject</target>
<note>Button to reject the end user license agreement, which disallows the user from being let into the app.</note>
</trans-unit>
<trans-unit id="Relay" xml:space="preserve">
<source>Relay</source>
<target>Relay</target>
@@ -660,16 +569,6 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Relays</target>
<note>Sidebar menu label for Relay servers view</note>
</trans-unit>
<trans-unit id="Relays have been notified and clients will be able to use this information to filter content. Thank you!" xml:space="preserve">
<source>Relays have been notified and clients will be able to use this information to filter content. Thank you!</source>
<target>Relays have been notified and clients will be able to use this information to filter content. Thank you!</target>
<note>Description of what was done as a result of sending a report to relay servers.</note>
</trans-unit>
<trans-unit id="Remove all" xml:space="preserve">
<source>Remove all</source>
<target>Remove all</target>
<note>Button label to remove all participants from a note reply.</note>
</trans-unit>
<trans-unit id="Reply to self" xml:space="preserve">
<source>Reply to self</source>
<target>Reply to self</target>
@@ -685,22 +584,6 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Replying to:</target>
<note>Indicating that the user is replying to the following listed people.</note>
</trans-unit>
<trans-unit id="Report" xml:space="preserve">
<source>Report</source>
<target>Report</target>
<note>Button to report a profile.
Context menu option for reporting content.</note>
</trans-unit>
<trans-unit id="Report ID:" xml:space="preserve">
<source>Report ID:</source>
<target>Report ID:</target>
<note>Label indicating that the text underneath is the identifier of the report that was sent to relay servers.</note>
</trans-unit>
<trans-unit id="Report sent!" xml:space="preserve">
<source>Report sent!</source>
<target>Report sent!</target>
<note>Message indicating that a report was successfully sent to relay servers.</note>
</trans-unit>
<trans-unit id="Repost" xml:space="preserve">
<source>Repost</source>
<target>Repost</target>
@@ -712,15 +595,10 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Reposted</target>
<note>Text indicating that the post was reposted (i.e. re-shared).</note>
</trans-unit>
<trans-unit id="Reposts" xml:space="preserve">
<source>Reposts</source>
<target>Reposts</target>
<note>Navigation bar title for Reposts view.</note>
</trans-unit>
<trans-unit id="Requests" xml:space="preserve">
<source>Requests</source>
<target>Requests</target>
<note>Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet). DM is the English abbreviation for Direct Message.</note>
<note>No comment provided by engineer.</note>
</trans-unit>
<trans-unit id="Reset" xml:space="preserve">
<source>Reset</source>
@@ -791,8 +669,7 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<trans-unit id="Share" xml:space="preserve">
<source>Share</source>
<target>Share</target>
<note>Button to share an image.
Button to share the link to a profile.</note>
<note>Button to share an image.</note>
</trans-unit>
<trans-unit id="Show" xml:space="preserve">
<source>Show</source>
@@ -814,16 +691,6 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Strike</target>
<note>Dropdown option label for Lightning wallet, Strike.</note>
</trans-unit>
<trans-unit id="Thanks!" xml:space="preserve">
<source>Thanks!</source>
<target>Thanks!</target>
<note>Button to close out of alert that informs that the action to block a user was successful.</note>
</trans-unit>
<trans-unit id="They are impersonating someone" xml:space="preserve">
<source>They are impersonating someone</source>
<target>They are impersonating someone</target>
<note>Button for user to report that the account is impersonating someone.</note>
</trans-unit>
<trans-unit id="This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective." xml:space="preserve">
<source>This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective.</source>
<target>This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective.</target>
@@ -875,16 +742,6 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Unfollows</target>
<note>Text to indicate that the button next to it is in a state that will unfollow a profile when tapped.</note>
</trans-unit>
<trans-unit id="User blocked" xml:space="preserve">
<source>User blocked</source>
<target>User blocked</target>
<note>Alert message to indicate</note>
</trans-unit>
<trans-unit id="User has been blocked" xml:space="preserve">
<source>User has been blocked</source>
<target>User has been blocked</target>
<note>Alert message that informs a user was blocked.</note>
</trans-unit>
<trans-unit id="Username" xml:space="preserve">
<source>Username</source>
<target>Username</target>
@@ -921,26 +778,11 @@ Part of a larger sentence to describe how many profiles a user is following.</no
<target>Welcome, %@!</target>
<note>Text to welcome user.</note>
</trans-unit>
<trans-unit id="What do you want to report?" xml:space="preserve">
<source>What do you want to report?</source>
<target>What do you want to report?</target>
<note>Header text to prompt user what issue they want to report.</note>
</trans-unit>
<trans-unit id="Yes, Overwrite" xml:space="preserve">
<source>Yes, Overwrite</source>
<target>Yes, Overwrite</target>
<note>Text of button that confirms to overwrite the existing mutelist.</note>
</trans-unit>
<trans-unit id="Your Name" xml:space="preserve">
<source>Your Name</source>
<target>Your Name</target>
<note>Label for Your Name section of user profile form.</note>
</trans-unit>
<trans-unit id="Your report will be sent to the relays you are connected to" xml:space="preserve">
<source>Your report will be sent to the relays you are connected to</source>
<target>Your report will be sent to the relays you are connected to</target>
<note>Footer text to inform user what will happen when the report is submitted.</note>
</trans-unit>
<trans-unit id="Zebedee" xml:space="preserve">
<source>Zebedee</source>
<target>Zebedee</target>
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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -23
View File
@@ -22,10 +22,6 @@ 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;
@@ -33,33 +29,16 @@ static void make_cursor(struct cursor *c, const u8 *content, size_t len)
c->p = content;
}
static int consume_until_boundary(struct cursor *cur) {
char c;
while (cur->p < cur->end) {
c = *cur->p;
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)
if (is_whitespace(c))
return 1;
cur->p++;
consumedAtLeastOne = true;
}
return or_end;
@@ -166,7 +145,7 @@ static int parse_hashtag(struct cursor *cur, struct block *block) {
return 0;
}
consume_until_boundary(cur);
consume_until_whitespace(cur, 1);
block->type = BLOCK_HASHTAG;
block->block.str.start = (const char*)(start + 1);
+2 -163
View File
@@ -12,9 +12,6 @@
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 */; };
@@ -128,15 +125,6 @@
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 */; };
4CC7AAFA297F64AC00430951 /* EventMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7AAF9297F64AC00430951 /* EventMenu.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 */; };
@@ -158,14 +146,6 @@
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 */; };
4CF0ABD42980996B00D66079 /* Report.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD32980996B00D66079 /* Report.swift */; };
4CF0ABD629817F5B00D66079 /* ReportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD529817F5B00D66079 /* ReportView.swift */; };
4CF0ABD82981980C00D66079 /* Lists.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABD72981980C00D66079 /* Lists.swift */; };
4CF0ABDC2981A19E00D66079 /* ListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABDB2981A19E00D66079 /* ListTests.swift */; };
4CF0ABDE2981A69500D66079 /* MutelistModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABDD2981A69500D66079 /* MutelistModel.swift */; };
4CF0ABE12981A83900D66079 /* MutelistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE02981A83900D66079 /* MutelistView.swift */; };
4CF0ABE32981BC7D00D66079 /* UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE22981BC7D00D66079 /* UserView.swift */; };
4CF0ABE52981EE0C00D66079 /* EULAView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF0ABE42981EE0C00D66079 /* EULAView.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 */; };
@@ -174,7 +154,6 @@
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 */; };
7C902AE32981D55B002AB16E /* ZoomableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C902AE22981D55B002AB16E /* ZoomableScrollView.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 */; };
@@ -182,7 +161,6 @@
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 */
@@ -207,35 +185,11 @@
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>"; };
3A185A04297F2C3800F4BDC0 /* lv-LV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "lv-LV"; path = "lv-LV.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
3A185A05297F2C3800F4BDC0 /* lv-LV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "lv-LV"; path = "lv-LV.lproj/Localizable.strings"; sourceTree = "<group>"; };
3A185A06297F2C3800F4BDC0 /* lv-LV */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "lv-LV"; path = "lv-LV.lproj/Localizable.stringsdict"; 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>"; };
3A929C20297F2CF80090925E /* it-IT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "it-IT"; path = "it-IT.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
3A929C21297F2CF80090925E /* it-IT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "it-IT"; path = "it-IT.lproj/Localizable.strings"; sourceTree = "<group>"; };
3A929C22297F2CF80090925E /* it-IT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "it-IT"; path = "it-IT.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>"; };
3ACD32D0297F2D1E002F68B9 /* it-CH */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "it-CH"; path = "it-CH.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
3ACD32D1297F2D1E002F68B9 /* it-CH */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "it-CH"; path = "it-CH.lproj/Localizable.strings"; sourceTree = "<group>"; };
3ACD32D2297F2D1E002F68B9 /* it-CH */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "it-CH"; path = "it-CH.lproj/Localizable.stringsdict"; 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>"; };
@@ -378,15 +332,6 @@
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>"; };
4CC7AAF9297F64AC00430951 /* EventMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMenu.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>"; };
@@ -411,20 +356,11 @@
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>"; };
4CF0ABD32980996B00D66079 /* Report.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Report.swift; sourceTree = "<group>"; };
4CF0ABD529817F5B00D66079 /* ReportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportView.swift; sourceTree = "<group>"; };
4CF0ABD72981980C00D66079 /* Lists.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lists.swift; sourceTree = "<group>"; };
4CF0ABDB2981A19E00D66079 /* ListTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTests.swift; sourceTree = "<group>"; };
4CF0ABDD2981A69500D66079 /* MutelistModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutelistModel.swift; sourceTree = "<group>"; };
4CF0ABE02981A83900D66079 /* MutelistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutelistView.swift; sourceTree = "<group>"; };
4CF0ABE22981BC7D00D66079 /* UserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserView.swift; sourceTree = "<group>"; };
4CF0ABE42981EE0C00D66079 /* EULAView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EULAView.swift; sourceTree = "<group>"; };
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>"; };
7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZoomableScrollView.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>"; };
@@ -432,7 +368,6 @@
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 */
@@ -474,14 +409,6 @@
path = "Empty Views";
sourceTree = "<group>";
};
3AA24800297E3DAE0090C62D /* Reposts */ = {
isa = PBXGroup;
children = (
3AA24801297E3DC20090C62D /* RepostView.swift */,
);
path = Reposts;
sourceTree = "<group>";
};
4C06670728FDE62900038D2A /* damus-c */ = {
isa = PBXGroup;
children = (
@@ -539,7 +466,6 @@
4C0A3F8D280F63FF000448DE /* Models */ = {
isa = PBXGroup;
children = (
3AA247FC297E3CFF0090C62D /* RepostsModel.swift */,
4C0A3F8E280F640A000448DE /* ThreadModel.swift */,
4C0A3F92280F66F5000448DE /* ReplyMap.swift */,
4C3BEFD12819DB9B00B3DE84 /* ProfileModel.swift */,
@@ -571,8 +497,6 @@
4FE60CDC295E1C5E00105A1F /* Wallet.swift */,
4CB88392296F798300DC99E7 /* ReactionsModel.swift */,
7C45AE70297353390031D7BC /* KFImageModel.swift */,
4CF0ABD32980996B00D66079 /* Report.swift */,
4CF0ABDD2981A69500D66079 /* MutelistModel.swift */,
);
path = Models;
sourceTree = "<group>";
@@ -580,9 +504,6 @@
4C75EFA227FA576C0006080F /* Views */ = {
isa = PBXGroup;
children = (
4CF0ABDF2981A83000D66079 /* Muting */,
4CC7AAEE297F11B300430951 /* Events */,
3AA24800297E3DAE0090C62D /* Reposts */,
4CB88394296F7F8100DC99E7 /* Reactions */,
4CB88387296AF97C00DC99E7 /* ActionBar */,
4CE4F9E228528C5200C00DD9 /* AddRelayView.swift */,
@@ -617,7 +538,6 @@
4C06670028FC7C5900038D2A /* RelayView.swift */,
4C0A3F94280F6C78000448DE /* ReplyQuoteView.swift */,
4CACA9D4280C31E100D9BBE8 /* ReplyView.swift */,
F7F0BA262978E54D009531F3 /* ParicipantsView.swift */,
4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */,
4C3AC7A628369BA200E1F516 /* SearchHomeView.swift */,
4C5C7E69284EDE2E00A22DF5 /* SearchResultsView.swift */,
@@ -632,9 +552,6 @@
9609F057296E220800069BF3 /* BannerImageView.swift */,
4CB8838E296F781C00DC99E7 /* ReactionsView.swift */,
6439E013296790CF0020672B /* ProfileZoomView.swift */,
4CF0ABD529817F5B00D66079 /* ReportView.swift */,
4CF0ABE42981EE0C00D66079 /* EULAView.swift */,
3AA247FE297E3D900090C62D /* RepostsView.swift */,
);
path = Views;
sourceTree = "<group>";
@@ -676,7 +593,6 @@
4C3A1D3629637E0500558C0F /* PreviewCache.swift */,
64FBD06E296255C400D9D3B2 /* Theme.swift */,
4CB8838529656C8B00DC99E7 /* NIP05.swift */,
4CF0ABD72981980C00D66079 /* Lists.swift */,
);
path = Util;
sourceTree = "<group>";
@@ -698,20 +614,6 @@
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 */,
4CC7AAF9297F64AC00430951 /* EventMenu.swift */,
);
path = Events;
sourceTree = "<group>";
};
4CE4F9DF285287A000C00DD9 /* Components */ = {
isa = PBXGroup;
children = (
@@ -723,10 +625,6 @@
4C3EA67E28FFC01D00C48A62 /* InvoiceView.swift */,
4CB8838A296F6E1E00DC99E7 /* NIP05Badge.swift */,
4CB8838C296F710400DC99E7 /* Reposted.swift */,
4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */,
4CC7AAEC297F0B9E00430951 /* Highlight.swift */,
4CF0ABE22981BC7D00D66079 /* UserView.swift */,
7C902AE22981D55B002AB16E /* ZoomableScrollView.swift */,
);
path = Components;
sourceTree = "<group>";
@@ -794,7 +692,6 @@
4C3EA67A28FF7B3900C48A62 /* InvoiceTests.swift */,
3ACBCB77295FE5C70037388A /* TimeAgoTests.swift */,
4CB88399297322D200DC99E7 /* DMTests.swift */,
4CF0ABDB2981A19E00D66079 /* ListTests.swift */,
);
path = damusTests;
sourceTree = "<group>";
@@ -816,14 +713,6 @@
name = Frameworks;
sourceTree = "<group>";
};
4CF0ABDF2981A83000D66079 /* Muting */ = {
isa = PBXGroup;
children = (
4CF0ABE02981A83900D66079 /* MutelistView.swift */,
);
path = Muting;
sourceTree = "<group>";
};
F7F0BA23297892AE009531F3 /* Modifiers */ = {
isa = PBXGroup;
children = (
@@ -928,13 +817,6 @@
Base,
"es-419",
"en-US",
"de-AT",
"de-DE",
"tr-TR",
"fr-FR",
"lv-LV",
"it-CH",
"it-IT",
);
mainGroup = 4CE6DEDA27F7A08100C66700;
packageReferences = (
@@ -999,7 +881,6 @@
4C363AA828297703006E126D /* InsertSort.swift in Sources */,
4C285C86283892E7008A31F1 /* CreateAccountModel.swift in Sources */,
4C64987C286D03E000EAE2B3 /* DirectMessagesView.swift in Sources */,
7C902AE32981D55B002AB16E /* ZoomableScrollView.swift in Sources */,
4C363A8C28236B92006E126D /* PubkeyView.swift in Sources */,
4C5C7E68284ED36500A22DF5 /* SearchHomeModel.swift in Sources */,
4C75EFB728049D990006080F /* RelayPool.swift in Sources */,
@@ -1010,10 +891,8 @@
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 */,
@@ -1021,9 +900,7 @@
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 */,
4CF0ABE32981BC7D00D66079 /* UserView.swift in Sources */,
4C216F362870A9A700040376 /* InputDismissKeyboard.swift in Sources */,
4C216F382871EDE300040376 /* DirectMessageModel.swift in Sources */,
4C75EFA627FF87A20006080F /* Nostr.swift in Sources */,
@@ -1043,10 +920,8 @@
4C3EA66828FF5F9900C48A62 /* hex.c in Sources */,
E9E4ED0B295867B900DD7078 /* ThreadV2View.swift in Sources */,
4C3BEFDC281DCE6100B3DE84 /* Liked.swift in Sources */,
4CF0ABE12981A83900D66079 /* MutelistView.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 */,
@@ -1054,14 +929,11 @@
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 */,
@@ -1082,27 +954,21 @@
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 */,
4CF0ABE52981EE0C00D66079 /* EULAView.swift 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 */,
4CF0ABD629817F5B00D66079 /* ReportView.swift in Sources */,
4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */,
4CF0ABD82981980C00D66079 /* Lists.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 */,
@@ -1118,7 +984,6 @@
4C0A3F95280F6C78000448DE /* ReplyQuoteView.swift in Sources */,
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */,
4CB88389296AF99A00DC99E7 /* EventDetailBar.swift in Sources */,
4CF0ABDE2981A69500D66079 /* MutelistModel.swift in Sources */,
4C3AC79B28306D7B00E1F516 /* Contacts.swift in Sources */,
4C3EA63D28FF52D600C48A62 /* bolt11.c in Sources */,
4CB55EF3295E5D59007FD187 /* RecommendedRelayView.swift in Sources */,
@@ -1129,17 +994,13 @@
E990020F2955F837003BBC5A /* EditMetadataView.swift in Sources */,
4CACA9D5280C31E100D9BBE8 /* ReplyView.swift in Sources */,
4C3A1D332960DB0500558C0F /* Markdown.swift in Sources */,
4CF0ABD42980996B00D66079 /* Report.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 */,
4CC7AAFA297F64AC00430951 /* EventMenu.swift in Sources */,
4C75EFBB2804A34C0006080F /* ProofOfWork.swift in Sources */,
4C3AC7A52836987600E1F516 /* MainTabView.swift in Sources */,
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */,
@@ -1158,7 +1019,6 @@
4C363AA02828A8DD006E126D /* LikeTests.swift in Sources */,
4C90BD1C283AC38E008EE7EF /* Bech32Tests.swift in Sources */,
4CE6DEF827F7A08200C66700 /* damusTests.swift in Sources */,
4CF0ABDC2981A19E00D66079 /* ListTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1192,13 +1052,6 @@
children = (
3A5C4575296A879E0032D398 /* es-419 */,
3A2B8B0A296A8982009CC16D /* en-US */,
3A5EA111297CCF6C00569477 /* de-AT */,
3AEABD22297CCFA8003F2975 /* de-DE */,
3AEB8005297CCEA900713A25 /* tr-TR */,
3A4F3322297CCFEE004B5F72 /* fr-FR */,
3A185A06297F2C3800F4BDC0 /* lv-LV */,
3ACD32D2297F2D1E002F68B9 /* it-CH */,
3A929C22297F2CF80090925E /* it-IT */,
);
name = Localizable.stringsdict;
sourceTree = "<group>";
@@ -1207,13 +1060,6 @@
isa = PBXVariantGroup;
children = (
3ACB685B297633BC00C46468 /* es-419 */,
3A5EA10F297CCF6C00569477 /* de-AT */,
3AEABD20297CCFA8003F2975 /* de-DE */,
3AEB8003297CCEA800713A25 /* tr-TR */,
3A4F3320297CCFEE004B5F72 /* fr-FR */,
3A185A04297F2C3800F4BDC0 /* lv-LV */,
3ACD32D0297F2D1E002F68B9 /* it-CH */,
3A929C20297F2CF80090925E /* it-IT */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
@@ -1222,13 +1068,6 @@
isa = PBXVariantGroup;
children = (
3ACB685E297633BC00C46468 /* es-419 */,
3A5EA110297CCF6C00569477 /* de-AT */,
3AEABD21297CCFA8003F2975 /* de-DE */,
3AEB8004297CCEA800713A25 /* tr-TR */,
3A4F3321297CCFEE004B5F72 /* fr-FR */,
3A185A05297F2C3800F4BDC0 /* lv-LV */,
3ACD32D1297F2D1E002F68B9 /* it-CH */,
3A929C21297F2CF80090925E /* it-IT */,
);
name = Localizable.strings;
sourceTree = "<group>";
@@ -1364,7 +1203,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = damus/damus.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 11;
CURRENT_PROJECT_VERSION = 7;
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
DEVELOPMENT_TEAM = XK7H4JAB3D;
ENABLE_PREVIEWS = YES;
@@ -1405,7 +1244,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = damus/damus.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 11;
CURRENT_PROJECT_VERSION = 7;
DEVELOPMENT_ASSET_PATHS = "\"damus/Preview Content\"";
DEVELOPMENT_TEAM = XK7H4JAB3D;
ENABLE_PREVIEWS = YES;
@@ -1,98 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1420"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEE227F7A08100C66700"
BuildableName = "damus.app"
BlueprintName = "damus"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEF227F7A08200C66700"
BuildableName = "damusTests.xctest"
BlueprintName = "damusTests"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEFC27F7A08200C66700"
BuildableName = "damusUITests.xctest"
BlueprintName = "damusUITests"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEE227F7A08100C66700"
BuildableName = "damus.app"
BlueprintName = "damus"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4CE6DEE227F7A08100C66700"
BuildableName = "damus.app"
BlueprintName = "damus"
ReferencedContainer = "container:damus.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
-39
View File
@@ -1,39 +0,0 @@
//
// 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
}
}
}
+64 -17
View File
@@ -115,6 +115,56 @@ private struct ImageContainerView: View {
// 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
}
}
}
@@ -127,14 +177,6 @@ struct ImageView: View {
@State private var selectedIndex = 0
@State var showMenu = true
var safeAreaInsets: UIEdgeInsets? {
return UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.first { $0.isKeyWindow }?.safeAreaInsets
}
var navBarView: some View {
VStack {
HStack {
@@ -180,24 +222,22 @@ struct ImageView: View {
ZoomableScrollView {
ImageContainerView(url: urls[index])
.aspectRatio(contentMode: .fit)
.padding(.top, safeAreaInsets?.top)
.padding(.bottom, safeAreaInsets?.bottom)
}
.ignoresSafeArea()
.tag(index)
.modifier(SwipeToDismissModifier(minDistance: 50, onDismiss: {
presentationMode.wrappedValue.dismiss()
}))
.ignoresSafeArea()
.tag(index)
}
}
.ignoresSafeArea()
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.gesture(TapGesture(count: 2).onEnded {
// Prevents menu from hiding on double tap
.onChange(of: selectedIndex, perform: { _ in
showMenu = true
})
.gesture(TapGesture(count: 1).onEnded {
.onTapGesture {
showMenu.toggle()
})
}
.overlay(
VStack {
if showMenu {
@@ -210,7 +250,14 @@ struct ImageView: View {
}
}
.animation(.easeInOut, value: showMenu)
.padding(.bottom, safeAreaInsets?.bottom)
.padding(
.bottom,
UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.first { $0.isKeyWindow }?.safeAreaInsets.bottom
)
)
}
}
-42
View File
@@ -1,42 +0,0 @@
//
// UserView.swift
// damus
//
// Created by William Casarin on 2023-01-25.
//
import SwiftUI
struct UserView: View {
let damus_state: DamusState
let pubkey: String
var body: some View {
let pmodel = ProfileModel(pubkey: pubkey, damus: damus_state)
let followers = FollowersModel(damus_state: damus_state, target: pubkey)
let pv = ProfileView(damus_state: damus_state, profile: pmodel, followers: followers)
NavigationLink(destination: pv) {
ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles)
VStack(alignment: .leading) {
let profile = damus_state.profiles.lookup(id: pubkey)
ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: false, show_nip5_domain: false)
if let about = profile?.about {
Text(about)
.lineLimit(3)
.font(.footnote)
}
}
Spacer()
}
.buttonStyle(PlainButtonStyle())
}
}
struct UserView_Previews: PreviewProvider {
static var previews: some View {
UserView(damus_state: test_damus_state(), pubkey: "pk")
}
}
-38
View File
@@ -1,38 +0,0 @@
//
// 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")!)
}
}
-152
View File
@@ -1,152 +0,0 @@
//
// ZoomableScrollView.swift
// damus
//
// Created by Oleg Abalonski on 1/25/23.
//
import SwiftUI
struct ZoomableScrollView<Content: View>: UIViewRepresentable {
private var content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
func makeUIView(context: Context) -> UIScrollView {
let scrollView = GesturedScrollView()
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, ignoreSafeArea: true))
}
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
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
let viewSize = hostingController.view.frame.size
guard let imageSize = scrollView.subviews[0].subviews.last?.frame.size else { return }
if scrollView.zoomScale > 1 {
let ratioW = viewSize.width / imageSize.width
let ratioH = viewSize.height / imageSize.height
let ratio = ratioW < ratioH ? ratioW:ratioH
let newWidth = imageSize.width * ratio
let newHeight = imageSize.height * ratio
let left = 0.5 * (newWidth * scrollView.zoomScale > viewSize.width ? (newWidth - viewSize.width) : (scrollView.frame.width - scrollView.contentSize.width))
let top = 0.5 * (newHeight * scrollView.zoomScale > viewSize.height ? (newHeight - viewSize.height) : (scrollView.frame.height - scrollView.contentSize.height))
scrollView.contentInset = UIEdgeInsets(top: top, left: left, bottom: top, right: left)
} else {
scrollView.contentInset = .zero
}
}
}
}
fileprivate class GesturedScrollView: UIScrollView, UIGestureRecognizerDelegate {
let doubleTapGesture: UITapGestureRecognizer
override init(frame: CGRect) {
doubleTapGesture = UITapGestureRecognizer()
super.init(frame: frame)
doubleTapGesture.addTarget(self, action: #selector(handleDoubleTap))
doubleTapGesture.numberOfTapsRequired = 2
addGestureRecognizer(doubleTapGesture)
doubleTapGesture.delegate = self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func handleDoubleTap(_ gesture: UITapGestureRecognizer) {
if self.zoomScale == 1 {
let pointInView = gesture.location(in: self.subviews.first)
let newZoomScale = self.maximumZoomScale / 4.0
let scrollViewSize = self.bounds.size
let width = scrollViewSize.width / newZoomScale
let height = scrollViewSize.height / newZoomScale
let originX = pointInView.x - (width / 2.0)
let originY = pointInView.y - (height / 2.0)
let zoomRect = CGRect(x: originX, y: originY, width: width, height: height)
self.zoom(to: zoomRect, animated: true)
} else {
self.setZoomScale(self.minimumZoomScale, animated: true)
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return gestureRecognizer == doubleTapGesture
}
}
fileprivate extension UIHostingController {
convenience init(rootView: Content, ignoreSafeArea: Bool) {
self.init(rootView: rootView)
if ignoreSafeArea {
disableSafeArea()
}
}
func disableSafeArea() {
guard let viewClass = object_getClass(view) else { return }
let viewSubclassName = String(cString: class_getName(viewClass)).appending("_IgnoreSafeArea")
if let viewSubclass = NSClassFromString(viewSubclassName) {
object_setClass(view, viewSubclass)
}
else {
guard let viewClassNameUtf8 = (viewSubclassName as NSString).utf8String else { return }
guard let viewSubclass = objc_allocateClassPair(viewClass, viewClassNameUtf8, 0) else { return }
if let method = class_getInstanceMethod(UIView.self, #selector(getter: UIView.safeAreaInsets)) {
let safeAreaInsets: @convention(block) (AnyObject) -> UIEdgeInsets = { _ in
return .zero
}
class_addMethod(viewSubclass, #selector(getter: UIView.safeAreaInsets), imp_implementationWithBlock(safeAreaInsets), method_getTypeEncoding(method))
}
objc_registerClassPair(viewSubclass)
object_setClass(view, viewSubclass)
}
}
}
+16 -134
View File
@@ -11,11 +11,11 @@ import Kingfisher
var BOOTSTRAP_RELAYS = [
"wss://relay.damus.io",
"wss://eden.nostr.land",
"wss://nostr-relay.wlvs.space",
"wss://nostr.fmt.wiz.biz",
"wss://relay.nostr.bg",
"wss://nostr.oxtr.dev",
"wss://relay.snort.social",
"wss://nostr.v0l.io",
"wss://brb.io",
]
@@ -26,12 +26,10 @@ struct TimestampedProfile {
enum Sheets: Identifiable {
case post
case report(ReportTarget)
case reply(NostrEvent)
var id: String {
switch self {
case .report: return "report"
case .post: return "post"
case .reply(let ev): return "reply-" + ev.id
}
@@ -81,10 +79,6 @@ struct ContentView: View {
@State var profile_open: Bool = false
@State var thread_open: Bool = false
@State var search_open: Bool = false
@State var blocking: String? = nil
@State var confirm_block: Bool = false
@State var user_blocked_confirm: Bool = false
@State var confirm_overwrite_mutelist: Bool = false
@State var filter_state : FilterState = .posts_and_replies
@State private var isSideBarOpened = false
@StateObject var home: HomeModel = HomeModel()
@@ -99,23 +93,15 @@ struct ContentView: View {
var PostingTimelineView: some View {
VStack {
ZStack {
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(userSettings: user_settings) {
self.active_sheet = .post
}
}
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))
}
.safeAreaInset(edge: .top, spacing: 0) {
VStack(spacing: 0) {
@@ -134,6 +120,11 @@ struct ContentView: View {
if let damus = self.damus_state {
TimelineView(events: $home.events, loading: $home.loading, damus: damus, show_friend_icon: false, filter: filter)
}
if privkey != nil {
PostButtonContainer(userSettings: user_settings) {
self.active_sheet = .post
}
}
}
}
@@ -187,7 +178,7 @@ struct ContentView: View {
.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.")
Text("DM", comment: "Toolbar label for DM view, which is the English abbreviation for Direct Message.")
.bold()
case .notifications:
Text("Notifications", comment: "Toolbar label for Notifications view.")
@@ -235,20 +226,6 @@ struct ContentView: View {
}
}
func MaybeReportView(target: ReportTarget) -> some View {
Group {
if let ds = damus_state {
if let sec = ds.keypair.privkey {
ReportView(pool: ds.pool, target: target, privkey: sec)
} else {
EmptyView()
}
} else {
EmptyView()
}
}
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
if let damus = self.damus_state {
@@ -299,8 +276,6 @@ struct ContentView: View {
}
.sheet(item: $active_sheet) { item in
switch item {
case .report(let target):
MaybeReportView(target: target)
case .post:
PostView(replying_to: nil, references: [])
case .reply(let event):
@@ -348,15 +323,6 @@ struct ContentView: View {
}
.onReceive(handle_notify(.like)) { like in
}
.onReceive(handle_notify(.report)) { notif in
let target = notif.object as! ReportTarget
self.active_sheet = .report(target)
}
.onReceive(handle_notify(.block)) { notif in
let pubkey = notif.object as! String
self.blocking = pubkey
self.confirm_block = true
}
.onReceive(handle_notify(.broadcast_event)) { obj in
let ev = obj.object as! NostrEvent
self.damus_state?.pool.send(.event(ev))
@@ -431,90 +397,6 @@ struct ContentView: View {
.onReceive(timer) { n in
self.damus_state?.pool.connect_to_disconnected()
}
.onReceive(handle_notify(.new_mutes)) { notif in
home.filter_muted()
}
.alert(NSLocalizedString("User blocked", comment: "Alert message to indicate "), isPresented: $user_blocked_confirm, actions: {
Button(NSLocalizedString("Thanks!", comment: "Button to close out of alert that informs that the action to block a user was successful.")) {
user_blocked_confirm = false
}
}, message: {
if let pubkey = self.blocking {
let profile = damus_state!.profiles.lookup(id: pubkey)
let name = Profile.displayName(profile: profile, pubkey: pubkey)
Text("\(name) has been blocked", comment: "Alert message that informs a user was blocked.")
} else {
Text("User has been blocked", comment: "Alert message that informs a user was blocked.")
}
})
.alert(NSLocalizedString("Create new mutelist", comment: "Title of alert prompting the user to create a new mutelist."), isPresented: $confirm_overwrite_mutelist, actions: {
Button(NSLocalizedString("Cancel", comment: "Button to cancel out of alert that creates a new mutelist.")) {
confirm_overwrite_mutelist = false
confirm_block = false
}
Button(NSLocalizedString("Yes, Overwrite", comment: "Text of button that confirms to overwrite the existing mutelist.")) {
guard let ds = damus_state else {
return
}
guard let keypair = ds.keypair.to_full() else {
return
}
guard let pubkey = blocking else {
return
}
guard let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: pubkey) else {
return
}
damus_state?.contacts.set_mutelist(mutelist)
ds.pool.send(.event(mutelist))
confirm_overwrite_mutelist = false
confirm_block = false
user_blocked_confirm = true
}
}, message: {
Text("No block list found, create a new one? This will overwrite any previous block lists.", comment: "Alert message prompt that asks if the user wants to create a new block list, overwriting previous block lists.")
})
.alert(NSLocalizedString("Block User", comment: "Title of alert for blocking a user."), isPresented: $confirm_block, actions: {
Button(NSLocalizedString("Cancel", comment: "Alert button to cancel out of alert for blocking a user."), role: .cancel) {
confirm_block = false
}
Button(NSLocalizedString("Block", comment: "Alert button to block a user."), role: .destructive) {
guard let ds = damus_state else {
return
}
if ds.contacts.mutelist == nil {
confirm_overwrite_mutelist = true
} else {
guard let keypair = ds.keypair.to_full() else {
return
}
guard let pubkey = blocking else {
return
}
guard let ev = create_or_update_mutelist(keypair: keypair, mprev: ds.contacts.mutelist, to_add: pubkey) else {
return
}
damus_state?.contacts.set_mutelist(ev)
ds.pool.send(.event(ev))
}
}
}, message: {
if let pubkey = blocking {
let profile = damus_state?.profiles.lookup(id: pubkey)
let name = Profile.displayName(profile: profile, pubkey: pubkey)
Text("Block \(name)?", comment: "Alert message prompt to ask if a user should be blocked.")
} else {
Text("Could not find user to block...", comment: "Alert message to indicate that the blocked user could not be found.")
}
})
}
func switch_timeline(_ timeline: Timeline) {
-38
View File
@@ -11,51 +11,13 @@ import Foundation
class Contacts {
private var friends: Set<String> = Set()
private var friend_of_friends: Set<String> = Set()
private var muted: Set<String> = Set()
let our_pubkey: String
var event: NostrEvent?
var mutelist: NostrEvent?
init(our_pubkey: String) {
self.our_pubkey = our_pubkey
}
func is_muted(_ pk: String) -> Bool {
return muted.contains(pk)
}
func set_mutelist(_ ev: NostrEvent) {
let oldlist = self.mutelist
self.mutelist = ev
let old = Set(oldlist?.referenced_pubkeys.map({ $0.ref_id }) ?? [])
let new = Set(ev.referenced_pubkeys.map({ $0.ref_id }))
let diff = old.symmetricDifference(new)
var new_mutes = Array<String>()
var new_unmutes = Array<String>()
for d in diff {
if new.contains(d) {
new_mutes.append(d)
} else {
new_unmutes.append(d)
}
}
// TODO: set local mutelist here
self.muted = Set(ev.referenced_pubkeys.map({ $0.ref_id }))
if new_mutes.count > 0 {
notify(.new_mutes, new_mutes)
}
if new_unmutes.count > 0 {
notify(.new_unmutes, new_unmutes)
}
}
func get_friendosphere() -> [String] {
var fs = get_friend_list()
fs.append(contentsOf: get_friend_of_friend_list())
+3 -41
View File
@@ -98,8 +98,6 @@ class HomeModel: ObservableObject {
handle_contact_event(sub_id: sub_id, relay_id: relay_id, ev: ev)
case .metadata:
handle_metadata_event(ev)
case .list:
handle_list_event(ev)
case .boost:
handle_boost_event(sub_id: sub_id, ev)
case .like:
@@ -126,12 +124,6 @@ class HomeModel: ObservableObject {
func handle_channel_meta(_ ev: NostrEvent) {
}
func filter_muted() {
self.events = events.filter { !damus_state.contacts.is_muted($0.pubkey) }
self.dms.dms = dms.dms.filter { !damus_state.contacts.is_muted($0.0) }
self.notifications = notifications.filter { !damus_state.contacts.is_muted($0.pubkey) }
}
func handle_delete_event(_ ev: NostrEvent) {
guard ev.is_valid else {
return
@@ -282,11 +274,7 @@ class HomeModel: ObservableObject {
var our_contacts_filter = NostrFilter.filter_kinds([3, 0])
our_contacts_filter.authors = [damus_state.pubkey]
var our_blocklist_filter = NostrFilter.filter_kinds([30000])
our_blocklist_filter.parameter = "mute"
our_blocklist_filter.authors = [damus_state.pubkey]
var dms_filter = NostrFilter.filter_kinds([
NostrKind.dm.rawValue,
])
@@ -323,7 +311,7 @@ class HomeModel: ObservableObject {
var home_filters = [home_filter]
var notifications_filters = [notifications_filter]
var contacts_filters = [contacts_filter, our_contacts_filter, our_blocklist_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] } ?? [:]
@@ -347,30 +335,7 @@ class HomeModel: ObservableObject {
pool.send(.subscribe(.init(filters: dms_filters, sub_id: dms_subid)))
}
}
func handle_list_event(_ ev: NostrEvent) {
// we only care about our lists
guard ev.pubkey == damus_state.pubkey else {
return
}
if let mutelist = damus_state.contacts.mutelist {
if ev.created_at <= mutelist.created_at {
return
}
}
guard let name = get_referenced_ids(tags: ev.tags, key: "d").first else {
return
}
guard name.ref_id == "mute" else {
return
}
damus_state.contacts.set_mutelist(ev)
}
func handle_metadata_event(_ ev: NostrEvent) {
process_metadata_event(profiles: damus_state.profiles, ev: ev)
}
@@ -411,9 +376,6 @@ class HomeModel: ObservableObject {
}
func should_hide_event(_ ev: NostrEvent) -> Bool {
if damus_state.contacts.is_muted(ev.pubkey) {
return true
}
return !ev.should_show_event
}
-18
View File
@@ -1,18 +0,0 @@
//
// ListModel.swift
// damus
//
// Created by William Casarin on 2023-01-25.
//
import Foundation
/*
class MutelistModel: ObservableObject {
let contacts: Contacts
@Published var users: [String]
}
*/
-59
View File
@@ -1,59 +0,0 @@
//
// Report.swift
// damus
//
// Created by William Casarin on 2023-01-24.
//
import Foundation
enum ReportType: String {
case explicit
case illegal
case spam
case impersonation
}
struct ReportNoteTarget {
let pubkey: String
let note_id: String
}
enum ReportTarget {
case user(String)
case note(ReportNoteTarget)
}
struct Report {
let type: ReportType
let target: ReportTarget
let message: String
}
func create_report_tags(target: ReportTarget, type: ReportType) -> [[String]] {
var tags: [[String]]
switch target {
case .user(let pubkey):
tags = [["p", pubkey]]
case .note(let notet):
tags = [["e", notet.note_id], ["p", notet.pubkey]]
}
tags.append(["report", type.rawValue])
return tags
}
func create_report_event(privkey: String, report: Report) -> NostrEvent? {
guard let pubkey = privkey_to_pubkey(privkey: privkey) else {
return nil
}
let kind = 1984
let tags = create_report_tags(target: report.target, type: report.type)
let ev = NostrEvent(content: report.message, pubkey: pubkey, kind: kind, tags: tags)
ev.id = calculate_event_id(ev: ev)
ev.sig = sign_event(privkey: privkey, ev: ev)
return ev
}
-77
View File
@@ -1,77 +0,0 @@
//
// RepostsModel.swift
// damus
//
// Created by Terry Yiu on 1/22/23.
//
import Foundation
class RepostsModel: ObservableObject {
let state: DamusState
let target: String
let sub_id: String
let profiles_id: String
@Published var reposts: [NostrEvent]
init (state: DamusState, target: String) {
self.state = state
self.target = target
self.sub_id = UUID().description
self.profiles_id = UUID().description
self.reposts = []
}
func get_filter() -> NostrFilter {
var filter = NostrFilter.filter_kinds([NostrKind.boost.rawValue])
filter.referenced_ids = [target]
filter.limit = 500
return filter
}
func subscribe() {
let filter = get_filter()
let filters = [filter]
self.state.pool.subscribe(sub_id: sub_id, filters: filters, handler: handle_nostr_event)
}
func unsubscribe() {
self.state.pool.unsubscribe(sub_id: sub_id)
}
func handle_event(relay_id: String, ev: NostrEvent) {
guard ev.kind == NostrKind.boost.rawValue else {
return
}
guard let reposted_event = last_etag(tags: ev.tags) else {
return
}
guard reposted_event == self.target else {
return
}
if insert_uniq_sorted_event(events: &self.reposts, new_ev: ev, cmp: { a, b in a.created_at < b.created_at } ) {
objectWillChange.send()
}
}
func handle_nostr_event(relay_id: String, ev: NostrConnectionEvent) {
guard case .nostr_event(let nev) = ev else {
return
}
switch nev {
case .event(_, let ev):
handle_event(relay_id: relay_id, ev: ev)
case .notice(_):
break
case .eose(_):
load_profiles(profiles_subid: profiles_id, relay_id: relay_id, events: reposts, damus_state: state)
break
}
}
}
+2 -6
View File
@@ -11,17 +11,13 @@ struct SwipeToDismissModifier: ViewModifier {
let minDistance: CGFloat?
var onDismiss: () -> Void
@State private var offset: CGSize = .zero
@GestureState private var viewOffset: CGSize = .zero
func body(content: Content) -> some View {
content
.offset(y: viewOffset.height)
.animation(.interactiveSpring(), value: viewOffset)
.offset(y: offset.height)
.animation(.interactiveSpring(), value: offset)
.simultaneousGesture(
DragGesture(minimumDistance: minDistance ?? 10)
.updating($viewOffset, body: { value, gestureState, transaction in
gestureState = CGSize(width: value.location.x - value.startLocation.x, height: value.location.y - value.startLocation.y)
})
.onChanged { gesture in
if gesture.translation.width < 50 {
offset = gesture.translation
-4
View File
@@ -53,10 +53,6 @@ struct Profile: Codable {
set(s) { value["website"] = s }
}
var website_url: URL? {
return self.website.flatMap { URL(string: $0) }
}
var lud06: String? {
get { return value["lud06"]; }
set(s) { value["lud06"] = s }
+1 -18
View File
@@ -790,6 +790,7 @@ func inner_event_or_self(ev: NostrEvent) -> NostrEvent {
return inner_ev
}
func first_eref_mention(ev: NostrEvent, privkey: String?) -> Mention? {
let blocks = ev.blocks(privkey).filter { block in
guard case .mention(let mention) = block else {
@@ -814,21 +815,3 @@ func first_eref_mention(ev: NostrEvent, privkey: String?) -> Mention? {
return nil
}
extension [ReferencedId] {
var pRefs: [ReferencedId] {
get {
self.filter { ref in
ref.key == "p"
}
}
}
var eRefs: [ReferencedId] {
get {
self.filter { ref in
ref.key == "e"
}
}
}
}
-2
View File
@@ -17,7 +17,6 @@ struct NostrFilter: Codable {
var limit: UInt32?
var authors: [String]?
var hashtag: [String]? = nil
var parameter: String? = nil
private enum CodingKeys : String, CodingKey {
case ids
@@ -25,7 +24,6 @@ struct NostrFilter: Codable {
case referenced_ids = "#e"
case pubkeys = "#p"
case hashtag = "#t"
case parameter = "#d"
case since
case until
case authors
-1
View File
@@ -19,5 +19,4 @@ enum NostrKind: Int {
case channel_create = 40
case channel_meta = 41
case chat = 42
case list = 30000
}
-13
View File
@@ -12,25 +12,12 @@ import Vault
let PUBKEY_HRP = "npub"
let PRIVKEY_HRP = "nsec"
struct FullKeypair {
let pubkey: String
let privkey: String
}
struct Keypair {
let pubkey: String
let privkey: String?
let pubkey_bech32: String
let privkey_bech32: String?
func to_full() -> FullKeypair? {
guard let privkey = self.privkey else {
return nil
}
return FullKeypair(pubkey: pubkey, privkey: privkey)
}
init(pubkey: String, privkey: String?) {
self.pubkey = pubkey
self.privkey = privkey
-91
View File
@@ -1,91 +0,0 @@
//
// Mute.swift
// damus
//
// Created by William Casarin on 2023-01-25.
//
import Foundation
func create_or_update_mutelist(keypair: FullKeypair, mprev: NostrEvent?, to_add: String) -> NostrEvent? {
return create_or_update_list_event(keypair: keypair, mprev: mprev, to_add: to_add, list_name: "mute", list_type: "p")
}
func remove_from_mutelist(keypair: FullKeypair, prev: NostrEvent, to_remove: String) -> NostrEvent? {
return remove_from_list_event(keypair: keypair, prev: prev, to_remove: to_remove, tag_type: "p")
}
func create_or_update_list_event(keypair: FullKeypair, mprev: NostrEvent?, to_add: String, list_name: String, list_type: String) -> NostrEvent? {
let pubkey = keypair.pubkey
if let prev = mprev {
if let okprev = ensure_list_name(list: prev, name: list_name), prev.pubkey == keypair.pubkey {
return add_to_list_event(keypair: keypair, prev: okprev, to_add: to_add, tag_type: list_type)
}
}
var tags = [["d", list_name], [list_type, to_add]]
let ev = NostrEvent(content: "", pubkey: pubkey, kind: 30000, tags: tags)
ev.tags = tags
ev.id = calculate_event_id(ev: ev)
ev.sig = sign_event(privkey: keypair.privkey, ev: ev)
return ev
}
func remove_from_list_event(keypair: FullKeypair, prev: NostrEvent, to_remove: String, tag_type: String) -> NostrEvent? {
var exists = false
for tag in prev.tags {
if tag.count >= 2 && tag[0] == tag_type && tag[1] == to_remove {
exists = true
}
}
// make sure we actually have the pubkey to remove
guard exists else {
return nil
}
let new_tags = prev.tags.filter { tag in
!(tag.count >= 2 && tag[0] == tag_type && tag[1] == to_remove)
}
let ev = NostrEvent(content: prev.content, pubkey: keypair.pubkey, kind: 30000, tags: new_tags)
ev.id = calculate_event_id(ev: ev)
ev.sig = sign_event(privkey: keypair.privkey, ev: ev)
return ev
}
func add_to_list_event(keypair: FullKeypair, prev: NostrEvent, to_add: String, tag_type: String) -> NostrEvent? {
for tag in prev.tags {
// we are already muting this user
if tag.count >= 2 && tag[0] == tag_type && tag[1] == to_add {
return nil
}
}
let new = NostrEvent(content: prev.content, pubkey: keypair.pubkey, kind: 30000, tags: prev.tags)
new.tags.append([tag_type, to_add])
new.id = calculate_event_id(ev: new)
new.sig = sign_event(privkey: keypair.privkey, ev: new)
return new
}
func ensure_list_name(list: NostrEvent, name: String) -> NostrEvent? {
for tag in list.tags {
if tag.count >= 2 && tag[0] == "d" {
if tag[1] != name {
return nil
} else {
return list
}
}
}
list.tags.insert(["d", name], at: 0)
return list
}
+72 -12
View File
@@ -11,90 +11,150 @@ extension Notification.Name {
static var thread_focus: Notification.Name {
return Notification.Name("thread focus")
}
}
extension Notification.Name {
static var relays_changed: Notification.Name {
return Notification.Name("relays_changed")
}
}
extension Notification.Name {
static var select_event: Notification.Name {
return Notification.Name("select_event")
}
}
extension Notification.Name {
static var select_quote: Notification.Name {
return Notification.Name("select quote")
}
}
extension Notification.Name {
static var reply: Notification.Name {
return Notification.Name("reply")
}
}
extension Notification.Name {
static var profile_updated: Notification.Name {
return Notification.Name("profile_updated")
}
}
extension Notification.Name {
static var switched_timeline: Notification.Name {
return Notification.Name("switched_timeline")
}
}
extension Notification.Name {
static var liked: Notification.Name {
return Notification.Name("liked")
}
}
extension Notification.Name {
static var open_profile: Notification.Name {
return Notification.Name("open_profile")
}
}
extension Notification.Name {
static var scroll_to_top: Notification.Name {
return Notification.Name("scroll_to_to")
}
}
extension Notification.Name {
static var broadcast_event: Notification.Name {
return Notification.Name("broadcast event")
}
}
extension Notification.Name {
static var open_thread: Notification.Name {
return Notification.Name("open thread")
}
}
extension Notification.Name {
static var notice: Notification.Name {
return Notification.Name("notice")
}
}
extension Notification.Name {
static var like: Notification.Name {
return Notification.Name("like note")
}
}
extension Notification.Name {
static var delete: Notification.Name {
return Notification.Name("delete note")
}
}
extension Notification.Name {
static var post: Notification.Name {
return Notification.Name("send post")
}
}
extension Notification.Name {
static var boost: Notification.Name {
return Notification.Name("boost")
}
}
extension Notification.Name {
static var boosted: Notification.Name {
return Notification.Name("boosted")
}
}
extension Notification.Name {
static var follow: Notification.Name {
return Notification.Name("follow")
}
}
extension Notification.Name {
static var unfollow: Notification.Name {
return Notification.Name("unfollow")
}
}
extension Notification.Name {
static var login: Notification.Name {
return Notification.Name("login")
}
}
extension Notification.Name {
static var logout: Notification.Name {
return Notification.Name("logout")
}
}
extension Notification.Name {
static var followed: Notification.Name {
return Notification.Name("followed")
}
}
extension Notification.Name {
static var chatroom_meta: Notification.Name {
return Notification.Name("chatroom_meta")
}
}
extension Notification.Name {
static var unfollowed: Notification.Name {
return Notification.Name("unfollowed")
}
static var report: Notification.Name {
return Notification.Name("report")
}
static var block: Notification.Name {
return Notification.Name("block")
}
static var new_mutes: Notification.Name {
return Notification.Name("new_mutes")
}
static var new_unmutes: Notification.Name {
return Notification.Name("new_unmutes")
}
}
func handle_notify(_ name: Notification.Name) -> NotificationCenter.Publisher {
+1 -4
View File
@@ -15,10 +15,7 @@ struct EventDetailBar: View {
var body: some View {
HStack {
if bar.boosts > 0 {
NavigationLink(destination: RepostsView(damus_state: state, model: RepostsModel(state: state, target: target))) {
Text("\(Text("\(bar.boosts)", comment: "Number of reposts.").font(.body.bold())) \(Text(String(format: NSLocalizedString("reposts_count", comment: "Part of a larger sentence to describe how many reposts there are."), bar.boosts)).foregroundColor(.gray))", comment: "Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.")
}
.buttonStyle(PlainButtonStyle())
Text("\(Text("\(bar.boosts)", comment: "Number of reposts.").font(.body.bold())) \(Text(String(format: NSLocalizedString("reposts_count", comment: "Part of a larger sentence to describe how many reposts there are."), bar.boosts)).foregroundColor(.gray))", comment: "Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.")
}
if bar.likes > 0 {
+1 -1
View File
@@ -18,7 +18,7 @@ struct InnerBannerImageView: View {
self.imageModel = KFImageModel(
url: url,
fallbackUrl: nil,
maxByteSize: 20_971_520, // 20 MiB
maxByteSize: 5000000,
downsampleSize: CGSize(width: 750, height: 250)
)
}
+1 -1
View File
@@ -24,7 +24,7 @@ struct ChatroomView: View {
next_ev: ind == count-1 ? nil : thread.events[ind+1],
damus_state: damus
)
.event_context_menu(ev, keypair: damus.keypair)
.event_context_menu(ev, pubkey: ev.pubkey, privkey: damus.keypair.privkey)
.onTapGesture {
if thread.initial_event.id == ev.id {
//dismiss()
+3 -3
View File
@@ -139,10 +139,10 @@ struct ConfigView: View {
.navigationTitle(NSLocalizedString("Settings", comment: "Navigation title for Settings view."))
.navigationBarTitleDisplayMode(.large)
.alert(NSLocalizedString("Logout", comment: "Alert for logging out the user."), isPresented: $confirm_logout) {
Button(NSLocalizedString("Cancel", comment: "Cancel out of logging out the user."), role: .cancel) {
Button(NSLocalizedString("Cancel", comment: "Cancel out of logging out the user.")) {
confirm_logout = false
}
Button(NSLocalizedString("Logout", comment: "Button for logging out the user."), role: .destructive) {
Button(NSLocalizedString("Logout", comment: "Button for logging out the user.")) {
notify(.logout, ())
}
} message: {
@@ -154,7 +154,7 @@ struct ConfigView: View {
return
}
if relay.starts(with: "wss://") == false && relay.starts(with: "ws://") == false {
if relay.starts(with: "wss://") == false {
relay = "wss://" + relay
}
-2
View File
@@ -11,7 +11,6 @@ struct CreateAccountView: View {
@StateObject var account: CreateAccountModel = CreateAccountModel()
@State var is_light: Bool = false
@State var is_done: Bool = false
@State var reading_eula: Bool = false
func SignupForm<FormContent: View>(@ViewBuilder content: () -> FormContent) -> some View {
return VStack(alignment: .leading, spacing: 10.0, content: content)
@@ -76,7 +75,6 @@ struct CreateAccountView: View {
NavigationLink(destination: SaveKeysView(account: account), isActive: $is_done) {
EmptyView()
}
DamusWhiteButton(NSLocalizedString("Create", comment: "Button to create account.")) {
self.is_done = true
}
+2 -2
View File
@@ -19,7 +19,7 @@ struct DMChatView: View {
VStack(alignment: .leading) {
ForEach(Array(zip(dms.events, dms.events.indices)), id: \.0.id) { (ev, ind) in
DMView(event: dms.events[ind], damus_state: damus_state)
.event_context_menu(ev, keypair: damus_state.keypair)
.event_context_menu(ev, pubkey: ev.pubkey, privkey: damus_state.keypair.privkey)
}
EndBlock(height: 80)
}
@@ -149,7 +149,7 @@ struct DMChatView: View {
.opacity(((dms.events.count == 0) ? 1.0 : 0.0))
.foregroundColor(.gray)
}
.navigationTitle(NSLocalizedString("DMs", comment: "Navigation title for DMs view, where DM is the English abbreviation for Direct Message."))
.navigationTitle(NSLocalizedString("DM", comment: "Navigation title for DM view, which is the English abbreviation for Direct Message."))
.toolbar { Header }
}
}
+5 -5
View File
@@ -49,7 +49,7 @@ struct DirectMessagesView: View {
func MaybeEvent(_ tup: (String, DirectMessageModel)) -> some View {
Group {
if let ev = tup.1.events.last {
EventView(damus: damus_state, event: ev, pubkey: tup.0)
EventView(damus: damus_state, event: ev, pubkey: tup.0, show_friend_icon: true)
.onTapGesture {
pubkey = tup.0
active_model = tup.1
@@ -63,11 +63,11 @@ struct DirectMessagesView: View {
var body: some View {
VStack {
Picker(NSLocalizedString("DM Type", comment: "DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet. DM is the English abbreviation for Direct Message."), selection: $dm_type) {
Text("DMs", comment: "Picker option for DM selector for seeing only DMs that have been responded to. DM is the English abbreviation for Direct Message.")
Picker(NSLocalizedString("DM Type", comment: "DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet."), selection: $dm_type) {
Text("DMs")
.tag(DMType.friend)
Text("Requests", comment: "Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet). DM is the English abbreviation for Direct Message.")
Text("Requests")
.tag(DMType.rando)
}
@@ -84,7 +84,7 @@ struct DirectMessagesView: View {
}
.padding(.horizontal)
.padding(.top)
.navigationTitle(NSLocalizedString("DMs", comment: "Navigation title for view of DMs, where DM is an English abbreviation for Direct Message."))
.navigationTitle(NSLocalizedString("Encrypted DMs", comment: "Navigation title for view of encrypted DMs, where DM is an English abbreviation for Direct Message."))
}
}
-96
View File
@@ -1,96 +0,0 @@
//
// EULAView.swift
// damus
//
// Created by William Casarin on 2023-01-25.
//
import SwiftUI
struct EULAView: View {
@Environment(\.dismiss) var dismiss
@State var creating_account = false
var body: some View {
ZStack {
DamusGradient()
ScrollView {
Text("EULA", comment: "Label indicating that the below text is the EULA, an acronym for End User License Agreement.")
.font(.title.bold())
.foregroundColor(.white)
Text(Markdown.parse(content: """
End User License Agreement
## Introduction
This End User License Agreement ("EULA") is a legal agreement between you and Damus Nostr Inc. for the use of our mobile application Damus. By installing, accessing, or using our application, you agree to be bound by the terms and conditions of this EULA.
## Prohibited Content and Conduct
You agree not to use our application to create, upload, post, send, or store any content that:
* Is illegal, infringing, or fraudulent
* Is defamatory, libelous, or threatening
* Is pornographic, obscene, or offensive
* Is discriminatory or promotes hate speech
* Is harmful to minors
* Is intended to harass or bully others
* Is intended to impersonate others
## You also agree not to engage in any conduct that:
* Harasses or bullies others
* Impersonates others
* Is intended to intimidate or threaten others
* Is intended to promote or incite violence
## Consequences of Violation
Any violation of this EULA, including the prohibited content and conduct outlined above, may result in the termination of your access to our application.
## Disclaimer of Warranties and Limitation of Liability
Our application is provided "as is" and "as available" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. We do not guarantee that our application will be uninterrupted or error-free. In no event shall Damus Nostr Inc. be liable for any damages whatsoever, including but not limited to direct, indirect, special, incidental, or consequential damages, arising out of or in connection with the use or inability to use our application.
## Changes to EULA
We reserve the right to update or modify this EULA at any time and without prior notice. Your continued use of our application following any changes to this EULA will be deemed to be your acceptance of such changes.
## Contact Information
If you have any questions about this EULA, please contact us at damus@jb55.com
## Acceptance of Terms
By using our Application, you signify your acceptance of this EULA. If you do not agree to this EULA, you may not use our Application.
"""))
.padding()
NavigationLink(destination: CreateAccountView(), isActive: $creating_account) {
EmptyView()
}
DamusWhiteButton(NSLocalizedString("Accept", comment: "Button to accept the end user license agreement before being allowed into the app.")) {
creating_account = true
}
DamusWhiteButton(NSLocalizedString("Reject", comment: "Button to reject the end user license agreement, which disallows the user from being let into the app.")) {
dismiss()
}
}
.padding()
}
.navigationBarTitleDisplayMode(.inline)
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: BackNav())
.foregroundColor(.white)
}
}
struct EULAView_Previews: PreviewProvider {
static var previews: some View {
EULAView()
}
}
+1 -1
View File
@@ -72,7 +72,7 @@ struct EventDetailView: View {
toggle_thread_view()
}
case .event(let ev, let highlight):
EventView(event: ev, has_action_bar: true, damus: damus)
EventView(event: ev, highlight: highlight, has_action_bar: true, damus: damus, show_friend_icon: true)
.onTapGesture {
if thread.initial_event.id == ev.id {
toggle_thread_view()
+249 -49
View File
@@ -8,9 +8,38 @@
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
}
}
}
enum EventViewKind {
case small
case normal
case big
case selected
}
@@ -20,40 +49,121 @@ func eventviewsize_to_font(_ size: EventViewKind) -> Font {
return .body
case .normal:
return .body
case .big:
return .headline
case .selected:
return .custom("selected", size: 21.0)
}
}
struct BuilderEventView: View {
let damus: DamusState
let event_id: String
@State var event: NostrEvent?
@State var subscription_uuid: String = UUID().description
func unsubscribe() {
damus.pool.unsubscribe(sub_id: subscription_uuid)
}
func subscribe(filters: [NostrFilter]) {
damus.pool.register_handler(sub_id: subscription_uuid, handler: handle_event)
damus.pool.send(.subscribe(.init(filters: filters, sub_id: subscription_uuid)))
}
func handle_event(relay_id: String, ev: NostrConnectionEvent) {
guard case .nostr_event(let nostr_response) = ev else {
return
}
guard case .event(let id, let nostr_event) = nostr_response else {
return
}
// Is current event
if id == subscription_uuid {
if event != nil {
return
}
event = nostr_event
unsubscribe()
}
}
func load() {
subscribe(filters: [
NostrFilter(
ids: [self.event_id],
limit: 1
)
])
}
var body: some View {
VStack {
if let event = event {
let ev = event.inner_event ?? event
NavigationLink(destination: BuildThreadV2View(damus: damus, event_id: ev.id)) {
EventView(damus: damus, event: event, show_friend_icon: true, size: .small, embedded: true)
}.buttonStyle(.plain)
} else {
ProgressView().padding()
}
}
.frame(minWidth: 0, maxWidth: .infinity)
.border(Color.gray.opacity(0.2), width: 1)
.cornerRadius(2)
.onAppear {
self.load()
}
}
}
struct EventView: View {
let event: NostrEvent
let highlight: Highlight
let has_action_bar: Bool
let damus: DamusState
let pubkey: String
let show_friend_icon: Bool
let size: EventViewKind
let embedded: Bool
@EnvironmentObject var action_bar: ActionBarModel
init(event: NostrEvent, has_action_bar: Bool, damus: DamusState) {
init(event: NostrEvent, highlight: Highlight, has_action_bar: Bool, damus: DamusState, show_friend_icon: Bool, size: EventViewKind = .normal, embedded: Bool = false) {
self.event = event
self.highlight = highlight
self.has_action_bar = has_action_bar
self.damus = damus
self.pubkey = event.pubkey
self.show_friend_icon = show_friend_icon
self.size = size
self.embedded = embedded
}
init(damus: DamusState, event: NostrEvent) {
init(damus: DamusState, event: NostrEvent, show_friend_icon: Bool, size: EventViewKind = .normal, embedded: Bool = false) {
self.event = event
self.highlight = .none
self.has_action_bar = false
self.damus = damus
self.pubkey = event.pubkey
self.show_friend_icon = show_friend_icon
self.size = size
self.embedded = embedded
}
init(damus: DamusState, event: NostrEvent, pubkey: String) {
init(damus: DamusState, event: NostrEvent, pubkey: String, show_friend_icon: Bool, size: EventViewKind = .normal, embedded: Bool = false) {
self.event = event
self.highlight = .none
self.has_action_bar = false
self.damus = damus
self.pubkey = pubkey
self.show_friend_icon = show_friend_icon
self.size = size
self.embedded = embedded
}
var body: some View {
@@ -80,47 +190,85 @@ struct EventView: View {
}
func TextEvent(_ event: NostrEvent, pubkey: String, booster_pubkey: String? = nil) -> some View {
let content = event.get_content(damus.keypair.privkey)
return HStack(alignment: .top) {
let profile = damus.profiles.lookup(id: pubkey)
VStack {
let pmodel = ProfileModel(pubkey: pubkey, damus: damus)
let pv = ProfileView(damus_state: damus, profile: pmodel, followers: FollowersModel(damus_state: damus, target: pubkey))
NavigationLink(destination: pv) {
ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus.profiles)
if size != .selected {
VStack {
let pmodel = ProfileModel(pubkey: pubkey, damus: damus)
let pv = ProfileView(damus_state: damus, profile: pmodel, followers: FollowersModel(damus_state: damus, target: pubkey))
if !embedded {
NavigationLink(destination: pv) {
ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: highlight, profiles: damus.profiles)
}
}
Spacer()
}
Spacer()
}
VStack(alignment: .leading) {
HStack(alignment: .center) {
EventProfileName(pubkey: pubkey, profile: profile, damus: damus, show_friend_confirmed: true, size: .normal)
if size == .selected {
VStack {
let pmodel = ProfileModel(pubkey: pubkey, damus: damus)
let pv = ProfileView(damus_state: damus, profile: pmodel, followers: FollowersModel(damus_state: damus, target: pubkey))
NavigationLink(destination: pv) {
ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: highlight, profiles: damus.profiles)
}
}
}
Text("\(format_relative_time(event.created_at))")
EventProfileName(pubkey: pubkey, profile: profile, damus: damus, show_friend_confirmed: show_friend_icon, size: size)
if size != .selected {
Text("\(format_relative_time(event.created_at))")
.font(eventviewsize_to_font(size))
.foregroundColor(.gray)
}
}
if event.is_reply(damus.keypair.privkey) {
Text("\(reply_desc(profiles: damus.profiles, event: event))")
.font(.footnote)
.foregroundColor(.gray)
Spacer()
}
EventBody(damus_state: damus, event: event, size: .normal)
if let mention = first_eref_mention(ev: event, privkey: damus.keypair.privkey) {
BuilderEventView(damus: damus, event_id: mention.ref.id)
}
if has_action_bar {
Rectangle().frame(height: 2).opacity(0)
let bar = make_actionbar_model(ev: event, damus: damus)
EventActionBar(damus_state: damus, event: event, bar: bar)
.padding([.top], 4)
.frame(maxWidth: .infinity, alignment: .leading)
}
Divider()
.padding([.top], 4)
let should_show_img = should_show_images(contacts: damus.contacts, ev: event, our_pubkey: damus.pubkey, booster_pubkey: booster_pubkey)
NoteContentView(privkey: damus.keypair.privkey, event: event, profiles: damus.profiles, previews: damus.previews, show_images: should_show_img, artifacts: .just_content(content), size: self.size)
.frame(maxWidth: .infinity, alignment: .leading)
.allowsHitTesting(!embedded)
if !embedded {
if let mention = first_eref_mention(ev: event, privkey: damus.keypair.privkey) {
BuilderEventView(damus: damus, event_id: mention.ref.id)
}
if has_action_bar {
if size == .selected {
Text("\(format_date(event.created_at))")
.padding(.top, 10)
.font(.footnote)
.foregroundColor(.gray)
Divider()
.padding([.bottom], 4)
} else {
Rectangle().frame(height: 2).opacity(0)
}
let bar = make_actionbar_model(ev: event, damus: damus)
EventActionBar(damus_state: damus, event: event, bar: bar)
}
Divider()
.padding([.top], 4)
}
}
.padding([.leading], 2)
}
@@ -129,7 +277,7 @@ struct EventView: View {
.id(event.id)
.frame(maxWidth: .infinity, minHeight: PFP_SIZE)
.padding([.bottom], 2)
.event_context_menu(event, keypair: damus.keypair)
.event_context_menu(event, pubkey: pubkey, privkey: damus.keypair.privkey)
}
}
@@ -171,9 +319,37 @@ extension View {
}
}
func event_context_menu(_ event: NostrEvent, keypair: Keypair) -> some View {
func event_context_menu(_ event: NostrEvent, pubkey: String, privkey: String?) -> some View {
return self.contextMenu {
EventMenuContext(event: event, keypair: keypair)
Button {
UIPasteboard.general.string = event.get_content(privkey)
} label: {
Label(NSLocalizedString("Copy Text", comment: "Context menu option for copying the text from an note."), systemImage: "doc.on.doc")
}
Button {
UIPasteboard.general.string = bech32_pubkey(pubkey) ?? pubkey
} label: {
Label(NSLocalizedString("Copy User ID", comment: "Context menu option for copying the ID of the user who created the note."), systemImage: "person")
}
Button {
UIPasteboard.general.string = bech32_note_id(event.id) ?? event.id
} label: {
Label(NSLocalizedString("Copy Note ID", comment: "Context menu option for copying the ID of the note."), systemImage: "note.text")
}
Button {
UIPasteboard.general.string = event_to_json(ev: event)
} label: {
Label(NSLocalizedString("Copy Note JSON", comment: "Context menu option for copying the JSON text from the note."), systemImage: "j.square.on.square")
}
Button {
NotificationCenter.default.post(name: .broadcast_event, object: event)
} label: {
Label(NSLocalizedString("Broadcast", comment: "Context menu option for broadcasting the user's note to all of the user's connected relay servers."), systemImage: "globe")
}
}
}
@@ -193,6 +369,33 @@ func format_date(_ created_at: Int64) -> String {
}
func reply_desc(profiles: Profiles, event: NostrEvent) -> String {
let desc = make_reply_description(event.tags)
let pubkeys = desc.pubkeys
let n = desc.others
if desc.pubkeys.count == 0 {
return NSLocalizedString("Reply to self", comment: "Label to indicate that the user is replying to themself.")
}
let names: [String] = pubkeys.map {
let prof = profiles.lookup(id: $0)
return Profile.displayName(profile: prof, pubkey: $0)
}
if names.count == 2 {
if n > 2 {
let othersCount = n - pubkeys.count
return String(format: NSLocalizedString("replying_to_two_and_others", comment: "Label to indicate that the user is replying to 2 users and others."), names[0], names[1], othersCount)
}
return String(format: NSLocalizedString("Replying to %@ & %@", comment: "Label to indicate that the user is replying to 2 users."), names[0], names[1])
}
let othersCount = n - pubkeys.count
return String(format: NSLocalizedString("replying_to_one_and_others", comment: "Label to indicate that the user is replying to 1 user and others."), names[0], othersCount)
}
func make_actionbar_model(ev: NostrEvent, damus: DamusState) -> ActionBarModel {
let likes = damus.likes.counts[ev.id]
@@ -215,25 +418,22 @@ func make_actionbar_model(ev: NostrEvent, damus: DamusState) -> ActionBarModel {
struct EventView_Previews: PreviewProvider {
static var previews: some View {
VStack {
/*
EventView(damus: test_damus_state(), event: NostrEvent(content: "hello there https://jb55.com/s/Oct12-150217.png https://jb55.com/red-me.jb55 cool", pubkey: "pk"), show_friend_icon: true, size: .small)
EventView(damus: test_damus_state(), event: NostrEvent(content: "hello there https://jb55.com/s/Oct12-150217.png https://jb55.com/red-me.jb55 cool", pubkey: "pk"), show_friend_icon: true, size: .normal)
EventView(damus: test_damus_state(), event: NostrEvent(content: "hello there https://jb55.com/s/Oct12-150217.png https://jb55.com/red-me.jb55 cool", pubkey: "pk"), show_friend_icon: true, size: .big)
*/
EventView(
event: test_event,
event: NostrEvent(
content: "hello there https://jb55.com/s/Oct12-150217.png https://jb55.com/red-me.jb55 cool",
pubkey: "pk",
createdAt: Int64(Date().timeIntervalSince1970 - 100)
),
highlight: .none,
has_action_bar: true,
damus: test_damus_state()
damus: test_damus_state(),
show_friend_icon: true,
size: .selected
)
}
.padding()
}
}
let test_event =
NostrEvent(
content: "hello there https://jb55.com/s/Oct12-150217.png https://jb55.com/red-me.jpg cool",
pubkey: "pk",
createdAt: Int64(Date().timeIntervalSince1970 - 100)
)
-81
View File
@@ -1,81 +0,0 @@
//
// BuilderEventView.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import SwiftUI
struct BuilderEventView: View {
let damus: DamusState
let event_id: String
@State var event: NostrEvent?
@State var subscription_uuid: String = UUID().description
func unsubscribe() {
damus.pool.unsubscribe(sub_id: subscription_uuid)
}
func subscribe(filters: [NostrFilter]) {
damus.pool.register_handler(sub_id: subscription_uuid, handler: handle_event)
damus.pool.send(.subscribe(.init(filters: filters, sub_id: subscription_uuid)))
}
func handle_event(relay_id: String, ev: NostrConnectionEvent) {
guard case .nostr_event(let nostr_response) = ev else {
return
}
guard case .event(let id, let nostr_event) = nostr_response else {
return
}
// Is current event
if id == subscription_uuid {
if event != nil {
return
}
event = nostr_event
unsubscribe()
}
}
func load() {
subscribe(filters: [
NostrFilter(
ids: [self.event_id],
limit: 1
)
])
}
var body: some View {
VStack {
if let event = event {
let ev = event.inner_event ?? event
NavigationLink(destination: BuildThreadV2View(damus: damus, event_id: ev.id)) {
EmbeddedEventView(damus_state: damus, event: event)
.padding(8)
}.buttonStyle(.plain)
} else {
ProgressView().padding()
}
}
.frame(minWidth: 0, maxWidth: .infinity)
.cornerRadius(8)
.border(Color.gray.opacity(0.2), width: 1)
.onAppear {
self.load()
}
}
}
struct BuilderEventView_Previews: PreviewProvider {
static var previews: some View {
BuilderEventView(damus: test_damus_state(), event_id: "536bee9e83c818e3b82c101935128ae27a0d4290039aaf253efe5f09232c1962")
}
}
@@ -1,35 +0,0 @@
//
// EmbeddedEventView.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import SwiftUI
struct EmbeddedEventView: View {
let damus_state: DamusState
let event: NostrEvent
var pubkey: String {
event.pubkey
}
var body: some View {
VStack(alignment: .leading) {
let profile = damus_state.profiles.lookup(id: pubkey)
EventProfile(damus_state: damus_state, pubkey: pubkey, profile: profile, size: .small)
EventBody(damus_state: damus_state, event: event, size: .small)
}
.event_context_menu(event, keypair: damus_state.keypair)
}
}
struct EmbeddedEventView_Previews: PreviewProvider {
static var previews: some View {
EmbeddedEventView(damus_state: test_damus_state(), event: test_event)
.padding()
}
}
-35
View File
@@ -1,35 +0,0 @@
//
// EventBody.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import SwiftUI
struct EventBody: View {
let damus_state: DamusState
let event: NostrEvent
let size: EventViewKind
var content: String {
event.get_content(damus_state.keypair.privkey)
}
var body: some View {
if event_is_reply(event, privkey: damus_state.keypair.privkey) {
ReplyDescription(event: event, profiles: damus_state.profiles)
}
let should_show_img = should_show_images(contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey, booster_pubkey: nil)
NoteContentView(privkey: damus_state.keypair.privkey, event: event, profiles: damus_state.profiles, previews: damus_state.previews, show_images: should_show_img, artifacts: .just_content(content), size: size)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
struct EventBody_Previews: PreviewProvider {
static var previews: some View {
EventBody(damus_state: test_damus_state(), event: test_event, size: .normal)
}
}
-101
View File
@@ -1,101 +0,0 @@
//
// EventMenu.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import SwiftUI
struct EventMenuContext: View {
let event: NostrEvent
let keypair: Keypair
var body: some View {
Button {
UIPasteboard.general.string = event.get_content(keypair.privkey)
} label: {
Label(NSLocalizedString("Copy Text", comment: "Context menu option for copying the text from an note."), systemImage: "doc.on.doc")
}
Button {
UIPasteboard.general.string = keypair.pubkey_bech32
} label: {
Label(NSLocalizedString("Copy User Pubkey", comment: "Context menu option for copying the ID of the user who created the note."), systemImage: "person")
}
Button {
UIPasteboard.general.string = bech32_note_id(event.id) ?? event.id
} label: {
Label(NSLocalizedString("Copy Note ID", comment: "Context menu option for copying the ID of the note."), systemImage: "note.text")
}
Button {
UIPasteboard.general.string = event_to_json(ev: event)
} label: {
Label(NSLocalizedString("Copy Note JSON", comment: "Context menu option for copying the JSON text from the note."), systemImage: "square.on.square")
}
Button {
NotificationCenter.default.post(name: .broadcast_event, object: event)
} label: {
Label(NSLocalizedString("Broadcast", comment: "Context menu option for broadcasting the user's note to all of the user's connected relay servers."), systemImage: "globe")
}
// Only allow reporting if logged in with private key and the currently viewed profile is not the logged in profile.
if keypair.pubkey != event.pubkey && keypair.privkey != nil {
Button(role: .destructive) {
let target: ReportTarget = .note(ReportNoteTarget(pubkey: event.pubkey, note_id: event.id))
notify(.report, target)
} label: {
Label(NSLocalizedString("Report", comment: "Context menu option for reporting content."), systemImage: "exclamationmark.bubble")
}
Button(role: .destructive) {
notify(.block, event.pubkey)
} label: {
Label(NSLocalizedString("Block", comment: "Context menu option for blocking users."), systemImage: "exclamationmark.octagon")
}
}
}
}
/*
struct EventMenu: UIViewRepresentable {
typealias UIViewType = UIButton
let saveAction = UIAction(title: "") { action in }
let saveMenu = UIMenu(title: "", children: [
UIAction(title: "First Menu Item", image: UIImage(systemName: "nameOfSFSymbol")) { action in
//code action for menu item
},
UIAction(title: "First Menu Item", image: UIImage(systemName: "nameOfSFSymbol")) { action in
//code action for menu item
},
UIAction(title: "First Menu Item", image: UIImage(systemName: "nameOfSFSymbol")) { action in
//code action for menu item
},
])
func makeUIView(context: Context) -> UIButton {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
button.showsMenuAsPrimaryAction = true
button.menu = saveMenu
return button
}
func updateUIView(_ uiView: UIButton, context: Context) {
uiView.setImage(UIImage(systemName: "plus"), for: .normal)
}
}
struct EventMenu_Previews: PreviewProvider {
static var previews: some View {
EventMenu(event: test_event, privkey: nil, pubkey: test_event.pubkey)
}
}
*/
-51
View File
@@ -1,51 +0,0 @@
//
// EventProfile.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import SwiftUI
func eventview_pfp_size(_ size: EventViewKind) -> CGFloat {
switch size {
case .small:
return PFP_SIZE * 0.5
case .normal:
return PFP_SIZE
case .selected:
return PFP_SIZE
}
}
struct EventProfile: View {
let damus_state: DamusState
let pubkey: String
let profile: Profile?
let size: EventViewKind
var pfp_size: CGFloat {
eventview_pfp_size(size)
}
var body: some View {
HStack(alignment: .center) {
VStack {
let pmodel = ProfileModel(pubkey: pubkey, damus: damus_state)
let pv = ProfileView(damus_state: damus_state, profile: pmodel, followers: FollowersModel(damus_state: damus_state, target: pubkey))
NavigationLink(destination: pv) {
ProfilePicView(pubkey: pubkey, size: pfp_size, highlight: .none, profiles: damus_state.profiles)
}
}
EventProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: true, size: size)
}
}
}
struct EventProfile_Previews: PreviewProvider {
static var previews: some View {
EventProfile(damus_state: test_damus_state(), pubkey: "pk", profile: nil, size: .normal)
}
}
-55
View File
@@ -1,55 +0,0 @@
//
// ReplyDescription.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import SwiftUI
// jb55 - TODO: this could be a lot better
struct ReplyDescription: View {
let event: NostrEvent
let profiles: Profiles
var body: some View {
Text("\(reply_desc(profiles: profiles, event: event))")
.font(.footnote)
.foregroundColor(.gray)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
struct ReplyDescription_Previews: PreviewProvider {
static var previews: some View {
ReplyDescription(event: test_event, profiles: test_damus_state().profiles)
}
}
func reply_desc(profiles: Profiles, event: NostrEvent) -> String {
let desc = make_reply_description(event.tags)
let pubkeys = desc.pubkeys
let n = desc.others
if desc.pubkeys.count == 0 {
return NSLocalizedString("Reply to self", comment: "Label to indicate that the user is replying to themself.")
}
let names: [String] = pubkeys.map {
let prof = profiles.lookup(id: $0)
return Profile.displayName(profile: prof, pubkey: $0)
}
if names.count == 2 {
if n > 2 {
let othersCount = n - pubkeys.count
return String(format: NSLocalizedString("replying_to_two_and_others", comment: "Label to indicate that the user is replying to 2 users and others."), names[0], names[1], othersCount)
}
return String(format: NSLocalizedString("Replying to %@ & %@", comment: "Label to indicate that the user is replying to 2 users."), names[0], names[1])
}
let othersCount = n - pubkeys.count
return String(format: NSLocalizedString("replying_to_one_and_others", comment: "Label to indicate that the user is replying to 1 user and others."), names[0], othersCount)
}
@@ -1,62 +0,0 @@
//
// SelectedEventView.swift
// damus
//
// Created by William Casarin on 2023-01-23.
//
import SwiftUI
struct SelectedEventView: View {
let damus: DamusState
let event: NostrEvent
var pubkey: String {
event.pubkey
}
var body: some View {
HStack(alignment: .top) {
let profile = damus.profiles.lookup(id: pubkey)
VStack(alignment: .leading) {
EventProfile(damus_state: damus, pubkey: pubkey, profile: profile, size: .normal)
EventBody(damus_state: damus, event: event, size: .selected)
if let mention = first_eref_mention(ev: event, privkey: damus.keypair.privkey) {
BuilderEventView(damus: damus, event_id: mention.ref.id)
}
Text("\(format_date(event.created_at))")
.padding(.top, 10)
.font(.footnote)
.foregroundColor(.gray)
Divider()
.padding([.bottom], 4)
let bar = make_actionbar_model(ev: event, damus: damus)
if !bar.is_empty {
EventDetailBar(state: damus, target: event.id, bar: bar)
Divider()
}
EventActionBar(damus_state: damus, event: event, bar: bar)
.padding([.top], 4)
Divider()
.padding([.top], 4)
}
.padding([.leading], 2)
.event_context_menu(event, keypair: damus.keypair)
}
}
}
struct SelectedEventView_Previews: PreviewProvider {
static var previews: some View {
SelectedEventView(damus: test_damus_state(), event: test_event)
.padding()
}
}
+20 -1
View File
@@ -15,7 +15,26 @@ struct FollowUserView: View {
var body: some View {
HStack {
UserView(damus_state: damus_state, pubkey: target.pubkey)
let pmodel = ProfileModel(pubkey: target.pubkey, damus: damus_state)
let followers = FollowersModel(damus_state: damus_state, target: target.pubkey)
let pv = ProfileView(damus_state: damus_state, profile: pmodel, followers: followers)
NavigationLink(destination: pv) {
ProfilePicView(pubkey: target.pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles)
VStack(alignment: .leading) {
let profile = damus_state.profiles.lookup(id: target.pubkey)
ProfileName(pubkey: target.pubkey, profile: profile, damus: damus_state, show_friend_confirmed: false, show_nip5_domain: false)
if let about = profile?.about {
Text(FollowUserView.markdown.process(about))
.lineLimit(3)
.font(.footnote)
}
}
Spacer()
}
.buttonStyle(PlainButtonStyle())
FollowButtonView(target: target, follow_state: damus_state.contacts.follow_state(target.pubkey))
}
-67
View File
@@ -1,67 +0,0 @@
//
// MutelistView.swift
// damus
//
// Created by William Casarin on 2023-01-25.
//
import SwiftUI
struct MutelistView: View {
let damus_state: DamusState
@State var users: [String]
func RemoveAction(pubkey: String) -> some View {
Button {
guard let mutelist = damus_state.contacts.mutelist else {
return
}
guard let keypair = damus_state.keypair.to_full() else {
return
}
guard let new_ev = remove_from_mutelist(keypair: keypair, prev: mutelist, to_remove: pubkey) else {
return
}
damus_state.contacts.set_mutelist(new_ev)
damus_state.pool.send(.event(new_ev))
users = get_mutelist_users(new_ev)
} label: {
Label(NSLocalizedString("Delete", comment: "Button to remove a user from their blocklist."), systemImage: "trash")
}
.tint(.red)
}
var body: some View {
List(users, id: \.self) { pubkey in
UserView(damus_state: damus_state, pubkey: pubkey)
.id(pubkey)
.swipeActions {
RemoveAction(pubkey: pubkey)
}
}
.navigationTitle(NSLocalizedString("Blocked Users", comment: "Navigation title of view to see list of blocked users."))
}
}
func get_mutelist_users(_ mlist: NostrEvent?) -> [String] {
guard let mutelist = mlist else {
return []
}
return mutelist.tags.reduce(into: Array<String>()) { pks, tag in
if tag.count >= 2 && tag[0] == "p" {
pks.append(tag[1])
}
}
}
struct MutelistView_Previews: PreviewProvider {
static var previews: some View {
MutelistView(damus_state: test_damus_state(), users: [test_event.pubkey, test_event.pubkey+"hi"])
}
}
-79
View File
@@ -1,79 +0,0 @@
//
// ParicipantsView.swift
// damus
//
// Created by Joel Klabo on 1/18/23.
//
import SwiftUI
struct ParticipantsView: View {
let damus_state: DamusState
@Binding var references: [ReferencedId]
@Binding var originalReferences: [ReferencedId]
var body: some View {
VStack {
Text("Edit participants", comment: "Text indicating that the view is used for editing which participants are replied to in a note.")
HStack {
Spacer()
Button {
// Remove all "p" refs, keep "e" refs
references = originalReferences.eRefs
} label: {
Text("Remove all", comment: "Button label to remove all participants from a note reply.")
}
.buttonStyle(.borderedProminent)
Spacer()
Button {
references = originalReferences
} label: {
Text("Add all", comment: "Button label to re-add all original participants as profiles to reply to in a note")
}
.buttonStyle(.borderedProminent)
Spacer()
}
VStack {
ForEach(originalReferences.pRefs) { participant in
let pubkey = participant.id
HStack {
ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles)
VStack(alignment: .leading) {
let profile = damus_state.profiles.lookup(id: pubkey)
ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: false, show_nip5_domain: false)
if let about = profile?.about {
Text(FollowUserView.markdown.process(about))
.lineLimit(3)
.font(.footnote)
}
}
Spacer()
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 30))
.foregroundColor(references.contains(participant) ? .purple : .gray)
}
.onTapGesture {
if references.contains(participant) {
references = references.filter {
$0 != participant
}
} else {
if references.contains(participant) {
// Don't add it twice
} else {
references.append(participant)
}
}
}
}
}
Spacer()
}
.padding()
}
}
+1 -1
View File
@@ -46,7 +46,7 @@ struct InnerProfilePicView: View {
self.imageModel = KFImageModel(
url: url,
fallbackUrl: fallbackUrl,
maxByteSize: 5_242_880, // 5Mib
maxByteSize: 1000000,
downsampleSize: CGSize(width: 200, height: 200)
)
}
+18 -78
View File
@@ -114,13 +114,11 @@ struct ProfileView: View {
@State var showing_select_wallet: Bool = false
@State var is_zoomed: Bool = false
@State var show_share_sheet: Bool = false
@State var action_sheet_presented: Bool = false
@StateObject var user_settings = UserSettingsStore()
@Environment(\.dismiss) var dismiss
@Environment(\.colorScheme) var colorScheme
@Environment(\.openURL) var openURL
// We just want to have a white "< Home" text here, however,
// setting the initialiser is causing issues, and it's late.
// Ref: https://blog.techchee.com/navigation-bar-title-style-color-and-custom-back-button-in-swiftui/
@@ -148,7 +146,9 @@ struct ProfileView: View {
}
}) {
Image(systemName: "bolt.circle")
.profile_button_style(scheme: colorScheme)
.symbolRenderingMode(.palette)
.foregroundStyle(colorScheme == .dark ? .white : .black, colorScheme == .dark ? .white : .black)
.font(.system(size: 32).weight(.thin))
.contextMenu {
Button {
UIPasteboard.general.string = profile.lnurl ?? ""
@@ -167,21 +167,15 @@ struct ProfileView: View {
static let markdown = Markdown()
var ActionSheetButton: some View {
Button(action: {
action_sheet_presented = true
}) {
Image(systemName: "ellipsis.circle")
.profile_button_style(scheme: colorScheme)
}
}
var ShareButton: some View {
Button(action: {
show_share_sheet = true
}) {
Image(systemName: "square.and.arrow.up.circle")
.profile_button_style(scheme: colorScheme)
Image(systemName: "square.and.arrow.up.circle.fill")
.symbolRenderingMode(.palette)
.font(.system(size: 32))
.padding()
.foregroundStyle(.white, .black, .black.opacity(0.8))
}
}
@@ -191,48 +185,24 @@ struct ProfileView: View {
.environmentObject(dm_model)
return NavigationLink(destination: dmview) {
Image(systemName: "bubble.left.circle")
.profile_button_style(scheme: colorScheme)
.symbolRenderingMode(.palette)
.font(.system(size: 32).weight(.thin))
.foregroundStyle(colorScheme == .dark ? .white : .black, colorScheme == .dark ? .white : .black)
}
}
private func getScrollOffset(_ geometry: GeometryProxy) -> CGFloat {
geometry.frame(in: .global).minY
}
private func getHeightForHeaderImage(_ geometry: GeometryProxy) -> CGFloat {
let offset = getScrollOffset(geometry)
let imageHeight = 150.0
if offset > 0 {
return imageHeight + offset
}
return imageHeight
}
private func getOffsetForHeaderImage(_ geometry: GeometryProxy) -> CGFloat {
let offset = getScrollOffset(geometry)
// Image was pulled down
if offset > 0 {
return -offset
}
return 0
}
var TopSection: some View {
ZStack(alignment: .top) {
GeometryReader { geometry in
GeometryReader { geo in
BannerImageView(pubkey: profile.pubkey, profiles: damus_state.profiles)
.aspectRatio(contentMode: .fill)
.frame(width: geometry.size.width, height: self.getHeightForHeaderImage(geometry))
.frame(width: geo.size.width, height: BANNER_HEIGHT)
.clipped()
.offset(x: 0, y: self.getOffsetForHeaderImage(geometry))
ShareButton
.offset(x: geo.size.width - 80.0, y: 50.0 )
}.frame(height: BANNER_HEIGHT)
VStack(alignment: .leading, spacing: 8.0) {
VStack(alignment: .leading) {
let data = damus_state.profiles.lookup(id: profile.pubkey)
let pfp_size: CGFloat = 90.0
@@ -248,7 +218,6 @@ struct ProfileView: View {
Spacer()
Group {
ActionSheetButton
if let profile = data {
if let lnurl = profile.lnurl, lnurl != "" {
@@ -281,10 +250,6 @@ struct ProfileView: View {
Text(ProfileView.markdown.process(data?.about ?? ""))
.font(.subheadline)
if let url = data?.website_url {
WebsiteLink(url: url)
}
Divider()
HStack {
@@ -374,23 +339,6 @@ struct ProfileView: View {
}
}
}
.confirmationDialog(NSLocalizedString("Actions", comment: "Title for confirmation dialog to either share, report, or block a profile."), isPresented: $action_sheet_presented) {
Button(NSLocalizedString("Share", comment: "Button to share the link to a profile.")) {
show_share_sheet = true
}
// Only allow reporting if logged in with private key and the currently viewed profile is not the logged in profile.
if profile.pubkey != damus_state.pubkey && damus_state.is_privkey_user {
Button(NSLocalizedString("Report", comment: "Button to report a profile."), role: .destructive) {
let target: ReportTarget = .user(profile.pubkey)
notify(.report, target)
}
Button(NSLocalizedString("Block", comment: "Button to block a profile."), role: .destructive) {
notify(.block, profile.pubkey)
}
}
}
.ignoresSafeArea()
}
}
@@ -491,11 +439,3 @@ struct KeyView: View {
}
}
}
extension View {
func profile_button_style(scheme: ColorScheme) -> some View {
self.symbolRenderingMode(.palette)
.font(.system(size: 32).weight(.thin))
.foregroundStyle(scheme == .dark ? .white : .black, scheme == .dark ? .white : .black)
}
}
+12 -11
View File
@@ -54,20 +54,23 @@ struct ProfileZoomView: View {
Color("DamusDarkGrey") // Or Color("DamusBlack")
.edgesIgnoringSafeArea(.all)
Button {
presentationMode.wrappedValue.dismiss()
} label: {
Image(systemName: "xmark")
.foregroundColor(.white)
.font(.subheadline)
.padding(.leading, 20)
HStack() {
Button {
presentationMode.wrappedValue.dismiss()
} label: {
Image(systemName: "xmark")
.foregroundColor(.white)
.font(.largeTitle)
.frame(width: 40, height: 40)
.padding(20)
}
}
.zIndex(1)
VStack(alignment: .center) {
Spacer()
.frame(height: 120)
ProfilePicView(pubkey: pubkey, size: 200.0, highlight: .none, profiles: profiles)
.padding(100)
.scaledToFit()
@@ -78,8 +81,6 @@ struct ProfileZoomView: View {
.modifier(SwipeToDismissModifier(minDistance: nil, onDismiss: {
presentationMode.wrappedValue.dismiss()
}))
Spacer()
}
}
+5 -19
View File
@@ -18,16 +18,11 @@ struct ReplyView: View {
let replying_to: NostrEvent
let damus: DamusState
@State var originalReferences: [ReferencedId] = []
@State var references: [ReferencedId] = []
@State var participantsShown: Bool = false
var body: some View {
VStack {
Text("Replying to:", comment: "Indicating that the user is replying to the following listed people.")
HStack(alignment: .top) {
let names = references.pRefs
let names = all_referenced_pubkeys(replying_to)
.map { pubkey in
let pk = pubkey.ref_id
let prof = damus.profiles.lookup(id: pk)
@@ -38,22 +33,13 @@ struct ReplyView: View {
.foregroundColor(.gray)
.font(.footnote)
}
.onTapGesture {
participantsShown.toggle()
}
.sheet(isPresented: $participantsShown) {
ParticipantsView(damus_state: damus, references: $references, originalReferences: $originalReferences)
}
ScrollView {
EventView(event: replying_to, has_action_bar: false, damus: damus)
EventView(event: replying_to, highlight: .none, has_action_bar: false, damus: damus, show_friend_icon: true)
}
PostView(replying_to: replying_to, references: references)
}
.onAppear {
references = gather_reply_ids(our_pubkey: damus.pubkey, from: replying_to)
originalReferences = references
PostView(replying_to: replying_to, references: gather_reply_ids(our_pubkey: damus.pubkey, from: replying_to))
}
.padding()
}
@@ -61,6 +47,6 @@ struct ReplyView: View {
struct ReplyView_Previews: PreviewProvider {
static var previews: some View {
ReplyView(replying_to: NostrEvent(content: "hi", pubkey: "pubkey"), damus: test_damus_state(), references: [])
ReplyView(replying_to: NostrEvent(content: "hi", pubkey: "pubkey"), damus: test_damus_state())
}
}
-115
View File
@@ -1,115 +0,0 @@
//
// ReportView.swift
// damus
//
// Created by William Casarin on 2023-01-25.
//
import SwiftUI
struct ReportView: View {
let pool: RelayPool
let target: ReportTarget
let privkey: String
@State var report_sent: Bool = false
@State var report_id: String = ""
var body: some View {
if report_sent {
Success
} else {
MainForm
}
}
var Success: some View {
VStack(alignment: .center, spacing: 20) {
Text("Report sent!", comment: "Message indicating that a report was successfully sent to relay servers.")
.font(.headline)
Text("Relays have been notified and clients will be able to use this information to filter content. Thank you!", comment: "Description of what was done as a result of sending a report to relay servers.")
Text("Report ID:", comment: "Label indicating that the text underneath is the identifier of the report that was sent to relay servers.")
Text(report_id)
Button(NSLocalizedString("Copy Report ID", comment: "Button to copy report ID.")) {
UIPasteboard.general.string = report_id
let g = UIImpactFeedbackGenerator(style: .medium)
g.impactOccurred()
}
}
.padding()
}
func do_send_report(type: ReportType) {
guard let ev = send_report(privkey: privkey, pool: pool, target: target, type: .spam) else {
return
}
guard let note_id = bech32_note_id(ev.id) else {
return
}
report_sent = true
report_id = note_id
}
var MainForm: some View {
VStack {
Text("Report", comment: "Label indicating that the current view is for the user to report content.")
.font(.headline)
.padding()
Form {
Section(content: {
Button(NSLocalizedString("It's spam", comment: "Button for user to report that the account or content has spam.")) {
do_send_report(type: .spam)
}
Button(NSLocalizedString("Nudity or explicit content", comment: "Button for user to report that the account or content has nudity or explicit content.")) {
do_send_report(type: .explicit)
}
Button(NSLocalizedString("Illegal content", comment: "Button for user to report that the account or content has illegal content.")) {
do_send_report(type: .illegal)
}
if case .user = target {
Button(NSLocalizedString("They are impersonating someone", comment: "Button for user to report that the account is impersonating someone.")) {
do_send_report(type: .impersonation)
}
}
}, header: {
Text("What do you want to report?", comment: "Header text to prompt user what issue they want to report.")
}, footer: {
Text("Your report will be sent to the relays you are connected to", comment: "Footer text to inform user what will happen when the report is submitted.")
})
}
}
}
}
func send_report(privkey: String, pool: RelayPool, target: ReportTarget, type: ReportType) -> NostrEvent? {
let report = Report(type: type, target: target, message: "")
guard let ev = create_report_event(privkey: privkey, report: report) else {
return nil
}
pool.send(.event(ev))
return ev
}
struct ReportView_Previews: PreviewProvider {
static var previews: some View {
let ds = test_damus_state()
VStack {
ReportView(pool: ds.pool, target: ReportTarget.user(""), privkey: "")
ReportView(pool: ds.pool, target: ReportTarget.user(""), privkey: "", report_sent: true, report_id: "report_id")
}
}
}
-24
View File
@@ -1,24 +0,0 @@
//
// RepostView.swift
// damus
//
// Created by Terry Yiu on 1/22/23.
//
import SwiftUI
struct RepostView: View {
let damus_state: DamusState
let repost: NostrEvent
var body: some View {
FollowUserView(target: .pubkey(repost.pubkey), damus_state: damus_state)
}
}
struct RepostView_Previews: PreviewProvider {
static var previews: some View {
RepostView(damus_state: test_damus_state(), repost: NostrEvent(id: "", content: "", pubkey: ""))
}
}
-38
View File
@@ -1,38 +0,0 @@
//
// RepostsView.swift
// damus
//
// Created by Terry Yiu on 1/22/23.
//
import SwiftUI
struct RepostsView: View {
let damus_state: DamusState
@StateObject var model: RepostsModel
var body: some View {
ScrollView {
LazyVStack {
ForEach(model.reposts, id: \.id) { ev in
RepostView(damus_state: damus_state, repost: ev)
}
}
.padding()
}
.navigationBarTitle(NSLocalizedString("Reposts", comment: "Navigation bar title for Reposts view."))
.onAppear {
model.subscribe()
}
.onDisappear {
model.unsubscribe()
}
}
}
struct RepostsView_Previews: PreviewProvider {
static var previews: some View {
let state = test_damus_state()
RepostsView(damus_state: state, model: RepostsModel(state: state, target: "pubkey"))
}
}
+1 -1
View File
@@ -42,7 +42,7 @@ struct SetupView: View {
DamusGradient()
VStack(alignment: .center) {
NavigationLink(destination: EULAView(), tag: .create_account, selection: $state ) {
NavigationLink(destination: CreateAccountView(), tag: .create_account, selection: $state ) {
EmptyView()
}
NavigationLink(destination: LoginView(), tag: .login, selection: $state ) {
+18 -8
View File
@@ -75,6 +75,22 @@ struct SideMenuView: View {
Divider()
.padding(.trailing,40)
/*
HStack(alignment: .bottom) {
Text("69,420")
.foregroundColor(.accentColor)
.font(.largeTitle)
Text("SATS")
.font(.caption)
.padding(.bottom,6)
}
Divider()
.padding(.trailing,40)
*/
// THERE IS A LIMIT OF 10 NAVIGATIONLINKS!!! (Consider some in other views)
NavigationLink(destination: ProfileView(damus_state: damus_state, profile: profile_model, followers: followers)) {
Label(NSLocalizedString("Profile", comment: "Sidebar menu label for Profile view."), systemImage: "person")
@@ -107,12 +123,6 @@ struct SideMenuView: View {
})
*/
NavigationLink(destination: MutelistView(damus_state: damus_state, users: get_mutelist_users(damus_state.contacts.mutelist) )) {
Label(NSLocalizedString("Blocked", comment: "Sidebar menu label for Profile view."), systemImage: "exclamationmark.octagon")
.font(.title2)
.foregroundColor(textColor())
}
NavigationLink(destination: ConfigView(state: damus_state).environmentObject(user_settings)) {
Label(NSLocalizedString("Settings", comment: "Sidebar menu label for accessing the app settings"), systemImage: "gear")
.font(.title2)
@@ -148,10 +158,10 @@ struct SideMenuView: View {
isSidebarVisible.toggle()
}
.alert("Logout", isPresented: $confirm_logout) {
Button(NSLocalizedString("Cancel", comment: "Cancel out of logging out the user."), role: .cancel) {
Button(NSLocalizedString("Cancel", comment: "Cancel out of logging out the user.")) {
confirm_logout = false
}
Button(NSLocalizedString("Logout", comment: "Button for logging out the user."), role: .destructive) {
Button(NSLocalizedString("Logout", comment: "Button for logging out the user.")) {
notify(.logout, ())
}
} message: {
+18 -4
View File
@@ -255,7 +255,14 @@ struct ThreadV2View: View {
// MARK: - Parents events view
VStack {
ForEach(thread.parentEvents, id: \.id) { event in
EventView(event: event, has_action_bar: true, damus: damus)
EventView(
event: event,
highlight: .none,
has_action_bar: true,
damus: damus,
show_friend_icon: true, // TODO: change it
size: .small
)
.onTapGesture {
nav_target = event.id
navigating = true
@@ -278,17 +285,24 @@ struct ThreadV2View: View {
})
// MARK: - Actual event view
SelectedEventView(
EventView(
event: thread.current,
highlight: .none,
has_action_bar: true,
damus: damus,
event: thread.current
show_friend_icon: true, // TODO: change it
size: .selected
).id("main")
// MARK: - Responses of the actual event view
ForEach(thread.childEvents, id: \.id) { event in
EventView(
event: event,
highlight: .none,
has_action_bar: true,
damus: damus
damus: damus,
show_friend_icon: true, // TODO: change it
size: .small
)
.onTapGesture {
nav_target = event.id
+1 -1
View File
@@ -43,7 +43,7 @@ struct InnerTimelineView: View {
//let is_chatroom = should_show_chatroom(ev)
//let tv = ThreadView(thread: tm, damus: damus, is_chatroom: is_chatroom)
EventView(event: ev, has_action_bar: true, damus: damus)
EventView(event: ev, highlight: .none, has_action_bar: true, damus: damus, show_friend_icon: show_friend_icon)
.onTapGesture {
nav_target = ev
navigating = true
-9
View File
@@ -1,9 +0,0 @@
/* Bundle display name */
"CFBundleDisplayName" = "Damus";
/* Bundle name */
"CFBundleName" = "damus";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Damus Zugriff auf deine Fotos zu gewähren erlaubt dir Bilder zu sichern.";
-503
View File
@@ -1,503 +0,0 @@
/* Blank space to separate profile picture from profile editor form. */
" " = "61b6edf1108e6f396680a33b02486a70_tr";
/* Description of how the nip05 identifier would be used for verification. */
"'%@' at '%@' will be used for verification" = "'%@' bei '%@' wird zur Verifizierung benutzt werden.";
/* Description of why the nip05 identifier is invalid. */
"'%@' is an invalid nip05 identifier. It should look like an email." = "'%@' ist eine ungültige nip05 Kennzeichnung. Diese sollte wie eine Emailadresse aussehen. ";
/* Navigation bar title for view that shows who is following a user. */
"(Profile.displayName(profile: profile, pubkey: whos))'s Followers" = "(Profile.displayName(profile: profile, pubkey: whos)) Follower";
/* Navigation bar title for view that shows who a user is following. */
"(who) following" = "(who) folgt";
/* Prefix character to username. */
"@" = "@";
/* Amount of time that has passed since reply quote event occurred.
Abbreviated version of a nostr public key. */
"%@" = "%@";
/* Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.
Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'. */
"%@ %@" = "%@ %@";
/* Explanation of what is done to keep personally identifiable information private. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction." = "%@. Ein Konto zu erstellen benötigt keine Telefonnummer, Emailadresse oder Namen. Fang jetzt gleich ganz reibungslos an.";
/* Explanation of what is done to keep private data encrypted. There is a heading that precedes this explanation which is a variable to this string. */
"%@. End-to-End encrypted private messaging. Keep Big Tech out of your DMs" = "%@. End-zu-End verschlüsselter privater Nachrichtenaustausch. Halte Tech-Riesen aus deinen PNs heraus";
/* Explanation of what can be done by users to earn money. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Tip your friend's posts and stack sats with Bitcoin⚡️, the native currency of the internet." = "%@. Belohne Beiträge deiner Freunde und sammle Sats mit Bitcoin⚡️, der eigenen Währung des Internets.";
/* Number of reposts.
Number of profiles a user is following. */
"%lld" = "%lld";
/* Fraction of how many of the user's relay servers that are operational. */
"%lld/%lld" = "%lld/%lld";
/* Placeholder for event mention. */
"< e >" = "< e >";
/* Label to prompt for about text entry for user to describe about themself. */
"About" = "Über";
/* Label for About Me section of user profile form. */
"About Me" = "Über mich";
/* Placeholder text for About Me description. */
"Absolute Boss" = "Absoluter Macher";
/* Label to indicate the public ID of the account. */
"Account ID" = "Konto ID";
/* Button to add recommended relay server.
Button to confirm adding user inputted relay. */
"Add" = "Hinzufügen";
/* Button label to re-add all original participants as profiles to reply to in a note */
"Add all" = "Alle hinzufügen";
/* Label for section for adding a relay server. */
"Add Relay" = "Relay hinzufügen";
/* Any amount of sats */
"Any" = "beliebig";
/* Alert message to ask if user wants to repost a post. */
"Are you sure you want to repost this?" = "Bist du sicher dass Du den Beitrag auf deinem Profil teilen möchtest?";
/* Label for Banner Image section of user profile form. */
"Banner Image" = "Bannerbild";
/* Reminder to user that they should save their account information. */
"Before we get started, you'll need to save your account info, otherwise you won't be able to login in the future if you ever uninstall Damus." = "Bevor wir anfangen, Du wirst deine Kontodaten sichern müssen, sonst wirst du dich in der Zukunft nicht mehr anmelden können wenn du Damus jemals deinstallierst.";
/* Dropdown option label for Lightning wallet, Bitcoin Beach. */
"Bitcoin Beach" = "Bitcoin Beach";
/* Label for Bitcoin Lightning Tips section of user profile form. */
"Bitcoin Lightning Tips" = "Bitcoin Lightning Zahlungen";
/* Dropdown option label for Lightning wallet, Blixt Wallet */
"Blixt Wallet" = "Blixt Wallet";
/* Dropdown option label for Lightning wallet, Blue Wallet. */
"Blue Wallet" = "Blue Wallet";
/* Dropdown option label for Lightning wallet, Breez. */
"Breez" = "Breez";
/* Context menu option for broadcasting the user's note to all of the user's connected relay servers. */
"Broadcast" = "Senden";
/* Button to cancel out of posting a note.
Button to cancel out of reposting a post.
Button to cancel out of view adding user inputted relay.
Cancel out of logging out the user. */
"Cancel" = "Abbrechen";
/* Dropdown option label for Lightning wallet, Cash App. */
"Cash App" = "Cash App";
/* Navigation bar title for Chatroom view. */
"Chat" = "Unterhaltungen";
/* Button for clearing cached data. */
"Clear" = "Löschen";
/* Section title for clearing cached data. */
"Clear Cache" = "Zwischenspeicher löschen";
/* Label indicating that a user's key was copied. */
"Copied" = "Kopiert";
/* Button to copy a relay server address. */
"Copy" = "Kopieren";
/* Context menu option for copying the ID of the account that created the note. */
"Copy Account ID" = "Konto ID kopieren";
/* Context menu option to copy an image into clipboard.
Context menu option to copy an image to clipboard. */
"Copy Image" = "Bild kopieren";
/* Context menu option to copy the URL of an image into clipboard. */
"Copy Image URL" = "Bild URL kopieren";
/* Title of section for copying a Lightning invoice identifier. */
"Copy invoice" = "Zahlungsdaten kopieren";
/* Context menu option for copying a user's Lightning URL. */
"Copy LNURL" = "LNURL kopieren";
/* Context menu option for copying the ID of the note. */
"Copy Note ID" = "Notiz ID kopieren";
/* Context menu option for copying the JSON text from the note. */
"Copy Note JSON" = "Notiz JSON kopieren";
/* Context menu option for copying the text from an note. */
"Copy Text" = "Text kopieren";
/* Context menu option for copying the ID of the user who created the note. */
"Copy User ID" = "Benutzer ID kopieren";
/* Button to create account. */
"Create" = "Erstellen";
/* Button to create an account. */
"Create Account" = "Konto erstellen";
/* Example description about Bitcoin creator(s), Satoshi Nakamoto. */
"Creator(s) of Bitcoin. Absolute legend." = "Erfinder von Bitcoin. Absolute Legende(n).";
/* Name of the app, shown on the first screen when user is not logged in. */
"Damus" = "Damus";
/* Button to pay a Lightning invoice with the user's default Lightning wallet. */
"Default Wallet" = "Voreingestelltes Wallet";
/* Button to delete a relay server that the user connects to. */
"Delete" = "Löschen";
/* Button to dismiss a text field alert. */
"Dismiss" = "Schließen";
/* Label to prompt display name entry. */
"Display Name" = "Profilname";
/* DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet. DM is the English abbreviation for Direct Message. */
"DM Type" = "PN Typ";
/* Navigation title for DMs view, where DM is the English abbreviation for Direct Message.
Navigation title for view of DMs, where DM is an English abbreviation for Direct Message. */
"DMs" = "PNs";
/* Button to dismiss wallet selection view for paying Lightning invoice. */
"Done" = "Fertig";
/* Heading indicating that this application allows users to earn money. */
"Earn Money" = "Verdiene Geld";
/* Button to edit user's profile. */
"Edit" = "Bearbeiten";
/* Text indicating that the view is used for editing which participants are replied to in a note. */
"Edit participants" = "Teilnehmer editieren";
/* Heading indicating that this application keeps private messaging end-to-end encrypted. */
"Encrypted" = "Verschlüsselt";
/* Prompt for user to enter an account key to login. */
"Enter your account key to login:" = "Gib deinen Kontoschlüssel ein um dich anzumelden:";
/* Error message indicating why saving keys failed. */
"Error: %@" = "Fehler: %@";
/* Filter state for seeing either only posts, or posts & replies. */
"Filter State" = "Filter Einstellung";
/* Button to follow a user. */
"Follow" = "Folgen";
/* Label describing followers of a user. */
"Followers" = "Follower";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of following a profile.
Part of a larger sentence to describe how many profiles a user is following. */
"Following" = "Folgt";
/* Label to indicate that the user is in the process of following another user. */
"Following..." = "Folge…";
/* Text to indicate that button next to it is in a state that will follow a profile when tapped. */
"Follows" = "Folgt";
/* Navigation bar title for Global view where posts from all connected relay servers appear. */
"Global" = "Weltweit";
/* Navigation link to go to post referenced by hex code. */
"Goto post %@" = "Gehe zum Beitrag %@";
/* Navigation link to go to profile. */
"Goto profile %@" = "Gehe zum Profil %@";
/* Navigation bar title for Home view where posts and replies appear from those who the user is following. */
"Home" = "Heim";
/* Placeholder example text for profile picture URL. */
"https://example.com/pic.jpg" = "https://beispiel.at/bild.jpg";
/* Placeholder example text for website URL for user profile. */
"https://jb55.com" = "https://jb55.com";
/* Error message indicating that an invalid account key was entered for login. */
"Invalid key" = "Ungültiger Schlüssel";
/* Placeholder example text for identifier used for NIP-05 verification. */
"jb55@jb55.com" = "jb55@jb55.com";
/* Moves the post button to the left side of the screen */
"Left Handed" = "Linkshändig";
/* Button to complete account creation and start using the app. */
"Let's go!" = "Lass uns loslegen!";
/* Placeholder text for entry of Lightning Address or LNURL. */
"Lightning Address or LNURL" = "Lightning-Adresse oder LNURL";
/* Indicates that the view is for paying a Lightning invoice. */
"Lightning Invoice" = "Lightning-Rechnung";
/* Dropdown option label for Lightning wallet, LNLink. */
"LNLink" = "LNLink";
/* Dropdown option label for system default for Lightning wallet. */
"Local default" = "System-Standard";
/* Button to log into account.
Button to log into an account. */
"Login" = "Einloggen";
/* Alert for logging out the user.
Button for logging out the user.
Button to logout the user. */
"Logout" = "Ausloggen";
/* Reminder message in alert to get customer to verify that their private security account key is saved saved before logging out. */
"Make sure your nsec account key is saved before you logout or you will lose access to this account" = "Stelle sicher, dass du deinen nsec-Schlüssel gespeichert hast, sonst wirst du den Zugang zu deinem Konto verlieren.";
/* Dropdown option label for Lightning wallet, Muun. */
"Muun" = "Muun";
/* Label for NIP-05 Verification section of user profile form. */
"NIP-05 Verification" = "NIP-05-Verifizierung";
/* No search results. */
"none" = "keine";
/* Indicates that there are no notes in the timeline to view. */
"Nothing to see here. Check back later!" = "Hier gibt es nichts zu sehen. Komm später wieder vorbei!";
/* Navigation title for notifications. */
"Notifications" = "Benachrichtigungen";
/* String indicating that a given timestamp just occurred */
"now" = "jetzt";
/* Prompt for user to enter in an account key to login. This text shows the characters the key could start with if it was a private key. */
"nsec1..." = "nsec1...";
/* Label indicating that a form input is optional. */
"optional" = "optional";
/* Button to pay a Lightning invoice. */
"Pay" = "Bezahlen";
/* Navigation bar title for view to pay Lightning invoice. */
"Pay the Lightning invoice" = "Bezahle die Lightning-Rechnung";
/* Dropdown option label for Lightning wallet, Phoenix. */
"Phoenix" = "Phoenix";
/* Button to post a note. */
"Post" = "Veröffentlichen";
/* Label for filter for seeing only posts (instead of posts and replies). */
"Posts" = "Beiträge";
/* Label for filter for seeing posts and replies (instead of only posts). */
"Posts & Replies" = "Beiträge & Antworten";
/* Heading indicating that this application keeps personally identifiable information private. A sentence describing what is done to keep data private comes after this heading. */
"Private" = "Privat";
/* Title of the secure field that holds the user's private key. */
"Private Key" = "Privater Schlüssel";
/* Sidebar menu label for Profile view. */
"Profile" = "Profil";
/* Label for Profile Picture section of user profile form. */
"Profile Picture" = "Profilbild";
/* Section title for the user's public account ID. */
"Public Account ID" = "Öffentliche Konto ID";
/* Label indicating that the text is a user's public account key. */
"Public key" = "Öffentlicher Schlüssel";
/* Label indicating that the text is a user's public account key. */
"Public Key" = "Öffentlicher Schlüssel";
/* Prompt to ask user if the key they entered is a public key. */
"Public Key?" = "Öffentlicher Schlüssel?";
/* Navigation bar title for Reactions view. */
"Reactions" = "Reaktionen";
/* Section title for recommend relay servers that could be added as part of configuration */
"Recommended Relays" = "Empfohlene Relays";
/* Text field for relay server. Used for testing purposes. */
"Relay" = "Relay";
/* Sidebar menu label for Relay servers view */
"Relays" = "Relays";
/* Button label to remove all participants from a note reply. */
"Remove all" = "Alle entfernen";
/* Label to indicate that the user is replying to themself. */
"Reply to self" = "Antwort an sich selbst";
/* Label to indicate that the user is replying to 2 users. */
"Replying to %@ & %@" = "Antwort an %1$@ & %2$@";
/* Indicating that the user is replying to the following listed people. */
"Replying to:" = "Antwort an:";
/* Button to confirm reposting a post.
Title of alert for confirming to repost a post. */
"Repost" = "Selbst teilen";
/* Text indicating that the post was reposted (i.e. re-shared). */
"Reposted" = "Selbst geteilt";
/* Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet). DM is the English abbreviation for Direct Message. */
"Requests" = "Anfragen";
/* Section title for resetting the user */
"Reset" = "Zurücksetzen";
/* Button to retry completing account creation after an error occurred. */
"Retry" = "Erneut versuchen";
/* Dropdown option label for Lightning wallet, River */
"River" = "River";
/* Example username of Bitcoin creator(s), Satoshi Nakamoto. */
"satoshi" = "satoshi";
/* Name of Bitcoin creator(s). */
"Satoshi Nakamoto" = "Satoshi Nakamoto";
/* Button for saving profile. */
"Save" = "Speichern";
/* Context menu option to save an image. */
"Save Image" = "Bild sichern";
/* Navigation link to search hashtag. */
"Search hashtag: #%@" = "Hashtag suchen: #%@";
/* Placeholder text to prompt entry of search query. */
"Search..." = "Suchen...";
/* Section title for user's secret account login key. */
"Secret Account Login Key" = "Geheimer Konto Anmeldeschlüssel";
/* Title of section for selecting a Lightning wallet to pay a Lightning invoice. */
"Select a Lightning wallet" = "Wähle ein Lightning Wallet";
/* Prompt selection of user's default wallet */
"Select default wallet" = "Wähle das voreingestellte Wallet";
/* Text prompt for user to send a message to the other user. */
"Send a message to start the conversation..." = "Sende eine Nachricht um eine Unterhaltung zu beginnen...";
/* Navigation title for Settings view.
Sidebar menu label for accessing the app settings */
"Settings" = "Einstellungen";
/* Button to share an image. */
"Share" = "Teilen";
/* Toggle to show or hide user's secret account login key. */
"Show" = "Anzeigen";
/* Toggle to show or hide selection of wallet. */
"Show wallet selector" = "Wallet-Auswahl zeigen";
/* Sidebar menu label to sign out of the account. */
"Sign out" = "Abmelden";
/* Dropdown option label for Lightning wallet, Strike. */
"Strike" = "Strike";
/* Warning that the inputted account key is a public key and the result of what happens because of it. */
"This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective." = "Dies ist ein öffentlicher Schlüssel, mit dem Sie keine Beiträge verfassen oder in irgendeiner Weise interagieren können. Er wird verwendet, um Konten aus deren Perspektive zu betrachten.";
/* Warning that the inputted account key for login is an old-style and asking user to verify if it is a public key. */
"This is an old-style nostr key. We're not sure if it's a pubkey or private key. Please toggle the button below if this a public key." = "Dies ist ein Nostr-Schlüssel im alten Format. Es ist nicht eindeutig, ob es ein öffentlicher oder privater Schlüssel ist. Bitte aktiviere die Schaltfläche unten, wenn es ein öffentlicher Schlüssel ist.";
/* Label to describe that a public key is the user's account ID and what they can do with it. */
"This is your account ID, you can give this to your friends so that they can follow you. Click to copy." = "Dies ist deine Konto-ID, die du an deine Freunde weitergeben kannst, damit sie dir folgen können. Zum Kopieren anklicken.";
/* Label to describe that a private key is the user's secret account key and what they should do with it. */
"This is your secret account key. You need this to access your account. Don't share this with anyone! Save it in a password manager and keep it safe!" = "Dies ist dein geheimer, privater Schlüssel. Du benötigst ihn, um auf dein Konto zuzugreifen. Gib den privaten Schlüssel an niemanden weiter! Speichere ihn in einem Passwort-Manager und bewahre ihn sicher auf!";
/* Navigation bar title for note thread.
Navigation bar title for threaded event detail view. */
"Thread" = "Thema";
/* Text box prompt to ask user to type their post. */
"Type your post here..." = "Schreibe deinen Beitrag hier...";
/* Non-breaking space character to fill in blank space next to event action button icons. */
"u{00A0}" = "u{00A0}";
/* Button to unfollow a user. */
"Unfollow" = "Entfolgen";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of unfollowing a profile. */
"Unfollowing" = "Entfolgen...";
/* Label to indicate that the user is in the process of unfollowing another user. */
"Unfollowing..." = "Entfolgen...";
/* Text to indicate that the button next to it is in a state that will unfollow a profile when tapped. */
"Unfollows" = "Entfolgen";
/* Label for Username section of user profile form.
Label to prompt username entry. */
"Username" = "Benutzername";
/* Sidebar menu label for Wallet view. */
"Wallet" = "Wallet";
/* Dropdown option label for Lightning wallet, Wallet Of Satoshi. */
"Wallet Of Satoshi" = "Wallet Of Satoshi";
/* Section title for selection of wallet. */
"Wallet Selector" = "Wallet-Auswahl";
/* Label for Website section of user profile form. */
"Website" = "Website";
/* Welcoming message to the reader. The variable is 'you', the reader. */
"Welcome to the social network %@ control." = "Willkommen in dem sozialen Netzwerk das %@ kontrollierst.";
/* Text to welcome user. */
"Welcome, %@!" = "Willkommen, %@!";
/* Placeholder example for relay server address. */
"wss://some.relay.com" = "wss://ein.relay.at";
/* You, in this context, is the person who controls their own social network. You is used in the context of a larger sentence that welcomes the reader to the social network that they control themself. */
"you" = "Du";
/* Label for Your Name section of user profile form. */
"Your Name" = "Dein Name";
/* Dropdown option label for Lightning wallet, Zebedee. */
"Zebedee" = "Zebedee";
/* Dropdown option label for Lightning wallet, Zeus LN. */
"Zeus LN" = "Zeus LN";
-154
View File
@@ -1,154 +0,0 @@
<?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>NOTES</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>1%d andere Notiz</string>
<key>other</key>
<string>1%d andere Notizen</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>··· %#@NOTES@ ···</string>
</dict>
<key>followers_count</key>
<dict>
<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>Follower</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@FOLLOWERS@</string>
</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>Reaktion</string>
<key>other</key>
<string>Reaktionen</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>Antwort an %@%#@OTHERS@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>&amp; 1%d andere</string>
<key>other</key>
<string>&amp; %d andere</string>
<key>zero</key>
<string></string>
</dict>
</dict>
<key>replying_to_two_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Antwort an %@, %@%#@OTHERS@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>&amp; %d andere</string>
<key>other</key>
<string>&amp; %d andere</string>
<key>zero</key>
<string></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>geteilter Beitrag</string>
<key>other</key>
<string>geteilte Beiträge</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>Trinkgeld</string>
<key>other</key>
<string>Trinkgelder</string>
</dict>
</dict>
</dict>
</plist>
-9
View File
@@ -1,9 +0,0 @@
/* Bundle display name */
"CFBundleDisplayName" = "Damus";
/* Bundle name */
"CFBundleName" = "damus";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Damus Zugriff auf deine Fotos zu gewähren erlaubt dir Bilder zu sichern.";
-503
View File
@@ -1,503 +0,0 @@
/* Blank space to separate profile picture from profile editor form. */
" " = "61b6edf1108e6f396680a33b02486a70_tr";
/* Description of how the nip05 identifier would be used for verification. */
"'%@' at '%@' will be used for verification" = "'%@' bei '%@' wird zur Verifizierung benutzt werden.";
/* Description of why the nip05 identifier is invalid. */
"'%@' is an invalid nip05 identifier. It should look like an email." = "'%@' ist eine ungültige nip05 Kennzeichnung. Diese sollte wie eine Emailadresse aussehen. ";
/* Navigation bar title for view that shows who is following a user. */
"(Profile.displayName(profile: profile, pubkey: whos))'s Followers" = "(Profile.displayName(profile: profile, pubkey: whos)) Follower";
/* Navigation bar title for view that shows who a user is following. */
"(who) following" = "(who) folgt";
/* Prefix character to username. */
"@" = "@";
/* Amount of time that has passed since reply quote event occurred.
Abbreviated version of a nostr public key. */
"%@" = "%@";
/* Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.
Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'. */
"%@ %@" = "%@ %@";
/* Explanation of what is done to keep personally identifiable information private. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction." = "Für das Erstellen eines Accounts ist keine Telefonnumer, E-Mail-Adresse und kein Name notwendig. Lege direkt los!";
/* Explanation of what is done to keep private data encrypted. There is a heading that precedes this explanation which is a variable to this string. */
"%@. End-to-End encrypted private messaging. Keep Big Tech out of your DMs" = "%@. Ende-zu-Ende verschlüsselte private Nachrichten. Halte „Big Tech“ aus deinen Direktnachrichten heraus.";
/* Explanation of what can be done by users to earn money. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Tip your friend's posts and stack sats with Bitcoin⚡️, the native currency of the internet." = "%@. Belohne Beiträge deiner Freunde und sammle Sats mit Bitcoin⚡️, der eigenen Währung des Internets.";
/* Number of reposts.
Number of profiles a user is following. */
"%lld" = "%lld";
/* Fraction of how many of the user's relay servers that are operational. */
"%lld/%lld" = "%lld/%lld";
/* Placeholder for event mention. */
"< e >" = "< e >";
/* Label to prompt for about text entry for user to describe about themself. */
"About" = "Über";
/* Label for About Me section of user profile form. */
"About Me" = "Über mich";
/* Placeholder text for About Me description. */
"Absolute Boss" = "Absoluter Macher";
/* Label to indicate the public ID of the account. */
"Account ID" = "Konto-ID";
/* Button to add recommended relay server.
Button to confirm adding user inputted relay. */
"Add" = "Hinzufügen";
/* Button label to re-add all original participants as profiles to reply to in a note */
"Add all" = "Alle hinzufügen";
/* Label for section for adding a relay server. */
"Add Relay" = "Relay hinzufügen";
/* Any amount of sats */
"Any" = "beliebig";
/* Alert message to ask if user wants to repost a post. */
"Are you sure you want to repost this?" = "Bist du sicher dass Du den Beitrag auf deinem Profil teilen möchtest?";
/* Label for Banner Image section of user profile form. */
"Banner Image" = "Banner Bild";
/* Reminder to user that they should save their account information. */
"Before we get started, you'll need to save your account info, otherwise you won't be able to login in the future if you ever uninstall Damus." = "Bevor wir anfangen, musst du deine Kontodaten sichern, sonst kannst du dich in Zukunft nicht mehr anmelden, wenn du Damus jemals deinstallierst.";
/* Dropdown option label for Lightning wallet, Bitcoin Beach. */
"Bitcoin Beach" = "Bitcoin Beach";
/* Label for Bitcoin Lightning Tips section of user profile form. */
"Bitcoin Lightning Tips" = "Bitcoin Lightning Zahlungen";
/* Dropdown option label for Lightning wallet, Blixt Wallet */
"Blixt Wallet" = "Blixt Wallet";
/* Dropdown option label for Lightning wallet, Blue Wallet. */
"Blue Wallet" = "Blue Wallet";
/* Dropdown option label for Lightning wallet, Breez. */
"Breez" = "Breez";
/* Context menu option for broadcasting the user's note to all of the user's connected relay servers. */
"Broadcast" = "Senden";
/* Button to cancel out of posting a note.
Button to cancel out of reposting a post.
Button to cancel out of view adding user inputted relay.
Cancel out of logging out the user. */
"Cancel" = "Abbrechen";
/* Dropdown option label for Lightning wallet, Cash App. */
"Cash App" = "Cash App";
/* Navigation bar title for Chatroom view. */
"Chat" = "Unterhaltung";
/* Button for clearing cached data. */
"Clear" = "Löschen";
/* Section title for clearing cached data. */
"Clear Cache" = "Zwischenspeicher löschen";
/* Label indicating that a user's key was copied. */
"Copied" = "Kopiert";
/* Button to copy a relay server address. */
"Copy" = "Kopieren";
/* Context menu option for copying the ID of the account that created the note. */
"Copy Account ID" = "Konto-ID kopieren";
/* Context menu option to copy an image into clipboard.
Context menu option to copy an image to clipboard. */
"Copy Image" = "Bild kopieren";
/* Context menu option to copy the URL of an image into clipboard. */
"Copy Image URL" = "Bild-URL kopieren";
/* Title of section for copying a Lightning invoice identifier. */
"Copy invoice" = "Rechnung kopieren";
/* Context menu option for copying a user's Lightning URL. */
"Copy LNURL" = "LNURL kopieren";
/* Context menu option for copying the ID of the note. */
"Copy Note ID" = "Notiz-ID kopieren";
/* Context menu option for copying the JSON text from the note. */
"Copy Note JSON" = "Notiz-JSON kopieren";
/* Context menu option for copying the text from an note. */
"Copy Text" = "Text kopieren";
/* Context menu option for copying the ID of the user who created the note. */
"Copy User ID" = "Benutzer-ID kopieren";
/* Button to create account. */
"Create" = "Erstellen";
/* Button to create an account. */
"Create Account" = "Konto erstellen";
/* Example description about Bitcoin creator(s), Satoshi Nakamoto. */
"Creator(s) of Bitcoin. Absolute legend." = "Erfinder von Bitcoin. Absolute Legende(n).";
/* Name of the app, shown on the first screen when user is not logged in. */
"Damus" = "Damus";
/* Button to pay a Lightning invoice with the user's default Lightning wallet. */
"Default Wallet" = "Voreingestellte Wallet";
/* Button to delete a relay server that the user connects to. */
"Delete" = "Löschen";
/* Button to dismiss a text field alert. */
"Dismiss" = "Schließen";
/* Label to prompt display name entry. */
"Display Name" = "Profilname";
/* DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet. DM is the English abbreviation for Direct Message. */
"DM Type" = "PN Art";
/* Navigation title for DMs view, where DM is the English abbreviation for Direct Message.
Navigation title for view of DMs, where DM is an English abbreviation for Direct Message. */
"DMs" = "PNs";
/* Button to dismiss wallet selection view for paying Lightning invoice. */
"Done" = "Fertig";
/* Heading indicating that this application allows users to earn money. */
"Earn Money" = "Verdiene Geld";
/* Button to edit user's profile. */
"Edit" = "Bearbeiten";
/* Text indicating that the view is used for editing which participants are replied to in a note. */
"Edit participants" = "Teilnehmer editieren";
/* Heading indicating that this application keeps private messaging end-to-end encrypted. */
"Encrypted" = "Verschlüsselt";
/* Prompt for user to enter an account key to login. */
"Enter your account key to login:" = "Gib deinen Kontoschlüssel ein um dich anzumelden:";
/* Error message indicating why saving keys failed. */
"Error: %@" = "Fehler: %@";
/* Filter state for seeing either only posts, or posts & replies. */
"Filter State" = "Filter Einstellung";
/* Button to follow a user. */
"Follow" = "Folgen";
/* Label describing followers of a user. */
"Followers" = "Follower";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of following a profile.
Part of a larger sentence to describe how many profiles a user is following. */
"Following" = "Folgt";
/* Label to indicate that the user is in the process of following another user. */
"Following..." = "Folge…";
/* Text to indicate that button next to it is in a state that will follow a profile when tapped. */
"Follows" = "Folgt";
/* Navigation bar title for Global view where posts from all connected relay servers appear. */
"Global" = "Weltweit";
/* Navigation link to go to post referenced by hex code. */
"Goto post %@" = "Gehe zum Beitrag %@";
/* Navigation link to go to profile. */
"Goto profile %@" = "Gehe zum Profil %@";
/* Navigation bar title for Home view where posts and replies appear from those who the user is following. */
"Home" = "Heim";
/* Placeholder example text for profile picture URL. */
"https://example.com/pic.jpg" = "https://beispiel.de/bild.jpg";
/* Placeholder example text for website URL for user profile. */
"https://jb55.com" = "https://jb55.com";
/* Error message indicating that an invalid account key was entered for login. */
"Invalid key" = "Ungültiger Schlüssel";
/* Placeholder example text for identifier used for NIP-05 verification. */
"jb55@jb55.com" = "jb55@jb55.com";
/* Moves the post button to the left side of the screen */
"Left Handed" = "Linkshändig";
/* Button to complete account creation and start using the app. */
"Let's go!" = "Los gehts!";
/* Placeholder text for entry of Lightning Address or LNURL. */
"Lightning Address or LNURL" = "Lightning-Adresse oder LNURL";
/* Indicates that the view is for paying a Lightning invoice. */
"Lightning Invoice" = "Lightning-Rechnung";
/* Dropdown option label for Lightning wallet, LNLink. */
"LNLink" = "LNLink";
/* Dropdown option label for system default for Lightning wallet. */
"Local default" = "System-Standard";
/* Button to log into account.
Button to log into an account. */
"Login" = "Anmelden";
/* Alert for logging out the user.
Button for logging out the user.
Button to logout the user. */
"Logout" = "Abmelden";
/* Reminder message in alert to get customer to verify that their private security account key is saved saved before logging out. */
"Make sure your nsec account key is saved before you logout or you will lose access to this account" = "Stelle sicher dass dein nsec Kontoschlüssel gesichert ist bevor du dich abmeldest oder du wirst den Zugang zu diesem Konto verlieren";
/* Dropdown option label for Lightning wallet, Muun. */
"Muun" = "Muun";
/* Label for NIP-05 Verification section of user profile form. */
"NIP-05 Verification" = "NIP-05-Verifizierung";
/* No search results. */
"none" = "keine";
/* Indicates that there are no notes in the timeline to view. */
"Nothing to see here. Check back later!" = "Hier gibts nichts zu sehen. Schau später wieder vorbei!";
/* Navigation title for notifications. */
"Notifications" = "Benachrichtigungen";
/* String indicating that a given timestamp just occurred */
"now" = "jetzt";
/* Prompt for user to enter in an account key to login. This text shows the characters the key could start with if it was a private key. */
"nsec1..." = "nsec1...";
/* Label indicating that a form input is optional. */
"optional" = "optional";
/* Button to pay a Lightning invoice. */
"Pay" = "Bezahlen";
/* Navigation bar title for view to pay Lightning invoice. */
"Pay the Lightning invoice" = "Bezahle die Lightning-Rechnung";
/* Dropdown option label for Lightning wallet, Phoenix. */
"Phoenix" = "Phoenix";
/* Button to post a note. */
"Post" = "Teilen";
/* Label for filter for seeing only posts (instead of posts and replies). */
"Posts" = "Beiträge";
/* Label for filter for seeing posts and replies (instead of only posts). */
"Posts & Replies" = "Beiträge & Antworten";
/* Heading indicating that this application keeps personally identifiable information private. A sentence describing what is done to keep data private comes after this heading. */
"Private" = "Privatsphäre";
/* Title of the secure field that holds the user's private key. */
"Private Key" = "Privater Schlüssel";
/* Sidebar menu label for Profile view. */
"Profile" = "Profil";
/* Label for Profile Picture section of user profile form. */
"Profile Picture" = "Profilbild";
/* Section title for the user's public account ID. */
"Public Account ID" = "Öffentliche Konto ID";
/* Label indicating that the text is a user's public account key. */
"Public key" = "Öffentlicher Schlüssel";
/* Label indicating that the text is a user's public account key. */
"Public Key" = "Öffentlicher Schlüssel";
/* Prompt to ask user if the key they entered is a public key. */
"Public Key?" = "Öffentlicher Schlüssel?";
/* Navigation bar title for Reactions view. */
"Reactions" = "Reaktionen";
/* Section title for recommend relay servers that could be added as part of configuration */
"Recommended Relays" = "Empfohlene Relays";
/* Text field for relay server. Used for testing purposes. */
"Relay" = "Relay";
/* Sidebar menu label for Relay servers view */
"Relays" = "Relays";
/* Button label to remove all participants from a note reply. */
"Remove all" = "Alle entfernen";
/* Label to indicate that the user is replying to themself. */
"Reply to self" = "Antwort an dich selbst";
/* Label to indicate that the user is replying to 2 users. */
"Replying to %@ & %@" = "%1$@ & %2$@ antworten";
/* Indicating that the user is replying to the following listed people. */
"Replying to:" = "Du antwortest:";
/* Button to confirm reposting a post.
Title of alert for confirming to repost a post. */
"Repost" = "Teilen";
/* Text indicating that the post was reposted (i.e. re-shared). */
"Reposted" = "Geteilt";
/* Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet). DM is the English abbreviation for Direct Message. */
"Requests" = "Anfragen";
/* Section title for resetting the user */
"Reset" = "Zurücksetzen";
/* Button to retry completing account creation after an error occurred. */
"Retry" = "Wiederholung";
/* Dropdown option label for Lightning wallet, River */
"River" = "River";
/* Example username of Bitcoin creator(s), Satoshi Nakamoto. */
"satoshi" = "satoshi";
/* Name of Bitcoin creator(s). */
"Satoshi Nakamoto" = "Satoshi Nakamoto";
/* Button for saving profile. */
"Save" = "Speichern";
/* Context menu option to save an image. */
"Save Image" = "Bild speichern";
/* Navigation link to search hashtag. */
"Search hashtag: #%@" = "Hashtag suchen: #%@";
/* Placeholder text to prompt entry of search query. */
"Search..." = "Suchen...";
/* Section title for user's secret account login key. */
"Secret Account Login Key" = "Geheimer Konto-Anmeldeschlüssel";
/* Title of section for selecting a Lightning wallet to pay a Lightning invoice. */
"Select a Lightning wallet" = "Wähle eine Lightning-Wallet";
/* Prompt selection of user's default wallet */
"Select default wallet" = "Wähle ein voreingestelltes Wallet";
/* Text prompt for user to send a message to the other user. */
"Send a message to start the conversation..." = "Sende eine Nachricht um die Unterhaltung zu beginnen...";
/* Navigation title for Settings view.
Sidebar menu label for accessing the app settings */
"Settings" = "Einstellungen";
/* Button to share an image. */
"Share" = "Teilen";
/* Toggle to show or hide user's secret account login key. */
"Show" = "Anzeigen";
/* Toggle to show or hide selection of wallet. */
"Show wallet selector" = "Wallet-Auswahl anzeigen";
/* Sidebar menu label to sign out of the account. */
"Sign out" = "Abmelden";
/* Dropdown option label for Lightning wallet, Strike. */
"Strike" = "Strike";
/* Warning that the inputted account key is a public key and the result of what happens because of it. */
"This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective." = "Dies ist ein öffentlicher Schlüssel, Du wirst keine Beiträge teilen oder oder auf irgendeine Weise interagieren können. Dies wird genutzt um Kontos aus deren Perspektive zu sehen.";
/* Warning that the inputted account key for login is an old-style and asking user to verify if it is a public key. */
"This is an old-style nostr key. We're not sure if it's a pubkey or private key. Please toggle the button below if this a public key." = "Dies ist ein veralteter nostr-Schlüssel. Wir sind und unsicher ob es ein öffentlicher Schlüssel oder ein privater Schlüssel ist. Bitte betätige die untenstehende Schaltfläche wenn es ein öffentlicher Schlüssel ist.";
/* Label to describe that a public key is the user's account ID and what they can do with it. */
"This is your account ID, you can give this to your friends so that they can follow you. Click to copy." = "Dies ist deine Konto-ID, die du an deine Freunde weitergeben kannst, damit sie dir folgen können. Zum Kopieren anklicken.";
/* Label to describe that a private key is the user's secret account key and what they should do with it. */
"This is your secret account key. You need this to access your account. Don't share this with anyone! Save it in a password manager and keep it safe!" = "Dies ist dein geheimer, privater Schlüssel. Du benötigst ihn, um auf dein Konto zuzugreifen. Gib den privaten Schlüssel an niemanden weiter! Speichere ihn in einem Passwort-Manager und bewahre ihn sicher auf!";
/* Navigation bar title for note thread.
Navigation bar title for threaded event detail view. */
"Thread" = "Thema";
/* Text box prompt to ask user to type their post. */
"Type your post here..." = "Schreibe deinen Beitrag hier...";
/* Non-breaking space character to fill in blank space next to event action button icons. */
"u{00A0}" = "u{00A0}";
/* Button to unfollow a user. */
"Unfollow" = "Entfolgen";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of unfollowing a profile. */
"Unfollowing" = "Entfolgen...";
/* Label to indicate that the user is in the process of unfollowing another user. */
"Unfollowing..." = "Entfolgen...";
/* Text to indicate that the button next to it is in a state that will unfollow a profile when tapped. */
"Unfollows" = "Entfolgen";
/* Label for Username section of user profile form.
Label to prompt username entry. */
"Username" = "Benutzername";
/* Sidebar menu label for Wallet view. */
"Wallet" = "Wallet";
/* Dropdown option label for Lightning wallet, Wallet Of Satoshi. */
"Wallet Of Satoshi" = "Wallet Of Satoshi";
/* Section title for selection of wallet. */
"Wallet Selector" = "Wallet-Auswahl";
/* Label for Website section of user profile form. */
"Website" = "Website";
/* Welcoming message to the reader. The variable is 'you', the reader. */
"Welcome to the social network %@ control." = "Willkommen in dem sozialen Netzwerk das %@ kontrollierst.";
/* Text to welcome user. */
"Welcome, %@!" = "Willkommen, %@!";
/* Placeholder example for relay server address. */
"wss://some.relay.com" = "wss://irgendein.relay.de";
/* You, in this context, is the person who controls their own social network. You is used in the context of a larger sentence that welcomes the reader to the social network that they control themself. */
"you" = "Du";
/* Label for Your Name section of user profile form. */
"Your Name" = "Dein Name";
/* Dropdown option label for Lightning wallet, Zebedee. */
"Zebedee" = "Zebedee";
/* Dropdown option label for Lightning wallet, Zeus LN. */
"Zeus LN" = "Zeus LN";
-154
View File
@@ -1,154 +0,0 @@
<?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>NOTES</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>%d andere Notiz</string>
<key>other</key>
<string>%d andere Notizen</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>··· %#@NOTES@ ···</string>
</dict>
<key>followers_count</key>
<dict>
<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>Follower</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@FOLLOWERS@</string>
</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>Reaktion</string>
<key>other</key>
<string>Reaktionen</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>Antwort an %@%#@OTHERS@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>&amp; %d andere</string>
<key>other</key>
<string>&amp; %d andere</string>
<key>zero</key>
<string></string>
</dict>
</dict>
<key>replying_to_two_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Antwort an %@, %@%#@OTHERS@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>&amp; %d andere</string>
<key>other</key>
<string>&amp; %d andere</string>
<key>zero</key>
<string></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>Mal geteilt</string>
<key>other</key>
<string>Mal geteilt</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>Trinkgeld</string>
<key>other</key>
<string>Trinkgelder</string>
</dict>
</dict>
</dict>
</plist>
-9
View File
@@ -1,9 +0,0 @@
/* Bundle display name */
"CFBundleDisplayName" = "Damus";
/* Bundle name */
"CFBundleName" = "damus";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Donner accès à Damus à vos photos vous permet d'enregistrer des images";
-503
View File
@@ -1,503 +0,0 @@
/* Blank space to separate profile picture from profile editor form. */
" " = "61b6edf1108e6f396680a33b02486a70_tr";
/* Description of how the nip05 identifier would be used for verification. */
"'%@' at '%@' will be used for verification" = "'%@' à '@' sera utilisé pour la vérification";
/* Description of why the nip05 identifier is invalid. */
"'%@' is an invalid nip05 identifier. It should look like an email." = "'@' est un identifiant nip05 invalide. Cela devrait ressembler à une adresse e-mail.";
/* Navigation bar title for view that shows who is following a user. */
"(Profile.displayName(profile: profile, pubkey: whos))'s Followers" = "Abonnés de (Profile.displayName(profile: profile, pubkey: whos))";
/* Navigation bar title for view that shows who a user is following. */
"(who) following" = "(who) suit";
/* Prefix character to username. */
"@" = "@";
/* Amount of time that has passed since reply quote event occurred.
Abbreviated version of a nostr public key. */
"%@" = "%@";
/* Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.
Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'. */
"%@ %@" = "%@ %@";
/* Explanation of what is done to keep personally identifiable information private. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction." = "%@. La création d'un compte ne nécessite pas de numéro de téléphone, d'e-mail ou de nom. Commencez tout de suite sans aucune friction.";
/* Explanation of what is done to keep private data encrypted. There is a heading that precedes this explanation which is a variable to this string. */
"%@. End-to-End encrypted private messaging. Keep Big Tech out of your DMs" = "%@. Messagerie privée cryptée de bout en bout. Gardez Big Tech hors de vos DMs";
/* Explanation of what can be done by users to earn money. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Tip your friend's posts and stack sats with Bitcoin⚡️, the native currency of the internet." = "%@. Donnez un pourboire aux publications de vos amis et empilez les sats avec Bitcoin⚡️, la monnaie native d'Internet.";
/* Number of reposts.
Number of profiles a user is following. */
"%lld" = "%lld";
/* Fraction of how many of the user's relay servers that are operational. */
"%lld/%lld" = "%lld/%lld";
/* Placeholder for event mention. */
"< e >" = "< e >";
/* Label to prompt for about text entry for user to describe about themself. */
"About" = "À propos de";
/* Label for About Me section of user profile form. */
"About Me" = "À Propos de Moi";
/* Placeholder text for About Me description. */
"Absolute Boss" = "Patron Absolu";
/* Label to indicate the public ID of the account. */
"Account ID" = "Identifiant de Compte";
/* Button to add recommended relay server.
Button to confirm adding user inputted relay. */
"Add" = "Ajouter";
/* Button label to re-add all original participants as profiles to reply to in a note */
"Add all" = "Tout ajouter";
/* Label for section for adding a relay server. */
"Add Relay" = "Ajouter un Relais";
/* Any amount of sats */
"Any" = "N'importe Lequel";
/* Alert message to ask if user wants to repost a post. */
"Are you sure you want to repost this?" = "Êtes-vous sûr de vouloir republier ceci ?";
/* Label for Banner Image section of user profile form. */
"Banner Image" = "Image Bannière";
/* Reminder to user that they should save their account information. */
"Before we get started, you'll need to save your account info, otherwise you won't be able to login in the future if you ever uninstall Damus." = "Avant de commencer, vous devrez enregistrer les informations de votre compte, sinon vous ne pourrez plus vous connecter à l'avenir si vous désinstallez Damus.";
/* Dropdown option label for Lightning wallet, Bitcoin Beach. */
"Bitcoin Beach" = "Bitcoin Beach";
/* Label for Bitcoin Lightning Tips section of user profile form. */
"Bitcoin Lightning Tips" = "Pourboires de Bitcoin Lightning";
/* Dropdown option label for Lightning wallet, Blixt Wallet */
"Blixt Wallet" = "Blixt Wallet";
/* Dropdown option label for Lightning wallet, Blue Wallet. */
"Blue Wallet" = "Blue Wallet";
/* Dropdown option label for Lightning wallet, Breez. */
"Breez" = "Breez";
/* Context menu option for broadcasting the user's note to all of the user's connected relay servers. */
"Broadcast" = "Diffuser";
/* Button to cancel out of posting a note.
Button to cancel out of reposting a post.
Button to cancel out of view adding user inputted relay.
Cancel out of logging out the user. */
"Cancel" = "Annuler";
/* Dropdown option label for Lightning wallet, Cash App. */
"Cash App" = "Cash App";
/* Navigation bar title for Chatroom view. */
"Chat" = "Chatter";
/* Button for clearing cached data. */
"Clear" = "Vider";
/* Section title for clearing cached data. */
"Clear Cache" = "Vider le Cache";
/* Label indicating that a user's key was copied. */
"Copied" = "Copié";
/* Button to copy a relay server address. */
"Copy" = "Copier";
/* Context menu option for copying the ID of the account that created the note. */
"Copy Account ID" = "Copier l'Identifiant de Compte";
/* Context menu option to copy an image into clipboard.
Context menu option to copy an image to clipboard. */
"Copy Image" = "Copier l'Image";
/* Context menu option to copy the URL of an image into clipboard. */
"Copy Image URL" = "Copier l'URL de l'Image";
/* Title of section for copying a Lightning invoice identifier. */
"Copy invoice" = "Copier la Facture";
/* Context menu option for copying a user's Lightning URL. */
"Copy LNURL" = "Copier le LNURL";
/* Context menu option for copying the ID of the note. */
"Copy Note ID" = "Copier l'Identifiant de la Note";
/* Context menu option for copying the JSON text from the note. */
"Copy Note JSON" = "Copier le JSON de la Note";
/* Context menu option for copying the text from an note. */
"Copy Text" = "Copier le Texte";
/* Context menu option for copying the ID of the user who created the note. */
"Copy User ID" = "Copier l'Identifiant de l'Utilisateur";
/* Button to create account. */
"Create" = "Créer";
/* Button to create an account. */
"Create Account" = "Créer un Compte";
/* Example description about Bitcoin creator(s), Satoshi Nakamoto. */
"Creator(s) of Bitcoin. Absolute legend." = "Créateur(s) de Bitcoin. Légende absolue.";
/* Name of the app, shown on the first screen when user is not logged in. */
"Damus" = "Damus";
/* Button to pay a Lightning invoice with the user's default Lightning wallet. */
"Default Wallet" = "Portefeuille par défaut";
/* Button to delete a relay server that the user connects to. */
"Delete" = "Effacer";
/* Button to dismiss a text field alert. */
"Dismiss" = "Rejeter";
/* Label to prompt display name entry. */
"Display Name" = "Afficher Nom";
/* DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet. DM is the English abbreviation for Direct Message. */
"DM Type" = "Type de message privé";
/* Navigation title for DMs view, where DM is the English abbreviation for Direct Message.
Navigation title for view of DMs, where DM is an English abbreviation for Direct Message. */
"DMs" = "Messages privés";
/* Button to dismiss wallet selection view for paying Lightning invoice. */
"Done" = "Fini";
/* Heading indicating that this application allows users to earn money. */
"Earn Money" = "Gagnes de l'argent";
/* Button to edit user's profile. */
"Edit" = "Modifier";
/* Text indicating that the view is used for editing which participants are replied to in a note. */
"Edit participants" = "Modifier les participants";
/* Heading indicating that this application keeps private messaging end-to-end encrypted. */
"Encrypted" = "Crypté";
/* Prompt for user to enter an account key to login. */
"Enter your account key to login:" = "Entrez votre clé de compte pour vous connecter:";
/* Error message indicating why saving keys failed. */
"Error: %@" = "Erreur: %@";
/* Filter state for seeing either only posts, or posts & replies. */
"Filter State" = "État du filtre";
/* Button to follow a user. */
"Follow" = "S'abonner";
/* Label describing followers of a user. */
"Followers" = "Abonnés";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of following a profile.
Part of a larger sentence to describe how many profiles a user is following. */
"Following" = "Abonnements";
/* Label to indicate that the user is in the process of following another user. */
"Following..." = "Abonnements...";
/* Text to indicate that button next to it is in a state that will follow a profile when tapped. */
"Follows" = "Suit";
/* Navigation bar title for Global view where posts from all connected relay servers appear. */
"Global" = "Global";
/* Navigation link to go to post referenced by hex code. */
"Goto post %@" = "Aller au post %@";
/* Navigation link to go to profile. */
"Goto profile %@" = "Aller au profil %@";
/* Navigation bar title for Home view where posts and replies appear from those who the user is following. */
"Home" = "Accueil";
/* Placeholder example text for profile picture URL. */
"https://example.com/pic.jpg" = "https://exemple.com/pic.jpg";
/* Placeholder example text for website URL for user profile. */
"https://jb55.com" = "https://jb55.com";
/* Error message indicating that an invalid account key was entered for login. */
"Invalid key" = "Clé non valide";
/* Placeholder example text for identifier used for NIP-05 verification. */
"jb55@jb55.com" = "jb55@jb55.com";
/* Moves the post button to the left side of the screen */
"Left Handed" = "Gaucher";
/* Button to complete account creation and start using the app. */
"Let's go!" = "Allons-y!";
/* Placeholder text for entry of Lightning Address or LNURL. */
"Lightning Address or LNURL" = "Adresse Lightning ou LNURL";
/* Indicates that the view is for paying a Lightning invoice. */
"Lightning Invoice" = "Facture Lightning";
/* Dropdown option label for Lightning wallet, LNLink. */
"LNLink" = "LNLink";
/* Dropdown option label for system default for Lightning wallet. */
"Local default" = "Valeur locale par défaut";
/* Button to log into account.
Button to log into an account. */
"Login" = "Se connecter";
/* Alert for logging out the user.
Button for logging out the user.
Button to logout the user. */
"Logout" = "Se déconnecter";
/* Reminder message in alert to get customer to verify that their private security account key is saved saved before logging out. */
"Make sure your nsec account key is saved before you logout or you will lose access to this account" = "Assurez-vous que votre clé de compte nsec est enregistrée avant de vous déconnecter ou vous perdrez l'accès à ce compte";
/* Dropdown option label for Lightning wallet, Muun. */
"Muun" = "Muun";
/* Label for NIP-05 Verification section of user profile form. */
"NIP-05 Verification" = "Vérification NIP-05";
/* No search results. */
"none" = "aucun";
/* Indicates that there are no notes in the timeline to view. */
"Nothing to see here. Check back later!" = "Rien à voir ici. Revenez plus tard!";
/* Navigation title for notifications. */
"Notifications" = "Notifications";
/* String indicating that a given timestamp just occurred */
"now" = "maintenant";
/* Prompt for user to enter in an account key to login. This text shows the characters the key could start with if it was a private key. */
"nsec1..." = "nsec1...";
/* Label indicating that a form input is optional. */
"optional" = "optionnel";
/* Button to pay a Lightning invoice. */
"Pay" = "Payer";
/* Navigation bar title for view to pay Lightning invoice. */
"Pay the Lightning invoice" = "Payer la facture Lightning";
/* Dropdown option label for Lightning wallet, Phoenix. */
"Phoenix" = "Phoenix";
/* Button to post a note. */
"Post" = "Publication";
/* Label for filter for seeing only posts (instead of posts and replies). */
"Posts" = "Publications";
/* Label for filter for seeing posts and replies (instead of only posts). */
"Posts & Replies" = "Publications & Réponses";
/* Heading indicating that this application keeps personally identifiable information private. A sentence describing what is done to keep data private comes after this heading. */
"Private" = "Privé";
/* Title of the secure field that holds the user's private key. */
"Private Key" = "Clé Privée";
/* Sidebar menu label for Profile view. */
"Profile" = "Profil";
/* Label for Profile Picture section of user profile form. */
"Profile Picture" = "Image de profil";
/* Section title for the user's public account ID. */
"Public Account ID" = "Identifiant publique de compte";
/* Label indicating that the text is a user's public account key. */
"Public key" = "Clé Publique";
/* Label indicating that the text is a user's public account key. */
"Public Key" = "Clé Publique";
/* Prompt to ask user if the key they entered is a public key. */
"Public Key?" = "Clé Publique?";
/* Navigation bar title for Reactions view. */
"Reactions" = "Réactions";
/* Section title for recommend relay servers that could be added as part of configuration */
"Recommended Relays" = "Relais Recommandés";
/* Text field for relay server. Used for testing purposes. */
"Relay" = "Relais";
/* Sidebar menu label for Relay servers view */
"Relays" = "Relais";
/* Button label to remove all participants from a note reply. */
"Remove all" = "Tout supprimer";
/* Label to indicate that the user is replying to themself. */
"Reply to self" = "Réponse à soi-même";
/* Label to indicate that the user is replying to 2 users. */
"Replying to %@ & %@" = "Répondre à %1$@ & %2$@";
/* Indicating that the user is replying to the following listed people. */
"Replying to:" = "Répondre à:";
/* Button to confirm reposting a post.
Title of alert for confirming to repost a post. */
"Repost" = "Republier";
/* Text indicating that the post was reposted (i.e. re-shared). */
"Reposted" = "A republié";
/* Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet). DM is the English abbreviation for Direct Message. */
"Requests" = "Demandes";
/* Section title for resetting the user */
"Reset" = "Réinitialiser";
/* Button to retry completing account creation after an error occurred. */
"Retry" = "Retenter";
/* Dropdown option label for Lightning wallet, River */
"River" = "River";
/* Example username of Bitcoin creator(s), Satoshi Nakamoto. */
"satoshi" = "satoshi";
/* Name of Bitcoin creator(s). */
"Satoshi Nakamoto" = "Satoshi Nakamoto";
/* Button for saving profile. */
"Save" = "Enregistrer";
/* Context menu option to save an image. */
"Save Image" = "Enregistrer Image";
/* Navigation link to search hashtag. */
"Search hashtag: #%@" = "Rechercher hashtag: #%@";
/* Placeholder text to prompt entry of search query. */
"Search..." = "Rechercher...";
/* Section title for user's secret account login key. */
"Secret Account Login Key" = "Clé secrète de connexion au compte";
/* Title of section for selecting a Lightning wallet to pay a Lightning invoice. */
"Select a Lightning wallet" = "Sélectionnez un portefeuille Lightning";
/* Prompt selection of user's default wallet */
"Select default wallet" = "Sélectionnez le portefeuille par défaut";
/* Text prompt for user to send a message to the other user. */
"Send a message to start the conversation..." = "Envoyez un message pour démarrer la conversation...";
/* Navigation title for Settings view.
Sidebar menu label for accessing the app settings */
"Settings" = "Paramètres";
/* Button to share an image. */
"Share" = "Partager";
/* Toggle to show or hide user's secret account login key. */
"Show" = "Afficher";
/* Toggle to show or hide selection of wallet. */
"Show wallet selector" = "Afficher le sélecteur de portefeuille";
/* Sidebar menu label to sign out of the account. */
"Sign out" = "Se déconnecter";
/* Dropdown option label for Lightning wallet, Strike. */
"Strike" = "Strike";
/* Warning that the inputted account key is a public key and the result of what happens because of it. */
"This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective." = "Il s'agit d'une clé publique, vous ne pourrez pas publier de messages ou interagir de quelque manière que ce soit. Ceci est utilisé pour visualiser les comptes de leur point de vue.";
/* Warning that the inputted account key for login is an old-style and asking user to verify if it is a public key. */
"This is an old-style nostr key. We're not sure if it's a pubkey or private key. Please toggle the button below if this a public key." = "Il s'agit d'une clé Nostr à l'ancienne. Nous ne savons pas s'il s'agit d'une clé publique ou d'une clé privée. Veuillez basculer le bouton ci-dessous s'il s'agit d'une clé publique.";
/* Label to describe that a public key is the user's account ID and what they can do with it. */
"This is your account ID, you can give this to your friends so that they can follow you. Click to copy." = "Ceci est votre identifiant de compte, vous pouvez le donner à vos amis afin qu'ils puissent vous suivre. Cliquez pour copier.";
/* Label to describe that a private key is the user's secret account key and what they should do with it. */
"This is your secret account key. You need this to access your account. Don't share this with anyone! Save it in a password manager and keep it safe!" = "Il s'agit de votre clé de compte secrète. Vous en aurez besoin pour accéder à votre compte. Ne le partagez avec personne ! Enregistrez-le dans un gestionnaire de mots de passe et gardez-le en sécurité!";
/* Navigation bar title for note thread.
Navigation bar title for threaded event detail view. */
"Thread" = "Fil de discussion";
/* Text box prompt to ask user to type their post. */
"Type your post here..." = "Tapez votre message ici...";
/* Non-breaking space character to fill in blank space next to event action button icons. */
"u{00A0}" = "u{00A0}";
/* Button to unfollow a user. */
"Unfollow" = "Se désabonner";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of unfollowing a profile. */
"Unfollowing" = "Ne plus suivre";
/* Label to indicate that the user is in the process of unfollowing another user. */
"Unfollowing..." = "Ne plus suivre...";
/* Text to indicate that the button next to it is in a state that will unfollow a profile when tapped. */
"Unfollows" = "Se désabonne de";
/* Label for Username section of user profile form.
Label to prompt username entry. */
"Username" = "Nom d'utilisateur";
/* Sidebar menu label for Wallet view. */
"Wallet" = "Portefeuille";
/* Dropdown option label for Lightning wallet, Wallet Of Satoshi. */
"Wallet Of Satoshi" = "Wallet Of Satoshi";
/* Section title for selection of wallet. */
"Wallet Selector" = "Sélecteur de portefeuille";
/* Label for Website section of user profile form. */
"Website" = "Site Internet";
/* Welcoming message to the reader. The variable is 'you', the reader. */
"Welcome to the social network %@ control." = "Bienvenue sur le réseau social %@ contrôle.";
/* Text to welcome user. */
"Welcome, %@!" = "Bienvenue, %@!";
/* Placeholder example for relay server address. */
"wss://some.relay.com" = "wss://un.relais.com";
/* You, in this context, is the person who controls their own social network. You is used in the context of a larger sentence that welcomes the reader to the social network that they control themself. */
"you" = "vous";
/* Label for Your Name section of user profile form. */
"Your Name" = "Votre Nom";
/* Dropdown option label for Lightning wallet, Zebedee. */
"Zebedee" = "Zebedee";
/* Dropdown option label for Lightning wallet, Zeus LN. */
"Zeus LN" = "Zeus LN";
-154
View File
@@ -1,154 +0,0 @@
<?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>NOTES</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>%d autre note</string>
<key>other</key>
<string>%d autres notes</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>··· %#@NOTES@ ···</string>
</dict>
<key>followers_count</key>
<dict>
<key>FOLLOWERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Abonné</string>
<key>other</key>
<string>Abonnés</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@FOLLOWERS@</string>
</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>Réaction</string>
<key>other</key>
<string>Réactions</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>Relais</string>
<key>other</key>
<string>Relais</string>
</dict>
</dict>
<key>replying_to_one_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Réponse à %@%#@OTHERS@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>&amp; %d autre</string>
<key>other</key>
<string>&amp; %d autres</string>
<key>zero</key>
<string></string>
</dict>
</dict>
<key>replying_to_two_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Répondre à %@, %@%#@OTHERS@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>&amp; %d autre</string>
<key>other</key>
<string>&amp; %d autres</string>
<key>zero</key>
<string></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>Republication</string>
<key>other</key>
<string>Republications</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>Pourboire</string>
<key>other</key>
<string>Pourboires</string>
</dict>
</dict>
</dict>
</plist>
-9
View File
@@ -1,9 +0,0 @@
/* Bundle display name */
"CFBundleDisplayName" = "Damus";
/* Bundle name */
"CFBundleName" = "damus";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Dai il permesso a Damus di accedere alle tue Foto per salvare immagini";
-503
View File
@@ -1,503 +0,0 @@
/* Blank space to separate profile picture from profile editor form. */
" " = "61b6edf1108e6f396680a33b02486a70_tr";
/* Description of how the nip05 identifier would be used for verification. */
"'%@' at '%@' will be used for verification" = "'%@' at '%@' sarà usato per la verifica";
/* Description of why the nip05 identifier is invalid. */
"'%@' is an invalid nip05 identifier. It should look like an email." = "'%@' non è valido. Dovrebbe essere simile ad un indirizzo email.";
/* Navigation bar title for view that shows who is following a user. */
"(Profile.displayName(profile: profile, pubkey: whos))'s Followers" = "Seguaci di (Profile.displayName(profile: profile, pubkey: whos))'";
/* Navigation bar title for view that shows who a user is following. */
"(who) following" = "(who) segui già";
/* Prefix character to username. */
"@" = "@";
/* Amount of time that has passed since reply quote event occurred.
Abbreviated version of a nostr public key. */
"%@" = "%@";
/* Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.
Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'. */
"%@ %@" = "%@ %@";
/* Explanation of what is done to keep personally identifiable information private. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction." = "%@. Per creare un account non hai bisogno di un numero di telefono, un indirizzo email o del tuo nome. Inizia ora senza impegni.";
/* Explanation of what is done to keep private data encrypted. There is a heading that precedes this explanation which is a variable to this string. */
"%@. End-to-End encrypted private messaging. Keep Big Tech out of your DMs" = "%@. I messaggi sono criptati utilizzando la crittografia end-to-end. Mantieni i colossi della tecnologia lontani dai tuoi messaggi";
/* Explanation of what can be done by users to earn money. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Tip your friend's posts and stack sats with Bitcoin⚡️, the native currency of the internet." = "%@. Paga i tuoi amici e accumula sats con Bitcoin⚡️, la moneta di internet.";
/* Number of reposts.
Number of profiles a user is following. */
"%lld" = "%lld";
/* Fraction of how many of the user's relay servers that are operational. */
"%lld/%lld" = "%lld/%lld";
/* Placeholder for event mention. */
"< e >" = "< e >";
/* Label to prompt for about text entry for user to describe about themself. */
"About" = "Informazioni";
/* Label for About Me section of user profile form. */
"About Me" = "Io";
/* Placeholder text for About Me description. */
"Absolute Boss" = "Capo supremo";
/* Label to indicate the public ID of the account. */
"Account ID" = "ID dell'account";
/* Button to add recommended relay server.
Button to confirm adding user inputted relay. */
"Add" = "Aggiungi";
/* Button label to re-add all original participants as profiles to reply to in a note */
"Add all" = "Aggiungi tutto";
/* Label for section for adding a relay server. */
"Add Relay" = "Aggiungi relè";
/* Any amount of sats */
"Any" = "Qualsiasi";
/* Alert message to ask if user wants to repost a post. */
"Are you sure you want to repost this?" = "Sei sicuro di voler segnalare questo post?";
/* Label for Banner Image section of user profile form. */
"Banner Image" = "Immagine banner";
/* Reminder to user that they should save their account information. */
"Before we get started, you'll need to save your account info, otherwise you won't be able to login in the future if you ever uninstall Damus." = "Prima di iniziare, dovrai salvare le informazioni del tuo account altrimenti non sarai in grado di accedere in futuro se dovessi disinstallare Damus.";
/* Dropdown option label for Lightning wallet, Bitcoin Beach. */
"Bitcoin Beach" = "Bitcoin Beach";
/* Label for Bitcoin Lightning Tips section of user profile form. */
"Bitcoin Lightning Tips" = "Mancia con Bitcoin Lightning";
/* Dropdown option label for Lightning wallet, Blixt Wallet */
"Blixt Wallet" = "Blixt Wallet";
/* Dropdown option label for Lightning wallet, Blue Wallet. */
"Blue Wallet" = "Blue Wallet";
/* Dropdown option label for Lightning wallet, Breez. */
"Breez" = "Breez";
/* Context menu option for broadcasting the user's note to all of the user's connected relay servers. */
"Broadcast" = "Trasmetti";
/* Button to cancel out of posting a note.
Button to cancel out of reposting a post.
Button to cancel out of view adding user inputted relay.
Cancel out of logging out the user. */
"Cancel" = "Annulla";
/* Dropdown option label for Lightning wallet, Cash App. */
"Cash App" = "Cash App";
/* Navigation bar title for Chatroom view. */
"Chat" = "Chat";
/* Button for clearing cached data. */
"Clear" = "Cancella";
/* Section title for clearing cached data. */
"Clear Cache" = "Cancella cache";
/* Label indicating that a user's key was copied. */
"Copied" = "Copiato";
/* Button to copy a relay server address. */
"Copy" = "Copia";
/* Context menu option for copying the ID of the account that created the note. */
"Copy Account ID" = "Copia ID dell'Account";
/* Context menu option to copy an image into clipboard.
Context menu option to copy an image to clipboard. */
"Copy Image" = "Copia Immagine";
/* Context menu option to copy the URL of an image into clipboard. */
"Copy Image URL" = "Copia URL dell'Immagine";
/* Title of section for copying a Lightning invoice identifier. */
"Copy invoice" = "Copia fattura";
/* Context menu option for copying a user's Lightning URL. */
"Copy LNURL" = "Copia LNURL";
/* Context menu option for copying the ID of the note. */
"Copy Note ID" = "Copia ID della Nota";
/* Context menu option for copying the JSON text from the note. */
"Copy Note JSON" = "Copia JSON della Nota";
/* Context menu option for copying the text from an note. */
"Copy Text" = "Copia Testo";
/* Context menu option for copying the ID of the user who created the note. */
"Copy User ID" = "Copia ID dell'Utente";
/* Button to create account. */
"Create" = "Crea";
/* Button to create an account. */
"Create Account" = "Crea Account";
/* Example description about Bitcoin creator(s), Satoshi Nakamoto. */
"Creator(s) of Bitcoin. Absolute legend." = "Creatore/i di Bitcoin. Leggenda assoluta";
/* Name of the app, shown on the first screen when user is not logged in. */
"Damus" = "Damus";
/* Button to pay a Lightning invoice with the user's default Lightning wallet. */
"Default Wallet" = "Portafoglio Principale";
/* Button to delete a relay server that the user connects to. */
"Delete" = "Cancella";
/* Button to dismiss a text field alert. */
"Dismiss" = "Lascia stare";
/* Label to prompt display name entry. */
"Display Name" = "Nome visualizzato";
/* DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet. DM is the English abbreviation for Direct Message. */
"DM Type" = "Tipo DM";
/* Navigation title for DMs view, where DM is the English abbreviation for Direct Message.
Navigation title for view of DMs, where DM is an English abbreviation for Direct Message. */
"DMs" = "DM";
/* Button to dismiss wallet selection view for paying Lightning invoice. */
"Done" = "Finito";
/* Heading indicating that this application allows users to earn money. */
"Earn Money" = "Guadagna Soldi";
/* Button to edit user's profile. */
"Edit" = "Modifica";
/* Text indicating that the view is used for editing which participants are replied to in a note. */
"Edit participants" = "Modifica partecipanti";
/* Heading indicating that this application keeps private messaging end-to-end encrypted. */
"Encrypted" = "Criptato";
/* Prompt for user to enter an account key to login. */
"Enter your account key to login:" = "Inserisci la chiave del tuo account per accedere";
/* Error message indicating why saving keys failed. */
"Error: %@" = "Errore: %@";
/* Filter state for seeing either only posts, or posts & replies. */
"Filter State" = "Filtra";
/* Button to follow a user. */
"Follow" = "Segui";
/* Label describing followers of a user. */
"Followers" = "Seguaci";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of following a profile.
Part of a larger sentence to describe how many profiles a user is following. */
"Following" = "Seguiti";
/* Label to indicate that the user is in the process of following another user. */
"Following..." = "Segui già...";
/* Text to indicate that button next to it is in a state that will follow a profile when tapped. */
"Follows" = "Segui";
/* Navigation bar title for Global view where posts from all connected relay servers appear. */
"Global" = "Globale";
/* Navigation link to go to post referenced by hex code. */
"Goto post %@" = "Vai al post %@";
/* Navigation link to go to profile. */
"Goto profile %@" = "Vai al profilo %@";
/* Navigation bar title for Home view where posts and replies appear from those who the user is following. */
"Home" = "Home";
/* Placeholder example text for profile picture URL. */
"https://example.com/pic.jpg" = "https://esempio.com/foto.jpg";
/* Placeholder example text for website URL for user profile. */
"https://jb55.com" = "https://jb55.com";
/* Error message indicating that an invalid account key was entered for login. */
"Invalid key" = "Chiave non valida";
/* Placeholder example text for identifier used for NIP-05 verification. */
"jb55@jb55.com" = "jb55@jb55.com";
/* Moves the post button to the left side of the screen */
"Left Handed" = "Mancino";
/* Button to complete account creation and start using the app. */
"Let's go!" = "Andiamo!";
/* Placeholder text for entry of Lightning Address or LNURL. */
"Lightning Address or LNURL" = "Indirizzo Lightning o LNURL";
/* Indicates that the view is for paying a Lightning invoice. */
"Lightning Invoice" = "Fattura Lightning";
/* Dropdown option label for Lightning wallet, LNLink. */
"LNLink" = "LNLink";
/* Dropdown option label for system default for Lightning wallet. */
"Local default" = "Predefinito";
/* Button to log into account.
Button to log into an account. */
"Login" = "Entra";
/* Alert for logging out the user.
Button for logging out the user.
Button to logout the user. */
"Logout" = "Esci";
/* Reminder message in alert to get customer to verify that their private security account key is saved saved before logging out. */
"Make sure your nsec account key is saved before you logout or you will lose access to this account" = "Assicurati di aver salvato la chiave privata (nSEC) prima di uscire o perderai l'accesso a questo account";
/* Dropdown option label for Lightning wallet, Muun. */
"Muun" = "Muun";
/* Label for NIP-05 Verification section of user profile form. */
"NIP-05 Verification" = "Verifica NIP-05";
/* No search results. */
"none" = "Nessun risultato";
/* Indicates that there are no notes in the timeline to view. */
"Nothing to see here. Check back later!" = "Niente da vedere qui. Controlla dopo!";
/* Navigation title for notifications. */
"Notifications" = "Notifiche";
/* String indicating that a given timestamp just occurred */
"now" = "ora";
/* Prompt for user to enter in an account key to login. This text shows the characters the key could start with if it was a private key. */
"nsec1..." = "nsec1...";
/* Label indicating that a form input is optional. */
"optional" = "opzione1";
/* Button to pay a Lightning invoice. */
"Pay" = "Paga";
/* Navigation bar title for view to pay Lightning invoice. */
"Pay the Lightning invoice" = "Paga la fattura Lightning";
/* Dropdown option label for Lightning wallet, Phoenix. */
"Phoenix" = "Phoenix";
/* Button to post a note. */
"Post" = "Post";
/* Label for filter for seeing only posts (instead of posts and replies). */
"Posts" = "Post";
/* Label for filter for seeing posts and replies (instead of only posts). */
"Posts & Replies" = "Post & Risposte";
/* Heading indicating that this application keeps personally identifiable information private. A sentence describing what is done to keep data private comes after this heading. */
"Private" = "Privato";
/* Title of the secure field that holds the user's private key. */
"Private Key" = "Chiave Privata";
/* Sidebar menu label for Profile view. */
"Profile" = "Profilo1";
/* Label for Profile Picture section of user profile form. */
"Profile Picture" = "Foto Profilo";
/* Section title for the user's public account ID. */
"Public Account ID" = "ID Pubblico dell'Account";
/* Label indicating that the text is a user's public account key. */
"Public key" = "Chiave Pubblica";
/* Label indicating that the text is a user's public account key. */
"Public Key" = "Chiave Pubblica";
/* Prompt to ask user if the key they entered is a public key. */
"Public Key?" = "È la chiave pubblica?";
/* Navigation bar title for Reactions view. */
"Reactions" = "Reazioni";
/* Section title for recommend relay servers that could be added as part of configuration */
"Recommended Relays" = "Relè consigliati";
/* Text field for relay server. Used for testing purposes. */
"Relay" = "Relè";
/* Sidebar menu label for Relay servers view */
"Relays" = "Relè";
/* Button label to remove all participants from a note reply. */
"Remove all" = "Rimuovi tutto";
/* Label to indicate that the user is replying to themself. */
"Reply to self" = "Rispondi a te stesso";
/* Label to indicate that the user is replying to 2 users. */
"Replying to %@ & %@" = "Rispondi a %1$@ e %2$@";
/* Indicating that the user is replying to the following listed people. */
"Replying to:" = "Rispondi a:";
/* Button to confirm reposting a post.
Title of alert for confirming to repost a post. */
"Repost" = "Reposta";
/* Text indicating that the post was reposted (i.e. re-shared). */
"Reposted" = "Repostato";
/* Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet). DM is the English abbreviation for Direct Message. */
"Requests" = "Richiesta";
/* Section title for resetting the user */
"Reset" = "Ricomincia";
/* Button to retry completing account creation after an error occurred. */
"Retry" = "Riprova";
/* Dropdown option label for Lightning wallet, River */
"River" = "River";
/* Example username of Bitcoin creator(s), Satoshi Nakamoto. */
"satoshi" = "satoshi";
/* Name of Bitcoin creator(s). */
"Satoshi Nakamoto" = "Satoshi Nakamoto";
/* Button for saving profile. */
"Save" = "Salva";
/* Context menu option to save an image. */
"Save Image" = "Salva Immagine";
/* Navigation link to search hashtag. */
"Search hashtag: #%@" = "Cerca hashtag: #%@";
/* Placeholder text to prompt entry of search query. */
"Search..." = "Cerca...";
/* Section title for user's secret account login key. */
"Secret Account Login Key" = "Chiave login segreta dell'Account";
/* Title of section for selecting a Lightning wallet to pay a Lightning invoice. */
"Select a Lightning wallet" = "Seleziona un portafoglio Lightning";
/* Prompt selection of user's default wallet */
"Select default wallet" = "Seleziona un wallet predefinito";
/* Text prompt for user to send a message to the other user. */
"Send a message to start the conversation..." = "Invia un messaggio e inizia la conversazione...";
/* Navigation title for Settings view.
Sidebar menu label for accessing the app settings */
"Settings" = "Impostazioni";
/* Button to share an image. */
"Share" = "Condividi";
/* Toggle to show or hide user's secret account login key. */
"Show" = "Mostra";
/* Toggle to show or hide selection of wallet. */
"Show wallet selector" = "Mostra wallet disponibili";
/* Sidebar menu label to sign out of the account. */
"Sign out" = "Esci";
/* Dropdown option label for Lightning wallet, Strike. */
"Strike" = "Strike";
/* Warning that the inputted account key is a public key and the result of what happens because of it. */
"This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective." = "Questa è una chiave pubblica, non potrai postare o interagire in alcun modo. Puoi utilizzarla solo per vedere gli account";
/* Warning that the inputted account key for login is an old-style and asking user to verify if it is a public key. */
"This is an old-style nostr key. We're not sure if it's a pubkey or private key. Please toggle the button below if this a public key." = "Questa è una chiave di vecchio tipo. Non siamo sicuri se si tratti di una chiave pubblica o privata. Utilizza il pulsante sottostante se si tratta di una chiave pubblica.";
/* Label to describe that a public key is the user's account ID and what they can do with it. */
"This is your account ID, you can give this to your friends so that they can follow you. Click to copy." = "Questo è l'ID del tuo account. Condividilo con i tuoi amici per farti seguire. Clicca per copiare";
/* Label to describe that a private key is the user's secret account key and what they should do with it. */
"This is your secret account key. You need this to access your account. Don't share this with anyone! Save it in a password manager and keep it safe!" = "Questa è la tua chiave privata. Ti serve ad accedere al tuo account. Non condividerla con nessuno! Salvala in un gestore password e tienila al sicuro";
/* Navigation bar title for note thread.
Navigation bar title for threaded event detail view. */
"Thread" = "Thread";
/* Text box prompt to ask user to type their post. */
"Type your post here..." = "Scrivi il tuo post qui...";
/* Non-breaking space character to fill in blank space next to event action button icons. */
"u{00A0}" = "u{00A0}";
/* Button to unfollow a user. */
"Unfollow" = "Smetti di seguire";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of unfollowing a profile. */
"Unfollowing" = "Smetti di seguire";
/* Label to indicate that the user is in the process of unfollowing another user. */
"Unfollowing..." = "Togliendo il segui...";
/* Text to indicate that the button next to it is in a state that will unfollow a profile when tapped. */
"Unfollows" = "Smetti di seguire";
/* Label for Username section of user profile form.
Label to prompt username entry. */
"Username" = "Nome utente";
/* Sidebar menu label for Wallet view. */
"Wallet" = "Portafoglio";
/* Dropdown option label for Lightning wallet, Wallet Of Satoshi. */
"Wallet Of Satoshi" = "Wallet Of Satoshi";
/* Section title for selection of wallet. */
"Wallet Selector" = "Seleziona un portafoglio";
/* Label for Website section of user profile form. */
"Website" = "Sito web";
/* Welcoming message to the reader. The variable is 'you', the reader. */
"Welcome to the social network %@ control." = "Benvenuto nel social network %@ controlla.";
/* Text to welcome user. */
"Welcome, %@!" = "Benvenuto, %@!";
/* Placeholder example for relay server address. */
"wss://some.relay.com" = "wss://un.relè.com";
/* You, in this context, is the person who controls their own social network. You is used in the context of a larger sentence that welcomes the reader to the social network that they control themself. */
"you" = "tu";
/* Label for Your Name section of user profile form. */
"Your Name" = "Nome";
/* Dropdown option label for Lightning wallet, Zebedee. */
"Zebedee" = "Zebedee";
/* Dropdown option label for Lightning wallet, Zeus LN. */
"Zeus LN" = "Zeus LN";
-154
View File
@@ -1,154 +0,0 @@
<?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>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>
<key>NSStringLocalizedFormatKey</key>
<string>··· %#@NOTES@ ···</string>
</dict>
<key>followers_count</key>
<dict>
<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>
<key>NSStringLocalizedFormatKey</key>
<string>%#@FOLLOWERS@</string>
</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>one</key>
<string> &amp; %d other</string>
<key>other</key>
<string> &amp; %d others</string>
<key>zero</key>
<string></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>one</key>
<string> &amp; %d other</string>
<key>other</key>
<string> &amp; %d others</string>
<key>zero</key>
<string></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>
-9
View File
@@ -1,9 +0,0 @@
/* Bundle display name */
"CFBundleDisplayName" = "Damus";
/* Bundle name */
"CFBundleName" = "damus";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Dai il permesso a Damus di accedere alle tue Foto per salvare immagini";
-503
View File
@@ -1,503 +0,0 @@
/* Blank space to separate profile picture from profile editor form. */
" " = "61b6edf1108e6f396680a33b02486a70_tr";
/* Description of how the nip05 identifier would be used for verification. */
"'%@' at '%@' will be used for verification" = "'%@' at '%@' sarà usato per la verifica";
/* Description of why the nip05 identifier is invalid. */
"'%@' is an invalid nip05 identifier. It should look like an email." = "'%@' non è un identificatore NIP05 valido. Dovrebbe essere simile ad un indirizzo email.";
/* Navigation bar title for view that shows who is following a user. */
"(Profile.displayName(profile: profile, pubkey: whos))'s Followers" = "Seguaci di (Profile.displayName(profile: profile, pubkey: whos))'";
/* Navigation bar title for view that shows who a user is following. */
"(who) following" = "(who) segui già";
/* Prefix character to username. */
"@" = "@";
/* Amount of time that has passed since reply quote event occurred.
Abbreviated version of a nostr public key. */
"%@" = "%@";
/* Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.
Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'. */
"%@ %@" = "%@ %@";
/* Explanation of what is done to keep personally identifiable information private. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction." = "%@. Per creare un account non hai bisogno di un numero di telefono, un indirizzo email o del tuo nome. Inizia ora senza impegni.";
/* Explanation of what is done to keep private data encrypted. There is a heading that precedes this explanation which is a variable to this string. */
"%@. End-to-End encrypted private messaging. Keep Big Tech out of your DMs" = "%@. I messaggi sono criptati utilizzando la crittografia end-to-end. Mantieni i colossi della tecnologia lontani dai tuoi messaggi";
/* Explanation of what can be done by users to earn money. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Tip your friend's posts and stack sats with Bitcoin⚡️, the native currency of the internet." = "%@. Paga i tuoi amici e accumula sats con Bitcoin⚡️, la moneta di internet.";
/* Number of reposts.
Number of profiles a user is following. */
"%lld" = "%lld";
/* Fraction of how many of the user's relay servers that are operational. */
"%lld/%lld" = "%lld/%lld";
/* Placeholder for event mention. */
"< e >" = "< e >";
/* Label to prompt for about text entry for user to describe about themself. */
"About" = "Informazioni";
/* Label for About Me section of user profile form. */
"About Me" = "Io";
/* Placeholder text for About Me description. */
"Absolute Boss" = "Capo supremo";
/* Label to indicate the public ID of the account. */
"Account ID" = "ID dell'account";
/* Button to add recommended relay server.
Button to confirm adding user inputted relay. */
"Add" = "Aggiungi";
/* Button label to re-add all original participants as profiles to reply to in a note */
"Add all" = "Aggiungi tutto";
/* Label for section for adding a relay server. */
"Add Relay" = "Aggiungi relè";
/* Any amount of sats */
"Any" = "Qualsiasi";
/* Alert message to ask if user wants to repost a post. */
"Are you sure you want to repost this?" = "Sei sicuro di voler segnalare questo post?";
/* Label for Banner Image section of user profile form. */
"Banner Image" = "Immagine banner";
/* Reminder to user that they should save their account information. */
"Before we get started, you'll need to save your account info, otherwise you won't be able to login in the future if you ever uninstall Damus." = "Prima di iniziare, dovrai salvare le informazioni del tuo account altrimenti non sarai in grado di accedere in futuro se dovessi disinstallare Damus.";
/* Dropdown option label for Lightning wallet, Bitcoin Beach. */
"Bitcoin Beach" = "Bitcoin Beach";
/* Label for Bitcoin Lightning Tips section of user profile form. */
"Bitcoin Lightning Tips" = "Mancia con Bitcoin Lightning";
/* Dropdown option label for Lightning wallet, Blixt Wallet */
"Blixt Wallet" = "Blixt Wallet";
/* Dropdown option label for Lightning wallet, Blue Wallet. */
"Blue Wallet" = "Blue Wallet";
/* Dropdown option label for Lightning wallet, Breez. */
"Breez" = "Breez";
/* Context menu option for broadcasting the user's note to all of the user's connected relay servers. */
"Broadcast" = "Trasmetti";
/* Button to cancel out of posting a note.
Button to cancel out of reposting a post.
Button to cancel out of view adding user inputted relay.
Cancel out of logging out the user. */
"Cancel" = "Annulla";
/* Dropdown option label for Lightning wallet, Cash App. */
"Cash App" = "Cash App";
/* Navigation bar title for Chatroom view. */
"Chat" = "Chat";
/* Button for clearing cached data. */
"Clear" = "Cancella";
/* Section title for clearing cached data. */
"Clear Cache" = "Cancella cache";
/* Label indicating that a user's key was copied. */
"Copied" = "Copiato";
/* Button to copy a relay server address. */
"Copy" = "Copia";
/* Context menu option for copying the ID of the account that created the note. */
"Copy Account ID" = "Copia ID dell'Account";
/* Context menu option to copy an image into clipboard.
Context menu option to copy an image to clipboard. */
"Copy Image" = "Copia Immagine";
/* Context menu option to copy the URL of an image into clipboard. */
"Copy Image URL" = "Copia URL dell'Immagine";
/* Title of section for copying a Lightning invoice identifier. */
"Copy invoice" = "Copia fattura";
/* Context menu option for copying a user's Lightning URL. */
"Copy LNURL" = "Copia LNURL";
/* Context menu option for copying the ID of the note. */
"Copy Note ID" = "Copia ID della Nota";
/* Context menu option for copying the JSON text from the note. */
"Copy Note JSON" = "Copia JSON della Nota";
/* Context menu option for copying the text from an note. */
"Copy Text" = "Copia Testo";
/* Context menu option for copying the ID of the user who created the note. */
"Copy User ID" = "Copia ID dell'Utente";
/* Button to create account. */
"Create" = "Crea";
/* Button to create an account. */
"Create Account" = "Crea Account";
/* Example description about Bitcoin creator(s), Satoshi Nakamoto. */
"Creator(s) of Bitcoin. Absolute legend." = "Creatore/i di Bitcoin. Leggenda assoluta";
/* Name of the app, shown on the first screen when user is not logged in. */
"Damus" = "Damus";
/* Button to pay a Lightning invoice with the user's default Lightning wallet. */
"Default Wallet" = "Portafoglio Principale";
/* Button to delete a relay server that the user connects to. */
"Delete" = "Cancella";
/* Button to dismiss a text field alert. */
"Dismiss" = "Lascia stare";
/* Label to prompt display name entry. */
"Display Name" = "Nome visualizzato";
/* DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet. DM is the English abbreviation for Direct Message. */
"DM Type" = "Tipo DM";
/* Navigation title for DMs view, where DM is the English abbreviation for Direct Message.
Navigation title for view of DMs, where DM is an English abbreviation for Direct Message. */
"DMs" = "DM";
/* Button to dismiss wallet selection view for paying Lightning invoice. */
"Done" = "Finito";
/* Heading indicating that this application allows users to earn money. */
"Earn Money" = "Guadagna Soldi";
/* Button to edit user's profile. */
"Edit" = "Modifica";
/* Text indicating that the view is used for editing which participants are replied to in a note. */
"Edit participants" = "Modifica partecipanti";
/* Heading indicating that this application keeps private messaging end-to-end encrypted. */
"Encrypted" = "Criptato";
/* Prompt for user to enter an account key to login. */
"Enter your account key to login:" = "Inserisci la chiave del tuo account per accedere";
/* Error message indicating why saving keys failed. */
"Error: %@" = "Errore: %@";
/* Filter state for seeing either only posts, or posts & replies. */
"Filter State" = "Filtra";
/* Button to follow a user. */
"Follow" = "Segui";
/* Label describing followers of a user. */
"Followers" = "Seguaci";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of following a profile.
Part of a larger sentence to describe how many profiles a user is following. */
"Following" = "Seguiti";
/* Label to indicate that the user is in the process of following another user. */
"Following..." = "Segui già...";
/* Text to indicate that button next to it is in a state that will follow a profile when tapped. */
"Follows" = "Segui";
/* Navigation bar title for Global view where posts from all connected relay servers appear. */
"Global" = "Globale";
/* Navigation link to go to post referenced by hex code. */
"Goto post %@" = "Vai al post %@";
/* Navigation link to go to profile. */
"Goto profile %@" = "Vai al profilo %@";
/* Navigation bar title for Home view where posts and replies appear from those who the user is following. */
"Home" = "Home";
/* Placeholder example text for profile picture URL. */
"https://example.com/pic.jpg" = "https://esempio.com/foto.jpg";
/* Placeholder example text for website URL for user profile. */
"https://jb55.com" = "https://jb55.com";
/* Error message indicating that an invalid account key was entered for login. */
"Invalid key" = "Chiave non valida";
/* Placeholder example text for identifier used for NIP-05 verification. */
"jb55@jb55.com" = "jb55@jb55.com";
/* Moves the post button to the left side of the screen */
"Left Handed" = "Mancino";
/* Button to complete account creation and start using the app. */
"Let's go!" = "Andiamo!";
/* Placeholder text for entry of Lightning Address or LNURL. */
"Lightning Address or LNURL" = "Indirizzo Lightning o LNURL";
/* Indicates that the view is for paying a Lightning invoice. */
"Lightning Invoice" = "Fattura Lightning";
/* Dropdown option label for Lightning wallet, LNLink. */
"LNLink" = "LNLink";
/* Dropdown option label for system default for Lightning wallet. */
"Local default" = "Predefinito";
/* Button to log into account.
Button to log into an account. */
"Login" = "Entra";
/* Alert for logging out the user.
Button for logging out the user.
Button to logout the user. */
"Logout" = "Esci";
/* Reminder message in alert to get customer to verify that their private security account key is saved saved before logging out. */
"Make sure your nsec account key is saved before you logout or you will lose access to this account" = "Assicurati di aver salvato la chiave privata (nSEC) prima di uscire o perderai l'accesso a questo account";
/* Dropdown option label for Lightning wallet, Muun. */
"Muun" = "Muun";
/* Label for NIP-05 Verification section of user profile form. */
"NIP-05 Verification" = "Verifica NIP-05";
/* No search results. */
"none" = "Nessun risultato";
/* Indicates that there are no notes in the timeline to view. */
"Nothing to see here. Check back later!" = "Niente da vedere qui. Controlla dopo!";
/* Navigation title for notifications. */
"Notifications" = "Notifiche";
/* String indicating that a given timestamp just occurred */
"now" = "ora";
/* Prompt for user to enter in an account key to login. This text shows the characters the key could start with if it was a private key. */
"nsec1..." = "nsec1...";
/* Label indicating that a form input is optional. */
"optional" = "opzione1";
/* Button to pay a Lightning invoice. */
"Pay" = "Paga";
/* Navigation bar title for view to pay Lightning invoice. */
"Pay the Lightning invoice" = "Paga la fattura Lightning";
/* Dropdown option label for Lightning wallet, Phoenix. */
"Phoenix" = "Phoenix";
/* Button to post a note. */
"Post" = "Post";
/* Label for filter for seeing only posts (instead of posts and replies). */
"Posts" = "Post";
/* Label for filter for seeing posts and replies (instead of only posts). */
"Posts & Replies" = "Post & Risposte";
/* Heading indicating that this application keeps personally identifiable information private. A sentence describing what is done to keep data private comes after this heading. */
"Private" = "Privato";
/* Title of the secure field that holds the user's private key. */
"Private Key" = "Chiave Privata";
/* Sidebar menu label for Profile view. */
"Profile" = "Profilo1";
/* Label for Profile Picture section of user profile form. */
"Profile Picture" = "Foto Profilo";
/* Section title for the user's public account ID. */
"Public Account ID" = "ID Pubblico dell'Account";
/* Label indicating that the text is a user's public account key. */
"Public key" = "Chiave Pubblica";
/* Label indicating that the text is a user's public account key. */
"Public Key" = "Chiave Pubblica";
/* Prompt to ask user if the key they entered is a public key. */
"Public Key?" = "È la chiave pubblica?";
/* Navigation bar title for Reactions view. */
"Reactions" = "Reazioni";
/* Section title for recommend relay servers that could be added as part of configuration */
"Recommended Relays" = "Relè consigliati";
/* Text field for relay server. Used for testing purposes. */
"Relay" = "Relè";
/* Sidebar menu label for Relay servers view */
"Relays" = "Relè";
/* Button label to remove all participants from a note reply. */
"Remove all" = "Rimuovi tutto";
/* Label to indicate that the user is replying to themself. */
"Reply to self" = "Rispondi a te stesso";
/* Label to indicate that the user is replying to 2 users. */
"Replying to %@ & %@" = "Rispondi a %1$@ e %2$@";
/* Indicating that the user is replying to the following listed people. */
"Replying to:" = "Rispondi a:";
/* Button to confirm reposting a post.
Title of alert for confirming to repost a post. */
"Repost" = "Reposta";
/* Text indicating that the post was reposted (i.e. re-shared). */
"Reposted" = "Repostato";
/* Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet). DM is the English abbreviation for Direct Message. */
"Requests" = "Richiesta";
/* Section title for resetting the user */
"Reset" = "Ricomincia";
/* Button to retry completing account creation after an error occurred. */
"Retry" = "Riprova";
/* Dropdown option label for Lightning wallet, River */
"River" = "River";
/* Example username of Bitcoin creator(s), Satoshi Nakamoto. */
"satoshi" = "satoshi";
/* Name of Bitcoin creator(s). */
"Satoshi Nakamoto" = "Satoshi Nakamoto";
/* Button for saving profile. */
"Save" = "Salva";
/* Context menu option to save an image. */
"Save Image" = "Salva Immagine";
/* Navigation link to search hashtag. */
"Search hashtag: #%@" = "Cerca hashtag: #%@";
/* Placeholder text to prompt entry of search query. */
"Search..." = "Cerca...";
/* Section title for user's secret account login key. */
"Secret Account Login Key" = "Chiave login segreta dell'Account";
/* Title of section for selecting a Lightning wallet to pay a Lightning invoice. */
"Select a Lightning wallet" = "Seleziona un portafoglio Lightning";
/* Prompt selection of user's default wallet */
"Select default wallet" = "Seleziona un wallet predefinito";
/* Text prompt for user to send a message to the other user. */
"Send a message to start the conversation..." = "Invia un messaggio e inizia la conversazione...";
/* Navigation title for Settings view.
Sidebar menu label for accessing the app settings */
"Settings" = "Impostazioni";
/* Button to share an image. */
"Share" = "Condividi";
/* Toggle to show or hide user's secret account login key. */
"Show" = "Mostra";
/* Toggle to show or hide selection of wallet. */
"Show wallet selector" = "Mostra wallet disponibili";
/* Sidebar menu label to sign out of the account. */
"Sign out" = "Esci";
/* Dropdown option label for Lightning wallet, Strike. */
"Strike" = "Strike";
/* Warning that the inputted account key is a public key and the result of what happens because of it. */
"This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective." = "Questa è una chiave pubblica, non potrai postare o interagire in alcun modo. Puoi utilizzarla solo per vedere gli account";
/* Warning that the inputted account key for login is an old-style and asking user to verify if it is a public key. */
"This is an old-style nostr key. We're not sure if it's a pubkey or private key. Please toggle the button below if this a public key." = "Questa è una chiave di vecchio tipo. Non siamo sicuri se si tratti di una chiave pubblica o privata. Utilizza il pulsante sottostante se si tratta di una chiave pubblica.";
/* Label to describe that a public key is the user's account ID and what they can do with it. */
"This is your account ID, you can give this to your friends so that they can follow you. Click to copy." = "Questo è l'ID del tuo account. Condividilo con i tuoi amici per farti seguire. Clicca per copiare";
/* Label to describe that a private key is the user's secret account key and what they should do with it. */
"This is your secret account key. You need this to access your account. Don't share this with anyone! Save it in a password manager and keep it safe!" = "Questa è la tua chiave privata. Ti serve ad accedere al tuo account. Non condividerla con nessuno! Salvala in un gestore password e tienila al sicuro";
/* Navigation bar title for note thread.
Navigation bar title for threaded event detail view. */
"Thread" = "Thread";
/* Text box prompt to ask user to type their post. */
"Type your post here..." = "Scrivi il tuo post qui...";
/* Non-breaking space character to fill in blank space next to event action button icons. */
"u{00A0}" = "u{00A0}";
/* Button to unfollow a user. */
"Unfollow" = "Smetti di seguire";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of unfollowing a profile. */
"Unfollowing" = "Smetti di seguire";
/* Label to indicate that the user is in the process of unfollowing another user. */
"Unfollowing..." = "Togliendo il segui...";
/* Text to indicate that the button next to it is in a state that will unfollow a profile when tapped. */
"Unfollows" = "Smetti di seguire";
/* Label for Username section of user profile form.
Label to prompt username entry. */
"Username" = "Nome utente";
/* Sidebar menu label for Wallet view. */
"Wallet" = "Portafoglio";
/* Dropdown option label for Lightning wallet, Wallet Of Satoshi. */
"Wallet Of Satoshi" = "Wallet Of Satoshi";
/* Section title for selection of wallet. */
"Wallet Selector" = "Seleziona un portafoglio";
/* Label for Website section of user profile form. */
"Website" = "Sito web";
/* Welcoming message to the reader. The variable is 'you', the reader. */
"Welcome to the social network %@ control." = "Benvenuto nel social network %@ controlla.";
/* Text to welcome user. */
"Welcome, %@!" = "Benvenuto, %@!";
/* Placeholder example for relay server address. */
"wss://some.relay.com" = "wss://un.relè.com";
/* You, in this context, is the person who controls their own social network. You is used in the context of a larger sentence that welcomes the reader to the social network that they control themself. */
"you" = "tu";
/* Label for Your Name section of user profile form. */
"Your Name" = "Nome";
/* Dropdown option label for Lightning wallet, Zebedee. */
"Zebedee" = "Zebedee";
/* Dropdown option label for Lightning wallet, Zeus LN. */
"Zeus LN" = "Zeus LN";
-154
View File
@@ -1,154 +0,0 @@
<?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>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>
<key>NSStringLocalizedFormatKey</key>
<string>··· %#@NOTES@ ···</string>
</dict>
<key>followers_count</key>
<dict>
<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>
<key>NSStringLocalizedFormatKey</key>
<string>%#@FOLLOWERS@</string>
</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>one</key>
<string> &amp; %d other</string>
<key>other</key>
<string> &amp; %d others</string>
<key>zero</key>
<string></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>one</key>
<string> &amp; %d other</string>
<key>other</key>
<string> &amp; %d others</string>
<key>zero</key>
<string></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>
-9
View File
@@ -1,9 +0,0 @@
/* Bundle display name */
"CFBundleDisplayName" = "Damus";
/* Bundle name */
"CFBundleName" = "damus";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Piešķir Damus piekļuvi saviem fotoattēliem, lai varat saglabāt attēlus.";
-503
View File
@@ -1,503 +0,0 @@
/* Blank space to separate profile picture from profile editor form. */
" " = "61b6edf1108e6f396680a33b02486a70_tr";
/* Description of how the nip05 identifier would be used for verification. */
"'%@' at '%@' will be used for verification" = "'%@' pie '%@' tiks izmantota priekš verifikācijas.";
/* Description of why the nip05 identifier is invalid. */
"'%@' is an invalid nip05 identifier. It should look like an email." = "'%@' ir nederīgs nip05 identifikators. Tam vajadzētu būt kā e-pasta adresei.";
/* Navigation bar title for view that shows who is following a user. */
"(Profile.displayName(profile: profile, pubkey: whos))'s Followers" = "(Profils.ParādāmaisVārds(profils: profils, kopAtslēga: kurš))'am Sekotāji";
/* Navigation bar title for view that shows who a user is following. */
"(who) following" = "(kurš) seko";
/* Prefix character to username. */
"@" = "@";
/* Amount of time that has passed since reply quote event occurred.
Abbreviated version of a nostr public key. */
"%@" = "%@";
/* Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.
Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'. */
"%@ %@" = "%@ %@";
/* Explanation of what is done to keep personally identifiable information private. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction." = "Lai izveidotu kontu, nav nepieciešams tālruņa numurs, e-pasts vai vārds. Sāciet uzreiz bez aizkaves.";
/* Explanation of what is done to keep private data encrypted. There is a heading that precedes this explanation which is a variable to this string. */
"%@. End-to-End encrypted private messaging. Keep Big Tech out of your DMs" = "%@. Pilnīga šifrēta privātā ziņojumapmaiņa. Esi privātajā iesūtnē bez lielo tekfirmu klātbūtnes.";
/* Explanation of what can be done by users to earn money. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Tip your friend's posts and stack sats with Bitcoin⚡️, the native currency of the internet." = "%@. Sponsorē draugu ziņas un krājiet Satiņus ar BitMonētu⚡️, interneta digitālo valūtu.";
/* Number of reposts.
Number of profiles a user is following. */
"%lld" = "%lld";
/* Fraction of how many of the user's relay servers that are operational. */
"%lld/%lld" = "%lld/%lld";
/* Placeholder for event mention. */
"< e >" = "< e >";
/* Label to prompt for about text entry for user to describe about themself. */
"About" = "Par";
/* Label for About Me section of user profile form. */
"About Me" = "Par Mani";
/* Placeholder text for About Me description. */
"Absolute Boss" = "Pilnīgs Priekšnieks";
/* Label to indicate the public ID of the account. */
"Account ID" = "Konta ID";
/* Button to add recommended relay server.
Button to confirm adding user inputted relay. */
"Add" = "Pievieno";
/* Button label to re-add all original participants as profiles to reply to in a note */
"Add all" = "Pievienot Visus";
/* Label for section for adding a relay server. */
"Add Relay" = "Pievienot Releju";
/* Any amount of sats */
"Any" = "Jebkurš";
/* Alert message to ask if user wants to repost a post. */
"Are you sure you want to repost this?" = "Vai tiešām vēlies šo ziņu pārpublicēt?";
/* Label for Banner Image section of user profile form. */
"Banner Image" = "Karoga Attēls";
/* Reminder to user that they should save their account information. */
"Before we get started, you'll need to save your account info, otherwise you won't be able to login in the future if you ever uninstall Damus." = "Pirms sākam darbu, jums ir jāsaglabā sava konta informācija, pretējā gadījumā jūs nevarēsiet pieteikties nākamjā reizē, ja kādreiz atinstalēsiet Damus.";
/* Dropdown option label for Lightning wallet, Bitcoin Beach. */
"Bitcoin Beach" = "Bitmonētas Pludmale";
/* Label for Bitcoin Lightning Tips section of user profile form. */
"Bitcoin Lightning Tips" = "Bitmonētas Zibens Naudiņa";
/* Dropdown option label for Lightning wallet, Blixt Wallet */
"Blixt Wallet" = "Blixt Maciņš";
/* Dropdown option label for Lightning wallet, Blue Wallet. */
"Blue Wallet" = "Blue Maciņš";
/* Dropdown option label for Lightning wallet, Breez. */
"Breez" = "Breez";
/* Context menu option for broadcasting the user's note to all of the user's connected relay servers. */
"Broadcast" = "Pārraidīt";
/* Button to cancel out of posting a note.
Button to cancel out of reposting a post.
Button to cancel out of view adding user inputted relay.
Cancel out of logging out the user. */
"Cancel" = "Atcelt";
/* Dropdown option label for Lightning wallet, Cash App. */
"Cash App" = "Cash App";
/* Navigation bar title for Chatroom view. */
"Chat" = "Čatiņš";
/* Button for clearing cached data. */
"Clear" = "Notīrīt";
/* Section title for clearing cached data. */
"Clear Cache" = "Notīrīt Kešatmiņu";
/* Label indicating that a user's key was copied. */
"Copied" = "Nokopēts";
/* Button to copy a relay server address. */
"Copy" = "Kopēt";
/* Context menu option for copying the ID of the account that created the note. */
"Copy Account ID" = "Nokopēt konta ID";
/* Context menu option to copy an image into clipboard.
Context menu option to copy an image to clipboard. */
"Copy Image" = "Nokopēt Attēlu";
/* Context menu option to copy the URL of an image into clipboard. */
"Copy Image URL" = "Nokopēt Attēla Adresi";
/* Title of section for copying a Lightning invoice identifier. */
"Copy invoice" = "Nokopēt Pavadzīmi";
/* Context menu option for copying a user's Lightning URL. */
"Copy LNURL" = "Nokopēt Zibens Adresi";
/* Context menu option for copying the ID of the note. */
"Copy Note ID" = "Nokopēt Ziņas ID";
/* Context menu option for copying the JSON text from the note. */
"Copy Note JSON" = "Nokopēt Ziņas JSON";
/* Context menu option for copying the text from an note. */
"Copy Text" = "Nokopēt Tekstu";
/* Context menu option for copying the ID of the user who created the note. */
"Copy User ID" = "Nokopēt Lietotāja ID";
/* Button to create account. */
"Create" = "Izveidot";
/* Button to create an account. */
"Create Account" = "Izveidot Kontu";
/* Example description about Bitcoin creator(s), Satoshi Nakamoto. */
"Creator(s) of Bitcoin. Absolute legend." = "Bitmonētas Radītājs(i). Pilnīgas Leģendas.";
/* Name of the app, shown on the first screen when user is not logged in. */
"Damus" = "Damus";
/* Button to pay a Lightning invoice with the user's default Lightning wallet. */
"Default Wallet" = "Noklusējuma Maciņš";
/* Button to delete a relay server that the user connects to. */
"Delete" = "Izdzēst";
/* Button to dismiss a text field alert. */
"Dismiss" = "Atmest";
/* Label to prompt display name entry. */
"Display Name" = "Parādāmais Vārds";
/* DM selector for seeing either DMs or message requests, which are messages that have not been responded to yet. DM is the English abbreviation for Direct Message. */
"DM Type" = "Privātās Iesūtnes Tips";
/* Navigation title for DMs view, where DM is the English abbreviation for Direct Message.
Navigation title for view of DMs, where DM is an English abbreviation for Direct Message. */
"DMs" = "Privātās Ziņas";
/* Button to dismiss wallet selection view for paying Lightning invoice. */
"Done" = "Pabeigts";
/* Heading indicating that this application allows users to earn money. */
"Earn Money" = "Pelni Naudu";
/* Button to edit user's profile. */
"Edit" = "Rediģēt";
/* Text indicating that the view is used for editing which participants are replied to in a note. */
"Edit participants" = "Rediģēt dalībniekus";
/* Heading indicating that this application keeps private messaging end-to-end encrypted. */
"Encrypted" = "Šifrēts";
/* Prompt for user to enter an account key to login. */
"Enter your account key to login:" = "Ievadi sava konta atslēgu, lai pieteiktos:";
/* Error message indicating why saving keys failed. */
"Error: %@" = "Kļūda: %@";
/* Filter state for seeing either only posts, or posts & replies. */
"Filter State" = "Filtrēt Štatu";
/* Button to follow a user. */
"Follow" = "Sekot";
/* Label describing followers of a user. */
"Followers" = "Sekotāji";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of following a profile.
Part of a larger sentence to describe how many profiles a user is following. */
"Following" = "Sekoju";
/* Label to indicate that the user is in the process of following another user. */
"Following..." = "Sekoju..";
/* Text to indicate that button next to it is in a state that will follow a profile when tapped. */
"Follows" = "Seko";
/* Navigation bar title for Global view where posts from all connected relay servers appear. */
"Global" = "Globāls";
/* Navigation link to go to post referenced by hex code. */
"Goto post %@" = "Ej uz ierakstu %@";
/* Navigation link to go to profile. */
"Goto profile %@" = "Ej uz profilu %@";
/* Navigation bar title for Home view where posts and replies appear from those who the user is following. */
"Home" = "Sākums";
/* Placeholder example text for profile picture URL. */
"https://example.com/pic.jpg" = "https://paraugs.lv/att.jpg";
/* Placeholder example text for website URL for user profile. */
"https://jb55.com" = "https://jb55.com";
/* Error message indicating that an invalid account key was entered for login. */
"Invalid key" = "Nepareiza atslēga";
/* Placeholder example text for identifier used for NIP-05 verification. */
"jb55@jb55.com" = "jb55@jb55.com";
/* Moves the post button to the left side of the screen */
"Left Handed" = "Kreilis";
/* Button to complete account creation and start using the app. */
"Let's go!" = "Uz priekšu!";
/* Placeholder text for entry of Lightning Address or LNURL. */
"Lightning Address or LNURL" = "Zibens Adrese vai ZibSaite";
/* Indicates that the view is for paying a Lightning invoice. */
"Lightning Invoice" = "Zibens Pavadzīme";
/* Dropdown option label for Lightning wallet, LNLink. */
"LNLink" = "ZibSaite";
/* Dropdown option label for system default for Lightning wallet. */
"Local default" = "Vietējais Noklusējums";
/* Button to log into account.
Button to log into an account. */
"Login" = "Pieteikties";
/* Alert for logging out the user.
Button for logging out the user.
Button to logout the user. */
"Logout" = "Iziet";
/* Reminder message in alert to get customer to verify that their private security account key is saved saved before logging out. */
"Make sure your nsec account key is saved before you logout or you will lose access to this account" = "Pirms iziešanas pārliecinieties, vai jūsu nsec konta atslēga ir saglabāta, pretējā gadījumā jūs zaudēsiet piekļuvi šim kontam";
/* Dropdown option label for Lightning wallet, Muun. */
"Muun" = "Muun";
/* Label for NIP-05 Verification section of user profile form. */
"NIP-05 Verification" = "NIP-05 Verifikācija";
/* No search results. */
"none" = "neviens";
/* Indicates that there are no notes in the timeline to view. */
"Nothing to see here. Check back later!" = "Nav ko redzēt te. Ienāc šeit vēlāk.";
/* Navigation title for notifications. */
"Notifications" = "Paziņojumi";
/* String indicating that a given timestamp just occurred */
"now" = "tagad";
/* Prompt for user to enter in an account key to login. This text shows the characters the key could start with if it was a private key. */
"nsec1..." = "nsec1...";
/* Label indicating that a form input is optional. */
"optional" = "pēc izvēles";
/* Button to pay a Lightning invoice. */
"Pay" = "Maksāt";
/* Navigation bar title for view to pay Lightning invoice. */
"Pay the Lightning invoice" = "Samaksāt Zibens Pavadzīmi";
/* Dropdown option label for Lightning wallet, Phoenix. */
"Phoenix" = "Phoenix";
/* Button to post a note. */
"Post" = "Publicēt";
/* Label for filter for seeing only posts (instead of posts and replies). */
"Posts" = "Ieraksti";
/* Label for filter for seeing posts and replies (instead of only posts). */
"Posts & Replies" = "Ieraksti & Atbildes";
/* Heading indicating that this application keeps personally identifiable information private. A sentence describing what is done to keep data private comes after this heading. */
"Private" = "Privāts";
/* Title of the secure field that holds the user's private key. */
"Private Key" = "Privātā Atslēga";
/* Sidebar menu label for Profile view. */
"Profile" = "Profils";
/* Label for Profile Picture section of user profile form. */
"Profile Picture" = "Profila Attēls";
/* Section title for the user's public account ID. */
"Public Account ID" = "Publiskais Konta ID";
/* Label indicating that the text is a user's public account key. */
"Public key" = "Publiskā atslēga";
/* Label indicating that the text is a user's public account key. */
"Public Key" = "Publiskā Atslēga";
/* Prompt to ask user if the key they entered is a public key. */
"Public Key?" = "Vai Publiskā Atslēga?";
/* Navigation bar title for Reactions view. */
"Reactions" = "Reakcijas";
/* Section title for recommend relay servers that could be added as part of configuration */
"Recommended Relays" = "Ieteicamie Releji";
/* Text field for relay server. Used for testing purposes. */
"Relay" = "Relejs";
/* Sidebar menu label for Relay servers view */
"Relays" = "Releji";
/* Button label to remove all participants from a note reply. */
"Remove all" = "Noņemt visu";
/* Label to indicate that the user is replying to themself. */
"Reply to self" = "Atbildēt sev";
/* Label to indicate that the user is replying to 2 users. */
"Replying to %@ & %@" = "Atbildot %1$@ & %2$@";
/* Indicating that the user is replying to the following listed people. */
"Replying to:" = "Atbildot";
/* Button to confirm reposting a post.
Title of alert for confirming to repost a post. */
"Repost" = "Pārpublicēt";
/* Text indicating that the post was reposted (i.e. re-shared). */
"Reposted" = "Pārpublicēts";
/* Picker option for DM selector for seeing only message requests (DMs that someone else sent the user which has not been responded to yet). DM is the English abbreviation for Direct Message. */
"Requests" = "Pieprasījumi";
/* Section title for resetting the user */
"Reset" = "Atiestatīt";
/* Button to retry completing account creation after an error occurred. */
"Retry" = "Mēģiniet vēlreiz";
/* Dropdown option label for Lightning wallet, River */
"River" = "Plūsma";
/* Example username of Bitcoin creator(s), Satoshi Nakamoto. */
"satoshi" = "satoshi";
/* Name of Bitcoin creator(s). */
"Satoshi Nakamoto" = "Satoshi Nakamoto";
/* Button for saving profile. */
"Save" = "Saglabāt";
/* Context menu option to save an image. */
"Save Image" = "Saglabāt Attēlu";
/* Navigation link to search hashtag. */
"Search hashtag: #%@" = "Meklēt Režģbirku #%@";
/* Placeholder text to prompt entry of search query. */
"Search..." = "Meklēt...";
/* Section title for user's secret account login key. */
"Secret Account Login Key" = "Konta Slepenā Pietiekšanās Atslēga";
/* Title of section for selecting a Lightning wallet to pay a Lightning invoice. */
"Select a Lightning wallet" = "Atlasīt Zibens maciņu";
/* Prompt selection of user's default wallet */
"Select default wallet" = "Atlasīt noklusējuma maciņu";
/* Text prompt for user to send a message to the other user. */
"Send a message to start the conversation..." = "Sūti ziņu, lai sāktu sarunu...";
/* Navigation title for Settings view.
Sidebar menu label for accessing the app settings */
"Settings" = "Uzstādījumi";
/* Button to share an image. */
"Share" = "Dalīties";
/* Toggle to show or hide user's secret account login key. */
"Show" = "Parādīt";
/* Toggle to show or hide selection of wallet. */
"Show wallet selector" = "Parādīt maciņu atlasītāju";
/* Sidebar menu label to sign out of the account. */
"Sign out" = "Atteikties";
/* Dropdown option label for Lightning wallet, Strike. */
"Strike" = "Strike";
/* Warning that the inputted account key is a public key and the result of what happens because of it. */
"This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective." = "Šī ir publiskā atslēga, jūs nevarēsit rakstīt ziņas vai kādā citā veidā darboties. To izmanto, lai tikai skatītu kontus no to skatpunkta.";
/* Warning that the inputted account key for login is an old-style and asking user to verify if it is a public key. */
"This is an old-style nostr key. We're not sure if it's a pubkey or private key. Please toggle the button below if this a public key." = "Šī ir vecā parauga nostr atslēga. Mēs neesam pārliecināti, vai tā ir kopAtslēga vai slepenā atslēga. Lūdzu, pārslēdziet ar tālāk esošo pogu, ja šī ir publiskā atslēga.";
/* Label to describe that a public key is the user's account ID and what they can do with it. */
"This is your account ID, you can give this to your friends so that they can follow you. Click to copy." = "Šis ir jūsu konta ID. Varat to iedot draugiem, lai viņi varētu jums sekot. Noklikšķiniet, lai nokopētu.";
/* Label to describe that a private key is the user's secret account key and what they should do with it. */
"This is your secret account key. You need this to access your account. Don't share this with anyone! Save it in a password manager and keep it safe!" = "Šī ir jūsu konta slepenā atslēga. Tā ir nepieciešama, lai piekļūtu savam kontam. Nedalies ar to nevienam! Saglabājiet to paroļu pārvaldniekā un glabājiet to drošībā!";
/* Navigation bar title for note thread.
Navigation bar title for threaded event detail view. */
"Thread" = "Plūsma";
/* Text box prompt to ask user to type their post. */
"Type your post here..." = "Rakstiet savu ziņu šeit...";
/* Non-breaking space character to fill in blank space next to event action button icons. */
"u{00A0}" = "u{00A0}";
/* Button to unfollow a user. */
"Unfollow" = "Atsekot";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of unfollowing a profile. */
"Unfollowing" = "Atsekoju";
/* Label to indicate that the user is in the process of unfollowing another user. */
"Unfollowing..." = "Atsekoju...";
/* Text to indicate that the button next to it is in a state that will unfollow a profile when tapped. */
"Unfollows" = "Atsekos";
/* Label for Username section of user profile form.
Label to prompt username entry. */
"Username" = "Lietotājvārds";
/* Sidebar menu label for Wallet view. */
"Wallet" = "Maciņš";
/* Dropdown option label for Lightning wallet, Wallet Of Satoshi. */
"Wallet Of Satoshi" = "Wallet Of Satoshi";
/* Section title for selection of wallet. */
"Wallet Selector" = "Maciņu Atlasītājs";
/* Label for Website section of user profile form. */
"Website" = "Mājaslapa";
/* Welcoming message to the reader. The variable is 'you', the reader. */
"Welcome to the social network %@ control." = "Esi sveicināts sociālo tīklu %@ vadībā.";
/* Text to welcome user. */
"Welcome, %@!" = "Laipni lūgts, %@!";
/* Placeholder example for relay server address. */
"wss://some.relay.com" = "wss://cits.relejs.lv";
/* You, in this context, is the person who controls their own social network. You is used in the context of a larger sentence that welcomes the reader to the social network that they control themself. */
"you" = "jūs";
/* Label for Your Name section of user profile form. */
"Your Name" = "Tavs Vārds";
/* Dropdown option label for Lightning wallet, Zebedee. */
"Zebedee" = "Zebedee";
/* Dropdown option label for Lightning wallet, Zeus LN. */
"Zeus LN" = "Zeus LN";
-168
View File
@@ -1,168 +0,0 @@
<?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>NOTES</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>%d cita piezīme</string>
<key>other</key>
<string>%d citas piezīmes</string>
<key>zero</key>
<string>%d other notes</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>··· %#@PIEZĪMES@ ···</string>
</dict>
<key>followers_count</key>
<dict>
<key>FOLLOWERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Sekotājs</string>
<key>other</key>
<string>Sekotāji</string>
<key>zero</key>
<string>Followers</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@SEKOTĀJI@</string>
</dict>
<key>reactions_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@REAKCIJAS@</string>
<key>REACTIONS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Reakcija</string>
<key>other</key>
<string>Reakcijas</string>
<key>zero</key>
<string>Reactions</string>
</dict>
</dict>
<key>relays_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@RELEJI@</string>
<key>RELAYS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Relejs</string>
<key>other</key>
<string>Releji</string>
<key>zero</key>
<string>Relays</string>
</dict>
</dict>
<key>replying_to_one_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Atbildot %@%#@CITIEM@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string> &amp; %d cits</string>
<key>other</key>
<string> &amp; %d citiem</string>
<key>zero</key>
<string></string>
</dict>
</dict>
<key>replying_to_two_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Atbildot %@, %@%#@CITIEM@</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string> &amp; %d cits</string>
<key>other</key>
<string> &amp; %d citiem</string>
<key>zero</key>
<string></string>
</dict>
</dict>
<key>reposts_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@PĀRPUBLICĒJUMI@</string>
<key>REPOSTS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Pārpublicēt</string>
<key>other</key>
<string>Pārpublicējumi</string>
<key>zero</key>
<string>Reposts</string>
</dict>
</dict>
<key>sats_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%1$#@SATIŅI@</string>
<key>SATS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>@</string>
<key>one</key>
<string>%2$@ satiņš</string>
<key>other</key>
<string>%2$@ satiņi</string>
<key>zero</key>
<string>%2$@ sats</string>
</dict>
</dict>
<key>tips_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@SPONSORĒJUMI@</string>
<key>TIPS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Sponsorējums</string>
<key>other</key>
<string>Sponsorējumi</string>
<key>zero</key>
<string>Tips</string>
</dict>
</dict>
</dict>
</plist>
-9
View File
@@ -1,9 +0,0 @@
/* Bundle display name */
"CFBundleDisplayName" = "Damus";
/* Bundle name */
"CFBundleName" = "damus";
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Damus'a fotoğraf kitaplığınıza erişim izni vermek, fotoğrafları kaydetmenize olanak tanır.";
-493
View File
@@ -1,493 +0,0 @@
/* Blank space to separate profile picture from profile editor form. */
" " = "61b6edf1108e6f396680a33b02486a70_tr";
/* Description of how the nip05 identifier would be used for verification. */
"'%@' at '%@' will be used for verification" = "'%@' adresindeki '%@' doğrulama için kullanılacaktır";
/* Description of why the nip05 identifier is invalid. */
"'%@' is an invalid nip05 identifier. It should look like an email." = "'%@' geçersiz bir nip05 tanımlayıcısı. Tanımlayıcı, e-posta gibi gözükmeli. ";
/* Navigation bar title for view that shows who is following a user. */
"(Profile.displayName(profile: profile, pubkey: whos))'s Followers" = "(Profile.displayName(profile: profile, pubkey: whos))'nin Takipçileri";
/* Navigation bar title for view that shows who a user is following. */
"(who) following" = "(who)'nin Takip Ettikleri";
/* Prefix character to username. */
"@" = "@";
/* Amount of time that has passed since reply quote event occurred.
Abbreviated version of a nostr public key. */
"%@" = "%@";
/* Sentence composed of 2 variables to describe how many reposts. In source English, the first variable is the number of reposts, and the second variable is 'Repost' or 'Reposts'.
Sentence composed of 2 variables to describe how many profiles a user is following. In source English, the first variable is the number of profiles being followed, and the second variable is 'Following'. */
"%@ %@" = "%@ %@";
/* Explanation of what is done to keep personally identifiable information private. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction." = "%@. Hesap oluşturmak için telefon numarası, e-posta veya isim gerekmez. Vakit kaybetmeden hemen hemen başlayın.";
/* Explanation of what is done to keep private data encrypted. There is a heading that precedes this explanation which is a variable to this string. */
"%@. End-to-End encrypted private messaging. Keep Big Tech out of your DMs" = "%@. Uçtan uca şifreli özel mesajlaşma. Teknoloji baronlarını DM'lerinden uzak tut";
/* Explanation of what can be done by users to earn money. There is a heading that precedes this explanation which is a variable to this string. */
"%@. Tip your friend's posts and stack sats with Bitcoin⚡️, the native currency of the internet." = "%@. Arkadaşlarınızın gönderilerine bahşiş verin ve internetin yerel para birimi olan Bitcoin⚡️ ile sats biriktirin.";
/* Number of reposts.
Number of profiles a user is following. */
"%lld" = "%lld";
/* Fraction of how many of the user's relay servers that are operational. */
"%lld/%lld" = "%lld/%lld";
/* Placeholder for event mention. */
"< e >" = "< e >";
/* Label to prompt for about text entry for user to describe about themself. */
"About" = "Hakkında";
/* Label for About Me section of user profile form. */
"About Me" = "Hakkında";
/* Placeholder text for About Me description. */
"Absolute Boss" = "Kral Adam";
/* Label to indicate the public ID of the account. */
"Account ID" = "Hesap Kimliği";
/* Button to add recommended relay server.
Button to confirm adding user inputted relay. */
"Add" = "Ekle";
/* Label for section for adding a relay server. */
"Add Relay" = "Röle Ekle";
/* Any amount of sats */
"Any" = "Herhangi";
/* Alert message to ask if user wants to repost a post. */
"Are you sure you want to repost this?" = "Bu gönderiyi yinelemek istediğinden emin misin?";
/* Label for Banner Image section of user profile form. */
"Banner Image" = "Pankart Resmi";
/* Reminder to user that they should save their account information. */
"Before we get started, you'll need to save your account info, otherwise you won't be able to login in the future if you ever uninstall Damus." = "Başlamadan önce, hesap bilgilierini kaydetmen gerekiyor. Aksi takdirde, Damus'u silme durumunda hesabına giriş yapamayacaksın.";
/* Dropdown option label for Lightning wallet, Bitcoin Beach. */
"Bitcoin Beach" = "Bitcoin Beach";
/* Label for Bitcoin Lightning Tips section of user profile form. */
"Bitcoin Lightning Tips" = "Bitcoin Lightning Bahşişleri";
/* Dropdown option label for Lightning wallet, Blixt Wallet */
"Blixt Wallet" = "Blixt Wallet";
/* Dropdown option label for Lightning wallet, Blue Wallet. */
"Blue Wallet" = "Blue Wallet";
/* Dropdown option label for Lightning wallet, Breez. */
"Breez" = "Breez";
/* Context menu option for broadcasting the user's note to all of the user's connected relay servers. */
"Broadcast" = "Yayınla";
/* Button to cancel out of posting a note.
Button to cancel out of reposting a post.
Button to cancel out of view adding user inputted relay.
Cancel out of logging out the user. */
"Cancel" = "İptal Et";
/* Dropdown option label for Lightning wallet, Cash App. */
"Cash App" = "Cash App";
/* Navigation bar title for Chatroom view. */
"Chat" = "Sohbet";
/* Button for clearing cached data. */
"Clear" = "Temizle";
/* Section title for clearing cached data. */
"Clear Cache" = "Önbelleği Temizle";
/* Label indicating that a user's key was copied. */
"Copied" = "Kopyalandı";
/* Button to copy a relay server address. */
"Copy" = "Kopyala";
/* Context menu option for copying the ID of the account that created the note. */
"Copy Account ID" = "Hesap Kimliğini Kopyala";
/* Context menu option to copy an image into clipboard.
Context menu option to copy an image to clipboard. */
"Copy Image" = "Resmi Kopyala";
/* Context menu option to copy the URL of an image into clipboard. */
"Copy Image URL" = "Resim URL'sini Kopyala";
/* Title of section for copying a Lightning invoice identifier. */
"Copy invoice" = "Faturayı Kopyala";
/* Context menu option for copying a user's Lightning URL. */
"Copy LNURL" = "LNURL'i Kopyala";
/* Context menu option for copying the ID of the note. */
"Copy Note ID" = "Gönderi Kimliğini Kopyala ";
/* Context menu option for copying the JSON text from the note. */
"Copy Note JSON" = "Gönderinin JSON Metnini Kopyala";
/* Context menu option for copying the text from an note. */
"Copy Text" = "Metni Kopyala";
/* Context menu option for copying the ID of the user who created the note. */
"Copy User ID" = "Hesap Kimliğini Kopyala";
/* Button to create account. */
"Create" = "Yarat";
/* Button to create an account. */
"Create Account" = "Hesap Yarat";
/* Example description about Bitcoin creator(s), Satoshi Nakamoto. */
"Creator(s) of Bitcoin. Absolute legend." = "Bitcoin'in Yaratıcısı. Kral Adam.";
/* Name of the app, shown on the first screen when user is not logged in. */
"Damus" = "Damus";
/* Button to pay a Lightning invoice with the user's default Lightning wallet. */
"Default Wallet" = "Varsayılan Cüzdan";
/* Button to delete a relay server that the user connects to. */
"Delete" = "Sil";
/* Button to dismiss a text field alert. */
"Dismiss" = "Yok Say";
/* Label to prompt display name entry. */
"Display Name" = "Görünür İsim";
/* Navigation title for DM view, which is the English abbreviation for Direct Message. */
"DM" = "DM";
/* Button to dismiss wallet selection view for paying Lightning invoice. */
"Done" = "Tamam";
/* Heading indicating that this application allows users to earn money. */
"Earn Money" = "Para Kazan";
/* Button to edit user's profile. */
"Edit" = "Düzenle";
/* Heading indicating that this application keeps private messaging end-to-end encrypted. */
"Encrypted" = "Şifreli";
/* Navigation title for view of encrypted DMs, where DM is an English abbreviation for Direct Message. */
"Encrypted DMs" = "Şifreli DM'ler";
/* Prompt for user to enter an account key to login. */
"Enter your account key to login:" = "Giriş yapmak için hesap anahtarını gir:";
/* Error message indicating why saving keys failed. */
"Error: %@" = "Hata: %@";
/* Filter state for seeing either only posts, or posts & replies. */
"Filter State" = "Filtre Durumu";
/* Button to follow a user. */
"Follow" = "Takip Et";
/* Label describing followers of a user. */
"Followers" = "Takipçiler";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of following a profile.
Part of a larger sentence to describe how many profiles a user is following. */
"Following" = "Takip Ediliyor";
/* Label to indicate that the user is in the process of following another user. */
"Following..." = "Takip Ediliyor...";
/* Text to indicate that button next to it is in a state that will follow a profile when tapped. */
"Follows" = "Takipler";
/* Navigation bar title for Global view where posts from all connected relay servers appear. */
"Global" = "Küresel";
/* Navigation link to go to post referenced by hex code. */
"Goto post %@" = "%@'a git";
/* Navigation link to go to profile. */
"Goto profile %@" = "%@'a git";
/* Navigation bar title for Home view where posts and replies appear from those who the user is following. */
"Home" = "Ev";
/* Placeholder example text for profile picture URL. */
"https://example.com/pic.jpg" = "https://example.com/pic.jpg";
/* Placeholder example text for website URL for user profile. */
"https://jb55.com" = "https://jb55.com";
/* Error message indicating that an invalid account key was entered for login. */
"Invalid key" = "Hatalı anahtar";
/* Placeholder example text for identifier used for NIP-05 verification. */
"jb55@jb55.com" = "jb55@jb55.com";
/* Moves the post button to the left side of the screen */
"Left Handed" = "Solak Modu";
/* Button to complete account creation and start using the app. */
"Let's go!" = "Haydi Başla!";
/* Placeholder text for entry of Lightning Address or LNURL. */
"Lightning Address or LNURL" = "Lightning Adresi ya da LNURL";
/* Indicates that the view is for paying a Lightning invoice. */
"Lightning Invoice" = "Lightning Faturası";
/* Dropdown option label for Lightning wallet, LNLink. */
"LNLink" = "LNLink";
/* Dropdown option label for system default for Lightning wallet. */
"Local default" = "Cihaz varsayılanı";
/* Button to log into account.
Button to log into an account. */
"Login" = "Giriş yap";
/* Alert for logging out the user.
Button for logging out the user.
Button to logout the user. */
"Logout" = "Çıkış yap";
/* Reminder message in alert to get customer to verify that their private security account key is saved saved before logging out. */
"Make sure your nsec account key is saved before you logout or you will lose access to this account" = "Çıkış yapmadan önce, nsec hesap anahtarını kaydetmeyi unutma. Aksi takdirde bu hesaba giremeyeceksin.";
/* Dropdown option label for Lightning wallet, Muun. */
"Muun" = "Muun";
/* Label for NIP-05 Verification section of user profile form. */
"NIP-05 Verification" = "NIP-05 Doğrulaması";
/* No search results. */
"none" = "sonuç yok";
/* Indicates that there are no notes in the timeline to view. */
"Nothing to see here. Check back later!" = "Görülecek bir şey yok. Daha sonra tekrar kontrol et!";
/* Navigation title for notifications. */
"Notifications" = "Bildirimler";
/* String indicating that a given timestamp just occurred */
"now" = "şimdi";
/* Prompt for user to enter in an account key to login. This text shows the characters the key could start with if it was a private key. */
"nsec1..." = "nsec1...";
/* Label indicating that a form input is optional. */
"optional" = "opsiyonel";
/* Button to pay a Lightning invoice. */
"Pay" = "Öde";
/* Navigation bar title for view to pay Lightning invoice. */
"Pay the Lightning invoice" = "Lightning faturasını öde";
/* Dropdown option label for Lightning wallet, Phoenix. */
"Phoenix" = "Phoenix";
/* Button to post a note. */
"Post" = "Gönder";
/* Label for filter for seeing only posts (instead of posts and replies). */
"Posts" = "Gönderiler";
/* Label for filter for seeing posts and replies (instead of only posts). */
"Posts & Replies" = "Gönderiler & Yorumlar";
/* Heading indicating that this application keeps personally identifiable information private. A sentence describing what is done to keep data private comes after this heading. */
"Private" = "Özel";
/* Label to indicate that the text below is the user's private key used by only the user themself as a secret to login to access their account. */
"Private Key" = "Özel Anahtar";
/* Title of the secure field that holds the user's private key. */
"PrivateKey" = "Özel Anahtar";
/* Sidebar menu label for Profile view. */
"Profile" = "Profil";
/* Label for Profile Picture section of user profile form. */
"Profile Picture" = "Profil Fotoğrafı";
/* Section title for the user's public account ID. */
"Public Account ID" = "Herkese Açık Hesap Kimliği";
/* Label indicating that the text is a user's public account key. */
"Public key" = "Umumi anahtar";
/* Label indicating that the text is a user's public account key. */
"Public Key" = "Herkese Açık Anahtar";
/* Prompt to ask user if the key they entered is a public key. */
"Public Key?" = "Herkese Açık Anahtar?";
/* Navigation bar title for Reactions view. */
"Reactions" = "Tepkiler";
/* Section title for recommend relay servers that could be added as part of configuration */
"Recommended Relays" = "Önerilen Röleler";
/* Text field for relay server. Used for testing purposes. */
"Relay" = "Röle";
/* Sidebar menu label for Relay servers view */
"Relays" = "Röleler";
/* Label to indicate that the user is replying to themself. */
"Reply to self" = "Kendine yanıt ver";
/* Label to indicate that the user is replying to 2 users. */
"Replying to %@ & %@" = "%1$@ & %2$@'ya yanıt ver";
/* Indicating that the user is replying to the following listed people. */
"Replying to:" = "Şunlara yanıt ver:";
/* Button to confirm reposting a post.
Title of alert for confirming to repost a post. */
"Repost" = "Yinele";
/* Text indicating that the post was reposted (i.e. re-shared). */
"Reposted" = "Yinelendi";
/* Section title for resetting the user */
"Reset" = "Sıfırla";
/* Button to retry completing account creation after an error occurred. */
"Retry" = "Yeniden Dene";
/* Dropdown option label for Lightning wallet, River */
"River" = "River";
/* Example username of Bitcoin creator(s), Satoshi Nakamoto. */
"satoshi" = "satoshi";
/* Name of Bitcoin creator(s). */
"Satoshi Nakamoto" = "Satoshi Nakamoto";
/* Button for saving profile. */
"Save" = "Kaydet";
/* Context menu option to save an image. */
"Save Image" = "Resmi Kaydet";
/* Navigation link to search hashtag. */
"Search hashtag: #%@" = "Etiketi ara: #%@";
/* Placeholder text to prompt entry of search query. */
"Search..." = "Ara...";
/* Section title for user's secret account login key. */
"Secret Account Login Key" = "Gizli Hesap Giriş Anahtarı";
/* Title of section for selecting a Lightning wallet to pay a Lightning invoice. */
"Select a Lightning wallet" = "Bir Lightning cüzdanı seç";
/* Prompt selection of user's default wallet */
"Select default wallet" = "Varsayılan cüzdanı seç";
/* Text prompt for user to send a message to the other user. */
"Send a message to start the conversation..." = "Sohbeti başlatmak için bir mesaj gönder";
/* Navigation title for Settings view.
Sidebar menu label for accessing the app settings */
"Settings" = "Ayarlar";
/* Button to share an image. */
"Share" = "Paylaş";
/* Toggle to show or hide user's secret account login key. */
"Show" = "Göster";
/* Toggle to show or hide selection of wallet. */
"Show wallet selector" = "Cüzdan seçiciyi göster";
/* Sidebar menu label to sign out of the account. */
"Sign out" = "Çıkış yap";
/* Dropdown option label for Lightning wallet, Strike. */
"Strike" = "Strike";
/* Warning that the inputted account key is a public key and the result of what happens because of it. */
"This is a public key, you will not be able to make posts or interact in any way. This is used for viewing accounts from their perspective." = "Bu herkese açık bir anahtardır, herhangi bir şekilde gönderi yapamaz veya etkileşimde bulunamazsınız. Bu, hesapları kendi bakış açılarından görüntülemek için kullanılır.";
/* Warning that the inputted account key for login is an old-style and asking user to verify if it is a public key. */
"This is an old-style nostr key. We're not sure if it's a pubkey or private key. Please toggle the button below if this a public key." = "Bu eski tip bir nostr anahtarı. Bunun bir pubkey mi yoksa private key mi olduğundan emin değiliz. Bu bir genel anahtarsa lütfen aşağıdaki düğmeyi değiştirin.";
/* Label to describe that a public key is the user's account ID and what they can do with it. */
"This is your account ID, you can give this to your friends so that they can follow you. Click to copy." = "Bu sizin hesap kimliğinizdir, sizi takip edebilmeleri için bunu arkadaşlarınıza verebilirsiniz. Kopyalamak için tıklayın.";
/* Label to describe that a private key is the user's secret account key and what they should do with it. */
"This is your secret account key. You need this to access your account. Don't share this with anyone! Save it in a password manager and keep it safe!" = "Bu sizin gizli hesap anahtarınızdır. Hesabınıza erişmek için buna ihtiyacınız var. Bunu kimseyle paylaşmayın! Bir şifre yöneticisine kaydedin ve güvende tutun!";
/* Navigation bar title for note thread.
Navigation bar title for threaded event detail view. */
"Thread" = "Konu";
/* Text box prompt to ask user to type their post. */
"Type your post here..." = "Gönderinizi buraya yazın...";
/* Non-breaking space character to fill in blank space next to event action button icons. */
"u{00A0}" = "u{00A0}";
/* Button to unfollow a user. */
"Unfollow" = "Takipten Çık";
/* Text to indicate that the button next to it is in a state that indicates that it is in the process of unfollowing a profile. */
"Unfollowing" = "Takipten Çıkılıyor";
/* Label to indicate that the user is in the process of unfollowing another user. */
"Unfollowing..." = "Takipten Çıkılıyor...";
/* Text to indicate that the button next to it is in a state that will unfollow a profile when tapped. */
"Unfollows" = "Takipten Çık";
/* Label for Username section of user profile form.
Label to prompt username entry. */
"Username" = "Kullanıcı Adı";
/* Sidebar menu label for Wallet view. */
"Wallet" = "Cüzdan";
/* Dropdown option label for Lightning wallet, Wallet Of Satoshi. */
"Wallet Of Satoshi" = "Wallet Of Satoshi";
/* Section title for selection of wallet. */
"Wallet Selector" = "Cüzdan Seçici";
/* Label for Website section of user profile form. */
"Website" = "Websitesi";
/* Welcoming message to the reader. The variable is 'you', the reader. */
"Welcome to the social network %@ control." = "Kontrolün %@'da olduğu sosyal ağa hoş geldiniz.";
/* Text to welcome user. */
"Welcome, %@!" = "Hoş geldin, %@";
/* Placeholder example for relay server address. */
"wss://some.relay.com" = "wss://some.relay.com";
/* You, in this context, is the person who controls their own social network. You is used in the context of a larger sentence that welcomes the reader to the social network that they control themself. */
"you" = "sen";
/* Label for Your Name section of user profile form. */
"Your Name" = "İsminiz";
/* Dropdown option label for Lightning wallet, Zebedee. */
"Zebedee" = "Zebedee";
/* Dropdown option label for Lightning wallet, Zeus LN. */
"Zeus LN" = "Zeus LN";
-154
View File
@@ -1,154 +0,0 @@
<?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>NOTES</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>1%d diğer not</string>
<key>other</key>
<string>%d diğer notlar</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>··· %#@NOTES@ ···</string>
</dict>
<key>followers_count</key>
<dict>
<key>FOLLOWERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>Takipçi</string>
<key>other</key>
<string>Takipçiler</string>
</dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@FOLLOWERS@</string>
</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>Tepki</string>
<key>other</key>
<string>Tepkiler</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>Röle</string>
<key>other</key>
<string>Röleler</string>
</dict>
</dict>
<key>replying_to_one_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%@%#@OTHERS@'lara yanıt </string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>&amp; %d diğer</string>
<key>other</key>
<string>&amp; %d diğerleri</string>
<key>zero</key>
<string></string>
</dict>
</dict>
<key>replying_to_two_and_others</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%@, %@%#@OTHERS@'a yanıt</string>
<key>OTHERS</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>&amp; %d diğer</string>
<key>other</key>
<string>&amp; %d diğerleri</string>
<key>zero</key>
<string></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>Yineleme</string>
<key>other</key>
<string>Yinelemeler</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$@ sat</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>Bahşiş</string>
<key>other</key>
<string>Bahşişler</string>
</dict>
</dict>
</dict>
</plist>
+1 -2
View File
@@ -50,8 +50,7 @@ final class DMTests: XCTestCase {
func testDMSortOrder() throws {
let notif = NewEventsBits()
let pubkey = "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"
let model = DirectMessagesModel(our_pubkey: pubkey)
let model = DirectMessagesModel()
let now = Int64(Date().timeIntervalSince1970)
-71
View File
@@ -1,71 +0,0 @@
//
// ListTests.swift
// damusTests
//
// Created by William Casarin on 2023-01-25.
//
import XCTest
@testable import damus
final class ListTests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testCreateMuteList() throws {
let privkey = "87f313b03f2548e6eaf1c188db47078e08e894252949779b639b28db0891937a"
let pubkey = "4b0c29bf96496130c1253102f6870c0eee05db38a257315858272aa43fd19685"
let to_mute = "2fa2630fea3d2c188c49f2799fcd92f0e9879ea6a36ae60770a5428ed6c19edd"
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: to_mute)!
XCTAssertEqual(mutelist.pubkey, pubkey)
XCTAssertEqual(mutelist.content, "")
XCTAssertEqual(mutelist.tags.count, 2)
XCTAssertEqual(mutelist.tags[0][0], "d")
XCTAssertEqual(mutelist.tags[0][1], "mute")
XCTAssertEqual(mutelist.tags[1][0], "p")
XCTAssertEqual(mutelist.tags[1][1], to_mute)
}
func testCreateAndRemoveMuteList() throws {
let privkey = "87f313b03f2548e6eaf1c188db47078e08e894252949779b639b28db0891937a"
let pubkey = "4b0c29bf96496130c1253102f6870c0eee05db38a257315858272aa43fd19685"
let to_mute = "2fa2630fea3d2c188c49f2799fcd92f0e9879ea6a36ae60770a5428ed6c19edd"
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: to_mute)!
let new = remove_from_mutelist(keypair: keypair, prev: mutelist, to_remove: to_mute)!
XCTAssertEqual(new.pubkey, pubkey)
XCTAssertEqual(new.content, "")
XCTAssertEqual(new.tags.count, 1)
XCTAssertEqual(new.tags[0][0], "d")
XCTAssertEqual(new.tags[0][1], "mute")
}
func testAddToExistingMutelist() throws {
let privkey = "87f313b03f2548e6eaf1c188db47078e08e894252949779b639b28db0891937a"
let pubkey = "4b0c29bf96496130c1253102f6870c0eee05db38a257315858272aa43fd19685"
let to_mute = "2fa2630fea3d2c188c49f2799fcd92f0e9879ea6a36ae60770a5428ed6c19edd"
let to_mute_2 = "976b4ab41f8634119b4f21f57ef5836a4bef65d0bf72c7ced67b8b170ba4a38d"
let keypair = FullKeypair(pubkey: pubkey, privkey: privkey)
let mutelist = create_or_update_mutelist(keypair: keypair, mprev: nil, to_add: to_mute)!
let new = create_or_update_mutelist(keypair: keypair, mprev: mutelist, to_add: to_mute_2)!
XCTAssertEqual(new.pubkey, pubkey)
XCTAssertEqual(new.content, "")
XCTAssertEqual(new.tags.count, 3)
XCTAssertEqual(new.tags[0][0], "d")
XCTAssertEqual(new.tags[0][1], "mute")
XCTAssertEqual(new.tags[1][0], "p")
XCTAssertEqual(new.tags[1][1], to_mute)
XCTAssertEqual(new.tags[2][0], "p")
XCTAssertEqual(new.tags[2][1], to_mute_2)
}
}
-28
View File
@@ -105,14 +105,6 @@ class damusTests: XCTestCase {
XCTAssertEqual(parsed[1].is_text, " br")
}
func testNoParseUrlWithOnlyWhitespace() {
let testString = "https:// "
let parsed = parse_mentions(content: testString, tags: [])
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed[0].is_text, testString)
}
func testParseMentionBlank() {
let parsed = parse_mentions(content: "", tags: [["e", "event_id"]])
@@ -145,26 +137,6 @@ class damusTests: XCTestCase {
XCTAssertEqual(parsed[2].is_text, " derp")
}
func testHashtagWithComma() {
let parsed = parse_mentions(content: "some hashtag #bitcoin, cool", tags: [])
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "some hashtag ")
XCTAssertEqual(parsed[1].is_hashtag, "bitcoin")
XCTAssertEqual(parsed[2].is_text, ", cool")
}
func testHashtagWithEmoji() {
let parsed = parse_mentions(content: "some hashtag #bitcoin☕️ cool", tags: [])
XCTAssertNotNil(parsed)
XCTAssertEqual(parsed.count, 3)
XCTAssertEqual(parsed[0].is_text, "some hashtag ")
XCTAssertEqual(parsed[1].is_hashtag, "bitcoin")
XCTAssertEqual(parsed[2].is_text, "☕️ cool")
}
func testParseHashtagEnd() {
let parsed = parse_mentions(content: "some hashtag #bitcoin", tags: [])
+4 -1
View File
@@ -7,4 +7,7 @@ git:
translation_files_expression: damus Localizations/<lang>.xcloc/Localized Contents/<lang>.xliff
settings:
pr_branch_name: transifex/<br_unique_id>
pr_branch_name: transifex/<br_unique_id>
language_mapping:
en_US: en-US
es_419: es-419