2021-03-23 17:54:30 +03:00
|
|
|
import * as React from "react";
|
2021-03-24 20:55:12 +03:00
|
|
|
import * as Events from "~/common/custom-events";
|
2021-03-23 17:54:30 +03:00
|
|
|
|
|
|
|
export const useFont = ({ url, name }, deps) => {
|
|
|
|
const [loading, setLoading] = React.useState(false);
|
|
|
|
const prevName = React.useRef(name);
|
|
|
|
|
|
|
|
if (!window.$SLATES_LOADED_FONTS) window.$SLATES_LOADED_FONTS = [];
|
|
|
|
const alreadyLoaded = window.$SLATES_LOADED_FONTS.includes(name);
|
|
|
|
|
|
|
|
React.useEffect(() => {
|
|
|
|
if (alreadyLoaded) return;
|
|
|
|
|
|
|
|
setLoading(true);
|
|
|
|
const customFonts = new FontFace(name, `url(${url})`);
|
|
|
|
customFonts.load().then((loadedFont) => {
|
|
|
|
document.fonts.add(loadedFont);
|
2021-03-24 20:55:12 +03:00
|
|
|
prevName.current = name;
|
2021-03-23 17:54:30 +03:00
|
|
|
setLoading(false);
|
2021-03-24 20:55:12 +03:00
|
|
|
|
2021-03-23 17:54:30 +03:00
|
|
|
window.$SLATES_LOADED_FONTS.push(name);
|
|
|
|
});
|
|
|
|
}, deps);
|
2021-03-24 20:55:12 +03:00
|
|
|
|
|
|
|
return { isFontLoading: loading, fontName: alreadyLoaded ? name : prevName.current };
|
2021-03-23 17:54:30 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
const initialState = {
|
|
|
|
context: {
|
|
|
|
darkmode: true,
|
|
|
|
showSettings: true,
|
|
|
|
settings: {
|
|
|
|
valign: "center",
|
|
|
|
textAlign: "left",
|
|
|
|
fontSize: 24,
|
|
|
|
column: 1,
|
2021-03-24 20:55:12 +03:00
|
|
|
lineHeight: 100,
|
2021-03-23 17:54:30 +03:00
|
|
|
tracking: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
view: "paragraph",
|
|
|
|
};
|
|
|
|
|
|
|
|
const reducer = (state, action) => {
|
2021-03-24 20:55:12 +03:00
|
|
|
const updateSettingsField = (field, newValue) => ({
|
|
|
|
...state,
|
|
|
|
context: {
|
|
|
|
...state.context,
|
|
|
|
settings: { ...state.context.settings, [field]: newValue },
|
|
|
|
},
|
|
|
|
});
|
2021-03-23 17:54:30 +03:00
|
|
|
switch (action.type) {
|
|
|
|
case "SET_DARK_MODE":
|
|
|
|
return { ...state, context: { ...state.context, darkmode: true } };
|
|
|
|
case "SET_LIGHT_MODE":
|
|
|
|
return { ...state, context: { ...state.context, darkmode: false } };
|
|
|
|
case "TOGGLE_SETTINGS_VISIBILITY":
|
|
|
|
return { ...state, context: { ...state.context, showSettings: !state.context.showSettings } };
|
2021-03-24 20:55:12 +03:00
|
|
|
case "UPDATE_FONT_SIZE":
|
|
|
|
return updateSettingsField("fontSize", action.value);
|
|
|
|
case "UPDATE_LINE_HEIGHT":
|
|
|
|
return updateSettingsField("lineHeight", action.value);
|
|
|
|
case "UPDATE_TRACKING":
|
|
|
|
return updateSettingsField("tracking", action.value);
|
|
|
|
case "UPDATE_COLUMN":
|
|
|
|
return updateSettingsField("column", action.value);
|
|
|
|
case "UPDATE_TEXT_ALIGN":
|
|
|
|
return updateSettingsField("textAlign", action.value);
|
|
|
|
case "UPDATE_VERTICAL_ALIGN":
|
|
|
|
return updateSettingsField("valign", action.value);
|
2021-03-23 17:54:30 +03:00
|
|
|
default:
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const useFontControls = () => {
|
|
|
|
const [current, send] = React.useReducer(reducer, initialState);
|
2021-03-24 20:55:12 +03:00
|
|
|
const handleDarkMode = (state) =>
|
|
|
|
Events.dispatchCustomEvent({
|
|
|
|
name: "set-slate-theme",
|
|
|
|
detail: { fontPreviewDarkMode: state },
|
|
|
|
});
|
|
|
|
const handlers = React.useMemo(() => ({
|
|
|
|
setDarkMode: () => handleDarkMode(true),
|
|
|
|
setLightMode: () => handleDarkMode(false),
|
|
|
|
toggleSettings: () => send({ type: "TOGGLE_SETTINGS_VISIBILITY" }),
|
|
|
|
updateFontSize: (v) => send({ type: "UPDATE_FONT_SIZE", value: v }),
|
|
|
|
updateLineHeight: (v) => send({ type: "UPDATE_LINE_HEIGHT", value: v }),
|
|
|
|
updateTracking: (v) => send({ type: "UPDATE_TRACKING", value: v }),
|
|
|
|
updateColumn: (v) => send({ type: "UPDATE_COLUMN", value: v }),
|
|
|
|
updateTextAlign: (v) => send({ type: "UPDATE_TEXT_ALIGN", value: v }),
|
|
|
|
updateVerticalAlign: (v) => send({ type: "UPDATE_VERTICAL_ALIGN", value: v }),
|
|
|
|
}));
|
2021-03-23 17:54:30 +03:00
|
|
|
return [current, handlers];
|
|
|
|
};
|