package Ġcom . qu an lv . music player . ui . fragments ĊĊ Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . support . v 4 . media . session . Playback State Compat Ċ import Ġandroid . view .* Ċ import Ġcom . qu an lv . music player . R Ċ import Ġcom . qu an lv . music player . databinding . Fragment Song Detail Binding Ċ import Ġcom . qu an lv . music player . extensions .* Ċ import Ġcom . qu an lv . music player . models . Media Item Data Ċ import Ġcom . qu an lv . music player . ui . fragments . base . Base Song Detail Fragment Ċ import Ġcom . qu an lv . music player . ui . view models . Song ViewModel Ċ import Ġcom . qu an lv . music player . utils . Auto Clear Binding Ċ import Ġcom . qu an lv . music player . utils . Beat Constants . BIND _ STATE _ BOUND Ċ import Ġcom . qu an lv . music player . utils . General Utils Ċ import Ġcom . qu an lv . music player . utils . General Utils . getS ong Uri Ċ import Ġkotlinx . android . synt hetic . main . fragment _ song _ detail .* Ċ import Ġkotlinx . coroutines . Dispatch ers . IO Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġorg . k oin . android x . view model . ext . android . shared ViewModel Ċ import Ġtim ber . log . Tim ber Ċ import Ġkotlin . math . absolute Value Ċ Ċ class ĠSong Detail Fragment Ġ: ĠBase Song Detail Fragment () Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġbinding Ġby ĠAuto Clear Binding < Fragment Song Detail Binding >( this ) ĊĠĠĠ Ġprivate Ġval Ġsong ViewModel Ġby Ġshared ViewModel < Song ViewModel >() ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġgesture Detector : ĠGest ure Detector ĊĠĠĠ Ġprivate Ġval Ġmin Fl ing Velocity Ġ= Ġ 8 0 0 ĊĠĠĠĠĊĠĠĠ Ġoverride Ġfun ĠonCreate View ( ĊĠĠĠĠĠĠĠ Ġinflater : ĠLayoutInflater , Ġcontainer : ĠViewGroup ?, ĊĠĠĠĠĠĠĠ ĠsavedInstanceState : ĠBundle ? ĊĠĠĠ Ġ): ĠView ? Ġ{ ĊĠĠĠĠĠĠĠ Ġbinding Ġ= Ġinflater . inflate With Binding ( R . layout . fragment _ song _ detail , Ġcontainer ) ĊĠĠĠĠĠĠĠ Ġreturn Ġbinding . root ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Activity Created ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Activity Created ( savedInstanceState ) ĊĠĠĠĠĠĠĠ Ġinit () ĊĠĠĠĠĠĠĠ Ġinit Swipe Gest ures () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit () Ġ{ ĊĠĠĠĠĠĠĠ Ġinit View Components () ĊĊĠĠĠĠĠĠĠ Ġsong Detail ViewModel . current Data . observe ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Needed ( song ViewModel . getS ong ById ( it . id ), Ġempty List (), Ġ 0 L ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġraw Ġ= Ġwith Context ( IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGeneral Utils . audio 2 Raw ( context !! , Ġget Song Uri ( it . id )) Ġ?: Ġbyte ArrayOf () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsong Detail ViewModel . update ( raw ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġsong Detail ViewModel . time . observe ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtotal Ġ= Ġsong Detail ViewModel . current Data . value ?. duration Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbinding . seek Bar . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġt Ġ= Ġprogress . percent To Ms ( total ). fix To Step ( 1 0 0 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( t Ġ!= Ġit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprogress Ġ= Ġit . fix To Percent ( total ). fix Percent Bounds () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġbinding . apply { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshared Song . setOnClickListener Ġ{ Ġshare Item () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsong Title . isSelected Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġsong Detail ViewModel . currentState . observe ( this ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsong Detail ViewModel . update ( it . position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . state Ġ== ĠPlay back State Compat . STATE _ PLAY ING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsong Detail ViewModel . update ( BIND _ STATE _ BOUND ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġsong Detail ViewModel . update () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġbinding . let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . viewModel Ġ= Ġsong Detail ViewModel ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . lifecycle Owner Ġ= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . execute Pending Bindings () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Detach () Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Detach () ĊĠĠĠĠĠĠĠ Ġsong Detail ViewModel . update ( byte ArrayOf ()) ĊĠĠĠĠĠĠĠ Ġsong Detail ViewModel . update () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinit View Components () Ġ{ ĊĠĠĠĠĠĠĠ Ġbinding . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext Btn . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain ViewModel . transport Controls ()?. skip To Next () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprevious Btn . setOnClickListener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain ViewModel . transport Controls ()?. skip To Previous () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseek Bar . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonStart Tracking Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsong Detail ViewModel . update () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Stop Tracking Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmedia Item Data Ġ= Ġsong Detail ViewModel . current Data . value Ġ?: ĠMedia Item Data () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain ViewModel . transport Controls () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . seek To (( it Ġ* Ġmedia Item Data . duration Ġ/ Ġ 1 0 0 ). to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Progress Changed Ġ= Ġ{ Ġposition , Ġby User Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( by User ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmedia Item Data Ġ= Ġsong Detail ViewModel . current Data . value Ġ?: ĠMedia Item Data () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsong Detail ViewModel . update (( position Ġ* Ġmedia Item Data . duration Ġ/ Ġ 1 0 0 ). toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠĠĊĠĠĠ Ġprivate Ġvar Ġtouch Listener : ĠView . On Touch Listener Ġ= ĠView . On Touch Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġv : ĠView , Ġmotion Event : ĠMotion Event Ġ-> Ġgesture Detector . on Touch Event ( motion Event ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( motion Event . action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ DOWN Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMotion Event . ACTION _ UP Ġ-> Ġv . perform Click () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠ Ġ} ĊĠĠĠĠĊĠĠĠ Ġprivate Ġfun Ġinit Swipe Gest ures () Ġ{ ĊĠĠĠĠĠĠĠ Ġgesture Detector Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠGest ure Detector ( activity , Ġobject Ġ: ĠGest ure Detector . On Gesture Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Down ( event : ĠMotion Event ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Fl ing ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe 1 : ĠMotion Event , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe 2 : ĠMotion Event , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvelocity X : ĠFloat , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvelocity Y : ĠFloat ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( velocity X . absolute Value Ġ> Ġmin Fl ing Velocity ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( velocity X Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain ViewModel . transport Controls ()?. skip To Next () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain ViewModel . transport Controls ()?. skip To Previous () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Show Press ( e : ĠMotion Event ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" on Show Press Ġdetected ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Single Tap Up ( e : ĠMotion Event ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Long Press ( e : ĠMotion Event ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" on Long Press Ġdetected ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Scroll ( e 1 : ĠMotion Event ?, Ġe 2 : ĠMotion Event ?, Ġdistance X : ĠFloat , Ġdistance Y : ĠFloat ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġnow _ playing _ cover . setOn Touch Listener ( touch Listener ) ĊĠĠĠ Ġ} Ċ } Ċ