Record / Convert tabs — now gated behind PUBLIC_MOBILE_APP=true. Hidden by default in VPS/dev mode; only show when explicitly opted into the mobile app build.

Edit/Upload UI — split into two concepts:
  - PUBLIC_EDIT_URL — the server base URL (empty = use proxy at /api/)
  - PUBLIC_EDIT_ENABLED=true — whether to show the edit/upload buttons at all

  bincio dev now sets PUBLIC_EDIT_ENABLED=true when instance.db exists (multi-user mode), so the upload button, edit button, and edit drawer all appear. The fetch calls already produce  correct relative URLs (${''}/api/upload = /api/upload) which the Vite proxy forwards to bincio serve.
This commit is contained in:
Davide Scaini
2026-04-09 13:16:00 +02:00
parent 2501c9e0f6
commit fb202b4edf
4 changed files with 22 additions and 10 deletions
+4 -2
View File
@@ -148,8 +148,10 @@ def dev(
env = {
**os.environ,
"BINCIO_DATA_DIR": str(data),
"PUBLIC_EDIT_URL": "", # empty = proxy /api/* to bincio serve
"VITE_API_PORT": str(api_port), # picked up by astro.config.mjs if needed
"PUBLIC_EDIT_URL": "", # empty = proxy /api/* to bincio serve
"PUBLIC_EDIT_ENABLED": "true" if has_auth else "", # show edit/upload UI in VPS mode
"PUBLIC_MOBILE_APP": "", # Record/Convert tabs off by default
"VITE_API_PORT": str(api_port), # picked up by astro.config.mjs
}
# Start astro dev in foreground (Ctrl+C stops everything)
+4 -3
View File
@@ -13,7 +13,8 @@
export let base: string = '/';
export let athlete: AthleteZones | null = null;
const editUrl = import.meta.env.PUBLIC_EDIT_URL;
const editUrl = import.meta.env.PUBLIC_EDIT_URL ?? '';
const editEnabled = editUrl !== '' || import.meta.env.PUBLIC_EDIT_ENABLED === 'true';
let detail: ActivityDetail | null = null;
let error = '';
@@ -89,7 +90,7 @@
<svelte:window on:keydown={onKeydown} />
{#if editOpen && editUrl}
{#if editOpen && editEnabled}
<EditDrawer activityId={activity.id} {editUrl} on:saved={onSaved} on:close={() => editOpen = false} />
{/if}
@@ -176,7 +177,7 @@
</div>
<div class="flex items-center gap-3">
<h1 class="text-2xl font-bold text-white">{displayTitle}</h1>
{#if editUrl}
{#if editEnabled}
<button
class="text-xs px-2 py-0.5 rounded border border-zinc-700 text-zinc-400 hover:border-zinc-500 hover:text-white transition-colors shrink-0"
on:click={() => editOpen = true}
+1
View File
@@ -36,6 +36,7 @@
let uploading = false;
let fileInput: HTMLInputElement;
// editUrl is empty in multi-user VPS mode — the Vite proxy forwards /api/* to bincio serve.
const api = `${editUrl}/api/activity/${activityId}`;
async function load() {
+13 -5
View File
@@ -10,6 +10,10 @@ interface Props {
}
const { title = 'BincioActivity', description = 'Your personal activity stats', public: isPublicPage = false } = Astro.props;
const editUrl = import.meta.env.PUBLIC_EDIT_URL ?? '';
// Edit UI is enabled when PUBLIC_EDIT_URL is set (single-user bincio-edit mode)
// OR when PUBLIC_EDIT_ENABLED=true (multi-user VPS mode — API proxied at /api/).
const editEnabled = editUrl !== '' || import.meta.env.PUBLIC_EDIT_ENABLED === 'true';
const mobileApp = import.meta.env.PUBLIC_MOBILE_APP === 'true';
const baseUrl = import.meta.env.BASE_URL ?? '/';
// Read root index.json at build time to detect instance configuration.
@@ -163,8 +167,12 @@ try {
<!-- Per-user nav links — updated by user-widget script in multi-user mode -->
<a id="nav-stats" href={singleHandle ? `${baseUrl}u/${singleHandle}/stats/` : `${baseUrl}stats/`} data-user-path="stats/" class="text-sm text-zinc-400 hover:text-white transition-colors">Stats</a>
<a id="nav-athlete" href={singleHandle ? `${baseUrl}u/${singleHandle}/athlete/` : `${baseUrl}athlete/`} data-user-path="athlete/" class="text-sm text-zinc-400 hover:text-white transition-colors">Athlete</a>
<a id="nav-record" href={singleHandle ? `${baseUrl}u/${singleHandle}/record/` : `${baseUrl}record/`} data-user-path="record/" class="text-sm text-zinc-400 hover:text-white transition-colors">Record</a>
<a href={`${baseUrl}convert/`} class="text-sm text-zinc-400 hover:text-white transition-colors">Convert</a>
{mobileApp && (
<a id="nav-record" href={singleHandle ? `${baseUrl}u/${singleHandle}/record/` : `${baseUrl}record/`} data-user-path="record/" class="text-sm text-zinc-400 hover:text-white transition-colors">Record</a>
)}
{mobileApp && (
<a href={`${baseUrl}convert/`} class="text-sm text-zinc-400 hover:text-white transition-colors">Convert</a>
)}
<div class="ml-auto flex items-center gap-1">
<!-- Logout button — hidden until logged in -->
@@ -174,7 +182,7 @@ try {
class="text-xs text-zinc-500 hover:text-white transition-colors px-2 h-8"
aria-label="Log out"
>Log out</button>
{editUrl && (
{editEnabled && (
<button
id="upload-btn"
class="text-zinc-400 hover:text-white transition-colors w-8 h-8 flex items-center justify-center rounded-md hover:bg-zinc-800 text-base"
@@ -191,7 +199,7 @@ try {
</div>
</nav>
{editUrl && (
{editEnabled && (
<!-- Add activity modal -->
<div
id="upload-modal"
@@ -360,7 +368,7 @@ try {
</script>
)}
{editUrl && (
{editEnabled && (
<script define:vars={{ editUrl, baseUrl }}>
const modal = document.getElementById('upload-modal');
const openBtn = document.getElementById('upload-btn');