-
Notifications
You must be signed in to change notification settings - Fork 304
fix: resolve race condition in auth bento password animation #2759
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
base: main
Are you sure you want to change the base?
Changes from all commits
e1e2b42
5bc0677
255bad7
c1d223e
45b04e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,17 +14,37 @@ | |
| let password = $state(''); | ||
| let button: HTMLButtonElement; | ||
|
|
||
| let controller: AbortController | null = null; | ||
|
|
||
| $effect(() => { | ||
| inView( | ||
| container, | ||
| () => { | ||
| if (!isMobile()) return; | ||
|
|
||
| write('•••••••••••••', (v) => (password = v), 1000).then(() => { | ||
| animate(button, { scale: [1, 0.95, 1] }, { duration: 0.25 }); | ||
| }); | ||
| controller?.abort(); | ||
| controller = new AbortController(); | ||
|
|
||
| write('•••••••••••••', (v) => (password = v), 1000, { | ||
| signal: controller.signal, | ||
| startIndex: password.length | ||
| }) | ||
| .then(() => { | ||
| animate(button, { scale: [1, 0.95, 1] }, { duration: 0.25 }); | ||
| }) | ||
| .catch((err: unknown) => { | ||
| if (err instanceof Error && err.message !== 'Aborted') console.error(err); | ||
| }); | ||
|
|
||
| return () => { | ||
| unwrite('•••••••••••••', (v) => (password = v)); | ||
| controller?.abort(); | ||
| controller = new AbortController(); | ||
| unwrite('•••••••••••••', (v) => (password = v), 500, { | ||
| signal: controller.signal, | ||
| startIndex: password.length | ||
| }).catch((err: unknown) => { | ||
| if (err instanceof Error && err.message !== 'Aborted') console.error(err); | ||
| }); | ||
| }; | ||
| }, | ||
| { amount: 'all' } | ||
|
|
@@ -33,13 +53,35 @@ | |
| hover(container, () => { | ||
| if (isMobile()) return; | ||
|
|
||
| write('•••••••••••••', (v) => (password = v), 1000).then(() => { | ||
| animate(button, { scale: [1, 0.95, 1] }, { duration: 0.25 }); | ||
| }); | ||
| controller?.abort(); | ||
| controller = new AbortController(); | ||
|
|
||
| write('•••••••••••••', (v) => (password = v), 1000, { | ||
| signal: controller.signal, | ||
| startIndex: password.length | ||
| }) | ||
| .then(() => { | ||
| animate(button, { scale: [1, 0.95, 1] }, { duration: 0.25 }); | ||
| }) | ||
| .catch((err: unknown) => { | ||
| if (err instanceof Error && err.message !== 'Aborted') console.error(err); | ||
| }); | ||
|
|
||
| return () => { | ||
| unwrite('•••••••••••••', (v) => (password = v)); | ||
| controller?.abort(); | ||
| controller = new AbortController(); | ||
| unwrite('•••••••••••••', (v) => (password = v), 500, { | ||
| signal: controller.signal, | ||
| startIndex: password.length | ||
| }).catch((err: unknown) => { | ||
| if (err instanceof Error && err.message !== 'Aborted') console.error(err); | ||
| }); | ||
| }; | ||
| }); | ||
|
|
||
| return () => { | ||
| controller?.abort(); | ||
| }; | ||
|
Comment on lines
+82
to
+84
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# First, find and examine the auth.svelte file
fd -t f "auth.svelte" -x cat -n {}Repository: appwrite/website Length of output: 8980 🏁 Script executed: #!/bin/bash
# Search for inView and hover usage in the codebase
rg -n "inView\|hover" src/routes/\(marketing\)/\(components\)/bento/\(animations\)/ -A 3 -B 1Repository: appwrite/website Length of output: 42 🌐 Web query:
💡 Result: If you mean Motion (the
Svelte example (with proper cleanup)<script>
import { onMount } from "svelte";
import { animate, hover, inView } from "motion";
let el;
onMount(() => {
// hover: return runs on hover end
const cancelHover = hover(el, (element) => {
const a = animate(element, { scale: 1.05 }, { duration: 0.15 });
return () => a.stop(); // hover end
});
// inView: return runs when leaving viewport
const stopInView = inView(el, (element) => {
const a = animate(element, { opacity: 1, y: 0 }, { duration: 0.25 });
return () => a.stop(); // left viewport
});
// Svelte teardown
return () => {
cancelHover();
stopInView();
};
});
</script>
<div bind:this={el} style="opacity:0; transform: translateY(12px);">
Watch me
</div>Notes that often trip people up
Sources: Motion hover docs [2], Motion inView docs [3], Motion upgrade guide (v12 signature change) [1]. Call the stop functions returned by The Required fix $effect(() => {
- inView(
+ const stopInView = inView(
container,
() => {
// ...
},
{ amount: 'all' }
);
- hover(container, () => {
+ const stopHover = hover(container, () => {
// ...
});
return () => {
controller?.abort();
+ stopInView();
+ stopHover();
};
});🤖 Prompt for AI Agents |
||
| }); | ||
| </script> | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.