diff --git a/README.md b/README.md index f235868f..aab25c0e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Phanpy
+**πŸ—£οΈ Pronunciation**: [`/fΓ¦npi/`](https://ythi.net/how-do-you-pronounce/phanpy/english/) ([`FAN-pee`](https://www.smogon.com/forums/threads/the-official-name-pronunciation-guide.3474941/)) [πŸ”Š Listen](https://www.youtube.com/watch?v=DIUbWe-ysJI) + This is an alternative web client for [Mastodon](https://joinmastodon.org/). - 🏒 **Production**: https://phanpy.social @@ -23,13 +25,7 @@ This is an alternative web client for [Mastodon](https://joinmastodon.org/). 🐘 Follow [@phanpy on Mastodon](https://hachyderm.io/@phanpy) for updates ✨ -Everything is designed and engineered for my own use case, following my taste and vision. This is a personal side project for me to learn about Mastodon and experiment with new UI/UX ideas. - -🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧 - -**🐘 This is an early ALPHA project. Many features are missing, many bugs are present. Please report issues as detailed as possible. Thanks πŸ™** - -🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧🚧 +Everything is designed and engineered following my taste and vision. This is a personal side project for me to learn about Mastodon and experiment with new UI/UX ideas. ## Features @@ -37,7 +33,7 @@ Everything is designed and engineered for my own use case, following my taste an - πŸͺŸ Compose window pop-out/in - πŸŒ— Light/dark/auto theme - πŸ”” Grouped notifications -- πŸͺΊ Nested replies view +- πŸͺΊ Nested comments thread - πŸ“¬Β Unsent draft recovery - 🎠 Boosts Carouselℒ️ - ⚑ Shortcutsℒ️ with view modes like multi-column or tab bar @@ -51,6 +47,33 @@ Everything is designed and engineered for my own use case, following my taste an - **No autoplay for video/GIF/whatever in timeline**.
The timeline is already a huge mess with lots of people, brands, news and media trying to grab your attention. Let's not make it worse. (Current exception now would be animated emojis.) - **Hash-based URLs**.
This web app is not meant to be a full-fledged replacement to Mastodon's existing front-end. There's no SEO, database, serverless or any long-running servers. I could be wrong one day. +## Subtle UI implementations + +### User name display + +![User name display](readme-assets/user-name-display.jpg) + +- On the timeline, the user name is displayed as `[NAME] @[username]`. +- For the `@[username]`, always exclude the instance domain name. +- If the `[NAME]` *looks the same* as the `@[username]`, then the `@[username]` is excluded as well. + +### Boosts Carousel + +![Boosts Carousel](readme-assets/boosts-carousel.jpg) + +- 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. +- 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"). +- Else, boosts carousel UI will be slotted in between the posts. + +### Thread number badge (e.g. Thread 1/X) + +![Thread number badge](readme-assets/thread-number-badge.jpg) + +- Check every post for `inReplyToId` from cache or additional API requests, until the root post is found. +- If root post is found, badge will show the index number of the post in the thread. +- Limit up to 3 API requests as the root post may be very old or the thread is super long. +- If index number couldn't be found, badge will fallback to showing `Thread` without the number. + ## Development Prerequisites: Node.js 18+ @@ -63,6 +86,12 @@ Prerequisites: Node.js 18+ - requires `.env.dev` file with `INSTANCES_SOCIAL_SECRET_TOKEN` variable set - `npm run sourcemap` - Run `source-map-explorer` on the production build +## Self-hosting + +This is a **pure static web app**. You can host it anywhere you want. Build it by running `npm run build` and serve the `dist` folder. + +Try search for "how to self-host static sites" as there are many ways to do it. + ## Tech stack - [Vite](https://vitejs.dev/) - Build tool diff --git a/package-lock.json b/package-lock.json index 906d5451..ac8811d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,16 +10,16 @@ "dependencies": { "@formatjs/intl-localematcher": "~0.2.32", "@github/text-expander-element": "~2.3.0", - "@iconify-icons/mingcute": "~1.2.4", + "@iconify-icons/mingcute": "~1.2.5", "@justinribeiro/lite-youtube": "~1.5.0", - "@szhsin/react-menu": "~3.5.2", + "@szhsin/react-menu": "~3.5.3", "dayjs": "~1.11.7", "dayjs-twitter": "~0.5.0", "fast-blurhash": "~1.1.2", "fast-deep-equal": "~3.1.3", - "idb-keyval": "~6.2.0", + "idb-keyval": "~6.2.1", "just-debounce-it": "~3.2.0", - "masto": "~5.11.2", + "masto": "~5.11.3", "mem": "~9.0.2", "p-retry": "~5.1.2", "p-throttle": "~5.0.0", @@ -33,7 +33,7 @@ "toastify-js": "~1.12.0", "uid": "~2.0.2", "use-debounce": "~9.0.4", - "use-long-press": "~3.1.0", + "use-long-press": "~3.1.3", "use-resize-observer": "~9.1.0", "valtio": "1.9.0" }, @@ -44,7 +44,7 @@ "postcss-dark-theme-class": "~0.7.3", "postcss-preset-env": "~8.3.2", "twitter-text": "~3.1.0", - "vite": "~4.3.3", + "vite": "~4.3.5", "vite-plugin-generate-file": "~0.0.4", "vite-plugin-html-config": "~1.0.11", "vite-plugin-pwa": "~0.14.7", @@ -2667,9 +2667,9 @@ } }, "node_modules/@iconify-icons/mingcute": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@iconify-icons/mingcute/-/mingcute-1.2.4.tgz", - "integrity": "sha512-4aaWYa6GxSdYmJg8iBVx6VDuKUcTDEbio929+GrswoxfyTsPUkOOgw2wffUDHjE3JDUAnrWj9teQTnBkFm7Gyg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@iconify-icons/mingcute/-/mingcute-1.2.5.tgz", + "integrity": "sha512-fTzhb0TVYuD89Do9sUR9mu2RYZ2XGOyOxzoZL2W53R9w+j0myuo0bnRpoGlbnXPV+/N+P8vUBJEsQRWvmEPQfw==", "dependencies": { "@iconify/types": "*" } @@ -2962,9 +2962,9 @@ } }, "node_modules/@szhsin/react-menu": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-3.5.2.tgz", - "integrity": "sha512-eR7dzDBrwlt9RSgGmLXjfA1Rd5tYqD5mnqjQgZJysf3Jt3vBPkrbDT1oW21nLpfUCkyUQOuZ38n2IdhWl9KkzQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-3.5.3.tgz", + "integrity": "sha512-jxo8oaRwxmVjUzkyOi/ZJiXaZiuFPMIxFzyJdUKfnhBLYiEOVTU9M2CiPuEkirILoareR2GJj2K3y8a81CBPlw==", "dependencies": { "prop-types": "^15.7.2", "react-transition-state": "^1.1.5" @@ -4293,12 +4293,9 @@ "dev": true }, "node_modules/idb-keyval": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.0.tgz", - "integrity": "sha512-uw+MIyQn2jl3+hroD7hF8J7PUviBU7BPKWw4f/ISf32D4LoGu98yHjrzWWJDASu9QNrX10tCJqk9YY0ClWm8Ng==", - "dependencies": { - "safari-14-idb-fix": "^3.0.0" - } + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", + "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==" }, "node_modules/inflight": { "version": "1.0.6", @@ -4860,9 +4857,9 @@ } }, "node_modules/masto": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/masto/-/masto-5.11.2.tgz", - "integrity": "sha512-1F2O4itZXCchqmGh/Dor+AfgyxKGfUrquLK81H+Adw9vs5BoOtdNThuFhXf1m2enXzbVEvJUwxBVd82s2x5FSg==", + "version": "5.11.3", + "resolved": "https://registry.npmjs.org/masto/-/masto-5.11.3.tgz", + "integrity": "sha512-GtSnrqm5fHPaaU0iwag4LCmvpp82rDng6yOZinmOJHHlUfo6Gnq5QY6x3lJCxCnsPIXpTu1yaX42bWrSQyoQPA==", "dependencies": { "@mastojs/ponyfills": "^1.0.4", "change-case": "^4.1.2", @@ -4870,7 +4867,7 @@ "isomorphic-ws": "^5.0.0", "qs": "^6.11.0", "semver": "^7.3.7", - "ws": "^8.12.0" + "ws": "^8.13.0" } }, "node_modules/masto/node_modules/semver": { @@ -6198,11 +6195,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safari-14-idb-fix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/safari-14-idb-fix/-/safari-14-idb-fix-3.0.0.tgz", - "integrity": "sha512-eBNFLob4PMq8JA1dGyFn6G97q3/WzNtFK4RnzT1fnLq+9RyrGknzYiM/9B12MnKAxuj1IXr7UKYtTNtjyKMBog==" - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6739,9 +6731,9 @@ } }, "node_modules/use-long-press": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/use-long-press/-/use-long-press-3.1.0.tgz", - "integrity": "sha512-SSCCgsIlGql/gWRf5v/5CoWxUkSccFuLiMO2tjggUdf0qt5FGb/TD1l0aJ2j+G3J0BT2a7jsJQIDsmUiUuhRTg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/use-long-press/-/use-long-press-3.1.3.tgz", + "integrity": "sha512-RAK+i3mIPAFL10Q9wVqfzjDTIg/oXSB60c+bbwNkc1GzIWNF7UfRydJ2VX8IQ+yG2eptzEuWb1CmJc2UNu6fOg==", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -6793,9 +6785,9 @@ } }, "node_modules/vite": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.3.tgz", - "integrity": "sha512-MwFlLBO4udZXd+VBcezo3u8mC77YQk+ik+fbc0GZWGgzfbPP+8Kf0fldhARqvSYmtIWoAJ5BXPClUbMTlqFxrA==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.5.tgz", + "integrity": "sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==", "dev": true, "dependencies": { "esbuild": "^0.17.5", @@ -7334,9 +7326,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "engines": { "node": ">=10.0.0" }, @@ -8964,9 +8956,9 @@ } }, "@iconify-icons/mingcute": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@iconify-icons/mingcute/-/mingcute-1.2.4.tgz", - "integrity": "sha512-4aaWYa6GxSdYmJg8iBVx6VDuKUcTDEbio929+GrswoxfyTsPUkOOgw2wffUDHjE3JDUAnrWj9teQTnBkFm7Gyg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@iconify-icons/mingcute/-/mingcute-1.2.5.tgz", + "integrity": "sha512-fTzhb0TVYuD89Do9sUR9mu2RYZ2XGOyOxzoZL2W53R9w+j0myuo0bnRpoGlbnXPV+/N+P8vUBJEsQRWvmEPQfw==", "requires": { "@iconify/types": "*" } @@ -9198,9 +9190,9 @@ } }, "@szhsin/react-menu": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-3.5.2.tgz", - "integrity": "sha512-eR7dzDBrwlt9RSgGmLXjfA1Rd5tYqD5mnqjQgZJysf3Jt3vBPkrbDT1oW21nLpfUCkyUQOuZ38n2IdhWl9KkzQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@szhsin/react-menu/-/react-menu-3.5.3.tgz", + "integrity": "sha512-jxo8oaRwxmVjUzkyOi/ZJiXaZiuFPMIxFzyJdUKfnhBLYiEOVTU9M2CiPuEkirILoareR2GJj2K3y8a81CBPlw==", "requires": { "prop-types": "^15.7.2", "react-transition-state": "^1.1.5" @@ -10204,12 +10196,9 @@ "dev": true }, "idb-keyval": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.0.tgz", - "integrity": "sha512-uw+MIyQn2jl3+hroD7hF8J7PUviBU7BPKWw4f/ISf32D4LoGu98yHjrzWWJDASu9QNrX10tCJqk9YY0ClWm8Ng==", - "requires": { - "safari-14-idb-fix": "^3.0.0" - } + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", + "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==" }, "inflight": { "version": "1.0.6", @@ -10621,9 +10610,9 @@ } }, "masto": { - "version": "5.11.2", - "resolved": "https://registry.npmjs.org/masto/-/masto-5.11.2.tgz", - "integrity": "sha512-1F2O4itZXCchqmGh/Dor+AfgyxKGfUrquLK81H+Adw9vs5BoOtdNThuFhXf1m2enXzbVEvJUwxBVd82s2x5FSg==", + "version": "5.11.3", + "resolved": "https://registry.npmjs.org/masto/-/masto-5.11.3.tgz", + "integrity": "sha512-GtSnrqm5fHPaaU0iwag4LCmvpp82rDng6yOZinmOJHHlUfo6Gnq5QY6x3lJCxCnsPIXpTu1yaX42bWrSQyoQPA==", "requires": { "@mastojs/ponyfills": "^1.0.4", "change-case": "^4.1.2", @@ -10631,7 +10620,7 @@ "isomorphic-ws": "^5.0.0", "qs": "^6.11.0", "semver": "^7.3.7", - "ws": "^8.12.0" + "ws": "^8.13.0" }, "dependencies": { "semver": { @@ -11455,11 +11444,6 @@ "queue-microtask": "^1.2.2" } }, - "safari-14-idb-fix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/safari-14-idb-fix/-/safari-14-idb-fix-3.0.0.tgz", - "integrity": "sha512-eBNFLob4PMq8JA1dGyFn6G97q3/WzNtFK4RnzT1fnLq+9RyrGknzYiM/9B12MnKAxuj1IXr7UKYtTNtjyKMBog==" - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -11857,9 +11841,9 @@ "requires": {} }, "use-long-press": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/use-long-press/-/use-long-press-3.1.0.tgz", - "integrity": "sha512-SSCCgsIlGql/gWRf5v/5CoWxUkSccFuLiMO2tjggUdf0qt5FGb/TD1l0aJ2j+G3J0BT2a7jsJQIDsmUiUuhRTg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/use-long-press/-/use-long-press-3.1.3.tgz", + "integrity": "sha512-RAK+i3mIPAFL10Q9wVqfzjDTIg/oXSB60c+bbwNkc1GzIWNF7UfRydJ2VX8IQ+yG2eptzEuWb1CmJc2UNu6fOg==", "requires": {} }, "use-resize-observer": { @@ -11892,9 +11876,9 @@ } }, "vite": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.3.tgz", - "integrity": "sha512-MwFlLBO4udZXd+VBcezo3u8mC77YQk+ik+fbc0GZWGgzfbPP+8Kf0fldhARqvSYmtIWoAJ5BXPClUbMTlqFxrA==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.5.tgz", + "integrity": "sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==", "dev": true, "requires": { "esbuild": "^0.17.5", @@ -12314,9 +12298,9 @@ "dev": true }, "ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "requires": {} }, "yallist": { diff --git a/package.json b/package.json index 91a72cd4..54eff130 100644 --- a/package.json +++ b/package.json @@ -12,16 +12,16 @@ "dependencies": { "@formatjs/intl-localematcher": "~0.2.32", "@github/text-expander-element": "~2.3.0", - "@iconify-icons/mingcute": "~1.2.4", + "@iconify-icons/mingcute": "~1.2.5", "@justinribeiro/lite-youtube": "~1.5.0", - "@szhsin/react-menu": "~3.5.2", + "@szhsin/react-menu": "~3.5.3", "dayjs": "~1.11.7", "dayjs-twitter": "~0.5.0", "fast-blurhash": "~1.1.2", "fast-deep-equal": "~3.1.3", - "idb-keyval": "~6.2.0", + "idb-keyval": "~6.2.1", "just-debounce-it": "~3.2.0", - "masto": "~5.11.2", + "masto": "~5.11.3", "mem": "~9.0.2", "p-retry": "~5.1.2", "p-throttle": "~5.0.0", @@ -35,7 +35,7 @@ "toastify-js": "~1.12.0", "uid": "~2.0.2", "use-debounce": "~9.0.4", - "use-long-press": "~3.1.0", + "use-long-press": "~3.1.3", "use-resize-observer": "~9.1.0", "valtio": "1.9.0" }, @@ -46,7 +46,7 @@ "postcss-dark-theme-class": "~0.7.3", "postcss-preset-env": "~8.3.2", "twitter-text": "~3.1.0", - "vite": "~4.3.3", + "vite": "~4.3.5", "vite-plugin-generate-file": "~0.0.4", "vite-plugin-html-config": "~1.0.11", "vite-plugin-pwa": "~0.14.7", diff --git a/readme-assets/boosts-carousel.jpg b/readme-assets/boosts-carousel.jpg new file mode 100644 index 00000000..610f23df Binary files /dev/null and b/readme-assets/boosts-carousel.jpg differ diff --git a/readme-assets/thread-number-badge.jpg b/readme-assets/thread-number-badge.jpg new file mode 100644 index 00000000..8519e062 Binary files /dev/null and b/readme-assets/thread-number-badge.jpg differ diff --git a/readme-assets/user-name-display.jpg b/readme-assets/user-name-display.jpg new file mode 100644 index 00000000..01802ec0 Binary files /dev/null and b/readme-assets/user-name-display.jpg differ diff --git a/src/app.css b/src/app.css index 10c41f09..753688e9 100644 --- a/src/app.css +++ b/src/app.css @@ -256,6 +256,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .timeline.contextual > li.descendant:not(.thread) > .status-link { padding-left: 40px; } +.timeline.contextual .replies[data-scroll-left]:not([data-scroll-left='0']) { + background-color: var(--bg-color); + box-shadow: inset 0 -3px var(--comment-line-color), + inset 0 3px var(--comment-line-color); +} .timeline.contextual .replies[data-comments-level='4'] { overflow: auto; } @@ -272,7 +277,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .replies[data-comments-level='4'] .replies[data-comments-level-overflow='true'] .status { - min-width: min(15em, 75vw); + min-width: min(20em, 80vw); } .timeline.contextual > li.descendant.thread @@ -432,7 +437,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .timeline.contextual > li .replies { margin-top: -12px; } -.timeline.contextual > li .replies :is(ul, li) { +.timeline.contextual > li .replies :is(ul, li):not(.content *) { margin: 0; padding: 0; list-style: none; @@ -478,10 +483,10 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .timeline.contextual > li .replies .replies-summary[hidden] { display: none; } -.timeline.contextual > li .replies li { +.timeline.contextual > li .replies li:not(.content li) { position: relative; } -.timeline.contextual > li .replies li { +.timeline.contextual > li .replies li:not(.content li) { --line-start: calc( var(--thread-start) + var(--line-margin-end) * var(--comments-level) ); @@ -503,7 +508,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .timeline.contextual > li .replies .replies .replies li { --line-start: calc(var(--thread-start) + (var(--line-margin-end) * 3)); } */ -.timeline.contextual > li.thread .replies li { +.timeline.contextual > li.thread .replies li:not(.content li) { --line-start: calc( var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + (var(--line-margin-end) * (var(--comments-level) - 1)) @@ -521,10 +526,10 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { (var(--line-margin-end) * 2) ); } */ -.timeline.contextual > li .replies li:last-child { +.timeline.contextual > li .replies li:not(.content li):last-child { background-size: 100% 20px; } -.timeline.contextual > li .replies li:before { +.timeline.contextual > li .replies li:not(.content li):before { content: ''; position: absolute; top: 10px; @@ -547,7 +552,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { var(--thread-start) + var(--line-margin-end) + (var(--line-margin-end) * 2) ); } */ -.timeline.contextual > li.thread .replies li:before { +.timeline.contextual > li.thread .replies li:not(.content li):before { --line-start: calc( var(--avatar-size) + var(--avatar-margin-start) + var(--avatar-margin-end) + (var(--line-margin-end) * (var(--comments-level) - 1)) @@ -709,7 +714,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { color: var(--carousel-color); text-shadow: 0 1px var(--bg-color); } -.status-carousel ul { +.status-carousel > ul { display: flex; overflow-x: auto; overflow-y: hidden; @@ -721,7 +726,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { align-items: flex-start; counter-reset: index; } -.status-carousel ul > li { +.status-carousel > ul > li { scroll-snap-align: center; scroll-snap-stop: always; flex-shrink: 0; @@ -736,8 +741,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { counter-increment: index; position: relative; } +.status-carousel > ul > li:is(:empty, :has(> a:empty)) { + display: none; +} @media (hover: hover) or (pointer: fine) or (min-width: 40em) { - .status-carousel ul { + .status-carousel > ul { scroll-snap-type: none; } } @@ -759,7 +767,7 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) { .status-carousel.boosts-carousel .status-reblog { background-image: none; } -.status-carousel.boosts-carousel ul > li:before { +.status-carousel.boosts-carousel > ul > li:before { content: counter(index); position: absolute; left: 0; @@ -1158,12 +1166,12 @@ body:has(.media-modal-container + .status-deck) .media-post-link { padding: 16px; background-color: var(--button-bg-blur-color); backdrop-filter: blur(16px); - z-index: 1; + z-index: 10; box-shadow: 0 3px 8px -1px var(--drop-shadow-color), 0 10px 36px -4px var(--button-bg-blur-color); transition: all 0.3s ease-in-out; } -#home-page:has(header[hidden]) ~ #compose-button, +.deck-container:has(header[hidden]) ~ #compose-button, #compose-button[hidden] { transform: translateY(200%); pointer-events: none; @@ -1309,6 +1317,9 @@ body:has(.media-modal-container + .status-deck) .media-post-link { .tag .icon { vertical-align: middle; } +.tag.collapsed { + margin: 0; +} /* MENU POPUP */ @@ -1897,6 +1908,9 @@ ul.link-list li a .icon { ); align-items: center; } +.filter-bar.centered { + justify-content: center; +} @media (min-width: 40em) { .filter-bar { background-color: transparent; diff --git a/src/app.jsx b/src/app.jsx index a2b4c2b3..63357bff 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -21,6 +21,7 @@ import { useSnapshot } from 'valtio'; import AccountSheet from './components/account-sheet'; import Compose from './components/compose'; import Drafts from './components/drafts'; +import Icon from './components/icon'; import Loader from './components/loader'; import MediaModal from './components/media-modal'; import Modal from './components/modal'; @@ -55,6 +56,7 @@ import { initPreferences, } from './utils/api'; import { getAccessToken } from './utils/auth'; +import openCompose from './utils/open-compose'; import showToast from './utils/show-toast'; import states, { getStatus, saveStatus } from './utils/states'; import store from './utils/store'; @@ -110,7 +112,7 @@ function App() { const masto = initClient({ instance: instanceURL, accessToken }); await Promise.allSettled([ - initInstance(masto), + initInstance(masto, instanceURL), initAccount(masto, instanceURL, accessToken), ]); initPreferences(masto); @@ -122,13 +124,13 @@ function App() { const account = getCurrentAccount(); if (account) { store.session.set('currentAccount', account.info.id); - const { masto } = api({ account }); + const { masto, instance } = api({ account }); console.log('masto', masto); initPreferences(masto); setUIState('loading'); (async () => { try { - await initInstance(masto); + await initInstance(masto, instance); } catch (e) { } finally { setIsLoggedIn(true); @@ -263,13 +265,30 @@ function App() { } /> )} -
- {isLoggedIn && - !snapStates.settings.shortcutsColumnsMode && - snapStates.settings.shortcutsViewMode !== 'multi-column' && ( - - )} -
+ {isLoggedIn && ( + + )} + {isLoggedIn && + !snapStates.settings.shortcutsColumnsMode && + snapStates.settings.shortcutsViewMode !== 'multi-column' && ( + + )} {!!snapStates.showCompose && ( { @@ -484,7 +503,7 @@ function BackgroundService({ isLoggedIn }) { console.error(e); }); }; - useInterval(() => checkForUpdates, visible && 1000 * 60 * 30); // 30 minutes + useInterval(checkForUpdates, visible && 1000 * 60 * 30); // 30 minutes usePageVisibility((visible) => { if (visible) { if (!lastCheckDate.current) { diff --git a/src/cloak-mode.css b/src/cloak-mode.css index b34134d2..d97a6d44 100644 --- a/src/cloak-mode.css +++ b/src/cloak-mode.css @@ -2,6 +2,7 @@ body.cloak .name-text, body.cloak .name-text *, body.cloak .status .content-container, body.cloak .status .content-container *, +body.cloak .status .content-compact, body.cloak .account-container :is(header, main > *:not(.actions)), body.cloak .account-container :is(header, main > *:not(.actions)) *, body.cloak .header-account, @@ -11,6 +12,11 @@ body.cloak .account-block { text-rendering: optimizeSpeed; filter: opacity(0.5); } +body.cloak .name-text *, +body.cloak .status .content-container *, +body.cloak .account-container :is(header, main > *:not(.actions)) * { + filter: none; +} body.cloak .status :is(img, video, audio), body.cloak .avatar, diff --git a/src/components/account-info.css b/src/components/account-info.css index 1133c8e3..ad10b696 100644 --- a/src/components/account-info.css +++ b/src/components/account-info.css @@ -199,17 +199,6 @@ margin: 0; } -.account-container .common-followers { - display: grid; - grid-template-rows: 1fr; - transition: grid-template-rows 0.5s ease-in-out; -} -.account-container .common-followers[hidden] { - grid-template-rows: 0fr; -} -.account-container .common-followers > .common-followers-inner { - overflow: hidden; -} .account-container .common-followers p { font-size: 90%; color: var(--text-insignificant-color); diff --git a/src/components/account-info.jsx b/src/components/account-info.jsx index 999402c3..a1e30168 100644 --- a/src/components/account-info.jsx +++ b/src/components/account-info.jsx @@ -487,8 +487,11 @@ function RelatedActions({ info, instance, authenticated }) { return ( <> -