You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-27 20:29:45 +02:00
Compare commits
7 Commits
ios-v12.0.
...
android-v2
Author | SHA1 | Date | |
---|---|---|---|
|
757c125bd3 | ||
|
2867b66cf1 | ||
|
5c6fd93753 | ||
|
ea65313bdb | ||
|
1711f7ec88 | ||
|
e0b5ef6630 | ||
|
4bbb3d1d58 |
@@ -36,7 +36,7 @@ Linux | <a href='https://github.com/laurent22/joplin/releases/download/v1.8.5/Jo
|
||||
|
||||
Operating System | Download | Alt. Download
|
||||
---|---|---
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.0.2/joplin-v2.0.2.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.0.2/joplin-v2.0.2-32bit.apk)
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://joplinapp.org/images/BadgeAndroid.png'/></a> | or download the APK file: [64-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.0.4/joplin-v2.0.4.apk) [32-bit](https://github.com/laurent22/joplin-android/releases/download/android-v2.0.4/joplin-v2.0.4-32bit.apk)
|
||||
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://joplinapp.org/images/BadgeIOS.png'/></a> | -
|
||||
|
||||
## Terminal application
|
||||
|
@@ -65,4 +65,4 @@ if [[ $COMMANDS != "" ]]; then
|
||||
fi
|
||||
|
||||
cd "$ROOT_DIR/packages/app-desktop"
|
||||
npm start -- --env dev --profile "$PROFILE_DIR"
|
||||
npm start -- --profile "$PROFILE_DIR"
|
||||
|
@@ -141,8 +141,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097633
|
||||
versionName "2.0.2"
|
||||
versionCode 2097635
|
||||
versionName "2.0.4"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
|
@@ -46,6 +46,8 @@ function isCannotSyncError(error: any): boolean {
|
||||
|
||||
export default class Synchronizer {
|
||||
|
||||
public static verboseMode: boolean = true;
|
||||
|
||||
private db_: any;
|
||||
private api_: any;
|
||||
private appType_: string;
|
||||
@@ -195,7 +197,11 @@ export default class Synchronizer {
|
||||
line.push(`(Remote ${s.join(', ')})`);
|
||||
}
|
||||
|
||||
this.logger().debug(line.join(': '));
|
||||
if (Synchronizer.verboseMode) {
|
||||
this.logger().info(line.join(': '));
|
||||
} else {
|
||||
this.logger().debug(line.join(': '));
|
||||
}
|
||||
|
||||
if (!this.progressReport_[action]) this.progressReport_[action] = 0;
|
||||
this.progressReport_[action] += actionCount;
|
||||
@@ -516,6 +522,40 @@ export default class Synchronizer {
|
||||
if (local.type_ == BaseModel.TYPE_RESOURCE && (action == 'createRemote' || action === 'updateRemote' || (action == 'itemConflict' && remote))) {
|
||||
const localState = await Resource.localState(local.id);
|
||||
if (localState.fetch_status !== Resource.FETCH_STATUS_DONE) {
|
||||
// This condition normally shouldn't happen
|
||||
// because the normal cases are as follow:
|
||||
//
|
||||
// - User creates a resource locally - in that
|
||||
// case the fetch status is DONE, so we cannot
|
||||
// end up here.
|
||||
//
|
||||
// - User fetches a new resource metadata, but
|
||||
// not the blob - in that case fetch status is
|
||||
// IDLE. However in that case, we cannot end
|
||||
// up in this place either, because the action
|
||||
// cannot be createRemote (because the
|
||||
// resource has not been created locally) or
|
||||
// updateRemote (because a resouce cannot be
|
||||
// modified locally unless the blob is present
|
||||
// too).
|
||||
//
|
||||
// Possibly the only case we can end up here is
|
||||
// if a resource metadata has been downloaded,
|
||||
// but not the blob yet. Then the sync target is
|
||||
// switched to a different one. In that case, we
|
||||
// can have a fetch status IDLE, with an
|
||||
// "updateRemote" action, if the timestamp of
|
||||
// the server resource is before the timestamp
|
||||
// of the local resource.
|
||||
//
|
||||
// In that case we can't do much so we mark the
|
||||
// resource as "cannot sync". Otherwise it will
|
||||
// throw the error "Processing a path that has
|
||||
// already been done" on the next loop, and sync
|
||||
// will never finish because we'll always end up
|
||||
// here.
|
||||
this.logger().info(`Need to upload a resource, but blob is not present: ${path}`);
|
||||
await handleCannotSyncItem(ItemClass, syncTargetId, local, 'Trying to upload resource, but only metadata is present.');
|
||||
action = null;
|
||||
} else {
|
||||
try {
|
||||
|
@@ -10,6 +10,7 @@ import Note from '../../models/Note';
|
||||
import Resource from '../../models/Resource';
|
||||
import ResourceFetcher from '../../services/ResourceFetcher';
|
||||
import BaseItem from '../../models/BaseItem';
|
||||
import { ModelType } from '../../BaseModel';
|
||||
|
||||
let insideBeforeEach = false;
|
||||
|
||||
@@ -333,6 +334,13 @@ describe('Synchronizer.resources', function() {
|
||||
await Resource.setLocalState(resource.id, { fetch_status: Resource.FETCH_STATUS_DONE });
|
||||
await synchronizerStart();
|
||||
|
||||
// At first, the resource is marked as cannot sync, so even after
|
||||
// synchronisation, nothing should happen.
|
||||
expect((await remoteResources()).length).toBe(0);
|
||||
|
||||
// The user can retry the item, in which case sync should happen.
|
||||
await BaseItem.saveSyncEnabled(ModelType.Resource, resource.id);
|
||||
await synchronizerStart();
|
||||
expect((await remoteResources()).length).toBe(1);
|
||||
}));
|
||||
|
||||
|
@@ -309,13 +309,15 @@ export default class ItemModel extends BaseModel<Item> {
|
||||
item.jop_encryption_applied = joplinItem.encryption_applied || 0;
|
||||
item.jop_share_id = joplinItem.share_id || '';
|
||||
|
||||
delete joplinItem.id;
|
||||
delete joplinItem.parent_id;
|
||||
delete joplinItem.share_id;
|
||||
delete joplinItem.type_;
|
||||
delete joplinItem.encryption_applied;
|
||||
const joplinItemToSave = { ...joplinItem };
|
||||
|
||||
item.content = Buffer.from(JSON.stringify(joplinItem));
|
||||
delete joplinItemToSave.id;
|
||||
delete joplinItemToSave.parent_id;
|
||||
delete joplinItemToSave.share_id;
|
||||
delete joplinItemToSave.type_;
|
||||
delete joplinItemToSave.encryption_applied;
|
||||
|
||||
item.content = Buffer.from(JSON.stringify(joplinItemToSave));
|
||||
} else {
|
||||
item.content = buffer;
|
||||
}
|
||||
|
@@ -108,17 +108,17 @@ export default class UserModel extends BaseModel<User> {
|
||||
}
|
||||
|
||||
public async checkMaxItemSizeLimit(user: User, buffer: Buffer, item: Item, joplinItem: any) {
|
||||
const itemTitle = joplinItem ? joplinItem.title || '' : '';
|
||||
const isNote = joplinItem && joplinItem.type_ === ModelType.Note;
|
||||
|
||||
// If the item is encrypted, we apply a multipler because encrypted
|
||||
// items can be much larger (seems to be up to twice the size but for
|
||||
// safety let's go with 2.2).
|
||||
const maxSize = user.max_item_size * (item.jop_encryption_applied ? 2.2 : 1);
|
||||
if (maxSize && buffer.byteLength > maxSize) {
|
||||
const itemTitle = joplinItem ? joplinItem.title || '' : '';
|
||||
const isNote = joplinItem && joplinItem.type_ === ModelType.Note;
|
||||
|
||||
throw new ErrorPayloadTooLarge(_('Cannot save %s "%s" because it is larger than than the allowed limit (%s)',
|
||||
isNote ? _('note') : _('attachment'),
|
||||
itemTitle ? itemTitle : name,
|
||||
itemTitle ? itemTitle : item.name,
|
||||
formatBytes(user.max_item_size)
|
||||
));
|
||||
}
|
||||
|
@@ -1,5 +1,9 @@
|
||||
# Joplin Android app changelog
|
||||
|
||||
## [android-v2.0.3](https://github.com/laurent22/joplin/releases/tag/android-v2.0.3) (Pre-release) - 2021-06-16T09:48:58Z
|
||||
|
||||
- Improved: Verbose mode for synchronizer (4bbb3d1)
|
||||
|
||||
## [android-v2.0.2](https://github.com/laurent22/joplin/releases/tag/android-v2.0.2) - 2021-06-15T20:03:21Z
|
||||
|
||||
- Improved: Conflict notes will now populate a new field with the ID of the conflict note. (#5049 by [@Ahmad45123](https://github.com/Ahmad45123))
|
||||
|
Reference in New Issue
Block a user