/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠNew ĠVector ĠLtd Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġim . vector . matrix . android . internal . session . room . timeline Ċ Ċ import Ġandroid . os . Handler Ċ import Ġandroid . os . Handler Thread Ċ import Ġandroid . os . Looper Ċ import Ġim . vector . matrix . android . api . Matrix Callback Ċ import Ġim . vector . matrix . android . api . session . crypto . Crypto Service Ċ import Ġim . vector . matrix . android . api . session . events . model . EventType Ċ import Ġim . vector . matrix . android . api . session . events . model . to Model Ċ import Ġim . vector . matrix . android . api . session . room . timeline . Timeline Ċ import Ġim . vector . matrix . android . api . session . room . timeline . Timeline Event Ċ import Ġim . vector . matrix . android . api . util . Cancel able Bag Ċ import Ġim . vector . matrix . android . api . util . addTo Ċ import Ġim . vector . matrix . android . internal . crypto . New Session Listener Ċ import Ġim . vector . matrix . android . internal . crypto . model . event . Encrypted Event Content Ċ import Ġim . vector . matrix . android . internal . database . mapper . as Domain Ċ import Ġim . vector . matrix . android . internal . database . model .* Ċ import Ġim . vector . matrix . android . internal . database . query . find In cluding Event Ċ import Ġim . vector . matrix . android . internal . database . query . find Last Live Chunk From Room Ċ import Ġim . vector . matrix . android . internal . database . query . where Ċ import Ġim . vector . matrix . android . internal . database . query . where In Room Ċ import Ġim . vector . matrix . android . internal . task . Task Executor Ċ import Ġim . vector . matrix . android . internal . task . configure With Ċ import Ġim . vector . matrix . android . internal . util . De bounc er Ċ import Ġio . realm .* Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ import Ġjava . util . concurrent . atomic . Atomic Reference Ċ import Ġkotlin . collections . ArrayList Ċ import Ġkotlin . collections . HashMap ĊĊ Ċ private Ġconst Ġval ĠINITIAL _ LOAD _ SIZE Ġ= Ġ 2 0 Ċ private Ġconst Ġval ĠMIN _ FETCH ING _ COUNT Ġ= Ġ 3 0 Ċ private Ġconst Ġval ĠDISPLAY _ INDEX _ UNKNOWN Ġ= ĠInt . MIN _ VALUE Ċ private Ġconst Ġval ĠTHREAD _ NAME Ġ= Ġ" TIME LINE _ DB _ THREAD " Ċ Ċ internal Ġclass ĠDefault Timeline ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġroom Id : ĠString , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġinitial EventId : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġrealm Configuration : ĠRealm Configuration , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġtask Executor : ĠTask Executor , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġcontext Of Event Task : ĠGet Context Of Event Task , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġtimeline Event Factory : ĠCache able Timeline Event Factory , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpagination Task : ĠPagination Task , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġcrypto Service : ĠCrypto Service , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġallowed Types : ĠList < String >? Ċ ) Ġ: ĠTimeline Ġ{ ĊĊĠĠĠ Ġoverride Ġvar Ġlistener : ĠTimeline . Listener ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Handler . get ()?. post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Snapshot () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġis Started Ġ= ĠAtomic Boolean ( false ) ĊĠĠĠ Ġprivate Ġval Ġis Ready Ġ= ĠAtomic Boolean ( false ) ĊĠĠĠ Ġprivate Ġval Ġbackground Handler Thread Ġ= ĠAtomic Reference < Handler Thread >() ĊĠĠĠ Ġprivate Ġval Ġbackground Handler Ġ= ĠAtomic Reference < Handler >() ĊĠĠĠ Ġprivate Ġval Ġmain Handler Ġ= ĠHandler ( Looper . get Main Looper ()) ĊĠĠĠ Ġprivate Ġval Ġbackground Realm Ġ= ĠAtomic Reference < Realm >() ĊĠĠĠ Ġprivate Ġval Ġcancel able Bag Ġ= ĠCancel able Bag () ĊĠĠĠ Ġprivate Ġval Ġde bounc er Ġ= ĠDe bounc er ( main Handler ) ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġlive Events : ĠRealm Results < Event Entity > ĊĠĠĠ Ġprivate Ġvar Ġroom Entity : ĠRoom Entity ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar Ġprev Display Index : ĠInt Ġ= ĠDISPLAY _ INDEX _ UNKNOWN ĊĠĠĠ Ġprivate Ġvar Ġnext Display Index : ĠInt Ġ= ĠDISPLAY _ INDEX _ UNKNOWN ĊĠĠĠ Ġprivate Ġval Ġis Live Ġ= Ġinitial EventId Ġ== Ġnull ĊĠĠĠ Ġprivate Ġval Ġbuilt Events Ġ= ĠCollections . synchronized List < Timeline Event >( ArrayList ()) ĊĠĠĠ Ġprivate Ġval Ġbuilt Events Id Map Ġ= ĠCollections . synchronized Map ( HashMap < String , ĠInt >()) ĊĠĠĠ Ġprivate Ġval Ġbackwards Pagination State Ġ= ĠAtomic Reference ( Pagination State ()) ĊĠĠĠ Ġprivate Ġval Ġforwards Pagination State Ġ= ĠAtomic Reference ( Pagination State ()) ĊĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġevent Relations : ĠRealm Results < Event Annotations Summary Entity > ĊĊĠĠĠ Ġprivate Ġval Ġevents ChangeListener Ġ= ĠOrdered Realm Collection ChangeListener < Realm Results < Event Entity >> Ġ{ Ġresults , Ġchange Set Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( change Set . state Ġ== ĠOrdered Collection Change Set . State . INITIAL ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Initial Load () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġchange Set Ġhas Ġdeletion Ġwe Ġare Ġhaving Ġa Ġgap , Ġso Ġwe Ġclear Ġeverything ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( change Set . deletion Ranges . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev Display Index Ġ= ĠDISPLAY _ INDEX _ UNKNOWN ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Display Index Ġ= ĠDISPLAY _ INDEX _ UNKNOWN ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events . clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events Id Map . clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtimeline Event Factory . clear () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchange Set . insertion Ranges . forEach Ġ{ Ġrange Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( start Display Index , Ġdirection ) Ġ= Ġif Ġ( range . startIndex Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPair ( live Events [ range . length Ġ- Ġ 1 ] !!. display Index , ĠTimeline . Direction . FOR WAR DS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPair ( live Events [ range . startIndex ] !!. display Index , ĠTimeline . Direction . BACK WAR DS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġget Pagination State ( direction ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state . is Pag in ating ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġare Ġgetting Ġnew Ġitems Ġfrom Ġpagination ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshould Post Snapshot Ġ= Ġpag inate Internal ( start Display Index , Ġdirection , Ġstate . requested Count ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( should Post Snapshot ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Snapshot () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġare Ġgetting Ġnew Ġitems Ġfrom Ġsync ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuild Timeline Events ( start Display Index , Ġdirection , Ġrange . length . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Snapshot () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġhas Changed Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchange Set . changes . forEach Ġ{ Ġindex Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevent Entity Ġ= Ġresults [ index ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent Entity ?. eventId ?. let Ġ{ Ġevent Id Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events Id Map [ eventId ]?. let Ġ{ Ġbuilt Index Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Update Ġthe Ġrelation Ġof Ġexisting Ġevent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events [ built Index ]?. let Ġ{ Ġte Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events [ built Index ] Ġ= Ġtimeline Event Factory . create ( event Entity , Ġevent Entity . realm ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas Changed Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has Changed ) Ġpost Snapshot () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġrelations Listener Ġ= ĠOrdered Realm Collection ChangeListener < Realm Results < Event Annotations Summary Entity >> Ġ{ Ġcollection , Ġchange Set Ġ-> ĊĊĠĠĠĠĠĠĠ Ġvar Ġhas Change Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġ( change Set . insert ions Ġ+ Ġchange Set . changes ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevent Relations Ġ= Ġcollection [ it ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( event Relations Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events Id Map [ event Relations . eventId ]?. let Ġ{ Ġbuilt Index Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Update Ġthe Ġrelation Ġof Ġexisting Ġevent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events [ built Index ]?. let Ġ{ Ġte Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events [ built Index ] Ġ= Ġte . copy ( annotations Ġ= Ġevent Relations . as Domain ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas Change Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( has Change ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpost Snapshot () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġnew Session Listener Ġ= Ġobject Ġ: ĠNew Session Listener Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon New Session ( roomId : ĠString ?, Ġsender Key : ĠString , ĠsessionId : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( roomId Ġ== Ġthis @ Default Timeline . roomId ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" New Ġsession Ġid Ġdetected Ġfor Ġthis Ġroom ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Handler . get ()?. post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrealm Ġ= Ġbackground Realm . get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġhas Change Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events . forEach Indexed Ġ{ Ġindex , Ġtimeline Event Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( timeline Event . is Encrypted ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevent Content Ġ= Ġtimeline Event . root . content . to Model < Encrypted Event Content >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( event Content ?. sessionId Ġ== ĠsessionId ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġ( timeline Event . root . m Clear Event Ġ== Ġnull Ġ|| Ġtimeline Event . root . m Crypto Error Ġ!= Ġnull )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// we Ġneed Ġto Ġrebuild Ġthis Ġevent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEvent Entity . where ( realm , Ġevent Id Ġ= Ġtimeline Event . root . eventId !! ). findFirst ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events [ index ] Ġ= Ġtimeline Event Factory . create ( it , Ġrealm ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhas Change Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has Change ) Ġpost Snapshot () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} Ċ Ċ // ĠPublic Ġmethods Ġ************************************************************************* ***** ĊĊĠĠĠ Ġoverride Ġfun Ġpag inate ( direction : ĠTimeline . Direction , Ġcount : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbackground Handler . get ()?. post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! can Pag inate ( direction )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ post ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" Pag inate Ġ$ direction Ġof Ġ$ count Ġitems ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Display Index Ġ= Ġif Ġ( direction Ġ== ĠTimeline . Direction . BACK WAR DS ) Ġprev Display Index Ġelse Ġnext Display Index ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshould Post Snapshot Ġ= Ġpag inate Internal ( start Display Index , Ġdirection , Ġcount ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( should Post Snapshot ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Snapshot () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġoverride Ġfun Ġstart () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Started . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" Start Ġtimeline Ġfor Ġroom Id : Ġ$ roomId Ġand Ġevent Id : Ġ$ initial EventId ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhandler Thread Ġ= ĠHandler Thread ( THREAD _ NAME Ġ+ ĠhashCode ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler Thread . start () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhandler Ġ= ĠHandler ( handler Thread . lo oper ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . background Handler Thread . set ( handler Thread ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . background Handler . set ( handler ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcrypto Service . add New Session Listener ( new Session Listener ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhandler . post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrealm Ġ= ĠRealm . getInstance ( realm Configuration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Realm . set ( realm ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclear Un linked Events ( realm ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroom Entity Ġ= ĠRoom Entity . where ( realm , Ġroom Id Ġ= Ġroom Id ). findFirst ()?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . sending Timeline Events . add ChangeListener Ġ{ Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost Snapshot () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlive Events Ġ= Ġbuild Event Query ( realm ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sort ( Event Entity Fields . DISPLAY _ INDEX , ĠSort . DESC ENDING ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. findAll Async () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġit . add ChangeListener ( events ChangeListener ) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Ready . set ( true ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent Relations Ġ= ĠEvent Annotations Summary Entity . where In Room ( realm , Ġroom Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. findAll Async () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġit . add ChangeListener ( relations Listener ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdispose () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Started . compare AndSet ( true , Ġfalse )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcrypto Service . remove Session Listener ( new Session Listener ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" Dispose Ġtimeline Ġfor Ġroom Id : Ġ$ roomId Ġand Ġevent Id : Ġ$ initial EventId ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Handler . get ()?. post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcancel able Bag . cancel () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlive Events . removeAll Change Listeners () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Realm . get AndSet ( null ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Handler . set ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Handler Thread . get AndSet ( null )?. quit () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġhas More To Load ( direction : ĠTimeline . Direction ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġhas More In Cache ( direction ) Ġ|| Ġ! has Reached End ( direction ) ĊĠĠĠ Ġ} Ċ Ċ // ĠPrivate Ġmethods Ġ************************************************************************* **** ĊĊĠĠĠ Ġprivate Ġfun Ġhas More In Cache ( direction : ĠTimeline . Direction ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlocal Realm Ġ= ĠRealm . getInstance ( realm Configuration ) ĊĠĠĠĠĠĠĠ Ġval Ġevent Entity Ġ= Ġbuild Event Query ( local Realm ). findFirst ( direction ) Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġval Ġhas More In Cache Ġ= Ġif Ġ( direction Ġ== ĠTimeline . Direction . FOR WAR DS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfirst Event Ġ= Ġbuilt Events . first OrNull () Ġ?: Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfirst Event . display Index Ġ< Ġevent Entity . display Index ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlast Event Ġ= Ġbuilt Events . last OrNull () Ġ?: Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Event . display Index Ġ> Ġevent Entity . display Index ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlocal Realm . close () ĊĠĠĠĠĠĠĠ Ġreturn Ġhas More In Cache ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Reached End ( direction : ĠTimeline . Direction ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlocal Realm Ġ= ĠRealm . getInstance ( realm Configuration ) ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Chunk Ġ= Ġfind Current Chunk ( local Realm ) Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġval Ġhas Reached End Ġ= Ġif Ġ( direction Ġ== ĠTimeline . Direction . FOR WAR DS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Chunk . is Last Forward ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevent Entity Ġ= Ġbuild Event Query ( local Realm ). findFirst ( direction ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Chunk . is Last Backward Ġ|| Ġevent Entity ?. type Ġ== ĠEventType . STATE _ ROOM _ CREATE ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlocal Realm . close () ĊĠĠĠĠĠĠĠ Ġreturn Ġhas Reached End ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġhas Ġto Ġbe Ġcalled Ġon ĠTimeline Thread Ġas Ġit Ġaccess Ġrealm Ġlive Ġresults ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġcreate Snapshot Ġshould Ġbe Ġposted ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġpag inate Internal ( start Display Index : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirection : ĠTimeline . Direction , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcount : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate Pagination State ( direction ) Ġ{ Ġit . copy ( requested Count Ġ= Ġcount , Ġis Pag in ating Ġ= Ġtrue ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġbuilt Count Ġ= Ġbuild Timeline Events ( start Display Index , Ġdirection , Ġcount . to Long ()) ĊĠĠĠĠĠĠĠ Ġval Ġshould Fetch More Ġ= Ġbuilt Count Ġ< Ġcount Ġ&& Ġ! has Reached End ( direction ) ĊĠĠĠĠĠĠĠ Ġif Ġ( should Fetch More ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Requested Count Ġ= Ġcount Ġ- Ġbuilt Count ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Pagination State ( direction ) Ġ{ Ġit . copy ( requested Count Ġ= Ġnew Requested Count ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfetching Count Ġ= ĠMath . max ( MIN _ FETCH ING _ COUNT , Ġnew Requested Count ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecute Pagination Task ( direction , Ġfetching Count ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Pagination State ( direction ) Ġ{ Ġit . copy ( is Pag in ating Ġ= Ġfalse , Ġrequested Count Ġ= Ġ 0 ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġ! should Fetch More ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Snapshot (): ĠList < Timeline Event > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġbuild Sending Events () Ġ+ Ġbuilt Events . toList () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild Sending Events (): ĠList < Timeline Event > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsending Events Ġ= ĠArrayList < Timeline Event >() ĊĠĠĠĠĠĠĠ Ġif Ġ( has Reached End ( Timeline . Direction . FOR WAR DS )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġroom Entity ?. sending Timeline Events ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . filter Ġ{ Ġallowed Types ?. contains ( it . type ) Ġ?: Ġfalse Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtimeline Event Ġ= Ġtimeline Event Factory . create ( it , Ġit . realm ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsending Events . add ( timeline Event ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsending Events ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcan Pag inate ( direction : ĠTimeline . Direction ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġis Ready . get () Ġ&& Ġ! get Pagination State ( direction ). is Pag in ating Ġ&& Ġhas More To Load ( direction ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Pagination State ( direction : ĠTimeline . Direction ): ĠPagination State Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTimeline . Direction . FOR WAR DS Ġ Ġ-> Ġforwards Pagination State . get () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTimeline . Direction . BACK WAR DS Ġ-> Ġbackwards Pagination State . get () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Pagination State ( direction : ĠTimeline . Direction , Ġupdate : Ġ( Pagination State ) Ġ-> ĠPagination State ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstate Reference Ġ= Ġwhen Ġ( direction ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTimeline . Direction . FOR WAR DS Ġ Ġ-> Ġforwards Pagination State ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTimeline . Direction . BACK WAR DS Ġ-> Ġbackwards Pagination State ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Value Ġ= Ġstate Reference . get () ĊĠĠĠĠĠĠĠ Ġval ĠnewValue Ġ= Ġupdate ( current Value ) ĊĠĠĠĠĠĠĠ Ġstate Reference . set ( newValue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġhas Ġto Ġbe Ġcalled Ġon ĠTimeline Thread Ġas Ġit Ġaccess Ġrealm Ġlive Ġresults ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġhandle Initial Load () Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġshould Fetch Initial Event Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġval Ġinitial Display Index Ġ= Ġif Ġ( is Live ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlive Events . first OrNull ()?. display Index ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinitial Event Ġ= Ġlive Events . where (). equalTo ( Event Entity Fields . EVENT _ ID , Ġinitial EventId ). findFirst () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshould Fetch Initial Event Ġ= Ġinitial Event Ġ== Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Event ?. display Index ĊĠĠĠĠĠĠĠ Ġ} Ġ?: ĠDISPLAY _ INDEX _ UNKNOWN ĊĊĠĠĠĠĠĠĠ Ġprev Display Index Ġ= Ġinitial Display Index ĊĠĠĠĠĠĠĠ Ġnext Display Index Ġ= Ġinitial Display Index ĊĠĠĠĠĠĠĠ Ġif Ġ( initial EventId Ġ!= Ġnull Ġ&& Ġshould Fetch Initial Event ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfetch Event ( initial EventId ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcount Ġ= ĠMath . min ( INITIAL _ LOAD _ SIZE , Ġlive Events . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Live ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpag inate Internal ( initial Display Index , ĠTimeline . Direction . BACK WAR DS , Ġcount ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpag inate Internal ( initial Display Index , ĠTimeline . Direction . FOR WAR DS , Ġcount Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpag inate Internal ( initial Display Index , ĠTimeline . Direction . BACK WAR DS , Ġcount Ġ/ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġpost Snapshot () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġhas Ġto Ġbe Ġcalled Ġon ĠTimeline Thread Ġas Ġit Ġaccess Ġrealm Ġlive Ġresults ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġexecute Pagination Task ( direction : ĠTimeline . Direction , Ġlimit : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= ĠgetToken Live ( direction ) Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= ĠPagination Task . Params ( roomId Ġ= Ġroom Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrom Ġ= Ġtoken , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirection Ġ= Ġdirection . to Pagination Direction (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlimit Ġ= Ġlimit ) ĊĊĠĠĠĠĠĠĠ ĠTim ber . v (" Should Ġfetch Ġ$ limit Ġitems Ġ$ direction ") ĊĠĠĠĠĠĠĠ Ġpagination Task . configure With ( params ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. enable Retry () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. dispatch To ( object Ġ: ĠMatrix Callback < Token Chunk Event Pers istor . Result > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonSuccess ( data : ĠToken Chunk Event Pers istor . Result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( data Ġ== ĠToken Chunk Event Pers istor . Result . SUCCESS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" Success Ġfetching Ġ$ limit Ġitems Ġ$ direction Ġfrom Ġpagination Ġrequest ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDatabase Ġwon 't Ġbe Ġupdated , Ġso Ġwe Ġforce Ġpagination Ġrequest ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackground Handler . get ()?. post Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute Pagination Task ( direction , Ġlimit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Failure ( failure : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . v (" Failure Ġfetching Ġ$ limit Ġitems Ġ$ direction Ġfrom Ġpagination Ġrequest ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. execute By ( task Executor ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. addTo ( cancel able Bag ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġhas Ġto Ġbe Ġcalled Ġon ĠTimeline Thread Ġas Ġit Ġaccess Ġrealm Ġlive Ġresults ĊĠĠĠĠ Ġ*/ ĊĊĠĠĠ Ġprivate Ġfun ĠgetToken Live ( direction : ĠTimeline . Direction ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġchunk Entity Ġ= Ġget Live Chunk () Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( direction Ġ== ĠTimeline . Direction . BACK WAR DS ) Ġchunk Entity . prev Token Ġelse Ġchunk Entity . nextToken ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġhas Ġto Ġbe Ġcalled Ġon ĠTimeline Thread Ġas Ġit Ġaccess Ġrealm Ġlive Ġresults ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Live Chunk (): ĠChunk Entity ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġlive Events . first OrNull ()?. chunk ?. first OrNull () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġhas Ġto Ġbe Ġcalled Ġon ĠTimeline Thread Ġas Ġit Ġaccess Ġrealm Ġlive Ġresults ĊĠĠĠĠ Ġ* Ġ@ return Ġnumber Ġof Ġitems Ġwho Ġhave Ġbeen Ġadded ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġbuild Timeline Events ( start Display Index : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirection : ĠTimeline . Direction , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcount : ĠLong ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( count Ġ< Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġoffset Results Ġ= Ġget Offset Results ( start Display Index , Ġdirection , Ġcount ) ĊĠĠĠĠĠĠĠ Ġif Ġ( offset Results . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġoffset Index Ġ= Ġoffset Results . last () !!. display Index ĊĠĠĠĠĠĠĠ Ġif Ġ( direction Ġ== ĠTimeline . Direction . BACK WAR DS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprev Display Index Ġ= Ġoffset Index Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext Display Index Ġ= Ġoffset Index Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġoffset Results . forEach Ġ{ Ġevent Entity Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtimeline Event Ġ= Ġtimeline Event Factory . create ( event Entity , Ġevent Entity . realm ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġposition Ġ= Ġif Ġ( direction Ġ== ĠTimeline . Direction . FOR WAR DS ) Ġ 0 Ġelse Ġbuilt Events . size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events . add ( position , Ġtimeline Event ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Need Ġto Ġshift Ġ: / ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events Id Map . entries . filter Ġ{ Ġit . value Ġ>= Ġposition Ġ}. forEach Ġ{ Ġit . setValue ( it . value Ġ+ Ġ 1 ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilt Events Id Map [ event Entity . eventId ] Ġ= Ġposition ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠTim ber . v (" Built Ġ${ offset Results . size } Ġitems Ġfrom Ġdb ") ĊĠĠĠĠĠĠĠ Ġreturn Ġoffset Results . size ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġhas Ġto Ġbe Ġcalled Ġon ĠTimeline Thread Ġas Ġit Ġaccess Ġrealm Ġlive Ġresults ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Offset Results ( start Display Index : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirection : ĠTimeline . Direction , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcount : ĠLong ): ĠRealm Results < Event Entity > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġoffset Query Ġ= Ġlive Events . where () ĊĠĠĠĠĠĠĠ Ġif Ġ( direction Ġ== ĠTimeline . Direction . BACK WAR DS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Query ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sort ( Event Entity Fields . DISPLAY _ INDEX , ĠSort . DESC ENDING ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. less Than OrEqualTo ( Event Entity Fields . DISPLAY _ INDEX , Ġstart Display Index ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset Query ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sort ( Event Entity Fields . DISPLAY _ INDEX , ĠSort . ASC ENDING ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. greater Than OrEqualTo ( Event Entity Fields . DISPLAY _ INDEX , Ġstart Display Index ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġoffset Query ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Allowed Types () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. limit ( count ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. findAll () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġbuild Event Query ( realm : ĠRealm ): ĠRealm Query < Event Entity > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( initial EventId Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEvent Entity ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. where ( realm , Ġroom Id Ġ= Ġroom Id , Ġlink Filter Mode Ġ= ĠEvent Entity . Link Filter Mode . LINK ED _ ONLY ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. equalTo ("${ Event Entity Fields . CHUNK }.${ Chunk Entity Fields . IS _ LAST _ FORWARD }", Ġtrue ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEvent Entity ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. where ( realm , Ġroom Id Ġ= Ġroom Id , Ġlink Filter Mode Ġ= ĠEvent Entity . Link Filter Mode . BOTH ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. ` in ` ("${ Event Entity Fields . CHUNK }.${ Chunk Entity Fields . EVENTS . EVENT _ ID }", ĠarrayOf ( initial EventId )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Current Chunk ( realm : ĠRealm ): ĠChunk Entity ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( initial EventId Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChunk Entity . find Last Live Chunk From Room ( realm , Ġroom Id ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠChunk Entity . find In cluding Event ( realm , Ġinitial EventId ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclear Un linked Events ( realm : ĠRealm ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrealm . execute Transaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun linked Chunks Ġ= ĠChunk Entity ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. where ( it , Ġroom Id Ġ= Ġroom Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. equalTo ( Chunk Entity Fields . EVENTS . IS _ UN LINK ED , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. findAll () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġun linked Chunks . delete All From Realm () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch Event ( eventId : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= ĠGet Context Of Event Task . Params ( roomId , Ġevent Id ) ĊĠĠĠĠĠĠĠ Ġcontext Of Event Task . configure With ( params ). execute By ( task Executor ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpost Snapshot () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsnapshot Ġ= Ġcreate Snapshot () ĊĠĠĠĠĠĠĠ Ġval Ġrunnable Ġ= ĠRunnable Ġ{ Ġlistener ?. on Updated ( snapshot ) Ġ} ĊĠĠĠĠĠĠĠ Ġde bounc er . de bounce (" post _ snapshot ", Ġrunnable , Ġ 5 0 ) ĊĠĠĠ Ġ} Ċ Ċ // ĠExtension Ġmethods Ġ************************************************************************* ** ĊĊĠĠĠ Ġprivate Ġfun ĠTimeline . Direction . to Pagination Direction (): ĠPagination Direction Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( this Ġ== ĠTimeline . Direction . BACK WAR DS ) ĠPagination Direction . BACK WAR DS Ġelse ĠPagination Direction . FOR WAR DS ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠRealm Query < Event Entity >. findFirst ( direction : ĠTimeline . Direction ): ĠEvent Entity ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( direction Ġ== ĠTimeline . Direction . FOR WAR DS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsort ( Event Entity Fields . DISPLAY _ INDEX , ĠSort . DESC ENDING ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsort ( Event Entity Fields . DISPLAY _ INDEX , ĠSort . ASC ENDING ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Allowed Types () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. findFirst () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠRealm Query < Event Entity >. filter Allowed Types (): ĠRealm Query < Event Entity > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( allowed Types Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ` in `( Event Entity Fields . TYPE , Ġallowed Types . to Typed Array ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġthis ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġdata Ġclass ĠPagination State ( ĊĠĠĠĠĠĠĠ Ġval Ġis Pag in ating : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠ Ġval Ġrequested Count : ĠInt Ġ= Ġ 0 Ċ ) Ċ