feat(settings): expandable Icon sets panel (view/upload/delete)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -11,11 +11,14 @@ function token() { return localStorage.getItem(TOKEN_KEY) || ''; }
|
||||
|
||||
async function call(method, path, body) {
|
||||
const headers = { 'Authorization': 'Bearer ' + token() };
|
||||
if (body !== undefined) headers['Content-Type'] = 'application/json';
|
||||
// FormData bodies: let the browser set the multipart/form-data boundary
|
||||
// automatically — do NOT set Content-Type or JSON.stringify.
|
||||
const isFormData = body instanceof FormData;
|
||||
if (body !== undefined && !isFormData) headers['Content-Type'] = 'application/json';
|
||||
const res = await fetch(path, {
|
||||
method,
|
||||
headers,
|
||||
body: body === undefined ? undefined : JSON.stringify(body)
|
||||
body: body === undefined ? undefined : (isFormData ? body : JSON.stringify(body))
|
||||
});
|
||||
if (res.status === 401) { await promptForToken(); return call(method, path, body); }
|
||||
if (res.status === 204) return null;
|
||||
@@ -61,11 +64,14 @@ function promptForToken() {
|
||||
}
|
||||
|
||||
export const api = {
|
||||
get: (p) => call('GET', p),
|
||||
post: (p, body) => call('POST', p, body ?? {}),
|
||||
put: (p, body) => call('PUT', p, body ?? {}),
|
||||
patch: (p, body) => call('PATCH', p, body ?? {}),
|
||||
del: (p) => call('DELETE', p),
|
||||
get: (p) => call('GET', p),
|
||||
post: (p, body) => call('POST', p, body ?? {}),
|
||||
put: (p, body) => call('PUT', p, body ?? {}),
|
||||
patch: (p, body) => call('PATCH', p, body ?? {}),
|
||||
del: (p) => call('DELETE', p),
|
||||
// POST a FormData body (multipart/form-data). Content-Type is omitted so
|
||||
// the browser appends the correct multipart boundary automatically.
|
||||
postForm: (p, fd) => call('POST', p, fd),
|
||||
setToken: (v) => localStorage.setItem(TOKEN_KEY, v),
|
||||
hasToken: () => !!token()
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user