/ README.md
README.md
1 <div align="center"> 2 <img src="public/logo-192.png" width="128" height="128" alt=""> 3 4 Agora 5 === 6 7 **Follow your interests across social networks!** 8 </div> 9 10 11 12 ## Features 13 - You can log in to a Mastodon, Bluesky, or Nostr account on Agora and it'll pull in your following/followers list from that account, while still allowing you to view/interact with posts from the other 2 protocols using bridges behind the scenes. 14 - Intelligently loads your instance's version of a post so that you can like/boost/comment on it without having to think about what instance it's on. 15 - I've integrated those bridges into the search, so that if you search for a Bluesky handle like [aoc.bsky.social](https://agorasocial.app/#/fosstodon.org/a/111133786401697678) or a nostr users hex code like [Jack Dorsey's](https://agorasocial.app/#/fosstodon.org/a/109934331230225572), and it'll automatically know to use the bridges for those protocols and search for the bridged profile. You can even search for [elonmusk@twitter.com](https://agorasocial.app/#/fosstodon.org/a/109418526633386531) and it'll treat Twitter like another instance, and load up the bridged version of the account! 16 - When you follow a hashtag like #linux, it'll automatically follow the corresponding [Lemmy community](https://agorasocial.app/#/fosstodon.org/a/107294672647205675) for that topic in your feed. 17 - 👪 Multiple accounts 18 - 🪟 Compose window pop-out/in 19 - 🌗 Light/dark/auto theme 20 - 🔔 Grouped notifications 21 - 🪺 Nested comments thread 22 - 📬 Unsent draft recovery 23 - 🎠 Boosts Carousel™️ 24 - #️⃣ Multi-hashtag timeline 25 26 ## Subtle UI implementations 27 28 ### User name display 29 30  31 32 - On the timeline, the user name is displayed as `[NAME] @[username]`. 33 - For the `@[username]`, always exclude the instance domain name. 34 - If the `[NAME]` *looks the same* as the `@[username]`, then the `@[username]` is excluded as well. 35 36 ### Boosts Carousel 37 38  39 40 - From the fetched posts (e.g. 20 posts per fetch), if number of boosts are more than quarter of total posts or more than 3 consecutive boosts, boosts carousel UI will be triggered. 41 - If number of boosts are more than 3 quarters of total posts, boosts carousel UI will be slotted at the end of total posts fetched (per "page"). 42 - Else, boosts carousel UI will be slotted in between the posts. 43 44 ### Thread number badge (e.g. Thread 1/X) 45 46  47 48 - Check every post for `inReplyToId` from cache or additional API requests, until the root post is found. 49 - If root post is found, badge will show the index number of the post in the thread. 50 - Limit up to 3 API requests as the root post may be very old or the thread is super long. 51 - If index number couldn't be found, badge will fallback to showing `Thread` without the number. 52 53 ### Hashtag stuffing collapsing 54 55  56 57 - First paragraph of post content with more than 3 hashtags will be collapsed to max 3 lines. 58 - Subsequent paragraphs after first paragraph with more than 3 hashtags will be collapsed to 1 line. 59 - Adjacent paragraphs with more than 1 hashtag after collapsed paragraphs will be collapsed to 1 line. 60 - If there are text around or between the hashtags, they will not be collapsed. 61 - Collapsed hashtags will be appended with `...` at the end. 62 - They are also slightly faded out to reduce visual noise. 63 - Opening the post view will reveal the hashtags uncollapsed. 64 65 ### Filtered posts 66 67 - "Hide completely"-filtered posts will be hidden, with no UI to reveal it. 68 - "Hide with a warning"-filtered posts will be partially hidden, showing the filter name and author name. 69 - Content can be partially revealed by hovering over the post, with tooltip showing the post text. 70 - Clicking it will open the Post page. 71 - Long-pressing or right-clicking it will "peek" the post with a bottom sheet UI. 72 - On boosts carousel, they are sorted to the end of the carousel. 73 74 ## Development 75 76 Prerequisites: Node.js 18+ 77 78 - `npm install` - Install dependencies 79 - `npm run dev` - Start development server 80 - `npm run build` - Build for production 81 - `npm run preview` - Preview the production build 82 - `npm run fetch-instances` - Fetch instances list from [instances.social](https://instances.social/), save it to `src/data/instances.json` 83 - requires `.env.dev` file with `INSTANCES_SOCIAL_SECRET_TOKEN` variable set 84 - `npm run sourcemap` - Run `source-map-explorer` on the production build 85 86 ## Self-hosting 87 88 This is a **pure static web app**. You can host it anywhere you want. Build it by running `npm run build` (after `npm install`) and serve the `dist` folder. 89 90 I personally use Vercel to host Agora. 91 92 ## Tech stack 93 94 - [Vite](https://vitejs.dev/) - Build tool 95 - [Preact](https://preactjs.com/) - UI library 96 - [Valtio](https://valtio.pmnd.rs/) - State management 97 - [React Router](https://reactrouter.com/) - Routing 98 - [masto.js](https://github.com/neet/masto.js/) - Mastodon API client 99 - [Iconify](https://iconify.design/) - Icon library 100 - [MingCute icons](https://www.mingcute.com/) 101 - Vanilla CSS - *Yes, I'm old school.* 102 103 Some of these may change in the future. The front-end world is ever-changing. 104 105 ## Alternative web clients 106 107 - [Pinafore](https://pinafore.social/) ([retired](https://nolanlawson.com/2023/01/09/retiring-pinafore/)) - forks ↓ 108 - [Semaphore](https://semaphore.social/) 109 - [Enafore](https://enafore.social/) 110 - [Cuckoo+](https://www.cuckoo.social/) 111 - [Sengi](https://nicolasconstant.github.io/sengi/) 112 - [Soapbox](https://fe.soapbox.pub/) 113 - [Elk](https://elk.zone/) - forks ↓ 114 - [elk.fedified.com](https://elk.fedified.com/) 115 - [Mastodeck](https://mastodeck.com/) 116 - [Trunks](https://trunks.social/) 117 - [Tooty](https://github.com/n1k0/tooty) 118 - [Litterbox](https://litterbox.koyu.space/) 119 - [Statuzer](https://statuzer.com/) 120 - [Tusked](https://tusked.app/) 121 - [More...](https://github.com/hueyy/awesome-mastodon/#clients) 122 123 ## 💁♂️ Notice to all other social media client developers 124 125 Please, please copy the UI ideas and experiments from this app. I think some of them are pretty good and it would be great if more apps have them. 126 127 If you're not a developer, please tell your favourite social media client developers about this app and ask them to copy the UI ideas and experiments. 128 129 ## License 130 131 [MIT](https://cheeaun.mit-license.org/).