UNPKG

@react-native-ohos/react-native-unistyles

Version:
189 lines (162 loc) 6.18 kB
/* * Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved * Use of this source code is governed by a MIT license that can be * found in the LICENSE file. */ import common from '@ohos.app.ability.common'; import { UnistylesInsets,Insets } from './Insets'; import { ConfigurationConstant } from '@kit.AbilityKit'; import { i18n } from '@kit.LocalizationKit'; import display from '@ohos.display'; import { DisplayMetrics, PhysicalPixels, TurboModuleContext } from '@rnoh/react-native-openharmony/ts'; export class UnistylesConfig{ private context: common.UIAbilityContext private ctx :TurboModuleContext constructor(context: common.UIAbilityContext,ctx :TurboModuleContext) { this.context = context; this.ctx = ctx; this.windowPhysicalPixels = this.ctx.getDisplayMetrics().windowPhysicalPixels; this.insets = new UnistylesInsets(this.context,ctx.safeAreaInsetsProvider.safeAreaInsets,this.windowPhysicalPixels.scale); this.lastLayoutConfig = this.getAppLayoutConfig(); this.lastConfig = this.getAppConfig() } private windowPhysicalPixels: PhysicalPixels; private insets: UnistylesInsets; private lastConfig: Config; private lastLayoutConfig: LayoutConfig; hasNewConfig(): Boolean { let newConfig = this.getAppConfig() let newContentSizeCategory = newConfig.contentSizeCategory != this.lastConfig.contentSizeCategory let newColorScheme = newConfig.colorScheme != this.lastConfig.colorScheme let newPixelRatio = newConfig.pixelRatio != this.lastConfig.pixelRatio let newFontScale = newConfig.fontScale != this.lastConfig.fontScale let newRtl = newConfig.rtl != this.lastConfig.rtl if (!newContentSizeCategory && !newColorScheme && !newPixelRatio && !newFontScale && !newRtl) { return false } this.lastConfig = newConfig return true } hasNewLayoutConfig() { let newConfig = this.getAppLayoutConfig() if (newConfig == this.lastLayoutConfig) { return false } this.lastLayoutConfig = newConfig return true } getConfig(): Config { return this.lastConfig } getLayoutConfig(): LayoutConfig { return this.lastLayoutConfig } private getAppConfig(): Config { return new Config( this.getColorScheme(), UnistylesConfig.getContentSizeCategory(display.getDefaultDisplaySync().scaledDensity), display.getDefaultDisplaySync().densityPixels, display.getDefaultDisplaySync().scaledDensity, i18n.isRTL(i18n.System.getSystemLanguage()) ) } private getAppLayoutConfig() { let screenWidth = (this.windowPhysicalPixels.width/this.windowPhysicalPixels.scale ) let screenHeight = (this.windowPhysicalPixels.height/this.windowPhysicalPixels.scale ) return new LayoutConfig( new Dimensions(screenWidth, screenHeight), this.insets.get(), new Dimensions(screenWidth, this.getStatusBarHeight()), new Dimensions(screenWidth, this.getNavigationBarHeight()) ) } public static getContentSizeCategory(fontScale: number): string { let contentSizeCategory:string; if(fontScale <= 0){ contentSizeCategory = "Unspecified"; }else if(fontScale <= 1){ contentSizeCategory = "ExtraSmall"; }else if(fontScale <= 2){ contentSizeCategory = "Small"; }else if(fontScale <= 3){ contentSizeCategory = "Medium"; }else if(fontScale <= 4){ contentSizeCategory = "Large"; }else if(fontScale <= 5){ contentSizeCategory = "ExtraLarge"; }else if(fontScale <= 6){ contentSizeCategory = "ExtraExtraLarge"; }else if(fontScale <= 7){ contentSizeCategory = "ExtraExtraExtraLarge"; }else if(fontScale <= 8){ contentSizeCategory = "AccessibilityMedium"; }else if(fontScale <= 9){ contentSizeCategory = "AccessibilityLarge"; }else if(fontScale <= 0){ contentSizeCategory = "AccessibilityExtraLarge"; }else if(fontScale <= 11){ contentSizeCategory = "AccessibilityExtraExtraLarge"; }else { contentSizeCategory = "AccessibilityExtraExtraExtraLarge"; } return contentSizeCategory } private getColorScheme(): string { switch (this.context.config.colorMode){ case ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET: return "unspecified"; case ConfigurationConstant.ColorMode.COLOR_MODE_DARK: return "dark"; case ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT: return "light"; default: return "unspecified"; } } private getStatusBarHeight() { let height:number = 0; height = this.ctx.safeAreaInsetsProvider.safeAreaInsets.top/this.ctx.getDisplayMetrics().screenPhysicalPixels.scale; return height; } private getNavigationBarHeight(){ let height:number = 0; height = this.ctx.safeAreaInsetsProvider.safeAreaInsets.bottom/this.ctx.getDisplayMetrics().screenPhysicalPixels.scale; return height; } } export class LayoutConfig{ screen:Dimensions; insets:Insets; statusBar:Dimensions; navigationBar:Dimensions; constructor(screen: Dimensions, insets: Insets, statusBar: Dimensions, navigationBar: Dimensions) { this.screen = screen; this.insets = insets; this.statusBar = statusBar; this.navigationBar = navigationBar; } isEqual(screen:Dimensions,insets:Insets, statusBar:Dimensions, navigationBar:Dimensions):boolean{ return this.screen.isEqual(screen) && this.insets.isEqual(insets) && this.statusBar.isEqual(statusBar) && this.navigationBar.isEqual(navigationBar) } } export class Dimensions{ width:number; height:number; constructor(width: number, height: number) { this.width = width; this.height = height; } isEqual(b:Dimensions){ return this.width == b.width && this.height == b.height; } } export class Config{ colorScheme:string; contentSizeCategory:string; pixelRatio:number; fontScale:number; rtl:boolean constructor(colorScheme:string,contentSizeCategory:string,pixelRatio:number,fontScale:number,rtl:boolean) { this.colorScheme = colorScheme; this.contentSizeCategory = contentSizeCategory; this.pixelRatio = pixelRatio; this.fontScale = fontScale; this.rtl = rtl; } }