perf: preload events and CalDAV config to avoid empty screens
Add CaldavConfigStore and preloadAppData() to load events (current month) and CalDAV config into stores before dismissing the auth loading spinner. This prevents the brief empty flash when first navigating to Calendar or Settings tabs. Also applies Prettier formatting across codebase.
This commit is contained in:
@@ -11,12 +11,7 @@ import { EventCard } from "../../components/EventCard";
|
||||
import { DeleteEventModal } from "../../components/DeleteEventModal";
|
||||
import { ModalBase } from "../../components/ModalBase";
|
||||
import { ScrollableDropdown } from "../../components/ScrollableDropdown";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { router, useFocusEffect } from "expo-router";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useThemeStore } from "../../stores/ThemeStore";
|
||||
|
||||
@@ -175,7 +175,11 @@ const Chat = () => {
|
||||
params: {
|
||||
mode: "chat",
|
||||
eventData: JSON.stringify(proposal.event),
|
||||
proposalContext: JSON.stringify({ messageId, proposalId, conversationId }),
|
||||
proposalContext: JSON.stringify({
|
||||
messageId,
|
||||
proposalId,
|
||||
conversationId,
|
||||
}),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -8,8 +8,9 @@ import { Ionicons } from "@expo/vector-icons";
|
||||
import { SimpleHeader } from "../../components/Header";
|
||||
import { THEMES } from "../../Themes";
|
||||
import CustomTextInput from "../../components/CustomTextInput";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { CaldavConfigService } from "../../services/CaldavConfigService";
|
||||
import { useCaldavConfigStore } from "../../stores";
|
||||
|
||||
const handleLogout = async () => {
|
||||
await AuthService.logout();
|
||||
@@ -34,38 +35,38 @@ type CaldavTextInputProps = {
|
||||
onValueChange: (text: string) => void;
|
||||
};
|
||||
|
||||
const CaldavTextInput = ({ title, value, onValueChange }: CaldavTextInputProps) => {
|
||||
const CaldavTextInput = ({
|
||||
title,
|
||||
value,
|
||||
onValueChange,
|
||||
}: CaldavTextInputProps) => {
|
||||
return (
|
||||
<View className="flex flex-row items-center py-1">
|
||||
<Text className="ml-4 w-24">{title}:</Text>
|
||||
<CustomTextInput className="flex-1 mr-4" text={value} onValueChange={onValueChange} />
|
||||
<CustomTextInput
|
||||
className="flex-1 mr-4"
|
||||
text={value}
|
||||
onValueChange={onValueChange}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const CaldavSettings = () => {
|
||||
const { theme } = useThemeStore();
|
||||
const { config, setConfig } = useCaldavConfigStore();
|
||||
|
||||
const [serverUrl, setServerUrl] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
const loadConfig = async () => {
|
||||
try {
|
||||
const config = await CaldavConfigService.getConfig();
|
||||
setServerUrl(config.serverUrl);
|
||||
setUsername(config.username);
|
||||
setPassword(config.password);
|
||||
} catch {
|
||||
// No config saved yet
|
||||
}
|
||||
};
|
||||
loadConfig();
|
||||
}, []);
|
||||
const [serverUrl, setServerUrl] = useState(config?.serverUrl ?? "");
|
||||
const [username, setUsername] = useState(config?.username ?? "");
|
||||
const [password, setPassword] = useState(config?.password ?? "");
|
||||
|
||||
const saveConfig = async () => {
|
||||
await CaldavConfigService.saveConfig(serverUrl, username, password);
|
||||
const saved = await CaldavConfigService.saveConfig(
|
||||
serverUrl,
|
||||
username,
|
||||
password,
|
||||
);
|
||||
setConfig(saved);
|
||||
};
|
||||
|
||||
const sync = async () => {
|
||||
@@ -84,9 +85,21 @@ const CaldavSettings = () => {
|
||||
</View>
|
||||
<View>
|
||||
<View className="pb-1">
|
||||
<CaldavTextInput title="url" value={serverUrl} onValueChange={setServerUrl} />
|
||||
<CaldavTextInput title="username" value={username} onValueChange={setUsername} />
|
||||
<CaldavTextInput title="password" value={password} onValueChange={setPassword} />
|
||||
<CaldavTextInput
|
||||
title="url"
|
||||
value={serverUrl}
|
||||
onValueChange={setServerUrl}
|
||||
/>
|
||||
<CaldavTextInput
|
||||
title="username"
|
||||
value={username}
|
||||
onValueChange={setUsername}
|
||||
/>
|
||||
<CaldavTextInput
|
||||
title="password"
|
||||
value={password}
|
||||
onValueChange={setPassword}
|
||||
/>
|
||||
</View>
|
||||
<View className="flex flex-row">
|
||||
<BaseButton className="mx-4 w-1/5" solid={true} onPress={saveConfig}>
|
||||
|
||||
@@ -19,7 +19,12 @@ import { Ionicons } from "@expo/vector-icons";
|
||||
import { ScrollableDropdown } from "../components/ScrollableDropdown";
|
||||
import { useDropdownPosition } from "../hooks/useDropdownPosition";
|
||||
import { EventService, ChatService } from "../services";
|
||||
import { buildRRule, CreateEventDTO, REPEAT_TYPE_LABELS, RepeatType } from "@calchat/shared";
|
||||
import {
|
||||
buildRRule,
|
||||
CreateEventDTO,
|
||||
REPEAT_TYPE_LABELS,
|
||||
RepeatType,
|
||||
} from "@calchat/shared";
|
||||
import { useChatStore } from "../stores";
|
||||
import CustomTextInput, {
|
||||
CustomTextInputProps,
|
||||
|
||||
@@ -5,6 +5,7 @@ import BaseBackground from "../components/BaseBackground";
|
||||
import AuthButton from "../components/AuthButton";
|
||||
import { AuthService } from "../services";
|
||||
import { CaldavConfigService } from "../services/CaldavConfigService";
|
||||
import { preloadAppData } from "../components/AuthGuard";
|
||||
import { useThemeStore } from "../stores/ThemeStore";
|
||||
|
||||
const LoginScreen = () => {
|
||||
@@ -25,6 +26,7 @@ const LoginScreen = () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await AuthService.login({ identifier, password });
|
||||
await preloadAppData();
|
||||
try {
|
||||
await CaldavConfigService.sync();
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user