aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-05 00:19:49 -0700
committerAdam Soltys <[email protected]>2026-10-05 00:19:49 -0700
commit609e5d77e7634eb2973b73a677c08f9f2b695951 (patch)
tree0e873a22948a0bf6c9bc304e8bea5669522a9606 /src
parent1a2a31365a09a9a5cbd4a43fac6481f3c2f57d72 (diff)
downloadcoinosv3-609e5d77e7634eb2973b73a677c08f9f2b695951.tar.gz
coinosv3-609e5d77e7634eb2973b73a677c08f9f2b695951.zip
Show cached communities immediately and simplify discovery
Diffstat (limited to 'src')
-rw-r--r--src/community-directory.json282
-rw-r--r--src/features/messages.js67
-rw-r--r--src/i18n.js2
3 files changed, 323 insertions, 28 deletions
diff --git a/src/community-directory.json b/src/community-directory.json
new file mode 100644
index 0000000..3d90f02
--- /dev/null
+++ b/src/community-directory.json
@@ -0,0 +1,282 @@
+[
+ {
+ "name": "Vector Community",
+ "description": "The Official Vector Privacy Community",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygrp0t08a8c422vhs7tg5mms8wjtawqrmurtxpvhxt6p6dm3a4hwtspsgqqqsg2s38pkw7#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbRw_Cn34fgsEYkvqGqu_LiY",
+ "member_count": 268
+ },
+ {
+ "name": "FOSS Apps",
+ "description": "Talk about your favorite FOSS Apps",
+ "category": "Privacy & Security",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygq6s5n5w8hvu4nncyly8jus4cv2rjd9c8mjcjxjcp3dh0zptjtcz5psgqqqsg2s6jmpkn#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbTaSCPrS_jGZlZozTNd5iIM",
+ "member_count": 83
+ },
+ {
+ "name": "Nostr Talk",
+ "description": "Nostr Community on Vector",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqyg9g7qululdtdsut52mv9ksgwj6zrv0k0smqchkzwtl09rc2s4wl0cpsgqqqsg2sahulk5#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbdxrjLZ21pC33OLWqd1FVl0",
+ "member_count": 73
+ },
+ {
+ "name": "Monero Community",
+ "description": "Monero Community on Vector",
+ "category": "Bitcoin & Crypto",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygr75m3mrzs0xfmsjkhkwa00svs272unprp2mz3ysjtnnnvxvygvwypsgqqqsg2sv666ef#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbSeQqxFnUQWdc6fw1Y6nib4",
+ "member_count": 66
+ },
+ {
+ "name": "0xPrivacy Community",
+ "description": "Breaking the digital cage, one guide at a time. \n#Monero • #TOR • #Nostr • #IPFS #mirrors\n\nhttps://linkfork.io/0xprivacy",
+ "category": "Privacy & Security",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygxel95damgkg9220up8p7xvj7uadh9pjp4c4vmx2nwrqgdf922ll5psgqqqsg2sueyzt7#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbTvwaMUcU_AGMnDxCXiYOnQ",
+ "member_count": 61
+ },
+ {
+ "name": "Bitcoin Community",
+ "description": "We are all Satoshi, except Craig Wright.",
+ "category": "Bitcoin & Crypto",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqyg843mgn60k47mgfk2lr3wtf06l5nt48ptszmu652zxnzjcede4epcpsgqqqsg2sxl92nz#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbSpQgbd1r25mUXY3o4dPaRY",
+ "member_count": 40
+ },
+ {
+ "name": "PIVX Community",
+ "description": "The Official PIVX Community on Vector",
+ "category": "Bitcoin & Crypto",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygrul6nvrcf56l5ufqq9vqkrcpajgp6xcseyqmwpltjgh8hfkh498gpsgqqqsg2sys4p52#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbUDwW71f6gB_MpbDP_vSYA8",
+ "member_count": 30
+ },
+ {
+ "name": "Movies & Shows",
+ "description": "A chat about movies & shows you love or hate",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygp95jafl95d2a3p9vdg0lwxlrkf0yqfnfxrpz9hcdq8ff6vea38mupsgqqqsg2shlm80j#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbRVod9h7AsPSPyREnZdkxW4",
+ "member_count": 28
+ },
+ {
+ "name": "Massive Music Group",
+ "description": "Your Home For Music",
+ "category": "Music",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqyg9v30lq49skxq7phwrs5zz0pfdw8kz8zqyqq33yxldl9sh5w4spd5psgqqqsg2s0pfdym#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvba4IDbyQoIlEO8OsEE41D0w",
+ "member_count": 26
+ },
+ {
+ "name": "ᘔᗩᗰᖇOᑕK ᖇᗩᗪIO",
+ "description": "100+ countries tuned in. Zero corporate bullshit. We broadcast psychedelic, afro-beat, surf & funk. Open-source, self-hosted, and unowned. ZamRock.net 📡",
+ "category": "Music",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqyg8pp9hm5tumdwz2u6dzplarspr5szqyp2a84jw79ck20m5rug67uqpsgqqqsg2smmn3mf#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbWu-qRb2VLnrnDxNO2anxtE",
+ "member_count": 23
+ },
+ {
+ "name": "Nostr Music Share",
+ "description": "Nostr music, nostr links or nevents only",
+ "category": "Music",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygrhvjedv5xznnmktkgyeaajull8fehvd6kytj533ez8jy56dcka5upsgqqqsg2suwp4yn#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbXm9exm8vfI0K88v5v68fAM",
+ "member_count": 20
+ },
+ {
+ "name": "Web-XDC Game Dev",
+ "description": "Community for development and testing of XDC games like this one: https://github.com/th2tran/gomoku-webxdc",
+ "category": "Gaming",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygqsj22nwsj7ey2uq966ye3knhw5058vtduvk847z35jfkl3ue9jtspsgqqqsg2s3dfnhc#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbUYe9Li8nvfk0cYNsBo7oWE",
+ "member_count": 20
+ },
+ {
+ "name": "Meme Addicts",
+ "description": "Spam the group with all your favorite memes",
+ "category": "Art & Creative",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygzlrevgglkj93u3rxys9duhet9ep4h4pp6qgfczvy2554vzc4wyrupsgqqqsg2szeprjm#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbZ8Lv5xiN62CYSQRoVb2VzI",
+ "member_count": 19
+ },
+ {
+ "name": "The Nostr Pirates",
+ "description": "Talk about Piracy , Tech or just retarded stuff as long as it's not porn and specially CP everything is allowed here",
+ "category": "Technology",
+ "invite_url": "https://vectorapp.io/invite/naddr1qvzqqqyzz5pzqck4pqttjtv3rjynfg333g68h3y8mtuuy5vwel29h5nt72dfwwk3qqqqjgu2kx#BAHD06ir6Cf2UoRvzBE2G16K",
+ "member_count": 19
+ },
+ {
+ "name": "Vector Gaming Group",
+ "description": "A Community To Discuss Vector Built In Games Or Any Other Games",
+ "category": "Gaming",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygxglnmwm09vgtvpyy9tmm8vt038wpcphq4tk0qr9kr5jjg05g2sf5psgqqqsg2sy03x73#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbcEzoWO0CYloQCAeOaEMTcA",
+ "member_count": 17
+ },
+ {
+ "name": "Philosophy",
+ "description": "Metaphysics, Epistemology, Ethics, Human Nature, Good and Evil, etc. The deep conversations about the ultimate fundamental abstract principles that shape reality and our understanding of it.",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqyg9erxx7zm7fhteclu0wkqygr09txg8vds03fre9k40gw56w0s4skgpsgqqqsg2syawhrk#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbQWq9Uyr_YUGd9XGHaGSF-o",
+ "member_count": 17
+ },
+ {
+ "name": "Conspiracy Theories/Truths",
+ "description": "Discussions of Any Topics That Are Categorized As Conspiracy Theories",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqyg8ycuht7vqvlzqg8e0z0zhsraq3yljthl5swahfsx2mdxtmsflatgpsgqqqsg2sv6g97v#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbUbWGoMYbbrG5HjLamPAb0k",
+ "member_count": 16
+ },
+ {
+ "name": "Lounge Chat",
+ "description": "Keep it civil and child friendly if possible. But otherwise anything goes.",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygzl4q3l3t049mqy4e6rthpes0f9e794juz54dhhv5gtatsskpaaygpsgqqqsg2sgvap7a#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbYyfHi5njaqBjK2JMKyjZVk",
+ "member_count": 15
+ },
+ {
+ "name": "Mega Utilities™",
+ "description": "Mega Utilities we create bots, websites, games, and more!",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qvzqqqyzz5pzpmcqczfxkr8ly7kqqp5lmqta32uyut4gz8qjq3z7x8l89ssy5xd7qqqqy23y9x#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbdBWhWXDbWyRZlSHLe2-oZc",
+ "member_count": 15
+ },
+ {
+ "name": "History",
+ "description": "Nostalgia, Ancient History & Everything in Between",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygyhmfjjmuy7eeegyxpq8u7et0xv0s4wscr29fqu2axk9xglpqsfacpsgqqqsg2s39wlra#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbdSbOfD0XUw1acQSoC_7Q2Y",
+ "member_count": 13
+ },
+ {
+ "name": "Barbie Fan Club",
+ "description": "A community of Barbie lovers celebrating everything pink, fabulous, and iconic. From vintage collectors to movie fans, we unite over the magic of this timeless doll who inspires generations. Because B",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygq2ngw90fmyaw9tqyqrcmjjan23gf7h70uv6lnw8q0rtplg2hwcrypsgqqqsg2slhc9ka#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbRVUG4y6PGcfVCWoXmvGdp8",
+ "member_count": 11
+ },
+ {
+ "name": "Effective Accelerationism",
+ "description": "The future, today: for those with interest in AI, Space, Tech, Energy, and the climbing of the Kardashev Scale.",
+ "category": "Technology",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygxqux0cm6s74lgveqg629f25sdlr654w07keuy882c2mjtv3grd9spsgqqqsg2sjedwa7#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbYiq8HmWCJdtqjVopXwpgaU",
+ "member_count": 11
+ },
+ {
+ "name": "Roger's Hangout",
+ "description": "Hanging out, coding, gaming together, and being a community.",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygymc3fcux23xmvz893ldn3sc2gg3khsgvawsyle8en97fe93hq7gvpsgqqqsg2sslmxry#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbcGBuDAZfIAWiPs7QnVpe-g",
+ "member_count": 11
+ },
+ {
+ "name": "Vectoriel Francophone",
+ "description": "Pour les utilisateurs francophones de Vector, ce chan est là pour se retrouver, échanger, discuter et proposer. For FR speaking people (but not exclusively) you're welcome to share and discuss",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygqclr7ymkke7w84h75cnwr7mvhwhxs00qgth2hqc6q94yz70sd6tcpsgqqqsg2sf40a0z#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbVhCn0du_XmF7Ol8madGfUQ",
+ "member_count": 10
+ },
+ {
+ "name": "Sapchat Group",
+ "description": "A group where everyone is encouraged to use 24h expiring messages",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygyufv2f236glg89f4mf02lplyv79zajyfnyz7s3scmslkruwp2avcpsgqqqsg2s3tau6j#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbeaTeU2Pkhp8qL079AY-_Go",
+ "member_count": 10
+ },
+ {
+ "name": "🔒 Retro Gaiden",
+ "description": "Retro Gaiden is a community by retro gamers for retro gamers. It’s an extension of the Retro Gaiden Mastodon server (retro-gaiden.com)\n\nThis space is primarily focused on retro gaming. Casual discussi",
+ "category": "Gaming",
+ "invite_url": "https://vectorapp.io/invite/naddr1qvzqqqyzz5pzq97fuz3tt55ck6laatahkyh85v0mung4pmt60u9lkr8r95hmjgu3qqqqsm9tn6#BAFiJBHI-TnHmwfMTAh3SLNm",
+ "member_count": 7
+ },
+ {
+ "name": "Pixel Art",
+ "description": "Pixel Art Community on Vector. Pixel Art Creators, Pixel Art Enthusiasts, and all around Pixel Art Lovers. Nostalgia Unlocked.",
+ "category": "Art & Creative",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygym72cl4da8dxpj9yld3hcerfxug69vg9t4u94v29xzuaj6g9qx3gpsgqqqsg2skdxg4g#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbTRoqt5b7KXbL44R3DtfR3M",
+ "member_count": 7
+ },
+ {
+ "name": "Vector Bot And Webxdc dev",
+ "description": "Developing vector bots and webxdc application.",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygqay0qa29v4q3lmwx5gq9ysnz7ethc7n7shaqdgs6fts75xxvtg2ypsgqqqsg2s3xqkhl#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbdD8WoQHbyKmhUGA7bAcIQ8",
+ "member_count": 7
+ },
+ {
+ "name": "TTRPGs",
+ "description": "A community for those interested in games such as Dungeons and Dragons, DC20, Pathfinder, and more.",
+ "category": "General",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygp3qz6z0s7j7ke53rx9nh0dpnpmlr54w32t3lyea6pecg04p8fkkvpsgqqqsg2s3astcn#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbUk-MH4eBH6jl69KgN2R6xg",
+ "member_count": 6
+ },
+ {
+ "name": "Design 'Til I Die",
+ "description": "Dedicated Designer Group.\n\nFeedback, Critique, Ideas, Suggestions, Software, Tools, Tricks, Clients, & Collaborations\n\nYou name it, we've done it.\n(probably the wrong way)",
+ "category": "Art & Creative",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqyg8qmmyqt3s3gnxl585xzu3vuyq2drx60wy5nrtqc8arx8djm9jftupsgqqqsg2sedyyjj#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbcyfwmTYHiQcFNJJp_utfyc",
+ "member_count": 6
+ },
+ {
+ "name": "Ethereum Community",
+ "description": "Ethereum Community on Vector\n\nDiscussing development, updates, price, and projects.\n\nDo not shill or directly advertise your token, contract address, or NFTs. You will be banned for spam and advertisi",
+ "category": "Bitcoin & Crypto",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygxnufhkreg6e045r2h2zxly5luvlxsufxpm0wj3avdqs3n82ylhevpsgqqqsg2sha4f8a#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbT9_GZYaNeNGah1x4Qm87ww",
+ "member_count": 5
+ },
+ {
+ "name": "Anime",
+ "description": "For anime fans!",
+ "category": "Art & Creative",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygyr5uyw6nelxuh3gxtpyw2yaprgttu29tpvkkg6lk8228fy06m2hspsgqqqsg2s7hzrm5#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbagcdETBjHpNBXfjftUjRLw",
+ "member_count": 5
+ },
+ {
+ "name": "MAD LADS",
+ "description": "Mad Lads is a popular 10,000-piece NFT collection on the Solana blockchain, created by Backpack. Launched in April 2023, it serves as the cultural arm of the Backpack exchange, featuring tokenized ap",
+ "category": "Bitcoin & Crypto",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygxe6m97f50cz2s0xpksgqnr5x222st92y4eq5awyw5pxgfp8vq9gspsgqqqsg2s2es8av#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbYudTNTya0pSsGz6PuBTQ-o",
+ "member_count": 3
+ },
+ {
+ "name": "Magick, Occult, Witchcraft",
+ "description": "Esoteric / Metaphysical discussion",
+ "category": "Other",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygzzk3x8c980vcn28pg4ldmlcmf5uujk5z2fh4ud62tfqrjq3mn7gspsgqqqsg2sxfjkha#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbdQCcecX3D27flKvJBKXS5M",
+ "member_count": 3
+ },
+ {
+ "name": "Zcash Community",
+ "description": "Zcash is a privacy-focused cryptocurrency launched in October 2016 by the Electric Coin Company, led by Zooko Wilcox. It uses zk-SNARKs zero-knowledge proofs to enable optional shielded transactions,",
+ "category": "Bitcoin & Crypto",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygzz8m37fsv7z5aqh7pd068h35xxv4qp9c73snmjd0rhggaw2mch4cpsgqqqsg2spaxzj7#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbccGKgU2EdmdcUuDSQ_LQlY",
+ "member_count": 2
+ },
+ {
+ "name": "Solana Community",
+ "description": "A general Solana discussion community on Vector.",
+ "category": "Bitcoin & Crypto",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygq0lxvwm4dwchp8f5dc2dyftrdgxn4jlv3k9ycgpcugfrw23kpylcpsgqqqsg2sggvjpf#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvba_b_Moz_ivhKvvOIe9mIlc",
+ "member_count": 2
+ },
+ {
+ "name": "Zano",
+ "description": "Community for Zano, a private cryptocurrency.\n\nFor more information, go to https://zano.org",
+ "category": "Bitcoin & Crypto",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygxy8c2kgkd9tu0wrukdz7z5sk3s8p8sm3nesfhr7n9w9sgulqw7lspsgqqqsg2srwqtx7#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbWQ_U3V5H4oQ01mnS4lrhGY",
+ "member_count": 2
+ },
+ {
+ "name": "Faith in Christ (✝)",
+ "description": "Faith in Christ Community on Vector\n↪ United by Christ through Faith and God's Grace\n\n\"The fear of the LORD is the beginning of wisdom, and knowledge of the Holy One is understanding.\" -Proverbs 9:10",
+ "category": "Other",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygyjfwmqna8xnjkex876c5z8209dn0fy5u9ear0tlv04czqupjpxt5psgqqqsg2su0n6q8#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbYr6O1rMeW2IRfpVh51GNPM",
+ "member_count": 2
+ },
+ {
+ "name": "Italiani",
+ "description": "Comunità italiana su Vector",
+ "category": "Local & Regional",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygy34e9vkrcfj37rvk4adxy75zw6m7uvsl9kt4l33zhwut2ct4mk2vpsgqqqsg2sewgx9d#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbRSSejOSBb8IrqbgqGlSEQ0",
+ "member_count": 2
+ },
+ {
+ "name": "Jade: AI Waifu",
+ "description": "Experimental AI personality",
+ "category": "Art & Creative",
+ "invite_url": "https://vectorapp.io/invite/naddr1qqqqygree0y66yu3cehka6zdd5yfrca4rct6hy2ka8ul3y52h9t5r22dzgpsgqqqsg2sglseng#BAADAQIAGG5vc3RyLmNvbXB1dGluZ2NhY2hlLmNvbeRV60HAcgvMBKMN18MgP-w",
+ "member_count": 1
+ }
+]
diff --git a/src/features/messages.js b/src/features/messages.js
index a9b21b0..8001d39 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -50,6 +50,7 @@ import { qrSvg } from '../qr.js';
// The coinos community's join material lives in ../community.js — shared
// with the public read-only chat page so the two can never drift.
import { COMMUNITY, EPOCH } from '../community.js';
+import COMMUNITY_DIRECTORY from '../community-directory.json';
const DM_RELAYS = ['wss://relay.coinos.io', 'wss://nos.lol'];
const NOTIFIER = 'https://nwcpush.coinos.io';
const APP_BASE = 'https://v3.coinos.io';
@@ -1857,30 +1858,50 @@ export function messagesFeature(ctx) {
scheduleRepaint();
}
- // ---- community discovery: the Vector Hub's public listing as suggestions
- // on Messages and under Browse. Fetched when Messages opens and kept
- // for the session; every listing is a CORD-05 link, which is exactly what
- // the paste box takes, so a tap previews it like a pasted invite.
+ // Public suggestions render immediately, including on a first/offline visit.
+ // The bundled snapshot is a fallback; the device cache refreshes once a day.
+ // Invite previews still check revocation and expiration on the relays.
const HUB_URL = 'https://vectorapp.io/api/hub';
- const hub = { state: 'idle', list: [] };
+ const HUB_CACHE_KEY = 'coinos-community-directory-v1';
+ const HUB_REFRESH_MS = 86400_000;
+ function normalizeHub(list) {
+ return list.filter((c) => c && c.name && parseInviteLink(c.invite_url || ''))
+ .map((c) => ({
+ name: String(c.name).slice(0, 64), description: String(c.description || '').slice(0, 200),
+ category: String(c.category || '').slice(0, 64), invite: c.invite_url,
+ members: Math.max(0, Number(c.member_count) || 0),
+ icon: /^data:image\//.test(c.icon_url || '') && c.icon_url.length <= 32_768 ? c.icon_url : null,
+ }))
+ .sort((a, b) => b.members - a.members);
+ }
+ const hub = { list: normalizeHub(COMMUNITY_DIRECTORY), at: 0, attempted: false, loading: false };
+ try {
+ const cached = JSON.parse(localStorage.getItem(HUB_CACHE_KEY) || 'null');
+ if (cached && Array.isArray(cached.list) && Number.isFinite(cached.at)) {
+ const list = normalizeHub(cached.list);
+ if (list.length || !cached.list.length) { hub.list = list; hub.at = cached.at; }
+ }
+ } catch {}
async function loadHub() {
- if (hub.state !== 'idle') return;
- hub.state = 'loading'; scheduleRepaint();
+ if (hub.loading || hub.attempted || (hub.at > 0 && Date.now() - hub.at < HUB_REFRESH_MS)) return;
+ hub.attempted = true; hub.loading = true;
try {
const res = await fetch(HUB_URL, { signal: AbortSignal.timeout(20_000) });
if (!res.ok) throw new Error('http ' + res.status);
- const list = await res.json();
- hub.list = (Array.isArray(list) ? list : [])
- .filter((c) => c && c.name && parseInviteLink(c.invite_url || ''))
- .map((c) => ({
- name: String(c.name).slice(0, 64), description: String(c.description || '').slice(0, 200),
- category: String(c.category || ''), invite: c.invite_url, members: Number(c.member_count) || 0,
- icon: /^data:image\//.test(c.icon_url || '') ? c.icon_url : null, official: !!c.official,
- }))
- .sort((a, b) => b.members - a.members);
- hub.state = 'ready';
- } catch { hub.state = 'error'; }
- scheduleRepaint();
+ const raw = await res.json();
+ if (!Array.isArray(raw)) throw new Error('invalid directory');
+ const list = normalizeHub(raw);
+ if (raw.length && !list.length) throw new Error('invalid invites');
+ hub.list = list; hub.at = Date.now();
+ try {
+ // Bound icon sizes so public suggestions do not crowd out wallet data.
+ const cached = list.map((c) => ({ name: c.name, description: c.description, category: c.category,
+ invite_url: c.invite, member_count: c.members, icon_url: c.icon }));
+ localStorage.setItem(HUB_CACHE_KEY, JSON.stringify({ at: hub.at, list: cached }));
+ } catch {}
+ scheduleRepaint();
+ } catch { /* Keep the usable directory if refresh fails or we're offline. */ }
+ finally { hub.loading = false; }
}
function hubRows({ preview = false } = {}) {
const q = preview ? '' : (ui.msgJoinText || '').trim().toLowerCase();
@@ -1908,13 +1929,7 @@ export function messagesFeature(ctx) {
h('div', { class: 'row between', style: 'align-items:baseline' },
h('h3', { style: 'margin:0' }, t(preview ? 'msgPopularCommunities' : 'msgDiscoverTitle')),
preview ? h('button', { class: 'btn-sm', onClick: (e) => { e.stopPropagation(); ui.msgJoinText = ''; ui.msgHomePanel = 'join'; render(); } }, t('msgBrowseCommunities')) : null),
- h('a', { class: 'small muted', href: 'https://vectorapp.io/hub/', target: '_blank', rel: 'noopener noreferrer' }, t('msgHubCredit')),
- hub.state === 'error' ? h('div', { class: 'row gap6', style: 'align-items:center' },
- h('span', { class: 'small muted grow' }, t('msgHubFailed')),
- h('button', { class: 'btn-sm', onClick: (e) => { e.stopPropagation(); hub.state = 'idle'; loadHub().catch(() => {}); } }, t('retry')))
- : hub.state !== 'ready' ? h('div', { class: 'row gap6', style: 'align-items:center;padding:6px 0' }, h('span', { class: 'spinner sm' }), h('span', { class: 'small muted' }, t('msgHubLoading')))
- : h('div', { class: 'list' + (preview ? '' : ' hub-list') }, hubRows({ preview })),
- h('div', { class: 'small muted' }, t('msgWhiteNoiseDiscovery')));
+ h('div', { class: 'list' + (preview ? '' : ' hub-list') }, hubRows({ preview })));
}
function joinFromText(text) {
diff --git a/src/i18n.js b/src/i18n.js
index 8881cfe..20818c7 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -676,9 +676,7 @@ const STR = {
msgDiscoverTitle: 'Suggested communities',
msgPopularCommunities: 'Popular communities',
msgBrowseCommunities: 'Browse all',
- msgHubCredit: 'Concord · From the Vector Hub',
msgHubNoSuggestions: 'No new communities to suggest right now.',
- msgWhiteNoiseDiscovery: 'White Noise groups require an invitation. Ask a member to invite your npub.',
msgHubLoading: 'Finding communities…',
msgHubFailed: 'Could not load suggestions right now.',
msgJoined: 'joined',