You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-09-02 20:46:21 +02:00
Compare commits
33 Commits
android-v1
...
android-v1
Author | SHA1 | Date | |
---|---|---|---|
|
85bf89fd97 | ||
|
c2a80b12f0 | ||
|
981c97cca5 | ||
|
091cbc5355 | ||
|
e5a8114887 | ||
|
4779fc6f43 | ||
|
86e7daaec4 | ||
|
cab73a26e7 | ||
|
554ddb3b51 | ||
|
3b22bdb8ae | ||
|
5fdd07679e | ||
|
69f75a1520 | ||
|
f9b7acb8b1 | ||
|
91f700ad54 | ||
|
966aca7753 | ||
|
4de8816ed5 | ||
|
bea68a1056 | ||
|
6fea7116b6 | ||
|
2955914ca5 | ||
|
fd150b5b9d | ||
|
334ffad196 | ||
|
a796a9d179 | ||
|
917dcea28a | ||
|
c901228dc5 | ||
|
da21580785 | ||
|
4d92187327 | ||
|
207d433fb3 | ||
|
ffc311d7bd | ||
|
a1e8e71359 | ||
|
7942e74dc6 | ||
|
c4e21c2b6a | ||
|
0a06aa6f9f | ||
|
f985cfa25c |
Binary file not shown.
Before Width: | Height: | Size: 986 B |
BIN
Assets/AdresseSupport.png
Normal file
BIN
Assets/AdresseSupport.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
BIN
Assets/AdresseTranslation.png
Normal file
BIN
Assets/AdresseTranslation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
@@ -597,7 +597,7 @@ msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr "Exportiere „%s“ ins „%s“ Format. Bitte warten..."
|
||||
msgstr "Exportiere „%s“ ins „%s“-Format. Bitte warten..."
|
||||
|
||||
msgid "Sidebar"
|
||||
msgstr "Seitenleiste"
|
||||
@@ -606,14 +606,14 @@ msgid "Note list"
|
||||
msgstr "Notizen-Liste"
|
||||
|
||||
msgid "Note title"
|
||||
msgstr "Notiz Titel"
|
||||
msgstr "Notiz-Titel"
|
||||
|
||||
msgid "Note body"
|
||||
msgstr "Notiz Text"
|
||||
msgstr "Notiz-Text"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr "Importiere „%s“ ins „%s“ Format. Bitte warten..."
|
||||
msgstr "Importiere „%s“ als „%s“-Format. Bitte warten..."
|
||||
|
||||
msgid "PDF File"
|
||||
msgstr "PDF-Datei"
|
||||
|
@@ -13,8 +13,10 @@ msgstr ""
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.1.1\n"
|
||||
"X-Generator: Poedit 2.2.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr ""
|
||||
@@ -127,13 +129,12 @@ msgstr "Markeert een taak als afgerond."
|
||||
msgid "Note is not a to-do: \"%s\""
|
||||
msgstr "Notitie is geen taak: \"%s\""
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, "
|
||||
"`status`, `decrypt-file` and `target-status`."
|
||||
msgstr ""
|
||||
"Beheert de E2EE-configuratie. Opdrachten zijn: `enable`, `disable`, "
|
||||
"`decrypt`, `status` en `target-status`."
|
||||
"`decrypt`, `status`, `decrypt-file` en `target-status`."
|
||||
|
||||
msgid "Enter master password:"
|
||||
msgstr "Voer het hoofdwachtwoord in:"
|
||||
@@ -260,13 +261,13 @@ msgid "To enter command line mode, press \":\""
|
||||
msgstr "Druk op \":\" om de opdrachtregelmodus te starten."
|
||||
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Druk op Esc om de opdrachtregelmodus af te sluiten."
|
||||
msgstr "Druk op Esc om de opdrachtregelmodus af te sluiten"
|
||||
|
||||
msgid ""
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
"Typ `help keymap` om de lijst met sneltoetsen en configuratie-opties te "
|
||||
"bekijken."
|
||||
"bekijken"
|
||||
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr "Importeert gegeven naar Joplin."
|
||||
@@ -459,21 +460,20 @@ msgid "Starting synchronisation..."
|
||||
msgstr "Bezig met starten van synchronisatie..."
|
||||
|
||||
msgid "Downloading resources..."
|
||||
msgstr ""
|
||||
msgstr "Resources downloaden…"
|
||||
|
||||
msgid "Cancelling... Please wait."
|
||||
msgstr "Bezig met annuleren... Even geduld."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
|
||||
"[tag] from [note], or to list the notes associated with [tag]. The command "
|
||||
"`tag list` can be used to list all the tags (use -l for long option)."
|
||||
msgstr ""
|
||||
"<tag-command> kan zijn \"add\", \"remove\" of \"list\" om [tag] toe te "
|
||||
"<tag-command> kan \"add\", \"remove\" of \"list\" zijn om [tag] toe te "
|
||||
"wijzen aan of te verwijderen uit [note] of om de met [tag] geassocieerde "
|
||||
"notities op te sommen. De opdracht `tag list` kan worden gebruikt om alle "
|
||||
"labels op te sommen."
|
||||
"labels op te sommen (gebruik “-l” voor “long” optie)."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Invalid command: \"%s\""
|
||||
@@ -587,18 +587,16 @@ msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr "Bezig met exporteren van \"%s\" in het formaat \"%s\". Even geduld..."
|
||||
|
||||
msgid "Sidebar"
|
||||
msgstr ""
|
||||
msgstr "Zijbalk"
|
||||
|
||||
msgid "Note list"
|
||||
msgstr ""
|
||||
msgstr "Notitielijst"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Note title"
|
||||
msgstr "Titel van notitieboek:"
|
||||
msgstr "Titel van notitie"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Note body"
|
||||
msgstr "Notitieboeken"
|
||||
msgstr "Inhoud van notitie"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
@@ -635,15 +633,14 @@ msgstr "Webclipper-opties"
|
||||
msgid "%s %s (%s, %s)"
|
||||
msgstr "%s %s (%s, %s)"
|
||||
|
||||
#, fuzzy
|
||||
msgid "&File"
|
||||
msgstr "Bestand"
|
||||
msgstr "&Bestand"
|
||||
|
||||
msgid "About Joplin"
|
||||
msgstr "Over Joplin"
|
||||
|
||||
msgid "Preferences..."
|
||||
msgstr ""
|
||||
msgstr "Voorkeuren…"
|
||||
|
||||
msgid "Check for updates..."
|
||||
msgstr "Controleren op updates..."
|
||||
@@ -665,11 +662,10 @@ msgid "Quit"
|
||||
msgstr "Afsluiten"
|
||||
|
||||
msgid "Close Window"
|
||||
msgstr ""
|
||||
msgstr "Venster afsluiten"
|
||||
|
||||
#, fuzzy
|
||||
msgid "&Edit"
|
||||
msgstr "Bewerken"
|
||||
msgstr "Be&werken"
|
||||
|
||||
msgid "Copy"
|
||||
msgstr "Kopiëren"
|
||||
@@ -680,9 +676,8 @@ msgstr "Knippen"
|
||||
msgid "Paste"
|
||||
msgstr "Plakken"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Select all"
|
||||
msgstr "Datum kiezen"
|
||||
msgstr "Alles selecteren"
|
||||
|
||||
msgid "Bold"
|
||||
msgstr "Vetgedrukt"
|
||||
@@ -691,7 +686,7 @@ msgid "Italic"
|
||||
msgstr "Cursief"
|
||||
|
||||
msgid "Link"
|
||||
msgstr ""
|
||||
msgstr "Koppeling"
|
||||
|
||||
msgid "Code"
|
||||
msgstr "Code"
|
||||
@@ -708,13 +703,11 @@ msgstr "Labels"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Alle notities doorzoeken"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Search in current note"
|
||||
msgstr "Alle notities doorzoeken"
|
||||
msgstr "Huidige notitie doorzoeken"
|
||||
|
||||
#, fuzzy
|
||||
msgid "&View"
|
||||
msgstr "Beeld"
|
||||
msgstr "Beel&d"
|
||||
|
||||
msgid "Toggle sidebar"
|
||||
msgstr "Zijbalk tonen/verbergen"
|
||||
@@ -722,17 +715,14 @@ msgstr "Zijbalk tonen/verbergen"
|
||||
msgid "Toggle editor layout"
|
||||
msgstr "Bewerkindeling tonen/verbergen"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Focus"
|
||||
msgstr "Inhoud focussen"
|
||||
msgstr "Focus"
|
||||
|
||||
#, fuzzy
|
||||
msgid "&Tools"
|
||||
msgstr "Hulpmiddelen"
|
||||
msgstr "E&xtra"
|
||||
|
||||
#, fuzzy
|
||||
msgid "&Help"
|
||||
msgstr "Hulp"
|
||||
msgstr "&Help"
|
||||
|
||||
msgid "Website and documentation"
|
||||
msgstr "Website en documentatie"
|
||||
@@ -741,7 +731,7 @@ msgid "Make a donation"
|
||||
msgstr "Doneren"
|
||||
|
||||
msgid "Toggle development tools"
|
||||
msgstr ""
|
||||
msgstr "Wissel ontwikkelhulpmiddelen"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Open %s"
|
||||
@@ -761,18 +751,18 @@ msgstr "De huidige versie is up-to-date."
|
||||
|
||||
#, javascript-format
|
||||
msgid "%s (pre-release)"
|
||||
msgstr ""
|
||||
msgstr "%s (pre-release)"
|
||||
|
||||
msgid "An update is available, do you want to download it now?"
|
||||
msgstr "Er is een update beschikbaar. Wil je deze nu downloaden?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Your version: %s"
|
||||
msgstr ""
|
||||
msgstr "Jouw versie: %s"
|
||||
|
||||
#, javascript-format
|
||||
msgid "New version: %s"
|
||||
msgstr ""
|
||||
msgstr "Nieuwe versie: %s"
|
||||
|
||||
msgid "Yes"
|
||||
msgstr "Ja"
|
||||
@@ -781,7 +771,7 @@ msgid "No"
|
||||
msgstr "Nee"
|
||||
|
||||
msgid "Token has been copied to the clipboard!"
|
||||
msgstr ""
|
||||
msgstr "Token is naar het klembord gekopieerd!"
|
||||
|
||||
msgid "The web clipper service is enabled and set to auto-start."
|
||||
msgstr "De webclipper-dienst is ingeschakeld en wordt automatisch opgestart."
|
||||
@@ -832,20 +822,21 @@ msgstr "Stap 2: Installeer de extensie"
|
||||
msgid "Download and install the relevant extension for your browser:"
|
||||
msgstr "Download en installeer de bijbehorende extensie in je browser:"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Advanced options"
|
||||
msgstr "Geavanceerde opties tonen"
|
||||
msgstr "Geavanceerde opties"
|
||||
|
||||
msgid "Authorisation token:"
|
||||
msgstr ""
|
||||
msgstr "Autorisatie-token:"
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
msgstr "Kopieer token"
|
||||
|
||||
msgid ""
|
||||
"This authorisation token is only needed to allow third-party applications to "
|
||||
"access Joplin."
|
||||
msgstr ""
|
||||
"Dit autorisatie-token is alleen nodig om applicaties van derden toegang te "
|
||||
"geven tot Joplin."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Notes and settings are stored in: %s"
|
||||
@@ -855,7 +846,7 @@ msgid "Check synchronisation configuration"
|
||||
msgstr "Synchronisatieconfiguratie controleren"
|
||||
|
||||
msgid "Browse..."
|
||||
msgstr ""
|
||||
msgstr "Bladeren…"
|
||||
|
||||
msgid "Apply"
|
||||
msgstr "Toepassen"
|
||||
@@ -951,9 +942,8 @@ msgstr "Status"
|
||||
msgid "Encryption is:"
|
||||
msgstr "Gebruikte versleuteling:"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Usage"
|
||||
msgstr "Gebruik: %s"
|
||||
msgstr "Gebruik"
|
||||
|
||||
msgid "Back"
|
||||
msgstr "Terug"
|
||||
@@ -998,9 +988,8 @@ msgstr "Sommige items kunnen niet worden gesynchroniseerd."
|
||||
msgid "View them now"
|
||||
msgstr "Items tonen"
|
||||
|
||||
#, fuzzy
|
||||
msgid "One or more master keys need a password."
|
||||
msgstr "Voer het hoofdwachtwoord in:"
|
||||
msgstr "Een of meer hoofdsleutels vereist een wachtwoord."
|
||||
|
||||
msgid "Set the password"
|
||||
msgstr "Wachtwoord instellen"
|
||||
@@ -1017,37 +1006,38 @@ msgstr ""
|
||||
"\"Nieuw notitieboek\"."
|
||||
|
||||
msgid "Location"
|
||||
msgstr ""
|
||||
msgstr "Locatie"
|
||||
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
msgstr "URL"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Note History"
|
||||
msgstr "Notitieboeken"
|
||||
msgstr "Notitiegeschiedenis"
|
||||
|
||||
msgid "Previous versions of this note"
|
||||
msgstr ""
|
||||
msgstr "Vorige versies van deze notitie"
|
||||
|
||||
msgid "Note properties"
|
||||
msgstr ""
|
||||
msgstr "Eigenschappen van notitie"
|
||||
|
||||
#, javascript-format
|
||||
msgid "The note \"%s\" has been successfully restored to the notebook \"%s\"."
|
||||
msgstr ""
|
||||
msgstr "De notitie “%s” is succesvol hersteld naar notitieboek “%s”."
|
||||
|
||||
#, fuzzy
|
||||
msgid "This note has no history"
|
||||
msgstr "Deze notitie is bewerkt:"
|
||||
msgstr "Deze notitie heeft geen geschiedenis"
|
||||
|
||||
msgid "Restore"
|
||||
msgstr ""
|
||||
msgstr "Herstel"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Click \"%s\" to restore the note. It will be copied in the notebook named "
|
||||
"\"%s\". The current version of the note will not be replaced or modified."
|
||||
msgstr ""
|
||||
"Klik “%s” om de notitie te herstellen. Het wordt gekopieerd naar het "
|
||||
"notitieboek genaamd “%s”. De huidige versie van de notitie wordt niet "
|
||||
"vervangen of aangepast."
|
||||
|
||||
msgid "Open..."
|
||||
msgstr "Openen..."
|
||||
@@ -1066,7 +1056,7 @@ msgid "Copy Link Address"
|
||||
msgstr "Linkadres kopiëren"
|
||||
|
||||
msgid "This attachment is not downloaded or not decrypted yet."
|
||||
msgstr ""
|
||||
msgstr "Deze bijlage is niet gedownload of nog niet ontsleuteld."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unsupported link or message: %s"
|
||||
@@ -1082,6 +1072,8 @@ msgstr ""
|
||||
|
||||
msgid "Only one note can be printed or exported to PDF at a time."
|
||||
msgstr ""
|
||||
"Slechts één notitie kan gelijktijdig worden afgedrukt of geëxporteerd naar "
|
||||
"PDF."
|
||||
|
||||
msgid "strong text"
|
||||
msgstr "vetgedrukte tekst"
|
||||
@@ -1163,21 +1155,23 @@ msgstr "Versleutelopties"
|
||||
msgid "Clipper Options"
|
||||
msgstr "Webclipperopties"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Delete notebook \"%s\"?\n"
|
||||
"\n"
|
||||
"All notes and sub-notebooks within this notebook will also be deleted."
|
||||
msgstr ""
|
||||
"Notitieboek verwijderen? Alle notities en sub-notitieboeken worden eveneens "
|
||||
"Notitieboek “%s” verwijderen?\n"
|
||||
"\n"
|
||||
"Alle notities en sub-notitieboeken in dit notitieboek worden eveneens "
|
||||
"verwijderd."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Remove tag \"%s\" from all notes?"
|
||||
msgstr "Wil je dit label verwijderen van alle notities?"
|
||||
msgstr "Label “%s” verwijderen van alle notities?"
|
||||
|
||||
msgid "Remove this search from the sidebar?"
|
||||
msgstr "Wil je deze zoekopdracht verwijderen uit de zijbalk?"
|
||||
msgstr "Deze zoekopdracht verwijderen uit de zijbalk?"
|
||||
|
||||
msgid "Delete"
|
||||
msgstr "Verwijderen"
|
||||
@@ -1192,15 +1186,15 @@ msgstr "Notitieboeken"
|
||||
msgid "Decrypting items: %d/%d"
|
||||
msgstr "Bezig met ontsleutelen van items: %d/%d"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Fetching resources: %d/%d"
|
||||
msgstr "Bronnen: %d/%d"
|
||||
msgstr "Bronnen ophalen: %d/%d"
|
||||
|
||||
msgid "Please select where the sync status should be exported to"
|
||||
msgstr "Kies waar de synchronisatiestatus naar moet worden geëxporteerd"
|
||||
|
||||
msgid "Retry"
|
||||
msgstr ""
|
||||
msgstr "Opnieuw proberen"
|
||||
|
||||
msgid "Add or remove tags"
|
||||
msgstr "Labels toevoegen of verwijderen"
|
||||
@@ -1215,32 +1209,32 @@ msgstr "%s - kopiëren"
|
||||
msgid "Switch between note and to-do type"
|
||||
msgstr "Schakelen tussen notitie en taak"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to note type"
|
||||
msgstr "Schakelen tussen notitie en taak"
|
||||
msgstr "Overschakelen naar notitie-type"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Switch to to-do type"
|
||||
msgstr "Schakelen tussen notitie en taak"
|
||||
msgstr "Overschakelen naar todo-type"
|
||||
|
||||
msgid "Copy Markdown link"
|
||||
msgstr "Markdownlink kopiëren"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Delete note \"%s\"?"
|
||||
msgstr "Notities verwijderen?"
|
||||
msgstr "Notitie “%s” verwijderen?"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Delete these %d notes?"
|
||||
msgstr "Deze notities verwijderen?"
|
||||
msgstr "Deze %d notities verwijderen?"
|
||||
|
||||
msgid ""
|
||||
"Type a note title to jump to it. Or type # followed by a tag name, or @ "
|
||||
"followed by a notebook name."
|
||||
msgstr ""
|
||||
"Typ de titel van een notitie om er naartoe te springen. Of typ # gevolgd "
|
||||
"door de naam van een label, of @ gevolgd door de naam van een notitieboek."
|
||||
|
||||
msgid "Goto Anything..."
|
||||
msgstr ""
|
||||
msgstr "Ga naar alles…"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Usage: %s"
|
||||
@@ -1357,6 +1351,7 @@ msgstr "De synchronisatie loopt al. Status: %s"
|
||||
msgid ""
|
||||
"Unknown item type downloaded - please upgrade Joplin to the latest version"
|
||||
msgstr ""
|
||||
"Onbekend type item gedownload - graag Joplin upgraden naar de laatste versie"
|
||||
|
||||
msgid "Encrypted"
|
||||
msgstr "Versleuteld"
|
||||
@@ -1400,6 +1395,9 @@ msgid ""
|
||||
"to it before syncing, otherwise all files will be removed! See the FAQ for "
|
||||
"more details: %s"
|
||||
msgstr ""
|
||||
"Let op: Als je deze locatie wijzigt, zorg dan dat je eerst alle inhoud hier "
|
||||
"naartoe kopieert voor synchronisatie. Anders worden alle bestanden "
|
||||
"verwijderd! Zie de FAQ voor meer details: %s"
|
||||
|
||||
msgid "Synchronisation target"
|
||||
msgstr "Synchronisatiedoel"
|
||||
@@ -1434,25 +1432,29 @@ msgid "WebDAV password"
|
||||
msgstr "WebDAV-wachtwoord"
|
||||
|
||||
msgid "Attachment download behaviour"
|
||||
msgstr ""
|
||||
msgstr "Gedrag bijlagen downloaden"
|
||||
|
||||
msgid ""
|
||||
"In \"Manual\" mode, attachments are downloaded only when you click on them. "
|
||||
"In \"Auto\", they are downloaded when you open the note. In \"Always\", all "
|
||||
"the attachments are downloaded whether you open the note or not."
|
||||
msgstr ""
|
||||
"In de mode “Handmatig” worden bijlagen alleen gedownload als je hen "
|
||||
"aanklikt. In “Auto” worden ze gedownload zodra je de notitie opent. In "
|
||||
"“Altijd” worden bijlagen altijd gedownload, of je de notitie nu opent of "
|
||||
"niet."
|
||||
|
||||
msgid "Always"
|
||||
msgstr ""
|
||||
msgstr "Altijd"
|
||||
|
||||
msgid "Manual"
|
||||
msgstr ""
|
||||
msgstr "Handmatig"
|
||||
|
||||
msgid "Auto"
|
||||
msgstr ""
|
||||
msgstr "Auto"
|
||||
|
||||
msgid "Max concurrent connections"
|
||||
msgstr ""
|
||||
msgstr "Max gelijktijdige verbindingen"
|
||||
|
||||
msgid "Language"
|
||||
msgstr "Taal"
|
||||
@@ -1484,9 +1486,8 @@ msgstr "Notities sorteren op"
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Sorteervolgorde omdraaien"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Sort notebooks by"
|
||||
msgstr "Notities sorteren op"
|
||||
msgstr "Notitieboeken sorteren op"
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Locatie opslaan in notities"
|
||||
@@ -1504,41 +1505,40 @@ msgid "When creating a new note:"
|
||||
msgstr "Bij het creëren van een nieuwe notitie:"
|
||||
|
||||
msgid "Enable soft breaks"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen zacht afbreken"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Enable math expressions"
|
||||
msgstr "Versleuteling inschakelen"
|
||||
msgstr "Inschakelen wiskundige expressies"
|
||||
|
||||
msgid "Enable ==mark== syntax"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen ==mark== syntaxis"
|
||||
|
||||
msgid "Enable footnotes"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen voetnoten"
|
||||
|
||||
msgid "Enable table of contents extension"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen inhoudsopgave"
|
||||
|
||||
msgid "Enable ~sub~ syntax"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen ~sub~ syntaxis"
|
||||
|
||||
msgid "Enable ^sup^ syntax"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen ^sup^ syntaxis"
|
||||
|
||||
msgid "Enable deflist syntax"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen deflist syntaxis"
|
||||
|
||||
msgid "Enable abbreviation syntax"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen afkortingen syntaxis"
|
||||
|
||||
msgid "Enable markdown emoji"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen markdown emoji"
|
||||
|
||||
msgid "Enable ++insert++ syntax"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen ++insert++ syntaxis"
|
||||
|
||||
msgid "Enable multimarkdown table extension"
|
||||
msgstr ""
|
||||
msgstr "Inschakelen multimarkdown tabel extensie"
|
||||
|
||||
msgid "Show tray icon"
|
||||
msgstr "Systeemvakpictogram tonen"
|
||||
@@ -1551,16 +1551,18 @@ msgid ""
|
||||
"this setting so that your notes are constantly being synchronised, thus "
|
||||
"reducing the number of conflicts."
|
||||
msgstr ""
|
||||
"Dit zal Joplin toestaan in de achtergrond te werken. Het is aanbevolen deze "
|
||||
"instelling in te schakelen, zodat je notities constant worden "
|
||||
"gesynchroniseerd, waardoor het aantal conflicten wordt beperkt."
|
||||
|
||||
msgid "Start application minimised in the tray icon"
|
||||
msgstr ""
|
||||
msgstr "Start applicatie geminimaliseerd in het systeemvak"
|
||||
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Globaal zoompercentage"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Editor font size"
|
||||
msgstr "Lettertype van bewerker"
|
||||
msgstr "Lettergrootte van bewerker"
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr "Lettertype van bewerker"
|
||||
@@ -1577,11 +1579,11 @@ msgid "Automatically update the application"
|
||||
msgstr "Applicatie automatisch bijwerken"
|
||||
|
||||
msgid "Get pre-releases when checking for updates"
|
||||
msgstr ""
|
||||
msgstr "Verkrijg pre-releases bij controleren op updates"
|
||||
|
||||
#, javascript-format
|
||||
msgid "See the pre-release page for more details: %s"
|
||||
msgstr ""
|
||||
msgstr "Zie de pre-release pagina voor meer details: %s"
|
||||
|
||||
msgid "Synchronisation interval"
|
||||
msgstr "Synchronisatietussenpoos"
|
||||
@@ -1630,49 +1632,44 @@ msgstr ""
|
||||
msgid "Ignore TLS certificate errors"
|
||||
msgstr "TLS-certificaatfouten negeren"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Enable note history"
|
||||
msgstr "Versleuteling inschakelen"
|
||||
msgstr "Inschakelen geschiedenis van notities"
|
||||
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
msgstr "dagen"
|
||||
|
||||
#, javascript-format
|
||||
msgid "%d days"
|
||||
msgstr ""
|
||||
msgstr "%d dagen"
|
||||
|
||||
msgid "Keep note history for"
|
||||
msgstr ""
|
||||
msgstr "Bewaar geschiedenis van notities voor"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Ongeldige optie: \"%s\". Geldige waarden zijn: %s."
|
||||
|
||||
#, fuzzy
|
||||
msgid "General"
|
||||
msgstr "Algemene opties"
|
||||
msgstr "Algemeen"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Synchronisation"
|
||||
msgstr "Synchronisatiestatus"
|
||||
msgstr "Synchronisatie"
|
||||
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
msgstr "Verschijningsvorm"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Note"
|
||||
msgstr "Notitieboeken"
|
||||
msgstr "Notitie"
|
||||
|
||||
msgid "Plugins"
|
||||
msgstr ""
|
||||
msgstr "Plugins"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Application"
|
||||
msgstr "Sluit de applicatie af."
|
||||
msgstr "Applicatie"
|
||||
|
||||
#, javascript-format
|
||||
msgid "The tag \"%s\" already exists. Please choose a different name."
|
||||
msgstr ""
|
||||
msgstr "Het label “%s” bestaat al. Kies een andere naam."
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Joplin-exportbestand"
|
||||
@@ -1686,9 +1683,8 @@ msgstr "Joplin-exportmap"
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Evernote-exportbestand"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Json Export Directory"
|
||||
msgstr "Joplin-exportmap"
|
||||
msgstr "JSON-exportmap"
|
||||
|
||||
msgid "File"
|
||||
msgstr "Bestand"
|
||||
@@ -1720,7 +1716,7 @@ msgstr ""
|
||||
"Geef het notitieboek op waar de notities naar moeten worden geïmporteerd."
|
||||
|
||||
msgid "Restored Notes"
|
||||
msgstr ""
|
||||
msgstr "Herstelde notities"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "Items die niet kunnen worden gesynchroniseerd"
|
||||
@@ -1734,23 +1730,25 @@ msgstr ""
|
||||
"synchronisatiedoel. Als je deze items wilt vinden, moet je zoeken naar de "
|
||||
"titel of ID ervan (welke hierboven tussen haakjes wordt getoond)."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "%s (%s) could not be uploaded: %s"
|
||||
msgstr "Dit bestand kan niet worden geopend: %s"
|
||||
msgstr "%s (%s) kon niet worden geupload: %s"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Item \"%s\" could not be downloaded: %s"
|
||||
msgstr "Dit bestand kan niet worden geopend: %s"
|
||||
msgstr "Item “%s” kan niet worden gedownload: %s"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Items that cannot be decrypted"
|
||||
msgstr "Items die niet kunnen worden gesynchroniseerd"
|
||||
msgstr "Items die niet kunnen worden ontsleuteld"
|
||||
|
||||
msgid ""
|
||||
"Joplin failed to decrypt these items multiple times, possibly because they "
|
||||
"are corrupted or too large. These items will remain on the device but Joplin "
|
||||
"will no longer attempt to decrypt them."
|
||||
msgstr ""
|
||||
"Joplin kon deze items meermaals niet ontsleutelen, mogelijk omdat ze "
|
||||
"beschadigd of te groot zijn. Deze items blijven op het apparaat, maar Joplin "
|
||||
"zal niet langer proberen ze te ontsleutelen."
|
||||
|
||||
msgid "Sync status (synced items / total items)"
|
||||
msgstr ""
|
||||
@@ -1787,10 +1785,10 @@ msgid "On %s: %s"
|
||||
msgstr "Op %s: %s"
|
||||
|
||||
msgid "Permission to use camera"
|
||||
msgstr ""
|
||||
msgstr "Toestemming om de camera te gebruiken"
|
||||
|
||||
msgid "Your permission to use your camera is required."
|
||||
msgstr ""
|
||||
msgstr "Je toestemming om de camera te gebruiken is vereist."
|
||||
|
||||
msgid "There are currently no notes. Create one by clicking on the (+) button."
|
||||
msgstr ""
|
||||
@@ -1822,12 +1820,11 @@ msgstr "%d notities verplaatsen naar notitieboek \"%s\"?"
|
||||
msgid "Press to set the decryption password."
|
||||
msgstr "Druk om het ontsleutelwachtwoord in te stellen."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Clear alarm"
|
||||
msgstr "Alarm instellen"
|
||||
msgstr "Alarm wissen"
|
||||
|
||||
msgid "Save alarm"
|
||||
msgstr "Alarm opslaam"
|
||||
msgstr "Alarm opslaan"
|
||||
|
||||
msgid "Select date"
|
||||
msgstr "Datum kiezen"
|
||||
@@ -1838,22 +1835,21 @@ msgstr "Bevestigen"
|
||||
msgid "Cancel synchronisation"
|
||||
msgstr "Synchronisatie annuleren"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Checking... Please wait."
|
||||
msgstr "Bezig met annuleren... Even geduld."
|
||||
msgstr "Controleren… Even geduld."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Success! Synchronisation configuration appears to be correct."
|
||||
msgstr "Synchronisatieconfiguratie controleren"
|
||||
msgstr "Succes! Configuratie van synchronisatie lijkt correct te zijn."
|
||||
|
||||
msgid ""
|
||||
"Error. Please check that URL, username, password, etc. are correct and that "
|
||||
"the sync target is accessible. The reported error was:"
|
||||
msgstr ""
|
||||
"Fout. Controleer of de URL, gebruikersnaam, wachtwoord, etc. kloppen en dat "
|
||||
"het synchronisatiedoel toegankelijk is. De gemelde fout :"
|
||||
|
||||
#, fuzzy
|
||||
msgid "The application has been authorised!"
|
||||
msgstr "De applicatie is geautoriseerd."
|
||||
msgstr "De applicatie is geautoriseerd!"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
@@ -1863,10 +1859,15 @@ msgid ""
|
||||
"\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
"Kon applicatie niet autoriseren:\n"
|
||||
"\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"Probeer opnieuw."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "Decrypted items: %s / %s"
|
||||
msgstr "Bezig met ontsleutelen van items: %d/%d"
|
||||
msgstr "Ontsleutelde items: %s / %s"
|
||||
|
||||
msgid "New tags:"
|
||||
msgstr "Nieuwe labels:"
|
||||
@@ -1874,9 +1875,8 @@ msgstr "Nieuwe labels:"
|
||||
msgid "Type new tags or select from list"
|
||||
msgstr "Typ nieuwe labels of kies ze uit de lijst"
|
||||
|
||||
#, fuzzy
|
||||
msgid "More information"
|
||||
msgstr "Configuratie"
|
||||
msgstr "Meer informatie"
|
||||
|
||||
msgid ""
|
||||
"To work correctly, the app needs the following permissions. Please enable "
|
||||
@@ -1904,17 +1904,17 @@ msgstr "Joplin-website"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Database v%s"
|
||||
msgstr ""
|
||||
msgstr "Database v%s"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
#, javascript-format
|
||||
msgid "FTS enabled: %d"
|
||||
msgstr "Te verwijderen: %d"
|
||||
msgstr "FTS ingeschakeld: %d"
|
||||
|
||||
msgid "Login with Dropbox"
|
||||
msgstr "Inloggen met Dropbox"
|
||||
|
||||
msgid "Enter code here"
|
||||
msgstr ""
|
||||
msgstr "Code hier invoeren"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Master Key %s"
|
||||
@@ -1965,15 +1965,14 @@ msgstr "De mobiele Joplin-app ondersteunt momenteel niet dit soort links: %s"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Links with protocol \"%s\" are not supported"
|
||||
msgstr ""
|
||||
msgstr "Links met protocol “%s” worden niet ondersteund"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unsupported image type: %s"
|
||||
msgstr "Niet-ondersteunde afbeeldingssoort: %s"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Take photo"
|
||||
msgstr "Foto bijvoegen"
|
||||
msgstr "Foto maken"
|
||||
|
||||
msgid "Attach photo"
|
||||
msgstr "Foto bijvoegen"
|
||||
@@ -2000,7 +1999,7 @@ msgid "View on map"
|
||||
msgstr "Tonen op kaart"
|
||||
|
||||
msgid "Go to source URL"
|
||||
msgstr ""
|
||||
msgstr "Ga naar bron-URL"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Bewerken"
|
||||
|
@@ -189,6 +189,39 @@ describe('services_rest_Api', function() {
|
||||
done();
|
||||
});
|
||||
|
||||
it('should create todos', async (done) => {
|
||||
let response = null;
|
||||
const f = await Folder.save({ title: "stuff to do" });
|
||||
|
||||
response = await api.route('POST', 'notes', null, JSON.stringify({
|
||||
title: 'testing',
|
||||
parent_id: f.id,
|
||||
is_todo: 1
|
||||
}));
|
||||
expect(response.is_todo).toBe(1);
|
||||
|
||||
response = await api.route('POST', 'notes', null, JSON.stringify({
|
||||
title: 'testing 2',
|
||||
parent_id: f.id,
|
||||
is_todo: 0
|
||||
}));
|
||||
expect(response.is_todo).toBe(0);
|
||||
|
||||
response = await api.route('POST', 'notes', null, JSON.stringify({
|
||||
title: 'testing 3',
|
||||
parent_id: f.id,
|
||||
}));
|
||||
expect(response.is_todo).toBeUndefined();
|
||||
|
||||
response = await api.route('POST', 'notes', null, JSON.stringify({
|
||||
title: 'testing 4',
|
||||
parent_id: f.id,
|
||||
is_todo: '1'
|
||||
}));
|
||||
expect(response.is_todo).toBe(1);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should create folders with supplied ID', async (done) => {
|
||||
const response = await api.route('POST', 'folders', null, JSON.stringify({
|
||||
id: '12345678123456781234567812345678',
|
||||
@@ -316,4 +349,4 @@ describe('services_rest_Api', function() {
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@@ -512,12 +512,20 @@ class Application extends BaseApplication {
|
||||
|
||||
function _showAbout() {
|
||||
const p = packageInfo;
|
||||
let gitInfo = '';
|
||||
if ("git" in p) {
|
||||
gitInfo = _('Revision: %s (%s)', p.git.hash, p.git.branch);
|
||||
}
|
||||
let message = [
|
||||
p.description,
|
||||
'',
|
||||
'Copyright © 2016-2019 Laurent Cozic',
|
||||
_('%s %s (%s, %s)', p.name, p.version, Setting.value('env'), process.platform),
|
||||
];
|
||||
if (!!gitInfo) {
|
||||
message.push("\n" + gitInfo);
|
||||
console.info(gitInfo);
|
||||
}
|
||||
bridge().showInfoMessageBox(message.join('\n'), {
|
||||
icon: bridge().electronApp().buildDir() + '/icons/32x32.png',
|
||||
});
|
||||
|
@@ -1,4 +1,5 @@
|
||||
const fs = require('fs-extra');
|
||||
const execSync = require('child_process').execSync;
|
||||
|
||||
// Electron Builder strip off certain important keys from package.json, which we need, in particular build.appId
|
||||
// so this script is used to preserve the keys that we need.
|
||||
@@ -16,6 +17,19 @@ const appId = packageInfo.build.appId;
|
||||
delete packageInfo.build;
|
||||
packageInfo.build = { appId: appId };
|
||||
|
||||
let branch;
|
||||
let hash;
|
||||
try {
|
||||
branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
|
||||
hash = execSync('git log --pretty="%h" -1').toString().trim();
|
||||
}
|
||||
catch(err) {
|
||||
console.warn("Could not get git info", err);
|
||||
}
|
||||
if (typeof branch !== 'undefined' && typeof hash !== 'undefined') {
|
||||
packageInfo.git = { branch: branch, hash: hash };
|
||||
}
|
||||
|
||||
let fileContent = "// Auto-generated by compile-package-info.js\n// Do not change directly\nconst packageInfo = " + JSON.stringify(packageInfo, null, 4) + ';';
|
||||
fileContent += "\n";
|
||||
fileContent += "module.exports = packageInfo;";
|
||||
|
@@ -62,8 +62,6 @@ class NoteTextComponent extends React.Component {
|
||||
|
||||
this.state = {
|
||||
note: null,
|
||||
noteMetadata: '',
|
||||
showNoteMetadata: false,
|
||||
folder: null,
|
||||
lastSavedNote: null,
|
||||
isLoading: true,
|
||||
@@ -644,10 +642,6 @@ class NoteTextComponent extends React.Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
refreshNoteMetadata(force = null) {
|
||||
return shared.refreshNoteMetadata(this, force);
|
||||
}
|
||||
|
||||
async noteRevisionViewer_onBack() {
|
||||
this.setState({ showRevisions: false });
|
||||
|
||||
@@ -666,10 +660,6 @@ class NoteTextComponent extends React.Component {
|
||||
this.scheduleSave();
|
||||
}
|
||||
|
||||
showMetadata_onPress() {
|
||||
shared.showMetadata_onPress(this);
|
||||
}
|
||||
|
||||
async webview_ipcMessage(event) {
|
||||
const msg = event.channel ? event.channel : '';
|
||||
const args = event.args;
|
||||
|
@@ -28,7 +28,7 @@ Linux | <a href='https://github.com/laurent22/joplin/releases/download/
|
||||
|
||||
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 APK File](https://github.com/laurent22/joplin-android/releases/download/android-v1.0.277/joplin-v1.0.277.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 APK File](https://github.com/laurent22/joplin-android/releases/download/android-v1.0.279/joplin-v1.0.279.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
|
||||
@@ -346,7 +346,7 @@ Please see the [donation page](https://joplinapp.org/donate/) for information on
|
||||
- Also see here for information about [the latest releases and general news](https://discourse.joplinapp.org/c/news).
|
||||
- For bug reports and feature requests, go to the [GitHub Issue Tracker](https://github.com/laurent22/joplin/issues).
|
||||
- The latest news are posted [on the Patreon page](https://www.patreon.com/joplin).
|
||||
- You can also follow us on [the Twitter feed](https://twitter.com/joplinapp).
|
||||
- You can also follow us on <a rel="me" href="https://mastodon.social/@joplinapp">the Mastodon feed</a> or [the Twitter feed](https://twitter.com/joplinapp).
|
||||
|
||||
# Contributing
|
||||
|
||||
@@ -359,7 +359,7 @@ Joplin is currently available in the languages below. If you would like to contr
|
||||
- [Download Poedit](https://poedit.net/), the translation editor, and install it.
|
||||
- [Download the file to be translated](https://raw.githubusercontent.com/laurent22/joplin/master/CliClient/locales/joplin.pot).
|
||||
- In Poedit, open this .pot file, go into the Catalog menu and click Configuration. Change "Country" and "Language" to your own country and language.
|
||||
- From then you can translate the file. Once it is done, please either [open a pull request](https://github.com/laurent22/joplin/pulls) or send the file to [this address](https://raw.githubusercontent.com/laurent22/joplin/master/Assets/Adresse.png).
|
||||
- From then you can translate the file. Once it is done, please either [open a pull request](https://github.com/laurent22/joplin/pulls) or send the file to [this address](https://raw.githubusercontent.com/laurent22/joplin/master/Assets/AdresseTranslation.png).
|
||||
|
||||
This translation will apply to the three applications - desktop, mobile and terminal.
|
||||
|
||||
|
@@ -94,8 +94,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 2097513
|
||||
versionName "1.0.277"
|
||||
versionCode 2097515
|
||||
versionName "1.0.279"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@ const DialogBox = require('react-native-dialogbox').default;
|
||||
// default height.
|
||||
const PADDING_V = 10;
|
||||
|
||||
class ScreenHeaderComponent extends Component {
|
||||
class ScreenHeaderComponent extends React.PureComponent {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -124,7 +124,7 @@ class ScreenHeaderComponent extends Component {
|
||||
titleText: {
|
||||
flex: 1,
|
||||
textAlignVertical: 'center',
|
||||
marginLeft: 0,
|
||||
marginLeft: 10,
|
||||
color: theme.raisedHighlightedColor,
|
||||
fontWeight: 'bold',
|
||||
fontSize: theme.fontSize,
|
||||
@@ -158,7 +158,11 @@ class ScreenHeaderComponent extends Component {
|
||||
}
|
||||
|
||||
async backButton_press() {
|
||||
await BackButtonService.back();
|
||||
if (this.props.noteSelectionEnabled) {
|
||||
this.props.dispatch({ type: 'NOTE_SELECTION_END' });
|
||||
} else {
|
||||
await BackButtonService.back();
|
||||
}
|
||||
}
|
||||
|
||||
searchButton_press() {
|
||||
@@ -311,9 +315,10 @@ class ScreenHeaderComponent extends Component {
|
||||
}
|
||||
|
||||
const titlePickerItems = (mustSelect) => {
|
||||
const folders = this.props.folders.filter(f => f.id !== Folder.conflictFolderId());
|
||||
let output = [];
|
||||
if (mustSelect) output.push({ label: _('Move to notebook...'), value: null });
|
||||
const folderTree = Folder.buildTree(this.props.folders);
|
||||
const folderTree = Folder.buildTree(folders);
|
||||
output = addFolderChildren(folderTree, output, 0);
|
||||
return output;
|
||||
}
|
||||
@@ -373,21 +378,30 @@ class ScreenHeaderComponent extends Component {
|
||||
</TouchableOpacity>
|
||||
) : null;
|
||||
|
||||
const showSideMenuButton = this.props.showSideMenuButton !== false && !this.props.noteSelectionEnabled;
|
||||
const showSearchButton = this.props.showSearchButton !== false && !this.props.noteSelectionEnabled;
|
||||
const showSideMenuButton = !!this.props.showSideMenuButton && !this.props.noteSelectionEnabled;
|
||||
const showSearchButton = !!this.props.showSearchButton && !this.props.noteSelectionEnabled;
|
||||
const showContextMenuButton = this.props.showContextMenuButton !== false;
|
||||
const showBackButton = !!this.props.noteSelectionEnabled || this.props.showBackButton !== false;
|
||||
|
||||
let backButtonDisabled = !this.props.historyCanGoBack;
|
||||
if (!!this.props.noteSelectionEnabled) backButtonDisabled = false;
|
||||
|
||||
const titleComp = createTitleComponent();
|
||||
const sideMenuComp = !showSideMenuButton ? null : sideMenuButton(this.styles(), () => this.sideMenuButton_press());
|
||||
const backButtonComp = backButton(this.styles(), () => this.backButton_press(), !this.props.historyCanGoBack);
|
||||
const backButtonComp = !showBackButton ? null : backButton(this.styles(), () => this.backButton_press(), backButtonDisabled);
|
||||
const searchButtonComp = !showSearchButton ? null : searchButton(this.styles(), () => this.searchButton_press());
|
||||
const deleteButtonComp = this.props.noteSelectionEnabled ? deleteButton(this.styles(), () => this.deleteButton_press()) : null;
|
||||
const sortButtonComp = this.props.sortButton_press ? sortButton(this.styles(), () => this.props.sortButton_press()) : null;
|
||||
const sortButtonComp = !this.props.noteSelectionEnabled && this.props.sortButton_press ? sortButton(this.styles(), () => this.props.sortButton_press()) : null;
|
||||
const windowHeight = Dimensions.get('window').height - 50;
|
||||
|
||||
const contextMenuStyle = { paddingTop: PADDING_V, paddingBottom: PADDING_V };
|
||||
|
||||
// HACK: if this button is removed during selection mode, the header layout is broken, so for now just make it 1 pixel large (normally it should be hidden)
|
||||
if (!!this.props.noteSelectionEnabled) contextMenuStyle.width = 1;
|
||||
|
||||
const menuComp = !menuOptionComponents.length || !showContextMenuButton ? null : (
|
||||
<Menu onSelect={(value) => this.menu_select(value)} style={this.styles().contextMenu}>
|
||||
<MenuTrigger style={{ paddingTop: PADDING_V, paddingBottom: PADDING_V }}>
|
||||
<MenuTrigger style={contextMenuStyle}>
|
||||
<Icon name='md-more' style={this.styles().contextMenuTrigger} />
|
||||
</MenuTrigger>
|
||||
<MenuOptions>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const React = require('react'); const Component = React.Component;
|
||||
const { Platform, TouchableOpacity, Linking, View, Switch, StyleSheet, Text, Button, ScrollView, TextInput } = require('react-native');
|
||||
const { Platform, TouchableOpacity, Linking, View, Switch, StyleSheet, Text, Button, ScrollView, TextInput, Alert } = require('react-native');
|
||||
const { connect } = require('react-redux');
|
||||
const { ScreenHeader } = require('lib/components/screen-header.js');
|
||||
const { _, setLocale } = require('lib/locale.js');
|
||||
@@ -14,6 +14,7 @@ const NavService = require('lib/services/NavService.js');
|
||||
const VersionInfo = require('react-native-version-info').default;
|
||||
const { ReportService } = require('lib/services/report.js');
|
||||
const { time } = require('lib/time-utils');
|
||||
const SearchEngine = require('lib/services/SearchEngine');
|
||||
const RNFS = require('react-native-fs');
|
||||
|
||||
import Slider from '@react-native-community/slider';
|
||||
@@ -78,6 +79,12 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
this.setState({ creatingReport: false });
|
||||
}
|
||||
|
||||
this.fixSearchEngineIndexButtonPress_ = async () => {
|
||||
this.setState({ fixingSearchIndex: true });
|
||||
await SearchEngine.instance().rebuildIndex();
|
||||
this.setState({ fixingSearchIndex: false });
|
||||
}
|
||||
|
||||
this.logButtonPress_ = () => {
|
||||
NavService.go('Log');
|
||||
}
|
||||
@@ -125,6 +132,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
sliderUnits: {
|
||||
color: theme.color,
|
||||
fontSize: theme.fontSize,
|
||||
marginRight: 10,
|
||||
},
|
||||
settingDescriptionText: {
|
||||
color: theme.color,
|
||||
@@ -190,6 +198,15 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
renderButton(key, title, clickHandler, options = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
let descriptionComp = null;
|
||||
if (options.description) {
|
||||
descriptionComp = (
|
||||
<View style={{flex:1, marginTop: 10}}>
|
||||
<Text style={this.styles().descriptionText}>{options.description}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View key={key} style={this.styles().settingContainer}>
|
||||
<View style={{flex:1, flexDirection: 'column'}}>
|
||||
@@ -197,6 +214,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
<Button title={title} onPress={clickHandler} disabled={!!options.disabled}/>
|
||||
</View>
|
||||
{ options.statusComp }
|
||||
{ descriptionComp }
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
@@ -229,7 +247,7 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
if (section.name === 'sync') {
|
||||
settingComps.push(this.renderButton('e2ee_config_button', _('Encryption Config') + ' ▶', this.e2eeConfig_));
|
||||
settingComps.push(this.renderButton('e2ee_config_button', _('Encryption Config'), this.e2eeConfig_));
|
||||
}
|
||||
|
||||
const headerWrapperStyle = this.styles().headerWrapperStyle;
|
||||
@@ -307,9 +325,9 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
return (
|
||||
<View key={key} style={this.styles().settingContainer}>
|
||||
<Text key="label" style={this.styles().settingText}>{md.label()}</Text>
|
||||
<View style={{display:'flex', flexDirection: 'column', alignItems: 'center', flex:1}}>
|
||||
<Slider key="control" minimumTrackTintColor={theme.color} maximumTrackTintColor={theme.color} style={{width:'100%'}} step={md.step} minimumValue={md.minimum} maximumValue={md.maximum} value={value} onValueChange={(value) => updateSettingValue(key, value)} />
|
||||
<View style={{display:'flex', flexDirection: 'row', alignItems: 'center', flex:1}}>
|
||||
<Text style={this.styles().sliderUnits}>{unitLabel}</Text>
|
||||
<Slider key="control" minimumTrackTintColor={theme.color} maximumTrackTintColor={theme.color} style={{flex:1}} step={md.step} minimumValue={md.minimum} maximumValue={md.maximum} value={value} onValueChange={(value) => updateSettingValue(key, value)} />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
@@ -332,11 +350,12 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
|
||||
const settingComps = shared.settingsToComponents2(this, 'mobile', settings);
|
||||
|
||||
settingComps.push(this.renderHeader('moreInfo', _('Tools')));
|
||||
settingComps.push(this.renderHeader('tools', _('Tools')));
|
||||
|
||||
settingComps.push(this.renderButton('status_button', _('Sync Status') + ' ▶', this.syncStatusButtonPress_));
|
||||
settingComps.push(this.renderButton('log_button', _('Log') + ' ▶', this.logButtonPress_));
|
||||
settingComps.push(this.renderButton('status_button', _('Sync Status'), this.syncStatusButtonPress_));
|
||||
settingComps.push(this.renderButton('log_button', _('Log'), this.logButtonPress_));
|
||||
settingComps.push(this.renderButton('export_report_button', this.state.creatingReport ? _('Creating report...') : _('Export Debug Report'), this.exportDebugButtonPress_, { disabled: this.state.creatingReport }));
|
||||
settingComps.push(this.renderButton('fix_search_engine_index', this.state.fixingSearchIndex ? _('Fixing search index...') : _('Fix search index'), this.fixSearchEngineIndexButtonPress_, { disabled: this.state.fixingSearchIndex, description: _('Use this to rebuild the search index if there is a problem with search. It may take some times depending on the number of notes.') }));
|
||||
|
||||
settingComps.push(this.renderHeader('moreInfo', _('More information')));
|
||||
|
||||
@@ -403,6 +422,8 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
||||
<ScreenHeader
|
||||
title={_('Configuration')}
|
||||
showSaveButton={true}
|
||||
showSearchButton={false}
|
||||
showSideMenuButton={false}
|
||||
saveButtonDisabled={!this.state.changedSettingKeys.length}
|
||||
onSaveButtonPress={this.saveButton_press}
|
||||
/>
|
||||
|
@@ -35,7 +35,8 @@ class FolderScreenComponent extends BaseScreenComponent {
|
||||
let styles = {
|
||||
textInput: {
|
||||
color: theme.color,
|
||||
paddingLeft: 10,
|
||||
paddingLeft: theme.marginLeft,
|
||||
marginTop: theme.marginTop,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -112,8 +113,10 @@ class FolderScreenComponent extends BaseScreenComponent {
|
||||
showSaveButton={true}
|
||||
saveButtonDisabled={saveButtonDisabled}
|
||||
onSaveButtonPress={() => this.saveFolderButton_press()}
|
||||
showSideMenuButton={false}
|
||||
showSearchButton={false}
|
||||
/>
|
||||
<TextInput underlineColorAndroid={theme.strongDividerColor} selectionColor={theme.textSelectionColor} style={this.styles().textInput} autoFocus={true} value={this.state.folder.title} onChangeText={(text) => this.title_changeText(text)} />
|
||||
<TextInput placeholder={_('Enter notebook title')} underlineColorAndroid={theme.strongDividerColor} selectionColor={theme.textSelectionColor} style={this.styles().textInput} autoFocus={true} value={this.state.folder.title} onChangeText={(text) => this.title_changeText(text)} />
|
||||
<dialogs.DialogBox ref={dialogbox => { this.dialogbox = dialogbox }}/>
|
||||
</View>
|
||||
);
|
||||
|
@@ -4,10 +4,12 @@ const { connect } = require('react-redux');
|
||||
const { uuid } = require('lib/uuid.js');
|
||||
const RNFS = require('react-native-fs');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const ObjectUtils = require('lib/ObjectUtils.js');
|
||||
const BaseItem = require('lib/models/BaseItem.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const md5 = require('md5');
|
||||
const { BackButtonService } = require('lib/services/back-button.js');
|
||||
const NavService = require('lib/services/NavService.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
@@ -52,8 +54,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
this.state = {
|
||||
note: Note.new(),
|
||||
mode: 'view',
|
||||
noteMetadata: '',
|
||||
showNoteMetadata: false,
|
||||
folder: null,
|
||||
lastSavedNote: null,
|
||||
isLoading: true,
|
||||
@@ -75,6 +75,8 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
HACK_webviewLoadingState: 0,
|
||||
};
|
||||
|
||||
this.doFocusUpdate_ = false;
|
||||
|
||||
// iOS doesn't support multiline text fields properly so disable it
|
||||
this.enableMultilineTitle_ = Platform.OS !== 'ios';
|
||||
|
||||
@@ -183,14 +185,25 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
this.takePhoto_onPress = this.takePhoto_onPress.bind(this);
|
||||
this.cameraView_onPhoto = this.cameraView_onPhoto.bind(this);
|
||||
this.cameraView_onCancel = this.cameraView_onCancel.bind(this);
|
||||
this.properties_onPress = this.properties_onPress.bind(this);
|
||||
this.onMarkForDownload = this.onMarkForDownload.bind(this);
|
||||
this.sideMenuOptions = this.sideMenuOptions.bind(this);
|
||||
this.folderPickerOptions_valueChanged = this.folderPickerOptions_valueChanged.bind(this);
|
||||
this.saveNoteButton_press = this.saveNoteButton_press.bind(this);
|
||||
this.onAlarmDialogAccept = this.onAlarmDialogAccept.bind(this);
|
||||
this.onAlarmDialogReject = this.onAlarmDialogReject.bind(this);
|
||||
this.todoCheckbox_change = this.todoCheckbox_change.bind(this);
|
||||
this.titleTextInput_contentSizeChange = this.titleTextInput_contentSizeChange.bind(this);
|
||||
this.title_changeText = this.title_changeText.bind(this);
|
||||
}
|
||||
|
||||
styles() {
|
||||
const themeId = this.props.theme;
|
||||
const theme = themeStyle(themeId);
|
||||
|
||||
if (this.styles_[themeId]) return this.styles_[themeId];
|
||||
const cacheKey = [themeId, this.state.titleTextInputHeight, this.state.HACK_webviewLoadingState].join('_');
|
||||
|
||||
if (this.styles_[cacheKey]) return this.styles_[cacheKey];
|
||||
this.styles_ = {};
|
||||
|
||||
let styles = {
|
||||
@@ -210,10 +223,12 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
paddingTop: theme.marginTop,
|
||||
paddingBottom: theme.marginBottom,
|
||||
},
|
||||
metadata: {
|
||||
paddingLeft: globalStyle.marginLeft,
|
||||
paddingRight: globalStyle.marginRight,
|
||||
checkbox: {
|
||||
color: theme.color,
|
||||
paddingRight: 10,
|
||||
paddingLeft: theme.marginLeft,
|
||||
paddingTop: 10, // Added for iOS (Not needed for Android??)
|
||||
paddingBottom: 10, // Added for iOS (Not needed for Android??)
|
||||
},
|
||||
};
|
||||
|
||||
@@ -229,8 +244,23 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
styles.titleContainerTodo = Object.assign({}, styles.titleContainer);
|
||||
styles.titleContainerTodo.paddingLeft = 0;
|
||||
|
||||
this.styles_[themeId] = StyleSheet.create(styles);
|
||||
return this.styles_[themeId];
|
||||
styles.titleTextInput = {
|
||||
flex: 1,
|
||||
marginTop: 0,
|
||||
paddingLeft: 0,
|
||||
color: theme.color,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
fontWeight: 'bold',
|
||||
fontSize: theme.fontSize,
|
||||
paddingTop: 10, // Added for iOS (Not needed for Android??)
|
||||
paddingBottom: 10, // Added for iOS (Not needed for Android??)
|
||||
};
|
||||
|
||||
if (this.enableMultilineTitle_) styles.titleTextInput.height = this.state.titleTextInputHeight;
|
||||
if (this.state.HACK_webviewLoadingState === 1) styles.titleTextInput.marginTop = 1;
|
||||
|
||||
this.styles_[cacheKey] = StyleSheet.create(styles);
|
||||
return this.styles_[cacheKey];
|
||||
}
|
||||
|
||||
isModified() {
|
||||
@@ -251,15 +281,18 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
await ResourceFetcher.instance().markForDownload(resourceIds);
|
||||
}
|
||||
|
||||
this.refreshNoteMetadata();
|
||||
this.focusUpdate();
|
||||
}
|
||||
|
||||
onMarkForDownload(event) {
|
||||
ResourceFetcher.instance().markForDownload(event.resourceId);
|
||||
}
|
||||
|
||||
refreshNoteMetadata(force = null) {
|
||||
return shared.refreshNoteMetadata(this, force);
|
||||
componentDidUpdate() {
|
||||
if (this.doFocusUpdate_) {
|
||||
this.doFocusUpdate_ = false;
|
||||
this.focusUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -276,10 +309,23 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
title_changeText(text) {
|
||||
shared.noteComponent_change(this, 'title', text);
|
||||
this.setState({ newAndNoTitleChangeNoteId: null });
|
||||
this.scheduleSave();
|
||||
}
|
||||
|
||||
body_changeText(text) {
|
||||
shared.noteComponent_change(this, 'body', text);
|
||||
this.scheduleSave();
|
||||
}
|
||||
|
||||
scheduleSave() {
|
||||
if (this.scheduleSaveIID_) {
|
||||
clearTimeout(this.scheduleSaveIID_);
|
||||
this.scheduleSaveIID_ = null;
|
||||
}
|
||||
|
||||
this.scheduleSaveIID_ = setTimeout(async () => {
|
||||
await shared.saveNoteButton_press(this);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
async saveNoteButton_press(folderId = null) {
|
||||
@@ -455,6 +501,8 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
this.setState({ note: newNote });
|
||||
|
||||
this.refreshResource(resource);
|
||||
|
||||
this.scheduleSave();
|
||||
}
|
||||
|
||||
async attachPhoto_onPress() {
|
||||
@@ -503,6 +551,15 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
});
|
||||
}
|
||||
|
||||
properties_onPress() {
|
||||
this.props.dispatch({
|
||||
type: 'NOTE_SIDE_MENU_OPTIONS_SET',
|
||||
options: this.sideMenuOptions(),
|
||||
});
|
||||
|
||||
this.props.dispatch({ type: 'SIDE_MENU_OPEN' });
|
||||
}
|
||||
|
||||
setAlarm_onPress() {
|
||||
this.setState({ alarmDialogShown: true });
|
||||
}
|
||||
@@ -520,10 +577,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
this.setState({ alarmDialogShown: false });
|
||||
}
|
||||
|
||||
showMetadata_onPress() {
|
||||
shared.showMetadata_onPress(this);
|
||||
}
|
||||
|
||||
async showOnMap_onPress() {
|
||||
if (!this.state.note.id) return;
|
||||
|
||||
@@ -552,11 +605,34 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
Clipboard.setString(Note.markdownTag(note));
|
||||
}
|
||||
|
||||
sideMenuOptions() {
|
||||
const note = this.state.note;
|
||||
if (!note) return [];
|
||||
|
||||
const output = [];
|
||||
|
||||
const createdDateString = time.unixMsToLocalDateTime(note.user_created_time);
|
||||
const updatedDateString = time.unixMsToLocalDateTime(note.user_updated_time);
|
||||
|
||||
output.push({ title: _('Created: %s', createdDateString) });
|
||||
output.push({ title: _('Updated: %s', updatedDateString) });
|
||||
output.push({ isDivider: true });
|
||||
|
||||
output.push({ title: _('View on map'), onPress: () => { this.showOnMap_onPress(); } });
|
||||
if (!!note.source_url) output.push({ title: _('Go to source URL'), onPress: () => { this.showSource_onPress(); } });
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
menuOptions() {
|
||||
const note = this.state.note;
|
||||
const isTodo = note && !!note.is_todo;
|
||||
const isSaved = note && note.id;
|
||||
const hasSource = note && note.source_url;
|
||||
|
||||
const cacheKey = md5([isTodo, isSaved].join('_'));
|
||||
if (!this.menuOptionsCache_) this.menuOptionsCache_ = {};
|
||||
|
||||
if (this.menuOptionsCache_[cacheKey]) return this.menuOptionsCache_[cacheKey];
|
||||
|
||||
let output = [];
|
||||
|
||||
@@ -565,10 +641,17 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
let canAttachPicture = true;
|
||||
if (Platform.OS === 'android' && Platform.Version < 21) canAttachPicture = false;
|
||||
if (canAttachPicture) {
|
||||
output.push({ title: _('Take photo'), onPress: () => { this.takePhoto_onPress(); } });
|
||||
output.push({ title: _('Attach photo'), onPress: () => { this.attachPhoto_onPress(); } });
|
||||
output.push({ title: _('Attach any file'), onPress: () => { this.attachFile_onPress(); } });
|
||||
output.push({ isDivider: true });
|
||||
output.push({ title: _('Attach...'), onPress: async () => {
|
||||
const buttonId = await dialogs.pop(this, _('Choose an option'), [
|
||||
{ text: _('Take photo'), id: 'takePhoto' },
|
||||
{ text: _('Attach photo'), id: 'attachPhoto' },
|
||||
{ text: _('Attach any file'), id: 'attachFile' },
|
||||
]);
|
||||
|
||||
if (buttonId === 'takePhoto') this.takePhoto_onPress();
|
||||
if (buttonId === 'attachPhoto') this.attachPhoto_onPress();
|
||||
if (buttonId === 'attachFile') this.attachFile_onPress();
|
||||
}});
|
||||
}
|
||||
|
||||
if (isTodo) {
|
||||
@@ -579,13 +662,12 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
if (isSaved) output.push({ title: _('Tags'), onPress: () => { this.tags_onPress(); } });
|
||||
output.push({ title: isTodo ? _('Convert to note') : _('Convert to todo'), onPress: () => { this.toggleIsTodo_onPress(); } });
|
||||
if (isSaved) output.push({ title: _('Copy Markdown link'), onPress: () => { this.copyMarkdownLink_onPress(); } });
|
||||
output.push({ isDivider: true });
|
||||
output.push({ title: this.state.showNoteMetadata ? _('Hide metadata') : _('Show metadata'), onPress: () => { this.showMetadata_onPress(); } });
|
||||
output.push({ title: _('View on map'), onPress: () => { this.showOnMap_onPress(); } });
|
||||
if (hasSource) output.push({ title: _('Go to source URL'), onPress: () => { this.showSource_onPress(); } });
|
||||
output.push({ isDivider: true });
|
||||
output.push({ title: _('Properties'), onPress: () => { this.properties_onPress(); } });
|
||||
output.push({ title: _('Delete'), onPress: () => { this.deleteNote_onPress(); } });
|
||||
|
||||
this.menuOptionsCache_ = {};
|
||||
this.menuOptionsCache_[cacheKey] = output;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -600,6 +682,49 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
this.setState({ titleTextInputHeight: height });
|
||||
}
|
||||
|
||||
focusUpdate() {
|
||||
this.scheduleFocusUpdateIID_ = null;
|
||||
if (!this.state.note) return;
|
||||
let fieldToFocus = !!this.state.note.is_todo ? 'title' : 'body';
|
||||
if (this.state.mode === 'view') fieldToFocus = '';
|
||||
|
||||
if (fieldToFocus === 'title') this.refs.titleTextField.focus();
|
||||
if (fieldToFocus === 'body') this.refs.noteBodyTextField.focus();
|
||||
}
|
||||
|
||||
async folderPickerOptions_valueChanged(itemValue, itemIndex) {
|
||||
const note = this.state.note;
|
||||
|
||||
if (!note.id) {
|
||||
await this.saveNoteButton_press(itemValue);
|
||||
} else {
|
||||
await Note.moveToFolder(note.id, itemValue);
|
||||
}
|
||||
|
||||
note.parent_id = itemValue;
|
||||
|
||||
const folder = await Folder.load(note.parent_id);
|
||||
|
||||
this.setState({
|
||||
lastSavedNote: Object.assign({}, note),
|
||||
note: note,
|
||||
folder: folder,
|
||||
});
|
||||
}
|
||||
|
||||
folderPickerOptions() {
|
||||
const options = {
|
||||
enabled: true,
|
||||
selectedFolderId: this.state.folder ? this.state.folder.id : null,
|
||||
onValueChange: this.folderPickerOptions_valueChanged,
|
||||
};
|
||||
|
||||
if (this.folderPickerOptions_ && options.selectedFolderId === this.folderPickerOptions_.selectedFolderId) return this.folderPickerOptions_;
|
||||
|
||||
this.folderPickerOptions_ = options;
|
||||
return this.folderPickerOptions_;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.isLoading) {
|
||||
return (
|
||||
@@ -655,20 +780,21 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
}}
|
||||
/>
|
||||
} else {
|
||||
const focusBody = !isNew && !!note.title;
|
||||
// autoFocus={fieldToFocus === 'body'}
|
||||
|
||||
// Note: blurOnSubmit is necessary to get multiline to work.
|
||||
// See https://github.com/facebook/react-native/issues/12717#issuecomment-327001997
|
||||
bodyComponent = (
|
||||
<TextInput
|
||||
autoCapitalize="sentences"
|
||||
autoFocus={focusBody}
|
||||
autoCapitalize="sentences"
|
||||
style={this.styles().bodyTextInput}
|
||||
ref="noteBodyTextField"
|
||||
multiline={true}
|
||||
value={note.body}
|
||||
onChangeText={(text) => this.body_changeText(text)}
|
||||
blurOnSubmit={false}
|
||||
selectionColor={theme.textSelectionColor}
|
||||
placeholder={_('Add body')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -681,10 +807,12 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
icon: 'md-create',
|
||||
onPress: () => {
|
||||
this.setState({ mode: 'edit' });
|
||||
|
||||
this.doFocusUpdate_ = true;
|
||||
},
|
||||
});
|
||||
|
||||
if (this.state.mode == 'edit') return null;//<ActionButton style={{display:'none'}}/>;
|
||||
if (this.state.mode == 'edit') return null;
|
||||
|
||||
return <ActionButton multiStates={true} buttons={buttons} buttonIndex={0} />
|
||||
}
|
||||
@@ -698,47 +826,22 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
const titleContainerStyle = isTodo ? this.styles().titleContainerTodo : this.styles().titleContainer;
|
||||
|
||||
let titleTextInputStyle = {
|
||||
flex: 1,
|
||||
marginTop: 0,
|
||||
paddingLeft: 0,
|
||||
color: theme.color,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
fontWeight: 'bold',
|
||||
fontSize: theme.fontSize,
|
||||
paddingTop: 10, // Added for iOS (Not needed for Android??)
|
||||
paddingBottom: 10, // Added for iOS (Not needed for Android??)
|
||||
};
|
||||
|
||||
if (this.enableMultilineTitle_) titleTextInputStyle.height = this.state.titleTextInputHeight;
|
||||
|
||||
let checkboxStyle = {
|
||||
color: theme.color,
|
||||
paddingRight: 10,
|
||||
paddingLeft: theme.marginLeft,
|
||||
paddingTop: 10, // Added for iOS (Not needed for Android??)
|
||||
paddingBottom: 10, // Added for iOS (Not needed for Android??)
|
||||
}
|
||||
|
||||
if (this.state.HACK_webviewLoadingState === 1) {
|
||||
titleTextInputStyle.marginTop = 1;
|
||||
}
|
||||
|
||||
const dueDate = isTodo && note.todo_due ? new Date(note.todo_due) : null;
|
||||
const dueDate = Note.dueDateObject(note);
|
||||
|
||||
const titleComp = (
|
||||
<View style={titleContainerStyle}>
|
||||
{ isTodo && <Checkbox style={checkboxStyle} checked={!!Number(note.todo_completed)} onChange={(checked) => { this.todoCheckbox_change(checked) }} /> }
|
||||
{ isTodo && <Checkbox style={this.styles().checkbox} checked={!!Number(note.todo_completed)} onChange={this.todoCheckbox_change} /> }
|
||||
<TextInput
|
||||
onContentSizeChange={(event) => this.titleTextInput_contentSizeChange(event)}
|
||||
autoFocus={isNew}
|
||||
onContentSizeChange={this.titleTextInput_contentSizeChange}
|
||||
multiline={this.enableMultilineTitle_}
|
||||
ref="titleTextField"
|
||||
underlineColorAndroid="#ffffff00"
|
||||
autoCapitalize="sentences"
|
||||
style={titleTextInputStyle}
|
||||
style={this.styles().titleTextInput}
|
||||
value={note.title}
|
||||
onChangeText={(text) => this.title_changeText(text)}
|
||||
onChangeText={this.title_changeText}
|
||||
selectionColor={theme.textSelectionColor}
|
||||
placeholder={_('Add title')}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
@@ -748,42 +851,23 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
return (
|
||||
<View style={this.rootStyle(this.props.theme).root}>
|
||||
<ScreenHeader
|
||||
folderPickerOptions={{
|
||||
enabled: true,
|
||||
selectedFolderId: folder ? folder.id : null,
|
||||
onValueChange: async (itemValue, itemIndex) => {
|
||||
if (!note.id) {
|
||||
await this.saveNoteButton_press(itemValue);
|
||||
} else {
|
||||
await Note.moveToFolder(note.id, itemValue);
|
||||
}
|
||||
|
||||
note.parent_id = itemValue;
|
||||
|
||||
const folder = await Folder.load(note.parent_id);
|
||||
|
||||
this.setState({
|
||||
lastSavedNote: Object.assign({}, note),
|
||||
note: note,
|
||||
folder: folder,
|
||||
});
|
||||
},
|
||||
}}
|
||||
folderPickerOptions={this.folderPickerOptions()}
|
||||
menuOptions={this.menuOptions()}
|
||||
showSaveButton={showSaveButton}
|
||||
saveButtonDisabled={saveButtonDisabled}
|
||||
onSaveButtonPress={() => this.saveNoteButton_press()}
|
||||
onSaveButtonPress={this.saveNoteButton_press}
|
||||
showSideMenuButton={false}
|
||||
showSearchButton={false}
|
||||
/>
|
||||
{ titleComp }
|
||||
{ bodyComponent }
|
||||
{ actionButtonComp }
|
||||
{ this.state.showNoteMetadata && <Text style={this.styles().metadata}>{this.state.noteMetadata}</Text> }
|
||||
|
||||
<SelectDateTimeDialog
|
||||
shown={this.state.alarmDialogShown}
|
||||
date={dueDate}
|
||||
onAccept={(date) => this.onAlarmDialogAccept(date) }
|
||||
onReject={() => this.onAlarmDialogReject() }
|
||||
onAccept={this.onAlarmDialogAccept}
|
||||
onReject={this.onAlarmDialogReject}
|
||||
/>
|
||||
|
||||
<DialogBox ref={dialogbox => { this.dialogbox = dialogbox }}/>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const React = require('react'); const Component = React.Component;
|
||||
const { AppState, View, Button, Text } = require('react-native');
|
||||
const { AppState, View, Button, Text, StyleSheet } = require('react-native');
|
||||
const { stateUtils } = require('lib/reducer.js');
|
||||
const { connect } = require('react-redux');
|
||||
const { reg } = require('lib/registry.js');
|
||||
@@ -72,6 +72,25 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
}
|
||||
|
||||
styles() {
|
||||
if (!this.styles_) this.styles_ = {};
|
||||
const themeId = this.props.theme;
|
||||
const theme = themeStyle(themeId);
|
||||
const cacheKey = themeId;
|
||||
|
||||
if (this.styles_[cacheKey]) return this.styles_[cacheKey];
|
||||
this.styles_ = {};
|
||||
|
||||
let styles = {
|
||||
noteList: {
|
||||
flex: 1,
|
||||
},
|
||||
};
|
||||
|
||||
this.styles_[cacheKey] = StyleSheet.create(styles);
|
||||
return this.styles_[cacheKey];
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
await this.refreshNotes();
|
||||
AppState.addEventListener('change', this.onAppStateChange_);
|
||||
@@ -85,6 +104,7 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
if (newProps.notesOrder !== this.props.notesOrder ||
|
||||
newProps.selectedFolderId != this.props.selectedFolderId ||
|
||||
newProps.selectedTagId != this.props.selectedTagId ||
|
||||
newProps.selectedSmartFilterId != this.props.selectedSmartFilterId ||
|
||||
newProps.notesParentType != this.props.notesParentType) {
|
||||
await this.refreshNotes(newProps);
|
||||
}
|
||||
@@ -111,10 +131,12 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
if (source == props.notesSource) return;
|
||||
|
||||
let notes = [];
|
||||
if (props.notesParentType == 'Folder') {
|
||||
if (props.notesParentType === 'Folder') {
|
||||
notes = await Note.previews(props.selectedFolderId, options);
|
||||
} else {
|
||||
} else if (props.notesParentType === 'Tag') {
|
||||
notes = await Tag.notes(props.selectedTagId, options);
|
||||
} else if (props.notesParentType === 'SmartFilter') {
|
||||
notes = await Note.previews(null, options);
|
||||
}
|
||||
|
||||
this.props.dispatch({
|
||||
@@ -131,7 +153,8 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
Folder.delete(folderId).then(() => {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Welcome',
|
||||
routeName: 'Notes',
|
||||
smartFilterId: 'c3176726992c11e9ac940492261af972',
|
||||
});
|
||||
}).catch((error) => {
|
||||
alert(error.message);
|
||||
@@ -147,23 +170,6 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
});
|
||||
}
|
||||
|
||||
menuOptions() {
|
||||
if (this.props.notesParentType == 'Folder') {
|
||||
if (this.props.selectedFolderId == Folder.conflictFolderId()) return [];
|
||||
|
||||
const folder = this.parentItem();
|
||||
if (!folder) return [];
|
||||
|
||||
let output = [];
|
||||
// if (!folder.encryption_applied) output.push({ title: _('Edit notebook'), onPress: () => { this.editFolder_onPress(this.props.selectedFolderId); } });
|
||||
// output.push({ title: _('Delete notebook'), onPress: () => { this.deleteFolder_onPress(this.props.selectedFolderId); } });
|
||||
|
||||
return output;
|
||||
} else {
|
||||
return []; // For tags - TODO
|
||||
}
|
||||
}
|
||||
|
||||
parentItem(props = null) {
|
||||
if (!props) props = this.props;
|
||||
|
||||
@@ -172,6 +178,8 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
output = Folder.byId(props.folders, props.selectedFolderId);
|
||||
} else if (props.notesParentType == 'Tag') {
|
||||
output = Tag.byId(props.tags, props.selectedTagId);
|
||||
} else if (props.notesParentType == 'SmartFilter') {
|
||||
output = { id: this.props.selectedSmartFilterId, title: _('All notes') };
|
||||
} else {
|
||||
return null;
|
||||
throw new Error('Invalid parent type: ' + props.notesParentType);
|
||||
@@ -179,6 +187,18 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
return output;
|
||||
}
|
||||
|
||||
folderPickerOptions() {
|
||||
const options = {
|
||||
enabled: this.props.noteSelectionEnabled,
|
||||
mustSelect: true,
|
||||
};
|
||||
|
||||
if (this.folderPickerOptions_ && options.enabled === this.folderPickerOptions_.enabled) return this.folderPickerOptions_;
|
||||
|
||||
this.folderPickerOptions_ = options;
|
||||
return this.folderPickerOptions_;
|
||||
}
|
||||
|
||||
render() {
|
||||
const parent = this.parentItem();
|
||||
const theme = themeStyle(this.props.theme);
|
||||
@@ -195,7 +215,7 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
if (!parent) {
|
||||
return (
|
||||
<View style={rootStyle}>
|
||||
<ScreenHeader title={title} menuOptions={this.menuOptions()} />
|
||||
<ScreenHeader title={title} />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -209,15 +229,14 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
<View style={rootStyle}>
|
||||
<ScreenHeader
|
||||
title={title}
|
||||
menuOptions={this.menuOptions()}
|
||||
showBackButton={false}
|
||||
parentComponent={thisComp}
|
||||
sortButton_press={this.sortButton_press}
|
||||
folderPickerOptions={{
|
||||
enabled: this.props.noteSelectionEnabled,
|
||||
mustSelect: true,
|
||||
}}
|
||||
folderPickerOptions={this.folderPickerOptions()}
|
||||
showSearchButton={true}
|
||||
showSideMenuButton={true}
|
||||
/>
|
||||
<NoteList style={{flex: 1}}/>
|
||||
<NoteList style={this.styles().noteList}/>
|
||||
{ actionButtonComp }
|
||||
<DialogBox ref={dialogbox => { this.dialogbox = dialogbox }}/>
|
||||
</View>
|
||||
@@ -233,6 +252,7 @@ const NotesScreen = connect(
|
||||
selectedFolderId: state.selectedFolderId,
|
||||
selectedNoteIds: state.selectedNoteIds,
|
||||
selectedTagId: state.selectedTagId,
|
||||
selectedSmartFilterId: state.selectedSmartFilterId,
|
||||
notesParentType: state.notesParentType,
|
||||
notes: state.notes,
|
||||
notesSource: state.notesSource,
|
||||
|
@@ -166,6 +166,8 @@ class SearchScreenComponent extends BaseScreenComponent {
|
||||
enabled: this.props.noteSelectionEnabled,
|
||||
mustSelect: true,
|
||||
}}
|
||||
showSideMenuButton={false}
|
||||
showSearchButton={false}
|
||||
/>
|
||||
<View style={this.styles().body}>
|
||||
<View style={this.styles().searchContainer}>
|
||||
|
@@ -1,64 +0,0 @@
|
||||
const React = require('react'); const Component = React.Component;
|
||||
const { View, Text, StyleSheet } = require('react-native');
|
||||
const { connect } = require('react-redux');
|
||||
const { ScreenHeader } = require('lib/components/screen-header.js');
|
||||
const { ActionButton } = require('lib/components/action-button.js');
|
||||
const { BaseScreenComponent } = require('lib/components/base-screen.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { themeStyle } = require('lib/components/global-style.js');
|
||||
|
||||
class WelcomeScreenComponent extends BaseScreenComponent {
|
||||
|
||||
static navigationOptions(options) {
|
||||
return { header: null };
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.styles_ = {};
|
||||
}
|
||||
|
||||
styles() {
|
||||
const themeId = this.props.theme;
|
||||
const theme = themeStyle(themeId);
|
||||
|
||||
if (this.styles_[themeId]) return this.styles_[themeId];
|
||||
this.styles_ = {};
|
||||
|
||||
let styles = {
|
||||
message: {
|
||||
margin: theme.margin,
|
||||
fontSize: theme.fontSize,
|
||||
color: theme.color,
|
||||
},
|
||||
};
|
||||
|
||||
this.styles_[themeId] = StyleSheet.create(styles);
|
||||
return this.styles_[themeId];
|
||||
}
|
||||
|
||||
render() {
|
||||
let message = this.props.folders.length ? _('Click on the (+) button to create a new note or notebook. Click on the side menu to access your existing notebooks.') : _('You currently have no notebook. Create one by clicking on (+) button.');
|
||||
|
||||
return (
|
||||
<View style={this.rootStyle(this.props.theme).root} >
|
||||
<ScreenHeader title={_('Welcome')}/>
|
||||
<Text style={this.styles().message}>{message}</Text>
|
||||
<ActionButton addFolderNoteButtons={true} parentFolderId={this.props.selectedFolderId}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const WelcomeScreen = connect(
|
||||
(state) => {
|
||||
return {
|
||||
folders: state.folders,
|
||||
theme: state.settings.theme,
|
||||
selectedFolderId: state.selectedFolderId,
|
||||
};
|
||||
}
|
||||
)(WelcomeScreenComponent)
|
||||
|
||||
module.exports = { WelcomeScreen };
|
@@ -5,13 +5,15 @@ import DatePicker from 'react-native-datepicker'
|
||||
import moment from 'moment';
|
||||
import { _ } from 'lib/locale.js';
|
||||
|
||||
class SelectDateTimeDialog extends Component {
|
||||
class SelectDateTimeDialog extends React.PureComponent {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.dialog_ = null;
|
||||
this.shown_ = false;
|
||||
this.state = { date: null };
|
||||
|
||||
this.onReject = this.onReject.bind(this);
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(newProps) {
|
||||
@@ -72,6 +74,7 @@ class SelectDateTimeDialog extends Component {
|
||||
ref={(dialog) => { this.dialog_ = dialog; }}
|
||||
dialogTitle={<DialogTitle title={_('Set alarm')} />}
|
||||
actions={popupActions}
|
||||
dismissOnTouchOutside={false}
|
||||
width={0.9}
|
||||
height={350}
|
||||
>
|
||||
|
@@ -109,12 +109,9 @@ shared.saveNoteButton_press = async function(comp, folderId = null, options = nu
|
||||
const modLastSavedNote = Object.assign({}, comp.state.lastSavedNote, geoInfo);
|
||||
|
||||
comp.setState({ note: modNote, lastSavedNote: modLastSavedNote });
|
||||
comp.refreshNoteMetadata();
|
||||
});
|
||||
}
|
||||
|
||||
comp.refreshNoteMetadata();
|
||||
|
||||
if (isNew) {
|
||||
// Clear the newNote item now that the note has been saved, and
|
||||
// make sure that the note we're editing is selected.
|
||||
@@ -195,13 +192,6 @@ shared.attachedResources = async function(noteBody) {
|
||||
return output;
|
||||
}
|
||||
|
||||
shared.refreshNoteMetadata = async function(comp, force = null) {
|
||||
if (force !== true && !comp.state.showNoteMetadata) return;
|
||||
|
||||
let noteMetadata = await Note.serializeAllProps(comp.state.note);
|
||||
comp.setState({ noteMetadata: noteMetadata });
|
||||
}
|
||||
|
||||
shared.isModified = function(comp) {
|
||||
if (!comp.state.note || !comp.state.lastSavedNote) return false;
|
||||
let diff = BaseModel.diffObjects(comp.state.lastSavedNote, comp.state.note);
|
||||
@@ -238,11 +228,6 @@ shared.initState = async function(comp) {
|
||||
comp.lastLoadedNoteId_ = note ? note.id : null;
|
||||
}
|
||||
|
||||
shared.showMetadata_onPress = function(comp) {
|
||||
comp.setState({ showNoteMetadata: !comp.state.showNoteMetadata });
|
||||
comp.refreshNoteMetadata(true);
|
||||
}
|
||||
|
||||
shared.toggleIsTodo_onPress = function(comp) {
|
||||
let newNote = Note.toggleIsTodo(comp.state.note);
|
||||
let newState = { note: newNote };
|
||||
|
126
ReactNativeClient/lib/components/side-menu-content-note.js
Normal file
126
ReactNativeClient/lib/components/side-menu-content-note.js
Normal file
@@ -0,0 +1,126 @@
|
||||
const React = require('react'); const Component = React.Component;
|
||||
const { TouchableOpacity , Button, Text, Image, StyleSheet, ScrollView, View, Alert } = require('react-native');
|
||||
const { connect } = require('react-redux');
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { FoldersScreenUtils } = require('lib/folders-screen-utils.js');
|
||||
const { Synchronizer } = require('lib/synchronizer.js');
|
||||
const NavService = require('lib/services/NavService.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { globalStyle, themeStyle } = require('lib/components/global-style.js');
|
||||
const shared = require('lib/components/shared/side-menu-shared.js');
|
||||
const { ActionButton } = require('lib/components/action-button.js');
|
||||
|
||||
class SideMenuContentNoteComponent extends Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.styles_ = {};
|
||||
}
|
||||
|
||||
styles() {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
if (this.styles_[this.props.theme]) return this.styles_[this.props.theme];
|
||||
this.styles_ = {};
|
||||
|
||||
let styles = {
|
||||
menu: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.backgroundColor
|
||||
},
|
||||
button: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
height: 36,
|
||||
alignItems: 'center',
|
||||
paddingLeft: theme.marginLeft,
|
||||
paddingRight: theme.marginRight,
|
||||
},
|
||||
sidebarIcon: {
|
||||
fontSize: 22,
|
||||
color: theme.color,
|
||||
},
|
||||
};
|
||||
|
||||
styles.sideButton = Object.assign({}, styles.button, { flex: 0 });
|
||||
styles.sideButtonDisabled = Object.assign({}, styles.sideButton, { opacity: 0.6 });
|
||||
styles.sideButtonText = Object.assign({}, styles.buttonText);
|
||||
|
||||
this.styles_[this.props.theme] = StyleSheet.create(styles);
|
||||
return this.styles_[this.props.theme];
|
||||
}
|
||||
|
||||
renderDivider(key) {
|
||||
return <View style={{ marginTop: 15, marginBottom: 15, flex: -1, borderBottomWidth: 1, borderBottomColor: globalStyle.dividerColor }} key={key}></View>
|
||||
}
|
||||
|
||||
renderSideBarButton(key, title, iconName, onPressHandler) {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
const content = (
|
||||
<View key={key} style={onPressHandler ? this.styles().sideButton : this.styles().sideButtonDisabled}>
|
||||
{ !iconName ? null : <Icon name={iconName} style={this.styles().sidebarIcon} /> }
|
||||
<Text style={this.styles().sideButtonText}>{title}</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
if (!onPressHandler) return content;
|
||||
|
||||
return (
|
||||
<TouchableOpacity key={key} onPress={onPressHandler}>
|
||||
{content}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
let items = [];
|
||||
|
||||
const options = this.props.options ? this.props.options : [];
|
||||
let dividerIndex = 0;
|
||||
|
||||
for (const option of options) {
|
||||
if (option.isDivider) {
|
||||
items.push(this.renderDivider('divider_' + dividerIndex++));
|
||||
} else {
|
||||
items.push(this.renderSideBarButton(option.title, option.title, null, option.onPress));
|
||||
}
|
||||
}
|
||||
|
||||
let style = {
|
||||
flex:1,
|
||||
borderRightWidth: 1,
|
||||
borderRightColor: globalStyle.dividerColor,
|
||||
backgroundColor: theme.backgroundColor,
|
||||
paddingTop: 10,
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={style}>
|
||||
<View style={{flex:1, opacity: this.props.opacity}}>
|
||||
<ScrollView scrollsToTop={false} style={this.styles().menu}>
|
||||
{ items }
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const SideMenuContentNote = connect(
|
||||
(state) => {
|
||||
return {
|
||||
theme: state.settings.theme,
|
||||
};
|
||||
}
|
||||
)(SideMenuContentNoteComponent)
|
||||
|
||||
module.exports = { SideMenuContentNote };
|
@@ -1,5 +1,5 @@
|
||||
const React = require('react'); const Component = React.Component;
|
||||
const { TouchableOpacity , Button, Text, Image, StyleSheet, ScrollView, View, Alert } = require('react-native');
|
||||
const { Easing, Animated, TouchableOpacity , Button, Text, Image, StyleSheet, ScrollView, View, Alert } = require('react-native');
|
||||
const { connect } = require('react-redux');
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
@@ -28,7 +28,14 @@ class SideMenuContentComponent extends Component {
|
||||
this.newFolderButton_press = this.newFolderButton_press.bind(this);
|
||||
this.synchronize_press = this.synchronize_press.bind(this);
|
||||
this.configButton_press = this.configButton_press.bind(this);
|
||||
this.allNotesButton_press = this.allNotesButton_press.bind(this);
|
||||
this.renderFolderItem = this.renderFolderItem.bind(this);
|
||||
|
||||
this.syncIconRotationValue = new Animated.Value(0);
|
||||
this.syncIconRotation = this.syncIconRotationValue.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: ['360deg', '0deg'],
|
||||
});
|
||||
}
|
||||
|
||||
styles() {
|
||||
@@ -79,12 +86,30 @@ class SideMenuContentComponent extends Component {
|
||||
styles.folderIcon.paddingTop = 3;
|
||||
|
||||
styles.sideButton = Object.assign({}, styles.button, { flex: 0 });
|
||||
styles.sideButtonSelected = Object.assign({}, styles.sideButton, { backgroundColor: theme.selectedColor });
|
||||
styles.sideButtonText = Object.assign({}, styles.buttonText);
|
||||
|
||||
this.styles_[this.props.theme] = StyleSheet.create(styles);
|
||||
return this.styles_[this.props.theme];
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.syncStarted !== prevProps.syncStarted) {
|
||||
if (this.props.syncStarted) {
|
||||
this.syncIconAnimation = Animated.loop(Animated.timing(this.syncIconRotationValue, {
|
||||
toValue: 1,
|
||||
duration: 3000,
|
||||
easing: Easing.linear,
|
||||
}));
|
||||
|
||||
this.syncIconAnimation.start();
|
||||
} else {
|
||||
if (this.syncIconAnimation) this.syncIconAnimation.stop();
|
||||
this.syncIconAnimation = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
folder_press(folder) {
|
||||
this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||
|
||||
@@ -96,6 +121,8 @@ class SideMenuContentComponent extends Component {
|
||||
}
|
||||
|
||||
async folder_longPress(folder) {
|
||||
if (folder === 'all') return;
|
||||
|
||||
const buttons = [];
|
||||
|
||||
Alert.alert(
|
||||
@@ -169,6 +196,16 @@ class SideMenuContentComponent extends Component {
|
||||
NavService.go('Config');
|
||||
}
|
||||
|
||||
allNotesButton_press() {
|
||||
this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Notes',
|
||||
smartFilterId: 'c3176726992c11e9ac940492261af972',
|
||||
});
|
||||
}
|
||||
|
||||
newFolderButton_press() {
|
||||
this.props.dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||
|
||||
@@ -192,19 +229,20 @@ class SideMenuContentComponent extends Component {
|
||||
flexDirection: 'row',
|
||||
height: 36,
|
||||
alignItems: 'center',
|
||||
paddingLeft: theme.marginLeft,
|
||||
paddingRight: theme.marginRight,
|
||||
};
|
||||
if (selected) folderButtonStyle.backgroundColor = theme.selectedColor;
|
||||
folderButtonStyle.paddingLeft = depth * 10;
|
||||
folderButtonStyle.paddingLeft = depth * 10 + theme.marginLeft;
|
||||
|
||||
const iconWrapperStyle = { paddingLeft: 10, paddingRight: 10 };
|
||||
if (selected) iconWrapperStyle.backgroundColor = theme.selectedColor;
|
||||
|
||||
let iconWrapper = null;
|
||||
|
||||
const iconName = this.props.collapsedFolderIds.indexOf(folder.id) >= 0 ? 'md-arrow-dropdown' : 'md-arrow-dropup';
|
||||
const iconComp = <Icon name={iconName} style={this.styles().folderIcon} />
|
||||
|
||||
const iconWrapper = !hasChildren ? null : (
|
||||
iconWrapper = !hasChildren ? null : (
|
||||
<TouchableOpacity style={iconWrapperStyle} folderid={folder.id} onPress={() => { if (hasChildren) this.folder_togglePress(folder) }}>
|
||||
{ iconComp }
|
||||
</TouchableOpacity>
|
||||
@@ -222,15 +260,31 @@ class SideMenuContentComponent extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderSideBarButton(key, title, iconName, onPressHandler) {
|
||||
renderSideBarButton(key, title, iconName, onPressHandler = null, selected = false) {
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
let icon = <Icon name={iconName} style={this.styles().sidebarIcon} />
|
||||
|
||||
if (key === 'synchronize_button') {
|
||||
icon = (
|
||||
<Animated.View style={{transform: [{rotate: this.syncIconRotation}]}}>
|
||||
{icon}
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
const content = (
|
||||
<View key={key} style={selected ? this.styles().sideButtonSelected : this.styles().sideButton}>
|
||||
{icon}
|
||||
<Text style={this.styles().sideButtonText}>{title}</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
if (!onPressHandler) return content;
|
||||
|
||||
return (
|
||||
<TouchableOpacity key={key} onPress={onPressHandler}>
|
||||
<View style={this.styles().sideButton}>
|
||||
<Icon name={iconName} style={this.styles().sidebarIcon} />
|
||||
<Text style={this.styles().sideButtonText}>{title}</Text>
|
||||
</View>
|
||||
{content}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
@@ -274,8 +328,8 @@ class SideMenuContentComponent extends Component {
|
||||
|
||||
items.push(this.renderSideBarButton(
|
||||
'synchronize_button',
|
||||
!this.props.syncStarted ? _('Synchronise') : _('Cancel synchronisation'),
|
||||
!this.props.syncStarted ? 'md-sync' : 'md-close',
|
||||
!this.props.syncStarted ? _('Synchronise') : _('Cancel'),
|
||||
'md-sync',
|
||||
this.synchronize_press
|
||||
));
|
||||
|
||||
@@ -297,6 +351,12 @@ class SideMenuContentComponent extends Component {
|
||||
// using padding. So instead creating blank elements for padding bottom and top.
|
||||
items.push(<View style={{ height: globalStyle.marginTop }} key='bottom_top_hack'/>);
|
||||
|
||||
items.push(this.renderSideBarButton('all_notes', _('All notes'), 'md-document', this.allNotesButton_press, this.props.notesParentType === 'SmartFilter'));
|
||||
|
||||
items.push(this.makeDivider('divider_all'));
|
||||
|
||||
items.push(this.renderSideBarButton('folder_header', _('Notebooks'), 'md-folder'));
|
||||
|
||||
if (this.props.folders.length) {
|
||||
const result = shared.renderFolders(this.props, this.renderFolderItem);
|
||||
const folderItems = result.items;
|
||||
|
@@ -194,6 +194,10 @@ class JoplinDatabase extends Database {
|
||||
queries.push('DELETE FROM settings WHERE key="sync.5.context"');
|
||||
queries.push('DELETE FROM settings WHERE key="sync.6.context"');
|
||||
queries.push('DELETE FROM settings WHERE key="sync.7.context"');
|
||||
|
||||
queries.push('DELETE FROM settings WHERE key="revisionService.lastProcessedChangeId"');
|
||||
queries.push('DELETE FROM settings WHERE key="resourceService.lastProcessedChangeId"');
|
||||
queries.push('DELETE FROM settings WHERE key="searchEngine.lastProcessedChangeId"');
|
||||
|
||||
await this.transactionExecBatch(queries);
|
||||
}
|
||||
|
@@ -250,7 +250,8 @@ class Note extends BaseItem {
|
||||
}
|
||||
|
||||
static previewFields() {
|
||||
return ['id', 'title', 'body', 'is_todo', 'todo_completed', 'parent_id', 'updated_time', 'user_updated_time', 'user_created_time', 'encryption_applied'];
|
||||
// return ['id', 'title', 'body', 'is_todo', 'todo_completed', 'parent_id', 'updated_time', 'user_updated_time', 'user_created_time', 'encryption_applied'];
|
||||
return ['id', 'title', 'is_todo', 'todo_completed', 'parent_id', 'updated_time', 'user_updated_time', 'user_created_time', 'encryption_applied'];
|
||||
}
|
||||
|
||||
static previewFieldsSql(fields = null) {
|
||||
@@ -602,6 +603,17 @@ class Note extends BaseItem {
|
||||
return note.is_todo && !note.todo_completed && note.todo_due >= time.unixMs() && !note.is_conflict;
|
||||
}
|
||||
|
||||
static dueDateObject(note) {
|
||||
if (!!note.is_todo && note.todo_due) {
|
||||
if (!this.dueDateObjects_) this.dueDateObjects_ = {};
|
||||
if (this.dueDateObjects_[note.todo_due]) return this.dueDateObjects_[note.todo_due];
|
||||
this.dueDateObjects_[note.todo_due] = new Date(note.todo_due);
|
||||
return this.dueDateObjects_[note.todo_due];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Tells whether the conflict between the local and remote note can be ignored.
|
||||
static mustHandleConflict(localNote, remoteNote) {
|
||||
// That shouldn't happen so throw an exception
|
||||
|
@@ -26,7 +26,7 @@ class ResourceService extends BaseService {
|
||||
WHERE item_type = ?
|
||||
AND id > ?
|
||||
ORDER BY id ASC
|
||||
LIMIT 100
|
||||
LIMIT 10
|
||||
`, [BaseModel.TYPE_NOTE, Setting.value('resourceService.lastProcessedChangeId')]);
|
||||
|
||||
if (!changes.length) break;
|
||||
|
@@ -7,6 +7,7 @@ const BaseModel = require('lib/BaseModel.js');
|
||||
const ItemChangeUtils = require('lib/services/ItemChangeUtils');
|
||||
const { pregQuote, scriptType } = require('lib/string-utils.js');
|
||||
const removeDiacritics = require('diacritics').remove;
|
||||
const { sprintf } = require('sprintf-js');
|
||||
|
||||
class SearchEngine {
|
||||
|
||||
@@ -91,6 +92,12 @@ class SearchEngine {
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
async rebuildIndex() {
|
||||
Setting.setValue('searchEngine.lastProcessedChangeId', 0)
|
||||
Setting.setValue('searchEngine.initialIndexingDone', false);
|
||||
return this.syncTables();
|
||||
}
|
||||
|
||||
async syncTables() {
|
||||
if (this.isIndexing_) return;
|
||||
|
||||
@@ -109,6 +116,11 @@ class SearchEngine {
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
const report = {
|
||||
inserted: 0,
|
||||
deleted: 0,
|
||||
};
|
||||
|
||||
let lastChangeId = Setting.value('searchEngine.lastProcessedChangeId');
|
||||
|
||||
try {
|
||||
@@ -119,9 +131,11 @@ class SearchEngine {
|
||||
WHERE item_type = ?
|
||||
AND id > ?
|
||||
ORDER BY id ASC
|
||||
LIMIT 100
|
||||
LIMIT 10
|
||||
`, [BaseModel.TYPE_NOTE, lastChangeId]);
|
||||
|
||||
const maxRow = await ItemChange.db().selectOne('SELECT max(id) FROM item_changes');
|
||||
|
||||
if (!changes.length) break;
|
||||
|
||||
const noteIds = changes.map(a => a.item_id);
|
||||
@@ -137,9 +151,11 @@ class SearchEngine {
|
||||
if (note) {
|
||||
const n = this.normalizeNote_(note);
|
||||
queries.push({ sql: 'INSERT INTO notes_normalized(id, title, body) VALUES (?, ?, ?)', params: [change.item_id, n.title, n.body] });
|
||||
report.inserted++;
|
||||
}
|
||||
} else if (change.type === ItemChange.TYPE_DELETE) {
|
||||
queries.push({ sql: 'DELETE FROM notes_normalized WHERE id = ?', params: [change.item_id] });
|
||||
report.deleted++;
|
||||
} else {
|
||||
throw new Error('Invalid change type: ' + change.type);
|
||||
}
|
||||
@@ -157,7 +173,7 @@ class SearchEngine {
|
||||
|
||||
await ItemChangeUtils.deleteProcessedChanges();
|
||||
|
||||
this.logger().info('SearchEngine: Updated FTS table in ' + (Date.now() - startTime) + 'ms');
|
||||
this.logger().info(sprintf('SearchEngine: Updated FTS table in %dms. Inserted: %d. Deleted: %d', Date.now() - startTime, report.inserted, report.deleted));
|
||||
|
||||
this.isIndexing_ = false;
|
||||
}
|
||||
|
@@ -456,6 +456,7 @@ class Api {
|
||||
if ('author' in requestNote) output.author = requestNote.author;
|
||||
if ('user_updated_time' in requestNote) output.user_updated_time = Database.formatValue(Database.TYPE_INT, requestNote.user_updated_time);
|
||||
if ('user_created_time' in requestNote) output.user_created_time = Database.formatValue(Database.TYPE_INT, requestNote.user_created_time);
|
||||
if ('is_todo' in requestNote) output.is_todo = Database.formatValue(Database.TYPE_INT, requestNote.is_todo);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -590,4 +591,4 @@ class Api {
|
||||
|
||||
}
|
||||
|
||||
module.exports = Api;
|
||||
module.exports = Api;
|
||||
|
@@ -619,12 +619,10 @@ class Synchronizer {
|
||||
if (!hasAutoEnabledEncryption && content.type_ === BaseModel.TYPE_MASTER_KEY && !masterKeysBefore) {
|
||||
hasAutoEnabledEncryption = true;
|
||||
this.logger().info("One master key was downloaded and none was previously available: automatically enabling encryption");
|
||||
this.logger().info("Using master key: ", content);
|
||||
this.logger().info("Using master key: ", content.id);
|
||||
await this.encryptionService().enableEncryption(content);
|
||||
await this.encryptionService().loadMasterKeysFromSettings();
|
||||
this.logger().info(
|
||||
"Encryption has been enabled with downloaded master key as active key. However, note that no password was initially supplied. It will need to be provided by user."
|
||||
);
|
||||
this.logger().info("Encryption has been enabled with downloaded master key as active key. However, note that no password was initially supplied. It will need to be provided by user.");
|
||||
}
|
||||
|
||||
if (!!content.encryption_applied) this.dispatch({ type: "SYNC_GOT_ENCRYPTED_ITEM" });
|
||||
|
@@ -37,7 +37,6 @@ const { ConfigScreen } = require('lib/components/screens/config.js');
|
||||
const { FolderScreen } = require('lib/components/screens/folder.js');
|
||||
const { LogScreen } = require('lib/components/screens/log.js');
|
||||
const { StatusScreen } = require('lib/components/screens/status.js');
|
||||
const { WelcomeScreen } = require('lib/components/screens/welcome.js');
|
||||
const { SearchScreen } = require('lib/components/screens/search.js');
|
||||
const { OneDriveLoginScreen } = require('lib/components/screens/onedrive-login.js');
|
||||
const { EncryptionConfigScreen } = require('lib/components/screens/encryption-config.js');
|
||||
@@ -46,6 +45,7 @@ const Setting = require('lib/models/Setting.js');
|
||||
const { MenuContext } = require('react-native-popup-menu');
|
||||
const { SideMenu } = require('lib/components/side-menu.js');
|
||||
const { SideMenuContent } = require('lib/components/side-menu-content.js');
|
||||
const { SideMenuContentNote } = require('lib/components/side-menu-content-note.js');
|
||||
const { DatabaseDriverReactNative } = require('lib/database-driver-react-native');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { _, setLocale, closestSupportedLocale, defaultLocale } = require('lib/locale.js');
|
||||
@@ -167,14 +167,17 @@ function historyCanGoBackTo(route, nextRoute) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const DEFAULT_ROUTE = {
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Notes',
|
||||
smartFilterId: 'c3176726992c11e9ac940492261af972',
|
||||
};
|
||||
|
||||
const appDefaultState = Object.assign({}, defaultState, {
|
||||
sideMenuOpenPercent: 0,
|
||||
route: {
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Welcome',
|
||||
params: {},
|
||||
},
|
||||
route: DEFAULT_ROUTE,
|
||||
noteSelectionEnabled: false,
|
||||
noteSideMenuOptions: null,
|
||||
});
|
||||
|
||||
const appReducer = (state = appDefaultState, action) => {
|
||||
@@ -229,8 +232,6 @@ const appReducer = (state = appDefaultState, action) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (action.routeName == 'Welcome') navHistory = [];
|
||||
|
||||
//reg.logger().info('Route: ' + currentRouteName + ' => ' + action.routeName);
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
@@ -249,6 +250,11 @@ const appReducer = (state = appDefaultState, action) => {
|
||||
newState.notesParentType = 'Tag';
|
||||
}
|
||||
|
||||
if ('smartFilterId' in action) {
|
||||
newState.smartFilterId = action.smartFilterId;
|
||||
newState.notesParentType = 'SmartFilter';
|
||||
}
|
||||
|
||||
if ('itemType' in action) {
|
||||
newState.selectedItemType = action.itemType;
|
||||
}
|
||||
@@ -321,6 +327,11 @@ const appReducer = (state = appDefaultState, action) => {
|
||||
newState.selectedNoteIds = [];
|
||||
break;
|
||||
|
||||
case 'NOTE_SIDE_MENU_OPTIONS_SET':
|
||||
|
||||
newState = Object.assign({}, state);
|
||||
newState.noteSideMenuOptions = action.options;
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -495,10 +506,7 @@ async function initialize(dispatch) {
|
||||
});
|
||||
|
||||
if (!folder) {
|
||||
dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Welcome',
|
||||
});
|
||||
dispatch(DEFAULT_ROUTE);
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'NAV_GO',
|
||||
@@ -684,10 +692,17 @@ class AppComponent extends React.Component {
|
||||
if (this.props.appState != 'ready') return null;
|
||||
const theme = themeStyle(this.props.theme);
|
||||
|
||||
const sideMenuContent = <SafeAreaView style={{flex:1, backgroundColor: theme.backgroundColor}}><SideMenuContent/></SafeAreaView>;
|
||||
let sideMenuContent = null;
|
||||
let menuPosition = 'left';
|
||||
|
||||
if (this.props.routeName === 'Note') {
|
||||
sideMenuContent = <SafeAreaView style={{flex:1, backgroundColor: theme.backgroundColor}}><SideMenuContentNote options={this.props.noteSideMenuOptions}/></SafeAreaView>;
|
||||
menuPosition = 'right';
|
||||
} else {
|
||||
sideMenuContent = <SafeAreaView style={{flex:1, backgroundColor: theme.backgroundColor}}><SideMenuContent/></SafeAreaView>;
|
||||
}
|
||||
|
||||
const appNavInit = {
|
||||
Welcome: { screen: WelcomeScreen },
|
||||
Notes: { screen: NotesScreen },
|
||||
Note: { screen: NoteScreen },
|
||||
Tags: { screen: TagsScreen },
|
||||
@@ -704,6 +719,7 @@ class AppComponent extends React.Component {
|
||||
return (
|
||||
<SideMenu
|
||||
menu={sideMenuContent}
|
||||
menuPosition={menuPosition}
|
||||
onChange={(isOpen) => this.sideMenu_change(isOpen)}
|
||||
onSliding={(percent) => {
|
||||
this.props.dispatch({
|
||||
@@ -733,7 +749,9 @@ const mapStateToProps = (state) => {
|
||||
appState: state.appState,
|
||||
noteSelectionEnabled: state.noteSelectionEnabled,
|
||||
selectedFolderId: state.selectedFolderId,
|
||||
theme: state.settings.theme
|
||||
routeName: state.route.routeName,
|
||||
theme: state.settings.theme,
|
||||
noteSideMenuOptions: state.noteSideMenuOptions,
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -478,6 +478,11 @@ function renderFileToHtml(sourcePath, targetPath, params) {
|
||||
function makeHomePageMd() {
|
||||
let md = fs.readFileSync(rootDir + '/README.md', 'utf8');
|
||||
md = md.replace(tocRegex_, '');
|
||||
|
||||
// HACK: GitHub needs the \| or the inline code won't be displayed correctly inside the table,
|
||||
// while MarkdownIt doesn't and will in fact display the \. So we remove it here.
|
||||
md = md.replace(/\\\| bash/g, '| bash');
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
|
@@ -550,7 +550,7 @@
|
||||
<h2><a name="v1-0-119-https-github-com-laurent22-joplin-releases-tag-v1-0-119-2018-12-18t12-40-22z" href="#v1-0-119-https-github-com-laurent22-joplin-releases-tag-v1-0-119-2018-12-18t12-40-22z" class="heading-anchor">🔗</a><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.119">v1.0.119</a> - 2018-12-18T12:40:22Z</h2>
|
||||
<p>Important: This release might be slow on startup due to the need to index all the notes, especially if you have many of them with lots of content. The best is simply to wait for it even if it takes several minutes. This is just a one off and afterwards startup time will be the same as before.</p>
|
||||
<ul>
|
||||
<li>New: Fast full text search engine. Works with multiple terms, support for prefixes, can restrict search to either note title or body. See <a href="https://joplin.cozic.net/#searching">https://joplin.cozic.net/#searching</a> for more info.</li>
|
||||
<li>New: Fast full text search engine. Works with multiple terms, support for prefixes, can restrict search to either note title or body. See <a href="https://joplinapp.org/#searching">https://joplinapp.org/#searching</a> for more info.</li>
|
||||
<li>New: Search within current note (Ctrl+F).</li>
|
||||
<li>New: Add separate editor font size option (<a href="https://github.com/laurent22/joplin/issues/1027">#1027</a>)</li>
|
||||
<li>Changed: Changed global search shortcut to F6.</li>
|
||||
@@ -563,7 +563,7 @@
|
||||
<h2><a name="v1-0-118-https-github-com-laurent22-joplin-releases-tag-v1-0-118-2019-01-11t08-34-13z" href="#v1-0-118-https-github-com-laurent22-joplin-releases-tag-v1-0-118-2019-01-11t08-34-13z" class="heading-anchor">🔗</a><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.118">v1.0.118</a> - 2019-01-11T08:34:13Z</h2>
|
||||
<p>Important: This release might be slow on startup due to the need to index all the notes, especially if you have many of them with lots of content. The best is simply to wait for it even if it takes several minutes. This is just a one off and afterwards startup time will be the same as before.</p>
|
||||
<ul>
|
||||
<li>New: Fast full text search engine. Works with multiple terms, support for prefixes, can restrict search to either note title or body. See <a href="https://joplin.cozic.net/#searching">https://joplin.cozic.net/#searching</a> for more info.</li>
|
||||
<li>New: Fast full text search engine. Works with multiple terms, support for prefixes, can restrict search to either note title or body. See <a href="https://joplinapp.org/#searching">https://joplinapp.org/#searching</a> for more info.</li>
|
||||
<li>New: Search within current note (Ctrl+F).</li>
|
||||
<li>New: Add separate editor font size option (<a href="https://github.com/laurent22/joplin/issues/1027">#1027</a>)</li>
|
||||
<li>Changed: Changed global search shortcut to F6.</li>
|
||||
@@ -764,7 +764,7 @@
|
||||
</ul>
|
||||
<h2><a name="v1-0-93-https-github-com-laurent22-joplin-releases-tag-v1-0-93-2018-05-14t11-36-01z" href="#v1-0-93-https-github-com-laurent22-joplin-releases-tag-v1-0-93-2018-05-14t11-36-01z" class="heading-anchor">🔗</a><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.93">v1.0.93</a> - 2018-05-14T11:36:01Z</h2>
|
||||
<ul>
|
||||
<li>New: A portable version is now available. To install it simply copy the file "JoplinPortable.exe" to your USB device. See the documentation for more information - <a href="https://joplin.cozic.net/#desktop-applications">https://joplin.cozic.net/#desktop-applications</a></li>
|
||||
<li>New: A portable version is now available. To install it simply copy the file "JoplinPortable.exe" to your USB device. See the documentation for more information - <a href="https://joplinapp.org/#desktop-applications">https://joplinapp.org/#desktop-applications</a></li>
|
||||
<li>Improved: Made import of ENEX files more robust and accurate</li>
|
||||
<li>Improved: Auto-update process should be more reliable.</li>
|
||||
<li>Fixed: Made sync-after-save interval longer to made synchronisations less frequent.</li>
|
||||
@@ -781,7 +781,7 @@
|
||||
</ul>
|
||||
<h2><a name="v1-0-89-https-github-com-laurent22-joplin-releases-tag-v1-0-89-2018-05-09t13-05-05z" href="#v1-0-89-https-github-com-laurent22-joplin-releases-tag-v1-0-89-2018-05-09t13-05-05z" class="heading-anchor">🔗</a><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.89">v1.0.89</a> - 2018-05-09T13:05:05Z</h2>
|
||||
<ul>
|
||||
<li>New: Resolves <a href="https://github.com/laurent22/joplin/issues/122">#122</a>: Added support for sub-notebooks. Please see doc for more info: <a href="https://joplin.cozic.net/#sub-notebooks">https://joplin.cozic.net/#sub-notebooks</a></li>
|
||||
<li>New: Resolves <a href="https://github.com/laurent22/joplin/issues/122">#122</a>: Added support for sub-notebooks. Please see doc for more info: <a href="https://joplinapp.org/#sub-notebooks">https://joplinapp.org/#sub-notebooks</a></li>
|
||||
<li>Improved: Export/Import links to notes</li>
|
||||
<li>Fixes <a href="https://github.com/laurent22/joplin/issues/480">#480</a>: Ignore invalid flag automatically passed by macOS</li>
|
||||
<li>Fixes <a href="https://github.com/laurent22/joplin/issues/61">#61</a>: Handle path that ends with slash for file system sync</li>
|
||||
|
@@ -300,7 +300,7 @@
|
||||
<h1><a name="creating-a-low-level-bug-report-on-ios" href="#creating-a-low-level-bug-report-on-ios" class="heading-anchor">🔗</a>Creating a low-level bug report on iOS</h1>
|
||||
<p>Some crashes cannot be investigated using Joplin's own tools. In that case, it can be very helpful to provide a native iOS crash report.</p>
|
||||
<p>For this, please follow these instructions:</p>
|
||||
<p>You can send it to this address <a href="https://raw.githubusercontent.com/laurent22/joplin/master/Assets/Adresse.png">https://raw.githubusercontent.com/laurent22/joplin/master/Assets/Adresse.png</a></p>
|
||||
<p>You can send it to this address <a href="https://raw.githubusercontent.com/laurent22/joplin/master/Assets/AdresseSupport.png">https://raw.githubusercontent.com/laurent22/joplin/master/Assets/AdresseSupport.png</a></p>
|
||||
<p><a href="https://developer.apple.com/library/content/qa/qa1747/_index.html">https://developer.apple.com/library/content/qa/qa1747/_index.html</a></p>
|
||||
<p>Getting Crash Logs Directly From a Device Without Xcode</p>
|
||||
<p>Your users can retrieve crash reports from their device and send them to you via email by following these instructions.</p>
|
||||
|
@@ -300,7 +300,7 @@
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td><a href='https://github.com/laurent22/joplin/releases/download/v1.0.160/Joplin-1.0.160-x86_64.AppImage'><img alt='Get it on Linux' width="134px" src='https://joplinapp.org/images/BadgeLinux.png'/></a></td>
|
||||
<td>An Arch Linux package <a href="#terminal-application">is also available</a>.<br><br>If it works with your distribution (it has been tested on Ubuntu, Fedora, Gnome and Mint), the recommended way is to use this script as it will handle the desktop icon too:<br><br> <code>wget -O - https://raw.githubusercontent.com/laurent22/joplin/master/Joplin_install_and_update.sh \| bash</code></td>
|
||||
<td>An Arch Linux package <a href="#terminal-application">is also available</a>.<br><br>If it works with your distribution (it has been tested on Ubuntu, Fedora, Gnome and Mint), the recommended way is to use this script as it will handle the desktop icon too:<br><br> <code>wget -O - https://raw.githubusercontent.com/laurent22/joplin/master/Joplin_install_and_update.sh | bash</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -641,7 +641,7 @@ $$
|
||||
<li>Also see here for information about <a href="https://discourse.joplinapp.org/c/news">the latest releases and general news</a>.</li>
|
||||
<li>For bug reports and feature requests, go to the <a href="https://github.com/laurent22/joplin/issues">GitHub Issue Tracker</a>.</li>
|
||||
<li>The latest news are posted <a href="https://www.patreon.com/joplin">on the Patreon page</a>.</li>
|
||||
<li>You can also follow us on <a href="https://twitter.com/joplinapp">the Twitter feed</a>.</li>
|
||||
<li>You can also follow us on <a rel="me" href="https://mastodon.social/@joplinapp">the Mastodon feed</a> or <a href="https://twitter.com/joplinapp">the Twitter feed</a>.</li>
|
||||
</ul>
|
||||
<h1><a name="contributing" href="#contributing" class="heading-anchor">🔗</a>Contributing</h1>
|
||||
<p>Please see the guide for information on how to contribute to the development of Joplin: <a href="https://github.com/laurent22/joplin/blob/master/CONTRIBUTING.md">https://github.com/laurent22/joplin/blob/master/CONTRIBUTING.md</a></p>
|
||||
@@ -651,7 +651,7 @@ $$
|
||||
<li><a href="https://poedit.net/">Download Poedit</a>, the translation editor, and install it.</li>
|
||||
<li><a href="https://raw.githubusercontent.com/laurent22/joplin/master/CliClient/locales/joplin.pot">Download the file to be translated</a>.</li>
|
||||
<li>In Poedit, open this .pot file, go into the Catalog menu and click Configuration. Change "Country" and "Language" to your own country and language.</li>
|
||||
<li>From then you can translate the file. Once it is done, please either <a href="https://github.com/laurent22/joplin/pulls">open a pull request</a> or send the file to <a href="https://raw.githubusercontent.com/laurent22/joplin/master/Assets/Adresse.png">this address</a>.</li>
|
||||
<li>From then you can translate the file. Once it is done, please either <a href="https://github.com/laurent22/joplin/pulls">open a pull request</a> or send the file to <a href="https://raw.githubusercontent.com/laurent22/joplin/master/Assets/AdresseTranslation.png">this address</a>.</li>
|
||||
</ul>
|
||||
<p>This translation will apply to the three applications - desktop, mobile and terminal.</p>
|
||||
<p>To <strong>update a translation</strong>, follow the same steps as above but instead of getting the .pot file, get the .po file for your language from the table below.</p>
|
||||
|
@@ -280,15 +280,15 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Total Windows downloads</td>
|
||||
<td>279,497</td>
|
||||
<td>291,223</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total macOs downloads</td>
|
||||
<td>119,042</td>
|
||||
<td>122,809</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total Linux downloads</td>
|
||||
<td>93,494</td>
|
||||
<td>96,536</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Windows %</td>
|
||||
@@ -319,34 +319,34 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.160">v1.0.160</a></td>
|
||||
<td>2019-06-15T00:21:40Z</td>
|
||||
<td>381</td>
|
||||
<td>117</td>
|
||||
<td>57</td>
|
||||
<td>555</td>
|
||||
<td>11,629</td>
|
||||
<td>3,795</td>
|
||||
<td>2,992</td>
|
||||
<td>18,416</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.159">v1.0.159</a></td>
|
||||
<td>2019-06-08T00:00:19Z</td>
|
||||
<td>5,046</td>
|
||||
<td>2,092</td>
|
||||
<td>1,055</td>
|
||||
<td>8,193</td>
|
||||
<td>5,122</td>
|
||||
<td>2,137</td>
|
||||
<td>1,071</td>
|
||||
<td>8,330</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.158">v1.0.158</a></td>
|
||||
<td>2019-05-27T19:01:18Z</td>
|
||||
<td>9,541</td>
|
||||
<td>3,478</td>
|
||||
<td>9,741</td>
|
||||
<td>3,484</td>
|
||||
<td>1,915</td>
|
||||
<td>14,934</td>
|
||||
<td>15,140</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.157">v1.0.157</a></td>
|
||||
<td>2019-05-26T17:55:53Z</td>
|
||||
<td>2,127</td>
|
||||
<td>2,133</td>
|
||||
<td>808</td>
|
||||
<td>272</td>
|
||||
<td>3,207</td>
|
||||
<td>3,213</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.153">v1.0.153</a></td>
|
||||
@@ -359,10 +359,10 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.152">v1.0.152</a></td>
|
||||
<td>2019-05-13T09:08:07Z</td>
|
||||
<td>13,722</td>
|
||||
<td>4,373</td>
|
||||
<td>13,750</td>
|
||||
<td>4,380</td>
|
||||
<td>4,045</td>
|
||||
<td>22,140</td>
|
||||
<td>22,175</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.151">v1.0.151</a></td>
|
||||
@@ -385,40 +385,40 @@
|
||||
<td>2019-05-08T19:12:24Z</td>
|
||||
<td>111</td>
|
||||
<td>36</td>
|
||||
<td>77</td>
|
||||
<td>224</td>
|
||||
<td>78</td>
|
||||
<td>225</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.145">v1.0.145</a></td>
|
||||
<td>2019-05-03T09:16:53Z</td>
|
||||
<td>6,868</td>
|
||||
<td>6,877</td>
|
||||
<td>2,830</td>
|
||||
<td>1,425</td>
|
||||
<td>11,123</td>
|
||||
<td>11,132</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.143">v1.0.143</a></td>
|
||||
<td>2019-04-22T10:51:38Z</td>
|
||||
<td>11,861</td>
|
||||
<td>3,512</td>
|
||||
<td>11,862</td>
|
||||
<td>3,513</td>
|
||||
<td>2,765</td>
|
||||
<td>18,138</td>
|
||||
<td>18,140</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.142">v1.0.142</a></td>
|
||||
<td>2019-04-02T16:44:51Z</td>
|
||||
<td>14,494</td>
|
||||
<td>14,503</td>
|
||||
<td>4,511</td>
|
||||
<td>4,708</td>
|
||||
<td>23,713</td>
|
||||
<td>4,710</td>
|
||||
<td>23,724</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.140">v1.0.140</a></td>
|
||||
<td>2019-03-10T20:59:58Z</td>
|
||||
<td>13,535</td>
|
||||
<td>4,120</td>
|
||||
<td>2,995</td>
|
||||
<td>20,650</td>
|
||||
<td>13,557</td>
|
||||
<td>4,122</td>
|
||||
<td>2,999</td>
|
||||
<td>20,678</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.139">v1.0.139</a></td>
|
||||
@@ -447,10 +447,10 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.135">v1.0.135</a></td>
|
||||
<td>2019-02-27T23:36:57Z</td>
|
||||
<td>12,192</td>
|
||||
<td>12,214</td>
|
||||
<td>3,915</td>
|
||||
<td>4,045</td>
|
||||
<td>20,152</td>
|
||||
<td>20,174</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.134">v1.0.134</a></td>
|
||||
@@ -471,10 +471,10 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.127">v1.0.127</a></td>
|
||||
<td>2019-02-14T23:12:48Z</td>
|
||||
<td>9,429</td>
|
||||
<td>9,452</td>
|
||||
<td>3,127</td>
|
||||
<td>2,905</td>
|
||||
<td>15,461</td>
|
||||
<td>15,484</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.126">v1.0.126</a></td>
|
||||
@@ -495,34 +495,34 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.120">v1.0.120</a></td>
|
||||
<td>2019-01-10T21:42:53Z</td>
|
||||
<td>15,557</td>
|
||||
<td>15,571</td>
|
||||
<td>5,164</td>
|
||||
<td>6,489</td>
|
||||
<td>27,210</td>
|
||||
<td>27,224</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.119">v1.0.119</a></td>
|
||||
<td>2018-12-18T12:40:22Z</td>
|
||||
<td>8,857</td>
|
||||
<td>3,203</td>
|
||||
<td>8,861</td>
|
||||
<td>3,205</td>
|
||||
<td>1,994</td>
|
||||
<td>14,054</td>
|
||||
<td>14,060</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.118">v1.0.118</a></td>
|
||||
<td>2019-01-11T08:34:13Z</td>
|
||||
<td>678</td>
|
||||
<td>682</td>
|
||||
<td>215</td>
|
||||
<td>75</td>
|
||||
<td>968</td>
|
||||
<td>972</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.117">v1.0.117</a></td>
|
||||
<td>2018-11-24T12:05:24Z</td>
|
||||
<td>16,210</td>
|
||||
<td>16,214</td>
|
||||
<td>4,849</td>
|
||||
<td>6,359</td>
|
||||
<td>27,418</td>
|
||||
<td>27,422</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.116">v1.0.116</a></td>
|
||||
@@ -535,26 +535,26 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.115">v1.0.115</a></td>
|
||||
<td>2018-11-16T16:52:02Z</td>
|
||||
<td>3,630</td>
|
||||
<td>3,632</td>
|
||||
<td>1,280</td>
|
||||
<td>784</td>
|
||||
<td>5,694</td>
|
||||
<td>5,696</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.114">v1.0.114</a></td>
|
||||
<td>2018-10-24T20:14:10Z</td>
|
||||
<td>11,369</td>
|
||||
<td>11,371</td>
|
||||
<td>3,475</td>
|
||||
<td>3,822</td>
|
||||
<td>18,666</td>
|
||||
<td>18,668</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.111">v1.0.111</a></td>
|
||||
<td>2018-09-30T20:15:09Z</td>
|
||||
<td>11,892</td>
|
||||
<td>3,135</td>
|
||||
<td>11,905</td>
|
||||
<td>3,139</td>
|
||||
<td>3,653</td>
|
||||
<td>18,680</td>
|
||||
<td>18,697</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.110">v1.0.110</a></td>
|
||||
@@ -583,42 +583,42 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.107">v1.0.107</a></td>
|
||||
<td>2018-09-16T19:51:07Z</td>
|
||||
<td>7,129</td>
|
||||
<td>7,133</td>
|
||||
<td>2,117</td>
|
||||
<td>1,699</td>
|
||||
<td>10,945</td>
|
||||
<td>10,949</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.106">v1.0.106</a></td>
|
||||
<td>2018-09-08T15:23:40Z</td>
|
||||
<td>4,531</td>
|
||||
<td>4,535</td>
|
||||
<td>1,440</td>
|
||||
<td>309</td>
|
||||
<td>6,280</td>
|
||||
<td>6,284</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.105">v1.0.105</a></td>
|
||||
<td>2018-09-05T11:29:36Z</td>
|
||||
<td>4,595</td>
|
||||
<td>4,599</td>
|
||||
<td>1,554</td>
|
||||
<td>1,441</td>
|
||||
<td>7,590</td>
|
||||
<td>7,594</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.104">v1.0.104</a></td>
|
||||
<td>2018-06-28T20:25:36Z</td>
|
||||
<td>14,992</td>
|
||||
<td>14,995</td>
|
||||
<td>4,656</td>
|
||||
<td>7,105</td>
|
||||
<td>26,753</td>
|
||||
<td>7,128</td>
|
||||
<td>26,779</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.103">v1.0.103</a></td>
|
||||
<td>2018-06-21T19:38:13Z</td>
|
||||
<td>2,016</td>
|
||||
<td>2,022</td>
|
||||
<td>859</td>
|
||||
<td>668</td>
|
||||
<td>3,543</td>
|
||||
<td>3,549</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.101">v1.0.101</a></td>
|
||||
@@ -657,8 +657,8 @@
|
||||
<td>2018-05-26T16:36:39Z</td>
|
||||
<td>2,688</td>
|
||||
<td>1,200</td>
|
||||
<td>1,277</td>
|
||||
<td>5,165</td>
|
||||
<td>1,288</td>
|
||||
<td>5,176</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.95">v1.0.95</a></td>
|
||||
@@ -680,9 +680,9 @@
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.93">v1.0.93</a></td>
|
||||
<td>2018-05-14T11:36:01Z</td>
|
||||
<td>1,770</td>
|
||||
<td>928</td>
|
||||
<td>933</td>
|
||||
<td>743</td>
|
||||
<td>3,441</td>
|
||||
<td>3,446</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.91">v1.0.91</a></td>
|
||||
@@ -711,10 +711,10 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.83">v1.0.83</a></td>
|
||||
<td>2018-04-04T19:43:58Z</td>
|
||||
<td>4,575</td>
|
||||
<td>2,444</td>
|
||||
<td>4,582</td>
|
||||
<td>2,448</td>
|
||||
<td>2,640</td>
|
||||
<td>9,659</td>
|
||||
<td>9,670</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.82">v1.0.82</a></td>
|
||||
@@ -736,9 +736,9 @@
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.79">v1.0.79</a></td>
|
||||
<td>2018-03-23T18:00:11Z</td>
|
||||
<td>920</td>
|
||||
<td>516</td>
|
||||
<td>518</td>
|
||||
<td>361</td>
|
||||
<td>1,797</td>
|
||||
<td>1,799</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.78">v1.0.78</a></td>
|
||||
@@ -769,8 +769,8 @@
|
||||
<td>2018-02-28T20:04:30Z</td>
|
||||
<td>1,845</td>
|
||||
<td>1,031</td>
|
||||
<td>1,233</td>
|
||||
<td>4,109</td>
|
||||
<td>1,235</td>
|
||||
<td>4,111</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.67">v1.0.67</a></td>
|
||||
@@ -793,8 +793,8 @@
|
||||
<td>2018-02-17T20:02:25Z</td>
|
||||
<td>186</td>
|
||||
<td>110</td>
|
||||
<td>120</td>
|
||||
<td>416</td>
|
||||
<td>122</td>
|
||||
<td>418</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v1.0.64">v1.0.64</a></td>
|
||||
@@ -817,16 +817,16 @@
|
||||
<td>2018-02-12T20:19:58Z</td>
|
||||
<td>550</td>
|
||||
<td>281</td>
|
||||
<td>358</td>
|
||||
<td>1,189</td>
|
||||
<td>359</td>
|
||||
<td>1,190</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v0.10.61">v0.10.61</a></td>
|
||||
<td>2018-02-08T18:27:39Z</td>
|
||||
<td>964</td>
|
||||
<td>609</td>
|
||||
<td>611</td>
|
||||
<td>947</td>
|
||||
<td>2,520</td>
|
||||
<td>2,522</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v0.10.60">v0.10.60</a></td>
|
||||
@@ -903,10 +903,10 @@
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v0.10.39">v0.10.39</a></td>
|
||||
<td>2017-12-11T21:19:44Z</td>
|
||||
<td>5,546</td>
|
||||
<td>4,034</td>
|
||||
<td>2,943</td>
|
||||
<td>12,523</td>
|
||||
<td>5,557</td>
|
||||
<td>4,043</td>
|
||||
<td>2,953</td>
|
||||
<td>12,553</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v0.10.38">v0.10.38</a></td>
|
||||
@@ -993,8 +993,8 @@
|
||||
<td>2017-11-24T14:27:49Z</td>
|
||||
<td>139</td>
|
||||
<td>679</td>
|
||||
<td>5,555</td>
|
||||
<td>6,373</td>
|
||||
<td>5,590</td>
|
||||
<td>6,408</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="https://github.com/laurent22/joplin/releases/tag/v0.10.23">v0.10.23</a></td>
|
||||
|
@@ -295,7 +295,7 @@ This big release aims at improving the overall usability of the application and
|
||||
|
||||
Important: This release might be slow on startup due to the need to index all the notes, especially if you have many of them with lots of content. The best is simply to wait for it even if it takes several minutes. This is just a one off and afterwards startup time will be the same as before.
|
||||
|
||||
- New: Fast full text search engine. Works with multiple terms, support for prefixes, can restrict search to either note title or body. See https://joplin.cozic.net/#searching for more info.
|
||||
- New: Fast full text search engine. Works with multiple terms, support for prefixes, can restrict search to either note title or body. See https://joplinapp.org/#searching for more info.
|
||||
- New: Search within current note (Ctrl+F).
|
||||
- New: Add separate editor font size option ([#1027](https://github.com/laurent22/joplin/issues/1027))
|
||||
- Changed: Changed global search shortcut to F6.
|
||||
@@ -309,7 +309,7 @@ Important: This release might be slow on startup due to the need to index all th
|
||||
|
||||
Important: This release might be slow on startup due to the need to index all the notes, especially if you have many of them with lots of content. The best is simply to wait for it even if it takes several minutes. This is just a one off and afterwards startup time will be the same as before.
|
||||
|
||||
- New: Fast full text search engine. Works with multiple terms, support for prefixes, can restrict search to either note title or body. See https://joplin.cozic.net/#searching for more info.
|
||||
- New: Fast full text search engine. Works with multiple terms, support for prefixes, can restrict search to either note title or body. See https://joplinapp.org/#searching for more info.
|
||||
- New: Search within current note (Ctrl+F).
|
||||
- New: Add separate editor font size option ([#1027](https://github.com/laurent22/joplin/issues/1027))
|
||||
- Changed: Changed global search shortcut to F6.
|
||||
@@ -523,7 +523,7 @@ This release is mainly to fix various issues with the recently released Web Clip
|
||||
|
||||
## [v1.0.93](https://github.com/laurent22/joplin/releases/tag/v1.0.93) - 2018-05-14T11:36:01Z
|
||||
|
||||
- New: A portable version is now available. To install it simply copy the file "JoplinPortable.exe" to your USB device. See the documentation for more information - https://joplin.cozic.net/#desktop-applications
|
||||
- New: A portable version is now available. To install it simply copy the file "JoplinPortable.exe" to your USB device. See the documentation for more information - https://joplinapp.org/#desktop-applications
|
||||
- Improved: Made import of ENEX files more robust and accurate
|
||||
- Improved: Auto-update process should be more reliable.
|
||||
- Fixed: Made sync-after-save interval longer to made synchronisations less frequent.
|
||||
@@ -541,7 +541,7 @@ Same as v1.0.90 but with a fix for [#510](https://github.com/laurent22/joplin/is
|
||||
|
||||
## [v1.0.89](https://github.com/laurent22/joplin/releases/tag/v1.0.89) - 2018-05-09T13:05:05Z
|
||||
|
||||
- New: Resolves [#122](https://github.com/laurent22/joplin/issues/122): Added support for sub-notebooks. Please see doc for more info: https://joplin.cozic.net/#sub-notebooks
|
||||
- New: Resolves [#122](https://github.com/laurent22/joplin/issues/122): Added support for sub-notebooks. Please see doc for more info: https://joplinapp.org/#sub-notebooks
|
||||
- Improved: Export/Import links to notes
|
||||
- Fixes [#480](https://github.com/laurent22/joplin/issues/480): Ignore invalid flag automatically passed by macOS
|
||||
- Fixes [#61](https://github.com/laurent22/joplin/issues/61): Handle path that ends with slash for file system sync
|
||||
|
@@ -37,7 +37,7 @@ Some crashes cannot be investigated using Joplin's own tools. In that case, it c
|
||||
|
||||
For this, please follow these instructions:
|
||||
|
||||
You can send it to this address https://raw.githubusercontent.com/laurent22/joplin/master/Assets/Adresse.png
|
||||
You can send it to this address https://raw.githubusercontent.com/laurent22/joplin/master/Assets/AdresseSupport.png
|
||||
|
||||
https://developer.apple.com/library/content/qa/qa1747/_index.html
|
||||
|
||||
|
@@ -2,79 +2,79 @@
|
||||
|
||||
Name | Value
|
||||
--- | ---
|
||||
Total Windows downloads | 279,497
|
||||
Total macOs downloads | 119,042
|
||||
Total Linux downloads | 93,494
|
||||
Total Windows downloads | 291,223
|
||||
Total macOs downloads | 122,809
|
||||
Total Linux downloads | 96,536
|
||||
Windows % | 57%
|
||||
macOS % | 24%
|
||||
Linux % | 19%
|
||||
|
||||
Version | Date | Windows | macOS | Linux | Total
|
||||
--- | --- | --- | --- | --- | ---
|
||||
[v1.0.160](https://github.com/laurent22/joplin/releases/tag/v1.0.160) | 2019-06-15T00:21:40Z | 381 | 117 | 57 | 555
|
||||
[v1.0.159](https://github.com/laurent22/joplin/releases/tag/v1.0.159) | 2019-06-08T00:00:19Z | 5,046 | 2,092 | 1,055 | 8,193
|
||||
[v1.0.158](https://github.com/laurent22/joplin/releases/tag/v1.0.158) | 2019-05-27T19:01:18Z | 9,541 | 3,478 | 1,915 | 14,934
|
||||
[v1.0.157](https://github.com/laurent22/joplin/releases/tag/v1.0.157) | 2019-05-26T17:55:53Z | 2,127 | 808 | 272 | 3,207
|
||||
[v1.0.160](https://github.com/laurent22/joplin/releases/tag/v1.0.160) | 2019-06-15T00:21:40Z | 11,629 | 3,795 | 2,992 | 18,416
|
||||
[v1.0.159](https://github.com/laurent22/joplin/releases/tag/v1.0.159) | 2019-06-08T00:00:19Z | 5,122 | 2,137 | 1,071 | 8,330
|
||||
[v1.0.158](https://github.com/laurent22/joplin/releases/tag/v1.0.158) | 2019-05-27T19:01:18Z | 9,741 | 3,484 | 1,915 | 15,140
|
||||
[v1.0.157](https://github.com/laurent22/joplin/releases/tag/v1.0.157) | 2019-05-26T17:55:53Z | 2,133 | 808 | 272 | 3,213
|
||||
[v1.0.153](https://github.com/laurent22/joplin/releases/tag/v1.0.153) | 2019-05-15T06:27:29Z | 822 | 73 | 94 | 989
|
||||
[v1.0.152](https://github.com/laurent22/joplin/releases/tag/v1.0.152) | 2019-05-13T09:08:07Z | 13,722 | 4,373 | 4,045 | 22,140
|
||||
[v1.0.152](https://github.com/laurent22/joplin/releases/tag/v1.0.152) | 2019-05-13T09:08:07Z | 13,750 | 4,380 | 4,045 | 22,175
|
||||
[v1.0.151](https://github.com/laurent22/joplin/releases/tag/v1.0.151) | 2019-05-12T15:14:32Z | 1,927 | 511 | 947 | 3,385
|
||||
[v1.0.150](https://github.com/laurent22/joplin/releases/tag/v1.0.150) | 2019-05-12T11:27:48Z | 395 | 109 | 56 | 560
|
||||
[v1.0.148](https://github.com/laurent22/joplin/releases/tag/v1.0.148) | 2019-05-08T19:12:24Z | 111 | 36 | 77 | 224
|
||||
[v1.0.145](https://github.com/laurent22/joplin/releases/tag/v1.0.145) | 2019-05-03T09:16:53Z | 6,868 | 2,830 | 1,425 | 11,123
|
||||
[v1.0.143](https://github.com/laurent22/joplin/releases/tag/v1.0.143) | 2019-04-22T10:51:38Z | 11,861 | 3,512 | 2,765 | 18,138
|
||||
[v1.0.142](https://github.com/laurent22/joplin/releases/tag/v1.0.142) | 2019-04-02T16:44:51Z | 14,494 | 4,511 | 4,708 | 23,713
|
||||
[v1.0.140](https://github.com/laurent22/joplin/releases/tag/v1.0.140) | 2019-03-10T20:59:58Z | 13,535 | 4,120 | 2,995 | 20,650
|
||||
[v1.0.148](https://github.com/laurent22/joplin/releases/tag/v1.0.148) | 2019-05-08T19:12:24Z | 111 | 36 | 78 | 225
|
||||
[v1.0.145](https://github.com/laurent22/joplin/releases/tag/v1.0.145) | 2019-05-03T09:16:53Z | 6,877 | 2,830 | 1,425 | 11,132
|
||||
[v1.0.143](https://github.com/laurent22/joplin/releases/tag/v1.0.143) | 2019-04-22T10:51:38Z | 11,862 | 3,513 | 2,765 | 18,140
|
||||
[v1.0.142](https://github.com/laurent22/joplin/releases/tag/v1.0.142) | 2019-04-02T16:44:51Z | 14,503 | 4,511 | 4,710 | 23,724
|
||||
[v1.0.140](https://github.com/laurent22/joplin/releases/tag/v1.0.140) | 2019-03-10T20:59:58Z | 13,557 | 4,122 | 2,999 | 20,678
|
||||
[v1.0.139](https://github.com/laurent22/joplin/releases/tag/v1.0.139) | 2019-03-09T10:06:48Z | 83 | 20 | 25 | 128
|
||||
[v1.0.138](https://github.com/laurent22/joplin/releases/tag/v1.0.138) | 2019-03-03T17:23:00Z | 113 | 42 | 68 | 223
|
||||
[v1.0.137](https://github.com/laurent22/joplin/releases/tag/v1.0.137) | 2019-03-03T01:12:51Z | 547 | 26 | 68 | 641
|
||||
[v1.0.135](https://github.com/laurent22/joplin/releases/tag/v1.0.135) | 2019-02-27T23:36:57Z | 12,192 | 3,915 | 4,045 | 20,152
|
||||
[v1.0.135](https://github.com/laurent22/joplin/releases/tag/v1.0.135) | 2019-02-27T23:36:57Z | 12,214 | 3,915 | 4,045 | 20,174
|
||||
[v1.0.134](https://github.com/laurent22/joplin/releases/tag/v1.0.134) | 2019-02-27T10:21:44Z | 1,431 | 532 | 201 | 2,164
|
||||
[v1.0.132](https://github.com/laurent22/joplin/releases/tag/v1.0.132) | 2019-02-26T23:02:05Z | 1,046 | 411 | 79 | 1,536
|
||||
[v1.0.127](https://github.com/laurent22/joplin/releases/tag/v1.0.127) | 2019-02-14T23:12:48Z | 9,429 | 3,127 | 2,905 | 15,461
|
||||
[v1.0.127](https://github.com/laurent22/joplin/releases/tag/v1.0.127) | 2019-02-14T23:12:48Z | 9,452 | 3,127 | 2,905 | 15,484
|
||||
[v1.0.126](https://github.com/laurent22/joplin/releases/tag/v1.0.126) | 2019-02-09T19:46:16Z | 914 | 53 | 109 | 1,076
|
||||
[v1.0.125](https://github.com/laurent22/joplin/releases/tag/v1.0.125) | 2019-01-26T18:14:33Z | 10,230 | 3,522 | 1,693 | 15,445
|
||||
[v1.0.120](https://github.com/laurent22/joplin/releases/tag/v1.0.120) | 2019-01-10T21:42:53Z | 15,557 | 5,164 | 6,489 | 27,210
|
||||
[v1.0.119](https://github.com/laurent22/joplin/releases/tag/v1.0.119) | 2018-12-18T12:40:22Z | 8,857 | 3,203 | 1,994 | 14,054
|
||||
[v1.0.118](https://github.com/laurent22/joplin/releases/tag/v1.0.118) | 2019-01-11T08:34:13Z | 678 | 215 | 75 | 968
|
||||
[v1.0.117](https://github.com/laurent22/joplin/releases/tag/v1.0.117) | 2018-11-24T12:05:24Z | 16,210 | 4,849 | 6,359 | 27,418
|
||||
[v1.0.120](https://github.com/laurent22/joplin/releases/tag/v1.0.120) | 2019-01-10T21:42:53Z | 15,571 | 5,164 | 6,489 | 27,224
|
||||
[v1.0.119](https://github.com/laurent22/joplin/releases/tag/v1.0.119) | 2018-12-18T12:40:22Z | 8,861 | 3,205 | 1,994 | 14,060
|
||||
[v1.0.118](https://github.com/laurent22/joplin/releases/tag/v1.0.118) | 2019-01-11T08:34:13Z | 682 | 215 | 75 | 972
|
||||
[v1.0.117](https://github.com/laurent22/joplin/releases/tag/v1.0.117) | 2018-11-24T12:05:24Z | 16,214 | 4,849 | 6,359 | 27,422
|
||||
[v1.0.116](https://github.com/laurent22/joplin/releases/tag/v1.0.116) | 2018-11-20T19:09:24Z | 3,458 | 1,087 | 704 | 5,249
|
||||
[v1.0.115](https://github.com/laurent22/joplin/releases/tag/v1.0.115) | 2018-11-16T16:52:02Z | 3,630 | 1,280 | 784 | 5,694
|
||||
[v1.0.114](https://github.com/laurent22/joplin/releases/tag/v1.0.114) | 2018-10-24T20:14:10Z | 11,369 | 3,475 | 3,822 | 18,666
|
||||
[v1.0.111](https://github.com/laurent22/joplin/releases/tag/v1.0.111) | 2018-09-30T20:15:09Z | 11,892 | 3,135 | 3,653 | 18,680
|
||||
[v1.0.115](https://github.com/laurent22/joplin/releases/tag/v1.0.115) | 2018-11-16T16:52:02Z | 3,632 | 1,280 | 784 | 5,696
|
||||
[v1.0.114](https://github.com/laurent22/joplin/releases/tag/v1.0.114) | 2018-10-24T20:14:10Z | 11,371 | 3,475 | 3,822 | 18,668
|
||||
[v1.0.111](https://github.com/laurent22/joplin/releases/tag/v1.0.111) | 2018-09-30T20:15:09Z | 11,905 | 3,139 | 3,653 | 18,697
|
||||
[v1.0.110](https://github.com/laurent22/joplin/releases/tag/v1.0.110) | 2018-09-29T12:29:21Z | 926 | 376 | 103 | 1,405
|
||||
[v1.0.109](https://github.com/laurent22/joplin/releases/tag/v1.0.109) | 2018-09-27T18:01:41Z | 2,074 | 681 | 314 | 3,069
|
||||
[v1.0.108](https://github.com/laurent22/joplin/releases/tag/v1.0.108) | 2018-09-29T18:49:29Z | 13 | 6 | 6 | 25
|
||||
[v1.0.107](https://github.com/laurent22/joplin/releases/tag/v1.0.107) | 2018-09-16T19:51:07Z | 7,129 | 2,117 | 1,699 | 10,945
|
||||
[v1.0.106](https://github.com/laurent22/joplin/releases/tag/v1.0.106) | 2018-09-08T15:23:40Z | 4,531 | 1,440 | 309 | 6,280
|
||||
[v1.0.105](https://github.com/laurent22/joplin/releases/tag/v1.0.105) | 2018-09-05T11:29:36Z | 4,595 | 1,554 | 1,441 | 7,590
|
||||
[v1.0.104](https://github.com/laurent22/joplin/releases/tag/v1.0.104) | 2018-06-28T20:25:36Z | 14,992 | 4,656 | 7,105 | 26,753
|
||||
[v1.0.103](https://github.com/laurent22/joplin/releases/tag/v1.0.103) | 2018-06-21T19:38:13Z | 2,016 | 859 | 668 | 3,543
|
||||
[v1.0.107](https://github.com/laurent22/joplin/releases/tag/v1.0.107) | 2018-09-16T19:51:07Z | 7,133 | 2,117 | 1,699 | 10,949
|
||||
[v1.0.106](https://github.com/laurent22/joplin/releases/tag/v1.0.106) | 2018-09-08T15:23:40Z | 4,535 | 1,440 | 309 | 6,284
|
||||
[v1.0.105](https://github.com/laurent22/joplin/releases/tag/v1.0.105) | 2018-09-05T11:29:36Z | 4,599 | 1,554 | 1,441 | 7,594
|
||||
[v1.0.104](https://github.com/laurent22/joplin/releases/tag/v1.0.104) | 2018-06-28T20:25:36Z | 14,995 | 4,656 | 7,128 | 26,779
|
||||
[v1.0.103](https://github.com/laurent22/joplin/releases/tag/v1.0.103) | 2018-06-21T19:38:13Z | 2,022 | 859 | 668 | 3,549
|
||||
[v1.0.101](https://github.com/laurent22/joplin/releases/tag/v1.0.101) | 2018-06-17T18:35:11Z | 1,290 | 581 | 401 | 2,272
|
||||
[v1.0.100](https://github.com/laurent22/joplin/releases/tag/v1.0.100) | 2018-06-14T17:41:43Z | 857 | 410 | 228 | 1,495
|
||||
[v1.0.99](https://github.com/laurent22/joplin/releases/tag/v1.0.99) | 2018-06-10T13:18:23Z | 1,238 | 581 | 372 | 2,191
|
||||
[v1.0.97](https://github.com/laurent22/joplin/releases/tag/v1.0.97) | 2018-06-09T19:23:34Z | 297 | 138 | 54 | 489
|
||||
[v1.0.96](https://github.com/laurent22/joplin/releases/tag/v1.0.96) | 2018-05-26T16:36:39Z | 2,688 | 1,200 | 1,277 | 5,165
|
||||
[v1.0.96](https://github.com/laurent22/joplin/releases/tag/v1.0.96) | 2018-05-26T16:36:39Z | 2,688 | 1,200 | 1,288 | 5,176
|
||||
[v1.0.95](https://github.com/laurent22/joplin/releases/tag/v1.0.95) | 2018-05-25T13:04:30Z | 387 | 190 | 87 | 664
|
||||
[v1.0.94](https://github.com/laurent22/joplin/releases/tag/v1.0.94) | 2018-05-21T20:52:59Z | 1,099 | 557 | 362 | 2,018
|
||||
[v1.0.93](https://github.com/laurent22/joplin/releases/tag/v1.0.93) | 2018-05-14T11:36:01Z | 1,770 | 928 | 743 | 3,441
|
||||
[v1.0.93](https://github.com/laurent22/joplin/releases/tag/v1.0.93) | 2018-05-14T11:36:01Z | 1,770 | 933 | 743 | 3,446
|
||||
[v1.0.91](https://github.com/laurent22/joplin/releases/tag/v1.0.91) | 2018-05-10T14:48:04Z | 816 | 536 | 290 | 1,642
|
||||
[v1.0.89](https://github.com/laurent22/joplin/releases/tag/v1.0.89) | 2018-05-09T13:05:05Z | 476 | 212 | 97 | 785
|
||||
[v1.0.85](https://github.com/laurent22/joplin/releases/tag/v1.0.85) | 2018-05-01T21:08:24Z | 1,641 | 934 | 617 | 3,192
|
||||
[v1.0.83](https://github.com/laurent22/joplin/releases/tag/v1.0.83) | 2018-04-04T19:43:58Z | 4,575 | 2,444 | 2,640 | 9,659
|
||||
[v1.0.83](https://github.com/laurent22/joplin/releases/tag/v1.0.83) | 2018-04-04T19:43:58Z | 4,582 | 2,448 | 2,640 | 9,670
|
||||
[v1.0.82](https://github.com/laurent22/joplin/releases/tag/v1.0.82) | 2018-03-31T19:16:31Z | 686 | 388 | 106 | 1,180
|
||||
[v1.0.81](https://github.com/laurent22/joplin/releases/tag/v1.0.81) | 2018-03-28T08:13:58Z | 986 | 572 | 754 | 2,312
|
||||
[v1.0.79](https://github.com/laurent22/joplin/releases/tag/v1.0.79) | 2018-03-23T18:00:11Z | 920 | 516 | 361 | 1,797
|
||||
[v1.0.79](https://github.com/laurent22/joplin/releases/tag/v1.0.79) | 2018-03-23T18:00:11Z | 920 | 518 | 361 | 1,799
|
||||
[v1.0.78](https://github.com/laurent22/joplin/releases/tag/v1.0.78) | 2018-03-17T15:27:18Z | 1,303 | 845 | 853 | 3,001
|
||||
[v1.0.77](https://github.com/laurent22/joplin/releases/tag/v1.0.77) | 2018-03-16T15:12:35Z | 166 | 89 | 29 | 284
|
||||
[v1.0.72](https://github.com/laurent22/joplin/releases/tag/v1.0.72) | 2018-03-14T09:44:35Z | 397 | 238 | 41 | 676
|
||||
[v1.0.70](https://github.com/laurent22/joplin/releases/tag/v1.0.70) | 2018-02-28T20:04:30Z | 1,845 | 1,031 | 1,233 | 4,109
|
||||
[v1.0.70](https://github.com/laurent22/joplin/releases/tag/v1.0.70) | 2018-02-28T20:04:30Z | 1,845 | 1,031 | 1,235 | 4,111
|
||||
[v1.0.67](https://github.com/laurent22/joplin/releases/tag/v1.0.67) | 2018-02-19T22:51:08Z | 1,806 | 585 | 0 | 2,391
|
||||
[v1.0.66](https://github.com/laurent22/joplin/releases/tag/v1.0.66) | 2018-02-18T23:09:09Z | 315 | 109 | 74 | 498
|
||||
[v1.0.65](https://github.com/laurent22/joplin/releases/tag/v1.0.65) | 2018-02-17T20:02:25Z | 186 | 110 | 120 | 416
|
||||
[v1.0.65](https://github.com/laurent22/joplin/releases/tag/v1.0.65) | 2018-02-17T20:02:25Z | 186 | 110 | 122 | 418
|
||||
[v1.0.64](https://github.com/laurent22/joplin/releases/tag/v1.0.64) | 2018-02-16T00:58:20Z | 1,076 | 531 | 1,117 | 2,724
|
||||
[v1.0.63](https://github.com/laurent22/joplin/releases/tag/v1.0.63) | 2018-02-14T19:40:36Z | 292 | 145 | 84 | 521
|
||||
[v1.0.62](https://github.com/laurent22/joplin/releases/tag/v1.0.62) | 2018-02-12T20:19:58Z | 550 | 281 | 358 | 1,189
|
||||
[v0.10.61](https://github.com/laurent22/joplin/releases/tag/v0.10.61) | 2018-02-08T18:27:39Z | 964 | 609 | 947 | 2,520
|
||||
[v1.0.62](https://github.com/laurent22/joplin/releases/tag/v1.0.62) | 2018-02-12T20:19:58Z | 550 | 281 | 359 | 1,190
|
||||
[v0.10.61](https://github.com/laurent22/joplin/releases/tag/v0.10.61) | 2018-02-08T18:27:39Z | 964 | 611 | 947 | 2,522
|
||||
[v0.10.60](https://github.com/laurent22/joplin/releases/tag/v0.10.60) | 2018-02-06T13:09:56Z | 713 | 503 | 545 | 1,761
|
||||
[v0.10.54](https://github.com/laurent22/joplin/releases/tag/v0.10.54) | 2018-01-31T20:21:30Z | 1,813 | 1,444 | 311 | 3,568
|
||||
[v0.10.52](https://github.com/laurent22/joplin/releases/tag/v0.10.52) | 2018-01-31T19:25:18Z | 38 | 618 | 7 | 663
|
||||
@@ -84,7 +84,7 @@ Version | Date | Windows | macOS | Linux | Total
|
||||
[v0.10.43](https://github.com/laurent22/joplin/releases/tag/v0.10.43) | 2018-01-08T10:12:10Z | 3,428 | 2,332 | 1,200 | 6,960
|
||||
[v0.10.41](https://github.com/laurent22/joplin/releases/tag/v0.10.41) | 2018-01-05T20:38:12Z | 1,030 | 1,534 | 231 | 2,795
|
||||
[v0.10.40](https://github.com/laurent22/joplin/releases/tag/v0.10.40) | 2018-01-02T23:16:57Z | 1,587 | 1,756 | 329 | 3,672
|
||||
[v0.10.39](https://github.com/laurent22/joplin/releases/tag/v0.10.39) | 2017-12-11T21:19:44Z | 5,546 | 4,034 | 2,943 | 12,523
|
||||
[v0.10.39](https://github.com/laurent22/joplin/releases/tag/v0.10.39) | 2017-12-11T21:19:44Z | 5,557 | 4,043 | 2,953 | 12,553
|
||||
[v0.10.38](https://github.com/laurent22/joplin/releases/tag/v0.10.38) | 2017-12-08T10:12:06Z | 1,041 | 1,213 | 299 | 2,553
|
||||
[v0.10.37](https://github.com/laurent22/joplin/releases/tag/v0.10.37) | 2017-12-07T19:38:05Z | 256 | 829 | 74 | 1,159
|
||||
[v0.10.36](https://github.com/laurent22/joplin/releases/tag/v0.10.36) | 2017-12-05T09:34:40Z | 1,008 | 1,340 | 431 | 2,779
|
||||
@@ -95,7 +95,7 @@ Version | Date | Windows | macOS | Linux | Total
|
||||
[v0.10.30](https://github.com/laurent22/joplin/releases/tag/v0.10.30) | 2017-11-30T20:28:16Z | 711 | 1,352 | 410 | 2,473
|
||||
[v0.10.28](https://github.com/laurent22/joplin/releases/tag/v0.10.28) | 2017-11-30T01:07:46Z | 1,282 | 1,683 | 864 | 3,829
|
||||
[v0.10.26](https://github.com/laurent22/joplin/releases/tag/v0.10.26) | 2017-11-29T16:02:17Z | 180 | 685 | 255 | 1,120
|
||||
[v0.10.25](https://github.com/laurent22/joplin/releases/tag/v0.10.25) | 2017-11-24T14:27:49Z | 139 | 679 | 5,555 | 6,373
|
||||
[v0.10.25](https://github.com/laurent22/joplin/releases/tag/v0.10.25) | 2017-11-24T14:27:49Z | 139 | 679 | 5,590 | 6,408
|
||||
[v0.10.23](https://github.com/laurent22/joplin/releases/tag/v0.10.23) | 2017-11-21T19:38:41Z | 125 | 630 | 21 | 776
|
||||
[v0.10.22](https://github.com/laurent22/joplin/releases/tag/v0.10.22) | 2017-11-20T21:45:57Z | 77 | 629 | 13 | 719
|
||||
[v0.10.21](https://github.com/laurent22/joplin/releases/tag/v0.10.21) | 2017-11-18T00:53:15Z | 45 | 622 | 5 | 672
|
||||
|
Reference in New Issue
Block a user