mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-21 21:29:00 +00:00
show bottom sheet when tapping avatar
This commit is contained in:
parent
19bf9cf3d4
commit
42fdc2560e
9 changed files with 116 additions and 20 deletions
|
|
@ -1405,6 +1405,9 @@
|
|||
<string name="eggs_footer_description">Check out the [Market](/shops/market) to buy just the eggs you need!</string>
|
||||
<string name="food_footer_description">Check out the [Market](/shops/market) to buy food or a Saddle to instantly raise your Pet!</string>
|
||||
<string name="hatchingPotions_footer_description">Check out the [Market](/shops/market) to buy standard and seasonal Hatching Potions!</string>
|
||||
<string name="open_profile">Open Profile</string>
|
||||
<string name="customize_avatar">Customize Avatar</string>
|
||||
<string name="share_avatar">Share Avatar</string>
|
||||
|
||||
<plurals name="you_x_others">
|
||||
<item quantity="zero">You</item>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
package com.habitrpg.android.habitica.interactors
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.graphics.scale
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.databinding.DialogLevelup10Binding
|
||||
import com.habitrpg.android.habitica.helpers.SoundManager
|
||||
|
|
@ -64,14 +62,6 @@ constructor(
|
|||
dialogAvatarView.setAvatar(requestValues.user)
|
||||
}
|
||||
|
||||
val message = requestValues.activity.getString(R.string.share_levelup, requestValues.newLevel)
|
||||
val avatarView = AvatarView(requestValues.activity, showBackground = true, showMount = true, showPet = true)
|
||||
avatarView.setAvatar(requestValues.user)
|
||||
var sharedImage: Bitmap? = null
|
||||
avatarView.onAvatarImageReady { image ->
|
||||
sharedImage = image?.scale(image.width * 3, image.height * 3, false)
|
||||
}
|
||||
|
||||
val alert = HabiticaAlertDialog(requestValues.activity)
|
||||
alert.setTitle(requestValues.activity.getString(R.string.levelup_header, requestValues.newLevel))
|
||||
alert.setAdditionalContentView(customView)
|
||||
|
|
@ -81,7 +71,16 @@ constructor(
|
|||
}
|
||||
}
|
||||
alert.addButton(R.string.share, false) { _, _ ->
|
||||
requestValues.activity.shareContent("levelup", message, sharedImage)
|
||||
MainScope().launchCatching {
|
||||
val usecase = ShareAvatarUseCase()
|
||||
usecase.callInteractor(ShareAvatarUseCase.RequestValues(
|
||||
requestValues.activity,
|
||||
requestValues.user,
|
||||
requestValues.activity.getString(R.string.share_levelup, requestValues.newLevel),
|
||||
"levelup"
|
||||
))
|
||||
}
|
||||
|
||||
}
|
||||
alert.isCelebratory = true
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package com.habitrpg.android.habitica.interactors
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.core.graphics.scale
|
||||
import com.habitrpg.android.habitica.ui.activities.BaseActivity
|
||||
import com.habitrpg.common.habitica.views.AvatarView
|
||||
import com.habitrpg.shared.habitica.models.Avatar
|
||||
import javax.inject.Inject
|
||||
|
||||
class ShareAvatarUseCase @Inject
|
||||
constructor() : UseCase<ShareAvatarUseCase.RequestValues, Unit>() {
|
||||
override suspend fun run(requestValues: RequestValues) {
|
||||
val avatarView = AvatarView(requestValues.activity, showBackground = true, showMount = true, showPet = true)
|
||||
avatarView.setAvatar(requestValues.avatar)
|
||||
var sharedImage: Bitmap? = null
|
||||
avatarView.onAvatarImageReady { image ->
|
||||
sharedImage = image?.scale(image.width * 3, image.height * 3, false)
|
||||
requestValues.activity.shareContent(requestValues.identifier, requestValues.message, sharedImage)
|
||||
}
|
||||
}
|
||||
|
||||
class RequestValues(val activity: BaseActivity, val avatar: Avatar, val message: String?, val identifier: String): UseCase.RequestValues
|
||||
}
|
||||
|
|
@ -224,11 +224,13 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||
open fun hideConnectionProblem() {
|
||||
}
|
||||
|
||||
fun shareContent(identifier: String, message: String, image: Bitmap? = null) {
|
||||
fun shareContent(identifier: String, message: String?, image: Bitmap? = null) {
|
||||
Analytics.sendEvent("shared", EventCategory.BEHAVIOUR, HitType.EVENT, mapOf("identifier" to identifier))
|
||||
val sharingIntent = Intent(Intent.ACTION_SEND)
|
||||
sharingIntent.type = "*/*"
|
||||
sharingIntent.putExtra(Intent.EXTRA_TEXT, message)
|
||||
if (message?.isNotBlank() == true) {
|
||||
sharingIntent.putExtra(Intent.EXTRA_TEXT, message)
|
||||
}
|
||||
if (image != null) {
|
||||
val path = MediaStore.Images.Media.insertImage(this.contentResolver, image, "${(Date())}", null)
|
||||
if (path != null) {
|
||||
|
|
|
|||
|
|
@ -17,9 +17,18 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||
import androidx.activity.viewModels
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.setPadding
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
|
|
@ -45,13 +54,13 @@ import com.habitrpg.android.habitica.helpers.Analytics
|
|||
import com.habitrpg.android.habitica.helpers.AppConfigManager
|
||||
import com.habitrpg.android.habitica.helpers.EventCategory
|
||||
import com.habitrpg.android.habitica.helpers.HitType
|
||||
import com.habitrpg.common.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.android.habitica.helpers.NotificationOpenHandler
|
||||
import com.habitrpg.android.habitica.helpers.SoundManager
|
||||
import com.habitrpg.android.habitica.helpers.collectAsStateLifecycleAware
|
||||
import com.habitrpg.android.habitica.interactors.CheckClassSelectionUseCase
|
||||
import com.habitrpg.android.habitica.interactors.DisplayItemDropUseCase
|
||||
import com.habitrpg.android.habitica.interactors.NotifyUserUseCase
|
||||
import com.habitrpg.android.habitica.interactors.ShareAvatarUseCase
|
||||
import com.habitrpg.android.habitica.models.TutorialStep
|
||||
import com.habitrpg.android.habitica.models.user.User
|
||||
import com.habitrpg.android.habitica.models.user.UserQuestStatus
|
||||
|
|
@ -61,7 +70,9 @@ import com.habitrpg.android.habitica.ui.theme.HabiticaTheme
|
|||
import com.habitrpg.android.habitica.ui.viewmodels.MainActivityViewModel
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.AppHeaderView
|
||||
import com.habitrpg.android.habitica.ui.views.ComposableAvatarView
|
||||
import com.habitrpg.android.habitica.ui.views.GroupPlanMemberList
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaButton
|
||||
import com.habitrpg.android.habitica.ui.views.SnackbarActivity
|
||||
import com.habitrpg.android.habitica.ui.views.dialogs.QuestCompletedDialog
|
||||
import com.habitrpg.android.habitica.ui.views.showAsBottomSheet
|
||||
|
|
@ -75,6 +86,7 @@ import com.habitrpg.common.habitica.extensions.dpToPx
|
|||
import com.habitrpg.common.habitica.extensions.getThemeColor
|
||||
import com.habitrpg.common.habitica.extensions.isUsingNightModeResources
|
||||
import com.habitrpg.common.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.common.habitica.helpers.MainNavigationController
|
||||
import com.habitrpg.common.habitica.helpers.launchCatching
|
||||
import com.habitrpg.common.habitica.views.AvatarView
|
||||
import com.habitrpg.shared.habitica.models.responses.MaintenanceResponse
|
||||
|
|
@ -284,6 +296,63 @@ open class MainActivity : BaseActivity(), SnackbarActivity {
|
|||
teamPlan = if (canShowTeamHeader) teamPlan else null,
|
||||
teamPlanMembers = teamPlanMembers,
|
||||
isMyProfile = true,
|
||||
onAvatarClicked = {
|
||||
showAsBottomSheet { dismiss ->
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = Modifier.padding(22.dp)
|
||||
) {
|
||||
ComposableAvatarView(avatar = user)
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(15.dp),
|
||||
) {
|
||||
HabiticaButton(
|
||||
background = HabiticaTheme.colors.tintedUiSub,
|
||||
color = Color.White,
|
||||
onClick = {
|
||||
dismiss()
|
||||
MainNavigationController.navigate(R.id.openProfileActivity)
|
||||
}) {
|
||||
Text(stringResource(id = R.string.open_profile))
|
||||
}
|
||||
|
||||
HabiticaButton(
|
||||
background = HabiticaTheme.colors.tintedUiSub,
|
||||
color = Color.White,
|
||||
onClick = {
|
||||
dismiss()
|
||||
MainNavigationController.navigate(R.id.avatarOverviewFragment)
|
||||
}) {
|
||||
Text(stringResource(id = R.string.customize_avatar))
|
||||
}
|
||||
|
||||
HabiticaButton(
|
||||
background = HabiticaTheme.colors.tintedUiSub,
|
||||
color = Color.White,
|
||||
onClick = {
|
||||
dismiss()
|
||||
user?.let {
|
||||
val usecase = ShareAvatarUseCase()
|
||||
lifecycleScope.launchCatching {
|
||||
usecase.callInteractor(
|
||||
ShareAvatarUseCase.RequestValues(
|
||||
this@MainActivity,
|
||||
it,
|
||||
null,
|
||||
"avatar_bottomsheet"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Text(stringResource(id = R.string.share_avatar))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onMemberRowClicked = {
|
||||
showAsBottomSheet { onClose ->
|
||||
val group by viewModel.userViewModel.currentTeamPlanGroup.collectAsState(
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ fun AppHeaderView(
|
|||
isMyProfile : Boolean = false,
|
||||
teamPlan : TeamPlan? = null,
|
||||
teamPlanMembers : List<Member>? = null,
|
||||
onAvatarClicked: (() -> Unit)? = null,
|
||||
onMemberRowClicked : () -> Unit,
|
||||
onClassSelectionClicked: () -> Unit
|
||||
) {
|
||||
|
|
@ -117,7 +118,7 @@ fun AppHeaderView(
|
|||
.size(110.dp, 100.dp)
|
||||
.padding(end = 16.dp)
|
||||
.clickable {
|
||||
MainNavigationController.navigate(R.id.avatarOverviewFragment)
|
||||
onAvatarClicked?.invoke()
|
||||
}
|
||||
)
|
||||
val animationValue =
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ private fun BottomSheetWrapper(
|
|||
content: @Composable (() -> Unit) -> Unit
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
|
||||
val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden, skipHalfExpanded = true)
|
||||
var isSheetOpened by remember { mutableStateOf(false) }
|
||||
|
||||
val systemUiController = rememberSystemUiController()
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ buildscript {
|
|||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.0'
|
||||
classpath 'com.android.tools.build:gradle:8.1.1'
|
||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||
classpath 'com.google.gms:google-services:4.3.15'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.8'
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import android.text.TextUtils
|
|||
import android.util.AttributeSet
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.view.marginStart
|
||||
import androidx.core.view.marginTop
|
||||
import coil.dispose
|
||||
|
|
@ -73,8 +72,8 @@ class AvatarView : FrameLayout {
|
|||
if (BuildConfig.DEBUG && (avatar == null || avatarRectF == null)) {
|
||||
error("Assertion failed")
|
||||
}
|
||||
val viewWidth = if (width > 0) width else layoutParams.width
|
||||
val viewHeight = if (height > 0) height else layoutParams.height
|
||||
val viewWidth = if (width > 0) width else (layoutParams?.width ?: 140)
|
||||
val viewHeight = if (height > 0) height else (layoutParams?.height ?: 147)
|
||||
val canvasRect = Rect(0, 0, if (viewWidth > 0) viewWidth else 140.dpToPx(context), if (viewHeight > 0) viewHeight else 147.dpToPx(context))
|
||||
if (canvasRect.isEmpty) return null
|
||||
avatarBitmap = Bitmap.createBitmap(
|
||||
|
|
|
|||
Loading…
Reference in a new issue