Launcher: hide the Mods page's sources and tabs that aren't usable yet

The Mods and Shader packs tabs search Horizon's registry only: no Modrinth /
CurseForge switch. The Modpacks, Resource packs and Data packs tabs are hidden;
Modpacks still opens from the sidebar (its tab shows while open) with its source
switch. A Java instance's Mods tab still searches Modrinth, with its filters.

Closes #4477

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rdbtCVSandClaude Opus 5.5 committed 2026-10-30 15:35:21 +00:00
1 parent 1da354b67a
commit 0416fe600c
3 files changed
+43 -42

No files matched your search

+5 -3
View File
@@ -81,9 +81,11 @@ start); the hedge places and its recipe crafts 4.
## The Mods page
The launcher's **Mods** page has the four kinds as tabs (Mods, Modpacks, Resource packs, Shader packs; the last
searches Horizon's registry), a search field (Enter searches), **Show everything** and
the source: Modrinth, with **CurseForge (coming soon)** beside it, disabled. Each result is an index row: its summary, author,
The launcher's **Mods** page has two tabs, **Mods** and **Shader packs**, both searching Horizon's registry (a Java
instance's Mods tab searches Modrinth for its version), and a search field (Enter searches). Modrinth's kinds aren't
usable yet, so the Resource packs and Data packs tabs and the source switch are hidden; the CLI still reaches them
(`mods search --kind ...`). The Modpacks tab shows only while the sidebar's modpacks or its + button have it open, with
**Show everything** and the source: Modrinth, with **CurseForge (coming soon)** beside it, disabled. Each result is an index row: its summary, author,
downloads, source and licence, how well it runs (and why), **Page** (the project's page on its source) and
**Install** (**Import** for a modpack). The Modpacks tab lists the imported packs first, with their coverage
report, **Port** and **Play** ([modpacks.md](modpacks.md)). Installed packs are listed above the results with their version, source,
+7 -8
View File
@@ -38,11 +38,10 @@ The opening, then Play ([clip](docs/opening.webm)):
starts the game. With no install on the computer the Play page offers the download alone and the
Minecraft folder row says none is needed. Without an owner,
the Play page asks to sign in first. `horizon-launcher prepare --download`.
- **Mods**: search Modrinth (CurseForge support is coming soon) for resource
packs and modpacks, each marked Works, Partly or Doesn't run in
Horizon; Java mod jars are never offered. Install puts a pack and what it needs in
`resourcepacks/` only after its SHA-512 matches, and a
modpack goes to the Modpacks page; installed packs show their source and checksum, with Update,
- **Mods**: two tabs, **Mods** and **Shader packs**, search Horizon's own registry (a Java
instance's mods come from Modrinth); Modrinth's resource packs and data packs aren't usable yet
and have no tab. Install puts a file in the game folder only after its checksum matches, and a
modpack (the sidebar's +) goes to the Modpacks page; installed packs show their source and checksum, with Update,
**Update all** and Remove ([docs/mod-browser.md](../docs/mod-browser.md)).
- **Modpacks**: import a Java modpack (a Modrinth `.mrpack`, a CurseForge zip, or a Prism,
MultiMC or CurseForge instance folder) and see its coverage report: per mod, ported, partial,
@@ -182,9 +181,9 @@ The opening, then Play ([clip](docs/opening.webm)):
`datapacks/` under its row: what is there (and which the game has turned off), **Add data pack…**,
and **Remove** (to the trash); a data pack `.zip` dropped on a world goes into it. The game turns
a new one on when the world opens. From the command line: `horizon-launcher worlds
datapack-list|datapack-add|datapack-remove <world> …`. The Mods page's **Data packs** tab finds
them on Modrinth and installs one into the world picked there (`mods search --kind datapack`,
`mods install <pack> --world <world>`), saying what of it runs in Horizon.
datapack-list|datapack-add|datapack-remove <world> …`. `horizon-launcher mods search --kind datapack`
finds them on Modrinth and `mods install <pack> --world <world>` installs one, saying what of it
runs in Horizon.
- **Packs**: Home lists the selected instance's resource packs and shader packs, each with a switch.
The choice is the game's own: `resourcePacks` in options.txt (a pack turned on goes on top, as
the game's Resource Packs screen does) and `pickedShaderPack` in `horizon-graphics.txt` (one shader
+31 -31
View File
@@ -1,5 +1,5 @@
//! The Mods page: search Horizon's own registry for mods made for Horizon, or Modrinth
//! (CurseForge: coming soon) for Java mods, modpacks and resource packs, see where each comes
//! The Mods page: search Horizon's own registry for mods and shader packs made for Horizon (a
//! Java instance's mods come from Modrinth), see where each comes
//! from and how well it runs (a Java mod's jar is checked first; a Horizon mod says whether it is
//! signed and what it may do), install it with its checksum checked, turn Horizon mods on and
//! off, and update or remove what was installed (`horizon_launcher::browser`). Imported modpacks
@@ -16,7 +16,7 @@ use java_instance::Target;
use std::collections::HashMap;
use std::path::PathBuf;
/// The kinds, as the Mods page's tabs: name and icon.
/// The kinds, as the Mods page's tabs: name and icon. Only [`SHOWN`]'s have a tab.
const KINDS: [(PackKind, &str, &str); 5] = [
(PackKind::Mod, "Mods", "box"),
(PackKind::Modpack, "Modpacks", "archive"),
@@ -24,9 +24,12 @@ const KINDS: [(PackKind, &str, &str); 5] = [
(PackKind::Shader, "Shader packs", "zap"),
(PackKind::DataPack, "Data packs", "notes"),
];
/// The kinds with a tab: Horizon's registry serves these. Modpacks, resource packs and data
/// packs come from Modrinth, not usable yet; the Modpacks tab shows while the sidebar has it open.
const SHOWN: [PackKind; 2] = [PackKind::Mod, PackKind::Shader];
/// Java mods checked at once.
const CHECKING: usize = 2;
/// The sources to pick from; CurseForge is shown beside them as coming soon.
/// The sources to pick from on the Modpacks tab; CurseForge is shown beside them as coming soon.
const SOURCES: [(SourceId, &str); 2] = [
(SourceId::Modrinth, "Modrinth"),
(SourceId::Horizon, "Horizon"),
@@ -139,18 +142,11 @@ impl Mods {
let kind = match page.as_deref() {
Ok("modpacks") => PackKind::Modpack,
Ok("shaders") => PackKind::Shader,
Ok("datapacks") => PackKind::DataPack,
_ => PackKind::Mod,
};
Self {
kind,
// `HORIZON_LAUNCHER_SOURCE=horizon` opens on Horizon's registry, for screenshots;
// shader packs are only there.
source: match std::env::var("HORIZON_LAUNCHER_SOURCE").as_deref() {
_ if kind == PackKind::Shader => SourceId::Horizon,
Ok("horizon") => SourceId::Horizon,
_ => SourceId::Modrinth,
},
source: source_for(kind),
text: LineEdit::new(String::new(), 100, 40),
focus: cx.focus_handle().tab_index(0).tab_stop(true),
focused: false,
@@ -285,6 +281,7 @@ impl Launcher {
}
if self.mods.kind != PackKind::Modpack {
self.mods.kind = PackKind::Modpack;
self.mods.source = source_for(PackKind::Modpack);
self.mods.browse.filters = Default::default();
self.mods.browse.open = None;
if self.mods.loaded {
@@ -857,28 +854,23 @@ impl Launcher {
}
let header = page_header(
"Mods",
"Mods and shader packs made for Horizon from its own reviewed registry, and Java \
mods, modpacks and resource packs from Modrinth: Horizon ports what a Java mod \
carries (blocks, items, recipes, worldgen) and says before you install what runs. Each file is checked \
against its source's checksum before it reaches your game folder.",
"Mods and shader packs made for Horizon, from its own reviewed registry. Each file \
is checked against the registry's checksum before it reaches your game folder.",
&t,
);
let this = cx.entity().downgrade();
let kinds = blocks::tabs("mods-kind", &KINDS, self.mods.kind, &t, {
let open = self.mods.kind;
let shown: Vec<_> = KINDS
.into_iter()
.filter(|&(kind, ..)| SHOWN.contains(&kind) || kind == open)
.collect();
let kinds = blocks::tabs("mods-kind", &shown, open, &t, {
let this = this.clone();
move |kind, _, cx| {
let _ = this.update(cx, |this, cx| {
if this.mods.kind != kind {
this.mods.kind = kind;
// Horizon's own shader packs are on its registry only.
if kind == PackKind::Shader {
this.mods.source = SourceId::Horizon;
}
// Data packs are on Modrinth only; a world may have been made since.
if kind == PackKind::DataPack {
this.mods.source = SourceId::Modrinth;
this.mods.read_worlds();
}
this.mods.source = source_for(kind);
// Categories and loaders differ by kind.
this.mods.browse.filters = Default::default();
this.mods.browse.open = None;
@@ -906,14 +898,14 @@ impl Launcher {
this.mods_search(0);
cx.notify();
}));
// CurseForge support is coming soon: shown, inert, never searched (like the Microsoft
// account's "Coming soon").
// A Java instance's mods and resource packs come from Modrinth, for its version.
// Only modpacks, reached from the sidebar, still pick their source: CurseForge is coming
// soon there, shown, inert, never searched (like the Microsoft account's "Coming soon").
// A Java instance's mods come from Modrinth, for its version.
let java = self.mods.java_for(self.mods.kind).is_some();
let source_note = (self.mods.kind != PackKind::DataPack && !java)
let source_note = (self.mods.kind == PackKind::Modpack)
.then(|| div().flex().child(self.mods_source_switch(cx)));
// The registry lists only what was made for Horizon: no "everything", no Modrinth filters.
let registry = self.mods.source == SourceId::Horizon;
let registry = self.mods.source == SourceId::Horizon && !java;
let filters = (!registry).then(|| self.mods_filters(cx));
let controls = div()
.flex()
@@ -1440,6 +1432,14 @@ impl Launcher {
}
}
/// Where a kind's tab searches: Horizon's registry, but Modrinth for modpacks.
fn source_for(kind: PackKind) -> SourceId {
match kind {
PackKind::Modpack => SourceId::Modrinth,
_ => SourceId::Horizon,
}
}
impl Launcher {
/// The source switch: Modrinth or Horizon's registry, CurseForge shown as coming soon and not
/// clickable, like the Microsoft account's "Coming soon".