Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/app/context.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2023 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { theme, ThemeConfig } from "antd";6import type { SizeType } from "antd/es/config-provider/SizeContext";7import { debounce } from "lodash";8import { createContext, ReactNode, useContext } from "react";9import { useIntl } from "react-intl";1011import {12CSS,13useEffect,14useMemo,15useState,16useTypedRedux,17} from "@cocalc/frontend/app-framework";18import { COLORS } from "@cocalc/util/theme";19import { IntlMessage, isIntlMessage } from "@cocalc/frontend/i18n";20import {21FONT_SIZE_ICONS_NARROW,22FONT_SIZE_ICONS_NORMAL,23NARROW_THRESHOLD_PX,24NAV_HEIGHT_NARROW_PX,25NAV_HEIGHT_PX,26PageStyle,27} from "./top-nav-consts";2829export interface AppState {30pageWidthPx: number;31pageStyle: PageStyle;32antdComponentSize?: SizeType;33antdTheme?: ThemeConfig;34formatIntl: (msg: IntlMessage | ReactNode | string) => ReactNode | string;35}3637export const AppContext = createContext<AppState>({38pageWidthPx: window.innerWidth,39pageStyle: calcStyle(isNarrow()),40formatIntl: () => "Loading…",41});4243export function useAppContext() {44return useContext(AppContext);45}4647export function useAppContextProvider() {48const intl = useIntl();4950const [pageWidthPx, setPageWidthPx] = useState<number>(window.innerWidth);5152const [narrow, setNarrow] = useState<boolean>(isNarrow());5354function update() {55setNarrow(isNarrow());56if (window.innerWidth != pageWidthPx) {57setPageWidthPx(window.innerWidth);58}59}6061useEffect(() => {62const handleResize = debounce(update, 50, {63leading: false,64trailing: true,65});6667window.addEventListener("resize", handleResize);68return () => window.removeEventListener("resize", handleResize);69}, []);7071// avoid updating the style on every resize event72const pageStyle: PageStyle = useMemo(() => {73return calcStyle(narrow);74}, [narrow]);7576function formatIntl(77msg: IntlMessage | ReactNode | string,78): ReactNode | string {79if (isIntlMessage(msg)) {80return intl.formatMessage(msg);81} else {82return msg;83}84}8586return {87formatIntl,88pageWidthPx,89pageStyle,90};91}9293export function useAntdStyleProvider() {94const other_settings = useTypedRedux("account", "other_settings");95const rounded = other_settings?.get("antd_rounded", true);96const animate = other_settings?.get("antd_animate", true);97const branded = other_settings?.get("antd_brandcolors", false);98const compact = other_settings?.get("antd_compact", false);99100const borderStyle = rounded101? undefined102: { borderRadius: 0, borderRadiusLG: 0, borderRadiusSM: 0 };103104const animationStyle = animate ? undefined : { motion: false };105106const brandedColors = branded107? { colorPrimary: COLORS.COCALC_BLUE }108: undefined;109110const algorithm = compact ? { algorithm: theme.compactAlgorithm } : undefined;111112const antdTheme: ThemeConfig = {113...algorithm,114token: {115...brandedColors,116...borderStyle,117...animationStyle,118},119components: {120Button: {121...brandedColors,122},123},124};125126return {127antdTheme,128};129}130131function isNarrow(): boolean {132return window.innerWidth != null && window.innerWidth <= NARROW_THRESHOLD_PX;133}134135function calcStyle(isNarrow: boolean): PageStyle {136const fontSizeIcons: string = isNarrow137? FONT_SIZE_ICONS_NARROW138: FONT_SIZE_ICONS_NORMAL;139const topPaddingIcons: string = isNarrow ? "2px" : "5px";140const sidePaddingIcons: string = isNarrow ? "7px" : "14px";141142const height = isNarrow ? NAV_HEIGHT_NARROW_PX : NAV_HEIGHT_PX;143144const topBarStyle: CSS = {145height: `${height}px`,146} as const;147148const fileUseStyle: CSS = {149background: "white",150border: `2px solid ${COLORS.GRAY_DDD}`,151borderRadius: "5px",152boxShadow: "0 0 15px #aaa",153fontSize: "10pt",154height: "90%",155margin: 0,156overflowX: "hidden",157overflowY: "auto",158padding: "4px",159position: "fixed",160right: "5vw",161top: `${height}px`,162width: isNarrow ? "90vw" : "50vw",163zIndex: 110,164} as const;165166const projectsNavStyle: CSS | undefined = isNarrow167? {168/* this makes it so the projects tabs are on a separate row; otherwise, there is literally no room for them at all... */169width: "100vw",170marginTop: "4px",171height: `${height}px`,172// no flex!173}174: {175flex: "1 1 auto", // necessary to stretch out to the full width176};177178return {179topBarStyle,180fileUseStyle,181projectsNavStyle,182isNarrow,183sidePaddingIcons,184topPaddingIcons,185fontSizeIcons,186height,187};188}189190191