1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-2860 Added tooltip to introduce long tap on back button

This commit is contained in:
nvgurova 2024-10-30 12:11:57 +01:00
parent 6ff075360b
commit 81cf73a0b2
No known key found for this signature in database
GPG key ID: 3283F7371DE9C0D2
5 changed files with 202 additions and 3 deletions

View file

@ -39,6 +39,22 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.anytypeio.anytype.R
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.runtime.getValue
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Popup
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.flow.StateFlow
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ObjectWrapper
import com.anytypeio.anytype.core_ui.extensions.throttledClick
@ -98,9 +114,13 @@ fun HomeScreen(
onSeeAllObjectsClicked: (WidgetView.Gallery) -> Unit,
onCreateObjectInsideWidget: (Id) -> Unit,
onCreateDataViewObject: (WidgetId, ViewId?) -> Unit,
onBackLongClicked: () -> Unit
onBackLongClicked: () -> Unit,
showTooltip: StateFlow<Boolean>,
onTooltipDismissed: () -> Unit,
) {
val isTooltipVisible by showTooltip.collectAsStateWithLifecycle()
Box(modifier = Modifier.fillMaxSize()) {
WidgetList(
widgets = widgets,
@ -166,6 +186,15 @@ fun HomeScreen(
addDocLongClick = onCreateNewObjectLongClicked,
isOwnerOrEditor = mode !is InteractionMode.ReadOnly
)
if (isTooltipVisible) {
SpaceSwitcherTooltip(
onDismissRequest = onTooltipDismissed,
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 90.dp),
)
}
}
}
@ -809,4 +838,103 @@ fun WidgetEditModeButton(
color = colorResource(id = R.color.text_white)
)
}
}
@Composable
fun SpaceSwitcherTooltip(
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier
) {
TooltipPopup(
modifier = modifier,
tooltipContent = {
Box(
modifier = Modifier
.height(100.dp)
.background(
color = colorResource(id = R.color.home_screen_tooltip),
shape = RoundedCornerShape(16.dp)
)
.padding(12.dp)
) {
IconButton(
onClick = onDismissRequest,
modifier = Modifier.align(Alignment.TopEnd)
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = "Close",
tint = colorResource(id = R.color.select_space_bottom_sheet_background_color)
)
}
Column(
modifier = Modifier
.align(Alignment.CenterStart)
.padding(end = 40.dp)
) {
Text(
text = "Switch spaces quicker",
color = Color.Black,
fontWeight = FontWeight.Bold,
fontSize = 14.sp
)
Text(
text = "Long tap on back button to switch Space",
color = Color.Black,
fontSize = 12.sp
)
}
}
}
)
}
@Composable
fun TooltipPopup(
modifier: Modifier = Modifier,
tooltipContent: @Composable () -> Unit
) {
Popup(
alignment = Alignment.BottomCenter,
offset = IntOffset(0, -180)
) {
BubbleLayout(
arrowHeight = 8.dp,
arrowPositionX = 0.5f
) {
tooltipContent()
}
}
}
@Composable
fun BubbleLayout(
modifier: Modifier = Modifier,
arrowHeight: Dp,
arrowPositionX: Float,
content: @Composable () -> Unit
) {
val tooltipColor = colorResource(id = R.color.home_screen_tooltip)
val arrowHeightPx = with(LocalDensity.current) { arrowHeight.toPx() }
Box(
modifier = modifier
.background(color = tooltipColor, shape = RoundedCornerShape(16.dp))
.drawBehind {
val path = androidx.compose.ui.graphics.Path()
if (arrowPositionX in 0f..1f) {
val arrowCenter = Offset(size.width * arrowPositionX, size.height)
path.apply {
moveTo(arrowCenter.x, arrowCenter.y)
lineTo(arrowCenter.x + arrowHeightPx, arrowCenter.y)
lineTo(arrowCenter.x, arrowCenter.y + arrowHeightPx)
lineTo(arrowCenter.x - arrowHeightPx, arrowCenter.y)
close()
}
}
drawPath(path, color = tooltipColor)
}
) {
content()
}
}

View file

@ -1,6 +1,7 @@
package com.anytypeio.anytype.ui.home
import android.os.Bundle
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -27,7 +28,6 @@ import com.anytypeio.anytype.core_utils.ext.toast
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
import com.anytypeio.anytype.core_utils.ui.BaseComposeFragment
import com.anytypeio.anytype.di.common.componentManager
import com.anytypeio.anytype.feature_discussions.ui.DiscussionScreenWrapper
import com.anytypeio.anytype.other.DefaultDeepLinkResolver
import com.anytypeio.anytype.presentation.home.Command
import com.anytypeio.anytype.presentation.home.HomeScreenViewModel
@ -73,6 +73,51 @@ class HomeScreenFragment : BaseComposeFragment(),
private val vm by viewModels<HomeScreenViewModel> { factory }
private var spaceSwitchCount: Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val tooltipShownOnce = isTooltipShown()
spaceSwitchCount = getSpaceSwitchCount()
if (!tooltipShownOnce && spaceSwitchCount >= 2) {
vm.showTooltip()
saveTooltipShown(true)
spaceSwitchCount = 0
} else if (!tooltipShownOnce) {
spaceSwitchCount++
}
saveSpaceSwitchCount(spaceSwitchCount)
}
private fun saveTooltipShown(shown: Boolean) {
val sharedPreferences =
requireContext().getSharedPreferences(SPACE_SWITCH_PREF, Context.MODE_PRIVATE)
sharedPreferences.edit().putBoolean(TOOLTIP_SHOWN_KEY, shown).apply()
}
private fun isTooltipShown(): Boolean {
val sharedPreferences =
requireContext().getSharedPreferences(SPACE_SWITCH_PREF, Context.MODE_PRIVATE)
return sharedPreferences.getBoolean(TOOLTIP_SHOWN_KEY, false)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
saveSpaceSwitchCount(spaceSwitchCount)
}
private fun saveSpaceSwitchCount(count: Int) {
val sharedPreferences =
requireContext().getSharedPreferences(SPACE_SWITCH_PREF, Context.MODE_PRIVATE)
sharedPreferences.edit().putInt(SPACE_SWITCH_COUNT_KEY, count).apply()
}
private fun getSpaceSwitchCount(): Int {
val sharedPreferences =
requireContext().getSharedPreferences(SPACE_SWITCH_PREF, Context.MODE_PRIVATE)
return sharedPreferences.getInt(SPACE_SWITCH_COUNT_KEY, 0)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -125,7 +170,9 @@ class HomeScreenFragment : BaseComposeFragment(),
onSeeAllObjectsClicked = vm::onSeeAllObjectsClicked,
onCreateObjectInsideWidget = vm::onCreateObjectInsideWidget,
onCreateDataViewObject = vm::onCreateDataViewObject,
onBackLongClicked = vm::onBackLongClicked
onBackLongClicked = vm::onBackLongClicked,
showTooltip = vm.showTooltip,
onTooltipDismissed = vm::onTooltipDismissed,
)
}
}
@ -390,6 +437,9 @@ class HomeScreenFragment : BaseComposeFragment(),
}
companion object {
private const val TOOLTIP_SHOWN_KEY = "tooltip_shown_key"
private const val SPACE_SWITCH_PREF = "HomeScreenPrefs"
private const val SPACE_SWITCH_COUNT_KEY = "space_switch_count_key"
const val SHOW_MNEMONIC_KEY = "arg.home-screen.show-mnemonic"
const val DEEP_LINK_KEY = "arg.home-screen.deep-link"
fun args(deeplink: String?) : Bundle = bundleOf(

View file

@ -130,4 +130,6 @@
<color name="home_screen_toolbar_button">#F2222222</color>
<color name="home_screen_tooltip">#F2F1F7</color>
</resources>

View file

@ -253,4 +253,6 @@
<color name="object_search_cursor_color">#007AFF</color>
<color name="home_screen_tooltip">#F2F1F7</color>
</resources>

View file

@ -127,6 +127,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
@ -340,6 +341,22 @@ class HomeScreenViewModel(
proceedWithViewStatePipeline()
}
private val _showTooltip = MutableStateFlow(false)
val showTooltip: StateFlow<Boolean> get() = _showTooltip
private var tooltipShownOnce = false
fun showTooltip() {
if (!tooltipShownOnce) {
_showTooltip.value = true
tooltipShownOnce = true
}
}
fun onTooltipDismissed() {
_showTooltip.value = false
}
private fun proceedWithViewStatePipeline() {
widgetObjectPipelineJobs += viewModelScope.launch {
if (!isWidgetSessionRestored) {