android built works
Build APK / build (push) Canceled after 0s

This commit is contained in:
2026-08-06 11:24:17 +02:00
parent 793e2d9044
commit ec165beeff
3 changed files with 84 additions and 3 deletions
@@ -100,7 +100,7 @@ function AnimatedCategoryButton({ category, selected, onPress, theme }: Animated
toValue: selected ? 1.05 : 1,
duration: 150,
easing: Easing.out(Easing.cubic),
useNativeDriver: true,
useNativeDriver: false,
}).start();
Animated.timing(borderWidthAnim, {
+72
View File
@@ -1,3 +1,4 @@
import { AppState, AppStateStatus } from 'react-native';
import { database, collections } from './index';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { apiFetch, getAuthToken } from '@/services/auth';
@@ -473,3 +474,74 @@ async function upsertFriendship(row: ServerRow, force: boolean): Promise<boolean
});
return true;
}
export const DEFAULT_WATCH_INTERVAL_MS = 60_000;
export interface UpdateWatcher {
stop: () => void;
isRunning: () => boolean;
}
let watcherStop: (() => void) | null = null;
let watcherActive = false;
let appInForeground = true;
let syncInFlight = false;
export function watchForUpdates(intervalMs: number = DEFAULT_WATCH_INTERVAL_MS): UpdateWatcher {
if (watcherStop) {
return {
stop: () => stopWatchingForUpdates(),
isRunning: () => watcherActive,
};
}
appInForeground = AppState.currentState === 'active';
const appStateSubscription = AppState.addEventListener('change', (state: AppStateStatus) => {
const next = state === 'active';
const wentForeground = next && !appInForeground;
appInForeground = next;
if (wentForeground) {
maybeSyncOnce().catch(() => {});
}
});
const timer = setInterval(() => {
if (appInForeground && !syncInFlight) {
maybeSyncOnce().catch(() => {});
}
}, intervalMs);
watcherActive = true;
watcherStop = () => {
clearInterval(timer);
appStateSubscription.remove();
watcherStop = null;
watcherActive = false;
};
return {
stop: () => stopWatchingForUpdates(),
isRunning: () => watcherActive,
};
}
async function maybeSyncOnce(): Promise<void> {
if (syncInFlight) return;
const token = await getAuthToken();
if (!token) return;
syncInFlight = true;
try {
await runSync();
} finally {
syncInFlight = false;
}
}
export function stopWatchingForUpdates(): void {
watcherStop?.();
}
export function isWatchingForUpdates(): boolean {
return watcherActive;
}
+11 -2
View File
@@ -1,7 +1,7 @@
import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { map } from 'rxjs/operators';
import { database, collections } from '../database';
import { runSync } from '../database/sync';
import { runSync, watchForUpdates, stopWatchingForUpdates } from '../database/sync';
import { getAuthToken } from '../services/auth';
import { DEFAULT_CATEGORIES } from '../constants';
import Category from '../models/Category';
@@ -41,7 +41,13 @@ export function DatabaseProvider({ children }: { children: ReactNode }) {
const token = await getAuthToken();
if (token) {
runSync().catch(() => {});
runSync()
.catch(() => {})
.finally(() => {
watchForUpdates();
});
} else {
stopWatchingForUpdates();
}
} catch (error) {
console.error('Failed to initialize database:', error);
@@ -51,6 +57,9 @@ export function DatabaseProvider({ children }: { children: ReactNode }) {
useEffect(() => {
initializeDatabase();
return () => {
stopWatchingForUpdates();
};
}, []);
return (