diff --git a/frontend/src/components/Scratch/LibraryPanel.module.css b/frontend/src/components/Scratch/LibraryPanel.module.css
deleted file mode 100644
index 919397ed..00000000
--- a/frontend/src/components/Scratch/LibraryPanel.module.css
+++ /dev/null
@@ -1,86 +0,0 @@
-.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;
-}
-
-.deleteButton {
- display: flex;
- align-items: center;
- gap: 4px;
- padding: 4px 8px;
-
- cursor: pointer;
-
- color: var(--g1900);
- background: none;
- border: 0;
-
-}
-.deleteButton > svg {
- width: 1em;
- color: var(--g1200);
-}
-
-.deleteButton:hover {
- border-radius: 4px;
- color: var(--g2000);
- background: var(--g400);
-}
-
-.addLibraryRow {
- display: inline-flex;
- margin: 1em;
- margin-bottom: 0em;
- width: 100%;
-}
-
-.addLibraryRow > button {
- margin-left: 1em;
- margin-right: 1em;
-}
-
-.librariesGrid {
- margin-top: 1.5em;
- display: grid;
- grid-template-columns: max-content 1fr max-content;
- grid-auto-flow: row;
- gap: 0.4em 0;
-}
diff --git a/frontend/src/components/Scratch/LibraryPanel.tsx b/frontend/src/components/Scratch/LibraryPanel.tsx
deleted file mode 100644
index 2158ef4e..00000000
--- a/frontend/src/components/Scratch/LibraryPanel.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-import { Fragment, useState } from "react"
-
-import { useLibraries } from "@/lib/api"
-import { Library, TerseScratch } from "@/lib/api/types"
-import { TrashIcon } from "@primer/octicons-react"
-
-import Button from "@/components/Button"
-import Select from "@/components/Select2"
-import useTranslation from "@/lib/i18n/translate"
-
-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 librariesTranslations = useTranslation("libraries")
-
- const hasLibrary = libName => scratch.libraries.some(lib => lib.name == libName)
- const libraryVersions = scratchlib => {
- const lib = libraries.find(lib => lib.name == scratchlib.name)
- if (lib != null) {
- return lib.supported_versions
- } else {
- return [scratchlib.version]
- }
- }
-
- const addLibrary = libName => {
- const lib = libraries.find(lib => lib.name == libName)
- if (lib != null) {
- return setLibraryVersion(libName, lib.supported_versions[0])
- }
- }
- const setLibraryVersion = (libName, ver) => {
- // 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 removeLibrary = 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,
- })
- }
-
- let librariesSelectOptions = libraries
- // Filter out libraries that are already in the scratch
- .filter(lib => !scratch.libraries.some(scratchlib => scratchlib.name == lib.name))
- // Turn them into something the Select component accepts.
- .map(lib => lib.supported_versions.map(ver => [lib.name, librariesTranslations.t(lib.name)]))
- .flat()
-
- // Prepend a null value to the selector.
- const selectOptions = Object.fromEntries([["__NULL__", "---"], ...librariesSelectOptions])
-
- const scratchLibraryElements = scratch.libraries.map(lib =>
-
- )
-
- const [selectedLib, setSelectedLib] = useState('__NULL__')
-
- return
-
- Libraries
-
-
-
-
-
- {scratchLibraryElements}
-
-
-
-}
diff --git a/frontend/src/components/Scratch/Scratch.tsx b/frontend/src/components/Scratch/Scratch.tsx
index b512f12c..63b8cc0d 100644
--- a/frontend/src/components/Scratch/Scratch.tsx
+++ b/frontend/src/components/Scratch/Scratch.tsx
@@ -21,7 +21,6 @@ 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"
@@ -34,7 +33,6 @@ enum TabId {
DIFF = "scratch_diff",
DECOMPILATION = "scratch_decompilation",
FAMILY = "scratch_family",
- LIBRARIES = "libraries",
}
const DEFAULT_LAYOUTS: Record<"desktop_2col" | "mobile_2row", Layout> = {
@@ -54,7 +52,6 @@ const DEFAULT_LAYOUTS: Record<"desktop_2col" | "mobile_2row", Layout> = {
TabId.SOURCE_CODE,
TabId.CONTEXT,
TabId.OPTIONS,
- TabId.LIBRARIES,
],
},
{
@@ -95,7 +92,6 @@ const DEFAULT_LAYOUTS: Record<"desktop_2col" | "mobile_2row", Layout> = {
TabId.SOURCE_CODE,
TabId.CONTEXT,
TabId.OPTIONS,
- TabId.LIBRARIES,
],
},
],
@@ -278,10 +274,6 @@ export default function Scratch({
return
{() => }
- case TabId.LIBRARIES:
- return
-
-
default:
return
}
diff --git a/frontend/src/components/compiler/CompilerOpts.module.css b/frontend/src/components/compiler/CompilerOpts.module.css
index 785f9250..a5e3a9fa 100644
--- a/frontend/src/components/compiler/CompilerOpts.module.css
+++ b/frontend/src/components/compiler/CompilerOpts.module.css
@@ -152,3 +152,70 @@
display: block;
width: 100%;
}
+
+.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;
+}
+
+.deleteButton {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ padding: 4px 8px;
+
+ cursor: pointer;
+
+ color: var(--g1900);
+ background: none;
+ border: 0;
+
+}
+.deleteButton > svg {
+ width: 1em;
+ color: var(--g1200);
+}
+
+.deleteButton:hover {
+ border-radius: 4px;
+ color: var(--g2000);
+ background: var(--g400);
+}
+
+.addLibraryRow {
+ display: inline-flex;
+ margin: 1em;
+ margin-bottom: 0em;
+ width: 100%;
+}
+
+.addLibraryRow > button {
+ margin-left: 1em;
+ margin-right: 1em;
+}
+
+.librariesGrid {
+ margin-top: 1.5em;
+ display: grid;
+ grid-template-columns: max-content 1fr max-content;
+ grid-auto-flow: row;
+ gap: 0.4em 0;
+}
diff --git a/frontend/src/components/compiler/CompilerOpts.tsx b/frontend/src/components/compiler/CompilerOpts.tsx
index 5117a1d6..5b3c084c 100644
--- a/frontend/src/components/compiler/CompilerOpts.tsx
+++ b/frontend/src/components/compiler/CompilerOpts.tsx
@@ -1,9 +1,13 @@
-import { createContext, useContext, ReactElement } from "react"
+import { createContext, useContext, useState, Fragment, ReactElement } from "react"
import Checkbox from "@/app/(navfooter)/settings/Checkbox"
import * as api from "@/lib/api"
+import { Library, TerseScratch } from "@/lib/api/types"
import useTranslation from "@/lib/i18n/translate"
+import { TrashIcon } from "@primer/octicons-react"
+import Button from "@/components/Button"
+import Select2 from "@/components/Select2"
import PlatformIcon from "../PlatformSelect/PlatformIcon"
import Select from "../Select" // TODO: use Select2
@@ -149,10 +153,11 @@ function DiffFlags({ schema }: FlagsProps) {
}
export type CompilerOptsT = {
- compiler: string
- compiler_flags: string
- diff_flags: string[]
- preset: string
+ compiler?: string
+ compiler_flags?: string
+ diff_flags?: string[]
+ preset?: string
+ libraries?: Library[]
}
export type Props = {
@@ -208,6 +213,10 @@ export default function CompilerOpts({ platform, value, onChange, diffLabel, onD
})
}
+ const setLibraries = (libraries: Library[]) => {
+ onChange({ libraries })
+ }
+
const optsEditorProvider = {
checkFlag(flag: string) {
return (" " + opts + " ").includes(" " + flag + " ")
@@ -262,6 +271,11 @@ export default function CompilerOpts({ platform, value, onChange, diffLabel, onD
+
+
+
Diff options
@@ -354,3 +368,85 @@ export function DiffOptsEditor({ platform, compiler: compilerId, diffLabel, onDi
}
+
+export function LibrariesEditor({ libraries, setLibraries }: {
+ libraries: Library[]
+ setLibraries: (libraries: Library[]) => void
+}) {
+ const supportedLibraries = api.useLibraries()
+ const librariesTranslations = useTranslation("libraries")
+
+ const hasLibrary = libName => libraries.some(lib => lib.name == libName)
+ const libraryVersions = scratchlib => {
+ const lib = supportedLibraries.find(lib => lib.name == scratchlib.name)
+ if (lib != null) {
+ return lib.supported_versions
+ } else {
+ return [scratchlib.version]
+ }
+ }
+
+ const addLibrary = libName => {
+ const lib = supportedLibraries.find(lib => lib.name == libName)
+ if (lib != null) {
+ return setLibraryVersion(libName, lib.supported_versions[0])
+ }
+ }
+ const setLibraryVersion = (libName, ver) => {
+ // clone the libraries
+ const libs = JSON.parse(JSON.stringify(libraries))
+ // Check if the library is already enabled, if so return it
+ const scratchlib = 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 })
+ }
+ setLibraries(libs)
+ }
+ const removeLibrary = libName => {
+ // clone the libraries
+ let libs = JSON.parse(JSON.stringify(libraries))
+ // Only keep the libs whose name are not libName
+ libs = libs.filter(lib => lib.name != libName)
+ setLibraries(libs)
+ }
+
+ let librariesSelectOptions = supportedLibraries
+ // Filter out libraries that are already in the scratch
+ .filter(lib => !libraries.some(scratchlib => scratchlib.name == lib.name))
+ // Turn them into something the Select component accepts.
+ .map(lib => lib.supported_versions.map(ver => [lib.name, librariesTranslations.t(lib.name)]))
+ .flat()
+
+ // Prepend a null value to the selector.
+ const selectOptions = Object.fromEntries([["__NULL__", "---"], ...librariesSelectOptions])
+
+ const scratchLibraryElements = libraries.map(lib =>
+
+ setLibraryVersion(lib.name, value)}
+ options={libraryVersions(lib)} />
+
+ )
+
+ const [selectedLib, setSelectedLib] = useState('__NULL__')
+
+ return <>
+ Libraries
+
+
+
+
+
+ {scratchLibraryElements}
+
+ >
+}