Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.bookmate.reader.book
- import android.app.Activity
- import android.graphics.drawable.Drawable
- import android.support.annotation.MainThread
- import android.view.View
- import com.bookmate.common.android.dimenInt
- import com.bookmate.common.android.dimenSizeInt
- import com.bookmate.common.android.vibrator
- import com.bookmate.common.disposableDelegate
- import com.bookmate.reader.book.feature.content.MediaContentManager
- import com.bookmate.reader.book.feature.contextmenu.ContextMenuActionManager
- import com.bookmate.reader.book.feature.contextmenu.ContextMenuManager
- import com.bookmate.reader.book.feature.history.ProgressHistoryManager
- import com.bookmate.reader.book.feature.history.ProgressHistoryManager.ProgressHistoryInfo
- import com.bookmate.reader.book.feature.marker.MarkersManager
- import com.bookmate.reader.book.feature.navigation.NavigationManager
- import com.bookmate.reader.book.feature.rendering.presenter.ReaderPresenter
- import com.bookmate.reader.book.feature.rendering.presenter.WebViewReaderPresenter
- import com.bookmate.reader.book.feature.rendering.presenter.state.WebViewReaderPresenterState
- import com.bookmate.reader.book.feature.rendering.view.BookReaderPagingView
- import com.bookmate.reader.book.feature.rendering.view.BookReaderScrollingView
- import com.bookmate.reader.book.feature.rendering.view.WebViewReadingHelperView
- import com.bookmate.reader.book.feature.selection.SelectionManager
- import com.bookmate.reader.book.feature.selection.SelectorConfig
- import com.bookmate.reader.book.model.document.Document
- import com.bookmate.reader.book.newway.ChapterManager
- import com.bookmate.reader.book.tracking.*
- import com.bookmate.reader.book.tracking.ProgressTracker.ProgressHandler
- import com.bookmate.reader.book.ui.Metrics
- import com.bookmate.reader.book.ui.behavior.Behavior
- import com.bookmate.reader.book.ui.presenter.ApplicationFeatureBridge
- import com.bookmate.reader.book.ui.viewmodel.CommonViewModel
- import com.bookmate.reader.book.utils.requireMainThread
- import com.bookmate.reader.book.utils.requireWorkerThread
- import com.bookmate.reader.book.webview.ReaderWebView
- import com.bookmate.reader.book.webview.WebViewManager
- import kotlinx.coroutines.*
- import kotlinx.coroutines.Dispatchers.Default
- import kotlinx.coroutines.Dispatchers.Main
- import kotlin.coroutines.CoroutineContext
- internal class ReaderComponentsInitializer : BaseReaderComponentsInitializer(), CoroutineScope {
- private var readerComponents: ReaderComponents? = null
- override var initializationListener: InitializationListener? = null
- private lateinit var scrollingView: BookReaderScrollingView
- private lateinit var pagingView: BookReaderPagingView
- private lateinit var progressHistoryManager: ProgressHistoryManager
- private lateinit var brightnessManager: BrightnessManager
- private lateinit var viewModel: CommonViewModel
- private lateinit var selectionManager: SelectionManager
- private lateinit var markersManager: MarkersManager
- private lateinit var contextMenuManager: ContextMenuManager
- private lateinit var contextMenuActionManager: ContextMenuActionManager
- private lateinit var mediaContentManager: MediaContentManager
- private lateinit var progressTrackerWithHandlers: Pair<ProgressTracker, List<ProgressHandler>>
- private lateinit var navigationManager: NavigationManager
- private lateinit var chapterManager: ChapterManager<*>
- private lateinit var presenter: ReaderPresenter<*>
- private var job: Job? = null
- override val coroutineContext: CoroutineContext = Main
- override val isInitialized: Boolean
- get() {
- requireMainThread()
- return readerComponents != null
- }
- override fun runIfInitialized(action: ReaderComponents.() -> Unit) {
- requireMainThread()
- readerComponents
- ?.action()
- ?: run { throw IllegalStateException("Components must be initialized") }
- }
- override fun runIfInitializedSafely(action: ReaderComponents.() -> Unit) {
- requireMainThread()
- readerComponents
- ?.action()
- }
- @MainThread
- override fun initialize(
- activity: Activity,
- getBehavior: () -> Behavior,
- toggleSystemUi: () -> Unit,
- updateUiProgress: (
- globalProgress: Double,
- globalProgressItemId: String?,
- progressHistoryInfo: ProgressHistoryInfo
- ) -> Unit,
- webViewReadingHelperView: WebViewReadingHelperView,
- webView: ReaderWebView,
- webViewWrapper: View,
- webViewManager: WebViewManager,
- brightnessOverlayDrawable: Drawable,
- bookUuid: String,
- bookReader: BookReader
- ) {
- launch {
- job?.cancelAndJoin()
- job = launch(Main) {
- requireMainThread()
- initializationListener?.onInitializationStarted()
- scrollingView = BookReaderScrollingView(webView, webViewReadingHelperView)
- pagingView = BookReaderPagingView(webView, webViewManager, webViewReadingHelperView)
- val components = withContext(Default) {
- getReaderComponents(
- activity,
- getBehavior,
- toggleSystemUi,
- updateUiProgress,
- brightnessOverlayDrawable,
- bookUuid,
- bookReader,
- webViewManager,
- scrollingView,
- pagingView
- )
- }
- yield()
- readerComponents = components
- initializationListener?.onInitializationEnded(components)
- }
- }
- }
- @MainThread
- override fun destroy() {
- launch {
- requireMainThread()
- job?.cancelAndJoin()
- var readerComponentsDestructionStarted = false
- runIfInitializedSafely {
- readerComponentsDestructionStarted = true
- initializationListener?.onDestructionStarted(this)
- readerComponents = null
- }
- checkAndDestroyEveryComponent()
- if (readerComponentsDestructionStarted) {
- initializationListener?.onDestructionEnded()
- }
- }
- }
- private fun checkAndDestroyEveryComponent() {
- if (this::scrollingView.isInitialized) scrollingView.release()
- if (this::pagingView.isInitialized) pagingView.release()
- if (this::progressHistoryManager.isInitialized) progressHistoryManager.clear()
- if (this::selectionManager.isInitialized) selectionManager.clear()
- if (this::contextMenuManager.isInitialized) contextMenuManager.release()
- if (this::mediaContentManager.isInitialized) mediaContentManager.release()
- if (this::progressTrackerWithHandlers.isInitialized) progressTrackerWithHandlers.apply {
- first.run {
- this -= second
- attachTo(null)
- }
- }
- if (this::contextMenuActionManager.isInitialized) contextMenuActionManager.release()
- if (this::presenter.isInitialized) presenter.release()
- }
- private suspend fun getReaderComponents(
- activity: Activity,
- getBehavior: () -> Behavior,
- toggleSystemUi: () -> Unit,
- updateUiProgress: (Double, String?, ProgressHistoryInfo) -> Unit,
- brightnessOverlayDrawable: Drawable,
- bookUuid: String,
- bookReader: BookReader,
- webViewManager: WebViewManager,
- scrollingView: BookReaderScrollingView,
- pagingView: BookReaderPagingView
- ): ReaderComponents {
- requireWorkerThread()
- // components independent
- yield()
- viewModel = CommonViewModel()
- yield()
- progressHistoryManager = bookReader.progressHistoryManager
- yield()
- brightnessManager = createBrightnessManager(activity, brightnessOverlayDrawable)
- yield()
- navigationManager = NavigationManager(Metrics, { toggleSystemUi() }, activity.resources)
- // components dependent
- yield()
- selectionManager = createSelectionManager(webViewManager, activity, viewModel)
- .also { it.init() }
- yield()
- mediaContentManager = createMediaContentManager(activity, webViewManager, bookUuid)
- .also { it.bindTo(viewModel) }
- yield()
- progressTrackerWithHandlers = createProgressTrackerWithHandlers(
- bookReader,
- updateUiProgress,
- progressHistoryManager
- ).also { it.first.attachTo(viewModel) }
- yield()
- markersManager = createMarkerManager(
- webViewManager,
- bookReader.document,
- bookReader.applicationFeatureBridge,
- viewModel,
- selectionManager
- )
- yield()
- presenter = WebViewReaderPresenter(
- markersManager = markersManager,
- bookLoadingViewModel = viewModel,
- bookLoadingInDirectionViewModel = viewModel,
- bookLoadingRetryViewModel = viewModel,
- viewScrollViewModel = viewModel,
- mediaElementsViewModel = viewModel,
- webViewManager = webViewManager,
- document = bookReader.document,
- pageLoadingExceptionDetectors = bookReader.pageLoadingExceptionDetectors,
- pageLoadingExceptionResolvers = bookReader.pageLoadingExceptionResolvers,
- metrics = Metrics
- ).also { presenter ->
- yield()
- markersManager.bindTo(presenter, viewModel, viewModel)
- yield()
- contextMenuActionManager = createContextMenuActionManager(
- bookReader.document,
- bookReader.applicationFeatureBridge,
- selectionManager,
- markersManager
- ).also { it.bindTo(presenter, viewModel) }
- yield()
- chapterManager = ChapterManager<WebViewReaderPresenterState>(
- document = bookReader.document,
- behavior = { getBehavior() },
- metrics = Metrics
- ).also { it.bindTo(presenter) }
- yield()
- BookProgressChangingManager<WebViewReaderPresenterState>(
- document = bookReader.document,
- behavior = { getBehavior() },
- metrics = Metrics,
- viewScrollViewModel = viewModel,
- bookProgressChangingViewModel = viewModel,
- scrollInfoTransformer = BaseScrollInfoTransformer(
- webViewManager,
- bookReader.document,
- { getBehavior() }
- )
- ).bindTo(presenter)
- }
- yield()
- contextMenuManager = createContextMenuManager(viewModel)
- .also { it.bindTo(viewModel, viewModel, markersManager) }
- return ReaderComponents(
- scrollingView,
- pagingView,
- progressHistoryManager,
- brightnessManager,
- viewModel,
- selectionManager,
- markersManager,
- contextMenuManager,
- contextMenuActionManager,
- mediaContentManager,
- progressTrackerWithHandlers.first,
- navigationManager,
- chapterManager,
- presenter
- )
- }
- private fun createProgressTrackerWithHandlers(
- bookReader: BookReader,
- updateUiProgress: (Double, String?, ProgressHistoryInfo) -> Unit,
- progressHistoryManager: ProgressHistoryManager
- ): Pair<ProgressTracker, List<ProgressHandler>> {
- val progressHandlers = listOf(
- UpdateUiProgressHandler { globalProgress, globalProgressItemId ->
- updateUiProgress(globalProgress, globalProgressItemId, progressHistoryManager.info)
- },
- ReadingStateProgressHandler()
- )
- val progressTracker = bookReader.progressTracker.apply {
- this += progressHandlers
- }
- return progressTracker to progressHandlers
- }
- private fun createBrightnessManager(
- activity: Activity,
- brightnessOverlayDrawable: Drawable
- ): BrightnessManager {
- return BrightnessManager(
- windowProvider = { activity.window },
- overlayProvider = { brightnessOverlayDrawable }
- )
- }
- private fun createMediaContentManager(
- activity: Activity,
- webViewManager: WebViewManager,
- bookUuid: String
- ): MediaContentManager {
- return MediaContentManager(
- context = activity,
- bookUuid = bookUuid,
- webViewManager = webViewManager,
- metrics = Metrics
- )
- }
- private fun createContextMenuActionManager(
- document: Document,
- applicationFeatureBridge: ApplicationFeatureBridge,
- selectionManager: SelectionManager,
- markerManager: MarkersManager
- ): ContextMenuActionManager {
- return ContextMenuActionManager(
- document = document,
- selectionManager = selectionManager,
- selectionActionModel = viewModel,
- applicationFeatureBridge = applicationFeatureBridge,
- markersManager = markerManager
- )
- }
- private fun createContextMenuManager(
- viewModel: CommonViewModel
- ): ContextMenuManager {
- return ContextMenuManager(
- contextMenuViewModel = viewModel,
- metrics = Metrics
- )
- }
- private fun createMarkerManager(
- webViewManager: WebViewManager,
- document: Document,
- applicationFeatureBridge: ApplicationFeatureBridge,
- viewModel: CommonViewModel,
- selectionManager: SelectionManager
- ): MarkersManager {
- return MarkersManager(
- document = document,
- webViewManager = webViewManager,
- selectionActionModel = viewModel,
- markerViewModel = viewModel,
- selectionManager = selectionManager,
- applicationFeatureBridge = applicationFeatureBridge
- )
- }
- private fun createSelectionManager(
- webViewManager: WebViewManager,
- activity: Activity,
- viewModel: CommonViewModel
- ): SelectionManager {
- return SelectionManager(
- webViewManager = webViewManager,
- metrics = Metrics,
- bookLoadingViewModel = viewModel,
- selectionViewModel = viewModel,
- selectionActionModel = viewModel,
- selectorConfig = SelectorConfig(
- { activity.vibrator },
- { activity.dimenInt(R.dimen.selector_tap_zone_radius) },
- {
- maxOf(
- activity.dimenSizeInt(R.dimen.selector_width),
- activity.dimenSizeInt(R.dimen.selector_height)
- )
- }
- )
- )
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement