Draft: POC of keyboard shortcut customization
What does this MR do?
A proof-of-concept MR that allows keyboard shortcuts to be customized or disabled as described in #251226.
For the sake of this proof-of-concept, only two shortcuts have been made customizable:
- Toggle performance bar (default: p b)
- Toggle markdown preview (default: ⌘+shift+p or ctrl+shift+p)
Screenshots
Here's how the keyboard shortcuts are customized in /profile/preferences
:
This is a temporary, ugly, proof-of-concept UI. A real UI will not make the user manually enter a JSON array of keyboard codes.
Usage
Multiple shortcuts can be assigned to a single command by providing an array with multiple values:
["shift+up", "shift+k"]
... or a command can be disabled by providing an empty arrray:
[]
Keyboard shortcut customizations don't take effect until the page is refreshed (or the user navigates to a different page).
What will the real UI look like?
See !43630 (closed) for an example of what a real UI might look like.
In phase 1, the UI won't allow users to customize keyboard shortcuts - only disable or enable individual shortcuts.
Under the hood, turning a shortcut off would customize the shortcut to []
, while turning a shortcut on would remove the customization.
In phase 2, users will be able to customize (and disable) individual keyboard shortcuts.
Questions to answer
-
Does it make sense to store shortcut customizations in the database (as shown in this MR) or should they be stored in
localStorage
?- I went with storing the customizations in the DB as part of this MR because this is personally what I would expect/want. @psimyn mentioned some reasons why we might instead consider
localStorage
here: #251226 (comment 415628416).- If we did want to instead store customizations in
localStorage
, it wouldn't fundamentally change this MR. It's just a matter of where the customization data is sourced from.
- If we did want to instead store customizations in
- I went with storing the customizations in the DB as part of this MR because this is personally what I would expect/want. @psimyn mentioned some reasons why we might instead consider
-
Assuming we store keyboard customizations in the database, does it make sense to store them as JSON (in a
text
field)?- Rationale for current approach: Rails never needs to interact with this data (it just stores it in the DB and sends it to the frontend). Storing as JSON allows new keyboard shortcuts to be added by frontend developers without new database migrations. Using a
text
field (instead ofjson
orjsonb
) prevents Rails from trying to unnecessarily serialize/deserialize the JSON string (although there might be a way to configure this when using ajson
orjsonb
column type).
- Rationale for current approach: Rails never needs to interact with this data (it just stores it in the DB and sends it to the frontend). Storing as JSON allows new keyboard shortcuts to be added by frontend developers without new database migrations. Using a
-
Does the current approach of submitting the keyboard shortcuts through a
<input type="hidden" />
as part of the Rails form make sense?- I think this makes sense, but just calling it out since I haven't seen this pattern used before in our codebase. The weird part is that the input's
name
has to match what Rails expects (so I'm sending thisname
to the frontend).
- I think this makes sense, but just calling it out since I haven't seen this pattern used before in our codebase. The weird part is that the input's
-
Does the current approach of only storing overrides in the database make sense?
- Rationale: Might as well store the smallest amount of data, especially since this will be sent on every page (through
window.gon.keyboard_shortcut_customizations
)
- Rationale: Might as well store the smallest amount of data, especially since this will be sent on every page (through
Answers
- For now, we will store keyboard shortcut customizations in
localStorage
to reduce the scope of this MR. Updating this feature to instead store customizations in the database should be relatively easy once everything is in place. - We can ignore this question for now, because
☝ - We can ignore this question for now, because we won't need to send anything to the backend (because
☝ ) - Yes, no issues with this approach at this point in time.