Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
chore: try to memo
Browse files Browse the repository at this point in the history
  • Loading branch information
dantetemplar committed Nov 30, 2024
1 parent 5c8aae0 commit 11c7885
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 31 deletions.
41 changes: 38 additions & 3 deletions frontend/src/components/mahjong/Controls.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { cn } from '@/lib/utils'
import React, { useEffect, useState } from 'react'
import useSound from 'use-sound'
import clickSound from './assets/click.mp3'
import styles from './Mahjong.module.scss'
Expand All @@ -16,27 +17,60 @@ export function Controls({
platesMiddle,
platesTrailing,
className,
startTime,
}: {
platesLeading?: Plate[]
platesMiddle?: Plate[]
platesTrailing?: Plate[]
className?: string
startTime: number
}) {
return (
<div className={cn(styles.controlsRoot, 'font-game', className)}>
{platesLeading && <PlatesGroup plates={platesLeading} />}
{platesMiddle && <PlatesGroup plates={platesMiddle} className="grow" />}
{platesTrailing && <PlatesGroup plates={platesTrailing} />}
{platesLeading && <PlatesGroup plates={platesLeading} startTime={startTime} />}
{platesMiddle && <PlatesGroup plates={platesMiddle} className="grow" startTime={startTime} />}
{platesTrailing && <PlatesGroup plates={platesTrailing} startTime={startTime} />}
</div>
)
}

function Timer_({ startTime }: { startTime: number }) {
const [elapsedTime, setElapsedTime] = useState(0)

useEffect(() => {
const interval = setInterval(() => {
setElapsedTime(Date.now() - startTime)
}, 1000)
return () => clearInterval(interval)
}, [startTime])

return (
<div key="timer" className="flex items-center gap-2">
<div
className={cn('h-fit text-[1rem] sm:text-[1.25rem] lg:text-[2rem] leading-[0]', styles.plateIcon)}
>
<span className="iconify ph--timer-fill" />
</div>
<div
className={cn('h-fit text-[0.75rem] sm:text-[1rem] lg:text-[1.5rem] leading-none', styles.plateText)}
>
{new Date(elapsedTime).toISOString().substring(14, 19)}
</div>
</div>

)
}

const Timer = React.memo(Timer_)

function PlatesGroup({
plates,
className,
startTime,
}: {
plates: Plate[]
className?: string
startTime: number
}) {
const [playClick] = useSound(clickSound)

Expand All @@ -55,6 +89,7 @@ function PlatesGroup({
role={plate.clickable ? 'button' : undefined}
tabIndex={plate.clickable ? 0 : undefined}
>
{plate.id === 'time' ? <Timer startTime={startTime} /> : null}
{plate.items.map((item, i) => (
<div key={i} className="flex items-center gap-2">
{item.icon && <div className={cn('h-fit text-[1rem] sm:text-[1.25rem] lg:text-[2rem] leading-[0]', styles.plateIcon)}>{item.icon}</div>}
Expand Down
10 changes: 1 addition & 9 deletions frontend/src/components/mahjong/Mahjong.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const MAX_SCALE = 1.25
export function Mahjong({ level }: { level: LevelInfo }) {
const navigate = useNavigate()
const [startTime] = useState(() => Date.now())
const [elapsedTime, setElapsedTime] = useState(0)
const [tiles, setTiles] = useState<TileT[]>([])

const [selected, setSelected] = useState<TileT | null>(null)
Expand Down Expand Up @@ -111,13 +110,6 @@ export function Mahjong({ level }: { level: LevelInfo }) {
}
}, [mergedAt, lottie])

useEffect(() => {
const interval = setInterval(() => {
setElapsedTime(Date.now() - startTime)
}, 1000)
return () => clearInterval(interval)
}, [startTime])

useEffect(() => {
if (tiles.length === 0) {
setFinishResults({
Expand Down Expand Up @@ -281,7 +273,6 @@ export function Mahjong({ level }: { level: LevelInfo }) {
id: 'time',
items: [
// mm:ss
{ icon: <span className="iconify ph--timer-fill" />, text: new Date(elapsedTime).toISOString().substring(14, 19) },
{ icon: <span className="iconify ph--cards-fill" />, text: tiles.length.toString() },
{ icon: <span className="iconify ph--trophy-fill" />, text: score.toString() },
],
Expand Down Expand Up @@ -321,6 +312,7 @@ export function Mahjong({ level }: { level: LevelInfo }) {
},
},
]}
startTime={startTime}
/>

<div
Expand Down
46 changes: 27 additions & 19 deletions frontend/src/components/mahjong/Tile.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
import type { CSSProperties } from 'react'
import type { Coordinate } from './game'
import { cn } from '@/lib/utils'
import { memo } from 'react'
import React from 'react'
import styles from './Mahjong.module.scss'

function _({
function _BrandTile({ brand }: { brand: string }) {
const imgPath = `/logos/${brand}-logo.png`
return (
<>
<span data-glass="" />
<span data-noise="" />
<div
data-logo=""
style={{
'--img': `url('${imgPath}')`,
} as CSSProperties}
>
<img
src={imgPath}
alt={brand}
/>
</div>
<span data-bg="" />
</>
)
}

const BrandTile = React.memo(_BrandTile)

export function Tile({
className,
brand,
closed,
Expand All @@ -21,7 +45,6 @@ function _({
coord: Coordinate
onClick?: () => void
}) {
const imgPath = `/logos/${brand}-logo.png`
return (
<div
className={cn(styles.tile, closed && styles.closed, selected && styles.selected, hinted && styles.hinted, className)}
Expand All @@ -36,24 +59,9 @@ function _({
data-wrapper=""
onClick={onClick}
>
<span data-glass="" />
<span data-noise="" />
<div
data-logo=""
style={{
'--img': `url('${imgPath}')`,
} as CSSProperties}
>
<img
src={imgPath}
alt={brand}
/>
</div>
<span data-bg="" />
<BrandTile brand={brand} />
</div>
<span data-back="" />
</div>
)
}

export const Tile = memo(_)
3 changes: 3 additions & 0 deletions frontend/src/components/mahjong/brands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,21 @@ export const brands = {
title: 'Kamaz',
url: 'logos/kamaz-logo.png',
description: 'Крупнейший российский производитель грузовиков, известный своими победами в ралли Дакар и надежной спецтехникой для сложных условий.',
history: 'Основан в 1969 году. Первая победа в ралли Дакар в 1988 году. Специализируется на грузовиках и спецтехнике.',
types: ['Грузовики'],
},
'lada': {
title: 'Lada',
url: 'logos/lada-logo.png',
description: 'Крупнейший российский автопроизводитель, выпускающий доступные и практичные автомобили. Известен моделями Granta, Vesta и легендарной Niva.',
history: 'Основан в 1966 году как Волжский автомобильный завод. Lada Niva 1977 года стала первым внедорожником массового производства в СССР.',
types: ['Компактный', 'Внедорожник'],
},
'uaz': {
title: 'UAZ',
url: 'logos/uaz-logo.png',
description: 'Российский производитель легендарных внедорожников повышенной проходимости. Модели Hunter и Patriot популярны среди любителей бездорожья.',
history: 'Основан в 1941 году. Первый автомобиль УАЗ-469 выпущен в 1971 году. Специализируется на внедорожниках и коммерческой технике.',
types: ['Внедорожник'],
},
}

0 comments on commit 11c7885

Please sign in to comment.