[GH-ISSUE #17] UX bugs #4

Closed
opened 2026-10-15 18:07:44 +00:00 by bsakaguchi · 8 comments
Owner

Originally created by @Technologicat on GitHub (Jan 26, 2024).
Original GitHub issue: https://github.com/SillyTavern/SillyTavern-Timelines/issues/17

From quickly trying out Timelines for a small creative writing test, the UX has some rough edges:

  • Checkpoint proliferation (serious issue):
    • Once you have created a checkpoint, it persists forever in the timeline view.
    • Renaming a checkpoint (by creating another checkpoint at the same chat message where one already exists, and confirming the link overwrite) retains both the new and old checkpoints on the timeline.
    • Deleting the chat file of a checkpoint (in Manage chat files) doesn't delete the checkpoint from the timeline. The ghost checkpoint persists forever, even after restarting ST.
      • In the timeline legend, the ghost checkpoint comes from the leftover bookmark_link in existing chat files that points to the deleted file. If you manually edit that out, the ghost checkpoint disappears from the legend.
      • In the list of buttons (when you have a node open in the timeline view), where does the ghost checkpoint come from? Call sequence in a 1-on-1 chat:
        • onTimelineButtonClick in SillyTavern/public/scripts/extensions/third-party/SillyTavern-Timelines/index.js
        • updateTimelineDataIfNeeded in SillyTavern/public/scripts/extensions/third-party/SillyTavern-Timelines/index.js
        • fetchData in SillyTavern/public/scripts/extensions/third-party/SillyTavern-Timelines/tl_node_data.js
        • API endpoint /api/characters/chats -> the returned filenames include deleted chat files
          • Nevermind, the API endpoint works correctly. No idea what happened here. This part works, as one would expect. The /chats endpoint handler in SillyTavern/src/endpoints/characters.js gets its list of chat files directly by scanning the folder on the disk. Not much can go wrong there.
          • What might have happened:
            • Edited out the bookmark_link, but forgot to delete the chat file -> "ghost checkpoint" in the jump buttons in a graph node (because the chat file still exists), although no longer listed in the legend
            • Then deleted the file too, but the reload button added while working on #16 was initially faulty:
              • Delete a chat file in Manage chat files
              • Open the timeline view (without refreshing the graph)
              • Attempt to jump to the chat file you just deleted (still exists as a ghost in the graph if not refreshed)
              • A new chat opens, because the requested chat file no longer exists.
    • Workaround: for now, if you intend to use Timelines, use branches (i.e. unnamed checkpoints) instead of named checkpoints? Timelines has a fulltext search so unnamed multiverse branches are not much of an issue.
    • Possible simple fix: when Timelines gathers information about checkpoints and finds a bookmark_link, it could also check that the linked chat file exists in the set of all chats (that the graph is built out of). Then dead links wouldn't matter. I'll try this approach. EDIT: Yep, pruning dead links when constructing the timeline graph solves this. Fix stashed for the next PR.
  • GUI navigation (minor issues):
    • Would be useful to automatically focus and zoom to the clicked checkpoint in the legend. Done, stashed for next PR.
    • Same for a text search result, if unique. Done, zooms to show all matches. This too stashed for next PR.
    • Also, when opening the timeline view, would be nice to focus and zoom the graph to the current chat.
      • Need to get that data from the context.
      • Then this also needs a button to fit the view to the whole graph.
      • EDIT: I have zoom-to-current-chat and zoom-to-fit stashed for the next PR now.
    • Placement of the panel when you click on a node.
      • Currently it either hinders navigation (if Fixed tooltip mode off), or requires glancing back and forth (if Fixed tooltip mode on).
    • When the timeline view is opened, if there is a previous fulltext search term, it remains in the search field but the search is not applied. The search should be applied (and perhaps the content of the field selected, so that starting to type would replace the current search term). Added to #16.
    • Hotkeys:
      • In case of several search results, pressing Tab to choose and Enter to zoom in would be useful for quick navigation.
      • Esc to close the timeline view would be nice, as some other views already have it.
        • But where to inject the handler? We shouldn't touch the Esc catcher in RossAscends-mods.js, since this is a third-party extension.

I'll see if I have the time to do something to these - as usual, no promises except of the async/await kind.

EDIT: My mistake. The API endpoint gets the correct file list.

Originally created by @Technologicat on GitHub (Jan 26, 2024). Original GitHub issue: https://github.com/SillyTavern/SillyTavern-Timelines/issues/17 From quickly trying out *Timelines* for a small creative writing test, the UX has some rough edges: - **Checkpoint proliferation** (serious issue): - Once you have created a checkpoint, it persists **forever** in the timeline view. - Renaming a checkpoint (by creating another checkpoint at the same chat message where one already exists, and confirming the link overwrite) retains both the new and old checkpoints on the timeline. - Deleting the chat file of a checkpoint (in *Manage chat files*) doesn't delete the checkpoint from the timeline. The ghost checkpoint persists forever, even after restarting ST. - In the timeline legend, the ghost checkpoint comes from the leftover `bookmark_link` in existing chat files that points to the deleted file. If you manually edit that out, the ghost checkpoint disappears from the legend. - In the list of buttons (when you have a node open in the timeline view), where does the ghost checkpoint come from? Call sequence in a 1-on-1 chat: - `onTimelineButtonClick` in `SillyTavern/public/scripts/extensions/third-party/SillyTavern-Timelines/index.js` - `updateTimelineDataIfNeeded` in `SillyTavern/public/scripts/extensions/third-party/SillyTavern-Timelines/index.js` - `fetchData` in `SillyTavern/public/scripts/extensions/third-party/SillyTavern-Timelines/tl_node_data.js` - API endpoint `/api/characters/chats` ~-> the returned filenames include deleted chat files~ - Nevermind, the API endpoint works correctly. No idea what happened here. This part works, as one would expect. The `/chats` endpoint handler in `SillyTavern/src/endpoints/characters.js` gets its list of chat files directly by scanning the folder on the disk. Not much can go wrong there. - What might have happened: - Edited out the `bookmark_link`, but forgot to delete the chat file -> "ghost checkpoint" in the jump buttons in a graph node (because the chat file still exists), although no longer listed in the legend - Then deleted the file too, but the reload button added while working on #16 was initially faulty: - Delete a chat file in *Manage chat files* - Open the timeline view (without refreshing the graph) - Attempt to jump to the chat file you just deleted (still exists as a ghost in the graph if not refreshed) - A new chat opens, because the requested chat file no longer exists. - Workaround: for now, if you intend to use *Timelines*, use branches (i.e. unnamed checkpoints) instead of named checkpoints? *Timelines* has a fulltext search so unnamed multiverse branches are not much of an issue. - ~Possible simple fix: when *Timelines* gathers information about checkpoints and finds a `bookmark_link`, it could also check that the linked chat file exists in the set of all chats (that the graph is built out of). Then dead links wouldn't matter. I'll try this approach.~ **EDIT**: Yep, pruning dead links when constructing the timeline graph solves this. Fix stashed for the next PR. - **GUI navigation** (minor issues): - ~Would be useful to automatically focus and zoom to the clicked checkpoint in the legend.~ Done, stashed for next PR. - ~Same for a text search result, if unique.~ Done, zooms to show all matches. This too stashed for next PR. - ~Also, when opening the timeline view, would be nice to focus and zoom the graph to the current chat.~ - ~Need to get that data from the context.~ - ~Then this also needs a button to fit the view to the whole graph.~ - **EDIT**: I have zoom-to-current-chat and zoom-to-fit stashed for the next PR now. - Placement of the panel when you click on a node. - Currently it either hinders navigation (if *Fixed tooltip* mode off), or requires glancing back and forth (if *Fixed tooltip* mode on). - ~When the timeline view is opened, if there is a previous fulltext search term, it remains in the search field but the search is not applied. The search should be applied (and perhaps the content of the field selected, so that starting to type would replace the current search term).~ Added to #16. - Hotkeys: - In case of several search results, pressing Tab to choose and Enter to zoom in would be useful for quick navigation. - Esc to close the timeline view would be nice, as some other views already have it. - But where to inject the handler? We shouldn't touch the Esc catcher in `RossAscends-mods.js`, since this is a third-party extension. I'll see if I have the time to do something to these - as usual, no promises except of the async/await kind. **EDIT**: *My mistake. The API endpoint gets the correct file list.*
Author
Owner

@Technologicat commented on GitHub (Jan 27, 2024):

Talking to myself here...

  • Creating a checkpoint spawns a new chat file, and uses the checkpoint name as part of its filename (beside the timestamp)
  • It also tags (bookmark_link) the relevant message in the originating chat file as having spawned that checkpoint
  • Timelines tracks the bookmark_link field to identify checkpoints

Therefore:

  • If you overwrite a checkpoint (re-checkpoint a message that already has a linked checkpoint a.k.a. bookmark_link), this spawns another new chat file, and overwrites the bookmark_link field in the originating chat file. But the previous spawned chat file still also exists; the originating chat file just no longer links to it.
  • If you delete a spawned chat file, the bookmark_link in the original chat file remains.
  • And as the user manual warns you, if you rename a chat file, that will break bookmark links pointing to it. Now it makes sense why.

Will need to think about what this all means for Timelines when less tired.

<!-- gh-comment-id:1912862741 --> @Technologicat commented on GitHub (Jan 27, 2024): Talking to myself here... - Creating a checkpoint spawns a new chat file, and uses the checkpoint name as part of its filename (beside the timestamp) - It also tags (`bookmark_link`) the relevant message in the *originating* chat file as having spawned that checkpoint - *Timelines* tracks the `bookmark_link` field to identify checkpoints Therefore: - If you overwrite a checkpoint (re-checkpoint a message that already has a linked checkpoint a.k.a. `bookmark_link`), this spawns another new chat file, and overwrites the `bookmark_link` field in the originating chat file. But the previous spawned chat file still also exists; the originating chat file just no longer links to it. - If you delete a spawned chat file, the `bookmark_link` in the original chat file remains. - And [as the user manual warns you](https://docs.sillytavern.app/usage/core-concepts/chatfilemanagement/#chat-import), if you rename a chat file, that will break bookmark links pointing to it. Now it makes sense why. Will need to think about what this all means for *Timelines* when less tired.
Author
Owner

@Technologicat commented on GitHub (Jan 29, 2024):

I have this pretty much working, now pending on #16.

@Cohee1207: What's the preferred way to handle hotkeys in third-party extensions? I'd like Esc to close the timeline view, like in many built-in views, but I suppose modding the Esc catcher in RossAscends-mods.js is not the way to do it. :)

<!-- gh-comment-id:1914912084 --> @Technologicat commented on GitHub (Jan 29, 2024): I have this pretty much working, now pending on #16. @Cohee1207: What's the preferred way to handle hotkeys in third-party extensions? I'd like `Esc` to close the timeline view, like in many built-in views, but I suppose modding the Esc catcher in `RossAscends-mods.js` is not the way to do it. :)
Author
Owner

@Cohee1207 commented on GitHub (Jan 29, 2024):

Possibly stopPropagation is your bro here if you want to cancel out the default top-level handler of Esc key.

<!-- gh-comment-id:1914938954 --> @Cohee1207 commented on GitHub (Jan 29, 2024): Possibly `stopPropagation` is your bro here if you want to cancel out the default top-level handler of Esc key.
Author
Owner

@Technologicat commented on GitHub (Jan 29, 2024):

Upcoming PR posted as #18.

Changelog moved there.

<!-- gh-comment-id:1914950167 --> @Technologicat commented on GitHub (Jan 29, 2024): Upcoming PR posted as #18. *Changelog moved there.*
Author
Owner

@Technologicat commented on GitHub (Jan 29, 2024):

Possibly stopPropagation is your bro here if you want to cancel out the default top-level handler of Esc key.

I have no problem with the top-level handler, except it's not closing the timeline view. :)

I noticed that the new Token probabilities feature added a case to RossAscends-mods.js, but that's a core feature, not a third-party plugin. Hence, I was thinking that I probably need to wire in a custom handler when the plugin initializes...

<!-- gh-comment-id:1914953693 --> @Technologicat commented on GitHub (Jan 29, 2024): > Possibly `stopPropagation` is your bro here if you want to cancel out the default top-level handler of Esc key. I have no problem with the top-level handler, except it's not closing the timeline view. :) I noticed that the new *Token probabilities* feature added a case to `RossAscends-mods.js`, but that's a core feature, not a third-party plugin. Hence, I was thinking that I probably need to wire in a custom handler when the plugin initializes...
Author
Owner

@Cohee1207 commented on GitHub (Jan 29, 2024):

Yes, a custom handler with stopPropagation cancels the event bubbling to the top-level handler if it was used to close a Timelines view.

<!-- gh-comment-id:1915100450 --> @Cohee1207 commented on GitHub (Jan 29, 2024): Yes, a custom handler with stopPropagation cancels the event bubbling to the top-level handler if it was used to close a Timelines view.
Author
Owner

@Technologicat commented on GitHub (Jan 29, 2024):

Yes, a custom handler with stopPropagation cancels the event bubbling to the top-level handler if it was used to close a Timelines view.

I missed the obvious implication, as usual. Thanks for the clarification. :)

<!-- gh-comment-id:1915620024 --> @Technologicat commented on GitHub (Jan 29, 2024): > Yes, a custom handler with stopPropagation cancels the event bubbling to the top-level handler if it was used to close a Timelines view. I missed the obvious implication, as usual. Thanks for the clarification. :)
Author
Owner

@Technologicat commented on GitHub (Feb 6, 2024):

Resolved by #18.

<!-- gh-comment-id:1930895438 --> @Technologicat commented on GitHub (Feb 6, 2024): Resolved by #18.
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
SillyTavern/SillyTavern-Timelines#4
No description provided.