Browse Source

Merge remote-tracking branch 'upstream/master' into whiteboards

Peng Xiao 3 years ago
parent
commit
ab6eec5fc3

+ 2 - 3
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -198,7 +198,6 @@
   [format properties user-config]
   (when (seq properties)
     (let [properties (seq properties)
-          properties (into {} properties)
           page-refs (get-page-ref-names-from-properties format properties user-config)
           properties (->> properties
                           (map (fn [[k v]]
@@ -512,7 +511,7 @@
                                 :content content
                                 :level 1
                                 :properties properties
-                                :properties-order properties-order
+                                :properties-order (vec properties-order)
                                 :refs property-refs
                                 :pre-block? true
                                 :unordered true
@@ -548,7 +547,7 @@
                 (assoc :properties (:properties properties))
 
                 (seq (:properties-order properties))
-                (assoc :properties-order (:properties-order properties)))
+                (assoc :properties-order (vec (:properties-order properties))))
         block (if (get-in block [:properties :collapsed])
                 (-> (assoc block :collapsed? true)
                     (update :properties (fn [m] (dissoc m :collapsed)))

+ 30 - 3
deps/graph-parser/test/logseq/graph_parser_test.cljs

@@ -1,5 +1,6 @@
 (ns logseq.graph-parser-test
   (:require [cljs.test :refer [deftest testing is]]
+            [clojure.string :as string]
             [logseq.graph-parser :as graph-parser]
             [logseq.db :as ldb]
             [logseq.graph-parser.block :as gp-block]
@@ -51,9 +52,35 @@
                                                         (reset! deleted-page page))})
           (catch :default _)))
       (is (= nil @deleted-page)
-          "Page should not be deleted when there is unexpected failure")))
+          "Page should not be deleted when there is unexpected failure"))))
 
-  (testing "parsing whiteboard page"
+(defn- test-property-order [num-properties]
+  (let [conn (ldb/start-conn)
+        properties (mapv #(keyword (str "p" %)) (range 0 num-properties))
+        text (->> properties
+                  (map #(str (name %) ":: " (name %) "-value"))
+                  (string/join "\n"))
+        ;; Test page properties and block properties
+        body (str text "\n- " text)
+        _ (graph-parser/parse-file conn "foo.md" body {})
+        properties-orders (->> (d/q '[:find (pull ?b [*])
+                                      :in $
+                                      :where [?b :block/content] [(missing? $ ?b :block/name)]]
+                                    @conn)
+                               (map first)
+                               (map :block/properties-order))]
+    (is (every? vector? properties-orders)
+        "Order is persisted as a vec to avoid edn serialization quirks")
+    (is (= [properties properties] properties-orders)
+        "Property order")))
+
+(deftest properties-order
+  (testing "Sort order and persistence of a few properties"
+    (test-property-order 4))
+  (testing "Sort order and persistence of 10 properties"
+    (test-property-order 10)))
+
+(testing "parsing whiteboard page"
     (let [conn (ldb/start-conn)]
       (graph-parser/parse-file conn "/whiteboards/foo.edn" (pr-str foo-edn) {})
       (is (= {:block/name "foo" :block/file {:file/path "/whiteboards/foo.edn"}}
@@ -66,4 +93,4 @@
                                @conn)
                    parent (:block/parent (ffirst blocks))]
                parent))
-          "parsed block in the whiteboard page has correct parent page"))))
+          "parsed block in the whiteboard page has correct parent page"))))

+ 33 - 1
e2e-tests/editor.spec.ts

@@ -178,4 +178,36 @@ test('copy & paste block ref and replace its content', async ({ page, block }) =
     } else {
         await page.keyboard.press('Control+Shift+v')
     }
-})
+})
+
+test('copy and paste block after editing new block', async ({ page, block }) => {
+  await createRandomPage(page)
+
+  // Create a block and copy it in block-select mode
+  await block.mustFill('Block being copied')
+  await page.waitForTimeout(100)
+  await page.keyboard.press('Escape')
+  await page.waitForTimeout(100)
+  if (IsMac) {
+    await page.keyboard.press('Meta+c')
+  } else {
+    await page.keyboard.press('Control+c')
+  }
+  // await page.waitForTimeout(100)
+  await page.keyboard.press('Enter')
+  await page.waitForTimeout(100)
+  await page.keyboard.press('Enter')
+  
+  await page.waitForTimeout(100)
+  // Create a new block with some text
+  await page.keyboard.insertText("Typed block")
+
+  // Quickly paste the copied block
+  if (IsMac) {
+      await page.keyboard.press('Meta+v')
+  } else {
+      await page.keyboard.press('Control+v')
+  }
+
+  await expect(page.locator('text="Typed block"')).toHaveCount(1);
+})

+ 18 - 13
e2e-tests/utils.ts

@@ -2,6 +2,7 @@ import { Page, Locator } from 'playwright'
 import { expect, ConsoleMessage } from '@playwright/test'
 import * as process from 'process'
 import { Block } from './types'
+import pathlib from 'path'
 
 export const IsMac = process.platform === 'darwin'
 export const IsLinux = process.platform === 'linux'
@@ -159,39 +160,35 @@ export async function openLeftSidebar(page: Page): Promise<void> {
   let sidebar = page.locator('#left-sidebar')
 
   // Left sidebar is toggled by `is-open` class
-  if (!/is-open/.test(await sidebar.getAttribute('class'))) {
+  if (!/is-open/.test(await sidebar.getAttribute('class') || '')) {
     await page.click('#left-menu.button')
     await page.waitForTimeout(10)
     await expect(sidebar).toHaveClass(/is-open/)
   }
 }
 
-export async function loadLocalGraph(page: Page, path?: string): Promise<void> {
+export async function loadLocalGraph(page: Page, path: string): Promise<void> {
   await setMockedOpenDirPath(page, path);
-
+  
   const onboardingOpenButton = page.locator('strong:has-text("Choose a folder")')
 
   if (await onboardingOpenButton.isVisible()) {
     await onboardingOpenButton.click()
   } else {
-    await page.click('#left-menu.button')
+    console.log("No onboarding button, loading file manually")
     let sidebar = page.locator('#left-sidebar')
-    if (!/is-open/.test(await sidebar.getAttribute('class'))) {
+    if (!/is-open/.test(await sidebar.getAttribute('class') || '')) {
       await page.click('#left-menu.button')
       await expect(sidebar).toHaveClass(/is-open/)
     }
-
+    
     await page.click('#left-sidebar #repo-switch');
     await page.waitForSelector('#left-sidebar .dropdown-wrapper >> text="Add new graph"',
-      { state: 'visible', timeout: 5000 })
-
+    { state: 'visible', timeout: 5000 })
     await page.click('text=Add new graph')
-    await page.waitForSelector('strong:has-text("Choose a folder")',
-      { state: 'visible', timeout: 5000 })
-    await page.click('strong:has-text("Choose a folder")')
+    await page.waitForSelector('strong:has-text("Choose a folder")',{ state: 'visible', timeout: 5000 })
 
-    const skip = page.locator('a:has-text("Skip")')
-    await skip.click()
+    expect(page.locator('#repo-name')).toHaveText(pathlib.basename(path))
   }
 
   setMockedOpenDirPath(page, ''); // reset it
@@ -207,6 +204,14 @@ export async function loadLocalGraph(page: Page, path?: string): Promise<void> {
   }
 
   await page.waitForFunction('window.document.title === "Logseq"')
+  await page.waitForTimeout(500)
+
+  // If there is an error notification from a previous test graph being deleted,
+  // close it first so it doesn't cover up the UI
+  while (await (page.locator('.notification-close-button').first()?.isVisible())) {
+    await page.click('.notification-close-button')
+    await page.waitForTimeout(250)
+  }
 
   console.log('Graph loaded for ' + path)
 }

+ 2 - 2
package.json

@@ -5,7 +5,7 @@
     "main": "static/electron.js",
     "devDependencies": {
         "@capacitor/cli": "3.2.2",
-        "@playwright/test": "^1.19.2",
+        "@playwright/test": "^1.24.2",
         "@tailwindcss/ui": "0.7.2",
         "@types/gulp": "^4.0.7",
         "cross-env": "^7.0.3",
@@ -14,7 +14,7 @@
         "gulp": "^4.0.2",
         "gulp-clean-css": "^4.3.0",
         "npm-run-all": "^4.1.5",
-        "playwright": "^1.19.2",
+        "playwright": "^1.24.2",
         "postcss": "8.2.13",
         "postcss-cli": "8.3.1",
         "postcss-import": "^14.0.0",

+ 2 - 2
src/main/frontend/components/block.cljs

@@ -1862,8 +1862,8 @@
   [config block]
   (let [properties (walk/keywordize-keys (:block/properties block))
         properties-order (:block/properties-order block)
-        properties (apply dissoc properties (property/built-in-properties))
-        properties-order (remove (property/built-in-properties) properties-order)
+        properties (apply dissoc properties (property/hidden-properties))
+        properties-order (remove (property/hidden-properties) properties-order)
         pre-block? (:block/pre-block? block)
         properties (if pre-block?
                      (let [repo (state/get-current-repo)

+ 1 - 1
src/main/frontend/components/editor.cljs

@@ -177,7 +177,7 @@
      result
      {:on-chosen   chosen-handler
       :on-enter    non-exist-block-handler
-      :empty-placeholder   [:div.text-gray-500.pl-4.pr-4 "Search for a block"]
+      :empty-placeholder   [:div.text-gray-500.pl-4.pr-4 (t :editor/block-search)]
       :item-render (fn [{:block/keys [page uuid]}]  ;; content returned from search engine is normalized
                      (let [page (or (:block/original-name page)
                                     (:block/name page))

+ 1 - 1
src/main/frontend/components/header.css

@@ -90,7 +90,6 @@
 
     a.restart {
       position: relative;
-      cursor: pointer !important;
       display: flex;
       align-items: center;
 
@@ -102,6 +101,7 @@
       > strong {
         display: inline-block;
         padding-left: 2px;
+        cursor: pointer;
       }
     }
   }

+ 4 - 4
src/main/frontend/components/search.cljs

@@ -30,8 +30,8 @@
     content
     (when (and content q)
       (let [q-words (string/split q #" ")
-            lc-content (util/search-normalize content)
-            lc-q (util/search-normalize q)]
+            lc-content (util/search-normalize content (state/enable-search-remove-accents?))
+            lc-q (util/search-normalize q (state/enable-search-remove-accents?))]
         (if (and (string/includes? lc-content lc-q)
                  (not (util/safe-re-find #" " q)))
           (let [i (string/index-of lc-content lc-q)
@@ -47,8 +47,8 @@
                                 result []]
                            (if (and (seq words) content)
                              (let [word (first words)
-                                   lc-word (util/search-normalize word)
-                                   lc-content (util/search-normalize content)]
+                                   lc-word (util/search-normalize word (state/enable-search-remove-accents?))
+                                   lc-content (util/search-normalize content (state/enable-search-remove-accents?))]
                                (if-let [i (string/index-of lc-content lc-word)]
                                  (recur (rest words)
                                         (subs content (+ i (count word)))

+ 6 - 9
src/main/frontend/components/sidebar.cljs

@@ -41,18 +41,15 @@
             [reitit.frontend.easy :as rfe]
             [rum.core :as rum]))
 
-(rum/defc nav-content-item
+(rum/defc nav-content-item < rum/reactive
   [name {:keys [class]} child]
 
-  [:div.nav-content-item.is-expand
-   {:class class}
+  [:div.nav-content-item
+   {:class (util/classnames [class {:is-expand (not (state/sub [:ui/navigation-item-collapsed? class]))}])}
    [:div.nav-content-item-inner
     [:div.header.items-center.mb-1
-     {:on-click (fn [^js/MouseEvent e]
-                  (let [^js target (.-target e)
-                        ^js parent (.closest target ".nav-content-item")]
-                    (.toggle (.-classList parent) "is-expand")))}
-
+     {:on-click (fn [^js/MouseEvent _e]
+                  (state/toggle-navigation-item-collapsed! class))}
      [:div.font-medium.fade-link name]
      [:span
       [:a.more svg/arrow-down-v2]]]
@@ -276,7 +273,7 @@
             :active (and (not srs-open?) (#{:whiteboard :whiteboards} route-name))
             :icon  "artboard"}))]]
 
-      (favorites t)
+      (when (and left-sidebar-open? (not config/publishing?)) (favorites t))
 
       (when (and left-sidebar-open? (not config/publishing?)) (recent-pages t))
 

+ 0 - 1
src/main/frontend/db/model.cljs

@@ -1432,7 +1432,6 @@
     (->> (map keys properties)
          (apply concat)
          distinct
-         (remove #{:id})
          sort)))
 
 (defn get-property-values

+ 487 - 17
src/main/frontend/dicts.cljc

@@ -616,7 +616,356 @@
         :file-sync/other-user-graph "Aktuelle lokale Grafik ist an das Remote-Graph des anderen Benutzers gebunden. Kann also nicht mit der Synchronisierung beginnen."
         :file-sync/graph-deleted "Das aktuelle Ferndiagramm wurde gelöscht"
         }
+   :nl {
+        :all-files "Alle bestanden"
+        :all-graphs "Alle grafieken"
+        :all-journals "Alle Journalen"
+        :all-pages "Alle pagina's"
+        :bold "Vet"
+        :cancel "Annuleren"
+        :cards-view "Kaarten bekijken"
+        :cloning "Klonen"
+        :close "Sluiten"
+        :code "Code"
+        :convert-markdown "Zet Markdown headings om in ongeordende lijsten (# -> -)"
+        :dark "Donker"
+        :delete "Verwijderen"
+        :developer-mode-alert "U moetde app opnieuw opstarten om het plugin systeem in te schakelen. Wil u het nu herstarten?"
+        :discord-title "Onze discord groep!"
+        :discourse-title "Ons forum!"
+        :download "Downloaden"
+        :export "Exporteren"
+        :export-datascript-edn "Datascript EDN exporteren"
+        :export-edn "Exporteren als EDN"
+        :export-graph "Grafiek exporteren"
+        :export-json "Exporteren als JSON"
+        :export-markdown "Exporteren als standaard Markdown (geen blok eigenschappen)"
+        :export-opml "Exporteren als OPML"
+        :export-page "Exporteer pagina"
+        :export-public-pages "Exporteer openbare pagina's"
+        :export-roam-json "Exporteer als Roam JSON"
+        :general "Algemeen"
+        :go-to "Ga naar"
+        :graph "Grafiek"
+        :graph-search "Zoek grafiek"
+        :graph-view "Bekijk grafiek"
+        :help-shortcut-title "Klik om sneltoetsen en andere tips te bekijken"
+        :highlight "Markeer"
+        :host "Host"
+        :html-link "Html-Link"
+        :import "Importeren"
+        :italics "Cursief"
+        :join-community "Sluit u aan bij de gemeenschap"
+        :language "Taal"
+        :loading-files "Bestanden laden"
+        :loading "Laden"
+        :login "Inloggen"
+        :logout "Uitloggen"
+        :logseq "Logseq"
+        :more "Meer"
+        :more-options "Meer opties"
+        :my-publishing "Mijn publicaties"
+        :new-file "Nieuw bestand"
+        :new-graph "Nieuwe grafiek toevoegen"
+        :new-page "Nieuwe pagina"
+        :no "Nee"
+        :on "Aan"
+        :open "Open"
+        :open-a-directory "Open een lokale map"
+        :open-new-window "Nieuwe venster"
+        :or "of"
+        :page-search "Zoek in de huidige pagina"
+        :parsing-files "Bestanden analyseren"
+        :plugins "Plugins"
+        :port "Poort"
+        :publishing "Publiceren"
+        :re-index "Herindexeren"
+        :re-index-detail "Grafiek herbouwen"
+        :re-index-discard-unsaved-changes-warning "Herindexeren zal de huidige grafiek weggooien, en vervolgens alle bestanden opnieuw verwerken zoals ze momenteel op schijf zijn opgeslagen. U verliest niet-opgeslagen wijzigingen en het kan even duren. Verder?"
+        :re-index-multiple-windows-warning "U moet de andere vensters sluiten voordat u deze grafiek opnieuw indexeert."
+        :redo "Herhaal"
+        :relaunch-confirm-to-work "U moet de app opnieuw opstarten om het te laten werken. Wil u het nu opnieuw opstarten?"
+        :remove-background "Verwijder achtergrond"
+        :remove-orphaned-pages "Verwijder gelinkte pagina's"
+        :save "Opslaan"
+        :search "Zoek of maak pagina"
+        :settings "Instellingen"
+        :settings-of-plugins "Plugin instellingen"
+        :sponsor-us "Sponsor ons"
+        :strikethrough "Doorgestreept"
+        :submit "Verzenden"
+        :sync-from-local-changes-detected "ReBijwerkenfresh detecteert en verwerkt bestanden die op uw schijf zijn gewijzigd en die afwijken van de eigenlijke inhoud van de Logseq pagina. Verder?"
+        :sync-from-local-files "Bijwerken"
+        :sync-from-local-files-detail "Importeer veranderingen uit lokale bestanden"
+        :themes "Thema's"
+        :to "naar"
+        :type "Type"
+        :undo "Ongedaan maken"
+        :unlink "ontkoppel"
+        :white "Licht"
+        :yes "Ja"
+
+        :asset/confirm-delete "Weet u zeker dat u dit wilt verwijderen {1}?"
+        :asset/physical-delete "Verwijder het bestand ook (let op dat het niet hersteld kan worden)"
+
+        :block/name "Pagina naam"
+
+        :command-palette/prompt "Type een commando"
+
+        :content/click-to-edit "Klik om te bewerken"
+        :content/copy "Kopieer"
+        :content/copy-as-json "Kopieer als JSON"
+        :content/copy-block-emebed "Kopieer blok embed"
+        :content/copy-block-ref "Kopieer blok ref"
+        :content/cut "Knip"
+        :content/focus-on-block "Concentreer op blok"
+        :content/make-todos "Maak {1}s"
+        :content/open-in-sidebar "Open in zijbalk"
+
+        :draw/back-to-logseq "Terug naar logseq"
+        :draw/delete "Verwijder"
+        :draw/invalid-file "Kon dit ongeldig excalidraw bestand niet laden"
+        :draw/list-files "Bestanden lijst"
+        :draw/more-options "Meer opties"
+        :draw/new-file "Nieuw bestand"
+        :draw/rename-failure "Bestand hernoemen mislukt, reden:"
+        :draw/rename-success "Bestand hernoemen succesvol!"
+        :draw/save "Opslaan"
+        :draw/save-changes "Wijzigingen opslaan"
+        :draw/specify-title "Geef eerst een titel op!"
+        :draw/title-placeholder "Geen titel"
+
+        :editor/block-search "Zoek voor een blok"
+        :editor/image-uploading "Uploaden"
+
+        :file/file "Bestand: "
+        :file/format-not-supported "Formaat .{1} wordt niet ondersteund."
+        :file/last-modified-at "Laatst aangepast op"
+        :file/name "Bestandsnaam"
+        :file/no-data "Geen gegevens"
+        
+        :file-sync/graph-deleted "Het huidige remote grafiek is verwijderd"
+        :file-sync/other-user-graph "De huidige lokale grafiek is gebonden aan de remote grafiek van de andere gebruiker. Dus kan de synchronisatie niet starten."
+        
+        :format/markdown "Markdown"
+        :format/org-mode "Org mode"
+        :format/preferred-mode "Wat is u favoriete mode?"
+        
+        :graph/persist "Logseq is de interne status aan het synchroniseren, wacht alstublieft enkele seconden."
+        :graph/persist-error "Interne status sync mislukt."
+        :graph/save "Opslaan..."
+        :graph/save-error "Opslaan mislukt"
+        :graph/save-success "Opslaan succesvol"
+        
+        :help/about "Over Logseq"
+        :help/awesome-logseq "Awesome Logseq"
+        :help/block-content-autocomplete "Blokinhoud (brontekst, citaten, zoekopdrachten, enz.) autocomplete"
+        :help/block-reference "Blok referentie"
+        :help/blog "Logseq blog"
+        :help/bug "Rapporteer een fout"
+        :help/changelog "Verander logboek"
+        :help/community "Discord gemeenschap"
+        :help/context-menu "Blok context menu"
+        :help/docs "Documentatie"
+        :help/feature "Functie verzoek"
+        :help/fold-unfold "Vouwen/ontvouwen van blokken (indien niet in bewerkingsmodus)"
+        :help/forum-community "Forum gemeenschap"
+        :help/key-commands "Belangrijke commando's"
+        :help/markdown-syntax "Markdown-syntax"
+        :help/org-mode-syntax "Org-mode-syntax"
+        :help/privacy "Privacybeleid"
+        :help/reference-autocomplete "Automatisch aanvullen van paginareferenties"
+        :help/roadmap "Roadmap"
+        :help/select-nfs-browser "Gebruik een andere browser (bijv. de nieuwste Chrome of Firefox) die NFS-functies ondersteunt om lokale mappen te openen."
+        :help/shortcut "Snelkoppeling"
+        :help/shortcut-page-title "Toetsenbord snelkoppelingen"
+        :help/shortcuts "Toetsenbord snelkoppelingen"
+        :help/shortcuts-triggers "Triggers"
+        :help/slash-autocomplete "Slash-Autocomplete"
+        :help/start "Aan de slag"
+        :help/terms "Voorwaarden"
+        :help/working-with-lists "(werken met lijsten)"
+        
+        :journal/go-to "Ga naar bestanden"
+        :journal/multiple-files-with-different-formats "Het lijkt erop dat u meerdere Journaalbestanden (met verschillende formaten) heeft voor dezelfde maand, alstublieft slechts één journaalbestand bewaren voor elke maand."
+        
+        :left-side-bar/journals "Journalen"
+        :left-side-bar/nav-favorites "Favorieten"
+        :left-side-bar/nav-recent-pages "Recent"
+        :left-side-bar/nav-shortcuts "Snelkoppelingen"
+        :left-side-bar/new-page "Nieuwe pagina"
+
+        :linked-references/filter-search "Zoeken in gelinkte pagina's"
+        
+        :on-boarding/add-graph "Grafiek toevoegen"
+        :on-boarding/demo-graph "Dit is een demo grafiek, wijzigingen worden niet opgeslagen totdat u een lokale map opent."
+        :on-boarding/new-graph-desc-1 "Logseq ondersteunt zowel Markdown als Org-mode. U kunt een bestaande map openen of een nieuwe aanmaken op uw apparaat, een map is ook gewoon bekend als een folder. Uw gegevens worden alleen op dit apparaat opgeslagen."
+        :on-boarding/new-graph-desc-2 "Nadat u map hebt geopend, worden er drie mappen in die map aangemaakt:"
+        :on-boarding/new-graph-desc-3 "/journals - bewaart de Journaal pagina's"
+        :on-boarding/new-graph-desc-4 "/pages - bewaart de andere pagina's"
+        :on-boarding/new-graph-desc-5 "/logseq - bewaart configuratie, custom.css, en wat metadata."
+        :on-boarding/open-local-dir "Open een lokale map"
+
+        :page/action-publish "Publiceer"
+        :page/add-to-favorites "Voeg aan favorieten toe"
+        :page/backlinks "Back-Links"
+        :page/copy-page-url "Kopieer pagina URL"
+        :page/copy-to-json "Kopieer de hele pagina als JSON"
+        :page/created-at "Aangemaakt op"
+        :page/delete "Verwijder pagina"
+        :page/delete-confirmation "Weet u zeker dat u deze pagina wilt verwijderen..."
+        :page/delete-success "Pagina {1} is succesvol verwijderd!"
+        :page/earlier "Eerder"
+        :page/edit-properties-placeholder "Eigenschappen"
+        :page/file-sync-versions "Pagina versie"
+        :page/hide-name "Verberg pagina naam"
+        :page/last-modified "Laatst aangepast op"
+        :page/make-private "Maak prive"
+        :page/make-public "Maak publiek"
+        :page/new-title "Wat is de nieuwe pagina titel?"
+        :page/no-more-journals "Geen Journaals meer"
+        :page/open-backup-directory "Open backups map pagina"
+        :page/open-in-finder "Open in map"
+        :page/open-with-default-app "Open met standaard app"
+        :page/presentation-mode "Presentatiemodus"
+        :page/priority "Prioriteit \"{1}\""
+        :page/rename "Hernoem pagina"
+        :page/rename-to "Hernoem \"{1}\" naar:"
+        :page/show-journals "Toon Journaals"
+        :page/show-name "Toon pagina naam"
+        :page/unfavorite "Pagina uit favorieten verwijderen"
+        :page/updated-at "Bijgewerkt op"
+        :page/version-history "Controleer pagina geschiedenis"
+        
+        :paginates/next "Volgende"
+        :paginates/pages "Totaal {1} pagina's"
+        :paginates/prev "Vorige"
+        
+        :pdf/copy-ref "Kopieer ref"
+        :pdf/copy-text "Kopieer tekst"
+        :pdf/linked-ref "Gekoppelde referenties"
+        :pdf/toggle-dashed "Gestippelde stijl voor gebiedsmarkering"
+
+        :plugin/all "Alle"
+        :plugin/check-all-updates "Check alle updates"
+        :plugin/check-update "Check update"
+        :plugin/contribute "✨ Schrijf en dien nieuwe plugin in"
+        :plugin/custom-js-alert "custom.js bestand gevonden, mag deze uitgevoerd worden? (Als je niet begrijpt wat dit bestand inhoud is het aangeraden om het uivoeren hiervan niet toe te staan, dit is in verband met beveiligings risico's.)" ;; TODO
+        :plugin/delete-alert "Weet je zeker dat je plugin [{1}] wilt verwijderen?"
+        :plugin/disabled "Uitgeschakeld"
+        :plugin/downloads "Downloads"
+        :plugin/enabled "Ingeschakeld"
+        :plugin/install "Installeren"
+        :plugin/installed "Geïnstalleerd"
+        :plugin/installing "Installeren"
+        :plugin/load-unpacked "Laad uitgepakte plugin"
+        :plugin/marketplace "Marketplace"
+        :plugin/marketplace-tips "Als de plugin niet correct werkt bij de eerste installatie, probeer dan Logseq te herstarten."
+        :plugin/not-installed "Niet geïnstalleerd"
+        :plugin/open-package "Open pakket"
+        :plugin/open-preferences "Open plugin voorkeuren bestand"
+        :plugin/open-settings "Open instellingen"
+        :plugin/refresh-lists "Vernieuw lijsten"
+        :plugin/reload "Herlaad"
+        :plugin/restart "Herstart app"
+        :plugin/stars "Sterren"
+        :plugin/title "Titel"
+        :plugin/uninstall "Verwijder"
+        :plugin/unpacked "Uitgepakt"
+        :plugin/unpacked-tips "Selecteer de plugin map"
+        :plugin/up-to-date "Het is up to date"
+        :plugin/update "Update"
+        :plugin/update-available "Update beschikbaar"
+        :plugin/updating "Bijwerken"
+        
+        :reference/linked "Gelinkte referentie"
+        :reference/unlinked-ref "Ongelinkte verwijzingen"
+        
+        :repo/download-zip "Download alle bestanden als een zip"
+        
+        :right-side-bar/all-pages "Alle pagina's"
+        :right-side-bar/block-ref "Blok verwijzingen"
+        :right-side-bar/contents "Inhoud"
+        :right-side-bar/favorites "Favorieten"
+        :right-side-bar/flashcards "Flashcards"
+        :right-side-bar/graph-view "Grafiekweergave"
+        :right-side-bar/help "Help"
+        :right-side-bar/new-page "Nieuwe pagina"
+        :right-side-bar/page "Pagina grafiek"
+        :right-side-bar/page-graph "Pagina grafiek"
+        :right-side-bar/recent "Recent"
+        :right-side-bar/show-journals "Toon Journaals"
+        :right-side-bar/switch-theme "Thema modes"
+        :right-side-bar/theme "{1} thema"
 
+        :search/items "items"
+        :search/page-names "Zoek paginanamen"
+        :search/publishing "Zoek"
+        :search/result-for "Zoekresultaat voor "
+        :select/default-prompt "Kies één"
+        :select.graph/add-graph "Ja, voeg nog een grafiek toe"
+        :select.graph/empty-placeholder-description "Geen overeenkomende grafieken. Wilt u er een toevoegen?"
+        :select.graph/prompt "Selecteer een grafiek"
+        
+        :settings-page/auto-updater "Auto updater"
+        :settings-page/clear "Verwijder"
+        :settings-page/clear-cache "Cache wissen"
+        :settings-page/current-graph "Huidige grafiek"
+        :settings-page/current-version "Huidige versie"
+        :settings-page/custom-configuration "Aangepaste configuratie"
+        :settings-page/custom-date-format "Gewenst datumformaat"
+        :settings-page/custom-theme "Aangepast thema"
+        :settings-page/customize-shortcuts "Toetsenbord snelkoppelingen"
+        :settings-page/developer-mode "Ontwikkelaar modus"
+        :settings-page/developer-mode-desc "De ontwikkelaarsmodus helpt bijdragers en extensie-ontwikkelaars om hun integratie met Logseq efficiënter te testen."
+        :settings-page/disable-developer-mode "Ontwikkelaarsmodus uitschakelen"
+        :settings-page/disable-sentry "Gebruiksgegevens en diagnostiek naar Logseq sturen"
+        :settings-page/edit-config-edn "Bewerk config.edn"
+        :settings-page/edit-custom-css "Bewerk custom.css"
+        :settings-page/edit-export-css "Bewerk export.css"
+        :settings-page/enable-all-pages-public "Alle pagina's openbaar bij publiceren"
+        :settings-page/enable-block-time "Tijdstempel voor blokken inschakelen"
+        :settings-page/enable-developer-mode "Ontwikkelaar modus"
+        :settings-page/enable-encryption "Encryptie"
+        :settings-page/enable-flashcards "Flashcards"
+        :settings-page/enable-journals "Journaals"
+        :settings-page/enable-shortcut-tooltip "Snelkoppeling tooltip inschakelen"
+        :settings-page/enable-timetracking "Tijdregistratie inschakelen"
+        :settings-page/enable-tooltip "Tooltips inschakelen"
+        :settings-page/export-theme "Exporteer thema"
+        :settings-page/git-commit-delay "Git auto commit seconden"
+        :settings-page/git-confirm "Je moet de app opnieuw opstarten nadat je de Git instellingen hebt aangepast."
+        :settings-page/git-desc "wordt gebruikt voor versiebeheer van pagina's. U kunt op het menu met de drie verticale stippen klikken om de wijzigingsgeschiedenis van de pagina te zien."
+        :settings-page/git-switcher-label "Git auto commit inschakelen"
+        :settings-page/home-default-page "De standaard startpagina instellen"
+        :settings-page/network-proxy "Netwerk proxy"
+        :settings-page/plugin-system "Plugin systeem"
+        :settings-page/preferred-file-format "Gewenst bestandsformaat"
+        :settings-page/preferred-outdenting "Logische uitdenting"
+        :settings-page/preferred-workflow "Voorkeur voor workflow"
+        :settings-page/shortcut-settings "Snelkoppelingen aanpassen"
+        :settings-page/show-brackets "Toon beugels"
+        :settings-page/spell-checker "Spellingcontrole"
+        :settings-page/tab-advanced "Geavanceerd"
+        :settings-page/tab-editor "Editor"
+        :settings-page/tab-general "Algemeen"
+        :settings-page/tab-shortcuts "Snelkoppelingen"
+        :settings-page/tab-version-control "Versiebeheer"
+
+        :text/image "Afbeelding"
+
+        :tips/all-done "Alles klaar"
+
+        :tutorial/dummy-notes "dummy-notes-en.md"
+        :tutorial/text "tutorial-en.md"
+
+        :updater/new-version-install "Een nieuwe versie is gedownload."
+        :updater/quit-and-install "Herstart om te installeren"
+
+        :user/delete-account "Verwijder account"
+        :user/delete-account-notice "Al uw gepubliceerde pagina's op logseq.com zullen worden verwijderd."
+        :user/delete-your-account "Verwijder uw account"
+        }
    :fr {:help/about "A propos de Logseq"
         :help/bug "Signaler une anomalie"
         :help/feature "Demander une fonctionnalité"
@@ -1371,7 +1720,19 @@
         :file-sync/other-user-graph "Huidige plaaslike grafiek is gebonde aan ander gebruiker se afgeleë grafiek. So kan nie begin om te sinkroniseer nie."
         :file-sync/graph-deleted "Huidige afstandgrafiek is geskrap"}
 
-   :es {:on-boarding/add-graph "Añade un grafo"
+  :es {:tutorial/text #?(:cljs (rc/inline "tutorial-es.md")
+                          :default "tutorial-es.md")
+        :tutorial/dummy-notes #?(:cljs (rc/inline "dummy-notes-es.md")
+                                 :default "dummy-notes-es.md")
+        :on-boarding/demo-graph "This is a demo graph, changes will not be saved until you open a local folder."
+        :on-boarding/add-graph "Add a graph"
+        :on-boarding/open-local-dir "Abrir un directorio local"
+        :on-boarding/new-graph-desc-1 "Logseq soporta tanto Markdown como Org-mode. Puede abrir un directorio existente o crear uno nuevo en su dispositivo, un directorio se conoce simplemente como una carpeta. Sus datos se almacenarán únicamente en este dispositivo."
+        :on-boarding/new-graph-desc-2 "Después que abra un directorio se crearán tres carpetas en ese directorio:"
+        :on-boarding/new-graph-desc-3 "/journals - almacena sus páginas de diarios"
+        :on-boarding/new-graph-desc-4 "/pages - almacena las otras páginas"
+        :on-boarding/new-graph-desc-5 "/logseq - almacena la configuración, custom.css, y algunos metadatos."
+        :help/start "Comenzando"
         :help/about "Acerca de Logseq"
         :help/roadmap "Hoja de ruta"
         :help/bug "Reportar un error"
@@ -1382,6 +1743,8 @@
         :help/privacy "Política de privacidad"
         :help/terms "Términos"
         :help/community "Comunidad de Discord"
+        :help/forum-community "Foro de la comunidad"
+        :help/awesome-logseq "Awesome Logseq"
         :help/shortcuts "Atajos de teclado"
         :help/shortcuts-triggers "Iniciadores"
         :help/shortcut "Atajo"
@@ -1398,6 +1761,7 @@
         :more "Más"
         :search/result-for "Resultado de búsqueda para "
         :search/items "elementos"
+        :search/page-names "Buscar en los nombres de página"
         :help/context-menu "Menú contextual"
         :help/fold-unfold "Ocultar/Expandir bloques (fuera del modo edición)"
         :help/markdown-syntax "Sintaxis de Markdown"
@@ -1410,21 +1774,27 @@
         :code "Código"
         :right-side-bar/help "Ayuda"
         :right-side-bar/switch-theme "Temas"
+        :right-side-bar/theme "Tema {1}"
         :right-side-bar/page "Gráfico de la página"
         :right-side-bar/recent "Reciente"
         :right-side-bar/contents "Contenido"
         :right-side-bar/favorites "Favoritos"
-        :right-side-bar/page-graph "Vista gráfica"
+        :right-side-bar/page-graph "Grafo de página"
         :right-side-bar/block-ref "Referencia de bloque"
-        :right-side-bar/graph-view "Graph view"
+        :right-side-bar/graph-view "Vista de Grafo"
         :right-side-bar/all-pages "Lista de páginas"
         :right-side-bar/flashcards "Flashcards"
-        :right-side-bar/new-page "Nueva pagina"
+        :right-side-bar/new-page "Nueva página"
+        :right-side-bar/show-journals "Mostrar Diarios"
         :left-side-bar/journals "Diarios"
+        :left-side-bar/new-page "Nueva página"
+        :left-side-bar/nav-favorites "Favoritos"
+        :left-side-bar/nav-shortcuts "Atajos de teclado"
+        :left-side-bar/nav-recent-pages "Recientes"
         :format/preferred-mode "¿Cuál es su modo preferido?"
         :format/markdown "Markdown"
         :format/org-mode "Modo Org"
-        :reference/linked "Referencia enlazada"
+        :reference/linked "Referencias enlazadas"
         :reference/unlinked-ref "Referencias sin enlazar"
         :page/presentation-mode "Modo presentación"
         :page/edit-properties-placeholder "Propiedades"
@@ -1438,6 +1808,9 @@
         :page/open-with-default-app "Abrir con la aplicación predeterminada"
         :page/action-publish "Publicar"
         :page/make-public "Hacer pública al publicar"
+        :page/version-history "Revisar el historial de la página"
+        :page/open-backup-directory "Abrir el directorio de copia de seguridad de la página"
+        :page/file-sync-versions "Versiones de la página"
         :page/make-private "Hacer privada"
         :page/delete "Eliminar página"
         :page/add-to-favorites "Añadir a Favoritos"
@@ -1449,13 +1822,18 @@
         :page/new-title "¿Cuál es el título de su nueva página?"
         :page/earlier "Anteriormente"
         :page/no-more-journals "No hay más diarios"
+        :page/copy-page-url "Copiar URL de la página"
         :journal/multiple-files-with-different-formats "Parece que tiene varios archivos de diario (con diferentes formatos) para el mismo mes, por favor guarde solo un archivo de diario para cada mes."
         :journal/go-to "Ir a Archivos"
         :file/name "Nombre del archivo"
-        :file/file "Archivos: "
+        :file/file "Archivo: "
         :file/last-modified-at "Fecha de modificación"
         :file/no-data "No hay datos"
         :file/format-not-supported "Formato .{1} no soportado."
+        :page/created-at "Creada el"
+        :page/updated-at "Actualizada el"
+        :page/backlinks "Back Links"
+        :linked-references/filter-search "Buscar en las páginas vinculadas"
         :editor/block-search "Buscar un bloque"
         :editor/image-uploading "Subiendo"
         :draw/invalid-file "No se pudo cargar este archivo inválido de excalidraw"
@@ -1465,7 +1843,7 @@
         :draw/title-placeholder "Sin título"
         :draw/save "Guardar"
         :draw/save-changes "Guardar cambios"
-        :draw/new-file "Nuevo archivo file"
+        :draw/new-file "Nuevo archivo"
         :draw/list-files "Listado de archivos"
         :draw/delete "Eliminar"
         :draw/more-options "Más opciones"
@@ -1477,21 +1855,37 @@
         :content/cut "Cortar"
         :content/make-todos "Hacer {1}s"
         :content/copy-block-ref "Copiar referencia de bloque"
-        :content/focus-on-block "Enfocar bloque"
+        :content/copy-block-emebed "Copiar bloque a incrustar (embed)"
+        :content/focus-on-block "Enfocar en bloque"
         :content/open-in-sidebar "Abrir en barra lateral"
         :content/copy-as-json "Copiar como JSON"
         :content/click-to-edit "Clic para editar"
+        :settings-page/git-desc "se usa para el control de versiones de páginas, puede presionar el menú vertical de tres puntos para verificar el historial de la página."
+        :settings-page/git-confirm "Debe reiniciar la aplicación después de actualizar las opciones de Git."
+        :settings-page/git-switcher-label "Habilitar Git auto commit"
+        :settings-page/git-commit-delay "Segundos para Git auto commit"
         :settings-page/edit-config-edn "Editar config.edn (para este repositorio)"
+        :settings-page/edit-custom-css "Editar custom.css"
+        :settings-page/edit-export-css "Editar export.css"
+        :settings-page/custom-configuration "Configuración personalizada"
+        :settings-page/custom-theme "Tema personalizado"
+        :settings-page/export-theme "Tema exportación"
         :settings-page/show-brackets "Mostrar corchetes"
+        :settings-page/spell-checker "Corrector ortográfico"
+        :settings-page/auto-updater "Auto actualizador"
         :settings-page/disable-sentry "Enviar datos de uso y diagnósticos a Logseq"
         :settings-page/preferred-outdenting "Disminución lógica de sangría"
-        :settings-page/custom-date-format "Formato de diario preferido"
+        :settings-page/custom-date-format "Formato de fecha preferido"
         :settings-page/preferred-file-format "Formato de archivo preferido"
         :settings-page/preferred-workflow "Flujo de trabajo preferido"
+        :settings-page/enable-shortcut-tooltip "Habilitar descripción emergente de atajos de teclado"
         :settings-page/enable-timetracking "Habilitar rastreo de tiempo"
         :settings-page/enable-tooltip "Habilitar descripción emergente"
         :settings-page/enable-journals "Habilitar diarios"
+        :settings-page/enable-all-pages-public "Hacer todas las páginas públicas al publicar"
         :settings-page/enable-encryption "Habilitar función de cifrado"
+        :settings-page/customize-shortcuts "Atajos de teclado"
+        :settings-page/shortcut-settings "Personalizar atajos"
         :settings-page/home-default-page "Establecer página de inicio"
         :settings-page/enable-block-time "Habilitar marcas temporales de bloque"
         :settings-page/clear-cache "Limpiar caché"
@@ -1499,8 +1893,17 @@
         :settings-page/developer-mode "Modo desarrollador"
         :settings-page/enable-developer-mode "Habilitar modo desarrollador"
         :settings-page/disable-developer-mode "Deshabilitar modo desarrollador"
-        :settings-page/developer-mode-desc "El modo desarrollado permite que los colaboradores y desarrolladore de extensiones probar sus integraciones con Logseq más eficientemente."
+        :settings-page/developer-mode-desc "El modo desarrollador permite a los colaboradores y desarrolladores de extensiones probar sus integraciones con Logseq más eficientemente."
         :settings-page/current-version "Versión actual"
+        :settings-page/current-graph "Grafo actual"
+        :settings-page/tab-general "General"
+        :settings-page/tab-editor "Editor"
+        :settings-page/tab-shortcuts "Atajos de teclado"
+        :settings-page/tab-version-control "Control de versiones"
+        :settings-page/tab-advanced "Avanzado"
+        :settings-page/plugin-system "Habilitar extensiones"
+        :settings-page/enable-flashcards "Flashcards"
+        :settings-page/network-proxy "Proxy de red"
         :logseq "Logseq"
         :on "ON"
         :more-options "Más opciones"
@@ -1510,18 +1913,39 @@
         :submit "Enviar"
         :cancel "Cancelar"
         :close "Cerrar"
+        :delete "Eliminar"
+        :save "Guardar"
+        :type "Tipo"
+        :host "Servidor"
+        :port "Puerto"
         :re-index "Reindexar"
+        :re-index-detail "Reconstruir el grafo"
+        :re-index-multiple-windows-warning "Debe cerrar las otras ventanas antes de reindexar este grafo."
+        :re-index-discard-unsaved-changes-warning "Al reindexar se descartará el grafo actual y se procesarán nuevamente todos los archivos según como están actualmente almacenados en disco. Perderá los cambios no guardados y puede tardar un poco. ¿Continuar?"
+        :open-new-window "Nueva ventana"
+        :sync-from-local-files "Refrescar"
+        :sync-from-local-files-detail "Importar cambios de los archivos locales"
+        :sync-from-local-changes-detected "Refrescar detecta y procesa los archivos modificados en su disco que difieren del contenido actual de la página en Logseq. ¿Continuar?"
         :unlink "desenlazar"
         :search/publishing "Buscar"
         :search "Buscar o Crear Página"
         :page-search "Buscar en la página actual"
+        :graph-search "Buscar grafo"
         :new-page "Nueva página"
         :new-file "Nuevo archivo"
         :new-graph "Añadir nuevo grafo"
         :graph "Grafo"
-        :graph-view "Vista gráfica"
+        :graph-view "Ver grafo"
+        :graph/persist "Logseq está sincronizando su estado interno, por favor espere unos segundos."
+        :graph/persist-error "Falló la sincronización del estado interno."
+        :graph/save "Guardando..."
+        :graph/save-success "Guardado satisfactoriamente"
+        :graph/save-error "Falló el guardado"
+        :cards-view "Ver tarjetas"
         :publishing "Publicar"
         :export "Exportar"
+        :export-graph "Exportar grafo"
+        :export-page "Exportar página"
         :export-markdown "Exportar como Markdown estándar (sin propiedades de bloque)"
         :export-opml "Exportar a OPML"
         :export-public-pages "Exportar páginas públicas"
@@ -1533,15 +1957,19 @@
         :all-graphs "Lista de grafos"
         :all-pages "Lista de páginas"
         :all-files "Lista de archivos"
+        :remove-orphaned-pages "Eliminar páginas huérfanas"
         :all-journals "Lista de diarios"
         :my-publishing "Mi publicación"
         :settings "Opciones"
+        :settings-of-plugins "Opciones de Extensiones"
         :plugins "Extensiones"
         :themes "Temas"
         :developer-mode-alert "Debe reiniciar la aplicación para habilitar las extensiones. ¿Desea reiniciarla ahora?"
+        :relaunch-confirm-to-work "Debe relanzar la aplicación para hacer que funcione. ¿Desea reiniciarla ahora?"
         :import "Importar"
         :join-community "Unirse a la comunidad"
         :sponsor-us "Hazte patrocinador"
+        :discourse-title "Nuestro foro!"
         :discord-title "¡Nuestro grupo de Discord!"
         :help-shortcut-title "Clic para ver atajos y otras sugerencias"
         :loading "Cargando"
@@ -1563,15 +1991,56 @@
         :user/delete-account "Eliminar cuenta"
         :user/delete-your-account "Eliminar su cuenta"
         :user/delete-account-notice "Todas sus páginas publicadas en Logseq serán eliminadas."
-
-        :help/shortcut-page-title "Atajos personalizados"
-
+        :help/shortcut-page-title "Atajos de teclado"
+        :plugin/installed "Instalado"
+        :plugin/not-installed "No instalado"
+        :plugin/installing "Instalando"
+        :plugin/install "Instalar"
+        :plugin/reload "Recargar"
+        :plugin/update "Actualizar"
+        :plugin/check-update "Buscar actualización"
+        :plugin/check-all-updates "Buscar actualizaciones"
+        :plugin/refresh-lists "Actualizar listas"
+        :plugin/enabled "Habilitado"
+        :plugin/disabled "Inactivo"
+        :plugin/update-available "Actualización disponible"
+        :plugin/updating "Actualizando"
+        :plugin/uninstall "Desinstalar"
+        :plugin/marketplace "Marketplace"
+        :plugin/downloads "Descargas"
+        :plugin/stars "Estrellas"
+        :plugin/title "Título"
+        :plugin/all "Todo"
+        :plugin/unpacked "Desempaquetado"
+        :plugin/delete-alert "¿Está seguro de desinstalar la extensión [{1}]?"
+        :plugin/open-settings "Abrir opciones"
+        :plugin/open-package "Abrir paquete"
+        :plugin/load-unpacked "Cargar extensión desempaquetada"
+        :plugin/open-preferences "Abrir el archivo de preferencias de la extensión"
+        :plugin/restart "Reiniciar la aplicación"
+        :plugin/unpacked-tips "Seleccionar el directorio de la extensión"
+        :plugin/contribute "✨ Escribir y publicar nueva extensión"
+        :plugin/marketplace-tips "Si la extensión no funciona correctamente cuando recién se instala, pruebe a reiniciar Logseq."
+        :plugin/up-to-date "Está actualizada"
+        :plugin/custom-js-alert "Se encontró el archivo custom.js, desea permitir que se ejecute? (Si no comprende el contenido de este archivo se recomienda no permitir su ejecución dado que representa ciertos riesgos de seguridad)."
+        :pdf/copy-ref "Copiar referencia"
+        :pdf/copy-text "Copiar texto"
+        :pdf/linked-ref "Referencias vinculadas"
+        :pdf/toggle-dashed "Estilo punteado para las áreas resaltadas"
+        :updater/new-version-install "Se descargó una nueva versión."
+        :updater/quit-and-install "Reiniciar para instalar"
+        :paginates/pages "Total {1} páginas"
+        :paginates/prev "Anterior"
+        :paginates/next "Siguiente"
+        :tips/all-done "Todo Hecho"
+        :command-palette/prompt "Escriba un comando"
         :select/default-prompt "Seleccione uno"
         :select.graph/prompt "Seleccione un grafo"
-        :select.graph/empty-placeholder-description "No encontramos un grafo. Queries añadir otro?"
-        :select.graph/add-graph "Si, añadame otro grafo"
+        :select.graph/empty-placeholder-description "No encontramos un grafo. Querie añadir otro?"
+        :select.graph/add-graph "Sí, añadir otro grafo"
         :file-sync/other-user-graph "El gráfico local actual está unido al gráfico remoto de otro usuario. Así que no se puede empezar a sincronizar"
-        :file-sync/graph-deleted "El gráfico remoto actual se ha eliminado"}
+        :file-sync/graph-deleted "El gráfico remoto actual se ha eliminado"
+     }
 
    :nb-NO {:tutorial/text #?(:cljs (rc/inline "tutorial-no.md")
                              :default "tutorial-no.md")
@@ -4135,6 +4604,7 @@
 (def languages [{:label "English" :value :en}
                 {:label "Français" :value :fr}
                 {:label "Deutsch" :value :de}
+                {:label "Dutch (Nederlands)" :value :nl}
                 {:label "简体中文" :value :zh-CN}
                 {:label "繁體中文" :value :zh-Hant}
                 {:label "Afrikaans" :value :af}

+ 19 - 14
src/main/frontend/handler/editor.cljs

@@ -385,7 +385,7 @@
         block (update block :block/refs remove-non-existed-refs!)
         block (attach-page-properties-if-exists! block)
         new-properties (merge
-                        (select-keys properties (property/built-in-properties))
+                        (select-keys properties (property/hidden-properties))
                         (:block/properties block))]
     (-> block
         (dissoc :block/top?
@@ -1941,6 +1941,9 @@
   (let [editing-block (when-let [editing-block (state/get-edit-block)]
                         (some-> (db/pull (:db/id editing-block))
                                 (assoc :block/content (state/get-edit-content))))
+        has-unsaved-edits (and editing-block
+                               (not= (:block/content (db/pull (:db/id editing-block)))
+                                     (state/get-edit-content)))
         target-block (or target-block editing-block)
         block (db/entity (:db/id target-block))
         page (if (:block/name block) block
@@ -1955,20 +1958,22 @@
 
                    :else
                    true)]
+    (when has-unsaved-edits
+      (outliner-tx/transact!
+        {:outliner-op :save-block}
+        (outliner-core/save-block! editing-block)))
     (outliner-tx/transact!
-     {:outliner-op :insert-blocks}
-     (when editing-block
-       (outliner-core/save-block! editing-block))
-     (when target-block
-       (let [format (or (:block/format target-block) (state/get-preferred-format))
-             blocks' (map (fn [block]
-                            (paste-block-cleanup block page exclude-properties format content-update-fn))
-                          blocks)
-             result (outliner-core/insert-blocks! blocks' target-block {:sibling? sibling?
-                                                                        :outliner-op :paste
-                                                                        :replace-empty-target? true
-                                                                        :keep-uuid? keep-uuid?})]
-         (edit-last-block-after-inserted! result))))))
+      {:outliner-op :insert-blocks}
+      (when target-block
+        (let [format (or (:block/format target-block) (state/get-preferred-format))
+              blocks' (map (fn [block]
+                             (paste-block-cleanup block page exclude-properties format content-update-fn))
+                           blocks)
+              result (outliner-core/insert-blocks! blocks' target-block {:sibling? sibling?
+                                                                         :outliner-op :paste
+                                                                         :replace-empty-target? true
+                                                                         :keep-uuid? keep-uuid?})]
+          (edit-last-block-after-inserted! result))))))
 
 (defn- block-tree->blocks
   "keep-uuid? - maintain the existing :uuid in tree vec"

+ 118 - 0
src/main/frontend/modules/shortcut/dicts.cljc

@@ -251,6 +251,124 @@
              :command.git/commit                     "Git Commit-Nachricht"
              :command.editor/select-block-down       "Block unterhalb auswählen"
              :command.editor/select-all-blocks       "Alle Blöcke auswählen"}
+   :nl      {:command.auto-complete/complete         "Automatisch aanvullen: Kies geselecteerd item"
+             :command.auto-complete/next             "Automatisch aanvullen: Selecteer volgend item"
+             :command.auto-complete/open-link        "Automatisch aanvullen: Open geselecteerd item in browser"
+             :command.auto-complete/prev             "Automatisch aanvullen: Selecteer vorig item"
+             :command.auto-complete/shift-complete   "Automatisch aanvullen: Open geselecteerd item in zijbalk"
+             :command.cards/forgotten                "Kaarten: vergeten"
+             :command.cards/next-card                "Kaarten: volgende kaart"
+             :command.cards/recall                   "Kaarten: het duurt even om terug te roepen"
+             :command.cards/remembered               "Kaarten: herinnerd"
+             :command.cards/toggle-answers           "Kaarten: toon/verberg antwoorden/clozes"
+             :command.command/run                    "Voer git commando uit"
+             :command.command/toggle-favorite        "Toevoegen aan/verwijderen uit favorieten"
+             :command.command-palette/toggle         "Schakel commando lijn"
+             :command.date-picker/complete           "Datumkiezer: Kies de geselecteerde dag"
+             :command.date-picker/next-day           "Datumkiezer: Volgende dag kiezen"
+             :command.date-picker/next-week          "Datumkiezer: Volgende week kiezen"
+             :command.date-picker/prev-day           "Datumkiezer: Vorige dag kiezen"
+             :command.date-picker/prev-week          "Datumkiezer: Vorige week kiezen"
+             :command.editor/backspace               "Backspace / Achteruit wissen"
+             :command.editor/backward-kill-word      "Een woord achterwaarts wissen"
+             :command.editor/backward-word           "Verplaats de cursor een woord achteruit"
+             :command.editor/beginning-of-block      "Verplaats de cursor naar het begin van een blok"
+             :command.editor/bold                    "Vet"
+             :command.editor/clear-block             "Wis volledige blokinhoud"
+             :command.editor/collapse-block-children "Samenvouwen"
+             :command.editor/copy                    "Kopiëren (kopieert een selectie of een blokverwijzing)"
+             :command.editor/copy-current-file       "Kopieer huidig bestand"
+             :command.editor/copy-embed              "Kopieer een blok embed dat wijst naar het huidige blok"
+             :command.editor/copy-text               "Kopieer selecties als tekst"
+             :command.editor/cut                     "Knip"
+             :command.editor/cycle-todo              "Draai de TODO status van het huidige item"
+             :command.editor/delete                  "Verwijderen / verwijderen vooruit"
+             :command.editor/delete-selection        "Verwijder geselecteerde blokken"
+             :command.editor/down                    "Verplaats cursor omlaag / Selecteer omlaag"
+             :command.editor/end-of-block            "Verplaats cursor naar het einde van een blok"
+             :command.editor/escape-editing          "Klaar met bewerken"
+             :command.editor/expand-block-children   "Openvouwen"
+             :command.editor/follow-link             "Volg de link onder de cursor"
+             :command.editor/forward-kill-word       "Een woord vooruit verwijderen"
+             :command.editor/forward-word            "Verplaats de cursor een woord vooruit"
+             :command.editor/highlight               "Markeer"
+             :command.editor/indent                  "Blok inspringen"
+             :command.editor/insert-link             "HTML Link"
+             :command.editor/insert-youtube-timestamp"Voeg youtube tijdstempel toe"
+             :command.editor/italics                 "Cursief"
+             :command.editor/kill-line-after         "Verwijder regel na cursorpositie"
+             :command.editor/kill-line-before        "Verwijder regel voor cursorpositie"
+             :command.editor/left                    "Verplaats cursor naar links / Open geselecteerd blok bij het begin"
+             :command.editor/move-block-down         "Verplaats blok omlaag"
+             :command.editor/move-block-up           "Verplaats blok omhoog"
+             :command.editor/new-block               "Maak nieuw blok"
+             :command.editor/new-line                "Nieuwe regel in huidig blok"
+             :command.editor/open-edit               "Bewerk geselecteerde blok"
+             :command.editor/open-file-in-default-app"Open bestand in standaard app"
+             :command.editor/open-file-in-directory  "Open bestand in bovenliggende map"
+             :command.editor/open-link-in-sidebar    "Open link in zijbalk"
+             :command.editor/outdent                 "Verminder blok inspringing"
+             :command.editor/paste-text-in-one-block-at-point"Plak tekst in een blok op punt"
+             :command.editor/redo                    "Herhaal"
+             :command.editor/replace-block-reference-at-point"Vervang de blokverwijzing door de inhoud op punt"
+             :command.editor/right                   "Beweeg cursor naar rechts / Open geselecteerd blok aan einde"
+             :command.editor/select-all-blocks       "Selecteer alle blokken"
+             :command.editor/select-block-down       "Selecteer blok hieronder"
+             :command.editor/select-block-up         "Selecteer blok hierboven"
+             :command.editor/select-down             "Selecteer inhoud hieronder"
+             :command.editor/select-up               "Selecteer inhoud hierboven"
+             :command.editor/strike-through          "Doorstrepen"
+             :command.editor/toggle-open-blocks      "Toggle open blocks (open of dichtklappen van alle blokken)"
+             :command.editor/undo                    "Ongedaan maken"
+             :command.editor/up                      "Verplaats cursor omhoog / Selecteer omhoog"
+             :command.editor/zoom-in                 "Zoom in bewerkingsblok / Vooruit anders"
+             :command.editor/zoom-out                "Zoom uit bewerkingsblok / Achteruit anders"
+             :command.git/commit                     "Maak git commit met bericht"
+             :command.go/all-pages                   "Ga naar alle pagina's"
+             :command.go/backward                    "Achteruit"
+             :command.go/flashcards                  "Flashcards Toggle"
+             :command.go/forward                     "Vooruit"
+             :command.go/graph-view                  "Ga naar grafiekweergave"
+             :command.go/home                        "Ga naar home"
+             :command.go/journals                    "Ga naar journaals"
+             :command.go/keyboard-shortcuts          "Ga naar sneltoetsen"
+             :command.go/next-journal                "Ga naar volgende journaal"
+             :command.go/prev-journal                "Ga naar vorige journaal"
+             :command.go/search                      "Zoeken in volledige tekst"
+             :command.go/search-in-page              "Zoeken in de huidige pagina"
+             :command.go/tomorrow                    "Ga naar morgen"
+             :command.graph/add                      "Voeg een grafiek toe"
+             :command.graph/open                     "Selecteer grafiek om te openen"
+             :command.graph/re-index                 "Huidige grafiek opnieuw indexeren"
+             :command.graph/remove                   "Verwijder een grafiek"
+             :command.graph/save                     "Huidige grafiek opslaan op schijf"
+             :command.misc/copy                      "Kopieer"
+             :command.pdf/close                      "Huidige pdf-viewer sluiten"
+             :command.pdf/next-page                  "Volgende pagina van huidige pdf doc"
+             :command.pdf/previous-page              "Vorige pagina van huidige pdf doc"
+             :command.search/re-index                "Bouw zoekindex opnieuw op"
+             :command.sidebar/clear                  "Wis alles in de rechter zijbalk"
+             :command.sidebar/open-today-page        "Open de pagina van vandaag in de rechter zijbalk"
+             :command.ui/goto-plugins                "Ga naar plugins dashboard"
+             :command.ui/select-theme-color          "Selecteer beschikbare themakleuren"
+             :command.ui/toggle-brackets             "Toggle tussen het weergeven van beugels"
+             :command.ui/toggle-cards                "Toggle kaarten"
+             :command.ui/toggle-contents             "Toggle inhoud in zijbalk"
+             :command.ui/toggle-document-mode        "Schakel tussen documentmodus"
+             :command.ui/toggle-help                 "Toggle help"
+             :command.ui/toggle-left-sidebar         "Toggle linker zijbalk"
+             :command.ui/toggle-right-sidebar        "Toggle rechter zijbalk"
+             :command.ui/toggle-settings             "Toggle settings"
+             :command.ui/toggle-theme                "Toggle tussen donker/licht thema"
+             :command.ui/toggle-wide-mode            "Toggle brede modus"
+             :shortcut.category/basics               "Basis"
+             :shortcut.category/block-command-editing"Blokcommando's bewerken"
+             :shortcut.category/block-editing        "Blokbewerking algemeen"
+             :shortcut.category/block-selection      "Blokselectie (druk op Esc om selectie te beëindigen)"
+             :shortcut.category/formatting           "Formatteren"
+             :shortcut.category/navigating           "Navigatie"
+             :shortcut.category/others               "Anderen"
+             :shortcut.category/toggle               "Toggle"}
    :fr      {:shortcut.category/formatting           "Formats"
              :command.editor/indent                  "Indenter un Bloc vers la droite"
              :command.editor/outdent                 "Indenter un Bloc vers la gauche"

+ 10 - 7
src/main/frontend/search.cljs

@@ -11,6 +11,7 @@
             [frontend.search.protocol :as protocol]
             [frontend.state :as state]
             [frontend.util :as util]
+            [frontend.util.property :as property]
             [goog.object :as gobj]
             [promesa.core :as p]))
 
@@ -77,20 +78,20 @@
 (defn fuzzy-search
   [data query & {:keys [limit extract-fn]
                  :or {limit 20}}]
-  (let [query (util/search-normalize query)]
+  (let [query (util/search-normalize query (state/enable-search-remove-accents?))]
     (->> (take limit
                (sort-by :score (comp - compare)
                         (filter #(< 0 (:score %))
                                 (for [item data]
                                   (let [s (str (if extract-fn (extract-fn item) item))]
                                     {:data item
-                                     :score (score query (util/search-normalize s))})))))
+                                     :score (score query (util/search-normalize s (state/enable-search-remove-accents?)))})))))
          (map :data))))
 
 (defn block-search
   [repo q option]
   (when-let [engine (get-engine repo)]
-    (let [q (util/search-normalize q)
+    (let [q (util/search-normalize q (state/enable-search-remove-accents?))
           q (if (util/electron?) q (escape-str q))]
       (when-not (string/blank? q)
         (protocol/query engine q option)))))
@@ -111,8 +112,8 @@
           (if (seq coll')
             (rest coll')
             (reduced false))))
-      (seq (util/search-normalize match))
-      (seq (util/search-normalize q))))))
+      (seq (util/search-normalize match (state/enable-search-remove-accents?)))
+      (seq (util/search-normalize q (state/enable-search-remove-accents?)))))))
 
 (defn page-search
   "Return a list of page names that match the query"
@@ -120,7 +121,7 @@
    (page-search q 10))
   ([q limit]
    (when-let [repo (state/get-current-repo)]
-     (let [q (util/search-normalize q)
+     (let [q (util/search-normalize q (state/enable-search-remove-accents?))
            q (clean-str q)]
        (when-not (string/blank? q)
          (let [indice (or (get-in @indices [repo :pages])
@@ -169,7 +170,9 @@
   ([q limit]
    (when q
      (let [q (clean-str q)
-           properties (map name (db-model/get-all-properties))]
+           properties (->> (db-model/get-all-properties)
+                           (remove (property/hidden-properties))
+                           (map name))]
        (when (seq properties)
          (if (string/blank? q)
            properties

+ 2 - 2
src/main/frontend/search/db.cljs

@@ -13,7 +13,7 @@
 (defn block->index
   "Convert a block to the index for searching"
   [{:block/keys [uuid page content] :as block}]
-  (when-let [content (util/search-normalize content)]
+  (when-let [content (util/search-normalize content (state/enable-search-remove-accents?))]
     {:id (:db/id block)
      :uuid (str uuid)
      :page page
@@ -42,7 +42,7 @@
     indice))
 
 (defn original-page-name->index
-  [p] {:name (util/search-normalize p)
+  [p] {:name (util/search-normalize p (state/enable-search-remove-accents?))
        :original-name p})
 
 (defn make-pages-indice!

+ 19 - 4
src/main/frontend/state.cljs

@@ -60,6 +60,8 @@
      :modal/close-btn?                      nil
      :modal/subsets                         []
 
+     ;; left sidebar
+     :ui/navigation-item-collapsed?         {}
 
      ;; right sidebar
      :ui/fullscreen?                        false
@@ -296,17 +298,22 @@
       (when-not (mobile-util/native-platform?)
         "local")))
 
+(def default-config
+  "Default config for a repo-specific, user config"
+  {:feature/enable-search-remove-accents? true
+   :default-arweave-gateway "https://arweave.net"})
+
 (defn get-config
+  "User config for the given repo or current repo if none given"
   ([]
    (get-config (get-current-repo)))
   ([repo-url]
-   (get-in @state [:config repo-url])))
-
-(def default-arweave-gateway "https://arweave.net")
+   (merge default-config
+          (get-in @state [:config repo-url]))))
 
 (defn get-arweave-gateway
   []
-  (:arweave/gateway (get-config) default-arweave-gateway))
+  (:arweave/gateway (get-config)))
 
 (defonce built-in-macros
          {"img" "[:img.$4 {:src \"$1\" :style {:width $2 :height $3}}]"})
@@ -755,6 +762,10 @@
          :custom-context-menu/show? false
          :custom-context-menu/links nil))
 
+(defn toggle-navigation-item-collapsed!
+  [item]
+  (update-state! [:ui/navigation-item-collapsed? item] not))
+
 (defn toggle-sidebar-open?!
   []
   (swap! state update :ui/sidebar-open? not))
@@ -1715,3 +1726,7 @@
 (defn unlinked-dir?
   [dir]
   (contains? (:file/unlinked-dirs @state) dir))
+
+(defn enable-search-remove-accents?
+  []
+  (:feature/enable-search-remove-accents? (get-config)))

+ 4 - 3
src/main/frontend/template.cljs

@@ -1,6 +1,5 @@
 (ns frontend.template
-  (:require [cljs-time.coerce :as tc]
-            [clojure.string :as string]
+  (:require [clojure.string :as string]
             [frontend.date :as date]
             [frontend.state :as state]
             [frontend.util :as util]))
@@ -29,6 +28,8 @@
                        (get (variable-rules) (string/lower-case match))
                        :else
                        (if-let [nld (date/nld-parse match)]
-                         (let [date (tc/to-local-date-time nld)]
+                         (let [;; NOTE: This following cannot handle timezones
+                               ;; date (tc/to-local-date-time nld)
+                               date (doto (goog.date.DateTime.) (.setTime (.getTime nld)))]
                            (util/format "[[%s]]" (date/journal-name date)))
                          match))))))

+ 1 - 1
src/main/frontend/ui.cljs

@@ -219,7 +219,7 @@
                                                                      :class color-class}
              content]]
            [:div.ml-4.flex-shrink-0.flex
-            [:button.inline-flex.text-gray-400.focus:outline-none.focus:text-gray-500.transition.ease-in-out.duration-150
+            [:button.inline-flex.text-gray-400.focus:outline-none.focus:text-gray-500.transition.ease-in-out.duration-150.notification-close-button
              {:on-click (fn []
                           (notification-handler/clear! uid))}
              [:svg.h-5.w-5

+ 5 - 2
src/main/frontend/util.cljc

@@ -917,8 +917,11 @@
 #?(:cljs
    (defn search-normalize
      "Normalize string for searching (loose)"
-     [s]
-     (removeAccents (.normalize (string/lower-case s) "NFKC"))))
+     [s remove-accents?]
+     (let [normalize-str (.normalize (string/lower-case s) "NFKC")]
+      (if remove-accents?
+        (removeAccents  normalize-str)
+        normalize-str))))
 
 #?(:cljs
    (defn file-name-sanity

+ 4 - 0
templates/config.edn

@@ -27,6 +27,10 @@
  ;; Enable Block timestamp
  :feature/enable-block-timestamps? false
 
+ ;; Enable remove accents when searching.
+ ;; After toggle this option, please remember to rebuild your search index by press (cmd+c cmd+s).
+ :feature/enable-search-remove-accents? true
+
  ;; Disable Built-in Scheduled and deadline Query
  ;; :feature/disable-scheduled-and-deadline-query? true
 

+ 14 - 0
templates/dummy-notes-es.md

@@ -0,0 +1,14 @@
+---
+title: ¿Cómo tomar notas ficticias?
+---
+
+- Hola, ¡yo soy un bloque!
+:PROPERTIES:
+:id: 5f713e91-8a3c-4b04-a33a-c39482428e2d
+:END:
+    - ¡Yo soy un bloque hijo!
+    - ¡Yo soy otro bloque hijo!
+- ¡Oye!, ¡yo soy otro bloque!
+:PROPERTIES:
+:id: 5f713ea8-8cba-403d-ac00-9964b1ec7190
+:END:

+ 26 - 0
templates/tutorial-es.md

@@ -0,0 +1,26 @@
+## Hola, ¡bienvenido a Logseq!
+- Logseq es una plataforma _privacidad-primero_, [open-source](https://github.com/logseq/logseq) para la gestión del _conocimiento_ y colaboración.
+- Este es un tutorial de 3 minutos acerca de cómo usar Logseq. ¡Empecemos!
+- Éstos son algunos consejos que pueden ser útiles.
+#+BEGIN_TIP
+Presione clic para editar un bloque.
+Presione `Enter` para crear un nuevo bloque.
+Presione `Shift+Enter` para crear una nueva línea.
+Escriba `/` para mostrar todos los comandos.
+#+END_TIP
+- 1. Creamos una página llamada [[¿Cómo tomar notas ficticias?]]. Puede presionar clic en el enlace para ir a la página, o puede presionar `Shift+Clic` para abrirla en la barra lateral derecha. Ahora debería ver tanto _Referencias Enlazadas_ como  _Referencias sin enlazar_.
+- 2. Referenciemos algunos bloques de [[¿Cómo tomar notas ficticias?]], puede presionar `Shift+Click` sobre cualquier referencia de bloque para abrirla en la barra lateral derecha. Pruebe a hacer algunos cambios en la barra lateral derecha, ¡los bloques referenciados cambiarán también!
+    - ((5f713e91-8a3c-4b04-a33a-c39482428e2d)) : Ésta es una referencia de bloque.
+    - ((5f713ea8-8cba-403d-ac00-9964b1ec7190)) : Ésta es otra referencia de bloque.
+- 3. Logseq soporta etiquetas?
+    - Por supuesto, esta es una etiqueta #ficticia.
+- 4. Logseq soporta tareas como porhacer/haciendo/terminado y prioridades?
+    - Sí, escriba `/` y seleccione su palabra clave favorita (TODO, DOING, DONE, WAITING, CANCELED, NOW, LATER) o prioridad (A/B/C).
+    - NOW [#A] Un tutorial ficticio acerca de "¿Cómo tomar notas ficticias?"
+    - LATER [#A] Revisar este asombroso video de [:a {:href "https://twitter.com/shuomi3" :target "_blank"} "@shuomi3"] acerca de cómo usar Logseq para tomar notas y organizar su vida!
+    {{youtube https://www.youtube.com/watch?v=BhHfF0P9A80&ab_channel=ShuOmi}}
+
+    - DONE Crear una página
+    - CANCELED [#C] Escribir una página con más de 1000 bloques
+- ¡Eso es todo! ¡Ahora puede crear más viñetas o abrir un directorio locar para importar algunas notas!
+- Puede descargar nuestra aplicación de escritorio de https://github.com/logseq/logseq/releases

File diff suppressed because it is too large
+ 44 - 627
yarn.lock


Some files were not shown because too many files changed in this diff