Adding Apps page filtering by platform. Fixes #256 (#259)

This commit is contained in:
Dessalines 2023-11-01 09:50:20 -04:00 committed by GitHub
parent ec0b9b7d09
commit 02967e4b03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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

View file

@ -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,
];

View file

@ -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();
}

View file

@ -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>
);

View file

@ -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`;

View file

@ -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,

View file

@ -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();
}