11using System ;
2+ using System . Collections ;
23using System . Collections . Generic ;
34using UnityEngine ;
45using UnityEngine . UIElements ;
89using Unity . BossRoom . Gameplay . Messages ;
910using Unity . BossRoom . Infrastructure ;
1011using VContainer ;
11- using Random = System . Random ;
1212
1313public class MessageFeed : MonoBehaviour
1414{
@@ -17,7 +17,7 @@ public class MessageFeed : MonoBehaviour
1717
1818 List < MessageViewModel > m_Messages ;
1919
20- VisualElement m_MessageContainer ;
20+ ListView m_MessageContainer ;
2121
2222 DisposableGroup m_Subscriptions ;
2323
@@ -95,12 +95,11 @@ void OnLifeStateChangedEvent(LifeStateChangedEventMessage eventMessage)
9595 break ;
9696 }
9797 }
98-
9998
10099 [ ContextMenu ( "Add Message" ) ]
101100 public void AddMessage ( )
102101 {
103- ShowMessage ( "Hello!" ) ;
102+ ShowMessage ( $ "Hello! { DateTime . Now . Millisecond } ") ;
104103 }
105104
106105 void Start ( )
@@ -111,7 +110,7 @@ void Start()
111110
112111 // Find the container of all messages
113112 var listView = root . Q < ListView > ( "messageList" ) ;
114-
113+
115114 // Since you've added an item template in the UXML this is not really necessary here
116115 listView . makeItem += ( ) =>
117116 {
@@ -130,23 +129,34 @@ void Start()
130129
131130 // the even when the control get's added to the "UI Canvas"
132131 newBox . RegisterCallback < AttachToPanelEvent > ( ( e ) =>
133- ( e . target as VisualElement ) ? . AddToClassList ( "messageBoxMove" ) ) ;
132+ {
133+ if ( e . target is VisualElement element )
134+ {
135+ element . RemoveFromClassList ( "messageBoxMove" ) ;
136+ StartCoroutine ( ToggleClassWithDelay ( element , "messageBoxMove" , TimeSpan . FromSeconds ( 0.02 ) ) ) ;
137+ }
138+ } ) ;
134139
135140 // fires before the element is actually removed
136141 newBox . RegisterCallback < DetachFromPanelEvent > ( ( e ) =>
137142 {
138- if ( e . target is VisualElement )
139- {
140-
141- }
143+ if ( e . target is VisualElement ) { }
142144 } ) ;
143145
144146 return newBox ;
145147 } ;
148+
149+
150+ listView . destroyItem += ( element ) =>
151+ {
152+
153+ } ;
146154
155+ // use this to set bindings / values on your view components
147156 listView . bindItem += ( element , i ) =>
148157 {
149- element . Q < Label > ( ) . text = m_Messages [ i ] . Message ;
158+ var label = element . Q < Label > ( ) ;
159+ label . text = m_Messages [ i ] . Message ;
150160 } ;
151161
152162 // collection change events will take care of creating and disposing items
@@ -160,6 +170,8 @@ void Start()
160170 // make sure other visual elements don't get pushed down by the message container
161171 m_MessageContainer.style.position = Position.Absolute;
162172 */
173+
174+ m_MessageContainer = listView ;
163175 }
164176
165177 void OnDestroy ( )
@@ -170,35 +182,45 @@ void OnDestroy()
170182 }
171183 }
172184
185+ List < MessageViewModel > _messagesToRemove = new List < MessageViewModel > ( ) ;
186+
173187 void Update ( )
174188 {
175- var messagesToRemove = new List < MessageViewModel > ( ) ;
189+ if ( m_Messages == null )
190+ return ;
191+
176192 foreach ( var m in m_Messages )
177193 {
178- if ( m . ShouldDispose ( ) )
194+ if ( m . ShouldDispose ( ) && ! _messagesToRemove . Contains ( m ) )
179195 {
180- messagesToRemove . Add ( m ) ;
196+ _messagesToRemove . Add ( m ) ;
181197 }
182-
183- // Check if a message should begin fading out
184- // if (Time.realtimeSinceStartup - m.startTime > 5 && m.style.opacity == 1)
185- //{
186- //StartFadeout(m, 1f);
187- // m.isShown = false;
188- //}
189198 }
190199
191- // TODO: start animation via events
192- foreach ( var m in messagesToRemove )
200+ foreach ( var m in _messagesToRemove )
193201 {
194- m_Messages . Remove ( m ) ;
202+ var fadeOutClassName = "messageBoxFadeOut" ;
203+
204+ var child = m_MessageContainer . Query < VisualElement > ( ) . Class ( "messageBox" )
205+ . AtIndex ( m_Messages . IndexOf ( m ) ) ;
206+
207+ if ( ! child . ClassListContains ( fadeOutClassName ) )
208+ {
209+ child . AddToClassList ( fadeOutClassName ) ;
210+ child . RegisterCallback < TransitionEndEvent > ( ( e ) =>
211+ {
212+ m_Messages . Remove ( m ) ;
213+ _messagesToRemove . Remove ( m ) ;
214+ child . RemoveFromClassList ( fadeOutClassName ) ;
215+ } ) ;
216+ }
195217 }
196218 }
197219
198220 void ShowMessage ( string message )
199221 {
200222 // Reuse or create a new message
201- MessageViewModel newMessage = null ;
223+ // MessageViewModel newMessage = null;
202224
203225 // a list view's virtualization logic actually takes care of this by default
204226 /*
@@ -212,29 +234,34 @@ void ShowMessage(string message)
212234 }
213235 }
214236 */
215- newMessage = new MessageViewModel ( message , TimeSpan . FromSeconds ( 5 ) ) ;
237+ var newMessage = new MessageViewModel ( message , TimeSpan . FromSeconds ( 5 ) ) ;
216238
217239 m_Messages . Add ( newMessage ) ; // Add to the list of messages
218240 }
219241
220- /*
221- static void StartFadeout(Message message, float opacity)
242+ IEnumerator ToggleClassWithDelay ( VisualElement element , string className , TimeSpan delay )
222243 {
223- message.messageBox.schedule.Execute(() =>
244+ yield return new WaitForSeconds ( ( float ) delay . TotalSeconds ) ;
245+
246+ element . ToggleInClassList ( className ) ;
247+ }
248+
249+
250+ static void StartFadeout ( VisualElement message , float opacity )
251+ {
252+ message . schedule . Execute ( ( ) =>
224253 {
225254 opacity -= 0.01f ;
226- message.messageBox. style.opacity = opacity;
255+ message . style . opacity = opacity ;
227256
228257 if ( opacity <= 0 )
229258 {
230259 // Once faded out fully, hide the message and reset state
231- message.messageBox.style.display = DisplayStyle.None;
232- message.isShown = false;
233- message.startTime = 0;
260+ message . style . display = DisplayStyle . None ;
234261 }
235262 } ) . Every ( ( long ) 0.1f ) . Until ( ( ) => opacity <= 0 ) ;
236263 }
237- */
264+
238265
239266 // if you bind the itemsource to the list you don't actually have to manually do this
240267 private class MessageViewModel
@@ -251,6 +278,7 @@ public MessageViewModel(string message, TimeSpan timeout = default)
251278 Message = message ;
252279 }
253280
281+ // probably an event would be nicer
254282 public bool ShouldDispose ( )
255283 {
256284 return _createdAt + _autoDispose < DateTime . Now ;
0 commit comments