22 Commits

Author SHA1 Message Date
MAZE
f877e49763 chore(release): 1.3.0 2024-02-01 20:36:46 +03:30
MAZE
f1d212abc8 chore: add binaural beats 2024-02-01 20:16:47 +03:30
MAZE
38f6f7dbe6 chore: add more sounds 2024-01-30 15:29:55 +03:30
MAZE
937bf29d09 chore: add more sounds 2024-01-30 00:04:59 +03:30
MAZE
e2172fd2bb chore: add more sounds 2024-01-29 23:49:07 +03:30
MAZE
1f12afa394 chore: add more sounds 2024-01-29 23:36:44 +03:30
MAZE
d96461d1ea fix: remove fading 2024-01-29 19:16:46 +03:30
MAZE
5467bbbc24 feat: add fading to intro and outro 2024-01-29 19:01:36 +03:30
MAZE
32da26ccfc fix: undo changes 2024-01-28 19:39:57 +03:30
MAZE
81f33d9d37 fix: add media session 2024-01-28 19:33:52 +03:30
MAZE
463667c868 fix: connect audio context to audio element 2024-01-28 19:28:55 +03:30
MAZE
b77c817db2 refactor: remove unmute and media session 2024-01-28 15:45:27 +03:30
MAZE
216b913ccd fix: add media session 2024-01-28 15:40:51 +03:30
MAZE
e422b52436 fix: add unmute for iOS 2024-01-28 15:35:09 +03:30
MAZE
1f635348e3 refactor: remove media session 2024-01-28 15:23:58 +03:30
MAZE
889962babe fix: add audio element 2024-01-28 15:15:30 +03:30
MAZE
5e0a84259f feat: add media session 2024-01-28 15:05:13 +03:30
MAZE
8e4d0531e0 fix: resume audio 2024-01-28 14:44:31 +03:30
MAZE
cd05704a73 chore: add more sounds 2024-01-22 19:58:06 +03:30
MAZE
01b4bdbb57 chore: add more sounds 2024-01-22 18:31:23 +03:30
MAZE
f682a910da feat: add loader for favorites 2024-01-09 16:09:07 +03:30
MAZE
a33ae450cf fix: increase decimal 2024-01-09 15:59:57 +03:30
40 changed files with 264 additions and 21 deletions

View File

@@ -45,6 +45,7 @@
"sort-keys-fix/sort-keys-fix": ["warn", "asc"],
"sort-destructure-keys/sort-destructure-keys": "warn",
"jsx-a11y/no-static-element-interactions": "off",
"jsx-a11y/media-has-caption": "off",
"react/jsx-sort-props": [
"warn",
{

View File

@@ -2,6 +2,45 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [1.3.0](https://github.com/remvze/moodist/compare/v1.2.0...v1.3.0) (2024-02-01)
### ♻️ Code Refactoring
* remove media session ([1f63534](https://github.com/remvze/moodist/commit/1f635348e3e5cf73ee76e1c5fac7b5f5b7f7ea6a))
* remove unmute and media session ([b77c817](https://github.com/remvze/moodist/commit/b77c817db25e1a738b6770b1ae86d792e0d42240))
### ✨ Features
* add fading to intro and outro ([5467bbb](https://github.com/remvze/moodist/commit/5467bbbc2437a5504e157122a995ad7a565ff0b8))
* add loader for favorites ([f682a91](https://github.com/remvze/moodist/commit/f682a910da97eb53cfb90ce955e953f05088e686))
* add media session ([5e0a842](https://github.com/remvze/moodist/commit/5e0a84259ff5586700c4e10087485d905be7ccee))
### 🐛 Bug Fixes
* add audio element ([889962b](https://github.com/remvze/moodist/commit/889962babe6e940ff283a41b145620d2a0477c70))
* add media session ([81f33d9](https://github.com/remvze/moodist/commit/81f33d9d375f63b4dd0bf58ad28a72354d85706e))
* add media session ([216b913](https://github.com/remvze/moodist/commit/216b913ccd0a7dfe0d03575f842aac9711ef0216))
* add unmute for iOS ([e422b52](https://github.com/remvze/moodist/commit/e422b52436c7dfc0b6cf866afa2b74dc219dcf2f))
* connect audio context to audio element ([463667c](https://github.com/remvze/moodist/commit/463667c868371540c46c9007e686961f9a4be7e5))
* increase decimal ([a33ae45](https://github.com/remvze/moodist/commit/a33ae450cf2c883228c76d04df8df75839c12753))
* remove fading ([d96461d](https://github.com/remvze/moodist/commit/d96461d1ea83c72bfe651d84cf34fabc029c200e))
* resume audio ([8e4d053](https://github.com/remvze/moodist/commit/8e4d0531e0e9aaf4e52b3b3a8666b74ff0c0222e))
* undo changes ([32da26c](https://github.com/remvze/moodist/commit/32da26ccfc0c5bdbe031e26ea48363ea0d8a7b23))
### 🚚 Chores
* add binaural beats ([f1d212a](https://github.com/remvze/moodist/commit/f1d212abc8b69a614bbdc4a23876e2eab7cbb574))
* add more sounds ([38f6f7d](https://github.com/remvze/moodist/commit/38f6f7dbe6898ed78e51eb3f0c7936f003ddca08))
* add more sounds ([937bf29](https://github.com/remvze/moodist/commit/937bf29d09cbce20ea0b6b0c87879f3a7dd1d497))
* add more sounds ([e2172fd](https://github.com/remvze/moodist/commit/e2172fd2bbd0e12a705c9efc98c72ad99d86d006))
* add more sounds ([1f12afa](https://github.com/remvze/moodist/commit/1f12afa3943154d70145ef6adc6aeee79f7a7af3))
* add more sounds ([cd05704](https://github.com/remvze/moodist/commit/cd05704a73ffb33aa0ccf5d789328a4cefc320f1))
* add more sounds ([01b4bdb](https://github.com/remvze/moodist/commit/01b4bdbb572285984bcdc9bb94c1a1b6dd2630c5))
## [1.2.0](https://github.com/remvze/moodist/compare/v1.1.0...v1.2.0) (2024-01-04)

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "moodist",
"version": "1.2.0",
"version": "1.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "moodist",
"version": "1.2.0",
"version": "1.3.0",
"dependencies": {
"@astrojs/react": "^3.0.3",
"@floating-ui/react": "0.26.0",

View File

@@ -1,7 +1,7 @@
{
"name": "moodist",
"type": "module",
"version": "1.2.0",
"version": "1.3.0",
"scripts": {
"dev": "astro dev",
"start": "astro dev",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,7 @@
import { useMemo } from 'react';
import { useMemo, useEffect } from 'react';
import { useShallow } from 'zustand/react/shallow';
import { BiSolidHeart } from 'react-icons/bi/index';
import { Howler } from 'howler';
import { useSoundStore } from '@/store';
@@ -36,6 +37,22 @@ export function App() {
);
}, [favorites, categories]);
useEffect(() => {
const onChange = () => {
const { ctx } = Howler;
if (ctx && !document.hidden) {
setTimeout(() => {
ctx.resume();
}, 100);
}
};
document.addEventListener('visibilitychange', onChange, false);
return () => document.removeEventListener('visibilitychange', onChange);
}, []);
const allCategories = useMemo(() => {
const favorites = [];

View File

@@ -23,7 +23,7 @@ export function ShareLinkModal({ onClose, show }: ShareLinkModalProps) {
.map(sound => ({
id: sound,
isSelected: sounds[sound].isSelected,
volume: sounds[sound].volume.toFixed(1),
volume: sounds[sound].volume.toFixed(2),
}))
.filter(sound => sound.isSelected);
}, [sounds, JSON.stringify(sounds)]); // eslint-disable-line

View File

@@ -5,7 +5,7 @@ import { Range } from './range';
import { Favorite } from './favorite';
import { useSound } from '@/hooks/use-sound';
import { useSoundStore } from '@/store';
import { useSoundStore, useLoadingStore } from '@/store';
import { cn } from '@/helpers/styles';
import styles from './sound.module.css';
@@ -37,6 +37,8 @@ export function Sound({
const volume = useSoundStore(state => state.sounds[id].volume);
const isSelected = useSoundStore(state => state.sounds[id].isSelected);
const isLoading = useLoadingStore(state => state.loaders[src]);
const sound = useSound(src, { loop: true, volume });
useEffect(() => {
@@ -80,7 +82,7 @@ export function Sound({
>
<Favorite id={id} />
<div className={styles.icon}>
{sound.isLoading ? (
{isLoading ? (
<span className={styles.spinner}>
<ImSpinner9 />
</span>

View File

@@ -6,11 +6,22 @@ import { places } from './sounds/places';
import { transport } from './sounds/transport';
import { things } from './sounds/things';
import { noise } from './sounds/noise';
import { binaural } from './sounds/binaural';
import type { Categories } from './types';
export const sounds: {
categories: Categories;
} = {
categories: [nature, rain, animals, urban, places, transport, things, noise],
categories: [
nature,
rain,
animals,
urban,
places,
transport,
things,
noise,
binaural,
],
};

View File

@@ -1,5 +1,17 @@
import { GiCricket, GiSeagull, GiWolfHead, GiOwl } from 'react-icons/gi/index';
import { FaDog, FaFrog, FaHorseHead, FaCat } from 'react-icons/fa/index';
import {
GiCricket,
GiSeagull,
GiWolfHead,
GiOwl,
GiWhaleTail,
} from 'react-icons/gi/index';
import {
FaDog,
FaFrog,
FaHorseHead,
FaCat,
FaCrow,
} from 'react-icons/fa/index';
import { PiBirdFill, PiDogBold } from 'react-icons/pi/index';
import type { Category } from '../types';
@@ -62,6 +74,18 @@ export const animals: Category = {
label: 'Cat Purring',
src: '/sounds/animals/cat-purring.mp3',
},
{
icon: <FaCrow />,
id: 'crows',
label: 'Crows',
src: '/sounds/animals/crows.mp3',
},
{
icon: <GiWhaleTail />,
id: 'whale',
label: 'Whale',
src: '/sounds/animals/whale.mp3',
},
],
title: 'Animals',
};

View File

@@ -0,0 +1,42 @@
import { TbWaveSine } from 'react-icons/tb/index';
import { BsSoundwave } from 'react-icons/bs/index';
import type { Category } from '../types';
export const binaural: Category = {
icon: <TbWaveSine />,
id: 'binaural',
sounds: [
{
icon: <BsSoundwave />,
id: 'binaural-delta',
label: 'Delta',
src: '/sounds/binaural/binaural-delta.wav',
},
{
icon: <BsSoundwave />,
id: 'binaural-theta',
label: 'Theta',
src: '/sounds/binaural/binaural-theta.wav',
},
{
icon: <BsSoundwave />,
id: 'binaural-alpha',
label: 'Alpha',
src: '/sounds/binaural/binaural-alpha.wav',
},
{
icon: <BsSoundwave />,
id: 'binaural-beta',
label: 'Beta',
src: '/sounds/binaural/binaural-beta.wav',
},
{
icon: <BsSoundwave />,
id: 'binaural-gamma',
label: 'Gamma',
src: '/sounds/binaural/binaural-gamma.wav',
},
],
title: 'Binaural Beats',
};

View File

@@ -40,7 +40,7 @@ export const nature: Category = {
src: '/sounds/nature/howling-wind.mp3',
},
{
icon: <FaWind />,
icon: <BiSolidTree />,
id: 'wind-in-trees',
label: 'Wind in Trees',
src: '/sounds/nature/wind-in-trees.mp3',

View File

@@ -1,11 +1,14 @@
import { BiSolidCoffeeAlt, BiSolidPlaneAlt } from 'react-icons/bi/index';
import { FaChurch } from 'react-icons/fa/index';
import { TbScubaMask } from 'react-icons/tb/index';
import { FaChurch, FaSubway, FaShoppingBasket } from 'react-icons/fa/index';
import { TbScubaMask, TbBeerFilled } from 'react-icons/tb/index';
import { GiVillage, GiCarousel } from 'react-icons/gi/index';
import {
MdTempleBuddhist,
MdConstruction,
MdLocationPin,
} from 'react-icons/md/index';
import { HiOfficeBuilding } from 'react-icons/hi/index';
import { AiFillExperiment } from 'react-icons/ai/index';
import type { Category } from '../types';
@@ -49,6 +52,48 @@ export const places: Category = {
label: 'Underwater',
src: '/sounds/places/underwater.mp3',
},
{
icon: <TbBeerFilled />,
id: 'crowded-bar',
label: 'Crowded Bar',
src: '/sounds/places/crowded-bar.mp3',
},
{
icon: <GiVillage />,
id: 'night-village',
label: 'Night Village',
src: '/sounds/places/night-village.mp3',
},
{
icon: <FaSubway />,
id: 'subway-station',
label: 'Subway Station',
src: '/sounds/places/subway-station.mp3',
},
{
icon: <HiOfficeBuilding />,
id: 'office',
label: 'Office',
src: '/sounds/places/office.mp3',
},
{
icon: <FaShoppingBasket />,
id: 'supermarket',
label: 'Supermarket',
src: '/sounds/places/supermarket.mp3',
},
{
icon: <GiCarousel />,
id: 'carousel',
label: 'Carousel',
src: '/sounds/places/carousel.mp3',
},
{
icon: <AiFillExperiment />,
id: 'laboratory',
label: 'Laboratory',
src: '/sounds/places/laboratory.mp3',
},
],
title: 'Places',
};

View File

@@ -1,9 +1,11 @@
import { GiWindchimes } from 'react-icons/gi/index';
import { GiWindchimes, GiFilmProjector } from 'react-icons/gi/index';
import { BsFillKeyboardFill } from 'react-icons/bs/index';
import { FaKeyboard, FaClock, FaFan } from 'react-icons/fa/index';
import { MdSmartToy } from 'react-icons/md/index';
import { MdSmartToy, MdWaterDrop, MdRadio } from 'react-icons/md/index';
import { TbBowlFilled } from 'react-icons/tb/index';
import { RiFilePaper2Fill } from 'react-icons/ri/index';
import { RiFilePaper2Fill, RiBubbleChartFill } from 'react-icons/ri/index';
import { BiSolidDryer } from 'react-icons/bi/index';
import { IoIosRadio } from 'react-icons/io/index';
import type { Category } from '../types';
@@ -53,6 +55,42 @@ export const things: Category = {
label: 'Ceiling Fan',
src: '/sounds/things/ceiling-fan.mp3',
},
{
icon: <BiSolidDryer />,
id: 'dryer',
label: 'Dryer',
src: '/sounds/things/dryer.mp3',
},
{
icon: <GiFilmProjector />,
id: 'slide-projector',
label: 'Slide Projector',
src: '/sounds/things/slide-projector.mp3',
},
{
icon: <MdWaterDrop />,
id: 'boiling-water',
label: 'Boiling Water',
src: '/sounds/things/boiling-water.mp3',
},
{
icon: <RiBubbleChartFill />,
id: 'bubbles',
label: 'Bubbles',
src: '/sounds/things/bubbles.mp3',
},
{
icon: <MdRadio />,
id: 'tuning-radio',
label: 'Tuning Radio',
src: '/sounds/things/tuning-radio.mp3',
},
{
icon: <IoIosRadio />,
id: 'morse-code',
label: 'Morse Code',
src: '/sounds/things/morse-code.mp3',
},
],
title: 'Things',
};

View File

@@ -2,6 +2,7 @@ import { BiSolidTraffic } from 'react-icons/bi/index';
import { FaCity, FaRoad } from 'react-icons/fa/index';
import { PiRoadHorizonFill, PiSirenBold } from 'react-icons/pi/index';
import { BsSoundwave, BsPeopleFill } from 'react-icons/bs/index';
import { RiSparkling2Fill } from 'react-icons/ri/index';
import type { Category } from '../types';
@@ -45,6 +46,12 @@ export const urban: Category = {
label: 'Traffic',
src: '/sounds/urban/traffic.mp3',
},
{
icon: <RiSparkling2Fill />,
id: 'fireworks',
label: 'Fireworks',
src: '/sounds/urban/fireworks.mp3',
},
],
title: 'Urban',
};

View File

@@ -1,6 +1,7 @@
import { useMemo, useEffect, useCallback, useState } from 'react';
import { Howl } from 'howler';
import { useLoadingStore } from '@/store';
import { useSSR } from './use-ssr';
export function useSound(
@@ -8,7 +9,9 @@ export function useSound(
options: { loop?: boolean; volume?: number } = {},
) {
const [hasLoaded, setHasLoaded] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const isLoading = useLoadingStore(state => state.loaders[src]);
const setIsLoading = useLoadingStore(state => state.set);
const { isBrowser } = useSSR();
const sound = useMemo<Howl | null>(() => {
let sound: Howl | null = null;
@@ -16,7 +19,7 @@ export function useSound(
if (isBrowser) {
sound = new Howl({
onload: () => {
setIsLoading(false);
setIsLoading(src, false);
setHasLoaded(true);
},
preload: false,
@@ -25,7 +28,7 @@ export function useSound(
}
return sound;
}, [src, isBrowser]);
}, [src, isBrowser, setIsLoading]);
useEffect(() => {
if (sound) {
@@ -41,7 +44,7 @@ export function useSound(
const play = useCallback(() => {
if (sound) {
if (!hasLoaded && !isLoading) {
setIsLoading(true);
setIsLoading(src, true);
sound.load();
}
@@ -49,7 +52,7 @@ export function useSound(
sound.play();
}
}
}, [sound, hasLoaded, isLoading]);
}, [src, setIsLoading, sound, hasLoaded, isLoading]);
const stop = useCallback(() => {
if (sound) sound.stop();

View File

@@ -1 +1,2 @@
export { useSoundStore } from './sound';
export { useLoadingStore } from './loading';

View File

@@ -0,0 +1,13 @@
import { create } from 'zustand';
interface LoadingStore {
loaders: Record<string, boolean>;
set: (id: string, value: boolean) => void;
}
export const useLoadingStore = create<LoadingStore>()((set, get) => ({
loaders: {},
set(id: string, value: boolean) {
set({ loaders: { ...get().loaders, [id]: value } });
},
}));