mirror of
https://github.com/LemmyNet/joinlemmy-site.git
synced 2024-11-24 21:31:16 +00:00
parent
ec0b9b7d09
commit
02967e4b03
8 changed files with 388 additions and 313 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 63e8c68ffc724a7e4e44de17c236c44d9b66d028
|
||||
Subproject commit 35366c5ec0f198860bb860e4c7b5deda9e47636a
|
|
@ -1 +1 @@
|
|||
Subproject commit ff8a2db505771c9f142ab31626b49de54a756192
|
||||
Subproject commit 419d6e7c67951d1210226091b2d09a0536b531c8
|
|
@ -9,6 +9,14 @@ export enum SourceType {
|
|||
Open,
|
||||
}
|
||||
|
||||
export enum Platform {
|
||||
All = "all_platforms",
|
||||
Android = "android",
|
||||
IOS = "ios",
|
||||
Web = "web",
|
||||
CLI = "cli",
|
||||
}
|
||||
|
||||
export interface AppDetails {
|
||||
name: string;
|
||||
description: string;
|
||||
|
@ -17,6 +25,7 @@ export interface AppDetails {
|
|||
banner?: string;
|
||||
links: AppLink[];
|
||||
sourceType: SourceType;
|
||||
platforms: Platform[];
|
||||
}
|
||||
|
||||
export interface AppLink {
|
||||
|
@ -43,7 +52,7 @@ export const API_LIBRARIES: ApiLibrary[] = [
|
|||
},
|
||||
];
|
||||
|
||||
const voyagerApp: AppDetails = {
|
||||
const VOYAGER: AppDetails = {
|
||||
name: "Voyager",
|
||||
description: "A Lemmy Client for iOS, Android and the web",
|
||||
link: "https://github.com/aeharding/voyager",
|
||||
|
@ -68,9 +77,10 @@ const voyagerApp: AppDetails = {
|
|||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Android, Platform.IOS, Platform.Web],
|
||||
};
|
||||
|
||||
const thunderApp: AppDetails = {
|
||||
const THUNDER: AppDetails = {
|
||||
name: "Thunder",
|
||||
description:
|
||||
"An open-source cross-platform Lemmy client for iOS and Android built with Flutter",
|
||||
|
@ -96,268 +106,303 @@ const thunderApp: AppDetails = {
|
|||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Android, Platform.IOS],
|
||||
};
|
||||
|
||||
export const ANDROID_APPS: AppDetails[] = [
|
||||
{
|
||||
name: "Jerboa",
|
||||
description: "A native Android app made by Lemmy's developers",
|
||||
link: "https://github.com/dessalines/jerboa",
|
||||
icon: "/static/assets/images/jerboa.svg",
|
||||
banner: "/static/assets/images/jerboa_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://f-droid.org/en/packages/com.jerboa",
|
||||
icon: "f-droid",
|
||||
},
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=com.jerboa",
|
||||
icon: "googleplay",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/dessalines/jerboa",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
{
|
||||
name: "Eternity",
|
||||
description: "A Lemmy client for Android written in Java.",
|
||||
link: "https://codeberg.org/Bazsalanszky/Eternity",
|
||||
icon: "/static/assets/images/eternity_icon.webp",
|
||||
banner: "/static/assets/images/eternity_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://apt.izzysoft.de/fdroid/index/apk/eu.toldi.infinityforlemmy",
|
||||
icon: "f-droid",
|
||||
},
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=eu.toldi.infinityforlemmy",
|
||||
icon: "googleplay",
|
||||
},
|
||||
{
|
||||
link: "https://codeberg.org/Bazsalanszky/Eternity",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
{
|
||||
name: "Combustible",
|
||||
description: "An Open-Source Lemmy Client For Android",
|
||||
link: "https://github.com/TheBrokenRail/Combustible",
|
||||
icon: "/static/assets/images/combustible_logo.webp",
|
||||
banner: "/static/assets/images/combustible_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://apt.izzysoft.de/fdroid/index/apk/com.thebrokenrail.combustible",
|
||||
icon: "f-droid",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/TheBrokenRail/Combustible",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
{
|
||||
name: "LiftOff!",
|
||||
description: "A mobile client for lemmy",
|
||||
link: "https://github.com/liftoff-app/liftoff",
|
||||
icon: "/static/assets/images/liftoff_icon.svg",
|
||||
banner: "/static/assets/images/liftoff_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://apt.izzysoft.de/fdroid/index/apk/com.liftoffapp.liftoff",
|
||||
icon: "f-droid",
|
||||
},
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=com.liftoffapp.liftoff&pli=1",
|
||||
icon: "googleplay",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/liftoff-app/liftoff",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
voyagerApp,
|
||||
thunderApp,
|
||||
{
|
||||
name: "Boost for Lemmy",
|
||||
description: "A smooth app for Lemmy.",
|
||||
link: "https://play.google.com/store/apps/details?id=com.rubenmayayo.lemmy",
|
||||
icon: "/static/assets/images/boost_icon.webp",
|
||||
banner: "/static/assets/images/boost_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=com.rubenmayayo.lemmy",
|
||||
icon: "googleplay",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Closed,
|
||||
},
|
||||
{
|
||||
name: "Sync for Lemmy",
|
||||
description: "A full-featured app for browsing Lemmy on the go.",
|
||||
link: "https://play.google.com/store/apps/details?id=io.syncapps.lemmy_sync",
|
||||
icon: "/static/assets/images/sync_icon.webp",
|
||||
banner: "/static/assets/images/sync_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=io.syncapps.lemmy_sync",
|
||||
icon: "googleplay",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Closed,
|
||||
},
|
||||
];
|
||||
const JERBOA: AppDetails = {
|
||||
name: "Jerboa",
|
||||
description: "A native Android app made by Lemmy's developers",
|
||||
link: "https://github.com/dessalines/jerboa",
|
||||
icon: "/static/assets/images/jerboa.svg",
|
||||
banner: "/static/assets/images/jerboa_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://f-droid.org/en/packages/com.jerboa",
|
||||
icon: "f-droid",
|
||||
},
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=com.jerboa",
|
||||
icon: "googleplay",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/dessalines/jerboa",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Android],
|
||||
};
|
||||
|
||||
export const IOS_APPS: AppDetails[] = [
|
||||
{
|
||||
name: "Mlem",
|
||||
description: "A Lemmy Client for iOS.",
|
||||
link: "https://github.com/mormaer/Mlem",
|
||||
icon: "/static/assets/images/mlem.png",
|
||||
banner: "/static/assets/images/mlem_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://testflight.apple.com/join/MelFP11Y",
|
||||
icon: "appleinc",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/mlemgroup/mlem",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
{
|
||||
name: "Lunar",
|
||||
description: "A Lemmy Client for iOS written in Swift and SwiftUI",
|
||||
link: "https://github.com/mani-sh-reddy/Lunar",
|
||||
icon: "/static/assets/images/lunar_logo.webp",
|
||||
banner: "/static/assets/images/lunar_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://testflight.apple.com/join/GEFCCQTb",
|
||||
icon: "appleinc",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/mani-sh-reddy/Lunar",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
voyagerApp,
|
||||
thunderApp,
|
||||
{
|
||||
name: "Memmy",
|
||||
description:
|
||||
"A Lemmy Client built in React Native for iOS available on the App Store.",
|
||||
link: "https://github.com/Memmy-App/memmy",
|
||||
icon: "/static/assets/images/memmy_icon.png",
|
||||
banner: "/static/assets/images/memmy_banner.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://apps.apple.com/us/app/memmy-for-lemmy/id6450204299?platform=iphone",
|
||||
icon: "appleinc",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/Memmy-App/memmy",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
];
|
||||
const ETERNITY: AppDetails = {
|
||||
name: "Eternity",
|
||||
description: "A Lemmy client for Android written in Java.",
|
||||
link: "https://codeberg.org/Bazsalanszky/Eternity",
|
||||
icon: "/static/assets/images/eternity_icon.webp",
|
||||
banner: "/static/assets/images/eternity_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://apt.izzysoft.de/fdroid/index/apk/eu.toldi.infinityforlemmy",
|
||||
icon: "f-droid",
|
||||
},
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=eu.toldi.infinityforlemmy",
|
||||
icon: "googleplay",
|
||||
},
|
||||
{
|
||||
link: "https://codeberg.org/Bazsalanszky/Eternity",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Android],
|
||||
};
|
||||
|
||||
export const WEB_APPS: AppDetails[] = [
|
||||
{
|
||||
name: "lemmy-ui",
|
||||
description: "The official web app for lemmy.",
|
||||
link: "https://github.com/LemmyNet/lemmy-ui",
|
||||
banner: "/static/assets/images/mobile_pic.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/LemmyNet/lemmy-ui",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
{
|
||||
name: "Photon",
|
||||
description: "A sleek lemmy web UI.",
|
||||
link: "https://github.com/Xyphyn/photon",
|
||||
banner: "/static/assets/images/photon.webp",
|
||||
icon: "/static/assets/images/photon-logo.svg",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/Xyphyn/photon",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
{
|
||||
name: "Alexandrite",
|
||||
description:
|
||||
"A beautiful and convenient desktop-first alternate web UI for Lemmy.",
|
||||
link: "https://github.com/sheodox/alexandrite",
|
||||
icon: "/static/assets/images/alexandrite_logo.svg",
|
||||
banner: "/static/assets/images/alexandrite_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/sheodox/alexandrite",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
{
|
||||
name: "mlmym",
|
||||
description: "A familiar desktop experience for lemmy",
|
||||
link: "https://github.com/rystaf/mlmym",
|
||||
banner: "/static/assets/images/mlmym_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/rystaf/mlmym",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
{
|
||||
name: "lemmyBB",
|
||||
description: "A lemmy frontend based on phpBB.",
|
||||
link: "https://github.com/LemmyNet/lemmyBB",
|
||||
banner: "/static/assets/images/lemmybb_2.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/LemmyNet/lemmyBB",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
];
|
||||
const COMBUSTIBLE: AppDetails = {
|
||||
name: "Combustible",
|
||||
description: "An Open-Source Lemmy Client For Android",
|
||||
link: "https://github.com/TheBrokenRail/Combustible",
|
||||
icon: "/static/assets/images/combustible_logo.webp",
|
||||
banner: "/static/assets/images/combustible_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://apt.izzysoft.de/fdroid/index/apk/com.thebrokenrail.combustible",
|
||||
icon: "f-droid",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/TheBrokenRail/Combustible",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Android],
|
||||
};
|
||||
|
||||
export const CLI_APPS: AppDetails[] = [
|
||||
{
|
||||
name: "neonmodem",
|
||||
description: "BBS-style TUI client",
|
||||
link: "https://github.com/mrusme/neonmodem",
|
||||
banner: "/static/assets/images/neonmodem.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/mrusme/neonmodem",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
},
|
||||
const LIFTOFF: AppDetails = {
|
||||
name: "LiftOff!",
|
||||
description: "A mobile client for lemmy",
|
||||
link: "https://github.com/liftoff-app/liftoff",
|
||||
icon: "/static/assets/images/liftoff_icon.svg",
|
||||
banner: "/static/assets/images/liftoff_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://apt.izzysoft.de/fdroid/index/apk/com.liftoffapp.liftoff",
|
||||
icon: "f-droid",
|
||||
},
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=com.liftoffapp.liftoff&pli=1",
|
||||
icon: "googleplay",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/liftoff-app/liftoff",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Android, Platform.IOS],
|
||||
};
|
||||
|
||||
const BOOST: AppDetails = {
|
||||
name: "Boost for Lemmy",
|
||||
description: "A smooth app for Lemmy.",
|
||||
link: "https://play.google.com/store/apps/details?id=com.rubenmayayo.lemmy",
|
||||
icon: "/static/assets/images/boost_icon.webp",
|
||||
banner: "/static/assets/images/boost_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=com.rubenmayayo.lemmy",
|
||||
icon: "googleplay",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Closed,
|
||||
platforms: [Platform.Android],
|
||||
};
|
||||
|
||||
const SYNC: AppDetails = {
|
||||
name: "Sync for Lemmy",
|
||||
description: "A full-featured app for browsing Lemmy on the go.",
|
||||
link: "https://play.google.com/store/apps/details?id=io.syncapps.lemmy_sync",
|
||||
icon: "/static/assets/images/sync_icon.webp",
|
||||
banner: "/static/assets/images/sync_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://play.google.com/store/apps/details?id=io.syncapps.lemmy_sync",
|
||||
icon: "googleplay",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Closed,
|
||||
platforms: [Platform.Android],
|
||||
};
|
||||
|
||||
const MLEM: AppDetails = {
|
||||
name: "Mlem",
|
||||
description: "A Lemmy Client for iOS.",
|
||||
link: "https://github.com/mormaer/Mlem",
|
||||
icon: "/static/assets/images/mlem.png",
|
||||
banner: "/static/assets/images/mlem_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://testflight.apple.com/join/MelFP11Y",
|
||||
icon: "appleinc",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/mlemgroup/mlem",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.IOS],
|
||||
};
|
||||
|
||||
const LUNAR: AppDetails = {
|
||||
name: "Lunar",
|
||||
description: "A Lemmy Client for iOS written in Swift and SwiftUI",
|
||||
link: "https://github.com/mani-sh-reddy/Lunar",
|
||||
icon: "/static/assets/images/lunar_logo.webp",
|
||||
banner: "/static/assets/images/lunar_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://testflight.apple.com/join/GEFCCQTb",
|
||||
icon: "appleinc",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/mani-sh-reddy/Lunar",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.IOS],
|
||||
};
|
||||
|
||||
const MEMMY: AppDetails = {
|
||||
name: "Memmy",
|
||||
description:
|
||||
"A Lemmy Client built in React Native for iOS available on the App Store.",
|
||||
link: "https://github.com/Memmy-App/memmy",
|
||||
icon: "/static/assets/images/memmy_icon.png",
|
||||
banner: "/static/assets/images/memmy_banner.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://apps.apple.com/us/app/memmy-for-lemmy/id6450204299?platform=iphone",
|
||||
icon: "appleinc",
|
||||
},
|
||||
{
|
||||
link: "https://github.com/Memmy-App/memmy",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.IOS],
|
||||
};
|
||||
|
||||
const LEMMY_UI: AppDetails = {
|
||||
name: "lemmy-ui",
|
||||
description: "The official web app for lemmy.",
|
||||
link: "https://github.com/LemmyNet/lemmy-ui",
|
||||
banner: "/static/assets/images/mobile_pic.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/LemmyNet/lemmy-ui",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Web],
|
||||
};
|
||||
|
||||
const PHOTON: AppDetails = {
|
||||
name: "Photon",
|
||||
description: "A sleek lemmy web UI.",
|
||||
link: "https://github.com/Xyphyn/photon",
|
||||
banner: "/static/assets/images/photon.webp",
|
||||
icon: "/static/assets/images/photon-logo.svg",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/Xyphyn/photon",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Web],
|
||||
};
|
||||
|
||||
const ALEXANDRITE: AppDetails = {
|
||||
name: "Alexandrite",
|
||||
description:
|
||||
"A beautiful and convenient desktop-first alternate web UI for Lemmy.",
|
||||
link: "https://github.com/sheodox/alexandrite",
|
||||
icon: "/static/assets/images/alexandrite_logo.svg",
|
||||
banner: "/static/assets/images/alexandrite_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/sheodox/alexandrite",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Web],
|
||||
};
|
||||
|
||||
const MLMYM: AppDetails = {
|
||||
name: "mlmym",
|
||||
description: "A familiar desktop experience for lemmy",
|
||||
link: "https://github.com/rystaf/mlmym",
|
||||
banner: "/static/assets/images/mlmym_screen.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/rystaf/mlmym",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Web],
|
||||
};
|
||||
|
||||
const LEMMYBB: AppDetails = {
|
||||
name: "lemmyBB",
|
||||
description: "A lemmy frontend based on phpBB.",
|
||||
link: "https://github.com/LemmyNet/lemmyBB",
|
||||
banner: "/static/assets/images/lemmybb_2.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/LemmyNet/lemmyBB",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.Web],
|
||||
};
|
||||
|
||||
const NEONMODEM: AppDetails = {
|
||||
name: "neonmodem",
|
||||
description: "BBS-style TUI client",
|
||||
link: "https://github.com/mrusme/neonmodem",
|
||||
banner: "/static/assets/images/neonmodem.webp",
|
||||
links: [
|
||||
{
|
||||
link: "https://github.com/mrusme/neonmodem",
|
||||
icon: "github",
|
||||
},
|
||||
],
|
||||
sourceType: SourceType.Open,
|
||||
platforms: [Platform.CLI],
|
||||
};
|
||||
|
||||
export const APP_LIST: AppDetails[] = [
|
||||
JERBOA,
|
||||
ETERNITY,
|
||||
COMBUSTIBLE,
|
||||
LIFTOFF,
|
||||
MLEM,
|
||||
LUNAR,
|
||||
MEMMY,
|
||||
LEMMY_UI,
|
||||
VOYAGER,
|
||||
THUNDER,
|
||||
PHOTON,
|
||||
ALEXANDRITE,
|
||||
MLMYM,
|
||||
LEMMYBB,
|
||||
NEONMODEM,
|
||||
BOOST,
|
||||
SYNC,
|
||||
];
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import { Component } from "inferno";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { Helmet } from "inferno-helmet";
|
||||
import { i18n } from "../i18next";
|
||||
import { T } from "inferno-i18next";
|
||||
import { BottomSpacer, TEXT_GRADIENT } from "./common";
|
||||
import { BottomSpacer, SELECT_CLASSES, TEXT_GRADIENT } from "./common";
|
||||
import {
|
||||
ANDROID_APPS,
|
||||
API_LIBRARIES,
|
||||
APP_LIST,
|
||||
AppDetails,
|
||||
AppLink,
|
||||
CLI_APPS,
|
||||
IOS_APPS,
|
||||
Platform,
|
||||
SourceType,
|
||||
WEB_APPS,
|
||||
} from "./app-definitions";
|
||||
import { Icon } from "./icon";
|
||||
import { I18nKeys } from "i18next";
|
||||
|
||||
const TitleBlock = () => (
|
||||
<div className="flex flex-col items-center pt-16 mb-8">
|
||||
<div className="flex flex-col items-center pt-16 mb-4">
|
||||
<T i18nKey="lemmy_apps" className="text-4xl font-bold mb-3">
|
||||
#<span className={TEXT_GRADIENT}>#</span>
|
||||
</T>
|
||||
|
@ -83,29 +82,6 @@ const AppTitle = ({ title }) => (
|
|||
<div className="text-2xl mb-3 text-gray-300">{title}</div>
|
||||
);
|
||||
|
||||
const MobileAppsBlock = () => (
|
||||
<div>
|
||||
<AppTitle title={i18n.t("mobile_apps_for_android")} />
|
||||
<AppGrid apps={ANDROID_APPS} />
|
||||
<AppTitle title={i18n.t("mobile_apps_for_ios")} />
|
||||
<AppGrid apps={IOS_APPS} />
|
||||
</div>
|
||||
);
|
||||
|
||||
const WebAppsBlock = () => (
|
||||
<div>
|
||||
<AppTitle title={i18n.t("web_apps")} />
|
||||
<AppGrid apps={WEB_APPS} />
|
||||
</div>
|
||||
);
|
||||
|
||||
const CliAppsBlock = () => (
|
||||
<div>
|
||||
<AppTitle title={i18n.t("cli_apps")} />
|
||||
<AppGrid apps={CLI_APPS} />
|
||||
</div>
|
||||
);
|
||||
|
||||
interface AppGridProps {
|
||||
apps: AppDetails[];
|
||||
}
|
||||
|
@ -142,13 +118,35 @@ const ApiLibrariesBlock = () => (
|
|||
</div>
|
||||
);
|
||||
|
||||
export class Apps extends Component<any, any> {
|
||||
interface State {
|
||||
apps: AppDetails[];
|
||||
platform: Platform;
|
||||
}
|
||||
|
||||
export class Apps extends Component<any, State> {
|
||||
state: State = {
|
||||
apps: [],
|
||||
platform: Platform.All,
|
||||
};
|
||||
|
||||
constructor(props: any, context: any) {
|
||||
super(props, context);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.scrollTo(0, 0);
|
||||
this.buildAppList();
|
||||
}
|
||||
|
||||
buildAppList() {
|
||||
let apps = APP_LIST;
|
||||
|
||||
// Platform filter
|
||||
if (this.state.platform !== Platform.All) {
|
||||
apps = apps.filter(a => a.platforms.includes(this.state.platform));
|
||||
}
|
||||
|
||||
this.setState({ apps });
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -159,12 +157,44 @@ export class Apps extends Component<any, any> {
|
|||
<meta property={"title"} content={title} />
|
||||
</Helmet>
|
||||
<TitleBlock />
|
||||
<MobileAppsBlock />
|
||||
<WebAppsBlock />
|
||||
<CliAppsBlock />
|
||||
{this.filterAndTitleBlock()}
|
||||
<AppGrid apps={this.state.apps} />
|
||||
<ApiLibrariesBlock />
|
||||
<BottomSpacer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
filterAndTitleBlock() {
|
||||
return (
|
||||
<div id="search">
|
||||
<div className="flex flex-row flex-wrap gap-4 mb-4">
|
||||
<div className="flex-none"></div>
|
||||
<div className="grow"></div>
|
||||
<div>
|
||||
<select
|
||||
className={`${SELECT_CLASSES} mr-2`}
|
||||
value={this.state.platform}
|
||||
onChange={linkEvent(this, handlePlatformChange)}
|
||||
name="platform_select"
|
||||
>
|
||||
{Object.entries(Platform).map(([name, platform]) => (
|
||||
<option key={name} value={platform}>
|
||||
{i18n.t(platform as string as I18nKeys)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function handlePlatformChange(i: Apps, event: any) {
|
||||
let platform: Platform = (event.target.value as Platform) ?? Platform.All;
|
||||
i.setState({
|
||||
platform,
|
||||
});
|
||||
i.buildAppList();
|
||||
}
|
||||
|
|
|
@ -142,3 +142,7 @@ export const DonateBlock = () => (
|
|||
);
|
||||
|
||||
export const BottomSpacer = () => <div className="pb-32" />;
|
||||
|
||||
export const SectionTitle = ({ title }) => (
|
||||
<div className="text-2xl mb-3">{title}</div>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import classNames from "classnames";
|
||||
import { Component, linkEvent } from "inferno";
|
||||
import { All_TOPIC, TOPICS, Topic } from "./instances-definitions";
|
||||
import { ALL_TOPIC, TOPICS, Topic } from "./instances-definitions";
|
||||
import { LANGUAGES, i18n } from "../i18next";
|
||||
import { I18nKeys } from "i18next";
|
||||
import { Icon } from "./icon";
|
||||
|
@ -120,14 +120,14 @@ export class InstancePicker extends Component<Props, State> {
|
|||
|
||||
function handleTopicChange(i: InstancePicker, event: any) {
|
||||
i.setState({
|
||||
topic: TOPICS.find(c => c.name == event.target.value) ?? All_TOPIC,
|
||||
topic: TOPICS.find(c => c.name == event.target.value) ?? ALL_TOPIC,
|
||||
activeStep: Step.Language,
|
||||
});
|
||||
}
|
||||
|
||||
function handleLanguageChange(i: InstancePicker, event: any) {
|
||||
i.setState({ language: event.target.value });
|
||||
const url = `/instances?topic=${i.state.topic?.name ?? All_TOPIC}&language=${
|
||||
const url = `/instances?topic=${i.state.topic?.name ?? ALL_TOPIC}&language=${
|
||||
i.state.language
|
||||
}&scroll=true`;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ export interface Topic {
|
|||
icon: string;
|
||||
}
|
||||
|
||||
export const All_TOPIC: Topic = {
|
||||
export const ALL_TOPIC: Topic = {
|
||||
name: "all_topics",
|
||||
icon: "folder",
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ const SPORTS: Topic = {
|
|||
};
|
||||
|
||||
export const TOPICS: Topic[] = [
|
||||
All_TOPIC,
|
||||
ALL_TOPIC,
|
||||
GENERAL,
|
||||
TECHNOLOGY,
|
||||
POLITICS,
|
||||
|
|
|
@ -4,12 +4,12 @@ import { i18n, LANGUAGES } from "../i18next";
|
|||
import { T } from "inferno-i18next";
|
||||
import { instance_stats } from "../instance_stats";
|
||||
import { getQueryParams, mdToHtml, numToSI } from "../utils";
|
||||
import { Badge, SELECT_CLASSES, TEXT_GRADIENT } from "./common";
|
||||
import { Badge, SELECT_CLASSES, SectionTitle, TEXT_GRADIENT } from "./common";
|
||||
import {
|
||||
INSTANCE_HELPERS,
|
||||
Topic,
|
||||
RECOMMENDED_INSTANCES,
|
||||
All_TOPIC,
|
||||
ALL_TOPIC,
|
||||
TOPICS,
|
||||
} from "./instances-definitions";
|
||||
import { Icon, IconSize } from "./icon";
|
||||
|
@ -80,10 +80,6 @@ const ComparisonBlock = () => (
|
|||
</div>
|
||||
);
|
||||
|
||||
const SectionTitle = ({ title }) => (
|
||||
<div className="text-2xl mb-3">{title}</div>
|
||||
);
|
||||
|
||||
interface InstanceCardGridProps {
|
||||
title: string;
|
||||
instances: any[];
|
||||
|
@ -367,7 +363,7 @@ function getSortFromQuery(sort?: string): Sort {
|
|||
}
|
||||
|
||||
function getTopicFromQuery(topic?: string): Topic {
|
||||
return TOPICS.find(c => c.name == topic) ?? All_TOPIC;
|
||||
return TOPICS.find(c => c.name == topic) ?? ALL_TOPIC;
|
||||
}
|
||||
|
||||
function getInstancesQueryParams() {
|
||||
|
@ -384,7 +380,7 @@ export class Instances extends Component<Props, State> {
|
|||
instances: [],
|
||||
sort: RANDOM_SORT,
|
||||
language: "all",
|
||||
topic: All_TOPIC,
|
||||
topic: ALL_TOPIC,
|
||||
scroll: false,
|
||||
};
|
||||
|
||||
|
@ -434,7 +430,7 @@ export class Instances extends Component<Props, State> {
|
|||
}
|
||||
|
||||
// Topic filter
|
||||
if (this.state.topic !== All_TOPIC) {
|
||||
if (this.state.topic !== ALL_TOPIC) {
|
||||
const topicRecs = recommended.filter(r =>
|
||||
r.topics.includes(this.state.topic),
|
||||
);
|
||||
|
@ -565,7 +561,7 @@ function handleSortChange(i: Instances, event: any) {
|
|||
|
||||
function handleTopicChange(i: Instances, event: any) {
|
||||
i.setState({
|
||||
topic: TOPICS.find(c => c.name == event.target.value) ?? All_TOPIC,
|
||||
topic: TOPICS.find(c => c.name == event.target.value) ?? ALL_TOPIC,
|
||||
});
|
||||
i.buildInstanceList();
|
||||
}
|
||||
|
@ -579,7 +575,7 @@ function handleSeeAll(i: Instances) {
|
|||
i.setState({
|
||||
sort: RANDOM_SORT,
|
||||
language: "all",
|
||||
topic: All_TOPIC,
|
||||
topic: ALL_TOPIC,
|
||||
});
|
||||
i.buildInstanceList();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue