-
Notifications
You must be signed in to change notification settings - Fork 5
New Feature: GitHub Sync #253
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
Conversation
Panel: SelectPanel, | ||
title: "Node Select", | ||
description: "Select a node to pull comments from", | ||
options: { | ||
items: [ | ||
"None", | ||
...getDiscourseNodes() | ||
.map((node) => node.text) | ||
.filter((text) => text !== "Block"), | ||
], | ||
}, | ||
defaultValue: "None", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe this should create be a CustomPanel and create a block on select/enter so the user can have multiple defined?
src/components/GitHubSync.tsx
Outdated
return () => { | ||
headerCommentObserver.forEach((o) => o.disconnect()); | ||
childCommentObserver.forEach((o) => o.disconnect()); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adding a console.log here didn't fire. not sure why or if that means these observers aren't being cleaned up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea this all doens't look right, this component is not mounting at all. I would replace the
ReactDOM.render(
<GitHubSyncPage
commentsContainerUid={commentsContainerUid}
extensionAPI={extensionAPI}
/>,
containerDiv
);
from above with just the contents of this useEffect
. Actually the "observing" is happening by the time we get to renderGitHubSyncPage
so I wouldn't even initiate new observers for both. I would render CommentsContainerComponent
directly there, and have a separate root observer for CommentsComponent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few problems I'm running into trying to implement this:
Observers Required
Both observers are required to re-render the buttons when a user clicks into a block.
If we just render CommentsContainerComponent
and remove the observer that renders it, if a user clicks into the block the buttons will be gone until the page reloads. Maybe a necessary trade-off? But I'd like to avoid that for the UX.
RE: Root Observer
The CommentsComponent
renders to children of the CommentsContainer
. To know if it's a child we need the CommentsContainer
el
or uid
which we get from a user defined query on page load. We wouldn't have that at root.
I guess we could add an attribute on block creation/page load, but we'd run into the re-render issue still (a user clicks into the block, buttons are gone until page is reloaded).
Or maybe we keep a running global cache of comment uids for the current page that clears on page unload ... we have to handle the sidebar windows too ... hmmm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a cache implementation: github-sync...github-sync-comment-uid-cache
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merged into this branch: #254
This is so cool!! I wanna give this one a thoughtful review, so making a note to revisit on Saturday |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Lots of feedback, nothing necessarily blocking.
One approach I like doing with big meaty PRs is keep the meaty one in draft, then split out reviewable chunks, rebasing the master along the way. It's a ton more work, but this helps reviewers give more thoughtful reviews on incremental pieces and I've often found ways to make things better by forcing myself to chunk down.
|
||
## Config Page | ||
|
||
This will be found at `[[roam/js/github-sync]]` in your graph. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First thing that stood out to me in the video - thoughts on this living within the existing node config pages instead of introducing a new page? Couple of motivations behind this:
- Reducing the amount of config locations the user needs to traverse too
- If we keep things defined at the node level, it will make it easier to one day port as it will be a property of a SamePage native data model (the Discourse Node, or Node) rather than something specific to Roam <> Github
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially this felt far enough away from Discourse Graph to be on it's own. Then I ended up hooking into Discourse Nodes for their definition 😅. But I could see users want to use only this feature and none of the other dgraph features ... then it would be kind of buried / confusing.
src/components/GitHubSync.tsx
Outdated
}, | ||
{ | ||
// @ts-ignore | ||
Panel: TextPanel, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's make this a SelectPanel where the options are all of the query blocks in the graph
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, instead of "Add some query block in your graph", I think I'd prefer an inline instance to define here. That "some query in your graph" won't be used for anything else
src/components/ExportGithub.tsx
Outdated
const initialRepos: UserRepos = [{ name: "", full_name: "" }]; | ||
export type UserRepos = UserReposResponse["data"]; | ||
export const initialRepos: UserRepos = [{ name: "", full_name: "" }]; | ||
export type GitHubDestination = "Issue" | "File"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[q] Why is this an option? I'd assume we'd only want to sync with issues?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignore, I see the use case now. To keep in sync with the array below you could instead do:
const GITHUB_DESTINATIONS = ["Issue", "File"] as const;
export type GitHubDestination = (typeof GITHUB_DESTINATIONS)[number];
makes it so that adding new options is only write-once instead of write-twice
/> | ||
<Button | ||
icon="import" | ||
title="Check for New Comments" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] We should either button text this like Add Comment
or have both put the title in tooltips
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intuition pushes back on this.
Adding comments is likely to happen far more often than downloading. Check for comments
or even just Download
places it in equal weights with Add Comment
and it also felt like it took up too much space when I tried it.
Similarly, having them both just icons downplays Add Comments
too much. If both are just icons, making Add Comments
intent Primary
might solve this, but most of the time a user is on the page they actually won't be adding comments, so it is likely too much of a distraction.
Finally, I see a future state where we query for new comments in the background and update the button to call attention to it only when there are new comments to be imported.
.map((r: any) => { | ||
const node = r[0]; | ||
return { | ||
id: node.props["github-sync"]["comment"]["id"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! was going to suggest maintaining some metadata like this
}, | ||
data: { | ||
title, | ||
body, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[oos] There will be formatting differences, like Roam bolding -> Github bolding.
This is where proxying through SamePage I think could be helpful, since we are defining the AtJson standard there to be interoperable across all text editors
}, | ||
}); | ||
const installations = res.installations; | ||
const APP_ID = isDev ? 882491 : 312167; // TODO - pull from process.env.GITHUB_APP_ID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[oos] yes please
src/components/Export.tsx
Outdated
gitHubAccessToken={gitHubAccessToken} | ||
setGitHubAccessToken={setGitHubAccessToken} | ||
setCanSendToGitHub={setCanSendToGitHub} | ||
githubDestination={githubDestination} | ||
setGithubDestination={setGithubDestination} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] in general, use case specific state/props and callbacks should be defined within use case specific components. is there a way we could push all of this state within the component instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could store these in localStorage
and do a check onClick
for these values. But if we do that for setCanSendToGitHub
we would lose the state dependent UI of a disabled Export
button.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renderPlayground(title, globalRefs); | ||
} else if (isCanvasPage(title) && !!h1.closest(".roam-article")) { | ||
renderTldrawCanvas(title, onloadArgs); | ||
} else if (isGitHubSyncPage(title)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] observer callbacks fire alot and roam queries within it could really slow down a graph. I would try to figure out a way to avoid doing roam queries within this method.
One way to do so is to maintain a cache of valid uids, and whenever you leave the github sync config page, that cache is updated. Then this method is only doing a lookup on the cache
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was definitely nervous about this. But unsure of a good solution.
I would expect that a user would visit the config page once then probably never again for a very long time. How would the cache be updated then?
Specifically, how would a page that is created via default Roam methods ([[
, search bar, or renaming a page, for example) be added to the cache? If it's on a timer, would the UI just not show up until that timer goes off or the user triggers a refresh?
src/components/GitHubSync.tsx
Outdated
return () => { | ||
headerCommentObserver.forEach((o) => o.disconnect()); | ||
childCommentObserver.forEach((o) => o.disconnect()); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea this all doens't look right, this component is not mounting at all. I would replace the
ReactDOM.render(
<GitHubSyncPage
commentsContainerUid={commentsContainerUid}
extensionAPI={extensionAPI}
/>,
containerDiv
);
from above with just the contents of this useEffect
. Actually the "observing" is happening by the time we get to renderGitHubSyncPage
so I wouldn't even initiate new observers for both. I would render CommentsContainerComponent
directly there, and have a separate root observer for CommentsComponent
Sent to client for review. |
Thank you for developing this function. It is amazing and very useful! Will we have it in the next official release? |
Thank you for the message @Qiwei-Zhao This is not yet ready for release. Some bugs to work out and changes to be added. |
Moved to DiscourseGraphs/discourse-graph#120 |
https://www.loom.com/share/0f3a0e72bc424d2f99783ab33a73f5fc