feat: enhance styling and layout for toolbar, map components, and editor

- Updated toolbar styles for improved layout and appearance, including padding and margin adjustments.
- Introduced new styles for scale menu and compact dropdowns.
- Enhanced map pin tooltips with better positioning and hover effects.
- Added new styles for map sheet filters, including search and date range controls.
- Improved editor styles for a more cohesive look and feel, including transport controls for video editing.
- Expanded GeoLocation interface to include additional address fields and formatted address.
- Updated MediaItem interface to include storage reference and uploadedBy fields.
- Enhanced MediaComment interface with author details for better user identification.
- Introduced GalleryUser interface to represent signed-in users in the host app.
This commit is contained in:
2026-07-23 07:34:20 +05:30
parent bc8bf2007d
commit 7673fc63ea
35 changed files with 3130 additions and 394 deletions
+39 -9
View File
@@ -184,19 +184,39 @@ export function confirmAction(opts: {
function SecuritySettingsModal() {
const api = useGalleryStoreApi();
const hasPw = useGallery((s) => s.lock.hash !== null);
const hasPw = useGallery((s) => s.lockConfigured);
// A server-backed lock reads/writes the host's backend, not this device.
const serverBacked = useGallery((s) => Boolean(s.config.lockProvider));
const [p1, setP1] = useState('');
const [p2, setP2] = useState('');
const [err, setErr] = useState<string | null>(null);
const [busy, setBusy] = useState(false);
const save = async () => {
if (p1.trim().length < 4) return setErr('Use at least 4 characters.');
if (p1 !== p2) return setErr('Passwords do not match.');
await api.getState().setLockPassword(p1.trim());
setBusy(true);
const state = api.getState();
state.clearLockError();
await state.setLockPassword(p1.trim());
setBusy(false);
// The store reports an unreachable provider rather than throwing.
if (api.getState().lockError === 'unavailable') {
setErr("Couldn't reach the server. Try again.");
return;
}
closeModal();
};
const remove = () => {
api.getState().removeLockPassword();
const remove = async () => {
setBusy(true);
const state = api.getState();
state.clearLockError();
await state.removeLockPassword();
setBusy(false);
if (api.getState().lockError === 'unavailable') {
setErr("Couldn't reach the server. Try again.");
return;
}
closeModal();
};
@@ -206,9 +226,13 @@ function SecuritySettingsModal() {
{hasPw ? 'Recently Deleted is Locked' : 'Lock Recently Deleted'}
</div>
<div className="apg-empty-card__text" style={{ marginBottom: 4 }}>
{hasPw
? 'Set a new password, or remove the lock. The password is stored only on this device.'
: 'Protect Recently Deleted with a password. It is stored only on this device (not uploaded).'}
{serverBacked
? hasPw
? 'Set a new password, or remove the lock. It applies to your account on every device.'
: 'Protect Recently Deleted with a password. It applies to your account on every device.'
: hasPw
? 'Set a new password, or remove the lock. The password is stored only on this device.'
: 'Protect Recently Deleted with a password. It is stored only on this device (not uploaded).'}
</div>
<input
className="apg-modal__input"
@@ -241,7 +265,8 @@ function SecuritySettingsModal() {
type="button"
className="apg-btn"
style={{ marginRight: 'auto', color: 'var(--apg-danger)' }}
onClick={remove}
disabled={busy}
onClick={() => void remove()}
>
Remove Lock
</button>
@@ -249,7 +274,12 @@ function SecuritySettingsModal() {
<button type="button" className="apg-btn" onClick={closeModal}>
Cancel
</button>
<button type="button" className="apg-btn apg-btn--primary" onClick={() => void save()}>
<button
type="button"
className="apg-btn apg-btn--primary"
disabled={busy}
onClick={() => void save()}
>
{hasPw ? 'Change' : 'Set Password'}
</button>
</div>