package Ġnet . ev end anan . l umi ere Ċ Ċ import Ġandroid . Manifest Ċ import Ġandroid . net . Uri Ċ import Ġandroid . util . Log Ċ import Ġandroidx . core . net . to Uri Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Job Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġjava . io . File Ċ import Ġjava . io . IOException Ċ import Ġjava . util . concurrent . Count DownLatch Ċ import Ġkotlin . apply Ċ import Ġkotlin . run Ċ Ċ interface ĠPres enter Ġ{ ĊĠĠĠ Ġfun Ġset Presenter Ui ( ui : ĠPres enter UI ) ĊĊĠĠĠ Ġfun Ġon Search Icon Clicked () ĊĊĠĠĠ Ġfun Ġon Media Action Clicked ( media : ĠMedia , Ġaction : ĠAction Type ) ĊĊĠĠĠ Ġfun Ġon Query ( query : ĠString , Ġprovider Type : ĠProvider Type ) ĊĊĠĠĠ Ġfun Ġdestroy () ĊĊĠĠĠ Ġobject ĠNO OP Ġ: ĠPres enter Ġ{ ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġset Presenter Ui ( ui : ĠPres enter UI ) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Search Icon Clicked () Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Media Action Clicked ( media : ĠMedia , Ġaction : ĠAction Type ) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Query ( query : ĠString , Ġprovider Type : ĠProvider Type ) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġdestroy () Ġ{} ĊĠĠĠ Ġ} Ċ } Ċ Ċ enum Ġclass ĠAction Type Ġ{ ĊĠĠĠ ĠMain , ĊĠĠĠ ĠShare , ĊĠĠĠ ĠSave , ĊĠĠĠ ĠF avorite Ċ } Ċ Ċ enum Ġclass ĠProvider Type Ġ{ ĊĠĠĠ ĠSearch , ĊĠĠĠ ĠT rend ing , ĊĠĠĠ ĠF avorites , ĊĠĠĠ ĠHistory , Ċ } Ċ Ċ interface ĠItems Provider Ġ{ ĊĠĠĠ Ġval Ġsupported Actions : ĠSet < ActionType > ĊĠĠĠ Ġval Ġtype : ĠProvider Type ĊĠĠĠ Ġval Ġhas Query : ĠBoolean ĊĠĠĠ Ġval Ġloading InProgress : ĠBoolean ĊĠĠĠ Ġval Ġmedia Items : ĠList < Media > Ċ } Ċ Ċ class ĠPermission Request ( val ĠrequestId : ĠInt , Ġval Ġpermissions : ĠList < String >) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġl atch Ġ= ĠCount DownLatch ( 1 ) ĊĠĠĠ Ġprivate Ġvar Ġgranted Ġ= Ġfalse ĊĊĠĠĠ Ġfun Ġon Permission Granted () Ġ{ ĊĠĠĠĠĠĠĠ Ġgranted Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Permission Denied () Ġ{ ĊĠĠĠĠĠĠĠ Ġgranted Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġl atch . count Down () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠwaitFor Response (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġl atch . await () ĊĠĠĠĠĠĠĠ Ġreturn Ġgranted ĊĠĠĠ Ġ} Ċ } Ċ Ċ interface ĠPres enter UI Ġ{ ĊĠĠĠ Ġfun Ġset Items Providers ( providers : ĠList < Items Provider >) ĊĠĠĠ Ġfun Ġfocus On Section ( provider Type : ĠProvider Type ) ĊĊĠĠĠ Ġfun Ġask For Permission ( permission Request : ĠPermission Request ) ĊĊĠĠĠ Ġfun Ġfab Visibility ( visible : ĠBoolean ) ĊĊĠĠĠ Ġfun Ġshow Progress () ĊĠĠĠ Ġfun Ġhide Progress () ĊĊĠĠĠ Ġfun Ġnotify Local Media File ( file : ĠFile , Ġshare Uri : ĠUri ) ĊĠĠĠ Ġfun Ġshow Share Window ( share Uri : ĠUri ) ĊĠĠĠ Ġfun Ġshare To Any Soft Keyboard ( share Uri : ĠUri ) ĊĊĠĠĠ Ġobject ĠNO OP Ġ: ĠPres enter UI Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġset Items Providers ( providers : ĠList < Items Provider >) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfocus On Section ( provider Type : ĠProvider Type ) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġask For Permission ( permission Request : ĠPermission Request ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpermission Request . on Permission Denied () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfab Visibility ( visible : ĠBoolean ) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġshow Progress () Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġhide Progress () Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġnotify Local Media File ( file : ĠFile , Ġshare Uri : ĠUri ) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġshow Share Window ( share Uri : ĠUri ) Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġshare To Any Soft Keyboard ( share Uri : ĠUri ) Ġ{} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠPres enter Impl ( ĊĠĠĠ Ġprivate Ġval Ġpicker Mode : ĠBoolean , ĊĠĠĠ Ġprivate Ġval Ġmedia Provider : ĠMedia Provider , ĊĠĠĠ Ġprivate Ġval Ġio : ĠIO , ĊĠĠĠ Ġprivate Ġval Ġdispatch ers : ĠDispatch ers Provider Ċ ) Ġ: ĊĠĠĠ ĠPres enter Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġui : ĠPres enter UI Ġ= ĠPres enter UI . NO OP ĊĠĠĠ Ġprivate Ġval Ġavailable Providers : ĠMutable Map < Provider Type , ĠItems Provider Impl > Ġ= Ġmutable Map Of () ĊĊĠĠĠ Ġprivate Ġvar ĠviewModel Job Ġ= ĠJob () ĊĠĠĠ Ġprivate Ġvar Ġsearch Job Ġ= ĠJob () ĊĠĠĠ Ġprivate Ġvar Ġdownload Job Ġ= ĠJob () ĊĠĠĠ Ġprivate Ġval Ġui Scope Ġ= ĠCor outine Scope ( dispatch ers . main ) ĊĊĠĠĠ Ġprivate Ġval Ġdefault Actions Ġ= Ġif Ġ( picker Mode ) Ġset Of ( ActionType . Main ) Ġelse Ġset Of ( ActionType . Share , ĠAction Type . Save ) ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġset Provider Items ( Provider Type . Trend ing , Ġtrue , Ġempty List ()) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( picker Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Search Icon Clicked () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġload Local G ifs () ĊĠĠĠĠĠĠĠ ĠviewModel Job Ġ= Ġui Scope . launch ( dispatch ers . immediate Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Provider Items ( Provider Type . Trend ing , Ġtrue , Ġempty List ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtrend ing Ġ= Ġwith Context ( dispatch ers . background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Provider . blocking Trend ing () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Provider Items ( Provider Type . Trend ing , Ġfalse , Ġtrend ing ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġload Local G ifs () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Job . cancel () ĊĠĠĠĠĠĠĠ ĠviewModel Job Ġ= Ġui Scope . launch ( dispatch ers . immediate Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhave Permission Ġ= ĠPermission Request ( 1 2 3 , ĠlistOf ( Manifest . permission . WRITE _ EXTERNAL _ STORAGE )). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . ask For Permission ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ run Ġwith Context ( dispatch ers . background ) Ġ{ ĠwaitFor Response () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( have Permission ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecent G ifs Ġ= Ġwith Context ( dispatch ers . background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Provider . blocking Recent s () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Provider Items ( Provider Type . History , Ġfalse , Ġrecent G ifs ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsaved Ġ= Ġwith Context ( dispatch ers . background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Provider . blocking Saved () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Provider Items ( Provider Type . F avorites , Ġfalse , Ġsaved ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġset Presenter Ui ( ui : ĠPres enter UI ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . ui Ġ= Ġui ĊĠĠĠĠĠĠĠ Ġload Local G ifs () ĊĠĠĠĠĠĠĠ Ġui . set Items Providers ( available Providers . values . to Sorted Collection ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( available Providers . containsKey ( Provider Type . Search )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġui . fab Visibility ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġui . focus On Section ( Provider Type . Search ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġui . fab Visibility ( true ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġset Provider Items ( provider Type : ĠProvider Type , Ġloading : ĠBoolean , Ġitems : ĠList < Media >) Ġ{ ĊĠĠĠĠĠĠĠ Ġavailable Providers . get Or Put ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprovider Type , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠItems Provider Impl ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprovider Type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprovider Type Ġ== ĠProvider Type . Search , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Actions . filter For Provider ( provider Type ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . loading InProgress Ġ= Ġloading ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . items . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd All ( items ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġui . set Items Providers ( available Providers . values . to Sorted Collection ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠSet < ActionType >. filter For Provider ( provider Type : ĠProvider Type ): ĠSet < ActionType > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( provider Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠProvider Type . F avorites Ġ-> Ġto Mutable Set (). apply Ġ{ Ġremove ( ActionType . Save ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthis ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Media Action Clicked ( media : ĠMedia , Ġaction : ĠAction Type ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d (" Presenter Impl ", Ġ" on Media Action Clicked Ġfor Ġ${ media . original } Ġwith Ġaction Ġ$ action ") ĊĠĠĠĠĠĠĠ Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAction Type . Save Ġ-> Ġsave ToLocal Storage ( media ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAction Type . Share Ġ-> Ġshare From App Storage ( media ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAction Type . Main Ġ-> Ġclick On Image ( media ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠTODO (" Implement Ġon Media Action Clicked Ġfor Ġ$ action ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdownload To App Storage ( media : ĠMedia ): ĠUri Ġ{ ĊĠĠĠĠĠĠĠ Ġio . app Storage Folder . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( isDirectory Ġ|| Ġmkdir s ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcopy ( media . original , ĠFile ( this @ apply , Ġmedia . filename ). to Uri ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Was Ġnot Ġable Ġto Ġcreate Ġfolder Ġ${ this @ apply } !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclick On Image ( media : ĠMedia ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( picker Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdownload Job . cancel () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdownload Job Ġ= Ġui Scope . launch ( dispatch ers . immediate Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" presenter ", Ġ" Starting Ġsaving Ġto Ġdisk ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . show Progress () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( dispatch ers . background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload To App Storage ( media ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġio . as Share Uri ( this ). let Ġ{ Ġuri For Any Soft Keyboard Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġio . grant Uri Read Access ( uri For Any Soft Keyboard , Ġ" com . men ny . android . any soft keyboard ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . share To Any Soft Keyboard ( uri For Any Soft Keyboard ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w (" presenter ", Ġ" Failed Ġto Ġstore Ġ${ media . original }. ĠError : Ġ${ e . message }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . hide Progress () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshare From App Storage ( media ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshare From App Storage ( media : ĠMedia ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdownload Job . cancel () ĊĊĠĠĠĠĠĠĠ Ġdownload Job Ġ= Ġui Scope . launch ( dispatch ers . immediate Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" presenter ", Ġ" Starting Ġsaving Ġto Ġdisk ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġui . show Progress () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( dispatch ers . background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload To App Storage ( media ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . show Share Window ( io . as Share Uri ( this )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w (" presenter ", Ġ" Failed Ġto Ġstore Ġ${ media . original }. ĠError : Ġ${ e . message }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . hide Progress () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsave ToLocal Storage ( media : ĠMedia ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdownload Job . cancel () ĊĊĠĠĠĠĠĠĠ Ġdownload Job Ġ= Ġui Scope . launch ( dispatch ers . immediate Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhave Permission Ġ= ĠPermission Request ( 1 2 3 , ĠlistOf ( Manifest . permission . WRITE _ EXTERNAL _ STORAGE )). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . ask For Permission ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ run Ġwith Context ( dispatch ers . background ) Ġ{ ĠwaitFor Response () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( have Permission ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d (" presenter ", Ġ" Starting Ġsaving Ġto Ġdisk ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . show Progress () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( dispatch ers . background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdownload To App Storage ( media ). let Ġ{ Ġapp File Uri Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġio . localStorage Folder . let Ġ{ Ġlocal File File Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( local File File . isDirectory Ġ|| Ġlocal File File . mkdir s ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( local File File , Ġmedia . filename ). let Ġ{ Ġtarget File Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcopy ( app File Uri , Ġtarget File . to Uri ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . notify Local Media File ( target File , Ġapp File Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . w (" presenter ", Ġ" Failed Ġto Ġstore Ġ${ media . original }. ĠError : Ġ${ e . message }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . hide Progress () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Local G ifs () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcopy ( input Uri : ĠUri , Ġoutput Uri : ĠUri ): ĠUri Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d (" presenter - copy ", Ġ" will Ġcopy Ġfrom Ġ$ input Uri Ġto Ġ$ output Uri ...") ĊĠĠĠĠĠĠĠ Ġio . open Uri For Reading ( input Uri ). use Ġ{ Ġreceived InputStream Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġio . open Uri For Writing ( output Uri ). use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreceived InputStream . copy To ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠLog . d (" presenter - copy ", Ġ" done Ġcopy Ġfrom Ġ$ input Uri Ġto Ġ$ output Uri .") ĊĊĠĠĠĠĠĠĠ Ġreturn Ġoutput Uri ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Search Icon Clicked () Ġ{ ĊĠĠĠĠĠĠĠ Ġavailable Providers [ Provider Type . Search ]. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . fab Visibility ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Provider Items ( Provider Type . Search , Ġfalse , Ġempty List ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġui . focus On Section ( Provider Type . Search ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Query ( query : ĠString , Ġprovider Type : ĠProvider Type ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsearch Job . cancel () ĊĊĠĠĠĠĠĠĠ Ġ// consider Ġputting Ġa Ġlocal - loading ĠGIF Ġimage Ġhere . ĊĠĠĠĠĠĠĠ Ġset Provider Items ( Provider Type . Search , Ġtrue , Ġempty List ()) ĊĊĠĠĠĠĠĠĠ Ġsearch Job Ġ= Ġui Scope . launch ( dispatch ers . immediate Main ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsearch Ġ= Ġif Ġ( query . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty List () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Context ( dispatch ers . background ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Provider . blocking Search ( query ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Provider Items ( Provider Type . Search , Ġfalse , Ġsearch ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġdestroy () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Job . cancel () ĊĠĠĠĠĠĠĠ Ġsearch Job . cancel () ĊĠĠĠĠĠĠĠ Ġdownload Job . cancel () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠItems Provider Impl ( ĊĠĠĠ Ġoverride Ġval Ġtype : ĠProvider Type , Ġoverride Ġval Ġhas Query : ĠBoolean , ĊĠĠĠ Ġoverride Ġval Ġsupported Actions : ĠSet < ActionType > Ċ ) Ġ: ĠItems Provider Ġ{ ĊĠĠĠ Ġinternal Ġval Ġitems Ġ= Ġmutable ListOf < Media >() ĊĊĠĠĠ Ġoverride Ġvar Ġloading InProgress Ġ= Ġfalse ĊĊĠĠĠ Ġoverride Ġval Ġmedia Items : ĠList < Media > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġitems Ċ } Ċ Ċ private Ġfun ĠCollection < Items Provider >. to Sorted Collection () Ġ= ĊĠĠĠ Ġthis . to Mutable List (). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġsort With ( Comparator Ġ{ Ġo 1 , Ġo 2 Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġo 1 . type . ordinal Ġ- Ġo 2 . type . ordinal ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ}