├── .husky ├── .gitignore └── pre-commit ├── .prettierignore ├── .github └── CODEOWNERS ├── .dockerignore ├── .prettierrc.json ├── src ├── assets │ ├── images │ │ ├── blorp.png │ │ ├── echo.webp │ │ ├── mlem.png │ │ ├── photon.webp │ │ ├── voyager.png │ │ ├── memmy_icon.png │ │ ├── neonmodem.webp │ │ ├── sync_icon.webp │ │ ├── arctic_icon.webp │ │ ├── boost_icon.webp │ │ ├── echo_screen.webp │ │ ├── lunar_logo.webp │ │ ├── mlem_screen.webp │ │ ├── mobile_pic.webp │ │ ├── sync_screen.webp │ │ ├── arctic_screen.webp │ │ ├── blorp_screen.webp │ │ ├── boost_screen.webp │ │ ├── eternity_icon.webp │ │ ├── jerboa_screen.webp │ │ ├── lemmur_screen.webp │ │ ├── lunar_screen.webp │ │ ├── main_powerful.webp │ │ ├── main_screen_1.webp │ │ ├── main_screen_2.webp │ │ ├── main_screen_3.webp │ │ ├── memmy_banner.webp │ │ ├── mlmym_screen.webp │ │ ├── summit_screen.webp │ │ ├── thunder_logo.webp │ │ ├── thunder_screen.webp │ │ ├── voyager_screen.webp │ │ ├── combustible_logo.webp │ │ ├── eternity_screen.webp │ │ ├── main_censorship.webp │ │ ├── main_federation.webp │ │ ├── main_open_source.webp │ │ ├── main_screenshot.webp │ │ ├── alexandrite_screen.webp │ │ ├── combustible_screen.webp │ │ ├── lemmy_lite_screen.webp │ │ ├── main_blazing_fast.webp │ │ ├── photon-logo.svg │ │ ├── rss.svg │ │ ├── summit_logo.svg │ │ └── lemmur.svg │ ├── fonts │ │ └── Inter.woff2 │ ├── icons │ │ ├── apple-touch-icon.png │ │ ├── bitcoin.svg │ │ ├── patreon.svg │ │ ├── ko-fi.svg │ │ ├── liberapay.svg │ │ └── opencollective.svg │ ├── news │ │ ├── 2021-09-04 - Lemmy.ml now uses open federation.md │ │ ├── 2019-09-06 - Lemmy Release v0.1.0 - Emojis, Usable Search urls, mod actions on post creators, UI Tweak.md │ │ ├── 2019-09-19 - Lemmy Release v0.2.0 - Image Uploads, Stickied Posts, Online Users count, View Source button.md │ │ ├── 2019-12-09 - Lemmy Release v0.5.0 - RSS feeds, custom language, url archiving, lots of bugs fixed.md │ │ ├── 2019-10-15 - Lemmy Release v0.3.0 - Themes, Auto-Updating front page, perma-deletes, custom rate limits.md │ │ ├── 2019-11-02 - Lemmy Release v0.4.0 - Username mentions, Default sorts, Vaporwave theme, Password Recovery, Arm64.md │ │ ├── 2022-07-19 - Lemmy Release v0.16.6 - A few bug fixes.md │ │ ├── 2022-09-14- Lemmy Release v0.16.7 - Bug fixes.md │ │ ├── 2020-01-16 - Lemmy Release v0.6.0 - Avatars, email notifications, and a whole lot more.md │ │ ├── 2023-12-20 - Lemmy Release v0.19.1 - Outgoing Federation fix.md │ │ ├── 2023-09-29 - Lemmy Release v0.18.5 - Fix federation for Admin Actions.md │ │ ├── 2024-01-10 - Lemmy Release v0.19.2 - More Federation Fixes.md │ │ ├── 2025-12-08 - Lemmy Release 0.19.14.md │ │ ├── 2020-06-23 - NLnet funding, and Lemmy v0.7.0 with new image hosting!.md │ │ ├── 2024-11-15 - Lemmy Release v0.19.7.md │ │ ├── 2022-11-02 - First release of LemmyBB.md │ │ ├── 2024-12-12 - Lemmy Release v0.19.8.md │ │ ├── 2024-01-22 - Lemmy Release v0.19.3 - A Few Bugfixes.md │ │ ├── 2024-09-11 - New NLnet funding for Lemmy.md │ │ ├── 2024-06-19 - Lemmy Release v0.19.5 - A Few Bugfixes.md │ │ ├── 2022-03-17 - Free Lemmy instance hosting.md │ │ ├── 2021-04-27 - Lemmy Release v0.11.0.md │ │ ├── 2023-08-08 - Lemmy Release v0.18.4.md │ │ ├── 2021-08-09 - Promoting Lemmy.md │ │ ├── 2025-02-10 - Lemmy Release v0.19.9.md │ │ ├── 2025-09-10 - Lemmy Release 0.19.13.md │ │ ├── 2025-03-19 - Lemmy Release v0.19.10 and Developer AMA.md │ │ ├── 2021-01-25 - Lemmy Release v0.9.0.md │ │ ├── 2023-07-11 - Lemmy Release v0.18.2.md │ │ ├── 2021-09-30 - Lemmy Release v0.13.0 - Comment and Post reporting are here!.md │ │ ├── 2021-04-05 - Lemmy v0.10.0 Release.md │ │ ├── 2023-06-17 - Update from Lemmy after the Reddit blackout.md │ │ ├── 2023-10-31 - Join-Lemmy Redesign and Funding Drive.md │ │ ├── 2025-06-13 - Lemmy Release 0.19.12.md │ │ ├── 2020-10-20 - Lemmy Release v0.8.0 - Federation beta!.md │ │ ├── 2025-04-08 - Lemmy Release v0.19.11.md │ │ └── 2025-12-24 - Lemmy Release v0.19.15 and Testing for 1.0.md │ ├── lemmy_federation_context.json │ └── glide.core.min.css ├── shared │ ├── donation_stats.ts │ ├── components │ │ ├── no-match.tsx │ │ ├── common.tsx │ │ ├── icon.tsx │ │ ├── news-item.tsx │ │ ├── app.tsx │ │ ├── donate-definitions.ts │ │ ├── contact.tsx │ │ ├── crypto.tsx │ │ ├── news.tsx │ │ ├── navbar.tsx │ │ ├── instance-picker.tsx │ │ ├── donate.tsx │ │ └── apps.tsx │ ├── routes.ts │ ├── i18next.ts │ └── utils.ts ├── client │ └── index.tsx ├── style.css └── server │ └── index.tsx ├── .gitignore ├── renovate.json ├── .babelrc ├── update_submodules.sh ├── deploy.sh ├── recommended-instances.json ├── tsconfig.json ├── README.md ├── .gitmodules ├── crawl.mjs ├── update_donations.mjs ├── generate_rss_feed.mjs ├── webpack.config.js ├── Dockerfile ├── eslint.config.mjs ├── generate_translations.mjs ├── .woodpecker.yml └── package.json /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm lint-staged 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | src/shared/translations 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @Nutomic @dessalines @SleeplessOne1917 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | dist 4 | lemmy-stats-crawler 5 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "semi": true 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/images/blorp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/blorp.png -------------------------------------------------------------------------------- /src/assets/images/echo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/echo.webp -------------------------------------------------------------------------------- /src/assets/images/mlem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/mlem.png -------------------------------------------------------------------------------- /src/assets/fonts/Inter.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/fonts/Inter.woff2 -------------------------------------------------------------------------------- /src/assets/images/photon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/photon.webp -------------------------------------------------------------------------------- /src/assets/images/voyager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/voyager.png -------------------------------------------------------------------------------- /src/assets/images/memmy_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/memmy_icon.png -------------------------------------------------------------------------------- /src/assets/images/neonmodem.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/neonmodem.webp -------------------------------------------------------------------------------- /src/assets/images/sync_icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/sync_icon.webp -------------------------------------------------------------------------------- /src/assets/images/arctic_icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/arctic_icon.webp -------------------------------------------------------------------------------- /src/assets/images/boost_icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/boost_icon.webp -------------------------------------------------------------------------------- /src/assets/images/echo_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/echo_screen.webp -------------------------------------------------------------------------------- /src/assets/images/lunar_logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/lunar_logo.webp -------------------------------------------------------------------------------- /src/assets/images/mlem_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/mlem_screen.webp -------------------------------------------------------------------------------- /src/assets/images/mobile_pic.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/mobile_pic.webp -------------------------------------------------------------------------------- /src/assets/images/sync_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/sync_screen.webp -------------------------------------------------------------------------------- /src/assets/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /src/assets/images/arctic_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/arctic_screen.webp -------------------------------------------------------------------------------- /src/assets/images/blorp_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/blorp_screen.webp -------------------------------------------------------------------------------- /src/assets/images/boost_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/boost_screen.webp -------------------------------------------------------------------------------- /src/assets/images/eternity_icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/eternity_icon.webp -------------------------------------------------------------------------------- /src/assets/images/jerboa_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/jerboa_screen.webp -------------------------------------------------------------------------------- /src/assets/images/lemmur_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/lemmur_screen.webp -------------------------------------------------------------------------------- /src/assets/images/lunar_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/lunar_screen.webp -------------------------------------------------------------------------------- /src/assets/images/main_powerful.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_powerful.webp -------------------------------------------------------------------------------- /src/assets/images/main_screen_1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_screen_1.webp -------------------------------------------------------------------------------- /src/assets/images/main_screen_2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_screen_2.webp -------------------------------------------------------------------------------- /src/assets/images/main_screen_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_screen_3.webp -------------------------------------------------------------------------------- /src/assets/images/memmy_banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/memmy_banner.webp -------------------------------------------------------------------------------- /src/assets/images/mlmym_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/mlmym_screen.webp -------------------------------------------------------------------------------- /src/assets/images/summit_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/summit_screen.webp -------------------------------------------------------------------------------- /src/assets/images/thunder_logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/thunder_logo.webp -------------------------------------------------------------------------------- /src/assets/images/thunder_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/thunder_screen.webp -------------------------------------------------------------------------------- /src/assets/images/voyager_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/voyager_screen.webp -------------------------------------------------------------------------------- /src/assets/images/combustible_logo.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/combustible_logo.webp -------------------------------------------------------------------------------- /src/assets/images/eternity_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/eternity_screen.webp -------------------------------------------------------------------------------- /src/assets/images/main_censorship.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_censorship.webp -------------------------------------------------------------------------------- /src/assets/images/main_federation.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_federation.webp -------------------------------------------------------------------------------- /src/assets/images/main_open_source.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_open_source.webp -------------------------------------------------------------------------------- /src/assets/images/main_screenshot.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_screenshot.webp -------------------------------------------------------------------------------- /src/assets/images/alexandrite_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/alexandrite_screen.webp -------------------------------------------------------------------------------- /src/assets/images/combustible_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/combustible_screen.webp -------------------------------------------------------------------------------- /src/assets/images/lemmy_lite_screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/lemmy_lite_screen.webp -------------------------------------------------------------------------------- /src/assets/images/main_blazing_fast.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LemmyNet/joinlemmy-site/main/src/assets/images/main_blazing_fast.webp -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | .git 3 | .build 4 | .idea 5 | .jshintrc 6 | .sass-cache 7 | .vscode 8 | coverage 9 | jsconfig.json 10 | node_modules 11 | .DS_Store 12 | *.map 13 | *.log 14 | *.swp 15 | *.orig 16 | src/shared/translations 17 | -------------------------------------------------------------------------------- /src/assets/news/2021-09-04 - Lemmy.ml now uses open federation.md: -------------------------------------------------------------------------------- 1 | # Lemmy.ml now uses open federation 2 | 3 | _Written by @dessalines, 2021-09-04_ 4 | 5 | You no longer have to ask us to add you manually, you can subscribe and interact without the approval process. 6 | -------------------------------------------------------------------------------- /src/assets/news/2019-09-06 - Lemmy Release v0.1.0 - Emojis, Usable Search urls, mod actions on post creators, UI Tweak.md: -------------------------------------------------------------------------------- 1 | # Emojis, Usable Search urls, mod actions on post creators, UI Tweak 2 | 3 | _Written by @dessalines, 2019-09-06_ 4 | 5 | [Issue list on Github](https://github.com/dessalines/lemmy/milestone/10?closed=1) 6 | -------------------------------------------------------------------------------- /src/assets/news/2019-09-19 - Lemmy Release v0.2.0 - Image Uploads, Stickied Posts, Online Users count, View Source button.md: -------------------------------------------------------------------------------- 1 | # Image Uploads, Stickied Posts, Online Users count, View Source button 2 | 3 | _Written by @dessalines, 2019-09-19_ 4 | 5 | [Issue list on Github](https://github.com/LemmyNet/lemmy/milestone/11?closed=1) 6 | -------------------------------------------------------------------------------- /src/assets/news/2019-12-09 - Lemmy Release v0.5.0 - RSS feeds, custom language, url archiving, lots of bugs fixed.md: -------------------------------------------------------------------------------- 1 | # RSS feeds, custom language, url archiving, lots of bugs fixed 2 | 3 | _Written by @dessalines, 2019-12-09_ 4 | 5 | Special thanks to @felix@radical.town for the RSS work! 6 | 7 | https://github.com/dessalines/lemmy/milestone/14?closed=1 8 | -------------------------------------------------------------------------------- /src/shared/donation_stats.ts: -------------------------------------------------------------------------------- 1 | export const donation_stats = [ 2 | { 3 | name_: "liberapay", 4 | patrons: 254, 5 | amount: 1135.5360387549065, 6 | }, 7 | { 8 | name_: "opencollective", 9 | patrons: 341, 10 | amount: 487.6445348587333, 11 | }, 12 | { 13 | name_: "patreon", 14 | patrons: 537, 15 | amount: 729.0555061344, 16 | }, 17 | ]; 18 | -------------------------------------------------------------------------------- /src/assets/news/2019-10-15 - Lemmy Release v0.3.0 - Themes, Auto-Updating front page, perma-deletes, custom rate limits.md: -------------------------------------------------------------------------------- 1 | # Themes, Auto-Updating front page, perma-deletes, custom rate limits 2 | 3 | _Written by @dessalines, 2019-10-15_ 4 | 5 | [Closed issues here.](https://github.com/dessalines/lemmy/milestone/12?closed=1) 6 | 7 | How to change theme: ![theme](https://i.imgur.com/iLzJZMZ.png) 8 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:recommended"], 4 | "schedule": ["every weekend"], 5 | "automerge": true, 6 | "packageRules": [ 7 | { 8 | "enabled": false, 9 | "matchPackageNames": ["*"] 10 | } 11 | ], 12 | "vulnerabilityAlerts": { 13 | "enabled": true 14 | }, 15 | "osvVulnerabilityAlerts": true 16 | } 17 | -------------------------------------------------------------------------------- /src/shared/components/no-match.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "inferno"; 2 | 3 | export class NoMatch extends Component { 4 | constructor(props: any, context: any) { 5 | super(props, context); 6 | } 7 | 8 | render() { 9 | return ( 10 |
11 |
404
12 |
13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/shared/components/common.tsx: -------------------------------------------------------------------------------- 1 | import classNames from "classnames"; 2 | 3 | export const Badge = ({ content, outline = false }) => ( 4 |
9 | {content} 10 |
11 | ); 12 | 13 | export const BottomSpacer = () =>
; 14 | 15 | export const SectionTitle = ({ title }) => ( 16 |
{title}
17 | ); 18 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "compact": false, 3 | "presets": [ 4 | [ 5 | "@babel/preset-env", 6 | { 7 | "loose": true, 8 | "targets": { 9 | "browsers": ["ie >= 11", "safari > 10"] 10 | } 11 | } 12 | ], 13 | ["@babel/typescript", { "isTSX": true, "allExtensions": true }] 14 | ], 15 | "plugins": [ 16 | "@babel/plugin-transform-runtime", 17 | ["babel-plugin-inferno", { "imports": true }], 18 | ["@babel/plugin-proposal-class-properties", { "loose": true }] 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/assets/icons/bitcoin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/photon-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /update_submodules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Note: 4 | # To update lemmy-js-client, first change its branch in your .gitmodules 5 | 6 | pushd ../joinlemmy-translations 7 | git fetch weblate 8 | git merge weblate/main 9 | git push 10 | popd 11 | 12 | pushd ../lemmy-translations 13 | git fetch weblate 14 | git merge weblate/main 15 | git push 16 | popd 17 | 18 | git submodule update --remote 19 | git add joinlemmy-translations 20 | git add lemmy-translations 21 | git add lemmy-docs 22 | git add lemmy-js-client 23 | 24 | git commit -m"Updating submodules" 25 | git push 26 | -------------------------------------------------------------------------------- /src/shared/components/icon.tsx: -------------------------------------------------------------------------------- 1 | export enum IconSize { 2 | Small = "w-3 h-3", 3 | Medium = "w-4 h-4", 4 | Large = "w-6 h-6", 5 | Largest = "w-8 h-8", 6 | } 7 | 8 | interface IconProps { 9 | icon: string; 10 | size?: IconSize; 11 | classes?: string; 12 | } 13 | 14 | export const Icon = ({ icon, size = IconSize.Medium, classes }: IconProps) => ( 15 | 16 | {icon} 17 | 18 | 19 | ); 20 | 21 | export const Spinner = () => ( 22 | 23 | ); 24 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Update all the submodules and translations 4 | ./update_submodules.sh 5 | 6 | pnpm crawl 7 | pnpm update-donations 8 | git add "src/shared/instance_stats.ts" 9 | git add "src/shared/donation_stats.ts" 10 | git commit -m "Crawl and donation instance statistics" 11 | 12 | # look for unused translations 13 | for langfile in joinlemmy-translations/translations/*.json; do 14 | lang=$(basename $langfile .json) 15 | if ! grep -q "\"./translations/$lang\"" src/shared/i18next.ts; then 16 | echo "Unused language $lang" 17 | fi 18 | done 19 | 20 | new_tag="$1" 21 | 22 | git tag $new_tag 23 | git push origin $new_tag 24 | -------------------------------------------------------------------------------- /src/assets/news/2019-11-02 - Lemmy Release v0.4.0 - Username mentions, Default sorts, Vaporwave theme, Password Recovery, Arm64.md: -------------------------------------------------------------------------------- 1 | # Username mentions, Default sorts, Vaporwave theme, Password Recovery, Arm64 2 | 3 | _Written by @dessalines, 2019-11-02_ 4 | 5 | [Lemmy Release v0.4.0](https://github.com/dessalines/lemmy/releases/tag/v0.4.0) - Username mentions, Default sorts, Vaporwave theme, Password Recovery, Arm64 support. 6 | 7 | [Closed issues here.](https://github.com/dessalines/lemmy/milestone/13?closed=1) 8 | 9 | Special thanks to @iav for assistance with Arm Dockerfiles. 10 | 11 | Vaporwave theme: ![Vaporwave theme](https://i.imgur.com/2u0Oyov.png) 12 | -------------------------------------------------------------------------------- /recommended-instances.json: -------------------------------------------------------------------------------- 1 | { 2 | "start_scan_instances": [ 3 | "lemmy.ml", 4 | "lemm.ee", 5 | "feddit.it", 6 | "lemmygrad.ml", 7 | "reddthat.com", 8 | "lemmy.sdf.org", 9 | "feddit.uk", 10 | "hexbear.net", 11 | "discuss.online", 12 | "feddit.org", 13 | "lemmings.world", 14 | "lemmy.world" 15 | ], 16 | "exclude": [ 17 | "lemmy.glasgow.social", 18 | "ds9.lemmy.ml", 19 | "voyager.lemmy.ml", 20 | "enterprise.lemmy.ml", 21 | "nrsk.no", 22 | "burggit.moe", 23 | "lemmy.burger.rodeo", 24 | "bakchodi.org", 25 | "lemmy.comfysnug.space", 26 | "rqd2.net", 27 | "test.hexbear.net" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "pretty": true, 4 | "target": "esnext", 5 | "module": "esnext", 6 | "strictNullChecks": true, 7 | "allowSyntheticDefaultImports": true, 8 | "preserveConstEnums": true, 9 | "sourceMap": true, 10 | "moduleResolution": "node", 11 | "lib": ["es2017", "dom"], 12 | "types": ["inferno"], 13 | "jsx": "preserve", 14 | "noUnusedLocals": true, 15 | "baseUrl": "./src", 16 | "noEmit": true, 17 | "skipLibCheck": true, 18 | "noUnusedParameters": true, 19 | "noImplicitReturns": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src/**/*", "node_modules/inferno/dist/index.d.ts"] 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JoinLemmy-site 2 | 3 | ## Local Development 4 | 5 | - Install [pnpm](https://pnpm.io/installation) 6 | - Get the code with `git clone https://github.com/LemmyNet/joinlemmy-site.git --recursive` (the recursive part is important to fetch git submodules) 7 | - Run `pnpm install`, then `pnpm start` 8 | - Open `http://localhost:1234/` in the browser 9 | 10 | ## Docker Development 11 | 12 | - Install Docker 13 | - Get the code with `git clone https://github.com/LemmyNet/joinlemmy-site.git --recursive` (the recursive part is important to fetch git submodules) 14 | - Build the image with `docker build . -t joinlemmy-site` 15 | - Start it with `docker run -p 1234:1234 joinlemmy-site` 16 | - Open `http://localhost:1234/` in the browser 17 | -------------------------------------------------------------------------------- /src/assets/icons/patreon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /src/client/index.tsx: -------------------------------------------------------------------------------- 1 | import { hydrate } from "inferno-hydrate"; 2 | import { BrowserRouter } from "inferno-router"; 3 | import { App } from "../shared/components/app"; 4 | import { getLanguageFromCookie, i18n } from "../shared/i18next"; 5 | 6 | // Setting the language for js browsers 7 | // If query param is set, server updates cookie automatically, 8 | // so no need to check the query here 9 | const languageCookie = getLanguageFromCookie(document.cookie); 10 | if (languageCookie !== undefined) { 11 | i18n.changeLanguage(languageCookie); 12 | } else { 13 | i18n.changeLanguage(navigator.language); 14 | } 15 | 16 | const wrapper = ( 17 | 18 | 19 | 20 | ); 21 | 22 | const root = document.getElementById("root"); 23 | 24 | if (root) { 25 | hydrate(wrapper, root); 26 | } 27 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lemmy-docs"] 2 | path = lemmy-docs 3 | url = https://github.com/lemmynet/lemmy-docs 4 | branch = main 5 | [submodule "joinlemmy-translations"] 6 | path = joinlemmy-translations 7 | url = https://github.com/lemmynet/joinlemmy-translations 8 | branch = main 9 | [submodule "lemmy-translations"] 10 | path = lemmy-translations 11 | url = https://github.com/lemmynet/lemmy-translations 12 | branch = main 13 | [submodule "lemmy-js-client-v0.19"] 14 | path = lemmy-js-client-v0.19 15 | url = https://github.com/LemmyNet/lemmy-js-client 16 | branch = release/v0.19 17 | [submodule "lemmy-js-client-main"] 18 | path = lemmy-js-client-main 19 | url = https://github.com/LemmyNet/lemmy-js-client 20 | branch = main 21 | [submodule "lemmy-stats-crawler"] 22 | path = lemmy-stats-crawler 23 | url = https://github.com/LemmyNet/lemmy-stats-crawler.git 24 | branch = main 25 | -------------------------------------------------------------------------------- /src/assets/icons/ko-fi.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/images/rss.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 12 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/assets/lemmy_federation_context.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": [ 3 | "https://w3id.org/security/v1", 4 | { 5 | "as": "https://www.w3.org/ns/activitystreams#", 6 | "lemmy": "https://join-lemmy.org/ns#", 7 | "litepub": "http://litepub.social/ns#", 8 | "pt": "https://joinpeertube.org/ns#", 9 | "sc": "http://schema.org/", 10 | "ChatMessage": "litepub:ChatMessage", 11 | "commentsEnabled": "pt:commentsEnabled", 12 | "sensitive": "as:sensitive", 13 | "matrixUserId": "lemmy:matrixUserId", 14 | "postingRestrictedToMods": "lemmy:postingRestrictedToMods", 15 | "removeData": "lemmy:removeData", 16 | "stickied": "lemmy:stickied", 17 | "moderators": { 18 | "@type": "@id", 19 | "@id": "lemmy:moderators" 20 | }, 21 | "expires": "as:endTime", 22 | "distinguished": "lemmy:distinguished", 23 | "language": "sc:inLanguage", 24 | "identifier": "sc:identifier", 25 | "Hashtag": "as:Hashtag" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /src/assets/icons/liberapay.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/news/2022-07-19 - Lemmy Release v0.16.6 - A few bug fixes.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.16.6 Release : bug fixes (2022-07-19) 2 | 3 | _Written by @dessalines and @nutomic, 2022-07-19_ 4 | 5 | A few bug fixes: 6 | 7 | - Fix problem where actors can have empty public key (fixes [#2347](https://github.com/LemmyNet/lemmy/issues/2347)) ([#2348](https://github.com/LemmyNet/lemmy/issues/2348)) 8 | - Be more explicit about returning deleted actors or not ([#2335](https://github.com/LemmyNet/lemmy/issues/2335)) 9 | - Dont allow blocking admin ([#2340](https://github.com/LemmyNet/lemmy/issues/2340)) 10 | - Increase RSS fetch limit to 20. Fixes [#2319](https://github.com/LemmyNet/lemmy/issues/2319) ([#2327](https://github.com/LemmyNet/lemmy/issues/2327)) 11 | - Fix length of post_report.original_post_name db field (fixes [#2311](https://github.com/LemmyNet/lemmy/issues/2311)) ([#2315](https://github.com/LemmyNet/lemmy/issues/2315)) 12 | - Add pub use for db crates in api_common ([#2305](https://github.com/LemmyNet/lemmy/issues/2305)) 13 | - Accept private like ([#1968](https://github.com/LemmyNet/lemmy/issues/1968)) ([#2301](https://github.com/LemmyNet/lemmy/issues/2301)) 14 | -------------------------------------------------------------------------------- /src/assets/images/summit_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/news/2022-09-14- Lemmy Release v0.16.7 - Bug fixes.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.16.7 Release : Bug fixes (2022-09-14) 2 | 3 | _Written by @dessalines and @nutomic, 2022-09-14_ 4 | 5 | A few bug fixes: 6 | 7 | - Fix missing auth on new post refresh. ([#764](https://github.com/LemmyNet/lemmy-ui/issues/764)) 8 | - Change CSP rule for connect-src (websocket) to wildcard (fixes [#730](https://github.com/LemmyNet/lemmy-ui/issues/730)) ([#737](https://github.com/LemmyNet/lemmy-ui/issues/737)) 9 | - Increase default search rate limit. ([#2424](https://github.com/LemmyNet/lemmy/issues/2424)) 10 | - Rejected federated pm from blocked users (fixes [#2398](https://github.com/LemmyNet/lemmy/issues/2398)) ([#2408](https://github.com/LemmyNet/lemmy/issues/2408)) 11 | - Handle Like, Undo/Like activities from Mastodon, add tests (fixes [#2378](https://github.com/LemmyNet/lemmy/issues/2378)) ([#2380](https://github.com/LemmyNet/lemmy/issues/2380)) 12 | - Dont allow login if account is banned or deleted (fixes [#2372](https://github.com/LemmyNet/lemmy/issues/2372)) ([#2374](https://github.com/LemmyNet/lemmy/issues/2374)) 13 | - Fix panics in search_by_apub_id() (fixes [#2371](https://github.com/LemmyNet/lemmy/issues/2371)) ([#2373](https://github.com/LemmyNet/lemmy/issues/2373)) 14 | -------------------------------------------------------------------------------- /src/assets/glide.core.min.css: -------------------------------------------------------------------------------- 1 | .glide { 2 | position: relative; 3 | width: 100%; 4 | box-sizing: border-box; 5 | } 6 | .glide * { 7 | box-sizing: inherit; 8 | } 9 | .glide__track { 10 | overflow: hidden; 11 | } 12 | .glide__slides { 13 | position: relative; 14 | width: 100%; 15 | list-style: none; 16 | backface-visibility: hidden; 17 | transform-style: preserve-3d; 18 | touch-action: pan-Y; 19 | overflow: hidden; 20 | margin: 0; 21 | padding: 0; 22 | white-space: nowrap; 23 | display: flex; 24 | flex-wrap: nowrap; 25 | will-change: transform; 26 | } 27 | .glide__slides--dragging { 28 | user-select: none; 29 | } 30 | .glide__slide { 31 | width: 100%; 32 | height: 100%; 33 | flex-shrink: 0; 34 | white-space: normal; 35 | user-select: none; 36 | -webkit-touch-callout: none; 37 | -webkit-tap-highlight-color: transparent; 38 | } 39 | .glide__slide a { 40 | user-select: none; 41 | -webkit-user-drag: none; 42 | -moz-user-select: none; 43 | -ms-user-select: none; 44 | } 45 | .glide__arrows { 46 | -webkit-touch-callout: none; 47 | user-select: none; 48 | } 49 | .glide__bullets { 50 | -webkit-touch-callout: none; 51 | user-select: none; 52 | } 53 | .glide--rtl { 54 | direction: rtl; 55 | } /*# sourceMappingURL=glide.core.min.css.map */ 56 | -------------------------------------------------------------------------------- /src/shared/routes.ts: -------------------------------------------------------------------------------- 1 | import { IRouteProps } from "inferno-router/dist/Route"; 2 | import { Main } from "./components/main"; 3 | import { Apps } from "./components/apps"; 4 | import { Instances } from "./components/instances"; 5 | import { Contact } from "./components/contact"; 6 | import { Donate } from "./components/donate"; 7 | import { News } from "./components/news"; 8 | import { NewsItem } from "./components/news-item"; 9 | import { Crypto } from "./components/crypto"; 10 | 11 | export const routes: IRouteProps[] = [ 12 | { 13 | path: `/`, 14 | exact: true, 15 | component: Main, 16 | }, 17 | { 18 | path: `/apps`, 19 | exact: true, 20 | component: Apps, 21 | }, 22 | { 23 | path: `/news`, 24 | exact: true, 25 | component: News, 26 | }, 27 | { 28 | path: `/news/:title`, 29 | exact: true, 30 | component: NewsItem, 31 | }, 32 | { 33 | path: `/instances`, 34 | exact: true, 35 | component: Instances, 36 | }, 37 | { 38 | path: `/contact`, 39 | exact: true, 40 | component: Contact, 41 | }, 42 | { 43 | path: `/support`, 44 | exact: true, 45 | component: Donate, 46 | }, 47 | { 48 | path: `/donate`, 49 | exact: true, 50 | component: Donate, 51 | }, 52 | { 53 | path: `/crypto`, 54 | exact: true, 55 | component: Crypto, 56 | }, 57 | ]; 58 | -------------------------------------------------------------------------------- /src/shared/components/news-item.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "inferno"; 2 | import { Helmet } from "inferno-helmet"; 3 | import { news_md } from "../translations/news"; 4 | import { isBrowser, mdToHtml } from "../utils"; 5 | import { BottomSpacer } from "./common"; 6 | 7 | export class NewsItem extends Component { 8 | constructor(props: any, context: any) { 9 | super(props, context); 10 | } 11 | 12 | componentDidMount() { 13 | if (isBrowser()) { 14 | window.scrollTo(0, 0); 15 | } 16 | } 17 | 18 | get title(): string { 19 | let title = decodeURIComponent(this.props.match.params.title); 20 | title = title.replace(/_/g, " "); 21 | return title; 22 | } 23 | 24 | get markdown(): string { 25 | return news_md.find(v => v.title === this.title)?.markdown ?? ""; 26 | } 27 | 28 | render() { 29 | return ( 30 |
31 | 32 | 33 | 34 |
35 |
36 |
37 |
38 |
39 | 40 |
41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/assets/news/2020-01-16 - Lemmy Release v0.6.0 - Avatars, email notifications, and a whole lot more.md: -------------------------------------------------------------------------------- 1 | # Avatars, email notifications, and a whole lot more 2 | 3 | _Written by @dessalines, 2020-01-16_ 4 | 5 | `v0.6.0` is here, and we've closed [41 issues!](https://github.com/dessalines/lemmy/milestone/15?closed=1) 6 | 7 | This is the biggest release by far: 8 | 9 | - Avatars! 10 | - Optional Email notifications for username mentions, post and comment replies. 11 | - Ability to change your password and email address. 12 | - Can set a custom language. 13 | - Lemmy-wide settings to disable downvotes, and close registration. 14 | - A better documentation system, hosted in lemmy itself. 15 | - [Huge DB performance gains](https://github.com/dessalines/lemmy/issues/411) (everthing down to < `30ms`) by using materialized views. 16 | - Fixed major issue with similar post URL and title searching. 17 | - Upgraded to Actix `2.0` 18 | - Faster comment / post voting. 19 | - Better small screen support. 20 | - Lots of bug fixes, refactoring of back end code. 21 | 22 | Another major announcement is that Lemmy now has another lead developer besides me, [@felix@radical.town](https://radical.town/@felix). Theyve created a better documentation system, implemented RSS feeds, simplified docker and project configs, upgraded actix, working on federation, a whole lot more. 23 | 24 | https://dev.lemmy.ml 25 | -------------------------------------------------------------------------------- /src/shared/components/app.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "inferno"; 2 | import { Route, Switch } from "inferno-router"; 3 | import { Provider } from "inferno-i18next"; 4 | import { i18n } from "../i18next"; 5 | import { routes } from "../routes"; 6 | import { NoMatch } from "./no-match"; 7 | import { Symbols } from "./symbols"; 8 | import { Footer, Navbar } from "./navbar"; 9 | 10 | export class App extends Component { 11 | constructor(props: any, context: any) { 12 | super(props, context); 13 | } 14 | render() { 15 | return ( 16 |
17 |
18 | 19 |
20 | 21 | 22 | {routes.map(({ path, exact, component: C, ...rest }) => ( 23 | C && } 28 | /> 29 | ))} 30 | } /> 31 | 32 |
33 |
34 | 35 |
36 |
37 |
38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/shared/components/donate-definitions.ts: -------------------------------------------------------------------------------- 1 | import { donation_stats } from "../donation_stats"; 2 | 3 | interface FundingPlatform { 4 | supporterCount: number; 5 | monthlyEUR: number; 6 | } 7 | 8 | // Monthly counts in EUR 9 | const liberapay: FundingPlatform = { 10 | supporterCount: donation_stats[0].patrons, 11 | monthlyEUR: donation_stats[0].amount, 12 | }; 13 | 14 | const openCollective: FundingPlatform = { 15 | supporterCount: donation_stats[1].patrons, 16 | monthlyEUR: donation_stats[1].amount, 17 | }; 18 | 19 | const patreon: FundingPlatform = { 20 | supporterCount: donation_stats[2].patrons, 21 | monthlyEUR: donation_stats[2].amount, 22 | }; 23 | 24 | const kofi: FundingPlatform = { 25 | supporterCount: 19, 26 | monthlyEUR: 112, 27 | }; 28 | 29 | const fundingPlatforms = [liberapay, patreon, openCollective, kofi]; 30 | 31 | export const TOTAL_RECURRING_MONTHLY_EUR = fundingPlatforms 32 | .map(f => f.monthlyEUR) 33 | .reduce((a, b) => a + b, 0); 34 | 35 | export const TOTAL_SUPPORTERS = fundingPlatforms 36 | .map(f => f.supporterCount) 37 | .reduce((a, b) => a + b, 0); 38 | 39 | // From https://www.developersalary.com 40 | export const MEDIAN_DEV_SALARY = 50_000; 41 | export const MEDIAN_DEV_MONTHLY_EUR = MEDIAN_DEV_SALARY / 12; 42 | 43 | // Number of devs funded off of recurring 44 | export const FUNDED_DEVS = TOTAL_RECURRING_MONTHLY_EUR / MEDIAN_DEV_MONTHLY_EUR; 45 | 46 | // Goal 47 | export const FUNDED_DEV_GOAL = 2; 48 | -------------------------------------------------------------------------------- /src/assets/icons/opencollective.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Rectangle 5 | Created with Sketch. 6 | 7 | 8 | 14 | 15 | -------------------------------------------------------------------------------- /src/shared/components/contact.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "inferno"; 2 | import { Helmet } from "inferno-helmet"; 3 | import { i18n } from "../i18next"; 4 | import { BottomSpacer } from "./common"; 5 | import { Icon } from "./icon"; 6 | 7 | const TitleBlock = () => ( 8 |
9 | {i18n.t("contact")} 10 |
11 | ); 12 | 13 | const ContactBlock = () => ( 14 |
15 |
16 |
17 | 21 | 25 | 26 |
27 |
28 |
29 | ); 30 | 31 | const ContactBtn = ({ title, url }) => ( 32 | 36 | 37 | {title} 38 | 39 | ); 40 | 41 | export class Contact extends Component { 42 | constructor(props: any, context: any) { 43 | super(props, context); 44 | } 45 | render() { 46 | const title = i18n.t("contact_title"); 47 | return ( 48 |
49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /crawl.mjs: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import { spawn } from "child_process"; 3 | 4 | const outDir = "src/shared/translations/"; 5 | const recommendationsFile = "recommended-instances.json"; 6 | const instanceStatsFile = "src/shared/instance_stats.ts"; 7 | 8 | fs.mkdirSync(outDir, { recursive: true }); 9 | 10 | // crawl instance stats 11 | try { 12 | const recommended_instances = JSON.parse( 13 | fs.readFileSync(recommendationsFile, "utf8"), 14 | ); 15 | var all_recommended = []; 16 | for (var k in recommended_instances) { 17 | if (k != "exclude") { 18 | all_recommended.push(...recommended_instances[k]); 19 | } 20 | } 21 | // Run the crawler with start instances and blocked instances. The parameter --joinlemmy-output 22 | // makes it exclude some output data which is not needed here. This is done in Rust because `jq` 23 | // uses excessive memory and crashes. 24 | const run = spawn( 25 | "sh", 26 | [ 27 | "-c", 28 | `cargo run --release -- --joinlemmy-output --start-instances ${all_recommended} \ 29 | --exclude-instances ${recommended_instances.exclude}`, 30 | ], 31 | { 32 | cwd: "lemmy-stats-crawler", 33 | encoding: "utf8", 34 | }, 35 | ); 36 | let savedOutput = ""; 37 | 38 | run.stdout.on("data", data => { 39 | const strData = data.toString(); 40 | savedOutput += strData; 41 | }); 42 | 43 | run.stderr.on("data", data => { 44 | const strData = data.toString(); 45 | process.stdout.write(strData); 46 | }); 47 | 48 | run.on("close", _exitCode => { 49 | // Convert stats to json to be compiled directly into the code. Not using JSON.parse here as it 50 | // uses too much memory and crashes. 51 | let data = `export const instance_stats = {stats: ${savedOutput}, recommended : ${JSON.stringify(recommended_instances)}};\n `; 52 | fs.writeFileSync(instanceStatsFile, data); 53 | }); 54 | run.await; 55 | } catch (err) { 56 | console.error(err); 57 | } 58 | -------------------------------------------------------------------------------- /update_donations.mjs: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import fetch from "node-fetch"; 3 | 4 | const donationStatsFile = "src/shared/donation_stats.ts"; 5 | 6 | const USDtoEURUrl = 7 | "https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.json"; 8 | 9 | const liberaPayUrl = "https://liberapay.com/Lemmy/public.json"; 10 | const openCollectiveUrl = "https://opencollective.com/lemmy.json"; 11 | 12 | // This needs a `JOINLEMMY_PATREON_ACCESS_TOKEN` env var 13 | const patreonUrl = 14 | "https://www.patreon.com/api/oauth2/api/current_user/campaigns"; 15 | const patreonToken = process.env["JOINLEMMY_PATREON_ACCESS_TOKEN"]; 16 | 17 | const usdToEurRes = await fetch(USDtoEURUrl); 18 | const usdToEur = (await usdToEurRes.json()).usd.eur; 19 | 20 | // In weekly USD 21 | const liberaPayRes = await fetch(liberaPayUrl); 22 | const liberaPayData = await liberaPayRes.json(); 23 | 24 | // In yearly USD, decimal 25 | const openCollectiveRes = await fetch(openCollectiveUrl); 26 | const openCollectiveData = await openCollectiveRes.json(); 27 | 28 | // In monthly USD, decimal 29 | const patreonRes = await fetch(patreonUrl, { 30 | headers: { Authorization: `Bearer ${patreonToken}` }, 31 | }); 32 | const patreonData = await patreonRes.json(); 33 | 34 | const donationData = [ 35 | { 36 | name_: "liberapay", 37 | patrons: liberaPayData.npatrons, 38 | amount: Number(liberaPayData.receiving.amount) * 4.348214 * usdToEur, 39 | }, 40 | { 41 | name_: "opencollective", 42 | patrons: openCollectiveData.backersCount, 43 | amount: (Number(openCollectiveData.yearlyIncome) / 100 / 12) * usdToEur, 44 | }, 45 | { 46 | name_: "patreon", 47 | patrons: patreonData.data[0].attributes.paid_member_count, 48 | amount: 49 | (Number(patreonData.data[0].attributes.pledge_sum) / 100) * usdToEur, 50 | }, 51 | ]; 52 | 53 | let data = `export const donation_stats = \n `; 54 | data += JSON.stringify(donationData, null, 2) + ";"; 55 | fs.writeFileSync(donationStatsFile, data); 56 | -------------------------------------------------------------------------------- /generate_rss_feed.mjs: -------------------------------------------------------------------------------- 1 | import fs from "fs-extra"; 2 | import MarkdownIt from "markdown-it"; 3 | import { Builder } from "xml2js"; 4 | 5 | async function generateRSSFeed() { 6 | const md = new MarkdownIt(); 7 | const posts = []; 8 | const files = await fs.readdir("./src/assets/news"); // a folder with markdown files 9 | const newestFirstFiles = Array.from(files).reverse(); 10 | 11 | for (const file of newestFirstFiles) { 12 | if (file.endsWith(".md")) { 13 | const content = await fs.readFile(`./src/assets/news/${file}`, "utf8"); 14 | const lines = content.split("\n"); 15 | const title = lines[0].replace(/^# /, ""); 16 | const dateFromFileName = file.slice(0, 10); 17 | const date = new Date(dateFromFileName).toUTCString(); 18 | const htmlContent = md.render(content); 19 | const link = `https://join-lemmy.org/news/${file 20 | .replace(".md", "") 21 | .replaceAll(" ", "_")}`; 22 | 23 | posts.push({ title, date, content: htmlContent, link }); 24 | } 25 | } 26 | 27 | const rss = { 28 | rss: { 29 | $: { 30 | version: "2.0", 31 | "xmlns:atom": "http://www.w3.org/2005/Atom", 32 | }, 33 | channel: [ 34 | { 35 | "atom:link": { 36 | $: { 37 | href: "https://join-lemmy.org/feed.xml", 38 | rel: "self", 39 | type: "application/rss+xml", 40 | }, 41 | }, 42 | title: "join-lemmy.org News", 43 | link: "https://join-lemmy.org/", 44 | description: "News about Lemmy, a link aggregator for the fediverse.", 45 | item: posts.map(post => ({ 46 | title: post.title, 47 | link: post.link, 48 | description: post.content, 49 | pubDate: post.date, 50 | guid: post.link, 51 | })), 52 | }, 53 | ], 54 | }, 55 | }; 56 | 57 | const builder = new Builder(); 58 | const xml = builder.buildObject(rss); 59 | 60 | await fs.writeFile("./dist/feed.xml", xml); 61 | } 62 | 63 | generateRSSFeed().then(() => console.log("RSS feed generated successfully.")); 64 | -------------------------------------------------------------------------------- /src/assets/news/2023-12-20 - Lemmy Release v0.19.1 - Outgoing Federation fix.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.19.1 Release 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Major Changes 8 | 9 | 0.19.0 has a critical bug where sending outgoing activities can stop working. The bug is fixed in this version. It also fixes the "hide read posts" user setting, fixes a problem with invalid comment paths, and another fix for private message reports. 10 | 11 | ## Upgrade instructions 12 | 13 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible#upgrading) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). The upgrade should take less than 30 minutes. 14 | 15 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 16 | 17 | ## Thanks to everyone 18 | 19 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 20 | 21 | ## Support development 22 | 23 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over three years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 24 | 25 | This month we are running a funding drive with the goal of increasing recurring donations from currently €4.000 to at least €12.000. With this amount @dessalines and @nutomic can each receive a yearly salary of €50.000 which is in line with median developer salaries. It will also allow one additional developer to work fulltime on Lemmy and speed up development. 26 | 27 | Read more details in the [funding drive announcement](https://join-lemmy.org/news/2023-10-31_-_Join-Lemmy_Redesign_and_Funding_Drive). 28 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss" source("."); 2 | @plugin "@tailwindcss/typography"; 3 | 4 | @plugin "daisyui"; 5 | @plugin "daisyui/theme" { 6 | name: "halloween"; 7 | default: true; 8 | --color-primary: oklch(0.65 0.2181 142.48); 9 | --color-secondary: oklch(0.69 0.1195 211.28); 10 | --color-base-content: white; 11 | } 12 | 13 | @theme { 14 | --font-*: initial; 15 | --font-sans: 16 | Inter, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", 17 | "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 18 | --color-gradient-start: oklch(0.77 0.1736 143.14); 19 | --color-gradient-end: oklch(0.65 0.2181 142.48); 20 | --color-background-gradient: oklch(0.75 0.2504 142.47); 21 | --depth: 0; 22 | --noise: 0; 23 | } 24 | 25 | /* 26 | The default border color has changed to `currentcolor` in Tailwind CSS v4, 27 | so we've added these compatibility styles to make sure everything still 28 | looks the same as it did with Tailwind CSS v3. 29 | 30 | If we ever want to remove these styles, we need to add an explicit border 31 | color utility to any element that depends on these defaults. 32 | */ 33 | @layer base { 34 | *, 35 | ::after, 36 | ::before, 37 | ::backdrop, 38 | ::file-selector-button { 39 | border-color: var(--color-gray-200, currentcolor); 40 | } 41 | } 42 | 43 | .lemmy-select { 44 | @apply select w-fit text-gray-400; 45 | } 46 | 47 | .text-gradient { 48 | @apply bg-linear-to-r bg-clip-text text-transparent from-gradient-start to-gradient-end; 49 | } 50 | 51 | .card-gradient { 52 | @apply bg-linear-to-r from-zinc-500/5 via-secondary/15 to-zinc-500/5; 53 | } 54 | 55 | .background-gradient-1 { 56 | @apply min-h-full bg-linear-to-r from-transparent via-background-gradient/15 to-transparent; 57 | } 58 | 59 | .background-gradient-2 { 60 | @apply min-h-full bg-linear-to-b from-transparent to-zinc-600/10 to-20%; 61 | } 62 | 63 | .icon { 64 | @apply block max-w-16 max-h-16 stroke-0 stroke-current fill-current; 65 | } 66 | 67 | @font-face { 68 | font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 69 | font-family: "Inter"; 70 | font-style: normal; 71 | font-weight: 400; 72 | src: url("../assets/fonts/Inter.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 73 | } 74 | -------------------------------------------------------------------------------- /src/assets/news/2023-09-29 - Lemmy Release v0.18.5 - Fix federation for Admin Actions.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.18.5 Release (2023-09-29) 2 | 3 | _Written by @nutomic and @dessalines, 2023-09-29_ 4 | 5 | ## What is Lemmy? 6 | 7 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 8 | 9 | ## Major Changes 10 | 11 | This release fixes a problem with federation of moderation actions performed by admin accounts. Specifically there is an check when receiving remote federation actions, which is incorrectly rejecting them in some cases. The problem is fixed by this release. 12 | 13 | There are no other changes. 14 | 15 | ## Support development 16 | 17 | @dessalines and @nutomic are working full-time on Lemmy to integrate community contributions, fix bugs, optimize performance and much more. This work is funded exclusively through donations. 18 | 19 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). No one likes recurring donations, but they’ve proven to be the only way that open-source software like Lemmy can stay independent and alive. 20 | 21 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 22 | - [Open Collective](https://opencollective.com/lemmy) 23 | - [Patreon](https://www.patreon.com/dessalines) 24 | - [Cryptocurrency](https://join-lemmy.org/donate) (scroll to bottom of page) 25 | 26 | ## Upgrade instructions 27 | 28 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible#upgrading) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). There are no config or API changes with this release. 29 | 30 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/#lemmy-admin-support-topics:discuss.online). 31 | 32 | ## Changes 33 | 34 | ### Lemmy 35 | 36 | - Fix federation of admin actions ([#3988](https://github.com/LemmyNet/lemmy/pull/3988)) 37 | -------------------------------------------------------------------------------- /src/assets/news/2024-01-10 - Lemmy Release v0.19.2 - More Federation Fixes.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.19.2 Release 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Major Changes 8 | 9 | - Outgoing federation bug fixes. 10 | - Lemmy can now receive reports sent from Mastodon and Kbin. 11 | - Added the ability for admins to view votes, to prevent downvote trolling. [Demo](https://github.com/LemmyNet/lemmy-ui/pull/2303). [#4088](https://github.com/LemmyNet/lemmy/issues/4088) 12 | - Various bug fixes and minor enhancements. 13 | 14 | ## Upgrade instructions 15 | 16 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible#upgrading) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 17 | 18 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 19 | 20 | ## Thanks to everyone 21 | 22 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 23 | 24 | ## Support development 25 | 26 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over three years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 27 | 28 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive. 29 | 30 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 31 | - [Open Collective](https://opencollective.com/lemmy) 32 | - [Patreon](https://www.patreon.com/dessalines) 33 | - [Cryptocurrency](https://join-lemmy.org/donate) (scroll to bottom of page) 34 | -------------------------------------------------------------------------------- /src/assets/news/2025-12-08 - Lemmy Release 0.19.14.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.19.14 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. Thanks to @flamingos-cant for contributing to resolve this. 6 | 7 | ## Changes 8 | 9 | Recently some malicious users started to use an exploit where they would post rule violating content and then delete the account. This would prevent admins and mods from viewing the user profile to find other posts, and would also prevent federation of ban actions. 10 | 11 | The new release fixes these problems. Thanks to @flamingos-cant for contributing to solve this. 12 | 13 | ## Upgrade instructions 14 | 15 | There are no breaking changes with this release. 16 | 17 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 18 | 19 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 20 | 21 | ## Thanks to everyone 22 | 23 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 24 | 25 | ## Support development 26 | 27 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over five years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 28 | 29 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 30 | 31 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 32 | - [Open Collective](https://opencollective.com/lemmy) 33 | - [Patreon](https://www.patreon.com/dessalines) 34 | - [Cryptocurrency](https://join-lemmy.org/crypto) 35 | -------------------------------------------------------------------------------- /src/assets/news/2020-06-23 - NLnet funding, and Lemmy v0.7.0 with new image hosting!.md: -------------------------------------------------------------------------------- 1 | # NLnet funding, and Lemmy v0.7.0 with new image hosting! 2 | 3 | _Written by @dessalines and @nutomic, 2020-06-23_ 4 | 5 | Let's start with the biggest news first: Lemmy is receiving funding from the [NLnet foundation](https://nlnet.nl/)! The funding is for a total amount of 45.000 €, which will allow [/u/dessalines](/u/dessalines) and me ([/u/nutomic](/u/nutomic) ) to work on Lemmy full-time for at least half a year. 6 | 7 | We have created various milestones for the work we are planning to do. Most of them are about getting ActivityPub federation ready for production. In addition, we will work on: 8 | 9 | - better accessibility 10 | - private communities and instances 11 | - reworking search 12 | - creating a `joinlemmy.ml` type site 13 | - the option to block other users or communities 14 | 15 | The details of the milestones will be posted on our github issue tracker soon. 16 | 17 | We're very excited about this opportunity, and can't wait to finish federation. 18 | 19 | In other news, we have just released [Lemmy v0.7.0.](https://github.com/LemmyNet/lemmy/blob/master/RELEASES.md#lemmy-v070-release-2020-06-2x) Most importantly, this update switches to [Pict-rs](https://git.asonix.dog/asonix/pict-rs/) for image hosting, due to various performance-related issues with Pictshare. Pict-rs was coded from scratch in Rust by the amazing @asonix, who also created the ActivityPub library for Rust. We can't thank him enough for all the work he is doing for Lemmy! 20 | 21 | We'd also like to thank the following people for their contributions: 22 | 23 | - @iav for their work in building arm compatible rust docker images and builds. 24 | - @ernestwisniewski and @bytesnake for code contributions. 25 | - Many others for contributing translations via the [Lemmy weblate.](https://weblate.yerbamate.dev/projects/lemmy/) 26 | - Our [Patreon](https://www.patreon.com/dessalines) and [Liberapay](https://liberapay.com/Lemmy/) supporters who help us devote more time to Lemmy (We're still very far from these being able to sustain two developers) 27 | - Everyone else who contributes to Lemmy, be it by coding, hosting instances or just using it and spreading the word! 28 | 29 | Other than that, since v0.6.0 in January [we've closed over 100 issues](https://github.com/LemmyNet/lemmy/milestone/16?closed=1), fixed tons of bugs and added many new features. 30 | 31 | [You can find the full changelog and upgrade instructions here](https://github.com/LemmyNet/lemmy/blob/master/RELEASES.md#lemmy-v070-release-2020-06-2x). 32 | 33 | Edit: [Here are the milestones for the funding](https://dev.lemmy.ml/post/35612) 34 | -------------------------------------------------------------------------------- /src/assets/news/2024-11-15 - Lemmy Release v0.19.7.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.19.7 Release 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Changes 8 | 9 | This is a small bugfix release with the following: 10 | 11 | - Fixing cors origin wildcard. by @dessalines in [#5194](https://github.com/LemmyNet/lemmy/pull/5194) 12 | - Fetch community mods synchronously by @Nutomic in [#5169](https://github.com/LemmyNet/lemmy/pull/5169) 13 | - Move aggregates to replaceable_schema, fix error (fixes #5186) by @Nutomic in [#5190](https://github.com/LemmyNet/lemmy/pull/5190) 14 | 15 | ### Full Changelog 16 | 17 | - [Lemmy Backend](https://github.com/LemmyNet/lemmy/compare/0.19.6...0.19.7) 18 | - [Lemmy-UI](https://github.com/LemmyNet/lemmy-ui/compare/0.19.6...0.19.7) 19 | 20 | ## Upgrade instructions 21 | 22 | There are no breaking changes with this release. 23 | 24 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 25 | 26 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 27 | 28 | ## Thanks to everyone 29 | 30 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 31 | 32 | ## Support development 33 | 34 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over five years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 35 | 36 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 37 | 38 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 39 | - [Open Collective](https://opencollective.com/lemmy) 40 | - [Patreon](https://www.patreon.com/dessalines) 41 | - [Cryptocurrency](https://join-lemmy.org/crypto) 42 | -------------------------------------------------------------------------------- /src/assets/news/2022-11-02 - First release of LemmyBB.md: -------------------------------------------------------------------------------- 1 | # First release of LemmyBB, a federated bulletin board written in Rust 2 | 3 | _Written by @nutomic, 2022-09-14_ 4 | 5 | We are excited to announce the release of lemmyBB. This is an alternative frontend for Lemmy, based on the design of [phpBB](https://www.phpbb.com/). It turns Lemmy from a link aggregator with upvotes and image previews into a traditional forum, or bulletin board. 6 | 7 | ![](https://lemmy.ml/pictrs/image/8d2509c3-d508-4d18-a735-4196d62dbd12.png) 8 | 9 | [Lemmy](https://github.com/LemmyNet/lemmy) is a self-hosted discussion platform which supports Activitypub for federation with other servers. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. 10 | 11 | By combining these projects, we get the benefits of both: a stable and performant backend which supports Activitypub federation, has an extensive API with mod tools and much more. Together with a classical frontend that is focused on text-based discussion, with no distraction of voting or overt number of image posts. 12 | 13 | The easiest way to try lemmyBB is by signing up on the flagship instance [fedibb.ml](https://fedibb.ml/) and joining the discussion. You can also install your own instance by following [these instructions](https://github.com/LemmyNet/lemmyBB#installation). Resource usage is very low as everything is written in Rust (except the PostgreSQL database). Fedibb.ml uses about 70 MB of RAM and a negligible amount of CPU. 14 | 15 | There are still many things to work on, and some missing features need to be added. A lot of polishing also needs to be done. Contributions are more than welcome, so if this sounds interesting, [consider getting involved](https://github.com/LemmyNet/lemmyBB)! 16 | 17 | LemmyBB can also serve as an example of Lemmy's potential as a generic backend for social media platforms. Instead of starting a project from scratch to write an API, database logic, authentication, federation etc, you could create a frontend for Lemmy. This can be written in your language of choice, and only needs to render HTML, and use the [Lemmy API](https://join-lemmy.org/api/index.html). This doesn't have to be a forum, a blogging platform or image gallery would also be possible. 18 | 19 | To be clear, lemmyBB is not meant to replace phpBB and it will never have all the same features. It was simply much easier to use this approach for someone like me who doesn't know much about frontend development. In that sense, I want to give a big thanks to the phpBB developers for publishing their work as open source, and making this project possible! 20 | -------------------------------------------------------------------------------- /src/assets/images/lemmur.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require("webpack"); 2 | const nodeExternals = require("webpack-node-externals"); 3 | const CopyPlugin = require("copy-webpack-plugin"); 4 | const RunNodeWebpackPlugin = require("run-node-webpack-plugin"); 5 | const { merge } = require("lodash"); 6 | 7 | const banner = ` 8 | hash:[contentHash], chunkhash:[chunkhash], name:[name], filebase:[base], query:[query], file:[file] 9 | Source code: https://github.com/LemmyNet/joinlemmy-site 10 | Created by dessalines 11 | @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL v3.0 12 | `; 13 | 14 | const base = { 15 | output: { 16 | filename: "js/server.js", 17 | publicPath: "/", 18 | }, 19 | resolve: { 20 | extensions: [".js", ".jsx", ".ts", ".tsx"], 21 | }, 22 | performance: { 23 | hints: false, 24 | }, 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.(js|jsx|tsx|ts)$/, // All ts and tsx files will be process by 29 | exclude: /node_modules/, // ignore node_modules 30 | loader: "babel-loader", 31 | }, 32 | // Due to some weird babel issue: https://github.com/webpack/webpack/issues/11467 33 | { 34 | test: /\.m?js/, 35 | resolve: { 36 | fullySpecified: false, 37 | }, 38 | }, 39 | ], 40 | }, 41 | plugins: [ 42 | new CopyPlugin({ 43 | patterns: [{ from: "./src/assets", to: "./assets" }], 44 | }), 45 | new webpack.BannerPlugin({ 46 | banner, 47 | }), 48 | ], 49 | }; 50 | 51 | const createServerConfig = (_env, mode) => { 52 | const config = merge({}, base, { 53 | mode, 54 | entry: "./src/server/index.tsx", 55 | output: { 56 | filename: "js/server.js", 57 | }, 58 | target: "node", 59 | externals: [nodeExternals(), "inferno-helmet"], 60 | }); 61 | 62 | if (mode === "development") { 63 | config.cache = { 64 | type: "filesystem", 65 | name: "server", 66 | }; 67 | 68 | config.plugins.push( 69 | new RunNodeWebpackPlugin({ 70 | runOnlyInWatchMode: true, 71 | }), 72 | ); 73 | } 74 | 75 | return config; 76 | }; 77 | const createClientConfig = (_env, mode) => { 78 | const config = merge({}, base, { 79 | mode, 80 | entry: "./src/client/index.tsx", 81 | output: { 82 | filename: "js/client.js", 83 | }, 84 | }); 85 | 86 | if (mode === "development") { 87 | config.cache = { 88 | type: "filesystem", 89 | name: "client", 90 | }; 91 | } 92 | 93 | return config; 94 | }; 95 | 96 | module.exports = (env, properties) => [ 97 | createServerConfig(env, properties.mode || "development"), 98 | createClientConfig(env, properties.mode || "development"), 99 | ]; 100 | -------------------------------------------------------------------------------- /src/assets/news/2024-12-12 - Lemmy Release v0.19.8.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.19.8 Release 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Changes 8 | 9 | This release includes a few minor fixes and improvements. Merry Christmas Everyone! 10 | 11 | ### Lemmy 12 | 13 | - [Fix post thumbnails by properly determining file type](https://github.com/LemmyNet/lemmy/pull/5225) 14 | - [Provide health endpoint for pictrs at `/pictrs/healthz`](https://github.com/LemmyNet/lemmy/pull/5224) 15 | - [Allow bypassing image proxy for specific domains](https://github.com/LemmyNet/lemmy/pull/5223) (can be configured via config value `pictrs.proxy_bypass_domains`, and `i.imgur.net` is bypassed by default) 16 | - [API returns content of removed comments for admins](https://github.com/LemmyNet/lemmy/pull/5245) 17 | 18 | ### Lemmy-UI 19 | 20 | - Updated translations 21 | 22 | ## Upgrade instructions 23 | 24 | There are no breaking changes with this release. 25 | 26 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 27 | 28 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 29 | 30 | ## Thanks to everyone 31 | 32 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 33 | 34 | ## Support development 35 | 36 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over five years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 37 | 38 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 39 | 40 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 41 | - [Open Collective](https://opencollective.com/lemmy) 42 | - [Patreon](https://www.patreon.com/dessalines) 43 | - [Cryptocurrency](https://join-lemmy.org/crypto) 44 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the git includes for the docs 2 | FROM alpine:3 AS docs_include 3 | RUN apk add --no-cache git bash curl 4 | WORKDIR /app 5 | COPY lemmy-docs ./lemmy-docs 6 | WORKDIR /app/lemmy-docs 7 | RUN ./update-includes.sh 8 | 9 | # Build the docs 10 | FROM alpine:3 AS docs 11 | WORKDIR /app 12 | RUN wget -O mdbook.tar.gz https://github.com/rust-lang/mdBook/releases/download/v0.4.30/mdbook-v0.4.30-x86_64-unknown-linux-musl.tar.gz 13 | RUN tar -xzf mdbook.tar.gz 14 | COPY lemmy-docs ./lemmy-docs 15 | RUN ./mdbook build lemmy-docs -d ../docs 16 | 17 | # Build the typedoc lemmy-js-client docs, and swagger.json 18 | FROM node:20-alpine AS api_v0.19 19 | WORKDIR /app 20 | COPY lemmy-js-client-v0.19 lemmy-js-client 21 | WORKDIR /app/lemmy-js-client 22 | RUN npm install -g corepack@latest && corepack enable pnpm 23 | RUN pnpm i 24 | RUN pnpm run docs 25 | # OpenAPI isn't currently working for the v0.19 docs, so no pnpm tsoa 26 | 27 | # Do the same for the api docs, but on main 28 | FROM node:20-alpine AS api_main 29 | WORKDIR /app 30 | COPY lemmy-js-client-main lemmy-js-client 31 | WORKDIR /app/lemmy-js-client 32 | RUN npm install -g corepack@latest && corepack enable pnpm 33 | RUN pnpm i 34 | RUN pnpm run docs 35 | RUN pnpm tsoa 36 | 37 | # Build the isomorphic app 38 | FROM node:20-alpine AS builder 39 | RUN apk update && apk add python3 build-base gcc wget git curl --no-cache 40 | RUN curl -sf https://gobinaries.com/tj/node-prune | sh 41 | RUN npm install -g corepack@latest && corepack enable pnpm 42 | 43 | WORKDIR /app 44 | 45 | # Cache deps 46 | COPY package.json pnpm-lock.yaml ./ 47 | RUN pnpm i 48 | 49 | # Build 50 | COPY tsconfig.json \ 51 | webpack.config.js \ 52 | .babelrc \ 53 | generate_translations.mjs \ 54 | generate_rss_feed.mjs \ 55 | ./ 56 | 57 | COPY joinlemmy-translations joinlemmy-translations 58 | COPY lemmy-translations lemmy-translations 59 | COPY src src 60 | 61 | # Copy the rust docs, lemmy-js-client docs, and OpenAPI docs. 62 | COPY --from=docs /app/docs ./src/assets/docs 63 | COPY --from=api_v0.19 /app/lemmy-js-client/docs ./src/assets/lemmy-js-client-v0.19-docs 64 | COPY --from=api_main /app/lemmy-js-client/docs ./src/assets/lemmy-js-client-main-docs 65 | COPY --from=api_main /app/lemmy-js-client/redoc-static.html ./src/assets/api_main.html 66 | 67 | RUN pnpm i 68 | RUN pnpm prebuild:prod 69 | RUN pnpm build:prod 70 | 71 | # Prune the image 72 | RUN node-prune ./node_modules 73 | 74 | RUN rm -rf ./node_modules/import-sort-parser-typescript 75 | RUN rm -rf ./node_modules/typescript 76 | RUN rm -rf ./node_modules/npm 77 | 78 | FROM node:20-alpine AS runner 79 | COPY --from=builder /app/dist /app/dist 80 | COPY --from=builder /app/node_modules /app/node_modules 81 | 82 | EXPOSE 1234 83 | WORKDIR /app 84 | CMD node dist/js/server.js 85 | -------------------------------------------------------------------------------- /src/assets/news/2024-01-22 - Lemmy Release v0.19.3 - A Few Bugfixes.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.19.3 Release 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Major Changes 8 | 9 | - Fixed lemmy-ui error page bug by @Sleepless in https://github.com/LemmyNet/lemmy-ui/pull/2302 10 | - Fix bug with Mastodon undo follow activities by @Nutomic in https://github.com/LemmyNet/lemmy/pull/4364 11 | - Count chars, not bytes for max title length (fixes #4366) by @Nutomic in https://github.com/LemmyNet/lemmy/pull/4367 12 | - Mark instance as alive after successful activity send (fixes #4039) by @Nutomic in https://github.com/LemmyNet/lemmy/pull/4377 13 | - Dont allow caching captcha response by @Nutomic in https://github.com/LemmyNet/lemmy/pull/4381 14 | - Revert "Dont ignore errors during login (fixes #4319) (#4321)" by @Nutomic in https://github.com/LemmyNet/lemmy/pull/4380 15 | - Removing group from woodpecker, as its deprecated. by @dessalines in https://github.com/LemmyNet/lemmy/pull/4387 16 | - Add secondary sort by published date for post view (fixes #4383) by @Nutomic in https://github.com/LemmyNet/lemmy/pull/4384 17 | 18 | ## Upgrade instructions 19 | 20 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible#upgrading) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 21 | 22 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 23 | 24 | ## Thanks to everyone 25 | 26 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 27 | 28 | ## Support development 29 | 30 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over three years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 31 | 32 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive. 33 | 34 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 35 | - [Open Collective](https://opencollective.com/lemmy) 36 | - [Patreon](https://www.patreon.com/dessalines) 37 | - [Cryptocurrency](https://join-lemmy.org/donate) (scroll to bottom of page) 38 | -------------------------------------------------------------------------------- /src/assets/news/2024-09-11 - New NLnet funding for Lemmy.md: -------------------------------------------------------------------------------- 1 | # New NLnet funding for Lemmy 2 | 3 | The [NLnet foundation](https://nlnet.nl/) has previously provided three funding rounds for Lemmy, which allowed Dessalines and Nutomic to work fulltime on the project. With this funding we were able to implement fundamental features such as federation, and to get Lemmy ready for production and to prepare for the huge migration of Reddit users. 4 | 5 | Now we have good news, a new round of funding was approved for a total of € 50.000. For the first time there will be two additional developers receiving funding: Phiresky, who has made numerous contributions to federation and database code. And Sunaurus, admin of lemm.ee who contributed many bug fixes. They will help to implement new features faster and spread the workload. 6 | 7 | By the way, if you want to see a particular feature implemented, we always welcome contributions via pull requests. Additionally we are available for paid work on specific features. You can send a mail to `contact at join-lemmy.org`, or message `@nutomic:matrix.org` to discuss the details. 8 | 9 | Without further ado, here are the approved milestones and payment amounts: 10 | 11 | - [Private communities](https://github.com/LemmyNet/lemmy/issues/187) ([RFC link](https://github.com/LemmyNet/rfcs/blob/main/0005-private-communities.md), 6000€) 12 | - [Improvements for outgoing federation](https://github.com/LemmyNet/lemmy/issues/4529) (3000€) 13 | - [SQL paging and filtering for multiple types](https://github.com/LemmyNet/lemmy/issues/2444) (6750€) 14 | - [Plugin System and example Plugin](https://github.com/LemmyNet/lemmy/pull/4695) (3000€) 15 | - [Post scheduling](https://github.com/LemmyNet/lemmy/issues/234) (1500€) 16 | - [Improve Linking Federated Posts](https://github.com/LemmyNet/lemmy/issues/2987) (2250€) 17 | - [Automatic Language Tagging](https://github.com/LemmyNet/lemmy/issues/2870) (1500€) 18 | - [Poll support](https://github.com/LemmyNet/lemmy/issues/787) (3500€) 19 | - Moderation Improvements (4500€) 20 | - [Include instance blocks in mod log](https://github.com/LemmyNet/lemmy/issues/2506) (750€) 21 | - [Implement warnings, notify user when warned](https://github.com/LemmyNet/lemmy/issues/1424) (2250€) 22 | - [Attach unresolved report counts to comment and post payloads](https://github.com/LemmyNet/lemmy/issues/4163) (1500€) 23 | - [Rework API Endpoints for API v4](https://github.com/LemmyNet/lemmy/issues/4428) (€ 6000) 24 | - [Separate endpoints for image upload](https://github.com/LemmyNet/lemmy/issues/1772) (3000€) 25 | - [Move taglines and emojis into separate paged endpoint](https://github.com/LemmyNet/lemmy/issues/4577) (1500) 26 | - [Reduce amount of redundant data returned](https://github.com/LemmyNet/lemmy/issues/2957) (1500€) 27 | - [Multi-communities](https://github.com/LemmyNet/lemmy/issues/818) (6000€) 28 | - [Ease discovery of federated communities](https://github.com/LemmyNet/lemmy/issues/2951) (3000€) 29 | - [Post tags](https://github.com/LemmyNet/lemmy/issues/317) ([RFC link](https://github.com/LemmyNet/rfcs/blob/main/0004-post-tags.md), 4500€) 30 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import pluginJs from "@eslint/js"; 2 | import tseslint from "typescript-eslint"; 3 | import prettier from "eslint-plugin-prettier/recommended"; 4 | import jsxa11y from "eslint-plugin-jsx-a11y"; 5 | import inferno from "eslint-plugin-inferno"; 6 | import globals from "globals"; 7 | 8 | export default [ 9 | pluginJs.configs.recommended, 10 | ...tseslint.configs.recommended, 11 | prettier, 12 | { 13 | plugins: { 14 | inferno: inferno, 15 | rules: inferno.configs.recommended, 16 | }, 17 | }, 18 | { 19 | plugins: { 20 | "jsx-a11y": jsxa11y, 21 | }, 22 | rules: jsxa11y.configs.recommended.rules, 23 | }, 24 | { 25 | languageOptions: { 26 | parser: tseslint.parser, 27 | globals: globals.node, 28 | }, 29 | }, 30 | // For some reason this has to be in its own block 31 | { 32 | ignores: [ 33 | "crawl.mjs", 34 | "generate_rss_feed.mjs", 35 | "generate_translations.mjs", 36 | "lemmy-js-client-main", 37 | "lemmy-js-client-v0.19", 38 | "webpack.config.js", 39 | "tailwind.config.js", 40 | "src/shared/build-config.js", 41 | "src/api_tests", 42 | "**/*.png", 43 | "**/*.css", 44 | "**/*.scss", 45 | "**/*.svg", 46 | "dist/*", 47 | ".yalc/*", 48 | "lemmy-docs", 49 | ], 50 | }, 51 | { 52 | files: ["src/**/*.js", "src/**/*.mjs", "src/**/*.ts", "src/**/*.tsx"], 53 | rules: { 54 | "@typescript-eslint/ban-ts-comment": 0, 55 | "@typescript-eslint/no-explicit-any": 0, 56 | "@typescript-eslint/no-unused-vars": [ 57 | "error", 58 | { argsIgnorePattern: "^_" }, 59 | ], 60 | "explicit-module-boundary-types": 0, 61 | "no-empty-function": 0, 62 | "no-non-null-assertion": 0, 63 | "arrow-body-style": 0, 64 | curly: 0, 65 | "eol-last": 0, 66 | eqeqeq: "error", 67 | "func-style": 0, 68 | "import/no-duplicates": 0, 69 | "max-statements": 0, 70 | "max-params": 0, 71 | "new-cap": 0, 72 | "no-console": 0, 73 | "no-duplicate-imports": 0, 74 | "no-extra-parens": 0, 75 | "no-return-assign": 0, 76 | "no-throw-literal": 0, 77 | "no-trailing-spaces": 0, 78 | "no-unused-expressions": 0, 79 | "no-useless-constructor": 0, 80 | "no-useless-escape": 0, 81 | "no-var": 0, 82 | "prefer-const": "error", 83 | "prefer-rest-params": 0, 84 | "prettier/prettier": "error", 85 | "quote-props": 0, 86 | "unicorn/filename-case": 0, 87 | "jsx-a11y/media-has-caption": 0, 88 | "jsx-a11y/label-has-associated-control": 0, 89 | "no-restricted-imports": [ 90 | "error", 91 | { 92 | patterns: [ 93 | { 94 | group: ["assets/*", "client/*", "server/*", "shared/*"], 95 | message: "Use relative import instead.", 96 | }, 97 | ], 98 | }, 99 | ], 100 | }, 101 | }, 102 | ]; 103 | -------------------------------------------------------------------------------- /src/assets/news/2024-06-19 - Lemmy Release v0.19.5 - A Few Bugfixes.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.19.5 Release 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Changes 8 | 9 | This is a smaller bugfix release, with the following changes: 10 | 11 | ### Lemmy 12 | 13 | - [Don't change encoding style in clean_url_params](https://github.com/LemmyNet/lemmy/pull/4802). 14 | - [Fix for federation last_successful_id](https://github.com/LemmyNet/lemmy/issues/4363). 15 | - [Fixing featured_local trigger](https://github.com/LemmyNet/lemmy/pull/4837). 16 | - [Fix postres TLS connection](https://github.com/LemmyNet/lemmy/pull/4844). 17 | 18 | ### Lemmy-UI 19 | 20 | - [Fix for fetch page title](https://github.com/LemmyNet/lemmy-ui/pull/2519). 21 | - [Fix create post focus resets](https://github.com/LemmyNet/lemmy-ui/pull/2520). 22 | - [Make media uploads viewable only on your own profile](https://github.com/LemmyNet/lemmy-ui/pull/2540). 23 | - [Fixing an auto-download bug](https://github.com/LemmyNet/lemmy-ui/pull/2552). 24 | - [Regenerating lemmy-ui themes](https://github.com/LemmyNet/lemmy-ui/pull/2554). 25 | 26 | ### Full Changelog 27 | 28 | - [Lemmy Backend](https://github.com/LemmyNet/lemmy/compare/0.19.4...0.19.5) 29 | - [Lemmy-UI](https://github.com/LemmyNet/lemmy-ui/compare/0.19.4...0.19.5) 30 | 31 | ## Upgrade instructions 32 | 33 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 34 | 35 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 36 | 37 | ## Thanks to everyone 38 | 39 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 40 | 41 | ## Support development 42 | 43 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over three years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 44 | 45 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 46 | 47 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 48 | - [Open Collective](https://opencollective.com/lemmy) 49 | - [Patreon](https://www.patreon.com/dessalines) 50 | - [Cryptocurrency](https://join-lemmy.org/donate) (scroll to bottom of page) 51 | -------------------------------------------------------------------------------- /src/assets/news/2022-03-17 - Free Lemmy instance hosting.md: -------------------------------------------------------------------------------- 1 | # Free Lemmy instance hosting 2 | 3 | _Written by @nutomic, 2022-03-17_ 4 | 5 | ## What is Lemmy? 6 | 7 | Lemmy is a selfhosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 8 | 9 | To see how it works in practice, you can [browse the list of existing Lemmy instances](https://join-lemmy.org/instances). 10 | 11 | ## Free instance hosting 12 | 13 | After two years of full-time development, Lemmy is in a very usable state. The main problem facing the project now is a lack of users, and low awareness of the project. To remedy this, we the Lemmy developers are launching a new promotion initiative. We will host selected instances for free, for one year. This can be about any topic, like video games, art, or a general forum for your country. The only exception is politics (there are many political instances already). 14 | 15 | The main purpose of this initiative is to promote the Lemmy project, so that more people will use it. For this reason, you should have a plan for growing and promoting the instance. For example, posting about it on your existing blog, posting on other forums, or inviting friends and colleagues. Paid advertising is unnecessary. Additionally, the topic should not be too narrow, but have relatively wide appeal. 16 | 17 | At this time, most existing Lemmy instances and users are concentrated in Europe and North America. For this reason, we especially want to encourage people from other parts of the world to apply, and create instances for their own regions. All languages can be used. 18 | 19 | If you are interested, send an email to contact@join-lemmy.org (in English) with a summary of the instance you want to create, how you plan to promote it, and some relevant details about yourself. The deadline is on 2022-04-18. 20 | 21 | If the application gets accepted, you will be an administrator, which involves a few responsibilities. First of all, you need a domain (the address under which the site can be reached, like `join-lemmy.org`). Then you will have to configure the instance name, description, rules, and a few other settings. And finally, you will be responsible for the moderation, which means removing spam, banning trolls, and dealing with other unwanted content. As the number of users grows, it makes sense to add more administratos to help with these things. After one year (or earlier at your request), we will transfer all the data to you, so that you can run the instance yourself. Then you need a server to install Lemmy on (or find someone else to help). 22 | 23 | Remember, if your potential instance doesn't meet the criteria or is not accepted, you can always [setup your own](https://join-lemmy.org/docs/en/administration/administration.html). People will be happy to help with any problems in our [Matrix channel](https://matrix.to/#/#lemmy:matrix.org) or [/c/lemmy_support forum](https://lemmy.ml/c/lemmy_support). 24 | 25 | Please consider sharing this announcement with others who might be interested. 26 | -------------------------------------------------------------------------------- /src/shared/i18next.ts: -------------------------------------------------------------------------------- 1 | import i18next, { i18nTyped, Resource } from "i18next"; 2 | 3 | // Languages 4 | import { bg } from "./translations/bg"; 5 | import { da } from "./translations/da"; 6 | import { de } from "./translations/de"; 7 | import { el } from "./translations/el"; 8 | import { en } from "./translations/en"; 9 | import { eo } from "./translations/eo"; 10 | import { es } from "./translations/es"; 11 | import { eu } from "./translations/eu"; 12 | import { fa } from "./translations/fa"; 13 | import { fi } from "./translations/fi"; 14 | import { fr } from "./translations/fr"; 15 | import { gl } from "./translations/gl"; 16 | import { id } from "./translations/id"; 17 | import { it } from "./translations/it"; 18 | import { ja } from "./translations/ja"; 19 | import { ko } from "./translations/ko"; 20 | import { nb_NO } from "./translations/nb_NO"; 21 | import { nn } from "./translations/nn"; 22 | import { nl } from "./translations/nl"; 23 | import { pl } from "./translations/pl"; 24 | import { pt } from "./translations/pt"; 25 | import { pt_BR } from "./translations/pt_BR"; 26 | import { ru } from "./translations/ru"; 27 | import { zh } from "./translations/zh"; 28 | 29 | export const LANGUAGES = [ 30 | { resource: bg, code: "bg", name: "Български" }, 31 | { resource: da, code: "da", name: "Dansk" }, 32 | { resource: de, code: "de", name: "Deutsch" }, 33 | { resource: el, code: "el", name: "Ελληνικά" }, 34 | { resource: en, code: "en", name: "English" }, 35 | { resource: eo, code: "eo", name: "Esperanto" }, 36 | { resource: es, code: "es", name: "Español" }, 37 | { resource: eu, code: "eu", name: "Euskara" }, 38 | { resource: fa, code: "fa", name: "فارسی" }, 39 | { resource: fi, code: "fi", name: "Suomi" }, 40 | { resource: fr, code: "fr", name: "Français" }, 41 | { resource: gl, code: "gl", name: "Galego" }, 42 | { resource: id, code: "id", name: "Bahasa Indonesia" }, 43 | { resource: it, code: "it", name: "Italiano" }, 44 | { resource: ja, code: "ja", name: "日本語" }, 45 | { resource: ko, code: "ko", name: "한국어" }, 46 | { resource: nb_NO, code: "nb-NO", name: "Norsk (bokmål)" }, 47 | { resource: nn, code: "nn", name: "nynorsk" }, 48 | { resource: nl, code: "nl", name: "Nederlands" }, 49 | { resource: pl, code: "pl", name: "Polski" }, 50 | { resource: pt, code: "pt", name: "Português" }, 51 | { resource: pt_BR, code: "pt-BR", name: "Português (Brasil)" }, 52 | { resource: ru, code: "ru", name: "Русский" }, 53 | { resource: zh, code: "zh", name: "中文" }, 54 | ]; 55 | 56 | const resources: Resource = {}; 57 | LANGUAGES.forEach(l => (resources[l.code] = l.resource)); 58 | 59 | function format(value: any, format: any): any { 60 | return format === "uppercase" ? value.toUpperCase() : value; 61 | } 62 | 63 | i18next.init({ 64 | debug: false, 65 | // load: 'languageOnly', 66 | // initImmediate: false, 67 | fallbackLng: "en", 68 | resources, 69 | interpolation: { format }, 70 | }); 71 | 72 | export const i18n = i18next as i18nTyped; 73 | 74 | export { resources }; 75 | 76 | // https://gist.github.com/hunan-rostomyan/28e8702c1cecff41f7fe64345b76f2ca 77 | export function getLanguageFromCookie(cookies?: string): string | undefined { 78 | const key = "lang="; 79 | return cookies 80 | ?.split(";") 81 | .map(c => c.trim()) 82 | .filter(cookie => cookie.substring(0, key.length) === key) 83 | .map(cookie => cookie.substring(key.length))[0]; 84 | } 85 | -------------------------------------------------------------------------------- /generate_translations.mjs: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import path from "path"; 3 | 4 | const translationDir = "joinlemmy-translations/translations/"; 5 | const outDir = "src/shared/translations/"; 6 | const translatorsJsonFile = "lemmy-translations/translators.json"; 7 | const newsDir = "src/assets/news"; 8 | 9 | fs.mkdirSync(outDir, { recursive: true }); 10 | 11 | // Write the news file 12 | try { 13 | let files = fs.readdirSync(newsDir); 14 | let data = `export const news_md = \n `; 15 | let arr = []; 16 | for (let file of files) { 17 | let p = `${newsDir}/${file}`; 18 | const title = path.parse(file).name; 19 | const markdown = fs.readFileSync(p, "utf8"); 20 | let val = { title: title, markdown: markdown }; 21 | arr.push(val); 22 | } 23 | data += JSON.stringify(arr, null, 2) + ";\n"; 24 | const target = outDir + "news.ts"; 25 | fs.writeFileSync(target, data); 26 | } catch (err) { 27 | console.error(err); 28 | } 29 | 30 | // Write the translations 31 | fs.readdir(translationDir, (_err, files) => { 32 | files.forEach(filename => { 33 | const lang = filename.split(".")[0]; 34 | try { 35 | const json = JSON.parse( 36 | fs.readFileSync(translationDir + filename, "utf8"), 37 | ); 38 | let data = `export const ${lang} = {\n translation: {`; 39 | for (const key in json) { 40 | if (key in json) { 41 | const value = json[key].replace(/"/g, '\\"'); 42 | data += `\n ${key}: "${value}",`; 43 | } 44 | } 45 | data += "\n },\n};"; 46 | const target = outDir + lang + ".ts"; 47 | fs.writeFileSync(target, data); 48 | } catch (err) { 49 | console.error(err); 50 | } 51 | }); 52 | // Add the translators.json file 53 | try { 54 | const json = JSON.parse(fs.readFileSync(translatorsJsonFile, "utf8")); 55 | let data = `export const translators = \n `; 56 | data += JSON.stringify(json, null, 2) + ";"; 57 | const target = outDir + "translators.ts"; 58 | fs.writeFileSync(target, data); 59 | } catch (err) { 60 | console.error(err); 61 | } 62 | }); 63 | 64 | // generate types for i18n keys 65 | const baseLanguage = "en"; 66 | 67 | fs.readFile(`${translationDir}${baseLanguage}.json`, "utf8", (_, fileStr) => { 68 | const keys = Object.keys(JSON.parse(fileStr)); 69 | 70 | const data = `import { i18n } from "i18next"; 71 | 72 | declare module "i18next" { 73 | export type I18nKeys = 74 | ${keys.map(key => ` | "${key}"`).join("\n")}; 75 | 76 | export interface TFunctionTyped { 77 | // basic usage 78 | < 79 | TResult extends TFunctionResult = string, 80 | TInterpolationMap extends Record = StringMap 81 | >( 82 | key: I18nKeys | I18nKeys[], 83 | options?: TOptions | string 84 | ): TResult; 85 | // overloaded usage 86 | < 87 | TResult extends TFunctionResult = string, 88 | TInterpolationMap extends Record = StringMap 89 | >( 90 | key: I18nKeys | I18nKeys[], 91 | defaultValue?: string, 92 | options?: TOptions | string 93 | ): TResult; 94 | } 95 | 96 | export interface i18nTyped extends i18n { 97 | t: TFunctionTyped; 98 | } 99 | } 100 | `; 101 | 102 | fs.writeFileSync(`${outDir}i18next.d.ts`, data); 103 | }); 104 | -------------------------------------------------------------------------------- /src/shared/utils.ts: -------------------------------------------------------------------------------- 1 | import { default as MarkdownIt } from "markdown-it"; 2 | import markdown_it_container from "markdown-it-container"; 3 | import markdown_it_bidi from "markdown-it-bidi"; 4 | import markdown_it_footnote from "markdown-it-footnote"; 5 | import markdown_it_ruby from "markdown-it-ruby"; 6 | import markdown_it_sub from "markdown-it-sub"; 7 | import markdown_it_sup from "markdown-it-sup"; 8 | 9 | const SHORTNUM_SI_FORMAT = new Intl.NumberFormat("en-US", { 10 | maximumFractionDigits: 1, 11 | //@ts-ignore 12 | notation: "compact", 13 | compactDisplay: "short", 14 | }); 15 | 16 | export function numToSI(value: any) { 17 | return SHORTNUM_SI_FORMAT.format(value); 18 | } 19 | 20 | export function isBrowser() { 21 | return typeof window !== "undefined"; 22 | } 23 | 24 | const spoilerConfig = { 25 | validate: (params: string) => { 26 | return params.trim().match(/^spoiler\s+(.*)$/); 27 | }, 28 | 29 | render: (tokens: any, idx: any) => { 30 | const m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/); 31 | if (tokens[idx].nesting === 1) { 32 | // opening tag 33 | const summary = mdToHtmlInline(md.utils.escapeHtml(m[1])).__html; 34 | return `
${summary} \n`; 35 | } else { 36 | // closing tag 37 | return "
\n"; 38 | } 39 | }, 40 | }; 41 | 42 | // Zero disables all rules. 43 | // Only explicitly allow a limited set of rules safe for use in post titles. 44 | export const mdLimited: MarkdownIt = new MarkdownIt("zero").enable([ 45 | "emphasis", 46 | "backticks", 47 | "strikethrough", 48 | ]); 49 | 50 | export function mdToHtmlInline(text: string) { 51 | return { __html: mdLimited.renderInline(text) }; 52 | } 53 | 54 | export const md = new MarkdownIt({ 55 | html: true, 56 | linkify: true, 57 | typographer: true, 58 | }) 59 | .use(markdown_it_sub) 60 | .use(markdown_it_sup) 61 | .use(markdown_it_footnote) 62 | .use(markdown_it_container, "spoiler", spoilerConfig) 63 | .use(markdown_it_ruby) 64 | .use(markdown_it_bidi); 65 | 66 | export function mdToHtml(text: string) { 67 | return { __html: md.render(text) }; 68 | } 69 | 70 | export function getQueryParams>(processors: { 71 | [K in keyof T]: (param: string) => T[K]; 72 | }): T { 73 | if (isBrowser()) { 74 | const searchParams = new URLSearchParams(window.location.search); 75 | 76 | return Array.from(Object.entries(processors)).reduce( 77 | (acc, [key, process]) => ({ 78 | ...acc, 79 | [key]: process(searchParams.get(key)), 80 | }), 81 | {} as T, 82 | ); 83 | } 84 | 85 | return {} as T; 86 | } 87 | 88 | export const NUMBER_FORMAT = new Intl.NumberFormat("en", { 89 | maximumFractionDigits: 0, 90 | }); 91 | 92 | export function monthsBetween(startDate: Date, endDate: Date) { 93 | // The number of milliseconds in one day 94 | const oneMonth = (1000 * 60 * 60 * 24 * 365) / 12; 95 | 96 | // Calculate the difference in milliseconds 97 | const differenceMs = Math.abs(startDate.getTime() - endDate.getTime()); 98 | 99 | // Convert back to days and return 100 | return Math.round(differenceMs / oneMonth); 101 | } 102 | 103 | export function sortRandom(list: T[]): T[] { 104 | return list 105 | .map(value => ({ value, sort: Math.random() })) 106 | .sort((a, b) => a.sort - b.sort) 107 | .map(({ value }) => value); 108 | } 109 | -------------------------------------------------------------------------------- /src/assets/news/2021-04-27 - Lemmy Release v0.11.0.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.11.0 2 | 3 | _Written by @dessalines and @nutomic, 2021-04-27_ 4 | 5 | Since our last release this month, we've had [~60](https://github.com/LemmyNet/lemmy/compare/0.10.0...main) commits to Lemmy. 6 | 7 | ### Lemmy Server 8 | 9 | #### Major Changes 10 | 11 | - Add option to disable strict allowlist ( [#1486](https://github.com/LemmyNet/lemmy/issues/1486)) [documentation](https://join.lemmy.ml/docs/en/federation/administration.html) 12 | - Add option to limit community creation to admins only ([#1587](https://github.com/LemmyNet/lemmy/issues/1587)) 13 | - Many search improvements: 14 | - Don't search for communities or users when the id is included. 15 | - Add creator id to search. 16 | 17 | #### General 18 | 19 | - Adding a user setting to show / hide scores. Fixes [#1503](https://github.com/LemmyNet/lemmy/issues/1503) 20 | - Add option to hide read posts. Fixes [#1561](https://github.com/LemmyNet/lemmy/issues/1561) 21 | - Mark accounts as bot, and hide bot posts/comments 22 | - Adding a short site description, to be used for joinlemmy instance list 23 | - Adding matrix id validation. Fixes [#1520](https://github.com/LemmyNet/lemmy/issues/1520) 24 | - Adding users active monthly for community sort. Fixes [#1527](https://github.com/LemmyNet/lemmy/issues/1527) 25 | - Don't allow zero-space char in display name. Fixes [#1317](https://github.com/LemmyNet/lemmy/issues/1317) 26 | - Adding more rust captcha features. Fixes [#1248](https://github.com/LemmyNet/lemmy/issues/1248) 27 | - Fixing slur filter regex. Fixes [#1593](https://github.com/LemmyNet/lemmy/issues/1593) 28 | 29 | #### API 30 | 31 | - Added `ChangePassword` as a separate endpoint from `SaveUserSettings` 32 | - No other breaking changes, but many fields that were previously required are now optional. 33 | - A full list of the API changes can be seen on this diff of [lemmy-js-client: 0.10.0 -> 0.11.0](https://github.com/LemmyNet/lemmy-js-client/compare/0.10.0...0.11.0-rc.13) . 34 | 35 | #### Federation 36 | 37 | - Implement federated bans fixes [#1298](https://github.com/LemmyNet/lemmy/issues/1298) 38 | - Remote mods can update/delete/undelete communities. 39 | 40 | ### Lemmy UI 41 | 42 | - Updating translations. 43 | - Add UI version to UI via docker. Fixes [#263](https://github.com/LemmyNet/lemmy-ui/issues/263) 44 | - Add Korean language 45 | - Add check for unused languages in update_translations.sh 46 | - Validate matrix id on the front end. Fixes [#245](https://github.com/LemmyNet/lemmy-ui/issues/245) 47 | - Communities page sorts by monthly active users. Fixes [#244](https://github.com/LemmyNet/lemmy-ui/issues/244) 48 | - Correctly render HTML in popup notifications 49 | - Fix html notif bug. Fixes [#254](https://github.com/LemmyNet/lemmy-ui/issues/254) 50 | - Fixing issue with debounce. Fixes [#236](https://github.com/LemmyNet/lemmy-ui/issues/236) 51 | 52 | ## Upgrade notes 53 | 54 | ### Servers 55 | 56 | If you'd like to make a DB backup before upgrading, follow [this guide](https://join.lemmy.ml/docs/en/administration/backup_and_restore.html). 57 | 58 | To upgrade your instance to `v0.11.0`, simply follow the instructions in the documentation: 59 | 60 | - [Upgrade with manual Docker installation](https://join.lemmy.ml/docs/en/administration/install_docker.html#updating) 61 | - [Upgrade with Ansible installation](https://join.lemmy.ml/docs/en/administration/install_ansible.html) 62 | 63 | ### Clients / Apps 64 | 65 | - A full list of the API changes can be seen on this diff of [lemmy-js-client: 0.10.0 -> 0.11.0](https://github.com/LemmyNet/lemmy-js-client/compare/0.10.0...0.11.0-rc.13) . 66 | -------------------------------------------------------------------------------- /src/assets/news/2023-08-08 - Lemmy Release v0.18.4.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.18.4 Release (2023-08-08) 2 | 3 | _Written by @nutomic, 2023-08-08_ 4 | 5 | ## What is Lemmy? 6 | 7 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 8 | 9 | ## Major Changes 10 | 11 | This version fixes the problem of comment context not loading properly. It also fixes a couple other bugs. 12 | 13 | ## Support development 14 | 15 | @dessalines and @nutomic are working full-time on Lemmy to integrate community contributions, fix bugs, optimize performance and much more. This work is funded exclusively through donations. 16 | 17 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). No one likes recurring donations, but they’ve proven to be the only way that open-source software like Lemmy can stay independent and alive. 18 | 19 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 20 | - [Open Collective](https://opencollective.com/lemmy) 21 | - [Patreon](https://www.patreon.com/dessalines) 22 | - [Cryptocurrency](https://join-lemmy.org/donate) (scroll to bottom of page) 23 | 24 | ## Upgrade instructions 25 | 26 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible#upgrading) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). There are no config or API changes with this release. 27 | 28 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/#lemmy-admin-support-topics:discuss.online). 29 | 30 | ## Changes 31 | 32 | ### Lemmy 33 | 34 | - Fix fetch instance software version from nodeinfo ([#3772](https://github.com/LemmyNet/lemmy/issues/3772)) 35 | - Correct logic to meet join-lemmy requirement, don't have closed signups. Allows Open and Applications. ([#3761](https://github.com/LemmyNet/lemmy/issues/3761)) 36 | - Fix ordering when doing a comment_parent type `list_comments` ([#3823](https://github.com/LemmyNet/lemmy/issues/3823)) 37 | 38 | ### Lemmy-UI 39 | 40 | - Mark post as read when clicking "Expand here" on the preview image on the post listing page ([#1600](https://github.com/LemmyNet/lemmy/issues/1600)) ([#1978](https://github.com/LemmyNet/lemmy/issues/1978)) 41 | - Update translation submodule ([#2023](https://github.com/LemmyNet/lemmy/issues/2023)) 42 | - Fix comment insertion from context views. Fixes #2030 ([#2031](https://github.com/LemmyNet/lemmy/issues/2031)) 43 | - Fix password autocomplete ([#2033](https://github.com/LemmyNet/lemmy/issues/2033)) 44 | - Fix suggested title " " spaces ([#2037](https://github.com/LemmyNet/lemmy/issues/2037)) 45 | - Expanded the RegEx to check if the title contains new line caracters. Should fix issue #1962 ([#1965](https://github.com/LemmyNet/lemmy/issues/1965)) 46 | - ES-Lint tweak ([#2001](https://github.com/LemmyNet/lemmy/issues/2001)) 47 | - Upgrading deps, running prettier. ([#1987](https://github.com/LemmyNet/lemmy/issues/1987)) 48 | - Fix document title of admin settings being overwritten by tagline and emoji forms ([#2003](https://github.com/LemmyNet/lemmy/issues/2003)) 49 | - Use proper modifier key in markdown text input on macOS ([#1995](https://github.com/LemmyNet/lemmy/issues/1995)) 50 | -------------------------------------------------------------------------------- /src/shared/components/crypto.tsx: -------------------------------------------------------------------------------- 1 | import { Helmet } from "inferno-helmet"; 2 | import { Badge } from "./common"; 3 | import { Component } from "inferno"; 4 | import * as QRCode from "qrcode"; 5 | import { Icon } from "./icon"; 6 | 7 | const title = "Crypto"; 8 | 9 | interface Cryptos { 10 | name: string; 11 | address: string; 12 | } 13 | 14 | const CRYPTOS: Cryptos[] = [ 15 | { 16 | name: "Bitcoin", 17 | address: "1Hefs7miXS5ff5Ck5xvmjKjXf5242KzRtK", 18 | }, 19 | { 20 | name: "Ethereum", 21 | address: "0x400c96c96acbC6E7B3B43B1dc1BB446540a88A01", 22 | }, 23 | { 24 | name: "Monero", 25 | address: 26 | "41taVyY6e1xApqKyMVDRVxJ76sPkfZhALLTjRvVKpaAh2pBd4wv9RgYj1tSPrx8wc6iE1uWUfjtQdTmTy2FGMeChGVKPQuV", 27 | }, 28 | ]; 29 | 30 | const QrModal = ({ name, imgData }) => ( 31 | 32 |
33 | 34 |
35 |
36 |
37 | 40 |
41 |
42 | 43 |
44 |
45 |
46 | ); 47 | 48 | interface State { 49 | cryptoQr: Map; 50 | } 51 | 52 | export class Crypto extends Component { 53 | state = { cryptoQr: new Map() }; 54 | constructor(props: any, context: any) { 55 | super(props, context); 56 | } 57 | 58 | async componentDidMount() { 59 | const cryptoQr = new Map(); 60 | for (const c of CRYPTOS) { 61 | cryptoQr.set(c.name, await QRCode.toDataURL(c.address)); 62 | } 63 | this.setState({ cryptoQr }); 64 | } 65 | 66 | render() { 67 | return ( 68 |
69 | 70 | 71 | 72 | {Array.from(this.state.cryptoQr.entries()).map(e => ( 73 | 74 | ))} 75 | 76 |
{title}
77 |
78 |
79 | 80 | {CRYPTOS.map(c => ( 81 | 82 | 83 | 92 | 104 | 105 | ))} 106 |
{c.name} 84 | 87 | {c.address} 88 | 89 | } 90 | /> 91 | 93 | 103 |
107 |
108 |
109 |
110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/shared/components/news.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "inferno"; 2 | import { Link } from "inferno-router"; 3 | import { Helmet } from "inferno-helmet"; 4 | import { i18n } from "../i18next"; 5 | import { isBrowser, mdToHtml } from "../utils"; 6 | import { news_md } from "../translations/news"; 7 | import { BottomSpacer } from "./common"; 8 | 9 | const title = i18n.t("news"); 10 | const news_reversed = news_md.reverse(); 11 | 12 | interface NewsInfo { 13 | title: string; 14 | dateStr: string; 15 | preview: string; 16 | url: string; 17 | } 18 | 19 | function buildNewsInfoArray(): Array { 20 | return news_reversed.map(n => { 21 | const split = n.title.split(" - "); 22 | 23 | return { 24 | dateStr: split[0], 25 | title: split[1], 26 | preview: split[2] || previewMarkdown(n.markdown), 27 | url: `news/${titleToUrl(n.title)}`, 28 | }; 29 | }); 30 | } 31 | 32 | function titleToUrl(title: string): string { 33 | return title.replace(/ /g, "_"); 34 | } 35 | 36 | function previewMarkdown(markdown: string): string { 37 | return markdown 38 | .replace(/#/g, "") 39 | .split(/\n/g) 40 | .slice(3) 41 | .join("\n") 42 | .replace(/[\n\r]/g, " ") 43 | .slice(0, 100) 44 | .concat("..."); 45 | } 46 | 47 | const TitleBlock = () => ( 48 |
49 | {title} 50 | 51 | {i18n.t("rss_feeds")} 56 | 57 |
58 | ); 59 | 60 | const NewsCards = () => buildNewsInfoArray().map(n => ); 61 | 62 | interface NewsProps { 63 | news: NewsInfo; 64 | } 65 | 66 | const NewsCard = ({ news }: NewsProps) => ( 67 |
68 |
69 |
70 |
71 |
72 | 73 | {news.title} 74 | 75 |
{news.dateStr}
76 |
77 | {news.preview && ( 78 |
82 | )} 83 |
84 | 88 | {i18n.t("read_more")} 89 | 90 |
91 |
92 |
93 | ); 94 | 95 | export class News extends Component { 96 | constructor(props: any, context: any) { 97 | super(props, context); 98 | } 99 | 100 | componentDidMount() { 101 | if (isBrowser()) { 102 | window.scrollTo(0, 0); 103 | } 104 | } 105 | 106 | render() { 107 | return ( 108 |
109 | 110 | 111 | 117 | 118 | 119 | 120 | 121 |
122 | ); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /.woodpecker.yml: -------------------------------------------------------------------------------- 1 | #clone: 2 | # git: 3 | # image: woodpeckerci/plugin-git 4 | # settings: 5 | # recursive: true 6 | # submodule_update_remote: true 7 | 8 | variables: 9 | - &install_pnpm "npm install --global corepack@latest && corepack enable pnpm" 10 | 11 | steps: 12 | prepare_repo: 13 | image: alpine:3 14 | commands: 15 | - apk add git 16 | - git submodule init 17 | - git submodule update 18 | when: 19 | - event: pull_request 20 | 21 | prettier_markdown_check: 22 | image: jauderho/prettier:3.7.3-alpine 23 | commands: 24 | - prettier -c . "!dist" "!lemmy-docs" "!lemmy-translations" "!joinlemmy-translations" "!lemmy-js-client-v0.19" "!lemmy-js-client-main" "!lemmy-stats-crawler" "!src/shared/instance_stats.ts" "!src/shared/donation_stats.ts" "!pnpm-lock.yaml" 25 | when: 26 | - event: pull_request 27 | 28 | install: 29 | image: node:20-bookworm-slim 30 | commands: 31 | - *install_pnpm 32 | - pnpm i 33 | when: 34 | - event: pull_request 35 | 36 | lint: 37 | image: node:20-bookworm-slim 38 | commands: 39 | - *install_pnpm 40 | - pnpm lint 41 | when: 42 | - event: pull_request 43 | 44 | build_dev: 45 | image: node:20-bookworm-slim 46 | commands: 47 | - *install_pnpm 48 | - pnpm prebuild:dev 49 | - pnpm build:dev 50 | when: 51 | - event: pull_request 52 | 53 | nightly_instance_crawl: 54 | image: node:20-bookworm-slim 55 | commands: 56 | # libpq and openssl can probably be removed after lemmy dep is upgraded to 0.16.4+ 57 | - apk add cargo pkgconfig openssl openssl-dev libpq libpq-dev 58 | - *install_pnpm 59 | - pnpm crawl 60 | when: 61 | - event: cron 62 | 63 | nightly_build_and_push_to_docker_hub: 64 | image: woodpeckerci/plugin-docker-buildx 65 | settings: 66 | dockerfile: Dockerfile 67 | repo: dessalines/joinlemmy-site 68 | tag: latest 69 | username: 70 | from_secret: docker_username 71 | password: 72 | from_secret: docker_password 73 | when: 74 | - event: cron 75 | 76 | release_instance_crawl: 77 | image: node:20-bookworm-slim 78 | commands: 79 | # libpq and openssl can probably be removed after lemmy dep is upgraded to 0.16.4+ 80 | - apk add cargo pkgconfig openssl openssl-dev libpq libpq-dev 81 | - *install_pnpm 82 | - pnpm crawl 83 | when: 84 | - event: tag 85 | 86 | release_build_and_push_to_docker_hub: 87 | image: woodpeckerci/plugin-docker-buildx 88 | settings: 89 | dockerfile: Dockerfile 90 | repo: dessalines/joinlemmy-site 91 | tag: latest 92 | username: 93 | from_secret: docker_username 94 | password: 95 | from_secret: docker_password 96 | when: 97 | - event: tag 98 | 99 | notify_success: 100 | image: alpine:3 101 | commands: 102 | - apk add curl 103 | - "curl -H'Title: ✔️ ${CI_REPO_NAME}/${CI_COMMIT_SOURCE_BRANCH}' -d'${CI_PIPELINE_URL}' ntfy.sh/lemmy_drone_ci" 104 | when: 105 | - event: pull_request 106 | status: [success] 107 | 108 | notify_failure: 109 | image: alpine:3 110 | commands: 111 | - apk add curl 112 | - "curl -H'Title: ❌ ${CI_REPO_NAME}/${CI_COMMIT_SOURCE_BRANCH}' -d'${CI_PIPELINE_URL}' ntfy.sh/lemmy_drone_ci" 113 | when: 114 | - event: pull_request 115 | status: [failure] 116 | 117 | notify_on_tag_deploy: 118 | image: alpine:3 119 | commands: 120 | - apk add curl 121 | - "curl -H'Title: ${CI_REPO_NAME}:${CI_COMMIT_TAG} deployed' -d'${CI_PIPELINE_URL}' ntfy.sh/lemmy_drone_ci" 122 | when: 123 | event: tag 124 | -------------------------------------------------------------------------------- /src/assets/news/2021-08-09 - Promoting Lemmy.md: -------------------------------------------------------------------------------- 1 | # Promoting Lemmy 2 | 3 | _Written by @nutomic, 2021-08-09_ 4 | 5 | I think most of us agree that the main problem which Lemmy has today is its lack of users. This is not for technical reasons, as we know it is quite stable and usable. The main cause is that the project is not widely known yet. In this post I will propose what we can do to change that. 6 | 7 | First, lets clarify why we should promote Lemmy. Clearly there are many different reasons, and every person prioritizes them differently. So I will just give some common examples: 8 | 9 | - Promote open source (and all the benefits that entails) 10 | - No advertising or tracking 11 | - Allow communities to manage themselves, instead of being controlled by corporations 12 | - Making Lemmy more active, particularly if you would like to see more discussions on certain topics 13 | 14 | So how can we promote Lemmy? 15 | 16 | I think one of the most effective thing we can do at this point is to post about Lemmy in other communities where we are active. This has the benefit that other people already trust us to some degree. Open source projects looking to setup a forum might also be a good target. When doing this, we should consider which aspects of the project would be most important to the target audience, and emphasize those. 17 | 18 | Another option is to contact bloggers, video creators, podcasters or others, and suggest that they report about Lemmy. As above, it is important to adjust the message to the target audience. Because Lemmy is quite small, it is unlikely that major tech magazines or professional content creators would care about it. Instead we should focus on smaller creators. This will also lead to more sustainable growth, and give us some legitimacy in the eyes of bigger creators. 19 | 20 | In both cases, we should avoid doing anything that might be perceived as spam. It is better to create one or two high-quality messages, which will give a good impression of the project, rather than a dozen generic ones that tarnish the reputation. 21 | 22 | It is worth noting that some important features are still missing in Lemmy, particularly mod tools (we are going to implement them in the next ~12 months). There also aren't many different instances yet. 23 | 24 | When promoting Lemmy like this, please avoid linking to lemmy.ml directly. This instance is already too big relative to other instances, and it is not meant to be a "flagship instance" ([What is lemmy.ml?](https://lemmy.ml/post/70280)). Instead you should try to find an appropriate instance on [join-lemmy.org](https://join-lemmy.org/instances) and link to it, or link to the joinlemmy site directly. You can also explicitly encourage the creation of new instances. 25 | 26 | On a side note, it might be worth mentioning the many ways that people can contribute to Lemmy (again depending on the audience). There are the obvious ones, like writing code for lemmy and lemmy-ui, writing documentation or translating. There are also multiple interesting options to create new projects, such as: 27 | 28 | - Create an [alternative frontend](https://join-lemmy.org/docs/en/client_development/custom_frontend.html): nojs frontend like [lemmy-lite](https://github.com/IronOxidizer/lemmy-lite), a traditional forum frontend or something like stackoverflow 29 | - Create a new client, be it for mobile, desktop or terminal. 30 | - Gather instance statistics using [lemmy-stats-crawler](https://yerbamate.ml/LemmyNet/lemmy-stats-crawler), and build some nice graphs. 31 | 32 | By the way, Lemmy is not just a Reddit alternative, so there is no reason to limit the promotion to Reddit. 33 | 34 | To help with these promotion efforts, [@dessalines](https://lemmy.ml/u/dessalines) and I would be happy to give interviews via email (in English, German or Spanish). For that, they can get in touch by mailing contact@lemmy.ml. 35 | -------------------------------------------------------------------------------- /src/assets/news/2025-02-10 - Lemmy Release v0.19.9.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.19.9 Release 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Changes 8 | 9 | This version fixes a potential security problem, by preventing Lemmy from accessing localhost URLs. There is also a fix for a crash during markdown parsing. Lemmy now uses [mimalloc](https://microsoft.github.io/mimalloc/) instead of the system allocator (usually glibc), which should improve performance and prevent unlimited memory growth over time. 10 | 11 | ### Lemmy 12 | 13 | - [Error handling for thumbnail generation](https://github.com/LemmyNet/lemmy/pull/5298) 14 | - [Use mimalloc as memory allocator](https://github.com/LemmyNet/lemmy/pull/5378) 15 | - [Additional security checks for URLs](https://github.com/LemmyNet/lemmy/pull/5338) ([details](https://github.com/LemmyNet/lemmy/security/advisories/GHSA-7723-35v7-qcxw)) . [Security Advisory](https://github.com/LemmyNet/lemmy/security/advisories/GHSA-7723-35v7-qcxw) 16 | - [Fix crash while rewriting markdown](https://github.com/LemmyNet/lemmy/pull/5395) 17 | - [Fix peertube federation](https://github.com/LemmyNet/lemmy/pull/5381) 18 | - [Append attachments to comments](https://github.com/LemmyNet/lemmy/pull/5143/files) (@flamingo-cant-draw) 19 | - [Enable site languages for new user](https://github.com/LemmyNet/lemmy/pull/5235) 20 | 21 | ### Lemmy-UI 22 | 23 | - [Enforce required validation on signup answers](https://github.com/LemmyNet/lemmy-ui/pull/2865) (@anhcuky) 24 | - [copy thumbnail URL during crossposting](https://github.com/LemmyNet/lemmy-ui/pull/2877) (@anhcuky) 25 | - [Adding a bottom-margin to spoiler details tag.](https://github.com/LemmyNet/lemmy-ui/pull/2882) 26 | - [Fixing login password limits.](https://github.com/LemmyNet/lemmy-ui/pull/2904) 27 | - [Adding zh-CN as default for zh lang.](https://github.com/LemmyNet/lemmy-ui/pull/2939) 28 | - Updated translations 29 | 30 | ## Upgrade instructions 31 | 32 | There are no breaking changes with this release. 33 | 34 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 35 | 36 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 37 | 38 | ## Thanks to everyone 39 | 40 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 41 | 42 | ## Support development 43 | 44 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over five years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 45 | 46 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 47 | 48 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 49 | - [Open Collective](https://opencollective.com/lemmy) 50 | - [Patreon](https://www.patreon.com/dessalines) 51 | - [Cryptocurrency](https://join-lemmy.org/crypto) 52 | -------------------------------------------------------------------------------- /src/assets/news/2025-09-10 - Lemmy Release 0.19.13.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.19.13 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Changes 8 | 9 | This version fixes a handful of bugs. Most importantly it prevents a background task from blocking the Lemmy server entirely. Edit marks on comments are now hidden if it was edited within 5 minutes of creation. Also the browser cache usage is significantly reduced. Additionally ARM builds are fixed by using the default memory allocator on that platform. 10 | 11 | ### Backend 12 | 13 | - Fixing active counts slow queries. by @dessalines in [#5907](https://github.com/LemmyNet/lemmy/pull/5907) 14 | - Only use mimalloc on x86 and purge images in background task by @Nutomic in [#5893](https://github.com/LemmyNet/lemmy/pull/5893) 15 | - Add missing comment depth check by @Nutomic in [#5842](https://github.com/LemmyNet/lemmy/pull/5842) 16 | - Dont sanitize RSS content manually (fixes #5850) by @Nutomic in [#5852](https://github.com/LemmyNet/lemmy/pull/5852) 17 | - Reduce false positives in URL blocklist to reduce scunthorpe problem by @Nothing4You in [#5807](https://github.com/LemmyNet/lemmy/pull/5807) 18 | 19 | ### Frontend 20 | 21 | - Don't show edit mark if comment was edited in less than 5 minutes by @jfaustino [#3197](https://github.com/LemmyNet/lemmy-ui/pull/3197) 22 | - Increase bio max length to 1000 chars by @nutomic [#3249](https://github.com/LemmyNet/lemmy-ui/pull/3249) 23 | - Change link from element.io to matrix.org by @nutomic [#3250](https://github.com/LemmyNet/lemmy-ui/pull/3250) 24 | - Remove all caches (fixes #3195) by @Nutomic in [#3248](https://github.com/LemmyNet/lemmy-ui/pull/3248) 25 | - Fixed ordering for search results by @Nutomic in [#3219](https://github.com/LemmyNet/lemmy-ui/pull/3219) 26 | - Add search field to community sidebar by @Nutomic in [#3217](https://github.com/LemmyNet/lemmy-ui/pull/3217) 27 | - Add checkbox for title only search by @Nutomic in [#3220](https://github.com/LemmyNet/lemmy-ui/pull/3220) 28 | 29 | ## Upgrade instructions 30 | 31 | There are no breaking changes with this release. 32 | 33 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 34 | 35 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 36 | 37 | ## Thanks to everyone 38 | 39 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 40 | 41 | ## Support development 42 | 43 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over five years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 44 | 45 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 46 | 47 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 48 | - [Open Collective](https://opencollective.com/lemmy) 49 | - [Patreon](https://www.patreon.com/dessalines) 50 | - [Cryptocurrency](https://join-lemmy.org/crypto) 51 | -------------------------------------------------------------------------------- /src/assets/news/2025-03-19 - Lemmy Release v0.19.10 and Developer AMA.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.19.10 and Developer AMA 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Developer AMA 8 | 9 | Next week we are going to hold an "Ask me Anything" where users can ask the Lemmy developers all sorts of questions. They will be answered by [@dessalines](https://lemmy.ml/u/dessalines) and [@nutomic](https://lemmy.ml/u/nutomic) who have been working on Lemmy since the beginning in 2019. Other maintainers may also chime in. You can ask about the beginnings of Lemmy, how we see the future of Lemmy, what makes Lemmy different from Reddit, internet and social media in general, as well as personal questions. 10 | 11 | The AMA thread will be opened next Tuesday, March 25 in [!announcements@lemmy.ml](https://lemmy.ml/c/announcements). We will start responding one day later. Until then you can let other people know about the AMA, think of good questions and read our previous AMAs: 12 | 13 | - [August 2023](https://lemmy.ml/post/2920188) 14 | - [January 2024](https://lemmy.ml/post/11023519) 15 | 16 | ## Changes 17 | 18 | - Fix Youtube thumbnails by increasing the metadata fetch limit to 1 MB [#5266](https://github.com/LemmyNet/lemmy/pull/5266) 19 | - Also remove private messages when banning user with "remove content" (goodbye Nicole) [#5414](https://github.com/LemmyNet/lemmy/pull/5414) 20 | - Ignore accept-language header if no site languages are specified, to avoid that users have English disabled and can't see most posts [#5485](https://github.com/LemmyNet/lemmy/pull/5485) 21 | - Enable english for users on instances with all languages enabled, to resolve the above problem [#5489](https://github.com/LemmyNet/lemmy/pull/5489) [#5493](https://github.com/LemmyNet/lemmy/pull/5493) 22 | - Only list local banned users under `/admin` [#5364](https://github.com/LemmyNet/lemmy/pull/5364) 23 | - Add crawl-delay to robots.txt [#3009](https://github.com/LemmyNet/lemmy-ui/pull/3009) 24 | - Optimize migrations which were included in 0.19.6 [#5301](https://github.com/LemmyNet/lemmy/pull/5301) 25 | 26 | ## Upgrade instructions 27 | 28 | There are no breaking changes with this release. 29 | 30 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 31 | 32 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 33 | 34 | ## Thanks to everyone 35 | 36 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 37 | 38 | ## Support development 39 | 40 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over five years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 41 | 42 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 43 | 44 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 45 | - [Open Collective](https://opencollective.com/lemmy) 46 | - [Patreon](https://www.patreon.com/dessalines) 47 | - [Cryptocurrency](https://join-lemmy.org/crypto) 48 | -------------------------------------------------------------------------------- /src/assets/news/2021-01-25 - Lemmy Release v0.9.0.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.9.0 2 | 3 | _Written by @dessalines and @nutomic, 2021-01-25_ 4 | 5 | ## Changes 6 | 7 | Since our last release in October of last year, and we've had [~450](https://github.com/LemmyNet/lemmy/compare/v0.8.0...main) commits. 8 | 9 | The biggest changes, as we'll outline below, are a re-work of Lemmy's database structure, a `v2` of Lemmy's API, and activitypub compliance fixes. The new re-worked DB is much faster, easier to maintain, and [now supports hierarchical rather than flat objects in the new API](https://github.com/LemmyNet/lemmy/issues/1275). 10 | 11 | We've also seen the first release of [Lemmur](https://github.com/krawieck/lemmur/releases/tag/v0.1.1), an android / iOS (soon) / windows / linux client, as well as [Lemmer](https://github.com/uuttff8/Lemmy-iOS), a native iOS client. Much thanks to @krawieck, @shilangyu, and @uuttff8 for making these great clients. If you can, please contribute to their [patreon](https://www.patreon.com/lemmur) to help fund lemmur development. 12 | 13 | ## LemmyNet projects 14 | 15 | ### Lemmy Server 16 | 17 | - [Moved views from SQL to Diesel](https://github.com/LemmyNet/lemmy/issues/1275). This was a spinal replacement for much of lemmy. 18 | - Removed all the old fast_tables and triggers, and created new aggregates tables. 19 | - Added a `v2` of the API to support the hierarchical objects created from the above changes. 20 | - Moved continuous integration to [drone](https://cloud.drone.io/LemmyNet/lemmy/), now includes formatting, clippy, and cargo build checks, unit testing, and federation testing. [Drone also deploys both amd64 and arm64 images to dockerhub.](https://hub.docker.com/r/dessalines/lemmy) 21 | - Split out documentation into git submodule. 22 | - Shortened slur filter to avoid false positives. 23 | - Added query performance testing and comparisons. Added indexes to make sure every query is `< 30 ms`. 24 | - Added compilation time testing. 25 | 26 | ### Federation 27 | 28 | This release includes some bug fixes for federation, and some changes to get us closer to compliance with the ActivityPub standard. 29 | 30 | - [Community bans now federating](https://github.com/LemmyNet/lemmy/issues/1287). 31 | - [Local posts sometimes got marked as remote](https://github.com/LemmyNet/lemmy/issues/1302). 32 | - [Creator of post/comment was not notified about new child comments](https://github.com/LemmyNet/lemmy/issues/1325). 33 | - [Community deletion now federated](https://github.com/LemmyNet/lemmy/issues/1256). 34 | 35 | None of these are breaking changes, so federation between 0.9.0 and 0.8.11 will work without problems. 36 | 37 | ### Lemmy javascript / typescript client 38 | 39 | - Updated the [lemmy-js-client](https://github.com/LemmyNet/lemmy-js-client) to use the new `v2` API. Our API docs now reference this project's files, to show what the http / websocket forms and responses should look like. 40 | - Drone now handles publishing its [npm packages.](https://www.npmjs.com/package/lemmy-js-client) 41 | 42 | ### Lemmy-UI 43 | 44 | - Updated it to use the `v2` API via `lemmy-js-client`, required changing nearly every component. 45 | - Added a live comment count. 46 | - Added drone deploying, and builds for ARM. 47 | - Fixed community link wrapping. 48 | - Community Titles are now used instead of names. 49 | - Various other bug fixes. 50 | 51 | ### Lemmy Docs 52 | 53 | - We moved documentation into a separate git repository, and support translation for the docs now! 54 | - Moved our code of conduct into the documentation. 55 | 56 | ## Upgrading 57 | 58 | If you'd like to make a DB backup before upgrading, follow [this guide](https://lemmy.ml/docs/en/administration/backup_and_restore.html). 59 | 60 | - [Upgrade with manual Docker installation](https://lemmy.ml/docs/en/administration/install_docker.html#updating) 61 | - [Upgrade with Ansible installation](https://lemmy.ml/docs/en/administration/install_ansible.html) 62 | 63 | ## Known issues 64 | 65 | Some older self-comments are being marked as unread in your inbox, click `Mark all as read` to resolve this. 66 | -------------------------------------------------------------------------------- /src/assets/news/2023-07-11 - Lemmy Release v0.18.2.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.18.2 Release 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Major Changes 8 | 9 | This is an emergency release to fix the cross-site scripting vulnerability that was exploited yesterday. The attack used a bug in custom emoji code in order to exfiltrate admin login tokens. This release fixes the bug. Additionally it disallows inline Javascript using [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). This should ensure that XSS vulnerabilities are impossible from now on. 10 | 11 | Special thanks to @makotech222 and @sunaruas for these fixes. 12 | 13 | Important note for instance admins: if your instance had any custom emojis configured, it is possible that the attacker has gained access to admin accounts. In order to invalidate all logins you need to execute the following command in PostgreSQL, and restart Lemmy afterwards. 14 | 15 | ```sql 16 | UPDATE secret SET jwt_secret = gen_random_uuid(); 17 | ``` 18 | 19 | ## Upgrade instructions 20 | 21 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible#upgrading) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 22 | 23 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/#lemmy-admin-support-topics:discuss.online). 24 | 25 | ## Support development 26 | 27 | We (@dessalines and @nutomic) have been working full-time on Lemmy for almost three years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/). 28 | 29 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). No one likes recurring donations, but they've proven to be the only way that open-source software like Lemmy can stay independent and alive. 30 | 31 | ## Changes 32 | 33 | ### Lemmy 34 | 35 | - Improve api response times by doing send_activity asynchronously ([#3493](https://github.com/LemmyNet/lemmy/issues/3493)) 36 | - Updating `login.rs` with generic `incorrect_login` response. ([#3549](https://github.com/LemmyNet/lemmy/issues/3549)) 37 | - Use async email sender ([#3554](https://github.com/LemmyNet/lemmy/issues/3554)) 38 | - Upgrade all dependencies ([#3526](https://github.com/LemmyNet/lemmy/issues/3526)) 39 | - Only update site_aggregates for local site ([#3516](https://github.com/LemmyNet/lemmy/issues/3516)) 40 | 41 | ### Lemmy-UI 42 | 43 | - Reopen PR 1420 Feature add three six and nine months options frontend ([#1689](https://github.com/LemmyNet/lemmy-ui/issues/1689)) 44 | - Add nonce-based CSP header ([#1907](https://github.com/LemmyNet/lemmy-ui/issues/1907)) 45 | - Use the 'node' user instead of root when running. ([#1894](https://github.com/LemmyNet/lemmy-ui/issues/1894)) 46 | - Add community name to featured post action in Modlog ([#1891](https://github.com/LemmyNet/lemmy-ui/issues/1891)) 47 | - Use canonical URLs ([#1883](https://github.com/LemmyNet/lemmy-ui/issues/1883)) 48 | - Add theme option for compact that respects browser default ([#1870](https://github.com/LemmyNet/lemmy-ui/issues/1870)) 49 | - Update post listing to prefer local image when available ([#1858](https://github.com/LemmyNet/lemmy-ui/issues/1858)) 50 | - Disallow /modlog since it is not relevant for bots ([#1850](https://github.com/LemmyNet/lemmy-ui/issues/1850)) 51 | - Fix XSS vuln ([#1897](https://github.com/LemmyNet/lemmy-ui/issues/1897)) 52 | - User inferno prompt instead of handrolled one ([#1867](https://github.com/LemmyNet/lemmy-ui/issues/1867)) 53 | - Darkly tweak ([#1811](https://github.com/LemmyNet/lemmy-ui/issues/1811)) 54 | - Update lemmy-js-client and lemmy-translations ([#1848](https://github.com/LemmyNet/lemmy-ui/issues/1848)) 55 | -------------------------------------------------------------------------------- /src/assets/news/2021-09-30 - Lemmy Release v0.13.0 - Comment and Post reporting are here!.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.13.0: Comment and Post reporting are here! 2 | 3 | _Written by @dessalines and @nutomic, 2021-09-30_ 4 | 5 | Since our last release earlier this month, we've had [~30](https://github.com/LemmyNet/lemmy/compare/0.12.0...main) commits to Lemmy. 6 | 7 | ## Major Changes 8 | 9 | - Added comment and post reporting in the front end, and cleaned up the reporting API. 10 | - _Note: these are local-only currently, reports are not yet federated._ 11 | - The JWT secret is now auto-generated by the database. 12 | - _Note: this will log out all users, so users will have to log in again._ 13 | - Lots of smaller UI fixes listed below. 14 | 15 | ## Upgrade notes 16 | 17 | ### Servers 18 | 19 | If you'd like to make a DB backup before upgrading, follow [this guide](https://join.lemmy.ml/docs/en/administration/backup_and_restore.html). 20 | 21 | To upgrade your instance to `v0.13.0`, simply follow the instructions in the documentation: 22 | 23 | - [Upgrade with manual Docker installation](https://join.lemmy.ml/docs/en/administration/install_docker.html#updating) 24 | - [Upgrade with Ansible installation](https://join.lemmy.ml/docs/en/administration/install_ansible.html) 25 | 26 | ## Changes 27 | 28 | ### Lemmy Server 29 | 30 | #### General 31 | 32 | - Adding a user agent. Fixes [#1769](https://github.com/LemmyNet/lemmy/issues/1769) 33 | - Ansible changes ([#1781](https://github.com/LemmyNet/lemmy/issues/1781)) 34 | - Clean up reporting ([#1776](https://github.com/LemmyNet/lemmy/issues/1776)) 35 | - Implement webmention support (fixes [#1395](https://github.com/LemmyNet/lemmy/issues/1395)) 36 | - Move jwt secret from config to database (fixes [#1728](https://github.com/LemmyNet/lemmy/issues/1728)) 37 | - Set a 10 char minimum password length. 38 | - Dont pass accept-encoding header to pictrs (ref [#1734](https://github.com/LemmyNet/lemmy/issues/1734)) ([#1738](https://github.com/LemmyNet/lemmy/issues/1738)) 39 | 40 | #### API 41 | 42 | - There are no breaking API changes, only the addition of reporting endpoints. 43 | - A full list of the API changes can be seen on this diff of [lemmy-js-client: 0.12.0 -> 0.13.0](https://github.com/LemmyNet/lemmy-js-client/compare/0.12.0...0.13.0) . 44 | 45 | #### Federation 46 | 47 | - Rewrite fetcher ([#1792](https://github.com/LemmyNet/lemmy/issues/1792)) 48 | 49 | ### Lemmy UI 50 | 51 | - Adding bn, ml, and cs langs 52 | - Reporting ([#434](https://github.com/LemmyNet/lemmy-ui/issues/434)) 53 | - Splitting login and signup pages. Fixes [#386](https://github.com/LemmyNet/lemmy-ui/issues/386) ([#431](https://github.com/LemmyNet/lemmy-ui/issues/431)) 54 | - Fixing image in newtab. Fixes [#382](https://github.com/LemmyNet/lemmy-ui/issues/382) ([#430](https://github.com/LemmyNet/lemmy-ui/issues/430)) 55 | - Navigate away from login page if already logged in. ([#429](https://github.com/LemmyNet/lemmy-ui/issues/429)) 56 | - Add username validation message. Fixes [#387](https://github.com/LemmyNet/lemmy-ui/issues/387) ([#428](https://github.com/LemmyNet/lemmy-ui/issues/428)) 57 | - Password strength meter ([#427](https://github.com/LemmyNet/lemmy-ui/issues/427)) 58 | - Fix community display name overflow. Fixes [#390](https://github.com/LemmyNet/lemmy-ui/issues/390) ([#425](https://github.com/LemmyNet/lemmy-ui/issues/425)) 59 | - Fix logout bug. Fixes [#391](https://github.com/LemmyNet/lemmy-ui/issues/391) ([#424](https://github.com/LemmyNet/lemmy-ui/issues/424)) 60 | - Fix up post, profile and community forms. Fixes [#409](https://github.com/LemmyNet/lemmy-ui/issues/409) ([#423](https://github.com/LemmyNet/lemmy-ui/issues/423)) 61 | - Adding markdown audio and video embeds. Fixes [#420](https://github.com/LemmyNet/lemmy-ui/issues/420) ([#421](https://github.com/LemmyNet/lemmy-ui/issues/421)) 62 | - Adding Si simplifier ([#418](https://github.com/LemmyNet/lemmy-ui/issues/418)) 63 | - Fix profile paging. Fixes [#416](https://github.com/LemmyNet/lemmy-ui/issues/416) ([#417](https://github.com/LemmyNet/lemmy-ui/issues/417)) 64 | - Use my fork of inferno-i18next. Fixes [#413](https://github.com/LemmyNet/lemmy-ui/issues/413) ([#415](https://github.com/LemmyNet/lemmy-ui/issues/415)) 65 | - Add version to package.json . Fixes [#411](https://github.com/LemmyNet/lemmy-ui/issues/411) 66 | -------------------------------------------------------------------------------- /src/shared/components/navbar.tsx: -------------------------------------------------------------------------------- 1 | import { ChangeEvent, linkEvent } from "inferno"; 2 | import { Link } from "inferno-router"; 3 | import { Icon, IconSize } from "./icon"; 4 | import { i18n, LANGUAGES } from "../i18next"; 5 | import classNames from "classnames"; 6 | 7 | const NavLink = ({ content }) => ( 8 |
  • {content}
  • 9 | ); 10 | 11 | const LINK_CLASS = "text-xl px-4 py-2 md:text-lg"; 12 | 13 | const NavLinks = () => ( 14 | <> 15 | 22 | {i18n.t("join")} 23 | 24 | } 25 | /> 26 | 29 | {i18n.t("news")} 30 | 31 | } 32 | /> 33 | 36 | {i18n.t("apps")} 37 | 38 | } 39 | /> 40 | 43 | {i18n.t("donate")} 44 | 45 | } 46 | /> 47 | 54 | {i18n.t("docs")} 55 | 56 | } 57 | /> 58 | 65 | {i18n.t("contact")} 66 | 67 | } 68 | /> 69 | 70 | ); 71 | 72 | function closeNavbarDropdown() { 73 | (document.activeElement as any).blur(); 74 | } 75 | 76 | function handleLanguageChange(_: any, event: ChangeEvent) { 77 | const new_location = location.href.split("?")[0]; 78 | location.href = new_location + `?lang=${event.target.value}`; 79 | } 80 | 81 | export const Footer = () => ; 82 | 83 | export const Navbar = ({ footer = false }) => ( 84 |
    89 |
    90 | 91 | 96 | 97 |
    98 |
    99 |
      100 | 101 |
    102 |
    103 |
    104 | {footer ? ( 105 | 109 | {i18n.t("copyright_line")} 110 | 111 | ) : ( 112 | <> 113 | 127 | 128 | )} 129 |
    134 |
    135 | 136 |
    137 |
      138 | 139 |
    140 |
    141 |
    142 |
    143 | ); 144 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "joinlemmy-site", 3 | "description": "A site for join-lemmy", 4 | "author": "Dessalines ", 5 | "license": "AGPL-3.0", 6 | "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977", 7 | "repository": "https://github.com/LemmyNet/joinlemmy-site", 8 | "scripts": { 9 | "build:dev": "webpack --mode=development", 10 | "build:prod": "webpack --mode=production", 11 | "clean": "rimraf dist", 12 | "crawl": "node crawl.mjs", 13 | "update-donations": "node update_donations.mjs", 14 | "lint": "pnpm translations:generate && tsc --noEmit && pnpm eslint --report-unused-disable-directives && pnpm prettier --check \"src/**/*.{ts,tsx,js,mjs,css,scss}\"", 15 | "prebuild:dev": "pnpm clean && pnpm translations:generate && pnpm tailwind && pnpm generate_rss_feed", 16 | "prebuild:prod": "pnpm clean && pnpm translations:generate && pnpm tailwind && pnpm generate_rss_feed", 17 | "generate_rss_feed": "node generate_rss_feed.mjs", 18 | "translations:generate": "node generate_translations.mjs", 19 | "translations:init": "git submodule init && pnpm translations:update", 20 | "translations:update": "git submodule update --remote --recursive", 21 | "tailwind": "pnpx @tailwindcss/cli -i ./src/style.css -o ./dist/styles/styles.css --minify", 22 | "prepare": "husky", 23 | "start": "pnpm build:dev --watch & pnpx @tailwindcss/cli --watch" 24 | }, 25 | "dependencies": { 26 | "@babel/core": "^7.23.2", 27 | "@babel/plugin-proposal-class-properties": "^7.18.6", 28 | "@babel/plugin-transform-runtime": "^7.23.2", 29 | "@babel/plugin-transform-typescript": "^7.22.15", 30 | "@babel/preset-env": "7.26.0", 31 | "@babel/preset-typescript": "^7.23.2", 32 | "@babel/runtime": "^7.23.2", 33 | "@glidejs/glide": "3.5.2", 34 | "babel-loader": "^9.1.3", 35 | "babel-plugin-inferno": "^6.7.0", 36 | "classnames": "^2.3.2", 37 | "clean-webpack-plugin": "^4.0.0", 38 | "copy-webpack-plugin": "^12.0.2", 39 | "express": "~4.21.0", 40 | "fs-extra": "^11.2.0", 41 | "i18next": "^23.16.5", 42 | "inferno": "^8.2.2", 43 | "inferno-create-element": "^8.2.2", 44 | "inferno-helmet": "^5.2.1", 45 | "inferno-hydrate": "^8.2.2", 46 | "inferno-i18next": "github:nimbusec-oss/inferno-i18next#semver:^7.4.2", 47 | "inferno-router": "^8.2.2", 48 | "inferno-server": "^8.2.2", 49 | "markdown-it": "^14.1.0", 50 | "markdown-it-bidi": "^0.2.0", 51 | "markdown-it-container": "^4.0.0", 52 | "markdown-it-emoji": "^3.0.0", 53 | "markdown-it-footnote": "^4.0.0", 54 | "markdown-it-ruby": "^1.1.1", 55 | "markdown-it-sub": "^2.0.0", 56 | "markdown-it-sup": "^2.0.0", 57 | "node-fetch": "^3.3.2", 58 | "qrcode": "^1.5.3", 59 | "run-node-webpack-plugin": "^1.3.0", 60 | "webpack": "5.96.1", 61 | "webpack-cli": "^5.1.4", 62 | "webpack-node-externals": "^3.0.0", 63 | "xml2js": "^0.6.2" 64 | }, 65 | "devDependencies": { 66 | "tailwindcss": "^4.1.6", 67 | "@tailwindcss/cli": "^4.1.6", 68 | "@tailwindcss/typography": "^0.5.16", 69 | "daisyui": "^5.0.35", 70 | "@eslint/js": "^9.25.1", 71 | "@types/express": "^5.0.0", 72 | "@types/glidejs__glide": "^3.6.3", 73 | "@types/node": "^22.9.0", 74 | "@types/node-fetch": "^2.6.12", 75 | "@types/qrcode": "^1.5.4", 76 | "@typescript-eslint/eslint-plugin": "^8.14.0", 77 | "@typescript-eslint/parser": "^8.14.0", 78 | "css-loader": "^7.0.0", 79 | "eslint": "^9.0.0", 80 | "eslint-config-prettier": "^9.1.0", 81 | "eslint-plugin-inferno": "^7.34.0", 82 | "eslint-plugin-jsx-a11y": "^6.10.0", 83 | "eslint-plugin-prettier": "^5.0.1", 84 | "globals": "^16.0.0", 85 | "husky": "^9.1.7", 86 | "lint-staged": "^15.0.2", 87 | "lodash": "^4.17.21", 88 | "prettier": "^3.6.2", 89 | "rimraf": "^6.0.0", 90 | "sass": "^1.81.0", 91 | "sass-loader": "^16.0.3", 92 | "style-loader": "^4.0.0", 93 | "terser": "^5.24.0", 94 | "typescript": "^5.2.2", 95 | "typescript-eslint": "^8.14.0", 96 | "webpack-dev-server": "5.2.1" 97 | }, 98 | "engines": { 99 | "node": ">=8.9.0" 100 | }, 101 | "engineStrict": true, 102 | "lint-staged": { 103 | "*.{ts,tsx,js}": [ 104 | "prettier --write", 105 | "eslint --fix" 106 | ] 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/assets/news/2021-04-05 - Lemmy v0.10.0 Release.md: -------------------------------------------------------------------------------- 1 | # Lemmy v0.10.0 Release 2 | 3 | _Written by @dessalines and @nutomic, 2021-04-05_ 4 | 5 | ## Changes 6 | 7 | Since our last release in February, we've had [~150](https://github.com/LemmyNet/lemmy/compare/0.9.9...main) commits to Lemmy. The biggest changes, as we'll outline below, are a split of Lemmy's user tables into federated and local tables, necessitating a `v3` of Lemmy's API, federated moderation, i18n support in join.lemmy.ml, and lots of back-end cleanup. 8 | 9 | ### Lemmy Server 10 | 11 | #### General 12 | 13 | - Rewrote config implementation, finally allowing us to use newer Rust versions. 14 | - Removed categories. 15 | - Various refactors. 16 | 17 | #### API 18 | 19 | - A full list of the API changes can be seen on this diff of [lemmy-js-client: 0.9.9 -> 0.10.0](https://github.com/LemmyNet/lemmy-js-client/compare/0.9.9...0.10.0-rc.13) . 20 | - Login invalidation on password change, thanks to @Mart-Bogdan 21 | 22 | #### Federation 23 | 24 | - It is now possible to add users from other instances as community mods. 25 | - Federating Matrix ID. 26 | - Many changes for better compatibility with ActivityPub standard. 27 | 28 | #### Database 29 | 30 | - Split the `user_` into `person` and `local_user` tables. 31 | - Strictly typed commonly used ID columns, to prevent DB errors using `i32` as ids. 32 | - Strictly typed URL fields, thanks to ajyoon. 33 | - Created default DB forms, now used in all the unit tests. 34 | 35 | ### Lemmy UI 36 | 37 | - Now using utf-8 emojis. 38 | - Support for all the above changes to Lemmy. 39 | - Typescript-safe i18n strings, thanks to @shilangyu. 40 | - Added expandable post text (click on open book icon). 41 | - Prettier cross-posting, which does smart quoting. 42 | - Bugfixes for restoring scroll position on post page, custom site favicons, and autocomplete for login fields. 43 | 44 | ### Lemmy Docs 45 | 46 | - Gazconroy built an [Async API spec for Lemmy](https://join.lemmy.ml/api/index.html), that now serves as our main API docs. 47 | 48 | ### join.lemmy.ml 49 | 50 | - Rewrote in inferno isomorphic, added i18n support via [weblate](https://weblate.yerbamate.ml/projects/lemmy/joinlemmy/). 51 | - Added a section on the support page thanking contributors. 52 | - Changed some page urls / titles 53 | 54 | ## Upgrade notes 55 | 56 | **Important**: there are multiple breaking changes: 57 | 58 | - Configuration via environment variables is not supported anymore, you must have all your config in the [lemmy.hjson](https://github.com/LemmyNet/lemmy/blob/main/ansible/templates/config.hjson) file ( except for `LEMMY_CONFIG_LOCATION` ). 59 | - The config format for `allowed_instances` and `blocked_instances` has changed, and you need to adjust your config file manually: 60 | - before: `allowed_instances: ds9.lemmy.ml,enterprise.lemmy.ml` 61 | - now: `allowed_instances: ["ds9.lemmy.ml", "enterprise.lemmy.ml"]` , and only one of the `allowed_instances` or `blocked_instances` blocks can be set. 62 | - The API has been upgraded from `v2` to `v3`, so all clients need to be updated: [lemmy-js-client: 0.9.9 -> 0.10.0](https://github.com/LemmyNet/lemmy-js-client/compare/0.9.9...0.10.0-rc.13) . 63 | 64 | If you'd like to make a DB backup before upgrading, follow [this guide](https://join.lemmy.ml/docs/en/administration/backup_and_restore.html). 65 | 66 | To upgrade your instance to `v0.10.0`, simply follow the instructions in the documentation: 67 | 68 | - [Upgrade with manual Docker installation](https://join.lemmy.ml/docs/en/administration/install_docker.html#updating) 69 | - [Upgrade with Ansible installation](https://join.lemmy.ml/docs/en/administration/install_ansible.html) 70 | 71 | ## Compilation time 72 | 73 | | | v0.9.0 (Rust 1.47) | v0.10.0 (Rust 1.47) | v0.10.0 (Rust 1.51) | 74 | | ----------- | ------------------ | ------------------- | ------------------- | 75 | | Clean | 140s | 146s | 119s | 76 | | Incremental | 28s | 22s | 19s | 77 | 78 | Despite ongoing efforts to speed up compilation, it has actually gotten slower when comparing with the same Rust version. Only thanks to improvements in newer Rust versions has our build process gotten faster. This could be simply because we added more code, while Lemmy v0.9.0 had 22.4k lines of Rust, v0.10.0 has 23.8k (an increase of 6%). 79 | 80 | v0.9.0 build graph: 81 | ![](https://lemmy.ml/pictrs/image/GVBqFnrLqG.jpg) 82 | 83 | v0.10.0 build graph: 84 | ![](https://lemmy.ml/pictrs/image/NllzjVEyNK.jpg) 85 | 86 | We extracted the crates `lemmy_api_crud` and `lemmy_apub_receive` from `lemmy_api` and `lemmy_apub`, respectively, and renamed `lemmy_structs` to `lemmy_api_common`. In the second graph you can see how parts of the api and apub crates are now built nicely in parallel, speeding up builds on multi-core systems. 87 | 88 | On the other hand, some crates have gotten much slower to compile, in particular `lemmy_db_queries` (6.5s slower), `lemmy_apub` (6.5s slower if we include `lemmy_apub_receive`). And `lemmy_db_views` is quite slow, just as before. 89 | -------------------------------------------------------------------------------- /src/server/index.tsx: -------------------------------------------------------------------------------- 1 | import express, { 2 | RequestHandler, 3 | Request, 4 | Response, 5 | NextFunction, 6 | } from "express"; 7 | import { StaticRouter } from "inferno-router"; 8 | import { renderToString } from "inferno-server"; 9 | // import { matchPath } from "inferno-router"; 10 | import path from "path"; 11 | import { App } from "../shared/components/app"; 12 | // import { routes } from "../shared/routes"; 13 | import process from "process"; 14 | import { Helmet } from "inferno-helmet"; 15 | import { getLanguageFromCookie, i18n } from "../shared/i18next"; 16 | 17 | const server = express(); 18 | const port = 1234; 19 | 20 | function cors(_req: Request, res: Response, next: NextFunction): void { 21 | res.header("Access-Control-Allow-Origin", "*"); 22 | next(); 23 | } 24 | 25 | server.use(express.json() as RequestHandler); 26 | server.use(express.urlencoded({ extended: false }) as RequestHandler); 27 | server.use("/static", express.static(path.resolve("./dist"))); 28 | server.use("/docs", express.static(path.resolve("./dist/assets/docs"))); 29 | 30 | // The v0.19 release docs 31 | server.use( 32 | "/api/v0.19", 33 | express.static(path.resolve("./dist/assets/lemmy-js-client-v0.19-docs")), 34 | ); 35 | server.use( 36 | "/lemmy-js-client-docs/v0.19", 37 | express.static(path.resolve("./dist/assets/lemmy-js-client-v0.19-docs")), 38 | ); 39 | 40 | // The main release docs 41 | server.use( 42 | "/api/main", 43 | express.static(path.resolve("./dist/assets/api_main.html")), 44 | ); 45 | server.use( 46 | "/lemmy-js-client-docs/main", 47 | express.static(path.resolve("./dist/assets/lemmy-js-client-main-docs")), 48 | ); 49 | server.use( 50 | "/context.json", 51 | cors, 52 | express.static(path.resolve("./dist/assets/lemmy_federation_context.json")), 53 | ); 54 | server.use("/feed.xml", express.static(path.resolve("./dist/feed.xml"))); 55 | 56 | function erudaInit(): string { 57 | if (process.env["NODE_ENV"] === "development") { 58 | return ` 59 | 60 | 61 | `; 62 | } else { 63 | return ""; 64 | } 65 | } 66 | 67 | function setLanguage(req: Request, res: Response): string { 68 | // Setting the language for non-js browsers 69 | const cookieLang = getLanguageFromCookie(req.headers.cookie); 70 | let language: string; 71 | if (req.query["lang"] !== undefined) { 72 | language = req.query["lang"].toString(); 73 | res.cookie("lang", language, { 74 | expires: new Date(Date.now() + 60 * 60 * 24 * 7), 75 | }); 76 | } else if (cookieLang !== undefined) { 77 | language = cookieLang; 78 | } else { 79 | language = req.headers["accept-language"] 80 | ? req.headers["accept-language"].split(",")[0] 81 | : "en"; 82 | } 83 | return language; 84 | } 85 | 86 | server.get("/*", async (req, res) => { 87 | // const activeRoute = routes.find(route => matchPath(req.path, route)) || {}; 88 | const context = {} as any; 89 | 90 | const language = setLanguage(req, res); 91 | i18n.changeLanguage(language); 92 | 93 | const wrapper = ( 94 | 95 | 96 | 97 | ); 98 | if (context.url) { 99 | return res.redirect(context.url); 100 | } 101 | 102 | const root = renderToString(wrapper); 103 | const helmet = Helmet.renderStatic(); 104 | 105 | res.send(` 106 | 107 | 108 | 109 | ${erudaInit()} 110 | 111 | ${helmet.title.toString()} 112 | ${helmet.meta.toString()} 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | ${helmet.link.toString()} 128 | 129 | 130 |
    ${root}
    131 | 132 | 133 | 134 | 135 | `); 136 | }); 137 | 138 | server.listen(port, () => { 139 | console.log(`http://localhost:${port}`); 140 | }); 141 | 142 | process.on("SIGINT", () => { 143 | console.info("Interrupted"); 144 | process.exit(0); 145 | }); 146 | -------------------------------------------------------------------------------- /src/shared/components/instance-picker.tsx: -------------------------------------------------------------------------------- 1 | import classNames from "classnames"; 2 | import { Component, linkEvent } from "inferno"; 3 | import { ALL_TOPIC, TOPICS, Topic } from "./instances-definitions"; 4 | import { LANGUAGES, i18n } from "../i18next"; 5 | import { I18nKeys } from "i18next"; 6 | import { Icon } from "./icon"; 7 | 8 | enum Step { 9 | Interest, 10 | Language, 11 | } 12 | 13 | interface Props { 14 | reset?: boolean; 15 | } 16 | 17 | interface State { 18 | activeStep: Step; 19 | topic?: Topic; 20 | language?: string; 21 | } 22 | 23 | export class InstancePicker extends Component { 24 | state: State = { 25 | activeStep: Step.Interest, 26 | }; 27 | 28 | constructor(props: any, context: any) { 29 | super(props, context); 30 | } 31 | 32 | componentWillReceiveProps(): void { 33 | this.setState({ 34 | activeStep: Step.Interest, 35 | }); 36 | } 37 | 38 | render() { 39 | return ( 40 | 41 |
    42 | 43 |
    44 |
    45 |
    46 | 49 |
    50 |
    51 | {this.state.activeStep === Step.Interest && ( 52 | <> 53 |

    54 | {i18n.t("what_topic")} 55 |

    56 |
    57 | {TOPICS.map(c => ( 58 | 66 | ))} 67 |
    68 | 69 | )} 70 | {this.state.activeStep === Step.Language && ( 71 | <> 72 |

    73 | {i18n.t("what_language")} 74 |

    75 |
    76 | 83 | {LANGUAGES.map(l => ( 84 | 91 | ))} 92 |
    93 | 94 | )} 95 | 96 |
      97 |
    • 98 | 106 |
    • 107 |
    • 108 | 116 |
    • 117 |
    118 |
    119 |
    120 |
    121 | ); 122 | } 123 | } 124 | 125 | function handleTopicChange(i: InstancePicker, event: any) { 126 | i.setState({ 127 | topic: TOPICS.find(c => c.name === event.target.value) ?? ALL_TOPIC, 128 | activeStep: Step.Language, 129 | }); 130 | } 131 | 132 | function handleLanguageChange(i: InstancePicker, event: any) { 133 | i.setState({ language: event.target.value }); 134 | const url = `/instances?topic=${i.state.topic?.name ?? ALL_TOPIC}&language=${ 135 | i.state.language 136 | }&scroll=true`; 137 | 138 | // Requires a page reload unfortunately 139 | window.location.href = url; 140 | } 141 | 142 | function handleResetInterests(i: InstancePicker) { 143 | i.setState({ topic: undefined, activeStep: Step.Interest }); 144 | } 145 | -------------------------------------------------------------------------------- /src/assets/news/2023-06-17 - Update from Lemmy after the Reddit blackout.md: -------------------------------------------------------------------------------- 1 | # Update from Lemmy after the Reddit blackout 2 | 3 | _Written by @dessalines and @nutomic, 2023-06-17_ 4 | 5 | If you are reading this then you most likely know about the recent news from reddit. As a result of these events, Lemmy has grown immensely in the last two weeks. The number of [monthly active users](https://the-federation.info/lemmy) has increased over 25 times, from 1.000 to 27.000 at time of writing. Suddenly Lemmy has become one of the largest Fediverse projects, ahead of Peertube and Pleroma. 6 | 7 | We are proud of this network growth, because it means that people want to take control of their social media into their own hands, as well as see the benefits of software made to serve human need, rather than the private profits of a few US tech giants. 8 | 9 | However such growth can't happen without problems. Users were confused, servers became overloaded, and countless bugs were reported that no one noticed before. For us maintainers (dessalines and nutomic), it has resulted in an endless stream of questions and notifications, which is impossible to keep up with. Previously there were 5 - 10 Github notifications per day; now they have risen to over 100 daily. 10 | 11 | Additionally, discussions on Matrix and Lemmy are also extremely active. Understandably, our focus has shifted to programming to make Lemmy better, rather than answering an ever-increasing backlog of questions. 12 | 13 | At the moment we are urgently working to solve major issues, such as optimizing slow database queries, ripping out the inefficient websocket API, and fixing a major security vulnerability (big thanks to deadcade). In addition we suddenly have to manage dozens of pull requests. To give us time to work on these priorities, it would be very beneficial if users could refrain from interacting with issue trackers when possible. Before opening an issue, make sure that it hasn't been reported before. And when writing comments, make sure that they actually contribute to solving the issue at hand. Generally it is better to move discussions to Lemmy if possible. We are very thankful to everyone who contributes by writing code, hosting instances, moderating communities, and answering questions. 14 | 15 | At the same time, we are seeing lots of requests to implement major new features, such as migration between instances, or combining similar communities. As described above, we are completely overloaded with work, and definitely won't have time to implement these in the near future. If there is a feature you want to see implemented, you will likely need to work on it yourself, or find someone who can. 16 | 17 | On another topic, there are rumors circulating that we are fascists or supported genocide. These claims are completely false, and like most viral twitter threads, are coming from a single Mastodon user on a personal vendetta who didn't provide any sources. Such slander doesn't deserve any response and is best left ignored. If you want to know the truth then read the following pages (both from 2021): 18 | 19 | - [History of Lemmy](https://join-lemmy.org/docs/en/users/07-history-of-lemmy.html) 20 | - [What is lemmy.ml](https://lemmy.ml/post/70280) 21 | 22 | As you can see we are not a faceless corporation that is accomodating to everyone. We are individuals with our own opinions. If you disagree with these, it is no problem! You can still freely use the Lemmy software on different instances. If you host your own instance, we have no control over it at all and are unable to censor what users say. For more details read the documentation on [censorship resistance](https://join-lemmy.org/docs/en/users/05-censorship-resistance.html). In practice, the [instance list](https://join-lemmy.org/instances) already contains various instances whose content would be banned from lemmy.ml immediately. 23 | 24 | Regarding development, we are happy to collaborate with anyone who is willing to put in the work, regardless of politics. The only condition is to follow the [rules](https://join-lemmy.org/docs/en/code_of_conduct.html) when posting in development spaces. Essentially, be respectful. 25 | 26 | For the past three years dessalines and I have been funded to work on Lemmy full-time by generous support from the [NLnet foundation](https://nlnet.nl/). 27 | These donations are paid out when we implement certain new features. But now we are busy answering questions, reviewing pull requests and urgently fixing problems. That means we are unable to work on the milestones agreed with NLnet, and won't receive payments from them. We are increasingly reliant on user donations to pay our bills. These donations currently add up to 1500 Euros per month, which is not even enough to pay minimum wage for the two of us. Hopefully more users can consider [donating](https://join-lemmy.org/donate), so that we can put our full attention to making Lemmy better for everyone, and possibly add more developers to our worker co-op in the future. 28 | 29 | Again, we'd like to thank everyone for their support and assistance, and we remain hopeful that together, as a federation, the fediverse and all its projects collectively, can win the battle for the internet, and create a better, more enjoyable experience than the one forced upon us by these nefarious tech giants. 30 | -------------------------------------------------------------------------------- /src/assets/news/2023-10-31 - Join-Lemmy Redesign and Funding Drive.md: -------------------------------------------------------------------------------- 1 | # Join-Lemmy Redesign and Funding Drive 2 | 3 | _Written by @nutomic and @dessalines, 2023-10-31_ 4 | 5 | ## Intro 6 | 7 | Some months have passed on since the [Reddit blackout](https://join-lemmy.org/news/2023-06-17_-_Update_from_Lemmy_after_the_Reddit_blackout) this June. It led to an explosive growth in Lemmy users, and lots of urgent work in scaling, bug fixes, user onboarding and more. Since then things have calmed down significantly, giving us breathing room and time to get more long-term work done. 8 | 9 | As of Nov. 2023, Lemmy is at **~36k monthly active users** 🥳 (_those who have posted or commented within the last month_). While user counts are not an explicit goal of ours, this is still a tremendous achievement, and one which we can all be proud to be a part of. It shows that people _truly do_ want alternatives to US tech companies, and will use them if they exist. 10 | 11 | ## Join-Lemmy Redesign 12 | 13 | Most recently we've been working on a redesign of join-lemmy.org to provide a better onboarding experience and cater towards new users. This includes: 14 | 15 | - A helpful new [instance picker](http://join-lemmy.org/?showJoinModal=true) to reduce [choice overload](https://thedecisionlab.com/reference-guide/psychology/choice-overload). 16 | - The [instances page](http://join-lemmy.org/instances) is now _filterable_, based a set of topics and languages, as well as _sortable_ based on activity. The default sort is `Random`, to encourage people to join smaller servers. 17 | - The [apps](http://join-lemmy.org/apps) page now has sections for Android, iOS, and web apps, as well as libraries. Feel free to do a pull request to add any apps that are missing. 18 | - The [donate](http://join-lemmy.org/donate) page now shows the total amount of monthly donations across all platforms. More details below. 19 | - The technology used is Typescript with [tailwind](https://tailwindcss.com/) and [daisyUI](https://daisyui.com/) CSS frameworks. 20 | 21 | **For server admins**: If your instance isn't listed already, you must explicitly add your server topics and languages by doing a pull request to [this file](https://github.com/LemmyNet/joinlemmy-site/blob/4bd4d7a0c450addb8696db22813796b7cf1de3c2/src/shared/components/instances-definitions.ts). 22 | 23 | As you may have noticed, texts on the website are unchanged, and images on the main page are still generic placeholders. We are hoping for your contributions to improve them. For the texts, edit [this file](https://github.com/LemmyNet/joinlemmy-translations/blob/1bc69869fda7ee144ddfbc4d9fb29af3a0d4619e/translations/en.json). Translations are managed via [weblate](https://weblate.join-lemmy.org/projects/lemmy/joinlemmy/). Images are located in [this folder](https://github.com/LemmyNet/joinlemmy-site/tree/main/src/assets/images). If you are good with AI tools, consider replacing `main_federation.webp` and similar with more colorful images. More `main_screen_x.webp` images with custom themes or alternative frontends would be nice too. In general feel free to open issues or pull requests for improvements to the site. 24 | 25 | ## Funding Drive 26 | 27 | Before the Reddit migration, our income was almost exclusively made up of generous donations from the [NLnet foundation](https://nlnet.nl/). This funding was based on getting paid for implementing new features, specified in advance. 28 | 29 | We've known that this funding could not last indefinitely, and that after several years of funding, NLnet's resources are better spent getting other projects up and running. Additionally, much of our time is spent on other equally important work: reviewing changes from community contributors, fixing bugs, doing support, and various organizational tasks. 30 | 31 | That is why we are launching our first **annual funding drive**. The goal is to increase monthly, recurring donations from currently €4.000 to at least €12.000. With this amount @dessalines and @nutomic can each receive a yearly salary of €50.000 which is in line with [median developer salaries](https://www.developersalary.com/). It will also allow one additional developer to work fulltime on Lemmy and speed up development. 32 | 33 | Recurring donations from Lemmy users are the most sustainable solution for the future. It also means that we need to worry less about funding, and can focus more on improving Lemmy. And instead of being accountable to an external organization, we work **directly for Lemmy's users**. While one-time donations are also welcome, they are too unpredictable for long-term planning. 34 | 35 | You can find available donation options on the [donate page](http://join-lemmy.org/donate). This page was also updated during the redesign to display current donations and funding goals. If each active Lemmy user donated **~€0.33 per month** it would be enough for 3 full-time developers. So please consider donating if you use Lemmy every day. Our preferred donation platform is Liberapay because it doesn't have any payment fees or delays, and is itself open source. 36 | 37 | Besides Lemmy's developers, please consider donating to those who develop open-source apps or software for the Lemmy ecosystem, as well as server admins and moderation teams who are the backbone of the Lemmyverse. We would be happy to add donation links for the above to join-lemmy.org as well! 38 | 39 | If you have any suggestions in regards to the topics mentioned in this post, please let us know. We also want to use this opportunity to thank the countless contributors who are working on Lemmy now. 40 | -------------------------------------------------------------------------------- /src/assets/news/2025-06-13 - Lemmy Release 0.19.12.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.19.12 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Changes 8 | 9 | This release includes various minor improvements and bug fixes. 10 | 11 | ### Backend 12 | 13 | - Fix Peertube federation by @flamingos-cant in [#5652](https://github.com/LemmyNet/lemmy/pull/5652) 14 | - Show NSFW content by default if content_warning exists by @xaegit in [#5655](https://github.com/LemmyNet/lemmy/pull/5655) 15 | - Register users in a transaction by @Nothing4You in [#5608](https://github.com/LemmyNet/lemmy/pull/5608) 16 | - Fix email notifications for denied applications by @Nutomic in [#5641](https://github.com/LemmyNet/lemmy/pull/5641) 17 | - Dont run scheduled tasks at startup by @Nutomic in [#5732](https://github.com/LemmyNet/lemmy/pull/5745) 18 | - Only use HTTP/1 for federation by @flamingos-cant in [#5744](https://github.com/LemmyNet/lemmy/pull/5744) 19 | - Update user count from local_user table instead of person table, and only count users with accepted application by @dullbananas in [#5495](https://github.com/LemmyNet/lemmy/pull/5495) 20 | - Decrement fail_count instead of reset to 0 by @Nutomic in [#5737](https://github.com/LemmyNet/lemmy/pull/5737) 21 | - Fix opentelemetry by @MrKaplan-lw in [#5702](https://github.com/LemmyNet/lemmy/pull/5702) 22 | - Fix post listing in nsfw communities by @Nutomic in [#5698](https://github.com/LemmyNet/lemmy/pull/5698) 23 | - Add missing post_read / hide / saved post_id indexes by @dessalines in [#5689](https://github.com/LemmyNet/lemmy/pull/5689) 24 | - Improve media deletion logic by @Nothing4You in [#5677](https://github.com/LemmyNet/lemmy/pull/5677) 25 | - Include published in VoteView order by for more consistent pagination by @MrKaplan-lw in [#5676](https://github.com/LemmyNet/lemmy/pull/5676) 26 | - Mark posts in NSFW communities as NSFW by @Nothing4You in [#5646](https://github.com/LemmyNet/lemmy/pull/5646) 27 | - Use version from git to indicate unreleased changes by @MrKaplan-lw in [#5622](https://github.com/LemmyNet/lemmy/pull/5622) 28 | 29 | ### Frontend 30 | 31 | - Add Rblind theme by @travis-jeans in [#3159](https://github.com/LemmyNet/lemmy-ui/pull/3159) 32 | - Remove browser cache by @SleeplessOne1917 in [#3150](https://github.com/LemmyNet/lemmy-ui/pull/3150) 33 | - Show registration denial reason on login by @dessalines in [#3175](https://github.com/LemmyNet/lemmy-ui/pull/3175) 34 | - Always escape HTML attributes in emoji autocomplete and custom emoji markdown renderer by @Nothing4You in [#3169](https://github.com/LemmyNet/lemmy-ui/pull/3169) 35 | - Fix missing user badge for deleted users by @MrKaplan-lw in [#3162](https://github.com/LemmyNet/lemmy-ui/pull/3162) 36 | - Add hungarian language by @dessalines in [#3158](https://github.com/LemmyNet/lemmy-ui/pull/3158) 37 | - Fixing cache-control header. by @dessalines in [#3148](https://github.com/LemmyNet/lemmy-ui/pull/3148) 38 | - Disable blur for NSFW images by default if content_warning exists by @xaegit in [#3128](https://github.com/LemmyNet/lemmy-ui/pull/3128) 39 | - Add `Vary: Cookie` Header (fixes #3117) by @xaegit in [#3119](https://github.com/LemmyNet/lemmy-ui/pull/3119) 40 | - Use alert-info for donation dialog by @dessalines in [#3115](https://github.com/LemmyNet/lemmy-ui/pull/3115) 41 | - Optimize Dockerfile by @Nothing4You in [#3090](https://github.com/LemmyNet/lemmy-ui/pull/3090) 42 | - Add support for using Lemmy UI with an external Lemmy instance by @SolninjaA in [#3041](https://github.com/LemmyNet/lemmy-ui/pull/3041) 43 | - Only show View registration button to admins on profiles of local users by @Nothing4You in [#3072](https://github.com/LemmyNet/lemmy-ui/pull/3072) 44 | 45 | ## Upgrade instructions 46 | 47 | There are no breaking changes with this release. 48 | 49 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 50 | 51 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 52 | 53 | ## Thanks to everyone 54 | 55 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 56 | 57 | ## Support development 58 | 59 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over five years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 60 | 61 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 62 | 63 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 64 | - [Open Collective](https://opencollective.com/lemmy) 65 | - [Patreon](https://www.patreon.com/dessalines) 66 | - [Cryptocurrency](https://join-lemmy.org/crypto) 67 | -------------------------------------------------------------------------------- /src/assets/news/2020-10-20 - Lemmy Release v0.8.0 - Federation beta!.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.8.0 - Federation beta! 2 | 3 | _Written by @dessalines and @nutomic, 2020-10-20_ 4 | 5 | ## Changes 6 | 7 | We've been working at warp speed since our `v0.7.0` release in June, adding over [870 commits](https://github.com/LemmyNet/lemmy/compare/v0.7.0...main) since then. :sweat: 8 | 9 | Here are some of the bigger changes: 10 | 11 | ### LemmyNet projects 12 | 13 | - Created [LemmyNet](https://github.com/LemmyNet), where all lemmy-related projects live. 14 | - Split out the frontend into a separete repository, [lemmy-ui](https://github.com/LemmyNet/lemmy-ui) 15 | - Created a [lemmy-js-client](https://github.com/LemmyNet/lemmy-js-client), for any js / typescript developers. 16 | - Split out i18n [lemmy-translations](https://github.com/LemmyNet/lemmy-translations), that any app or site developers can import and use. Lemmy currently supports [~30 languages!](https://weblate.yerbamate.dev/projects/lemmy/lemmy/) 17 | 18 | ### Lemmy Server 19 | 20 | #### Federation 21 | 22 | - The first **federation public beta release**, woohoo :fireworks: 23 | - All Lemmy functionality now works over ActivityPub (except turning remote users into mods/admins) 24 | - Instance allowlist and blocklist 25 | - Documentation for [admins](https://dev.lemmy.ml/docs/administration_federation.html) and [devs](https://dev.lemmy.ml/docs/contributing_federation_overview.html) on how federation works 26 | - Upgraded to newest versions of @asonix activitypub libraries 27 | - Full local federation setup for manual testing 28 | - Automated testing for nearly every federation action 29 | - Many additional security checks 30 | - Lots and lots of refactoring 31 | - Asynchronous sending of outgoing activities 32 | 33 | ### User Interface 34 | 35 | - Separated the UI from the server code, in [lemmy-ui](https://github.com/LemmyNet/lemmy-ui). 36 | - The UI can now read with javascript disabled! 37 | - It's now a fully isomorphic application using [inferno-isomorphic](https://infernojs.org/docs/guides/isomorphic). This means that page loads are now much faster, as the server does the work. 38 | - The UI now also supports open-graph and twitter cards! Linking to lemmy posts (from whatever platform you use) looks pretty now: ![](https://i.imgur.com/6TZ2v7s.png) 39 | - Improved the search page ( more features incoming ). 40 | - The default view is now `Local`, instead of `All`, since all would show all federated posts. 41 | - User settings are now shared across browsers ( a page refresh will pick up changes ). 42 | - A much leaner mobile view. 43 | 44 | #### Backend 45 | 46 | - Re-organized the rust codebase into separate workspaces for backend and frontend. 47 | - Removed materialized views, making the database **a lot faster**. 48 | - New post sorts `Active` (previously called hot), and `Hot`. Active shows posts with recent comments, hot shows highly ranked posts. 49 | - New sort for `Local` ( meaning from local communities). 50 | - Customizeable site, user, and community icons and banners. 51 | - Added user preferred names / display names, bios, and cakedays. 52 | - Visual / Audio captchas through the lemmy API. 53 | - Lots of API field verifications. 54 | - Upgraded to pictrs-v2 ( thanks to @asonix ) 55 | - Wayyy too many bugfixes to count. 56 | 57 | ## Contributors 58 | 59 | We'd also like to thank both the [NLnet foundation](https://nlnet.nl/) for their support in allowing us to work full-time on Lemmy ( as well as their support for [other important open-source projects](https://nlnet.nl/project/current.html) ), [those who sponsor us](https://dev.lemmy.ml/sponsors), and those who [help translate Lemmy](https://weblate.yerbamate.dev/projects/lemmy/). Every little bit does help. We remain committed to never allowing advertisements, monetizing, or venture-capital in Lemmy; software should be communal, and should benefit humanity, not a small group of company owners. 60 | 61 | ## Upgrading 62 | 63 | - [with manual Docker installation](https://dev.lemmy.ml/docs/administration_install_docker.html#updating) 64 | - [with Ansible installation](https://dev.lemmy.ml/docs/administration_install_ansible.html) 65 | 66 | ## Testing Federation 67 | 68 | Federation is finally ready in Lemmy, pending possible bugs or other issues. So for now we suggest to enable federation only on test servers, or try it on our own test servers ( [enterprise](https://enterprise.lemmy.ml/), [ds9](https://ds9.lemmy.ml/), [voyager](https://voyager.lemmy.ml/) ). 69 | 70 | If everything goes well, after a few weeks we will enable federation on dev.lemmy.ml, at first with a limited number of trusted instances. We will also likely change the domain to https://lemmy.ml . Keep in mind that changing domains after turning on federation will break things. 71 | 72 | To enable on your instance, edit your [lemmy.hjson](https://github.com/LemmyNet/lemmy/blob/main/config/defaults.hjson#L60) federation section to `enabled: true`, and restart. 73 | 74 | ### Connecting to another server 75 | 76 | The server https://ds9.lemmy.ml has open federation, so after either adding it to the `allowed_instances` list in your `config.hjson`, or if you have open federation, you don't need to add it explicitly. 77 | 78 | To federate / connect with a server, type in `!community_name@server.tld`, in your server's search box [like so](https://voyager.lemmy.ml/search/q/!main%40ds9.lemmy.ml/type/All/sort/TopAll/page/1). 79 | 80 | To connect with the `main` community on ds9, the search is `!main@ds9.lemmy.ml`. 81 | 82 | You can then click the community, and you will see a local version of the community, which you can subscribe to. New posts and comments from `!main@ds9.lemmy.ml` will now show up on your front page, or `/c/All` 83 | -------------------------------------------------------------------------------- /src/shared/components/donate.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "inferno"; 2 | import { Helmet } from "inferno-helmet"; 3 | import { i18n } from "../i18next"; 4 | import { isBrowser } from "../utils"; 5 | import { BottomSpacer } from "./common"; 6 | import { Link } from "inferno-router"; 7 | import { T } from "inferno-i18next"; 8 | import { 9 | FUNDED_DEVS, 10 | FUNDED_DEV_GOAL, 11 | MEDIAN_DEV_SALARY, 12 | TOTAL_RECURRING_MONTHLY_EUR, 13 | TOTAL_SUPPORTERS, 14 | } from "./donate-definitions"; 15 | import { NUMBER_FORMAT } from "../utils"; 16 | import { Icon } from "./icon"; 17 | 18 | export class Donate extends Component { 19 | constructor(props: any, context: any) { 20 | super(props, context); 21 | } 22 | 23 | componentDidMount() { 24 | if (isBrowser()) { 25 | window.scrollTo(0, 0); 26 | } 27 | } 28 | 29 | render() { 30 | const title = i18n.t("donate_title"); 31 | return ( 32 |
    33 | 34 | 35 | 36 | 37 | 38 |
    39 | ); 40 | } 41 | } 42 | 43 | const DonateDesc = () => ( 44 |

    45 | 46 |
    47 |
    48 |
    49 |

    50 | ); 51 | 52 | const DonateButtons = () => ( 53 | 94 | ); 95 | 96 | const FundingGoal = () => { 97 | const percent_funded = Math.min( 98 | Math.round((FUNDED_DEVS / FUNDED_DEV_GOAL) * 100), 99 | 100, 100 | ); 101 | 102 | var progress_classes = "h-5 progress w-auto mb-6 "; 103 | var text_classes = "flex flex-row flex-wrap justify-between gap-4 "; 104 | if (percent_funded < 60) { 105 | progress_classes += "progress-error"; 106 | text_classes += "text-error/75"; 107 | } else if (percent_funded < 90) { 108 | progress_classes += "progress-warning"; 109 | text_classes += "text-warning"; 110 | } else { 111 | progress_classes += "progress-success"; 112 | text_classes += "text-success"; 113 | } 114 | 115 | return ( 116 |
    117 |
    118 |
    119 |
    120 |
    121 | {i18n.t("supporters", { 122 | formattedCount: NUMBER_FORMAT.format(TOTAL_SUPPORTERS), 123 | })} 124 |
    125 |
    126 |
    127 | 128 | €{NUMBER_FORMAT.format(TOTAL_RECURRING_MONTHLY_EUR)} 129 | 130 | {i18n.t("per_month", { formattedCount: "" })} 131 |
    132 |
    138 | {i18n.t("percent_funded", { 139 | formattedCount: percent_funded, 140 | })} 141 |
    142 |
    143 | 148 |
    149 | ); 150 | }; 151 | 152 | const DonateBlock = () => ( 153 |
    154 |
    155 |
    156 |

    157 | {i18n.t("donate_subtitle")} 158 |

    159 | 160 | 161 | 162 |
    163 |
    164 |
    165 | ); 166 | -------------------------------------------------------------------------------- /src/assets/news/2025-04-08 - Lemmy Release v0.19.11.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.19.11 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. 6 | 7 | ## Changes 8 | 9 | This release fixes a security vulnerability which allows an attacker to delete images uploaded by other users. You can read the details in the [security advisory](https://github.com/LemmyNet/lemmy/security/advisories/GHSA-wr2m-38xh-rpc9). Thanks to @Nothing4You for discovering and fixing it. 10 | 11 | A new donation dialog is shown to users once per year, to help fund Lemmy development. 12 | 13 | There are also various backports from the development branch. Importantly the "Private instance" setting can now be used with federation enabled. This way only logged-in users can browse posts and comments, which stops AI crawlers from overloading the server. Also moderators can now view votes in the post/comment options. 14 | 15 | ### Backend 16 | 17 | - Remove unnecessary pictrs purge calls ([#5566](https://github.com/LemmyNet/lemmy/issues/5566)) 18 | - Donation dialog ([#5559](https://github.com/LemmyNet/lemmy/issues/5559)) 19 | - Send out email after registration denied, email confirmed ([#5553](https://github.com/LemmyNet/lemmy/pull/5553)) 20 | - Change private instance setting to allow federation ([#5530](https://github.com/LemmyNet/lemmy/issues/5530)) 21 | - Proxy post.url if it is an image ([#5545](https://github.com/LemmyNet/lemmy/issues/5545)) 22 | - When creating community copy allowed languages from creator profile ([#5490](https://github.com/LemmyNet/lemmy/issues/5490)) 23 | - Include image alt text in post search ([#5449](https://github.com/LemmyNet/lemmy/issues/5449)) 24 | - Add config option to enable json logging ([#5471](https://github.com/LemmyNet/lemmy/issues/5471), [#5557](https://github.com/LemmyNet/lemmy/issues/5557)) 25 | - Embed images in RSS feeds ([#5488](https://github.com/LemmyNet/lemmy/issues/5488)) 26 | - Fix federation of sticky posts ([#5593](https://github.com/LemmyNet/lemmy/pull/5593)) 27 | - Deleted user shouldnt break federation outbox ([#5443](https://github.com/LemmyNet/lemmy/issues/5443), [#5573](https://github.com/LemmyNet/lemmy/issues/5573)) 28 | - Fix some image embeds by escaping alt text [(#5506](https://github.com/LemmyNet/lemmy/issues/5506)) 29 | - Properly federate distinguish comment ([#5586](https://github.com/LemmyNet/lemmy/pull/5586)) 30 | - Increase default registration rate limit to 10 per hour ([#5600](https://github.com/LemmyNet/lemmy/pull/5600)) 31 | - Remove debug ratelimit being used in production ([#5551](https://github.com/LemmyNet/lemmy/pull/5551)) 32 | 33 | ### Frontend 34 | 35 | - Implement donation dialog ([#3034](https://github.com/LemmyNet/lemmy-ui/pull/3034)) 36 | - Hide images in private message reports ([#3053](https://github.com/LemmyNet/lemmy-ui/pull/3053)) 37 | - Dont render images in private message ([#3043](https://github.com/LemmyNet/lemmy-ui/pull/3043)) 38 | - Changed checkbox text "Only moderators can post to this community" from legend to label on the Create Community page ([#3046](https://github.com/LemmyNet/lemmy-ui/pull/3046)) 39 | - Trigger toast error on community request failure ([#3045](https://github.com/LemmyNet/lemmy-ui/pull/3045)) 40 | - Add local link next to fedilink on posts ([#3033](https://github.com/LemmyNet/lemmy-ui/pull/3033)) 41 | - Add banned badges to post and comment listings ([#3030](https://github.com/LemmyNet/lemmy-ui/pull/3030)) 42 | - Linkify user @ mentions ([#3029](https://github.com/LemmyNet/lemmy-ui/pull/3029)) 43 | - Adding ability for mods to view votes. ([#3027](https://github.com/LemmyNet/lemmy-ui/pull/3027)) 44 | - Upvote, downvote, view source, and favorite icons become larger when pressed to improve visibility on grayscale screens ([#2960](https://github.com/LemmyNet/lemmy-ui/pull/2960)) 45 | - Improve colour contrast of the mini-overlay in the top right corner of link or image post thumbnails ([#2961](https://github.com/LemmyNet/lemmy-ui/pull/2961)) 46 | - Improve screenreader accessibility by adding a main element to more pages (issue #2891) ([#2944](https://github.com/LemmyNet/lemmy-ui/pull/2944)) 47 | - Using input group for allowed and block instance buttons. ([#2905](https://github.com/LemmyNet/lemmy-ui/pull/2905)) 48 | - Moving totp and delete account settings into their own cards. ([#2907](https://github.com/LemmyNet/lemmy-ui/pull/2907)) 49 | - Hide NSFW field for create post form, for NSFW communities. ([#2887](https://github.com/LemmyNet/lemmy-ui/pull/2887)) 50 | - Modify the logic for appending the URL after uploading an image, placing the image URL after the cursor. ([#2804](https://github.com/LemmyNet/lemmy-ui/pull/2804)) 51 | 52 | ## Upgrade instructions 53 | 54 | There are no breaking changes with this release. 55 | 56 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 57 | 58 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 59 | 60 | ## Thanks to everyone 61 | 62 | We'd like to thank our many contributors and users of Lemmy for coding, translating, testing, and helping find and fix bugs. We're glad many people find it useful and enjoyable enough to contribute. 63 | 64 | ## Support development 65 | 66 | We are able to develop Lemmy as an open source platform free of tracking and ads thanks to the generosity of our users. Once a year we ask you to consider donating to support our work. Financial security allows us to continue maintaining and improving the platform. If you’d like to make a one-time or recurring donation simply use the links below. Thank you for using Lemmy. 67 | 68 | Nutomic and Dessalines, Lemmy Developers 69 | 70 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 71 | - [Open Collective](https://opencollective.com/lemmy) 72 | - [Patreon](https://www.patreon.com/dessalines) 73 | - [Cryptocurrency](https://join-lemmy.org/crypto) 74 | -------------------------------------------------------------------------------- /src/assets/news/2025-12-24 - Lemmy Release v0.19.15 and Testing for 1.0.md: -------------------------------------------------------------------------------- 1 | # Lemmy Release v0.19.15 and Testing for 1.0 2 | 3 | ## What is Lemmy? 4 | 5 | Lemmy is a self-hosted social link aggregation and discussion platform. It is completely free and open, and not controlled by any company. This means that there is no advertising, tracking, or secret algorithms. Content is organized into communities, so it is easy to subscribe to topics that you are interested in, and ignore others. Voting is used to bring the most interesting items to the top. Thanks to @flamingos-cant for contributing to resolve this. 6 | 7 | ## Changes 8 | 9 | We messed up the previous release and did not include the full list of changes. In fact there were a handful of other bug fixes, and notably a maximum page limit of 10 to prevent a DDoS attack. Some users were also hitting this limit, so with this version the limit is increased to 100. We apologize for these mistakes. 10 | 11 | Here is the full changelog since 0.19.13: 12 | 13 | - Don't allow accessing page numbers greater than 10 by @dessalines [#6017](https://github.com/LemmyNet/lemmy/pull/6017) 14 | - Update deps based on cargo audit by @Nutomic in [#6258](https://github.com/LemmyNet/lemmy/pull/6258) 15 | - Increase page limit to 100 by @Nutomic in [#6252](https://github.com/LemmyNet/lemmy/pull/6252) 16 | - Ban federation for deleted users by @Nutomic in [#6207](https://github.com/LemmyNet/lemmy/pull/6207) 17 | - Federate mod actions on deleted users by @Nutomic in [#6199](https://github.com/LemmyNet/lemmy/pull/6199) 18 | - Allow admins to view deleted user profiles by @Nutomic in [#6194](https://github.com/LemmyNet/lemmy/pull/6194) 19 | - Adding creator and community indexes for post_aggregates. by @dessalines in [#6025](https://github.com/LemmyNet/lemmy/pull/6025) 20 | - Ignore apub person banners which cannot be parsed by @Nutomic in [#6015](https://github.com/LemmyNet/lemmy/pull/6015)u 21 | 22 | --- 23 | 24 | Now for the good news, the development version of Lemmy 1.0 is available for testing on voyager.lemmy.ml with lots of new features. Registration is open, you're welcome to create an account. Feel free to post spam and try everything out. Here is only a short overview: 25 | 26 | - **Multi-communities**: Combine different communities together into a custom feed. 27 | - **Post scheduling**: Specify when your post should be published. 28 | - **Keyword filter**: Automatically hide posts about certain topics. 29 | - **Private communities**: Only followers can view the content, and need to be approved manually by mods. Other community visibilities are also available (unlisted, local only). 30 | - **New notification system**: Including notifications for mod actions, and subscribing to communities and posts to be notified about new comments. 31 | - **OAuth**: Login to Lemmy with existing account from another website. Use [this link](https://voyager.lemmy.ml/signup?sso_provider_id=1) to signup with your Github account (the UI still needs to be improved). 32 | - **Post Tags**: Categorize posts within a community (UI part not implemented yet). 33 | - **User vote totals**: You can see the total number of upvotes and downvotes given to each user. 34 | - **User notes**: You can keep notes on other users. 35 | - **Combined Feeds**: View your saved, liked posts and comments together in a single list. 36 | - **Comment Locking**: Mods can now lock comments recursively. 37 | - **GDPR style data exporting**: You can now export your full posting history as a JSON file. 38 | - **Plugins**: Can be written in JS, Python, Rust, and any other language that targets Webassembly. The test server has a plugin for automatic language tagging of posts. 39 | - **Cursor pagination**: Don't lose your place in the feed when switching pages. 40 | - **API v3 compat**: Lemmy 1.0 can be used by existing apps with no changes (but most new features are only available via the new API v4). 41 | - **More**: Countless smaller features, bug fixes and improvements, too much to list here. 42 | 43 | All the above mentioned features are already implemented and fully working, but may need some polishing. If you encounter any problems, please open an issue ([backend](https://github.com/LemmyNet/lemmy/issues), [frontend](https://github.com/LemmyNet/lemmy-ui/issues)). voyager.lemmy.ml is automatically updated to the latest development version every night, so that changes can immediately be tested. 44 | 45 | Keep in mind that Lemmy 1.0 is still in alpha state. There may be breaking changes and critical bugs, so do not attempt to upgrade your own instances yet. We intend to publish the first beta version in January, along with API docs and upgrade instructions for test servers. 46 | 47 | We hope that you are as excited about these new features as we are. With all this said, happy testing and Merry Christmas! 48 | 49 | ## Upgrade instructions 50 | 51 | There are no breaking changes with this release. 52 | 53 | Follow the upgrade instructions for [ansible](https://github.com/LemmyNet/lemmy-ansible/blob/main/UPGRADING.md) or [docker](https://join-lemmy.org/docs/en/administration/install_docker.html#updating). 54 | 55 | If you need help with the upgrade, you can ask in our [support forum](https://lemmy.ml/c/lemmy_support) or on the [Matrix Chat](https://matrix.to/#/!OwmdVYiZSXrXbtCNLw:matrix.org). 56 | 57 | ## Thanks to everyone 58 | 59 | We’d like to thank our many contributors and users of Lemmy for coding, translating, testing, donating and reporting bugs. We're glad many people find it useful and enjoyable enough to contribute. 60 | 61 | ## Support development 62 | 63 | We (@dessalines and @nutomic) have been working full-time on Lemmy for over five years. This is largely thanks to support from [NLnet foundation](https://nlnet.nl/), as well as [donations from individual users](https://join-lemmy.org/donate). 64 | 65 | If you like using Lemmy, and want to make sure that we will always be available to work full time building it, consider [donating to support its development](https://join-lemmy.org/donate). A recurring donation is the best way to ensure that open-source software like Lemmy can stay independent and alive, and helps us grow our little developer co-op to support more full-time developers. 66 | 67 | - [Liberapay](https://liberapay.com/Lemmy) (preferred option) 68 | - [Open Collective](https://opencollective.com/lemmy) 69 | - [Patreon](https://www.patreon.com/dessalines) 70 | - [Cryptocurrency](https://join-lemmy.org/crypto) 71 | -------------------------------------------------------------------------------- /src/shared/components/apps.tsx: -------------------------------------------------------------------------------- 1 | import { Component, linkEvent } from "inferno"; 2 | import { Helmet } from "inferno-helmet"; 3 | import { i18n } from "../i18next"; 4 | import { T } from "inferno-i18next"; 5 | import { BottomSpacer } from "./common"; 6 | import { 7 | API_LIBRARIES, 8 | APP_LIST, 9 | ToolDetails, 10 | AppDetails, 11 | AppLink, 12 | Platform, 13 | SourceType, 14 | MODERATION_TOOLS, 15 | } from "./app-definitions"; 16 | import { Icon } from "./icon"; 17 | import { I18nKeys } from "i18next"; 18 | import { sortRandom } from "../utils"; 19 | 20 | const TitleBlock = () => ( 21 |
    22 | 23 | ## 24 | 25 |

    26 | {i18n.t("choose_from_apps")} 27 |

    28 |
    29 | ); 30 | 31 | interface AppDetailsCardProps { 32 | app: AppDetails; 33 | } 34 | 35 | const AppDetailsTitle = ({ app }: AppDetailsCardProps) => ( 36 |
    37 | 42 | 43 | {app.name} 44 | 45 |
    46 | ); 47 | 48 | interface AppDetailsButtonsProps { 49 | links: AppLink[]; 50 | } 51 | 52 | const AppDetailsButtons = ({ links }: AppDetailsButtonsProps) => ( 53 |
    54 | {links.map(l => ( 55 | 59 | 60 | 61 | ))} 62 |
    63 | ); 64 | 65 | const AppDetailsCard = ({ app }: AppDetailsCardProps) => ( 66 |
    67 |
    68 | 69 | 74 |

    {app.description}

    75 | {app.sourceType === SourceType.Closed && ( 76 |
    77 | 78 | {i18n.t("closed_source_warning")} 79 |
    80 | )} 81 | 82 |
    83 |
    84 | ); 85 | 86 | const AppTitle = ({ title }) => ( 87 |
    {title}
    88 | ); 89 | 90 | interface AppGridProps { 91 | apps: AppDetails[]; 92 | } 93 | 94 | const AppGrid = ({ apps }: AppGridProps) => ( 95 |
    96 | {apps.map(a => ( 97 | 98 | ))} 99 |
    100 | ); 101 | 102 | interface ToolsBlockProps { 103 | title: string; 104 | items: ToolDetails[]; 105 | } 106 | 107 | const ToolsBlock = ({ title, items }: ToolsBlockProps) => ( 108 |
    109 | 110 |
    111 |
    112 |
      113 | {items.map(a => ( 114 |
    • 115 | 116 | 117 | 118 | {a.name} 119 | 120 | 121 | - 122 | {a.description} 123 |
    • 124 | ))} 125 |
    126 |
    127 |
    128 |
    129 | ); 130 | 131 | interface State { 132 | apps: AppDetails[]; 133 | platform: Platform; 134 | } 135 | 136 | export class Apps extends Component { 137 | state: State = { 138 | apps: [], 139 | platform: Platform.All, 140 | }; 141 | 142 | constructor(props: any, context: any) { 143 | super(props, context); 144 | } 145 | 146 | componentDidMount() { 147 | window.scrollTo(0, 0); 148 | this.buildAppList(); 149 | } 150 | 151 | buildAppList() { 152 | let apps = APP_LIST; 153 | 154 | // Platform filter 155 | if (this.state.platform !== Platform.All) { 156 | apps = apps.filter(a => a.platforms.includes(this.state.platform)); 157 | } 158 | 159 | // Random sort 160 | apps = sortRandom(apps); 161 | 162 | this.setState({ apps }); 163 | } 164 | 165 | render() { 166 | const title = i18n.t("apps_title"); 167 | return ( 168 |
    169 | 170 | 171 | 172 | 173 | {this.filterAndTitleBlock()} 174 | 175 |
    176 | 177 | 181 |
    182 | 183 |
    184 | ); 185 | } 186 | 187 | filterAndTitleBlock() { 188 | return ( 189 | 209 | ); 210 | } 211 | } 212 | 213 | function handlePlatformChange(i: Apps, event: any) { 214 | const platform: Platform = (event.target.value as Platform) ?? Platform.All; 215 | i.setState({ 216 | platform, 217 | }); 218 | i.buildAppList(); 219 | } 220 | --------------------------------------------------------------------------------