Merge branch 'master' into feat/tweet-shape

This commit is contained in:
Bad3r
2023-01-10 05:23:44 +00:00
committed by GitHub
16 changed files with 553 additions and 175 deletions

View File

@@ -2245,7 +2245,7 @@
plugin-slotted? (and config/lsp-enabled? (state/slot-hook-exist? uuid))
block-ref? (:block-ref? config)
stop-events? (:stop-events? config)
block-ref-with-title? (and block-ref? (seq title))
block-ref-with-title? (and block-ref? (not (state/show-full-blocks?)) (seq title))
block-type (or (:ls-type properties) :default)
content (if (string? content) (string/trim content) "")
mouse-down-key (if (util/ios?)

View File

@@ -366,6 +366,12 @@
logical-outdenting?
config-handler/toggle-logical-outdenting!))
(defn showing-full-blocks [t show-full-blocks?]
(toggle "show_full_blocks"
(t :settings-page/show-full-blocks)
show-full-blocks?
config-handler/toggle-show-full-blocks!))
(defn preferred-pasting-file [t preferred-pasting-file?]
(toggle "preferred_pasting_file"
(t :settings-page/preferred-pasting-file)
@@ -607,6 +613,7 @@
enable-timetracking? (state/enable-timetracking?)
enable-all-pages-public? (state/all-pages-public?)
logical-outdenting? (state/logical-outdenting?)
show-full-blocks? (state/show-full-blocks?)
preferred-pasting-file? (state/preferred-pasting-file?)
enable-tooltip? (state/enable-tooltip?)
enable-shortcut-tooltip? (state/sub :ui/shortcut-tooltip?)
@@ -622,6 +629,7 @@
(when (util/electron?) (switch-spell-check-row t))
(outdenting-row t logical-outdenting?)
(showing-full-blocks t show-full-blocks?)
(preferred-pasting-file t preferred-pasting-file?)
(when-not (or (util/mobile?) (mobile-util/native-platform?))
(shortcut-tooltip-row t enable-shortcut-tooltip?))

View File

@@ -218,8 +218,9 @@
:settings-page/spell-checker "Spell checker"
:settings-page/auto-updater "Auto updater"
:settings-page/disable-sentry "Send usage data and diagnostics to Logseq"
:settings-page/disable-sentry-desc "Logseq will never collect your local graph database or sell your data."
:settings-page/disable-sentry-desc "Logseq will never collect your local graph database or sell your data."
:settings-page/preferred-outdenting "Logical outdenting"
:settings-page/show-full-blocks "Show all lines of a block reference"
:settings-page/custom-date-format "Preferred date format"
:settings-page/custom-date-format-warning "Re-index required! Existing journal references would be broken!"
:settings-page/preferred-file-format "Preferred file format"
@@ -1449,6 +1450,20 @@
:user/delete-account-notice "Toutes vos pages publiées sur logseq.com seront supprimées"
:user/delete-your-account "Supprimer votre compte"
:whiteboard/link-whiteboard-or-block "Lier un tablau blanc/page/bloc"
:file/validate-existing-file-error "La page existe déjà avec un autre fichier: {1}, fichier actuel: {2}. Veuillez n'en garder qu'un et réindexer votre graphique."
:notification/clear-all "Tout effacer"
:on-boarding/closed-feature "Fermé {1}"
:on-boarding/tour-whiteboard-home "{1} Commencez pour vos tableaux blancs"
:on-boarding/tour-whiteboard-home-description "Les tableaux blancs ont leur propre section dans l'application où vous pouvez les voir en un coup d'œil, en créer de nouveaux ou les supprimer facilement."
:on-boarding/tour-whiteboard-new "{1} Créer un nouveau tableau blanc"
:on-boarding/tour-whiteboard-new-description "Il existe plusieurs façons de créer un nouveau tableau blanc. L'un d'eux est toujours ici dans le tableau de bord."
:on-boarding/welcome-whiteboard-modal-description "Les tableaux blancs sont un excellent outil de brainstorming et d'organisation. Vous pouvez maintenant placer n'importe laquelle de vos pensées de la base de connaissances ou de nouvelles à côté l'une de l'autre sur une toile spatiale pour vous connecter, vous associer et comprendre de nouvelles façons."
:on-boarding/welcome-whiteboard-modal-skip "Sauter"
:on-boarding/welcome-whiteboard-modal-start "Démarrer le tableau blanc"
:on-boarding/welcome-whiteboard-modal-title "Un nouveau cadre pour vos pensées."
:settings-page/clear-cache-warning "Vider le cache supprimera les graphiques ouverts. Vous perdrez les modifications non enregistrées."
:settings-page/disable-sentry-desc "Logseq ne collectera jamais votre base de données de graphes locale ni ne vendra vos données."
}
:zh-CN {:accessibility/skip-to-main-content "跳转到主内容"
@@ -1586,7 +1601,7 @@
:file/name "文件名"
:file/file "文件:"
:file/last-modified-at "最后更改于"
:file/no-data "没有数据"
:file/no-data "没有数据"
:file/validate-existing-file-error "页面已存在另一个文件: {1}, 当前文件: {2}. 请保留其中一个文件,然后重建当前图谱的索引。"
:file-rn/re-index "重命名文件后,如果其他设备同步了改文件,强烈建议在同步成功后重新建立索引。"
:file-rn/need-action "建议执行文件重命名操作以匹配新格式。当重命名的文件被同步后,请在所有设备上重新建立索引。"
@@ -2346,6 +2361,7 @@
: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/show-full-blocks "Mostrar todas las líneas de una referencia a bloque"
: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"
@@ -3187,7 +3203,89 @@
:settings-page/custom-global-configuration "Configuração global personalizada"
:settings-page/edit-global-config-edn "Editar config.edn global"
:settings-page/sync "Sincronizar"
:settings-page/tab-features "Recursos"}
:settings-page/tab-features "Recursos"
:all-whiteboards "Todos os quadros brancos"
:auto-heading "Título automático"
:go-to-whiteboard "Ir para o quadro branco"
:heading "Título {1}"
:new-whiteboard "Novo quadro branco"
:not-available-in-mode "Não disponível no modo {1}"
:remove-heading "Remover título"
:untitled "Sem título"
:accessibility/skip-to-main-content "Ir para o conteúdo principal"
:color/blue "Azul"
:color/gray "Cinza"
:color/green "Verde"
:color/pink "Rosa"
:color/purple "Roxo"
:color/red "Vermelho"
:color/yellow "Amarelo"
:conversion/non-desktop "O diretório Graph em versões antigas precisa ser convertido para o novo formato. Por favor, use o aplicativo de desktop para fazer a conversão."
:conversion/write-filename-format "Aplicar formato para arquivos recebidos"
:file/validate-existing-file-error "A página já existe com outro arquivo: {1}, arquivo atual: {2}. Por favor, mantenha apenas um deles e reindexe seu gráfico."
:file-rn/affected-pages "Páginas afetadas após a alteração do formato"
:file-rn/all-action "Aplicar todas as ações!"
:file-rn/apply-rename "Aplicar a operação de renomeação de arquivo"
:file-rn/close-panel "Fechar o painel"
:file-rn/confirm-proceed "Atualizar formato!"
:file-rn/filename-desc-1 "Esta configuração define como uma página é armazenada em um arquivo. Logseq armazena uma página em um arquivo com o mesmo nome."
:file-rn/filename-desc-2 "Alguns caracteres como \"/\" ou \"?\" são inválidos para um nome de arquivo."
:file-rn/filename-desc-3 "Logseq substitui caracteres inválidos por seu URL codificado equivalente para torná-los válidos (por exemplo, \"?\" torna-se \"%3F\")."
:file-rn/filename-desc-4 "O separador de espaço de nomes \"/\" também é substituído por \"___\" (sublinhado triplo) para consideração estética."
:file-rn/format-deprecated "Você está usando um formato desatualizado. A atualização para o formato mais recente é altamente recomendada. Faça backup de seus dados e feche os clientes Logseq em outros dispositivos antes da operação."
:file-rn/instruct-1 "É um processo de 2 etapas para atualizar o formato do nome do arquivo:"
:file-rn/instruct-2 "1. Clique em "
:file-rn/instruct-3 "2. Siga as instruções abaixo para renomear os arquivos para o novo formato:"
:file-rn/legend "🟢 Ações opcionais de renomeação; 🟡 Ação de renomeação necessária para evitar mudança de título; 🔴 Mudança de última hora."
:file-rn/need-action "As ações de renomeação de arquivo são sugeridas para corresponder ao novo formato. A reindexação é necessária em todos os dispositivos quando os arquivos renomeados são sincronizados."
:file-rn/no-action "Bom trabalho! Nenhuma ação adicional necessária."
:file-rn/optional-rename "Sugestão: "
:file-rn/or-select-actions " ou renomear individualmente os arquivos abaixo, então "
:file-rn/or-select-actions-2 ". Essas ações não estarão disponíveis depois que você fechar este painel."
:file-rn/otherwise-breaking "Ou o título se tornará"
:file-rn/re-index "A reindexação é fortemente recomendada após a renomeação dos arquivos e em outros dispositivos após a sincronização."
:file-rn/rename "renomeie o arquivo \"{1}\" para \"{2}\""
:file-rn/select-confirm-proceed "Dev: formato de gravação"
:file-rn/select-format "(Opção do modo de desenvolvedor, perigoso!) Selecione o formato do nome do arquivo"
:file-rn/suggest-rename "Ação necessária: "
:file-rn/unreachable-title "Aviso! O nome da página se tornará {1} no formato de nome de arquivo atual, a menos que a propriedade `title::` seja definida manualmente"
:left-side-bar/create "Criar"
:left-side-bar/new-whiteboard "Novo quadro branco"
:notification/clear-all "Limpar tudo"
:on-boarding/closed-feature "Fechado {1}"
:on-boarding/tour-whiteboard-home "{1} Início para seus quadros brancos"
:on-boarding/tour-whiteboard-home-description "Os quadros brancos têm sua própria seção no aplicativo, onde você pode vê-los rapidamente, criar novos ou excluí-los facilmente."
:on-boarding/tour-whiteboard-new "{1} Criar novo quadro branco"
:on-boarding/tour-whiteboard-new-description "Existem várias maneiras de criar um novo quadro branco. Um deles está sempre aqui no painel."
:on-boarding/welcome-whiteboard-modal-description "Quadros brancos são uma ótima ferramenta para brainstorming e organização. Agora você pode colocar qualquer um dos seus pensamentos da base de conhecimento ou novos próximos uns dos outros em uma tela espacial para conectar, associar e entender de novas maneiras."
:on-boarding/welcome-whiteboard-modal-skip "Pular"
:on-boarding/welcome-whiteboard-modal-start "Iniciar quadro branco"
:on-boarding/welcome-whiteboard-modal-title "Um novo quadro para seus pensamentos."
:page/show-whiteboards "Mostrar quadros brancos"
:pdf/doc-metadata "Metadados do documento"
:pdf/hl-block-colored "Rótulo colorido para bloco de destaque"
:plugin.install-from-file/menu-title "Instalar de plugins.edn"
:plugin.install-from-file/notice "Os seguintes plugins substituirão seus plugins:"
:plugin.install-from-file/success "Todos os plugins instalados"
:plugin.install-from-file/title "Instalar plugins de plugins.edn"
:right-side-bar/separator "Manipulador de redimensionamento da barra lateral direita"
:right-side-bar/whiteboards "Quadros brancos"
:search-item/block "Bloco"
:search-item/file "Arquivo"
:search-item/page "Página"
:search-item/whiteboard "Quadro branco"
:settings-page/alpha-features "Recursos em fase Alfa"
:settings-page/beta-features "Recursos em fase Beta"
:settings-page/clear-cache-warning "A limpeza do cache descartará os gráficos abertos. Você perderá as alterações não salvas."
:settings-page/custom-date-format-warning "É necessário reindexar! As referências de periódicos existentes seriam quebradas!"
:settings-page/disable-sentry-desc "A Logseq nunca coletará seu banco de dados gráfico local ou venderá seus dados."
:settings-page/edit-setting "Editar"
:settings-page/enable-whiteboards "Quadros brancos"
:settings-page/filename-format "Formato dos nomes de arquivos"
:settings-page/login-prompt "Para acessar novos recursos antes de qualquer outra pessoa, você deve ser um Patrocinador Coletivo Aberto ou Apoiador do Logseq e, portanto, fazer o login primeiro."
:settings-page/preferred-pasting-file "Arquivo preferência para colar"
:settings-page/tab-assets "Recursos"
:whiteboard/link-whiteboard-or-block "Vincular quadro branco/página/bloco"}
:pt-PT {:on-boarding/demo-graph "Isto é um grafo de demonstração, nenhuma mudança será guardada até abrir uma pasta local."
:on-boarding/add-graph "Adicionar grafo"
@@ -3529,7 +3627,90 @@
:settings-page/custom-global-configuration "Configuração global personalizada"
:settings-page/edit-global-config-edn "Editar config.edn global"
:settings-page/sync "Sincronizar"
:settings-page/tab-features "Recursos"}
:settings-page/tab-features "Recursos"
:all-whiteboards "Todos os quadros brancos"
:auto-heading "Título automático"
:go-to-whiteboard "Ir para o quadro branco"
:heading "Título {1}"
:not-available-in-mode "Não disponível no modo {1}"
:remove-heading "Remover título"
:untitled "Sem título"
:accessibility/skip-to-main-content "Ir para o conteúdo principal"
:color/blue "Azul"
:color/gray "Cinza"
:color/green "Verde"
:color/pink "Rosa"
:color/purple "Roxo"
:color/red "Vermelho"
:color/yellow "Amarelo"
:conversion/non-desktop "O diretório Graph em versões antigas precisa ser convertido para o novo formato. Por favor, use o aplicativo de desktop para fazer a conversão."
:conversion/write-filename-format "Aplicar formato para arquivos recebidos"
:file/validate-existing-file-error "A página já existe com outro arquivo: {1}, arquivo atual: {2}. Por favor, mantenha apenas um deles e reindexe seu gráfico."
:file-rn/affected-pages "Páginas afetadas após a alteração do formato"
:file-rn/all-action "Aplicar todas as ações!"
:file-rn/apply-rename "Aplicar a operação de renomeação de arquivo"
:file-rn/close-panel "Fechar o painel"
:file-rn/confirm-proceed "Atualizar formato!"
:file-rn/filename-desc-1 "Esta configuração define como uma página é armazenada em um arquivo. Logseq armazena uma página em um arquivo com o mesmo nome."
:file-rn/filename-desc-2 "Alguns caracteres como \"/\" ou \"?\" são inválidos para um nome de arquivo."
:file-rn/filename-desc-3 "Logseq substitui caracteres inválidos por seu URL codificado equivalente para torná-los válidos (por exemplo, \"?\" torna-se \"%3F\")."
:file-rn/filename-desc-4 "O separador de espaço de nomes \"/\" também é substituído por \"___\" (sublinhado triplo) para consideração estética."
:file-rn/format-deprecated "Você está usando um formato desatualizado. A atualização para o formato mais recente é altamente recomendada. Faça backup de seus dados e feche os clientes Logseq em outros dispositivos antes da operação."
:file-rn/instruct-1 "É um processo de 2 etapas para atualizar o formato do nome do arquivo:"
:file-rn/instruct-2 "1. Clique em "
:file-rn/instruct-3 "2. Siga as instruções abaixo para renomear os arquivos para o novo formato:"
:file-rn/legend "🟢 Ações opcionais de renomeação; 🟡 Ação de renomeação necessária para evitar mudança de título; 🔴 Mudança de última hora."
:file-rn/need-action "As ações de renomeação de arquivo são sugeridas para corresponder ao novo formato. A reindexação é necessária em todos os dispositivos quando os arquivos renomeados são sincronizados."
:file-rn/no-action "Bom trabalho! Nenhuma ação adicional necessária."
:file-rn/optional-rename "Sugestão: "
:file-rn/or-select-actions " ou renomear individualmente os arquivos abaixo, então "
:file-rn/or-select-actions-2 ". Essas ações não estarão disponíveis depois que você fechar este painel."
:file-rn/otherwise-breaking "Ou o título se tornará"
:file-rn/re-index "A reindexação é fortemente recomendada após a renomeação dos arquivos e em outros dispositivos após a sincronização."
:file-rn/rename "renomeie o arquivo \"{1}\" para \"{2}\""
:file-rn/select-confirm-proceed "Dev: formato de gravação"
:file-rn/select-format "(Opção do modo de desenvolvedor, perigoso!) Selecione o formato do nome do arquivo"
:file-rn/suggest-rename "Ação necessária: "
:file-rn/unreachable-title "Aviso! O nome da página se tornará {1} no formato de nome de arquivo atual, a menos que a propriedade `title::` seja definida manualmente"
:left-side-bar/create "Criar"
:left-side-bar/new-whiteboard "Novo quadro branco"
:notification/clear-all "Limpar tudo"
:on-boarding/closed-feature "Fechado {1}"
:on-boarding/tour-whiteboard-home "{1} Início para seus quadros brancos"
:on-boarding/tour-whiteboard-home-description "Os quadros brancos têm sua própria seção no aplicativo, onde você pode vê-los rapidamente, criar novos ou excluí-los facilmente."
:on-boarding/tour-whiteboard-new "{1} Criar novo quadro branco"
:on-boarding/tour-whiteboard-new-description "Existem várias maneiras de criar um novo quadro branco. Um deles está sempre aqui no painel."
:on-boarding/welcome-whiteboard-modal-description "Quadros brancos são uma ótima ferramenta para brainstorming e organização. Agora você pode colocar qualquer um dos seus pensamentos da base de conhecimento ou novos próximos uns dos outros em uma tela espacial para conectar, associar e entender de novas maneiras."
:on-boarding/welcome-whiteboard-modal-skip "Pular"
:on-boarding/welcome-whiteboard-modal-start "Iniciar quadro branco"
:on-boarding/welcome-whiteboard-modal-title "Um novo quadro para seus pensamentos."
:page/show-whiteboards "Mostrar quadros brancos"
:pdf/doc-metadata "Metadados do documento"
:pdf/hl-block-colored "Rótulo colorido para bloco de destaque"
:plugin.install-from-file/menu-title "Instalar de plugins.edn"
:plugin.install-from-file/notice "Os seguintes plugins substituirão seus plugins:"
:plugin.install-from-file/success "Todos os plugins instalados"
:plugin.install-from-file/title "Instalar plugins de plugins.edn"
:right-side-bar/separator "Manipulador de redimensionamento da barra lateral direita"
:right-side-bar/whiteboards "Quadros brancos"
:search-item/block "Bloco"
:search-item/file "Arquivo"
:search-item/page "Página"
:search-item/whiteboard "Quadro branco"
:settings-page/alpha-features "Recursos em fase Alfa"
:settings-page/beta-features "Recursos em fase Beta"
:settings-page/clear-cache-warning "A limpeza do cache descartará os gráficos abertos. Você perderá as alterações não salvas."
:settings-page/custom-date-format-warning "É necessário reindexar! As referências de periódicos existentes seriam quebradas!"
:settings-page/disable-sentry-desc "A Logseq nunca coletará seu banco de dados gráfico local ou venderá seus dados."
:settings-page/edit-setting "Editar"
:settings-page/enable-whiteboards "Quadros brancos"
:settings-page/filename-format "Formato dos nomes de arquivos"
:settings-page/login-prompt "Para acessar novos recursos antes de qualquer outra pessoa, você deve ser um Patrocinador Coletivo Aberto ou Apoiador do Logseq e, portanto, fazer o login primeiro."
:settings-page/preferred-pasting-file "Arquivo preferência para colar"
:settings-page/tab-assets "Recursos"
:whiteboard/link-whiteboard-or-block "Vincular quadro branco/página/bloco"
:new-whiteboard "Novo quadro branco"}
:ru {:on-boarding/demo-graph "Это демонстрационный граф, изменения не будут сохранены, пока вы не откроете локальный файл."
:on-boarding/add-graph "Добавить новый граф"

View File

@@ -604,28 +604,29 @@
keep this `FileMetadata` in result"
[s1 s2]
(reduce
(fn [result item]
(let [path (:path item)
encrypted-path (:encrypted-path item)
checksum (:etag item)
last-modified (:last-modified item)]
(if (some
#(cond
(not= encrypted-path (:encrypted-path %))
false
(= checksum (:etag %))
true
(>= last-modified (:last-modified %))
false
;; these special files have higher priority in s1
(contains? higher-priority-remote-files path)
false
(< last-modified (:last-modified %))
true)
s2)
result
(conj result item))))
#{} s1))
(fn [result item]
(let [path (:path item)
lower-case-path (some-> path string/lower-case)
;; encrypted-path (:encrypted-path item)
checksum (:etag item)
last-modified (:last-modified item)]
(if (some
#(cond
(not= lower-case-path (some-> (:path %) string/lower-case))
false
(= checksum (:etag %))
true
(>= last-modified (:last-modified %))
false
;; these special files have higher priority in s1
(contains? higher-priority-remote-files path)
false
(< last-modified (:last-modified %))
true)
s2)
result
(conj result item))))
#{} s1))
(comment
(defn map->FileMetadata [m]
@@ -1179,6 +1180,36 @@
(let [encrypted-paths-to-drop (set (persistent! *encrypted-paths-to-drop))]
(filterv #(not (contains? encrypted-paths-to-drop (:encrypted-path %))) file-meta-list))))
(defn- filter-case-different-same-files
"filter case-different-but-same-name files, last-modified one wins"
[file-meta-list encrypted-path->path-map]
(let [seen (volatile! {})]
(loop [result-file-meta-list (transient {})
[f & others] file-meta-list]
(if f
(let [origin-path (get encrypted-path->path-map (:encrypted-path f))
_ (assert (some? origin-path) f)
path (string/lower-case origin-path)
last-modified (:last-modified f)
last-modified-seen (get @seen path)]
(cond
(or (and path (nil? last-modified-seen))
(and path (some? last-modified-seen) (> last-modified last-modified-seen)))
;; 1. not found in seen
;; 2. found in seen, but current f wins
(do (vswap! seen conj [path last-modified])
(recur (conj! result-file-meta-list [path f]) others))
(and path (some? last-modified-seen) (<= last-modified last-modified-seen))
;; found in seen, and seen-f has more recent last-modified epoch
(recur result-file-meta-list others)
:else
(do (println :debug-filter-case-different-same-files:unreachable f path)
(recur result-file-meta-list others))))
(vals (persistent! result-file-meta-list))))))
(extend-type RemoteAPI
IRemoteAPI
(<user-info [this]
@@ -1189,28 +1220,28 @@
(let [file-meta-list (transient #{})
encrypted-path-list (transient [])
exp-r
(<!
(go-loop [continuation-token nil]
(let [r (<! (.<request this "get_all_files"
(into
{}
(remove (comp nil? second)
{:GraphUUID graph-uuid :ContinuationToken continuation-token}))))]
(if (instance? ExceptionInfo r)
r
(let [next-continuation-token (:NextContinuationToken r)
objs (:Objects r)]
(apply conj! encrypted-path-list (map (comp remove-user-graph-uuid-prefix :Key) objs))
(apply conj! file-meta-list
(map
#(hash-map :checksum (:checksum %)
:encrypted-path (remove-user-graph-uuid-prefix (:Key %))
:size (:Size %)
:last-modified (:LastModified %)
:txid (:Txid %))
objs))
(when-not (empty? next-continuation-token)
(recur next-continuation-token)))))))]
(<!
(go-loop [continuation-token nil]
(let [r (<! (.<request this "get_all_files"
(into
{}
(remove (comp nil? second)
{:GraphUUID graph-uuid :ContinuationToken continuation-token}))))]
(if (instance? ExceptionInfo r)
r
(let [next-continuation-token (:NextContinuationToken r)
objs (:Objects r)]
(apply conj! encrypted-path-list (map (comp remove-user-graph-uuid-prefix :Key) objs))
(apply conj! file-meta-list
(map
#(hash-map :checksum (:checksum %)
:encrypted-path (remove-user-graph-uuid-prefix (:Key %))
:size (:Size %)
:last-modified (:LastModified %)
:txid (:Txid %))
objs))
(when-not (empty? next-continuation-token)
(recur next-continuation-token)))))))]
(if (instance? ExceptionInfo exp-r)
exp-r
(let [file-meta-list* (persistent! file-meta-list)
@@ -1229,7 +1260,9 @@
true
(:txid %)
nil)
(filter-files-with-unnormalized-path file-meta-list* encrypted-path->path-map))))))))))
(-> file-meta-list*
(filter-files-with-unnormalized-path encrypted-path->path-map)
(filter-case-different-same-files encrypted-path->path-map)))))))))))
(<get-remote-files-meta [this graph-uuid filepaths]
{:pre [(coll? filepaths)]}
@@ -1286,59 +1319,59 @@
(:Transactions r))
encrypted-paths (mapcat :paths txns-with-encrypted-paths)
encrypted-path->path-map
(zipmap
encrypted-paths
(<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
(zipmap
encrypted-paths
(<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
txns
(mapv
(fn [txn]
(assoc txn :paths (mapv #(get encrypted-path->path-map %) (:paths txn))))
txns-with-encrypted-paths)]
(mapv
(fn [txn]
(assoc txn :paths (mapv #(get encrypted-path->path-map %) (:paths txn))))
txns-with-encrypted-paths)]
txns)))))
(<get-diff [this graph-uuid from-txid]
;; TODO: path in transactions should be relative path(now s3 key, which includes graph-uuid and user-uuid)
;; TODO: path in transactions should be relative path(now s3 key, which includes graph-uuid and user-uuid)
(user/<wrap-ensure-id&access-token
(let [r (<! (.<request this "get_diff" {:GraphUUID graph-uuid :FromTXId from-txid}))]
(if (instance? ExceptionInfo r)
r
(let [txns-with-encrypted-paths (sort-by :TXId (:Transactions r))
txns-with-encrypted-paths*
(mapv
(fn [txn]
(assoc txn :TXContent
(mapv
(fn [[to-path from-path checksum]]
[(remove-user-graph-uuid-prefix to-path)
(some-> from-path remove-user-graph-uuid-prefix)
checksum])
(:TXContent txn))))
txns-with-encrypted-paths)
(mapv
(fn [txn]
(assoc txn :TXContent
(mapv
(fn [[to-path from-path checksum]]
[(remove-user-graph-uuid-prefix to-path)
(some-> from-path remove-user-graph-uuid-prefix)
checksum])
(:TXContent txn))))
txns-with-encrypted-paths)
encrypted-paths
(mapcat
(fn [txn]
(remove
#(or (nil? %) (not (string/starts-with? % "e.")))
(mapcat
(fn [[to-path from-path _checksum]] [to-path from-path])
(:TXContent txn))))
txns-with-encrypted-paths*)
(mapcat
(fn [txn]
(remove
#(or (nil? %) (not (string/starts-with? % "e.")))
(mapcat
(fn [[to-path from-path _checksum]] [to-path from-path])
(:TXContent txn))))
txns-with-encrypted-paths*)
encrypted-path->path-map
(zipmap
encrypted-paths
(<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
(zipmap
encrypted-paths
(<! (<decrypt-fnames rsapi graph-uuid encrypted-paths)))
txns
(mapv
(fn [txn]
(assoc
txn :TXContent
(mapv
(fn [[to-path from-path checksum]]
[(get encrypted-path->path-map to-path to-path)
(some->> from-path (get encrypted-path->path-map))
checksum])
(:TXContent txn))))
txns-with-encrypted-paths*)]
(mapv
(fn [txn]
(assoc
txn :TXContent
(mapv
(fn [[to-path from-path checksum]]
[(get encrypted-path->path-map to-path to-path)
(some->> from-path (get encrypted-path->path-map))
checksum])
(:TXContent txn))))
txns-with-encrypted-paths*)]
[txns
(:TXId (last txns))
(:TXId (first txns))])))))
@@ -2314,7 +2347,9 @@
{:stop true})
(let [remote-all-files-meta remote-all-files-meta-or-exp
local-all-files-meta (<! local-all-files-meta-c)
diff-remote-files (diff-file-metadata-sets remote-all-files-meta local-all-files-meta)
{diff-remote-files :result elapsed-time :time}
(util/with-time (diff-file-metadata-sets remote-all-files-meta local-all-files-meta))
_ (println ::diff-file-metadata-sets-elapsed-time elapsed-time "ms")
recent-10-days-range ((juxt #(tc/to-long (t/minus % (t/days 10))) #(tc/to-long %)) (t/today))
sorted-diff-remote-files
(sort-by
@@ -2476,12 +2511,14 @@
true)
(or (string/starts-with? (.-dir e) base-path)
(string/starts-with? (str "file://" (.-dir e)) base-path)) ; valid path prefix
(not (ignored? e)) ;not ignored
(not (ignored? e)) ;not ignored
;; download files will also trigger file-change-events, ignore them
(when-some [recent-remote->local-file-item
(<! (<file-change-event=>recent-remote->local-file-item
graph-uuid e))]
(not (contains? (:recent-remote->local-files @*sync-state) recent-remote->local-file-item)))))))
(if (= "unlink" (:type e))
true
(when-some [recent-remote->local-file-item
(<! (<file-change-event=>recent-remote->local-file-item
graph-uuid e))]
(not (contains? (:recent-remote->local-files @*sync-state) recent-remote->local-file-item))))))))
(set-remote->local-syncer! [_ s] (set! remote->local-syncer s))
@@ -2504,7 +2541,7 @@
(fn [e]
(go
(and (rsapi-ready? rsapi graph-uuid)
(<! (<fast-filter-e-fn e))
(<! (<fast-filter-e-fn e))
(do
(swap! *sync-state sync-state--add-queued-local->remote-files e)
(let [v (<! (<filter-local-changes-pred e base-path graph-uuid))]
@@ -2731,20 +2768,21 @@
(go-loop []
(let [{:keys [remote->local remote->local-full-sync local->remote-full-sync local->remote resume pause stop]}
(async/alt!
private-remote->local-full-sync-chan {:remote->local-full-sync true}
private-remote->local-sync-chan {:remote->local true}
private-full-sync-chan {:local->remote-full-sync true}
private-pause-resume-chan ([v] (if v {:resume true} {:pause true}))
remote-change-chan ([v] (println "remote change:" v) {:remote->local v})
ratelimit-local-changes-chan ([v]
(if (nil? v)
{:stop true}
(let [rest-v (util/drain-chan ratelimit-local-changes-chan)
vs (cons v rest-v)]
(println "local changes:" vs)
{:local->remote vs})))
(timeout (* 20 60 1000)) {:local->remote-full-sync true}
:priority true)]
private-remote->local-full-sync-chan {:remote->local-full-sync true}
private-remote->local-sync-chan {:remote->local true}
private-full-sync-chan {:local->remote-full-sync true}
private-pause-resume-chan ([v] (if v {:resume true} {:pause true}))
remote-change-chan ([v] (println "remote change:" v) {:remote->local v})
ratelimit-local-changes-chan ([v]
(if (nil? v)
{:stop true}
(let [rest-v (util/drain-chan ratelimit-local-changes-chan)
vs (cons v rest-v)]
(println "local changes:" vs)
{:local->remote vs})))
(timeout (* 20 60 1000)) {:local->remote-full-sync true}
(timeout (* 5 60 1000)) {:remote->local true}
:priority true)]
(cond
stop
nil
@@ -3296,5 +3334,4 @@
(comment
(def *x (atom nil))
(add-tap (fn [v] (reset! *x v)))
)

View File

@@ -44,6 +44,10 @@
(let [logical-outdenting? (state/logical-outdenting?)]
(set-config! :editor/logical-outdenting? (not logical-outdenting?))))
(defn toggle-show-full-blocks! []
(let [show-full-blocks? (state/show-full-blocks?)]
(set-config! :ui/show-full-blocks? (not show-full-blocks?))))
(defn toggle-ui-enable-tooltip! []
(let [enable-tooltip? (state/enable-tooltip?)]
(set-config! :ui/enable-tooltip? (not enable-tooltip?))))

View File

@@ -136,7 +136,7 @@
(defn- remove-transit-ids [block] (dissoc block :db/id :block/file))
(defn save-tree-aux!
[page-block tree]
[page-block tree blocks-just-deleted?]
(let [page-block (db/pull (:db/id page-block))
file-db-id (-> page-block :block/file :db/id)
file-path (-> (db-utils/entity file-db-id) :file/path)]
@@ -146,17 +146,21 @@
(up/ugly-pr-str {:blocks tree
:pages (list (remove-transit-ids page-block))})
(string/triml))
(tree->file-content tree {:init-level init-level}))
files [[file-path new-content]]
repo (state/get-current-repo)]
(file-handler/alter-files-handler! repo files {} {}))
(tree->file-content tree {:init-level init-level}))]
(if (and (string/blank? new-content)
(not blocks-just-deleted?))
(state/pub-event! [:capture-error {:error (js/Error. "Empty content")
:payload {:file-path file-path}}])
(let [files [[file-path new-content]]
repo (state/get-current-repo)]
(file-handler/alter-files-handler! repo files {} {}))))
;; In e2e tests, "card" page in db has no :file/path
(js/console.error "File path from page-block is not valid" page-block tree))))
(defn save-tree!
[page-block tree]
[page-block tree blocks-just-deleted?]
{:pre [(map? page-block)]}
(let [ok-handler #(save-tree-aux! page-block tree)
(let [ok-handler #(save-tree-aux! page-block tree blocks-just-deleted?)
file (or (:block/file page-block)
(when-let [page (:db/id (:block/page page-block))]
(:block/file (db-utils/entity page))))]

View File

@@ -44,34 +44,37 @@
(defn do-write-file!
[repo page-db-id]
[repo page-db-id outliner-op]
(let [page-block (db/pull repo '[*] page-db-id)
page-db-id (:db/id page-block)
whiteboard? (= "whiteboard" (:block/type page-block))
blocks-count (model/get-page-blocks-count repo page-db-id)]
(if (or (and (> blocks-count 500)
(not (state/input-idle? repo {:diff 3000}))) ;; long page
;; when this whiteboard page is just being updated
(and whiteboard? (not (state/whiteboard-page-idle? repo page-block))))
(async/put! (state/get-file-write-chan) [repo page-db-id])
(let [pull-keys (if whiteboard? whiteboard-blocks-pull-keys-with-persisted-ids '[*])
blocks (model/get-page-blocks-no-cache repo (:block/name page-block) {:pull-keys pull-keys})
blocks (if whiteboard? (map cleanup-whiteboard-block blocks) blocks)]
(when-not (and (= 1 (count blocks))
(string/blank? (:block/content (first blocks)))
(nil? (:block/file page-block)))
(let [tree-or-blocks (if whiteboard? blocks
(tree/blocks->vec-tree repo blocks (:block/name page-block)))]
(if page-block
(file/save-tree! page-block tree-or-blocks)
(js/console.error (str "can't find page id: " page-db-id)))))))))
blocks-count (model/get-page-blocks-count repo page-db-id)
blocks-just-deleted? (and (zero? blocks-count)
(contains? #{:delete-blocks :move-blocks} outliner-op))]
(when (or (>= blocks-count 1) blocks-just-deleted?)
(if (or (and (> blocks-count 500)
(not (state/input-idle? repo {:diff 3000}))) ;; long page
;; when this whiteboard page is just being updated
(and whiteboard? (not (state/whiteboard-page-idle? repo page-block))))
(async/put! (state/get-file-write-chan) [repo page-db-id outliner-op])
(let [pull-keys (if whiteboard? whiteboard-blocks-pull-keys-with-persisted-ids '[*])
blocks (model/get-page-blocks-no-cache repo (:block/name page-block) {:pull-keys pull-keys})
blocks (if whiteboard? (map cleanup-whiteboard-block blocks) blocks)]
(when-not (and (= 1 (count blocks))
(string/blank? (:block/content (first blocks)))
(nil? (:block/file page-block)))
(let [tree-or-blocks (if whiteboard? blocks
(tree/blocks->vec-tree repo blocks (:block/name page-block)))]
(if page-block
(file/save-tree! page-block tree-or-blocks blocks-just-deleted?)
(js/console.error (str "can't find page id: " page-db-id))))))))))
(defn write-files!
[pages]
(when (seq pages)
(when-not config/publishing?
(doseq [[repo page-id] (set pages)]
(try (do-write-file! repo page-id)
(doseq [[repo page-id outliner-op] (set pages)]
(try (do-write-file! repo page-id outliner-op)
(catch :default e
(notification/show!
[:div
@@ -81,15 +84,17 @@
(log/error :file/write-file-error {:error e})))))))
(defn sync-to-file
[{page-db-id :db/id}]
(if (nil? page-db-id)
(notification/show!
"Write file failed, can't find the current page!"
:error)
(when-let [repo (state/get-current-repo)]
(if (:graph/importing @state/state) ; write immediately
(write-files! [[repo page-db-id]])
(async/put! (state/get-file-write-chan) [repo page-db-id (tc/to-long (t/now))])))))
([page]
(sync-to-file page nil))
([{page-db-id :db/id} outliner-op]
(if (nil? page-db-id)
(notification/show!
"Write file failed, can't find the current page!"
:error)
(when-let [repo (state/get-current-repo)]
(if (:graph/importing @state/state) ; write immediately
(write-files! [[repo page-db-id outliner-op]])
(async/put! (state/get-file-write-chan) [repo page-db-id outliner-op (tc/to-long (t/now))]))))))
(def *writes-finished? (atom {}))

View File

@@ -11,7 +11,7 @@
(defn updated-page-hook
[tx-report page]
(when-not (get-in tx-report [:tx-meta :created-from-journal-template?])
(file/sync-to-file page)))
(file/sync-to-file page (:outliner-op (:tx-meta tx-report)))))
;; TODO: it'll be great if we can calculate the :block/path-refs before any
;; outliner transaction, this way we can group together the real outliner tx

View File

@@ -565,6 +565,8 @@
:shortcut.category/navigating "Navigation"
:shortcut.category/others "Autres"
:shortcut.category/toggle "Basculer"
:command.editor/select-parent "Sélectionnez le bloc parent"
:command.sidebar/close-top "Ferme l'élément supérieur dans la barre latérale droite"
}
:af {:shortcut.category/formatting "Formatering"
@@ -1020,7 +1022,14 @@
:command.go/electron-find-in-page "Procurar texto na página"
:command.go/electron-jump-to-the-next "Ir para a próxima correspondência da sua pesquisa"
:command.go/electron-jump-to-the-previous "Voltar para a correspondência anterior da sua pesquisa"
:command.graph/re-index "Reindexar o grafo atual"}
:command.graph/re-index "Reindexar o grafo atual"
:command.editor/new-whiteboard "Novo quadro branco"
:command.editor/select-parent "Selecione o bloco pai"
:command.go/whiteboards "Ir para os quadros brancos"
:command.graph/export-as-html "Exportar páginas de gráficos públicos como html"
:command.pdf/find "PDF: Pesquisar no documento PDF atual"
:command.sidebar/close-top "Fechar item superior na barra lateral direita"
:command.ui/install-plugins-from-file "Instalar plugins de plugins.edn"}
:pt-BR {:shortcut.category/formatting "Formatação"
:shortcut.category/basics "Básico"
@@ -1144,7 +1153,15 @@
:command.go/electron-find-in-page "Localizar texto na página"
:command.go/electron-jump-to-the-next "Ir para a próxima correspondência da sua pesquisa"
:command.go/electron-jump-to-the-previous "Voltar para a correspondência anterior da sua pesquisa"
:command.graph/re-index "Reindexar o grafo atual"}
:command.graph/re-index "Reindexar o grafo atual"
:command.editor/new-whiteboard "Novo quadro branco"
:command.editor/select-parent "Selecione o bloco pai"
:command.go/whiteboards "Ir para os quadros brancos"
:command.graph/export-as-html "Exportar páginas de gráficos públicos como html"
:command.pdf/find "PDF: Pesquisar no documento PDF atual"
:command.sidebar/close-top "Fechar item superior na barra lateral direita"
:command.ui/install-plugins-from-file "Instalar plugins de plugins.edn"}
:ja {:shortcut.category/formatting "フォーマット"
:shortcut.category/basics "基本操作"
@@ -1522,7 +1539,8 @@
:command.ui/install-plugins-from-file "Eklentileri plugins.edn dosyasından yükleyin"
:command.editor/toggle-open-blocks "Açık blokları kapat/aç (tüm blokları daralt veya genişlet)"
:command.ui/toggle-cards "Kartları aç/kapat"
:command.git/commit "Git commit mesajı"}
:command.git/commit "Git commit mesajı"
:command.editor/select-parent "Ebeveyn bloğunu seçin"}
:ko {:shortcut.category/formatting "포맷"
:shortcut.category/basics "기본 동작"

View File

@@ -38,6 +38,7 @@
[:block/content-max-length :int]
[:ui/show-command-doc? :boolean]
[:ui/show-empty-bullets? :boolean]
[:ui/show-full-blocks? :boolean]
[:query/views [:map-of
:keyword
[:sequential any?]]]

View File

@@ -670,6 +670,10 @@ Similar to re-frame subscriptions"
[]
(:editor/logical-outdenting? (sub-config)))
(defn show-full-blocks?
[]
(:ui/show-full-blocks? (sub-config)))
(defn preferred-pasting-file?
[]
(:editor/preferred-pasting-file? (sub-config)))