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

GitHub/Gist code fetching & automatic highlighting #252

Closed
wants to merge 37 commits into from

Conversation

iPwnPancakes
Copy link

@iPwnPancakes iPwnPancakes commented Oct 8, 2023

This PR closes #246

Notes:

  • Created a new route under /code
  • Added a new control component: GitHubRepositoryControl
  • The only allowed hosts are: raw.githubusercontent.com, gist.githubusercontent.com, and github.com
  • Code is only fetched if it passes frontend validation
  • Applies highlights based off of URL given, so links ending with #L12 or something will highlight line 12. Also supports ranges like #L1-L20

This might be overkill, but one immediate extension I could see being made to this is allowing code from sources like GitLab or something, but that's a problem for the future.

I did intend to implement some cypress tests, but I for the life of me could not figure out how to get an environment set up. I can figure it out, but I thought it would be nice to get some feedback while I figure it out.

@KevinBatdorf
Copy link
Owner

Nice! I'll take a look and try it out this week. I'll comment a few things that stand out now though in a quick review

Copy link
Owner

@KevinBatdorf KevinBatdorf left a comment

Choose a reason for hiding this comment

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

A bunch of notes but relatively little things. I could even do them all pretty quickly if you'd prefer. I appreciate the PR!

Also, make sure to add your name to the contributors list in the readme (if you'd like)

php/router.php Outdated Show resolved Hide resolved
php/routes.php Outdated Show resolved Hide resolved
php/routes.php Outdated Show resolved Hide resolved
php/routes.php Outdated Show resolved Hide resolved
php/routes.php Outdated Show resolved Hide resolved
src/editor/controls/GitHubRepositoryControl.tsx Outdated Show resolved Hide resolved
src/editor/controls/GitHubRepositoryControl.tsx Outdated Show resolved Hide resolved
src/editor/controls/Sidebar.tsx Outdated Show resolved Hide resolved
src/editor/controls/Sidebar.tsx Outdated Show resolved Hide resolved
Comment on lines 406 to 410
setAttributes({
code,
enableHighlighting: Boolean(lineNumbers),
lineHighlights: Boolean(lineNumbers) ? `[${lineNumbers.startLine},${lineNumbers.endLine}]` : '',
});
Copy link
Owner

Choose a reason for hiding this comment

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

I believe this should only be updating the code right?

Copy link
Author

Choose a reason for hiding this comment

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

So those other lines are there to allow users to be able to preserve highlighted lines from GitHub links. Would you like me to remove that capability from this PR?

Copy link
Owner

Choose a reason for hiding this comment

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

Oh I didn't realize that. That's interesting. I like the idea actually.

I think that makes sense for the first time it fetches, but not for syncing long term though

Could it work like this?

  1. User pastes the link
  2. We fetch the code
  3. Parse it to get line numbers
  4. Remove the line numbers from the URL
  5. Add line number highlights and URL (which no longer includes line numbers reference)
  6. Then when syncing next time, next week, etc we just sync the code with no line numbers

So we just have it as is, but we dont persist the url with the line numbers. that way it only ever adds the highlights once. I'm just thinking about users that want to sync with a gist they edit, and the line numbers might now always be the same. i'd hate for them to need to add the URL.

Alternatively we could add a checkbox like "preserve line highlights" or something.

What do you think?

Comment on lines 34 to 38
if (isValidUrl(value)) {
inputRef.current?.classList.remove('cbp-input-error');
} else {
inputRef.current?.classList.add('cbp-input-error');
}
Copy link
Owner

Choose a reason for hiding this comment

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

Should use a react approach here and either just add a ternary on the component, or use the classnames package.

Copy link
Author

Choose a reason for hiding this comment

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

So unfortunately you can't really set the className on the TextComponent and have it apply the styles to the input by itself (maybe I need to submit a PR for that too lol)
image

I went ahead and changed it to a ternary within a useEffect. Would you like me to still use the classnames package?

Copy link
Owner

Choose a reason for hiding this comment

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

Maybe just make the text red? You could use a

tag directly instead of the help prop. Might need to add something like m-0 p-0 -mt-1 also if it's too low.

The issue with directly manipulating the dom is that react doesn't track those changes so it could bug out when doing a diff (if not today because conditions are right, maybe in 2 years something changes).

Also, for the text, I was thinking about this a bit more. What do you think about:

  1. The main panel is labelled "Sync" instead of "GitHub"
  2. The inner control title is "GitHub" instead of "Github Repo Link"
  3. The help text is "Supports GitHub file links and Gists"
  4. The button says "Save" instead of "Fetch Code" and I guess behaves the same

I also think maybe adding the highlights makes it a bit confusing. If the goal is to keep a file in sync (in case they change the Gist, for example) it would update and put any highlights out of place. It might even be worth disabling those features entirely (even disabling editing too actually). What do you think?

  1. ignore any line highlisghts entirely (so no need to parse the url at all)
  2. At the top of the panel add a short note on the expectations, that this will override any code edits and forcefully sync the file each page load.

Thanks again, and hope this isn't asking too much. It's great so far :P I'm happy to work on it too though.

Copy link
Author

Choose a reason for hiding this comment

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

and hope this isn't asking too much

Not at all! In fact I really appreciate all the time you're taking to instruct me about your preferences! I'm learning quite a bit, of course I want to be respectful of your time too so if you want to take ownership of something to push things along feel free! This is your repository after all 👍

I also think maybe adding the highlights makes it a bit confusing. If the goal is to keep a file in sync (in case they change the Gist, for example) it would update and put any highlights out of place.

Yknow, while working on the other code change around highlights, I'm realizing now that this is really prone to accidental overwrites. If I put myself in the place of the writer/user, I really want things to stay "deterministic". I don't want simply typing into the GitHub textbox to overwrite my changes, I would probably much prefer to only overwrite my code when I click the "Save" button.
Same thing with code highlighting, because now there would be 2 places where highlighting could change.

I would have to agree with the option with removing the features! Apologies for the complications 😅

Copy link
Author

Choose a reason for hiding this comment

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

Hmm, I am having trouble trying to only set the code when the user clicks the "Save" button though. Since I am using the hook at the top of my component it keeps fetching/setting the remote code.

Copy link
Owner

Choose a reason for hiding this comment

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

I would probably much prefer to only overwrite my code when I click the "Save" button.

So the question is actually what is the feature, or what problem is this feature solving? I believe we're seeing it a bit differently so let me write out summaries of both and get your opinoin.

  1. It's solving the problem of importing code into the page. So instead of copy/pasting the code into the editor, we are giving them a text input and a button to copy/paste the url and fetch it for them. Additionally, they can go and refetch if they press the button again later (e.g. in 6 months). To me this implies the source file will not be changing that often, so the feature would be "to help users import the code"
  2. It's solving a problem for users that manage an actively changing gist or file in a repo that they want to keep in sync without much effort. In my head I pictured having 5-6 on a page and they all just sync when the user goes to edit the page (caveat being it requires they edit the page for it to re-sync). So the feature in this case is "to help auto sync with code that is managed elsewhere"

My descriptions may be biased too, but even writing them out it's not super clear that this will be that useful of a feature if it can't auto-sync behind the scenes (like once an hour or something) even when the user is not editing the page. I also hesitate to give a feature that implies it does something it doesn't, if you know what I mean.

If the idea is to provide easy imports (which I'm not against either), I'd almost rather it incorporate the github oath flow and use the GH api to load in recent gists/repos in the sidebar similar to how selecting a theme works (code previews load in and they can press to import).

Since I am using the hook at the top of my component it keeps fetching/setting the remote code.

I can check the code but typically you would use a useEffect and then update the code when the data changes, and you wouldn't fetch the data until a URL existed. So you'd need an intermediary state variable to handle the form input that didnt't feed into swr

@iPwnPancakes
Copy link
Author

I made it so that the line highlighting is only set if it was not set previously. Lemme know what you think 👍

@KevinBatdorf
Copy link
Owner

That sounds right. I'll probably have some time tonight or tomorrow to look at the code again. Been a busy week

@iPwnPancakes
Copy link
Author

I'll write up a response to your previous comment tonight, but I did want to put out there that I would be very open to pairing on this together. That way we could get in sync pretty quickly in the event my response is confusing or if clarification is needed 👍 If you don't think it's necessary that's fine as well

@KevinBatdorf
Copy link
Owner

KevinBatdorf commented Oct 19, 2023

Another idea I was thinking is that we could make the plugin "pluggable" and this sort of feature could be another plugin add-on, like "Code Block Pro - Import From GitHub" and if you want I could help you get it published to w.org as a plugin you manage and of course have creative control over.

Edit: If we land on this idea i'd happy link to it in the readme as well

@iPwnPancakes
Copy link
Author

Ohhhhh I think that idea would work quite well actually!

After some cursory searching, it seems as though Gutenberg is set up quite well for this kind of thing via their category property when using registerBlockType. Maybe we could have two categories, maybe something like the base sidebar options being under a core category and the CBP plugin blocks being under their own category

@KevinBatdorf
Copy link
Owner

Well actually I think it would involve just adding a <Slot> (related docs) that anyone could register another panel in the sidebar, that would give you access to attributes and setAttributes (could also pass in the list of themes/langs too) and you'd be able to use any wp components, etc.

Then you'd use registerPlugin to add something that hooks into that slot. It should work pretty well actually. I'll open a PR with a full example tomorrow. And an example plugin as well.

@KevinBatdorf
Copy link
Owner

I have a PR with the slotfills and wrote up some instructions on adding a plugin if you're interested in this route.

#254

https://gist.github.com/KevinBatdorf/de687d5e620dfe2af7645b35b917cd87

You can actually filter attributes too (to add a url attribute - but you might want to namespace it like mypluginname-url), but it's a bit more complicated. You can see how I did it in another plugin: https://github.com/KevinBatdorf/pattern-css/blob/main/src/index.tsx#L31

@KevinBatdorf
Copy link
Owner

Any thoughts on this? I understand if you don't want to take that approach. Should I close this for now? Can revisit it another time if you'd like.

@iPwnPancakes
Copy link
Author

Any thoughts on this? I understand if you don't want to take that approach. Should I close this for now? Can revisit it another time if you'd like.

That approach is perfect actually! Allows us to develop our respective changes independently! Now, the commit history on this thing is probably killer hahaha. I propose we close this PR and I'll ping you once I develop the GitHub plugin 👍

Apologies for the long break, I took a vacation so I wasn't paying attention to my emails or anything 😅 Then I caught COVID. Feeling a lot better now

@KevinBatdorf
Copy link
Owner

Ahh that's no good. Worst way to end a holiday 😩 I'm traveling next week actually and worried about that too. Probably I need to be extra careful. Glad you're doing better now though.

Ok I'll close this and yeah just keep in touch about any updates.

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.

[Feature Request] Ability to link code from GitHub repositories & gists
2 participants