package Ġcom . d ari op elle gr ini . decl ar ativ er ec y cl er Ċ Ċ import Ġandroid . util . Log Ċ import Ġandroidx . recyclerview . widget . Diff Util Ċ import Ġandroidx . recyclerview . widget . RecyclerView Ċ import Ġcom . d ari op elle gr ini . decl ar ativ er ec y cl er . decorator . Header Item Decoration Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . with Context ĊĊ Ċ class ĠDiff Recycler Manager < T >( val Ġre cyclerView : ĠRecyclerView , Ġlayout Manager : ĠRecyclerView . LayoutManager ) Ġwhere ĠT Ġ: ĠRow , ĠT Ġ: ĠDifferent iable < T > Ġ{ ĊĠĠĠ Ġval Ġrows Ġ= Ġmutable ListOf < T >() ĊĠĠĠ Ġvar Ġshould Scroll Ġ= Ġfalse ĊĊĠĠĠ Ġprivate Ġval Ġadapter : ĠRe cycler Manager Adapter ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġadapter Ġ= ĠRe cycler Manager Adapter ( rows ) ĊĠĠĠĠĠĠĠ Ġre cyclerView . layout Manager Ġ= Ġlayout Manager ĊĠĠĠĠĠĠĠ Ġre cyclerView . adapter Ġ= Ġadapter ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠAdd ĊĠĠĠ Ġfun Ġadd ( row : ĠT , Ġposition : ĠInt , Ġscroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreload ( rows . to Mutable List (). apply Ġ{ Ġadd ( position , Ġrow ) Ġ}) ĊĠĠĠĠĠĠĠ Ġif Ġ( scroll ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġre cyclerView . scrollTo Position ( position ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpush ( row : ĠT , Ġscroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġadd ( row , Ġ 0 , Ġscroll ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġappend ( row : ĠT , Ġscroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġadd ( row , Ġrows Size , Ġscroll ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠAdd Ġlists ĊĠĠĠ Ġfun Ġadd ( rows List : ĠList < T >, Ġposition : ĠInt , Ġscroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreload ( rows . to Mutable List (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd All ( position , Ġrows List ) ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġif Ġ( scroll ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġre cyclerView . scrollTo Position ( position ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpush ( rows List : ĠList < T >, Ġscroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġadd ( rows List , Ġ 0 , Ġscroll ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġappend ( rows List : ĠList < T >, Ġscroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġadd ( rows List , Ġrows Size , Ġscroll ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠRemove ĊĠĠĠ Ġfun Ġremove ( row : ĠT , Ġscroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġposition Ġ= Ġrows . indexOf ( row ) ĊĠĠĠĠĠĠĠ Ġif Ġ( position Ġ> Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreload ( rows . to Mutable List (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove At ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scroll ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre cyclerView . scrollTo Position ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove ( position : ĠInt , Ġscroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( rows . size Ġ> Ġposition ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreload ( rows . to Mutable List (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremove At ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scroll ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre cyclerView . scrollTo Position ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpop ( scroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġremove ( 0 , Ġscroll ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove Last ( scroll : ĠBoolean Ġ= Ġshould Scroll ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( last Position Ġ> Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremove ( last Position , Ġscroll ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ// ĠRemove Ġlist ĊĠĠĠ Ġfun Ġremove ( closure : Ġ( T ) Ġ-> ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreload ( rows . filter ( closure )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove ( rows List : ĠList < T >) Ġ{ ĊĠĠĠĠĠĠĠ Ġreload ( rows . filter Ġ{ Ġ! rows List . contains ( it ) Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove ( from : ĠInt , Ġto : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( rows . size Ġ> Ġfrom Ġ&& Ġrows . size Ġ> Ġto ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreload ( rows . sub List ( from , Ġto )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" Decl arative Recycler ", Ġ" Check Ġrange Ġsize Ġand Ġrow Ġsize . ĠOut Ġof Ġbounds ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠClear ĊĠĠĠ Ġfun Ġclear () Ġ{ ĊĠĠĠĠĠĠĠ Ġreload ( listOf ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠRe load ĊĠĠĠ Ġfun Ġreload ( new Rows : ĠList < T >, Ġscroll : ĠScroll Type ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġscroll If Ne cessary Ġ= Ġscroll Ġ!= Ġnull Ġ&& Ġnew Rows . size Ġ> Ġrows . size ĊĠĠĠĠĠĠĠ Ġval Ġdiff Result Ġ= ĠDiff Util . calculate Diff ( Recycler Diff Callback ( rows , Ġnew Rows )) ĊĠĠĠĠĠĠĠ Ġrows . clear () ĊĠĠĠĠĠĠĠ Ġrows . addAll ( new Rows ) ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdiff Result . dispatch Updates To ( adapter ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scroll If Ne cessary ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( scroll ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠScroll Type . S MO OTH Ġ-> Ġre cyclerView . smooth Scroll To Position ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠScroll Type . INST ANT Ġ-> Ġre cyclerView . scrollTo Position ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" Diff Recycler Manager ", Ġ"$ e ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġsuspend Reload ( new Rows : ĠList < T >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdiff Result Ġ= Ġwith Context ( Dispatch ers . Default ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDiff Util . calculate Diff ( Recycler Diff Callback ( rows , Ġnew Rows )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrows . clear () ĊĠĠĠĠĠĠĠ Ġrows . addAll ( new Rows ) ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdiff Result . dispatch Updates To ( adapter ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" Diff Recycler Manager ", Ġ"$ e ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġreload ( var arg Ġnew Rows : ĠT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreload ( new Rows . toList ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠProperties ĊĠĠĠ Ġval Ġrows Size : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġrows . size ĊĊĠĠĠ Ġval Ġlast Position : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġrows Size Ġ- Ġ 1 ĊĊĠĠĠ Ġ// ĠSt icky ĠHeader ĊĠĠĠ Ġfun Ġconfigure Sticky Headers () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdecorator Ġ= ĠHeader Item Decoration ( re cyclerView ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrows . size Ġ> Ġit Ġ&& Ġ( rows [ it ] Ġas ? ĠSt icky Header )?. is Sticky Header Ġ== Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġre cyclerView . addItem Decoration ( decorator ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠDecor ation ĊĠĠĠ Ġfun Ġadd Decoration ( item Decoration : ĠRecyclerView . Item Decoration ) Ġ{ ĊĠĠĠĠĠĠĠ Ġre cyclerView . addItem Decoration ( item Decoration ) ĊĠĠĠ Ġ} Ċ }