Add sleep-safe activity window
This commit is contained in:
@@ -52,7 +52,8 @@ import kotlinx.coroutines.delay
|
||||
@Composable
|
||||
fun TouchGrassActivityScreen(
|
||||
lcdDark: Color,
|
||||
onGrassTap: () -> Unit
|
||||
onGrassTap: () -> Unit,
|
||||
statusText: String = "Pet is taking time alone."
|
||||
) {
|
||||
var grassFingerColumn by remember { mutableIntStateOf(-1) }
|
||||
var grassWaveTick by remember { mutableIntStateOf(0) }
|
||||
@@ -127,7 +128,7 @@ fun TouchGrassActivityScreen(
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "Pet is taking time alone.",
|
||||
text = statusText,
|
||||
color = lcdDark,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
@@ -139,7 +140,8 @@ fun WatchTvActivityScreen(
|
||||
lcdDark: Color,
|
||||
selectedChannel: TvChannel,
|
||||
weatherLabel: String,
|
||||
onChannelSelected: (TvChannel) -> Unit
|
||||
onChannelSelected: (TvChannel) -> Unit,
|
||||
statusText: String = "Pet is outside having alone time."
|
||||
) {
|
||||
var tvFrame by remember { mutableIntStateOf(0) }
|
||||
var tvPowerState by remember { mutableIntStateOf(1) }
|
||||
@@ -459,7 +461,7 @@ fun WatchTvActivityScreen(
|
||||
}
|
||||
|
||||
Text(
|
||||
text = "Pet is outside having alone time.",
|
||||
text = statusText,
|
||||
color = lcdDark,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
@@ -671,6 +671,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
var testWantMenuOpen by remember { mutableStateOf(false) }
|
||||
var testBondMenuOpen by remember { mutableStateOf(false) }
|
||||
var downtimeMode by remember { mutableStateOf(DowntimeMode.None) }
|
||||
var sleepWakeConfirm by remember { mutableStateOf(false) }
|
||||
var selectedTvChannel by remember { mutableStateOf(TvChannel.Weather) }
|
||||
|
||||
var currentWant by remember { mutableStateOf("") }
|
||||
@@ -2290,6 +2291,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
}
|
||||
fun wakeFromAutoSleep() {
|
||||
if (isSleeping && sleepMode == "Auto") {
|
||||
sleepWakeConfirm = false
|
||||
downtimeMode = DowntimeMode.None
|
||||
val sleptOutside = location == "Outside"
|
||||
val startedAtMs = if (autoSleepStartedAtMs > 0L) autoSleepStartedAtMs else System.currentTimeMillis()
|
||||
val sleptMs = (System.currentTimeMillis() - startedAtMs).coerceAtLeast(0L)
|
||||
@@ -2334,6 +2337,39 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
}
|
||||
}
|
||||
|
||||
fun wakeFromManualNap() {
|
||||
if (isSleeping && sleepMode == "Nap") {
|
||||
sleepWakeConfirm = false
|
||||
downtimeMode = DowntimeMode.None
|
||||
roughWakeDarkFlash = true
|
||||
activityMood = "Asleep"
|
||||
frameProp = ""
|
||||
framePropAnimation = ""
|
||||
framePropStyle = 0
|
||||
|
||||
saveScope.launch {
|
||||
delay(if (testingMode) 1_500L else 1_200L)
|
||||
|
||||
if (isSleeping && sleepMode == "Nap") {
|
||||
isSleeping = false
|
||||
sleepMode = ""
|
||||
autoSleepStartedAtMs = 0L
|
||||
restoredManualNap = false
|
||||
roughWakeDarkFlash = false
|
||||
roughWakeNervousHold = false
|
||||
|
||||
status = "Nervous"
|
||||
activityMood = "RoughWake"
|
||||
roughWakeAlert = true
|
||||
frameProp = "!?!"
|
||||
framePropAnimation = ""
|
||||
framePropStyle = 0
|
||||
happiness = (happiness - 1).coerceAtLeast(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val currentNeedsPetName by rememberUpdatedState(needsPetName)
|
||||
val currentSaveLoaded by rememberUpdatedState(saveLoaded)
|
||||
val currentLocation by rememberUpdatedState(location)
|
||||
@@ -3895,6 +3931,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
sickCount = 0
|
||||
}
|
||||
|
||||
sleepWakeConfirm = false
|
||||
downtimeMode = DowntimeMode.None
|
||||
isSleeping = false
|
||||
sleepMode = ""
|
||||
autoSleepStartedAtMs = 0L
|
||||
@@ -4833,13 +4871,18 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
val downtimeActive =
|
||||
testingMode && downtimeMode != DowntimeMode.None
|
||||
!isSleeping && downtimeMode != DowntimeMode.None
|
||||
|
||||
val downtimeTitle = when {
|
||||
testingMode && downtimeMode == DowntimeMode.TouchGrass -> "TOUCH GRASS"
|
||||
testingMode && downtimeMode == DowntimeMode.WatchTv -> "WATCH TV"
|
||||
else -> ""
|
||||
}
|
||||
val downtimeTitle =
|
||||
if (isSleeping) {
|
||||
""
|
||||
} else {
|
||||
when (downtimeMode) {
|
||||
DowntimeMode.TouchGrass -> "TOUCH GRASS"
|
||||
DowntimeMode.WatchTv -> "WATCH TV"
|
||||
DowntimeMode.None -> ""
|
||||
}
|
||||
}
|
||||
|
||||
if (downtimeTitle.isNotEmpty()) {
|
||||
Text(
|
||||
@@ -4864,17 +4907,29 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
)
|
||||
)
|
||||
|
||||
if (testingMode && downtimeMode == DowntimeMode.TouchGrass) {
|
||||
if (!isSleeping && downtimeMode == DowntimeMode.TouchGrass) {
|
||||
TouchGrassActivityScreen(
|
||||
lcdDark = petFrameForeground,
|
||||
onGrassTap = {}
|
||||
onGrassTap = {},
|
||||
statusText =
|
||||
if (isSleeping) {
|
||||
"$displayPetName is sleeping."
|
||||
} else {
|
||||
"Pet is taking time alone."
|
||||
}
|
||||
)
|
||||
} else if (testingMode && downtimeMode == DowntimeMode.WatchTv) {
|
||||
} else if (!isSleeping && downtimeMode == DowntimeMode.WatchTv) {
|
||||
WatchTvActivityScreen(
|
||||
lcdDark = petFrameForeground,
|
||||
selectedChannel = selectedTvChannel,
|
||||
weatherLabel = weather,
|
||||
onChannelSelected = { selectedTvChannel = it }
|
||||
onChannelSelected = { selectedTvChannel = it },
|
||||
statusText =
|
||||
if (isSleeping) {
|
||||
"$displayPetName is sleeping."
|
||||
} else {
|
||||
"Pet is outside having alone time."
|
||||
}
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
@@ -5532,6 +5587,209 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
"RecoverWeak"
|
||||
)
|
||||
|
||||
if (isSleeping) {
|
||||
androidx.compose.ui.window.Popup(
|
||||
alignment = Alignment.TopCenter,
|
||||
properties = androidx.compose.ui.window.PopupProperties(
|
||||
focusable = true
|
||||
)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(configuration.screenWidthDp.dp)
|
||||
.height(configuration.screenHeightDp.dp)
|
||||
.background(petHomeBackground)
|
||||
.border(2.dp, petFrameForeground)
|
||||
.padding(screenPadding)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = "$displayPetName is sleeping.",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = petFrameForeground,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
LCDSubMenuFrame(lcdDark = petFrameForeground) {
|
||||
LCDSubButton(
|
||||
text = "TOUCH GRASS",
|
||||
modifier = Modifier.weight(1f),
|
||||
fillWidthFraction = 1f,
|
||||
enabled = !roughWakeDarkFlash,
|
||||
lcdDark = petFrameForeground,
|
||||
lcdFaded = lcdFaded,
|
||||
onClick = {
|
||||
downtimeMode = DowntimeMode.TouchGrass
|
||||
}
|
||||
)
|
||||
|
||||
LCDSubButton(
|
||||
text = "WATCH TV",
|
||||
modifier = Modifier.weight(1f),
|
||||
fillWidthFraction = 1f,
|
||||
enabled = !roughWakeDarkFlash,
|
||||
lcdDark = petFrameForeground,
|
||||
lcdFaded = lcdFaded,
|
||||
onClick = {
|
||||
downtimeMode = DowntimeMode.WatchTv
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
when (downtimeMode) {
|
||||
DowntimeMode.TouchGrass -> {
|
||||
TouchGrassActivityScreen(
|
||||
lcdDark = petFrameForeground,
|
||||
onGrassTap = {},
|
||||
statusText = "$displayPetName is sleeping."
|
||||
)
|
||||
}
|
||||
|
||||
DowntimeMode.WatchTv -> {
|
||||
WatchTvActivityScreen(
|
||||
lcdDark = petFrameForeground,
|
||||
selectedChannel = selectedTvChannel,
|
||||
weatherLabel = weather,
|
||||
onChannelSelected = {
|
||||
selectedTvChannel = it
|
||||
},
|
||||
statusText = "$displayPetName is sleeping."
|
||||
)
|
||||
}
|
||||
|
||||
DowntimeMode.None -> {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = petArt,
|
||||
fontSize = 24.sp,
|
||||
lineHeight = 24.sp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
textAlign = TextAlign.Center,
|
||||
color = petFrameForeground
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Text(
|
||||
text = "ZzZ",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = petFrameForeground
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
LCDMenuButton(
|
||||
text = "EXIT QUIETLY",
|
||||
enabled = !roughWakeDarkFlash,
|
||||
lcdDark = petFrameForeground,
|
||||
lcdFaded = lcdFaded,
|
||||
onClick = {
|
||||
downtimeMode = DowntimeMode.None
|
||||
(context as? android.app.Activity)
|
||||
?.moveTaskToBack(true)
|
||||
}
|
||||
)
|
||||
|
||||
LCDMenuButton(
|
||||
text = "WAKE ${displayPetName.uppercase()}",
|
||||
enabled = !roughWakeDarkFlash,
|
||||
lcdDark = petFrameForeground,
|
||||
lcdFaded = lcdFaded,
|
||||
onClick = {
|
||||
sleepWakeConfirm = true
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (sleepWakeConfirm) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.matchParentSize()
|
||||
.background(petHomeBackground),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(24.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "ARE YOU SURE?",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = petFrameForeground,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "Wake $displayPetName?",
|
||||
color = petFrameForeground,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
LCDSubMenuFrame(
|
||||
lcdDark = petFrameForeground
|
||||
) {
|
||||
LCDSubButton(
|
||||
text = "CANCEL",
|
||||
modifier = Modifier.weight(1f),
|
||||
fillWidthFraction = 1f,
|
||||
enabled = true,
|
||||
lcdDark = petFrameForeground,
|
||||
lcdFaded = lcdFaded,
|
||||
onClick = {
|
||||
sleepWakeConfirm = false
|
||||
}
|
||||
)
|
||||
|
||||
LCDSubButton(
|
||||
text = "WAKE",
|
||||
modifier = Modifier.weight(1f),
|
||||
fillWidthFraction = 1f,
|
||||
enabled = true,
|
||||
lcdDark = petFrameForeground,
|
||||
lcdFaded = lcdFaded,
|
||||
onClick = {
|
||||
when (sleepMode) {
|
||||
"Auto" ->
|
||||
wakeFromAutoSleep()
|
||||
|
||||
"Nap" ->
|
||||
wakeFromManualNap()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(0.dp))
|
||||
}
|
||||
|
||||
if (location == "Inside") {
|
||||
LCDMenuButton(
|
||||
text = if (careMenuOpen) "CARE ▲" else "CARE ▼",
|
||||
|
||||
Reference in New Issue
Block a user