web: mark SAVE PHOTO PRO and keep MY PHOTOS for the accounts that have one
Saving into the account's own folder has always been the account's act — the button opened the way in and the API answers an unproven address with a 403 — but nothing on the button said so, so it read as a button that quietly did nothing. It now wears the same PRO marker the chips do, and only while the folder is not the visitor's. MY PHOTOS is that folder's listing, so the tab is only offered once an account can hold one. A guest loses the tab entirely rather than opening it on an empty folder that could never fill; an account that has signed up but not proven its address keeps the tab, and the tab keeps offering the way to prove it.
This commit is contained in:
@@ -2244,6 +2244,7 @@ export function Workspace() {
|
||||
<div className="shell">
|
||||
<TopBar
|
||||
recipeName={recipe.name}
|
||||
pro={pro}
|
||||
user={user}
|
||||
exporting={exporting}
|
||||
savingPhoto={savingPhoto}
|
||||
@@ -2286,7 +2287,7 @@ export function Workspace() {
|
||||
) : null}
|
||||
|
||||
<div className="workspace">
|
||||
<ToolRail tab={tab} onTab={setTab} onDropRecipe={favoriteById} />
|
||||
<ToolRail tab={tab} onTab={setTab} onDropRecipe={favoriteById} signedIn={!!user} />
|
||||
|
||||
<div className="chips">
|
||||
{/* column 1 — the tab's own chips, RESET ruled off at the foot */}
|
||||
|
||||
@@ -141,7 +141,10 @@
|
||||
/* Edited value, strip closed: the text glows amber, the border does not. */
|
||||
.chip.amber, .chip.amber .val { color: var(--accent); }
|
||||
.chip .val { color: var(--text-dim); font-family: var(--mono); font-size: 11px; }
|
||||
.chip .pro { font-size: 9px; letter-spacing: 0.08em; color: var(--accent); }
|
||||
.chip .pro, .btn .pro { font-size: 9px; letter-spacing: 0.08em; color: var(--accent); }
|
||||
/* A button is not a flex row the way a chip is, so the marker carries its own
|
||||
gap off the label it qualifies. */
|
||||
.btn .pro { margin-left: 6px; }
|
||||
.chip:disabled { opacity: 0.4; cursor: not-allowed; }
|
||||
/* The font group as a dropdown: one row that shows the current pairing instead
|
||||
of three chips that all have to fit. */
|
||||
|
||||
@@ -28,17 +28,22 @@ export function ToolRail({
|
||||
tab,
|
||||
onTab,
|
||||
onDropRecipe,
|
||||
signedIn = false,
|
||||
}: {
|
||||
tab: TabId;
|
||||
onTab: (tab: TabId) => void;
|
||||
// A recipe chip dragged onto FAVORITED is filed there (see App's favorite()).
|
||||
onDropRecipe?: (id: string) => void;
|
||||
// MY PHOTOS is the account's own folder, so the tab is only offered once
|
||||
// there is an account to hold one.
|
||||
signedIn?: boolean;
|
||||
}) {
|
||||
const { t } = useI18n();
|
||||
const favorited = (id: TabId) => id === 'favorited';
|
||||
const tabs = signedIn ? TABS : TABS.filter((entry) => entry.id !== 'photos');
|
||||
return (
|
||||
<nav className="rail" aria-label="tool tabs">
|
||||
{TABS.map((entry) => (
|
||||
{tabs.map((entry) => (
|
||||
<button
|
||||
key={entry.id}
|
||||
type="button"
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { User } from '../api';
|
||||
// the web build adds — theme (light/dark + accent group) and language.
|
||||
export function TopBar({
|
||||
recipeName,
|
||||
pro,
|
||||
user,
|
||||
exporting,
|
||||
savingPhoto,
|
||||
@@ -25,6 +26,9 @@ export function TopBar({
|
||||
onLogout,
|
||||
}: {
|
||||
recipeName: string;
|
||||
// Saving into the account's own folder is the account's own act, so the
|
||||
// button wears the same PRO marker the chips do until the address is proven.
|
||||
pro: boolean;
|
||||
user: User | null;
|
||||
exporting: boolean;
|
||||
savingPhoto: boolean;
|
||||
@@ -110,6 +114,7 @@ export function TopBar({
|
||||
: photoMax === null
|
||||
? t('save.photoNoMax', { n: photoCount })
|
||||
: t('save.photo', { n: photoCount, max: photoMax })}
|
||||
{!pro ? <span className="pro">PRO</span> : null}
|
||||
</button>
|
||||
<button type="button" className="btn primary" data-key="export-photo" disabled={exporting} onClick={onExport}>
|
||||
{exporting ? t('act.exporting') : t('act.export')}
|
||||
|
||||
Reference in New Issue
Block a user