package Ġcom . bern af err ari . change detection . detail st ext Ċ Ċ import Ġandroid . app . Application Ċ import Ġandroidx . lifecycle . Android ViewModel Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġandroidx . paging . Live Paged List Builder Ċ import Ġandroidx . paging . Paged List Ċ import Ġcom . bern af err ari . change detection . data . Snap Ċ import Ġcom . bern af err ari . change detection . data . source . Snap s Repository Ċ import Ġcom . bern af err ari . change detection . extensions . getPosition For Adapter Ċ import Ġcom . bern af err ari . change detection . extensions . remove Cl utter And Be aut ify Html If Ne cessary Ċ import Ġcom . bern af err ari . change detection . extensions . un escape Html Ċ import Ġcom . bern af err ari . change detection . group ie . Text Recycler Ċ import Ġcom . bern af err ari . change detection . util . Single Live Event Ċ import Ġcom . bern af err ari . diff utils . dif fs . text . Diff Row Generator Ċ import Ġcom . x wr ay . group ie . Section Ċ import Ġkotlinx . coroutines .* Ċ import Ġjava . nio . charset . Charset Ċ import Ġkotlin . coroutines . Coroutine Context Ċ Ċ /** Ċ Ġ* ĠEx poses Ġthe Ġdata Ġto Ġbe Ġused Ġin Ġthe Ġsite Ġdiff Ġscreen . Ċ Ġ*/ Ċ class ĠText ViewModel ( ĊĠĠĠ Ġcontext : ĠApplication , ĊĠĠĠ Ġprivate Ġval Ġm Snap s Repository : ĠSnap s Repository Ċ ) Ġ: ĠAndroid ViewModel ( context ), ĠCor outine Scope Ġ{ ĊĊĠĠĠ Ġval Ġshow Not En ough Info Error Ġ= ĠSingle Live Event < Boolean >() ĊĠĠĠ Ġval Ġshow No Changes Detected Error Ġ= ĠSingle Live Event < Void >() ĊĠĠĠ Ġval Ġshow Progress Ġ= ĠSingle Live Event < Void >() ĊĊĠĠĠ Ġprivate Ġvar Ġjob : ĠJob Ġ= ĠJob () ĊĊĠĠĠ Ġoverride Ġval Ġcoroutine Context : ĠCor outine Context ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠDispatch ers . Main Ġ+ Ġjob ĊĊĠĠĠ Ġoverride Ġfun Ġon Cle ared () Ġ{ ĊĠĠĠĠĠĠĠ Ġjob . cancel () ĊĠĠĠĠĠĠĠ Ġsuper . on Cle ared () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġto Ġremove Ġa Ġdiff ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġid ĠThe Ġdiff Ġurl Ġto Ġbe Ġremoved . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġremove Snap ( id : ĠString ?) Ġ= ĠGlobal Scope . launch Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( id Ġ!= Ġnull ) Ġm Snap s Repository . delete Snap ( id ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġcurrent Job : ĠJob ? Ġ= Ġnull ĊĠĠĠ Ġvar Ġchange Plus Original : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġwhen Ġwe Ġwant Ġto Ġgenerate Ġa Ġdiff Ġbetween Ġtwo Ġitems . ĠTakes Ġas Ġinput Ġtwo Ġids Ġand Ġthe Ġtop ĊĠĠĠĠ Ġ* Ġsection Ġand Ġoutputs Ġthe Ġresult Ġto Ġthis Ġtop Ġsection . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġtop Section ĠĠĠ ĠThe Ġsection Ġcorresponding Ġto Ġthe Ġtop Ġre cycler view , Ġwhich Ġwill ĊĠĠĠĠ Ġ* Ġbe Ġupdated Ġwith Ġthe Ġresult Ġfrom Ġthe Ġdiff . ĊĠĠĠĠ Ġ* Ġ@ param Ġoriginal Id ĠĠĠ ĠThe Ġsnap Id Ġfrom Ġthe Ġoriginal Ġitem Ġ( which Ġwill Ġbe Ġin Ġred ) ĊĠĠĠĠ Ġ* Ġ@ param Ġrev ised Id ĠĠĠĠ ĠThe Ġsnap Id Ġfrom Ġthe Ġrev ised Ġitem Ġ( which Ġwill Ġbe Ġin Ġgreen ) ĊĠĠĠĠ Ġ* Ġwhich Ġwill Ġbe Ġupdated Ġby Ġ[ generate Diff ] Ġwith Ġcorresponding Ġdiff ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġgenerate Diff ( top Section : ĠSection , Ġoriginal Id : ĠString ?, Ġrev ised Id : ĠString ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Job ?. cancel () ĊĠĠĠĠĠĠĠ Ġif Ġ( original Id . isNull Or Blank () Ġ|| Ġrev ised Id . isNull Or Blank ()) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmutable ListOf < Text Recycler >(). also Ġ{ Ġmutable List Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmutable List . addAll ( mutable ListOf ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthis Ġway Ġit Ġcaptures Ġif Ġshow Not En ough Info Error Ġis Ġnull Ġor Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( show Not En ough Info Error . value Ġ!= Ġtrue Ġ&& Ġmutable List . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow No Changes Detected Error . call () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtop Section . update ( mutable ListOf ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcurrent Job Ġ= Ġlaunch ( Dispatch ers . Main ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( original , Ġnew ) Ġ= Ġget From Db ( original Id , Ġrev ised Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( only Diff , Ġnon Diff ) Ġ= Ġgenerate Diff Rows ( original , Ġnew ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmutable List Ġ= Ġmutable ListOf < Text Recycler >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( change Plus Original ) Ġmutable List . addAll ( non Diff ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmutable List . addAll ( only Diff ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmutable List . sortBy Ġ{ Ġitem Ġ-> Ġitem . index Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthis Ġway Ġit Ġcaptures Ġif Ġshow Not En ough Info Error Ġis Ġnull Ġor Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( show Not En ough Info Error . value Ġ!= Ġtrue Ġ&& Ġmutable List . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow No Changes Detected Error . call () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThere Ġis Ġa Ġbug Ġon ĠGroup ie Ġ 2 . 1 . 0 Ġwhich Ġis Ġrendering Ġthe Ġdiff Ġoperation Ġon ĠUI Ġthread . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġremove Ġ+ Ġinsert Ġis Ġche aper Ġthan Ġchecking Ġif Ġthere Ġwas Ġa Ġchange Ġon Ġthousands Ġof Ġlines . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtop Section . update ( mutable ListOf ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtop Section . update ( mutable List ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġwhen Ġwe Ġwant Ġto Ġgenerate Ġa Ġdiff Ġbetween Ġtwo Ġitems . ĠTakes Ġas Ġinput Ġtwo Ġids Ġand Ġthe Ġtop ĊĠĠĠĠ Ġ* Ġsection Ġand Ġoutputs Ġthe Ġresult Ġto Ġthis Ġtop Ġsection . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġtop Section ĠĠĠ ĠThe Ġsection Ġcorresponding Ġto Ġthe Ġtop Ġre cycler view , Ġwhich Ġwill ĊĠĠĠĠ Ġ* Ġbe Ġupdated Ġwith Ġthe Ġresult Ġfrom Ġthe Ġdiff . ĊĠĠĠĠ Ġ* Ġ@ param Ġoriginal Id ĠĠĠ ĠThe Ġsnap Id Ġfrom Ġthe Ġoriginal Ġitem Ġ( which Ġwill Ġbe Ġin Ġred ) ĊĠĠĠĠ Ġ* Ġ@ param Ġrev ised Id ĠĠĠĠ ĠThe Ġsnap Id Ġfrom Ġthe Ġrev ised Ġitem Ġ( which Ġwill Ġbe Ġin Ġgreen ) ĊĠĠĠĠ Ġ* Ġwhich Ġwill Ġbe Ġupdated Ġby Ġ[ generate Diff ] Ġwith Ġcorresponding Ġdiff ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġgenerate Diff Visual ( original Id : ĠString ?, Ġrev ised Id : ĠString ?): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( original Id . isNull Or Blank () Ġ|| Ġrev ised Id . isNull Or Blank ()) Ġreturn Ġ"" ĊĠĠĠĠĠĠĠ Ġval Ġ( original , Ġnew ) Ġ= Ġget From Db ( original Id , Ġrev ised Id ) ĊĠĠĠĠĠĠĠ Ġreturn Ġgenerate Visual Diff Rows ( original , Ġnew ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġwill Ġasynchronously Ġfetch Ġa Ġpair Ġof Ġsnap s Ġfrom Ġthe Ġdatabase Ġbased Ġon Ġtheir Ġids ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġoriginal Id ĠThe Ġoriginal Ġdiff Ġurl Ġto Ġbe Ġfetched . ĊĠĠĠĠ Ġ* Ġ@ param Ġnew Id ĠThe Ġnewest Ġurl Ġto Ġbe Ġfetched . ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġpair Ġof Ġdiffs ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġget From Db ( ĊĠĠĠĠĠĠĠ Ġoriginal Id : ĠString , ĊĠĠĠĠĠĠĠ Ġnew Id : ĠString ĊĠĠĠ Ġ): ĠPair < Pair < Snap , ĠByteArray >, ĠPair < Snap , ĠByteArray >> Ġ= ĊĠĠĠĠĠĠĠ Ġm Snap s Repository . getS nap Pair ( original Id , Ġnew Id ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġwill Ġasynchronously Ġfetch Ġa Ġpair Ġof Ġdiffs Ġfrom Ġthe Ġdatabase Ġbased Ġon Ġtheir Ġids ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġoriginal Id ĠThe Ġoriginal Ġdiff Ġurl Ġto Ġbe Ġfetched . ĊĠĠĠĠ Ġ* Ġ@ param Ġnew Id ĠThe Ġnewest Ġurl Ġto Ġbe Ġfetched . ĊĠĠĠĠ Ġ* Ġ@ return Ġa Ġpair Ġof Ġdiffs ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġget Snap Value ( snap Id : ĠString ): ĠString Ġ= ĊĠĠĠĠĠĠĠ Ġm Snap s Repository . getS nap Content ( snap Id ). toString ( Charset . default Charset ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCalled Ġwhen Ġthere Ġis Ġa Ġselection . ĠThis Ġis Ġa Ġsimple ĠFin ite ĠState ĠMachine , Ġwhere ĊĠĠĠĠ Ġ* Ġit Ġdec ides Ġthe Ġcolor Ġto Ġselect Ġbased Ġon Ġprevious Ġselection . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġitem ĠĠĠ ĠPass Ġthe Ġitem Ġto Ġbe Ġselected ĊĠĠĠĠ Ġ* Ġ@ param Ġtop Section ĠPass Ġthe Ġtop Ġpart Ġof Ġthe Ġscreen , ĊĠĠĠĠ Ġ* Ġwhich Ġwill Ġbe Ġupdated Ġby Ġ[ generate Diff ] Ġwith Ġcorresponding Ġdiff ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġf sm Select With Correct Color ( item : ĠText ViewHolder , Ġf : Ġ( String ?, ĠString ?) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( item . color Selected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠItem Selected . NONE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( item . adapter . color Selected . count Ġ{ Ġit . value Ġ!= ĠItem Selected . NONE Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNOT H ING ĠIS ĠSELECT ED Ġ-> ĠSELECT ĠRE VISED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . setColor ( ItemSelected . RE VISED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠONE ĠTH ING ĠIS ĠSELECT ED ĠAND ĠIT ĠIS ĠRE VISED Ġ-> ĠOR IGIN AL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠONE ĠTH ING ĠIS ĠSELECT ED ĠAND ĠIT ĠIS ĠOR IGIN AL Ġ-> ĠRE VISED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( _, Ġvalue ) Ġin Ġitem . adapter . color Selected ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ== ĠItem Selected . NONE ) Ġcontinue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ== ĠItem Selected . ORIGIN AL ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . adapter . color Selected . getPosition For Adapter ( ItemSelected . ORIGIN AL ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ Ġposition Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . setColor ( ItemSelected . RE VISED ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . adapter . getItem From Adapter ( position )?. snap Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . snap ?. snap Id ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . adapter . color Selected . getPosition For Adapter ( ItemSelected . RE VISED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ Ġposition Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . setColor ( ItemSelected . ORIGIN AL ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . snap ?. snap Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . adapter . getItem From Adapter ( position )?. snap Id ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTWO ĠARE ĠSELECT ED . ĠUN SELECT ĠTHE ĠOR IGIN AL , ĠSELECT ĠAN OTHER ĠTH ING . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( position , Ġ_) Ġin Ġitem . adapter . color Selected . filter Ġ{ Ġit . value Ġ== ĠItem Selected . ORIGIN AL Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . adapter . setColor ( ItemSelected . NONE , Ġposition ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . setColor ( ItemSelected . ORIGIN AL ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . adapter . color Selected . getPosition For Adapter ( ItemSelected . RE VISED ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ Ġposition Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . snap ?. snap Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . adapter . getItem From Adapter ( position )?. snap Id ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitem . setColor ( ItemSelected . NONE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠWhen Ġthere Ġis Ġonly Ġone Ġitem Ġselected , Ġwe Ġwant Ġto Ġshow Ġan Ġerror Ġmessage ĊĠĠĠĠ Ġ* Ġand Ġclear Ġthe ĠRecyclerView ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġadapter ĠĠĠ ĠThe Ġadapter Ġwith Ġa Ġmap Ġof Ġselected Ġgradient Color ĊĠĠĠĠ Ġ* Ġ@ param Ġtop Section ĠThe Ġtop Ġsection , Ġwhich Ġwill Ġbe Ġcleared Ġif Ġthere Ġare ĊĠĠĠĠ Ġ* Ġnot Ġenough Ġgradient Color Ġselected ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġupdate Can Show Diff ( adapter : ĠText Adapter , Ġcallback : Ġ() Ġ-> ĠUnit ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġadapter . color Selected . count Ġ{ Ġit . value Ġ!= ĠItem Selected . NONE Ġ}. let Ġ{ ĠnumOf Items Not None Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( num Of Items Not None Ġ< Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEmpty Ġwhen Ġthere Ġis Ġnot Ġenough Ġselection ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcallback () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġshow Not En ough Info Error . value Ġ= ĠnumOf Items Not None Ġ!= Ġ 2 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġgenerate Visual Diff Rows ( ĊĠĠĠĠĠĠĠ Ġoriginal : ĠPair < Snap , ĠByteArray >, ĊĠĠĠĠĠĠĠ Ġrev ised : ĠPair < Snap , ĠByteArray > ĊĠĠĠ Ġ): ĠString Ġ= Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġold Tag Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġf : ĠBoolean Ġ-> Ġif Ġ( f ) Ġ"< span Ġclass =\" edit Old Inline \" Ġstyle =\" background - color :# acf 2 bd \"> " Ġelse Ġ"</ span >" Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġnew Tag Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġf : ĠBoolean Ġ-> Ġif Ġ( f ) Ġ"< span Ġclass =\" edit New Inline \" Ġstyle =\" background - color :# ffd ce 0 \"> " Ġelse Ġ"</ span >" Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġgenerator Ġ= ĠDiff Row Generator . create () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. show Inline D iffs ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. merge Original Rev ised ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. inline Diff By Word ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. old Tag ( old Tag ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. new Tag ( new Tag ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġfun Ġfind Correct Charset ( content : ĠSnap ): ĠCharset Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontent . content Charset . take Unless Ġ{ Ġit . isBlank () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠCharset . forName ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠCharset . default Charset () ĊĊĠĠĠĠĠĠĠ Ġ// Ġfind Ġthe Ġcorrect Ġcharset ĊĠĠĠĠĠĠĠ Ġval Ġnew Charset Ġ= Ġfind Correct Charset ( rev ised . first ) ĊĠĠĠĠĠĠĠ Ġval Ġoriginal Charset Ġ= Ġfind Correct Charset ( original . first ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġcompute Ġthe Ġdifferences Ġfor Ġtwo Ġtest Ġtexts . ĊĠĠĠĠĠĠĠ Ġ// Ġgenerate Diff Rows Ġwill Ġsplit Ġthe Ġlines Ġanyway , Ġso Ġthere Ġis Ġno Ġneed Ġfor Ġsplitting Ġagain Ġhere . ĊĊĠĠĠĠĠĠĠ Ġval Ġrows Ġ= Ġgenerator . generate Diff Rows ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal Ġ= Ġmutable ListOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal . second . toString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOk Http Charset . bom Aware Charset ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsource Ġ= Ġoriginal . second , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcharset Ġ= Ġoriginal Charset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrev ised Ġ= Ġmutable ListOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrev ised . second . toString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOk Http Charset . bom Aware Charset ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsource Ġ= Ġrev ised . second , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcharset Ġ= Ġnew Charset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġmapping Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠ Ġrows . forEach Ġ{ Ġmapping . append ( it . old Line . un escape Html () Ġ+ Ġ"\ n ") Ġ} ĊĠĠĠĠĠĠĠ Ġprintln (" mapping : Ġ$ mapping ") ĊĠĠĠĠĠĠĠ Ġmapping . toString () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġgenerate Diff Rows ( ĊĠĠĠĠĠĠĠ Ġoriginal : ĠPair < Snap , ĠByteArray >, ĊĠĠĠĠĠĠĠ Ġrev ised : ĠPair < Snap , ĠByteArray > ĊĠĠĠ Ġ): ĠPair < Mutable List < Text Recycler >, ĠMutable List < Text Recycler >> Ġ= Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġgenerator Ġ= ĠDiff Row Generator . create () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. show Inline D iffs ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. inline Diff By Word ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. old Tag Ġ{ Ġ_ Ġ-> Ġ" TEXT RE MOVED " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. new Tag Ġ{ Ġ_ Ġ-> Ġ" TEXT AD DED " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠ Ġfun Ġfind Correct Charset ( content : ĠSnap ): ĠCharset Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontent . content Charset . take Unless Ġ{ Ġit . isBlank () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠCharset . forName ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠCharset . default Charset () ĊĊĠĠĠĠĠĠĠ Ġ// Ġfind Ġthe Ġcorrect Ġcharset ĊĠĠĠĠĠĠĠ Ġval Ġnew Charset Ġ= Ġfind Correct Charset ( rev ised . first ) ĊĠĠĠĠĠĠĠ Ġval Ġoriginal Charset Ġ= Ġfind Correct Charset ( original . first ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġcompute Ġthe Ġdifferences Ġfor Ġtwo Ġtest Ġtexts . ĊĠĠĠĠĠĠĠ Ġ// Ġgenerate Diff Rows Ġwill Ġsplit Ġthe Ġlines Ġanyway , Ġso Ġthere Ġis Ġno Ġneed Ġfor Ġsplitting Ġagain Ġhere . ĊĊĠĠĠĠĠĠĠ Ġval Ġrows Ġ= Ġgenerator . generate Diff Rows ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal Ġ= Ġmutable ListOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoriginal . second . toString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOk Http Charset . bom Aware Charset ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsource Ġ= Ġoriginal . second , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcharset Ġ= Ġoriginal Charset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). remove Cl utter And Be aut ify Html If Ne cessary ( original . first . contentType ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrev ised Ġ= Ġmutable ListOf ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrev ised . second . toString ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOk Http Charset . bom Aware Charset ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsource Ġ= Ġrev ised . second , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcharset Ġ= Ġnew Charset ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). remove Cl utter And Be aut ify Html If Ne cessary ( rev ised . first . contentType ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġupdating Non Diff Ġ= Ġmutable ListOf < Text Recycler >() ĊĠĠĠĠĠĠĠ Ġval Ġupdating Only Diff Ġ= Ġmutable ListOf < Text Recycler >() ĊĊĠĠĠĠĠĠĠ Ġ// Ġfor Ġsome Ġreason , Ġun escape Html Ġisn 't Ġworking Ġwhen Ġput Ġafter Ġremove Cl utter And Be aut ify Html ĊĠĠĠĠĠĠĠ Ġ// Ġbut Ġit Ġis Ġworking Ġfine Ġwhen Ġput Ġhere . ĊĠĠĠĠĠĠĠ Ġrows . forEach Indexed Ġ{ Ġindex , Ġrow Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( row . old Line Ġ== Ġrow . new Line ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdating Non Diff . add ( Text Recycler ( row . old Line . un escape Html (), Ġindex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( row . old Line . un escape Html ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrow . new Line . isBlank () Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdating Only Diff . add ( Text Recycler ("- " Ġ+ Ġrow . old Line . un escape Html (), Ġindex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrow . old Line . isBlank () Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdating Only Diff . add ( Text Recycler (" +" Ġ+ Ġrow . new Line . un escape Html (), Ġindex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdating Only Diff . add ( Text Recycler ("- " Ġ+ Ġrow . old Line . un escape Html (), Ġindex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdating Only Diff . add ( Text Recycler (" +" Ġ+ Ġrow . new Line . un escape Html (), Ġindex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠPair ( updating Only Diff , Ġupdating Non Diff ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun ĠgetAll Snap s Paged For Id ( id : ĠString , Ġfilter : ĠString ): ĠLive Data < Paged List < Snap >> Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠLive Paged List Builder ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Snap s Repository . getS nap For Paging ( id , Ġfilter ), ĠP aged List . Config . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set PageSize ( PAGE _ SIZE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Enable Place holders ( ENABLE _ PLACE HOLDER S ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ Ġ). build () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠA Ġgood Ġpage Ġsize Ġis Ġa Ġvalue Ġthat Ġfill s Ġat Ġleast Ġa Ġscreen Ġworth Ġof Ġcontent Ġon Ġa Ġlarge ĊĠĠĠĠĠĠĠĠ Ġ* Ġdevice Ġso Ġthe ĠUser Ġis Ġunlikely Ġto Ġsee Ġa Ġnull Ġitem . ĊĠĠĠĠĠĠĠĠ Ġ* ĠYou Ġcan Ġplay Ġwith Ġthis Ġconstant Ġto Ġobserve Ġthe Ġpaging Ġbehavior . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ< p > ĊĠĠĠĠĠĠĠĠ Ġ* ĠIt 's Ġpossible Ġto Ġvary Ġthis Ġwith Ġlist Ġdevice Ġsize , Ġbut Ġoften Ġunnecessary , Ġunless Ġa Ġuser ĊĠĠĠĠĠĠĠĠ Ġ* Ġscrolling Ġon Ġa Ġlarge Ġdevice Ġis Ġexpected Ġto Ġscroll Ġthrough Ġitems Ġmore Ġquickly Ġthan Ġa Ġsmall ĊĠĠĠĠĠĠĠĠ Ġ* Ġdevice , Ġsuch Ġas Ġwhen Ġthe Ġlarge Ġdevice Ġuses Ġa Ġgrid Ġlayout Ġof Ġitems . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠPAGE _ SIZE Ġ= Ġ 8 ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠIf Ġplaceholders Ġare Ġenabled , ĠP aged List Ġwill Ġreport Ġthe Ġfull Ġsize Ġbut Ġsome Ġitems Ġmight ĊĠĠĠĠĠĠĠĠ Ġ* Ġbe Ġnull Ġin Ġon Bind Ġmethod Ġ( Paged ListAdapter Ġtriggers Ġa Ġre bind Ġwhen Ġdata Ġis Ġloaded ). ĊĠĠĠĠĠĠĠĠ Ġ* Ġ< p > ĊĠĠĠĠĠĠĠĠ Ġ* ĠIf Ġplaceholders Ġare Ġdisabled , Ġon Bind Ġwill Ġnever Ġreceive Ġnull Ġbut Ġas Ġmore Ġpages Ġare ĊĠĠĠĠĠĠĠĠ Ġ* Ġloaded , Ġthe Ġscroll bars Ġwill Ġj itter Ġas Ġnew Ġpages Ġare Ġloaded . ĠYou Ġshould Ġprobably Ġdisable ĊĠĠĠĠĠĠĠĠ Ġ* Ġscroll bars Ġif Ġyou Ġdisable Ġplaceholders . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠENABLE _ PLACE HOLDER S Ġ= Ġtrue ĊĠĠĠ Ġ} Ċ } Ċ