Skip to content

Commit

Permalink
Merge pull request #205 from open-sauced/beta
Browse files Browse the repository at this point in the history
main <- v1.10.0-beta.3
  • Loading branch information
bdougie authored Jul 12, 2023
2 parents 52dc3eb + 8e603c6 commit d271bc8
Show file tree
Hide file tree
Showing 13 changed files with 240 additions and 32 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/issue-metrics.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Monthly issue metrics
on:
workflow_dispatch:
schedule:
- cron: '13 2 1 * *'

jobs:
build:
name: issue metrics
runs-on: ubuntu-latest

steps:

- name: Get dates for last month
shell: bash
run: |
# Get the current date
current_date=$(date +'%Y-%m-%d')
# Calculate the previous month
previous_date=$(date -d "$current_date -1 month" +'%Y-%m-%d')
# Extract the year and month from the previous date
previous_year=$(date -d "$previous_date" +'%Y')
previous_month=$(date -d "$previous_date" +'%m')
# Calculate the first day of the previous month
first_day=$(date -d "$previous_year-$previous_month-01" +'%Y-%m-%d')
# Calculate the last day of the previous month
last_day=$(date -d "$first_day +1 month -1 day" +'%Y-%m-%d')
echo "$first_day..$last_day"
echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
- name: Run issue-metrics tool
uses: github/issue-metrics@v2
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
SEARCH_QUERY: 'repo:open-sauced/ai is:issue created:${{ env.last_month }} -reason:"not planned"'

- name: Create issue
uses: peter-evans/create-issue-from-file@v4
with:
title: Monthly issue metrics report
content-filepath: ./issue_metrics.md
assignees: bdougie
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,35 @@

> All notable changes to this project will be documented in this file
## [1.10.0-beta.4](https://github.com/open-sauced/ai/compare/v1.10.0-beta.3...v1.10.0-beta.4) (2023-07-12)


### 🐛 Bug Fixes

* Create issue-metrics.yml ([4a6c19d](https://github.com/open-sauced/ai/commit/4a6c19dfe767c11e02206f40a8000a02a7139181))

## [1.10.0-beta.3](https://github.com/open-sauced/ai/compare/v1.10.0-beta.2...v1.10.0-beta.3) (2023-07-11)


### 🐛 Bug Fixes

* Rename project-utilities.md to 3-project-utilities.md ([d0a6702](https://github.com/open-sauced/ai/commit/d0a67026188786cc91a004a2488723439b8a9051))
* Updated RepoChecker to allow all types of repos ([#202](https://github.com/open-sauced/ai/issues/202)) ([2161918](https://github.com/open-sauced/ai/commit/2161918c3c4fe731a65e9aaa80cce154faf7b0b6)), closes [issue#112](https://github.com/open-sauced/issue/issues/112) [issue#112](https://github.com/open-sauced/issue/issues/112)

## [1.10.0-beta.2](https://github.com/open-sauced/ai/compare/v1.10.0-beta.1...v1.10.0-beta.2) (2023-07-11)


### 🍕 Features

* Cherry pick susmita ([#204](https://github.com/open-sauced/ai/issues/204)) ([7458724](https://github.com/open-sauced/ai/commit/74587246034fb985d1a56cad0a1eface13a67ab0))

## [1.10.0-beta.1](https://github.com/open-sauced/ai/compare/v1.9.0...v1.10.0-beta.1) (2023-07-10)


### 🍕 Features

* react/unreact on highlights ([#200](https://github.com/open-sauced/ai/issues/200)) ([c65eca0](https://github.com/open-sauced/ai/commit/c65eca043b78dd662d58768e6ab0bebb2fe9b845))

## [1.9.0](https://github.com/open-sauced/ai/compare/v1.8.0...v1.9.0) (2023-06-29)


Expand Down
18 changes: 18 additions & 0 deletions docs/3-project-utilities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
The utility functions used by the OpenSauced Extension project can be found in [src/utils](https://github.com/open-sauced/ai/tree/beta/src/utils). Each utility function serves a single purpose and is intended to be reusable across different parts of the project. The utilities are organized into domain-specific sub-directories within the utils folder, such as [/utils/dom-utils](https://github.com/open-sauced/ai/tree/beta/src/utils/dom-utils) for utilities related to manipulating the DOM.

| NOTE: This page is not meant to be an exhaustive list of all utility functions used in the project, but to highlight a few of the ones that may otherwise be esoteric. |
| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

### [cachedFetch()](https://github.com/open-sauced/ai/blob/beta/src/utils/cache.ts)

Added in PR [#36](https://github.com/open-sauced/ai/pull/36), the function allows you to cache responses from API calls in local storage, reducing the number of network requests and improving performance. It takes a URL and optional options object as arguments, including an option to set the time in seconds before the cache expires and force a refresh. If there is a cached response that has not expired, it returns that instead of making another call. Otherwise, it makes a fetch request and caches the response if it meets certain criteria (status code 200 and content type JSON or text).

### [createHtmlElement()](https://github.com/open-sauced/ai/blob/beta/src/utils/createHtmlElement.ts)

Added in PR [#20](https://github.com/open-sauced/ai/pull/20), the function creates an HTML element of a specified tag name and with optional properties. The properties can include styles, which are applied to the element's inline style attribute. Other non-style properties are also supported and added to the created element using `Object.assign()`. [Orginal implementation](https://gist.github.com/nickytonline/8223b27b19c080c28d9f0d3b7fce1e82).

### [checkAuthentication()](https://github.com/open-sauced/ai/blob/beta/src/utils/checkAuthentication.ts)
Added in PR [#56](https://github.com/open-sauced/ai/pull/56), this function checks if the user is authenticated by retrieving a cookie from Chrome storage and verifying its validity. If the cookie does not exist or is invalid, it removes any saved authentication token from Chrome storage.

### [domUpdateWatch()](https://github.com/open-sauced/ai/blob/beta/src/utils/dom-utils/domUpdateWatcher.ts)
Added in PR [64](https://github.com/open-sauced/ai/pull/64), this function is used to observe changes in the DOM and trigger a callback function when changes occur. The function uses a `MutationObserver` to track changes in the document body, and checks if the page has fully loaded before executing the callback with any specified delay time.
4 changes: 2 additions & 2 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "opensauced-browser-extension",
"private": true,
"version": "1.9.0",
"version": "1.10.0-beta.4",
"files": [
"dist"
],
Expand Down
142 changes: 120 additions & 22 deletions src/popup/components/HighlightSlide.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useState } from "react";
import { getHighlightReactions } from "../../utils/fetchOpenSaucedApiData";
import { getHighlightReactions, getUserHighlightReactions, reactOnHighlight, removeReactionOnHighlight } from "../../utils/fetchOpenSaucedApiData";
import { getAuthToken } from "../../utils/checkAuthentication";

interface HighlightSlideProps {
highlight: {
Expand All @@ -12,26 +13,39 @@ interface HighlightSlideProps {
emojis: Record<string, string>[];
}

interface HighlightReaction {
url: string;
reaction_count: string;
reactedByUser: boolean;
emojiId: string;
}

export const HighlightSlide = ({ highlight, emojis }: HighlightSlideProps) => {
const [highlightReactions, setHighlightReactions] = useState<Record<string, string>[]>([]);
const [highlightReactions, setHighlightReactions] = useState<HighlightReaction[]>([]);
const [reactingDivOpen, setReactingDivOpen] = useState(false);

useEffect(() => {
async function fetchHighlightReactions () {
const highlightReactionData = await getHighlightReactions(highlight.id);
async function fetchHighlightReactions () {
const highlightReactionData = await getHighlightReactions(highlight.id);
const userHighlightReactionData = await getUserHighlightReactions( await getAuthToken(), highlight.id);

const highlightReactionsWithEmojiUrls = emojis.filter(emoji => highlightReactionData.some(highlightReaction => highlightReaction.emoji_id === emoji.id)).map(emoji => {
const highlightReaction = highlightReactionData.find(highlightReaction => highlightReaction.emoji_id === emoji.id)!;

const highlightReactionsWithEmojiUrls = emojis.filter(emoji => highlightReactionData.some(highlightReaction => highlightReaction.emoji_id === emoji.id)).map(emoji => {
const highlightReaction = highlightReactionData.find(highlightReaction => highlightReaction.emoji_id === emoji.id)!;
const reactedByUser = userHighlightReactionData.some(userHighlightReaction => userHighlightReaction.emoji_id === emoji.id);

return {
url: emoji.url,
reaction_count: highlightReaction.reaction_count,
highlight_url: highlight.url,
};
});
return {
url: emoji.url,
reaction_count: highlightReaction.reaction_count,
reactedByUser,
emojiId: emoji.id,
} as HighlightReaction;
});


setHighlightReactions(highlightReactionsWithEmojiUrls);
}
setHighlightReactions(highlightReactionsWithEmojiUrls);
}

useEffect(() => {
void fetchHighlightReactions();
}, []);

Expand All @@ -41,6 +55,17 @@ export const HighlightSlide = ({ highlight, emojis }: HighlightSlideProps) => {
.join("/");
const openGraphUrl = `https://opengraph.githubassets.com/1/${openGraphSearchParameter}`;

const addReactionToHighlight = async (highlightId: string, emojiId: string) => {
await reactOnHighlight(await getAuthToken(), highlightId, emojiId);
setReactingDivOpen(false);
await fetchHighlightReactions();
};

const removeReactionFromHighlight = async (highlightId: string, emojiId: string) => {
await removeReactionOnHighlight(await getAuthToken(), highlightId, emojiId);
await fetchHighlightReactions();
};

return (
<div className="border border-white/40 rounded-md p-3 mt-2 bg-white">
{/* fixed height, content ellipsis */}
Expand Down Expand Up @@ -92,17 +117,94 @@ export const HighlightSlide = ({ highlight, emojis }: HighlightSlideProps) => {
/>

<div className="flex gap-2 mt-2 h-6 items-center">
<div className="flex gap-1 items-center">
<button
aria-haspopup="menu"
className="p-0.5 rounded-full bg-lightOrange"
type="button"
onClick={() => setReactingDivOpen(!reactingDivOpen)}
>
<svg
className="w-5 h-5"
fill="hsla(19, 100%, 50%, .3)"
height="1em"
stroke="currentColor"
strokeWidth="0"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
/>
</svg>
</button>
</div>

<div
aria-labelledby="options-menu"
aria-orientation="vertical"
className={`${reactingDivOpen ? "block" : "hidden"} rounded-full shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-100 focus:outline-none flex`}
id="reacting-div"
role="menu"
>
{emojis.map(emoji => (
<div
key={emoji.name}
className="p-2 text-sm hover:bg-gray-100 flex gap-2 items-center cursor-pointer"
role="menuitem"
tabIndex={-1}
onClick={async () => {
await addReactionToHighlight( highlight.id, emoji.id);
}}
onKeyDown={async () => {
await addReactionToHighlight( highlight.id, emoji.id);
}}
>
<img
alt="Emoji"
className="rounded-full w-6 aspect-square border border-orange p-1"
src={emoji.url}
/>
</div>
))}
</div>


{
highlightReactions.length > 0
highlightReactions.length > 0 && !reactingDivOpen
? (
highlightReactions.map(highlightReaction => (
<div
key={highlightReaction.url}
className="flex gap-1 items-center"
role="button"
tabIndex={0}
onClick={
highlightReaction.reactedByUser
? async () => {
await removeReactionFromHighlight(highlight.id, highlightReaction.emojiId);
}
: async () => {
await addReactionToHighlight(highlight.id, highlightReaction.emojiId);
}
}
onKeyDown={
highlightReaction.reactedByUser
? async () => {
await removeReactionFromHighlight(highlight.id, highlightReaction.emojiId);
}
: async () => {
await addReactionToHighlight(highlight.id, highlightReaction.emojiId);
}
}
>
<img
alt="Emoji"
className="rounded-full w-6 aspect-square border border-orange p-1"
className={`rounded-full w-6 aspect-square border border-orange p-1 ${highlightReaction.reactedByUser ? "bg-lightOrange" : ""}`}
src={highlightReaction.url}
/>

Expand All @@ -111,11 +213,7 @@ export const HighlightSlide = ({ highlight, emojis }: HighlightSlideProps) => {
</span>
</div>
)))
: (
<span className="text-slate-500">
No reactions yet.
</span>
)
: null
}
</div>

Expand Down
1 change: 0 additions & 1 deletion src/popup/pages/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ const Home = () => {

return;
}
console.log(inputFields);
inputFields[0].value = data.name;
inputFields[1].value = data.description;
}
Expand Down
3 changes: 0 additions & 3 deletions src/popup/pages/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { FaChevronLeft } from "react-icons/fa";
import OpenSaucedLogo from "../../assets/opensauced-logo.svg";
import { goBack } from "react-chrome-extension-router";
import Toggle from "../components/ToggleSwitch";
import AIPRDescription from "./aiprdescription";
import { useEffect, useState } from "react";
Expand Down
19 changes: 19 additions & 0 deletions src/utils/fetchOpenSaucedApiData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,27 @@ export const getHighlightReactions = async (highlightId: string):Promise<Record<
return response.json();
};

export const getUserHighlightReactions = async (userToken: string, highlightId: string):Promise<Record<string, string>[]> => {
const response = await fetch(`${OPEN_SAUCED_USER_HIGHLIGHTS_ENDPOINT}/${highlightId}/reactions`, {
headers: { Authorization: `Bearer ${userToken}` },
method: "GET",
});

return response.json();
};

export const getEmojis = async ():Promise<GeneralAPIResponse> => {
const response = await fetch(`${OPEN_SAUCED_EMOJIS_ENDPOINT}`, { method: "GET" });

return response.json();
};

export const reactOnHighlight = async (userToken: string, highlightId: string, emojiId: string) => fetch(`${OPEN_SAUCED_USER_HIGHLIGHTS_ENDPOINT}/${highlightId}/reactions/${emojiId}`, {
headers: { Authorization: `Bearer ${userToken}` },
method: "POST",
});

export const removeReactionOnHighlight = async (userToken: string, highlightId: string, emojiId: string) => fetch(`${OPEN_SAUCED_USER_HIGHLIGHTS_ENDPOINT}/${highlightId}/reactions/${emojiId}`, {
headers: { Authorization: `Bearer ${userToken}` },
method: "DELETE",
});
2 changes: 1 addition & 1 deletion src/utils/urlMatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const isGithubProfilePage = (url: string) => {
};

export const isGithubRepoPage = (url: string) => {
const githubRepoPattern = /github\.com\/[^/]+\/[^/]+$/;
const githubRepoPattern = /github\.com\/[^/]+\/[^/]+\/?$/;

return githubRepoPattern.test(url);
};
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
extend: {
colors: {
orange: "hsla(19, 100%, 50%, 1)",
lightOrange: "hsla(19, 100%, 50%, 0.5)"
},
boxShadow: {
button: "0 0 0.2rem 0.2rem rgb(245, 131, 106, 0.2)",
Expand Down
2 changes: 1 addition & 1 deletion test/utils/urlMatcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ test('isGithubRepoPage', () => {
expect(isGithubRepoPage('https://www.github.com/')).toBe(false)
expect(isGithubRepoPage('https://www.github.com/username/')).toBe(false)
expect(isGithubRepoPage('https://www.github.com/username/repo')).toBe(true)
expect(isGithubRepoPage('https://www.github.com/username/repo/')).toBe(false)
expect(isGithubRepoPage('https://www.github.com/username/repo/')).toBe(true)
expect(isGithubRepoPage('https://www.github.com/username/repo/https://google.com/')).toBe(false)
expect(isGithubRepoPage('www.github.com/username/repo')).toBe(true)
expect(isGithubRepoPage('github.com/username/repo')).toBe(true)
Expand Down
2 changes: 1 addition & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { crx } from "@crxjs/vite-plugin";
import * as manifest from "./manifest.json";
import manifest from "./manifest.json" assert { type: "json" };

// https://vitejs.dev/config/
export default defineConfig({
Expand Down

0 comments on commit d271bc8

Please sign in to comment.