Initial import of LogDarioSeq baseline

Establishes version control for the personal Logseq DB fork before
starting the server-client architecture migration and domain features
described in docs/agent-guide and the approved implementation plan.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 15:32:15 +02:00
commit 40631362b3
2016 changed files with 543898 additions and 0 deletions

41
resources/404.html Normal file
View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Not Found</title>
<script type="text/javascript">
// Single Page Apps for GitHub Pages
// https://github.com/rafgraph/spa-github-pages
// Copyright (c) 2016 Rafael Pedicini, licensed under the MIT License
// ----------------------------------------------------------------------
// This script takes the current url and converts the path and query
// string into just a query string, and then redirects the browser
// to the new url with only a query string and hash fragment,
// e.g. https://www.foo.tld/one/two?a=b&c=d#qwe, becomes
// https://www.foo.tld/?p=/one/two&q=a=b~and~c=d#qwe
// Note: this 404.html file must be at least 512 bytes for it to work
// with Internet Explorer (it is currently > 512 bytes)
// If you're creating a Project Pages site and NOT using a custom domain,
// then set segmentCount to 1 (enterprise users may need to set it to > 1).
// This way the code will only replace the route part of the path, and not
// the real directory in which the app resides, for example:
// https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
// https://username.github.io/repo-name/?p=/one/two&q=a=b~and~c=d#qwe
// Otherwise, leave segmentCount as 0.
var segmentCount = 0;
var l = window.location;
l.replace(
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
l.pathname.split('/').slice(0, 1 + segmentCount).join('/') + '/?p=/' +
l.pathname.slice(1).split('/').slice(segmentCount).join('/').replace(/&/g, '~and~') +
(l.search ? '&q=' + l.search.slice(1).replace(/&/g, '~and~') : '') +
l.hash
);
</script>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,166 @@
/*
lsradix theme for code-mirror
http://ethanschoonover.com/lsradix
*/
/*
lsradix color palette
http://ethanschoonover.com/lsradix/img/lsradix-palette.png
*/
.lsradix.base03 { color: var(--lx-gray-01, #002b36); }
.dark .lsradix.base03 { color: var(--lx-gray-02, #002b36); }
.lsradix.base02 { color: var(--lx-gray-02, #073642); }
.dark .lsradix.base02 { color: var(--lx-gray-01, #073642); }
.lsradix.base01 { color: var(--lx-gray-03, #586e75); }
.lsradix.base00 { color: var(--lx-gray-04, #657b83); }
.lsradix.base0 { color: var(--lx-gray-09, #839496); }
.lsradix.base1 { color: var(--lx-gray-10, #93a1a1); }
.lsradix.base2 { color: var(--lx-gray-11, #eee8d5); }
.lsradix.base3 { color: var(--lx-gray-11, #fdf6e3); }
.lsradix.solar-yellow { color: var(--rx-yellow-11, #b58900); }
.lsradix.solar-orange { color: var(--rx-orange-11, #cb4b16); }
.lsradix.solar-red { color: var(--rx-red-11, #dc322f); }
.lsradix.solar-magenta { color: var(--rx-pink-11, #d33682); }
.lsradix.solar-violet { color: var(--rx-purple-11, #6c71c4); }
.lsradix.solar-blue { color: var(--rx-blue-11, #268bd2); }
.lsradix.solar-cyan { color: var(--rx-sky-11, #2aa198); }
.lsradix.solar-green { color: var(--rx-grass-11, #859900); }
/* Color scheme for code-mirror */
.cm-s-lsradix {
line-height: 1.45em;
color-profile: sRGB;
rendering-intent: auto;
}
.cm-s-lsradix.cm-s-dark {
background-color: var(--lx-gray-01, hsl(var(--secondary)/.7));
color: var(--ls-primary-text-color, var(--lx-gray-10, hsl(var(--secondary-foreground))));
}
.dark .cm-s-lsradix.cm-s-dark {
background-color: var(--lx-gray-02, hsl(var(--secondary)/.7));
}
.cm-s-lsradix.cm-s-light {
background-color: var(--lx-gray-02, hsl(var(--secondary)/.7));
color: var(--lx-gray-10, hsl(var(--secondary-foreground)));
}
.cm-s-lsradix .CodeMirror-widget {
text-shadow: none;
}
.cm-s-lsradix .cm-header { color: var(--lx-gray-03, #586e75); }
.cm-s-lsradix .cm-quote { color: var(--lx-gray-10, #93a1a1); }
.cm-s-lsradix .cm-keyword { color: var(--rx-orange-11, #cb4b16); }
.cm-s-lsradix .cm-atom { color: var(--rx-pink-11, #d33682); }
.cm-s-lsradix .cm-number { color: var(--rx-pink-11, #d33682); }
.cm-s-lsradix .cm-def { color: var(--rx-sky-11, #2aa198); }
/* .cm-s-lsradix .cm-variable { color: var(--lx-gray-09, #839496); } */
.cm-s-lsradix .cm-variable { color: var(--lx-gray-12, #839496); }
.cm-s-lsradix .cm-variable-2 { color: var(--rx-yellow-11, #b58900); }
.cm-s-lsradix .cm-variable-3, .cm-s-lsradix .cm-type { color: var(--rx-purple-11, #6c71c4); }
.cm-s-lsradix .cm-property { color: var(--rx-sky-11, #2aa198); }
.cm-s-lsradix .cm-operator { color: var(--rx-purple-11, #6c71c4); }
.cm-s-lsradix .cm-comment { color: var(--lx-gray-10, #586e75); font-style:italic; }
.cm-s-lsradix .cm-string { color: var(--rx-grass-11, #859900); }
.cm-s-lsradix .cm-string-2 { color: var(--rx-yellow-11, #b58900); }
.cm-s-lsradix .cm-meta { color: var(--rx-grass-11, #859900); }
.cm-s-lsradix .cm-qualifier { color: var(--rx-yellow-11, #b58900); }
.cm-s-lsradix .cm-builtin { color: var(--rx-pink-11, #d33682); }
.cm-s-lsradix .cm-bracket { color: var(--rx-orange-11, #cb4b16); }
.cm-s-lsradix .CodeMirror-matchingbracket { color: var(--rx-grass-11, #859900); }
.cm-s-lsradix .CodeMirror-nonmatchingbracket { color: var(--rx-red-11, #dc322f); }
.cm-s-lsradix .cm-tag { color: var(--lx-gray-10, #93a1a1); }
.cm-s-lsradix .cm-attribute { color: var(--rx-sky-11, #2aa198); }
.cm-s-lsradix .cm-hr {
color: transparent;
border-top: 1px solid var(--lx-gray-03, #586e75);
display: block;
}
.cm-s-lsradix .cm-link { color: var(--lx-gray-10, #93a1a1); cursor: pointer; }
.cm-s-lsradix .cm-special { color: var(--rx-purple-11, #6c71c4); }
.cm-s-lsradix .cm-em {
color: #999;
text-decoration: underline;
text-decoration-style: dotted;
}
.cm-s-lsradix .cm-error,
.cm-s-lsradix .cm-invalidchar {
/* color: var(--lx-gray-03, #586e75); */
color: var(--lx-gray-10, #586e75);
border-bottom: 1px dotted var(--rx-red-11, #dc322f);
}
.cm-s-lsradix.cm-s-dark div.CodeMirror-selected { background: var(--lx-gray-06, rgb(4 38 47 / 99%)); }
.cm-s-lsradix.cm-s-dark.CodeMirror ::selection { background: var(--lx-gray-06, rgb(4 38 47 / 99%)); }
.cm-s-lsradix.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: var(--lx-gray-06, rgb(4 38 47 / 99%)); }
.cm-s-lsradix.cm-s-light div.CodeMirror-selected { background: var(--lx-gray-06, #eee8d5); }
.cm-s-lsradix.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: var(--lx-gray-06, #eee8d5); }
.cm-s-lsradix.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-light .CodeMirror-line > span::-moz-selection, .cm-s-light .CodeMirror-line > span > span::-moz-selection { background: var(--lx-gray-06, #eee8d5); }
/* Editor styling */
/* Remove gutter border */
.cm-s-lsradix .CodeMirror-gutters {
border-right: 0;
}
/* Gutter colors and line number styling based of color scheme (dark / light) */
/* Dark */
.cm-s-lsradix.cm-s-dark .CodeMirror-gutters {
background-color: var(--lx-gray-03, hsl(var(--secondary)));
}
.cm-s-lsradix.cm-s-dark .CodeMirror-linenumber {
color: var(--lx-gray-09, #586e75);
}
/* Light */
.cm-s-lsradix.cm-s-light .CodeMirror-gutters {
background-color: var(--lx-gray-03, hsl(var(--secondary)));
}
.cm-s-lsradix.cm-s-light .CodeMirror-linenumber {
color: var(--lx-gray-09, #839496);
}
/* Common */
.cm-s-lsradix .CodeMirror-linenumber {
padding: 0 5px;
}
.cm-s-lsradix .CodeMirror-guttermarker-subtle { color: var(--lx-gray-03, #586e75); }
.cm-s-lsradix.cm-s-dark .CodeMirror-guttermarker { color: #ddd; }
.cm-s-lsradix.cm-s-light .CodeMirror-guttermarker { color: var(--rx-orange-11, #cb4b16); }
.cm-s-lsradix .CodeMirror-gutter .CodeMirror-gutter-text {
color: var(--lx-gray-03, #586e75);
}
/* Cursor */
.cm-s-lsradix .CodeMirror-cursor { border-left: 1px solid #819090; }
/* Fat cursor */
.cm-s-lsradix.cm-s-light.cm-fat-cursor .CodeMirror-cursor { background: #77ee77; }
.cm-s-lsradix.cm-s-light .cm-animate-fat-cursor { background-color: #77ee77; }
.cm-s-lsradix.cm-s-dark.cm-fat-cursor .CodeMirror-cursor { background: var(--lx-gray-03, #586e75); }
.cm-s-lsradix.cm-s-dark .cm-animate-fat-cursor { background-color: var(--lx-gray-03, #586e75); }
/* Active line */
.cm-s-lsradix.cm-s-dark .CodeMirror-activeline-background {
background: rgba(255, 255, 255, 0.06);
}
.cm-s-lsradix.cm-s-light .CodeMirror-activeline-background {
background: rgba(0, 0, 0, 0.06);
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

561
resources/css/shui.css Normal file
View File

@@ -0,0 +1,561 @@
html * {
border-color: hsl(var(--border));
}
html[data-theme=light] {
--accent: var(--rx-gray-12-hsl);
--accent-foreground: var(--rx-gray-02-hsl);
--input: var(--rx-gray-05-hsl);
--secondary: 240 4.8% 95.9%;
--kbd-glow-top: transparent;
--kbd-glow-bottom: rgba(0, 0, 0, 0.10);
}
html[data-theme=dark] {
--accent: var(--rx-gray-12-hsl);
--accent-foreground: var(--rx-gray-02-hsl);
--primary-foreground: 0 0% 22%;
--background: 0 0% 11%;
--foreground: 0 0% 95%;
--card: 0 0% 11%;
--card-foreground: 0 0% 95%;
--secondary: 0 0% 20%;
--secondary-foreground: 0 0% 98%;
--border: 0 0% 16%;
--muted: 0 0% 15%;
--popover: 0 0% 7%;
--popover-foreground: 0 0 95%;
--input: 0 0% 16%;
--kbd-glow-top: rgba(255, 255, 255, 0.15);
--kbd-glow-bottom: rgba(0, 0, 0, 0.25);
}
html {
div[data-radix-menu-content],
.ui__select-content {
--accent: var(--rx-gray-04-hsl);
--accent-foreground: var(--rx-gray-12-hsl);
--muted: var(--rx-gray-05-hsl);
}
.ui__calendar {
--accent: var(--rx-gray-04-hsl);
--accent-foreground: var(--rx-gray-12-hsl);
}
&:not([data-color=logseq]) {
.ui__dropdown-menu-item,
div[data-radix-popper-content-wrapper] div[data-radix-collection-item] {
&:focus, &.is-active {
background-color: var(--lx-gray-04, hsl(var(--accent)));
}
}
.ui__dropdown-menu-content.has-search-key {
> .head:focus-within + div[data-radix-collection-item] {
background-color: var(--lx-gray-04, hsl(var(--accent)));
}
}
div[data-radix-popper-content-wrapper] div[role=menu],
.menu-links-wrapper,
.menu-links-outer,
.absolute-modal[data-modal-name] {
background-color: var(--lx-popover-bg, var(--lx-gray-01, hsl(var(--popover))));
}
}
&[data-color=logseq] {
.references-blocks-item {
--lx-bg-override: var(--rx-gray-03-alpha);
}
.block-children-left-border:hover {
--ls-block-left-color: var(--rx-logseq-11);
}
}
&[data-color=none] {
--ls-block-bullet-color: var(--rx-gray-08);
--ls-block-bullet-active-color: var(--rx-gray-12);
::selection {
@apply bg-primary/20;
}
#ui__ac-inner {
}
.cp__cmdk {
--lx-gray-07: var(--rx-gray-07);
}
.ui__toggle {
&-background-off {
@apply bg-gray-08;
.switcher {
@apply bg-gray-10;
}
}
&-background-on {
.switcher {
@apply bg-gray-03;
}
}
}
.tl-container {
--ls-primary-background-color: hsl(var(--background));
--ls-secondary-background-color: var(--rx-gray-01);
--ls-tertiary-background-color: var(--rx-gray-03);
--ls-quaternary-background-color: var(--rx-gray-05);
}
}
}
html[data-theme=light] {
&[data-color=logseq] {
.references-blocks-item {
--lx-bg-override: var(--rx-gray-03-alpha);
}
}
.extensions__pdf-container {
--lx-pdf-container-dark-bg: var(--lx-gray-11, #042f3c);
}
}
html[data-theme=dark] {
background-color: #161616;
&[data-color=logseq] {
@apply bg-[#002b36];
.ui__modal-panel {
@apply border-accent-01;
}
.tippy-tooltip {
@apply border-accent-02;
}
.references-blocks-item {
background-color: var(--lx-gray-03, var(--ls-secondary-background-color));
}
.cp__right-sidebar-inner {
.references-blocks-item {
background-color: var(--lx-gray-04, var(--ls-tertiary-background-color));
}
}
.cp__themes-installed {
.it.is-active, .it:hover {
@apply bg-accent-01;
}
}
.ui__button {
&.as-outline {
--accent: 192 100% 12%;
}
}
div[data-radix-menu-content],
.ui__select-content {
--accent: 190 100% 15%;
--muted: 192 100% 13%;
--secondary-foreground: 0 0% 82%;
}
.ui__button {
&.as-ghost {
@apply hover:bg-accent-01;
}
}
.menu-separator {
@apply opacity-20;
}
.ui__calendar {
--accent: 196 100% 15%;
}
.rc-datepicker {
--accent: 200 97% 37%;
}
.cp__cmdk {
.border-gray-06,
.border-gray-07 {
border-color: var(--ls-border-color, var(--lx-gray-06));
opacity: .6;
}
> .hints {
@apply border-accent-01 bg-gray-02;
}
}
.tl-button {
&:hover {
@apply bg-accent-02;
}
}
.cp__header {
> .r > div:not(.ui__dropdown-trigger) a.button, button.button,
.ui__button.as-ghost {
@apply opacity-60 hover:opacity-90;
}
}
.form-input {
@apply border-accent-01;
}
}
}
.ui__dialog-overlay, .ui__alert-dialog-overlay,
.ui__dialog-content, .ui__alert-dialog-content,
.ui__dropdown-menu-content, .ui__select-content {
&.z-50 {
@apply z-[999];
}
}
div[data-radix-popper-content-wrapper] {
@apply !z-[999];
&:has(> .repos-list) {
@apply !z-[var(--ls-z-index-level-5)];
}
}
.ui__dialog-overlay {
&[data-align=start],
&[data-align=top] {
@apply !items-start;
.ui__dialog-content {
@apply top-20;
}
}
}
.ui__dialog-content {
@apply outline-none m-0;
&:not([data-auto-width]) {
width: calc(100% - 2rem);
}
&[data-auto-width] {
@apply max-w-[90vw] w-max sm:max-w-[960px];
}
&[data-close-btn=false] {
.ui__dialog-close {
@apply hidden;
}
}
}
.ui__alert-dialog-content {
&[data-mode=confirm] {
.ui__alert-dialog-footer {
@apply flex justify-between font-normal items-center select-none;
}
}
}
/* Deprecated: .ui__button-shortcut-key - replaced by shui-shortcut-key */
/* Unified Keyboard Shortcut Component Styles */
/* Combo Keys - simultaneous key combinations with separator */
.shui-shortcut-combo {
@apply flex items-start relative rounded;
background-color: var(--lx-gray-06-alpha, var(--rx-gray-06-alpha));
border: 1px solid var(--lx-gray-06-alpha, var(--rx-gray-06-alpha));
box-sizing: border-box;
white-space: nowrap;
min-width: 0;
transition: transform 140ms ease-out, box-shadow 140ms ease-out, filter 140ms ease-out;
filter: brightness(1);
}
/* Glow effect for combo and separate keys */
/* Top highlight and bottom shadow use theme-aware variables for light/dark visibility */
/* Combo keys: glow on container (wraps all keys together) */
.shui-shortcut-combo.shui-shortcut-glow {
box-shadow: var(--kbd-glow-top) 0px 1px 0px 0px inset, var(--kbd-glow-bottom) 0px -1px 0px 0px inset;
border: none;
}
/* Separate keys: glow on individual keys (not container) */
.shui-shortcut-separate.shui-shortcut-glow kbd.shui-shortcut-key {
box-shadow: var(--kbd-glow-top) 0px 1px 0px 0px inset, var(--kbd-glow-bottom) 0px -1px 0px 0px inset;
border: none;
}
.shui-shortcut-combo kbd.shui-shortcut-key {
@apply flex flex-col items-center justify-center px-1 py-0.5 relative shrink-0;
min-width: 20px;
background: transparent;
border: none;
}
.shui-shortcut-separator {
background-color: var(--lx-gray-07-alpha, var(--rx-gray-07-alpha));
align-self: stretch;
flex-shrink: 0;
width: 1px;
}
/* Separate Keys - sequential key presses with 4px gap */
.shui-shortcut-separate {
@apply flex items-start relative;
gap: 4px;
white-space: nowrap;
min-width: 0;
}
.shui-shortcut-separate kbd.shui-shortcut-key {
@apply flex flex-col items-center justify-center px-1 py-0.5 relative rounded shrink-0;
background-color: var(--lx-gray-06-alpha, var(--rx-gray-06-alpha));
border: 1px solid var(--lx-gray-06-alpha, var(--rx-gray-06-alpha));
box-sizing: border-box;
min-width: 20px;
}
/* Compact Keys - minimal text-only style */
.shui-shortcut-compact {
@apply flex items-start relative;
font-family: 'Inter', sans-serif;
font-weight: normal;
line-height: 16px;
font-style: normal;
color: var(--lx-gray-12, var(--rx-gray-12));
font-size: 12px;
text-align: center;
letter-spacing: -0.5px;
white-space: nowrap;
gap: 2px;
}
/* Individual key styling with inner glow */
kbd.shui-shortcut-key,
.shui-shortcut-key {
@apply text-xs font-normal h-5 flex items-center justify-center;
font-family: 'Inter', sans-serif;
color: var(--lx-gray-12, var(--rx-gray-12));
font-size: 12px;
text-align: center;
letter-spacing: -0.5px;
padding: 2px 4px;
line-height: 16px;
min-width: fit-content;
transition: transform 140ms ease-out, box-shadow 140ms ease-out, filter 140ms ease-out;
box-shadow: 0 0 0 transparent;
filter: brightness(1);
}
/* Keys in separate containers get their own styling */
.shui-shortcut-separate kbd.shui-shortcut-key {
@apply rounded;
background-color: var(--lx-gray-06-alpha, var(--rx-gray-06-alpha));
border: 1px solid var(--lx-gray-06-alpha, var(--rx-gray-06-alpha));
box-sizing: border-box;
}
/* Override shortcut text color inside primary buttons for better contrast */
.bg-primary kbd.shui-shortcut-key,
.bg-primary .shui-shortcut-key,
.bg-primary .shui-shortcut-compact,
.bg-primary\/90 kbd.shui-shortcut-key,
.bg-primary\/90 .shui-shortcut-key,
.bg-primary\/90 .shui-shortcut-compact,
.bg-primary\/100 kbd.shui-shortcut-key,
.bg-primary\/100 .shui-shortcut-key,
.bg-primary\/100 .shui-shortcut-compact {
color: hsl(var(--primary-foreground));
}
/* Key press animation — separate keys: animate individual kbd elements */
kbd.shui-shortcut-key-pressed,
.shui-shortcut-key-pressed {
transform: translateY(1px);
filter: brightness(0.92);
}
.shui-shortcut-separate.shui-shortcut-glow kbd.shui-shortcut-key-pressed {
box-shadow: var(--kbd-glow-top) 0px 2px 0px 0px inset, var(--kbd-glow-bottom) 0px -0.5px 0px 0px inset;
}
/* Key press animation — combo keys: animate the container (the whole keycap) */
.shui-shortcut-combo.shui-shortcut-key-pressed {
transform: translateY(1px);
filter: brightness(0.92);
}
.shui-shortcut-combo.shui-shortcut-glow.shui-shortcut-key-pressed {
box-shadow: var(--kbd-glow-top) 0px 2px 0px 0px inset, var(--kbd-glow-bottom) 0px -0.5px 0px 0px inset;
}
/* Row highlight animation — accent band sweep (only on actual row elements) */
.shui-shortcut-row.shui-shortcut-row--pressed,
.shortcut-row.shui-shortcut-row--pressed {
background-image: linear-gradient(
90deg,
transparent 0%,
transparent 35%,
rgba(223, 239, 254, 0.08) 50%,
transparent 65%,
transparent 100%
);
background-size: 300% 100%;
background-repeat: no-repeat;
animation: shortcut-row-sweep 700ms ease-out forwards;
}
@keyframes shortcut-row-sweep {
from { background-position: -50% 0; }
to { background-position: 150% 0; }
}
/* Ensure consistent height for shortcut containers */
.shui-shortcut-row {
min-height: 20px;
align-items: center;
flex-wrap: nowrap;
}
/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
kbd.shui-shortcut-key,
.shui-shortcut-key,
.shui-shortcut-combo {
transition: none;
transform: none;
filter: none;
box-shadow: 0 0 0 transparent;
}
.shui-shortcut-row.shui-shortcut-row--pressed,
.shortcut-row.shui-shortcut-row--pressed {
animation: none !important;
background-image: none !important;
}
}
.ui__list-item-highlighted-span {
background-color: var(--lx-accent-06, var(--color-level-4));
}
.dark .ui__list-item-highlighted-span {
background-color: var(--lx-accent-08-alpha, var(--color-level-4));
}
.ui__dropdown-menu-content, div[data-radix-menu-content],
.ui__select-content {
@apply overflow-y-auto;
&[data-side=top] {
max-height: calc(var(--radix-dropdown-menu-content-available-height) - 20px);
}
&[data-side=bottom] {
max-height: calc(var(--radix-dropdown-menu-content-available-height) - 10px);
}
&.text-popover-foreground {
color: inherit;
}
}
.ui__popover-content {
@apply overflow-y-auto;
&[data-side=top] {
max-height: calc(var(--radix-popover-content-available-height) - 40px);
}
&[data-side=bottom] {
max-height: calc(var(--radix-popover-content-available-height) - 20px);
}
}
.ui__popover-content {
@apply !pointer-events-auto;
}
.ui__multi-select-content {
@apply relative;
> .head {
@apply sticky top-0 z-10;
}
.search-input {
> .ui__input {
@apply rounded-[1px] h-8;
}
}
&:has([data-radix-collection-item]) {
> .head {
@apply mb-1.5;
}
}
}
.ui__calendar {
.del-date-btn {
@apply absolute right-[4px] top-[17px] px-1 opacity-70 hover:opacity-100
active:opacity-80 hover:text-red-rx-09 rounded-md !h-6 !w-6;
}
input[type=number] {
appearance: initial;
}
}
.popper-arrow {
fill: white;
filter: drop-shadow(0 0 3px var(--lx-gray-12));
clip-path: inset(0 -10px -10px -10px);
}
.dark-theme {
.popper-arrow {
/* FIXME: set the best color for different themes */
fill: none;
}
}
.ui__toast-content {
&.untitled {
.ui__toast-header {
@apply absolute top-1 right-1 w-fit z-1;
}
.ui__toast-body {
@apply flex-initial py-2;
}
.ui__toast-text {
@apply flex flex-row items-center gap-2 overflow-auto;
}
.ui__toast-description {
@apply max-w-full overflow-auto;
}
}
}

View File

@@ -0,0 +1,153 @@
/**
* This file is managed manually by Webfont app.
* Steps:
* - download the zip from Webfont app
* - get the tabler-icons-extension.woff2 and replace the one in fonts/tabler-icons-extension.woff2
* - update the tie-xxx css rules
*/
@font-face {
font-family: 'tabler-icons-extension';
src: url('./fonts/tabler-icons-extension.woff2?mxgthk') format('woff2');
font-style: normal;
font-weight: 400;
}
.tie {
display: inline-block;
font-family: "tabler-icons-extension" !important;
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
vertical-align: -.125em;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.tie-add-link::before {
content: "\ea01";
}
.tie-app-feature::before {
content: "\ea02";
}
.tie-block::before {
content: "\ea03";
}
.tie-block-search::before {
content: "\ea04";
}
.tie-cloud-exclamation::before {
content: "\ea05";
}
.tie-connector::before {
content: "\ea06";
}
.tie-group::before {
content: "\ea07";
}
.tie-h-auto::before {
content: "\ea08";
}
.tie-heading-off::before {
content: "\ea09";
}
.tie-internal-link::before {
content: "\ea0a";
}
.tie-link-to-block::before {
content: "\ea0b";
}
.tie-link-to-page::before {
content: "\ea0c";
}
.tie-link-to-whiteboard::before {
content: "\ea0d";
}
.tie-move-to-sidebar-right::before {
content: "\ea0e";
}
.tie-new-block::before {
content: "\ea0f";
}
.tie-new-page::before {
content: "\ea10";
}
.tie-new-whiteboard::before {
content: "\ea11";
}
.tie-new-whiteboard-element::before {
content: "\ea12";
}
.tie-object-compact::before {
content: "\ea13";
}
.tie-object-expanded::before {
content: "\ea14";
}
.tie-open-as-page::before {
content: "\ea15";
}
.tie-page::before {
content: "\ea16";
}
.tie-page-search::before {
content: "\ea17";
}
.tie-references-hide::before {
content: "\ea18";
}
.tie-references-show::before {
content: "\ea19";
}
.tie-select-cursor::before {
content: "\ea1a";
}
.tie-text::before {
content: "\ea1b";
}
.tie-ungroup::before {
content: "\ea1c";
}
.tie-whiteboard::before {
content: "\ea1d";
}
.tie-whiteboard-element::before {
content: "\ea1e";
}
.tie-whiteboard-search::before {
content: "\ea1f";
}

4
resources/css/tabler-icons.min.css vendored Normal file

File diff suppressed because one or more lines are too long

2339
resources/css/ui.css Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,89 @@
appId: com.logseq.logseq
electronUpdaterCompatibility: ">=2.16"
directories:
buildResources: .
output: dist
files:
- "**/*"
- "!dist/**"
- "!mobile/**"
- "!android/**"
- "!ios/**"
- "!js/publishing/*.map"
- "!js/publishing/manifest.edn"
- "!js/publishing/module-loader.*"
- "!js/sqlite3.wasm"
- "!css/fonts/tabler-icons.eot"
- "!css/fonts/tabler-icons.ttf"
- "!css/fonts/tabler-icons.woff"
- "!**/node_modules/**/*.map"
- "!**/node_modules/**/*.d.ts"
- "!**/node_modules/**/*.d.cts"
- "!**/node_modules/**/*.d.mts"
- "!**/node_modules/**/*.{ts,cts,mts}"
- "!**/node_modules/**/*.{c,cc,cpp,h,hpp,gyp}"
- "!**/node_modules/**/*.test-d.ts"
- "!**/node_modules/**/*.test-d.cts"
- "!**/node_modules/**/*.test-d.mts"
- "!**/node_modules/**/*.{test,spec}.{js,cjs,mjs,ts,cts,mts}"
- "!**/node_modules/**/*{example,benchmark,bench,tests,runkit}*.{js,cjs,mjs,ts,cts,mts}"
- "!**/node_modules/**/*.{md,markdown}"
- "!**/node_modules/**/{test,tests,__tests__,powered-test,example,examples,benchmark,benchmarks}/**"
- "!**/node_modules/**/{tsconfig.json,eslint.config.js,.editorconfig}"
toolsets:
appimage: "1.0.2"
protocols:
- name: logseq
schemes:
- logseq
publish:
- provider: github
owner: logseq
repo: logseq
extraResources:
- from: .agents/skills/logseq-cli/SKILL.md
to: .agents/skills/logseq-cli/SKILL.md
- from: ../sidecar
to: sidecar
mac:
artifactName: ${productName}-darwin-${arch}-${version}.${ext}
icon: icons/logseq_big_sur.icns
target:
- dmg
- zip
hardenedRuntime: true
entitlements: entitlements.plist
entitlementsInherit: entitlements.plist
dmg:
format: ULFO
win:
icon: icons/logseq.ico
target:
- nsis
- zip
nsis:
artifactName: ${productName}-win-${arch}-${version}-nsis.${ext}
oneClick: false
allowToChangeInstallationDirectory: true
installerIcon: icons/logseq.ico
uninstallerIcon: icons/logseq.ico
linux:
artifactName: ${productName}-linux-${arch}-${version}.${ext}
icon: icons/logseq.png
category: Office
target:
- AppImage
- zip
mimeTypes:
- x-scheme-handler/logseq

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,61 @@
const test = require('node:test')
const assert = require('node:assert/strict')
const fs = require('fs')
const path = require('path')
const config = require('./forge.config')
const repoRoot = path.resolve(__dirname, '..')
function normalizeResourcePath(resourcePath) {
return path.resolve(resourcePath)
}
function collectExtraResources() {
return (config.packagerConfig?.extraResource || []).map(normalizeResourcePath)
}
function isCoveredByExtraResources(targetPath, extraResources) {
const normalizedTarget = path.resolve(targetPath)
return extraResources.some((resource) =>
normalizedTarget === resource || normalizedTarget.startsWith(resource + path.sep)
)
}
test('packager includes all JavaScript files under dist/', () => {
const distDir = path.resolve(repoRoot, 'dist')
const distJsFiles = fs
.readdirSync(distDir)
.filter((name) => name.endsWith('.js'))
.map((name) => path.join(distDir, name))
assert.ok(
distJsFiles.length > 0,
'Expected dist/ to contain at least one JavaScript file for packaging checks'
)
const extraResources = collectExtraResources()
for (const jsFile of distJsFiles) {
assert.ok(
isCoveredByExtraResources(jsFile, extraResources),
`Expected extraResource to include or cover ${jsFile}`
)
}
})
test('packager includes dist/build directory', () => {
const distBuildDir = path.resolve(repoRoot, 'dist/build')
assert.ok(
fs.existsSync(distBuildDir),
'Expected dist/build directory to exist for packaging checks'
)
const extraResources = collectExtraResources()
assert.ok(
isCoveredByExtraResources(distBuildDir, extraResources),
`Expected extraResource to include or cover ${distBuildDir}`
)
})

BIN
resources/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

1297
resources/icons.edn Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
resources/icons/logseq.icns Normal file

Binary file not shown.

BIN
resources/icons/logseq.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
resources/icons/logseq.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
resources/img/checker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
resources/img/credits.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
resources/img/dmg-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

BIN
resources/img/file-edn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
resources/img/folder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
resources/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

52
resources/index.html Normal file
View File

@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="minimum-scale=1, initial-scale=1, maximum-scale=1, width=device-width, shrink-to-fit=no" name="viewport">
<link href="./css/tabler-icons.min.css" rel="stylesheet" type="text/css">
<link href="./css/inter.css" rel="stylesheet" type="text/css">
<link href="./css/style.css" rel="stylesheet" type="text/css">
<link href="./img/logo.png" rel="shortcut icon" type="image/png">
<link href="./img/logo.png" rel="shortcut icon" sizes="192x192">
<link href="./img/logo.png" rel="apple-touch-icon">
<meta content="Logseq" name="apple-mobile-web-app-title">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="yes" name="apple-touch-fullscreen">
<meta content="black-translucent" name="apple-mobile-web-app-status-bar-style">
<meta content="yes" name="mobile-web-app-capable">
<meta content="summary" name="twitter:card">
<meta content="A privacy-first, open-source platform for knowledge management and collaboration." name="twitter:description">
<meta content="@logseq" name="twitter:site">
<meta content="A privacy-first, open-source platform for knowledge management and collaboration." name="twitter:title">
<meta content="https://asset.logseq.com/static/img/logo.png" name="twitter:image:src">
<meta content="A privacy-first, open-source platform for knowledge management and collaboration." name="twitter:image:alt">
<meta content="A privacy-first, open-source platform for knowledge management and collaboration." property="og:title">
<meta content="site" property="og:type">
<meta content="https://logseq.com" property="og:url">
<meta content="https://asset.logseq.com/static/img/logo.png" property="og:image">
<meta content="A privacy-first, open-source platform for knowledge management and collaboration." property="og:description">
<title>Logseq: A privacy-first platform for knowledge management and collaboration</title>
<meta content="logseq" property="og:site_name">
<meta content="A privacy-first, open-source platform for knowledge management and collaboration." name="description">
</head>
<body>
<div id="root"></div>
<script>window.__LSP__HOST__ = true</script>
<script>window.user = null</script>
<script src="./js/magic_portal.js"></script>
<script defer src="./js/highlight.min.js"></script>
<script defer src="./js/interact.min.js"></script>
<script defer src="./js/marked.umd.js"></script>
<script defer type="module" src="./js/pdfjs/pdf.mjs"></script>
<script defer type="module" src="./js/pdf_viewer3.mjs"></script>
<script defer src="./js/eventemitter3.umd.min.js"></script>
<script defer src="./js/photoswipe.umd.min.js"></script>
<script defer src="./js/photoswipe-lightbox.umd.min.js"></script>
<script defer src="./js/html2canvas.min.js"></script>
<script defer src="./js/lsplugin.core.js"></script>
<script defer src="./js/main.js"></script>
<script defer src="./js/prop-types.min.js"></script>
<script defer src="./js/tabler.ext.js"></script>
<script defer src="./js/code-editor.js"></script>
</body>
</html>

1
resources/js/eventemitter3.umd.min.js vendored Normal file
View File

@@ -0,0 +1 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).EventEmitter3=t()}(this,(function(){"use strict";var e={};return function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function s(e,t,r,s,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var c=new o(r,s||e,i),f=n?n+t:t;return e._events[f]?e._events[f].fn?e._events[f]=[e._events[f],c]:e._events[f].push(c):(e._events[f]=c,e._eventsCount++),e}function i(e,t){0==--e._eventsCount?e._events=new r:delete e._events[t]}function c(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),c.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},c.prototype.listeners=function(e){var t=n?n+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var o=0,s=r.length,i=new Array(s);o<s;o++)i[o]=r[o].fn;return i},c.prototype.listenerCount=function(e){var t=n?n+e:e,r=this._events[t];return r?r.fn?1:r.length:0},c.prototype.emit=function(e,t,r,o,s,i){var c=n?n+e:e;if(!this._events[c])return!1;var f,u,a=this._events[c],l=arguments.length;if(a.fn){switch(a.once&&this.removeListener(e,a.fn,void 0,!0),l){case 1:return a.fn.call(a.context),!0;case 2:return a.fn.call(a.context,t),!0;case 3:return a.fn.call(a.context,t,r),!0;case 4:return a.fn.call(a.context,t,r,o),!0;case 5:return a.fn.call(a.context,t,r,o,s),!0;case 6:return a.fn.call(a.context,t,r,o,s,i),!0}for(u=1,f=new Array(l-1);u<l;u++)f[u-1]=arguments[u];a.fn.apply(a.context,f)}else{var p,v=a.length;for(u=0;u<v;u++)switch(a[u].once&&this.removeListener(e,a[u].fn,void 0,!0),l){case 1:a[u].fn.call(a[u].context);break;case 2:a[u].fn.call(a[u].context,t);break;case 3:a[u].fn.call(a[u].context,t,r);break;case 4:a[u].fn.call(a[u].context,t,r,o);break;default:if(!f)for(p=1,f=new Array(l-1);p<l;p++)f[p-1]=arguments[p];a[u].fn.apply(a[u].context,f)}}return!0},c.prototype.on=function(e,t,n){return s(this,e,t,n,!1)},c.prototype.once=function(e,t,n){return s(this,e,t,n,!0)},c.prototype.removeListener=function(e,t,r,o){var s=n?n+e:e;if(!this._events[s])return this;if(!t)return i(this,s),this;var c=this._events[s];if(c.fn)c.fn!==t||o&&!c.once||r&&c.context!==r||i(this,s);else{for(var f=0,u=[],a=c.length;f<a;f++)(c[f].fn!==t||o&&!c[f].once||r&&c[f].context!==r)&&u.push(c[f]);u.length?this._events[s]=1===u.length?u[0]:u:i(this,s)}return this},c.prototype.removeAllListeners=function(e){var t;return e?(t=n?n+e:e,this._events[t]&&i(this,t)):(this._events=new r,this._eventsCount=0),this},c.prototype.off=c.prototype.removeListener,c.prototype.addListener=c.prototype.on,c.prefixed=n,c.EventEmitter=c,e.exports=c}({get exports(){return e},set exports(t){e=t}}),e}));//# sourceMappingURL=eventemitter3.umd.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
/*! @license DOMPurify 3.3.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.3/LICENSE */

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
/*! @license DOMPurify 3.3.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.3/LICENSE */

View File

@@ -0,0 +1 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.MagicPortal=t()}(this,function(){var e=function(e){var t=this;this.rpc_counter=0,this.channel=e,this.foreign=new Map,this.local=new Map,this.calls=new Map,this.queue=[],this.connectionEstablished=!1,this.channel.addEventListener("message",function(e){var n=e.data;if(n&&"object"==typeof n)switch(n.type){case"MP_INIT":return t.onInit(n);case"MP_SET":return t.onSet(n);case"MP_CALL":return t.onCall(n);case"MP_RETURN":return t.onReturn(n)}}),this.channel.postMessage({type:"MP_INIT",id:1,reply:!0})};e.prototype.onInit=function(e){this.connectionEstablished=!0;var t=this.queue;this.queue=[];for(var n=0,o=t;n<o.length;n+=1){this.channel.postMessage(o[n])}e.reply&&this.channel.postMessage({type:"MP_INIT",reply:!1})},e.prototype.onSet=function(e){for(var t=this,n={},o=e.object,i=function(){var i=r[s],c=!e.void.includes(i);n[i]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];return t.rpc_counter=(t.rpc_counter+1)%Number.MAX_SAFE_INTEGER,new Promise(function(n,s){t.postMessage({type:"MP_CALL",object:o,method:i,id:t.rpc_counter,args:e,reply:c}),c?t.calls.set(t.rpc_counter,{resolve:n,reject:s}):n()})}},s=0,r=e.methods;s<r.length;s+=1)i();var c=this.foreign.get(e.object);this.foreign.set(e.object,n),"function"==typeof c&&c(n)},e.prototype.onCall=function(e){var t=this,n=this.local.get(e.object);n&&n[e.method].apply(n,e.args).then(function(n){return e.reply&&t.channel.postMessage({type:"MP_RETURN",id:e.id,result:n})}).catch(function(n){return t.channel.postMessage({type:"MP_RETURN",id:e.id,error:n.message})})},e.prototype.onReturn=function(e){if(this.calls.has(e.id)){var t=this.calls.get(e.id),n=t.resolve,o=t.reject;this.calls.delete(e.id),e.error?o(e.error):n(e.result)}},e.prototype.postMessage=function(e){this.connectionEstablished?this.channel.postMessage(e):this.queue.push(e)},e.prototype.set=function(e,t,n){void 0===n&&(n={}),this.local.set(e,t);var o=Object.entries(t).filter(function(e){return"function"==typeof e[1]}).map(function(e){return e[0]});this.postMessage({type:"MP_SET",object:e,methods:o,void:n.void||[]})},e.prototype.get=function(e){return new Promise(function(t,n){var o=this;return this.foreign.has(e)?t(this.foreign.get(e)):t(new Promise(function(t,n){return o.foreign.set(e,t)}))}.bind(this))};return function(t){var n=new e(t);Object.defineProperties(this,{get:{writable:!1,configurable:!1,value:n.get.bind(n)},set:{writable:!1,configurable:!1,value:n.set.bind(n)}})}});

12391
resources/js/pdf_viewer3.mjs Normal file

File diff suppressed because one or more lines are too long

163
resources/js/preload.js Normal file
View File

@@ -0,0 +1,163 @@
const fs = require('fs')
const path = require('path')
const os = require('os')
const { ipcRenderer, contextBridge, shell, clipboard, webFrame, webUtils } = require('electron')
const IS_MAC = process.platform === 'darwin'
const IS_WIN32 = process.platform === 'win32'
const ALLOWED_EXTERNAL_PROTOCOLS = ['https:', 'http:', 'mailto:', 'zotero:', 'file:']
function getFilePathFromClipboard () {
if (IS_WIN32) {
const rawFilePath = clipboard.read('FileNameW')
return rawFilePath.replace(new RegExp(String.fromCharCode(0), 'g'), '')
} else if (IS_MAC) {
return clipboard.read('public.file-url').replace('file://', '')
} else {
return clipboard.readText()
}
}
/**
* Read the contents of the clipboard for a custom format.
* @param {string} format The custom format to read.
* @returns Buffer containing the contents of the clipboard for the specified format, or null if not available.
*/
function getClipboardData (format) {
if (clipboard.has(format, "clipboard")) {
return clipboard.readBuffer(format)
}
else {
return null;
}
}
contextBridge.exposeInMainWorld('apis', {
getFilePath: (file) => webUtils.getPathForFile(file),
doAction: async (arg) => {
return await ipcRenderer.invoke('main', arg)
},
invoke: async (channel, args) => {
return await ipcRenderer.invoke(channel, ...args)
},
addListener: ipcRenderer.on.bind(ipcRenderer),
removeListener: ipcRenderer.removeListener.bind(ipcRenderer),
removeAllListeners: ipcRenderer.removeAllListeners.bind(ipcRenderer),
on: (channel, callback) => {
const newCallback = (_, data) => callback(data)
ipcRenderer.on(channel, newCallback)
},
off: (channel, callback) => {
if (!callback) {
ipcRenderer.removeAllListeners(channel)
} else {
ipcRenderer.removeListener(channel, callback)
}
},
once: (channel, callback) => {
ipcRenderer.on(channel, callback)
},
checkForUpdates: async (...args) => {
await ipcRenderer.invoke('check-for-updates', ...args)
},
setUpdatesCallback (cb) {
if (typeof cb !== 'function') return
const channel = 'updates-callback'
ipcRenderer.removeAllListeners(channel)
ipcRenderer.on(channel, cb)
},
installUpdatesAndQuitApp () {
ipcRenderer.invoke('install-updates', true)
},
async openExternal (url, options) {
const protocol = new URL(url).protocol
if (!ALLOWED_EXTERNAL_PROTOCOLS.includes(protocol)) {
throw new Error('illegal protocol')
}
await shell.openExternal(url, options)
},
async openPath (relativePath) {
const absolutePath = path.resolve(
relativePath.startsWith('~') ? path.join(os.homedir(), relativePath.slice(1)) : relativePath
);
await shell.openPath(absolutePath)
},
/**
* save all publish assets to disk
*
* @param {string} html html file with embedded state
*/
exportPublishAssets (html, customCSSPath, exportCSSPath, repoPath, assetFilenames, outputDir) {
ipcRenderer.invoke(
'export-publish-assets',
html,
customCSSPath,
exportCSSPath,
repoPath,
assetFilenames,
outputDir
)
},
toggleMaxOrMinActiveWindow (isToggleMin = false) {
ipcRenderer.invoke('toggle-max-or-min-active-win', isToggleMin)
},
/**
* internal
* @param type
* @param args
* @private
*/
async _callApplication (type, ...args) {
return await ipcRenderer.invoke('call-application', type, ...args)
},
/**
* internal
* @param type
* @param args
* @private
*/
async _callMainWin (type, ...args) {
return await ipcRenderer.invoke('call-main-win', type, ...args)
},
/**
* Write binary data to a file, creating parent dirs as needed.
* Used for asset files that can't be transit-serialized through doAction.
*/
writeFileBytes (filePath, data) {
const dir = path.dirname(filePath)
fs.mkdirSync(dir, { recursive: true })
fs.writeFileSync(filePath, Buffer.from(data))
},
getFilePathFromClipboard,
getClipboardData,
setZoomFactor (factor) {
webFrame.setZoomFactor(factor)
},
setZoomLevel (level) {
webFrame.setZoomLevel(level)
},
isAbsolutePath: path.isAbsolute.bind(path)
})

File diff suppressed because one or more lines are too long

56
resources/js/worker.js Normal file
View File

@@ -0,0 +1,56 @@
importScripts(
// Batched optimization
"./lightning-fs.min.js",
// Fixed a bug
"./magic_portal.js"
);
const detect = () => {
if (typeof window !== 'undefined' && !self.skipWaiting) {
return 'window'
} else if (typeof self !== 'undefined' && !self.skipWaiting) {
return 'Worker'
} else if (typeof self !== 'undefined' && self.skipWaiting) {
return 'ServiceWorker'
}
};
const fsName = 'logseq';
const createFS = () => new LightningFS(fsName);
let fs = createFS();
let pfs = fs.promises;
if (typeof self !== 'undefined') {
self.fs = fs;
self.pfs = pfs;
}
if (detect() === 'Worker') {
const portal = new MagicPortal(self);
portal.set('fs', fs);
portal.set('pfs', pfs);
portal.set('workerThread', {
rimraf: async function (path) {
// Knowing path is a directory,
// first, assume everything inside path is a file.
let files = await pfs.readdir(path);
for (let file of files) {
let child = path + '/' + file
try {
await pfs.unlink(child)
} catch (err) {
if (err.code !== 'EISDIR') throw err
}
}
// Assume what's left are directories and recurse.
let dirs = await pfs.readdir(path)
for (let dir of dirs) {
let child = path + '/' + dir
await rimraf(child, pfs)
}
// Finally, delete the empty directory
await pfs.rmdir(path)
}
});
}

168
resources/marketplace.html Normal file
View File

@@ -0,0 +1,168 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Logseq Marketplace</title>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/4.0.0/github-markdown.min.css"
integrity="sha512-Oy18vBnbSJkXTndr2n6lDMO5NN31UljR8e/ICzVPrGpSud4Gkckb8yUpqhKuUNoE+o9gAb4O/rAxxw1ojyUVzg=="
crossorigin="anonymous" referrerpolicy="no-referrer"/>
<style>
html, body {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: sans-serif;
width: 100%;
min-height: 100%;
}
html::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.1);
}
html::-webkit-scrollbar {
background-color: rgba(0, 0, 0, 0.05);
}
html::-webkit-scrollbar-thumb:active {
background-color: rgba(0, 0, 0, 0.2);
}
html::-webkit-scrollbar {
width: 6px;
height: 8px;
}
html::-webkit-scrollbar-corner {
background: transparent;
}
body {
display: flex;
}
#app {
display: flex;
justify-content: center;
flex: 1;
width: 900px;
min-height: 100%;
padding: 30px;
margin: 0 auto;
color: #333;
}
#app > strong {
padding-top: 30vh;
font-weight: 400;
}
pre {
max-width: 800px;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="./js/marked.umd.js"></script>
<script src="./js/purify.js"></script>
<script>
;(async function () {
const app = document.getElementById('app')
const url = new URL(location.href)
const setMsg = (msg) => app.innerHTML = `<strong>${msg}</strong>`
const repo = url.searchParams.get('repo')
if (!repo) {
return setMsg('Repo parameter not found!')
}
const setContent = (content) => app.innerHTML = `<main class="markdown-body">${content}</main>`
const endpoint = (repo, branch, file) => `https://raw.githubusercontent.com/${repo}/${branch}/${file}`
let defaultPoints = [
endpoint(repo, 'master', 'README.md'), endpoint(repo, 'main', 'README.md'),
endpoint(repo, 'master', 'readme.md'), endpoint(repo, 'main', 'readme.md')]
let content = ''
let readme
const fixLink = (link) => readme.replace(/[^\/]+\.md$/i, link)
const isRelative = (href) => href && !href.startsWith('http') && !!href.match(/^([.\/]+|[^\/]+)/) &&
href.replace(/^[.\/]+/, '')
marked.use({
renderer: {
link({ href, title, text }) {
return `<a href="${href}" target="_blank" title="${title}">${text}</a>`
},
image({ href, title, text }) {
let link = isRelative(href)
if (link) {
link = fixLink(link)
return `<img style="max-width: 100%;" src="${link}" alt="${title}" />`
}
return false
},
},
})
// force fix Markdown content
function fixAllImageTagHref (content) {
const isRelativeImageSrc = (src) => src && !src.match(/^(?:[a-z][a-z\d+.-]*:|\/\/|#)/i) && isRelative(src)
return content.replace(/<img\b[^>]*>/gi, (img) => {
return img.replace(/\bsrc\s*=\s*(['"]?)([^'"\s>]+)\1/i, (attr, quote, src) => {
const link = isRelativeImageSrc(src)
return link ? attr.replace(src, fixLink(link)) : attr
})
})
}
// load exist points content
async function loadPage(points) {
setMsg('Loading ...')
for (let url of points) {
try {
const res = await fetch(url)
if (res.status !== 200) {
throw new Error(res.statusText)
}
content = await res.text()
readme = url
break
} catch (e) {
console.debug('Error:', url, e.message)
}
}
content = marked.parse(fixAllImageTagHref(content))
setContent(DOMPurify.sanitize(content))
}
// load default
await loadPage(defaultPoints)
// handle link
document.querySelector('#app').addEventListener('click', (e) => {
const target = e.target
const href = target.getAttribute('href')
if (!!href && href.endsWith('.md') && !href.startsWith('http')) {
loadPage([
endpoint(repo, 'master', href),
endpoint(repo, 'main', href)
])
e.preventDefault()
}
})
}())
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@@ -0,0 +1,29 @@
<!doctype html>
<html lang="en" data-color="logseq">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover, user-scalable=no">
<link href="./css/style.css" rel="stylesheet" type="text/css">
<title>Logseq: A privacy-first platform for knowledge management and collaboration</title>
</head>
<body>
<div id="root"></div>
<script>var isCapacitorNew=true</script>
<script src="./js/magic_portal.js"></script>
<script defer src="./js/highlight.min.js"></script>
<script defer src="./js/interact.min.js"></script>
<script defer src="./js/marked.umd.js"></script>
<script defer src="./js/eventemitter3.umd.min.js"></script>
<script defer src="./js/photoswipe.umd.min.js"></script>
<script defer src="./js/photoswipe-lightbox.umd.min.js"></script>
<script defer src="./js/prop-types.min.js"></script>
<script defer src="./js/main.js"></script>
<script defer src="./js/tabler.ext.js"></script>
<script defer src="./js/code-editor.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
window.Capacitor?.Plugins?.SplashScreen?.hide()
})
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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