@@ -25,11 +25,24 @@ namespace FirebaseAdmin.Messaging
2525 /// </summary>
2626 public sealed class LightSettings
2727 {
28+ private LightSettingsColor lightColor = new LightSettingsColor ( ) ;
29+
2830 /// <summary>
29- /// Gets or sets the lightSettingsColor value in the light settings.
31+ /// Gets or sets the color value of the light settings.
3032 /// </summary>
3133 [ JsonIgnore ]
32- public LightSettingsColor Color { get ; set ; }
34+ public string Color
35+ {
36+ get
37+ {
38+ return this . lightColor . ColorString ( ) ;
39+ }
40+
41+ set
42+ {
43+ this . lightColor = LightSettingsColor . FromString ( value ) ;
44+ }
45+ }
3346
3447 /// <summary>
3548 /// Gets or sets the light on duration in milliseconds.
@@ -44,45 +57,19 @@ public sealed class LightSettings
4457 public long LightOffDurationMillis { get ; set ; }
4558
4659 /// <summary>
47- /// Gets or sets a string representation of <see cref="LightSettingsColor"/> .
60+ /// Gets or sets the light settings color representation as accepted by the FCM backend service .
4861 /// </summary>
4962 [ JsonProperty ( "color" ) ]
50- private string LightSettingsColorString
63+ private LightSettingsColor LightColor
5164 {
5265 get
5366 {
54- var colorStringBuilder = new StringBuilder ( ) ;
55-
56- colorStringBuilder
57- . Append ( "#" )
58- . Append ( Convert . ToInt32 ( this . Color . Red * 255 ) . ToString ( "X" ) )
59- . Append ( Convert . ToInt32 ( this . Color . Green * 255 ) . ToString ( "X" ) )
60- . Append ( Convert . ToInt32 ( this . Color . Blue * 255 ) . ToString ( "X" ) ) ;
61-
62- return colorStringBuilder . ToString ( ) ;
67+ return this . lightColor ;
6368 }
6469
6570 set
6671 {
67- var pattern = new Regex ( "^#[0-9a-fA-F]{6}$" ) ;
68-
69- if ( string . IsNullOrEmpty ( value ) )
70- {
71- throw new ArgumentException ( "Invalid LightSettingsColor. LightSettingsColor annot be null or empty" ) ;
72- }
73-
74- if ( ! pattern . IsMatch ( value ) )
75- {
76- throw new ArgumentException ( $ "Invalid LightSettingsColor { value } . LightSettingsColor must be in the form #RRGGBB") ;
77- }
78-
79- this . Color = new LightSettingsColor
80- {
81- Red = Convert . ToInt32 ( value . Substring ( 1 , 2 ) , 16 ) / 255.0f ,
82- Green = Convert . ToInt32 ( value . Substring ( 3 , 2 ) , 16 ) / 255.0f ,
83- Blue = Convert . ToInt32 ( value . Substring ( 5 , 2 ) , 16 ) / 255.0f ,
84- Alpha = 1.0f ,
85- } ;
72+ this . lightColor = value ;
8673 }
8774 }
8875
@@ -119,5 +106,89 @@ private string LightOffDurationMillisString
119106 this . LightOffDurationMillis = TimeConverter . StringToLongMillis ( value ) ;
120107 }
121108 }
109+
110+ /// <summary>
111+ /// Copies this Light Settings, and validates the content of it to ensure that it can be
112+ /// serialized into the JSON format expected by the FCM service.
113+ /// </summary>
114+ internal LightSettings CopyAndValidate ( )
115+ {
116+ // Copy and validate the leaf-level properties
117+ var copy = new LightSettings ( )
118+ {
119+ Color = this . Color ,
120+ LightOnDurationMillis = this . LightOnDurationMillis ,
121+ LightOffDurationMillis = this . LightOffDurationMillis ,
122+ } ;
123+
124+ return copy ;
125+ }
126+
127+ /// <summary>
128+ /// The LightSettings Color object as expected by the FCM backend service.
129+ /// </summary>
130+ private class LightSettingsColor
131+ {
132+ /// <summary>
133+ /// Gets or sets the red component.
134+ /// </summary>
135+ [ JsonProperty ( "red" ) ]
136+ internal float Red { get ; set ; }
137+
138+ /// <summary>
139+ /// Gets or sets the green component.
140+ /// </summary>
141+ [ JsonProperty ( "green" ) ]
142+ internal float Green { get ; set ; }
143+
144+ /// <summary>
145+ /// Gets or sets the blue component.
146+ /// </summary>
147+ [ JsonProperty ( "blue" ) ]
148+ internal float Blue { get ; set ; }
149+
150+ /// <summary>
151+ /// Gets or sets the alpha component.
152+ /// </summary>
153+ [ JsonProperty ( "alpha" ) ]
154+ internal float Alpha { get ; set ; }
155+
156+ internal static LightSettingsColor FromString ( string color )
157+ {
158+ if ( string . IsNullOrEmpty ( color ) )
159+ {
160+ throw new ArgumentException ( "Light settings color must not be null or empty" ) ;
161+ }
162+
163+ if ( ! Regex . Match ( color , "^#[0-9a-fA-F]{6}$" ) . Success && ! Regex . Match ( color , "^#[0-9a-fA-F]{8}$" ) . Success )
164+ {
165+ throw new ArgumentException ( $ "Invalid Light Settings Color { color } . Must be in the form of #RRGGBB or #RRGGBBAA.") ;
166+ }
167+
168+ var colorString = color . Length == 7 ? color + "FF" : color ;
169+
170+ return new LightSettingsColor ( )
171+ {
172+ Red = Convert . ToInt32 ( colorString . Substring ( 1 , 2 ) , 16 ) / 255.0f ,
173+ Green = Convert . ToInt32 ( colorString . Substring ( 3 , 2 ) , 16 ) / 255.0f ,
174+ Blue = Convert . ToInt32 ( colorString . Substring ( 5 , 2 ) , 16 ) / 255.0f ,
175+ Alpha = Convert . ToInt32 ( colorString . Substring ( 7 , 2 ) , 16 ) / 255.0f ,
176+ } ;
177+ }
178+
179+ internal string ColorString ( )
180+ {
181+ var colorStringBuilder = new StringBuilder ( ) ;
182+
183+ colorStringBuilder
184+ . Append ( "#" )
185+ . Append ( Convert . ToInt32 ( this . Red * 255 ) . ToString ( "X" ) )
186+ . Append ( Convert . ToInt32 ( this . Green * 255 ) . ToString ( "X" ) )
187+ . Append ( Convert . ToInt32 ( this . Blue * 255 ) . ToString ( "X" ) )
188+ . Append ( Convert . ToInt32 ( this . Alpha * 255 ) . ToString ( "X" ) ) ;
189+
190+ return colorStringBuilder . ToString ( ) ;
191+ }
192+ }
122193 }
123194}
0 commit comments