package Ġcom . example . instagram _ clone _ clean _ architecture . app . presentation . activity Ċ Ċ import Ġandroid . net . Uri Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . lifecycle . Transform ations Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġcom . example . instagram _ clone _ clean _ architecture . App Nav Graph Directions Ċ import Ġcom . example . instagram _ clone _ clean _ architecture . app . domain . use case . Cache User Selected Image UseCase Ċ import Ġcom . example . instagram _ clone _ clean _ architecture . app . domain . use case . Get Cached Login User UseCase Ċ import Ġcom . example . library _ base . domain . exception . Failure Ċ import Ġcom . example . library _ base . presentation . navigation . Navigation Manager Ċ import Ġcom . example . library _ base . presentation . view model . Base Action Ċ import Ġcom . example . library _ base . presentation . view model . Base ViewModel Ċ import Ġcom . example . library _ base . presentation . view model . Base ViewState Ċ import Ġkotlinx . coroutines . Coroutine Dispatcher Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . launch Ċ Ċ class ĠMain ViewModel ( ĊĠĠĠ Ġprivate Ġval Ġnav Manager : ĠNavigation Manager , ĊĠĠĠ Ġprivate Ġval Ġcache User Selected Image UseCase : ĠCache User Selected Image UseCase , ĊĠĠĠ Ġprivate Ġval Ġget Cached Login User UseCase : ĠGet Cached Login User UseCase , ĊĠĠĠ Ġprivate Ġval Ġdefault Dispatcher : ĠCor outine Dispatcher Ġ= ĠDispatch ers . Main Ċ ) Ġ: ĠBase ViewModel < Main ViewModel . ViewState , ĠMain ViewModel . Action >( ĊĠĠĠ ĠView State () Ċ ) Ġ{ ĊĊĠĠĠ Ġval Ġis Login : ĠLive Data < Boolean > Ġ= ĠTransform ations . map ( state LiveData ) Ġ{ ĊĠĠĠĠĠĠĠ Ġit . local UserId Ġ!= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Navigate To Feed s () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state . local UserId Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Local ĠLogin ĠUser Ġid Ġshould Ġnot Ġbe Ġnull Ġin Ġ${ this :: class . java }") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnav Dir Ġ= ĠApp Nav Graph Directions . feature Feed s Nav Graph ( state . local UserId !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnav Manager . on Nav Event ( nav Dir ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Navigate To Profile () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( state . local UserId Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Local ĠLogin ĠUser Ġid Ġshould Ġnot Ġbe Ġnull Ġin Ġ${ this :: class . java }") ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnav Dir Ġ= ĠApp Nav Graph Directions . feature Profile Nav Graph ( state . local UserId !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnav Manager . on Nav Event ( nav Dir ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Navigate To Search () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnav Dir Ġ= ĠApp Nav Graph Directions . feature Search Nav Graph () ĊĠĠĠĠĠĠĠ Ġnav Manager . on Nav Event ( nav Dir ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcache User Selected Image ( image Uri : ĠUri ) Ġ= ĠviewModel Scope . launch ( default Dispatcher ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparam Ġ= ĠCache User Selected Image UseCase . Param ( image Uri ) ĊĊĠĠĠĠĠĠĠ Ġcache User Selected Image UseCase ( param ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġload Local UserData () Ġ= ĠviewModel Scope . launch ( default Dispatcher ) Ġ{ ĊĠĠĠĠĠĠĠ Ġget Cached Login User UseCase ( Unit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . fold ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Suc ceed Ġ= Ġ{ Ġuser Profile Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Action ( Action . Local UserData Loaded ( user Profile . id )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail Ġ= Ġ{ Ġfailure Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Action ( Action . Local UserData Loaded ( null )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Failure ( failure ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonLoad Data () Ġ{ ĊĠĠĠĠĠĠĠ Ġsend Action ( Action . Reload Data ) ĊĠĠĠĠĠĠĠ Ġload Local UserData () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Reduce State ( action : ĠAction ): ĠView State Ġ= Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠAction . Local UserData Loaded Ġ-> Ġstate . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Local UserData Loading Ġ= Ġfalse , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocal UserId Ġ= Ġaction . userId ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġis ĠAction . Fail On Local Account Error Ġ-> Ġstate . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Local Account Error Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġis ĠAction . Reload Data Ġ-> Ġstate . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Local UserData Loading Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Local Account Error Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġon Failure ( failure : ĠFailure ) Ġ= Ġwhen Ġ( failure ) Ġ{ ĊĠĠĠĠĠĠĠ Ġis ĠFailure . Local Account NotFound Ġ-> Ġsend Action ( Action . Fail On Local Account Error ) ĊĠĠĠĠĠĠĠ Ġis ĠFailure . Cache NotFound Ġ-> Ġsend Action ( Action . Fail On Local Account Error ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Unknown Ġfailure Ġ$ failure Ġin Ġ${ this :: class . java }") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠView State ( ĊĠĠĠĠĠĠĠ Ġval Ġis Local UserData Loading : ĠBoolean Ġ= Ġtrue , ĊĠĠĠĠĠĠĠ Ġval Ġis Local Account Error : ĠBoolean Ġ= Ġfalse , ĊĠĠĠĠĠĠĠ Ġval Ġlocal UserId : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġ) Ġ: ĠBase ViewState ĊĊĠĠĠ Ġsealed Ġclass ĠAction Ġ: ĠBase Action Ġ{ ĊĠĠĠĠĠĠĠ Ġclass ĠLocal UserData Loaded ( val ĠuserId : ĠString ?) Ġ: ĠAction () ĊĠĠĠĠĠĠĠ Ġobject ĠFail On Local Account Error Ġ: ĠAction () ĊĠĠĠĠĠĠĠ Ġobject ĠRe load Data Ġ: ĠAction () ĊĠĠĠ Ġ} Ċ Ċ }