You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-13 22:12:50 +02:00
Handle default folder on react-native
This commit is contained in:
@@ -35,6 +35,8 @@ class NotesScreenComponent extends React.Component {
|
||||
type: 'Navigation/NAVIGATE',
|
||||
routeName: 'Folders',
|
||||
});
|
||||
}).catch((error) => {
|
||||
alert(error.message);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -53,8 +53,9 @@ class SideMenuContentComponent extends Component {
|
||||
let buttons = [];
|
||||
for (let i = 0; i < this.props.folders.length; i++) {
|
||||
let f = this.props.folders[i];
|
||||
let title = f.title + (f.is_default ? ' *' : '');
|
||||
buttons.push(
|
||||
<Button style={styles.button} title={f.title} onPress={() => { this.folder_press(f) }} key={f.id} />
|
||||
<Button style={styles.button} title={title} onPress={() => { this.folder_press(f) }} key={f.id} />
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,7 @@ import SQLite from 'react-native-sqlite-storage';
|
||||
import { Log } from 'src/log.js';
|
||||
import { uuid } from 'src/uuid.js';
|
||||
import { promiseChain } from 'src/promise-chain.js';
|
||||
import { _ } from 'src/locale.js'
|
||||
|
||||
const structureSql = `
|
||||
CREATE TABLE folders (
|
||||
@@ -9,7 +10,8 @@ CREATE TABLE folders (
|
||||
parent_id TEXT NOT NULL DEFAULT "",
|
||||
title TEXT NOT NULL DEFAULT "",
|
||||
created_time INT NOT NULL DEFAULT 0,
|
||||
updated_time INT NOT NULL DEFAULT 0
|
||||
updated_time INT NOT NULL DEFAULT 0,
|
||||
is_default BOOLEAN NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE notes (
|
||||
@@ -117,7 +119,7 @@ class Database {
|
||||
}
|
||||
|
||||
open() {
|
||||
this.db_ = SQLite.openDatabase({ name: '/storage/emulated/0/Download/joplin-27.sqlite' }, (db) => {
|
||||
this.db_ = SQLite.openDatabase({ name: '/storage/emulated/0/Download/joplin-32.sqlite' }, (db) => {
|
||||
Log.info('Database was open successfully');
|
||||
}, (error) => {
|
||||
Log.error('Cannot open database: ', error);
|
||||
@@ -373,6 +375,7 @@ class Database {
|
||||
tx.executeSql(statements[i]);
|
||||
}
|
||||
tx.executeSql('INSERT INTO settings (`key`, `value`, `type`) VALUES ("clientId", "' + uuid.create() + '", "' + Database.enumId('settings', 'string') + '")');
|
||||
tx.executeSql('INSERT INTO folders (`id`, `title`, `is_default`, `created_time`) VALUES ("' + uuid.create() + '", "' + _('Default list') + '", 1, ' + Math.round((new Date()).getTime() / 1000) + ')');
|
||||
}).then(() => {
|
||||
Log.info('Database schema created successfully');
|
||||
// Calling initialize() now that the db has been created will make it go through
|
||||
|
@@ -2,6 +2,7 @@ import { BaseModel } from 'src/base-model.js';
|
||||
import { Log } from 'src/log.js';
|
||||
import { promiseChain } from 'src/promise-chain.js';
|
||||
import { Note } from 'src/models/note.js';
|
||||
import { _ } from 'src/locale.js';
|
||||
|
||||
class Folder extends BaseModel {
|
||||
|
||||
@@ -40,7 +41,13 @@ class Folder extends BaseModel {
|
||||
}
|
||||
|
||||
static delete(folderId, options = null) {
|
||||
return this.noteIds(folderId).then((ids) => {
|
||||
return this.load(folderId).then((folder) => {
|
||||
if (!!folder.is_default) {
|
||||
throw new Error(_('Cannot delete the default list'));
|
||||
}
|
||||
}).then(() => {
|
||||
return this.noteIds(folderId);
|
||||
}).then((ids) => {
|
||||
let chain = [];
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
chain.push(() => {
|
||||
|
@@ -20,7 +20,7 @@ class Registry {
|
||||
|
||||
static api() {
|
||||
if (this.api_) return this.api_;
|
||||
this.api_ = new WebApi('http://192.168.1.2');
|
||||
this.api_ = new WebApi('http://192.168.1.3');
|
||||
return this.api_;
|
||||
}
|
||||
|
||||
|
@@ -9,94 +9,6 @@ use AppBundle\Controller\ApiController;
|
||||
use AppBundle\Model\Change;
|
||||
use AppBundle\Exception\UnauthorizedException;
|
||||
|
||||
/*
|
||||
|
||||
JS
|
||||
|
||||
|
||||
class Session
|
||||
::login()
|
||||
|
||||
class Synchronizer
|
||||
::fromId(id)
|
||||
|
||||
class Note
|
||||
|
||||
class User
|
||||
|
||||
|
||||
HISTORY
|
||||
|
||||
client_id, create, type, id => get full object from api
|
||||
update, type, id => get full object from api
|
||||
delete, type, id => remove object
|
||||
|
||||
Revisions
|
||||
----------------
|
||||
id
|
||||
client_id
|
||||
(user_id ?)
|
||||
action (create, update, delete)
|
||||
item_type (note, folder)
|
||||
item_field (title, body, completed...)
|
||||
item_id
|
||||
|
||||
if current client ID = revision.client_id - skip
|
||||
|
||||
Current client id = 123
|
||||
|
||||
Client ID | Action | Item ID
|
||||
------------------------------------
|
||||
456 delete 777
|
||||
123 update 777 - conflict - move to folder - note that deleted by X and then modified by Y
|
||||
|
||||
|
||||
Client ID | Action | Item ID | Rev ID
|
||||
------------------------------------------------------
|
||||
456 update 777 | 2
|
||||
123 update 777 - conflict | 3
|
||||
|
||||
Find rev 1 and do three way merge with 2 and 3 - means there's a need to store history of all versions of body/title
|
||||
|
||||
|
||||
|
||||
// Each item should have a revision ID.
|
||||
// When processing revisions => if item revision = revision.id - skip
|
||||
|
||||
|
||||
API CALL
|
||||
|
||||
/synchronizer/?rev_id=<rev_id_that_caller_synched_to>
|
||||
|
||||
SIMPLE IMPLEMENTATION:
|
||||
|
||||
loop through changes
|
||||
create list of actions:
|
||||
create one action per item ID / field (by merging all into one)
|
||||
|
||||
loop through actions
|
||||
skip current client id = action.client_id
|
||||
|
||||
send back list:
|
||||
|
||||
{
|
||||
sync_id: 132456,
|
||||
notes: [
|
||||
{
|
||||
action: 'update',
|
||||
field: 'body',
|
||||
body: 'blabla'
|
||||
}
|
||||
],
|
||||
has_more: true
|
||||
}
|
||||
|
||||
If has_more, resume with last sync_id
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class SynchronizerController extends ApiController {
|
||||
|
||||
/**
|
||||
@@ -108,8 +20,6 @@ class SynchronizerController extends ApiController {
|
||||
if (!$this->user() || !$this->session()) throw new UnauthorizedException();
|
||||
|
||||
$actions = Change::changesDoneAfterId($this->user()->id, $this->session()->client_id, $lastChangeId);
|
||||
// $actions['user_id'] = Change::hex($this->user()->id);
|
||||
// $actions['client_id'] = Change::hex($this->session()->client_id);
|
||||
return static::successResponse($actions);
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,14 @@ class Session extends BaseModel {
|
||||
public $useUuid = true;
|
||||
public $incrementing = false;
|
||||
|
||||
static protected $fields = array(
|
||||
'id' => array('public' => 'string'),
|
||||
'created_time' => array('public' => 'int'),
|
||||
'updated_time' => array('public' => 'int'),
|
||||
'owner_id' => array('public' => 'string'),
|
||||
'client_id' => array('public' => 'string'),
|
||||
);
|
||||
|
||||
static public function hashPassword($password) {
|
||||
return password_hash($password, PASSWORD_DEFAULT);
|
||||
}
|
||||
|
Reference in New Issue
Block a user