Řambo
Explore posts from serversTTCTheo's Typesafe Cult
•Created by Řambo on 8/2/2023 in #questions
Improve performance - Avoid Re-renders when changing range input used as a volume slider
alright thanks
9 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 8/2/2023 in #questions
Improve performance - Avoid Re-renders when changing range input used as a volume slider
import { useVolume } from '@/VolumeContext';
import React, { useCallback } from 'react';
const VolumeSlider = () => {
const { volume, updateVolume } = useVolume();
const handleVolumeChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const newVolume = parseFloat(event.target.value);
updateVolume(newVolume);
},
[updateVolume]
);
return (
<input
type="range"
min={0}
max={1}
step={0.01}
value={volume}
onChange={handleVolumeChange}
className="accent-gold"
/>
);
};
export default VolumeSlider;
import { useVolume } from '@/VolumeContext';
import React, { useCallback } from 'react';
const VolumeSlider = () => {
const { volume, updateVolume } = useVolume();
const handleVolumeChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const newVolume = parseFloat(event.target.value);
updateVolume(newVolume);
},
[updateVolume]
);
return (
<input
type="range"
min={0}
max={1}
step={0.01}
value={volume}
onChange={handleVolumeChange}
className="accent-gold"
/>
);
};
export default VolumeSlider;
9 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 8/2/2023 in #questions
Improve performance - Avoid Re-renders when changing range input used as a volume slider
import { ReactNode, createContext, useContext, useState } from 'react';
type VolumeContextData = {
volume: number;
updateVolume: (newVolume: number) => void;
};
const VolumeContext = createContext<VolumeContextData>({
volume: 0.5,
updateVolume: () => {},
});
export function useVolume() {
return useContext(VolumeContext);
}
type VolumeProviderProps = {
children: ReactNode;
};
export function VolumeProvider({ children }: VolumeProviderProps) {
const [volume, setVolume] = useState(0.5);
const updateVolume = (newVolume: number) => {
setVolume(newVolume);
};
return (
<VolumeContext.Provider value={{ volume, updateVolume }}>
{children}
</VolumeContext.Provider>
);
}
import { ReactNode, createContext, useContext, useState } from 'react';
type VolumeContextData = {
volume: number;
updateVolume: (newVolume: number) => void;
};
const VolumeContext = createContext<VolumeContextData>({
volume: 0.5,
updateVolume: () => {},
});
export function useVolume() {
return useContext(VolumeContext);
}
type VolumeProviderProps = {
children: ReactNode;
};
export function VolumeProvider({ children }: VolumeProviderProps) {
const [volume, setVolume] = useState(0.5);
const updateVolume = (newVolume: number) => {
setVolume(newVolume);
};
return (
<VolumeContext.Provider value={{ volume, updateVolume }}>
{children}
</VolumeContext.Provider>
);
}
9 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 8/2/2023 in #questions
Improve performance - Avoid Re-renders when changing range input used as a volume slider
import { useVolume } from '@/VolumeContext';
import { ElementRef, useEffect, useState } from 'react';
function useSound() {
const [audio, setAudio] = useState<ElementRef<'audio'> | null>(null);
const [isPlaying, setIsPlaying] = useState(false);
const { volume } = useVolume();
useEffect(() => {
setAudio(new Audio());
}, []);
useEffect(() => {
if (!audio) return;
const handleEnded = () => {
setIsPlaying(false);
};
audio.addEventListener('ended', handleEnded);
return () => {
if (audio) {
audio.removeEventListener('ended', handleEnded);
}
};
}, [audio]);
useEffect(() => {
if (!audio) return;
console.log('USESOUND VOLUME CHANGE');
audio.volume = volume;
}, [audio, volume]);
const play = (src: string) => {
if (!audio) return;
audio.src = src;
audio.play();
setIsPlaying(true);
};
const pause = () => {
if (!audio) return;
audio.pause();
setIsPlaying(false);
};
return { play, pause, isPlaying };
}
export default useSound;
import { useVolume } from '@/VolumeContext';
import { ElementRef, useEffect, useState } from 'react';
function useSound() {
const [audio, setAudio] = useState<ElementRef<'audio'> | null>(null);
const [isPlaying, setIsPlaying] = useState(false);
const { volume } = useVolume();
useEffect(() => {
setAudio(new Audio());
}, []);
useEffect(() => {
if (!audio) return;
const handleEnded = () => {
setIsPlaying(false);
};
audio.addEventListener('ended', handleEnded);
return () => {
if (audio) {
audio.removeEventListener('ended', handleEnded);
}
};
}, [audio]);
useEffect(() => {
if (!audio) return;
console.log('USESOUND VOLUME CHANGE');
audio.volume = volume;
}, [audio, volume]);
const play = (src: string) => {
if (!audio) return;
audio.src = src;
audio.play();
setIsPlaying(true);
};
const pause = () => {
if (!audio) return;
audio.pause();
setIsPlaying(false);
};
return { play, pause, isPlaying };
}
export default useSound;
9 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 8/2/2023 in #questions
Improve performance - Avoid Re-renders when changing range input used as a volume slider
function Quote({ quote, champName, quoteAudioURL, skin }: Props) {
const { isPlaying, play, pause } = useSound();
return (
<div className="relative h-full rounded-md overflow-hidden z-0 flex items-center p-4">
<Image
src={skin}
alt="Champion Skin"
fill
className="object-cover -z-10"
/>
<div className="absolute inset-0 bg-black bg-opacity-60" />
<div className="z-10 flex items-center gap-4">
{isPlaying ? (
<PauseCircle
size={56}
color="white"
className="flex-shrink-0 cursor-pointer"
onClick={pause}
/>
) : (
<PlayCircle
size={56}
color="white"
className="flex-shrink-0 cursor-pointer"
onClick={() => play(quoteAudioURL)}
/>
)}
<div>
<p
className={`${spiegel.variable} line-clamp-3 text-xl font-spiegel`}
>
{quote}
</p>
<p
className={`${spiegel.variable} text-gray-400 font-spiegel font-semibold tracking-wide`}
>
{champName}
</p>
</div>
</div>
</div>
);
}
function Quote({ quote, champName, quoteAudioURL, skin }: Props) {
const { isPlaying, play, pause } = useSound();
return (
<div className="relative h-full rounded-md overflow-hidden z-0 flex items-center p-4">
<Image
src={skin}
alt="Champion Skin"
fill
className="object-cover -z-10"
/>
<div className="absolute inset-0 bg-black bg-opacity-60" />
<div className="z-10 flex items-center gap-4">
{isPlaying ? (
<PauseCircle
size={56}
color="white"
className="flex-shrink-0 cursor-pointer"
onClick={pause}
/>
) : (
<PlayCircle
size={56}
color="white"
className="flex-shrink-0 cursor-pointer"
onClick={() => play(quoteAudioURL)}
/>
)}
<div>
<p
className={`${spiegel.variable} line-clamp-3 text-xl font-spiegel`}
>
{quote}
</p>
<p
className={`${spiegel.variable} text-gray-400 font-spiegel font-semibold tracking-wide`}
>
{champName}
</p>
</div>
</div>
</div>
);
}
9 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 8/2/2023 in #questions
Improve performance - Avoid Re-renders when changing range input used as a volume slider
export default function Home({
championData,
}: InferGetStaticPropsType<typeof getStaticProps>) {
const [query, setQuery] = useState('');
const [visibleItems, setVisibleItems] = useState(90);
const queriedData = useFuzzySearch(
query,
['quote', 'name'],
championData,
visibleItems
);
const containerRef = useRef<HTMLDivElement>(null);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setQuery(e.target.value);
containerRef.current?.scrollTo({ top: 0, behavior: 'instant' });
const newVisibleItems = visibleItems === 90 ? visibleItems : 90;
setVisibleItems(newVisibleItems);
};
return (
<VolumeProvider>
<section
ref={containerRef}
className="flex flex-col gap-4 max-h-screen overflow-y-auto no-scrollbar"
>
<VolumeSlider />
<input
className={}
type="text"
value={query}
placeholder="Search quotes..."
onChange={handleChange}
/>
<InfiniteScroller
loadMore={() => {
setVisibleItems((prevVisibleItems) => prevVisibleItems + 50);
}}
loader={<p>Loading...</p>}
rootMargin="200px"
hasMore={queriedData.length >= visibleItems}
>
<List
items={queriedData.slice(0, visibleItems)}
keyExtractor={({ name, quote, url }) => name + quote + url}
className="grid gap-4 auto-rows-fr sm:grid-cols-2 px-4 xl:grid-cols-3"
renderItem={({ name, icon, quote, url, skin }, i) => (
<Quote
quote={quote}
champName={name}
champIcon={icon}
quoteAudioURL={url}
skin={skin}
/>
)}
/>
</InfiniteScroller>
</section>
</VolumeProvider>
);
}
export default function Home({
championData,
}: InferGetStaticPropsType<typeof getStaticProps>) {
const [query, setQuery] = useState('');
const [visibleItems, setVisibleItems] = useState(90);
const queriedData = useFuzzySearch(
query,
['quote', 'name'],
championData,
visibleItems
);
const containerRef = useRef<HTMLDivElement>(null);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setQuery(e.target.value);
containerRef.current?.scrollTo({ top: 0, behavior: 'instant' });
const newVisibleItems = visibleItems === 90 ? visibleItems : 90;
setVisibleItems(newVisibleItems);
};
return (
<VolumeProvider>
<section
ref={containerRef}
className="flex flex-col gap-4 max-h-screen overflow-y-auto no-scrollbar"
>
<VolumeSlider />
<input
className={}
type="text"
value={query}
placeholder="Search quotes..."
onChange={handleChange}
/>
<InfiniteScroller
loadMore={() => {
setVisibleItems((prevVisibleItems) => prevVisibleItems + 50);
}}
loader={<p>Loading...</p>}
rootMargin="200px"
hasMore={queriedData.length >= visibleItems}
>
<List
items={queriedData.slice(0, visibleItems)}
keyExtractor={({ name, quote, url }) => name + quote + url}
className="grid gap-4 auto-rows-fr sm:grid-cols-2 px-4 xl:grid-cols-3"
renderItem={({ name, icon, quote, url, skin }, i) => (
<Quote
quote={quote}
champName={name}
champIcon={icon}
quoteAudioURL={url}
skin={skin}
/>
)}
/>
</InfiniteScroller>
</section>
</VolumeProvider>
);
}
9 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 2/9/2023 in #questions
Vercel deployment - React Router
function App() {
const [isGameOver, setIsGameOver] = useState(false);
const navbarRef = useRef<HTMLElement | null>(null);
return (
<Routes>
<Route element={<Root isGameOver={isGameOver} navbarRef={navbarRef} />}>
<Route index element={<Home />}></Route>
<Route
path="/level/:id"
element={
<Level
isGameOver={isGameOver}
setIsGameOver={setIsGameOver}
navbarRef={navbarRef}
/>
}
></Route>
</Route>
<Route path="*" element={<Error />}></Route>
</Routes>
);
}
function App() {
const [isGameOver, setIsGameOver] = useState(false);
const navbarRef = useRef<HTMLElement | null>(null);
return (
<Routes>
<Route element={<Root isGameOver={isGameOver} navbarRef={navbarRef} />}>
<Route index element={<Home />}></Route>
<Route
path="/level/:id"
element={
<Level
isGameOver={isGameOver}
setIsGameOver={setIsGameOver}
navbarRef={navbarRef}
/>
}
></Route>
</Route>
<Route path="*" element={<Error />}></Route>
</Routes>
);
}
10 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 2/9/2023 in #questions
Vercel deployment - React Router
no
10 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 2/9/2023 in #questions
Vercel deployment - React Router
10 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 12/14/2022 in #questions
How to deal with constantly updating data
alright thanks
7 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 12/14/2022 in #questions
How to deal with constantly updating data
just react
7 replies
TTCTheo's Typesafe Cult
•Created by Řambo on 12/14/2022 in #questions
How to deal with constantly updating data
what if im not using nextjs
7 replies