@@ -25,6 +25,9 @@ export class TerritoryPatternsModal extends LitElement {
2525 public previewButton : HTMLElement | null = null ;
2626
2727 @state ( ) private selectedPattern : PlayerPattern | null ;
28+ @state ( ) private selectedColor : string | null = null ;
29+
30+ @state ( ) private activeTab : "patterns" | "colors" = "patterns" ;
2831
2932 private cosmetics : Cosmetics | null = null ;
3033
@@ -44,20 +47,47 @@ export class TerritoryPatternsModal extends LitElement {
4447 if ( userMeResponse === null ) {
4548 this . userSettings . setSelectedPatternName ( undefined ) ;
4649 this . selectedPattern = null ;
50+ this . selectedColor = null ;
4751 }
4852 this . userMeResponse = userMeResponse ;
4953 this . cosmetics = await fetchCosmetics ( ) ;
5054 this . selectedPattern =
5155 this . cosmetics !== null
5256 ? this . userSettings . getSelectedPatternName ( this . cosmetics )
5357 : null ;
58+ this . selectedColor = this . userSettings . getSelectedColor ( ) ?? null ;
5459 this . refresh ( ) ;
5560 }
5661
5762 createRenderRoot ( ) {
5863 return this ;
5964 }
6065
66+ private renderTabNavigation ( ) : TemplateResult {
67+ return html `
68+ < div class ="flex border-b border-gray-600 mb-4 justify-center ">
69+ < button
70+ class ="px-4 py-2 text-sm font-medium transition-colors duration-200 ${ this
71+ . activeTab === "patterns"
72+ ? "text-blue-400 border-b-2 border-blue-400 bg-blue-400/10"
73+ : "text-gray-400 hover:text-white" } "
74+ @click =${ ( ) => ( this . activeTab = "patterns" ) }
75+ >
76+ ${ translateText ( "territory_patterns.title" ) }
77+ </ button >
78+ < button
79+ class ="px-4 py-2 text-sm font-medium transition-colors duration-200 ${ this
80+ . activeTab === "colors"
81+ ? "text-blue-400 border-b-2 border-blue-400 bg-blue-400/10"
82+ : "text-gray-400 hover:text-white" } "
83+ @click =${ ( ) => ( this . activeTab = "colors" ) }
84+ >
85+ ${ translateText ( "territory_patterns.colors" ) }
86+ </ button >
87+ </ div >
88+ ` ;
89+ }
90+
6191 private renderPatternGrid ( ) : TemplateResult {
6292 const buttons : TemplateResult [ ] = [ ] ;
6393 for ( const pattern of Object . values ( this . cosmetics ?. patterns ?? { } ) ) {
@@ -105,14 +135,39 @@ export class TerritoryPatternsModal extends LitElement {
105135 ` ;
106136 }
107137
138+ private renderColorSwatchGrid ( ) : TemplateResult {
139+ const hexCodes = ( this . userMeResponse ?. player . flares ?? [ ] )
140+ . filter ( ( flare ) => flare . startsWith ( "color:" ) )
141+ . map ( ( flare ) => "#" + flare . split ( ":" ) [ 1 ] ) ;
142+ return html `
143+ < div class ="flex flex-wrap gap-3 p-2 justify-center items-center ">
144+ ${ hexCodes . map (
145+ ( hexCode ) => html `
146+ < div
147+ class ="w-12 h-12 rounded-lg border-2 border-white/30 cursor-pointer transition-all duration-200 hover:scale-110 hover:shadow-lg "
148+ style ="background-color: ${ hexCode } ; "
149+ title ="${ hexCode } "
150+ @click =${ ( ) => this . selectColor ( hexCode ) }
151+ > </ div >
152+ ` ,
153+ ) }
154+ </ div >
155+ ` ;
156+ }
157+
108158 render ( ) {
109159 if ( ! this . isActive ) return html `` ;
110160 return html `
111161 < o-modal
112162 id ="territoryPatternsModal "
113- title ="${ translateText ( "territory_patterns.title" ) } "
163+ title ="${ this . activeTab === "patterns"
164+ ? translateText ( "territory_patterns.title" )
165+ : translateText ( "territory_patterns.colors" ) } "
114166 >
115- ${ this . renderPatternGrid ( ) }
167+ ${ this . renderTabNavigation ( ) }
168+ ${ this . activeTab === "patterns"
169+ ? this . renderPatternGrid ( )
170+ : this . renderColorSwatchGrid ( ) }
116171 </ o-modal >
117172 ` ;
118173 }
@@ -130,6 +185,8 @@ export class TerritoryPatternsModal extends LitElement {
130185 }
131186
132187 private selectPattern ( pattern : PlayerPattern | null ) {
188+ this . selectedColor = null ;
189+ this . userSettings . setSelectedColor ( undefined ) ;
133190 if ( pattern === null ) {
134191 this . userSettings . setSelectedPatternName ( undefined ) ;
135192 } else {
@@ -145,8 +202,32 @@ export class TerritoryPatternsModal extends LitElement {
145202 this . close ( ) ;
146203 }
147204
205+ private selectColor ( hexCode : string ) {
206+ this . selectedPattern = null ;
207+ this . userSettings . setSelectedPatternName ( undefined ) ;
208+ this . selectedColor = hexCode ;
209+ this . userSettings . setSelectedColor ( hexCode ) ;
210+ this . refresh ( ) ;
211+ this . close ( ) ;
212+ }
213+
214+ private renderColorPreview (
215+ hexCode : string ,
216+ width : number ,
217+ height : number ,
218+ ) : TemplateResult {
219+ return html `
220+ < div
221+ class ="rounded "
222+ style ="width: ${ width } px; height: ${ height } px; background-color: ${ hexCode } ; "
223+ > </ div >
224+ ` ;
225+ }
226+
148227 public async refresh ( ) {
149- const preview = renderPatternPreview ( this . selectedPattern ?? null , 48 , 48 ) ;
228+ const preview = this . selectedColor
229+ ? this . renderColorPreview ( this . selectedColor , 48 , 48 )
230+ : renderPatternPreview ( this . selectedPattern ?? null , 48 , 48 ) ;
150231 this . requestUpdate ( ) ;
151232
152233 // Wait for the DOM to be updated and the o-modal element to be available
0 commit comments