Advertisement
Guest User

Untitled

a guest
Jan 17th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.75 KB | None | 0 0
  1. package com.bookmate.reader.book
  2.  
  3. import android.app.Activity
  4. import android.graphics.drawable.Drawable
  5. import android.support.annotation.MainThread
  6. import android.view.View
  7. import com.bookmate.common.android.dimenInt
  8. import com.bookmate.common.android.dimenSizeInt
  9. import com.bookmate.common.android.vibrator
  10. import com.bookmate.common.disposableDelegate
  11. import com.bookmate.reader.book.feature.content.MediaContentManager
  12. import com.bookmate.reader.book.feature.contextmenu.ContextMenuActionManager
  13. import com.bookmate.reader.book.feature.contextmenu.ContextMenuManager
  14. import com.bookmate.reader.book.feature.history.ProgressHistoryManager
  15. import com.bookmate.reader.book.feature.history.ProgressHistoryManager.ProgressHistoryInfo
  16. import com.bookmate.reader.book.feature.marker.MarkersManager
  17. import com.bookmate.reader.book.feature.navigation.NavigationManager
  18. import com.bookmate.reader.book.feature.rendering.presenter.ReaderPresenter
  19. import com.bookmate.reader.book.feature.rendering.presenter.WebViewReaderPresenter
  20. import com.bookmate.reader.book.feature.rendering.presenter.state.WebViewReaderPresenterState
  21. import com.bookmate.reader.book.feature.rendering.view.BookReaderPagingView
  22. import com.bookmate.reader.book.feature.rendering.view.BookReaderScrollingView
  23. import com.bookmate.reader.book.feature.rendering.view.WebViewReadingHelperView
  24. import com.bookmate.reader.book.feature.selection.SelectionManager
  25. import com.bookmate.reader.book.feature.selection.SelectorConfig
  26. import com.bookmate.reader.book.model.document.Document
  27. import com.bookmate.reader.book.newway.ChapterManager
  28. import com.bookmate.reader.book.tracking.*
  29. import com.bookmate.reader.book.tracking.ProgressTracker.ProgressHandler
  30. import com.bookmate.reader.book.ui.Metrics
  31. import com.bookmate.reader.book.ui.behavior.Behavior
  32. import com.bookmate.reader.book.ui.presenter.ApplicationFeatureBridge
  33. import com.bookmate.reader.book.ui.viewmodel.CommonViewModel
  34. import com.bookmate.reader.book.utils.requireMainThread
  35. import com.bookmate.reader.book.utils.requireWorkerThread
  36. import com.bookmate.reader.book.webview.ReaderWebView
  37. import com.bookmate.reader.book.webview.WebViewManager
  38. import kotlinx.coroutines.*
  39. import kotlinx.coroutines.Dispatchers.Default
  40. import kotlinx.coroutines.Dispatchers.Main
  41. import kotlin.coroutines.CoroutineContext
  42.  
  43. internal class ReaderComponentsInitializer : BaseReaderComponentsInitializer(), CoroutineScope {
  44.  
  45. private var readerComponents: ReaderComponents? = null
  46.  
  47. override var initializationListener: InitializationListener? = null
  48.  
  49. private lateinit var scrollingView: BookReaderScrollingView
  50. private lateinit var pagingView: BookReaderPagingView
  51. private lateinit var progressHistoryManager: ProgressHistoryManager
  52. private lateinit var brightnessManager: BrightnessManager
  53. private lateinit var viewModel: CommonViewModel
  54. private lateinit var selectionManager: SelectionManager
  55. private lateinit var markersManager: MarkersManager
  56. private lateinit var contextMenuManager: ContextMenuManager
  57. private lateinit var contextMenuActionManager: ContextMenuActionManager
  58. private lateinit var mediaContentManager: MediaContentManager
  59. private lateinit var progressTrackerWithHandlers: Pair<ProgressTracker, List<ProgressHandler>>
  60. private lateinit var navigationManager: NavigationManager
  61. private lateinit var chapterManager: ChapterManager<*>
  62. private lateinit var presenter: ReaderPresenter<*>
  63.  
  64. private var job: Job? = null
  65.  
  66. override val coroutineContext: CoroutineContext = Main
  67.  
  68. override val isInitialized: Boolean
  69. get() {
  70. requireMainThread()
  71. return readerComponents != null
  72. }
  73.  
  74. override fun runIfInitialized(action: ReaderComponents.() -> Unit) {
  75. requireMainThread()
  76. readerComponents
  77. ?.action()
  78. ?: run { throw IllegalStateException("Components must be initialized") }
  79. }
  80.  
  81. override fun runIfInitializedSafely(action: ReaderComponents.() -> Unit) {
  82. requireMainThread()
  83. readerComponents
  84. ?.action()
  85. }
  86.  
  87. @MainThread
  88. override fun initialize(
  89. activity: Activity,
  90. getBehavior: () -> Behavior,
  91. toggleSystemUi: () -> Unit,
  92. updateUiProgress: (
  93. globalProgress: Double,
  94. globalProgressItemId: String?,
  95. progressHistoryInfo: ProgressHistoryInfo
  96. ) -> Unit,
  97. webViewReadingHelperView: WebViewReadingHelperView,
  98. webView: ReaderWebView,
  99. webViewWrapper: View,
  100. webViewManager: WebViewManager,
  101. brightnessOverlayDrawable: Drawable,
  102. bookUuid: String,
  103. bookReader: BookReader
  104. ) {
  105. launch {
  106. job?.cancelAndJoin()
  107.  
  108. job = launch(Main) {
  109. requireMainThread()
  110.  
  111. initializationListener?.onInitializationStarted()
  112.  
  113. scrollingView = BookReaderScrollingView(webView, webViewReadingHelperView)
  114. pagingView = BookReaderPagingView(webView, webViewManager, webViewReadingHelperView)
  115.  
  116. val components = withContext(Default) {
  117. getReaderComponents(
  118. activity,
  119. getBehavior,
  120. toggleSystemUi,
  121. updateUiProgress,
  122. brightnessOverlayDrawable,
  123. bookUuid,
  124. bookReader,
  125. webViewManager,
  126. scrollingView,
  127. pagingView
  128. )
  129. }
  130.  
  131. yield()
  132.  
  133. readerComponents = components
  134. initializationListener?.onInitializationEnded(components)
  135. }
  136. }
  137. }
  138.  
  139. @MainThread
  140. override fun destroy() {
  141. launch {
  142. requireMainThread()
  143.  
  144. job?.cancelAndJoin()
  145.  
  146. var readerComponentsDestructionStarted = false
  147.  
  148. runIfInitializedSafely {
  149. readerComponentsDestructionStarted = true
  150. initializationListener?.onDestructionStarted(this)
  151. readerComponents = null
  152. }
  153.  
  154. checkAndDestroyEveryComponent()
  155.  
  156. if (readerComponentsDestructionStarted) {
  157. initializationListener?.onDestructionEnded()
  158. }
  159. }
  160. }
  161.  
  162. private fun checkAndDestroyEveryComponent() {
  163. if (this::scrollingView.isInitialized) scrollingView.release()
  164. if (this::pagingView.isInitialized) pagingView.release()
  165. if (this::progressHistoryManager.isInitialized) progressHistoryManager.clear()
  166. if (this::selectionManager.isInitialized) selectionManager.clear()
  167. if (this::contextMenuManager.isInitialized) contextMenuManager.release()
  168. if (this::mediaContentManager.isInitialized) mediaContentManager.release()
  169. if (this::progressTrackerWithHandlers.isInitialized) progressTrackerWithHandlers.apply {
  170. first.run {
  171. this -= second
  172. attachTo(null)
  173. }
  174. }
  175. if (this::contextMenuActionManager.isInitialized) contextMenuActionManager.release()
  176. if (this::presenter.isInitialized) presenter.release()
  177. }
  178.  
  179. private suspend fun getReaderComponents(
  180. activity: Activity,
  181. getBehavior: () -> Behavior,
  182. toggleSystemUi: () -> Unit,
  183. updateUiProgress: (Double, String?, ProgressHistoryInfo) -> Unit,
  184. brightnessOverlayDrawable: Drawable,
  185. bookUuid: String,
  186. bookReader: BookReader,
  187. webViewManager: WebViewManager,
  188. scrollingView: BookReaderScrollingView,
  189. pagingView: BookReaderPagingView
  190. ): ReaderComponents {
  191. requireWorkerThread()
  192.  
  193. // components independent
  194. yield()
  195. viewModel = CommonViewModel()
  196.  
  197. yield()
  198. progressHistoryManager = bookReader.progressHistoryManager
  199.  
  200. yield()
  201. brightnessManager = createBrightnessManager(activity, brightnessOverlayDrawable)
  202.  
  203. yield()
  204. navigationManager = NavigationManager(Metrics, { toggleSystemUi() }, activity.resources)
  205.  
  206. // components dependent
  207. yield()
  208. selectionManager = createSelectionManager(webViewManager, activity, viewModel)
  209. .also { it.init() }
  210.  
  211. yield()
  212. mediaContentManager = createMediaContentManager(activity, webViewManager, bookUuid)
  213. .also { it.bindTo(viewModel) }
  214.  
  215. yield()
  216. progressTrackerWithHandlers = createProgressTrackerWithHandlers(
  217. bookReader,
  218. updateUiProgress,
  219. progressHistoryManager
  220. ).also { it.first.attachTo(viewModel) }
  221.  
  222. yield()
  223. markersManager = createMarkerManager(
  224. webViewManager,
  225. bookReader.document,
  226. bookReader.applicationFeatureBridge,
  227. viewModel,
  228. selectionManager
  229. )
  230.  
  231. yield()
  232. presenter = WebViewReaderPresenter(
  233. markersManager = markersManager,
  234. bookLoadingViewModel = viewModel,
  235. bookLoadingInDirectionViewModel = viewModel,
  236. bookLoadingRetryViewModel = viewModel,
  237. viewScrollViewModel = viewModel,
  238. mediaElementsViewModel = viewModel,
  239. webViewManager = webViewManager,
  240. document = bookReader.document,
  241. pageLoadingExceptionDetectors = bookReader.pageLoadingExceptionDetectors,
  242. pageLoadingExceptionResolvers = bookReader.pageLoadingExceptionResolvers,
  243. metrics = Metrics
  244. ).also { presenter ->
  245. yield()
  246. markersManager.bindTo(presenter, viewModel, viewModel)
  247.  
  248. yield()
  249. contextMenuActionManager = createContextMenuActionManager(
  250. bookReader.document,
  251. bookReader.applicationFeatureBridge,
  252. selectionManager,
  253. markersManager
  254. ).also { it.bindTo(presenter, viewModel) }
  255.  
  256. yield()
  257. chapterManager = ChapterManager<WebViewReaderPresenterState>(
  258. document = bookReader.document,
  259. behavior = { getBehavior() },
  260. metrics = Metrics
  261. ).also { it.bindTo(presenter) }
  262.  
  263. yield()
  264. BookProgressChangingManager<WebViewReaderPresenterState>(
  265. document = bookReader.document,
  266. behavior = { getBehavior() },
  267. metrics = Metrics,
  268. viewScrollViewModel = viewModel,
  269. bookProgressChangingViewModel = viewModel,
  270. scrollInfoTransformer = BaseScrollInfoTransformer(
  271. webViewManager,
  272. bookReader.document,
  273. { getBehavior() }
  274. )
  275. ).bindTo(presenter)
  276. }
  277.  
  278. yield()
  279. contextMenuManager = createContextMenuManager(viewModel)
  280. .also { it.bindTo(viewModel, viewModel, markersManager) }
  281.  
  282. return ReaderComponents(
  283. scrollingView,
  284. pagingView,
  285. progressHistoryManager,
  286. brightnessManager,
  287. viewModel,
  288. selectionManager,
  289. markersManager,
  290. contextMenuManager,
  291. contextMenuActionManager,
  292. mediaContentManager,
  293. progressTrackerWithHandlers.first,
  294. navigationManager,
  295. chapterManager,
  296. presenter
  297. )
  298. }
  299.  
  300. private fun createProgressTrackerWithHandlers(
  301. bookReader: BookReader,
  302. updateUiProgress: (Double, String?, ProgressHistoryInfo) -> Unit,
  303. progressHistoryManager: ProgressHistoryManager
  304. ): Pair<ProgressTracker, List<ProgressHandler>> {
  305.  
  306. val progressHandlers = listOf(
  307. UpdateUiProgressHandler { globalProgress, globalProgressItemId ->
  308. updateUiProgress(globalProgress, globalProgressItemId, progressHistoryManager.info)
  309. },
  310. ReadingStateProgressHandler()
  311. )
  312.  
  313. val progressTracker = bookReader.progressTracker.apply {
  314. this += progressHandlers
  315. }
  316.  
  317. return progressTracker to progressHandlers
  318. }
  319.  
  320. private fun createBrightnessManager(
  321. activity: Activity,
  322. brightnessOverlayDrawable: Drawable
  323. ): BrightnessManager {
  324. return BrightnessManager(
  325. windowProvider = { activity.window },
  326. overlayProvider = { brightnessOverlayDrawable }
  327. )
  328. }
  329.  
  330. private fun createMediaContentManager(
  331. activity: Activity,
  332. webViewManager: WebViewManager,
  333. bookUuid: String
  334. ): MediaContentManager {
  335. return MediaContentManager(
  336. context = activity,
  337. bookUuid = bookUuid,
  338. webViewManager = webViewManager,
  339. metrics = Metrics
  340. )
  341. }
  342.  
  343. private fun createContextMenuActionManager(
  344. document: Document,
  345. applicationFeatureBridge: ApplicationFeatureBridge,
  346. selectionManager: SelectionManager,
  347. markerManager: MarkersManager
  348. ): ContextMenuActionManager {
  349. return ContextMenuActionManager(
  350. document = document,
  351. selectionManager = selectionManager,
  352. selectionActionModel = viewModel,
  353. applicationFeatureBridge = applicationFeatureBridge,
  354. markersManager = markerManager
  355. )
  356. }
  357.  
  358. private fun createContextMenuManager(
  359. viewModel: CommonViewModel
  360. ): ContextMenuManager {
  361. return ContextMenuManager(
  362. contextMenuViewModel = viewModel,
  363. metrics = Metrics
  364. )
  365. }
  366.  
  367. private fun createMarkerManager(
  368. webViewManager: WebViewManager,
  369. document: Document,
  370. applicationFeatureBridge: ApplicationFeatureBridge,
  371. viewModel: CommonViewModel,
  372. selectionManager: SelectionManager
  373. ): MarkersManager {
  374. return MarkersManager(
  375. document = document,
  376. webViewManager = webViewManager,
  377. selectionActionModel = viewModel,
  378. markerViewModel = viewModel,
  379. selectionManager = selectionManager,
  380. applicationFeatureBridge = applicationFeatureBridge
  381. )
  382. }
  383.  
  384. private fun createSelectionManager(
  385. webViewManager: WebViewManager,
  386. activity: Activity,
  387. viewModel: CommonViewModel
  388. ): SelectionManager {
  389. return SelectionManager(
  390. webViewManager = webViewManager,
  391. metrics = Metrics,
  392. bookLoadingViewModel = viewModel,
  393. selectionViewModel = viewModel,
  394. selectionActionModel = viewModel,
  395. selectorConfig = SelectorConfig(
  396. { activity.vibrator },
  397. { activity.dimenInt(R.dimen.selector_tap_zone_radius) },
  398. {
  399. maxOf(
  400. activity.dimenSizeInt(R.dimen.selector_width),
  401. activity.dimenSizeInt(R.dimen.selector_height)
  402. )
  403. }
  404. )
  405. )
  406. }
  407.  
  408. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement