Skip to content

Commit

Permalink
feat: react/unreact on highlights
Browse files Browse the repository at this point in the history
  • Loading branch information
diivi committed Jul 4, 2023
1 parent 52dc3eb commit 12a44c0
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 23 deletions.
135 changes: 113 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 @@ -13,25 +14,31 @@ interface HighlightSlideProps {
}

export const HighlightSlide = ({ highlight, emojis }: HighlightSlideProps) => {
const [highlightReactions, setHighlightReactions] = useState<Record<string, string>[]>([]);
const [highlightReactions, setHighlightReactions] = useState<Record<string, any>[]>([]);
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 reactedByUser = userHighlightReactionData.some(userHighlightReaction => userHighlightReaction.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)!;
return {
url: emoji.url,
reaction_count: highlightReaction.reaction_count,
reactedByUser,
emojiId: emoji.id
};
});

return {
url: emoji.url,
reaction_count: highlightReaction.reaction_count,
highlight_url: highlight.url,
};
});

setHighlightReactions(highlightReactionsWithEmojiUrls);
}

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

Expand All @@ -41,6 +48,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 +110,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 +206,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
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",
});
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

0 comments on commit 12a44c0

Please sign in to comment.