Skip to content

Commit

Permalink
Merge pull request #35 from LinwoodDev/feature/notebook
Browse files Browse the repository at this point in the history
Group notes in note books
  • Loading branch information
CodeDoctorDE authored May 11, 2024
2 parents 3c5480f + 00d940d commit ae24cfd
Show file tree
Hide file tree
Showing 61 changed files with 3,358 additions and 2,953 deletions.
5 changes: 3 additions & 2 deletions api/lib/converters/ical.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class ICalConverter {

ICalConverter([this.data]);

void read(List<String> lines, [Event? event]) {
void read(List<String> lines, {Event? event, Notebook? notebook}) {
final offset =
lines.indexWhere((element) => element.trim() == 'BEGIN:VCALENDAR');
if (offset == -1) {
Expand All @@ -19,6 +19,7 @@ class ICalConverter {
Note? currentNote;
final items = List<CalendarItem>.from(data?.items ?? []);
var currentEvent = event ?? Event(id: createUniqueMultihash());
var currentNotebook = notebook ?? Notebook(id: createUniqueMultihash());
final notes = List<Note>.from(data?.notes ?? []);
for (int i = offset; i < lines.length; i++) {
final line = lines[i];
Expand Down Expand Up @@ -73,7 +74,7 @@ class ICalConverter {
eventId: currentEvent.id,
);
} else if (value == 'VTODO') {
currentNote = Note();
currentNote = Note(notebookId: currentNotebook.id!);
}
continue;
case 'END':
Expand Down
5 changes: 5 additions & 0 deletions api/lib/models/cached.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class CachedData with _$CachedData {
const factory CachedData({
DateTime? lastUpdated,
@Default([]) List<Event> events,
@Default([]) List<Notebook> notebooks,
@Default([]) List<CalendarItem> items,
@Default([]) List<Note> notes,
}) = _CachedData;
Expand All @@ -28,6 +29,10 @@ class CachedData with _$CachedData {
...events,
...other.events.where((e) => !events.any((e2) => e2.id == e.id))
],
notebooks: [
...notebooks,
...other.notebooks.where((e) => !notebooks.any((e2) => e2.id == e.id))
],
items: [
...items,
...other.items.where((e) => !items.any((e2) => e2.id == e.id))
Expand Down
32 changes: 31 additions & 1 deletion api/lib/models/cached.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ CachedData _$CachedDataFromJson(Map<String, dynamic> json) {
mixin _$CachedData {
DateTime? get lastUpdated => throw _privateConstructorUsedError;
List<Event> get events => throw _privateConstructorUsedError;
List<Notebook> get notebooks => throw _privateConstructorUsedError;
List<CalendarItem> get items => throw _privateConstructorUsedError;
List<Note> get notes => throw _privateConstructorUsedError;

Expand All @@ -40,6 +41,7 @@ abstract class $CachedDataCopyWith<$Res> {
$Res call(
{DateTime? lastUpdated,
List<Event> events,
List<Notebook> notebooks,
List<CalendarItem> items,
List<Note> notes});
}
Expand All @@ -59,6 +61,7 @@ class _$CachedDataCopyWithImpl<$Res, $Val extends CachedData>
$Res call({
Object? lastUpdated = freezed,
Object? events = null,
Object? notebooks = null,
Object? items = null,
Object? notes = null,
}) {
Expand All @@ -71,6 +74,10 @@ class _$CachedDataCopyWithImpl<$Res, $Val extends CachedData>
? _value.events
: events // ignore: cast_nullable_to_non_nullable
as List<Event>,
notebooks: null == notebooks
? _value.notebooks
: notebooks // ignore: cast_nullable_to_non_nullable
as List<Notebook>,
items: null == items
? _value.items
: items // ignore: cast_nullable_to_non_nullable
Expand All @@ -94,6 +101,7 @@ abstract class _$$CachedDataImplCopyWith<$Res>
$Res call(
{DateTime? lastUpdated,
List<Event> events,
List<Notebook> notebooks,
List<CalendarItem> items,
List<Note> notes});
}
Expand All @@ -111,6 +119,7 @@ class __$$CachedDataImplCopyWithImpl<$Res>
$Res call({
Object? lastUpdated = freezed,
Object? events = null,
Object? notebooks = null,
Object? items = null,
Object? notes = null,
}) {
Expand All @@ -123,6 +132,10 @@ class __$$CachedDataImplCopyWithImpl<$Res>
? _value._events
: events // ignore: cast_nullable_to_non_nullable
as List<Event>,
notebooks: null == notebooks
? _value._notebooks
: notebooks // ignore: cast_nullable_to_non_nullable
as List<Notebook>,
items: null == items
? _value._items
: items // ignore: cast_nullable_to_non_nullable
Expand All @@ -141,9 +154,11 @@ class _$CachedDataImpl extends _CachedData {
const _$CachedDataImpl(
{this.lastUpdated,
final List<Event> events = const [],
final List<Notebook> notebooks = const [],
final List<CalendarItem> items = const [],
final List<Note> notes = const []})
: _events = events,
_notebooks = notebooks,
_items = items,
_notes = notes,
super._();
Expand All @@ -162,6 +177,15 @@ class _$CachedDataImpl extends _CachedData {
return EqualUnmodifiableListView(_events);
}

final List<Notebook> _notebooks;
@override
@JsonKey()
List<Notebook> get notebooks {
if (_notebooks is EqualUnmodifiableListView) return _notebooks;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_notebooks);
}

final List<CalendarItem> _items;
@override
@JsonKey()
Expand All @@ -182,7 +206,7 @@ class _$CachedDataImpl extends _CachedData {

@override
String toString() {
return 'CachedData(lastUpdated: $lastUpdated, events: $events, items: $items, notes: $notes)';
return 'CachedData(lastUpdated: $lastUpdated, events: $events, notebooks: $notebooks, items: $items, notes: $notes)';
}

@override
Expand All @@ -193,6 +217,8 @@ class _$CachedDataImpl extends _CachedData {
(identical(other.lastUpdated, lastUpdated) ||
other.lastUpdated == lastUpdated) &&
const DeepCollectionEquality().equals(other._events, _events) &&
const DeepCollectionEquality()
.equals(other._notebooks, _notebooks) &&
const DeepCollectionEquality().equals(other._items, _items) &&
const DeepCollectionEquality().equals(other._notes, _notes));
}
Expand All @@ -203,6 +229,7 @@ class _$CachedDataImpl extends _CachedData {
runtimeType,
lastUpdated,
const DeepCollectionEquality().hash(_events),
const DeepCollectionEquality().hash(_notebooks),
const DeepCollectionEquality().hash(_items),
const DeepCollectionEquality().hash(_notes));

Expand All @@ -224,6 +251,7 @@ abstract class _CachedData extends CachedData {
const factory _CachedData(
{final DateTime? lastUpdated,
final List<Event> events,
final List<Notebook> notebooks,
final List<CalendarItem> items,
final List<Note> notes}) = _$CachedDataImpl;
const _CachedData._() : super._();
Expand All @@ -236,6 +264,8 @@ abstract class _CachedData extends CachedData {
@override
List<Event> get events;
@override
List<Notebook> get notebooks;
@override
List<CalendarItem> get items;
@override
List<Note> get notes;
Expand Down
5 changes: 5 additions & 0 deletions api/lib/models/cached.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 47 additions & 63 deletions api/lib/models/event/item/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class CalendarItemDatabaseService extends CalendarItemService
description TEXT NOT NULL DEFAULT '',
location VARCHAR(100) NOT NULL DEFAULT '',
eventId BLOB(16),
groupId BLOB(16),
placeId BLOB(16),
start INTEGER,
end INTEGER,
status VARCHAR(20) NOT NULL DEFAULT 'confirmed',
Expand All @@ -42,7 +44,14 @@ class CalendarItemDatabaseService extends CalendarItemService
}

@override
FutureOr<void> migrate(Database db, int version) {}
Future<void> migrate(Database db, int version) async {
if (version < 3) {
await db.transaction((txn) async {
await txn.execute("ALTER TABLE calendarItems ADD groupId BLOB(16)");
await txn.execute("ALTER TABLE calendarItems ADD placeId BLOB(16)");
});
}
}

@override
Future<List<ConnectedModel<CalendarItem, Event?>>> getCalendarItems(
Expand All @@ -65,15 +74,11 @@ class CalendarItemDatabaseService extends CalendarItemService
}
if (start != null) {
where = where == null ? 'start >= ?' : '$where AND start >= ?';
whereArgs = whereArgs == null
? [start.secondsSinceEpoch]
: [...whereArgs, start.secondsSinceEpoch];
whereArgs = [...?whereArgs, start.secondsSinceEpoch];
}
if (end != null) {
where = where == null ? 'end <= ?' : '$where AND end <= ?';
whereArgs = whereArgs == null
? [end.secondsSinceEpoch]
: [...whereArgs, end.secondsSinceEpoch];
whereArgs = [...?whereArgs, end.secondsSinceEpoch];
}
if (date != null) {
var startCalendarItem = date.onlyDate();
Expand All @@ -82,24 +87,15 @@ class CalendarItemDatabaseService extends CalendarItemService
where = where == null
? '(start BETWEEN ? AND ? OR end BETWEEN ? AND ? OR (start <= ? AND end >= ?))'
: '$where AND (start BETWEEN ? AND ? OR end BETWEEN ? AND ? OR (start <= ? AND end >= ?))';
whereArgs = whereArgs == null
? [
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
]
: [
...whereArgs,
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
];
whereArgs = [
...?whereArgs,
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
startCalendarItem.secondsSinceEpoch,
endCalendarItem.secondsSinceEpoch,
];
}
if (pending) {
where = where == null
Expand All @@ -110,61 +106,49 @@ class CalendarItemDatabaseService extends CalendarItemService
where = where == null
? '(name LIKE ? OR description LIKE ?)'
: '$where AND (name LIKE ? OR description LIKE ?)';
whereArgs = whereArgs == null
? ['%$search%', '%$search%']
: [...whereArgs, '%$search%', '%$search%'];
whereArgs = [...?whereArgs, '%$search%', '%$search%'];
}
if (groupId != null) {
where = where == null ? 'groupId = ?' : '$where AND groupId = ?';
whereArgs = whereArgs == null
? [groupId.fullBytes]
: [...whereArgs, groupId.fullBytes];
final statement = "(groupId = ? OR events.groupId = ?)";
where = where == null ? statement : '$where AND $statement';
whereArgs = [...?whereArgs, groupId.fullBytes, groupId.fullBytes];
}
if (placeId != null) {
where = where == null ? 'placeId = ?' : '$where AND placeId = ?';
whereArgs = whereArgs == null
? [placeId.fullBytes]
: [...whereArgs, placeId.fullBytes];
final statement = "(placeId = ? OR events.placeId = ?)";
where = where == null ? statement : '$where AND $statement';
whereArgs = [...?whereArgs, placeId.fullBytes, placeId.fullBytes];
}
if (eventId != null) {
where = where == null ? 'eventId = ?' : '$where AND eventId = ?';
whereArgs = whereArgs == null
? [eventId.fullBytes]
: [...whereArgs, eventId.fullBytes];
whereArgs = [...?whereArgs, eventId.fullBytes];
}
const eventPrefix = "event_";
final result = await db?.query(
"calendarItems LEFT JOIN events ON events.id = calendarItems.eventId",
columns: [
"events.*",
"calendarItems.runtimeType AS calendarItemruntimeType",
"calendarItems.id AS calendarItemid",
"calendarItems.name AS calendarItemname",
"calendarItems.description AS calendarItemdescription",
"calendarItems.location AS calendarItemlocation",
"calendarItems.eventId AS calendarItemeventId",
"calendarItems.start AS calendarItemstart",
"calendarItems.end AS calendarItemend",
"calendarItems.status AS calendarItemstatus",
"calendarItems.repeatType AS calendarItemrepeatType",
"calendarItems.interval AS calendarIteminterval",
"calendarItems.variation AS calendarItemvariation",
"calendarItems.count AS calendarItemcount",
"calendarItems.until AS calendarItemuntil",
"calendarItems.exceptions AS calendarItemexceptions",
"calendarItems.autoGroupId AS calendarItemautoGroupId",
"calendarItems.searchStart AS calendarItemsearchStart",
"calendarItems.autoDuration AS calendarItemautoDuration",
"events.id AS ${eventPrefix}id",
"events.parentId AS ${eventPrefix}parentId",
"events.groupId AS ${eventPrefix}groupId",
"events.placeId AS ${eventPrefix}placeId",
"events.blocked AS ${eventPrefix}blocked",
"events.name AS ${eventPrefix}name",
"events.description AS ${eventPrefix}description",
"events.location AS ${eventPrefix}location",
"events.extra AS ${eventPrefix}extra",
"calendarItems.*",
],
where: where,
whereArgs: whereArgs,
);
return result?.map((e) {
return ConnectedModel<CalendarItem, Event?>(
CalendarItem.fromDatabase(Map.fromEntries(e.entries
.where((element) => element.key.startsWith('calendarItem'))
.map((e) => MapEntry(
e.key.substring("calendarItem".length), e.value)))),
e['id'] == null ? null : Event.fromDatabase(e),
CalendarItem.fromDatabase(e),
e['${eventPrefix}id'] == null
? null
: Event.fromDatabase(Map.fromEntries(e.entries
.where((element) => element.key.startsWith(eventPrefix))
.map((e) => MapEntry(
e.key.substring(eventPrefix.length), e.value)))),
);
}).toList() ??
[];
Expand Down
9 changes: 8 additions & 1 deletion api/lib/models/event/item/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ part 'model.g.dart';
enum CalendarItemType { appointment, moment, pending }

@freezed
class CalendarItem with _$CalendarItem implements DescriptiveModel {
class CalendarItem
with _$CalendarItem, IdentifiedModel, NamedModel, DescriptiveModel {
const CalendarItem._();

const factory CalendarItem.fixed({
@MultihashConverter() Multihash? id,
@Default('') String name,
@Default('') String description,
@Default('') String location,
@MultihashConverter() Multihash? groupId,
@MultihashConverter() Multihash? placeId,
@MultihashConverter() Multihash? eventId,
@Default(EventStatus.confirmed) EventStatus status,
@DateTimeConverter() DateTime? start,
Expand All @@ -30,6 +33,8 @@ class CalendarItem with _$CalendarItem implements DescriptiveModel {
@Default('') String name,
@Default('') String description,
@Default('') String location,
@MultihashConverter() Multihash? groupId,
@MultihashConverter() Multihash? placeId,
@MultihashConverter() Multihash? eventId,
@Default(EventStatus.confirmed) EventStatus status,
@DateTimeConverter() DateTime? start,
Expand All @@ -47,6 +52,8 @@ class CalendarItem with _$CalendarItem implements DescriptiveModel {
@Default('') String name,
@Default('') String description,
@Default('') String location,
@MultihashConverter() Multihash? groupId,
@MultihashConverter() Multihash? placeId,
@MultihashConverter() Multihash? eventId,
@Default(EventStatus.confirmed) EventStatus status,
@DateTimeConverter() DateTime? start,
Expand Down
Loading

0 comments on commit ae24cfd

Please sign in to comment.