-
-
Notifications
You must be signed in to change notification settings - Fork 623
feat: AI menu auto scrolling #2039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
e7d4b14
e78f1aa
b075999
98be316
3546b42
a5b4e7a
7696fd1
5d1e5ba
8ccd526
a223c7a
4118b17
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,9 @@ export class AIExtension extends BlockNoteExtension { | |
} | ||
| undefined; | ||
|
||
private scrollInProgress = false; | ||
private autoScroll = false; | ||
|
||
public static key(): string { | ||
return "ai"; | ||
} | ||
|
@@ -134,6 +137,51 @@ export class AIExtension extends BlockNoteExtension { | |
options.agentCursor || { name: "AI", color: "#8bc6ff" }, | ||
), | ||
); | ||
|
||
// Scrolls to the block being edited by the AI while auto scrolling is | ||
// enabled. | ||
this.editor.onCreate(() => { | ||
this.editor.onChange(() => { | ||
if (!this.autoScroll) { | ||
return; | ||
} | ||
|
||
const aiMenuState = this._store.getState().aiMenuState; | ||
const aiMenuNonErrorState = | ||
aiMenuState === "closed" ? undefined : aiMenuState; | ||
if (aiMenuNonErrorState?.status === "ai-writing") { | ||
const blockElement = this.editor.domElement?.querySelector( | ||
`[data-node-type="blockContainer"][data-id="${aiMenuNonErrorState.blockId}"]`, | ||
); | ||
blockElement?.scrollIntoView({ block: "center" }); | ||
} | ||
}); | ||
}); | ||
Comment on lines
17
to
29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why wrap in an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The underlying TipTap editor is undefined when the extension constructor is run, and so an error gets thrown attempting to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to fix this then, because I don't think this is a great pattern |
||
|
||
// Listens for `scroll` and `scrollend` events to see if a new scroll was | ||
// started before an existing one ended. This is the most reliable way we | ||
// have of checking if a scroll event was caused by the user and not by | ||
// `scrollIntoView`, as the events are otherwise indistinguishable. If a | ||
// scroll was started before an existing one finished (meaning the user has | ||
// scrolled), auto scrolling is disabled. | ||
document.addEventListener( | ||
matthewlipski marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
"scroll", | ||
() => { | ||
if (this.scrollInProgress) { | ||
this.autoScroll = false; | ||
} | ||
|
||
this.scrollInProgress = true; | ||
}, | ||
true, | ||
); | ||
document.addEventListener( | ||
"scrollend", | ||
() => { | ||
this.scrollInProgress = false; | ||
}, | ||
true, | ||
); | ||
} | ||
|
||
/** | ||
|
@@ -148,6 +196,12 @@ export class AIExtension extends BlockNoteExtension { | |
status: "user-input", | ||
}, | ||
}); | ||
|
||
// Scrolls to the block when the menu opens. | ||
const blockElement = this.editor.domElement?.querySelector( | ||
`[data-node-type="blockContainer"][data-id="${blockID}"]`, | ||
); | ||
blockElement?.scrollIntoView({ block: "center" }); | ||
} | ||
|
||
/** | ||
|
@@ -387,6 +441,7 @@ export class AIExtension extends BlockNoteExtension { | |
sender, | ||
chatRequestOptions: opts.chatRequestOptions, | ||
onStart: () => { | ||
this.autoScroll = true; | ||
this.setAIResponseStatus("ai-writing"); | ||
}, | ||
}); | ||
|
matthewlipski marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.