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

feat: chat dialog for talking to repos #226

Merged
merged 17 commits into from
Aug 10, 2023
1,291 changes: 1,214 additions & 77 deletions npm-shrinkwrap.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
"react-dom": "^18.0.0",
"react-hot-toast": "^2.4.1",
"react-icons": "^4.8.0",
"react-markdown": "^8.0.7",
"react-syntax-highlighter": "^15.5.0",
"swiper": "^9.4.0"
},
"devDependencies": {
Expand All @@ -32,6 +34,7 @@
"@types/node-emoji": "^1.8.2",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/react-syntax-highlighter": "^15.5.7",
"@typescript-eslint/eslint-plugin": "^5.59.1",
"@vitejs/plugin-react": "^1.3.0",
"@vitest/coverage-c8": "^0.31.1",
Expand Down
10 changes: 10 additions & 0 deletions src/assets/open-sauced-orange-bg-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// OpenSauced constants
export const OPEN_SAUCED_INSIGHTS_DOMAIN = import.meta.env.VITE_OPEN_SAUCED_INSIGHTS_DOMAIN;
export const OPEN_SAUCED_API_ENDPOINT = import.meta.env.VITE_OPEN_SAUCED_API_ENDPOINT;
export const REPO_QUERY_API_ENDPOINT = "https://opensauced.tools";
export const SUPABASE_LOGIN_URL = `https://${import.meta.env.VITE_OPEN_SAUCED_SUPABASE_ID}.supabase.co/auth/v1/authorize?provider=github&redirect_to=https://${OPEN_SAUCED_INSIGHTS_DOMAIN}/`;


export const REPO_QUERY_EMBED_ENDPOINT = `${REPO_QUERY_API_ENDPOINT}/embed`;
export const REPO_QUERY_QUERY_ENDPOINT = `${REPO_QUERY_API_ENDPOINT}/query`;
export const REPO_QUERY_COLLECTION_ENDPOINT = `${REPO_QUERY_API_ENDPOINT}/collection`;

export const SUPABASE_AUTH_COOKIE_NAME = `sb-${import.meta.env.VITE_OPEN_SAUCED_SUPABASE_ID}-auth-token`;
export const OPEN_SAUCED_AUTH_TOKEN_KEY = "os-access-token";
export const OPEN_SAUCED_OPTED_LOG_OUT_KEY = "opted-log-out";
Expand Down
27 changes: 27 additions & 0 deletions src/content-scripts/components/RepoQuery/RepoQuery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import ReactDOM from "react-dom/client";
import { RepoQuery } from "../../../repo-query/pages/main";
import { createHtmlElement } from "../../../utils/createHtmlElement";

export const RepoQueryRoot = (ownerName: string, repoName: string) => {
const repoQueryRoot = createHtmlElement("div", {
id: "repo-query-root",
innerHTML: `
<div>
</div>
`,
});
diivi marked this conversation as resolved.
Show resolved Hide resolved

ReactDOM.createRoot(repoQueryRoot).render(
<React.StrictMode>
<RepoQuery
ownerName={ownerName}
repoName={repoName}
/>
</React.StrictMode>,
);


return repoQueryRoot;
};

14 changes: 14 additions & 0 deletions src/content-scripts/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
getGithubUsername,
isGithubProfilePage,
isGithubPullRequestPage,
isGithubRepoPage,
isPullRequestCreatePage,
isPullRequestFilesChangedPage,
} from "../utils/urlMatchers";
Expand All @@ -16,6 +17,8 @@ import domUpdateWatch from "../utils/dom-utils/domUpdateWatcher";
import injectDescriptionGeneratorButton from "../utils/dom-utils/addDescriptionGenerator";
import injectChangeSuggestorButton from "../utils/dom-utils/changeSuggestorButton";
import prEditWatch, { prReviewWatch } from "../utils/dom-utils/prWatcher";
import injectChatDialog from "../utils/dom-utils/addChatDialog";
import { pageUrlWatch } from "../utils/dom-utils/pageUrlWatcher";

const processGithubPage = async () => {
if (prefersDarkMode(document.cookie)) {
Expand All @@ -39,6 +42,17 @@ const processGithubPage = async () => {
} else {
injectInviteToOpenSauced(username);
}
} else if (isGithubRepoPage(window.location.href)) {
const ownerName = getGithubUsername(window.location.href) ?? "";
const repoName = window.location.href.split("/").pop() ?? "";

await injectChatDialog(ownerName, repoName);

pageUrlWatch(() => {
if (document.getElementById("repo-query-root")) {
document.getElementById("repo-query-root")?.remove();
}
}, 50);
}

/*
Expand Down
23 changes: 23 additions & 0 deletions src/repo-query/components/ChatCircle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import openSaucedLogoIcon from "../../assets/open-sauced-orange-bg-logo.svg";

export const ChatCircle = ({ toggleDialog }: { toggleDialog: () => void }) => (
<div
role="button"
tabIndex={0}
onClick={toggleDialog}
onKeyDown={
e => {
if (e.key === "Enter") {
toggleDialog();
}
}
}
>
<img
alt="Open Sauced Logo"
className="w-14 h-14 rounded-full fixed bottom-0 right-0 m-8 z-50 cursor-pointer"
id="chat-dialog-button-logo"
src={chrome.runtime.getURL(openSaucedLogoIcon)}
/>
</div>
diivi marked this conversation as resolved.
Show resolved Hide resolved
);
130 changes: 130 additions & 0 deletions src/repo-query/components/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { useState } from "react";
import openSaucedLogoIcon from "../../assets/open-sauced-orange-bg-logo.svg";
import { Home } from "../pages/home";
Anush008 marked this conversation as resolved.
Show resolved Hide resolved
import { IndexingPage } from "../pages/indexing";
import { Chat } from "../pages/chat";

// pages enum
export enum RepoQueryPages {
Home = "home",
Indexing = "indexing",
Chat = "chat",
}

export const Dialog = ({ isOpen, toggleDialog, ownerName, repoName }: { isOpen: boolean, toggleDialog: () => void, ownerName: string, repoName: string }) => {
const [currentPage, setCurrentPage] = useState(RepoQueryPages.Home);

return (
<div
diivi marked this conversation as resolved.
Show resolved Hide resolved
className="fixed bottom-20 right-0 m-8 z-50"
id="chat-dialog"
style={{ display: isOpen ? "block" : "none" }}
>
<div
className="flex flex-row justify-between items-center w-96 h-16 rounded-tl-xl rounded-tr-lg bg-slate-800 shadow-lg"
id="chat-dialog-header"
>
<div
className="flex flex-row justify-between w-full pr-4 items-center"
id="chat-dialog-header-left"
>
<div
className="flex flex-row items-center"
id="chat-dialog-header-left-logo-container"
>
<img
alt="OpenSauced logo"
className="w-12 h-12 rounded-full ml-4"
id="chat-dialog-header-left-logo"
src={`${chrome.runtime.getURL(openSaucedLogoIcon)}`}
/>

<div
className="ml-4"
id="chat-dialog-header-left-text"
>
<div
className="text-lg font-bold text-white"
id="chat-dialog-header-left-text-title"
>
OpenSauced
</div>

<div
className="text-sm text-gray-400"
id="chat-dialog-header-left-text-subtitle"
>
RepoQuery
</div>
</div>
</div>

<div
className="w-8 h-8 rounded-full bg-gray-200 flex flex-row justify-center items-center ml-4 cursor-pointer"
id="chat-dialog-header-left-close"
role="button"
tabIndex={0}
onClick={toggleDialog}
onKeyDown={
e => {
if (e.key === "Enter") {
toggleDialog();
}
}
}
>
<svg
className="w-4 h-4 text-gray-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 18L18 6M6 6l12 12"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
/>
</svg>
</div>
</div>
</div>

<div
className="flex flex-col w-96 h-96 rounded-bl-xl rounded-br-lg bg-white shadow-lg"
id="chat-dialog-body"
>
{
currentPage === RepoQueryPages.Home
? (
<Home
ownerName={ownerName}
repoName={repoName}
setCurrentPage={setCurrentPage}
/>
)
: currentPage === RepoQueryPages.Indexing
? (
<IndexingPage
ownerName={ownerName}
repoName={repoName}
setCurrentPage={setCurrentPage}
/>
)

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
: currentPage === RepoQueryPages.Chat
? (
<Chat
ownerName={ownerName}
repoName={repoName}
setCurrentPage={setCurrentPage}
/>
)
: null
}
</div>
</div>
);
};
Loading