@@ -603,76 +603,122 @@ const StackMenuPopup: FC<{
603603 ) ;
604604} ;
605605
606+ const getCommitTargetOperation = ( {
607+ sourceItem,
608+ commitId,
609+ previousCommitId,
610+ nextCommitId,
611+ input,
612+ element,
613+ } : {
614+ sourceItem : SourceItem ;
615+ commitId : string ;
616+ previousCommitId : string | undefined ;
617+ nextCommitId : string | undefined ;
618+ input : Parameters < typeof attachInstruction > [ 1 ] [ "input" ] ;
619+ element : Element ;
620+ } ) : Operation | null => {
621+ const isNoOpCommitMove = ( sourceCommitId : string , side : InsertSide ) : boolean =>
622+ sourceCommitId === commitId ||
623+ ( side === "above" && previousCommitId === sourceCommitId ) ||
624+ ( side === "below" && nextCommitId === sourceCommitId ) ;
625+
626+ const rubOperation = getRubOperation ( {
627+ sourceItem,
628+ target : { _tag : "Commit" , commitId } ,
629+ } ) ;
630+
631+ const instruction = extractInstruction (
632+ attachInstruction (
633+ { sourceItem } ,
634+ {
635+ input,
636+ element,
637+ operations : {
638+ "reorder-before" :
639+ ( sourceItem . _tag === "Commit" && ! isNoOpCommitMove ( sourceItem . commitId , "above" ) ) ||
640+ ( sourceItem . _tag === "TreeChanges" && sourceItem . source . parent . _tag === "Changes" ) ||
641+ ( sourceItem . _tag === "TreeChanges" && sourceItem . source . parent . _tag === "Commit" )
642+ ? "available"
643+ : "not-available" ,
644+ "reorder-after" :
645+ ( sourceItem . _tag === "Commit" && ! isNoOpCommitMove ( sourceItem . commitId , "below" ) ) ||
646+ ( sourceItem . _tag === "TreeChanges" && sourceItem . source . parent . _tag === "Changes" ) ||
647+ ( sourceItem . _tag === "TreeChanges" && sourceItem . source . parent . _tag === "Commit" )
648+ ? "available"
649+ : "not-available" ,
650+ combine : rubOperation ? "available" : "not-available" ,
651+ } ,
652+ } ,
653+ ) ,
654+ ) ;
655+
656+ if ( ! instruction ) return null ;
657+
658+ return Match . value ( instruction . operation ) . pipe (
659+ Match . when ( "combine" , ( ) : Operation | null =>
660+ rubOperation ? { _tag : "Rub" , ...rubOperation } : null ,
661+ ) ,
662+ Match . orElse ( ( side ) : Operation | null => {
663+ const insertSide = Match . value ( side ) . pipe (
664+ Match . when ( "reorder-before" , ( ) : InsertSide => "above" ) ,
665+ Match . when ( "reorder-after" , ( ) : InsertSide => "below" ) ,
666+ Match . exhaustive ,
667+ ) ;
668+
669+ if ( sourceItem . _tag === "Commit" )
670+ return {
671+ _tag : "CommitMove" ,
672+ subjectCommitId : sourceItem . commitId ,
673+ relativeTo : { type : "commit" , subject : commitId } ,
674+ side : insertSide ,
675+ } ;
676+
677+ if ( sourceItem . _tag === "TreeChanges" && sourceItem . source . parent . _tag === "Changes" )
678+ return {
679+ _tag : "CommitCreate" ,
680+ relativeTo : { type : "commit" , subject : commitId } ,
681+ side : insertSide ,
682+ changes : sourceItem . source . changes . map ( ( { change, hunkHeaders } ) =>
683+ createDiffSpec ( change , hunkHeaders ) ,
684+ ) ,
685+ message : "" ,
686+ } ;
687+
688+ if ( sourceItem . _tag === "TreeChanges" && sourceItem . source . parent . _tag === "Commit" )
689+ return {
690+ _tag : "CommitCreateFromCommittedChanges" ,
691+ sourceCommitId : sourceItem . source . parent . commitId ,
692+ relativeTo : { type : "commit" , subject : commitId } ,
693+ side : insertSide ,
694+ changes : sourceItem . source . changes . map ( ( { change, hunkHeaders } ) =>
695+ createDiffSpec ( change , hunkHeaders ) ,
696+ ) ,
697+ } ;
698+
699+ return null ;
700+ } ) ,
701+ ) ;
702+ } ;
703+
606704const CommitTarget : FC <
607705 {
608706 commitId : string ;
609707 previousCommitId : string | undefined ;
610708 nextCommitId : string | undefined ;
611709 } & useRender . ComponentProps < "div" >
612710> = ( { commitId, previousCommitId, nextCommitId, render, ...props } ) => {
613- const isNoOpCommitMove = ( sourceCommitId : string , side : InsertSide ) : boolean =>
614- sourceCommitId === commitId ||
615- ( side === "above" && previousCommitId === sourceCommitId ) ||
616- ( side === "below" && nextCommitId === sourceCommitId ) ;
617-
618711 const [ operation , dropRef ] = useDroppable ( ( { source, input, element } ) => {
619712 const sourceItem = parseDragData ( source . data ) ;
620713 if ( ! sourceItem ) return null ;
621-
622- const rubOperation = getRubOperation ( {
714+ return getCommitTargetOperation ( {
623715 sourceItem,
624- target : { _tag : "Commit" , commitId } ,
716+ commitId,
717+ previousCommitId,
718+ nextCommitId,
719+ input,
720+ element,
625721 } ) ;
626-
627- const instruction = extractInstruction (
628- attachInstruction (
629- { sourceItem } ,
630- {
631- input,
632- element,
633- operations : {
634- "reorder-before" :
635- sourceItem . _tag === "Commit" && ! isNoOpCommitMove ( sourceItem . commitId , "above" )
636- ? "available"
637- : "not-available" ,
638- "reorder-after" :
639- sourceItem . _tag === "Commit" && ! isNoOpCommitMove ( sourceItem . commitId , "below" )
640- ? "available"
641- : "not-available" ,
642- combine : rubOperation ? "available" : "not-available" ,
643- } ,
644- } ,
645- ) ,
646- ) ;
647-
648- if ( ! instruction ) return null ;
649-
650- return Match . value ( instruction . operation ) . pipe (
651- Match . when ( "combine" , ( ) : Operation | null =>
652- rubOperation ? { _tag : "Rub" , ...rubOperation } : null ,
653- ) ,
654- Match . when ( "reorder-before" , ( ) : Operation | null =>
655- sourceItem . _tag === "Commit"
656- ? {
657- _tag : "CommitMove" ,
658- subjectCommitId : sourceItem . commitId ,
659- relativeTo : { type : "commit" , subject : commitId } ,
660- side : "above" ,
661- }
662- : null ,
663- ) ,
664- Match . when ( "reorder-after" , ( ) : Operation | null =>
665- sourceItem . _tag === "Commit"
666- ? {
667- _tag : "CommitMove" ,
668- subjectCommitId : sourceItem . commitId ,
669- relativeTo : { type : "commit" , subject : commitId } ,
670- side : "below" ,
671- }
672- : null ,
673- ) ,
674- Match . exhaustive ,
675- ) ;
676722 } ) ;
677723
678724 const droppable = useRender ( {
@@ -683,39 +729,62 @@ const CommitTarget: FC<
683729 } ) ,
684730 } ) ;
685731
686- const tooltip = operation
732+ const rubTooltip = operation
687733 ? Match . value ( operation ) . pipe (
688734 Match . tag ( "Rub" , ( operation ) => rubOperationLabel ( operation ) ) ,
689- Match . tag ( "CommitMove" , ( ) => null ) ,
690735 Match . orElse ( ( ) => null ) ,
691736 )
692737 : null ;
693738
694739 return (
695740 < div className = { styles . commit } >
696- < Tooltip . Root open = { tooltip !== null } >
741+ < Tooltip . Root open = { rubTooltip !== null } >
697742 < Tooltip . Trigger render = { droppable } />
698743 < Tooltip . Portal >
699744 < Tooltip . Positioner sideOffset = { 8 } >
700745 < Tooltip . Popup className = { classes ( uiStyles . popup , uiStyles . tooltip ) } >
701- { tooltip }
746+ { rubTooltip }
702747 </ Tooltip . Popup >
703748 </ Tooltip . Positioner >
704749 </ Tooltip . Portal >
705750 </ Tooltip . Root >
706- { operation ?. _tag === "CommitMove" && (
707- < div
708- className = { classes (
709- styles . commitMoveTarget ,
710- pipe (
711- operation . side ,
712- Match . value ,
713- Match . when ( "above" , ( ) => styles . commitMoveTargetAbove ) ,
714- Match . when ( "below" , ( ) => styles . commitMoveTargetBelow ) ,
715- Match . exhaustive ,
716- ) ,
717- ) }
718- />
751+
752+ { ( operation ?. _tag === "CommitMove" ||
753+ operation ?. _tag === "CommitCreate" ||
754+ operation ?. _tag === "CommitCreateFromCommittedChanges" ) && (
755+ < Tooltip . Root open >
756+ < Tooltip . Trigger
757+ render = {
758+ < div
759+ className = { classes (
760+ styles . commitInsertionTarget ,
761+ pipe (
762+ operation . side ,
763+ Match . value ,
764+ Match . when ( "above" , ( ) => styles . commitInsertionTargetAbove ) ,
765+ Match . when ( "below" , ( ) => styles . commitInsertionTargetBelow ) ,
766+ Match . exhaustive ,
767+ ) ,
768+ ) }
769+ />
770+ }
771+ />
772+ < Tooltip . Portal >
773+ < Tooltip . Positioner sideOffset = { 8 } >
774+ < Tooltip . Popup className = { classes ( uiStyles . popup , uiStyles . tooltip ) } >
775+ { Match . value ( operation ) . pipe (
776+ Match . tag ( "CommitMove" , ( ) => "Move commit here" ) ,
777+ Match . tag (
778+ "CommitCreateFromCommittedChanges" ,
779+ "CommitCreate" ,
780+ ( ) => "Commit changes here" ,
781+ ) ,
782+ Match . exhaustive ,
783+ ) }
784+ </ Tooltip . Popup >
785+ </ Tooltip . Positioner >
786+ </ Tooltip . Portal >
787+ </ Tooltip . Root >
719788 ) }
720789 </ div >
721790 ) ;
0 commit comments