package Ġcom . tk u hn . recipe finder . ui Ċ Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġcom . tk u hn . recipe finder . Esp ress o Id ling Resources Ċ import Ġcom . tk u hn . recipe finder . datasource . network . Resource Ċ import Ġcom . tk u hn . recipe finder . datasource . network . Resource Error Ċ import Ġcom . tk u hn . recipe finder . utils . Live Event Ċ import Ġcom . tk u hn . recipe finder . utils . extensions . set Distinct Value Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . flow . collect Ċ import Ġkotlinx . coroutines . launch Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ Ċ open Ġclass ĠBase ViewModel Ġ: ĠViewModel () Ġ{ ĊĊĠĠĠ Ġval Ġsn ack Message Ġ= ĠLive Event < String >() ĊĠĠĠ Ġval ĠisLoading Ġ= ĠMutable LiveData < Boolean >() ĊĠĠĠ Ġval Ġhide Keyboard Event Ġ= ĠLive Event < Void >() ĊĠĠĠ Ġprivate Ġval Ġload Data Ids Ġ= Ġmutable Map Of < Mutable LiveData < Boolean >, ĠMutable Set < Int >>() ĊĊĠĠĠ Ġprotected Ġfun Ġ< T > Ġload ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput : ĠFlow < Resource < T >>, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġloading : ĠMutable LiveData < Boolean > Ġ= ĠisLoading , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠonSuccess : Ġ(() Ġ-> ĠUnit )? Ġ= Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠonError : Ġ(( error : ĠResource Error ) Ġ-> ĠUnit )? Ġ= Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Data : Ġ(( data : ĠT ) Ġ-> ĠUnit )? Ġ= Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Background : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠE sp ress o Id ling Resources . increment () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġes press o De crement ed Ġ= ĠAtomic Boolean () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput . collect Ġ{ Ġresource Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( resource ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Success Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Success Ġwith Ġdata Ġdata : Ġ${ resource . data }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonSuccess ?. invoke () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! on Background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Is Loading Change ( id , Ġloading , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( espress o De crement ed . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠE sp ress o Id ling Resources . decrement () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Error ĠĠ Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerror Ġ= Ġresource . error ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Error Ġbecause Ġof Ġ$ error ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonError ?. invoke ( resource . error ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! on Background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsn ack Message . value Ġ= Ġerror . message ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Is Loading Change ( id , Ġloading , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( espress o De crement ed . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠE sp ress o Id ling Resources . decrement () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Loading Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Loading ...") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! on Background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Is Loading Change ( id , Ġloading , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresource . data ?. let Ġ{ Ġdata Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Data ?. invoke ( data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġon Is Loading Change ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġloading : ĠMutable LiveData < Boolean >, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis InProgress : ĠBoolean ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is InProgress ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġload Data Ids . get Or Put ( loading , Ġ{ Ġmutable Set Of () Ġ}). add ( id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġloading . set Distinct Value ( true ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġload Data Ids [ loading ]?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . remove ( id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Data Ids . remove ( loading ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloading . set Distinct Value ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġfun Ġhide Keyboard () Ġ{ ĊĠĠĠĠĠĠĠ Ġhide Keyboard Event . call () ĊĠĠĠ Ġ} Ċ } Ċ