/* Ċ Ġ* ĠMIT ĠLicense Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 1 . ĠM ak sym ĠO li iny k . Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ġall Ċ Ġ* Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN ĠTHE Ċ Ġ* ĠSOFTWARE . Ċ Ġ*/ Ċ Ċ @ file : Suppress (" FunctionName ") Ċ Ċ package Ġcom . max . reader . app . update Ċ Ċ import Ġcom . max . reader . Build Config Ċ import Ġcom . max . reader . app .* Ċ import Ġcom . max . reader . app . message .* Ċ import Ġcom . max . reader . screens . article . details . Article Details State Ċ import Ġcom . max . reader . screens . article . list . Articles State Ċ import Ġcom . max . reader . screens . article . list . Query Ċ import Ġcom . max . reader . screens . article . list . Query Type Ċ import Ġcom . max . reader . screens . article . list . Query Type .* Ċ import Ġcom . max . reader . screens . settings . Settings State Ċ import Ġcom . oli yn ick . max . tea . core . component . Update With Ċ import Ġcom . oli yn ick . max . tea . core . component . command Ċ import Ġcom . oli yn ick . max . tea . core . component . no Command Ċ Ċ fun Ġinterface ĠApp Navigation Ġ{ ĊĊĠĠĠ Ġfun Ġnavigate ( ĊĠĠĠĠĠĠĠ Ġnav : ĠNavigation , ĊĠĠĠĠĠĠĠ Ġstate : ĠApp State , ĊĠĠĠ Ġ): ĠUpdate With < AppState , ĠCommand > Ċ } Ċ Ċ fun ĠApp Navigation () Ġ= ĠApp Navigation Ġ{ Ġnav , Ġstate Ġ-> ĊĠĠĠ Ġwhen Ġ( nav ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġgson Ġserializer Ġbreaks Ġsing letons Ġidentity , Ġthus Ġwe Ġshould Ġrely Ġon Ġ` is ` Ġcheck Ġrather ĊĠĠĠĠĠĠĠ Ġ// Ġthen Ġrefer ential Ġequality ĊĠĠĠĠĠĠĠ Ġis ĠNavigate To Feed Ġ-> Ġstate . push Bottom Navigation Screen ( nav , ĠQuery (" android ", ĠRegular )) ĊĠĠĠĠĠĠĠ Ġis ĠNavigate To Favorite Ġ-> Ġstate . push Bottom Navigation Screen ( nav , ĠQuery ("", ĠF avorite )) ĊĠĠĠĠĠĠĠ Ġis ĠNavigate To Trend ing Ġ-> Ġstate . push Bottom Navigation Screen ( nav , ĠQuery ("", ĠT rend ing )) ĊĠĠĠĠĠĠĠ Ġis ĠNavigate To Article Details Ġ-> Ġstate . push Article Details Screen ( nav ) ĊĠĠĠĠĠĠĠ Ġis ĠNavigate To Settings Ġ-> Ġstate . push Bottom Navigation Screen For Settings ( nav ) ĊĠĠĠĠĠĠĠ Ġis ĠPop Ġ-> Ġstate . pop () ĊĠĠĠ Ġ} Ċ } Ċ Ċ // Ġtodo Ġrefactor , Ġimplement Ġusing Ġanother Ġapproach Ċ // Ġif Ġwe Ġencounter Ġany Ġscreen Ġout Ġof Ġbottom Ġbar Ġscreens , Ġwe Ġjust Ġclose Ġthe Ġapp ; Ċ // Ġwe Ġpop Ġthe Ġlast Ġscreen Ġin Ġanother Ġcase Ċ fun ĠApp State . pop () Ġ= ĊĠĠĠ Ġif Ġ( screens . last (). is Bottom Bar Screen ) Ġthis Ġcommand ĠClose App ĊĠĠĠ Ġelse Ġpop Screen (). no Command () Ċ Ċ fun ĠApp State . push Article Details Screen ( ĊĠĠĠ Ġnav : ĠNavigate To Article Details , Ċ ) Ġ= Ġpush Screen ( Article Details State ( nav . id , Ġnav . article )). no Command () Ċ Ċ fun ĠApp State . push Bottom Navigation Screen For Settings ( ĊĠĠĠ Ġnav : ĠNavigate To Settings , Ċ ): ĠUpdate With < AppState , ĠCommand > Ġ= ĊĠĠĠ Ġpush Screen IfNot Exists With State ( nav ) Ġ{ ĠSettings State Ġ} ĊĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġ( newState , Ġ_) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build Config . DEBUG ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Settings Scre ens Number ( newState , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ċ Ċ inline Ġfun ĠApp State . push Screen IfNot Exists With State ( ĊĠĠĠ Ġnav : ĠNavigation , ĊĠĠĠ Ġcross inline Ġscreen With Command : Ġ() Ġ-> ĠScreen State , Ċ ): ĠUpdate With < AppState , ĠCommand > Ġ= ĊĠĠĠ Ġpush Screen IfNot Exists ( nav ) Ġ{ Ġscreen With Command () Ġto Ġempty Set () Ġ} Ċ Ċ inline Ġfun ĠApp State . push Screen IfNot Exists ( ĊĠĠĠ Ġnav : ĠNavigation , ĊĠĠĠ Ġcross inline Ġscreen With Command : Ġ( Screen Id ) Ġ-> ĠUpdate With < Screen State , ĠCommand >, Ċ ): ĠUpdate With < AppState , ĠCommand > Ġ{ ĊĠĠĠ Ġval Ġi Ġ= Ġfind Existing Screen For Navigation ( nav ) ĊĠĠĠ Ġval Ġscreen To Command Ġby Ġlazy ( Lazy Thread Safety Mode . NONE ) Ġ{ Ġscreen With Command ( nav . id ) Ġ} ĊĠĠĠ Ġval Ġswap Ġ= Ġi Ġ>= Ġ 0 ĊĠĠĠ Ġval ĠnewState Ġ= Ġif Ġ( swap ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġmove Ġcurrent Ġscreen Ġto Ġthe Ġend Ġof Ġscreens Ġstack , ĊĠĠĠĠĠĠĠ Ġ// Ġso Ġthat Ġit 'll Ġbe Ġpop ped Ġout Ġfirst ĊĠĠĠĠĠĠĠ Ġswap With Last ( i ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġpush Screen ( screen To Command . first ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġif Ġ( swap ) ĠnewState . no Command () ĊĠĠĠ Ġelse ĠnewState Ġcommand Ġscreen To Command . second Ċ } Ċ Ċ fun ĠApp State . push Bottom Navigation Screen ( ĊĠĠĠ Ġnav : ĠNavigation , ĊĠĠĠ Ġquery : ĠQuery , Ċ ): ĠUpdate With < AppState , ĠCommand > Ġ= ĊĠĠĠ Ġpush Screen IfNot Exists ( nav ) Ġ{ Ġscreen Id Ġ-> ĊĠĠĠĠĠĠĠ ĠArticles State . new Loading ( screen Id , Ġquery ) Ġcommand ĠLoad Articles By Query ( screen Id , Ġquery ) ĊĠĠĠ Ġ}. also Ġ{ Ġ( newState , Ġ_) Ġ-> ĊĠĠĠĠĠĠĠ Ġif Ġ( Build Config . DEBUG ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Articles Scre ens Number ( nav , Ġquery , ĠnewState , Ġthis ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ fun ĠApp State . find Existing Screen For Navigation ( ĊĠĠĠ Ġnav : ĠNavigation , Ċ ): ĠInt Ġ= Ġscreens . indexOf First Ġ{ Ġs Ġ-> Ġnav . id Ġ== Ġs . id Ġ} Ċ Ċ private Ġinline Ġval ĠScreen State . is Bottom Bar Screen : ĠBoolean ĊĠĠĠ Ġget () Ġ= Ġthis Ġis ĠArticles State Ġ|| Ġthis Ġis ĠSettings State Ċ Ċ private Ġfun Ġcheck Articles Scre ens Number ( ĊĠĠĠ Ġnav : ĠNavigation , ĊĠĠĠ Ġquery : ĠQuery , ĊĠĠĠ ĠnewState : ĠApp State , ĊĠĠĠ Ġold State : ĠApp State , Ċ ) Ġ{ ĊĠĠĠ Ġval Ġgrouped Ġ= ĠnewState . screens . groupBy Ġ{ Ġscreen Ġ-> Ġ( screen Ġas ? ĠArticles State )?. query ?. type Ġ} ĊĊĠĠĠ Ġval Ġpredicate Ġ= ĊĠĠĠĠĠĠĠ ĠQuery Type . values (). map Ġ{ Ġtype Ġ-> Ġgrouped [ type ]?. size Ġ?: Ġ 0 Ġ}. all Ġ{ Ġsize Ġ-> Ġsize Ġ<= Ġ 1 Ġ} ĊĊĠĠĠ Ġcheck ( predicate ) Ġ{ ĊĠĠĠĠĠĠĠ ĠWrong Scre ens Number ErrorMessage ( nav , Ġquery , ĠnewState , Ġold State ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġcheck Settings Scre ens Number ( ĊĠĠĠ ĠnewState : ĠApp State , ĊĠĠĠ Ġold State : ĠApp State , Ċ ) Ġ= ĊĠĠĠ Ġcheck ( newState . screens . count Ġ{ Ġscreen Ġ-> Ġscreen Ġis ĠSettings State Ġ} Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠ ĠWrong Settings Scre ens Number ErrorMessage ( newState , Ġold State ) ĊĠĠĠ Ġ} Ċ Ċ private Ġfun ĠWrong Settings Scre ens Number ErrorMessage ( ĊĠĠĠ ĠnewState : ĠApp State , ĊĠĠĠ Ġold State : ĠApp State , Ċ ) Ġ= Ġ" Wrong Ġnumber Ġof Ġsettings Ġscreens Ġafter Ġupdate ," Ġ+ ĊĠĠĠĠĠĠĠ Ġ" new Ġstate : Ġ$ newState ,\ n old Ġstate : Ġ$ old State " Ċ Ċ private Ġfun ĠWrong Scre ens Number ErrorMessage ( ĊĠĠĠ Ġnav : ĠNavigation , ĊĠĠĠ Ġquery : ĠQuery , ĊĠĠĠ ĠnewState : ĠApp State , ĊĠĠĠ Ġold State : ĠApp State , Ċ ) Ġ= Ġ" Wrong Ġnumber Ġof Ġbottom Ġnavigation Ġscreens Ġafter Ġnavigation Ġupdate : Ġ" Ġ+ ĊĠĠĠĠĠĠĠ Ġ"$ nav ,\ n query : Ġ$ query ,\ n new Ġstate : Ġ$ newState ,\ n old Ġstate : Ġ$ old State " Ċ Ċ private Ġfun ĠLoad Articles By Query ( ĊĠĠĠ Ġid : ĠScreen Id , ĊĠĠĠ Ġquery : ĠQuery , ĊĠĠĠ Ġresults PerPage : ĠInt Ġ= ĠArticles State . Articles PerPage , Ċ ) Ġ= ĠLoad Articles By Query ( id , Ġquery , Ġ 0 , Ġresults PerPage ) Ċ