Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Jay 2020-01-06 02:36:31 -08:00
commit 858c4989cd
12 changed files with 258 additions and 304 deletions

View File

@ -1,139 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.bluelinelabs.conductor.RestoreViewOnCreateController;
import com.bluelinelabs.conductor.Router;
import com.bluelinelabs.conductor.RouterTransaction;
import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler;
/**
* A controller that displays a dialog window, floating on top of its activity's window.
* This is a wrapper over {@link Dialog} object like {@link android.app.DialogFragment}.
*
* <p>Implementations should override this class and implement {@link #onCreateDialog(Bundle)} to create a custom dialog, such as an {@link android.app.AlertDialog}
*/
public abstract class DialogController extends RestoreViewOnCreateController {
private static final String SAVED_DIALOG_STATE_TAG = "android:savedDialogState";
private Dialog dialog;
private boolean dismissed;
/**
* Convenience constructor for use when no arguments are needed.
*/
protected DialogController() {
super(null);
}
/**
* Constructor that takes arguments that need to be retained across restarts.
*
* @param args Any arguments that need to be retained.
*/
protected DialogController(@Nullable Bundle args) {
super(args);
}
@NonNull
@Override
final protected View onCreateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable Bundle savedViewState) {
dialog = onCreateDialog(savedViewState);
//noinspection ConstantConditions
dialog.setOwnerActivity(getActivity());
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
dismissDialog();
}
});
if (savedViewState != null) {
Bundle dialogState = savedViewState.getBundle(SAVED_DIALOG_STATE_TAG);
if (dialogState != null) {
dialog.onRestoreInstanceState(dialogState);
}
}
return new View(getActivity());//stub view
}
@Override
protected void onSaveViewState(@NonNull View view, @NonNull Bundle outState) {
super.onSaveViewState(view, outState);
Bundle dialogState = dialog.onSaveInstanceState();
outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState);
}
@Override
protected void onAttach(@NonNull View view) {
super.onAttach(view);
dialog.show();
}
@Override
protected void onDetach(@NonNull View view) {
super.onDetach(view);
dialog.hide();
}
@Override
protected void onDestroyView(@NonNull View view) {
super.onDestroyView(view);
dialog.setOnDismissListener(null);
dialog.dismiss();
dialog = null;
}
/**
* Display the dialog, create a transaction and pushing the controller.
* @param router The router on which the transaction will be applied
*/
public void showDialog(@NonNull Router router) {
showDialog(router, null);
}
/**
* Display the dialog, create a transaction and pushing the controller.
* @param router The router on which the transaction will be applied
* @param tag The tag for this controller
*/
public void showDialog(@NonNull Router router, @Nullable String tag) {
dismissed = false;
router.pushController(RouterTransaction.with(this)
.pushChangeHandler(new SimpleSwapChangeHandler(false))
.popChangeHandler(new SimpleSwapChangeHandler(false))
.tag(tag));
}
/**
* Dismiss the dialog and pop this controller
*/
public void dismissDialog() {
if (dismissed) {
return;
}
getRouter().popController(this);
dismissed = true;
}
@Nullable
protected Dialog getDialog() {
return dialog;
}
/**
* Build your own custom Dialog container such as an {@link android.app.AlertDialog}
*
* @param savedViewState A bundle for the view's state, which would have been created in {@link #onSaveViewState(View, Bundle)} or {@code null} if no saved state exists.
* @return Return a new Dialog instance to be displayed by the Controller
*/
@NonNull
protected abstract Dialog onCreateDialog(@Nullable Bundle savedViewState);
}

View File

@ -0,0 +1,118 @@
package eu.kanade.tachiyomi.ui.base.controller
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bluelinelabs.conductor.RestoreViewOnCreateController
import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler
/**
* A controller that displays a dialog window, floating on top of its activity's window.
* This is a wrapper over [Dialog] object like [android.app.DialogFragment].
*
*
* Implementations should override this class and implement [.onCreateDialog] to create a custom dialog, such as an [android.app.AlertDialog]
*/
abstract class DialogController : RestoreViewOnCreateController {
protected var dialog: Dialog? = null
private set
private var dismissed = false
/**
* Convenience constructor for use when no arguments are needed.
*/
protected constructor() : super(null)
/**
* Constructor that takes arguments that need to be retained across restarts.
*
* @param args Any arguments that need to be retained.
*/
protected constructor(args: Bundle?) : super(args)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedViewState: Bundle?): View {
dialog = onCreateDialog(savedViewState)
dialog!!.ownerActivity = activity
dialog!!.setOnDismissListener { dismissDialog() }
if (savedViewState != null) {
val dialogState = savedViewState.getBundle(SAVED_DIALOG_STATE_TAG)
if (dialogState != null) {
dialog!!.onRestoreInstanceState(dialogState)
}
}
return View(activity) //stub view
}
override fun onSaveViewState(view: View, outState: Bundle) {
super.onSaveViewState(view, outState)
val dialogState = dialog!!.onSaveInstanceState()
outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState)
}
override fun onAttach(view: View) {
super.onAttach(view)
dialog!!.show()
}
override fun onDetach(view: View) {
super.onDetach(view)
dialog!!.hide()
}
override fun onDestroyView(view: View) {
super.onDestroyView(view)
dialog!!.setOnDismissListener(null)
dialog!!.dismiss()
dialog = null
}
/**
* Display the dialog, create a transaction and pushing the controller.
* @param router The router on which the transaction will be applied
*/
open fun showDialog(router: Router) {
showDialog(router, null)
}
/**
* Display the dialog, create a transaction and pushing the controller.
* @param router The router on which the transaction will be applied
* @param tag The tag for this controller
*/
fun showDialog(router: Router, tag: String?) {
dismissed = false
router.pushController(RouterTransaction.with(this)
.pushChangeHandler(SimpleSwapChangeHandler(false))
.popChangeHandler(SimpleSwapChangeHandler(false))
.tag(tag))
}
/**
* Dismiss the dialog and pop this controller
*/
fun dismissDialog() {
if (dismissed) {
return
}
router.popController(this)
dismissed = true
}
/**
* Build your own custom Dialog container such as an [android.app.AlertDialog]
*
* @param savedViewState A bundle for the view's state, which would have been created in [.onSaveViewState] or `null` if no saved state exists.
* @return Return a new Dialog instance to be displayed by the Controller
*/
protected abstract fun onCreateDialog(savedViewState: Bundle?): Dialog
companion object {
private const val SAVED_DIALOG_STATE_TAG = "android:savedDialogState"
}
}

View File

@ -13,7 +13,7 @@ abstract class NucleusController<P : Presenter<*>>(val bundle: Bundle? = null) :
private val delegate = NucleusConductorDelegate(this)
val presenter: P
get() = delegate.presenter
get() = delegate.presenter!!
init {
addLifecycleListener(NucleusConductorLifecycleListener(delegate))

View File

@ -1,61 +0,0 @@
package eu.kanade.tachiyomi.ui.base.presenter;
import android.os.Bundle;
import androidx.annotation.Nullable;
import nucleus.factory.PresenterFactory;
import nucleus.presenter.Presenter;
public class NucleusConductorDelegate<P extends Presenter> {
@Nullable private P presenter;
@Nullable private Bundle bundle;
private PresenterFactory<P> factory;
public NucleusConductorDelegate(PresenterFactory<P> creator) {
this.factory = creator;
}
public P getPresenter() {
if (presenter == null) {
presenter = factory.createPresenter();
presenter.create(bundle);
bundle = null;
}
return presenter;
}
Bundle onSaveInstanceState() {
Bundle bundle = new Bundle();
// getPresenter(); // Workaround a crash related to saving instance state with child routers
if (presenter != null) {
presenter.save(bundle);
}
return bundle;
}
void onRestoreInstanceState(Bundle presenterState) {
bundle = presenterState;
}
void onTakeView(Object view) {
getPresenter();
if (presenter != null) {
//noinspection unchecked
presenter.takeView(view);
}
}
void onDropView() {
if (presenter != null) {
presenter.dropView();
}
}
void onDestroy() {
if (presenter != null) {
presenter.destroy();
}
}
}

View File

@ -0,0 +1,45 @@
package eu.kanade.tachiyomi.ui.base.presenter
import android.os.Bundle
import nucleus.factory.PresenterFactory
import nucleus.presenter.Presenter
class NucleusConductorDelegate<P : Presenter<*>>(private val factory: PresenterFactory<P>) {
var presenter: P? = null
get() {
if (field == null) {
field = factory.createPresenter()
field!!.create(bundle)
bundle = null
}
return field
}
private var bundle: Bundle? = null
fun onSaveInstanceState(): Bundle {
val bundle = Bundle()
// getPresenter(); // Workaround a crash related to saving instance state with child routers
presenter?.save(bundle)
return bundle
}
fun onRestoreInstanceState(presenterState: Bundle?) {
bundle = presenterState
}
@Suppress("TYPE_MISMATCH")
fun onTakeView(view: Any) {
presenter?.takeView(view)
}
fun onDropView() {
presenter?.dropView()
}
fun onDestroy() {
presenter?.destroy()
}
}

View File

@ -1,44 +0,0 @@
package eu.kanade.tachiyomi.ui.base.presenter;
import android.os.Bundle;
import androidx.annotation.NonNull;
import android.view.View;
import com.bluelinelabs.conductor.Controller;
public class NucleusConductorLifecycleListener extends Controller.LifecycleListener {
private static final String PRESENTER_STATE_KEY = "presenter_state";
private NucleusConductorDelegate delegate;
public NucleusConductorLifecycleListener(NucleusConductorDelegate delegate) {
this.delegate = delegate;
}
@Override
public void postCreateView(@NonNull Controller controller, @NonNull View view) {
delegate.onTakeView(controller);
}
@Override
public void preDestroyView(@NonNull Controller controller, @NonNull View view) {
delegate.onDropView();
}
@Override
public void preDestroy(@NonNull Controller controller) {
delegate.onDestroy();
}
@Override
public void onSaveInstanceState(@NonNull Controller controller, @NonNull Bundle outState) {
outState.putBundle(PRESENTER_STATE_KEY, delegate.onSaveInstanceState());
}
@Override
public void onRestoreInstanceState(@NonNull Controller controller, @NonNull Bundle savedInstanceState) {
delegate.onRestoreInstanceState(savedInstanceState.getBundle(PRESENTER_STATE_KEY));
}
}

View File

@ -0,0 +1,33 @@
package eu.kanade.tachiyomi.ui.base.presenter
import android.os.Bundle
import android.view.View
import com.bluelinelabs.conductor.Controller
class NucleusConductorLifecycleListener(private val delegate: NucleusConductorDelegate<*>) : Controller.LifecycleListener() {
override fun postCreateView(controller: Controller, view: View) {
delegate.onTakeView(controller)
}
override fun preDestroyView(controller: Controller, view: View) {
delegate.onDropView()
}
override fun preDestroy(controller: Controller) {
delegate.onDestroy()
}
override fun onSaveInstanceState(controller: Controller, outState: Bundle) {
outState.putBundle(PRESENTER_STATE_KEY, delegate.onSaveInstanceState())
}
override fun onRestoreInstanceState(controller: Controller, savedInstanceState: Bundle) {
delegate.onRestoreInstanceState(savedInstanceState.getBundle(PRESENTER_STATE_KEY))
}
companion object {
private const val PRESENTER_STATE_KEY = "presenter_state"
}
}

View File

@ -85,7 +85,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>(),
/**
* The maximum bitmap size supported by the device.
*/
val maxBitmapSize by lazy { GLUtil.getMaxTextureSize() }
val maxBitmapSize by lazy { GLUtil.maxTextureSize }
/**
* Viewer used to display the pages (pager, webtoon, ...).

View File

@ -1,8 +1,6 @@
package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
import android.graphics.Typeface
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatTextView
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.StyleSpan
@ -12,6 +10,8 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatTextView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
@ -36,7 +36,10 @@ class WebtoonTransitionHolder(
/**
* Text view used to display the text of the current and next/prev chapters.
*/
private var textView = TextView(context)
private var textView = TextView(context).apply {
textSize = 17.5F
wrapContent()
}
/**
* View container of the current status of the transition page. Child views will be added

View File

@ -1,54 +0,0 @@
package eu.kanade.tachiyomi.util;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
public final class GLUtil {
private GLUtil() throws InstantiationException {
throw new InstantiationException("This class is not for instantiation");
}
public static int getMaxTextureSize() {
// Safe minimum default size
final int IMAGE_MAX_BITMAP_DIMENSION = 2048;
// Get EGL Display
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
// Initialise
int[] version = new int[2];
egl.eglInitialize(display, version);
// Query total number of configurations
int[] totalConfigurations = new int[1];
egl.eglGetConfigs(display, null, 0, totalConfigurations);
// Query actual list configurations
EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]];
egl.eglGetConfigs(display, configurationsList, totalConfigurations[0], totalConfigurations);
int[] textureSize = new int[1];
int maximumTextureSize = 0;
// Iterate through all the configurations to located the maximum texture size
for (int i = 0; i < totalConfigurations[0]; i++) {
// Only need to check for width since opengl textures are always squared
egl.eglGetConfigAttrib(display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize);
// Keep track of the maximum texture size
if (maximumTextureSize < textureSize[0])
maximumTextureSize = textureSize[0];
}
// Release
egl.eglTerminate(display);
// Return largest texture size found, or default
return Math.max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION);
}
}

View File

@ -0,0 +1,54 @@
package eu.kanade.tachiyomi.util
import javax.microedition.khronos.egl.EGL10
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.egl.EGLContext
import kotlin.math.max
class GLUtil private constructor() {
companion object {
// Safe minimum default size
private const val IMAGE_MAX_BITMAP_DIMENSION = 2048
val maxTextureSize: Int
get() {
// Get EGL Display
val egl = EGLContext.getEGL() as EGL10
val display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
// Initialise
val version = IntArray(2)
egl.eglInitialize(display, version)
// Query total number of configurations
val totalConfigurations = IntArray(1)
egl.eglGetConfigs(display, null, 0, totalConfigurations)
// Query actual list configurations
val configurationsList = arrayOfNulls<EGLConfig>(totalConfigurations[0])
egl.eglGetConfigs(display, configurationsList, totalConfigurations[0], totalConfigurations)
val textureSize = IntArray(1)
var maximumTextureSize = 0
// Iterate through all the configurations to located the maximum texture size
for (i in 0 until totalConfigurations[0]) {
// Only need to check for width since opengl textures are always squared
egl.eglGetConfigAttrib(display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize)
// Keep track of the maximum texture size
if (maximumTextureSize < textureSize[0]) maximumTextureSize = textureSize[0]
}
// Release
egl.eglTerminate(display)
// Return largest texture size found, or default
return max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION)
}
}
init {
throw InstantiationException("This class is not for instantiation")
}
}

View File

@ -20,7 +20,6 @@ allprojects {
repositories {
google()
maven { url "https://www.jitpack.io" }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
jcenter()
}
}