Skip to content
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

➕ Add skip feature to workaround https://github.com/j… #144

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function useSound(
soundEnabled,
interrupt,
onload,
skip,
...delegated
}?: HookOptions
): ReturnedValue;
45 changes: 19 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import useOnMount from './use-on-mount';
import useMount from 'use-mount';

import { HookOptions, PlayOptions, PlayFunction, ReturnedValue } from './types';

Expand All @@ -13,11 +13,11 @@ export default function useSound<T = any>(
soundEnabled = true,
interrupt = false,
onload,
skip = false,
...delegated
}: HookOptions<T> = {} as HookOptions
) {
const HowlConstructor = React.useRef<HowlStatic | null>(null);
const isMounted = React.useRef(false);

const [duration, setDuration] = React.useState<number | null>(null);

Expand All @@ -29,7 +29,7 @@ export default function useSound<T = any>(
onload.call(this);
}

if (isMounted.current) {
if (isMounted) {
// @ts-ignore
setDuration(this.duration() * 1000);
}
Expand All @@ -39,29 +39,22 @@ export default function useSound<T = any>(
};

// We want to lazy-load Howler, since sounds can't play on load anyway.
useOnMount(() => {
import('howler').then(mod => {
if (!isMounted.current) {
// Depending on the module system used, `mod` might hold
// the export directly, or it might be under `default`.
HowlConstructor.current = mod.Howl ?? mod.default.Howl;

isMounted.current = true;

new HowlConstructor.current({
src: Array.isArray(src) ? src : [src],
volume,
rate: playbackRate,
onload: handleLoad,
...delegated,
});
}
});

return () => {
isMounted.current = false;
};
});
const { isMounted } = useMount(async () => {
if (!skip) {
const mod = await import('howler');
// Depending on the module system used, `mod` might hold
// the export directly, or it might be under `default`.
HowlConstructor.current = mod.Howl ?? mod.default.Howl;

new HowlConstructor.current({
src: Array.isArray(src) ? src : [src],
volume,
rate: playbackRate,
onload: handleLoad,
...delegated,
});
}
}, [skip]);

// When the `src` changes, we have to do a whole thing where we recreate
// the Howl instance. This is because Howler doesn't expose a way to
Expand Down
1 change: 1 addition & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface HookOptions {
interrupt?: boolean;
soundEnabled?: boolean;
sprite?: SpriteMap;
skip?: boolean;
onload?: () => void;
}
export interface PlayOptions {
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type HookOptions<T = any> = T & {
interrupt?: boolean;
soundEnabled?: boolean;
sprite?: SpriteMap;
skip?: boolean;
onload?: () => void;
};

Expand Down
8 changes: 8 additions & 0 deletions src/use-mount.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DependencyList } from 'react';
declare const useMount: (
callback?: Function,
deps?: DependencyList
) => {
isMounted: boolean;
};
export default useMount;
24 changes: 24 additions & 0 deletions src/use-mount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { DependencyList, useRef } from 'react';
import useOnMount from './use-on-mount';

const useMount = (callback: Function = () => {}, deps: DependencyList = []) => {
// Ref to track component mount state
const isMounted = useRef(false);

useOnMount(() => {
// Component has mounted, set the flag
if (!isMounted.current) {
isMounted.current = true;
callback();
}

// Cleanup function to reset the flag when component unmounts
return () => {
isMounted.current = false;
};
}, deps);

return { isMounted: isMounted.current };
};

export default useMount;
8 changes: 6 additions & 2 deletions src/use-on-mount.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
import * as React from 'react';
export default function useOnMount(callback: React.EffectCallback): void;
import { EffectCallback, DependencyList } from 'react';
declare const useOnMount: (
callback: EffectCallback,
deps?: DependencyList
) => void;
export default useOnMount;
10 changes: 6 additions & 4 deletions src/use-on-mount.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as React from 'react';
import { useEffect, EffectCallback, DependencyList } from 'react';

export default function useOnMount(callback: React.EffectCallback) {
React.useEffect(callback, []);
}
const useOnMount = (callback: EffectCallback, deps: DependencyList = []) => {
useEffect(callback, deps);
};

export default useOnMount;