-
Notifications
You must be signed in to change notification settings - Fork 605
Update modal component branch #4109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
44e43b9
to
b41b27d
Compare
class BranchDragActions { | ||
constructor( | ||
private branchController: BranchController, | ||
private branch: Branch | ||
) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about whether I should have some
interface DropzoneActions {
accepts: //...
onDrop: //...
}
So we'd have one class for each dropzone actions. It would also mean that we could pass something that implements that interface directly to the Dropzone component, but I didn't quite want to go that far yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, makes sense. Definitely sounds like a good next step. However as you said, lets maybe save that for a more full-scale refactor of the whole drag-n-drop system 👍
export class BranchDragActionsFactory { | ||
constructor(private branchController: BranchController) {} | ||
|
||
build(branch: Branch) { | ||
return new BranchDragActions(this.branchController, branch); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using a factory so that when we go to use the drag actions, we only need to provide the relevant state, rather than having to also provide a bunch of controllers and servicies
<div class="canvas-dropzone"> | ||
<Dropzone {accepts} ondrop={onDrop}> | ||
{#snippet overlay({ hovered, activated })} | ||
<div class="new-virtual-branch" class:activated class:hovered> | ||
<div class="new-virtual-branch__content"> | ||
<div class="stimg"> | ||
<div class="stimg__hand"> | ||
{@html handSvg} | ||
</div> | ||
<div class="stimg__top-sheet"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this is quite a specialised dropzone, I chose not to have some generic component for the overlay that it uses.
@@ -159,7 +159,7 @@ | |||
kind="solid" | |||
on:click={async () => { | |||
await branchController.deleteBranch(branch.id); | |||
deleteBranchModal.close(); | |||
close(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😁 a cheeky unrelated change... if only we could work in multiple branches at the same time
const actions = $derived.by(() => { | ||
if (!$branch) return; | ||
|
||
if (commit instanceof RemoteCommit) { | ||
return () => false; | ||
} | ||
return (data: DraggableCommit) => { | ||
if (data.commit.isParentOf(commit)) { | ||
branchController.squashBranchCommit(data.branchId, commit.id); | ||
} else if (commit.isParentOf(data.commit)) { | ||
branchController.squashBranchCommit(data.branchId, data.commit.id); | ||
} | ||
}; | ||
} | ||
return commitDragActionsFactory.build($branch, commit); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was considering saying something like $derived($branch && commitDragActionsFactory.build($branch, commit))
, but I decided that I really just want to keep everything as simple as possible, and being explicit and having that sort of guard clause to me just expressed the intent much better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, makes it more readable too, etc. etc. Good call 👍
{#if actions} | ||
{@render ammendDropzone()} | ||
{:else} | ||
{@render children()} | ||
{/if} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component needs to gracefully fall back to not talking to the branchController because its used in the remoteBranch and trunk pages.
I thought about having the snippets inside the if block too, but it ended up looking too messy
{#snippet ammendDropzone()} | ||
<Dropzone accepts={actions!.acceptAmend.bind(actions)} ondrop={actions!.onAmend.bind(actions)}> | ||
{@render squashDropzone()} | ||
|
||
{#snippet overlay({ hovered, activated })} | ||
<CardOverlay {hovered} {activated} label="Ammend commit" /> | ||
{/snippet} | ||
</Dropzone> | ||
{/snippet} | ||
|
||
{#snippet squashDropzone()} | ||
<Dropzone accepts={actions!.acceptSquash.bind(actions)} ondrop={actions!.onSquash.bind(actions)}> | ||
{@render children()} | ||
|
||
{#snippet overlay({ hovered, activated })} | ||
<CardOverlay {hovered} {activated} label="Squash commit" /> | ||
{/snippet} | ||
</Dropzone> | ||
{/snippet} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If anyone has n idea about how to better express the nesting, I am all ears
function getReorderDropzoneOffset({ | ||
isFirst = false, | ||
isMiddle = false, | ||
isLast = false | ||
}: { | ||
isFirst?: boolean; | ||
isMiddle?: boolean; | ||
isLast?: boolean; | ||
}) { | ||
if (isFirst) return 12; | ||
if (isMiddle) return 6; | ||
if (isLast) return 0; | ||
return 0; | ||
} | ||
</script> | ||
|
||
{#snippet reorderDropzone(dropzone: ReorderDropzone, yOffsetPx: number)} | ||
<Dropzone accepts={dropzone.accepts.bind(dropzone)} ondrop={dropzone.onDrop.bind(dropzone)}> | ||
{#snippet overlay({ hovered, activated })} | ||
<LineOverlay {hovered} {activated} {yOffsetPx} /> | ||
{/snippet} | ||
</Dropzone> | ||
{/snippet} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't think an entire component was required for the Reordering dropzone. I'm willing to be swayed on this position though.
app/src/lib/dragging/dropzone.ts
Outdated
this.registeredOnDrop = async (e: DragEvent) => await this.onDrop(e, data); | ||
this.registeredOnDragEnter = this.onDragEnter.bind(this); | ||
this.registeredOnDragLeave = this.onDragLeave.bind(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do make the assumption that the user can't drag two things at once, but that seems like a pretty sound assumption to me
app/src/lib/dragging/dropzone.ts
Outdated
|
||
export const dropzoneRegistry = new Map<HTMLElement, Dropzone>(); | ||
|
||
export function dropzone(node: HTMLElement, opts: DropzoneConfiguration) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now only consumed by the Dropzone, so its not relevant to support a partial configuration that contains defaults
} | ||
|
||
// Private classes used to calculate distances between commtis | ||
class Indexer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to move the indexing and distance calculations into their own classes, because its now on longer required to be publicly exported (like it was when we used the old ReorderDropzone.svelte component)
4728b8e
to
976e0a1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM functionality-wise!
I have a few small niggles design-wise, but you mentioned you still need to talk to Pavel so I'll just hold off 😊
Waiting on sveltejs/svelte-eslint-parser#540 in order for our linting to support nested snippets. |
asdfasdf
f755df4
to
95e6b14
Compare
No description provided.