Merge pull request #307 from Reeywhaar/image-upload-ui

Image upload ui
This commit is contained in:
Umputun
2019-04-14 22:58:39 -05:00
committed by GitHub
12 changed files with 311 additions and 25 deletions
+22 -2
View File
@@ -1,6 +1,6 @@
import { siteId, url } from './settings';
import { BASE_URL } from './constants';
import { Config, Comment, Tree, User, BlockedUser, Sorting, AuthProvider, BlockTTL } from './types';
import { BASE_URL, API_BASE } from './constants';
import { Config, Comment, Tree, User, BlockedUser, Sorting, AuthProvider, BlockTTL, Image } from './types';
import fetcher from './fetcher';
/* common */
@@ -234,6 +234,25 @@ export const enableComments = (): Promise<void> =>
withCredentials: true,
});
export const uploadImage = (image: File): Promise<Image> => {
const data = new FormData();
data.append('file', image);
return fetcher
.post<{ id: string }>({
url: `/picture`,
withCredentials: true,
contentType: 'multipart/form-data',
body: data,
})
.then(resp => ({
name: image.name,
size: image.size,
type: image.type,
url: BASE_URL + API_BASE + '/picture/' + resp.id,
}));
};
export default {
logIn,
logOut,
@@ -260,4 +279,5 @@ export default {
getBlocked,
disableComments,
enableComments,
uploadImage,
};
+31 -12
View File
@@ -6,29 +6,46 @@ import { getCookie } from './cookies';
export type FetcherMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head';
const methods: FetcherMethod[] = ['get', 'post', 'put', 'patch', 'delete', 'head'];
type FetcherInit =
| string
| {
url: string;
body?: string | object | Blob | ArrayBuffer;
overriddenApiBase?: string;
withCredentials?: boolean;
};
interface FetcherInitBase {
url: string;
overriddenApiBase?: string;
withCredentials?: boolean;
}
interface FetcherInitJSON extends FetcherInitBase {
contentType?: 'application/json';
body?: string | object | Blob | ArrayBuffer;
}
interface FetcherInitMultipart extends FetcherInitBase {
contentType: 'multipart/form-data';
body: FormData;
}
type FetcherInit = string | FetcherInitJSON | FetcherInitMultipart;
type FetcherObject = { [K in FetcherMethod]: <T = unknown>(data: FetcherInit) => Promise<T> };
const fetcher = methods.reduce<Partial<FetcherObject>>((acc, method) => {
acc[method] = <T = unknown>(data: FetcherInit): Promise<T> => {
const { url, body = undefined, withCredentials = false, overriddenApiBase = API_BASE } =
typeof data === 'string' ? { url: data } : data;
const {
url,
body = undefined,
withCredentials = false,
overriddenApiBase = API_BASE,
contentType = 'application/json',
} = typeof data === 'string' ? { url: data } : data;
const basename = `${BASE_URL}${overriddenApiBase}`;
const headers = new Headers({
Accept: 'application/json',
'Content-Type': 'application/json',
'X-XSRF-TOKEN': getCookie('XSRF-TOKEN') || '',
});
if (contentType !== 'multipart/form-data') {
headers.append('Content-Type', contentType);
}
let rurl = `${basename}${url}`;
const parameters: RequestInit = {
@@ -39,7 +56,9 @@ const fetcher = methods.reduce<Partial<FetcherObject>>((acc, method) => {
};
if (body) {
if (typeof body === 'object') {
if (contentType === 'multipart/form-data') {
parameters.body = body as FormData;
} else if (typeof body === 'object' && !(body instanceof Blob) && !(body instanceof ArrayBuffer)) {
parameters.body = JSON.stringify(body);
} else {
parameters.body = body;
+1
View File
@@ -25,6 +25,7 @@ export const StaticStore: StaticStoreType = {
low_score: 0,
positive_score: false,
readonly_age: 0,
max_image_size: 0,
},
query: querySettings as QuerySettingsType,
};
+21
View File
@@ -101,6 +101,7 @@ export interface Config {
critical_score: number;
positive_score: boolean;
readonly_age: number;
max_image_size: number;
}
export interface RemarkConfig {
@@ -138,3 +139,23 @@ export enum CommentMode {
Reply,
Edit,
}
/**
* Used as api.uploadImage response type
*/
export interface Image {
name: string;
size: number;
/** mime type of an image */
type: string;
url: string;
}
/** error struct returned in case of api call error */
export interface ApiError {
code: number;
/** simple explanation */
details: string;
/** in-depth explanation */
error: string;
}