Files
discord-decomp/modules/parent_tools/native/ScheduleDowntimeScreen.tsx
T
2026-11-01 12:12:55 +02:00

404 lines
14 KiB
TypeScript

// Metro module 13965 (f13966).
import { useMemo, useState, useCallback, useLayoutEffect } from "react";
import { Pressable, ScrollView, View } from "react-native";
import UserStore from "../../../stores/UserStore";
import { UserSettingsSections } from "../../../Constants";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { HelpMessage, HelpMessageTypes } from "../../../design/void/native";
import { Stack } from "../../../design/components/Stack/native/Stack.native";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import FamilyCenter_messages from "../FamilyCenter.messages";
import { useStackNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { useSettingNavigationRoute } from "../../user_settings/core/native/useSettingNavigationRoute";
import { toTimeProto, getShortDayLabels, computeOverlappingInfo, timeToMinutes, formatTime, DAYS_ORDERED } from "../FamilyCenterRestrictedHoursUtils";
import { useStateFromStores } from "../../../_bundle/defaultAreStatesEqual";
import useTimeValue from "../hooks/useTimeValue";
import { updateRestrictedScheduleRule, addRestrictedScheduleRule, deleteRestrictedScheduleRule } from "../RestrictedScheduleActionCreators";
import { TrashIcon } from "../../../design/components/Icon/native/redesign/generated/TrashIcon";
import { TableRowGroup } from "../../../design/components/TableRow/native/TableRowGroup.native";
import { TableSwitchRow } from "../../../design/components/TableRow/native/TableSwitchRow.native";
import { TableRow } from "../../../design/components/TableRow/native/TableRow.native";
import { SafeAreaPaddingView } from "../../../components_native/common/SafeAreaView";
import { Button } from "../../../design/components/Button/native/Button.native";
function $mk92354($env) {
return (a0) => (0, $env[0])({
hours: a0.hours(),
minutes: a0.minutes()
});
}
let useStyles;
const OverlappingSchedulesWarning = function OverlappingSchedulesWarning(props) {
const conflictingEntries = props.conflictingEntries;
return conflictingEntries.length !== 0 ? <HelpMessage messageType={HelpMessageTypes.WARNING} borderRadius={Module712.radii.md}>
<Stack spacing={8}>
<Text variant="text-sm/medium">
{intl.string(FamilyCenter_messages["26A0Df"])}
</Text>
<Stack spacing={4}>
{conflictingEntries.map((conflictingEntry) => {
const dayLabel = conflictingEntry.dayLabel;
return <Text key={dayLabel} variant="text-sm/medium">
{`${dayLabel} ${conflictingEntry.timeRange}`}
</Text>;
})}
</Stack>
</Stack>
</HelpMessage> : null;
};
useStyles = createStyles({
container: {
flex: 1
},
scrollContent: {
paddingHorizontal: Module712.space.PX_16,
paddingTop: Module712.space.PX_24,
gap: Module712.space.PX_24
},
section: {
gap: Module712.space.PX_8
},
sectionHeader: {
gap: Module712.space.PX_4
},
daysContainer: {
flexDirection: "row",
gap: Module712.space.PX_8
},
dayButton: {
flex: 1,
aspectRatio: 1,
borderRadius: Module712.radii.round,
alignItems: "center",
justifyContent: "center",
backgroundColor: Module712.colors.REDESIGN_BUTTON_TERTIARY_BACKGROUND,
borderWidth: 1,
borderColor: "transparent"
},
dayButtonSelected: {
backgroundColor: "rgba(88, 101, 242, 0.16)",
borderColor: "rgba(88, 101, 242, 1)"
},
overlapWarningContent: {
marginTop: Module712.space.PX_24
},
footer: {
paddingHorizontal: Module712.space.PX_16,
paddingVertical: Module712.space.PX_16,
gap: Module712.space.PX_8
}
});
export default function ScheduleDowntimeScreen() {
let styles, stackNavigation, rule, memo, memo2, teenId, c20817_6, stateFromStores, c20817_10, c20817_12, memo3, callback;
let _handleSubmit2 = function _handleSubmit() {
const r9 = async () => {
let r56;
let c30679_2;
let c30679_3 = 0;
L18: {
try {
if (teenId != null) {
setState3(true);
c30679_3 = 1;
const r19 = {
label: "",
start_time: toTimeProto(c20817_10),
end_time: toTimeProto(c20817_12),
days: Array.from(state2),
enabled: state
};
if (c20817_6) {
if (rule?.ruleId != null) {
await updateRestrictedScheduleRule(teenId, rule.ruleId, r19);
} else {
r56 = addRestrictedScheduleRule(teenId, r19);
await r56;
}
} else {
r56 = addRestrictedScheduleRule(teenId, r19);
await r56;
}
stackNavigation.goBack();
c30679_3 = 0;
(0, setState3)(false);
break L18;
}
} catch ($e) {
const r33 = $e;
let r7 = r33;
c30679_2 = r33;
if (c30679_3 !== 0) {
while (true) {
try {
const r117 = c30679_2;
c30679_3 = 0;
(0, setState3)(false);
throw r117;
} catch (r114) {
r7 = r114;
c30679_2 = r114;
if (c30679_3 === 0) {
break;
}
}
}
}
throw r7;
}
return void 0;
}
};
_handleSubmit2 = r9;
return r9.apply(this, arguments);
};
styles = useStyles();
stackNavigation = useStackNavigation();
const params = useSettingNavigationRoute().params;
rule = params?.rule;
memo = useMemo(() => getShortDayLabels("narrow"), []);
memo2 = useMemo(() => getShortDayLabels("short"), []);
teenId = params?.teenId;
const r4 = rule != null;
c20817_6 = r4;
let r55 = rule?.enabled;
if (r55 == null) {
r55 = true;
}
const [state, setState] = useState(r55);
stateFromStores = useStateFromStores([UserStore], () => {
let r9;
if (teenId == null) {
r9 = [];
} else {
const user = UserStore.getUser(teenId);
r9 = user == null ? void 0 : user.restrictedSchedule?.rules;
if (r9 == null) {
r9 = [];
}
}
return r9;
});
const r69 = rule?.startTime != null;
let initial = null;
if (r69) {
let minutes = rule.startTime.minutes;
if (minutes == null) {
minutes = 0;
}
initial = {
hours: rule.startTime.hours,
minutes,
seconds: 0,
nanos: 0
};
}
let [r33, c20817_11] = useTimeValue({
initial,
defaultValue: {
hours: 22,
minutes: 0
}
});
c20817_10 = r33;
const r84 = rule?.endTime != null;
let initial2 = null;
if (r84) {
let minutes2 = rule.endTime.minutes;
if (minutes2 == null) {
minutes2 = 0;
}
initial2 = {
hours: rule.endTime.hours,
minutes: minutes2,
seconds: 0,
nanos: 0
};
}
let [r34, c20817_13] = useTimeValue({
initial: initial2,
defaultValue: {
hours: 7,
minutes: 0
}
});
c20817_12 = r34;
const [state2, setState2] = useState(new Set(rule?.days));
const [state3, setState3] = useState(false);
memo3 = useMemo(() => c20817_6 ? rule?.ruleId != null ? stateFromStores.filter((stateFromStore) => stateFromStore.ruleId !== rule.ruleId) : stateFromStores : stateFromStores, [r4, rule?.ruleId, stateFromStores]);
const memo4 = useMemo(() => computeOverlappingInfo(state2, memo3, memo2), [memo2, memo3, state2]);
callback = useCallback(async () => {
let rules, c27596_3;
let c27596_4 = 0;
L24: {
L23: {
try {
if (teenId == null) {
break L24;
}
if (rule?.ruleId != null) {
setState3(true);
c27596_4 = 1;
await deleteRestrictedScheduleRule(teenId, rule.ruleId);
const user = UserStore.getUser(teenId);
rules = user == null ? void 0 : user.restrictedSchedule?.rules;
if (rules == null) {
rules = [];
}
if (rules.length === 0) {
stackNavigation.navigate(UserSettingsSections.FAMILY_CENTER);
} else {
stackNavigation.goBack();
}
c27596_4 = 0;
(0, setState3)(false);
break L23;
}
break L24;
} catch ($e) {
const r26 = $e;
let r7 = r26;
c27596_3 = r26;
if (c27596_4 !== 0) {
while (true) {
try {
const r93 = c27596_3;
c27596_4 = 0;
(0, setState3)(false);
throw r93;
} catch (r90) {
r7 = r90;
c27596_3 = r90;
if (c27596_4 === 0) {
break;
}
}
}
}
throw r7;
}
}
return void 0;
}
}, [teenId, rule?.ruleId, stackNavigation]);
useLayoutEffect(() => {
if (c20817_6) {
stackNavigation.setOptions({
headerRight: () => <Pressable onPress={callback} accessibilityRole="button" accessibilityLabel={intl.string(t.oyYWHE)} hitSlop={8} disabled={state3}>
<TrashIcon color={Module712.colors.ICON_FEEDBACK_CRITICAL} size="md" />
</Pressable>
});
}
}, [stackNavigation, r4, callback, state3]);
const r137 = timeToMinutes(r33);
const r141 = timeToMinutes(r34);
const r146 = {
startTime: formatTime(r33),
endTime: formatTime(r34),
timeHook: (a0, a1) => <Text key={a1} variant="text-sm/medium" color="text-default">
{a0}
</Text>
};
const r27 = r137 > r141 ? intl.format(FamilyCenter_messages.R87Y2K, r146) : intl.format(FamilyCenter_messages.vX7xid, r146);
const r168 = state2.size > 0 && r137 !== r141 && !state3;
return teenId == null ? null : <View style={styles.container}>
<ScrollView>
<View style={styles.scrollContent}>
<Text variant="text-md/medium" color="text-subtle">
{intl.string(FamilyCenter_messages.AcJ4ke)}
</Text>
{r4 && <TableRowGroup hasIcons={false}>
<TableSwitchRow label={intl.string(FamilyCenter_messages["30Owsd"])} value={state} onValueChange={function handleEnabledChange() {
setState((prevState) => !prevState);
}} />
</TableRowGroup>}
<View style={styles.section}>
<Text variant="text-sm/semibold" color="text-subtle">
{intl.string(FamilyCenter_messages["37z4a2"])}
</Text>
<TableRowGroup hasIcons={false}>
<TableRow label={intl.string(FamilyCenter_messages.DsXytO)} trailing={<Text variant="text-md/normal">
{formatTime(r33)}
</Text>} arrow onPress={function handleStartTimePress() {
let env27597;
const title = intl.string(FamilyCenter_messages["8bLRt0"]);
const r27 = env27597 = {};
env27597[0] = (a0) => {
c20817_11(a0);
const r1 = (timeToMinutes(a0) + 540) % 1440;
c20817_13({
hours: Math.floor(r1 / 60),
minutes: r1 % 60
});
};
ActionSheetActionCreators.openLazy(import("../../../components_native/DatePickerActionSheet"), "ScheduleDowntimeStartTimePicker", {
title,
mode: "time",
startDate: new Date(2025, 0, 1, c20817_10.hours, c20817_10.minutes, 0, 0),
onSubmit: $mk92354(r27)
});
}} />
<TableRow label={intl.string(FamilyCenter_messages["5SHDP6"])} trailing={<Text variant="text-md/normal">
{formatTime(r34)}
</Text>} arrow onPress={function handleEndTimePress() {
let env27598;
const title = intl.string(FamilyCenter_messages["+JkWJV"]);
const r28 = env27598 = {};
env27598[0] = c20817_13;
ActionSheetActionCreators.openLazy(import("../../../components_native/DatePickerActionSheet"), "ScheduleDowntimeEndTimePicker", {
title,
mode: "time",
startDate: new Date(2025, 0, 1, c20817_12.hours, c20817_12.minutes, 0, 0),
onSubmit: $mk92354(r28)
});
}} />
</TableRowGroup>
</View>
<View style={styles.section}>
<View style={styles.sectionHeader}>
<Text variant="text-sm/semibold" color="text-subtle">
{intl.string(FamilyCenter_messages.HaV0Sg)}
</Text>
<Text variant="text-sm/normal" color="text-muted">{r27}</Text>
</View>
<View style={styles.daysContainer}>
{DAYS_ORDERED.map((item, index) => {
const selected = state2.has(item);
return <Pressable key={item} style={[styles.dayButton, selected && styles.dayButtonSelected]} onPress={() => {
let c30680_0 = item;
setState2((prevState2) => {
const set = new Set(prevState2);
if (set.has(c30680_0)) {
set.delete(c30680_0);
} else {
set.add(c30680_0);
}
return set;
});
}} accessibilityRole="button" accessibilityState={{
selected
}} accessibilityLabel={memo[index]}>
<Text variant="text-sm/semibold" color={selected ? "control-secondary-text-default" : "text-muted"}>
{memo[index]}
</Text>
</Pressable>;
})}
</View>
{memo4.conflictingEntries.length > 0 && <View style={styles.overlapWarningContent}>
<OverlappingSchedulesWarning conflictingEntries={memo4.conflictingEntries} />
</View>}
</View>
</View>
</ScrollView>
<SafeAreaPaddingView bottom>
<View style={styles.footer}>
<Button text={intl.string(r4 ? FamilyCenter_messages.TDc9mW : FamilyCenter_messages.pvcruO)} onPress={function handleSubmit() {
return _handleSubmit2.apply(this, arguments);
}} disabled={!r168} loading={state3} variant="primary" size="lg" />
<Button text={intl.string(t["ETE/oC"])} onPress={() => stackNavigation.goBack()} disabled={state3} variant="secondary" size="lg" />
</View>
</SafeAreaPaddingView>
</View>;
};