package Ġcom . ca jet an p . youtube plus Ċ Ċ import Ġandroid . app . Notification Manager Ċ import Ġandroid . app . Pending Intent Ċ import Ġandroid . app . Service Ċ import Ġandroidx . lifecycle . ViewModel Providers Ċ import Ġandroid . content . Broadcast Receiver Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . Intent Ċ import Ġandroid . content . Intent Filter Ċ import Ġandroid . content . pm . Activity Info Ċ import Ġandroid . graphics . Bitmap Ċ import Ġandroid . graphics . Bitmap Factory Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . os . IB inder Ċ import Ġandroid . preference . Preference Manager Ċ import Ġandroid . support . v 4 . media . session . Media Session Compat Ċ import Ġandroid . support . v 4 . media . session . Playback State Compat Ċ import Ġandroid . util . Log Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroid . view . View Ċ import Ġandroid . widget . Toast Ċ import Ġandroidx . core . app . Notification Compat Ċ import Ġandroidx . recyclerview . widget . Linear LayoutManager Ċ import Ġcom . ca jet an p . youtube plus . adapters . Content ListAdapter Ċ import Ġcom . ca jet an p . youtube plus . data . Video Data Ċ import Ġcom . ca jet an p . youtube plus . data . Main Data ViewModel Ċ import Ġcom . ca jet an p . youtube plus . fragments . Seek Dialog Fragment Ċ import Ġcom . ca jet an p . youtube plus . utils . Feed Item Ċ import Ġcom . ca jet an p . youtube plus . utils . FullScreen Helper Ċ import Ġcom . ca jet an p . youtube plus . utils . ItemType Ċ import Ġcom . ca jet an p . youtube plus . utils . YouTube Data Ċ import Ġcom . google . api . services . youtube . model . Playlist Item Ċ import Ġcom . google . api . services . youtube . model . Video Ċ import Ġcom . pi er fr ances co so ff rit ti . android youtube player . player . Player Constants Ċ import Ġcom . pi er fr ances co so ff rit ti . android youtube player . player . listeners . Abstract YouTube Player Listener Ċ import Ġcom . pi er fr ances co so ff rit ti . android youtube player . player . listeners . YouTube Player FullScreen Listener Ċ import Ġcom . pi er fr ances co so ff rit ti . android youtube player . ui . Player UI Controller Ċ import Ġcom . pi er fr ances co so ff rit ti . android youtube player . ui . menu . MenuItem Ċ import Ġcom . pi er fr ances co so ff rit ti . android youtube player . ui . menu . YouTube Player Menu Ċ import Ġcom . pi er fr ances co so ff rit ti . android youtube player . utils . YouTube Player Tracker Ċ import Ġkotlinx . android . synt hetic . main . activity _ player .* Ċ import Ġorg . jetbrains . ank o .* Ċ import Ġjava . lang . IllegalArgumentException Ċ import Ġjava . net . URL Ċ Ċ class ĠPlayer Activity Ġ: ĠAppCompatActivity (), ĠYouTube Data . Video Data Listener , ĊĠĠĠĠĠĠĠ ĠYouTube Data . Video List Data Listener , ĠContent ListAdapter . ListItem ClickListener , ĊĠĠĠĠĠĠĠ ĠSeek Dialog Fragment . Seek Dialog Listener , ĠYouTube Data . Playlist Data Listener , ĊĠĠĠĠĠĠĠ ĠYouTube Data . Related Videos Listener Ġ{ ĊĊĠĠĠ Ġprivate Ġval ĠTAG : ĠString Ġ= Ġthis . java Class . simple Name ĊĊĠĠĠ Ġprivate Ġval Ġm FullScreen Helper : ĠFull Screen Helper Ġ= ĠFull Screen Helper ( this ) ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Media Session : ĠMedia Session Compat ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm State Builder : ĠPlay back State Compat . Builder ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm YouTube Data : ĠYouTube Data ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm UI Controller : ĠPlayer UI Controller ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Video Id : ĠString ĊĠĠĠ Ġprivate Ġvar Ġm Video Data : ĠVideo ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Video Thumbnail : ĠBitmap ĊĊĠĠĠ Ġprivate Ġval ĠmContext : ĠContext Ġ= Ġthis ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Main Data ViewModel : ĠMain Data ViewModel ĊĊĠĠĠ Ġprivate Ġval Ġm Tracker : ĠYouTube Player Tracker Ġ= ĠYouTube Player Tracker () ĊĊĠĠĠ Ġprivate Ġval Ġm Broadcast Receiver Ġ= Ġobject Ġ: ĠBroadcast Receiver () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Receive ( context : ĠContext , Ġintent : ĠIntent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( intent . extras ?. getString ( getString ( R . string . player _ action _ key )) Ġ== ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . player _ action _ play _ pause )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmain Player View ?. toggle Play Pause () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTODO : Ġrefactor Ġsome Ġmethods Ġwith Ġdefault Ġarguments ĊĊĠĠĠ Ġprivate Ġvar Ġplaylist Mode Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġm Adapter : ĠContent ListAdapter ĊĠĠĠ Ġprivate Ġvar Ġm Prev PageToken : ĠString Ġ= Ġ"" ĊĠĠĠ Ġprivate Ġvar Ġm Next PageToken : ĠString Ġ= Ġ"" ĊĠĠĠ Ġprivate Ġvar ĠmCurrent Video Index Ġ= Ġ 0 ĊĊĠĠĠ Ġ// //////////////////////////////////////////////////////////////////////////// // ĊĠĠĠ Ġ// ĠLifecycle ĊĠĠĠ Ġ// //////////////////////////////////////////////////////////////////////////// // ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdark Mode Ġ= ĠPreference Manager . getDefault SharedPreferences ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. getBoolean ( getString ( R . string . dark _ mode _ key ), Ġfalse ) ĊĠĠĠĠĠĠĠ Ġset Theme ( if Ġ( dark Mode ) ĠR . style . Player Activity Theme Dark Ġelse ĠR . style . Player Activity Theme Light ) ĊĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( R . layout . activity _ player ) ĊĊĠĠĠĠĠĠĠ Ġm YouTube Data Ġ= ĠYouTube Data ( this ) ĊĠĠĠĠĠĠĠ Ġm Main Data ViewModel Ġ= ĠViewModel Providers . of ( this ). get ( Main Data ViewModel :: class . java ) ĊĊĠĠĠĠĠĠĠ Ġval Ġplaylist Id Ġ= Ġget Playlist Id ( intent ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( playlist Id ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠA Ġsingle Ġvideo ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Video Id Ġ= Ġget Intent Video Id ( intent !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm YouTube Data . receive Video Data ( m Video Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Player () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Related Videos ( m Video Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠA Ġplaylist , Ġsetup Ġplayer Ġafter Ġreceiving Ġthe Ġdata ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Player () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Playlist ( playlist Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġsetup Media Session () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon New Intent ( intent : ĠIntent ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on New Intent ( intent ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( intent . extras Ġ== Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĊĠĠĠĠĠĠĠ Ġm Prev PageToken Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġm Next PageToken Ġ= Ġ"" ĊĠĠĠĠĠĠĠ ĠmCurrent Video Index Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġval Ġplaylist Id Ġ= Ġget Playlist Id ( intent ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( playlist Id ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplaylist Mode Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġpossible Ġimprovements ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this :: m Adapter . isInitialized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . clear Items () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvideo List . visibility Ġ= ĠView . GONE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . playlist Mode Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġswitch Video ( get Intent Video Id ( intent )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Related Videos ( m Video Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplaylist Mode Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! this :: m Adapter . isInitialized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Playlist ( playlist Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . switch Now Playing ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . clear Items () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . playlist Mode Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm YouTube Data . receive Playlist Results ( playlist Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Activity Result ( request Code : ĠInt , ĠresultCode : ĠInt , Ġdata : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġm YouTube Data . on Parent Activity Result ( request Code , ĠresultCode , Ġdata ) ĊĠĠĠĠĠĠĠ Ġsuper . on Activity Result ( request Code , ĠresultCode , Ġdata ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Request Permissions Result ( request Code : ĠInt , Ġpermissions : ĠArray < out ĠString >, Ġgrant Results : ĠInt Array ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm YouTube Data . receive Video Data ( m Video Id ) ĊĠĠĠĠĠĠĠ Ġsuper . on Request Permissions Result ( request Code , Ġpermissions , Ġgrant Results ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Destroy () Ġ{ ĊĠĠĠĠĠĠĠ Ġ( getSystem Service ( Context . NOTIFICATION _ SERVICE ) Ġas ĠNotification Manager ). cancel ( 0 ) ĊĠĠĠĠĠĠĠ Ġunregister Receiver ( m Broadcast Receiver ) ĊĠĠĠĠĠĠĠ Ġmain Player View . release () ĊĠĠĠĠĠĠĠ Ġsuper . on Destroy () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// //////////////////////////////////////////////////////////////////////////// // ĊĠĠĠ Ġ// ĠInit ĊĠĠĠ Ġ// //////////////////////////////////////////////////////////////////////////// // ĊĊĠĠĠ Ġprivate Ġfun Ġsetup Player () Ġ{ ĊĠĠĠĠĠĠĠ Ġregister Receiver ( m Broadcast Receiver , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent Filter (). apply Ġ{ Ġadd Action ( Intent . ACTION _ MEDIA _ BUTTON ) Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġstart Service ( Intent ( this , ĠPlayer Lifecycle Service :: class . java )) ĊĊĠĠĠĠĠĠĠ Ġval Ġid Available Ġ= Ġthis :: m Video Id . isInitialized ĊĊĠĠĠĠĠĠĠ Ġmain Player View . enable Background Playback ( true ) ĊĠĠĠĠĠĠĠ Ġmain Player View . initialize ({ Ġinitial ised YouTube Player Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial ised YouTube Player . addListener ( m Tracker ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial ised YouTube Player . addListener ( object : ĠAbstract YouTube Player Listener () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Ready () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( id Available Ġ&& Ġm Video Id . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinitial ised YouTube Player . load Video ( m Video Id , Ġ 0 F ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon StateChange ( state : ĠPlayer Constants . Player State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state Ġ== ĠPlayer Constants . Player State . ENDED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( playlist Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠmCurrent Video Index ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġswitch Video ( m Adapter . getItem ( m Current Video Index ). id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . switch Now Playing ( m Current Video Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġswitch Video ( m Adapter . getItem ( 0 ). id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsetup Related Videos ( m Adapter . getItem ( 0 ). id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġplayer State : ĠInt ? Ġ= Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlayer Constants . Player State . PLAY ING Ġ-> ĠPlay back State Compat . STATE _ PLAY ING ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlayer Constants . Player State . PA USED Ġ-> ĠPlay back State Compat . STATE _ PA USED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlayer Constants . Player State . ENDED Ġ-> ĠPlay back State Compat . STATE _ PA USED ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( player State Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm State Builder . setState ( player State , Ġm Tracker . current Second . to Long (), Ġ 1 f ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Media Session . set Playback State ( m State Builder . build ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Media Notification ( m State Builder . build ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on StateChange ( state ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ}, Ġtrue ) ĊĊĠĠĠĠĠĠĠ Ġmain Player View . add FullScreen Listener ( object : ĠYouTube Player FullScreen Listener Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon YouTube Player Enter FullScreen () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequested Orientation Ġ= ĠActivity Info . SCREEN _ OR IENTATION _ LAND SC APE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm FullScreen Helper . enter FullScreen () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon YouTube Player Exit FullScreen () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequested Orientation Ġ= ĠActivity Info . SCREEN _ OR IENTATION _ POR TRA IT ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm FullScreen Helper . exit FullScreen () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġm UI Controller Ġ= Ġmain Player View . player UI Controller ĊĠĠĠĠĠĠĠ Ġm UI Controller . show Video Title ( true ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( m UI Controller . menu Ġ== Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĊĠĠĠĠĠĠĠ Ġm UI Controller . show Menu Button ( true ) ĊĠĠĠĠĠĠĠ Ġadd Menu Items ( m UI Controller . menu Ġas ĠYouTube Player Menu ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsetup Related Videos ( related To Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġplaylist Mode Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġm Adapter Ġ= ĠContent ListAdapter ( emptyList (), Ġthis , Ġthis ) ĊĠĠĠĠĠĠĠ Ġm Adapter . on Bottom Reached Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Next PageToken . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠprogressBar Bottom . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm YouTube Data . receive Related Videos ( related To Id , Ġm Next PageToken ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Adapter . playlist Mode Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġvideo List . adapter Ġ= Ġm Adapter ĊĠĠĠĠĠĠĠ ĠLog . d (" Player Activity ", Ġ" Re ceiving Ġrelated Ġvideos ") ĊĠĠĠĠĠĠĠ Ġm YouTube Data . receive Related Videos ( related To Id , Ġm Next PageToken ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsetup Playlist ( playlist Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġplaylist Mode Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġm Adapter Ġ= ĠContent ListAdapter ( emptyList (), Ġthis , Ġthis ) ĊĠĠĠĠĠĠĠ Ġm Adapter . switch Now Playing ( m Current Video Index ) ĊĠĠĠĠĠĠĠ Ġm Adapter . on Bottom Reached Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Next PageToken . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠprogressBar Bottom . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm YouTube Data . receive Playlist Results ( playlist Id , Ġm Next PageToken ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġm Adapter . playlist Mode Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġvideo List . adapter Ġ= Ġm Adapter ĊĠĠĠĠĠĠĠ Ġm YouTube Data . receive Playlist Results ( playlist Id ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Menu Items ( menu : ĠYouTube Player Menu ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmenu . addItem ( MenuItem ( getString ( R . string . seek ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠR . drawable . ic _ timer _ black _ 2 4 dp ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbundle Ġ= ĠBundle (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput String ( getString ( R . string . duration _ string _ key ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Video Data ?. content Details ?. duration ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput Int ( getString ( R . string . current _ second _ key ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMath . round ( m Tracker . current Second )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠSeek Dialog Fragment (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġarguments Ġ= Ġbundle ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. show ( support FragmentManager , ĠgetString ( R . string . see ker _ dialog _ id )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmenu . dismiss () ĊĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠĠĠĠĠ Ġdo Async Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontains Ġ= Ġm Main Data ViewModel . contains F avour ite ( m Video Id ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtext Ġ= Ġwhen Ġ( contains ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue Ġ-> ĠgetString ( R . string . fav our ites _ remove ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse Ġ-> ĠgetString ( R . string . fav our ites _ add ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġicon Ġ= Ġwhen Ġ( contains ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue Ġ-> ĠR . drawable . ic _ star _ black _ 2 4 dp ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse Ġ-> ĠR . drawable . ic _ star _ border _ black _ 2 4 dp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġwhen Ġ( contains ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue Ġ-> ĠgetString ( R . string . fav our ites _ removed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse Ġ-> ĠgetString ( R . string . fav our ites _ added ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġui Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmenu . addItem ( MenuItem ( text , Ġicon ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( contains ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue Ġ-> Ġm Main Data ViewModel . delete F avour ite ( Video Data ( m Video Id )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse Ġ-> Ġm Main Data ViewModel . insert F avour ite ( Video Data ( m Video Id )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠToast . makeText ( mContext , Ġmessage , ĠToast . LENGTH _ SHORT ). show () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRemove Ġmenu Ġitems ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( x Ġin Ġ 0 Ġuntil Ġmenu . item Count ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmenu . removeItem ( 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdd Ġitems Ġagain Ġto Ġupdate Ġthe Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Menu Items ( menu ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmenu . dismiss () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsetup Media Session () Ġ{ ĊĠĠĠĠĠĠĠ Ġm Media Session Ġ= ĠMedia Session Compat ( this , ĠTAG ) ĊĊĠĠĠĠĠĠĠ Ġm Media Session . set Flags ( Media Session Compat . FLAG _ HAND LES _ MEDIA _ BUTTON S Ġor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMedia Session Compat . FLAG _ HAND LES _ TRANSPORT _ CONTRO LS ) ĊĊĠĠĠĠĠĠĠ Ġm Media Session . set Media Button Receiver ( null ) ĊĠĠĠĠĠĠĠ Ġm State Builder Ġ= ĠPlay back State Compat . Builder (). set Actions ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . ACTION _ PLAY Ġor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . ACTION _ PAUSE Ġor Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . ACTION _ SKIP _ TO _ PREVIOUS Ġor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPlay back State Compat . ACTION _ PLAY _ PAUSE ) ĊĊĠĠĠĠĠĠĠ Ġm Media Session . set Playback State ( m State Builder . build ()) ĊĠĠĠĠĠĠĠ Ġm Media Session . set Callback ( Player Session Callback ()) ĊĠĠĠĠĠĠĠ Ġm Media Session . isActive Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshow Media Notification ( state : ĠPlay back State Compat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġis Playing Ġ= Ġstate . state Ġ== ĠPlay back State Compat . STATE _ PLAY ING ĊĊĠĠĠĠĠĠĠ Ġval Ġicon Ġ= Ġif Ġ( is Playing ) ĠR . drawable . ic _ pause _ 3 6 dp Ġelse ĠR . drawable . ic _ play _ 3 6 dp ĊĠĠĠĠĠĠĠ Ġval Ġplay Pause Ġ= Ġif Ġ( is Playing ) ĠgetString ( R . string . pause ) Ġelse ĠgetString ( R . string . play ) ĊĊĠĠĠĠĠĠĠ Ġval Ġbuilder : ĠNotification Compat . Builder Ġ= ĠNotification Compat . Builder ( this , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . notification _ channel _ id )) ĊĊĠĠĠĠĠĠĠ Ġval Ġplay Pause Action Ġ= ĠNotification Compat . Action ( icon , Ġplay Pause , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPending Intent . get Broadcast ( this , Ġ 2 9 2 3 5 8 8 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaction Ġ= ĠIntent . ACTION _ MEDIA _ BUTTON ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput Extra ( getString ( R . string . player _ action _ key ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠgetString ( R . string . player _ action _ play _ pause )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPending Intent . FLAG _ UPDATE _ CURRENT )) ĊĊĠĠĠĠĠĠĠ Ġval Ġcontent Pending Intent Ġ= ĠPending Intent . getActivity ( this , Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent ( this , ĠPlayer Activity :: class . java ), Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġbuilder . setContent Intent ( content Pending Intent ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Small Icon ( R . drawable . ic _ youtube _ 2 4 dp ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setVisibility ( Notification Compat . VIS IBILITY _ PUBLIC ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. addAction ( play Pause Action ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set O ngo ing ( is Playing ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setStyle ( android x . media . app . Notification Compat . Media Style () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Show Actions In Compact View ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Media Session ( m Media Session . session Token )) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( this :: m Video Thumbnail . isInitialized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . setContent Title ( m Video Data ?. snippet ?. title ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setContent Text ( m Video Data ?. snippet ?. channel Title ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Large Icon ( m Video Thumbnail ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( m Video Data Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( getSystem Service ( Context . NOTIFICATION _ SERVICE ) Ġas ĠNotification Manager ). cancel ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ( getSystem Service ( Context . NOTIFICATION _ SERVICE ) Ġas ĠNotification Manager ). notify ( 0 , Ġbuilder . build ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// //////////////////////////////////////////////////////////////////////////// // ĊĠĠĠ Ġ// ĠUtils ĊĠĠĠ Ġ// //////////////////////////////////////////////////////////////////////////// // ĊĊĠĠĠ Ġprivate Ġfun Ġget Intent Video Id ( intent : ĠIntent ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġextras : ĠBundle Ġ= Ġintent . extras !! ĊĠĠĠĠĠĠĠ Ġval Ġvideo Url : ĠString Ġ= Ġextras . getString ( Intent . EXTRA _ TEXT ) Ġ?: Ġ"" ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġextras . containsKey ( getString ( R . string . video _ id _ key )) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextras . getString ( getString ( R . string . video _ id _ key )) Ġas ĠString ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvideo Url . isNotEmpty () Ġ-> Ġvideo Url . substring ( video Url . length Ġ- Ġ 1 1 , Ġvideo Url . length ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" No Ġvideo Ġid Ġavailable , Ġcannot Ġinitialise Ġthe Ġplayer ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Playlist Id ( intent : ĠIntent ?): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġextras : ĠBundle Ġ= Ġintent ?. extras Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġvideo Url : ĠString Ġ= Ġextras . getString ( Intent . EXTRA _ TEXT ) Ġ?: Ġ"" ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġextras . containsKey ( getString ( R . string . playlist _ id _ key )) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġextras . getString ( getString ( R . string . playlist _ id _ key )) Ġas ĠString ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvideo Url . contains (" playlist ? list =") Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvideo Url . substring ( video Url . indexOf (" playlist ? list =", Ġ 0 ) Ġ+ Ġ 1 4 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġswitch Video ( video Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Video Id Ġ= Ġvideo Id ĊĠĠĠĠĠĠĠ Ġm Video Data Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġm YouTube Data . receive Video Data ( video Id ) ĊĠĠĠĠĠĠĠ Ġmain Player View . player . load Video ( video Id , Ġ 0 f ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! playlist Mode ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// //////////////////////////////////////////////////////////////////////////// // ĊĠĠĠ Ġ// ĠCallback s Ġ& Ġothers ĊĠĠĠ Ġ// //////////////////////////////////////////////////////////////////////////// // ĊĊĠĠĠ Ġprivate Ġfun Ġset Album Art ( url : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdo Async Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= ĠBitmap Factory . decode Stream ( URL ( url ). open Connection (). getInputStream ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġui Thread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Video Thumbnail Ġ= Ġbitmap ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshow Media Notification ( m State Builder . build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinner Ġclass ĠPlayer Session Callback Ġ: ĠMedia Session Compat . Callback () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Play () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmain Player View . toggle Play Pause () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Pause () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmain Player View . toggle Play Pause () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠPlayer Lifecycle Service Ġ: ĠService () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Bind ( intent : ĠIntent ?): ĠI Binder ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Task Removed ( root Intent : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Task Removed ( root Intent ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( getSystem Service ( Context . NOTIFICATION _ SERVICE ) Ġas ĠNotification Manager ). cancel ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop Self () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Video Data Received ( video Data : ĠVideo ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Video Data Ġ= Ġvideo Data ĊĊĠĠĠĠĠĠĠ Ġif Ġ( m Video Data ?. snippet ?. thumb nails ?. standard Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġm Video Data ?. snippet ?. thumb nails ?. standard ?. url ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( url Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Album Art ( url ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( m Video Data ?. content Details ?. duration Ġ== ĠgetString ( R . string . live _ video _ duration )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmain Player View . player UI Controller . enable Live Video UI ( true ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Playlist Data Received ( results : ĠList < Playlist Item >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnext PageToken : ĠString , Ġprevious PageToken : ĠString ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġplaylist Items : ĠList < Video Data > Ġ= Ġresults . map Ġ{ ĠVideo Data ( it . content Details . video Id ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠFirst Ġcall , Ġplay Ġthe Ġfirst Ġvideo Ġwhen Ġthe Ġplayer Ġis Ġready ĊĠĠĠĠĠĠĠ Ġif Ġ( m Prev PageToken . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmain Player View . player . addListener ( object Ġ: ĠAbstract YouTube Player Listener () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Ready () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġswitch Video ( playlist Items [ 0 ]. video Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġm Prev PageToken Ġ= Ġprevious PageToken ĊĠĠĠĠĠĠĠ Ġm Next PageToken Ġ= Ġnext PageToken ĊĊĠĠĠĠĠĠĠ Ġm YouTube Data . receive Video List Results ( playlist Items ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Video List Received ( results : ĠList < Video >, Ġblock : Ġ(( List < Video >) Ġ-> ĠList < Video >) ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġblock ?. invoke ( results )?. toList () Ġ?: Ġresults . toList () ĊĠĠĠĠĠĠĠ Ġm Adapter . add Items ( result . map Ġ{ ĠFeed Item ( it . id , Ġvideo Ġ= Ġit ) Ġ}) ĊĊĠĠĠĠĠĠĠ Ġvideo List . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠ ĠprogressBar Bottom . visibility Ġ= ĠView . GONE ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Related Videos Received ( results : ĠList < Feed Item >, Ġnext PageToken : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġm Adapter . add Items ( results ) ĊĠĠĠĠĠĠĠ ĠprogressBar Bottom . visibility Ġ= ĠView . GONE ĊĊĠĠĠĠĠĠĠ ĠLog . d (" Player Activity ", Ġ" Related Ġvideos Ġreceived ") ĊĠĠĠĠĠĠĠ Ġvideo List . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠ ĠprogressBar Centre . visibility Ġ= ĠView . IN VISIBLE ĊĠĠĠĠĠĠĠ Ġm Next PageToken Ġ= Ġnext PageToken ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon ListItem Click ( id : ĠString , Ġposition : ĠInt , Ġtype : ĠItem Type ) Ġ{ ĊĠĠĠĠĠĠĠ Ġswitch Video ( id ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( playlist Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . switch Now Playing ( position ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠmCurrent Video Index Ġ= Ġposition ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Adapter . clear Items () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Next PageToken Ġ= Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvideo List . visibility Ġ= ĠView . IN VISIBLE ĊĠĠĠĠĠĠĠĠĠĠĠ ĠprogressBar Centre . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm YouTube Data . receive Related Videos ( m Video Id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon ListItem Long Click ( id : ĠString , Ġtype : ĠItem Type ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . alert ( getString ( R . string . fav our ite _ add _ confirmation )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġyes Button Ġ{ Ġm Main Data ViewModel . insert F avour ite ( Video Data ( id )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġno Button Ġ{ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. show () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Seek Button Clicked ( duration : ĠFloat ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmain Player View . player . seek To ( duration ) ĊĠĠĠĠĠĠĠ Ġmain Player View . resume Playback () ĊĠĠĠ Ġ} Ċ } Ċ