feat: redesign icon, hide servers in sidebar, collapse news
This commit is contained in:
1 parent
f67b017c5f
commit
e1ec2068e6
5 files changed
+12422
-13989
No files matched your search
@@ -4,22 +4,23 @@ Date: Mon, 14 Sep 2026 09:56:18 +0200
|
|||||||
Subject: [PATCH] Rename the app to Modrinth Enhanced
|
Subject: [PATCH] Rename the app to Modrinth Enhanced
|
||||||
|
|
||||||
Changes the product name, the binary name, the window title and the
|
Changes the product name, the binary name, the window title and the
|
||||||
version label shown in settings. A small "Enhanced" pill is added next
|
version label shown in settings.
|
||||||
to the wordmark in the title bar so the fork is recognisable at a
|
|
||||||
glance.
|
The title bar keeps the plain Modrinth wordmark: a badge next to it
|
||||||
|
pushes the width of that bar up, and the name is already visible in the
|
||||||
|
window title and in settings.
|
||||||
|
|
||||||
The bundle identifier is deliberately left as `ModrinthApp` so that
|
The bundle identifier is deliberately left as `ModrinthApp` so that
|
||||||
Modrinth Enhanced keeps using the same data directory as the official
|
Modrinth Enhanced keeps using the same data directory as the official
|
||||||
app and stays a drop-in replacement for it.
|
app and stays a drop-in replacement for it.
|
||||||
---
|
---
|
||||||
apps/app-frontend/index.html | 2 +-
|
apps/app-frontend/index.html | 2 +-
|
||||||
apps/app-frontend/src/App.vue | 5 +++++
|
|
||||||
.../src/components/ui/modal/AppSettingsModal.vue | 2 +-
|
.../src/components/ui/modal/AppSettingsModal.vue | 2 +-
|
||||||
apps/app-frontend/src/locales/en-US/index.json | 2 +-
|
apps/app-frontend/src/locales/en-US/index.json | 2 +-
|
||||||
apps/app/tauri.conf.json | 6 +++---
|
apps/app/tauri.conf.json | 6 +++---
|
||||||
apps/app/tauri.linux.conf.json | 2 +-
|
apps/app/tauri.linux.conf.json | 2 +-
|
||||||
apps/app/tauri.macos.conf.json | 2 +-
|
apps/app/tauri.macos.conf.json | 2 +-
|
||||||
7 files changed, 13 insertions(+), 8 deletions(-)
|
6 files changed, 8 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
diff --git a/apps/app-frontend/index.html b/apps/app-frontend/index.html
|
diff --git a/apps/app-frontend/index.html b/apps/app-frontend/index.html
|
||||||
index 50867a4..6367788 100644
|
index 50867a4..6367788 100644
|
||||||
@@ -34,22 +35,6 @@ index 50867a4..6367788 100644
|
|||||||
|
|
||||||
<link rel="stylesheet" href="/src/assets/stylesheets/global.scss" />
|
<link rel="stylesheet" href="/src/assets/stylesheets/global.scss" />
|
||||||
</head>
|
</head>
|
||||||
diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue
|
|
||||||
index a2ae0e6..1d1a9ce 100644
|
|
||||||
--- a/apps/app-frontend/src/App.vue
|
|
||||||
+++ b/apps/app-frontend/src/App.vue
|
|
||||||
@@ -2374,6 +2374,11 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
|
||||||
<div data-tauri-drag-region class="app-grid-statusbar bg-bg-raised h-[--top-bar-height] flex">
|
|
||||||
<div data-tauri-drag-region class="flex min-w-0 flex-1 items-center overflow-hidden p-2">
|
|
||||||
<TextLogo class="h-7 w-auto shrink-0 text-contrast pointer-events-none" />
|
|
||||||
+ <span
|
|
||||||
+ data-tauri-drag-region
|
|
||||||
+ class="ml-1.5 shrink-0 rounded-full bg-brand-highlight px-1.5 py-0.5 text-[0.625rem] font-bold uppercase leading-none tracking-wide text-brand pointer-events-none"
|
|
||||||
+ >Enhanced</span
|
|
||||||
+ >
|
|
||||||
<div data-tauri-drag-region class="ml-2 flex shrink-0 items-center gap-2">
|
|
||||||
<IconButton
|
|
||||||
type="outlined"
|
|
||||||
diff --git a/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue b/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue
|
diff --git a/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue b/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue
|
||||||
index dd55fe5..0f33d0e 100644
|
index dd55fe5..0f33d0e 100644
|
||||||
--- a/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue
|
--- a/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue
|
||||||
|
|||||||
+12207
-13957
File diff suppressed because it is too large.
Load diff
@@ -16,7 +16,7 @@ webview, no matter which call site reaches for it.
|
|||||||
2 files changed, 25 insertions(+), 48 deletions(-)
|
2 files changed, 25 insertions(+), 48 deletions(-)
|
||||||
|
|
||||||
diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue
|
diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue
|
||||||
index 1d1a9ce..4df835f 100644
|
index a2ae0e6..33c29ce 100644
|
||||||
--- a/apps/app-frontend/src/App.vue
|
--- a/apps/app-frontend/src/App.vue
|
||||||
+++ b/apps/app-frontend/src/App.vue
|
+++ b/apps/app-frontend/src/App.vue
|
||||||
@@ -366,10 +366,10 @@ const hasPlus = computed(
|
@@ -366,10 +366,10 @@ const hasPlus = computed(
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Modrinth Enhanced <patches@modrinth-enhanced.invalid>
|
||||||
|
Date: Mon, 14 Sep 2026 13:06:38 +0200
|
||||||
|
Subject: [PATCH] Hide Modrinth Servers in the sidebar and fold away the news
|
||||||
|
|
||||||
|
Two sidebar preferences, both stored as feature flags so they survive a
|
||||||
|
restart without needing a settings migration:
|
||||||
|
|
||||||
|
* The Modrinth Servers button in the left sidebar is off by default and
|
||||||
|
can be turned back on under Settings > Features > Sidebar.
|
||||||
|
* The news section in the right sidebar collapses by clicking its
|
||||||
|
heading, remembering the state the way the friends list does.
|
||||||
|
---
|
||||||
|
apps/app-frontend/src/App.vue | 31 +++++++++++++++++--
|
||||||
|
.../ui/settings/display/FeaturesSettings.vue | 27 ++++++++++++++++
|
||||||
|
.../src/composables/use-app-settings.ts | 2 ++
|
||||||
|
packages/app-lib/src/state/settings.rs | 2 ++
|
||||||
|
4 files changed, 59 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue
|
||||||
|
index 33c29ce..4c3663f 100644
|
||||||
|
--- a/apps/app-frontend/src/App.vue
|
||||||
|
+++ b/apps/app-frontend/src/App.vue
|
||||||
|
@@ -11,6 +11,7 @@ import {
|
||||||
|
import {
|
||||||
|
ArrowBigUpDashIcon,
|
||||||
|
ArrowLeftRightIcon,
|
||||||
|
+ ChevronDownIcon,
|
||||||
|
ChevronLeftIcon,
|
||||||
|
ChevronRightIcon,
|
||||||
|
CompassIcon,
|
||||||
|
@@ -370,6 +371,21 @@ const hasPlus = computed(
|
||||||
|
// ad cookie consent flow that only exists to serve it are both switched off.
|
||||||
|
const showAd = computed(() => false)
|
||||||
|
const adConsentAvailable = computed(() => false)
|
||||||
|
+
|
||||||
|
+// Whether the news section in the right sidebar is folded away. Kept in the
|
||||||
|
+// feature flags so it survives a restart, the same way the friends list
|
||||||
|
+// remembers its collapsed sections.
|
||||||
|
+const newsCollapsed = computed(() => appSettings.getFeatureFlag('news_collapsed'))
|
||||||
|
+
|
||||||
|
+function setNewsCollapsed(collapsed: boolean) {
|
||||||
|
+ appSettings.featureFlags.news_collapsed = collapsed
|
||||||
|
+ getSettings()
|
||||||
|
+ .then((settings) => {
|
||||||
|
+ settings.feature_flags.news_collapsed = collapsed
|
||||||
|
+ return setSettings(settings)
|
||||||
|
+ })
|
||||||
|
+ .catch(handleError)
|
||||||
|
+}
|
||||||
|
providePageContext({
|
||||||
|
hierarchicalSidebarAvailable: ref(true),
|
||||||
|
showAds: showAd,
|
||||||
|
@@ -2278,6 +2294,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||||
|
<ImageIcon />
|
||||||
|
</NavButton>
|
||||||
|
<NavButton
|
||||||
|
+ v-if="appSettings.getFeatureFlag('show_hosting_in_sidebar')"
|
||||||
|
v-tooltip.right="formatMessage(messages.modrinthHosting)"
|
||||||
|
to="/hosting/manage"
|
||||||
|
:is-primary="(r) => r.path === '/hosting/manage' || r.path === '/hosting/manage/'"
|
||||||
|
@@ -2528,10 +2545,18 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||||
|
class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid"
|
||||||
|
/>
|
||||||
|
<div v-if="news && news.length > 0" class="p-4 flex flex-col items-center">
|
||||||
|
- <h3 class="text-base mb-4 text-primary font-medium m-0 text-left w-full">
|
||||||
|
+ <button
|
||||||
|
+ class="button-base m-0 mb-4 flex w-full cursor-pointer items-center justify-between gap-2 border-0 bg-transparent p-0 text-left text-base font-medium text-primary"
|
||||||
|
+ :aria-expanded="!newsCollapsed"
|
||||||
|
+ @click="setNewsCollapsed(!newsCollapsed)"
|
||||||
|
+ >
|
||||||
|
{{ formatMessage(messages.news) }}
|
||||||
|
- </h3>
|
||||||
|
- <div class="space-y-4 flex flex-col items-center w-full">
|
||||||
|
+ <ChevronDownIcon
|
||||||
|
+ class="h-5 w-5 shrink-0 transition-transform"
|
||||||
|
+ :class="{ '-rotate-90': newsCollapsed }"
|
||||||
|
+ />
|
||||||
|
+ </button>
|
||||||
|
+ <div v-if="!newsCollapsed" class="space-y-4 flex flex-col items-center w-full">
|
||||||
|
<NewsArticleCard
|
||||||
|
v-for="(item, index) in news"
|
||||||
|
:key="`news-${index}`"
|
||||||
|
diff --git a/apps/app-frontend/src/components/ui/settings/display/FeaturesSettings.vue b/apps/app-frontend/src/components/ui/settings/display/FeaturesSettings.vue
|
||||||
|
index 1d3e379..54f1c51 100644
|
||||||
|
--- a/apps/app-frontend/src/components/ui/settings/display/FeaturesSettings.vue
|
||||||
|
+++ b/apps/app-frontend/src/components/ui/settings/display/FeaturesSettings.vue
|
||||||
|
@@ -43,6 +43,7 @@ const quickInstances = useQuickInstanceLimit()
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
const showJumpInFlag: FeatureFlag = 'worlds_in_home'
|
||||||
|
+const showHostingFlag: FeatureFlag = 'show_hosting_in_sidebar'
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
syncAcrossDevicesTitle: {
|
||||||
|
@@ -95,6 +96,14 @@ const messages = defineMessages({
|
||||||
|
id: 'app.features-settings.show-skin-selector.description',
|
||||||
|
defaultMessage: 'Show a button in the left sidebar to open the skin selector.',
|
||||||
|
},
|
||||||
|
+ showHostingTitle: {
|
||||||
|
+ id: 'app.features-settings.show-hosting.title',
|
||||||
|
+ defaultMessage: 'Show Modrinth Servers in sidebar',
|
||||||
|
+ },
|
||||||
|
+ showHostingDescription: {
|
||||||
|
+ id: 'app.features-settings.show-hosting.description',
|
||||||
|
+ defaultMessage: 'Show a button in the left sidebar to manage Modrinth Servers.',
|
||||||
|
+ },
|
||||||
|
quickInstancesTitle: {
|
||||||
|
id: 'app.features-settings.quick-instances.title',
|
||||||
|
defaultMessage: 'Quick instances in sidebar',
|
||||||
|
@@ -125,6 +134,7 @@ type FeaturesSettingsState = {
|
||||||
|
showScreenshotsTab: boolean
|
||||||
|
showAllScreenshots: boolean
|
||||||
|
showSkinSelector: boolean
|
||||||
|
+ showHosting: boolean
|
||||||
|
quickInstanceCount: number
|
||||||
|
showJumpIn: boolean
|
||||||
|
}
|
||||||
|
@@ -144,6 +154,7 @@ function getFeaturesSettingsState(
|
||||||
|
showScreenshotsTab: settings.show_screenshots_tab_in_instances,
|
||||||
|
showAllScreenshots: globalSyncedOptions.screenshots,
|
||||||
|
showSkinSelector: settings.show_skin_selector_in_sidebar,
|
||||||
|
+ showHosting: settings.feature_flags[showHostingFlag] ?? DEFAULT_FEATURE_FLAGS[showHostingFlag],
|
||||||
|
quickInstanceCount: quickInstances.limit.value ?? QUICK_INSTANCE_LIMIT_MAX,
|
||||||
|
showJumpIn: settings.feature_flags[showJumpInFlag] ?? DEFAULT_FEATURE_FLAGS[showJumpInFlag],
|
||||||
|
}
|
||||||
|
@@ -184,6 +195,7 @@ const settingsMutation = useMutation({
|
||||||
|
feature_flags: {
|
||||||
|
...latestSettings.feature_flags,
|
||||||
|
[showJumpInFlag]: value.showJumpIn,
|
||||||
|
+ [showHostingFlag]: value.showHosting,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -206,6 +218,7 @@ const settingsMutation = useMutation({
|
||||||
|
appSettings.showScreenshotsTabInInstances = value.showScreenshotsTab
|
||||||
|
appSettings.showSkinSelectorInSidebar = value.showSkinSelector
|
||||||
|
appSettings.featureFlags[showJumpInFlag] = value.showJumpIn
|
||||||
|
+ appSettings.featureFlags[showHostingFlag] = value.showHosting
|
||||||
|
|
||||||
|
if (updateQuickInstanceCount) {
|
||||||
|
quickInstances.setLimit(value.quickInstanceCount)
|
||||||
|
@@ -366,6 +379,20 @@ onBeforeUnmount(() => {
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
+ <div class="flex items-center justify-between gap-4">
|
||||||
|
+ <div>
|
||||||
|
+ <h3 class="m-0 text-lg font-semibold text-contrast">
|
||||||
|
+ {{ formatMessage(messages.showHostingTitle) }}
|
||||||
|
+ </h3>
|
||||||
|
+ <p class="m-0 mt-1">{{ formatMessage(messages.showHostingDescription) }}</p>
|
||||||
|
+ </div>
|
||||||
|
+ <Toggle
|
||||||
|
+ id="show-hosting-in-sidebar"
|
||||||
|
+ v-model="current.showHosting"
|
||||||
|
+ :aria-label="formatMessage(messages.showHostingTitle)"
|
||||||
|
+ />
|
||||||
|
+ </div>
|
||||||
|
+
|
||||||
|
<div class="flex flex-col gap-2.5">
|
||||||
|
<h3 class="m-0 text-lg font-semibold text-contrast">
|
||||||
|
{{ formatMessage(messages.quickInstancesTitle) }}
|
||||||
|
diff --git a/apps/app-frontend/src/composables/use-app-settings.ts b/apps/app-frontend/src/composables/use-app-settings.ts
|
||||||
|
index 0d58903..4f0b2aa 100644
|
||||||
|
--- a/apps/app-frontend/src/composables/use-app-settings.ts
|
||||||
|
+++ b/apps/app-frontend/src/composables/use-app-settings.ts
|
||||||
|
@@ -24,6 +24,8 @@ export const DEFAULT_FEATURE_FLAGS = {
|
||||||
|
friends_pending_collapsed: true,
|
||||||
|
dismissed_photosensitivity_filter_warning: false,
|
||||||
|
localhost_sign_in: false,
|
||||||
|
+ show_hosting_in_sidebar: false,
|
||||||
|
+ news_collapsed: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FeatureFlag = keyof typeof DEFAULT_FEATURE_FLAGS
|
||||||
|
diff --git a/packages/app-lib/src/state/settings.rs b/packages/app-lib/src/state/settings.rs
|
||||||
|
index 20601b8..b02bbe0 100644
|
||||||
|
--- a/packages/app-lib/src/state/settings.rs
|
||||||
|
+++ b/packages/app-lib/src/state/settings.rs
|
||||||
|
@@ -88,6 +88,8 @@ pub enum FeatureFlag {
|
||||||
|
FriendsPendingCollapsed,
|
||||||
|
DismissedPhotosensitivityFilterWarning,
|
||||||
|
LocalhostSignIn,
|
||||||
|
+ ShowHostingInSidebar,
|
||||||
|
+ NewsCollapsed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Settings {
|
||||||
+19
-10
@@ -1,10 +1,12 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Render the Modrinth Enhanced icon set from its vector source.
|
"""Render the Modrinth Enhanced icon set from its vector sources.
|
||||||
|
|
||||||
The source lives in the patched checkout as
|
Two sources live in the patched checkout next to the generated files:
|
||||||
`apps/app/icons/modrinth-enhanced.svg`; this rewrites every generated icon
|
`apps/app/icons/modrinth-enhanced.svg` for 64px and up, and
|
||||||
next to it. Run it after editing that SVG, then commit the result in
|
`modrinth-enhanced-small.svg` for everything below that, where the full maze
|
||||||
build/upstream and re-export the patches.
|
no longer resolves. This rewrites every generated icon from them. Run it after
|
||||||
|
editing either SVG, then commit the result in build/upstream and re-export the
|
||||||
|
patches.
|
||||||
|
|
||||||
Needs `rsvg-convert` (librsvg). ImageMagick is not used: the ICNS and ICO
|
Needs `rsvg-convert` (librsvg). ImageMagick is not used: the ICNS and ICO
|
||||||
writers below are a few lines each and work the same everywhere, whereas
|
writers below are a few lines each and work the same everywhere, whereas
|
||||||
@@ -26,6 +28,11 @@ ICONS = os.path.join(
|
|||||||
"icons",
|
"icons",
|
||||||
)
|
)
|
||||||
SVG = os.path.join(ICONS, "modrinth-enhanced.svg")
|
SVG = os.path.join(ICONS, "modrinth-enhanced.svg")
|
||||||
|
SVG_SMALL = os.path.join(ICONS, "modrinth-enhanced-small.svg")
|
||||||
|
|
||||||
|
# Below this the full mark's rings are thinner than a pixel and smear into each
|
||||||
|
# other, so the cropped source is used instead.
|
||||||
|
SMALL_MAX = 48
|
||||||
|
|
||||||
# Every PNG the Tauri bundles reference, and the size it has to be.
|
# Every PNG the Tauri bundles reference, and the size it has to be.
|
||||||
PNGS = {
|
PNGS = {
|
||||||
@@ -64,10 +71,11 @@ ICNS_TYPES = [
|
|||||||
|
|
||||||
|
|
||||||
def render(size, path):
|
def render(size, path):
|
||||||
"""Rasterise the source at exactly `size`, rather than downscaling one
|
"""Rasterise the source for `size` at exactly that size, rather than
|
||||||
large render, so the small sizes stay crisp."""
|
downscaling one large render, so the small sizes stay crisp."""
|
||||||
|
source = SVG_SMALL if size <= SMALL_MAX else SVG
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
["rsvg-convert", "-w", str(size), "-h", str(size), SVG, "-o", path],
|
["rsvg-convert", "-w", str(size), "-h", str(size), source, "-o", path],
|
||||||
check=True,
|
check=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -114,8 +122,9 @@ def build_icns(cache, path):
|
|||||||
def main():
|
def main():
|
||||||
if not shutil.which("rsvg-convert"):
|
if not shutil.which("rsvg-convert"):
|
||||||
sys.exit("rsvg-convert is required (install librsvg)")
|
sys.exit("rsvg-convert is required (install librsvg)")
|
||||||
if not os.path.isfile(SVG):
|
for source in (SVG, SVG_SMALL):
|
||||||
sys.exit(f"No icon source at {SVG}. Run scripts/prepare.sh first.")
|
if not os.path.isfile(source):
|
||||||
|
sys.exit(f"No icon source at {source}. Run scripts/prepare.sh first.")
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as tmp:
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
cache = {}
|
cache = {}
|
||||||
|
|||||||
Reference in new issue
Block a user