import { Injectable } from '@angular/core' ; import { Theme } from 'ng-devui/theme' ; import { ReplaySubject } from 'rxjs' ; import { ThemeType } from 'src/app/@shared/models/theme' ; import { LARGE_RADIUS , LARGE_SIZE , MEDIUM_RADIUS , MEDIUM_SIZE , NORMAL_RADIUS , NORMAL_SIZE } from 'src/config/custom-theme' ; import { CustomThemeService } from './custom-theme.service' ; export interface ThemeConfigItem { name : string ; id : string ; data : { 'devui-border-radius' ? : string ; 'devui-border-radius-card' ? : string ; 'devui-font-size' ? : string ; 'devui-font-size-card-title' ? : string ; 'devui-font-size-page-title' ? : string ; 'devui-font-size-modal-title' ? : string ; 'devui-font-size-price' ? : string ; 'devui-font-size-data-overview' ? : string ; 'devui-font-size-icon' ? : string ; 'devui-font-size-sm' ? : string ; 'devui-font-size-md' ? : string ; 'devui-font-size-lg' ? : string ; } ; } export interface ThemeConfig { name : 'themes' | 'font' | 'radius' ; icon : string ; items : ThemeConfigItem [ ] ; } @ Injectable ( ) export class PersonalizeService { themes : ThemeConfigItem [ ] = [ ] ; private _themeChange = new ReplaySubject < any > ( 1 ) ; configs : ThemeConfig [ ] = [ { name : 'themes' , icon : 'icon-color' , items : [ ] , } , { name : 'font' , icon : 'icon-font' , items : [ { name : 'normal' , id : 'normal' , data : NORMAL_SIZE , } , { name : 'medium' , id : 'medium' , data : MEDIUM_SIZE , } , { name : 'large' , id : 'large' , data : LARGE_SIZE , } , ] , } , { name : 'radius' , icon : 'icon-quick-stop' , items : [ { name : 'normal' , id : 'normal' , data : NORMAL_RADIUS , } , { name : 'medium' , id : 'medium' , data : MEDIUM_RADIUS , } , { name : 'large' , id : 'large' , data : LARGE_RADIUS , } , ] , } , ] ; defaultCustom = { brand : '#343a40' , isDark : false , } ; constructor ( private customThemeService ) { } initTheme ( ) { if ( ( window as { [ key ] : any ; } ) [ 'devuiThemes' ] ) { ( window as { [ key ] : any ; } ) [ 'devuiThemes' ] . devuiDarkTheme . data [ 'devui-placeholder' ] = '#8A8A8A' ; this . themes = Object . values ( ( window as { [ key ] : any ; } ) [ 'devuiThemes' ] ) ; const { brand , isDark } = localStorage . getItem ( 'user-custom-theme-config' ) ? JSON . parse ( localStorage . getItem ( 'user-custom-theme-config' ) ! ) : this . defaultCustom ; const themeData = this . getCustomThemeData ( brand , isDark ) ; this . setTheme ( ( window as { [ key ] : any ; } ) [ 'devuiThemes' ] [ 'customTheme' ] , themeData , isDark ) ; this . configs [ 0 ] . items = this . themes ; const themeId = localStorage . getItem ( 'theme' ) || this . themes [ 0 ] . id ; const fontId = localStorage . getItem ( 'font' ) || this . configs [ 1 ] . items [ 0 ] . id ; const radiusId = localStorage . getItem ( 'radius' ) || this . configs [ 2 ] . items [ 0 ] . id ; this . changeTheme ( themeId , fontId , radiusId ) ; } } changeTheme ( themeId , fId ? , rId ? ) { let theme ; const themes = ( this . configs [ 0 ] . items as any ) . filter ( ( i ) => { return i . id === themeId ; } ) ; const { radiusId , fontId , fontData , radiusData } = this . getSizeAndRadiusData ( fId , rId ) ; const customData = Object . assign ( { } , fontData , radiusData ) ; if ( themes . length ) { theme = themes [ 0 ] ; } else { theme = this . configs [ 0 ] . items [ 0 ] ; } theme . data = Object . assign ( theme . data , customData ) ; ( window as { [ key ] : any ; } ) [ 'devuiThemeService' ] . applyTheme ( theme ) ; localStorage . setItem ( 'theme' , theme . id ) ; localStorage . setItem ( 'font' , fontId ) ; localStorage . setItem ( 'radius' , radiusId ) ; } getCustomThemeData ( color , isDark ) { const themeData = this . customThemeService . genThemeData ( [ { colorName : 'devui-brand' , color : color , } , ] , isDark , 'hsl' ) ; return themeData ; } setTheme ( theme , themeData , isDark ) { Object . assign ( theme , { data : themeData , isDark , } ) ; } getSizeAndRadiusData ( fId ? , rId ? ) { const fontId = fId || localStorage . getItem ( 'font' ) || this . configs [ 1 ] . items [ 0 ] . id ; const radiusId = rId || localStorage . getItem ( 'radius' ) || this . configs [ 2 ] . items [ 0 ] . id ; const fonts = ( this . configs [ 1 ] . items as any ) . filter ( ( font ) => { return font . id === fontId ; } ) ; const radiusList = ( this . configs [ 2 ] . items as any ) . filter ( ( radius ) => { return radius . id === radiusId ; } ) ; return { fontId , radiusId , fontData : fonts [ 0 ] . data , radiusData : radiusList [ 0 ] . data , } ; } setCustomThemeData ( themeData , color , isDark ) { const len = this . configs [ 0 ] . items . length ; const theme = this . configs [ 0 ] . items [ len - 1 ] ; const { fontData , radiusData } = this . getSizeAndRadiusData ( ) ; Object . assign ( themeData , fontData , radiusData ) ; this . setTheme ( theme , color , isDark ) ; theme . data = Object . assign ( theme . data , themeData ) ; ( window as { [ key ] : any ; } ) [ 'devuiThemeService' ] . applyTheme ( theme ) ; localStorage . setItem ( 'user-custom-theme-config' , JSON . stringify ( { brand : color , isDark } ) ) ; localStorage . setItem ( 'theme' , ThemeType . Custom ) ; } setUiTheme ( ) { const currentTheme = ( window as { [ key ] : any ; } ) [ 'devuiCurrentTheme' ] || ThemeType . Default ; this . _themeChange . next ( currentTheme ) ; } getUiTheme ( ) { const themeService = ( window as { [ key ] : any ; } ) [ 'devuiThemeService' ] ; this . setUiTheme ( ) ; if ( ! ( themeService && themeService . eventBus ) ) { return ; } const themeChangedFunc = ( ) => { this . setUiTheme ( ) ; } ; themeService . eventBus . add ( 'themeChanged' , themeChangedFunc ) ; return this . _themeChange . asObservable ( ) ; } setRefTheme ( themeId ) { const devuiThemes = Object . values ( ( window as { [ key ] : any ; } ) [ 'devuiThemes' ] ) ; const themes = devuiThemes . filter ( ( i ) => ( i as Theme ) . id === themeId ) ; if ( themes . length ) { ( window as { [ key ] : any ; } ) [ 'devuiThemeService' ] . applyTheme ( themes [ 0 ] ) ; } } }