mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-19 07:35:26 +02:00
bugfixes & improvements
This commit is contained in:
parent
5670de4b68
commit
4f9ea307b0
@ -41,6 +41,7 @@
|
||||
|
||||
|
||||
"memoryViewIsDownloading": "Erinnerung wird heruntergeladen",
|
||||
"memoryViewDownloadFailed": "Erinnerung konnte nicht geladen werden.",
|
||||
|
||||
|
||||
"memorySheetSavedToGallery": "In Gallerie gespeichert!",
|
||||
|
@ -33,7 +33,7 @@
|
||||
"grantPermissionScreenTitle": "Grant Permissions",
|
||||
|
||||
"permissionsRequiredPageTitle": "Permissions Required",
|
||||
"permissionsRequiredPageDescription": "Please grant the following permissions to use this app.",
|
||||
"permissionsRequiredPageDescription": "Please grant the following permissions to use this app.",
|
||||
"permissionsRequiredPagePermanentlyDenied": "You have permanently denied permissions required to use this app. Please enable them in the settings.",
|
||||
"permissionsRequiredPageOpenSettings": "Open Settings",
|
||||
"permissionsRequiredPageGrantCameraPermission": "Grant camera permission",
|
||||
@ -41,6 +41,7 @@
|
||||
|
||||
|
||||
"memoryViewIsDownloading": "Downloading memory",
|
||||
"memoryViewDownloadFailed": "Memory could not be loaded.",
|
||||
|
||||
|
||||
"memorySheetSavedToGallery": "Saved to Gallery!",
|
||||
|
@ -1,158 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:quid_faciam_hodie/foreign_types/memory.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
|
||||
final supabase = Supabase.instance.client;
|
||||
|
||||
class CalendarModel extends ChangeNotifier {
|
||||
// Maps each day to an amount of memories on that day.
|
||||
// To remove days later we only store the IDs of the memories.
|
||||
final Map<String, Set<String>> _values = {};
|
||||
bool _isInitializing = true;
|
||||
|
||||
RealtimeSubscription? _serverSubscription;
|
||||
|
||||
bool get isInitializing => _isInitializing;
|
||||
|
||||
CalendarModel();
|
||||
|
||||
static String formatCreationDateKey(final DateTime date) =>
|
||||
DateFormat('yyyy-MM-dd').format(date);
|
||||
|
||||
static Map<String, Set<String>> mapFromMemoriesList(
|
||||
final List<Memory> memories) {
|
||||
final map = <String, Set<String>>{};
|
||||
|
||||
for (final memory in memories) {
|
||||
final key = formatCreationDateKey(memory.creationDate);
|
||||
|
||||
if (map.containsKey(key)) {
|
||||
map[key]!.add(memory.id);
|
||||
} else {
|
||||
map[key] = {
|
||||
memory.id,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_serverSubscription?.unsubscribe(timeout: Duration.zero);
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void setIsInitializing(final bool value) {
|
||||
_isInitializing = value;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> _loadInitialData() async {
|
||||
final response = await supabase
|
||||
.from('memories')
|
||||
.select()
|
||||
.order('created_at', ascending: false)
|
||||
.execute();
|
||||
final newMemories = List<Memory>.from(
|
||||
List<Map<String, dynamic>>.from(response.data).map(Memory.parse),
|
||||
);
|
||||
|
||||
_values.addAll(mapFromMemoriesList(newMemories));
|
||||
}
|
||||
|
||||
void _removeEmptyDates() {
|
||||
_values.removeWhere((key, value) => value.isEmpty);
|
||||
}
|
||||
|
||||
void _addMemory(final Memory memory) {
|
||||
final key = formatCreationDateKey(memory.creationDate);
|
||||
|
||||
if (_values.containsKey(key)) {
|
||||
_values[key]!.add(memory.id);
|
||||
} else {
|
||||
_values[key] = {
|
||||
memory.id,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void _removeMemory(final String id) {
|
||||
// Search for the id and remove it
|
||||
for (final memories in _values.values) {
|
||||
memories.remove(id);
|
||||
}
|
||||
|
||||
_removeEmptyDates();
|
||||
}
|
||||
|
||||
Future<void> _onServerUpdate(
|
||||
final SupabaseRealtimePayload response,
|
||||
) async {
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (response.eventType) {
|
||||
case 'INSERT':
|
||||
final memory = Memory.parse(response.newRecord!);
|
||||
|
||||
_addMemory(memory);
|
||||
|
||||
break;
|
||||
case 'DELETE':
|
||||
final id = response.oldRecord!['id'];
|
||||
|
||||
_removeMemory(id);
|
||||
break;
|
||||
// Used for easier debugging
|
||||
case 'UPDATE':
|
||||
final memory = Memory.parse(response.newRecord!);
|
||||
|
||||
_removeMemory(response.oldRecord!['id']);
|
||||
_addMemory(memory);
|
||||
break;
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> initialize() async {
|
||||
setIsInitializing(true);
|
||||
|
||||
await _loadInitialData();
|
||||
|
||||
setIsInitializing(false);
|
||||
notifyListeners();
|
||||
|
||||
// Watch new updates
|
||||
_serverSubscription = supabase
|
||||
.from('memories')
|
||||
.on(SupabaseEventTypes.all, _onServerUpdate)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
Map<DateTime, Map<DateTime, int>> getMonthDayAmountMapping() {
|
||||
final map = <DateTime, Map<DateTime, int>>{};
|
||||
|
||||
for (final entry in _values.entries) {
|
||||
final key = entry.key;
|
||||
final date = DateTime.parse(key);
|
||||
final monthDate = DateTime(date.year, date.month, 1);
|
||||
final memoryIDs = entry.value;
|
||||
|
||||
if (map.containsKey(monthDate)) {
|
||||
map[monthDate]![date] = memoryIDs.length;
|
||||
} else {
|
||||
map[monthDate] = {
|
||||
date: memoryIDs.length,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import 'package:quid_faciam_hodie/foreign_types/memory.dart';
|
||||
|
||||
class MemoryPack {
|
||||
final List<Memory> _memories;
|
||||
|
||||
const MemoryPack(this._memories);
|
||||
|
||||
List<Memory> get memories => _memories;
|
||||
|
||||
void orderMemories() {
|
||||
_memories.sort((a, b) => b.creationDate.compareTo(a.creationDate));
|
||||
}
|
||||
|
||||
void updateWithNewMemory(final String memoryID, final Memory memory) {
|
||||
final index = _memories.indexWhere((memory) => memory.id == memoryID);
|
||||
|
||||
if (index == -1) {
|
||||
throw Exception('Memory not found');
|
||||
}
|
||||
|
||||
_memories[index] = memory;
|
||||
|
||||
orderMemories();
|
||||
}
|
||||
|
||||
void addMemory(final Memory memory) {
|
||||
_memories.add(memory);
|
||||
orderMemories();
|
||||
}
|
||||
}
|
@ -36,9 +36,9 @@ class TimelineModel extends PropertyChangeNotifier<String> {
|
||||
|
||||
List<Memory> atIndex(final int index) => _timeline.values.elementAt(index);
|
||||
|
||||
List<Memory> get _currentMemoryPack => atIndex(currentIndex);
|
||||
bool get _isAtLastMemory => _memoryIndex == _currentMemoryPack.length - 1;
|
||||
Memory get currentMemory => _currentMemoryPack.elementAt(_memoryIndex);
|
||||
List<Memory> get _currentMemories => atIndex(currentIndex);
|
||||
bool get _isAtLastMemory => _memoryIndex == _currentMemories.length - 1;
|
||||
Memory get currentMemory => _currentMemories.elementAt(_memoryIndex);
|
||||
|
||||
void _removeEmptyDates() {
|
||||
_timeline.removeWhere((key, memories) => memories.isEmpty);
|
||||
@ -129,7 +129,7 @@ class TimelineModel extends PropertyChangeNotifier<String> {
|
||||
}
|
||||
|
||||
setCurrentIndex(currentIndex - 1);
|
||||
setMemoryIndex(_currentMemoryPack.length - 1);
|
||||
setMemoryIndex(_currentMemories.length - 1);
|
||||
}
|
||||
|
||||
void nextMemory() {
|
||||
|
@ -98,7 +98,7 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'Login',
|
||||
localizations.loginScreenTitle,
|
||||
style: theme.textTheme.headline1,
|
||||
),
|
||||
const SizedBox(height: LARGE_SPACE),
|
||||
|
@ -86,7 +86,7 @@ class _MemoryViewState extends State<MemoryView> {
|
||||
if (status == MemoryFetchStatus.error) {
|
||||
return Center(
|
||||
child: Text(
|
||||
'Memory could not be loaded.',
|
||||
localizations.memoryViewDownloadFailed,
|
||||
style: theme.textTheme.bodyText2!.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
|
@ -41,9 +41,11 @@ class _TodayPhotoButtonState extends State<TodayPhotoButton> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
final memories = context.read<Memories>();
|
||||
try {
|
||||
final memories = context.read<Memories>();
|
||||
|
||||
memories.removeListener(loadMemory);
|
||||
memories.removeListener(loadMemory);
|
||||
} catch (_) {}
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user