package Ġcom . tan may . quotes . data Ċ Ċ // import Ġandroidx . paging . Experimental Paging Api Ċ // import Ġandroidx . paging . Load Type Ċ // import Ġandroidx . paging . Paging State Ċ // import Ġandroidx . paging . Remote Mediator Ċ import Ġandroidx . room . with Transaction Ċ import Ġcom . tan may . quotes . api . Data Ċ import Ġcom . tan may . quotes . api . Quotes Api Ċ import Ġcom . tan may . quotes . db . Quotes Database Ċ import Ġretrofit 2 . HttpException Ċ import Ġjava . io . IOException Ċ Ċ private Ġconst Ġval ĠQU OT ES _ START ING _ PAGE _ INDEX Ġ= Ġ 1 ĊĊ Ċ //@ Experimental Paging Api Ċ class ĠQu otes Remote Mediator ( ĊĠĠĠ Ġval Ġapi Ġ: ĠQu otes Api , ĊĠĠĠ Ġprivate Ġval Ġquotes Database : ĠQu otes Database , ĊĠĠĠ Ġval Ġtag : ĠString ){ Ċ // ): ĠRemote Mediator < Int , F etched Quotes Data >() Ġ{ Ċ Ċ // ĠĠĠ Ġoverride Ġsuspend Ġfun Ġload ( Ċ // ĠĠĠĠĠĠĠ Ġload Type : ĠLoad Type , Ċ // ĠĠĠĠĠĠĠ Ġstate : ĠP aging State < Int , ĠF etched Quotes Data > Ċ // ĠĠĠ Ġ): ĠMed iator Result Ġ{ Ċ // Ċ // ĠĠĠĠĠĠĠ Ġval Ġpage Ġ= Ġwhen Ġ( load Type ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠLoad Type . REFRESH Ġ-> Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote Keys Ġ= Ġget Remote Key Closest To Current Position ( state ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Keys ?. next Key ?. minus ( 1 ) Ġ?: ĠQU OT ES _ START ING _ PAGE _ INDEX Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠLoad Type . PRE PEND Ġ-> Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote Keys Ġ= Ġget Remote Key For First Item ( state ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġprevious Ġkey Ġis Ġnull , Ġthen Ġthe Ġlist Ġis Ġempty Ġso Ġwe Ġshould Ġwait Ġfor Ġdata Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfetched Ġby Ġremote Ġrefresh Ġand Ġcan Ġsimply Ġskip Ġloading Ġthis Ġtime Ġby Ġreturning Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ` false ` Ġfor Ġend Of Pagination Reached . Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Key Ġ= Ġremote Keys ?. prev Key Ġ?: Ġreturn ĠMed iator Result . Success ( end Of Pagination Reached Ġ= Ġfalse ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprev Key Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠLoad Type . APPEND Ġ-> Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote Keys Ġ= Ġget Remote Key For Last Item ( state ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġnext Ġkey Ġis Ġnull , Ġthen Ġthe Ġlist Ġis Ġempty Ġso Ġwe Ġshould Ġwait Ġfor Ġdata Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfetched Ġby Ġremote Ġrefresh Ġand Ġcan Ġsimply Ġskip Ġloading Ġthis Ġtime Ġby Ġreturning Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ` false ` Ġfor Ġend Of Pagination Reached . Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Key Ġ= Ġremote Keys ?. next Key Ġ?: Ġreturn ĠMed iator Result . Success ( end Of Pagination Reached Ġ= Ġfalse ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext Key Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠ Ġtry Ġ{ Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġif Ġ( tag Ġ== Ġ" ALL ") Ġapi . get Quotes ( page , Ġstate . config . pageSize ) Ġelse Ġapi . get Quotes By Genre ( tag , Ġpage , Ġstate . config . pageSize ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġquotes Ġ= Ġresponse . data Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis EndOf List Ġ= Ġquotes . isEmpty () Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġquotes Database . with Transaction Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġclear Ġall Ġtables Ġin Ġthe Ġdatabase Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( load Type Ġ== ĠLoad Type . REFRESH ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquotes Database . get Repo Dao (). clear Remote Keys () Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquotes Database . quotes Dao (). delete F etched Quote () Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprev Key Ġ= Ġif Ġ( page Ġ== ĠQU OT ES _ START ING _ PAGE _ INDEX ) Ġnull Ġelse Ġpage Ġ- Ġ 1 Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Key Ġ= Ġif Ġ( is EndOf List ) Ġnull Ġelse Ġpage Ġ+ Ġ 1 Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkeys Ġ= Ġquotes . map Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRemote Keys ( repo Id Ġ= Ġit ._ id , Ġprev Key Ġ= Ġprev Key , Ġnext Key Ġ= Ġnext Key ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsaved Quotes Ġ= Ġquotes Database . quotes Dao (). getAll Saved Quotes () Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfetched Quotes Data Ġ= Ġquotes . map Ġ{ Ġq Data Ġ-> Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( check Quote Book Marked ( q Data , Ġsaved Quotes )) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠF etched Quotes Data ( Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ id Ġ= Ġq Data ._ id , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquote Author Ġ= Ġq Data . quote Author , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquote Genre Ġ= Ġq Data . quote Genre , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquote Text Ġ= Ġq Data . quote Text , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Book marked Ġ= Ġtrue , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTAG Ġ= Ġtag Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠF etched Quotes Data ( Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ id Ġ= Ġq Data ._ id , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquote Author Ġ= Ġq Data . quote Author , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquote Genre Ġ= Ġq Data . quote Genre , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquote Text Ġ= Ġq Data . quote Text , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTAG Ġ= Ġtag Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquotes Database . get Repo Dao (). insert All ( keys ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquotes Database . quotes Dao (). insert F etched Quote ( f etched Quotes Data ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMed iator Result . Success ( end Of Pagination Reached Ġ= Ġis EndOf List ) Ċ // ĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠIOException ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMed iator Result . Error ( exception ) Ċ // ĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠHttp Exception ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠMed iator Result . Error ( exception ) Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠ Ġ} Ċ // Ċ // Ċ // ĠĠĠ Ġprivate Ġfun Ġ Ġcheck Quote Book Marked ( q Data Ġ: ĠData , Ġsaved Ġ: List < Quotes Data >) Ġ: ĠBoolean { Ċ // ĠĠĠĠĠĠĠ Ġfor Ġ( q Ġin Ġsaved ){ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( q Data . quote Text Ġ== Ġq . quote Text ){ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġreturn Ġfalse Ċ // ĠĠĠ Ġ} Ċ // Ċ // Ċ // ĠĠĠ Ġprivate Ġsuspend Ġfun Ġget Remote Key For Last Item ( state : ĠP aging State < Int , ĠF etched Quotes Data >): ĠRemote Keys ? Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġlast Ġpage Ġthat Ġwas Ġretrieved , Ġthat Ġcontained Ġitems . Ċ // ĠĠĠĠĠĠĠ Ġ// ĠFrom Ġthat Ġlast Ġpage , Ġget Ġthe Ġlast Ġitem Ċ // ĠĠĠĠĠĠĠ Ġreturn Ġstate . pages . last OrNull () Ġ{ Ġit . data . isNotEmpty () Ġ} ?. data ?. last OrNull () Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ Ġrepo Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġremote Ġkeys Ġof Ġthe Ġlast Ġitem Ġretrieved Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquotes Database . get Repo Dao (). remote Keys Quotes Id ( repo ._ id ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠ Ġ} Ċ // Ċ // ĠĠĠ Ġprivate Ġsuspend Ġfun Ġget Remote Key For First Item ( state : ĠP aging State < Int , ĠF etched Quotes Data >): ĠRemote Keys ? Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġfirst Ġpage Ġthat Ġwas Ġretrieved , Ġthat Ġcontained Ġitems . Ċ // ĠĠĠĠĠĠĠ Ġ// ĠFrom Ġthat Ġfirst Ġpage , Ġget Ġthe Ġfirst Ġitem Ċ // ĠĠĠĠĠĠĠ Ġreturn Ġstate . pages . first OrNull Ġ{ Ġit . data . isNotEmpty () Ġ} ?. data ?. first OrNull () Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ Ġrepo Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġremote Ġkeys Ġof Ġthe Ġfirst Ġitems Ġretrieved Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquotes Database . get Repo Dao (). remote Keys Quotes Id ( repo ._ id ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠ Ġ} Ċ // Ċ // ĠĠĠ Ġprivate Ġsuspend Ġfun Ġget Remote Key Closest To Current Position ( Ċ // ĠĠĠĠĠĠĠ Ġstate : ĠP aging State < Int , ĠF etched Quotes Data > Ċ // ĠĠĠ Ġ): ĠRemote Keys ? Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġ// ĠThe Ġpaging Ġlibrary Ġis Ġtrying Ġto Ġload Ġdata Ġafter Ġthe Ġanchor Ġposition Ċ // ĠĠĠĠĠĠĠ Ġ// ĠGet Ġthe Ġitem Ġclosest Ġto Ġthe Ġanchor Ġposition Ċ // ĠĠĠĠĠĠĠ Ġreturn Ġstate . anchor Position ?. let Ġ{ Ġposition Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġstate . closest Item To Position ( position )? ._ id ?. let Ġ{ Ġrepo Id Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquotes Database . get Repo Dao (). remote Keys Quotes Id ( repo Id ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠ Ġ} ĊĊ Ċ }