Skip to content

Commit

Permalink
Merge pull request #317 from art-institute-of-chicago/tour_advance
Browse files Browse the repository at this point in the history
Advances tour stop when it's audio playback ends (AIC-555)
  • Loading branch information
Cliabhach authored Nov 1, 2018
2 parents ad86bac + 43a385f commit 42d62ab
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 8 deletions.
1 change: 1 addition & 0 deletions media/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ dependencies {
implementation project(':analytics')
implementation project(':base')
implementation project(':db')
implementation project(':tour_manager')
}
13 changes: 9 additions & 4 deletions media/src/main/java/edu/artic/media/audio/AudioPlayerService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import edu.artic.media.R
import edu.artic.media.audio.AudioPlayerService.PlayBackAction
import edu.artic.media.audio.AudioPlayerService.PlayBackAction.*
import edu.artic.media.audio.AudioPlayerService.PlayBackState.*
import edu.artic.tours.manager.TourProgressManager
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.Subject
import javax.inject.Inject
Expand Down Expand Up @@ -168,6 +169,9 @@ class AudioPlayerService : DaggerService(), PlayerService {
@Inject
lateinit var audioPrefManager: AudioPrefManager

@Inject
lateinit var tourProgressManager: TourProgressManager

/**
* Something with one or more audio tracks. See [currentTrack] and [AudioFileModel].
*/
Expand Down Expand Up @@ -205,6 +209,7 @@ class AudioPlayerService : DaggerService(), PlayerService {
analyticsTracker.reportEvent(EventCategoryName.PlayBack, AnalyticsAction.playbackCompleted, currentTrack.value?.title.orEmpty())
audioPlayBackStatus.onNext(PlayBackState.Stopped(given))
playerNotificationManager.setPlayer(null)
tourProgressManager.playBackEnded(given)
currentTrack.onNext(EMPTY_AUDIO_FILE)
}
playbackState == Player.STATE_IDLE -> audioPlayBackStatus.onNext(PlayBackState.Stopped(given))
Expand Down Expand Up @@ -232,8 +237,8 @@ class AudioPlayerService : DaggerService(), PlayerService {
when (playBackAction) {
is PlayBackAction.Play -> {
playerNotificationManager.setPlayer(player)
// No need to seek here; that'll be done in 'setArticObject' if needed
setArticObject(playBackAction.audioFile, playBackAction.audioModel)
// No need to seek here; that'll be done in 'changeAudio' if needed
changeAudio(playBackAction.audioFile, playBackAction.audioModel)
/**
* If the audio is being played for the first time, make sure we invoke
* [AudioServiceHook.displayAudioTutorial] event.
Expand Down Expand Up @@ -362,7 +367,7 @@ class AudioPlayerService : DaggerService(), PlayerService {
}
}

fun setArticObject(_articObject: Playable, audio: AudioFileModel, resetPosition: Boolean = false) {
fun changeAudio(_articObject: Playable, audio: AudioFileModel, resetPosition: Boolean = false) {

val isDifferentAudio = (currentTrack as BehaviorSubject).value != audio

Expand Down Expand Up @@ -453,7 +458,7 @@ class AudioPlayerService : DaggerService(), PlayerService {
* If nothing is [currently playing][audioPlayBackStatus], this skips
* the 'pause' and 'resume' operations.
*
* @see setArticObject
* @see changeAudio
*/
override fun switchAudioTrack(alternative: AudioFileModel) {
playable?.let {
Expand Down
1 change: 1 addition & 0 deletions tour_manager/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ dependencies {
kapt libs.dagger_android_compiler
implementation project(':db')
implementation libs.rx_kotlin
implementation libs.rx_helpers
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package edu.artic.tours.manager

import dagger.Module
import dagger.Provides
import edu.artic.db.daos.ArticAudioFileDao
import javax.inject.Singleton

/**
Expand All @@ -15,6 +16,6 @@ abstract class TourManagerModule {
@JvmStatic
@Provides
@Singleton
fun tourProgressManager(): TourProgressManager = TourProgressManager()
fun tourProgressManager(audioFileDao: ArticAudioFileDao): TourProgressManager = TourProgressManager(audioFileDao)
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
package edu.artic.tours.manager

import android.annotation.SuppressLint
import android.support.annotation.WorkerThread
import com.fuzz.rx.Optional
import com.fuzz.rx.filterValue
import edu.artic.db.INTRO_TOUR_STOP_OBJECT_ID
import edu.artic.db.daos.ArticAudioFileDao
import edu.artic.db.models.ArticTour
import edu.artic.db.models.AudioFileModel
import io.reactivex.rxkotlin.Observables
import io.reactivex.rxkotlin.subscribeBy
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.Subject


import timber.log.Timber

/**
* Responsible for managing the communication between tour carousel and the map.
* @author Sameer Dhakal (Fuzz)
*/
class TourProgressManager {
class TourProgressManager(val audioFileDao: ArticAudioFileDao) {
/**
* Selected ArticObject
*/
Expand All @@ -23,4 +30,61 @@ class TourProgressManager {
val selectedTour: Subject<Optional<ArticTour>> = BehaviorSubject.createDefault(Optional(null))
val proposedTour: Subject<Optional<Pair<ArticTour, ArticTour.TourStop>>> = BehaviorSubject.createDefault(Optional(null))
val leaveTourRequest: Subject<Boolean> = PublishSubject.create()

/**
* If [audioFileModel] belongs to currently selected tour i.e. [selectedTour],
* this method advances [selectedStop] to next tour stop.
*/
@WorkerThread
@SuppressLint("CheckResult")
fun playBackEnded(audioFileModel: AudioFileModel) {
Observables.combineLatest(selectedTour.filterValue(), selectedStop)
.take(1)
.subscribe { (tour, currentStopID) ->

/**
* Get audio file id
*/
val audioFileID: String? = if (currentStopID == INTRO_TOUR_STOP_OBJECT_ID) {
tour.tourAudio
} else {
tour.tourStops.find { it.objectId == currentStopID }?.audioId
}

audioFileID?.let { audioID ->
audioFileDao
.getAudioByIdAsync(audioID)
.toObservable()
.subscribeBy(
onNext = { audioFile ->

/**
* Check if currently ended audio playback session belongs to
* current tour stop.
*/
val isCurrentStopsAudioTranslation = audioFile
.allTranslations()
.contains(audioFileModel)

/**
* Advance [selectedStop] if current audio translation playback
* completed.
*/
if (isCurrentStopsAudioTranslation) {
val indexOfCurrentTourStop = tour.tourStops.indexOfFirst { it.objectId == currentStopID }
val nextStopIndex = Math.min(indexOfCurrentTourStop + 1, tour.tourStops.size)
tour.tourStops[nextStopIndex].objectId?.let {
selectedStop.onNext(it)
}
}
},
onError = { t ->
Timber.e(t, "Couldn't fetch audio by $audioID")
})
}
}

}


}

0 comments on commit 42d62ab

Please sign in to comment.