package Ġcom . just eat . j ub ako Ċ Ċ import Ġandroid . util . Log Ċ import Ġandroidx . annotation . Visible ForTesting Ċ import Ġandroidx . fragment . app . Fragment Activity Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġandroidx . lifecycle . ViewModel Providers Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . Job Ċ import Ġkotlinx . coroutines . Supervisor Job Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlin . coroutines . Coroutine Context Ċ Ċ open Ġclass ĠJ ub ako Ġ: ĠViewModel (), ĠCor outine Scope Ġ{ ĊĠĠĠ Ġprivate Ġval Ġjob Ġ= ĠSuper visor Job () ĊĠĠĠ Ġoverride Ġval Ġcoroutine Context : ĠCor outine Context ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġjob Ġ+ ĠDispatch ers . Main ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġvar Ġloading Job : ĠJob ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġvar ĠIO Ġ= ĠDispatch ers . IO ĊĊĠĠĠ Ġdata Ġclass ĠData ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġscope : ĠCor outine Scope , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġassembler : ĠJ ub ako Assembler , ĊĠĠĠĠĠĠĠ Ġval Ġsource : ĠMutable List < Content Description < Any >> Ġ= Ġmutable ListOf (), ĊĠĠĠĠĠĠĠ Ġval Ġdestination : ĠContent Description Collection Ġ= ĠContent Description Collection (), ĊĠĠĠĠĠĠĠ Ġval Ġview Specs : ĠMutable List < Any > Ġ= Ġmutable ListOf () ĊĠĠĠ Ġ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠĠĠĠĠ Ġinternal Ġvar Ġloading Job : ĠJob ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġfun ĠgetItem ( position : ĠInt ) Ġ= Ġdestination [ position ] ĊĠĠĠĠĠĠĠ Ġfun Ġnum Items Loaded () Ġ= Ġdestination . size () ĊĠĠĠĠĠĠĠ Ġfun Ġby Content Description Id ( content Description Id : ĠString ): ĠContent Description < Any >? Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource . find Ġ{ Ġit . id Ġ== Ġcontent Description Id Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun ĠindexOf ( item : ĠContent Description < Any >? ): ĠInt Ġ= Ġsource . indexOf ( item ) ĊĠĠĠĠĠĠĠ Ġfun Ġloaded ( item : ĠContent Description < Any >): ĠBoolean Ġ= Ġdestination . contains ( item ) ĊĠĠĠĠĠĠĠ Ġfun Ġhas More () Ġ= Ġassembler . hasMore () ĊĊĠĠĠĠĠĠĠ Ġfun Ġassemble More (): ĠLive Data < State > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlive Data Ġ= ĠMutable LiveData < State >() ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . log (" As semb ling ĠMore ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġloading Job Ġ= Ġscope . launch ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload ( assembler ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlive Data . value Ġ= ĠState . As semb led ( this @ Data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . log (" As semble ĠError ", ĠLog . get StackTrace String ( exception )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlive Data . value Ġ= ĠState . As semble Error ( exception ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlive Data ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġdata : ĠData ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġloading State : ĠMutable LiveData < State > Ġ= ĠMutable LiveData () ĊĊĠĠĠ Ġsealed Ġclass ĠState Ġ{ ĊĠĠĠĠĠĠĠ Ġobject ĠAs semb ling Ġ: ĠState () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠAs semb led ( val Ġdata : ĠData ) Ġ: ĠState () ĊĠĠĠĠĠĠĠ Ġdata Ġclass ĠAs semble Error ( val Ġerror : ĠThrowable ) Ġ: ĠState () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLoad Ġcontent Ġusing Ġthe Ġgiven Ġ[ J ub ako Assembler ], Ġcalling Ġthis ĊĠĠĠĠ Ġ* Ġfunction Ġagain Ġwill Ġdo Ġnothing Ġuntil Ġyou Ġcall Ġ[ reset ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġopen Ġfun Ġload ( content Assembler : ĠJ ub ako Assembler ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġ// ĠOnly Ġset Ġassembler Ġonce Ġ( unless Ġon Reload ) ĊĠĠĠĠĠĠĠ Ġ// ĊĠĠĠĠĠĠĠ Ġif Ġ( data Ġ!= Ġnull Ġ|| Ġloading Job Ġ!= Ġnull ) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġlogger . log (" As semb ling ") ĊĠĠĠĠĠĠĠ Ġloading State . value Ġ= ĠState . As semb ling ĊĊĠĠĠĠĠĠĠ Ġloading Job Ġ= Ġlaunch ( IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdata Ġ= Ġcomplete As semble ( content Assembler ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloading State . value Ġ= ĠState . As semb led ( data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . log ( logger . tag , Ġ" As semble ĠError ", Ġ"${ Log . get StackTrace String ( exception )} ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch ( Dispatch ers . Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloading State . value Ġ= ĠState . As semble Error ( exception ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloading Job Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġcomplete As semble ( content Assembler : ĠJ ub ako Assembler ) Ġ= ĊĠĠĠĠĠĠĠ ĠData ( this , Ġcontent Assembler ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġload ( content Assembler ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġ= Ġthis ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAllow Ġcontent Ġto Ġbe Ġloaded Ġagain Ġfrom Ġthe Ġbeginning ... ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġreset () Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . log (" Reset ") ĊĠĠĠĠĠĠĠ Ġloading Job ?. cancel () ĊĠĠĠĠĠĠĠ Ġloading Job Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ// ĠTODO Ġreset ting Ġfast Ġcauses Ġan Ġin consistency Ġclearing Ġdestination ĊĠĠĠĠĠĠĠ Ġdata ?. destination ?. clear () ĊĠĠĠĠĠĠĠ Ġdata Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Cle ared () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Cle ared () ĊĠĠĠĠĠĠĠ Ġjob . cancel () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġlogger : ĠLogger Ġ= ĠLogger ( false ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġobserve ( activity : ĠFragment Activity , Ġchanged : Ġ( State ) Ġ-> ĠUnit ): ĠJ ub ako Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠviewModel Ġ= ĠViewModel Providers . of ( activity ). get ( J ub ako :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠviewModel . loading State . observe ( activity , ĠObserver Ġ{ Ġchanged ( it ) Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠviewModel ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġopen Ġclass ĠLogger ( var Ġenabled : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġopen Ġval Ġtag Ġ= ĠJ ub ako :: class . java . simple Name !! ĊĊĠĠĠĠĠĠĠ Ġopen Ġfun Ġlog ( state : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( enabled ) ĠLog . d ( tag , Ġ" [$ state ]") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġopen Ġfun Ġlog ( tag : ĠString , Ġstate : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( enabled ) ĠLog . d ( tag , Ġ" [$ state ]") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġopen Ġfun Ġlog ( tag : ĠString , Ġstate : ĠString , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( enabled ) ĠLog . d ( tag , Ġ" [$ state ] Ġ$ message ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġsuspend Ġfun ĠJ ub ako . Data . load ( content Assembler : ĠJ ub ako Assembler ) Ġ{ ĊĠĠĠ Ġval Ġdescription Providers Ġ= Ġcontent Assembler . assemble () ĊĠĠĠ ĠJ ub ako . logger . log (" As semb led ", Ġ"${ description Providers . size } Ġmore Ġdescriptions Ġ( total : Ġ${ source . size }) ") ĊĠĠĠ Ġdescription Providers . forEach Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdescription Ġ= Ġit . create Description () ĊĠĠĠĠĠĠĠ Ġsource . add ( description ) ĊĠĠĠĠĠĠĠ Ġview Specs . add ( description . view Spec ) ĊĠĠĠ Ġ} Ċ } Ċ