diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt index 2d2662ab3..3ae531fdc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.ui.reader import android.Manifest +import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.content.SharedPreferences @@ -17,10 +18,13 @@ import androidx.core.view.isVisible import androidx.core.view.postDelayed import androidx.core.view.updatePadding import androidx.fragment.app.commit +import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.activity_reader.* import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import moxy.MvpDelegate import moxy.ktx.moxyPresenter @@ -40,6 +44,7 @@ import org.koitharu.kotatsu.ui.reader.thumbnails.PagesThumbnailsSheet import org.koitharu.kotatsu.ui.reader.wetoon.WebtoonReaderFragment import org.koitharu.kotatsu.utils.GridTouchHelper import org.koitharu.kotatsu.utils.MangaShortcut +import org.koitharu.kotatsu.utils.ScreenOrientationHelper import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.anim.Motion import org.koitharu.kotatsu.utils.ext.* @@ -56,6 +61,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh private set private lateinit var touchHelper: GridTouchHelper + private lateinit var orientationHelper: ScreenOrientationHelper private var isTapSwitchEnabled = true private var isVolumeKeysSwitchEnabled = false @@ -67,6 +73,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh setContentView(R.layout.activity_reader) supportActionBar?.setDisplayHomeAsUpEnabled(true) touchHelper = GridTouchHelper(this, this) + orientationHelper = ScreenOrientationHelper(this) toolbar_bottom.inflateMenu(R.menu.opt_reader_bottom) toolbar_bottom.setOnMenuItemClickListener(::onOptionsItemSelected) @@ -89,6 +96,10 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh settings.subscribe(this) loadSettings() + orientationHelper.observeAutoOrientation() + .onEach { + toolbar_bottom.menu.findItem(R.id.action_screen_rotate).isVisible = !it + }.launchIn(lifecycleScope) if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) { presenter.init(state.manga) @@ -165,6 +176,10 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh ) true } + R.id.action_screen_rotate -> { + orientationHelper.toggleOrientation() + true + } R.id.action_pages_thumbs -> { if (reader?.hasItems == true) { val pages = reader?.getPages() @@ -325,14 +340,18 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh presenter.setMode(state.manga, mode) } + @SuppressLint("ShowToast") override fun onPageSaved(uri: Uri?) { if (uri != null) { Snackbar.make(container, R.string.page_saved, Snackbar.LENGTH_LONG) + .setAnchorView(appbar_bottom) .setAction(R.string.share) { ShareHelper.shareImage(this, uri) }.show() } else { - Snackbar.make(container, R.string.error_occurred, Snackbar.LENGTH_SHORT).show() + Snackbar.make(container, R.string.error_occurred, Snackbar.LENGTH_SHORT) + .setAnchorView(appbar_bottom) + .show() } } @@ -369,8 +388,16 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh } override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { - appbar_top.updatePadding(top = insets.systemWindowInsetTop) - appbar_bottom.updatePadding(bottom = insets.systemWindowInsetBottom) + appbar_top.updatePadding( + top = insets.systemWindowInsetTop, + right = insets.systemWindowInsetRight, + left = insets.systemWindowInsetLeft + ) + appbar_bottom.updatePadding( + bottom = insets.systemWindowInsetBottom, + right = insets.systemWindowInsetRight, + left = insets.systemWindowInsetLeft + ) return insets.consumeSystemWindowInsets() } diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ScreenOrientationHelper.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ScreenOrientationHelper.kt new file mode 100644 index 000000000..8e19bfc43 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ScreenOrientationHelper.kt @@ -0,0 +1,53 @@ +package org.koitharu.kotatsu.utils + +import android.app.Activity +import android.content.pm.ActivityInfo +import android.content.res.Configuration +import android.database.ContentObserver +import android.os.Handler +import android.provider.Settings +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.channels.sendBlocking +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.onStart + +class ScreenOrientationHelper(private val activity: Activity) { + + val isAutoRotationEnabled: Boolean + get() = Settings.System.getInt( + activity.contentResolver, + Settings.System.ACCELEROMETER_ROTATION, + 0 + ) == 1 + + var isLandscape: Boolean + get() = activity.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + set(value) { + activity.requestedOrientation = if (value) { + ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE + } else { + ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT + } + } + + fun toggleOrientation() { + isLandscape = !isLandscape + } + + fun observeAutoOrientation() = callbackFlow { + val observer = object : ContentObserver(Handler(activity.mainLooper)) { + override fun onChange(selfChange: Boolean) { + sendBlocking(isAutoRotationEnabled) + } + } + activity.contentResolver.registerContentObserver( + Settings.System.CONTENT_URI, true, observer + ) + awaitClose { + activity.contentResolver.unregisterContentObserver(observer) + } + }.onStart { + emit(isAutoRotationEnabled) + }.distinctUntilChanged() +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_screen_rotation.xml b/app/src/main/res/drawable/ic_screen_rotation.xml new file mode 100644 index 000000000..bfb33a144 --- /dev/null +++ b/app/src/main/res/drawable/ic_screen_rotation.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/menu/opt_reader_bottom.xml b/app/src/main/res/menu/opt_reader_bottom.xml index b8f4beb24..4c72591b6 100644 --- a/app/src/main/res/menu/opt_reader_bottom.xml +++ b/app/src/main/res/menu/opt_reader_bottom.xml @@ -1,10 +1,17 @@ + + - - + + + app:showAsAction="never" /> \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 57db050c6..d296344af 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -59,7 +59,7 @@ \"%s\" удалено с устройства Дождитесь окончания загрузки Сохранить страницу - Страницы сохранена + Страница сохранена Поделиться изображением Импорт Удалить @@ -142,4 +142,5 @@ Ожидание подключения… Очистить ленту обновлений Лента обновлений очищена + Повернуть экран \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a67b32984..f9644ce0e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -143,4 +143,5 @@ Waiting for network… Clear updates feed Updates feed cleared + Rotate screen \ No newline at end of file