Skip to content

Commit

Permalink
Add new libraries tab in frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
roblabla committed Sep 23, 2023
1 parent 7b3ef11 commit ae0d586
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 1 deletion.
42 changes: 42 additions & 0 deletions frontend/src/components/Scratch/LibraryPanel.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.section {
padding: 1.5em;
border-radius: 0;
background: transparent;
}

.section > h3 {
font-size: 1.1em;
font-weight: 500;

padding: 0.5em;
padding-top: 0;

color: var(--g1200);
}

.section:not(:last-child) {
border-bottom: 1px solid var(--a100);
}

.library {
display: inline-flex;
flex-direction: row;

width: 100%;
border-radius: 0.5em;
}

.libraryName {
cursor: default;
font-size: 0.8rem;

font-size: 1.0em;
font-weight: 500;

padding: .5em;

}

.librarySelect {
flex-grow: 1;
}
85 changes: 85 additions & 0 deletions frontend/src/components/Scratch/LibraryPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { useLibraries } from "@/lib/api"
import { Library, TerseScratch } from "@/lib/api/types"

import Select from "../Select2"

import styles from "./LibraryPanel.module.css"

type LibrariesT = {
libraries: Library[]
}

type Props = {
scratch: TerseScratch
onChange: (value: LibrariesT) => void
}

export default function LibraryPanel({ scratch, onChange }: Props) {
const libraries = useLibraries()

const hasLibrary = libName => scratch.libraries.some(lib => lib.name == libName)
const libraryVersion = lib => {
const scratchlib = scratch.libraries.find(scratchlib => scratchlib.name == lib.name)
if (scratchlib != null) {
return scratchlib.version
} else {
return "___NULL_VERSION___"
}
}

const setLibraryVersion = (libName, ver) => {
if (ver == "___NULL_VERSION___") {
return unsetLibrary(libName)
}

// clone the libraries
const libs = JSON.parse(JSON.stringify(scratch.libraries))
// Check if the library is already enabled, if so return it
const scratchlib = scratch.libraries.find(scratchlib => scratchlib.name == libName)
if (scratchlib != null) {
// If it is, set the version
scratchlib.version = ver
} else {
// If it isn't, add the library to the list
libs.push({ name: libName, version: ver })
}
onChange({
libraries: libs,
})
}
const unsetLibrary = libName => {
// clone the libraries
let libs = JSON.parse(JSON.stringify(scratch.libraries))
// Only keep the libs whose name are not libName
libs = libs.filter(lib => lib.name != libName)
onChange({
libraries: libs,
})
}
const toggleLibrary = lib => {
if (hasLibrary(lib.name)) {
unsetLibrary(lib.name)
} else {
setLibraryVersion(lib.name, lib.supported_versions[0])
}
}

const selectOptions = lib => Object.fromEntries([["___NULL_VERSION___", "Disabled"], ...lib.supported_versions.map(ver => [ver, ver])])

const librariesElements = libraries.map(lib => <div key={lib.name} className={styles.library}>
<input type="checkbox" checked={hasLibrary(lib.name)} onChange={() => toggleLibrary(lib)} />
<label className={styles.libraryName}>{lib.name}</label>
<Select
value={libraryVersion(lib)}
onChange={value => setLibraryVersion(lib.name, value)}
options={selectOptions(lib)}
className={styles.librarySelect} />
</div>)

return <div>
<section className={styles.section}>
<h3>Libraries</h3>
{librariesElements}
</section>
</div>
}
8 changes: 8 additions & 0 deletions frontend/src/components/Scratch/Scratch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import AboutScratch from "./AboutScratch"
import DecompilationPanel from "./DecompilePanel"
import FamilyPanel from "./FamilyPanel"
import useLanguageServer from "./hooks/useLanguageServer"
import LibraryPanel from "./LibraryPanel"
import styles from "./Scratch.module.scss"
import ScratchMatchBanner from "./ScratchMatchBanner"
import ScratchToolbar from "./ScratchToolbar"
Expand All @@ -33,6 +34,7 @@ enum TabId {
DIFF = "scratch_diff",
DECOMPILATION = "scratch_decompilation",
FAMILY = "scratch_family",
LIBRARIES = "libraries",
}

const DEFAULT_LAYOUTS: Record<"desktop_2col" | "mobile_2row", Layout> = {
Expand All @@ -52,6 +54,7 @@ const DEFAULT_LAYOUTS: Record<"desktop_2col" | "mobile_2row", Layout> = {
TabId.SOURCE_CODE,
TabId.CONTEXT,
TabId.OPTIONS,
TabId.LIBRARIES,
],
},
{
Expand Down Expand Up @@ -92,6 +95,7 @@ const DEFAULT_LAYOUTS: Record<"desktop_2col" | "mobile_2row", Layout> = {
TabId.SOURCE_CODE,
TabId.CONTEXT,
TabId.OPTIONS,
TabId.LIBRARIES,
],
},
],
Expand Down Expand Up @@ -274,6 +278,10 @@ export default function Scratch({
return <Tab key={id} tabKey={id} label="Family">
{() => <FamilyPanel scratch={scratch} />}
</Tab>
case TabId.LIBRARIES:
return <Tab key={id} tabKey={id} label="Libraries">
<LibraryPanel scratch={scratch} onChange={setScratch} />
</Tab>
default:
return <Tab key={id} tabKey={id} label={id} disabled />
}
Expand Down
14 changes: 13 additions & 1 deletion frontend/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import useSWR, { Revalidator, RevalidatorOptions, mutate } from "swr"
import { useDebouncedCallback } from "use-debounce"

import { ResponseError, get, post, patch, delete_ } from "./api/request"
import { AnonymousUser, User, Scratch, TerseScratch, Compilation, Page, Compiler, Platform, Project, ProjectMember } from "./api/types"
import { AnonymousUser, User, Scratch, TerseScratch, Compilation, Page, Compiler, LibraryVersions, Platform, Project, ProjectMember } from "./api/types"
import { ignoreNextWarnBeforeUnload } from "./hooks"

function onErrorRetry<C>(error: ResponseError, key: string, config: C, revalidate: Revalidator, { retryCount }: RevalidatorOptions) {
Expand Down Expand Up @@ -82,6 +82,7 @@ export function useSaveScratch(localScratch: Scratch): () => Promise<Scratch> {
name: undefinedIfUnchanged(savedScratch, localScratch, "name"),
description: undefinedIfUnchanged(savedScratch, localScratch, "description"),
match_override: undefinedIfUnchanged(savedScratch, localScratch, "match_override"),
libraries: undefinedIfUnchanged(savedScratch, localScratch, "libraries"),
})

await mutate(localScratch.url, updatedScratch, false)
Expand Down Expand Up @@ -166,6 +167,7 @@ export function useCompilation(scratch: Scratch | null, autoRecompile = true, au
compiler_flags: scratch.compiler_flags,
diff_flags: scratch.diff_flags,
diff_label: scratch.diff_label,
libraries: scratch.libraries,
source_code: scratch.source_code,
context: savedScratch ? undefinedIfUnchanged(savedScratch, scratch, "context") : scratch.context,
}).then((compilation: Compilation) => {
Expand Down Expand Up @@ -251,6 +253,16 @@ export function useCompilers(): Record<string, Compiler> {
return data.compilers
}

export function useLibraries(): LibraryVersions[] {
const { data } = useSWR("/libraries", get, {
refreshInterval: 0,
suspense: true, // TODO: remove
onErrorRetry,
})

return data.libraries
}

export function usePaginated<T>(url: string, firstPage?: Page<T>): {
results: T[]
hasNext: boolean
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/lib/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface TerseScratch {
match_override: boolean
project: string
project_function: string
libraries: Library[]
}

export interface Scratch extends TerseScratch {
Expand Down Expand Up @@ -165,6 +166,16 @@ export type Compiler = {
diff_flags: Flag[]
}

export type Library = {
name: string
version: string
}

export type LibraryVersions = {
name: string
supported_versions: string[]
}

export type Platform = {
name: string
description: string
Expand Down

0 comments on commit ae0d586

Please sign in to comment.