Giter VIP home page Giter VIP logo

fritter's Introduction

Fritter

An example application that demonstrates how to build peer-to-peer Web applications with Beaker Browser, Dat, and WebDB.

Fritter demo

Features

Fritter is a simple social feed application; it implements:

  • Writing posts
  • Replying to posts
  • Favoriting posts and replies
  • Following users
  • Editing your profile

Fritter uses libfritter to manage its data definitions and methods. Check it out to see a well-documented example of using WebDB.

What is a peer-to-peer Web app?

The peer-to-peer (p2p) Web is a loose term for describing the community of websites and applications that are built on top of p2p protocols like dat://.

A p2p Web app is like any other website or app: it's a collection of HTML, CSS, JavaScript, and other files. What makes it different? It uses a p2p protocol (in this case dat://) instead of HTTP. Most p2p websites and apps are not supported in mainstream browsers like Firefox or Chrome, but you can use Beaker to access websites that use the dat:// protocol.

How Fritter works

User profiles

User profiles on the p2p Web are a bit different than user profiles on the traditional Web. Instead of being stored in a server-side database, they're simply websites! This means you can look at all the files that comprise a profile. Check out Dog Legs McBoots's profile to see for yourself:

dat://232ac2ce8ad4ed80bd1b6de4cbea7d7b0cad1441fa62312c57a6088394717e41

profile.json contains some basic information about the profile:

{
  "name": "Dog legs McBoot",
  "bio": "A good boy",
  "avatar": "avatar.png",
  "follows": []
}

Posts are stored as individual files in the /posts directory. Each file is addressed by its base36-encoded timestamp. Votes/likes/favorites are recorded in the /votes directory using the same technique.

/posts
|-- 0jbdviucy.json
|-- 0jbdvkv1r.json
|-- 0jbdvsjo9.json

A post includes the content of the post, a timestamp, and if applicable, information about the post it's in reply to:

{
  "text": "hi",
  "threadRoot": "dat://232ac2ce8ad4ed80bd1b6de4cbea7d7b0cad1441fa62312c57a6088394717e41/posts/0jbdvsjo9.json",
  "threadParent": "dat://232ac2ce8ad4ed80bd1b6de4cbea7d7b0cad1441fa62312c57a6088394717e41/posts/0jbdvsjo9.json",
  "createdAt":1513703188329
}

Storing user profiles

Fritter uses Beaker's DatArchive APIs to access the Dat network. This makes it possible to store profiles locally on the user's computer, and to transfer profile information directly between user devices.

Fritter keeps track of the URL for the user's profile with Local Storage under the key userUrl. In a more robust implementation of an app like Fritter, users could switch between their profiles by being prompted to select a profile using Beaker's DatArchive.selectArchive() method, and then updating the value of localStorage.userUrl.

Getting started

Try Fritter

Visit Fritter in Beaker to create your own profile:

dat://9900f9aad4d6e79e0beb1c46333852b99829e4dfcdfa9b690eeeab3c367c1b9a

Keep in mind that Fritter is an example application and is missing some features like notifications and search that would make it a viable social media application.

Customizing Fritter

On the p2p Web, user profiles are simply websites that are formatted so they can be used by many different applications. This makes it possible to customize websites and apps without needing to create a new profile!

For example, to use a custom theme on Fritter, you could fork Fritter using Beaker, then update Fritter's CSS as much or as little as you'd like. Alternatively, you can clone this repository, implement your changes, then deploy your custom version of Fritter onto the Dat network using Beaker or the Dat CLI.

Questions or concerns?

fritter's People

Contributors

brechtcs avatar dkunin avatar hypercubed avatar kevinmarks avatar pfrazee avatar safrmo avatar taravancil avatar webdesserts 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  avatar

Watchers

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

fritter's Issues

Pixel-tracking issue

Allowing image embeds from HTTP/S makes it possible to pixel-track users. Arguably it does for dat:// sites too.

The most paranoid policy would be to only render images from dats that you're following.

We should decide how we want to approach this.

Exception in notifications view

I had 2 unread notifications. When I opened it:

Uncaught (in promise) TypeError: Cannot read property 'getRecordURL' of null
    at FritterApp.threadUrl (dat://fritter.hashbase.io/assets/index.js:1767:29)
    at renderNotification (dat://fritter.hashbase.io/assets/index.js:608:31)
    at Array.map (native)
    at renderFeed (dat://fritter.hashbase.io/assets/index.js:584:27)
    at module.exports (dat://fritter.hashbase.io/assets/index.js:25785:11)
    at renderView (dat://fritter.hashbase.io/assets/index.js:25677:14)
    at Object.render (dat://fritter.hashbase.io/assets/index.js:25643:11)
    at FritterApp.render (dat://fritter.hashbase.io/assets/index.js:1439:11)
    at FritterApp.setView (dat://fritter.hashbase.io/assets/index.js:1429:10)
    at <anonymous>

Infinite loop?

When I scroll down I see the same tweets of different users over and over again...

Selective sharing and user blocking?

I realize I may be asking for the sun, moon, and stars here, but it would spectacular if Fritter had the option of selectively sharing content and blocking users. Right now, of course, Fritter has the model that I don't have to follow others but anyone that follows anyone else following me can also find and follow me.

My idea for this is almost certainly either fundamentally flawed or else already under consideration. But I figure I'll share it anyway. Selective sharing and user blocking:

  1. 'Public' Fritter sharing works as it does today.
  2. Fritter accounts generate a short-lived symmetric key for decrypting their selectively shared content.
  3. Fritter accounts publish one message per each permitted follower with that symmetric key encrypted using the follower's public key. Other followers read something in the key-distribution message to indicate it's not meant for them and ignore it. OR the account publishes one giant message that is some kind of delimited string of follower public keys and follower public key encrypted symmetric keys.
  4. Then the account publishes the actual content, and the followers use the symmetric key to decrypt. Anyone can download and anyone can even help distribute the person's content using dat, but without the symmetric key the data is useless.
  5. When a new follower is added, the Fritter account just distributes their symmetric key to new followers. When a follower is removed, the Fritter account generates and distributes a new symmetric key that will be used for all subsequent posts.
  6. When the Fritter account wants to share a message with only a few followers, a new symmetric key is generated and shared with those recipients. Then when the user returns to sharing with their entire set of followers, a new symmetric key is generated and shared again. If you follow someone that publishes a message but has not distributed the new symmetric key to you, your Fritter client ignores the message and you never see it in your "feed".

Thoughts? I mean the ugly side is that a busy account with lots of activity would be generating thousands of tiny messages for key exchanges just to post "OMG the dog just stole a slice of pizza off the table!" But despite the high volume of symmetric key exchange messages the key exchange message size would be tiny.

I ask for this because I think a p2p social network is wonderful, but me and most of the people I know want a p2p Facebook/Instagram, not a p2p Twitter.

Feed fails loading - timestamp function fails

return date.toLocaleDateString()

This fails if the passed date is a number, not a Date. On my end, it occurs when renderFeedItem passes a post's createdAt and if it is a number, preventing the feed from loading.

I'm wondering, was createdAt meant to be a Date? Haven't looked too deeply into Fritter's code yet, but I remember seeing a requirement that createdAt must be a number.

Hard to tell if someone is following you

It would be nice if there was something on a persons fritter profile that indicated whether they followed you. That way it'd be more obvious if they'd be able to see posts from you.

Currently the way to work around this is to go to their "following" list and searching for yourself, which isn't the quickest solution.

Encrypted data storage

For some future features that require entries that are not supposed do be read by others (eg settings, private messages,... ) an encrypted storage would be useful.
I've read about the privacy problem in multiple threads, so i write a new one.

The encryption key itself could be encrypted with the public key of the page/account, so the key can be shared with others if needed (eg for private messages) .

Public Database for Active Users

would it make since for each user to have a hyperdb type database associated with their account, and the keys were all public so that any other client could edit it, then add their public key to the list when they want to become visible. So if the first user is not following the second user, the second user could reply to the first user, then auto add their key to the database so that the first user could see the second user's reply.

Offline users profiles

User profiles on the p2p Web are a bit different than user profiles on the traditional Web. Instead of being stored in a server-side database, they're simply websites! This means you can look at all the files that comprise a profile only if that user is online?how fritter display posts from users which are offline?

"X feeds synced" UX

I'd recommend against the spinner to indicate loading user archives: https://cl.ly/1p02320w0P3r

It gives a nervous sense of awaiting completion.

In my opinion, Dat apps on Beaker will have to make the inability to connect to an infrequently available Dat archive (say, another user one is following) less annoying and feel more acceptable. Occasional synchronization should be completely tolerable in the new P2P era.

Getting notifications meant for others

fritter-notifications

Clicking on 'Notifications' shows me three notifications from Andre Staltz for three different posts by Tim Caswell. I'm currently following Andre but not (yet) Tim, and I haven't interacted with those posts in any before seeing them in my Notifications.

blank page on first visit

Hello! ๐Ÿ‘‹

I'm seeing a blank page on my first visit to dat://fritter.hashbase.io (using Beaker).

Here's the log:

index.js:2075 Rebuilding indexes.
index.js:2093 Database is opened.
index.js:25650 Uncaught (in promise) TypeError: Cannot read property 'url' of null
    at Object.render (index.js:25650)
    at FritterApp.render (index.js:1439)
    at FritterApp.setView (index.js:1374)
    at Function.router.on (index.js:1294)
    at emit (index.js:25200)
    at FritterApp.emit [as router] (index.js:16949)
    at onRouteChange (index.js:1299)
    at FritterApp.setup (index.js:1320)
    at <anonymous>
render @ index.js:25650
render @ index.js:1439
setView @ index.js:1374
router.on @ index.js:1294
emit @ index.js:25200
emit @ index.js:16949
onRouteChange @ index.js:1299
setup @ index.js:1320
index.js:1677 Uncaught (in promise) TypeError: Cannot read property 'followUrls' of null
    at whoToFollowSeedUrls.forEach.url (dat://fritter.hashbase.io/assets/index.js:1677:34)
    at Array.forEach (native)
    at FritterApp.loadWhoToFollow (dat://fritter.hashbase.io/assets/index.js:1676:25)
    at FritterApp.setup (dat://fritter.hashbase.io/assets/index.js:1330:10)
    at <anonymous>
whoToFollowSeedUrls.forEach.url @ index.js:1677
loadWhoToFollow @ index.js:1676
setup @ index.js:1330

Mentions

It'd be very nice if we could mention other users. This will require:

  • A UI element for detecting when the user is mentioning somebody during composition.
  • An update to the post JSON which codifies the mentioned people.
  • Add mentions to the notifications index. (I'm in the process of adding this index now.)

Index friends of friends, but don't show in timline unless following

Fritter is great, but one of the biggest pain points is that it's hard to discover people to follow or that are following you.

Having centralized repositories for discovering people is probably also a bad idea since it would defeat the purpose of being decentralzied and p2p in the first place.

Indexing everyone that signs up is going to be a big load on performance and is probably not a good way forward either.

I propose that when you "follow" a person, that all of the people they're following get indexed too.

The firends-of-friends shouldn't show up in your timeline, but you should still see posts that mention you and should still see their posts in replies to posts on your timeline.

This will make it easy to organically grow your social network through people that you know or that your friends know.

Thus, if a new user joins fritter, if somebody follows, them, they can start interacting with that person's social network and slowly get integrated into it.

In addition, this will make it possible to start indexing who your followers are since it didn't make sense to do it when it would just be a subset of people you follow.

Double post

I replied to a post by Paul while mistakenly having two identically named profiles pointing to the same profile location:
profiles
I'm not sure how this is possible but I'm sure the reason they both existed was because I had recreated my profile in order to test something. Having these two profiles pointing to the same location is the best reason I can come up as to why my one reply turned into two, but it could be something else entirely.

How can you "log in" on another computer?

Really like fritter ๐Ÿ‘ It looks awesome!

I want to log in on another computer, how would I do that? Without somebody else also being able to log in as me.

Wouldn't there need to a password on a private/public key that would allow only me to sign my tweets?

Resolve DNS of viewed users

Right now if you view my profile with the DNS shortname (ie dat://fritter.hashbase.io/user/dat://fritter-pfrazee.hashbase.io) the app will treat the profile you view as different from the raw URL version. To solve that, we need to resolve the URL before indexing it.

When a non-profile is loaded as a profile, there is no way to clear the error.

Repro steps

I created a basic dat webpage with Beaker here: dat://0dcb87b647072fe9b527c3ebe63c1ee5def6660b67c03980f78d1711c722f7c9
Then I navigated to the Fritter instance
And I selected the basic dat webpage
Then I expect the page to load

Instead I see a blank page
and the console has raised the following error

screen shot 2018-04-26 at 9 50 07 am

When this work is complete I expect Fritter to reject invalid profiles and require a user create or update the appropriate fields in their profile page.

Issues creating new users

Sometimes the name gets cleared
Sometimes people create their user and then an exception throws (no is current user)?

License: ok to fork / reuse?

I love this concept, congrats!

Would it be OK to fork this project and try this concept using different p2p libraries? There is no LICENSE, so maybe this is not something the authors would approve? A clarification would be much appreciated.

Thanks

Santi

Replace the cache-busting query param on avatars

I created a new profile and followed a lot of people. Things stopped making progress, but not because of the CPU or network load -- it looked like the page's network request queue had gotten jammed up very badly by avatar image requests.

We currently have a ?cache=${Date.now()} on avatar images to make sure you always get the latest avatar. That causes each avatar request to be treated as a separate request, and that's why the network queue got clogged.

We'll need to replace the cache-buster with something a little smarter. It should only be needed after you update your profile pic.

Add dat-polyfill

Fritter is a great application for showing off the power of the P2P web.

That's why I think it would be a great starting point to get people onboarded from the regular web.

I've managed to get fritter to work on the web using dat-polyfill. From the look of it, pretty much everything is working.

  • Creating new accounts
  • Following users
  • Viewing images / clicking links

Would you be open to having the dat-polyfill added into the main fritter repo? With that in place, people can view content from fritter on their phones, or on their desktops without having to install Beaker.

My goal with this is to give people a taste of what it's like and to make the technology more accessible. Ideally, people using the polyfill version of fritter should have something popping up prompting them to install Beaker (or Bunsen once that's out on mobile), along with a description of why it'd be better (privacy, offline-first, etc).

Some of the limitations of I can thing of when using this approach:

  • Gateways can discover which dats a user is accessing, so users should be aware that they might have their dat URLs seen by third parties (my gateway doesn't track any of this, but it's a technical limitation)
  • Currently there's just my gateway that's up which has this websocket sync thing, and it doesn't have TLS support yet.
    • I'll need to figure out getting letsencrypt wildcard certs up, or you'll need to set up a different one elsewhere. Maybe a reason for adding WS support to Hashbase
  • My gateway doesn't support the 404 fallback yet so URLs on fritter won't work on it after refreshing
    • This won't matter too much since people will be accessing it through the hashbase version of fritter which works properly
  • I don't have the versions of dat-polyfill or dat-archive-web that work tagged yet, but that'll be done soon.

New user experience: empty feed, nobody to follow

i was just next to @feross when he made a fritter account

it starts out with an empty page and nobody to follow. i sent my fritter profile URL out of band, and as soon as he followed that, he got sidebar suggestions

proposal: add yourselves to Who To Follow, if no others are available

@pfrazee @taravancil

it would be kind of like MySpace Tom, except there's two of you and the user still has to click Follow first!

i think this would make new users less likely to get stuck and give up.

once they follow one of you, they'll get a bunch of sidebar suggestions. even if they don't do that, they can still click on your profile URLs and explore from there

Emoticons and photos

It would be great if we can insert emoticons and upload photos into the post like on twitter.

reply visibility

#20 (comment)

didn't account for replies to people you don't follow. Added to the TODO list!

dat://fritter.hashbase.io/thread/dat://6348fac3c70e916885ead7dce6927f01e02c0efd1a9273849891c23b7e7bac4d/posts/0jcgk0s2p.json

what you'll see if you don't follow the source

dat://fritter.hashbase.io/thread/dat://6e96b27838c76991ac3563f729beb7c6e6c362fe369793784cd1c729b2b37299/posts/0jcgjwrvg.json

example

I cannot follow other people + Questions

Hi
I have several questions about how Fritter work. But I will start this issue by explaining my problem.

I am on Fritter as HackerNight, I don't see any post. Does nobody post things on Fritter? I only see one user called "Tara Vancil" This when I click on the user or on Follow something loads but never finish loading. Is it normal? I beleive not but can you explain me how it works. I don't understand how the "fritter.hashbase.io" knows my archive profile hosted on dat.

The other thing I wanted to know is that, how does it works, what is the connection between my archive profile hosted on my computer and your fritter.hashbase.io main website. I never needed to input my user URL. How can you know what is it.

The third question is, is this repository always active or is it discontinued, the last open issue is from 2018 and the last commit has been made in november 2018.

Thanks in advance to any users or collaborators who could answer this issue.

Have a nice day!

Fritter hangs trying to connect to self

I'm not sure if this is a Fritter issue, a broader Beaker Browser bug, or a Beaker Browser on Linux bug. I opened firewall port 3282 on my firewall and on the VM running Beaker Browser and had the firewall redirect incoming traffic to 192.168.1.19 (the IP of the VM) so that anything I post on Fritter is available through dat to the world. But now when I open any link inside Fritter, the content never loads and my debug log is filled with these messages:

error (0ms) id=754371 type=tcp host=::ffff:192.168.1.19:3282 error=Error: Remote sent invalid feed message
closing connection (2ms) id=754371 type=tcp host=::ffff:192.168.1.19:3282
closing connection (5002ms) id=754363 type=utp host=0.0.0.0:3282
error (7505ms) id=754358 type=tcp host=::ffff:192.168.1.19:3282 error=Error: Remote timed out
closing connection (7507ms) id=754358 type=tcp host=::ffff:192.168.1.19:3282
and then it starts over
error (4ms) id=754372 type=tcp host=::ffff:192.168.1.19:3282 error=Error: Remote sent invalid feed message

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.