Skip to content
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

migrate commands to command palette (Closes #389) #391

Merged
merged 29 commits into from
Apr 3, 2023

Conversation

mdroidian
Copy link
Collaborator

@mdroidian mdroidian commented Mar 23, 2023

Let me know if I'm on the right track 👍 @dvargas92495

components PR: RoamJS/roamjs-components#3

@mdroidian
Copy link
Collaborator Author

Also, the docs seem to strongly recommend against setting a default shortcut.
Do we still want to go ahead with that?

Copy link
Collaborator

@dvargas92495 dvargas92495 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also make sure the removeCommand is added in roamjs-components

src/features/tutorials.tsx Outdated Show resolved Hide resolved
@mdroidian
Copy link
Collaborator Author

Struggling with Typescript definition and console error with the decorators.tsx: d4d78f7

Typescript error:

Type '{ settings: 
{ get: (k: string) => unknown; getAll: () => Record<string, unknown>; 
panel: { create: (c: PanelConfig) => void; }; 
set: (k: string, v: unknown) => Promise<void>; }; 
ui: { commandPalette?: { ...; }; }; }' 
is not assignable to type 'never'.ts(2322)

Console error:

Uncaught TypeError: parseRoamMarked is not a function
    at callback (decorators.tsx:482:27)
    at callback (createHashtagObserver.js:12:13)
    at Array.forEach (<anonymous>)
    at createHTMLObserver (createHTMLObserver.js:8:27)
    at createHashtagObserver (createHashtagObserver.js:5:94)
    at toggleFeature (decorators.tsx:473:119)
    at onClick (decorators.tsx:335:7)
...

@@ -263,7 +264,7 @@ const settings = [
"Context Enabled",
"Hex Color Preview Enabled",
] as const;
const DecoratorSettings = ({ isOpen, onClose }: RoamOverlayProps) => {
const DecoratorSettings = ({ isOpen, onClose, extensionAPI }: RoamOverlayProps) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need to fix the type here: RoamOverlayProps<{ extensionAPI: OnloadArgs["extensionAPI"]}>

Copy link
Collaborator Author

@mdroidian mdroidian Mar 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went a different route and removed the addCommand from toggleFeature
It made more sense to me to not "turn on and off" the feature every decoration save.
It also removes the need for type updates. And this makes more sense to me as well, as extensionAPI shouldn't be required for Decorations
3eb2707#diff-ea4e85188fe94af5ae70fed25db2d64551b1b568075d213927ed8f69a97fb202

@mdroidian
Copy link
Collaborator Author

Console error:

Uncaught TypeError: parseRoamMarked is not a function
    at callback (decorators.tsx:482:27)
    at callback (createHashtagObserver.js:12:13)
    at Array.forEach (<anonymous>)
    at createHTMLObserver (createHTMLObserver.js:8:27)
    at createHashtagObserver (createHashtagObserver.js:5:94)
    at toggleFeature (decorators.tsx:473:119)
    at onClick (decorators.tsx:335:7)
...

Maybe this isn't actually from the code change. Looks like something similar exists in the current version.

helpers.ts:120 Uncaught TypeError: i is not a function
    at callback (6a693c5a-69ce-4ef4-842d-c096939dbf20:2:1646319)
    at callback (6a693c5a-69ce-4ef4-842d-c096939dbf20:2:1245300)
    at Array.forEach (<anonymous>)
    at t.default (6a693c5a-69ce-4ef4-842d-c096939dbf20:2:1244712)
    at t.Z (6a693c5a-69ce-4ef4-842d-c096939dbf20:2:1245189)
    at _n (6a693c5a-69ce-4ef4-842d-c096939dbf20:2:1646081)
    at onClick (6a693c5a-69ce-4ef4-842d-c096939dbf20:2:1644114)
...

Steps to replicate:

  1. Turn off all decorations
  2. Disable Workbench
  3. Reload Graph
  4. Enable Workbench
  5. Toggle all decorations. Save.

@dvargas92495
Copy link
Collaborator

Yea this looks like a current bug from when the context decorator is enabled - I'd try to ignore this for now as its a separate issue

@mdroidian
Copy link
Collaborator Author

for b21a052

Removed the toggle right/left sidebar, as those are built into Roam now.

Also, let me know how you feel about code formatting
image

I went with that because if felt more readable to me than the 200+ lines from the Prettier extension.

@mdroidian
Copy link
Collaborator Author

mdroidian commented Mar 30, 2023

Issues found with current jumpNav (Hot Keys)

  • X - Expand/Collapse block tree to a certain level, specified by the following numeric key press
    • number press adds number to block

And these appear to not work:

  • S - Add shortcut to page to left sidebar
  • z - Toggle Unlinked Refs
  • y - Toggle Queries
  • b - Jump to the bottom of page
    • jumps to top of page
  • q - Toggle View type
    • toggles to document, but not back to bullet

@mdroidian mdroidian changed the title migrate commands to command palette migrate commands to command palette (Closes #389) Mar 30, 2023
@mdroidian
Copy link
Collaborator Author

Well here's an unfortunate side effect of addCommand
When a command is invoke that uses the command palette sets focus of the block, then the cursor disappears.
Using a hot key, this problem does not occur.

Added timeout here: 4629860

But I feel it is bordering an unreasonable length of time.

@mdroidian mdroidian marked this pull request as ready for review March 30, 2023 02:49
@dvargas92495
Copy link
Collaborator

I went with that because if felt more readable to me than the 200+ lines from the Prettier extension.

The useful part of the prettier extension is the standardization, not necessarily the decisions it comes with by default. The problem with making exceptions is that someone else working on the team will eventually edit the file, hit save, then prettier will auto format.

If you disagree with prettier defaults, the scalable solution would be to change the prettier rules, so that it gets formatted automatically. If it's unable to be encoded, then the opinion is subjective, which means it will inevitably be overwritten by somebody else's subjective experience, and now time on the PR is being spent on code formatting instead of code content.

Added timeout here

Man the problem here is I think this API from Roam is actually not very reliable - ideally we don't need a setTimeout at all. This should be fine for now

Gonna start reviewing PR now

Copy link
Collaborator

@dvargas92495 dvargas92495 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My biggest question is why did we remove all of the hotkeys to the commands?

The goal of the task was to make all of the commands have configurable hotkeys, while still retaining the default value we had so that there's no interruption in functionality

});

return () => {
FEATURES.forEach(({ module }) => module.toggleFeature(false));
FEATURES.forEach(({ module }) => module.toggleFeature(false, extensionAPI));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One meta comment for future PRs - Big refactors like this are more digestable for reviewers as small as possible. This also helps on the engineering front as well.

I still struggle with this mightily (just look at some SamePage commits). But we should always ask ourselves: What is the smallest PR that we could submit that accomplishes our goal?

For example, PR 1 could have just been this file + 1 module. The rest of the modules will ignore the param and we would be able to iterate on convention before applying it to the rest of the modules

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, smaller PR's makes sense.

But at the same time, I was discovering it as I went. So I wouldn't have know that the first PR wouldn't have had to be overwritten / changed.

And when I think:

What is the smallest PR that we could submit that accomplishes our goal?

If the goal is to migrate all workbench commands to command palette, that first PR wouldn't have achieved that.

I guess I should have spent more time scoping the problem.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making a note to clarify more on Monday 👍

Comment on lines +265 to +270
addCommand(
{
label: "Create New Alert",
callback: createNewAlert,
},
extensionAPI
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to change for this PR, but a note for future reference.

In typescript, when there's more than one parameter I often prefer a single object instead of multiple params. So for example, I probably would have done:

addCommand(
        {
          label: "Create New Alert",
          callback: createNewAlert,
          extensionAPI
        },
)

The reason being is life becomes way easier for consumers:

  • Order of parameters no longer matters
  • We could freely make any of the parameters optional
  • Easier to refactor in the future: adding/removing parameters doesn't involve changing all consumers in most cases
  • Parameters are named, giving the consumer extra context on what the function expects

src/features/article.tsx Show resolved Hide resolved
src/features/dailyNotesPopup.tsx Show resolved Hide resolved
@@ -382,6 +370,7 @@ const endNavigate = () => {
if (document.body.classList.contains(NAVIGATE_CLASS)) {
document.body.classList.remove(NAVIGATE_CLASS);
}
window.removeEventListener("keydown", keyDownListener);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're using isNavigating to control whether we do deepnav stuff or not, so seems like we should be able to add/remove this event listener during just the toggleFeature method

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is additionally poor on my part because the listener is added on activeDeepNav() and toggleFeature()

So are you saying it is better to have an event listener always on vs only turning it on when needed?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more a comment that isNavigating is already doing this work. If we want to do the smart listener approach you suggest (this is probably better, but harder to get right), then we should prob get rid of isNavigating since it will add confusion

endNavigate();
document.getElementById(STYLE_ID)?.remove?.();
document.removeEventListener("keydown", keyDownListener, true);
window.removeEventListener("keydown", keyDownListener);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did we switch from document to window?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unintentional mistake.


export const removeCommand = (label: string, extensionAPI: OnloadArgs["extensionAPI"]) => {
extensionAPI.ui.commandPalette.removeCommand({label});
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With big files like this, one tactic I like to do is leave a comment like this:

This is the only substantive change to the file, the rest just add extensionAPI as an argument to addCommand. Any other differences I flag below

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't follow.
That would be a comment in the code or on the commit?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the commit to make it easier for reviewers looking over big files how to read it going in

src/features/jumpNav.tsx Outdated Show resolved Hide resolved
@mdroidian
Copy link
Collaborator Author

I went with that because if felt more readable to me than the 200+ lines from the Prettier extension.

The useful part of the prettier extension is the standardization, not necessarily the decisions it comes with by default. The problem with making exceptions is that someone else working on the team will eventually edit the file, hit save, then prettier will auto format.

If you disagree with prettier defaults, the scalable solution would be to change the prettier rules, so that it gets formatted automatically. If it's unable to be encoded, then the opinion is subjective, which means it will inevitably be overwritten by somebody else's subjective experience, and now time on the PR is being spent on code formatting instead of code content.

This makes sense, but if someone else were to contribute to this code, how would they be made aware of the prettier / format on save convention?

@mdroidian
Copy link
Collaborator Author

Speaking of which, I'm not using the "on save feature". Should I be?
I just an uneasy feeling when I go to edit a few lines by the commit shows quite a few more changes than I made.

@dvargas92495
Copy link
Collaborator

how would they be made aware of the prettier / format on save convention?

This is somewhat implicit by seeing prettier in a repo in the industry at this point. Sortof like if you see a testing library you can assume that the project is running tests in Github in some capacity and they should all be passing before merging

Speaking of which, I'm not using the "on save feature". Should I be?

I highly recommend it, it's life changing 👍

I just an uneasy feeling when I go to edit a few lines by the commit shows quite a few more changes than I made.

That's okay bc of two reasons:

  1. Prettier only does whitespace changes - it does not affect semantic reasoning
  2. Because of 1, you can review PRs by checking "hide whitespace changes" to ignore those changes when reviewing

@mdroidian
Copy link
Collaborator Author

mdroidian commented Apr 1, 2023

A few notes / questions on default hotkeys:

  1. DNP Jump Date Forward / Back conflict with the inbuild Roam Cycle Version

  2. alt-shift-p doesn't work for me (in Privacy Mode)

As a matter of fact, I can't set any hotkey using the UI to alt-shift-p.
I did check another program, however, and alt-shift-p worked, so it doesn't seem to be my system that is the issue.
Could you check if it works for you?

  1. How do you want to handle the default hotkeys for Hot Keys (jumpNav.tsx)?

The docs say

All the hot keys in this module are initiated with a modifier + j + another character. So Alt+j, Ctrl+j and CMD+j are all equivalent in this context. The final character, pressed in succession after modifier + j, is what determines the action taken.

I don't believe we can set more than one hotkey as a default.

  1. I believe the code in weekly-notes.ts actually allowed for both hotkeys because .isIOS is "true if client is iphone, ipad or ipod"

I coded it to stay in line with the docs

To jump to this week's page, hit Alt+w or Ctrl+Shift+W (Mac Only).

@dvargas92495
Copy link
Collaborator

DNP Jump Date Forward / Back conflict with the inbuild Roam Cycle Version

How do you want to handle the default hotkeys for Hot Keys (jumpNav.tsx)?

Ok so I'm going to double back and what I said before and make an exception for this and jumpnav. Let's remove the defaults, and be sure to make announcements in #roam-js and twitter, emphasizing that the reason why we removed the defaults here are so that users could configure them in Roam's hot key panel.

alt-shift-p doesn't work for me (in Privacy Mode)

Works for me - Sometimes chrome extensions could conflict with hot keys

@mdroidian
Copy link
Collaborator Author

It might be prudent to not merge this until the docs have been updated.
Also, I have another idea to toss your way on Monday that relates to this.

Works for me - Sometimes chrome extensions could conflict with hot keys

🤦‍♂️ That was it!

@dvargas92495 dvargas92495 merged commit dec57eb into RoamJS:main Apr 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants