planetary-social / nos Goto Github PK
View Code? Open in Web Editor NEWnos.social social media for all of us, using nostr
Home Page: https://nos.social
License: Mozilla Public License 2.0
nos.social social media for all of us, using nostr
Home Page: https://nos.social
License: Mozilla Public License 2.0
Right now the home feed shows root posts and replies. Let's change it so that it only shows root posts.
Right now we are storing private keys in NSUserDefaults where they are not encrypted at rest. We need to store and load these from the system keychain instead. To do this we need to update the SettingsView and NewPostView to use some kind of KeyStorage
actor instead of AppStorage
. This may be a good place to introduce the Dependencies library which would allow us to mock such storage for testing and SwiftUI previews.
In general we need to clean up our styles and colors to match Figma for somewhat consistent branding before we go to TestFlight.
Let's add a share button to the ProfileView and allow the user to copy the NIP-19 npub version of user's public key, similar to how Planetary does it.
Let's put a button on the Settings screen that only shows up on debug builds that writes some sample data into the app that we can use for testing and demoing.
Let's allow the user to edit their name, bio, avatar URL, and personal website as it looks in this Figma. Don't work about the NIP-05 or UNS fields for now.
We are going to have a few onboarding screens that we show to new users, much like we do in Planetary. (you can simulate onboarding in Planetary by going to side menu -> Settings -> Advanced -> Debug menu -> Logout and Onboard). We don't know exactly what the content will be, but we can go ahead and write the logic to:
Currently we just publish events to all relays. Sometimes an event fails to post to one or more relays due to communication issues or because the user closed the app. Let's create a new one-to-many relationship between Events and Relays in Core Data, call it publishedOn
. Then when we publish an event to the relay service it can keep track of which relays we have successfully published to using this relationship, and continue retrying periodically until we successfully post the event to all relays.
Nostr identities at their core are public private keypairs. Profile data like usernames and profile photos are published in kind: 0
events as described in NIP-01. We parse this data and store it in the Author model when we see these events, but we are only fetching the most recent events from relays and often the kind: 0
events are not included.
We need to notice when we are displaying a post from a user we don't have profile data from. When this happens we should ask the RelayService
to fetch it, store it in Core Data, and update our views with the new info.
Currently if you unfollow someone in a client other than Nos, Nos won't pick it up. We create new Follow objects in EventProcessor, but we don't have any logic to delete old ones.
Right now we only support importing hex encoded private keys in settings. Let's display the user's private key in nsec
format instead of hex, and update our code and the text field placeholder to include nsec
format keys.
Currently the ProfileView only displays any posts and metadata we happen to have cached for a particular user. Let's update it so that when the profile view is shown it requests the latest events and metadata for the given user from the relays. When the profile view goes away it should close these subscriptions.
We allow users to remove relays on the RelayView. Let's make sure we close all open connections to a relay as soon as the user deletes it.
We just show a placeholder image for now.
When a note is too long it gets truncated and a "READ MORE" button is displayed. After clicking the button, the whole note should be displayed.
Right now the home feed doesn't show the CurrentUser's notes unless they follow themselves. Let's fix this so we see our own posts always.
Let's build a discover screen modeled off the one in Planetary. It should use the same card style, but for the layout let's implement the staggered grid described in this video. For the data to be shown, for now let's just show the most recent events from all relays. Don't worry about the search bar for now.
Let's add the ellipsis button back to NoteCard and allow the user to copy the NIP-19 note ID of a note, similar to how Planetary allows you to copy the ID of a message in MessageCard.
On the settings screen we warn users that their private key is stored unencrypted on the disk. This is no longer the case now. Let's replace the message with one that tells the user never to share their private key with anyone.
We should display linked images in a gallery that we display at the bottom of a notecard. We can look at Planetary for an example UI, but the code under the hood should used CachedAsyncImage
like we do for profile pics.
Note that there are two sets of UI for this: they look one way on the Home and Thread view and another on the Discover tab (I believe these are called .compact and .golden styles in the NoteCard code)
Right now the main tabs are nested inside two navigation bars: the one in AppView, and the one in their own view (HomeFeedView, DiscoverView, etc.). Let's fix this because it prevents the main tabs from adding items to the outer navigation bar. I'm not sure what the best way to restructure things is. Maybe when an item is tapped in the side menu we can just present it modally for now.
Nostr kind: 1 notes can mention other users using "p" tags. The content
part of the note contains the index of the p tag (i.e. #[0]
) instead of the name of the user who was mentioned. Let's render these mentions as the user's name instead of just showing the placeholder. We may also need to fetch metadata for the mentioned user if we don't have their name.
https://iris.to/post/note1wkn0tyrgajwun9zk3kte0qtdgslf0a3a093hkevwwr6maf5jc95qzx9772
{
"content": "#[0] I just did some follow list pruning in gossip and pushed my new contact list to relays. Is there any way to force Iris to pull it down?",
"created_at": 1677098082,
"id": "75a6f59068ec9dc994568d9797816d443e97f63d79637b658e70f5bea692c168",
"kind": 1,
"pubkey": "d0a1ffb8761b974cec4a3be8cbcb2e96a7090dcf465ffeac839aa4ca20c9a59e",
"sig": "e57b613584d7f0ddecbd7faf9aa4a0dc2505a41a2620ad1abbf01ab97b5f7ecae1a0839f56d65a1225ff52caffe876dfd2336c9c399afee1914dc83edb4c177f",
"tags": [
[
"p",
"4523be58d395b1b196a9b8c82b038b6895cb02b683d0c253a955068dba1facd0",
"",
"mention"
]
]
}
We need a relay we can test with. Mine filled up with spam.
Let's populate the number of replies on our NoteCard views and show the avatars of repliers. It should look the same as it does in Planetary:
The code to do this in Planetary is in MessageCard.swift
and looks like this:
HStack {
StackedAvatarsView(avatars: replies, size: 20, border: 0)
if let replies = attributedReplies {
Text(replies)
.font(.subheadline)
.foregroundColor(Color.secondaryTxt)
}
Spacer()
Image.buttonReply
}
.padding(15)
}
To calculate the number of replies I think we'll need to start parsing the #e
tags on events as defined in NIP-01 and create a new relationship between events in Core Data.
We should add Generated.strings and potentially our ExportString.sh script from Planetary. Then we need to set up integration with the Nos Crowdin project
Let's build a Follow button for profile pages that looks like Planetary's RelationshipButton
and wire it up to our data model. When following or unfollowing someone we also need to publish a new contact list/kind: 3 event that adds or removes the profile we just followed or unfollowed.
If the HomeFeedView is initialized with a nil user, the default Event.fetchRequest()
runs and the app crashes with Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of NSFetchedResultsController requires a fetch request with sort descriptors'
.
Steps to reproduce:
We should fix this by replacing the current default fetch request with Event.emptyRequest()
(modeled after Follow.emptyRequest()
)
Right now we show all replies in a flat list. Let's support nested replies so that discussions can take several branches as seen in this Figma. Basically we can use the same logic we use to display the reply count and push the ThreadView from the HomeFeedView, and apply it to the notes displayed in the ThreadView as well.
We need to verify the Schnorr signature of all Nostr events we download according to NIP-1. This prevents malicious users and relays from impersonating other users. Any events whose signature cannot be verified should be discarded.
We want users of Nostr and the Universal Name System to be able to display their Universal Name on their profile page in Nos. This will mostly be done via NIP-05, including the extension proposed here.
Acceptance criteria:
Nostr clients publish the list of accounts they are following in a kind: 3
event. The format of these events is documented in NIP-02. We should add a Core Data model (call it Follow?) to hold this information and extend EventProcessor
to parse and save them. This will be a good place to use TDD since the RelayService
doesn't prioritize downloading kind 3 events necessarily, so it might be hard to test in production.
This is a pre-requisite to following other profiles.
Blocked by #3.
Currently the HomeView
displays all the kind: 1
events in Core Data. Let's change it so that it only shows events from people we follow.
Let's copy over the IdentityView
and related classes from the Planetary codebase, and adapt it to display a profile page in Nos. Most of the functionality from Planetary won't apply and can be commented out or deleted.
The items we would like to display for this skeleton version are: name, bio (about), and a feed of events from this author. Let's make this page open when tapping an author's name or profile picture on a NoteCard (this part blocked by #5).
Let's copy over our MessageCard SwiftUI view from Planetary and modify it to display kind: 1
Nostr events. Ignore colors for now because we don't have designs for those yet.
On a fresh install (or first time opening app after force quitting), the app will crash when you try to go to the relay view from the profile view.
Steps to reproduce:
Expected: view changes to Relays view
Actual: App crashes
If the HomeFeedView is initialized with a nil user, the default Event.fetchRequest()
runs and the app crashes with Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of NSFetchedResultsController requires a fetch request with sort descriptors'
.
Steps to reproduce:
We should fix this by replacing the current default fetch request with Event.emptyRequest()
(modeled after Follow.emptyRequest()
)
Let's create a new tab that displays a list of notifications when people interact with your notes. Figma.
For this ticket we won't worry about the styling, badges, or push notifications. We also won't support notifications for follows, likes, or reposts yet.
So the initial version should be a list of:
We used to be able to delete relays on the relays page. Now we can't. Let's fix it.
Our layout is wonky and the app crashes when launched on iPad.
Let's fix these issues so that the iPad matches the iPhone layout.
We have a stubbed ThreadView that we show when you tap on a NoteCard from the home feed. Let's build this screen out. We would like to show all the replies to an event in NoteCards below the root note on this screen. This will require us to change our Core Data model to better represent "e" tags so we can query for all the replies to an event.
Right now all our main views (Home feed, relays, settings) are presented in a single NavigationStack
. Let's move the Home Feed and Relays into a standard tab bar component, and put the Settings in a side menu that opens from a little profile avatar in the top left of the HomeView and RelayView, just like Planetary. Don't worry about icons or styling for now.
The Planetary side menu and tab bar are built using UIKit, but we'll want to do these in SwiftUI in Nos so there won't be much code that we can copy. But there is a standard SwiftUI tab bar that we can use, and there is probably a lot of example code for a side/hamburger style menu out on the internet we could use. (Planetary's side menu doesn't open if you swipe from the left side of the screen, it would be great if we could support this in Nos, but let's not spend too much time on it).
Let's add a search bar to the discover tab that users can use to look up other users. It won't do full text search (yet), but it should accept npub format public keys and open the profile page for the user when "Enter" is tapped on the keyboard. The placeholder text should be "Find a user by ID".
Note: right now we don't request any data from relays when showing the profile view, but that will be done in #66.
The Universal Name System provides an API that we can use to prove that the same person owns a given Universal Name and Nostr keypair. We want to support UNS users who want to verify their Nostr keys. The full flow likely involves some UI, some URL schemes and redirects to bounce the user between Nos and the UNS website.
I think the core communication with the UNS API looks something like this:
verification_id
and message
message
(does message include a kind? or just content?) and sign it with your Nostr private key.verification_id
and your pub_key
.@mplorentz has the secrets needed to access the UNS API
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.