Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
365 changes: 250 additions & 115 deletions bsg-frontend/apps/extension/customComponents/RoomDisplays/ChatDisplay.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,20 @@ export const StatisticsDisplay = ({ isActive }: { isActive: boolean }) => {
useEffect(() => setHasAnimated(false), [isActive]);

const chartConfig: ChartConfig = {
score: { label: "Score", color: "#FFFFFF" },
solveTime: { label: "Solve Time", color: "#FFFFFF" },
runTime: { label: "Run Time", color: "#FFFFFF" },
memory: { label: "Memory", color: "#FFFFFF" }
score: { label: "Score", color: "#62AF2E" },
solveTime: { label: "Solve Time", color: "rgb(2,177,40)" },
runTime: { label: "Run Time", color: "rgb(0,123,255)" },
memory: { label: "Memory", color: "rgb(255,183,0)" }
};

const chartColors: Record<ActiveChart, string> = {
score: '#62AF2E',
solveTime: 'rgb(2,177,40)',
runTime: 'rgb(0,123,255)',
memory: 'rgb(255,183,0)',
percentile: 'rgb(255,157,20)'
}

type SubmissionEntry = {
username: string,
solveTime: number,
Expand Down Expand Up @@ -161,23 +169,23 @@ export const StatisticsDisplay = ({ isActive }: { isActive: boolean }) => {
background
stackId='breakdown'
dataKey='solveTime'
fill='#DDDDDD'
fill={chartColors['solveTime']}
isAnimationActive={false}
className=''
/>
<RadialBar
background
stackId='breakdown'
dataKey='runTime'
fill='#BBBBBB'
fill={chartColors['runTime']}
isAnimationActive={false}
className=''
/>
<RadialBar
background
stackId='breakdown'
dataKey='memory'
fill='#999999'
fill={chartColors['memory']}
isAnimationActive={false}
className=''
/>
Expand All @@ -186,7 +194,7 @@ export const StatisticsDisplay = ({ isActive }: { isActive: boolean }) => {
<RadialBar
background
dataKey='score'
fill='#FFFFFF'
fill={chartColors['score']}
isAnimationActive={isAnimationsActive && !hasAnimated}
onAnimationEnd={() => setHasAnimated(true)}
className=''
Expand All @@ -196,7 +204,7 @@ export const StatisticsDisplay = ({ isActive }: { isActive: boolean }) => {
</ChartContainer>
</div>

<div className="flex flex-col gap-2 w-full">
<div className="flex flex-col gap-1 w-full">
<div className="flex gap-2 items-center text-sm text-foreground/60 font-medium">
Room Statistics
</div>
Expand Down Expand Up @@ -366,19 +374,19 @@ export const StatisticsDisplay = ({ isActive }: { isActive: boolean }) => {
<>
<Bar
dataKey='solveTime'
fill='#FFFFFF'
fill={chartColors['solveTime']}
radius={[4, 4, 0, 0]}
isAnimationActive={isAnimationsActive}
/>
<Bar
dataKey='runTime'
fill='#FFFFFF'
fill={chartColors['runTime']}
radius={[4, 4, 0, 0]}
isAnimationActive={isAnimationsActive}
/>
<Bar
dataKey='memory'
fill='#FFFFFF'
fill={chartColors['memory']}
radius={[4, 4, 0, 0]}
isAnimationActive={isAnimationsActive}
/>
Expand All @@ -387,8 +395,9 @@ export const StatisticsDisplay = ({ isActive }: { isActive: boolean }) => {
</>
:
<Bar
key={activeChart}
dataKey={activeChart}
fill='#FFFFFF'
fill={chartColors[activeChart]}
radius={[4, 4, 0, 0]}
isAnimationActive={isAnimationsActive}
/>
Expand Down
67 changes: 61 additions & 6 deletions bsg-frontend/apps/extension/hooks/useChatSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ export const useChatSocket = () => {
const chatRef = useRef<HTMLDivElement | null>(null);
const isAtBottom = useRef<boolean>(true);
const atLimitTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const categoryRefs = useRef<Record<string, HTMLDivElement | null>>({});
const emojiMenuRef = useRef<HTMLDivElement | null>(null);

const [ messages, setMessages ] = useState<Message[]>([]);
const [ inputText, setInputText ] = useState<string>('');
const [ showJump, setShowJump ] = useState<boolean>(false);
const [ atLimit, setAtLimit ] = useState<boolean>(false);
const [messages, setMessages] = useState<Message[]>([]);
const [inputText, setInputText] = useState<string>('');
const [showJump, setShowJump] = useState<boolean>(false);
const [atLimit, setAtLimit] = useState<boolean>(false);
const [emojiSearch, setEmojiSearch] = useState<string>('');

const userEmail = useUserStore(s => s.email);
const username = useUserStore(s => s.username);
Expand Down Expand Up @@ -77,7 +80,7 @@ export const useChatSocket = () => {

if (responseType === 'chat-message') {
console.log('recieved chat message: ' + JSON.stringify(message))
setMessages( prev => [...prev, {
setMessages(prev => [...prev, {
userHandle: message.userHandle,
userName: message.userName,
userPhoto: message.userPhoto,
Expand Down Expand Up @@ -178,7 +181,7 @@ export const useChatSocket = () => {
const chat = chatRef.current;
const textArea = inputRef.current;
if (!roomId || !chat || !textArea) return;

const text = inputText.trim();
if (!text) return;

Expand Down Expand Up @@ -258,6 +261,52 @@ export const useChatSocket = () => {
}
}

const insertEmoji = (emoji: string) => {
const textarea = inputRef.current;
if (!textarea) return;

const start = textarea.selectionStart;
const end = textarea.selectionEnd;
const newText = inputText.slice(0, start) + emoji + inputText.slice(end);

if (newText.length <= MAX_CHARS) {
setInputText(newText);
requestAnimationFrame(() => {
textarea.selectionStart = start + emoji.length;
textarea.selectionEnd = start + emoji.length;
textarea.focus();
handleExpand();
});
} else if (inputText.length < MAX_CHARS) {
setInputText(newText.substring(0, MAX_CHARS));
requestAnimationFrame(() => {
textarea.focus();
handleExpand();
});

setAtLimit(true);
if (atLimitTimeoutRef.current) clearTimeout(atLimitTimeoutRef.current);
atLimitTimeoutRef.current = setTimeout(() => setAtLimit(false), 500);
} else {
setAtLimit(true);
if (atLimitTimeoutRef.current) clearTimeout(atLimitTimeoutRef.current);
atLimitTimeoutRef.current = setTimeout(() => setAtLimit(false), 500);
}
};

const scrollToCategory = (category: string) => {
setEmojiSearch('');

setTimeout(() => {
const menuEl = emojiMenuRef.current;
const categoryEl = categoryRefs.current[category];

if (menuEl && categoryEl) {
menuEl.scrollTop = categoryEl.offsetTop - menuEl.offsetTop;
}
}, 0);
}

useEffect(() => {
const textArea = inputRef.current;
const container = containerRef.current;
Expand Down Expand Up @@ -352,5 +401,11 @@ export const useChatSocket = () => {
atLimit,
MAX_CHARS,
clearMessages,
insertEmoji,
categoryRefs,
emojiMenuRef,
scrollToCategory,
emojiSearch,
setEmojiSearch
};
};
20 changes: 16 additions & 4 deletions bsg-frontend/extension/contentScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@
const tabsetLayout = document.querySelector('.flexlayout__layout');
if (!tabsetLayout) console.log("tabset layout not found");

// Remove scrollbar overflowing from tabs (purely visual)
const initialTabs = tabsetLayout.querySelectorAll('.flexlayout__tab');
initialTabs.forEach(tab => tab.style.clipPath = 'inset(0 round 8px)');

const removeActive = () => {
panelActive = false;
activeTabsetObserver.disconnect();
Expand Down Expand Up @@ -379,21 +383,29 @@
}
});

// Watch for new tabsets being added
const newTabsetObserver = new MutationObserver((mutations) => {
// Watch for new tab and tabsets being added
const newTabObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType !== Node.ELEMENT_NODE) return;

if (node.matches('.flexlayout__tabset, .flexlayout__tab')) {
if (node.classList.contains('flexlayout__tabset')) {
removeActive();
}

if (node.classList.contains('flexlayout__tab')) {
// Style tabs as they are added
node.style.clipPath = 'inset(0 round 8px)';
removeActive();
}
});
});
});

// TODO: Oberserve when flexlayout__tabset-active is assigned to a new panel

// Only observe added and removed nodes from LeetCode tabset layout
newTabsetObserver.observe(tabsetLayout, {
newTabObserver.observe(tabsetLayout, {
childList: true,
attributes: false,
characterData: false
Expand Down
Loading
Loading