Merge branch 'next-notifications' into 'next'

Next: Restore most notification types

See merge request soapbox-pub/soapbox-fe!1230
next-virtuoso
Alex Gleason 2 years ago
commit a4e6443448

@ -0,0 +1,290 @@
{
"account": {
"acct": "Hollahollara@spinster.xyz",
"avatar": "https://gleasonator.com/proxy/LArKQiIrW265rGIJGwdgX7rRsao/aHR0cHM6Ly9tZWRpYS5zcGluc3Rlci54eXovYWNjb3VudHMvYXZhdGFycy8wMDAvMTQxLzI5NC9vcmlnaW5hbC9lNjA1NjljMjBjNGY3ODNjLnBuZw/e60569c20c4f783c.png",
"avatar_static": "https://gleasonator.com/proxy/LArKQiIrW265rGIJGwdgX7rRsao/aHR0cHM6Ly9tZWRpYS5zcGluc3Rlci54eXovYWNjb3VudHMvYXZhdGFycy8wMDAvMTQxLzI5NC9vcmlnaW5hbC9lNjA1NjljMjBjNGY3ODNjLnBuZw/e60569c20c4f783c.png",
"bot": false,
"created_at": "2020-05-29T03:15:59.000Z",
"display_name": "Hollahollara",
"emojis": [],
"fields": [],
"followers_count": 0,
"following_count": 0,
"fqn": "Hollahollara@spinster.xyz",
"header": "https://gleasonator.com/proxy/XSANC57uDBL3tM0LBLEer7yMyaA/aHR0cHM6Ly9tZWRpYS5zcGluc3Rlci54eXovYWNjb3VudHMvaGVhZGVycy8wMDAvMTQxLzI5NC9vcmlnaW5hbC84NTMzMWEzMjJkMTIyN2Q0LnBuZw/85331a322d1227d4.png",
"header_static": "https://gleasonator.com/proxy/XSANC57uDBL3tM0LBLEer7yMyaA/aHR0cHM6Ly9tZWRpYS5zcGluc3Rlci54eXovYWNjb3VudHMvaGVhZGVycy8wMDAvMTQxLzI5NC9vcmlnaW5hbC84NTMzMWEzMjJkMTIyN2Q0LnBuZw/85331a322d1227d4.png",
"id": "9vWfJdLwuJSyJXqCeG",
"last_status_at": "2022-04-16T20:33:32",
"locked": true,
"note": "Adult human female. Artist. Evil terv. Millennial, killing all the things. Public Universal Friend.<br/><br/><a href=\"http://www.jenniferaldridge.com\">www.jenniferaldridge.com</a><br/><br/><br/>",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [],
"ap_id": "https://spinster.xyz/users/Hollahollara",
"background_image": null,
"deactivated": false,
"favicon": "https://gleasonator.com/proxy/owo6QgsHm_0ogz5enHyvD68wDUA/aHR0cHM6Ly9zcGluc3Rlci54eXovZmF2aWNvbi5wbmc/favicon.png",
"hide_favorites": true,
"hide_followers": true,
"hide_followers_count": false,
"hide_follows": true,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": false,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 7191,
"url": "https://spinster.xyz/users/Hollahollara",
"username": "Hollahollara"
},
"created_at": "2022-04-14T20:36:52.000Z",
"id": "427825",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"status": {
"account": {
"acct": "alex",
"avatar": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
"avatar_static": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
"bot": false,
"created_at": "2020-01-08T01:25:43.000Z",
"display_name": "Alex Gleason",
"emojis": [],
"fields": [
{
"name": "Website",
"value": "<a href=\"https://alexgleason.me\" rel=\"ugc\">https://alexgleason.me</a>"
},
{
"name": "Soapbox",
"value": "<a href=\"https://soapbox.pub\" rel=\"ugc\">https://soapbox.pub</a>"
},
{
"name": "Email",
"value": "alex@alexgleason.me"
},
{
"name": "Gender identity",
"value": "Soyboy"
},
{
"name": "Donate (PayPal)",
"value": "<a href=\"https://paypal.me/gleasonator\" rel=\"ugc\">https://paypal.me/gleasonator</a>"
},
{
"name": "$BTC",
"value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
},
{
"name": "$ETH",
"value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
},
{
"name": "$DOGE",
"value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
},
{
"name": "$XMR",
"value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
}
],
"follow_requests_count": 0,
"followers_count": 2602,
"following_count": 1603,
"fqn": "alex@gleasonator.com",
"header": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
"header_static": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
"id": "9v5bmRalQvjOy0ECcC",
"last_status_at": "2022-04-16T19:23:50",
"locked": false,
"note": "I create Fediverse software that empowers people online.<br/><br/>I&#39;m vegan btw<br/><br/>Note: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.",
"pleroma": {
"accepts_chat_messages": true,
"accepts_email_list": true,
"allow_following_move": true,
"also_known_as": [
"https://mitra.social/users/alex"
],
"ap_id": "https://gleasonator.com/users/alex",
"background_image": null,
"birthday": "1993-07-03",
"deactivated": false,
"email": "alex@alexgleason.me",
"favicon": "https://gleasonator.com/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": true,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": true,
"location": "Texas",
"notification_settings": {
"block_from_strangers": false,
"hide_notification_contents": false
},
"relationship": {},
"skip_thread_containment": false,
"tags": [],
"unread_conversation_count": 392,
"unread_notifications_count": 2
},
"source": {
"fields": [
{
"name": "Website",
"value": "https://alexgleason.me"
},
{
"name": "Soapbox",
"value": "https://soapbox.pub"
},
{
"name": "Email",
"value": "alex@alexgleason.me"
},
{
"name": "Gender identity",
"value": "Soyboy"
},
{
"name": "Donate (PayPal)",
"value": "https://paypal.me/gleasonator"
},
{
"name": "$BTC",
"value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
},
{
"name": "$ETH",
"value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
},
{
"name": "$DOGE",
"value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
},
{
"name": "$XMR",
"value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
}
],
"note": "I create Fediverse software that empowers people online.\r\n\r\nI'm vegan btw\r\n\r\nNote: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.",
"pleroma": {
"actor_type": "Person",
"discoverable": false,
"no_rich_text": false,
"show_birthday": true,
"show_role": true
},
"privacy": "public",
"sensitive": false
},
"statuses_count": 24050,
"url": "https://gleasonator.com/users/alex",
"username": "alex"
},
"application": {
"name": "Soapbox FE",
"website": "https://soapbox.pub/"
},
"bookmarked": false,
"card": null,
"content": "",
"created_at": "2022-04-12T01:31:00.000Z",
"emojis": [],
"favourited": false,
"favourites_count": 11,
"id": "AIMEslRcKrcu02D3HU",
"in_reply_to_account_id": null,
"in_reply_to_id": null,
"language": null,
"media_attachments": [
{
"blurhash": "etMZzVWq%1%1o#_NayWCofae_Ns:R*kDjYS5a{jYoJj]V@a}WBbGof",
"description": "",
"id": "AIMEqtBeZtvpQvqfIG",
"meta": {
"original": {
"aspect": 0.9726443768996961,
"height": 658,
"width": 640
}
},
"pleroma": {
"mime_type": "image/jpeg"
},
"preview_url": "https://media.gleasonator.com/6c0a1d878b7c9d1d737f415645cf34cdacdf6438c468348f4fa7534a15798023.jpg",
"remote_url": "https://media.gleasonator.com/6c0a1d878b7c9d1d737f415645cf34cdacdf6438c468348f4fa7534a15798023.jpg",
"text_url": "https://media.gleasonator.com/6c0a1d878b7c9d1d737f415645cf34cdacdf6438c468348f4fa7534a15798023.jpg",
"type": "image",
"url": "https://media.gleasonator.com/6c0a1d878b7c9d1d737f415645cf34cdacdf6438c468348f4fa7534a15798023.jpg"
}
],
"mentions": [],
"muted": false,
"pinned": false,
"pleroma": {
"content": {
"text/plain": ""
},
"content_type": null,
"conversation_id": "AIMEslPqRSCzuXNdWC",
"direct_conversation_id": null,
"emoji_reactions": [
{
"count": 4,
"me": false,
"name": "😆"
},
{
"count": 1,
"me": false,
"name": "🤢"
}
],
"expires_at": null,
"in_reply_to_account_acct": null,
"local": true,
"parent_visible": false,
"pinned_at": null,
"quote": null,
"quote_url": null,
"quote_visible": false,
"spoiler_text": {
"text/plain": ""
},
"thread_muted": false
},
"poll": null,
"reblog": null,
"reblogged": false,
"reblogs_count": 4,
"replies_count": 0,
"sensitive": false,
"spoiler_text": "",
"tags": [],
"text": null,
"uri": "https://gleasonator.com/objects/7953f9fb-d3d7-4f50-b9d8-27e311ac1f5e",
"url": "https://gleasonator.com/notice/AIMEslRcKrcu02D3HU",
"visibility": "public"
},
"type": "favourite"
}

@ -0,0 +1,61 @@
{
"account": {
"acct": "neko@rdrama.cc",
"avatar": "https://gleasonator.com/proxy/QJ3einzsXdobgWPsyZowxnor1zY/aHR0cHM6Ly9yZHJhbWEuY2MvbWVkaWEvODcyNDhjYjctZWYwNC00ZThjLWEwYzEtNTYxNWMyNWM0MTk1L2Jsb2I/blob",
"avatar_static": "https://gleasonator.com/proxy/QJ3einzsXdobgWPsyZowxnor1zY/aHR0cHM6Ly9yZHJhbWEuY2MvbWVkaWEvODcyNDhjYjctZWYwNC00ZThjLWEwYzEtNTYxNWMyNWM0MTk1L2Jsb2I/blob",
"bot": false,
"created_at": "2022-04-16T20:23:16.000Z",
"display_name": "Nekobit",
"emojis": [],
"fields": [],
"followers_count": 19,
"following_count": 357,
"fqn": "neko@rdrama.cc",
"header": "https://gleasonator.com/proxy/ojpBSVKfePvLnb7pwqepQspzIko/aHR0cHM6Ly9yZHJhbWEuY2MvbWVkaWEvNjBkMTJjOWYtOTNkNi00ODBmLThhMGUtMTE3M2ZkNjg5MzhmL3dhbGxwYXBlcmZsYXJlLmNvbV93YWxscGFwZXItd2ViLmpwZw/wallpaperflare.com_wallpaper-web.jpg",
"header_static": "https://gleasonator.com/proxy/ojpBSVKfePvLnb7pwqepQspzIko/aHR0cHM6Ly9yZHJhbWEuY2MvbWVkaWEvNjBkMTJjOWYtOTNkNi00ODBmLThhMGUtMTE3M2ZkNjg5MzhmL3dhbGxwYXBlcmZsYXJlLmNvbV93YWxscGFwZXItd2ViLmpwZw/wallpaperflare.com_wallpaper-web.jpg",
"id": "AIW9zGESDwdT27vk0W",
"last_status_at": "2022-04-16T21:49:29",
"locked": false,
"note": "New instance, hello!<br/><br/>Please follow if you followed my <a href=\"http://desuposter.club\">desuposter.club</a> alt",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [],
"ap_id": "https://rdrama.cc/users/neko",
"background_image": null,
"deactivated": false,
"favicon": "https://gleasonator.com/proxy/dbCdmChqVRi0vjYTCpRj5lDLtNM/aHR0cHM6Ly9yZHJhbWEuY2MvZmF2aWNvbi5wbmc/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": false,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 6,
"url": "https://rdrama.cc/users/neko",
"username": "neko"
},
"created_at": "2022-04-16T20:24:03.000Z",
"id": "429280",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"type": "follow"
}

@ -0,0 +1,61 @@
{
"account": {
"acct": "alex@spinster.xyz",
"avatar": "https://gleasonator.com/images/avi.png",
"avatar_static": "https://gleasonator.com/images/avi.png",
"bot": false,
"created_at": "2020-01-08T03:08:22.000Z",
"display_name": "**MOVED**",
"emojis": [],
"fields": [],
"followers_count": 1005,
"following_count": 724,
"fqn": "alex@spinster.xyz",
"header": "https://gleasonator.com/proxy/yxa7ucolLFAsmBHYJzksSh_zoao/aHR0cHM6Ly9tZWRpYS5zcGluc3Rlci54eXovYWNjb3VudHMvaGVhZGVycy8wMDAvMDAwLzAwMS9vcmlnaW5hbC83ZmE4MWY5ZmZiYWVjZDk3LnBuZw/7fa81f9ffbaecd97.png",
"header_static": "https://gleasonator.com/proxy/yxa7ucolLFAsmBHYJzksSh_zoao/aHR0cHM6Ly9tZWRpYS5zcGluc3Rlci54eXovYWNjb3VudHMvaGVhZGVycy8wMDAvMDAwLzAwMS9vcmlnaW5hbC83ZmE4MWY5ZmZiYWVjZDk3LnBuZw/7fa81f9ffbaecd97.png",
"id": "9v5bmXkCYkqU30gp9s",
"last_status_at": null,
"locked": true,
"note": "Moved to <a href=\"https://spinster.xyz/@alex@gleasonator.com\">https://spinster.xyz/@alex@gleasonator.com</a>",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [],
"ap_id": "https://spinster.xyz/users/alex",
"background_image": null,
"deactivated": false,
"favicon": "https://gleasonator.com/proxy/owo6QgsHm_0ogz5enHyvD68wDUA/aHR0cHM6Ly9zcGluc3Rlci54eXovZmF2aWNvbi5wbmc/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": false,
"is_moderator": false,
"is_suggested": false,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 2687,
"url": "https://spinster.xyz/users/alex",
"username": "alex"
},
"created_at": "2020-12-30T02:23:35.000Z",
"id": "87967",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"type": "follow_request"
}

@ -0,0 +1,226 @@
{
"account": {
"acct": "silverpill@mitra.social",
"avatar": "https://gleasonator.com/proxy/ZbLqy9s8Hxn9I5K23y2mffsL6iY/aHR0cHM6Ly9taXRyYS5zb2NpYWwvbWVkaWEvNmE3ODViZjdkZDA1ZjYxYzM1OTBlODkzNWFhNDkxNTZhNDk5YWMzMGZkMWU0MDJmNzllN2UxNjRhZGIzNmUyYy5wbmc/6a785bf7dd05f61c3590e8935aa49156a499ac30fd1e402f79e7e164adb36e2c.png",
"avatar_static": "https://gleasonator.com/proxy/ZbLqy9s8Hxn9I5K23y2mffsL6iY/aHR0cHM6Ly9taXRyYS5zb2NpYWwvbWVkaWEvNmE3ODViZjdkZDA1ZjYxYzM1OTBlODkzNWFhNDkxNTZhNDk5YWMzMGZkMWU0MDJmNzllN2UxNjRhZGIzNmUyYy5wbmc/6a785bf7dd05f61c3590e8935aa49156a499ac30fd1e402f79e7e164adb36e2c.png",
"bot": false,
"created_at": "2021-11-11T22:31:51.000Z",
"display_name": "silverpill",
"emojis": [],
"fields": [
{
"name": "Matrix",
"value": "@silverpill:poa.st"
},
{
"name": "Alt",
"value": "@silverpill@poa.st"
},
{
"name": "Code",
"value": "<a href=\"https://codeberg.org/silverpill/\">https://codeberg.org/silverpill/</a>"
},
{
"name": "$XMR",
"value": "884y9LmsWY7PQNsyR7bJy1dvj91tuF5spVabyCnPk4KfQtSuzFbQobTFC7xSemJgVW1FWAwnJbjTZX5zZWbBrfkv62DB62d"
}
],
"followers_count": 0,
"following_count": 0,
"fqn": "silverpill@mitra.social",
"header": "https://gleasonator.com/images/banner.png",
"header_static": "https://gleasonator.com/images/banner.png",
"id": "ADIzJ7q9gExPvDKBCS",
"last_status_at": "2022-04-15T11:27:33",
"locked": false,
"note": "",
"pleroma": {
"accepts_chat_messages": false,
"also_known_as": [],
"ap_id": "https://mitra.social/users/silverpill",
"background_image": null,
"deactivated": false,
"favicon": "https://gleasonator.com/proxy/XSE9_kQbQyYcSFWszWx2GgCbBuY/aHR0cHM6Ly9taXRyYS5zb2NpYWwvZmF2aWNvbi5pY28/favicon.ico",
"hide_favorites": true,
"hide_followers": true,
"hide_followers_count": false,
"hide_follows": true,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": false,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 135,
"url": "https://mitra.social/users/silverpill",
"username": "silverpill"
},
"created_at": "2022-04-15T11:27:33.000Z",
"id": "428172",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"status": {
"account": {
"acct": "silverpill@mitra.social",
"avatar": "https://gleasonator.com/proxy/ZbLqy9s8Hxn9I5K23y2mffsL6iY/aHR0cHM6Ly9taXRyYS5zb2NpYWwvbWVkaWEvNmE3ODViZjdkZDA1ZjYxYzM1OTBlODkzNWFhNDkxNTZhNDk5YWMzMGZkMWU0MDJmNzllN2UxNjRhZGIzNmUyYy5wbmc/6a785bf7dd05f61c3590e8935aa49156a499ac30fd1e402f79e7e164adb36e2c.png",
"avatar_static": "https://gleasonator.com/proxy/ZbLqy9s8Hxn9I5K23y2mffsL6iY/aHR0cHM6Ly9taXRyYS5zb2NpYWwvbWVkaWEvNmE3ODViZjdkZDA1ZjYxYzM1OTBlODkzNWFhNDkxNTZhNDk5YWMzMGZkMWU0MDJmNzllN2UxNjRhZGIzNmUyYy5wbmc/6a785bf7dd05f61c3590e8935aa49156a499ac30fd1e402f79e7e164adb36e2c.png",
"bot": false,
"created_at": "2021-11-11T22:31:51.000Z",
"display_name": "silverpill",
"emojis": [],
"fields": [
{
"name": "Matrix",
"value": "@silverpill:poa.st"
},
{
"name": "Alt",
"value": "@silverpill@poa.st"
},
{
"name": "Code",
"value": "<a href=\"https://codeberg.org/silverpill/\">https://codeberg.org/silverpill/</a>"
},
{
"name": "$XMR",
"value": "884y9LmsWY7PQNsyR7bJy1dvj91tuF5spVabyCnPk4KfQtSuzFbQobTFC7xSemJgVW1FWAwnJbjTZX5zZWbBrfkv62DB62d"
}
],
"followers_count": 0,
"following_count": 0,
"fqn": "silverpill@mitra.social",
"header": "https://gleasonator.com/images/banner.png",
"header_static": "https://gleasonator.com/images/banner.png",
"id": "ADIzJ7q9gExPvDKBCS",
"last_status_at": "2022-04-15T11:27:33",
"locked": false,
"note": "",
"pleroma": {
"accepts_chat_messages": false,
"also_known_as": [],
"ap_id": "https://mitra.social/users/silverpill",
"background_image": null,
"deactivated": false,
"favicon": "https://gleasonator.com/proxy/XSE9_kQbQyYcSFWszWx2GgCbBuY/aHR0cHM6Ly9taXRyYS5zb2NpYWwvZmF2aWNvbi5pY28/favicon.ico",
"hide_favorites": true,
"hide_followers": true,
"hide_followers_count": false,
"hide_follows": true,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": false,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 135,
"url": "https://mitra.social/users/silverpill",
"username": "silverpill"
},
"application": null,
"bookmarked": true,
"card": {
"author_name": "",
"author_url": "",
"blurhash": null,
"description": "The ActivityPub protocol is a decentralized social networking protocol\n based upon the [ActivityStreams] 2.0 data format.\n It provides a client to server API for creating, updating and deleting\n content, as well as a federated server to server API for delivering\n notifications and content.",
"embed_url": "",
"height": 0,
"html": "",
"image": null,
"provider_name": "www.w3.org",
"provider_url": "https://www.w3.org",
"title": "ActivityPub",
"type": "link",
"url": "https://www.w3.org/TR/activitypub/#retrieving-objects",
"width": 0
},
"content": "<span class=\"h-card\"><a class=\"u-url mention\" href=\"https://gleasonator.com/users/alex\">@alex</a></span> <span class=\"h-card\"><a class=\"u-url mention\" href=\"https://lain.com/users/lain\">@lain</a></span> The second one is suggested by ActivityPub spec: <a href=\"https://www.w3.org/TR/activitypub/#retrieving-objects\">https://www.w3.org/TR/activitypub/#retrieving-objects</a><br/>\nThe first one is likely a legacy of earlier ActivityStreams standards, I&#39;m not sure",
"created_at": "2022-04-15T11:27:28.000Z",
"emojis": [],
"favourited": true,
"favourites_count": 2,
"id": "AITJf9Wpr0msWChNBI",
"in_reply_to_account_id": "9v5bmRalQvjOy0ECcC",
"in_reply_to_id": "AISPFI5nnPaS7J94rI",
"language": null,
"media_attachments": [],
"mentions": [
{
"acct": "alex",
"id": "9v5bmRalQvjOy0ECcC",
"url": "https://gleasonator.com/users/alex",
"username": "alex"
},
{
"acct": "lain@lain.com",
"id": "9v5bqYwY2jfmvPNhTM",
"url": "https://lain.com/users/lain",
"username": "lain"
}
],
"muted": false,
"pinned": false,
"pleroma": {
"content": {
"text/plain": "@alex @lain The second one is suggested by ActivityPub spec: https://www.w3.org/TR/activitypub/#retrieving-objects\nThe first one is likely a legacy of earlier ActivityStreams standards, I'm not sure"
},
"content_type": null,
"conversation_id": "AISPFI2bzH2DxPeWsy",
"direct_conversation_id": null,
"emoji_reactions": [],
"expires_at": null,
"in_reply_to_account_acct": "alex",
"local": false,
"parent_visible": true,
"pinned_at": null,
"quote": null,
"quote_url": null,
"quote_visible": false,
"spoiler_text": {
"text/plain": ""
},
"thread_muted": false
},
"poll": null,
"reblog": null,
"reblogged": false,
"reblogs_count": 0,
"replies_count": 0,
"sensitive": false,
"spoiler_text": "",
"tags": [],
"text": null,
"uri": "https://mitra.social/objects/01802cfa-633c-1c2c-e9cf-e6e0ffef0afe",
"url": "https://mitra.social/objects/01802cfa-633c-1c2c-e9cf-e6e0ffef0afe",
"visibility": "public"
},
"type": "mention"
}

@ -0,0 +1,119 @@
{
"account": {
"acct": "alex@fedibird.com",
"avatar": "https://gleasonator.com/images/avi.png",
"avatar_static": "https://gleasonator.com/images/avi.png",
"bot": false,
"created_at": "2022-01-24T21:25:37.000Z",
"display_name": "alex@fedibird.com",
"emojis": [],
"fields": [],
"followers_count": 0,
"following_count": 2,
"fqn": "alex@fedibird.com",
"header": "https://gleasonator.com/images/banner.png",
"header_static": "https://gleasonator.com/images/banner.png",
"id": "AFmHQ18XZ7Lco68MW8",
"last_status_at": "2022-03-16T22:07:53",
"locked": false,
"note": "<p></p>",
"pleroma": {
"accepts_chat_messages": null,
"also_known_as": [],
"ap_id": "https://fedibird.com/users/alex",
"background_image": null,
"birthday": "1993-07-03",
"deactivated": false,
"favicon": "https://gleasonator.com/proxy/HzfsidHss3CuA7aM2zxXN-tAjF8/aHR0cHM6Ly9mZWRpYmlyZC5jb20vZmF2aWNvbi5pY28/favicon.ico",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": false,
"location": "Texas",
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 5,
"url": "https://fedibird.com/@alex",
"username": "alex"
},
"created_at": "2022-03-17T00:08:48.000Z",
"id": "406814",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"target": {
"acct": "benis911",
"avatar": "https://gleasonator.com/images/avi.png",
"avatar_static": "https://gleasonator.com/images/avi.png",
"bot": false,
"created_at": "2021-03-26T20:42:11.000Z",
"display_name": "benis911",
"emojis": [],
"fields": [],
"followers_count": 0,
"following_count": 0,
"fqn": "benis911@gleasonator.com",
"header": "https://media.gleasonator.com/fc595bbbcf5aabefecd1c2adfe5b7f5457db59847992881668653a0338ba25bd.jpg",
"header_static": "https://media.gleasonator.com/fc595bbbcf5aabefecd1c2adfe5b7f5457db59847992881668653a0338ba25bd.jpg",
"id": "A5c5LK7EJTFR0u26Pg",
"last_status_at": "2022-03-19T22:33:38",
"locked": false,
"note": "hello world 2",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [
"https://gleasonator.com/users/alex",
"https://poa.st/users/alex",
"https://fedibird.com/users/alex"
],
"ap_id": "https://gleasonator.com/users/benis911",
"background_image": null,
"birthday": "2000-01-25",
"deactivated": false,
"favicon": "https://gleasonator.com/favicon.png",
"hide_favorites": true,
"hide_followers": true,
"hide_followers_count": true,
"hide_follows": true,
"hide_follows_count": true,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": false,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "hello world 2",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 174,
"url": "https://gleasonator.com/users/benis911",
"username": "benis911"
},
"type": "move"
}

@ -0,0 +1,73 @@
{
"account": {
"acct": "dave",
"avatar": "https://media.gleasonator.com/68c29c30c18f30dd2898f85466bf1670312dda816617e6d31421c7e4c30a8265.png",
"avatar_static": "https://media.gleasonator.com/68c29c30c18f30dd2898f85466bf1670312dda816617e6d31421c7e4c30a8265.png",
"bot": false,
"created_at": "2020-02-01T07:28:46.000Z",
"display_name": "Elden Beedle 🇺🇦 🇫🇷",
"emojis": [],
"fields": [],
"followers_count": 490,
"following_count": 367,
"fqn": "dave@gleasonator.com",
"header": "https://media.gleasonator.com/47e8907c322a0e55d12b211846aa27c6b386e947326fe14bb09c89ef7317901d.jpg",
"header_static": "https://media.gleasonator.com/47e8907c322a0e55d12b211846aa27c6b386e947326fe14bb09c89ef7317901d.jpg",
"id": "9v5c0Pkz3MT5KTfam8",
"last_status_at": "2022-04-16T19:57:10",
"locked": false,
"note": "Beedle is back, baby!<br/><br/>Mostly just crosspost memes and stuff I find on the internet",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [],
"ap_id": "https://gleasonator.com/users/dave",
"background_image": null,
"birthday": "1990-01-01",
"deactivated": false,
"favicon": "https://gleasonator.com/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": true,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "Beedle is back, baby!\r\n\r\nMostly just crosspost memes and stuff I find on the internet",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 16758,
"url": "https://gleasonator.com/users/dave",
"username": "dave"
},
"chat_message": {
"account_id": "9v5c0Pkz3MT5KTfam8",
"attachment": null,
"card": null,
"chat_id": "9yX4Q9DiC2te6lvk5g",
"content": "Cool, it works, I&#39;ll keep letting you know when I find broken stuff",
"created_at": "2022-04-16T19:22:54.000Z",
"emojis": [],
"id": "AIW4bHoICoZ9CsRTW4",
"unread": false
},
"created_at": "2022-04-16T19:22:55.000Z",
"id": "429247",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"type": "pleroma:chat_mention"
}

@ -0,0 +1,301 @@
{
"account": {
"acct": "dave",
"avatar": "https://media.gleasonator.com/68c29c30c18f30dd2898f85466bf1670312dda816617e6d31421c7e4c30a8265.png",
"avatar_static": "https://media.gleasonator.com/68c29c30c18f30dd2898f85466bf1670312dda816617e6d31421c7e4c30a8265.png",
"bot": false,
"created_at": "2020-02-01T07:28:46.000Z",
"display_name": "Elden Beedle 🇺🇦 🇫🇷",
"emojis": [],
"fields": [],
"followers_count": 490,
"following_count": 367,
"fqn": "dave@gleasonator.com",
"header": "https://media.gleasonator.com/47e8907c322a0e55d12b211846aa27c6b386e947326fe14bb09c89ef7317901d.jpg",
"header_static": "https://media.gleasonator.com/47e8907c322a0e55d12b211846aa27c6b386e947326fe14bb09c89ef7317901d.jpg",
"id": "9v5c0Pkz3MT5KTfam8",
"last_status_at": "2022-04-16T19:57:10",
"locked": false,
"note": "Beedle is back, baby!<br/><br/>Mostly just crosspost memes and stuff I find on the internet",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [],
"ap_id": "https://gleasonator.com/users/dave",
"background_image": null,
"birthday": "1990-01-01",
"deactivated": false,
"favicon": "https://gleasonator.com/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": true,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "Beedle is back, baby!\r\n\r\nMostly just crosspost memes and stuff I find on the internet",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 16758,
"url": "https://gleasonator.com/users/dave",
"username": "dave"
},
"created_at": "2022-04-16T16:52:15.000Z",
"emoji": "😮",
"id": "429071",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"status": {
"account": {
"acct": "alex",
"avatar": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
"avatar_static": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
"bot": false,
"created_at": "2020-01-08T01:25:43.000Z",
"display_name": "Alex Gleason",
"emojis": [],
"fields": [
{
"name": "Website",
"value": "<a href=\"https://alexgleason.me\" rel=\"ugc\">https://alexgleason.me</a>"
},
{
"name": "Soapbox",
"value": "<a href=\"https://soapbox.pub\" rel=\"ugc\">https://soapbox.pub</a>"
},
{
"name": "Email",
"value": "alex@alexgleason.me"
},
{
"name": "Gender identity",
"value": "Soyboy"
},
{
"name": "Donate (PayPal)",
"value": "<a href=\"https://paypal.me/gleasonator\" rel=\"ugc\">https://paypal.me/gleasonator</a>"
},
{
"name": "$BTC",
"value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
},
{
"name": "$ETH",
"value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
},
{
"name": "$DOGE",
"value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
},
{
"name": "$XMR",
"value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
}
],
"follow_requests_count": 0,
"followers_count": 2602,
"following_count": 1603,
"fqn": "alex@gleasonator.com",
"header": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
"header_static": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
"id": "9v5bmRalQvjOy0ECcC",
"last_status_at": "2022-04-16T19:23:50",
"locked": false,
"note": "I create Fediverse software that empowers people online.<br/><br/>I&#39;m vegan btw<br/><br/>Note: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.",
"pleroma": {
"accepts_chat_messages": true,
"accepts_email_list": true,
"allow_following_move": true,
"also_known_as": [
"https://mitra.social/users/alex"
],
"ap_id": "https://gleasonator.com/users/alex",
"background_image": null,
"birthday": "1993-07-03",
"deactivated": false,
"email": "alex@alexgleason.me",
"favicon": "https://gleasonator.com/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": true,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": true,
"location": "Texas",
"notification_settings": {
"block_from_strangers": false,
"hide_notification_contents": false
},
"relationship": {},
"skip_thread_containment": false,
"tags": [],
"unread_conversation_count": 392,
"unread_notifications_count": 0
},
"source": {
"fields": [
{
"name": "Website",
"value": "https://alexgleason.me"
},
{
"name": "Soapbox",
"value": "https://soapbox.pub"
},
{
"name": "Email",
"value": "alex@alexgleason.me"
},
{
"name": "Gender identity",
"value": "Soyboy"
},
{
"name": "Donate (PayPal)",
"value": "https://paypal.me/gleasonator"
},
{
"name": "$BTC",
"value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
},
{
"name": "$ETH",
"value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
},
{
"name": "$DOGE",
"value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
},
{
"name": "$XMR",
"value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
}
],
"note": "I create Fediverse software that empowers people online.\r\n\r\nI'm vegan btw\r\n\r\nNote: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.",
"pleroma": {
"actor_type": "Person",
"discoverable": false,
"no_rich_text": false,
"show_birthday": true,
"show_role": true
},
"privacy": "public",
"sensitive": false
},
"statuses_count": 24050,
"url": "https://gleasonator.com/users/alex",
"username": "alex"
},
"application": {
"name": "Soapbox FE",
"website": "https://soapbox.pub/"
},
"bookmarked": false,
"card": {
"author_name": "Kaze Emanuar",
"author_url": "https://www.youtube.com/c/KazeEmanuar",
"blurhash": null,
"description": "",
"embed_url": null,
"height": 113,
"html": "<iframe width=\"200\" height=\"113\" src=\"https://www.youtube.com/embed/t_rzYnXEQlE?feature=oembed\" allowfullscreen=\"\"></iframe>",
"image": "https://gleasonator.com/proxy/mI004Vq00johZtAUmMp0fC_XAuM/aHR0cHM6Ly9pLnl0aW1nLmNvbS92aS90X3J6WW5YRVFsRS9ocWRlZmF1bHQuanBn/hqdefault.jpg",
"provider_name": "YouTube",
"provider_url": "https://www.youtube.com/",
"title": "FIXING the ENTIRE SM64 Source Code (INSANE N64 performance)",
"type": "video",
"url": "https://youtu.be/t_rzYnXEQlE",
"width": 200
},
"content": "<p>Bruh. This guy rewrote the reversed engineered Super Mario 64 code for 10x performance. Games need to be open source. <a href=\"https://youtu.be/t_rzYnXEQlE\">https://youtu.be/t_rzYnXEQlE</a></p>",
"created_at": "2022-04-16T16:40:28.000Z",
"emojis": [],
"favourited": false,
"favourites_count": 11,
"id": "AIVq6SrJg5yb8eGVsm",
"in_reply_to_account_id": null,
"in_reply_to_id": null,
"language": null,
"media_attachments": [],
"mentions": [],
"muted": false,
"pinned": false,
"pleroma": {
"content": {
"text/plain": "Bruh. This guy rewrote the reversed engineered Super Mario 64 code for 10x performance. Games need to be open source. https://youtu.be/t_rzYnXEQlE"
},
"content_type": null,
"conversation_id": "AIVq6SqFk37r5LlfE0",
"direct_conversation_id": null,
"emoji_reactions": [
{
"count": 1,
"me": false,
"name": "❤️"
},
{
"count": 2,
"me": false,
"name": "😮"
},
{
"count": 1,
"me": false,
"name": "😆"
},
{
"count": 1,
"me": false,
"name": "👍🏻"
},
{
"count": 1,
"me": false,
"name": "🔥"
}
],
"expires_at": null,
"in_reply_to_account_acct": null,
"local": true,
"parent_visible": false,
"pinned_at": null,
"quote": null,
"quote_url": null,
"quote_visible": false,
"spoiler_text": {
"text/plain": ""
},
"thread_muted": false
},
"poll": null,
"reblog": null,
"reblogged": false,
"reblogs_count": 7,
"replies_count": 2,
"sensitive": false,
"spoiler_text": "",
"tags": [],
"text": null,
"uri": "https://gleasonator.com/objects/160dcbb2-73bc-4cd2-971e-e7f6a38602a0",
"url": "https://gleasonator.com/notice/AIVq6SrJg5yb8eGVsm",
"visibility": "public"
},
"type": "pleroma:emoji_reaction"
}

@ -0,0 +1,202 @@
{
"account": {
"acct": "dave",
"avatar": "https://media.gleasonator.com/68c29c30c18f30dd2898f85466bf1670312dda816617e6d31421c7e4c30a8265.png",
"avatar_static": "https://media.gleasonator.com/68c29c30c18f30dd2898f85466bf1670312dda816617e6d31421c7e4c30a8265.png",
"bot": false,
"created_at": "2020-02-01T07:28:46.000Z",
"display_name": "Elden Beedle 🇺🇦 🇫🇷",
"emojis": [],
"fields": [],
"followers_count": 490,
"following_count": 367,
"fqn": "dave@gleasonator.com",
"header": "https://media.gleasonator.com/47e8907c322a0e55d12b211846aa27c6b386e947326fe14bb09c89ef7317901d.jpg",
"header_static": "https://media.gleasonator.com/47e8907c322a0e55d12b211846aa27c6b386e947326fe14bb09c89ef7317901d.jpg",
"id": "9v5c0Pkz3MT5KTfam8",
"last_status_at": "2022-04-16T19:57:10",
"locked": false,
"note": "Beedle is back, baby!<br/><br/>Mostly just crosspost memes and stuff I find on the internet",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [],
"ap_id": "https://gleasonator.com/users/dave",
"background_image": null,
"birthday": "1990-01-01",
"deactivated": false,
"favicon": "https://gleasonator.com/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": true,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "Beedle is back, baby!\r\n\r\nMostly just crosspost memes and stuff I find on the internet",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 16758,
"url": "https://gleasonator.com/users/dave",
"username": "dave"
},
"created_at": "2022-04-14T01:12:27.000Z",
"id": "427339",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"status": {
"account": {
"acct": "dave",
"avatar": "https://media.gleasonator.com/68c29c30c18f30dd2898f85466bf1670312dda816617e6d31421c7e4c30a8265.png",
"avatar_static": "https://media.gleasonator.com/68c29c30c18f30dd2898f85466bf1670312dda816617e6d31421c7e4c30a8265.png",
"bot": false,
"created_at": "2020-02-01T07:28:46.000Z",
"display_name": "Elden Beedle 🇺🇦 🇫🇷",
"emojis": [],
"fields": [],
"followers_count": 490,
"following_count": 367,
"fqn": "dave@gleasonator.com",
"header": "https://media.gleasonator.com/47e8907c322a0e55d12b211846aa27c6b386e947326fe14bb09c89ef7317901d.jpg",
"header_static": "https://media.gleasonator.com/47e8907c322a0e55d12b211846aa27c6b386e947326fe14bb09c89ef7317901d.jpg",
"id": "9v5c0Pkz3MT5KTfam8",
"last_status_at": "2022-04-16T19:57:10",
"locked": false,
"note": "Beedle is back, baby!<br/><br/>Mostly just crosspost memes and stuff I find on the internet",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [],
"ap_id": "https://gleasonator.com/users/dave",
"background_image": null,
"birthday": "1990-01-01",
"deactivated": false,
"favicon": "https://gleasonator.com/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": true,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "Beedle is back, baby!\r\n\r\nMostly just crosspost memes and stuff I find on the internet",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 16758,
"url": "https://gleasonator.com/users/dave",
"username": "dave"
},
"application": {
"name": "Soapbox FE",
"website": "https://soapbox.pub/"
},
"bookmarked": false,
"card": null,
"content": "<p>Focusing on just the look, what do you guys think?</p>",
"created_at": "2022-04-13T01:12:26.000Z",
"emojis": [],
"favourited": false,
"favourites_count": 1,
"id": "AIOHjtGEaqUHoXGVf6",
"in_reply_to_account_id": "9v5c0Pkz3MT5KTfam8",
"in_reply_to_id": "AIOFTLqQrljhdNBNHE",
"language": null,
"media_attachments": [],
"mentions": [
{
"acct": "dave",
"id": "9v5c0Pkz3MT5KTfam8",
"url": "https://gleasonator.com/users/dave",
"username": "dave"
}
],
"muted": false,
"pinned": false,
"pleroma": {
"content": {
"text/plain": "Focusing on just the look, what do you guys think?"
},
"content_type": null,
"conversation_id": "AIOFTLp0x2bNYyWF4C",
"direct_conversation_id": null,
"emoji_reactions": [],
"expires_at": null,
"in_reply_to_account_acct": "dave",
"local": true,
"parent_visible": true,
"pinned_at": null,
"quote": null,
"quote_url": null,
"quote_visible": false,
"spoiler_text": {
"text/plain": ""
},
"thread_muted": false
},
"poll": {
"emojis": [],
"expired": true,
"expires_at": "2022-04-14T01:12:26.000Z",
"id": "AIOHjtAuucEZY2mGNE",
"multiple": false,
"options": [
{
"title": "Looks good, looking forward to wider deployment",
"votes_count": 10
},
{
"title": "Not a fan, l'll stick to the current UI thanks",
"votes_count": 1
},
{
"title": "Hard to say, need to actually try to decide honestly",
"votes_count": 1
}
],
"own_votes": [
0
],
"voted": true,
"voters_count": 12,
"votes_count": 12
},
"reblog": null,
"reblogged": false,
"reblogs_count": 1,
"replies_count": 1,
"sensitive": false,
"spoiler_text": "",
"tags": [],
"text": null,
"uri": "https://gleasonator.com/objects/a8465271-a48d-4c39-a0a9-d3eda3ab2735",
"url": "https://gleasonator.com/notice/AIOHjtGEaqUHoXGVf6",
"visibility": "public"
},
"type": "poll"
}

@ -0,0 +1,284 @@
{
"account": {
"acct": "rob@nicecrew.digital",
"avatar": "https://gleasonator.com/proxy/RcEgR4-0InIpw_sCpDWV-XrAbmY/aHR0cHM6Ly9uaWNlY3Jldy5kaWdpdGFsL21lZGlhL2M0MTllMTk1Nzg0MmEzMTY5M2MzNDExNTZlMTBhNmQwMTY2ZTM5YzQzM2ExZTczMmVmYWNlYmJkYjAyMDYzZjEucG5n/c419e1957842a31693c341156e10a6d0166e39c433a1e732efacebbdb02063f1.png",
"avatar_static": "https://gleasonator.com/proxy/RcEgR4-0InIpw_sCpDWV-XrAbmY/aHR0cHM6Ly9uaWNlY3Jldy5kaWdpdGFsL21lZGlhL2M0MTllMTk1Nzg0MmEzMTY5M2MzNDExNTZlMTBhNmQwMTY2ZTM5YzQzM2ExZTczMmVmYWNlYmJkYjAyMDYzZjEucG5n/c419e1957842a31693c341156e10a6d0166e39c433a1e732efacebbdb02063f1.png",
"bot": false,
"created_at": "2022-03-10T12:30:41.000Z",
"display_name": "Rob Colbert",
"emojis": [],
"fields": [
{
"name": "Shing.tv",
"value": "<a href=\"https://shing.tv\" rel=\"ugc\">https://shing.tv</a>"
},
{
"name": "LibertyLinks",
"value": "<a href=\"https://libertylinks.io\" rel=\"ugc\">https://libertylinks.io</a>"
},
{
"name": "GiveSendGo",
"value": "<a href=\"https://givesendgo.com/dtp\" rel=\"ugc\">https://givesendgo.com/dtp</a>"
}
],
"followers_count": 0,
"following_count": 0,
"fqn": "rob@nicecrew.digital",
"header": "https://gleasonator.com/proxy/t4--aro68-XZlasaR2bYiuiZMcA/aHR0cHM6Ly9uaWNlY3Jldy5kaWdpdGFsL21lZGlhL2E5ODYzYWE4YjEzM2QwMzkxNmU1N2MzNDgzMzBhZmE5MTM5MDFlNGZiMDEwYjk1Y2FiZjlmYmZiZTA4N2QxODMucG5n/a9863aa8b133d03916e57c348330afa913901e4fb010b95cabf9fbfbe087d183.png",
"header_static": "https://gleasonator.com/proxy/t4--aro68-XZlasaR2bYiuiZMcA/aHR0cHM6Ly9uaWNlY3Jldy5kaWdpdGFsL21lZGlhL2E5ODYzYWE4YjEzM2QwMzkxNmU1N2MzNDgzMzBhZmE5MTM5MDFlNGZiMDEwYjk1Y2FiZjlmYmZiZTA4N2QxODMucG5n/a9863aa8b133d03916e57c348330afa913901e4fb010b95cabf9fbfbe087d183.png",
"id": "AHGmnebARD1aa1IiBc",
"last_status_at": "2022-04-16T21:08:35",
"locked": false,
"note": "Creator and CTO of the Digital Telepresence Platform and DTP Technologies, LLC.",
"pleroma": {
"accepts_chat_messages": true,
"also_known_as": [],
"ap_id": "https://nicecrew.digital/users/rob",
"background_image": null,
"deactivated": false,
"favicon": "https://gleasonator.com/proxy/gb2NPo0Kv_svADN1_J9_9iSwlrY/aHR0cHM6Ly9uaWNlY3Jldy5kaWdpdGFsL2Zhdmljb24ucG5n/favicon.png",
"hide_favorites": true,
"hide_followers": true,
"hide_followers_count": false,
"hide_follows": true,
"hide_follows_count": false,
"is_admin": false,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": false,
"location": null,
"relationship": {},
"skip_thread_containment": false,
"tags": []
},
"source": {
"fields": [],
"note": "",
"pleroma": {
"actor_type": "Person",
"discoverable": false
},
"sensitive": false
},
"statuses_count": 761,
"url": "https://nicecrew.digital/users/rob",
"username": "rob"
},
"created_at": "2022-04-16T03:43:24.000Z",
"id": "428608",
"pleroma": {
"is_muted": false,
"is_seen": true
},
"status": {
"account": {
"acct": "alex",
"avatar": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
"avatar_static": "https://media.gleasonator.com/6d64aecb17348b23aaff78db4687b9476cb0da1c07cc6a819c2e6ec7144c18b1.png",
"bot": false,
"created_at": "2020-01-08T01:25:43.000Z",
"display_name": "Alex Gleason",
"emojis": [],
"fields": [
{
"name": "Website",
"value": "<a href=\"https://alexgleason.me\" rel=\"ugc\">https://alexgleason.me</a>"
},
{
"name": "Soapbox",
"value": "<a href=\"https://soapbox.pub\" rel=\"ugc\">https://soapbox.pub</a>"
},
{
"name": "Email",
"value": "alex@alexgleason.me"
},
{
"name": "Gender identity",
"value": "Soyboy"
},
{
"name": "Donate (PayPal)",
"value": "<a href=\"https://paypal.me/gleasonator\" rel=\"ugc\">https://paypal.me/gleasonator</a>"
},
{
"name": "$BTC",
"value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
},
{
"name": "$ETH",
"value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
},
{
"name": "$DOGE",
"value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
},
{
"name": "$XMR",
"value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
}
],
"follow_requests_count": 0,
"followers_count": 2602,
"following_count": 1603,
"fqn": "alex@gleasonator.com",
"header": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
"header_static": "https://media.gleasonator.com/accounts/headers/000/000/001/original/9d0e4dbf1c9dbc8f.png",
"id": "9v5bmRalQvjOy0ECcC",
"last_status_at": "2022-04-16T19:23:50",
"locked": false,
"note": "I create Fediverse software that empowers people online.<br/><br/>I&#39;m vegan btw<br/><br/>Note: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.",
"pleroma": {
"accepts_chat_messages": true,
"accepts_email_list": true,
"allow_following_move": true,
"also_known_as": [
"https://mitra.social/users/alex"
],
"ap_id": "https://gleasonator.com/users/alex",
"background_image": null,
"birthday": "1993-07-03",
"deactivated": false,
"email": "alex@alexgleason.me",
"favicon": "https://gleasonator.com/favicon.png",
"hide_favorites": true,
"hide_followers": false,
"hide_followers_count": false,
"hide_follows": false,
"hide_follows_count": false,
"is_admin": true,
"is_confirmed": true,
"is_moderator": false,
"is_suggested": true,
"location": "Texas",
"notification_settings": {
"block_from_strangers": false,
"hide_notification_contents": false
},
"relationship": {},
"skip_thread_containment": false,
"tags": [],
"unread_conversation_count": 392,
"unread_notifications_count": 0
},
"source": {
"fields": [
{
"name": "Website",
"value": "https://alexgleason.me"
},
{
"name": "Soapbox",
"value": "https://soapbox.pub"
},
{
"name": "Email",
"value": "alex@alexgleason.me"
},
{
"name": "Gender identity",
"value": "Soyboy"
},
{
"name": "Donate (PayPal)",
"value": "https://paypal.me/gleasonator"
},
{
"name": "$BTC",
"value": "bc1q9cx35adpm73aq2fw40ye6ts8hfxqzjr5unwg0n"
},
{
"name": "$ETH",
"value": "0xAc9aB5Fc04Dc1cB1789Af75b523Bd23C70B2D717"
},
{
"name": "$DOGE",
"value": "D5zVZs6jrRakaPVGiErkQiHt9sayzm6V5D"
},
{
"name": "$XMR",
"value": "45JDCLrjJ4bgVUSbbs2yjy9m5Mf4VLPW8fG7jw9sq5u69rXZZopQogZNeyYkMBnXpkaip4p4QwaaJNhdTotPa9g44DBCzdK"
}
],
"note": "I create Fediverse software that empowers people online.\r\n\r\nI'm vegan btw\r\n\r\nNote: If you have a question for me, please tag me publicly. This gives the opportunity for others to chime in, and bystanders to learn.",
"pleroma": {
"actor_type": "Person",
"discoverable": false,
"no_rich_text": false,
"show_birthday": true,
"show_role": true
},
"privacy": "public",
"sensitive": false
},
"statuses_count": 24050,
"url": "https://gleasonator.com/users/alex",
"username": "alex"
},
"application": {
"name": "Soapbox FE",
"website": "https://soapbox.pub/"
},
"bookmarked": false,
"card": null,
"content": "<p>The <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9v5boQSsaxVc3AU8u0\" href=\"https://status.fsf.org/fsf\" rel=\"ugc\">@<span>fsf</span></a></span> needs to give out an award to every American who has never downloaded TikTok.</p>",
"created_at": "2022-04-16T03:42:50.000Z",
"emojis": [],
"favourited": false,
"favourites_count": 15,
"id": "AIUihbqUEe5Uvv7P9s",
"in_reply_to_account_id": null,
"in_reply_to_id": null,
"language": null,
"media_attachments": [],
"mentions": [
{
"acct": "fsf@status.fsf.org",
"id": "9v5boQSsaxVc3AU8u0",
"url": "https://status.fsf.org/fsf",
"username": "fsf"
}
],
"muted": false,
"pinned": false,
"pleroma": {
"content": {
"text/plain": "The @fsf needs to give out an award to every American who has never downloaded TikTok."
},
"content_type": null,
"conversation_id": "AIUihbp4JuxArWSGwq",
"direct_conversation_id": null,
"emoji_reactions": [
{
"count": 2,
"me": false,
"name": "🔥"
}
],
"expires_at": null,
"in_reply_to_account_acct": null,
"local": true,
"parent_visible": false,
"pinned_at": null,
"quote": null,
"quote_url": null,
"quote_visible": false,
"spoiler_text": {
"text/plain": ""
},
"thread_muted": false
},
"poll": null,
"reblog": null,
"reblogged": false,
"reblogs_count": 8,
"replies_count": 4,
"sensitive": false,
"spoiler_text": "",
"tags": [],
"text": null,
"uri": "https://gleasonator.com/objects/6be95787-fb9c-41cd-96cf-9652b2680863",
"url": "https://gleasonator.com/notice/AIUihbqUEe5Uvv7P9s",
"visibility": "public"
},
"type": "reblog"
}

@ -84,7 +84,7 @@ export const defaultSettings = ImmutableMap({
shows: ImmutableMap({
follow: true,
follow_request: false,
follow_request: true,
favourite: true,
reblog: true,
mention: true,

@ -29,7 +29,7 @@ import type {
} from 'soapbox/types/entities';
// Defined in components/scrollable_list
type ScrollPosition = { height: number, top: number };
export type ScrollPosition = { height: number, top: number };
export const textForScreenReader = (intl: IntlShape, status: StatusEntity, rebloggedByText?: string): string => {
const { account } = status;
@ -598,7 +598,7 @@ class Status extends ImmutablePureComponent<IStatus, IStatusState> {
// const domain = getDomain(status.account);
return (
<HotKeys handlers={handlers}>
<HotKeys handlers={handlers} data-testid='status'>
<div
className='status cursor-pointer'
tabIndex={this.props.focusable && !this.props.muted ? 0 : undefined}

@ -0,0 +1,103 @@
import * as React from 'react';
import { updateNotifications } from '../../../../actions/notifications';
import { render, screen, rootState, createTestStore } from '../../../../jest/test-helpers';
import { makeGetNotification } from '../../../../selectors';
import Notification from '../notification';
const getNotification = makeGetNotification();
/** Prepare the notification for use by the component */
const normalize = (notification: any) => {
const store = createTestStore(rootState);
store.dispatch(updateNotifications(notification) as any);
const state = store.getState();
return {
// @ts-ignore
notification: getNotification(state, state.notifications.items.get(notification.id)),
state,
};
};
describe('<Notification />', () => {
it('renders a follow notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-follow.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toBeInTheDocument();
expect(screen.getByTestId('account')).toContainHTML('neko@rdrama.cc');
});
it('renders a favourite notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-favourite.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toContainHTML('Hollahollara@spinster.xyz');
expect(screen.getByTestId('status')).toContainHTML('https://media.gleasonator.com');
});
it('renders a follow_request notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-follow_request.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toBeInTheDocument();
expect(screen.getByTestId('account')).toContainHTML('alex@spinster.xyz');
});
it('renders a mention notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-mention.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toContainHTML('silverpill@mitra.social');
expect(screen.getByTestId('status')).toContainHTML('ActivityPub spec');
});
it('renders a move notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-move.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toContainHTML('alex@fedibird.com');
expect(screen.getByTestId('account')).toContainHTML('benis911');
});
it('renders a pleroma:emoji_reaction notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-pleroma-emoji_reaction.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toContainHTML('😮');
expect(screen.getByTestId('status')).toContainHTML('Super Mario 64');
});
it('renders a pleroma:chat_mention notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-pleroma-chat_mention.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toContainHTML('dave');
});
it('renders a poll notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-poll.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toBeInTheDocument();
expect(screen.getByTestId('status')).toContainHTML('what do you guys think?');
});
it('renders a reblog notification', async() => {
const { notification, state } = normalize(require('soapbox/__fixtures__/notification-reblog.json'));
render(<Notification notification={notification} />, undefined, state);
expect(screen.getByTestId('notification')).toContainHTML('rob@nicecrew.digital');
expect(screen.getByTestId('status')).toContainHTML('never downloaded TikTok');
});
});

@ -1,251 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import { HotKeys } from 'react-hotkeys';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage, useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import Icon from '../../../components/icon';
import Permalink from '../../../components/permalink';
import { HStack, Text } from '../../../components/ui';
import AccountContainer from '../../../containers/account_container';
import StatusContainer from '../../../containers/status_container';
const notificationForScreenReader = (intl, message, timestamp) => {
const output = [message];
output.push(intl.formatDate(timestamp, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }));
return output.join(', ');
};
// Workaround for dynamic messages (https://github.com/formatjs/babel-plugin-react-intl/issues/119#issuecomment-326202499)
function FormattedMessageFixed(props) {
return <FormattedMessage {...props} />;
}
const buildLink = (account) => (
<bdi>
<Permalink
className='text-gray-800 dark:text-gray-200 font-bold hover:underline'
href={`/@${account.get('acct')}`}
title={account.get('acct')}
to={`/@${account.get('acct')}`}
dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }}
/>
</bdi>
);
export const NOTIFICATION_TYPES = ['follow', 'mention', 'favourite', 'reblog', 'status'];
const icons = {
follow: require('@tabler/icons/icons/user-plus.svg'),
mention: require('@tabler/icons/icons/at.svg'),
favourite: require('@tabler/icons/icons/heart.svg'),
reblog: require('@tabler/icons/icons/repeat.svg'),
status: require('@tabler/icons/icons/home.svg'),
};
const messages = {
follow: {
id: 'notification.follow',
defaultMessage: '{name} followed you',
},
mention: {
id: 'notification.mentioned',
defaultMessage: '{name} mentioned you',
},
favourite: {
id: 'notification.favourite',
defaultMessage: '{name} liked your TRUTH',
},
reblog: {
id: 'notification.reblog',
defaultMessage: '{name} re-TRUTH your TRUTH',
},
status: {
id: 'notification.status',
defaultMessage: '{name} just posted',
},
};
const buildMessage = (type, account) => {
const link = buildLink(account);
return (
<FormattedMessageFixed
id={messages[type].id}
defaultMessage={messages[type].defaultMessage}
values={{ name: link }}
/>
);
};
const Notification = (props) => {
const { hidden, notification, onMoveUp, onMoveDown } = props;
const history = useHistory();
const intl = useIntl();
const type = notification.get('type');
const timestamp = notification.get('created_at');
const account = notification.get('account');
const getHandlers = () => ({
reply: handleMention,
favourite: handleHotkeyFavourite,
boost: handleHotkeyBoost,
mention: handleMention,
open: handleOpen,
openProfile: handleOpenProfile,
moveUp: handleMoveUp,
moveDown: handleMoveDown,
toggleHidden: handleHotkeyToggleHidden,
});
const handleOpen = () => {
if (notification.get('status')) {
history.push(`/@${notification.getIn(['account', 'acct'])}/posts/${notification.getIn(['status', 'id'])}`);
} else {
handleOpenProfile();
}
};
const handleOpenProfile = () => {
history.push(`/@${notification.getIn(['account', 'acct'])}`);
};
const handleMention = (event) => {
event.preventDefault();
props.onMention(notification.get('account'), history);
};
const handleHotkeyFavourite = () => {
const status = notification.get('status');
if (status) props.onFavourite(status);
};
const handleHotkeyBoost = (e) => {
const status = notification.get('status');
if (status) props.onReblog(status, e);
};
const handleHotkeyToggleHidden = () => {
const status = notification.get('status');
if (status) props.onToggleHidden(status);
};
const handleMoveUp = () => {
onMoveUp(notification.get('id'));
};
const handleMoveDown = () => {
onMoveDown(notification.get('id'));
};
const renderContent = () => {
switch (type) {
case 'follow':
return (
<AccountContainer
id={notification.getIn(['account', 'id'])}
withNote={false}
hidden={hidden}
avatarSize={48}
/>
);
case 'favourite':
case 'mention':
case 'reblog':
case 'status':
return (
<StatusContainer
id={notification.getIn(['status', 'id'])}
withDismiss
hidden={hidden}
onMoveDown={handleMoveDown}
onMoveUp={handleMoveUp}
contextType='notifications'
getScrollPosition={props.getScrollPosition}
updateScrollBottom={props.updateScrollBottom}
cachedMediaWidth={props.cachedMediaWidth}
cacheMediaWidth={props.cacheMediaWidth}
/>
);
default:
return null;
}
};
if (!NOTIFICATION_TYPES.includes(type)) {
return null;
}
const message = buildMessage(type, account);
return (
<HotKeys handlers={getHandlers()}>
<div
className='notification focusable'
tabIndex='0'
aria-label={
notificationForScreenReader(
intl,
intl.formatMessage({
id: messages[type].id,
defaultMessage: messages[type].defaultMessage,
},
{
name: notification.getIn(['account', 'acct']),
}),
notification.get('created_at'),
)
}
>
<div className='p-4 focusable'>
<div className='mb-2'>
<HStack alignItems='center' space={1.5}>
<Icon
src={icons[type]}
className='text-primary-600'
/>
<div>
<Text
theme='muted'
size='sm'
title={timestamp}
>
{message}
</Text>
</div>
</HStack>
</div>
<div>
{renderContent()}
</div>
</div>
</div>
</HotKeys>
);
};
Notification.propTypes = {
hidden: PropTypes.bool,
notification: ImmutablePropTypes.record.isRequired,
onMoveUp: PropTypes.func.isRequired,
onMoveDown: PropTypes.func.isRequired,
onMention: PropTypes.func.isRequired,
onFavourite: PropTypes.func.isRequired,
onReblog: PropTypes.func.isRequired,
onToggleHidden: PropTypes.func.isRequired,
getScrollPosition: PropTypes.func,
updateScrollBottom: PropTypes.func,
cacheMediaWidth: PropTypes.func,
cachedMediaWidth: PropTypes.number,
siteTitle: PropTypes.string,
};
export default Notification;

@ -0,0 +1,307 @@
import React from 'react';
import { HotKeys } from 'react-hotkeys';
import { FormattedMessage, useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import Icon from '../../../components/icon';
import Permalink from '../../../components/permalink';
import { HStack, Text, Emoji } from '../../../components/ui';
import AccountContainer from '../../../containers/account_container';
import StatusContainer from '../../../containers/status_container';
import type { History } from 'history';
import type { ScrollPosition } from 'soapbox/components/status';
import type { NotificationType } from 'soapbox/normalizers/notification';
import type { Account, Status, Notification as NotificationEntity } from 'soapbox/types/entities';
const notificationForScreenReader = (intl: ReturnType<typeof useIntl>, message: string, timestamp: Date) => {
const output = [message];
output.push(intl.formatDate(timestamp, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }));
return output.join(', ');
};
// Workaround for dynamic messages (https://github.com/formatjs/babel-plugin-react-intl/issues/119#issuecomment-326202499)
function FormattedMessageFixed(props: any) {
return <FormattedMessage {...props} />;
}
const buildLink = (account: Account): JSX.Element => (
<bdi>
<Permalink
className='text-gray-800 dark:text-gray-200 font-bold hover:underline'
href={`/@${account.acct}`}
title={account.acct}
to={`/@${account.acct}`}
dangerouslySetInnerHTML={{ __html: account.display_name_html }}
/>
</bdi>
);
const icons: Record<NotificationType, string> = {
follow: require('@tabler/icons/icons/user-plus.svg'),
follow_request: require('@tabler/icons/icons/user-plus.svg'),
mention: require('@tabler/icons/icons/at.svg'),
favourite: require('@tabler/icons/icons/heart.svg'),
reblog: require('@tabler/icons/icons/repeat.svg'),
status: require('@tabler/icons/icons/home.svg'),
poll: require('@tabler/icons/icons/chart-bar.svg'),
move: require('@tabler/icons/icons/briefcase.svg'),
'pleroma:chat_mention': require('@tabler/icons/icons/messages.svg'),
'pleroma:emoji_reaction': require('@tabler/icons/icons/mood-happy.svg'),
};
const messages: Record<NotificationType, { id: string, defaultMessage: string }> = {
follow: {
id: 'notification.follow',
defaultMessage: '{name} followed you',
},
follow_request: {
id: 'notification.follow_request',
defaultMessage: '{name} has requested to follow you',
},
mention: {
id: 'notification.mentioned',
defaultMessage: '{name} mentioned you',
},
favourite: {
id: 'notification.favourite',
defaultMessage: '{name} liked your post',
},
reblog: {
id: 'notification.reblog',
defaultMessage: '{name} reposted your post',
},
status: {
id: 'notification.status',
defaultMessage: '{name} just posted',
},
poll: {
id: 'notification.poll',
defaultMessage: 'A poll you have voted in has ended',
},
move: {
id: 'notification.move',
defaultMessage: '{name} moved to {targetName}',
},
'pleroma:chat_mention': {
id: 'notification.chat_mention',
defaultMessage: '{name} sent you a message',
},
'pleroma:emoji_reaction': {
id: 'notification.pleroma:emoji_reaction',
defaultMessage: '{name} reacted to your post',
},
};
const buildMessage = (type: NotificationType, account: Account): JSX.Element => {
const link = buildLink(account);
return (
<FormattedMessageFixed
id={messages[type].id}
defaultMessage={messages[type].defaultMessage}
values={{ name: link }}
/>
);
};
interface INotificaton {
hidden?: boolean,
notification: NotificationEntity,
onMoveUp: (notificationId: string) => void,
onMoveDown: (notificationId: string) => void,
onMention: (account: Account, history: History) => void,
onFavourite: (status: Status) => void,
onReblog: (status: Status, e?: KeyboardEvent) => void,
onToggleHidden: (status: Status) => void,
getScrollPosition?: () => ScrollPosition | undefined,
updateScrollBottom?: (bottom: number) => void,
cacheMediaWidth: () => void,
cachedMediaWidth: number,
siteTitle?: string,
}
const Notification: React.FC<INotificaton> = (props) => {
const { hidden = false, notification, onMoveUp, onMoveDown } = props;
const history = useHistory();
const intl = useIntl();
const type = notification.type;
const { account, status } = notification;
const getHandlers = () => ({
reply: handleMention,
favourite: handleHotkeyFavourite,
boost: handleHotkeyBoost,
mention: handleMention,
open: handleOpen,
openProfile: handleOpenProfile,
moveUp: handleMoveUp,
moveDown: handleMoveDown,
toggleHidden: handleHotkeyToggleHidden,
});
const handleOpen = () => {
if (status && typeof status === 'object' && account && typeof account === 'object') {
history.push(`/@${account.acct}/posts/${status.id}`);
} else {
handleOpenProfile();
}
};
const handleOpenProfile = () => {
if (account && typeof account === 'object') {
history.push(`/@${account.acct}`);
}
};
const handleMention = (e?: KeyboardEvent) => {
e?.preventDefault();
if (account && typeof account === 'object') {
props.onMention(account, history);
}
};
const handleHotkeyFavourite = (e?: KeyboardEvent) => {
if (status && typeof status === 'object') {
props.onFavourite(status);
}
};
const handleHotkeyBoost = (e?: KeyboardEvent) => {
if (status && typeof status === 'object') {
props.onReblog(status, e);
}
};
const handleHotkeyToggleHidden = (e?: KeyboardEvent) => {
if (status && typeof status === 'object') {
props.onToggleHidden(status);
}
};
const handleMoveUp = () => {
onMoveUp(notification.id);
};
const handleMoveDown = () => {
onMoveDown(notification.id);
};
const renderIcon = (): React.ReactNode => {
if (type === 'pleroma:emoji_reaction' && notification.emoji) {
return (
<Emoji
emoji={notification.emoji}
className='w-4 h-4'
/>
);
} else if (type) {
return (
<Icon
src={icons[type]}
className='text-primary-600'
/>
);
} else {
return null;
}
};
const renderContent = () => {
switch (type) {
case 'follow':
case 'follow_request':
return account && typeof account === 'object' ? (
<AccountContainer
id={account.id}
hidden={hidden}
avatarSize={48}
/>
) : null;
case 'move':
return account && typeof account === 'object' && notification.target && typeof notification.target === 'object' ? (
<AccountContainer
id={notification.target.id}
hidden={hidden}
avatarSize={48}
/>
) : null;
case 'favourite':
case 'mention':
case 'reblog':
case 'status':
case 'poll':
case 'pleroma:emoji_reaction':
return status && typeof status === 'object' ? (
<StatusContainer
// @ts-ignore
id={status.id}
withDismiss
hidden={hidden}
onMoveDown={handleMoveDown}
onMoveUp={handleMoveUp}
contextType='notifications'
getScrollPosition={props.getScrollPosition}
updateScrollBottom={props.updateScrollBottom}
cachedMediaWidth={props.cachedMediaWidth}
cacheMediaWidth={props.cacheMediaWidth}
/>
) : null;
default:
return null;
}
};
const message: React.ReactNode = type && account && typeof account === 'object' ? buildMessage(type, account) : null;
return (
<HotKeys handlers={getHandlers()} data-testid='notification'>
<div
className='notification focusable'
tabIndex={0}
aria-label={
notificationForScreenReader(
intl,
intl.formatMessage({
id: type && messages[type].id,
defaultMessage: type && messages[type].defaultMessage,
},
{
name: account && typeof account === 'object' ? account.acct : '',
targetName: notification.target && typeof notification.target === 'object' ? notification.target.acct : '',
}),
notification.created_at,
)
}
>
<div className='p-4 focusable'>
<div className='mb-2'>
<HStack alignItems='center' space={1.5}>
{renderIcon()}
<div>
<Text
theme='muted'
size='sm'
>
{message}
</Text>
</div>
</HStack>
</div>
<div>
{renderContent()}
</div>
</div>
</div>
</HotKeys>
);
};
export default Notification;

@ -23,7 +23,6 @@ import ScrollableList from '../../components/scrollable_list';
import TimelineQueueButtonHeader from '../../components/timeline_queue_button_header';
import { Column } from '../../components/ui';
import { NOTIFICATION_TYPES } from './components/notification';
import FilterBarContainer from './containers/filter_bar_container';
import NotificationContainer from './containers/notification_container';
@ -200,13 +199,12 @@ class Notifications extends React.PureComponent {
}
this.scrollableContent = scrollableContent;
const notificationsToRender = notifications.filter((notification) => NOTIFICATION_TYPES.includes(notification.get('type')));
const scrollContainer = (
<ScrollableList
scrollKey='notifications'
isLoading={isLoading}
showLoading={isLoading && notificationsToRender.size === 0}
showLoading={isLoading && notifications.size === 0}
hasMore={hasMore}
emptyMessage={emptyMessage}
placeholderComponent={PlaceholderNotification}
@ -216,8 +214,8 @@ class Notifications extends React.PureComponent {
onScrollToTop={this.handleScrollToTop}
onScroll={this.handleScroll}
className={classNames({
'divide-y divide-gray-200 dark:divide-gray-600 divide-solid': notificationsToRender.size > 0,
'space-y-2': notificationsToRender.size === 0,
'divide-y divide-gray-200 dark:divide-gray-600 divide-solid': notifications.size > 0,
'space-y-2': notifications.size === 0,
})}
>
{scrollableContent}

@ -70,4 +70,5 @@ export {
applyActions,
rootState,
rootReducer,
createTestStore,
};

@ -11,8 +11,8 @@ import {
import type { Account, Status, EmbeddedEntity } from 'soapbox/types/entities';
type NotificationType = ''
| 'follow'
export type NotificationType =
'follow'
| 'follow_request'
| 'mention'
| 'reblog'
@ -32,7 +32,7 @@ export const NotificationRecord = ImmutableRecord({
id: '',
status: null as EmbeddedEntity<Status>,
target: null as EmbeddedEntity<Account>, // move
type: '' as NotificationType,
type: '' as NotificationType | '',
});
export const normalizeNotification = (notification: Record<string, any>) => {

@ -188,6 +188,16 @@ describe('notifications reducer', () => {
expect(result.items.get('10743').type).toEqual('favourite');
});
it('imports follow_request notification', () => {
const action = {
type: NOTIFICATIONS_UPDATE,
notification: require('soapbox/__fixtures__/notification-follow_request.json'),
};
const result = reducer(initialState, action);
expect(result.items.get('87967').type).toEqual('follow_request');
});
it('increments `unread` counter when top is false', () => {
const action = { type: NOTIFICATIONS_UPDATE, notification };
const result = reducer(initialState, action);

@ -1,4 +1,7 @@
import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutable';
import {
Map as ImmutableMap,
OrderedSet as ImmutableOrderedSet,
} from 'immutable';
import {
FOLLOWERS_FETCH_SUCCESS,
@ -68,13 +71,13 @@ const normalizeList = (state, type, id, accounts, next) => {
const appendToList = (state, type, id, accounts, next) => {
return state.updateIn([type, id], map => {
return map.set('next', next).update('items', list => list.concat(accounts.map(item => item.id)));
return map.set('next', next).update('items', ImmutableOrderedSet(), list => list.concat(accounts.map(item => item.id)));
});
};
const normalizeFollowRequest = (state, notification) => {
return state.updateIn(['follow_requests', 'items'], list => {
return list.filterNot(item => item === notification.account.id).unshift(notification.account.id);
return state.updateIn(['follow_requests', 'items'], ImmutableOrderedSet(), list => {
return ImmutableOrderedSet([notification.account.id]).union(list);
});
};

Loading…
Cancel
Save