Replace useFetcher with useFetch.
This commit is contained in:
parent
d4f593c4ce
commit
942cba97da
15 changed files with 292 additions and 740 deletions
31
src/lib/fetch.d.ts
vendored
31
src/lib/fetch.d.ts
vendored
|
@ -1,31 +0,0 @@
|
|||
import { ISearchProps } from "../components/searchBar";
|
||||
import { IBookmarkGroupProps } from "../components/bookmarks";
|
||||
import { IAppProps, IAppCategoryProps } from "../components/apps";
|
||||
import { IThemeProps } from "./theme";
|
||||
import { IImprintProps } from "../components/imprint";
|
||||
import { IGreeterProps } from "../components/greeter";
|
||||
|
||||
declare module "../data/apps.json" {
|
||||
export const categories: IAppCategoryProps[];
|
||||
export const apps: IAppProps[];
|
||||
}
|
||||
|
||||
declare module "../data/search.json" {
|
||||
export const search: ISearchProps;
|
||||
}
|
||||
|
||||
declare module "../data/bookmarks.json" {
|
||||
export const groups: IBookmarkGroupProps[];
|
||||
}
|
||||
|
||||
declare module "../data/themes.json" {
|
||||
export const themes: IThemeProps[];
|
||||
}
|
||||
|
||||
declare module "../data/imprint.json" {
|
||||
export const imprint: IImprintProps;
|
||||
}
|
||||
|
||||
declare module "../data/greeter.json" {
|
||||
export const greeter: IGreeterProps;
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { IAppListProps } from "../components/apps";
|
||||
import { IThemeProps } from "./useTheme";
|
||||
import { IBookmarkListProps } from "../components/bookmarks";
|
||||
import { ISearchProps } from "../components/searchBar";
|
||||
import { IImprintProps } from "../components/imprint";
|
||||
import { IGreeterProps } from "../components/greeter";
|
||||
|
||||
const inProduction = process.env.NODE_ENV === "production";
|
||||
|
||||
interface IFetchItemProps {
|
||||
url: string;
|
||||
setHook?: React.Dispatch<React.SetStateAction<any>>;
|
||||
}
|
||||
|
||||
interface IFetchListProps {
|
||||
app: IFetchItemProps;
|
||||
bookmarks: IFetchItemProps;
|
||||
greeter: IFetchItemProps;
|
||||
imprint: IFetchItemProps;
|
||||
search: IFetchItemProps;
|
||||
themes: IFetchItemProps;
|
||||
}
|
||||
|
||||
let fetchList: IFetchListProps = {
|
||||
app: { url: "/data/app.json" },
|
||||
bookmarks: { url: "/data/bookmarks.json" },
|
||||
greeter: { url: "/data/greeter.json" },
|
||||
imprint: { url: "/data/imprint.json" },
|
||||
search: { url: "/data/search.json" },
|
||||
themes: { url: "/data/themes.json" },
|
||||
};
|
||||
|
||||
export const handleResponse = (response: Response, type: string) => {
|
||||
if (response.ok) return response.json();
|
||||
throw new Error("Error fetching " + type + " data");
|
||||
};
|
||||
|
||||
const handleError = (error: Error) => {
|
||||
console.error(error.message);
|
||||
};
|
||||
|
||||
const fetchURL = (url: string, type: string) => {
|
||||
const response = inProduction ? fetch(url) : import(".." + url);
|
||||
|
||||
return response
|
||||
.then((response: Response) => handleResponse(response, type))
|
||||
.catch(handleError);
|
||||
};
|
||||
|
||||
const useFetch = () => {
|
||||
const [appData, setAppData] = useState<IAppListProps>();
|
||||
fetchList.app.setHook = setAppData;
|
||||
|
||||
const [bookmarkData, setBookmarkData] = useState<IBookmarkListProps>();
|
||||
fetchList.bookmarks.setHook = setBookmarkData;
|
||||
|
||||
const [greeterData, setGreeterData] = useState<IGreeterProps>();
|
||||
fetchList.greeter.setHook = setGreeterData;
|
||||
|
||||
const [imprintData, setImprintData] = useState<IImprintProps>();
|
||||
fetchList.imprint.setHook = setImprintData;
|
||||
|
||||
const [searchData, setSearchData] = useState<ISearchProps>();
|
||||
fetchList.search.setHook = setSearchData;
|
||||
|
||||
const [themeData, setThemeData] = useState<Array<IThemeProps>>();
|
||||
fetchList.themes.setHook = setThemeData;
|
||||
|
||||
const callback = useCallback(() => {
|
||||
Object.entries(fetchList).forEach(([key, val]) => {
|
||||
fetchURL(val.url, key).then((data) => {
|
||||
val.setHook(data);
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => callback(), [callback]);
|
||||
|
||||
return {
|
||||
appData,
|
||||
bookmarkData,
|
||||
greeterData,
|
||||
imprintData,
|
||||
searchData,
|
||||
themeData,
|
||||
callback,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFetch;
|
32
src/lib/fetcher.d.ts
vendored
32
src/lib/fetcher.d.ts
vendored
|
@ -1,32 +0,0 @@
|
|||
import { ISearchProps } from "../components/searchBar";
|
||||
import { IBookmarkGroupProps } from "../components/bookmarks";
|
||||
import { IAppCategoryProps } from "../components/appCategory";
|
||||
import { IAppProps } from "../components/app";
|
||||
import { IThemeProps } from "./theme";
|
||||
import { IImprintProps } from "../components/imprint";
|
||||
import { IGreeterProps } from "../components/greeter";
|
||||
|
||||
declare module "../data/apps.json" {
|
||||
export const categories: IAppCategoryProps[];
|
||||
export const apps: IAppProps[];
|
||||
}
|
||||
|
||||
declare module "../data/search.json" {
|
||||
export const search: ISearchProps;
|
||||
}
|
||||
|
||||
declare module "../data/bookmarks.json" {
|
||||
export const groups: IBookmarkGroupProps[];
|
||||
}
|
||||
|
||||
declare module "../data/themes.json" {
|
||||
export const themes: IThemeProps[];
|
||||
}
|
||||
|
||||
declare module "../data/imprint.json" {
|
||||
export const imprint: IImprintProps;
|
||||
}
|
||||
|
||||
declare module "../data/greeter.json" {
|
||||
export const greeter: IGreeterProps;
|
||||
}
|
|
@ -1,278 +0,0 @@
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { ISearchProps } from "../components/searchBar";
|
||||
import { IBookmarkGroupProps } from "../components/bookmarks";
|
||||
import { IAppCategoryProps } from "../components/appCategory";
|
||||
import { IAppProps } from "../components/app";
|
||||
import { IThemeProps } from "./useTheme";
|
||||
import { IImprintProps } from "../components/imprint";
|
||||
import { IGreeterProps } from "../components/greeter";
|
||||
|
||||
const errorMessage = "Failed to load data.";
|
||||
const inProduction = process.env.NODE_ENV === "production";
|
||||
|
||||
/**
|
||||
* Handles the response from the fetch requests
|
||||
* @param {Response} response - The response given by the fetch request
|
||||
* @returns - The response in JSON
|
||||
* @throws - Error with given error message if request failed
|
||||
*/
|
||||
export const handleResponse = (response: Response) => {
|
||||
if (response.ok) return response.json();
|
||||
throw new Error(errorMessage);
|
||||
};
|
||||
|
||||
export interface ISearchDataProps {
|
||||
search: ISearchProps;
|
||||
error: string | boolean;
|
||||
}
|
||||
|
||||
export interface IBookmarkDataProps {
|
||||
groups: Array<IBookmarkGroupProps>;
|
||||
error: string | boolean;
|
||||
}
|
||||
|
||||
export interface IAppDataProps {
|
||||
categories: Array<IAppCategoryProps>;
|
||||
apps: Array<IAppProps>;
|
||||
error: string | boolean;
|
||||
}
|
||||
|
||||
export interface IThemeDataProps {
|
||||
themes: Array<IThemeProps>;
|
||||
error: string | boolean;
|
||||
}
|
||||
|
||||
export interface IImprintDataProps {
|
||||
imprint: IImprintProps;
|
||||
error: string | boolean;
|
||||
}
|
||||
|
||||
export interface IGreeterDataProps {
|
||||
greeter: IGreeterProps;
|
||||
error: string | boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default values for the respective state variables
|
||||
*/
|
||||
export const defaults = {
|
||||
app: {
|
||||
categories: [],
|
||||
apps: [],
|
||||
error: false,
|
||||
},
|
||||
bookmark: {
|
||||
groups: [],
|
||||
error: false,
|
||||
},
|
||||
search: {
|
||||
search: {
|
||||
placeholder: "",
|
||||
defaultProvider: "https://google.com/search?q=",
|
||||
providers: [],
|
||||
},
|
||||
error: false,
|
||||
},
|
||||
theme: {
|
||||
themes: [],
|
||||
error: false,
|
||||
},
|
||||
imprint: {
|
||||
imprint: {
|
||||
name: { text: "", link: "" },
|
||||
address: { text: "", link: "" },
|
||||
phone: { text: "", link: "" },
|
||||
email: { text: "", link: "" },
|
||||
url: { text: "", link: "" },
|
||||
text: "",
|
||||
},
|
||||
error: false,
|
||||
},
|
||||
greeter: {
|
||||
greeter: {
|
||||
months: [
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
],
|
||||
days: [
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
],
|
||||
greetings: [
|
||||
{
|
||||
greeting: "Good night!",
|
||||
start: 0,
|
||||
end: 6,
|
||||
},
|
||||
{
|
||||
greeting: "Good morning!",
|
||||
start: 6,
|
||||
end: 12,
|
||||
},
|
||||
{
|
||||
greeting: "Good afternoon!",
|
||||
start: 12,
|
||||
end: 18,
|
||||
},
|
||||
{
|
||||
greeting: "Good evening!",
|
||||
start: 18,
|
||||
end: 0,
|
||||
},
|
||||
],
|
||||
dateformat: "%wd, %m %d%e %y",
|
||||
},
|
||||
error: false,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles fetch errors by returning the error message.
|
||||
* @param {string} type - The type of fetch request that threw an error
|
||||
* @param {Error} error - The error itself
|
||||
*/
|
||||
export const handleError = (status: string, error: Error) => {
|
||||
switch (status) {
|
||||
case "apps":
|
||||
return { ...defaults.app, error: error.message };
|
||||
case "bookmark":
|
||||
return { ...defaults.bookmark, error: error.message };
|
||||
case "searchProvider":
|
||||
return { ...defaults.search, error: error.message };
|
||||
case "theme":
|
||||
return { ...defaults.theme, error: error.message };
|
||||
case "imprint":
|
||||
return { ...defaults.imprint, error: error.message };
|
||||
case "greeter":
|
||||
return { ...defaults.greeter, error: error.message };
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetches all of the data by doing fetch requests (only available in production)
|
||||
*/
|
||||
export const fetchProduction = Promise.all([
|
||||
fetch("/data/apps.json")
|
||||
.then(handleResponse)
|
||||
.catch((error: Error) => handleError("apps", error)),
|
||||
fetch("/data/bookmarks.json")
|
||||
.then(handleResponse)
|
||||
.catch((error: Error) => handleError("bookmark", error)),
|
||||
fetch("/data/search.json")
|
||||
.then(handleResponse)
|
||||
.catch((error: Error) => handleError("searchProvider", error)),
|
||||
fetch("/data/themes.json")
|
||||
.then(handleResponse)
|
||||
.catch((error: Error) => handleError("theme", error)),
|
||||
fetch("/data/imprint.json")
|
||||
.then(handleResponse)
|
||||
.catch((error: Error) => handleError("imprint", error)),
|
||||
fetch("/data/greeter.json")
|
||||
.then(handleResponse)
|
||||
.catch((error: Error) => handleError("greeter", error)),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Fetches all of the data by importing it (only available in development)
|
||||
*/
|
||||
export const fetchDevelopment = Promise.all([
|
||||
import("../data/apps.json"),
|
||||
import("../data/bookmarks.json"),
|
||||
import("../data/search.json"),
|
||||
import("../data/themes.json"),
|
||||
import("../data/imprint.json"),
|
||||
import("../data/greeter.json"),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Fetches app, bookmark, search, theme and imprint data and returns it.
|
||||
*/
|
||||
export const useFetcher = () => {
|
||||
const [appData, setAppData] = useState<IAppDataProps>(defaults.app);
|
||||
|
||||
const [bookmarkData, setBookmarkData] = useState<IBookmarkDataProps>(
|
||||
defaults.bookmark,
|
||||
);
|
||||
|
||||
const [searchProviderData, setSearchProviderData] =
|
||||
useState<ISearchDataProps>(defaults.search);
|
||||
|
||||
const [themeData, setThemeData] = useState<IThemeDataProps>(defaults.theme);
|
||||
|
||||
const [imprintData, setImprintData] = useState<IImprintDataProps>(
|
||||
defaults.imprint,
|
||||
);
|
||||
|
||||
const [greeterData, setGreeterData] = useState<IGreeterDataProps>(
|
||||
defaults.greeter,
|
||||
);
|
||||
|
||||
const callback = useCallback(() => {
|
||||
(inProduction ? fetchProduction : fetchDevelopment).then(
|
||||
([
|
||||
appData,
|
||||
bookmarkData,
|
||||
searchData,
|
||||
themeData,
|
||||
imprintData,
|
||||
greeterData,
|
||||
]: [
|
||||
IAppDataProps,
|
||||
IBookmarkDataProps,
|
||||
ISearchDataProps,
|
||||
IThemeDataProps,
|
||||
IImprintDataProps,
|
||||
IGreeterDataProps,
|
||||
]) => {
|
||||
setAppData(appData.error ? appData : { ...appData, error: false });
|
||||
setBookmarkData(
|
||||
bookmarkData.error ? bookmarkData : { ...bookmarkData, error: false },
|
||||
);
|
||||
setSearchProviderData(
|
||||
searchData.error ? searchData : { ...searchData, error: false },
|
||||
);
|
||||
setThemeData(
|
||||
themeData.error ? themeData : { ...themeData, error: false },
|
||||
);
|
||||
setImprintData(
|
||||
imprintData.error ? imprintData : { ...imprintData, error: false },
|
||||
);
|
||||
setGreeterData(
|
||||
greeterData.error ? greeterData : { ...greeterData, error: false },
|
||||
);
|
||||
},
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => callback(), [callback]);
|
||||
|
||||
return {
|
||||
appData,
|
||||
bookmarkData,
|
||||
searchProviderData,
|
||||
themeData,
|
||||
imprintData,
|
||||
greeterData,
|
||||
callback,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFetcher;
|
95
src/lib/useFetch.tsx
Normal file
95
src/lib/useFetch.tsx
Normal file
|
@ -0,0 +1,95 @@
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { IAppListProps } from "../components/appList";
|
||||
import { IBookmarkListProps } from "../components/bookmarks";
|
||||
import { ISearchProps } from "../components/searchBar";
|
||||
import { IThemeDataProps } from "./useTheme";
|
||||
import { IImprintProps } from "../components/imprint";
|
||||
import { IGreeterDataProps } from "../components/greeter";
|
||||
|
||||
export interface IDataProps<I> {
|
||||
response?: I;
|
||||
error?: string | boolean;
|
||||
}
|
||||
|
||||
const inProduction = process.env.NODE_ENV === "production";
|
||||
|
||||
/**
|
||||
* Handles the response from the fetch requests
|
||||
* @param {Response} response - The response given by the fetch request
|
||||
* @returns - The response in JSON
|
||||
* @throws - Error with given error message if request failed
|
||||
*/
|
||||
export const handleResponse = async (response: Response) => {
|
||||
if (!response.ok) throw new Error(response.statusText);
|
||||
return response.json();
|
||||
};
|
||||
|
||||
const fetchFile = (f: string) => {
|
||||
if (!inProduction) return require(`../data/${f}.json`);
|
||||
|
||||
return fetch(`/data/${f}.json`)
|
||||
.then(handleResponse)
|
||||
.catch((error: Error) => {
|
||||
return { error: error.message };
|
||||
});
|
||||
};
|
||||
|
||||
interface IFetchProps {
|
||||
appData: IDataProps<IAppListProps>;
|
||||
bookmarkData: IDataProps<IBookmarkListProps>;
|
||||
searchData: IDataProps<ISearchProps>;
|
||||
themeData: IDataProps<IThemeDataProps>;
|
||||
imprintData: IDataProps<IImprintProps>;
|
||||
greeterData: IDataProps<IGreeterDataProps>;
|
||||
callback?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches app, bookmark, search, theme and imprint data and returns it.
|
||||
*/
|
||||
export const useFetcher = (): IFetchProps => {
|
||||
let defaults: IDataProps<any> = { error: true };
|
||||
|
||||
const [appData, setAppData] = useState<IDataProps<IAppListProps>>(defaults);
|
||||
const [bookmarkData, setBookmarkData] =
|
||||
useState<IDataProps<IBookmarkListProps>>(defaults);
|
||||
const [searchData, setSearchData] =
|
||||
useState<IDataProps<ISearchProps>>(defaults);
|
||||
const [themeData, setThemeData] =
|
||||
useState<IDataProps<IThemeDataProps>>(defaults);
|
||||
const [imprintData, setImprintData] =
|
||||
useState<IDataProps<IImprintProps>>(defaults);
|
||||
const [greeterData, setGreeterData] =
|
||||
useState<IDataProps<IGreeterDataProps>>(defaults);
|
||||
|
||||
const callback = useCallback(() => {
|
||||
let files = ["apps", "bookmarks", "search", "themes", "imprint", "greeter"];
|
||||
|
||||
Promise.all(files.map((f) => fetchFile(f))).then(
|
||||
([apps, bookmarks, search, themes, imprint, greeter]: any) => {
|
||||
setAppData({ response: apps });
|
||||
setBookmarkData({
|
||||
response: bookmarks,
|
||||
});
|
||||
setSearchData({ response: search });
|
||||
setThemeData({ response: themes });
|
||||
setImprintData({ response: imprint });
|
||||
setGreeterData({ response: greeter });
|
||||
},
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => callback(), [callback]);
|
||||
|
||||
return {
|
||||
appData,
|
||||
bookmarkData,
|
||||
searchData,
|
||||
themeData,
|
||||
imprintData,
|
||||
greeterData,
|
||||
};
|
||||
};
|
||||
|
||||
export default useFetcher;
|
|
@ -6,6 +6,10 @@ export interface IThemeProps extends IItemProps {
|
|||
backgroundColor: string;
|
||||
}
|
||||
|
||||
export interface IThemeDataProps {
|
||||
themes: IThemeProps[];
|
||||
}
|
||||
|
||||
export const defaultTheme: IThemeProps = {
|
||||
label: "Classic",
|
||||
value: 0,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue