🤫小彩蛋🤫
This commit is contained in:
parent
87bb8adfa0
commit
9c4c6d6b32
6 changed files with 267 additions and 3 deletions
|
|
@ -12,6 +12,7 @@ import cn.super12138.todo.ui.pages.editor.TodoEditorPage
|
||||||
import cn.super12138.todo.ui.pages.main.MainPage
|
import cn.super12138.todo.ui.pages.main.MainPage
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsAbout
|
import cn.super12138.todo.ui.pages.settings.SettingsAbout
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsAboutLicence
|
import cn.super12138.todo.ui.pages.settings.SettingsAboutLicence
|
||||||
|
import cn.super12138.todo.ui.pages.settings.SettingsAboutSpecial
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsAppearance
|
import cn.super12138.todo.ui.pages.settings.SettingsAppearance
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsData
|
import cn.super12138.todo.ui.pages.settings.SettingsData
|
||||||
import cn.super12138.todo.ui.pages.settings.SettingsInterface
|
import cn.super12138.todo.ui.pages.settings.SettingsInterface
|
||||||
|
|
@ -123,8 +124,16 @@ fun TodoNavigation(
|
||||||
|
|
||||||
composable(TodoScreen.SettingsAbout.name) {
|
composable(TodoScreen.SettingsAbout.name) {
|
||||||
SettingsAbout(
|
SettingsAbout(
|
||||||
|
toSpecialPage = { navController.navigate(TodoScreen.SettingsAboutSpecial.name) },
|
||||||
|
toLicencePage = { navController.navigate(TodoScreen.SettingsAboutLicence.name) },
|
||||||
onNavigateUp = { navController.navigateUp() },
|
onNavigateUp = { navController.navigateUp() },
|
||||||
toLicencePage = { navController.navigate(TodoScreen.SettingsAboutLicence.name) }
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
composable(TodoScreen.SettingsAboutSpecial.name) {
|
||||||
|
SettingsAboutSpecial(
|
||||||
|
viewModel = viewModel,
|
||||||
|
onNavigateUp = { navController.navigateUp() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ enum class TodoScreen {
|
||||||
SettingsInterface,
|
SettingsInterface,
|
||||||
SettingsData,
|
SettingsData,
|
||||||
SettingsAbout,
|
SettingsAbout,
|
||||||
|
SettingsAboutSpecial,
|
||||||
SettingsAboutLicence
|
SettingsAboutLicence
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package cn.super12138.todo.ui.pages.settings
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
|
@ -14,6 +15,10 @@ import androidx.compose.material.icons.outlined.Person4
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
|
@ -28,8 +33,9 @@ import cn.super12138.todo.utils.SystemUtils
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsAbout(
|
fun SettingsAbout(
|
||||||
onNavigateUp: () -> Unit,
|
toSpecialPage: () -> Unit,
|
||||||
toLicencePage: () -> Unit,
|
toLicencePage: () -> Unit,
|
||||||
|
onNavigateUp: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||||
|
|
@ -46,10 +52,22 @@ fun SettingsAbout(
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
) {
|
) {
|
||||||
|
var clickCount by remember { mutableIntStateOf(0) }
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
leadingIcon = Icons.Outlined.Numbers,
|
leadingIcon = Icons.Outlined.Numbers,
|
||||||
title = stringResource(R.string.pref_app_version),
|
title = stringResource(R.string.pref_app_version),
|
||||||
description = SystemUtils.getAppVersion(context)
|
description = SystemUtils.getAppVersion(context),
|
||||||
|
onClick = {
|
||||||
|
clickCount++
|
||||||
|
if (clickCount == 5) {
|
||||||
|
if ((System.currentTimeMillis() % 2) == 0.toLong()) {
|
||||||
|
toSpecialPage()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(context, "✨", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
clickCount = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
leadingIcon = Icons.Outlined.Person4,
|
leadingIcon = Icons.Outlined.Person4,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,234 @@
|
||||||
|
package cn.super12138.todo.ui.pages.settings
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.expandVertically
|
||||||
|
import androidx.compose.animation.scaleIn
|
||||||
|
import androidx.compose.animation.scaleOut
|
||||||
|
import androidx.compose.animation.shrinkVertically
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
|
import androidx.compose.foundation.layout.asPaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.statusBars
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.shape.CornerSize
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.Brush
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
|
import androidx.compose.ui.platform.LocalView
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import cn.super12138.todo.R
|
||||||
|
import cn.super12138.todo.ui.viewmodels.MainViewModel
|
||||||
|
import cn.super12138.todo.utils.VibrationUtils
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SettingsAboutSpecial(
|
||||||
|
viewModel: MainViewModel,
|
||||||
|
onNavigateUp: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val configuration = LocalConfiguration.current
|
||||||
|
val screenHeight = configuration.screenHeightDp.dp
|
||||||
|
var showBanner by rememberSaveable { mutableStateOf(false) }
|
||||||
|
Surface(color = SpecialDefaults.WallColor) {
|
||||||
|
Box(Modifier.fillMaxSize()) {
|
||||||
|
AnimatedVisibility(
|
||||||
|
visible = showBanner,
|
||||||
|
enter = expandVertically(),
|
||||||
|
exit = shrinkVertically()
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(screenHeight / 4)
|
||||||
|
.clip(MaterialTheme.shapes.large)
|
||||||
|
.background(SpecialDefaults.BannerColor)
|
||||||
|
.padding(WindowInsets.statusBars.asPaddingValues())
|
||||||
|
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.happy_birthday),
|
||||||
|
style = MaterialTheme.typography.headlineMedium
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 蛋糕
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
) {
|
||||||
|
Cake(
|
||||||
|
onCandleClick = {
|
||||||
|
showBanner = it
|
||||||
|
if (it) viewModel.playConfetti()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// 桌子
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(SpecialDefaults.TableHeight)
|
||||||
|
.background(SpecialDefaults.TableColor)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Cake(
|
||||||
|
onCandleClick: (Boolean) -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier
|
||||||
|
) {
|
||||||
|
val configuration = LocalConfiguration.current
|
||||||
|
val screenWidth = configuration.screenWidthDp.dp
|
||||||
|
Row {
|
||||||
|
Candle(onClick = onCandleClick)
|
||||||
|
}
|
||||||
|
CakePiece(
|
||||||
|
width = screenWidth / 4,
|
||||||
|
height = SpecialDefaults.Cake2Height,
|
||||||
|
color = SpecialDefaults.Cake2Color
|
||||||
|
)
|
||||||
|
CakePiece(
|
||||||
|
width = screenWidth / 3,
|
||||||
|
height = SpecialDefaults.Cake1Height,
|
||||||
|
color = SpecialDefaults.Cake1Color
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun CakePiece(
|
||||||
|
width: Dp,
|
||||||
|
height: Dp,
|
||||||
|
color: Color,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier
|
||||||
|
.width(width)
|
||||||
|
.height(height)
|
||||||
|
.clip(
|
||||||
|
MaterialTheme.shapes.small.copy(
|
||||||
|
bottomStart = CornerSize(0.dp),
|
||||||
|
bottomEnd = CornerSize(0.dp)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.background(color)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Candle(
|
||||||
|
onClick: (Boolean) -> Unit = {},
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
var showFlame by rememberSaveable { mutableStateOf(false) }
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
val view = LocalView.current
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
modifier = modifier.clickable(
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
indication = null,
|
||||||
|
onClick = {
|
||||||
|
showFlame = !showFlame
|
||||||
|
VibrationUtils.performHapticFeedback(view)
|
||||||
|
onClick(showFlame)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// 火苗
|
||||||
|
Box {
|
||||||
|
androidx.compose.animation.AnimatedVisibility(
|
||||||
|
visible = showFlame,
|
||||||
|
enter = scaleIn(),
|
||||||
|
exit = scaleOut(),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.Center)
|
||||||
|
.padding(bottom = 2.5.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.size(10.dp)
|
||||||
|
.background(
|
||||||
|
brush = Brush.radialGradient(
|
||||||
|
listOf(
|
||||||
|
SpecialDefaults.FlameCenterColor,
|
||||||
|
SpecialDefaults.FlameAroundColor,
|
||||||
|
Color.Transparent
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.width(SpecialDefaults.WickWidth)
|
||||||
|
.height(SpecialDefaults.WickHeight)
|
||||||
|
.background(SpecialDefaults.WickColor)
|
||||||
|
.align(Alignment.BottomCenter)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
Modifier
|
||||||
|
.width(SpecialDefaults.CandleBodyWidth)
|
||||||
|
.height(SpecialDefaults.CandleBodyHeight)
|
||||||
|
.background(Color(0xFFECCE48))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object SpecialDefaults {
|
||||||
|
// Color
|
||||||
|
val WallColor = Color(0xFFFFFBEA)
|
||||||
|
val TableColor = Color(0xFF412200)
|
||||||
|
val Cake1Color = Color(0xFFFFE9A0)
|
||||||
|
val Cake2Color = Color(0xFFFFECBF)
|
||||||
|
val FlameCenterColor = Color(0xFFFF5100)
|
||||||
|
val FlameAroundColor = Color(0xFFF82323)
|
||||||
|
val WickColor = Color(0xFF1E1E1E)
|
||||||
|
val BannerColor = Color(0xFFFFF1BC)
|
||||||
|
|
||||||
|
// Size
|
||||||
|
val TableHeight = 30.dp
|
||||||
|
val Cake1Height = 60.dp
|
||||||
|
val Cake2Height = 45.dp
|
||||||
|
val CandleBodyWidth = 10.dp
|
||||||
|
val CandleBodyHeight = 20.dp
|
||||||
|
val WickWidth = 1.5.dp
|
||||||
|
val WickHeight = 8.dp
|
||||||
|
}
|
||||||
|
|
@ -107,4 +107,5 @@
|
||||||
<string name="pref_secure_mode">安全模式</string>
|
<string name="pref_secure_mode">安全模式</string>
|
||||||
<string name="pref_secure_mode_desc">阻止截屏并保护后台预览图</string>
|
<string name="pref_secure_mode_desc">阻止截屏并保护后台预览图</string>
|
||||||
<string name="label_more">更多</string>
|
<string name="label_more">更多</string>
|
||||||
|
<string name="happy_birthday">待办1岁生日快乐</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -108,4 +108,5 @@
|
||||||
<string name="pref_secure_mode">Secure Mode</string>
|
<string name="pref_secure_mode">Secure Mode</string>
|
||||||
<string name="pref_secure_mode_desc">Prevent screenshots and protect the background preview image</string>
|
<string name="pref_secure_mode_desc">Prevent screenshots and protect the background preview image</string>
|
||||||
<string name="label_more">More</string>
|
<string name="label_more">More</string>
|
||||||
|
<string name="happy_birthday">Happy 1st birthday to ToDo</string>
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in a new issue