Skip to content

Commit ae24cfd

Browse files
authored
Merge pull request #35 from LinwoodDev/feature/notebook
Group notes in note books
2 parents 3c5480f + 00d940d commit ae24cfd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+3358
-2953
lines changed

api/lib/converters/ical.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class ICalConverter {
99

1010
ICalConverter([this.data]);
1111

12-
void read(List<String> lines, [Event? event]) {
12+
void read(List<String> lines, {Event? event, Notebook? notebook}) {
1313
final offset =
1414
lines.indexWhere((element) => element.trim() == 'BEGIN:VCALENDAR');
1515
if (offset == -1) {
@@ -19,6 +19,7 @@ class ICalConverter {
1919
Note? currentNote;
2020
final items = List<CalendarItem>.from(data?.items ?? []);
2121
var currentEvent = event ?? Event(id: createUniqueMultihash());
22+
var currentNotebook = notebook ?? Notebook(id: createUniqueMultihash());
2223
final notes = List<Note>.from(data?.notes ?? []);
2324
for (int i = offset; i < lines.length; i++) {
2425
final line = lines[i];
@@ -73,7 +74,7 @@ class ICalConverter {
7374
eventId: currentEvent.id,
7475
);
7576
} else if (value == 'VTODO') {
76-
currentNote = Note();
77+
currentNote = Note(notebookId: currentNotebook.id!);
7778
}
7879
continue;
7980
case 'END':

api/lib/models/cached.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class CachedData with _$CachedData {
1414
const factory CachedData({
1515
DateTime? lastUpdated,
1616
@Default([]) List<Event> events,
17+
@Default([]) List<Notebook> notebooks,
1718
@Default([]) List<CalendarItem> items,
1819
@Default([]) List<Note> notes,
1920
}) = _CachedData;
@@ -28,6 +29,10 @@ class CachedData with _$CachedData {
2829
...events,
2930
...other.events.where((e) => !events.any((e2) => e2.id == e.id))
3031
],
32+
notebooks: [
33+
...notebooks,
34+
...other.notebooks.where((e) => !notebooks.any((e2) => e2.id == e.id))
35+
],
3136
items: [
3237
...items,
3338
...other.items.where((e) => !items.any((e2) => e2.id == e.id))

api/lib/models/cached.freezed.dart

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ CachedData _$CachedDataFromJson(Map<String, dynamic> json) {
2222
mixin _$CachedData {
2323
DateTime? get lastUpdated => throw _privateConstructorUsedError;
2424
List<Event> get events => throw _privateConstructorUsedError;
25+
List<Notebook> get notebooks => throw _privateConstructorUsedError;
2526
List<CalendarItem> get items => throw _privateConstructorUsedError;
2627
List<Note> get notes => throw _privateConstructorUsedError;
2728

@@ -40,6 +41,7 @@ abstract class $CachedDataCopyWith<$Res> {
4041
$Res call(
4142
{DateTime? lastUpdated,
4243
List<Event> events,
44+
List<Notebook> notebooks,
4345
List<CalendarItem> items,
4446
List<Note> notes});
4547
}
@@ -59,6 +61,7 @@ class _$CachedDataCopyWithImpl<$Res, $Val extends CachedData>
5961
$Res call({
6062
Object? lastUpdated = freezed,
6163
Object? events = null,
64+
Object? notebooks = null,
6265
Object? items = null,
6366
Object? notes = null,
6467
}) {
@@ -71,6 +74,10 @@ class _$CachedDataCopyWithImpl<$Res, $Val extends CachedData>
7174
? _value.events
7275
: events // ignore: cast_nullable_to_non_nullable
7376
as List<Event>,
77+
notebooks: null == notebooks
78+
? _value.notebooks
79+
: notebooks // ignore: cast_nullable_to_non_nullable
80+
as List<Notebook>,
7481
items: null == items
7582
? _value.items
7683
: items // ignore: cast_nullable_to_non_nullable
@@ -94,6 +101,7 @@ abstract class _$$CachedDataImplCopyWith<$Res>
94101
$Res call(
95102
{DateTime? lastUpdated,
96103
List<Event> events,
104+
List<Notebook> notebooks,
97105
List<CalendarItem> items,
98106
List<Note> notes});
99107
}
@@ -111,6 +119,7 @@ class __$$CachedDataImplCopyWithImpl<$Res>
111119
$Res call({
112120
Object? lastUpdated = freezed,
113121
Object? events = null,
122+
Object? notebooks = null,
114123
Object? items = null,
115124
Object? notes = null,
116125
}) {
@@ -123,6 +132,10 @@ class __$$CachedDataImplCopyWithImpl<$Res>
123132
? _value._events
124133
: events // ignore: cast_nullable_to_non_nullable
125134
as List<Event>,
135+
notebooks: null == notebooks
136+
? _value._notebooks
137+
: notebooks // ignore: cast_nullable_to_non_nullable
138+
as List<Notebook>,
126139
items: null == items
127140
? _value._items
128141
: items // ignore: cast_nullable_to_non_nullable
@@ -141,9 +154,11 @@ class _$CachedDataImpl extends _CachedData {
141154
const _$CachedDataImpl(
142155
{this.lastUpdated,
143156
final List<Event> events = const [],
157+
final List<Notebook> notebooks = const [],
144158
final List<CalendarItem> items = const [],
145159
final List<Note> notes = const []})
146160
: _events = events,
161+
_notebooks = notebooks,
147162
_items = items,
148163
_notes = notes,
149164
super._();
@@ -162,6 +177,15 @@ class _$CachedDataImpl extends _CachedData {
162177
return EqualUnmodifiableListView(_events);
163178
}
164179

180+
final List<Notebook> _notebooks;
181+
@override
182+
@JsonKey()
183+
List<Notebook> get notebooks {
184+
if (_notebooks is EqualUnmodifiableListView) return _notebooks;
185+
// ignore: implicit_dynamic_type
186+
return EqualUnmodifiableListView(_notebooks);
187+
}
188+
165189
final List<CalendarItem> _items;
166190
@override
167191
@JsonKey()
@@ -182,7 +206,7 @@ class _$CachedDataImpl extends _CachedData {
182206

183207
@override
184208
String toString() {
185-
return 'CachedData(lastUpdated: $lastUpdated, events: $events, items: $items, notes: $notes)';
209+
return 'CachedData(lastUpdated: $lastUpdated, events: $events, notebooks: $notebooks, items: $items, notes: $notes)';
186210
}
187211

188212
@override
@@ -193,6 +217,8 @@ class _$CachedDataImpl extends _CachedData {
193217
(identical(other.lastUpdated, lastUpdated) ||
194218
other.lastUpdated == lastUpdated) &&
195219
const DeepCollectionEquality().equals(other._events, _events) &&
220+
const DeepCollectionEquality()
221+
.equals(other._notebooks, _notebooks) &&
196222
const DeepCollectionEquality().equals(other._items, _items) &&
197223
const DeepCollectionEquality().equals(other._notes, _notes));
198224
}
@@ -203,6 +229,7 @@ class _$CachedDataImpl extends _CachedData {
203229
runtimeType,
204230
lastUpdated,
205231
const DeepCollectionEquality().hash(_events),
232+
const DeepCollectionEquality().hash(_notebooks),
206233
const DeepCollectionEquality().hash(_items),
207234
const DeepCollectionEquality().hash(_notes));
208235

@@ -224,6 +251,7 @@ abstract class _CachedData extends CachedData {
224251
const factory _CachedData(
225252
{final DateTime? lastUpdated,
226253
final List<Event> events,
254+
final List<Notebook> notebooks,
227255
final List<CalendarItem> items,
228256
final List<Note> notes}) = _$CachedDataImpl;
229257
const _CachedData._() : super._();
@@ -236,6 +264,8 @@ abstract class _CachedData extends CachedData {
236264
@override
237265
List<Event> get events;
238266
@override
267+
List<Notebook> get notebooks;
268+
@override
239269
List<CalendarItem> get items;
240270
@override
241271
List<Note> get notes;

api/lib/models/cached.g.dart

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/lib/models/event/item/database.dart

Lines changed: 47 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class CalendarItemDatabaseService extends CalendarItemService
2424
description TEXT NOT NULL DEFAULT '',
2525
location VARCHAR(100) NOT NULL DEFAULT '',
2626
eventId BLOB(16),
27+
groupId BLOB(16),
28+
placeId BLOB(16),
2729
start INTEGER,
2830
end INTEGER,
2931
status VARCHAR(20) NOT NULL DEFAULT 'confirmed',
@@ -42,7 +44,14 @@ class CalendarItemDatabaseService extends CalendarItemService
4244
}
4345

4446
@override
45-
FutureOr<void> migrate(Database db, int version) {}
47+
Future<void> migrate(Database db, int version) async {
48+
if (version < 3) {
49+
await db.transaction((txn) async {
50+
await txn.execute("ALTER TABLE calendarItems ADD groupId BLOB(16)");
51+
await txn.execute("ALTER TABLE calendarItems ADD placeId BLOB(16)");
52+
});
53+
}
54+
}
4655

4756
@override
4857
Future<List<ConnectedModel<CalendarItem, Event?>>> getCalendarItems(
@@ -65,15 +74,11 @@ class CalendarItemDatabaseService extends CalendarItemService
6574
}
6675
if (start != null) {
6776
where = where == null ? 'start >= ?' : '$where AND start >= ?';
68-
whereArgs = whereArgs == null
69-
? [start.secondsSinceEpoch]
70-
: [...whereArgs, start.secondsSinceEpoch];
77+
whereArgs = [...?whereArgs, start.secondsSinceEpoch];
7178
}
7279
if (end != null) {
7380
where = where == null ? 'end <= ?' : '$where AND end <= ?';
74-
whereArgs = whereArgs == null
75-
? [end.secondsSinceEpoch]
76-
: [...whereArgs, end.secondsSinceEpoch];
81+
whereArgs = [...?whereArgs, end.secondsSinceEpoch];
7782
}
7883
if (date != null) {
7984
var startCalendarItem = date.onlyDate();
@@ -82,24 +87,15 @@ class CalendarItemDatabaseService extends CalendarItemService
8287
where = where == null
8388
? '(start BETWEEN ? AND ? OR end BETWEEN ? AND ? OR (start <= ? AND end >= ?))'
8489
: '$where AND (start BETWEEN ? AND ? OR end BETWEEN ? AND ? OR (start <= ? AND end >= ?))';
85-
whereArgs = whereArgs == null
86-
? [
87-
startCalendarItem.secondsSinceEpoch,
88-
endCalendarItem.secondsSinceEpoch,
89-
startCalendarItem.secondsSinceEpoch,
90-
endCalendarItem.secondsSinceEpoch,
91-
startCalendarItem.secondsSinceEpoch,
92-
endCalendarItem.secondsSinceEpoch,
93-
]
94-
: [
95-
...whereArgs,
96-
startCalendarItem.secondsSinceEpoch,
97-
endCalendarItem.secondsSinceEpoch,
98-
startCalendarItem.secondsSinceEpoch,
99-
endCalendarItem.secondsSinceEpoch,
100-
startCalendarItem.secondsSinceEpoch,
101-
endCalendarItem.secondsSinceEpoch,
102-
];
90+
whereArgs = [
91+
...?whereArgs,
92+
startCalendarItem.secondsSinceEpoch,
93+
endCalendarItem.secondsSinceEpoch,
94+
startCalendarItem.secondsSinceEpoch,
95+
endCalendarItem.secondsSinceEpoch,
96+
startCalendarItem.secondsSinceEpoch,
97+
endCalendarItem.secondsSinceEpoch,
98+
];
10399
}
104100
if (pending) {
105101
where = where == null
@@ -110,61 +106,49 @@ class CalendarItemDatabaseService extends CalendarItemService
110106
where = where == null
111107
? '(name LIKE ? OR description LIKE ?)'
112108
: '$where AND (name LIKE ? OR description LIKE ?)';
113-
whereArgs = whereArgs == null
114-
? ['%$search%', '%$search%']
115-
: [...whereArgs, '%$search%', '%$search%'];
109+
whereArgs = [...?whereArgs, '%$search%', '%$search%'];
116110
}
117111
if (groupId != null) {
118-
where = where == null ? 'groupId = ?' : '$where AND groupId = ?';
119-
whereArgs = whereArgs == null
120-
? [groupId.fullBytes]
121-
: [...whereArgs, groupId.fullBytes];
112+
final statement = "(groupId = ? OR events.groupId = ?)";
113+
where = where == null ? statement : '$where AND $statement';
114+
whereArgs = [...?whereArgs, groupId.fullBytes, groupId.fullBytes];
122115
}
123116
if (placeId != null) {
124-
where = where == null ? 'placeId = ?' : '$where AND placeId = ?';
125-
whereArgs = whereArgs == null
126-
? [placeId.fullBytes]
127-
: [...whereArgs, placeId.fullBytes];
117+
final statement = "(placeId = ? OR events.placeId = ?)";
118+
where = where == null ? statement : '$where AND $statement';
119+
whereArgs = [...?whereArgs, placeId.fullBytes, placeId.fullBytes];
128120
}
129121
if (eventId != null) {
130122
where = where == null ? 'eventId = ?' : '$where AND eventId = ?';
131-
whereArgs = whereArgs == null
132-
? [eventId.fullBytes]
133-
: [...whereArgs, eventId.fullBytes];
123+
whereArgs = [...?whereArgs, eventId.fullBytes];
134124
}
125+
const eventPrefix = "event_";
135126
final result = await db?.query(
136127
"calendarItems LEFT JOIN events ON events.id = calendarItems.eventId",
137128
columns: [
138-
"events.*",
139-
"calendarItems.runtimeType AS calendarItemruntimeType",
140-
"calendarItems.id AS calendarItemid",
141-
"calendarItems.name AS calendarItemname",
142-
"calendarItems.description AS calendarItemdescription",
143-
"calendarItems.location AS calendarItemlocation",
144-
"calendarItems.eventId AS calendarItemeventId",
145-
"calendarItems.start AS calendarItemstart",
146-
"calendarItems.end AS calendarItemend",
147-
"calendarItems.status AS calendarItemstatus",
148-
"calendarItems.repeatType AS calendarItemrepeatType",
149-
"calendarItems.interval AS calendarIteminterval",
150-
"calendarItems.variation AS calendarItemvariation",
151-
"calendarItems.count AS calendarItemcount",
152-
"calendarItems.until AS calendarItemuntil",
153-
"calendarItems.exceptions AS calendarItemexceptions",
154-
"calendarItems.autoGroupId AS calendarItemautoGroupId",
155-
"calendarItems.searchStart AS calendarItemsearchStart",
156-
"calendarItems.autoDuration AS calendarItemautoDuration",
129+
"events.id AS ${eventPrefix}id",
130+
"events.parentId AS ${eventPrefix}parentId",
131+
"events.groupId AS ${eventPrefix}groupId",
132+
"events.placeId AS ${eventPrefix}placeId",
133+
"events.blocked AS ${eventPrefix}blocked",
134+
"events.name AS ${eventPrefix}name",
135+
"events.description AS ${eventPrefix}description",
136+
"events.location AS ${eventPrefix}location",
137+
"events.extra AS ${eventPrefix}extra",
138+
"calendarItems.*",
157139
],
158140
where: where,
159141
whereArgs: whereArgs,
160142
);
161143
return result?.map((e) {
162144
return ConnectedModel<CalendarItem, Event?>(
163-
CalendarItem.fromDatabase(Map.fromEntries(e.entries
164-
.where((element) => element.key.startsWith('calendarItem'))
165-
.map((e) => MapEntry(
166-
e.key.substring("calendarItem".length), e.value)))),
167-
e['id'] == null ? null : Event.fromDatabase(e),
145+
CalendarItem.fromDatabase(e),
146+
e['${eventPrefix}id'] == null
147+
? null
148+
: Event.fromDatabase(Map.fromEntries(e.entries
149+
.where((element) => element.key.startsWith(eventPrefix))
150+
.map((e) => MapEntry(
151+
e.key.substring(eventPrefix.length), e.value)))),
168152
);
169153
}).toList() ??
170154
[];

api/lib/models/event/item/model.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ part 'model.g.dart';
1111
enum CalendarItemType { appointment, moment, pending }
1212

1313
@freezed
14-
class CalendarItem with _$CalendarItem implements DescriptiveModel {
14+
class CalendarItem
15+
with _$CalendarItem, IdentifiedModel, NamedModel, DescriptiveModel {
1516
const CalendarItem._();
1617

1718
const factory CalendarItem.fixed({
1819
@MultihashConverter() Multihash? id,
1920
@Default('') String name,
2021
@Default('') String description,
2122
@Default('') String location,
23+
@MultihashConverter() Multihash? groupId,
24+
@MultihashConverter() Multihash? placeId,
2225
@MultihashConverter() Multihash? eventId,
2326
@Default(EventStatus.confirmed) EventStatus status,
2427
@DateTimeConverter() DateTime? start,
@@ -30,6 +33,8 @@ class CalendarItem with _$CalendarItem implements DescriptiveModel {
3033
@Default('') String name,
3134
@Default('') String description,
3235
@Default('') String location,
36+
@MultihashConverter() Multihash? groupId,
37+
@MultihashConverter() Multihash? placeId,
3338
@MultihashConverter() Multihash? eventId,
3439
@Default(EventStatus.confirmed) EventStatus status,
3540
@DateTimeConverter() DateTime? start,
@@ -47,6 +52,8 @@ class CalendarItem with _$CalendarItem implements DescriptiveModel {
4752
@Default('') String name,
4853
@Default('') String description,
4954
@Default('') String location,
55+
@MultihashConverter() Multihash? groupId,
56+
@MultihashConverter() Multihash? placeId,
5057
@MultihashConverter() Multihash? eventId,
5158
@Default(EventStatus.confirmed) EventStatus status,
5259
@DateTimeConverter() DateTime? start,

0 commit comments

Comments
 (0)