From f792fbb5fc70bbeb64b83018dd387c38f3d2048c Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 2 Jul 2021 17:53:36 +0100 Subject: [PATCH 1/5] Desktop: Fixes #5133: Items keep being uploaded to Joplin Server after a note has been shared --- packages/lib/models/Folder.sharing.test.ts | 24 ++++++++++++++++++- packages/lib/models/Folder.ts | 27 +++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/lib/models/Folder.sharing.test.ts b/packages/lib/models/Folder.sharing.test.ts index 9e7bed52c0..ad71fee0f5 100644 --- a/packages/lib/models/Folder.sharing.test.ts +++ b/packages/lib/models/Folder.sharing.test.ts @@ -1,4 +1,4 @@ -import { setupDatabaseAndSynchronizer, switchClient, createFolderTree, supportDir } from '../testing/test-utils'; +import { setupDatabaseAndSynchronizer, switchClient, createFolderTree, supportDir, msleep } from '../testing/test-utils'; import Folder from '../models/Folder'; import { allNotesFolders } from '../testing/test-utils-synchronizer'; import Note from '../models/Note'; @@ -385,6 +385,28 @@ describe('models_Folder.sharing', function() { expect((await Note.loadByTitle('note 1')).share_id).toBe(''); expect((await Folder.loadByTitle('folder 1')).share_id).toBe(''); expect((await Resource.load(resourceId1)).share_id).toBe(''); + + { + // If we run it again, it should not update the notes since the share_id + // has already been cleared. + const resource1 = await Resource.load(resourceId1); + const resource2 = await Resource.load(resourceId2); + const note1 = await Note.loadByTitle('note 1'); + const note2 = await Note.loadByTitle('note 2'); + const folder1 = await Folder.loadByTitle('folder 1'); + const folder2 = await Folder.loadByTitle('folder 2'); + + await msleep(1); + + await Folder.updateNoLongerSharedItems(['1']); + + expect((await Resource.load(resourceId1)).updated_time).toBe(resource1.updated_time); + expect((await Resource.load(resourceId2)).updated_time).toBe(resource2.updated_time); + expect((await Note.loadByTitle('note 1')).updated_time).toBe(note1.updated_time); + expect((await Note.loadByTitle('note 2')).updated_time).toBe(note2.updated_time); + expect((await Folder.loadByTitle('folder 1')).updated_time).toBe(folder1.updated_time); + expect((await Folder.loadByTitle('folder 2')).updated_time).toBe(folder2.updated_time); + } }); }); diff --git a/packages/lib/models/Folder.ts b/packages/lib/models/Folder.ts index 92b4618d2d..ec861714c2 100644 --- a/packages/lib/models/Folder.ts +++ b/packages/lib/models/Folder.ts @@ -7,8 +7,11 @@ import Database from '../database'; import BaseItem from './BaseItem'; import Resource from './Resource'; import { isRootSharedFolder } from '../services/share/reducer'; +import Logger from '../Logger'; const { substrWithEllipsis } = require('../string-utils.js'); +const logger = Logger.create('models/Folder'); + interface FolderEntityWithChildren extends FolderEntity { children?: FolderEntity[]; } @@ -288,9 +291,16 @@ export default class Folder extends BaseItem { let sharedFolderIds: string[] = []; + const report = { + shareUpdateCount: 0, + unshareUpdateCount: 0, + }; + for (const rootFolder of rootFolders) { const children = await this.allChildrenFolders(rootFolder.id); + report.shareUpdateCount += children.length; + for (const child of children) { if (child.share_id !== rootFolder.share_id) { await this.save({ @@ -316,6 +326,9 @@ export default class Folder extends BaseItem { } const foldersToUnshare = await this.db().selectAll(sql.join(' ')); + + report.unshareUpdateCount += foldersToUnshare.length; + for (const item of foldersToUnshare) { await this.save({ id: item.id, @@ -323,6 +336,8 @@ export default class Folder extends BaseItem { updated_time: Date.now(), }, { autoTimestamp: false }); } + + logger.debug('updateFolderShareIds:', report); } public static async updateNoteShareIds() { @@ -335,6 +350,8 @@ export default class Folder extends BaseItem { WHERE notes.share_id != folders.share_id `); + logger.debug('updateNoteShareIds: notes to update:', rows.length); + for (const row of rows) { await Note.save({ id: row.id, @@ -359,6 +376,8 @@ export default class Folder extends BaseItem { OR n.is_shared != r.is_shared `); + logger.debug('updateResourceShareIds: resources to update:', rows.length); + for (const row of rows) { await Resource.save({ id: row.id, @@ -384,12 +403,14 @@ export default class Folder extends BaseItem { 'resources': Resource, }; + const report: any = {}; + for (const tableName of ['folders', 'notes', 'resources']) { const ItemClass = tableNameToClasses[tableName]; const query = activeShareIds.length ? ` SELECT id FROM ${tableName} - WHERE share_id NOT IN ("${activeShareIds.join('","')}") + WHERE share_id != "" AND share_id NOT IN ("${activeShareIds.join('","')}") ` : ` SELECT id FROM ${tableName} WHERE share_id != '' @@ -397,6 +418,8 @@ export default class Folder extends BaseItem { const rows = await this.db().selectAll(query); + report[tableName] = rows.length; + for (const row of rows) { await ItemClass.save({ id: row.id, @@ -405,6 +428,8 @@ export default class Folder extends BaseItem { }, { autoTimestamp: false }); } } + + logger.debug('updateNoLongerSharedItems:', report); } static async allAsTree(folders: FolderEntity[] = null, options: any = null) { From 07ea79bb46b11845902a94accf8e8ba3a46521bf Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 2 Jul 2021 18:14:49 +0100 Subject: [PATCH 2/5] Desktop: Fixed issue where untitled notes where created after a note had been shared and synced --- packages/lib/models/Folder.sharing.test.ts | 9 +++++++++ packages/lib/models/Folder.ts | 21 +++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/lib/models/Folder.sharing.test.ts b/packages/lib/models/Folder.sharing.test.ts index ad71fee0f5..7fcb5c20f6 100644 --- a/packages/lib/models/Folder.sharing.test.ts +++ b/packages/lib/models/Folder.sharing.test.ts @@ -356,6 +356,8 @@ describe('models_Folder.sharing', function() { const resourceService = new ResourceService(); + const folder1: FolderEntity = await Folder.loadByTitle('folder 1'); + const folder2: FolderEntity = await Folder.loadByTitle('folder 2'); let note1: NoteEntity = await Note.loadByTitle('note 1'); let note2: NoteEntity = await Note.loadByTitle('note 2'); note1 = await shim.attachFileToNote(note1, testImagePath); @@ -369,6 +371,13 @@ describe('models_Folder.sharing', function() { await Folder.updateNoLongerSharedItems(['1']); + // Since `updateNoLongerSharedItems` sets the parent_id too, + // double-check that it's not actually modified. + expect((await Note.loadByTitle('note 1')).parent_id).toBe(folder1.id); + expect((await Note.loadByTitle('note 2')).parent_id).toBe(folder2.id); + expect((await Folder.loadByTitle('folder 1')).parent_id).toBe(folder1.parent_id); + expect((await Folder.loadByTitle('folder 2')).parent_id).toBe(folder2.parent_id); + // At this point, all items associated with share 2 should have their // share_id cleared, because the share no longer exists. We also // double-check that share 1 hasn't been cleared. diff --git a/packages/lib/models/Folder.ts b/packages/lib/models/Folder.ts index ec861714c2..a0e6d8819b 100644 --- a/packages/lib/models/Folder.ts +++ b/packages/lib/models/Folder.ts @@ -320,12 +320,12 @@ export default class Folder extends BaseItem { // if they've been moved out of a shared folder. // await this.unshareItems(ModelType.Folder, sharedFolderIds); - const sql = ['SELECT id FROM folders WHERE share_id != ""']; + const sql = ['SELECT id, parent_id FROM folders WHERE share_id != ""']; if (sharedFolderIds.length) { sql.push(` AND id NOT IN ("${sharedFolderIds.join('","')}")`); } - const foldersToUnshare = await this.db().selectAll(sql.join(' ')); + const foldersToUnshare: FolderEntity[] = await this.db().selectAll(sql.join(' ')); report.unshareUpdateCount += foldersToUnshare.length; @@ -334,6 +334,7 @@ export default class Folder extends BaseItem { id: item.id, share_id: '', updated_time: Date.now(), + parent_id: item.parent_id, }, { autoTimestamp: false }); } @@ -407,12 +408,16 @@ export default class Folder extends BaseItem { for (const tableName of ['folders', 'notes', 'resources']) { const ItemClass = tableNameToClasses[tableName]; + const hasParentId = tableName !== 'resources'; + + const fields = ['id']; + if (hasParentId) fields.push('parent_id'); const query = activeShareIds.length ? ` - SELECT id FROM ${tableName} + SELECT ${this.db().escapeFields(fields)} FROM ${tableName} WHERE share_id != "" AND share_id NOT IN ("${activeShareIds.join('","')}") ` : ` - SELECT id FROM ${tableName} + SELECT ${this.db().escapeFields(fields)} FROM ${tableName} WHERE share_id != '' `; @@ -421,11 +426,15 @@ export default class Folder extends BaseItem { report[tableName] = rows.length; for (const row of rows) { - await ItemClass.save({ + const toSave: any = { id: row.id, share_id: '', updated_time: Date.now(), - }, { autoTimestamp: false }); + }; + + if (hasParentId) toSave.parent_id = row.parent_id; + + await ItemClass.save(toSave, { autoTimestamp: false }); } } From 94ea177b761c2d84296e2b859c1b7e561db98b38 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 2 Jul 2021 18:17:37 +0100 Subject: [PATCH 3/5] Desktop release v2.1.8 --- packages/app-desktop/package-lock.json | 2 +- packages/app-desktop/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app-desktop/package-lock.json b/packages/app-desktop/package-lock.json index 398654068d..c23c6f8ad6 100644 --- a/packages/app-desktop/package-lock.json +++ b/packages/app-desktop/package-lock.json @@ -1,6 +1,6 @@ { "name": "@joplin/app-desktop", - "version": "2.1.7", + "version": "2.1.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/app-desktop/package.json b/packages/app-desktop/package.json index 767a3453bc..b003ce4e98 100644 --- a/packages/app-desktop/package.json +++ b/packages/app-desktop/package.json @@ -1,6 +1,6 @@ { "name": "@joplin/app-desktop", - "version": "2.1.7", + "version": "2.1.8", "description": "Joplin for Desktop", "main": "main.js", "private": true, From e08a909bdb762401025ed49f021c1f04b645bae8 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sat, 3 Jul 2021 09:31:15 +0100 Subject: [PATCH 4/5] Android release v2.1.4 --- README.md | 2 +- packages/app-mobile/android/app/build.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bc9c71f925..887e2851f7 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Linux | Get it on Google Play | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.1.3/joplin-v2.1.3.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.1.3/joplin-v2.1.3-32bit.apk) +Android | Get it on Google Play | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.1.4/joplin-v2.1.4.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.1.4/joplin-v2.1.4-32bit.apk) iOS | Get it on the App Store | - ## Terminal application diff --git a/packages/app-mobile/android/app/build.gradle b/packages/app-mobile/android/app/build.gradle index 11937c8804..dc08b77fc4 100644 --- a/packages/app-mobile/android/app/build.gradle +++ b/packages/app-mobile/android/app/build.gradle @@ -141,8 +141,8 @@ android { applicationId "net.cozic.joplin" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 2097638 - versionName "2.1.3" + versionCode 2097639 + versionName "2.1.4" ndk { abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64" } From cebec1a9926a125ba0d9bf1c062ed8907db129eb Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sat, 3 Jul 2021 09:33:36 +0100 Subject: [PATCH 5/5] Android 2.1.4 --- readme/changelog_android.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readme/changelog_android.md b/readme/changelog_android.md index 6b82a072c2..9322e81e09 100644 --- a/readme/changelog_android.md +++ b/readme/changelog_android.md @@ -1,5 +1,10 @@ # Joplin Android app changelog +## [android-v2.1.4](https://github.com/laurent22/joplin/releases/tag/android-v2.1.4) - 2021-07-03T08:31:36Z + +- Fixed: Fixes #5133: Items keep being uploaded to Joplin Server after a note has been shared. +- Fixed: Fixed issue where untitled notes where created after a note had been shared and synced + ## [android-v2.1.3](https://github.com/laurent22/joplin/releases/tag/android-v2.1.3) - 2021-06-27T13:34:12Z - New: Add support for X-API-MIN-VERSION header (51f3c00)