Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/desktop",
"productName": "ZenNotes",
"version": "2.72.0",
"version": "2.73.0",
"description": "ZenNotes desktop shell",
"private": true,
"main": "./out/main/index.js",
Expand Down
20 changes: 10 additions & 10 deletions apps/desktop/terminal-release.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@
"release": {
"repository": "ZenNotes/tui",
"protocol": 1,
"version": "0.9.0",
"commit": "a0d335c459c04fdccb8686d81d481e10634a3948",
"version": "0.9.1",
"commit": "c6e988604834fa65314e6f8617f2e83b4461334e",
"artifacts": {
"darwin-arm64": {
"url": "https://github.com/ZenNotes/tui/releases/download/v0.9.0/zn_0.9.0_darwin_arm64.tar.gz",
"sha256": "1f97fcbf307ccfba03496311bdc04e9708c10e822ac2abdf03ffa7131197f92e"
"url": "https://github.com/ZenNotes/tui/releases/download/v0.9.1/zn_0.9.1_darwin_arm64.tar.gz",
"sha256": "6ee4b0d9ed60417453bae5aed10c1cb92cd2d1504be79afb5e6b8fb31caed99a"
},
"darwin-x64": {
"url": "https://github.com/ZenNotes/tui/releases/download/v0.9.0/zn_0.9.0_darwin_amd64.tar.gz",
"sha256": "2f95711520fda368cff318d744b87b3afa98cccefcb34b35d86cce967c4c0bb8"
"url": "https://github.com/ZenNotes/tui/releases/download/v0.9.1/zn_0.9.1_darwin_amd64.tar.gz",
"sha256": "58c990a91900df44684f942d11907fec79c2712ca1a513278f957328779478c6"
},
"linux-arm64": {
"url": "https://github.com/ZenNotes/tui/releases/download/v0.9.0/zn_0.9.0_linux_arm64.tar.gz",
"sha256": "b0a08f2575fec89e87f76fcb5dc9a7410c9b8e3327922e587605ccdd3588f2dc"
"url": "https://github.com/ZenNotes/tui/releases/download/v0.9.1/zn_0.9.1_linux_arm64.tar.gz",
"sha256": "b8a3dd4a3f160c2d5d9184a0a4ca941822d410623ef3c609aa841638dc866a54"
},
"linux-x64": {
"url": "https://github.com/ZenNotes/tui/releases/download/v0.9.0/zn_0.9.0_linux_amd64.tar.gz",
"sha256": "6ca45da7e8adcbed0037888961239fe4dbb6b960ec87844a8b6fb2439484f523"
"url": "https://github.com/ZenNotes/tui/releases/download/v0.9.1/zn_0.9.1_linux_amd64.tar.gz",
"sha256": "8064c1282f63ce520ba252c09be4d867c8b8b4417d88c547cd5ea4e74a2a84da"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion apps/quicklook/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/quicklook",
"private": true,
"version": "2.72.0",
"version": "2.73.0",
"type": "module",
"description": "The macOS Quick Look preview for Markdown files: the page it renders and the Swift extension that serves it",
"homepage": "https://zennotes.org",
Expand Down
2 changes: 1 addition & 1 deletion apps/share-viewer/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/share-viewer",
"private": true,
"version": "2.72.0",
"version": "2.73.0",
"type": "module",
"description": "Read-only renderer for publicly shared ZenNotes, embedded by the zennotes.org website",
"homepage": "https://zennotes.org",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/web",
"private": true,
"version": "2.72.0",
"version": "2.73.0",
"type": "module",
"description": "ZenNotes web client for self-hosted and hosted deployments",
"homepage": "https://zennotes.org",
Expand Down
20 changes: 10 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "zennotes-monorepo",
"private": true,
"version": "2.72.0",
"version": "2.73.0",
"description": "ZenNotes monorepo for desktop, web, and self-hosted server builds",
"packageManager": "npm@10.9.2",
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion packages/app-core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zennotes/app-core",
"private": true,
"version": "2.72.0",
"version": "2.73.0",
"type": "module",
"exports": {
"./main": "./src/main.tsx",
Expand Down
23 changes: 21 additions & 2 deletions packages/app-core/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1201,10 +1201,29 @@ function App(): JSX.Element {
}
}, [])

// A window-drag strip belongs to the window, not the page, so a tab or note
// dragged inside the app may not be able to drop on one (the blank end of a
// tab strip with the title bar off). Nothing moves the window mid-drag, so
// the strips stand down until the drag ends.
useEffect(() => {
const root = document.documentElement
const start = (): void => root.classList.add('zn-app-dragging')
const end = (): void => root.classList.remove('zn-app-dragging')
window.addEventListener('dragstart', start, true)
window.addEventListener('dragend', end, true)
window.addEventListener('drop', end, true)
return () => {
window.removeEventListener('dragstart', start, true)
window.removeEventListener('dragend', end, true)
window.removeEventListener('drop', end, true)
end()
}
}, [])

if (!hasCompletedOnboarding) {
return (
<div className="zn-app-shell w-screen bg-paper-100 text-ink-900">
{!zenMode && <TitleBar />}
{!zenMode && <TitleBar standalone />}
<Suspense fallback={<div className="flex-1" />}>
<OnboardingWizard />
</Suspense>
Expand All @@ -1223,7 +1242,7 @@ function App(): JSX.Element {
if (!vault) {
return (
<div className="zn-app-shell w-screen bg-paper-100 text-ink-900">
{!zenMode && <TitleBar />}
{!zenMode && <TitleBar standalone />}
<Suspense fallback={<div className="flex-1" />}>
<EmptyVault />
</Suspense>
Expand Down
62 changes: 2 additions & 60 deletions packages/app-core/src/components/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
registerHalfPageMotion,
} from "../lib/cm-vim-half-page-motion";
import { registerHeadingMotion } from "../lib/cm-vim-heading-motion";
import { registerOpenLineContinuation } from "../lib/cm-vim-open-line";
import { registerReflowOperator } from "../lib/cm-vim-reflow";
import {
harperAddWordAtCursor,
Expand Down Expand Up @@ -88,7 +89,6 @@ import {
selectActiveBuffer,
} from "../lib/buffer-navigation";
import { applyVimInsertEscape } from "../lib/vim-insert-escape";
import { listContinuationPrefix } from "../lib/list-continuation";
import { focusEditorNormalMode } from "../lib/editor-focus";
import { toVimSequence } from "../lib/vim-key-sequence";
import { registerNoteMoveExCommands } from "../lib/vim-ex-commands";
Expand Down Expand Up @@ -506,65 +506,7 @@ function registerVimCommands(): void {
{ context: "visual" },
);

// #320: opening a line with o/O on a list item carries the marker forward —
// like pressing Enter — so bullets repeat, ordered numbers advance (the
// renumber pass fixes the exact value for both o and O), indentation is
// preserved, and a checkbox continues as a fresh unchecked box. Non-list lines
// fall back to Vim's built-in open-line. The handler runs as `actions[name]`,
// so `this` is Vim's action table — reuse its open-line + insert-mode entry.
type VimActionTable = {
newLineAndEnterInsertMode: (
cm: unknown,
args: unknown,
vim: unknown,
) => void;
enterInsertMode: (cm: unknown, args: unknown, vim: unknown) => void;
};
Vim.defineAction("zenOpenLineContinuingList", function (
this: VimActionTable,
cm: ReturnType<typeof getCM>,
actionArgs: { after?: boolean; repeat?: number },
vim: { insertMode?: boolean },
) {
const view = (cm as unknown as { cm6?: EditorView }).cm6;
const prefix = view
? listContinuationPrefix(
view.state.doc.lineAt(view.state.selection.main.head).text,
)
: null;
if (!view || prefix == null) {
this.newLineAndEnterInsertMode(cm, actionArgs, vim);
return;
}
const line = view.state.doc.lineAt(view.state.selection.main.head);
vim.insertMode = true;
if (actionArgs.after) {
view.dispatch({
changes: { from: line.to, insert: `\n${prefix}` },
selection: { anchor: line.to + 1 + prefix.length },
});
} else {
view.dispatch({
changes: { from: line.from, insert: `${prefix}\n` },
selection: { anchor: line.from + prefix.length },
});
}
this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim);
} as unknown as Parameters<typeof Vim.defineAction>[1]);
Vim.mapCommand(
"o",
"action",
"zenOpenLineContinuingList",
{ after: true },
{ context: "normal", isEdit: true, interlaceInsertRepeat: true },
);
Vim.mapCommand(
"O",
"action",
"zenOpenLineContinuingList",
{ after: false },
{ context: "normal", isEdit: true, interlaceInsertRepeat: true },
);
registerOpenLineContinuation();

// #290/#312: make j/k move by display line through soft-wrapped content.
// Shared with the Quick Note window (QuickCaptureApp) via the same helper.
Expand Down
24 changes: 21 additions & 3 deletions packages/app-core/src/components/EditorPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ import {
import { isTabStripOverflowing } from '../lib/tab-strip-overflow'
import { editorTabSize } from '../lib/editor-tab-size'
import { cursorDrawSelection } from '../lib/cm-cursor-blink'
import { chromeCarriesWindowDrag, isPaneOnTopEdge } from '../lib/window-chrome'

const MODE_OPTIONS: Array<{
mode: PaneMode
Expand Down Expand Up @@ -949,6 +950,12 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
)
const sidebarOpen = useStore((s) => s.sidebarOpen)
const zenMode = useStore((s) => s.zenMode)
// With the title bar off, the top pane's chrome is what moves the window.
const runtime = window.zen.getAppInfo().runtime
const dragsWindow = useStore(
(s) =>
chromeCarriesWindowDrag(s.showWindowTitleBar, runtime) && isPaneOnTopEdge(s.paneLayout, paneId)
)
const toggleSidebar = useStore((s) => s.toggleSidebar)
const setFocusedPanel = useStore((s) => s.setFocusedPanel)
const focusedPanel = useStore((s) => s.focusedPanel)
Expand Down Expand Up @@ -3562,7 +3569,9 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
data-tab-pane-id={paneId}
data-tab-path={tab.path}
data-tab-active={active ? 'true' : undefined}
className="relative"
// A window-drag strip takes the mouse from everything in it that is
// not marked no-drag, and a tab is dragged and right-clicked itself.
className={dragsWindow ? 'relative no-drag' : 'relative'}
draggable={!isVirtual}
onDragStart={(e) => {
if (isVirtual) {
Expand Down Expand Up @@ -4005,7 +4014,8 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
// Outer header holds the back/forward nav buttons + the (flex-1) tab strip.
const tabStripHeaderClass = [
'glass-header flex shrink-0 items-stretch border-b border-paper-300/70 pl-1',
wrapTabs ? 'min-h-[var(--z-tab-height)]' : 'h-[var(--z-tab-height)]'
wrapTabs ? 'min-h-[var(--z-tab-height)]' : 'h-[var(--z-tab-height)]',
dragsWindow ? 'drag-region' : ''
].join(' ')
const tabStripClass = [
'workspace-tab-strip flex min-w-0 flex-1 items-stretch gap-0',
Expand Down Expand Up @@ -4370,8 +4380,16 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
</div>
</div>
)}
{dragsWindow && !hasTabs && !content && !zenMode && (
// No tab strip and no header: keep something to move the window by.
<div aria-hidden className="drag-region h-8 shrink-0" />
)}
{content && !zenMode && (
<header className="glass-header flex h-12 shrink-0 items-center justify-between gap-3 px-4">
<header
className={`glass-header flex h-12 shrink-0 items-center justify-between gap-3 px-4${
dragsWindow && !hasTabs ? ' drag-region' : ''
}`}
>
<div className="flex min-w-0 flex-1 items-center gap-1">
<Breadcrumb
note={content}
Expand Down
10 changes: 9 additions & 1 deletion packages/app-core/src/components/NoteList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
} from '../lib/vault-layout'
import { assetTabPath } from '../lib/asset-tabs'
import { getScrollTopForVirtualIndex, getVirtualRange } from '../lib/virtual-list'
import { chromeCarriesWindowDrag } from '../lib/window-chrome'

function formatDate(ms: number): string {
const d = new Date(ms)
Expand Down Expand Up @@ -96,6 +97,9 @@ export function NoteList(): JSX.Element {
const prefetchNotes = useStore((s) => s.prefetchNotes)
const focusedPanel = useStore((s) => s.focusedPanel)
const vimMode = useStore((s) => s.vimMode)
const dragsWindow = useStore((s) =>
chromeCarriesWindowDrag(s.showWindowTitleBar, window.zen.getAppInfo().runtime)
)
const noteListCursorIndex = useStore((s) => s.noteListCursorIndex)
const setFocusedPanel = useStore((s) => s.setFocusedPanel)
const systemFolderLabels = useStore((s) => s.systemFolderLabels)
Expand Down Expand Up @@ -724,7 +728,11 @@ export function NoteList(): JSX.Element {
onMouseDownCapture={() => setFocusedPanel('notelist')}
onFocusCapture={() => setFocusedPanel('notelist')}
>
<header className="glass-header flex h-12 shrink-0 items-center justify-between px-4">
<header
className={`glass-header flex h-12 shrink-0 items-center justify-between px-4${
dragsWindow ? ' drag-region' : ''
}`}
>
<div className="flex items-baseline gap-2">
<h2 className="text-sm font-semibold text-ink-900">{heading}</h2>
<span className="text-xs text-ink-500">
Expand Down
Loading
Loading