@@ -17,7 +17,7 @@ import {
1717 type Dispatch ,
1818 type SetStateAction ,
1919} from "react" ;
20- import { useImmer , type Updater } from "use-immer" ;
20+ import { type Updater } from "use-immer" ;
2121import type { DateArr , ImmerContestData } from "@/types/contestData" ;
2222import dayjs from "dayjs" ;
2323import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" ;
@@ -52,23 +52,9 @@ const ConfigPanel: FC<{
5252 const { modal, message } = App . useApp ( ) ;
5353 const formRef = useRef < HTMLFormElement > ( null ) ;
5454 const [ width , setWidth ] = useState ( 220 ) ;
55- const [ images , updateImages ] = useImmer <
56- {
57- name : string ;
58- url : string ;
59- editMode : boolean ;
60- } [ ]
61- > ( [ ] ) ;
62- const imagesRef = useRef ( images ) ;
63-
64- useEffect ( ( ) => {
65- imagesRef . current = images ;
66- } , [ images ] ) ;
67- useEffect (
68- ( ) => ( ) => imagesRef . current . forEach ( ( x ) => URL . revokeObjectURL ( x . url ) ) ,
69- [ ] ,
55+ const [ imageEditModeId , setImageEditModeId ] = useState < number | undefined > (
56+ undefined
7057 ) ;
71-
7258 useEffect ( ( ) => {
7359 if ( ! formRef . current ) return ;
7460 const form = formRef . current ;
@@ -98,24 +84,32 @@ const ConfigPanel: FC<{
9884 }
9985 function updateLang (
10086 index : number ,
101- cb : ( x : ImmerContestData [ "support_languages" ] [ number ] ) => void ,
87+ cb : ( x : ImmerContestData [ "support_languages" ] [ number ] ) => void
10288 ) {
10389 updateContestData ( ( x ) => {
10490 cb ( x . support_languages [ index ] ) ;
10591 } ) ;
10692 }
10793 function updateProblemData (
10894 index : number ,
109- cb : ( x : ImmerContestData [ "problems" ] [ number ] ) => void ,
95+ cb : ( x : ImmerContestData [ "problems" ] [ number ] ) => void
11096 ) {
11197 updateContestData ( ( x ) => {
11298 cb ( x . problems [ index ] ) ;
11399 } ) ;
114100 }
101+ function updateImages (
102+ index : number ,
103+ cb : ( x : ImmerContestData [ "images" ] [ number ] ) => void
104+ ) {
105+ updateContestData ( ( x ) => {
106+ cb ( x . images [ index ] ) ;
107+ } ) ;
108+ }
115109 const removeProblem = removeProblemCallback (
116110 modal ,
117111 setPanel ,
118- updateContestData ,
112+ updateContestData
119113 ) ;
120114 return (
121115 < form className = "contest-editor-config" ref = { formRef } >
@@ -277,7 +271,7 @@ const ConfigPanel: FC<{
277271 onClick = { ( ) =>
278272 updateContestData ( ( x ) => {
279273 const i = x . support_languages . findIndex (
280- ( v ) => v . key === lang . key ,
274+ ( v ) => v . key === lang . key
281275 ) ;
282276 if ( i === - 1 )
283277 throw new Error ( "Target language not found" ) ;
@@ -305,7 +299,7 @@ const ConfigPanel: FC<{
305299 for ( const p of x . problems )
306300 if ( ! ( newLang . name in p . submit_filename ) )
307301 p . submit_filename . push (
308- p . name + `.lang${ x . support_languages . length + 1 } ` ,
302+ p . name + `.lang${ x . support_languages . length + 1 } `
309303 ) ;
310304 x . support_languages . push ( newLang ) ;
311305 } )
@@ -386,7 +380,7 @@ const ConfigPanel: FC<{
386380 onChange = { ( e ) =>
387381 updateProblemData (
388382 index ,
389- ( x ) => ( x . title = e . target . value ) ,
383+ ( x ) => ( x . title = e . target . value )
390384 )
391385 }
392386 />
@@ -412,7 +406,7 @@ const ConfigPanel: FC<{
412406 onChange = { ( e ) =>
413407 updateProblemData (
414408 index ,
415- ( x ) => ( x . dir = e . target . value ) ,
409+ ( x ) => ( x . dir = e . target . value )
416410 )
417411 }
418412 className = "contest-editor-config-monoinput"
@@ -426,7 +420,7 @@ const ConfigPanel: FC<{
426420 onChange = { ( e ) =>
427421 updateProblemData (
428422 index ,
429- ( x ) => ( x . exec = e . target . value ) ,
423+ ( x ) => ( x . exec = e . target . value )
430424 )
431425 }
432426 className = "contest-editor-config-monoinput"
@@ -444,7 +438,7 @@ const ConfigPanel: FC<{
444438 onChange = { ( e ) =>
445439 updateProblemData (
446440 index ,
447- ( x ) => ( x . input = e . target . value ) ,
441+ ( x ) => ( x . input = e . target . value )
448442 )
449443 }
450444 className = "contest-editor-config-monoinput"
@@ -458,7 +452,7 @@ const ConfigPanel: FC<{
458452 onChange = { ( e ) =>
459453 updateProblemData (
460454 index ,
461- ( x ) => ( x . output = e . target . value ) ,
455+ ( x ) => ( x . output = e . target . value )
462456 )
463457 }
464458 className = "contest-editor-config-monoinput"
@@ -475,7 +469,7 @@ const ConfigPanel: FC<{
475469 onChange = { ( e ) =>
476470 updateProblemData (
477471 index ,
478- ( x ) => ( x . time_limit = e . target . value ) ,
472+ ( x ) => ( x . time_limit = e . target . value )
479473 )
480474 }
481475 />
@@ -488,7 +482,7 @@ const ConfigPanel: FC<{
488482 onChange = { ( e ) =>
489483 updateProblemData (
490484 index ,
491- ( x ) => ( x . memory_limit = e . target . value ) ,
485+ ( x ) => ( x . memory_limit = e . target . value )
492486 )
493487 }
494488 />
@@ -503,7 +497,7 @@ const ConfigPanel: FC<{
503497 onChange = { ( e ) =>
504498 updateProblemData (
505499 index ,
506- ( x ) => ( x . testcase = e . target . value ) ,
500+ ( x ) => ( x . testcase = e . target . value )
507501 )
508502 }
509503 />
@@ -517,7 +511,7 @@ const ConfigPanel: FC<{
517511 onChange = { ( e ) =>
518512 updateProblemData (
519513 index ,
520- ( x ) => ( x . point_equal = e . target . value ) ,
514+ ( x ) => ( x . point_equal = e . target . value )
521515 )
522516 }
523517 />
@@ -532,7 +526,7 @@ const ConfigPanel: FC<{
532526 onChange = { ( e ) =>
533527 updateProblemData (
534528 index ,
535- ( x ) => ( x . pretestcase = e . target . value ) ,
529+ ( x ) => ( x . pretestcase = e . target . value )
536530 )
537531 }
538532 />
@@ -551,7 +545,7 @@ const ConfigPanel: FC<{
551545 onChange = { ( e ) =>
552546 updateProblemData (
553547 index ,
554- ( x ) => ( x . submit_filename [ findex ] = e . target . value ) ,
548+ ( x ) => ( x . submit_filename [ findex ] = e . target . value )
555549 )
556550 }
557551 className = "contest-editor-config-monoinput"
@@ -577,24 +571,20 @@ const ConfigPanel: FC<{
577571 < div className = "contest-editor-config-label contest-editor-config-image" >
578572 < div > 本地图片</ div >
579573 < div >
580- { images . map ( ( img , index ) => (
574+ { contestData . images . map ( ( img , index ) => (
581575 < Card
582576 key = { img . url }
583577 classNames = { { body : "contest-editor-config-image-card" } }
584578 >
585579 < Image src = { img . url } alt = { img . name } height = { 150 } />
586580 < div >
587- { ! img . editMode ? (
581+ { imageEditModeId !== index ? (
588582 < >
589583 < div > { img . name } </ div >
590584 < Button
591585 type = "text"
592586 icon = { < FontAwesomeIcon icon = { faPenToSquare } /> }
593- onClick = { ( ) =>
594- updateImages ( ( x ) => {
595- x [ index ] . editMode = true ;
596- } )
597- }
587+ onClick = { ( ) => setImageEditModeId ( index ) }
598588 />
599589 </ >
600590 ) : (
@@ -603,15 +593,11 @@ const ConfigPanel: FC<{
603593 value = { img . name }
604594 autoFocus
605595 onChange = { ( e ) =>
606- updateImages ( ( x ) => {
607- x [ index ] . name = e . target . value ;
608- } )
609- }
610- onBlur = { ( ) =>
611- updateImages ( ( x ) => {
612- x [ index ] . editMode = false ;
596+ updateImages ( index , ( x ) => {
597+ x . name = e . target . value ;
613598 } )
614599 }
600+ onBlur = { ( ) => setImageEditModeId ( undefined ) }
615601 />
616602 ) }
617603 </ div >
@@ -628,18 +614,18 @@ const ConfigPanel: FC<{
628614 console . error ( "Error when copy." , e ) ;
629615 message . error (
630616 "复制失败:" +
631- ( e instanceof Error ? e . message : String ( e ) ) ,
617+ ( e instanceof Error ? e . message : String ( e ) )
632618 ) ;
633- } ,
619+ }
634620 )
635621 }
636622 />
637623 < Button
638624 type = "text"
639625 icon = { < FontAwesomeIcon icon = { faTrashCan } /> }
640626 onClick = { ( ) =>
641- updateImages ( ( imgs ) => {
642- imgs . splice ( index , 1 ) ;
627+ updateContestData ( ( x ) => {
628+ x . images . splice ( index , 1 ) ;
643629 } )
644630 }
645631 />
@@ -666,11 +652,10 @@ const ConfigPanel: FC<{
666652 console . log ( options ) ;
667653 const file = options . file ;
668654 if ( ! ( file instanceof File ) ) throw new Error ( "Invalid file" ) ;
669- updateImages ( ( imgs ) => {
670- imgs . push ( {
655+ updateContestData ( ( x ) => {
656+ x . images . push ( {
671657 name : file . name ,
672658 url : URL . createObjectURL ( file ) ,
673- editMode : false ,
674659 } ) ;
675660 } ) ;
676661 } }
0 commit comments