Skip to content

Commit

Permalink
Fix duplicate items when importing backup
Browse files Browse the repository at this point in the history
  • Loading branch information
AhsanSarwar45 committed Sep 21, 2024
1 parent 756e50c commit 662c329
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 40 deletions.
4 changes: 4 additions & 0 deletions lib/alarm/types/alarm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -450,4 +450,8 @@ class Alarm extends CustomizableListItem {
'settings': _settings.valueToJson(),
'skippedTime': _skippedTime?.millisecondsSinceEpoch,
};

bool isEqualTo(Alarm other) {
return _time == other._time && _settings.isEqualTo(other._settings);
}
}
6 changes: 6 additions & 0 deletions lib/common/types/tag.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@ class Tag extends ListItem {
description = other.description;
color = other.color;
}

bool isEqualTo(Tag other) {
return name == other.name &&
description == other.description &&
color == other.color;
}
}
14 changes: 14 additions & 0 deletions lib/common/types/time.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,18 @@ class Time extends JsonSerializable {
return time >= startTime || time <= endTime;
}
}

@override
bool operator ==(Object other) {
if (other is Time) {
return hour == other.hour &&
minute == other.minute &&
second == other.second;
}
return false;
}

@override
int get hashCode => Object.hash(hour, minute, second);

}
70 changes: 43 additions & 27 deletions lib/settings/data/backup_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:clock_app/alarm/logic/update_alarms.dart';
import 'package:clock_app/alarm/types/alarm.dart';
import 'package:clock_app/app.dart';
import 'package:clock_app/clock/types/city.dart';
import 'package:clock_app/common/types/tag.dart';
import 'package:clock_app/common/utils/json_serialize.dart';
import 'package:clock_app/common/utils/list_storage.dart';
import 'package:clock_app/settings/data/settings_schema.dart';
Expand All @@ -27,11 +28,13 @@ final backupOptions = [
return await loadTextFile("tags");
},
decode: (context, value) async {
await saveList<TimerPreset>("tags", [
...listFromString<TimerPreset>(value)
.map((tag) => TimerPreset.from(tag)),
...await loadList<TimerPreset>("tags")
]);
final existingItems = await loadList<Tag>("tags");
final itemsToAdd = listFromString<Tag>(value)
.where((tag) =>
!existingItems.any((existingTag) => existingTag.isEqualTo(tag)))
.map((tag) => Tag.from(tag));

await saveList<Tag>("tags", [...itemsToAdd, ...existingItems]);
},
),
BackupOption(
Expand All @@ -45,10 +48,15 @@ final backupOptions = [
return listToString(customColorSchemes);
},
decode: (context, value) async {
final existingItems = await loadList<ColorSchemeData>("color_schemes");
final itemsToAdd = listFromString<ColorSchemeData>(value)
.where((colorScheme) => !existingItems.any((existingColorScheme) =>
existingColorScheme.isEqualTo(colorScheme)))
.map((scheme) => ColorSchemeData.from(scheme));

await saveList<ColorSchemeData>("color_schemes", [
...listFromString<ColorSchemeData>(value)
.map((scheme) => ColorSchemeData.from(scheme)),
...await loadList<ColorSchemeData>("color_schemes")
...itemsToAdd,
...existingItems,
]);
if (context.mounted) App.refreshTheme(context);
},
Expand All @@ -63,11 +71,13 @@ final backupOptions = [
return listToString(customThemes);
},
decode: (context, value) async {
await saveList<StyleTheme>("style_themes", [
...listFromString<StyleTheme>(value)
.map((theme) => StyleTheme.from(theme)),
...await loadList<StyleTheme>("style_themes")
]);
final existingItems = await loadList<StyleTheme>("style_themes");
final itemsToAdd = listFromString<StyleTheme>(value)
.where((theme) => !existingItems
.any((existingTheme) => existingTheme.isEqualTo(theme)))
.map((theme) => StyleTheme.from(theme));
await saveList<StyleTheme>(
"style_themes", [...itemsToAdd, ...existingItems]);
if (context.mounted) App.refreshTheme(context);
},
),
Expand All @@ -94,10 +104,12 @@ final backupOptions = [
return await loadTextFile("alarms");
},
decode: (context, value) async {
await saveList<Alarm>("alarms", [
...listFromString<Alarm>(value).map((alarm) => Alarm.fromAlarm(alarm)),
...await loadList<Alarm>("alarms")
]);
final existingItems = await loadList<Alarm>("alarms");
final itemsToAdd = listFromString<Alarm>(value)
.where((alarm) => !existingItems
.any((existingAlarm) => existingAlarm.isEqualTo(alarm)))
.map((alarm) => Alarm.fromAlarm(alarm));
await saveList<Alarm>("alarms", [...itemsToAdd, ...existingItems]);
await updateAlarms("Updated alarms on importing backup");
},
),
Expand All @@ -108,11 +120,12 @@ final backupOptions = [
return await loadTextFile("timers");
},
decode: (context, value) async {
await saveList<ClockTimer>("timers", [
...listFromString<ClockTimer>(value)
.map((timer) => ClockTimer.from(timer)),
...await loadList<ClockTimer>("timers")
]);
final existingItems = await loadList<ClockTimer>("timers");
final itemsToAdd = listFromString<ClockTimer>(value)
.where((timer) => !existingItems
.any((existingTimer) => existingTimer.isEqualTo(timer)))
.map((timer) => ClockTimer.from(timer));
await saveList<ClockTimer>("timers", [...itemsToAdd, ...existingItems]);
await updateTimers("Updated timers on importing backup");
},
),
Expand Down Expand Up @@ -151,11 +164,14 @@ final backupOptions = [
return await loadTextFile("timer_presets");
},
decode: (context, value) async {
await saveList<TimerPreset>("timer_presets", [
...listFromString<TimerPreset>(value)
.map((preset) => TimerPreset.from(preset)),
...await loadList<TimerPreset>("timer_presets")
]);
final existingItems = await loadList<TimerPreset>("timer_presets");
final itemsToAdd = listFromString<TimerPreset>(value)
.where((preset) => !existingItems
.any((existingPreset) => existingPreset.isEqualTo(preset)))
.map((preset) => TimerPreset.from(preset));

await saveList<TimerPreset>(
"timer_presets", [...itemsToAdd, ...existingItems]);
},
),
];
7 changes: 2 additions & 5 deletions lib/settings/types/setting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ abstract class Setting<T> extends SettingItem {
}
}

class CustomizableListSetting<T extends CustomizableListItem> extends Setting<List<T>> {
class CustomizableListSetting<T extends CustomizableListItem>
extends Setting<List<T>> {
List<T> possibleItems;
Widget Function(T item, [VoidCallback?, VoidCallback?]) cardBuilder;
Widget Function(T item) addCardBuilder;
Expand Down Expand Up @@ -198,8 +199,6 @@ class ListSetting<T extends ListItem> extends Setting<List<T>> {
);
}



Widget getItemAddCard(T item) {
return addCardBuilder(item);
}
Expand All @@ -209,7 +208,6 @@ class ListSetting<T extends ListItem> extends Setting<List<T>> {
return cardBuilder(item, onDelete, onDuplicate);
}


@override
dynamic valueToJson() {
return _value.map((e) => e.toJson()).toList();
Expand All @@ -222,7 +220,6 @@ class ListSetting<T extends ListItem> extends Setting<List<T>> {
}
}


class CustomSetting<T extends JsonSerializable> extends Setting<T> {
// The screen that will be navigated to when this setting is tapped.
Widget Function(BuildContext, CustomSetting<T>) screenBuilder;
Expand Down
4 changes: 4 additions & 0 deletions lib/settings/types/setting_group.dart
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ class SettingGroup extends SettingItem {
}
}

bool isEqualTo(SettingGroup other) {
return json.encode(valueToJson()) == json.encode(other.valueToJson());
}

@override
dynamic valueToJson() {
Json json = {};
Expand Down
10 changes: 4 additions & 6 deletions lib/settings/types/setting_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ abstract class SettingItem {
// Settings which influence whether this setting is enabled
List<EnableConditionEvaluator> enableSettings;

String displayName(BuildContext context) =>
getLocalizedName(context);
String displayName(BuildContext context) => getLocalizedName(context);

String displayDescription(BuildContext context) =>
getDescription(context);
String displayDescription(BuildContext context) => getDescription(context);

bool get isEnabled {
for (var enableSetting in enableSettings) {
Expand Down Expand Up @@ -48,8 +46,8 @@ abstract class SettingItem {
return path.reversed.toList();
}

SettingItem(
this.name, this.getLocalizedName, this.getDescription, this.searchTags, this.enableConditions )
SettingItem(this.name, this.getLocalizedName, this.getDescription,
this.searchTags, this.enableConditions)
: id = name,
_settingListeners = [],
enableSettings = [];
Expand Down
16 changes: 16 additions & 0 deletions lib/theme/types/color_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,22 @@ class ColorSchemeData extends ThemeItem {

ColorSchemeData.fromJson(Json json)
: super.fromJson(json, colorSchemeSettingsSchema.copy());

bool isEqualTo(ColorSchemeData other) {
return background == other.background &&
error == other.error &&
accent == other.accent &&
onError == other.onError &&
card == other.card &&
onCard == other.onCard &&
onAccent == other.onAccent &&
onBackground == other.onBackground &&
shadow == other.shadow &&
outline == other.outline &&
useAccentAsShadow == other.useAccentAsShadow &&
useAccentAsOutline == other.useAccentAsOutline &&
name == other.name;
}
}

ColorScheme getColorScheme(ColorSchemeData colorSchemeData) {
Expand Down
12 changes: 11 additions & 1 deletion lib/theme/types/style_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class StyleTheme extends ThemeItem {
.setValueWithoutNotify(borderWidth);
}

StyleTheme.from(StyleTheme colorSchemeData) : super.from(colorSchemeData);
StyleTheme.from(StyleTheme super.colorSchemeData) : super.from();

@override
String get name => settings.getSetting("Name").value;
Expand All @@ -65,4 +65,14 @@ class StyleTheme extends ThemeItem {

StyleTheme.fromJson(Json json)
: super.fromJson(json, styleThemeSettingsSchema.copy());

bool isEqualTo(StyleTheme other) {
return name == other.name &&
shadowElevation == other.shadowElevation &&
shadowOpacity == other.shadowOpacity &&
shadowBlurRadius == other.shadowBlurRadius &&
shadowSpreadRadius == other.shadowSpreadRadius &&
borderRadius == other.borderRadius &&
borderWidth == other.borderWidth;
}
}
14 changes: 14 additions & 0 deletions lib/timer/types/time_duration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,18 @@ class TimeDuration extends JsonSerializable {
minutes = json != null ? json['minutes'] ?? 0 : 0,
seconds = json != null ? json['seconds'] ?? 0 : 0,
milliseconds = json != null ? json['milliseconds'] ?? 0 : 0;

@override
bool operator ==(Object other) {
if (other is TimeDuration) {
return hours == other.hours &&
minutes == other.minutes &&
seconds == other.seconds &&
milliseconds == other.milliseconds;
}
return false;
}

@override
int get hashCode => Object.hash(hours, minutes, seconds, milliseconds);
}
6 changes: 5 additions & 1 deletion lib/timer/types/timer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class ClockTimer extends CustomizableListItem {
}

Future<void> snooze() async {
TimeDuration addedDuration = TimeDuration(minutes: addLength.floor());
TimeDuration addedDuration = TimeDuration(minutes: addLength.floor());
_currentDuration = addedDuration;
_milliSecondsRemainingOnPause = addedDuration.inSeconds * 1000;
await start();
Expand Down Expand Up @@ -262,4 +262,8 @@ class ClockTimer extends CustomizableListItem {
copy() {
return ClockTimer.from(this);
}

bool isEqualTo(ClockTimer other) {
return _duration == other._duration && _settings.isEqualTo(other._settings);
}
}
5 changes: 5 additions & 0 deletions lib/timer/types/timer_preset.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:clock_app/common/types/json.dart';
import 'package:clock_app/common/types/list_item.dart';
import 'package:clock_app/common/utils/id.dart';
import 'package:clock_app/developer/logic/logger.dart';
import 'package:clock_app/timer/types/time_duration.dart';

class TimerPreset extends ListItem {
Expand Down Expand Up @@ -45,6 +46,10 @@ class TimerPreset extends ListItem {
}
}

bool isEqualTo(TimerPreset other) {
return name == other.name && duration == other.duration;
}

@override
copy() {
return TimerPreset(name, duration);
Expand Down

0 comments on commit 662c329

Please sign in to comment.