Skip to content

Commit

Permalink
[REFACTOR] Display scrim over content only if strategy is StackedTwoP…
Browse files Browse the repository at this point in the history
…aneStrategy in TwoPane.

[FEAT] Add logic to set wallpaper using wallpaper and cropper activity.
[FIX] Fix zoom interfering with scroll in Viewer.
  • Loading branch information
iZakirSheikh committed Sep 13, 2024
1 parent c8105c5 commit 9ed29c9
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 15 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId = "com.googol.android.apps.photos"
minSdk = 24
targetSdk = 35
versionCode = 16
versionName = "0.1.0-dev16"
versionCode = 17
versionName = "0.1.0-dev17"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
52 changes: 44 additions & 8 deletions app/src/main/java/com/zs/gallery/impl/ViewerViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package com.zs.gallery.impl

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.util.Log
Expand All @@ -29,6 +30,7 @@ import androidx.compose.material.icons.outlined.Image
import androidx.compose.material.icons.outlined.Share
import androidx.compose.material.icons.outlined.Star
import androidx.compose.material.icons.outlined.StarOutline
import androidx.compose.material.icons.outlined.Wallpaper
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
Expand All @@ -55,7 +57,7 @@ private const val TAG = "ViewerViewModel"

private val DELETE = MenuItem("action_delete", R.string.delete, Icons.Outlined.Delete)
private val SHARE = MenuItem("action_share", R.string.share, Icons.Outlined.Share)
private val USE_AS = MenuItem("action_use_as", R.string.use_as, Icons.Outlined.Image)
private val USE_AS = MenuItem("action_use_as", R.string.set_as_wallpaper, Icons.Outlined.Wallpaper)
private val EDIT_IN = MenuItem("action_edit_in", R.string.edit_in, Icons.Outlined.Edit)
private val STAR = MenuItem("action_like", R.string.like, Icons.Outlined.StarOutline)
private val UN_STAR = MenuItem("action_unlike", R.string.unlike, Icons.Outlined.Star)
Expand All @@ -79,12 +81,44 @@ private fun EditIn(uri: Uri) =
* @return An Intent configured for setting the wallpaper.
*/
private fun Wallpaper(uri: Uri) =
Intent(Intent.ACTION_ATTACH_DATA).apply {
Intent("android.service.wallpaper.CROP_AND_SET_WALLPAPER").apply {
setDataAndType(uri, "image/*")
putExtra("mimeType", "image/*") // Specifies the MIME type of the image
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // Grants temporary read permission to the wallpaper app
addCategory(Intent.CATEGORY_DEFAULT)
}

/**
* Sets the wallpaper using the provided URI.
*
* This function attempts to set the wallpaper using the default wallpaper cropper app.
* If the specified package is not found, it falls back to a generic wallpaper intent.
* If any other exception occurs, it shows a toast message to the user.
*
* @param uri The URI of the image to be set as wallpaper.
*/
private fun Activity.setWallpaper(uri: Uri) {
try {
// Create an intent to set the wallpaper using the specified URI
val intent = Wallpaper(uri).apply {
// Set the package to use the default wallpaper cropper app
setPackage("com.android.wallpapercropper")
}
// Attempt to start the activity with the specified package
startActivity(intent)
} catch (e: ActivityNotFoundException) {
// If the specified package is not found, fallback to a generic wallpaper intent
startActivity(Wallpaper(uri))
} catch (e: Exception) {
// If any other exception occurs, show a toast message to the user
android.widget.Toast.makeText(
this,
"No wallpaper app found",
android.widget.Toast.LENGTH_SHORT
).show()
}
}


class ViewerViewModel(
handle: SavedStateHandle,
Expand All @@ -104,7 +138,9 @@ class ViewerViewModel(
override var details: MediaFile? by mutableStateOf(null)
override var showDetails: Boolean
get() = details != null
set(value) { details = if (value) current else null }
set(value) {
details = if (value) current else null
}

override val actions: List<MenuItem> by derivedStateOf {
buildList {
Expand All @@ -125,15 +161,15 @@ class ViewerViewModel(
STAR, UN_STAR -> toggleLike()
DELETE -> remove(activity)
SHARE -> share(activity)
USE_AS -> {
val current = current ?: return
activity.startActivity(Wallpaper(current.mediaUri))
}

EDIT_IN -> {
val current = current ?: return
activity.startActivity(EditIn(current.mediaUri))
}

USE_AS -> {
val image = current?.mediaUri ?: return
activity.setWallpaper(image)
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions app/src/main/java/com/zs/gallery/viewer/Viewer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package com.zs.gallery.viewer

import android.content.Intent
import android.net.Uri
import android.util.Log
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalSharedTransitionApi
Expand Down Expand Up @@ -133,7 +134,7 @@ private suspend fun ZoomableState.scaledInsideAndCenterAlignedFrom(painter: Pain
* Indicates whether the content is currently at its default zoom level (not zoomed in).
*/
private val ZoomableState.isZoomedOut
get() = zoomFraction == null || zoomFraction == 0f
get() = (zoomFraction ?: 0f) <= 0.0001f

/**
* TODO - Instead of opening video in 3rd party; Add inBuilt Impl in future versions.
Expand Down Expand Up @@ -162,7 +163,7 @@ private fun FloatingActionMenu(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.animateContentSize()
) {
Menu(actions, onItemClicked = onAction)
Menu(actions, onItemClicked = onAction, collapsed = 3)
}
},
)
Expand Down Expand Up @@ -268,6 +269,7 @@ private fun MainContent(
// Horizontal pager to display the images/videos
// Disable swipe when zoomed in
// Preload adjacent pages for smoother transitions
Log.d(TAG, "MainContent - ZoomFraction: ${zoomable.zoomFraction}")
HorizontalPager(
state = pager,
key = { values[it].id },
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
<string name="info">Info</string>
<string name="edit_in">Edit In</string>
<string name="use_as">Use as</string>
<string name="set_as_wallpaper">Set as Wallpaper</string>
<string name="like">Like</string>
<string name="unlike">Unfavorite</string>
<string name="details">Details</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ private inline fun Slot(content: @Composable () -> Unit) =
Box(content = { content() })


private val TwoPaneStrategy.scrim get() =
if (this is StackedTwoPaneStrategy) DEFAULT_SCRIM_COLOR else Color.Transparent

/**
* A two-pane layout that displays content and details using a configurable strategy.
*
Expand Down Expand Up @@ -134,13 +137,13 @@ fun TwoPane(
spacing: Dp = DEFAULT_SPACING,
background: Color = AppTheme.colors.background,
onColor: Color = AppTheme.colors.onBackground,
scrim: Color = DEFAULT_SCRIM_COLOR,
strategy: TwoPaneStrategy = VerticalTwoPaneStrategy(0.5f),
scrim: Color = strategy.scrim,
details: @Composable () -> Unit = { },
topBar: @Composable () -> Unit = { },
floatingActionButton: @Composable () -> Unit = { },
fabPosition: FabPosition = FabPosition.End,
onDismissRequest: (() -> Unit)? = null,
strategy: TwoPaneStrategy = VerticalTwoPaneStrategy(0.5f)
fabPosition: FabPosition = FabPosition.End,
) {
// The indent propagated through window.contentIndent
// The removes its old value; which means child has access to only topBar indent.
Expand Down

0 comments on commit 9ed29c9

Please sign in to comment.