package Ġdol phin . android . apps . Blood Service App Ċ Ċ import Ġandroid . util . Sparse Array Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . lifecycle . Saved State Handle Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġdol phin . android . apps . Blood Service App . provider . Blood Center Ċ import Ġdol phin . android . apps . Blood Service App . provider . Blood Data Parser Ċ import Ġdol phin . android . apps . Blood Service App . provider . Don ate Day Ċ import Ġdol phin . android . apps . Blood Service App . provider . Spot List Ċ import Ġdol phin . android . apps . Blood Service App . ui . Ui State Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . flow . Mutable State Flow Ċ import Ġkotlinx . coroutines . flow . Sharing Started Ċ import Ġkotlinx . coroutines . flow . State Flow Ċ import Ġkotlinx . coroutines . flow . flow Ċ import Ġkotlinx . coroutines . flow . flow On Ċ import Ġkotlinx . coroutines . flow . state In Ċ Ċ /** Ċ Ġ* ĠApp Ġdata Ġ[ ViewModel ] Ġin Ġ[ Saved State Handle ]. Ċ Ġ* Ċ Ġ* Ġ@ param Ġsaved State Ġsaved Ġapp Ġstate Ċ Ġ*/ Ċ class ĠApp DataModel ( private Ġval Ġsaved State : ĠSaved State Handle ) Ġ: ĠViewModel () Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠKEY _ UI _ STATE Ġ= Ġ" ui _ state " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġflag Ġof Ġapp Ġabout ĠFirebase ĠRemote Config Ġload Ġup . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġready Ġ= ĠMutable LiveData ( false ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġflag Ġof Ġapp Ġabout Ġsystem Ġdark Ġmode Ġis Ġenabled Ġor Ġnot ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġdark Mode Ġ= ĠMutable State Flow ( false ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġflag Ġto Ġshow / hide Ġprivacy Ġreview Ġpane ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġshow Privacy Review Ġ= ĠMutable State Flow ( false ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġflag Ġto Ġshow / hide Ġmobile Ġads ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġshow Ads Ġ= ĠMutable State Flow ( true ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApp ĠUI Ġstate . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġui State : ĠLive Data < Ui State > Ġ= Ġsaved State . get LiveData ( KEY _ UI _ STATE ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠInternal Ġapp Ġui Ġstate ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġstate : ĠUi State ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġui State . value Ġ?: ĠUi State . Main ĊĠĠĠĠĠĠĠ Ġprivate Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsaved State . set ( KEY _ UI _ STATE , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChange Ġapp Ġui Ġstate ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġstate Ġtarget Ġapp Ġui Ġstate ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġchange Ui State ( state : ĠUi State ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . state Ġ= Ġstate ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSelected Ġblood Ġcenter ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġcenter Ġ= ĠMutable LiveData < Blood Center . Center >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠInitialize Ġthe Ġparser Ġand Ġother Ġdata Ġinstance . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġparser Ġa Ġhelper Ġinstance Ġto Ġread Ġdata Ġfrom Ġinternet ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġhelper Ġis Ġready ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġinit ( parser : ĠB lood Data Parser ): ĠState Flow < Boolean > Ġ= Ġflow Ġ{ ĊĠĠĠĠĠĠĠ Ġparser . warm Up () ĊĠĠĠĠĠĠĠ Ġemit ( true ) ĊĠĠĠ Ġ}. flow On ( Dispatch ers . IO ). state In ( ĊĠĠĠĠĠĠĠ Ġscope Ġ= ĠviewModel Scope , ĊĠĠĠĠĠĠĠ Ġstarted Ġ= ĠSh aring Started . E ager ly , ĊĠĠĠĠĠĠĠ Ġinitial Value Ġ= Ġfalse , ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġvar Ġstorage Cache : ĠSparse Array < HashMap < String , ĠInt >> ? Ġ= Ġnull ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġstorage Ġdata Ġfrom Ġinternet ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġparser Ġa Ġhelper Ġinstance Ġto Ġread Ġdata Ġfrom Ġinternet ĊĠĠĠĠ Ġ* Ġ@ param Ġforce Refresh Ġtrue Ġif Ġwe Ġwant Ġto Ġdownload Ġlatest Ġdata Ġfrom Ġinternet ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġupdate Ġis Ġin Ġprogress ing ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Storage Data ( ĊĠĠĠĠĠĠĠ Ġparser : ĠB lood Data Parser , ĊĠĠĠĠĠĠĠ Ġforce Refresh : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠ Ġcenter Id : ĠInt Ġ= Ġ- 1 , ĊĠĠĠ Ġ): ĠState Flow < Boolean > Ġ= Ġflow Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( storage Cache Ġ== Ġnull Ġ|| Ġforce Refresh ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemit Storage Map ( HashMap ()) Ġ// Ġclear Ġthe Ġlist ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstorage Cache Ġ= Ġparser . getB lood Storage ( force Refresh ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġstorage Cache ?. let Ġ{ Ġcache Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( center Id Ġ> Ġ 0 ) Ġemit Storage Map ( cache [ center Id ] Ġ?: ĠHashMap ()) ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġkotlin . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemit Storage Map ( HashMap ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġemit ( false ) ĊĠĠĠ Ġ}. flow On ( Dispatch ers . IO ). state In ( ĊĠĠĠĠĠĠĠ Ġscope Ġ= ĠviewModel Scope , ĊĠĠĠĠĠĠĠ Ġstarted Ġ= ĠSh aring Started . E ager ly , ĊĠĠĠĠĠĠĠ Ġinitial Value Ġ= Ġtrue , ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġval Ġstorage s Ġ= ĠMutable State Flow < HashMap < String , ĠInt >>( HashMap ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġstorage Ġcache Ġlive Ġdata Ġto Ġupdate Ġcompose Ġui . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġstorage Map : ĠState Flow < HashMap < String , ĠInt >> Ġ= Ġstorage s ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUpdate Ġstorage Ġdata Ġto Ġcompose Ġui . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġmaps Ġtarget Ġblood Ġcenter Ġstorage ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġemit Storage Map ( maps : ĠHashMap < String , ĠInt >) Ġ{ ĊĠĠĠĠĠĠĠ Ġstorage s . emit ( maps ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġdon ation Cache Ġ= ĠSparse Array < List < Don ate Day >>() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġdon ation Ġlist Ġfrom Ġinternet . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġparser Ġa Ġhelper Ġinstance Ġto Ġread Ġdata Ġfrom Ġinternet ĊĠĠĠĠ Ġ* Ġ@ param Ġid Ġtarget Ġblood Ġcenter Ġid ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġupdate Ġis Ġin Ġprogress ing ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Don ation Data ( ĊĠĠĠĠĠĠĠ Ġparser : ĠB lood Data Parser , ĊĠĠĠĠĠĠĠ Ġid : ĠInt Ġ= Ġcenter . value ?. id Ġ?: Ġ- 1 ĊĠĠĠ Ġ): ĠState Flow < Boolean > Ġ= Ġflow Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( don ation Cache [ id ] Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ days List . emit ( ArrayList ()) Ġ// Ġclear Ġthe Ġlist ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdon ation Cache . put ( id , Ġparser . get Latest Week Calendar ( id )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ_ days List . emit ( don ation Cache [ id ]) ĊĠĠĠĠĠĠĠ Ġemit ( false ) ĊĠĠĠ Ġ}. flow On ( Dispatch ers . IO ). state In ( ĊĠĠĠĠĠĠĠ Ġscope Ġ= ĠviewModel Scope , ĊĠĠĠĠĠĠĠ Ġstarted Ġ= ĠSh aring Started . E ager ly , ĊĠĠĠĠĠĠĠ Ġinitial Value Ġ= Ġtrue , ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġval Ġ_ days List Ġ= ĠMutable State Flow < List < Don ate Day >>( ArrayList ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġdon ation Ġlist Ġlive Ġdata Ġto Ġupdate Ġcompose Ġui . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġdays List : ĠState Flow < List < Don ate Day >> Ġ= Ġ_ days List ĊĊĠĠĠ Ġprivate Ġval Ġspot City Cache Ġ= ĠSparse Array < ArrayList < Spot List >>() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġdon ation Ġspot Ġlist Ġfrom Ġinternet . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġparser Ġa Ġhelper Ġinstance Ġto Ġread Ġdata Ġfrom Ġinternet ĊĠĠĠĠ Ġ* Ġ@ param Ġid Ġtarget Ġblood Ġcenter Ġid ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġupdate Ġis Ġin Ġprogress ing ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Spot List Data ( ĊĠĠĠĠĠĠĠ Ġparser : ĠB lood Data Parser , ĊĠĠĠĠĠĠĠ Ġid : ĠInt Ġ= Ġcenter . value ?. id Ġ?: Ġ- 1 ĊĠĠĠ Ġ): ĠState Flow < Boolean > Ġ= Ġflow Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( spot City Cache [ id ] Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlist Ġ= ĠArrayList < Spot List >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġemit Spot List ( list ) Ġ// Ġclear Ġthe Ġlist ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( order , Ġdata ) Ġ= Ġparser . get Don ation Spot Location Map ( id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder . forEach Ġ{ Ġid Ġ-> Ġlist . add ( data . get ( id )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġspot City Cache . put ( id , Ġlist ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġemit Spot List ( list Ġ= Ġspot City Cache [ id ]) ĊĠĠĠĠĠĠĠ Ġemit ( false ) ĊĠĠĠ Ġ}. flow On ( Dispatch ers . IO ). state In ( ĊĠĠĠĠĠĠĠ Ġscope Ġ= ĠviewModel Scope , ĊĠĠĠĠĠĠĠ Ġstarted Ġ= ĠSh aring Started . E ager ly , ĊĠĠĠĠĠĠĠ Ġinitial Value Ġ= Ġtrue , ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġval Ġ_ spot List Ġ= ĠMutable State Flow < List < Spot List >>( ArrayList ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġspot Ġlist Ġlive Ġdata Ġto Ġupdate Ġcompose Ġui . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġspot List : ĠState Flow < List < Spot List >> Ġ= Ġ_ spot List ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUpdate Ġspot Ġlist Ġto Ġcompose Ġui . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġlist Ġspot Ġlist Ġof Ġtarget Ġblood Ġcenter ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġemit Spot List ( list : ĠList < Spot List >) Ġ{ ĊĠĠĠĠĠĠĠ Ġ_ spot List . emit ( list ) ĊĠĠĠĠĠĠĠ Ġcurrent City . emit ( if Ġ( list . isNotEmpty ()) Ġlist . first (). city Id Ġelse Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġcurrent City Ġ= ĠMutable State Flow ( 0 ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCurrent Ġselected Ġcity . ĠOnly Ġuseful Ġin ĠSpot List Ui . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġcity : ĠState Flow < Int > Ġ= Ġcurrent City ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChange Ġa Ġnew Ġcity ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġcity Id Ġnew Ġcity ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġchange City ( city Id : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent City . value Ġ= Ġcity Id ĊĠĠĠ Ġ} Ċ } Ċ