(feat): improve mobile cal ui a bit
All checks were successful
/ build-web (push) Successful in 7m40s
/ build-desktop (linux) (push) Successful in 12m10s
/ build-mobile (push) Successful in 19m34s
/ release (push) Successful in 3m31s

(feat): add popout for call ui on mobile
(fix): fix cache and profile avatar upload stuff
This commit is contained in:
Alois 2026-07-31 22:17:08 +02:00
commit b5ce3c554d
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
14 changed files with 443 additions and 155 deletions

View file

@ -21,6 +21,7 @@ const USER_CACHE_MAX_AGE = 5 * 60 * 1000;
interface contextValue {
get(userId: number): Promise<User>;
update(user: User): Promise<void>;
}
const UserContext = createContext<contextValue | undefined>(undefined);
@ -39,6 +40,7 @@ export default function UserProvider(props: { children: ReactNode }) {
const { load } = useStorage();
const { contacts } = useSession();
const [accountId, setAccountId] = useState<number | null>(null);
const [cacheVersion, setCacheVersion] = useState(0);
useEffect(() => {
void load("user_id").then((accountId) => {
@ -53,6 +55,7 @@ export default function UserProvider(props: { children: ReactNode }) {
*/
const get = useCallback(
async (userId: number): Promise<User> => {
void cacheVersion;
if (userId == null) {
throw new Error("userId is required");
}
@ -63,28 +66,26 @@ export default function UserProvider(props: { children: ReactNode }) {
}
const request = (async () => {
const cache = accountId ? createCache(String(accountId)) : null;
const cache = createCache(String(accountId ?? userId));
const cachedValue =
storageRef.current[userId] ?? (await cache?.profiles.get(userId));
storageRef.current[userId] ?? (await cache.profiles.get(userId));
const cachedResult =
schemas.GetUserData.response.safeParse(cachedValue);
const cached = cachedResult.success ? cachedResult.data : undefined;
if (cached) {
storageRef.current[userId] = cached;
const checkedAt = checkedAtRef.current[userId];
if (checkedAt && Date.now() - checkedAt < USER_CACHE_MAX_AGE) {
if (!checkedAt || Date.now() - checkedAt < USER_CACHE_MAX_AGE) {
checkedAtRef.current[userId] = Date.now();
return cached;
}
}
try {
const userData = await send("GetUserData", { UserId: userId });
if (
userData.type === "ErrorNotFound" ||
userData.data.UserId === 0
) {
if (userData.type === "ErrorNotFound" || userData.data.UserId === 0) {
delete storageRef.current[userId];
delete checkedAtRef.current[userId];
await cache?.profiles.delete(userId);
await cache.profiles.delete(userId);
throw new Error("GetUserData failed: user not found");
}
if (userData.type.startsWith("Error")) {
@ -111,7 +112,17 @@ export default function UserProvider(props: { children: ReactNode }) {
delete pendingRef.current[userId];
}
},
[accountId, send],
[accountId, cacheVersion, send],
);
const update = useCallback(
async (user: User) => {
await createCache(String(accountId ?? user.UserId)).profiles.put(user);
storageRef.current[user.UserId] = user;
checkedAtRef.current[user.UserId] = Date.now();
setCacheVersion((version) => version + 1);
},
[accountId],
);
useEffect(() => {
@ -120,7 +131,7 @@ export default function UserProvider(props: { children: ReactNode }) {
}, [accountId, contacts, get]);
return (
<UserContext.Provider value={{ get }}>
<UserContext.Provider value={{ get, update }}>
{props.children}
</UserContext.Provider>
);