bugfixes & improvements

This commit is contained in:
Myzel394 2022-08-17 13:09:50 +02:00
parent 5670de4b68
commit 4f9ea307b0
8 changed files with 13 additions and 197 deletions

View File

@ -41,6 +41,7 @@
"memoryViewIsDownloading": "Erinnerung wird heruntergeladen",
"memoryViewDownloadFailed": "Erinnerung konnte nicht geladen werden.",
"memorySheetSavedToGallery": "In Gallerie gespeichert!",

View File

@ -41,6 +41,7 @@
"memoryViewIsDownloading": "Downloading memory",
"memoryViewDownloadFailed": "Memory could not be loaded.",
"memorySheetSavedToGallery": "Saved to Gallery!",

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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() {

View File

@ -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),

View File

@ -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,
),

View File

@ -41,9 +41,11 @@ class _TodayPhotoButtonState extends State<TodayPhotoButton> {
@override
void dispose() {
try {
final memories = context.read<Memories>();
memories.removeListener(loadMemory);
} catch (_) {}
super.dispose();
}