Skip to content

Commit 3357f54

Browse files
committed
Simplified upload workflow, added new upload options on a per file basis, and implemented a new Upload settings page with some sensible image upload defaults.
1 parent fc83edb commit 3357f54

11 files changed

Lines changed: 807 additions & 435 deletions

File tree

dist/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
<meta name="twitter:image" content="https://raw.githubusercontent.com/Letdown2491/bloom/main/public/og-image.png">
2222

2323
<meta name="keywords" content="Bloom, Blossom, NIP-96, NIP-94, Nostr, file manager, distributed storage, metadata, media playback, open source">
24-
<script type="module" crossorigin src="/assets/index-Cp5KAttE.js"></script>
24+
<script type="module" crossorigin src="/assets/index-230vQDDm.js"></script>
2525
<link rel="modulepreload" crossorigin href="/assets/vendor-DhynQjd6.js">
2626
<link rel="modulepreload" crossorigin href="/assets/qrcode-Dz3BF1n8.js">
2727
<link rel="modulepreload" crossorigin href="/assets/react-B5NV7uPC.js">
2828
<link rel="modulepreload" crossorigin href="/assets/react-query-D8im5Lt0.js">
2929
<link rel="modulepreload" crossorigin href="/assets/music-metadata-C2reaobX.js">
3030
<link rel="modulepreload" crossorigin href="/assets/axios-ngrFHoWO.js">
31-
<link rel="stylesheet" crossorigin href="/assets/index--IEX9Vxs.css">
31+
<link rel="stylesheet" crossorigin href="/assets/index-D2Ca-wBG.css">
3232
</head>
3333
<body class="bg-slate-950 text-slate-100">
3434
<div id="root"></div>

src/app/App.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ export default function App() {
199199
setKeepSearchExpanded,
200200
setTheme,
201201
setSortDirection,
202+
setOptimizeImageUploadsByDefault,
203+
setStripImageMetadataByDefault,
204+
setDefaultImageResizeOption,
202205
setSyncEnabled,
203206
syncState,
204207
} = useUserPreferences();
@@ -2010,6 +2013,27 @@ export default function App() {
20102013
[setTheme],
20112014
);
20122015

2016+
const handleSetOptimizeImageUploadsByDefault = useCallback(
2017+
(value: boolean) => {
2018+
setOptimizeImageUploadsByDefault(value);
2019+
},
2020+
[setOptimizeImageUploadsByDefault],
2021+
);
2022+
2023+
const handleSetStripImageMetadataByDefault = useCallback(
2024+
(value: boolean) => {
2025+
setStripImageMetadataByDefault(value);
2026+
},
2027+
[setStripImageMetadataByDefault],
2028+
);
2029+
2030+
const handleSetDefaultImageResizeOption = useCallback(
2031+
(value: number) => {
2032+
setDefaultImageResizeOption(value);
2033+
},
2034+
[setDefaultImageResizeOption],
2035+
);
2036+
20132037
const handleToggleSearch = useCallback(() => {
20142038
if (keepSearchExpanded) {
20152039
selectTab("browse");
@@ -2680,6 +2704,12 @@ export default function App() {
26802704
onSetShowListPreviews={handleSetShowPreviewsInList}
26812705
onSetKeepSearchExpanded={handleSetKeepSearchExpanded}
26822706
onSetTheme={handleSetTheme}
2707+
optimizeImageUploadsByDefault={preferences.optimizeImageUploadsByDefault}
2708+
stripImageMetadataByDefault={preferences.stripImageMetadataByDefault}
2709+
defaultImageResizeOption={preferences.defaultImageResizeOption}
2710+
onSetOptimizeImageUploadsByDefault={handleSetOptimizeImageUploadsByDefault}
2711+
onSetStripImageMetadataByDefault={handleSetStripImageMetadataByDefault}
2712+
onSetDefaultImageResizeOption={handleSetDefaultImageResizeOption}
26832713
saving={saving}
26842714
signer={signer}
26852715
onAddServer={handleAddServer}

src/app/__tests__/App.uploadReturn.test.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ const preferencesMock = {
2626
showGridPreviews: true,
2727
showListPreviews: true,
2828
keepSearchExpanded: false,
29+
theme: "dark",
30+
optimizeImageUploadsByDefault: true,
31+
stripImageMetadataByDefault: true,
32+
defaultImageResizeOption: 0,
2933
};
3034

3135
const syncStateMock = {
@@ -64,6 +68,10 @@ vi.mock("../context/UserPreferencesContext", () => ({
6468
setShowGridPreviews: vi.fn(),
6569
setShowListPreviews: vi.fn(),
6670
setKeepSearchExpanded: vi.fn(),
71+
setTheme: vi.fn(),
72+
setOptimizeImageUploadsByDefault: vi.fn(),
73+
setStripImageMetadataByDefault: vi.fn(),
74+
setDefaultImageResizeOption: vi.fn(),
6775
setSyncEnabled: vi.fn(async () => undefined),
6876
syncState: syncStateMock,
6977
}),

src/app/context/UserPreferencesContext.tsx

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export type PreferencesSyncState = {
5050
pending: boolean;
5151
};
5252

53+
const IMAGE_RESIZE_MAX_ID = 3;
54+
5355
type UserPreferencesContextValue = {
5456
preferences: UserPreferences;
5557
setDefaultServerUrl: (url: string | null) => void;
@@ -61,6 +63,9 @@ type UserPreferencesContextValue = {
6163
setShowListPreviews: (value: boolean) => void;
6264
setKeepSearchExpanded: (value: boolean) => void;
6365
setTheme: (theme: "dark" | "light") => void;
66+
setOptimizeImageUploadsByDefault: (value: boolean) => void;
67+
setStripImageMetadataByDefault: (value: boolean) => void;
68+
setDefaultImageResizeOption: (value: number) => void;
6469
setSyncEnabled: (value: boolean) => Promise<void>;
6570
syncState: PreferencesSyncState;
6671
preferencesReady: boolean;
@@ -99,7 +104,10 @@ const preferencesEqual = (a: UserPreferences, b: UserPreferences) =>
99104
a.showGridPreviews === b.showGridPreviews &&
100105
a.showListPreviews === b.showListPreviews &&
101106
a.keepSearchExpanded === b.keepSearchExpanded &&
102-
a.theme === b.theme;
107+
a.theme === b.theme &&
108+
a.optimizeImageUploadsByDefault === b.optimizeImageUploadsByDefault &&
109+
a.stripImageMetadataByDefault === b.stripImageMetadataByDefault &&
110+
a.defaultImageResizeOption === b.defaultImageResizeOption;
103111

104112
export const UserPreferencesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
105113
const { ndk, signer, user, ensureConnection } = useNdk();
@@ -517,6 +525,37 @@ export const UserPreferencesProvider: React.FC<{ children: React.ReactNode }> =
517525
[mutatePreferences],
518526
);
519527

528+
const setOptimizeImageUploadsByDefault = useCallback(
529+
(value: boolean) => {
530+
mutatePreferences(prev => {
531+
if (prev.optimizeImageUploadsByDefault === value) return prev;
532+
return { ...prev, optimizeImageUploadsByDefault: value };
533+
});
534+
},
535+
[mutatePreferences],
536+
);
537+
538+
const setStripImageMetadataByDefault = useCallback(
539+
(value: boolean) => {
540+
mutatePreferences(prev => {
541+
if (prev.stripImageMetadataByDefault === value) return prev;
542+
return { ...prev, stripImageMetadataByDefault: value };
543+
});
544+
},
545+
[mutatePreferences],
546+
);
547+
548+
const setDefaultImageResizeOption = useCallback(
549+
(value: number) => {
550+
const clamped = Math.max(0, Math.min(IMAGE_RESIZE_MAX_ID, Math.trunc(value)));
551+
mutatePreferences(prev => {
552+
if (prev.defaultImageResizeOption === clamped) return prev;
553+
return { ...prev, defaultImageResizeOption: clamped };
554+
});
555+
},
556+
[mutatePreferences],
557+
);
558+
520559
const setSyncEnabled = useCallback(
521560
async (value: boolean) => {
522561
if (value === syncEnabled) return;
@@ -569,6 +608,9 @@ export const UserPreferencesProvider: React.FC<{ children: React.ReactNode }> =
569608
setShowListPreviews,
570609
setKeepSearchExpanded,
571610
setTheme,
611+
setOptimizeImageUploadsByDefault,
612+
setStripImageMetadataByDefault,
613+
setDefaultImageResizeOption,
572614
setSyncEnabled,
573615
syncState,
574616
preferencesReady: initialSyncReady,
@@ -584,6 +626,9 @@ export const UserPreferencesProvider: React.FC<{ children: React.ReactNode }> =
584626
setShowListPreviews,
585627
setKeepSearchExpanded,
586628
setTheme,
629+
setOptimizeImageUploadsByDefault,
630+
setStripImageMetadataByDefault,
631+
setDefaultImageResizeOption,
587632
setSyncEnabled,
588633
syncState,
589634
initialSyncReady,

src/app/services/preferencesStorage.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import type { FilterMode } from "../../shared/types/filter";
22
import type { UserPreferences } from "../../shared/types/preferences";
33
import { normalizeEpochSeconds } from "../../shared/utils/time";
44

5+
const RESIZE_OPTIONS_MAX_ID = 3;
6+
57
export const DEFAULT_PREFERENCES: UserPreferences = {
68
defaultServerUrl: null,
79
defaultViewMode: "list",
@@ -12,6 +14,9 @@ export const DEFAULT_PREFERENCES: UserPreferences = {
1214
showListPreviews: true,
1315
keepSearchExpanded: false,
1416
theme: "dark",
17+
optimizeImageUploadsByDefault: false,
18+
stripImageMetadataByDefault: true,
19+
defaultImageResizeOption: 0,
1520
};
1621

1722
const STORAGE_KEY = "bloom:user-preferences";
@@ -81,6 +86,19 @@ export const loadStoredPreferences = (): UserPreferences => {
8186
? parsed.defaultServerUrl.trim()
8287
: null;
8388
const theme = isTheme(parsed?.theme) ? parsed!.theme : "dark";
89+
const optimizeImageUploadsByDefault =
90+
typeof parsed?.optimizeImageUploadsByDefault === "boolean"
91+
? parsed.optimizeImageUploadsByDefault
92+
: DEFAULT_PREFERENCES.optimizeImageUploadsByDefault;
93+
const stripImageMetadataByDefault =
94+
typeof parsed?.stripImageMetadataByDefault === "boolean"
95+
? parsed.stripImageMetadataByDefault
96+
: true;
97+
const rawResizeOption = parsed?.defaultImageResizeOption;
98+
const defaultImageResizeOption =
99+
typeof rawResizeOption === "number" && Number.isFinite(rawResizeOption)
100+
? Math.max(0, Math.min(RESIZE_OPTIONS_MAX_ID, Math.trunc(rawResizeOption)))
101+
: 0;
84102
return {
85103
defaultServerUrl,
86104
defaultViewMode,
@@ -91,6 +109,9 @@ export const loadStoredPreferences = (): UserPreferences => {
91109
showListPreviews,
92110
keepSearchExpanded,
93111
theme,
112+
optimizeImageUploadsByDefault,
113+
stripImageMetadataByDefault,
114+
defaultImageResizeOption,
94115
};
95116
} catch {
96117
return DEFAULT_PREFERENCES;

0 commit comments

Comments
 (0)