package Ġcom . ke fas jw iry adi . bac aber ita . repository Ċ Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Transform ations Ċ import Ġcom . ke fas jw iry adi . bac aber ita . db . App Database Ċ import Ġcom . ke fas jw iry adi . bac aber ita . domain . Article Ċ import Ġcom . ke fas jw iry adi . bac aber ita . domain . Article Fetch Result Ċ import Ġcom . ke fas jw iry adi . bac aber ita . domain . Article SearchResult Ċ import Ġcom . ke fas jw iry adi . bac aber ita . network . News ApiService Ċ import Ġcom . ke fas jw iry adi . bac aber ita . util . Absent LiveData Ċ import Ġcom . ke fas jw iry adi . bac aber ita . util . clean Ċ import Ġcom . ke fas jw iry adi . bac aber ita . util . getContent Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġtim ber . log . Tim ber Ċ Ċ class ĠApp Repository ( ĊĠĠĠ Ġapp Database : ĠApp Database , ĊĠĠĠ Ġprivate Ġval Ġnews ApiService : ĠNews ApiService Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġarticle Dao Ġ= Ġapp Database . article Dao () ĊĊĠĠĠ Ġfun Ġget Articles ( category : ĠString ): ĠLive Data < List < Article >> Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠTransform ations . switch Map ( article Dao . get Articles ( category )) Ġ{ Ġarticle Fetch Result Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( article Fetch Result Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . get Articles By Urls Ordered ( article Fetch Result . article Urls ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAbs ent LiveData . create () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Favorite Articles (): ĠLive Data < List < Article >> Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġarticle Dao . get Favorite Articles () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġget Article Fetch Result ( category : ĠString ): ĠArticle Fetch Result ? Ġ= ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ with Context Ġarticle Dao . get Article Fetch Result ( category ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġrefresh Articles ( category : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" refresh Articles : Ġgetting Ġarticles Ġ$ category Ġfrom Ġnetwork ...") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarticles Container Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnews ApiService . get Articles ( category Ġ= Ġcategory , Ġpage Ġ= Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarticles Ġ= Ġarticles Container . articles ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticles . clean () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" refresh Articles : Ġarticles Ġfrom Ġnetwork : Ġ\ n \ t ${ articles [ 0 ] }\ n \ t ${ articles [ 1 ]}" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" refresh Articles : Ġclearing Ġdatabase ...") ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" refresh Articles : Ġinserting Ġarticles Ġto Ġdatabase ...") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . insert Articles ( articles ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . insert Article Fetch Result ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArticle Fetch Result ( category , Ġarticles . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . url ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, Ġarticles Container . total Results , Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" refresh Articles : Ġdone ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġload Next Page ( category : ĠString , Ġpage : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . d (" load Next Page : Ġ$ category Ġ$ page ") ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarticles Container Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnews ApiService . get Articles ( category Ġ= Ġcategory , Ġpage Ġ= Ġpage ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġarticles Ġ= Ġarticles Container . articles ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticles . clean () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . insert Articles ( articles ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMerge Ġresult Ġwith Ġprevious Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprevious Result Ġ= Ġarticle Dao . get Article Fetch Result ( category ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( previous Result Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġurls Ġ= ĠArrayList ( previous Result . article Urls ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġurls . addAll ( articles Container . articles . map Ġ{ Ġarticle Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarticle . url ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . insert Article Fetch Result ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArticle Fetch Result ( category , Ġurls , Ġarticles Container . total Results , Ġpage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġadd Favorite Article ( article : ĠArticle ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle . favorite Ġ= ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . insert Article ( article ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġremove Favorite Article ( article : ĠArticle ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle . favorite Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . insert Article ( article ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġinsert Article ( article : ĠArticle ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . insert Article ( article ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġsearch Articles ( query : ĠString , Ġpage : ĠInt ) Ġ= Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġarticles Network Container Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnews ApiService . search Articles ( query Ġ= Ġquery , Ġpage Ġ= Ġpage ) ĊĠĠĠĠĠĠĠ Ġval Ġarticles Ġ= Ġarticles Network Container . articles ĊĠĠĠĠĠĠĠ Ġarticles . clean () ĊĠĠĠĠĠĠĠ Ġreturn @ with Context ĠArticle SearchResult ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġquery , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticles , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticles Network Container . total Results , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpage ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġget Full Content ( article : ĠArticle ) Ġ= Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( article . content Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhtml Ġ= Ġnews ApiService . get Html ( article . url ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle . full Content Ġ= Ġhtml . getContent ( article . content !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġarticle Dao . insert Article ( article ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Article Ld ( url : ĠString ): ĠLive Data < Article > Ġ= Ġarticle Dao . get Article Ld ( url ) ĊĊĠĠĠ Ġsuspend Ġfun Ġget Article ( url : ĠString ): ĠArticle ? Ġ= Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn @ with Context Ġarticle Dao . get Article ( url ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ@ Volatile ĊĠĠĠĠĠĠĠ Ġprivate Ġvar ĠINSTANCE : ĠApp Repository ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġfun Ġget Repository ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapp Database : ĠApp Database , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnews ApiService : ĠNews ApiService ĊĠĠĠĠĠĠĠ Ġ): ĠApp Repository Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġlocal Instance Ġ= ĠINSTANCE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( local Instance Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Instance Ġ= ĠApp Repository ( app Database , Ġnews ApiService ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠINSTANCE Ġ= Ġlocal Instance ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlocal Instance ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} Ċ Ċ }