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:
parent
6ff075360b
commit
81cf73a0b2
5 changed files with 202 additions and 3 deletions
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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(
|
||||
|
|
|
@ -130,4 +130,6 @@
|
|||
|
||||
<color name="home_screen_toolbar_button">#F2222222</color>
|
||||
|
||||
<color name="home_screen_tooltip">#F2F1F7</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -253,4 +253,6 @@
|
|||
|
||||
<color name="object_search_cursor_color">#007AFF</color>
|
||||
|
||||
<color name="home_screen_tooltip">#F2F1F7</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue