Skip to content

Commit

Permalink
fix: allow macro prompt to remain open even if the events were more t…
Browse files Browse the repository at this point in the history
…han 100 events ago

Previously we were only looking for a series of prompt action events within the last 100 events. However, if things are happening in the background while the prompt is still open, those events can keep racking up and eventually the prompt window will close (though klipperscreen still displays it).

I've now refactored this code so that it will internally keep an array of the prompt events and we will process through all the events at first, but we will set a checkpoint at the most recent processed event so that we don't go back and re-process ones that were already done. Effectively this means on first load sure we iterated through potentially a lot of events, but then after that we're really only processing through at most a few events.

In addition, the part of the code that would parse out the message, because it would replace all double quotes, it meant that I could not do this:

```gcode
RESPOND TYPE=command MSG="action:prompt_begin \"Question of the day\""
RESPOND TYPE=command MSG="action:prompt_button Foo Bar|RESPOND MSG=\"FOO BAR\""
RESPOND TYPE=command MSG="action:prompt_show"
```

If I tried to click that button I would get the following error:

```
Malformed command 'RESPOND MSG=FOO BAR'
```

I've updated the message parsing to effectively just strip off matching open and closing single or double quotes from the message. For example, all of the following would result in a message of `Question of the day`:

```
RESPOND TYPE=command MSG="action:prompt_begin \"Question of the day\""
RESPOND TYPE=command MSG="action:prompt_begin 'Question of the day'"
RESPOND TYPE=command MSG="action:prompt_begin Question of the day"
```

Signed-off-by: Branden Cash <203336+ammmze@users.noreply.github.com>
  • Loading branch information
ammmze committed Nov 15, 2024
1 parent 42a4d85 commit 7019d50
Showing 1 changed file with 60 additions and 15 deletions.
75 changes: 60 additions & 15 deletions src/components/dialogs/TheMacroPrompt.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,27 +58,72 @@ export default class TheMacroPrompt extends Mixins(BaseMixin) {
mdiCloseThick = mdiCloseThick
private internalCloseCommand: number | null = null
private checkpointEvent: ServerStateEvent | null = null
private currentPrompt: ServerStateEventPrompt[] = []
// regex that extracts the type and message, omitting the wrapping double quotes of the message (if any)
private promptMessageExp =
/^\/\/ action:prompt_(?<type>[^\s]+) *(?:(?<quote>['"])(?<msg1>.*)\k<quote>|(?<msg2>.*))\s*$/
get events() {
return this.$store.state.server.events.slice(-100)
return this.$store.state.server.events
}
get macroPromptEvents() {
return this.events
.filter((event: ServerStateEvent) => event.type === 'action')
.filter((event: ServerStateEvent) => event.message.startsWith('// action:prompt_'))
.map((event: ServerStateEvent) => {
const type = (event.message ?? '').replace('// action:prompt_', '').split(' ')[0].trim()
const message = (event.message ?? '').replace(`// action:prompt_${type}`, '').replace(/"/g, '').trim()
const promptContent: ServerStateEventPrompt = {
date: event.date,
type,
message,
}
return promptContent
const events: ServerStateEvent[] = this.events
const promptEvents: ServerStateEventPrompt[] = []
// process events from most recent (end of array) to oldest (beginning of array) event until we reach
// the events we have already processed
for (let i = events.length - 1; i >= 0; i--) {
const event = events[i]
// if we've reached the checkpoint event (i.e. the point where we know there are no earlier prompts to process)
if (event === this.checkpointEvent) {
// break the loop
break
}
// not a prompt action, skip it
if (event.type !== 'action' || !event.message?.startsWith('// action:prompt_')) {
continue
}
const type = (event.message ?? '').replace('// action:prompt_', '').split(' ')[0].trim()
// stop processing and clear events once we find a end action
if (type === 'end') {
this.currentPrompt = []
break
}
console.log(event.message)
// extract our message from the action event
// supports no quote, double quote, and single quote wrapped messages
const { groups: { msg1, msg2, msg3 } = {} } = event.message.match(this.promptMessageExp) ?? {}
const message = (msg1 ?? msg2 ?? msg3 ?? '').trim()
// prepend the event to prompt events found in this chunk
promptEvents.unshift({
date: event.date,
type,
message,
})
// stop processing events once we find a begin action
if (type === 'begin') {
this.currentPrompt = []
break
}
}
// save our checkpoint event...we'll never have to look at messages prior to the checkpoint again
this.checkpointEvent = events[events.length - 1]
// if we found new prompt events in this chunk, let's append them
if (promptEvents.length > 0) {
this.currentPrompt = [...this.currentPrompt, ...promptEvents]
}
return this.currentPrompt
}
get lastPromptBeginPos() {
Expand Down

0 comments on commit 7019d50

Please sign in to comment.