diff --git a/packages/lib/models/Resource.ts b/packages/lib/models/Resource.ts index 71069d996c..408f4c6098 100644 --- a/packages/lib/models/Resource.ts +++ b/packages/lib/models/Resource.ts @@ -389,15 +389,31 @@ export default class Resource extends BaseItem { return newResource; } - static async createConflictResourceNote(resource: ResourceEntity) { - const Note = this.getClass('Note'); + public static async resourceConflictFolderId(): Promise { + const folder = await this.resourceConflictFolder(); + return folder.id; + } + private static async resourceConflictFolder(): Promise { + const conflictFolderTitle = _('Conflicts (attachments)'); + const Folder = this.getClass('Folder'); + + const folder = await Folder.loadByTitle(conflictFolderTitle); + if (!folder || folder.parent_id) { + return Folder.save({ title: conflictFolderTitle }); + } + + return folder; + } + + public static async createConflictResourceNote(resource: ResourceEntity) { + const Note = this.getClass('Note'); const conflictResource = await Resource.duplicateResource(resource.id); await Note.save({ title: _('Attachment conflict: "%s"', resource.title), body: _('There was a [conflict](%s) on the attachment below.\n\n%s', 'https://joplinapp.org/conflict/', Resource.markdownTag(conflictResource)), - is_conflict: 1, + parent_id: await this.resourceConflictFolderId(), }, { changeSource: ItemChange.SOURCE_SYNC }); } diff --git a/packages/lib/services/synchronizer/Synchronizer.resources.test.ts b/packages/lib/services/synchronizer/Synchronizer.resources.test.ts index f0f222b8df..5fece25467 100644 --- a/packages/lib/services/synchronizer/Synchronizer.resources.test.ts +++ b/packages/lib/services/synchronizer/Synchronizer.resources.test.ts @@ -254,14 +254,21 @@ describe('Synchronizer.resources', function() { // attached to it, and check that it has the original content. const allNotes = await Note.all(); expect(allNotes.length).toBe(2); + const resourceConflictFolderId = await Resource.resourceConflictFolderId(); const conflictNote = allNotes.find((v: NoteEntity) => { - return !!v.is_conflict; + return v.parent_id === resourceConflictFolderId; }); expect(!!conflictNote).toBe(true); const resourceIds = await Note.linkedResourceIds(conflictNote.body); expect(resourceIds.length).toBe(1); const conflictContent = await Resource.resourceBlobContent(resourceIds[0], 'utf8'); expect(conflictContent).toBe('1234 MOD 1'); + + // Also check that the conflict folder has been created and that it + // is a top folder. + const resourceConflictFolder = await Folder.load(resourceConflictFolderId); + expect(resourceConflictFolder).toBeTruthy(); + expect(resourceConflictFolder.parent_id).toBeFalsy(); } }));