mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 18:12:29 +08:00
Merge branch 'develop' of https://github.com/TriliumNext/Notes into develop
This commit is contained in:
commit
adc9172681
@ -128,7 +128,7 @@ Download the repository, install dependencies using `pnpm` and then run the envi
|
|||||||
git clone https://github.com/TriliumNext/Notes.git
|
git clone https://github.com/TriliumNext/Notes.git
|
||||||
cd Notes
|
cd Notes
|
||||||
pnpm install
|
pnpm install
|
||||||
pnpm nx run edit-docs:serve
|
pnpm nx run edit-docs:edit-docs
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building the Executable
|
### Building the Executable
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
import { t } from "../../services/i18n.js";
|
|
||||||
import options from "../../services/options.js";
|
|
||||||
import CommandButtonWidget from "./command_button.js";
|
|
||||||
|
|
||||||
export default class CreateAiChatButton extends CommandButtonWidget {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.icon("bx bx-bot")
|
|
||||||
.title(t("ai.create_new_ai_chat"))
|
|
||||||
.titlePlacement("bottom")
|
|
||||||
.command("createAiChat")
|
|
||||||
.class("icon-action");
|
|
||||||
}
|
|
||||||
|
|
||||||
isEnabled() {
|
|
||||||
return options.get("aiEnabled") === "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
async refreshWithNote() {
|
|
||||||
if (this.isEnabled()) {
|
|
||||||
this.$widget.show();
|
|
||||||
} else {
|
|
||||||
this.$widget.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -186,7 +186,7 @@ export default class NoteActionsWidget extends NoteContextAwareWidget {
|
|||||||
|
|
||||||
this.$convertNoteIntoAttachmentButton.toggle(note.isEligibleForConversionToAttachment());
|
this.$convertNoteIntoAttachmentButton.toggle(note.isEligibleForConversionToAttachment());
|
||||||
|
|
||||||
this.toggleDisabled(this.$findInTextButton, ["text", "code", "book"].includes(note.type));
|
this.toggleDisabled(this.$findInTextButton, ["text", "code", "book", "mindMap"].includes(note.type));
|
||||||
|
|
||||||
this.toggleDisabled(this.$showAttachmentsButton, !isInOptions);
|
this.toggleDisabled(this.$showAttachmentsButton, !isInOptions);
|
||||||
this.toggleDisabled(this.$showSourceButton, ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "geoMap"].includes(note.type));
|
this.toggleDisabled(this.$showSourceButton, ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "geoMap"].includes(note.type));
|
||||||
|
@ -188,7 +188,7 @@ export default class FindWidget extends NoteContextAwareWidget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!["text", "code", "render"].includes(this.note?.type ?? "")) {
|
if (!["text", "code", "render", "mindMap"].includes(this.note?.type ?? "")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +250,8 @@ export default class FindWidget extends NoteContextAwareWidget {
|
|||||||
case "text":
|
case "text":
|
||||||
const readOnly = await this.noteContext?.isReadOnly();
|
const readOnly = await this.noteContext?.isReadOnly();
|
||||||
return readOnly ? this.htmlHandler : this.textHandler;
|
return readOnly ? this.htmlHandler : this.textHandler;
|
||||||
|
case "mindMap":
|
||||||
|
return this.htmlHandler;
|
||||||
default:
|
default:
|
||||||
console.warn("FindWidget: Unsupported note type for find widget", this.note?.type);
|
console.warn("FindWidget: Unsupported note type for find widget", this.note?.type);
|
||||||
}
|
}
|
||||||
@ -352,7 +354,7 @@ export default class FindWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
return super.isEnabled() && ["text", "code", "render"].includes(this.note?.type ?? "");
|
return super.isEnabled() && ["text", "code", "render", "mindMap"].includes(this.note?.type ?? "");
|
||||||
}
|
}
|
||||||
|
|
||||||
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
||||||
|
@ -85,7 +85,7 @@ export default class FindInHtml {
|
|||||||
if (this.$results?.length) {
|
if (this.$results?.length) {
|
||||||
const $current = this.$results.eq(this.currentIndex);
|
const $current = this.$results.eq(this.currentIndex);
|
||||||
this.$results.removeClass(FIND_RESULT_SELECTED_CSS_CLASSNAME);
|
this.$results.removeClass(FIND_RESULT_SELECTED_CSS_CLASSNAME);
|
||||||
$current[0].scrollIntoView();
|
$current[0].scrollIntoView({ block: 'center', inline: 'center'});
|
||||||
$current.addClass(FIND_RESULT_SELECTED_CSS_CLASSNAME);
|
$current.addClass(FIND_RESULT_SELECTED_CSS_CLASSNAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -378,16 +378,45 @@ export default class TabRowWidget extends BasicWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scrollTabContainer(direction: number, behavior: ScrollBehavior = "smooth") {
|
scrollTabContainer(direction: number, behavior: ScrollBehavior = "smooth") {
|
||||||
const currentScrollLeft = this.$tabScrollingContainer[0]?.scrollLeft;
|
this.$tabScrollingContainer[0].scrollBy({
|
||||||
this.$tabScrollingContainer[0].scrollTo({
|
left: direction,
|
||||||
left: currentScrollLeft + direction,
|
|
||||||
behavior
|
behavior
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
setupScrollEvents() {
|
setupScrollEvents() {
|
||||||
this.$tabScrollingContainer[0].addEventListener('wheel', (event) => {
|
let deltaX = 0;
|
||||||
this.scrollTabContainer(event.deltaY * 1.5);
|
let isScrolling = false;
|
||||||
|
const stepScroll = () => {
|
||||||
|
if (Math.abs(deltaX) > 5) {
|
||||||
|
const step = Math.round(deltaX * 0.2);
|
||||||
|
deltaX -= step;
|
||||||
|
this.scrollTabContainer(step, "instant");
|
||||||
|
requestAnimationFrame(stepScroll);
|
||||||
|
} else {
|
||||||
|
this.scrollTabContainer(deltaX, "instant");
|
||||||
|
deltaX = 0;
|
||||||
|
isScrolling = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.$tabScrollingContainer[0].addEventListener('wheel', async (event) => {
|
||||||
|
if (!event.shiftKey && event.deltaX === 0) {
|
||||||
|
event.preventDefault();
|
||||||
|
// Clamp deltaX between TAB_CONTAINER_MIN_WIDTH and TAB_CONTAINER_MIN_WIDTH * 3
|
||||||
|
deltaX += Math.sign(event.deltaY) * Math.max(Math.min(Math.abs(event.deltaY), TAB_CONTAINER_MIN_WIDTH * 3), TAB_CONTAINER_MIN_WIDTH);
|
||||||
|
if (!isScrolling) {
|
||||||
|
isScrolling = true;
|
||||||
|
stepScroll();
|
||||||
|
}
|
||||||
|
} else if (event.shiftKey) {
|
||||||
|
event.preventDefault();
|
||||||
|
if (event.deltaY > 0) {
|
||||||
|
await appContext.tabManager.activateNextTabCommand();
|
||||||
|
} else {
|
||||||
|
await appContext.tabManager.activatePreviousTabCommand();
|
||||||
|
}
|
||||||
|
this.activeTabEl.scrollIntoView();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$scrollButtonLeft[0].addEventListener('click', () => this.scrollTabContainer(-200));
|
this.$scrollButtonLeft[0].addEventListener('click', () => this.scrollTabContainer(-200));
|
||||||
|
@ -286,4 +286,13 @@ export default class MindMapWidget extends TypeWidget {
|
|||||||
utils.downloadSvgAsPng(this.note.title, svg);
|
utils.downloadSvgAsPng(this.note.title, svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async executeWithContentElementEvent({ resolve, ntxId }: EventData<"executeWithContentElement">) {
|
||||||
|
if (!this.isNoteContext(ntxId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.initialized;
|
||||||
|
|
||||||
|
resolve(this.$content.find('.main-node-container'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ test("Search works when dismissing a tab", async ({ page, context }) => {
|
|||||||
|
|
||||||
await app.getTab(0).click();
|
await app.getTab(0).click();
|
||||||
await app.openAndClickNoteActionMenu("Search in note");
|
await app.openAndClickNoteActionMenu("Search in note");
|
||||||
await expect(app.findAndReplaceWidget).toBeVisible();
|
await expect(app.findAndReplaceWidget.first()).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("New tab displays workspaces", async ({ page, context }) => {
|
test("New tab displays workspaces", async ({ page, context }) => {
|
||||||
|
@ -72,7 +72,7 @@ export default function buildLaunchBarConfig() {
|
|||||||
id: "_lbLlmChat",
|
id: "_lbLlmChat",
|
||||||
title: t("hidden-subtree.llm-chat-title"),
|
title: t("hidden-subtree.llm-chat-title"),
|
||||||
type: "launcher",
|
type: "launcher",
|
||||||
command: "createAiChat",
|
builtinWidget: "aiChatLauncher",
|
||||||
icon: "bx bx-bot",
|
icon: "bx bx-bot",
|
||||||
attributes: [
|
attributes: [
|
||||||
{ type: "label", name: "desktopOnly" }
|
{ type: "label", name: "desktopOnly" }
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
* [Text notes: add a way to move up and down text lines via a keyboard shortcut](https://github.com/TriliumNext/Notes/issues/1002) by @dogfuntom
|
* [Text notes: add a way to move up and down text lines via a keyboard shortcut](https://github.com/TriliumNext/Notes/issues/1002) by @dogfuntom
|
||||||
* [improve tab scroll UX by switching from instant to smooth behavior](https://github.com/TriliumNext/Notes/pull/2030) by @SiriusXT
|
* [improve tab scroll UX by switching from instant to smooth behavior](https://github.com/TriliumNext/Notes/pull/2030) by @SiriusXT
|
||||||
* Calendar view: display calendar view if `#viewType=calendar` is set.
|
* Calendar view: display calendar view if `#viewType=calendar` is set.
|
||||||
|
* [Mind map: add search support](https://github.com/TriliumNext/Notes/pull/2055) by @SiriusXT
|
||||||
|
|
||||||
## 📖 Documentation
|
## 📖 Documentation
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user