import * as React from "react"; import {reduxTools} from "@yoronsoft/js-utils"; import {ColorValue, Dimensions, NativeModules, Platform, StatusBar} from "react-native"; import storage from "../storage"; import emitter from "../emitter"; import { ITheme, IThemeDefaultCss, ThemeApp, ThemeColor, ThemeCss, ThemeFlexCssData, ThemeFlexDirection, ThemeFont, ThemeHeader, ThemeJustifyContent, ThemeLoading, ThemeModal, ThemeNav, ThemePopup } from "./theme"; import {getConfigName, loggerConfig} from "../config"; const themeType = `${getConfigName}_theme_type`; const themeValue = `${getConfigName}_theme_value`; const themeData = `${getConfigName}_theme_data`; const themeSelectType = `${getConfigName}_theme_selectType`; const logger = loggerConfig('theme'); const theme: ITheme = { init: function (all: { [key: string]: object }, defaultSelect: string): void { reduxTools.create(themeType, defaultSelect); reduxTools.create(themeValue, all[defaultSelect]); storage.get(themeType).then(res => { if (res) { logger.log(`当前缓存主题:${res}`); this.set(all, res); } }); }, getType: function (): string { return reduxTools.get(themeType); }, get: function (): T { return reduxTools.get(themeValue) as T; }, set: function (all: { [key: string]: object }, select: string): void { reduxTools.update(themeType, select); reduxTools.update(themeValue, all[select]); storage.set(themeType, select); emitter.set(themeData, true); emitter.set(themeSelectType, true); }, useGet: function (): T { const [data, setData] = React.useState(theme.get()); React.useEffect(() => { const emitterData = emitter.get(themeData, () => setData(theme.get())); return () => emitterData.remove(); }, []); return data as T; }, useGetType: function (): string { const [data, setData] = React.useState(theme.getType()); React.useEffect(() => { const emitterData = emitter.get(themeSelectType, () => setData(theme.getType())); return () => emitterData.remove(); }, []); return data; } }; const themeCss: IThemeDefaultCss = { get: function (mainColor?: ColorValue): ThemeCss { mainColor = mainColor ?? "#fff"; const window = Dimensions.get("window"); const screen = Dimensions.get("screen"); const {StatusBarManager} = NativeModules; window.scale; window.fontScale; const app: ThemeApp = { width: window.width, height: window.height, scale: window.scale, fontScale: window.fontScale, screenWidth: screen.width, screenHeight: screen.height, screenFontScale: screen.fontScale, screenScale: screen.scale, barHeight: StatusBar.currentHeight ?? 48, footerHeight: screen.height - window.height, main: mainColor, barBg: "#fff", bg: "#fff", leftIconColor: "#000", mask: "rgba(0,0,0,.2)", line: "#d5d5d5" }; const font: ThemeFont = {color: "#666", size: 14, white: '#fff', black: '#000'}; const nav: ThemeNav = {bg: "#fff", color: "#808080", height: 55, selectColor: "#000"}; const header: ThemeHeader = {bg: "#fff", color: "#666", height: 50, line: app.line, size: 16}; const loading: ThemeLoading = { width: 150, height: 155, mask: app.mask, bg: "rgba(0,0,0,.3)", borderRadius: 15, color: "#fff" }; const modal: ThemeModal = { width: 250, minHeight: 200, mask: app.mask, bg: "#fff", borderRadius: 15, color: "#666" } const popup: ThemePopup = {bg: "#fff", mask: app.mask, cancelColor: '#fff'}; const color: ThemeColor = {black: "#000", white: "#fff"}; const css: ThemeCss = { main: app.main, width: app.width, height: app.height, app: app, rowBetween: _setFlexCss("row", "between"), rowBetweenCenter: _setFlexCss("row", "between", true), rowStart: _setFlexCss("row", "start", false, true), rowStartCenter: _setFlexCss("row", "start", true), rowAround: _setFlexCss("row", "around"), rowAroundCenter: _setFlexCss("row", "around", true), rowEnd: _setFlexCss("row", "end"), rowEndCenter: _setFlexCss("row", "end", true), colBetween: _setFlexCss("col", "between"), colBetweenCenter: _setFlexCss("col", "between", true), colStart: _setFlexCss("col", "start"), colStartCenter: _setFlexCss("col", "start", true), colAround: _setFlexCss("col", "around"), colAroundCenter: _setFlexCss("col", "around", true), colEnd: _setFlexCss("col", "end"), colEndCenter: _setFlexCss("col", "end", true), colCenter: { ..._setFlexCss("row", "around", true), ..._setFlexCss("col", "around", true) }, rowCenter: { ..._setFlexCss("row", "around", true), ..._setFlexCss("col", "around", true) }, nav: nav, header: header, loading: loading, modal: modal, popup: popup, font: font, color: color }; if (Platform.OS === "ios" && typeof StatusBarManager.getHeight === "function") StatusBarManager.getHeight((res: any) => css.app.barHeight = res.height); return css; } }; const _setFlexCss = function (direction: string, justifyContent: string, isAlign?: boolean, wrap?: boolean): ThemeFlexCssData { let directionValue: ThemeFlexDirection = "row", justifyContentValue: ThemeJustifyContent = "space-around"; if (direction === "row") directionValue = "row"; else if (direction === "col") directionValue = "column"; if (justifyContent === "between") justifyContentValue = "space-between"; else if (justifyContent === "start") justifyContentValue = "flex-start"; else if (justifyContent === "around") justifyContentValue = "space-around"; else if (justifyContent === "end") justifyContentValue = "flex-end"; let style: ThemeFlexCssData = {flexDirection: directionValue, justifyContent: justifyContentValue}; if (isAlign) style.alignItems = 'center'; if (wrap) style.flexWrap = "wrap"; return style; }; export default theme export { themeCss }; export type { ITheme, IThemeDefaultCss, ThemeApp, ThemeColor, ThemeCss, ThemeFont, ThemeHeader, ThemeLoading, ThemeNav, ThemePopup };