Skip to content

Commit

Permalink
Merge pull request #2670 from kadirkid/add-support-for-dual-pages-on-…
Browse files Browse the repository at this point in the history
…foldable-devices

Add support for dual pages on foldable devices
  • Loading branch information
ahmedre authored Apr 21, 2024
2 parents 5552df6 + 2f52097 commit 57ef28f
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 38 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ dependencies {
implementation libs.androidx.recyclerview
implementation libs.material
implementation libs.androidx.swiperefreshlayout
implementation libs.androidx.window

// compose
implementation libs.compose.ui
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ object PagerActivityModule {
@Provides
@ActivityScope
fun provideImageWidth(@ActivityContext context: Context, screenInfo: QuranScreenInfo): String {
return if (QuranUtils.isDualPages(context, screenInfo)) {
return if (QuranUtils.isDualPages(context, screenInfo, false)) {
screenInfo.tabletWidthParam
} else {
screenInfo.widthParam
Expand Down
107 changes: 74 additions & 33 deletions app/src/main/java/com/quran/labs/androidquran/ui/PagerActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,15 @@ import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.viewpager.widget.NonRestoringViewPager
import androidx.viewpager.widget.ViewPager
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import androidx.viewpager.widget.ViewPager.SimpleOnPageChangeListener
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowInfoTracker
import com.quran.data.core.QuranInfo
import com.quran.data.dao.BookmarksDao
import com.quran.data.model.QuranText
Expand Down Expand Up @@ -133,8 +138,10 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
Expand Down Expand Up @@ -168,6 +175,7 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat
private var promptedForExtraDownload = false
private var progressDialog: ProgressDialog? = null
private var isInMultiWindowMode = false
private var isFoldableDeviceOpenAndVertical = false

private var bookmarksMenuItem: MenuItem? = null

Expand Down Expand Up @@ -262,8 +270,57 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat
// field injection
pagerActivityComponent.inject(this)

isFoldableDeviceOpenAndVertical =
savedInstanceState?.getBoolean(LAST_FOLDING_STATE, isFoldableDeviceOpenAndVertical)
?: isFoldableDeviceOpenAndVertical

lifecycleScope.launch(scope.coroutineContext) {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
WindowInfoTracker.getOrCreate(this@PagerActivity)
.windowLayoutInfo(this@PagerActivity)
.mapNotNull { it.displayFeatures.filterIsInstance<FoldingFeature>().firstOrNull() }
.collectLatest { foldingFeatures ->
val localState = foldingFeatures.state == FoldingFeature.State.FLAT &&
foldingFeatures.orientation == FoldingFeature.Orientation.VERTICAL
if (isFoldableDeviceOpenAndVertical != localState) {
isFoldableDeviceOpenAndVertical = localState
initialize(savedInstanceState)
}
}
}
}

setContentView(R.layout.quran_page_activity_slider)
initialize(savedInstanceState)
requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean? ->
audioPresenter.onPostNotificationsPermissionResponse(
isGranted!!
)
}

// read the list of translations
requestTranslationsList()

downloadBridge.subscribeToDownloads {
onDownloadSuccess()
}

bookmarksDao.pageBookmarksWithoutTags().combine(currentPageFlow) { bookmarks, currentPage ->
bookmarks to currentPage
}.onEach { (bookmarks, page) ->
val isBookmarked = if (isDualPages) {
bookmarks.any { it.page == page || it.page == page - 1 }
} else {
bookmarks.any { it.page == page }
}
refreshBookmarksMenu(isBookmarked)
}.launchIn(scope)
}

private fun initialize(savedInstanceState: Bundle?) {
var shouldAdjustPageNumber = false
isDualPages = QuranUtils.isDualPages(this, quranScreenInfo)
isDualPages = QuranUtils.isDualPages(this, quranScreenInfo, isFoldableDeviceOpenAndVertical)
isSplitScreen = quranSettings.isQuranSplitWithTranslation
audioStatusRepositoryBridge = AudioStatusRepositoryBridge(
audioStatusRepository,
Expand Down Expand Up @@ -323,7 +380,6 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat

compositeDisposable = CompositeDisposable()

setContentView(R.layout.quran_page_activity_slider)
audioStatusBar = findViewById(R.id.audio_area)
audioBarParams = audioStatusBar.layoutParams as MarginLayoutParams

Expand Down Expand Up @@ -498,31 +554,6 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat
{ ayah: SuraAyah -> ensurePage(ayah.sura, ayah.ayah) },
{ sliderPage: Int -> showSlider(slidingPagerAdapter.getPagePosition(sliderPage)) }
))

requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean? ->
audioPresenter.onPostNotificationsPermissionResponse(
isGranted!!
)
}

// read the list of translations
requestTranslationsList()

downloadBridge.subscribeToDownloads {
onDownloadSuccess()
}

bookmarksDao.pageBookmarksWithoutTags().combine(currentPageFlow) { bookmarks, currentPage ->
bookmarks to currentPage
}.onEach { (bookmarks, page) ->
val isBookmarked = if (isDualPages) {
bookmarks.any { it.page == page || it.page == page - 1 }
} else {
bookmarks.any { it.page == page }
}
refreshBookmarksMenu(isBookmarked)
}.launchIn(scope)
}

override fun onRequestPermissionsResult(
Expand Down Expand Up @@ -551,9 +582,9 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat
viewPager.addOnPageChangeListener(pageChangedListener)
awaitClose { viewPager.removeOnPageChangeListener(pageChangedListener) }
}
.onStart { emit(currentPage) }
.buffer(onBufferOverflow = BufferOverflow.DROP_OLDEST)
.shareIn(scope, SharingStarted.Eagerly, 1)
.onStart { emit(currentPage) }
.buffer(onBufferOverflow = BufferOverflow.DROP_OLDEST)
.shareIn(scope, SharingStarted.Eagerly, 1)

private val statusBarHeight: Int
get() {
Expand Down Expand Up @@ -646,9 +677,17 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat

private fun startPosition(ayahSelection: AyahSelection): SuraAyah? {
return when (ayahSelection) {
is AyahSelection.Ayah -> { ayahSelection.suraAyah }
is AyahRange -> { ayahSelection.startSuraAyah }
else -> { null }
is AyahSelection.Ayah -> {
ayahSelection.suraAyah
}

is AyahRange -> {
ayahSelection.startSuraAyah
}

else -> {
null
}
}
}

Expand Down Expand Up @@ -979,6 +1018,7 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat
state.putBoolean(LAST_READING_MODE_IS_TRANSLATION, showingTranslation)
state.putBoolean(LAST_ACTIONBAR_STATE, isActionBarHidden)
state.putBoolean(LAST_WAS_DUAL_PAGES, isDualPages)
state.putBoolean(LAST_FOLDING_STATE, isFoldableDeviceOpenAndVertical)
super.onSaveInstanceState(state)
}

Expand Down Expand Up @@ -1839,6 +1879,7 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat
private const val LAST_READ_PAGE = "LAST_READ_PAGE"
private const val LAST_READING_MODE_IS_TRANSLATION = "LAST_READING_MODE_IS_TRANSLATION"
private const val LAST_ACTIONBAR_STATE = "LAST_ACTIONBAR_STATE"
private const val LAST_FOLDING_STATE = "LAST_FOLDING_STATE"

const val EXTRA_JUMP_TO_TRANSLATION: String = "jumpToTranslation"
const val EXTRA_HIGHLIGHT_SURA: String = "highlightSura"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ public static String getLocalizedNumber(Context context, int number) {
return numberFormat.format(number);
}

public static boolean isDualPages(Context context, QuranScreenInfo qsi) {
public static boolean isDualPages(Context context, QuranScreenInfo qsi, boolean isValidFoldableDeviceAndOpen) {
if (context != null && qsi != null) {
final Resources resources = context.getResources();
if (qsi.isDualPageMode() &&
if ((qsi.isDualPageMode() &&
resources.getConfiguration().orientation ==
Configuration.ORIENTATION_LANDSCAPE) {
Configuration.ORIENTATION_LANDSCAPE) || isValidFoldableDeviceAndOpen) {
final SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(Constants.PREF_DUAL_PAGE_ENABLED,
Expand Down
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ androidxSwipeRefreshVersion = "1.1.0"
androidxPagingVersion = "3.2.1"
androidxPagingComposeVersion = "3.2.1"
androidxWorkManagerVersion = "2.9.0"
androidxWindowManager = "1.2.0"

# firebase
firebaseAnalyticsVersion = "21.6.2"
Expand Down Expand Up @@ -96,7 +97,7 @@ androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version
androidx-paging-runtime-ktx = { module = "androidx.paging:paging-runtime-ktx", version.ref = "androidxPagingVersion" }
androidx-paging-compose = { module = "androidx.paging:paging-compose", version.ref = "androidxPagingComposeVersion" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidxNavigationVersion" }

androidx-window = { module = "androidx.window:window", version.ref = "androidxWindowManager" }
# compose
compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "compose-compiler" }
compose-foundation = { module = "androidx.compose.foundation:foundation" }
Expand Down

0 comments on commit 57ef28f

Please sign in to comment.