mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-19 15:45:26 +02:00
bugfixes & improvements
This commit is contained in:
parent
5670de4b68
commit
4f9ea307b0
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
|
|
||||||
"memoryViewIsDownloading": "Erinnerung wird heruntergeladen",
|
"memoryViewIsDownloading": "Erinnerung wird heruntergeladen",
|
||||||
|
"memoryViewDownloadFailed": "Erinnerung konnte nicht geladen werden.",
|
||||||
|
|
||||||
|
|
||||||
"memorySheetSavedToGallery": "In Gallerie gespeichert!",
|
"memorySheetSavedToGallery": "In Gallerie gespeichert!",
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
"grantPermissionScreenTitle": "Grant Permissions",
|
"grantPermissionScreenTitle": "Grant Permissions",
|
||||||
|
|
||||||
"permissionsRequiredPageTitle": "Permissions Required",
|
"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.",
|
"permissionsRequiredPagePermanentlyDenied": "You have permanently denied permissions required to use this app. Please enable them in the settings.",
|
||||||
"permissionsRequiredPageOpenSettings": "Open Settings",
|
"permissionsRequiredPageOpenSettings": "Open Settings",
|
||||||
"permissionsRequiredPageGrantCameraPermission": "Grant camera permission",
|
"permissionsRequiredPageGrantCameraPermission": "Grant camera permission",
|
||||||
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
|
|
||||||
"memoryViewIsDownloading": "Downloading memory",
|
"memoryViewIsDownloading": "Downloading memory",
|
||||||
|
"memoryViewDownloadFailed": "Memory could not be loaded.",
|
||||||
|
|
||||||
|
|
||||||
"memorySheetSavedToGallery": "Saved to Gallery!",
|
"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> atIndex(final int index) => _timeline.values.elementAt(index);
|
||||||
|
|
||||||
List<Memory> get _currentMemoryPack => atIndex(currentIndex);
|
List<Memory> get _currentMemories => atIndex(currentIndex);
|
||||||
bool get _isAtLastMemory => _memoryIndex == _currentMemoryPack.length - 1;
|
bool get _isAtLastMemory => _memoryIndex == _currentMemories.length - 1;
|
||||||
Memory get currentMemory => _currentMemoryPack.elementAt(_memoryIndex);
|
Memory get currentMemory => _currentMemories.elementAt(_memoryIndex);
|
||||||
|
|
||||||
void _removeEmptyDates() {
|
void _removeEmptyDates() {
|
||||||
_timeline.removeWhere((key, memories) => memories.isEmpty);
|
_timeline.removeWhere((key, memories) => memories.isEmpty);
|
||||||
@ -129,7 +129,7 @@ class TimelineModel extends PropertyChangeNotifier<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setCurrentIndex(currentIndex - 1);
|
setCurrentIndex(currentIndex - 1);
|
||||||
setMemoryIndex(_currentMemoryPack.length - 1);
|
setMemoryIndex(_currentMemories.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nextMemory() {
|
void nextMemory() {
|
||||||
|
@ -98,7 +98,7 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
'Login',
|
localizations.loginScreenTitle,
|
||||||
style: theme.textTheme.headline1,
|
style: theme.textTheme.headline1,
|
||||||
),
|
),
|
||||||
const SizedBox(height: LARGE_SPACE),
|
const SizedBox(height: LARGE_SPACE),
|
||||||
|
@ -86,7 +86,7 @@ class _MemoryViewState extends State<MemoryView> {
|
|||||||
if (status == MemoryFetchStatus.error) {
|
if (status == MemoryFetchStatus.error) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Memory could not be loaded.',
|
localizations.memoryViewDownloadFailed,
|
||||||
style: theme.textTheme.bodyText2!.copyWith(
|
style: theme.textTheme.bodyText2!.copyWith(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
|
@ -41,9 +41,11 @@ class _TodayPhotoButtonState extends State<TodayPhotoButton> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
final memories = context.read<Memories>();
|
try {
|
||||||
|
final memories = context.read<Memories>();
|
||||||
|
|
||||||
memories.removeListener(loadMemory);
|
memories.removeListener(loadMemory);
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user