@@ -8,6 +8,7 @@ var ChronicleScreen = (function() {
88 var MAX_POST_LENGTH = 280 ;
99 var BLESS_ENERGY = 100 ; // 1% = 100 basis points
1010 var currentTab = 'all' ; // all, guild, friends, world
11+ var REQUIRED_TAG = '#viz_magic' ;
1112
1213 function render ( ) {
1314 var t = Helpers . t ;
@@ -85,6 +86,7 @@ var ChronicleScreen = (function() {
8586 // Send button
8687 Helpers . $ ( 'btn-chronicle-send' ) . addEventListener ( 'click' , function ( ) {
8788 var text = Helpers . $ ( 'chronicle-input' ) . value . trim ( ) ;
89+ text = _ensureRequiredTag ( text ) ;
8890 if ( ! text || text . length > MAX_POST_LENGTH ) return ;
8991 SoundManager . play ( 'bless_send' ) ;
9092
@@ -110,46 +112,102 @@ var ChronicleScreen = (function() {
110112
111113 var state = StateEngine . getState ( ) ;
112114 var entries = _collectStateEntries ( state ) ;
113- var user = VizAccount . getCurrentUser ( ) ;
115+ var accounts = _getFeedAccounts ( state ) ;
114116
115- if ( ! user || typeof VoiceProtocol === 'undefined' || ! VoiceProtocol . loadChronicle ) {
117+ if ( ! accounts . length || typeof VoiceProtocol === 'undefined' || ! VoiceProtocol . loadChronicle ) {
116118 _renderFeedEntries ( _filterByTab ( entries , state ) ) ;
117119 return ;
118120 }
119121
120- VoiceProtocol . loadChronicle ( user , 20 , function ( err , voiceEntries ) {
121- if ( ! err && voiceEntries && voiceEntries . length ) {
122- for ( var i = 0 ; i < voiceEntries . length ; i ++ ) {
123- var voiceEntry = voiceEntries [ i ] ;
124- var voiceText = '' ;
125- if ( voiceEntry . message ) {
126- if ( voiceEntry . message . type === 'text' ) voiceText = voiceEntry . message . text || '' ;
127- else if ( voiceEntry . message . type === 'publication' ) voiceText = voiceEntry . message . title || voiceEntry . message . description || '' ;
128- }
129- if ( ! voiceText ) continue ;
130- entries . push ( {
131- type : 'voice' ,
132- account : voiceEntry . sender ,
133- text : voiceText ,
134- actionType : 'chronicle_post' ,
135- timestamp : voiceEntry . blockTime || null ,
136- blockNum : voiceEntry . blockNum || 0
137- } ) ;
138- }
122+ _loadVoiceEntriesForAccounts ( accounts , 20 , function ( voiceEntries ) {
123+ for ( var i = 0 ; i < voiceEntries . length ; i ++ ) {
124+ entries . push ( voiceEntries [ i ] ) ;
139125 }
140-
141126 _renderFeedEntries ( _filterByTab ( _dedupeEntries ( entries ) , state ) ) ;
142127 } ) ;
143128 }
144129
130+ function _getFeedAccounts ( state ) {
131+ var accounts = [ ] ;
132+ var seen = { } ;
133+ var user = VizAccount . getCurrentUser ( ) ;
134+
135+ function add ( account ) {
136+ if ( ! account || seen [ account ] ) return ;
137+ seen [ account ] = true ;
138+ accounts . push ( account ) ;
139+ }
140+
141+ add ( user ) ;
142+
143+ if ( state && state . characters ) {
144+ for ( var account in state . characters ) {
145+ if ( state . characters . hasOwnProperty ( account ) ) add ( account ) ;
146+ }
147+ }
148+
149+ if ( typeof GuildSystem !== 'undefined' && state && state . guilds && user ) {
150+ var guild = GuildSystem . findGuildByMember ( state . guilds , user ) ;
151+ if ( guild && guild . members ) {
152+ for ( var member in guild . members ) {
153+ if ( guild . members . hasOwnProperty ( member ) ) add ( member ) ;
154+ }
155+ }
156+ }
157+
158+ return accounts ;
159+ }
160+
161+ function _loadVoiceEntriesForAccounts ( accounts , maxEntries , callback ) {
162+ var allEntries = [ ] ;
163+ var index = 0 ;
164+
165+ function next ( ) {
166+ if ( index >= accounts . length ) {
167+ callback ( allEntries ) ;
168+ return ;
169+ }
170+
171+ var account = accounts [ index ++ ] ;
172+ VoiceProtocol . loadChronicle ( account , maxEntries , function ( err , voiceEntries ) {
173+ if ( ! err && voiceEntries && voiceEntries . length ) {
174+ for ( var i = 0 ; i < voiceEntries . length ; i ++ ) {
175+ var normalized = _normalizeVoiceEntry ( voiceEntries [ i ] ) ;
176+ if ( normalized ) allEntries . push ( normalized ) ;
177+ }
178+ }
179+ next ( ) ;
180+ } ) ;
181+ }
182+
183+ next ( ) ;
184+ }
185+
186+ function _normalizeVoiceEntry ( voiceEntry ) {
187+ if ( ! voiceEntry || ! voiceEntry . message ) return null ;
188+ var voiceText = '' ;
189+ if ( voiceEntry . message . type === 'text' ) voiceText = voiceEntry . message . text || '' ;
190+ else if ( voiceEntry . message . type === 'publication' ) voiceText = voiceEntry . message . title || voiceEntry . message . description || '' ;
191+ if ( ! voiceText || ! _hasRequiredTag ( voiceText ) ) return null ;
192+
193+ return {
194+ type : 'voice' ,
195+ account : voiceEntry . sender ,
196+ text : voiceText ,
197+ actionType : 'chronicle_post' ,
198+ timestamp : voiceEntry . blockTime || null ,
199+ blockNum : voiceEntry . blockNum || 0
200+ } ;
201+ }
202+
145203 function _collectStateEntries ( state ) {
146204 var entries = [ ] ;
147205
148206 if ( state . recentActions ) {
149207 for ( var i = state . recentActions . length - 1 ; i >= 0 && entries . length < 50 ; i -- ) {
150208 var action = state . recentActions [ i ] ;
151209 var narrative = _actionToNarrative ( action ) ;
152- if ( narrative ) {
210+ if ( narrative && _entryMatchesRequiredTag ( action . type , narrative ) ) {
153211 entries . push ( {
154212 type : 'action' ,
155213 account : action . sender ,
@@ -278,6 +336,25 @@ var ChronicleScreen = (function() {
278336 } ) ;
279337 }
280338
339+ function _hasRequiredTag ( text ) {
340+ if ( ! text ) return false ;
341+ return String ( text ) . toLowerCase ( ) . indexOf ( REQUIRED_TAG ) !== - 1 ;
342+ }
343+
344+ function _ensureRequiredTag ( text ) {
345+ text = ( text || '' ) . trim ( ) ;
346+ if ( ! text ) return '' ;
347+ if ( _hasRequiredTag ( text ) ) return text ;
348+ return text + ' ' + REQUIRED_TAG ;
349+ }
350+
351+ function _entryMatchesRequiredTag ( actionType , text ) {
352+ if ( actionType === 'chronicle_post' ) {
353+ return _hasRequiredTag ( text ) ;
354+ }
355+ return true ;
356+ }
357+
281358 function _actionToNarrative ( action ) {
282359 var t = Helpers . t ;
283360 var charInfo = StateEngine . getCharacter ( action . sender ) ;
@@ -337,14 +414,25 @@ var ChronicleScreen = (function() {
337414 if ( currentTab === 'all' ) return entries ;
338415
339416 var user = VizAccount . getCurrentUser ( ) ;
340- // For now, simple filtering
341- // guild/friends require guild membership data which we can add later
417+ if ( currentTab === 'friends' ) {
418+ return user ? entries . filter ( function ( e ) { return e . account === user ; } ) : [ ] ;
419+ }
420+
421+ if ( currentTab === 'guild' ) {
422+ if ( typeof GuildSystem === 'undefined' || ! state || ! state . guilds || ! user ) return [ ] ;
423+ var guild = GuildSystem . findGuildByMember ( state . guilds , user ) ;
424+ if ( ! guild || ! guild . members ) return [ ] ;
425+ return entries . filter ( function ( e ) {
426+ return e . account && guild . members [ e . account ] ;
427+ } ) ;
428+ }
429+
342430 if ( currentTab === 'world' ) {
343- // Show duel events only
344431 return entries . filter ( function ( e ) {
345- return e . type === 'duel ' ;
432+ return e . type === 'voice' || e . actionType === 'chronicle_post ';
346433 } ) ;
347434 }
435+
348436 return entries ;
349437 }
350438
0 commit comments