diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/base/PageDecodeErrorLayout.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/base/PageDecodeErrorLayout.kt index 91bd719fb..562356551 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/base/PageDecodeErrorLayout.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/base/PageDecodeErrorLayout.kt @@ -1,71 +1,40 @@ package eu.kanade.tachiyomi.ui.reader.viewer.base -import android.content.Context -import android.content.Intent import android.net.Uri import android.support.v4.content.ContextCompat -import android.view.Gravity import android.view.View -import android.view.ViewGroup -import android.view.ViewGroup.LayoutParams.WRAP_CONTENT -import android.widget.Button -import android.widget.LinearLayout -import android.widget.TextView import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.source.model.Page import eu.kanade.tachiyomi.ui.reader.ReaderActivity +import kotlinx.android.synthetic.main.page_decode_error.view.* -class PageDecodeErrorLayout(context: Context) : LinearLayout(context) { - - /** - * Text color for black theme. - */ - private val whiteColor = ContextCompat.getColor(context, R.color.textColorSecondaryDark) - - /** - * Text color for white theme. - */ - private val blackColor = ContextCompat.getColor(context, R.color.textColorSecondaryLight) +class PageDecodeErrorLayout( + val view: View, + val page: Page, + val theme: Int, + val retryListener: () -> Unit +) { init { - orientation = LinearLayout.VERTICAL - gravity = Gravity.CENTER + val textColor = if (theme == ReaderActivity.BLACK_THEME) + ContextCompat.getColor(view.context, R.color.textColorSecondaryDark) + else + ContextCompat.getColor(view.context, R.color.textColorSecondaryLight) + + view.decode_error_text.setTextColor(textColor) + + view.decode_retry.setOnClickListener { + retryListener() + } + + view.decode_open_browser.setOnClickListener { + val intent = android.content.Intent(android.content.Intent.ACTION_VIEW, Uri.parse(page.imageUrl)) + view.context.startActivity(intent) + } + + if (page.imageUrl == null) { + view.decode_open_browser.visibility = View.GONE + } } - constructor(context: Context, page: Page, theme: Int, retryListener: () -> Unit) : this(context) { - - // Error message. - TextView(context).apply { - gravity = Gravity.CENTER - setText(R.string.decode_image_error) - setTextColor(if (theme == ReaderActivity.BLACK_THEME) whiteColor else blackColor) - addView(this) - } - - // Retry button. - Button(context).apply { - layoutParams = ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT) - setText(R.string.action_retry) - setOnClickListener { - retryListener() - } - addView(this) - } - - // Open in browser button. - Button(context).apply { - layoutParams = ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT) - setText(R.string.action_open_in_browser) - setOnClickListener { v -> - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(page.imageUrl)) - context.startActivity(intent) - } - - if (page.imageUrl == null) { - visibility = View.GONE - } - addView(this) - } - - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PageView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PageView.kt index 8791efecb..25b172637 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PageView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PageView.kt @@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.viewer.base.PageDecodeErrorLayout import eu.kanade.tachiyomi.ui.reader.viewer.pager.horizontal.RightToLeftReader import eu.kanade.tachiyomi.ui.reader.viewer.pager.vertical.VerticalReader +import eu.kanade.tachiyomi.util.inflate import kotlinx.android.synthetic.main.chapter_image.view.* import kotlinx.android.synthetic.main.item_pager_reader.view.* import rx.Observable @@ -45,7 +46,7 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet? /** * Layout of decode error. */ - private var decodeErrorLayout: PageDecodeErrorLayout? = null + private var decodeErrorLayout: View? = null fun initialize(reader: PagerReader, page: Page) { val activity = reader.activity as ReaderActivity @@ -243,14 +244,20 @@ class PageView @JvmOverloads constructor(context: Context, attrs: AttributeSet? * Called when an image fails to decode. */ private fun onImageDecodeError(reader: PagerReader) { + progress_container.visibility = View.GONE + if (decodeErrorLayout != null || !reader.isAdded) return val activity = reader.activity as ReaderActivity - decodeErrorLayout = PageDecodeErrorLayout(context, page, activity.readerTheme, - { activity.presenter.retryPage(page) }) - - addView(decodeErrorLayout) + val layout = inflate(R.layout.page_decode_error) + PageDecodeErrorLayout(layout, page, activity.readerTheme, { + if (reader.isAdded) { + activity.presenter.retryPage(page) + } + }) + decodeErrorLayout = layout + addView(layout) } } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonHolder.kt index c3fa5a0f3..c7e6ff400 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonHolder.kt @@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.source.model.Page import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.viewer.base.PageDecodeErrorLayout +import eu.kanade.tachiyomi.util.inflate import kotlinx.android.synthetic.main.chapter_image.view.* import kotlinx.android.synthetic.main.item_webtoon_reader.view.* import rx.Observable @@ -49,7 +50,7 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) /** * Layout of decode error. */ - private var decodeErrorLayout: PageDecodeErrorLayout? = null + private var decodeErrorLayout: View? = null init { with(view.image_view) { @@ -74,7 +75,7 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) }) } - view.progress_container.minimumHeight = view.resources.displayMetrics.heightPixels + view.progress_container.minimumHeight = view.resources.displayMetrics.heightPixels * 2 view.setOnTouchListener(adapter.touchListener) view.retry_button.setOnTouchListener { v, event -> @@ -107,6 +108,7 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) decodeErrorLayout = null } view.image_view.recycle() + view.image_view.visibility = View.GONE view.progress_container.visibility = View.VISIBLE } @@ -116,24 +118,25 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) * @see processStatus */ private fun observeStatus() { + unsubscribeStatus() + val page = page ?: return val statusSubject = SerializedSubject(PublishSubject.create()) page.setStatusSubject(statusSubject) - statusSubscription?.unsubscribe() statusSubscription = statusSubject.startWith(page.status) .observeOn(AndroidSchedulers.mainThread()) .subscribe { processStatus(it) } - webtoonReader.subscriptions.add(statusSubscription) + addSubscription(statusSubscription) } /** * Observes the progress of the page and updates view. */ private fun observeProgress() { - progressSubscription?.unsubscribe() + unsubscribeProgress() val page = page ?: return @@ -145,6 +148,8 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) .subscribe { progress -> view.progress_text.text = view.context.getString(R.string.download_progress, progress) } + + addSubscription(progressSubscription) } /** @@ -171,12 +176,27 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) } } + /** + * Adds a subscription to a list of subscriptions that will automatically unsubscribe when the + * activity or the reader is destroyed. + */ + private fun addSubscription(subscription: Subscription?) { + webtoonReader.subscriptions.add(subscription) + } + + /** + * Removes a subscription from the list of subscriptions. + */ + private fun removeSubscription(subscription: Subscription?) { + subscription?.let { webtoonReader.subscriptions.remove(it) } + } + /** * Unsubscribes from the status subscription. */ private fun unsubscribeStatus() { page?.setStatusSubject(null) - statusSubscription?.unsubscribe() + removeSubscription(statusSubscription) statusSubscription = null } @@ -184,7 +204,7 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) * Unsubscribes from the progress subscription. */ private fun unsubscribeProgress() { - progressSubscription?.unsubscribe() + removeSubscription(progressSubscription) progressSubscription = null } @@ -194,7 +214,7 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) private fun setQueued() = with(view) { progress_container.visibility = View.VISIBLE progress_text.visibility = View.INVISIBLE - retry_button.visibility = View.GONE + retry_container.visibility = View.GONE decodeErrorLayout?.let { (view as ViewGroup).removeView(it) decodeErrorLayout = null @@ -225,6 +245,7 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) val path = page?.imagePath if (path != null && File(path).exists()) { progress_text.visibility = View.INVISIBLE + image_view.visibility = View.VISIBLE image_view.setImage(ImageSource.uri(path)) } else { page?.status = Page.ERROR @@ -236,7 +257,7 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) */ private fun setError() = with(view) { progress_container.visibility = View.GONE - retry_button.visibility = View.VISIBLE + retry_container.visibility = View.VISIBLE } /** @@ -250,13 +271,19 @@ class WebtoonHolder(private val view: View, private val adapter: WebtoonAdapter) * Called when the image fails to decode. */ private fun onImageDecodeError() { + view.progress_container.visibility = View.GONE + val page = page ?: return if (decodeErrorLayout != null || !webtoonReader.isAdded) return - decodeErrorLayout = PageDecodeErrorLayout(view.context, page, readerActivity.readerTheme, - { readerActivity.presenter.retryPage(page) }) - - (view as ViewGroup).addView(decodeErrorLayout) + val layout = (view as ViewGroup).inflate(R.layout.page_decode_error) + PageDecodeErrorLayout(layout, page, readerActivity.readerTheme, { + if (webtoonReader.isAdded) { + readerActivity.presenter.retryPage(page) + } + }) + decodeErrorLayout = layout + view.addView(layout) } /** diff --git a/app/src/main/res/layout/item_webtoon_reader.xml b/app/src/main/res/layout/item_webtoon_reader.xml index 64a182e59..2006b30ec 100644 --- a/app/src/main/res/layout/item_webtoon_reader.xml +++ b/app/src/main/res/layout/item_webtoon_reader.xml @@ -32,12 +32,20 @@ -