mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-18 15:25:27 +02:00
improvements & bugfixes; added cache manager
This commit is contained in:
parent
4630c6d983
commit
d92451d808
@ -1 +1 @@
|
||||
const STARTUP_PAGE_KEY = 'startup_page';
|
||||
const CACHE_KEY = '_cache';
|
||||
|
@ -7,3 +7,4 @@ const PHOTO_SHOW_AFTER_CREATION_DURATION = Duration(milliseconds: 500);
|
||||
final UnmodifiableSetView<double> DEFAULT_ZOOM_LEVELS =
|
||||
UnmodifiableSetView({0.6, 1, 2, 5, 10, 20, 50, 100});
|
||||
const CALENDAR_DATE_IN_MAX_DELAY = Duration(milliseconds: 500);
|
||||
const CACHE_INVALIDATION_DURATION = Duration(days: 7);
|
||||
|
@ -13,6 +13,7 @@ import 'package:quid_faciam_hodie/screens/server_loading_screen.dart';
|
||||
import 'package:quid_faciam_hodie/screens/settings_screen.dart';
|
||||
import 'package:quid_faciam_hodie/screens/timeline_screen.dart';
|
||||
import 'package:quid_faciam_hodie/screens/welcome_screen.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
import 'managers/global_values_manager.dart';
|
||||
import 'models/memories.dart';
|
||||
@ -43,6 +44,27 @@ class MyApp extends StatefulWidget {
|
||||
class _MyAppState extends State<MyApp> {
|
||||
final memories = Memories();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
watchAuthenticationStatus();
|
||||
}
|
||||
|
||||
Future<void> watchAuthenticationStatus() async {
|
||||
await GlobalValuesManager.waitForServerInitialization();
|
||||
|
||||
Supabase.instance.client.auth.onAuthStateChange((event, session) {
|
||||
switch (event) {
|
||||
case AuthChangeEvent.signedIn:
|
||||
memories.refresh();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider.value(
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
|
||||
import 'package:quid_faciam_hodie/screens/login_screen.dart';
|
||||
import 'package:quid_faciam_hodie/screens/main_screen.dart';
|
||||
import 'package:quid_faciam_hodie/screens/welcome_screen.dart';
|
||||
import 'package:supabase/supabase.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
@ -10,7 +10,7 @@ class AuthState<T extends StatefulWidget> extends SupabaseAuthState<T> {
|
||||
void onUnauthenticated() {
|
||||
if (mounted) {
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(LoginScreen.ID, (route) => false);
|
||||
.pushNamedAndRemoveUntil(WelcomeScreen.ID, (route) => false);
|
||||
}
|
||||
}
|
||||
|
||||
|
55
lib/managers/cache_manager.dart
Normal file
55
lib/managers/cache_manager.dart
Normal file
@ -0,0 +1,55 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:quid_faciam_hodie/constants/storage_keys.dart';
|
||||
import 'package:quid_faciam_hodie/constants/values.dart';
|
||||
|
||||
const storage = FlutterSecureStorage();
|
||||
|
||||
class CacheManager {
|
||||
static _createKey(final String key) => '$CACHE_KEY/$key';
|
||||
|
||||
static Future<bool> isCacheValid(final String key) async {
|
||||
final cacheKey = _createKey(key);
|
||||
final existingEntry = await storage.read(key: cacheKey);
|
||||
|
||||
if (existingEntry != null) {
|
||||
final entry = jsonDecode(existingEntry);
|
||||
final DateTime creationDate = DateTime.parse(entry['creationDate']);
|
||||
|
||||
// Check if the entry is still valid using CACHE_INVALIDATION_DURATION as the validity duration.
|
||||
return DateTime.now().difference(creationDate) <
|
||||
CACHE_INVALIDATION_DURATION;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static Future<void> set(final String key, final String data) async {
|
||||
final cacheKey = _createKey(key);
|
||||
final cacheEntry = {
|
||||
'creationDate': DateTime.now().toIso8601String(),
|
||||
'data': data,
|
||||
};
|
||||
|
||||
return storage.write(
|
||||
key: cacheKey,
|
||||
value: json.encode({
|
||||
key: cacheEntry,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
static Future<String?> get(final String key) async {
|
||||
final cacheKey = _createKey(key);
|
||||
final existingEntry = await storage.read(key: cacheKey);
|
||||
|
||||
if (existingEntry == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final entry = jsonDecode(existingEntry);
|
||||
|
||||
return entry['data'];
|
||||
}
|
||||
}
|
@ -1,20 +1,20 @@
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:quid_faciam_hodie/enums.dart';
|
||||
import 'package:quid_faciam_hodie/foreign_types/memory.dart';
|
||||
import 'package:quid_faciam_hodie/managers/cache_manager.dart';
|
||||
import 'package:quid_faciam_hodie/managers/global_values_manager.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
const uuid = Uuid();
|
||||
const storage = FlutterSecureStorage();
|
||||
|
||||
final supabase = Supabase.instance.client;
|
||||
|
||||
class FileManager {
|
||||
static Map<String, Uint8List> fileCache = {};
|
||||
|
||||
static Future<Memory> getMemoryMetadata(final String id) async {
|
||||
await GlobalValuesManager.waitForServerInitialization();
|
||||
|
||||
@ -56,51 +56,31 @@ class FileManager {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List?> getLastFile(final User user) async {
|
||||
final response = await supabase
|
||||
.from('memories')
|
||||
.select()
|
||||
.eq('user_id', user.id)
|
||||
.order('created_at', ascending: false)
|
||||
.limit(1)
|
||||
.single()
|
||||
.execute();
|
||||
|
||||
if (response.data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final memory = response.data;
|
||||
final location = memory['location'];
|
||||
final memoryType =
|
||||
location.split('.').last == 'jpg' ? MemoryType.photo : MemoryType.video;
|
||||
|
||||
try {
|
||||
final file = await _getFileData('memories', location);
|
||||
|
||||
return [file, memoryType];
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Uint8List> _getFileData(final String table, final String path,
|
||||
{final bool disableCache = false}) async {
|
||||
final key = '$table:$path';
|
||||
|
||||
if (!disableCache && fileCache.containsKey(key)) {
|
||||
return fileCache[key]!;
|
||||
}
|
||||
|
||||
static Future<Uint8List> _downloadFileData(
|
||||
final String table, final String path) async {
|
||||
final response = await supabase.storage.from(table).download(path);
|
||||
|
||||
if (response.error != null) {
|
||||
throw Exception('Error downloading file: ${response.error!.message}');
|
||||
}
|
||||
|
||||
final data = response.data!;
|
||||
return response.data!;
|
||||
}
|
||||
|
||||
fileCache[key] = data;
|
||||
static Future<Uint8List> _getFileData(final String table, final String path,
|
||||
{final bool disableCache = false}) async {
|
||||
final key = '$table:$path';
|
||||
|
||||
// Check cache
|
||||
if (!disableCache && await CacheManager.isCacheValid(key)) {
|
||||
final data = (await CacheManager.get(key))!;
|
||||
return Uint8List.fromList(data.codeUnits);
|
||||
}
|
||||
|
||||
final data = await _downloadFileData(table, path);
|
||||
|
||||
final cacheData = String.fromCharCodes(data);
|
||||
await CacheManager.set(key, cacheData);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -68,6 +68,13 @@ class Memories extends PropertyChangeNotifier<String> {
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
Future<void> refresh() async {
|
||||
memories.clear();
|
||||
_serverSubscription?.unsubscribe();
|
||||
|
||||
setIsInitialized(false);
|
||||
}
|
||||
|
||||
Future<void> _onServerUpdate(
|
||||
final SupabaseRealtimePayload response,
|
||||
) async {
|
||||
|
@ -73,7 +73,6 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
|
||||
message: localizations.loginScreenLoginFailed,
|
||||
);
|
||||
|
||||
emailController.clear();
|
||||
passwordController.clear();
|
||||
}
|
||||
return;
|
||||
|
@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
|
||||
@ -14,6 +15,8 @@ import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
final supabase = Supabase.instance.client;
|
||||
|
||||
const storage = FlutterSecureStorage();
|
||||
|
||||
class SettingsScreen extends StatefulWidget {
|
||||
static const ID = '/settings';
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user