theme-context.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { createContext, useContext } from 'use-context-selector'
  2. import { hexToRGBA } from './utils'
  3. export class Theme {
  4. public chatColorTheme: string | null
  5. public chatColorThemeInverted: boolean
  6. public primaryColor = '#1C64F2'
  7. public backgroundHeaderColorStyle = 'backgroundImage: linear-gradient(to right, #2563eb, #0ea5e9)'
  8. public headerBorderBottomStyle = ''
  9. public colorFontOnHeaderStyle = 'color: white'
  10. public colorPathOnHeader = 'text-text-primary-on-surface'
  11. public backgroundButtonDefaultColorStyle = 'backgroundColor: #1C64F2'
  12. public roundedBackgroundColorStyle = 'backgroundColor: rgb(245 248 255)'
  13. public chatBubbleColorStyle = 'backgroundColor: rgb(225 239 254)'
  14. public chatBubbleColor = 'rgb(225 239 254)'
  15. constructor(chatColorTheme: string | null = null, chatColorThemeInverted = false) {
  16. this.chatColorTheme = chatColorTheme
  17. this.chatColorThemeInverted = chatColorThemeInverted
  18. this.configCustomColor()
  19. this.configInvertedColor()
  20. }
  21. private configCustomColor() {
  22. if (this.chatColorTheme !== null && this.chatColorTheme !== '') {
  23. this.primaryColor = this.chatColorTheme ?? '#1C64F2'
  24. this.backgroundHeaderColorStyle = `backgroundColor: ${this.primaryColor}`
  25. this.backgroundButtonDefaultColorStyle = `backgroundColor: ${this.primaryColor}; color: ${this.colorFontOnHeaderStyle};`
  26. this.roundedBackgroundColorStyle = `backgroundColor: ${hexToRGBA(this.primaryColor, 0.05)}`
  27. this.chatBubbleColorStyle = `backgroundColor: ${hexToRGBA(this.primaryColor, 0.15)}`
  28. this.chatBubbleColor = `${hexToRGBA(this.primaryColor, 0.15)}`
  29. }
  30. }
  31. private configInvertedColor() {
  32. if (this.chatColorThemeInverted) {
  33. this.backgroundHeaderColorStyle = 'backgroundColor: #ffffff'
  34. this.colorFontOnHeaderStyle = `color: ${this.primaryColor}`
  35. this.headerBorderBottomStyle = 'borderBottom: 1px solid #ccc'
  36. this.colorPathOnHeader = this.primaryColor
  37. }
  38. }
  39. }
  40. export class ThemeBuilder {
  41. private _theme?: Theme
  42. private buildChecker = false
  43. public get theme() {
  44. if (this._theme === undefined) {
  45. this._theme = new Theme()
  46. return this._theme
  47. }
  48. else {
  49. return this._theme
  50. }
  51. }
  52. public buildTheme(chatColorTheme: string | null = null, chatColorThemeInverted = false) {
  53. if (!this.buildChecker) {
  54. this._theme = new Theme(chatColorTheme, chatColorThemeInverted)
  55. this.buildChecker = true
  56. }
  57. else {
  58. if (this.theme?.chatColorTheme !== chatColorTheme || this.theme?.chatColorThemeInverted !== chatColorThemeInverted) {
  59. this._theme = new Theme(chatColorTheme, chatColorThemeInverted)
  60. this.buildChecker = true
  61. }
  62. }
  63. }
  64. }
  65. const ThemeContext = createContext<ThemeBuilder>(new ThemeBuilder())
  66. export const useThemeContext = () => useContext(ThemeContext)