Skip to content

Commit

Permalink
lint
Browse files Browse the repository at this point in the history
  • Loading branch information
conorgolden1 committed May 16, 2024
1 parent 4200fe9 commit 9cb0182
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 75 deletions.
2 changes: 1 addition & 1 deletion frontend/src/app/(navfooter)/u/[username]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default async function Page({ params }: { params: { username: string } })
{user.username}
</h1>

<div className="flex justify-center md:justify-start flex-wrap items-center gap-2 pt-1 text-sm text-gray-11">
<div className="flex flex-wrap items-center justify-center gap-2 pt-1 text-sm text-gray-11 md:justify-start">
<GhostButton href={userGithubHtmlUrl(user)}>
<div className="flex items-center gap-1">
{userGithubHtmlUrl(user) && <MarkGithubIcon size={16} aria-label="GitHub username" />}
Expand Down
44 changes: 20 additions & 24 deletions frontend/src/components/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ReactNode, useEffect, useRef, useState } from "react"
import { ReactNode, useCallback, useEffect, useRef, useState } from "react"

import { ChevronDownIcon } from "@primer/octicons-react"
import classNames from "classnames"

import styles from "./Dropdown.module.scss"
Expand All @@ -11,49 +10,46 @@ export type Props = {
children: ReactNode
}

const useClickOutside = (ref, handler) => {

};

export default function Dropdown({ options, children, className }: Props) {
const [isOpen, setIsOpen] = useState(false)
const ref = useRef(null)

const toggleDropdown = () => {
setIsOpen(!isOpen);
};
setIsOpen(!isOpen)
}

const closeDropdown = () => {
setIsOpen(false);
};
const closeDropdown = useCallback(() => {
setIsOpen(false)
}, [])

useEffect(() => {
const listener = (event) => {
const listener = event => {
if (!ref?.current || ref.current.contains(event.target)) {
return;
return
}
closeDropdown();
};
console.log("Called")
closeDropdown()
}

document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
document.addEventListener("mousedown", listener)
document.addEventListener("touchstart", listener)
return () => {
document.removeEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
};
}, [closeDropdown, ref]);
document.removeEventListener("mousedown", listener)
document.addEventListener("touchstart", listener)
}
}, [closeDropdown, ref])

return (
<div ref={ref} className="inline-table">
<button className={className} onClick={toggleDropdown}>
{children}
</button>
<div className={classNames(styles.group, styles.options, { [styles.open]: isOpen })}>
<div className={classNames(styles.options, { [styles.open]: isOpen })}>
{Object.entries(options).map(([value, onChange]) =>
<button
className={styles.option}
onClick={(event) => {
options[value](event)
onClick={event => {
onChange(event)
closeDropdown()
}}
key={value}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Scratch/AboutScratch.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Link from "next/link"

import { formatDistanceToNowStrict } from "date-fns"
import useSWR from "swr"

import { Scratch, Preset, get, usePreset } from "@/lib/api"
Expand All @@ -12,7 +13,6 @@ import { getScoreText } from "../ScoreBadge"
import UserLink from "../user/UserLink"

import styles from "./AboutScratch.module.scss"
import { formatDistanceToNowStrict } from "date-fns"

function ScratchLink({ url }: { url: string }) {
const { data: scratch, error } = useSWR<Scratch>(url, get)
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/Scratch/Comments.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@

.counter {
float: right;
line-height: 1.25rem;
padding-bottom: 4px;
font: 0.8rem var(--monospace);
color: var(--g1200);
Expand Down
69 changes: 31 additions & 38 deletions frontend/src/components/Scratch/Comments.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
"use client"

import { ChangeEvent, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import useSWR, { mutate } from "swr";
import { ChangeEvent, useRef, useState } from "react"

import * as api from "@/lib/api"
import { Comment } from "@/lib/api";
import { commentUrl } from "@/lib/api/urls";
import { useRouter } from "next/navigation"

import { ArrowUpIcon, KebabHorizontalIcon, CheckIcon } from "@primer/octicons-react"
import { formatDistanceToNowStrict } from "date-fns"
import useSWR, { mutate } from "swr"

import { ArrowUpIcon, KebabHorizontalIcon, CheckIcon } from "@primer/octicons-react"
import Loading from "@/components/loading.svg"
import * as api from "@/lib/api"
import { Comment } from "@/lib/api"
import { commentUrl } from "@/lib/api/urls"

import AsyncButton from "../AsyncButton"
import UserLink from "../user/UserLink";
import Button from "../Button";
import Button from "../Button"
import Dropdown from "../Dropdown"
import UserLink from "../user/UserLink"

import styles from "./Comments.module.scss"
import Dropdown from "../Dropdown";

const maxTextLength = 5000

Expand All @@ -33,15 +33,15 @@ async function deleteComment(comment: Comment) {

function EditComment({ comment, stopEditing, submit }: { comment: any, stopEditing: () => void, submit: (text: string) => Promise<unknown> }) {
const [text, setText] = useState(comment.text)
const textareaRef = useRef<HTMLTextAreaElement>(null);
const textareaRef = useRef<HTMLTextAreaElement>(null)

const handleInput = (e: ChangeEvent<HTMLTextAreaElement>) => {
if (textareaRef.current) {
textareaRef.current.style.height = "auto";
textareaRef.current.style.height = `${e.target.scrollHeight + 2}px`;
textareaRef.current.style.height = "auto"
textareaRef.current.style.height = `${e.target.scrollHeight + 2}px`
}
setText(e.target.value)
};
}

return (
<div>
Expand All @@ -56,7 +56,6 @@ function EditComment({ comment, stopEditing, submit }: { comment: any, stopEditi
ref={textareaRef}
autoComplete="off"
rows={1}
className={styles.textInput}
onChange={handleInput}
maxLength={maxTextLength}
defaultValue={comment.text}
Expand All @@ -65,12 +64,12 @@ function EditComment({ comment, stopEditing, submit }: { comment: any, stopEditi
</form>
<AsyncButton
className={styles.submit}
onClick={async () => { await submit(text)} }
onClick={async () => await submit(text)}
><CheckIcon /></AsyncButton>
</div>
<div className="flex flex-row-reverse gap-1 items-center">
<div className={styles.counter}>{text.length} / {maxTextLength}</div>
<div className="flex flex-row-reverse items-center gap-1">
<button className="text-xs" onClick={stopEditing}>Cancel</button>
<div className={styles.counter}>{text.length} / {maxTextLength}</div>
</div>
</section>
<br />
Expand All @@ -89,7 +88,7 @@ function CommentItem({ comment, canModify }: { comment: any, canModify?: boolean
"Delete Comment🚫": (event: KeyboardEvent) => {
if (event.shiftKey || confirm("Are you sure you want to delete this scratch? This action cannot be undone.")) {
deleteComment(comment)
comment.isDeleted = true;
comment.isDeleted = true
router.refresh()
}
},
Expand Down Expand Up @@ -139,7 +138,6 @@ function CommentItem({ comment, canModify }: { comment: any, canModify?: boolean
}

function CommentList({ results, canModify }: { results: Comment[], canModify?: boolean }) {

return (
<div className="flex flex-col-reverse">
{results.map((comment: Comment) => {
Expand All @@ -150,50 +148,48 @@ function CommentList({ results, canModify }: { results: Comment[], canModify?: b
}

export default function Comments({ scratch, scrollRef }: { scratch: api.TerseScratch, scrollRef: any }) {

const userIsYou = api.useUserIsYou()
const canModify = (scratch.owner && userIsYou(scratch.owner)) || api.useThisUserIsAdmin()


const router = useRouter()

const [needsUpdating, setNeedsUpdating] = useState(false)
const [text, setText] = useState("")

const textareaRef = useRef<HTMLTextAreaElement>(null);
const textareaRef = useRef<HTMLTextAreaElement>(null)
const bottomRef = useRef<HTMLDivElement>(null)

const { results, isLoading, hasNext, loadNext } = api.usePaginated<api.Comment>(`/comment?scratch=${scratch.slug}&page_size=20`)
// Check for new comments
const { error } = useSWR(`/comment?scratch=${scratch.slug}&page_size=1`, api.get, {
refreshInterval: 30 * 1000, // 30 Seconds
onSuccess: (newData) => {
onSuccess: newData => {
if (results[0]?.slug && newData.results[0]?.slug) {
setNeedsUpdating(results[0].slug !== newData.results[0]?.slug)
}
}
},
})

const refreshResults = async () => {
const submitAndRefresh = async () => {
const response = await api.post(`/comment?scratch_id=${scratch.slug}`, { text: text })
if (response) {
await api.get(`/comment?slug=${response.slug}`).then((comment) => {
await api.get(`/comment?slug=${response.slug}`).then(comment => {
results.unshift(comment.results[0])
})
textareaRef.current.style.height = "33px";
textareaRef.current.value = "";
textareaRef.current.style.height = "33px"
textareaRef.current.value = ""
}
router.refresh()
}

const handleInput = (e: ChangeEvent<HTMLTextAreaElement>) => {
if (textareaRef.current) {
textareaRef.current.style.height = "auto";
textareaRef.current.style.height = `${e.target.scrollHeight + 2}px`;
textareaRef.current.style.height = "auto"
textareaRef.current.style.height = `${e.target.scrollHeight + 2}px`
scrollRef.current.scrollTop = scrollRef.current.scrollHeight
}
setText(e.target.value)
};
}

function NeedsRefresh({ error }: { error: string }) {
const message = error ? error : "Refresh"
Expand All @@ -211,12 +207,10 @@ export default function Comments({ scratch, scrollRef }: { scratch: api.TerseScr
}

if (isLoading) {
return (<>
{isLoading && <div className="flex size-full items-center justify-center">
return (
<div className="flex size-full items-center justify-center">
<Loading className="size-8 animate-pulse" />
</div>
}
</>
)
}

Expand All @@ -243,7 +237,6 @@ export default function Comments({ scratch, scrollRef }: { scratch: api.TerseScr
ref={textareaRef}
autoComplete="off"
rows={1}
className={styles.textInput}
onChange={handleInput}
maxLength={maxTextLength}
placeholder="Message..."
Expand All @@ -252,7 +245,7 @@ export default function Comments({ scratch, scrollRef }: { scratch: api.TerseScr
</form>
<AsyncButton
className={styles.submit}
onClick={async () => { await refreshResults() }}
onClick={async () => await submitAndRefresh()}
><ArrowUpIcon /></AsyncButton>
</div>
<div className={styles.counter}>{text.length} / {maxTextLength}</div>
Expand Down
10 changes: 4 additions & 6 deletions frontend/src/components/Scratch/CommentsPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useRef } from "react"

import dynamic from "next/dynamic"

import { TerseScratch } from "@/lib/api"
import Loading from "@/components/loading.svg"
import { useRef } from "react"

import { TerseScratch } from "@/lib/api"

type Props = {
scratch: TerseScratch
Expand All @@ -14,12 +14,10 @@ const Comments = dynamic(() => import("./Comments"), {
</div>,
})



export default function CommentsPanel({ scratch }: Props) {
const scrollRef = useRef<HTMLDivElement>(null)
return (
<div ref={scrollRef} className="h-full pl-4 pr-4 overflow-y-auto overflow-x-hidden">
<div ref={scrollRef} className="h-full overflow-y-auto overflow-x-hidden px-4">
<Comments scratch={scratch} scrollRef={scrollRef} />
</div>
)
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Scratch/FamilyPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Props = {
}

export default function FamilyPanel({ scratch }: Props) {
return <div className="h-full p-4 overflow-auto">
return <div className="h-full overflow-auto p-4">
<SortableFamilyList scratch={scratch} />
</div>
}
2 changes: 1 addition & 1 deletion frontend/src/components/Scratch/Scratch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ import ScoreBadge, { calculateScorePercent } from "../ScoreBadge"
import { Tab, TabCloseButton } from "../Tabs"

import AboutScratch from "./AboutScratch"
import CommentsPanel from "./CommentsPanel"
import DecompilationPanel from "./DecompilePanel"
import FamilyPanel from "./FamilyPanel"
import useLanguageServer from "./hooks/useLanguageServer"
import styles from "./Scratch.module.scss"
import ScratchMatchBanner from "./ScratchMatchBanner"
import ScratchProgressBar from "./ScratchProgressBar"
import ScratchToolbar from "./ScratchToolbar"
import CommentsPanel from "./CommentsPanel"

enum TabId {
ABOUT = "scratch_about",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Scratch/ScratchToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Link from "next/link"

import { DownloadIcon, FileIcon, IterationsIcon, RepoForkedIcon, SyncIcon, TrashIcon, UploadIcon } from "@primer/octicons-react"
import classNames from "classnames"
import { formatDistanceToNowStrict } from "date-fns"
import ContentEditable from "react-contenteditable"

import * as api from "@/lib/api"
Expand All @@ -18,7 +19,6 @@ import UserAvatar from "../user/UserAvatar"

import useFuzzySaveCallback, { FuzzySaveAction } from "./hooks/useFuzzySaveCallback"
import styles from "./ScratchToolbar.module.scss"
import { formatDistanceToNowStrict } from "date-fns"

const ACTIVE_MS = 1000 * 60

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ScratchList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ReactNode } from "react"
import Link from "next/link"

import classNames from "classnames"
import { formatDistanceToNowStrict } from 'date-fns'
import { formatDistanceToNowStrict } from "date-fns"

import * as api from "@/lib/api"
import { presetUrl, scratchUrl } from "@/lib/api/urls"
Expand Down

0 comments on commit 9cb0182

Please sign in to comment.