Giter Club home page Giter Club logo

nos's People

Contributors

boreq avatar cascadiagames avatar cjorgensen avatar dcadenas avatar jcswift23 avatar joshuatbrown avatar kroese avatar maddiebaka avatar martindsq avatar mplorentz avatar rabble avatar shanecb avatar tyiu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

nos's Issues

Render replies in ThreadView

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.

Render profile pictures

We are parsing and storing the profilePhotoURL on our Author model. Let's use SwiftUI's AsyncImage to display these profile photos in our NoteCard views (blocked by #5).

Note: you may not see many profilePhotoURLs in the app db until we do #6. But we can mock them and test them in SwiftUI previews.

Add a button to write sample data to db

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.

Move key storage into keychain

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.

Build skeleton profile UI

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).

Verify event signatures in EventProcessor

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.

Disconnect from relays we remove

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.

Build a skeleton onboarding flow

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:

  • detect if this is the app's first launch (if there is no private key in storage)
  • generate a new private key, or support the user pasting one in
  • show a series of screens that the user can click next to navigate through
  • Dismiss and show the home view at the end.

Create a Notifications tab

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:

  • notes that mention you
  • notes that are replies to your notes

Image

Apply new colors

In general we need to clean up our styles and colors to match Figma for somewhat consistent branding before we go to TestFlight.

Add a reply view to threads

At the bottom of our thread view let's show a text box that allows a user to reply to the root message of the thread. We can model this UI off Planetary. The UI will be different but the code to publish an event can be copied from the NewPostView.

Build follow button + functionality

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.

Calculate reply count and display in NoteCard

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:

Image

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.

Show our own posts on the home feed

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.

Add search bar for looking up npubs

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 empty home feed message overlaps pushed views

Steps to reproduce:

  1. Do a fresh installation of Nos
  2. Open the side menu
  3. tap "Your profile"
    Expected: only the message about no events being shown for the profile is displayed.
    Actual: The empty home feed message is also displayed.

Image

Add button to copy note ID on NoteCard

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.

Display Universal Names via NIP-05

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:

  • When editing my profile in Nos there is a field where I can enter my UNS name.
  • When editing my profile in Nos there is a link I can tap to learn more about UNS near the UNS name field.
  • When viewing my profile in Nos after setting my UNS name, my name is displayed on my profile like [email protected].
  • When I tap on a user's UNS name on a profile page in Nos I am redirected to their UNS profile page. If my name is [email protected] then I am redirected to matt.universalname.space (exact URL TBD).

Better support for nested replies

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.

Create EditProfile screen

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.

App crash when switching from profile view to relay view

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.

Screen.Recording.2023-02-27.at.1.52.51.PM.mov

Steps to reproduce:

  1. Do a fresh install of Nos (or force quit and reopen app)
  2. Open side menu
  3. Tap "Your profile"
  4. Tap "Relays" in the tab bar

Expected: view changes to Relays view
Actual: App crashes

Fix double navigation bar

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.

Render user mentions in NoteCard

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.

Example

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"
    ]
  ]
}

App crashes when HomeFeedView initialized with nil user

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:

  1. go to settings
  2. delete private key
  3. tap back arrow
    Expected: app transitions back to HomeFeedView with no issues
    Actual: app crashes

We should fix this by replacing the current default fetch request with Event.emptyRequest() (modeled after Follow.emptyRequest())

Ask relays for all posts from a user when we open the ProfileView

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.

App crashes when HomeFeedView initialized with nil user

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:

  1. go to settings
  2. delete private key
  3. tap back arrow
    Expected: app transitions back to HomeFeedView with no issues
    Actual: app crashes

We should fix this by replacing the current default fetch request with Event.emptyRequest() (modeled after Follow.emptyRequest())

Parse and store contact list

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.

Download profile info for all displayed authors

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.

Support unfollows from other clients

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.

Build a discover screen

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.

Allow users to verify their ownership of a Nostr pubkey with the UNS API

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:

  • authenticate user with UNS?
  • call /v1/resolver/social_connection to get verification_id and message
  • Create a nostr event with message (does message include a kind? or just content?) and sign it with your Nostr private key.
  • Maybe publish the event to relays?
  • Call /v1/resolver/social_connections/nostr/signature and pass it the signature of the event, and the verification_id and your pub_key.
  • UNS verifies that the message was signed correctly

@mplorentz has the secrets needed to access the UNS API

Retry sending events to relays

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.

Nos crashes on iPad

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.

Set up side menu + tab bar

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).

Render images in NoteCards

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.