fix: drop tally embed from hosting panel
This commit is contained in:
1 parent
02e18e3765
commit
537b73b3dc
3 files changed
+174
-5
No files matched your search
@@ -77,6 +77,11 @@ cd ../..
|
||||
scripts/export-patches.sh # rewrite patches/ from those commits
|
||||
```
|
||||
|
||||
The icons are the one thing that is generated rather than written. Edit
|
||||
`build/upstream/apps/app/icons/modrinth-enhanced.svg`, run `scripts/render-icons.py`, and every PNG,
|
||||
`.ico` and `.icns` next to it is rewritten from that source; rendering the unchanged source again
|
||||
reproduces the current files byte for byte.
|
||||
|
||||
Patches are applied with `git am --3way`, so small upstream movements around a hunk resolve by
|
||||
themselves. When one genuinely conflicts, `scripts/prepare.sh` stops and leaves the conflict staged
|
||||
in `build/upstream` to be resolved with `git am --continue`, after which `scripts/export-patches.sh`
|
||||
|
||||
@@ -3,7 +3,7 @@ From: Modrinth Enhanced <patches@modrinth-enhanced.invalid>
|
||||
Date: Mon, 14 Sep 2026 10:23:01 +0200
|
||||
Subject: [PATCH] Remove telemetry
|
||||
|
||||
Product analytics, crash reporting and the user survey embed are all
|
||||
Product analytics, crash reporting and the survey embeds are all
|
||||
removed, and the Modrinth analytics endpoints the launcher itself posts
|
||||
to are no longer called:
|
||||
|
||||
@@ -13,9 +13,12 @@ to are no longer called:
|
||||
PostHog SDK is no longer part of the bundle at all.
|
||||
* `helpers/error-reporting.ts` no longer loads `@sentry/vue`; errors are
|
||||
logged locally, as they are in upstream development builds.
|
||||
* The third-party Tally embed is dropped from `index.html` and the
|
||||
survey list is no longer fetched, so the popup that carries the
|
||||
signed-in Modrinth user id never appears.
|
||||
* The third-party Tally embed is gone. It was loaded from `index.html`
|
||||
on every start for the app's own survey popup, and injected again by
|
||||
the Modrinth Hosting panel in `@modrinth/ui` when a server carries a
|
||||
survey notice. Neither loads it now, and the app no longer fetches the
|
||||
survey list, so the popup that carries the signed-in Modrinth user id
|
||||
never appears.
|
||||
* `analytics/playtime` and `analytics/minecraft-server-play` are no
|
||||
longer posted from `app-lib`. The latter also removes a Mojang session
|
||||
handshake whose only purpose was to authenticate that report.
|
||||
@@ -38,7 +41,8 @@ for them.
|
||||
.../app-frontend/src/locales/en-US/index.json | 2 +-
|
||||
apps/app/tauri.conf.json | 6 +-
|
||||
packages/app-lib/src/api/instance/run.rs | 83 +++--------------
|
||||
8 files changed, 50 insertions(+), 218 deletions(-)
|
||||
.../layouts/wrapped/hosting/manage/root.vue | 8 +-
|
||||
9 files changed, 53 insertions(+), 223 deletions(-)
|
||||
|
||||
diff --git a/apps/app-frontend/index.html b/apps/app-frontend/index.html
|
||||
index 6367788..9738bbc 100644
|
||||
@@ -449,3 +453,22 @@ index 25626c1..d638128 100644
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
diff --git a/packages/ui/src/layouts/wrapped/hosting/manage/root.vue b/packages/ui/src/layouts/wrapped/hosting/manage/root.vue
|
||||
index 9ccd656..065aad6 100644
|
||||
--- a/packages/ui/src/layouts/wrapped/hosting/manage/root.vue
|
||||
+++ b/packages/ui/src/layouts/wrapped/hosting/manage/root.vue
|
||||
@@ -906,11 +906,9 @@ function showSurvey() {
|
||||
}
|
||||
|
||||
function loadTallyScript() {
|
||||
- if (document.querySelector('script[src*="tally.so"]')) return
|
||||
- const script = document.createElement('script')
|
||||
- script.src = 'https://tally.so/widgets/embed.js'
|
||||
- script.defer = true
|
||||
- document.head.appendChild(script)
|
||||
+ // Modrinth Enhanced does not load the third-party Tally embed. Without it
|
||||
+ // `getTally()` stays undefined and `showSurvey()` above does nothing, so a
|
||||
+ // survey notice on a hosted server is simply not turned into a popup.
|
||||
}
|
||||
|
||||
async function handleInstallationRetry() {
|
||||
Executable
+141
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Render the Modrinth Enhanced icon set from its vector source.
|
||||
|
||||
The source lives in the patched checkout as
|
||||
`apps/app/icons/modrinth-enhanced.svg`; this rewrites every generated icon
|
||||
next to it. Run it after editing that 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
|
||||
writers below are a few lines each and work the same everywhere, whereas
|
||||
ImageMagick's ICNS support depends on how it was built.
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import struct
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
ICONS = os.path.join(
|
||||
os.environ.get("WORKTREE", os.path.join(REPO_ROOT, "build", "upstream")),
|
||||
"apps",
|
||||
"app",
|
||||
"icons",
|
||||
)
|
||||
SVG = os.path.join(ICONS, "modrinth-enhanced.svg")
|
||||
|
||||
# Every PNG the Tauri bundles reference, and the size it has to be.
|
||||
PNGS = {
|
||||
"icon.png": 512,
|
||||
"128x128.png": 128,
|
||||
"128x128@2x.png": 256,
|
||||
"StoreLogo.png": 50,
|
||||
"Square30x30Logo.png": 30,
|
||||
"Square44x44Logo.png": 44,
|
||||
"Square71x71Logo.png": 71,
|
||||
"Square89x89Logo.png": 89,
|
||||
"Square107x107Logo.png": 107,
|
||||
"Square142x142Logo.png": 142,
|
||||
"Square150x150Logo.png": 150,
|
||||
"Square284x284Logo.png": 284,
|
||||
"Square310x310Logo.png": 310,
|
||||
}
|
||||
|
||||
ICO_SIZES = [16, 24, 32, 48, 64, 256]
|
||||
FAVICON_SIZES = [16, 24, 32, 64]
|
||||
|
||||
# ICNS chunk type -> pixel size. All chunks carry PNG payloads, which macOS
|
||||
# 10.7 and newer understand.
|
||||
ICNS_TYPES = [
|
||||
(b"icp4", 16),
|
||||
(b"icp5", 32),
|
||||
(b"ic11", 32),
|
||||
(b"ic12", 64),
|
||||
(b"ic07", 128),
|
||||
(b"ic13", 256),
|
||||
(b"ic08", 256),
|
||||
(b"ic14", 512),
|
||||
(b"ic09", 512),
|
||||
(b"ic10", 1024),
|
||||
]
|
||||
|
||||
|
||||
def render(size, path):
|
||||
"""Rasterise the source at exactly `size`, rather than downscaling one
|
||||
large render, so the small sizes stay crisp."""
|
||||
subprocess.run(
|
||||
["rsvg-convert", "-w", str(size), "-h", str(size), SVG, "-o", path],
|
||||
check=True,
|
||||
)
|
||||
|
||||
|
||||
def build_ico(sizes, cache, path):
|
||||
entries, blobs, offset = [], [], 6 + 16 * len(sizes)
|
||||
for size in sizes:
|
||||
with open(cache[size], "rb") as handle:
|
||||
data = handle.read()
|
||||
entries.append(
|
||||
struct.pack(
|
||||
"<BBBBHHII",
|
||||
# 256 is written as 0 in an ICO directory entry.
|
||||
size if size < 256 else 0,
|
||||
size if size < 256 else 0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
32,
|
||||
len(data),
|
||||
offset,
|
||||
)
|
||||
)
|
||||
blobs.append(data)
|
||||
offset += len(data)
|
||||
with open(path, "wb") as handle:
|
||||
handle.write(struct.pack("<HHH", 0, 1, len(sizes)))
|
||||
for entry in entries:
|
||||
handle.write(entry)
|
||||
for blob in blobs:
|
||||
handle.write(blob)
|
||||
|
||||
|
||||
def build_icns(cache, path):
|
||||
chunks = b""
|
||||
for kind, size in ICNS_TYPES:
|
||||
with open(cache[size], "rb") as handle:
|
||||
data = handle.read()
|
||||
chunks += kind + struct.pack(">I", len(data) + 8) + data
|
||||
with open(path, "wb") as handle:
|
||||
handle.write(b"icns" + struct.pack(">I", len(chunks) + 8) + chunks)
|
||||
|
||||
|
||||
def main():
|
||||
if not shutil.which("rsvg-convert"):
|
||||
sys.exit("rsvg-convert is required (install librsvg)")
|
||||
if not os.path.isfile(SVG):
|
||||
sys.exit(f"No icon source at {SVG}. Run scripts/prepare.sh first.")
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
cache = {}
|
||||
needed = set(PNGS.values()) | set(ICO_SIZES) | set(FAVICON_SIZES)
|
||||
needed |= {size for _, size in ICNS_TYPES}
|
||||
for size in sorted(needed):
|
||||
cache[size] = os.path.join(tmp, f"{size}.png")
|
||||
render(size, cache[size])
|
||||
|
||||
for name, size in PNGS.items():
|
||||
shutil.copyfile(cache[size], os.path.join(ICONS, name))
|
||||
build_ico(ICO_SIZES, cache, os.path.join(ICONS, "icon.ico"))
|
||||
build_ico(FAVICON_SIZES, cache, os.path.join(ICONS, "favicon.ico"))
|
||||
build_icns(cache, os.path.join(ICONS, "icon.icns"))
|
||||
|
||||
for name in sorted(os.listdir(ICONS)):
|
||||
full = os.path.join(ICONS, name)
|
||||
if os.path.isfile(full):
|
||||
print(f"{name:24s} {os.path.getsize(full):>8d} bytes")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user