# Pre-release 1.4 is now available for testing (Updated 23/11/20)

**URL:** <https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247>\
**Category:** Beta Testing\
**Created:** [5 November 2020 22:46 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247 "2020-11-05T22:46:39Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![msbentley](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/msbentley/32/1219_2.png) [@msbentley](https://discourse.joplinapp.org/u/msbentley)\
**Post date:** [10 November 2020 08:32 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/41 "2020-11-10T08:32:46Z")

</div>

Hi @laurent if I understand, this should apply to _all_ API calls that return multiple values, right? I'm using the `search` endpoint, and indeed I now see the results returned under `items`, but I do not see the limit of 100 items, nor do I ever see `cursor` - I get thousands of results returned.

This is fine by me 😉 But it isn't in line with what I read above?

Edit: I see the expected result for e.g. the `notes` endpoint, just not search...

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [10 November 2020 09:26 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/42 "2020-11-10T09:26:53Z")

</div>

> [@msbentley](#):
>
> Hi @laurent if I understand, this should apply to _all_ API calls that return multiple values, right? I'm using the `search` endpoint, and indeed I now see the results returned under `items` , but I do not see the limit of 100 items, nor do I ever see `cursor` - I get thousands of results returned.
> 
> This is fine by me 😉 But it isn't in line with what I read above?

Yes, this end point is not yet enabled for that but I made it return an "items" property so that you can already setup your code as if it was. In other words, if there's a cursor property, you should follow it, and otherwise you have all the results.

---

<div class="post-metadata">

**Author:** ![msbentley](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/msbentley/32/1219_2.png) [@msbentley](https://discourse.joplinapp.org/u/msbentley)\
**Post date:** [10 November 2020 09:27 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/43 "2020-11-10T09:27:49Z")

</div>

Perfect, thanks - I've already made the update for `notes` and it works well, so I'll do the same for `search`!

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [10 November 2020 09:47 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/44 "2020-11-10T09:47:05Z")

</div>

In fact, I've just noticed a potential issue with the cursor approach, which would make it hard to implement a "page" parameter. This technique also doesn't quite solve some of the problems I had in mind, like reliably iterating over a feed of changing data (it handles items being deleted, but not added).

So because of this I will switch to a model similar to the [Stack Exchange Paging API](https://api.stackexchange.com/docs/paging):

- Paginated data may return an `has_more` field. If it is present, it means more pages of data can be fetched.
- You can specify a `page` query parameter to get a specific page in the dataset. Page number starts and defaults to "1".
- You can request the total number of items using the `.total` field property (eg. `fields=.total`), in which case it will be returned as the "total" property.

So the pseudo code would be changed like this:

```javascript
async function fetchJson(url) {
	return (await fetch(url)).json();
}

async function fetchAllNotes() {
	let pageNum = 1;

	do {
		const response = await fetchJson('http://localhost:41184/notes?page=' + pageNum++);
		console.info('Printing notes:');
		console.info(response.items);
	} while (response.has_more)
}

```

I hope it doesn't mean too many changes to your code. I expect that in the loop where you fetch data, you need to remove the `cursor` handling and instead look at the "has\_more" field, with a counter to fetch the relevant page.

If you have any questions or see any issue with this approach please let me know.

---

<div class="post-metadata">

**Author:** ![foxmask](https://avatars.discourse-cdn.com/v4/letter/f/c68b51/32.png) [@foxmask](https://discourse.joplinapp.org/u/foxmask)\
**Post date:** [10 November 2020 10:01 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/45 "2020-11-10T10:01:13Z")

</div>

this is how django works too

> **[Paginator | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/paginator/)**

```auto

Page.has_next()¶

    Returns True if there’s a next page.

Page.has_previous()¶

    Returns True if there’s a previous page.

Page.has_other_pages()¶

    Returns True if there’s a next or previous page.

Page.next_page_number()¶

    Returns the next page number. Raises InvalidPage if next page doesn’t exist.

Page.previous_page_number()¶

    Returns the previous page number. Raises InvalidPage if previous page doesn’t exist.

Page.start_index()¶

    Returns the 1-based index of the first object on the page, relative to all of the objects in the paginator’s list. For example, when paginating a list of 5 objects with 2 objects per page, the second page’s start_index() would return 3.

Page.end_index()¶

    Returns the 1-based index of the last object on the page, relative to all of the objects in the paginator’s list. For example, when paginating a list of 5 objects with 2 objects per page, the second page’s end_index() would return 4.

```

the source code

> <https://github.com/django/django/blob/master/django/core/paginator.py>

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [10 November 2020 10:07 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/46 "2020-11-10T10:07:00Z")

</div>

Yes I've seen that in the Dropbox or OneDrive API too, so it seems quite standard.

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [10 November 2020 12:34 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/47 "2020-11-10T12:34:21Z")

</div>

Well, this time I plan to wait until v1.4 is stable before testing. . .

---

<div class="post-metadata">

**Author:** ![t0dd](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/t0dd/32/743_2.png) [@t0dd](https://discourse.joplinapp.org/u/t0dd)\
**Post date:** [11 November 2020 05:26 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/48 "2020-11-11T05:26:58Z")

</div>

The way I built my RPMs ([github.com/taw00/joplin-rpm](http://github.com/taw00/joplin-rpm)) in the past (Joplin 1.3) was essentially:

```auto
npm install
cd ElectronClient
yarn dist

```

That would trigger electron-builder and -packager to do magic javascript build-stuff and package things that I barely understand.

And then I would package into RPM pretty much everything under `ElectronClient/dist/linux-unpacked/*`.

With 1.4.7 this breaks. The directory structure is different and I am not sure how to you generate the bits at the end and where they land. I looked through the documentation and some of the scripts and it still remains a mystery.

Can someone help me out?

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [11 November 2020 09:20 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/49 "2020-11-11T09:20:59Z")

</div>

Everything is in BUILD.md. If something's missing from it let me know.

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [11 November 2020 14:24 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/50 "2020-11-11T14:24:32Z")

</div>

An new version is out:

IMPORTANT: If you use the Clipper API, please note that there are a few breaking changes in this version. See this link for more information: [https://github.com/laurent22/joplin/pull/3983](https://github.com/laurent22/joplin/pull/3983)

* * *

- New: Added toolbar button to switch spell checker language
- Improved: Api: Change pagination to has\_more model
- Fixed: Fixed inconsistent note list state when using search (#3904)
- Fixed: Fixed text editor button tooltips
- Fixed: Regression: Fix exporting to HTML and PDF
- Fixed: Tags could not be selected in some cases (#3876)

> **[Release v1.4.9 · laurent22/joplin](https://github.com/laurent22/joplin/releases/tag/v1.4.9)**
>
> IMPORTANT: If you use the Clipper API, please note that there are a few breaking changes in this version. See this link for more information: #3983
> 
> 
> New: Added toolbar button to switch spell check...

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [11 November 2020 14:28 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/51 "2020-11-11T14:28:28Z")

</div>

@foxmask, @rxliuli, @msbentley, the updated API now has the has\_more change that was discussed above and the [doc](https://joplinapp.org/api/references/rest_api/#pagination) has been updated too.

Sorry about this change after you've already started updating your apps, but that was unfortunately necessary as the previous model was not efficient enough to handle a "page" query parameter. If you have any question about it, please let me know.

---

<div class="post-metadata">

**Author:** ![foxmask](https://avatars.discourse-cdn.com/v4/letter/f/c68b51/32.png) [@foxmask](https://discourse.joplinapp.org/u/foxmask)\
**Post date:** [12 November 2020 14:19 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/52 "2020-11-12T14:19:15Z")

</div>

no problem, this is how projects progress

---

<div class="post-metadata">

**Author:** ![james-carroll](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/james-carroll/32/28844_2.png) [@james-carroll](https://discourse.joplinapp.org/u/james-carroll)\
**Post date:** [12 November 2020 18:06 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/53 "2020-11-12T18:06:47Z")

</div>

I have basically the same process, bar replace the `yarn dist` with `npm run dist`.

The changes to compensate for my build process were along the lines of this diff.

```auto
- cd ElectronClient
+ cd packages/app-desktop/
       npm run dist
- cp -r $SNAPCRAFT_PART_BUILD/ElectronClient/dist/linux-unpacked/ $SNAPCRAFT_PART_INSTALL/
+ cp -r dist/linux-unpacked/ $SNAPCRAFT_PART_INSTALL/
+ mv $SNAPCRAFT_PART_INSTALL/linux-unpacked/@joplinapp-desktop $SNAPCRAFT_PART_INSTALL/linux-unpacked/joplin

```

Which is to say there's 2 change of directory structure and the binary itself has also changed name, but everything else seems to work the same as before. Of course, Yarn itself might have some influence here, I'm no expert there, so you could try `npm run dist` rather than `yarn dist` to see if that influences anything.

---

<div class="post-metadata">

**Author:** ![rxliuli](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/rxliuli/32/4083_2.png) [@rxliuli](https://discourse.joplinapp.org/u/rxliuli)\
**Post date:** [12 November 2020 23:57 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/54 "2020-11-12T23:57:29Z")

</div>

The npm package of the api client is being processed. The only problem at present is that I don’t know how to get the total number of data, I want to give the user a progress bar instead of the prompt "I'm processing"

* * *

It seems that the /notes api now only returns the three fields of `id/parent_id/title` by default. Is this an api change? Still a mistake?  
Previous default return field

```auto
id
title
is_todo
todo_completed
parent_id
updated_time
user_updated_time
user_created_time
encryption_applied
_type

```

Are there other APIs that have undergone similar changes? (Folder/resource/tag)

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [13 November 2020 21:51 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/55 "2020-11-13T21:51:18Z")

</div>

> [@foxmask](#):
>
> `NoteResource.deleteByResource`

@foxmask, I cannot replicate this, and the test for it is passing as well. Was the app by any chance built from source? Or if not, which version was it?

---

<div class="post-metadata">

**Author:** ![foxmask](https://avatars.discourse-cdn.com/v4/letter/f/c68b51/32.png) [@foxmask](https://discourse.joplinapp.org/u/foxmask)\
**Post date:** [13 November 2020 22:07 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/56 "2020-11-13T22:07:29Z")

</div>

no I don't. I use only the provided binary

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [13 November 2020 22:09 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/57 "2020-11-13T22:09:26Z")

</div>

Right, now I know what's the issue is. It indeed was broken for a short time and I thought I had fixed it before the pre-release but I must have done it afterwards. So no problem then, it will work from the next version.

---

<div class="post-metadata">

**Author:** ![t0dd](https://yyz2.discourse-cdn.com/flex028/user_avatar/discourse.joplinapp.org/t0dd/32/743_2.png) [@t0dd](https://discourse.joplinapp.org/u/t0dd)\
**Post date:** [14 November 2020 04:52 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/58 "2020-11-14T04:52:29Z")

</div>

@james-carroll -- thanks. I would have eventually stumbled over this process, but you saved me a tremendous amount of time.

@laurent The `build.md` docs are geared to a different purpose. I suppose the bits missing that I would wish for would be the finalization instructions for those who would want to build the stand-alone application (like we packagers do), whether it be an appimage or the "unpacked" variant. Also, there is nothing about how to build the cli. I have not been success with that yet.

Thanks all.

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [14 November 2020 09:53 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/59 "2020-11-14T09:53:08Z")

</div>

v1.4.10 is now available. From now on I will list the API breaking changes, if any, at the top to avoid any surprise. In general I don't expect many breaking changes and when there will be I will try instead to deprecate the feature, so that you have plenty of time to update your plugins.

**Breaking Changes:**

- If you use the Clipper API, please note that there are a few breaking changes in this version. See this link for more information: [https://github.com/laurent22/joplin/pull/3983](https://github.com/laurent22/joplin/pull/3983)
- Plugins: `joplin.views.dialogs.open()` now returns an object instead of the button ID that was clicked. So for example instead of getting just `"ok"`, you will get `{ "id": "ok" }`. This is to allow adding form data to that object.

**Deprecated:**

- Plugins: All `create()` functions under `joplin.views` now take a `viewId` as a first parameter. It will still work for now if you don't provide one, but please update your plugins.
- Plugins: `MenuItemLocation.Context` is deprecated and is now an alias for `MenuItemLocation.NoteListContextMenu`

Plugin doc has been updated with some info about the [development process](https://joplinapp.org/api/references/plugin_api/classes/joplin.html).

* * *

- New: Add {{bowm}} and {{bows}} - Beginning Of Week (Monday/Sunday) (#4023 by Helmut K. C. Tessarek)
- New: Plugins: Add support for editor context menu
- New: Allow customising application layout
- Improved: Allow lowercase filters when doing search
- Improved: Make Markdown editor selection more visible in Dark mode
- Improved: Plugins: Allow retrieving form values from dialogs
- Fixed: Api: Fix note and resource association end points
- Fixed: Fix drag and drop behaviour to "copy" instead of "move" (#4031 by [@CalebJohn](https://github.com/CalebJohn))
- Fixed: Fix handling of certain keys in shortcut editor (#4022 by Helmut K. C. Tessarek)
- Fixed: Fixed issue with note being saved after word has been replaced by spell checker
- Fixed: Plugins: Fix crash when path includes trailing slash
- Fixed: Regression: Fix application name

* * *

- New: Added toolbar button to switch spell checker language
- New: Api: Added way to get the notes associated with a resource
- New: Api: Added ability to watch resource file
- New: API: Adds ability to paginate data (#3983)
- New: Adds spell checker support for Rich Text editor (#3974)
- Fixed: Fixed inconsistent note list state when using search (#3904)
- Fixed: Fixed text editor button tooltips
- Fixed: Regression: Fix exporting to HTML and PDF
- Fixed: Tags could not be selected in some cases (#3876)
- Improved: Change Markdown rendering to align with CommonMark spec (#3839)
- Improved: Plugins: Force plugin devtool dialog to be detached

> **[Release v1.4.10 · laurent22/joplin](https://github.com/laurent22/joplin/releases/tag/v1.4.10)**
>
> Breaking Changes:
> 
> If you use the Clipper API, please note that there are a few breaking changes in this version. See this link for more information: #3983
> Plugins: joplin.views.dialogs.open() now ...

---

<div class="post-metadata">

**Author:** ![laurent](https://avatars.discourse-cdn.com/v4/letter/l/ce7236/32.png) [@laurent](https://discourse.joplinapp.org/u/laurent)\
**Post date:** [14 November 2020 09:58 UTC](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247/60 "2020-11-14T09:58:27Z")

</div>

> [@t0dd](#):
>
> Also, there is nothing about how to build the cli.

It's in packages/tools/release-cli.js

> [@t0dd](#):
>
> I suppose the bits missing that I would wish for would be the finalization instructions for those who would want to build the stand-alone application (like we packagers do)

The reason it's not documented is that it's not really supported, however you can always check `.travis.yml` to see how it's done. Mostly you need to run `npm run dist` after having done the steps listed in BUILD.md.

[Previous page](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247.md?page=2)

[Next page](https://discourse.joplinapp.org/t/pre-release-1-4-is-now-available-for-testing-updated-23-11-20/12247.md?page=4)
