mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 23:16:21 +00:00
🆙 Update Rare-Value page and fix the loading of the json
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { AddLinkEventTracker, GetRoomEngine, GetSessionDataManager, ILinkEventTracker, IRareValue, RemoveLinkEventTracker } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { FC, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { LocalizeFormattedNumber, LocalizeText } from '../../api';
|
||||
import { Column, Flex, LayoutCurrencyIcon, LayoutImage, Text } from '../../common';
|
||||
import { useRareValues } from '../../hooks';
|
||||
import { NitroCard, NitroInput } from '../../layout';
|
||||
|
||||
const PAGE_SIZE = 50;
|
||||
|
||||
interface RareValueRow
|
||||
{
|
||||
spriteId: number;
|
||||
@@ -17,7 +19,10 @@ export const RareValuesView: FC<{}> = () =>
|
||||
{
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ searchValue, setSearchValue ] = useState('');
|
||||
const [ visibleCount, setVisibleCount ] = useState(PAGE_SIZE);
|
||||
const { values = null, loaded = false } = useRareValues();
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const sentinelRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@@ -79,35 +84,90 @@ export const RareValuesView: FC<{}> = () =>
|
||||
return rows.filter(row => row.name.toLocaleLowerCase().includes(query));
|
||||
}, [ rows, searchValue ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setVisibleCount(PAGE_SIZE);
|
||||
if(scrollRef.current) scrollRef.current.scrollTop = 0;
|
||||
}, [ filtered ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible) return;
|
||||
if(visibleCount >= filtered.length) return;
|
||||
|
||||
const sentinel = sentinelRef.current;
|
||||
const root = scrollRef.current;
|
||||
if(!sentinel || !root) return;
|
||||
|
||||
const observer = new IntersectionObserver(entries =>
|
||||
{
|
||||
if(entries.some(entry => entry.isIntersecting))
|
||||
{
|
||||
setVisibleCount(prev => Math.min(prev + PAGE_SIZE, filtered.length));
|
||||
}
|
||||
}, { root, rootMargin: '120px 0px' });
|
||||
|
||||
observer.observe(sentinel);
|
||||
return () => observer.disconnect();
|
||||
}, [ isVisible, visibleCount, filtered.length ]);
|
||||
|
||||
if(!isVisible) return null;
|
||||
|
||||
const visibleRows = filtered.slice(0, visibleCount);
|
||||
const hasMore = visibleCount < filtered.length;
|
||||
|
||||
return (
|
||||
<NitroCard className="w-[420px] h-[480px]" uniqueKey="rare-values">
|
||||
<NitroCard className="w-[460px] h-[520px]" uniqueKey="rare-values">
|
||||
<NitroCard.Header
|
||||
headerText={ LocalizeText('rarevalues.title') }
|
||||
onCloseClick={ () => setIsVisible(false) } />
|
||||
<NitroCard.Content>
|
||||
<Column gap={ 2 } className="h-full p-1">
|
||||
<NitroInput
|
||||
placeholder={ LocalizeText('generic.search') }
|
||||
value={ searchValue }
|
||||
onChange={ event => setSearchValue(event.target.value) } />
|
||||
<Column gap={ 0 } overflow="auto" className="grow">
|
||||
<Column gap={ 2 } className="h-full p-2">
|
||||
<Flex alignItems="center" gap={ 2 } className="rounded border border-black/10 bg-white px-2 py-1 shadow-inner">
|
||||
<span className="text-black/40">🔍</span>
|
||||
<NitroInput
|
||||
placeholder={ LocalizeText('generic.search') }
|
||||
value={ searchValue }
|
||||
onChange={ event => setSearchValue(event.target.value) }
|
||||
className="grow !border-0 !bg-transparent !p-0 !shadow-none focus:!ring-0" />
|
||||
</Flex>
|
||||
{ loaded &&
|
||||
<Flex alignItems="center" justifyContent="between" className="px-1 text-[11px] text-black/55">
|
||||
<span>{ filtered.length } { LocalizeText('rarevalues.title').toLowerCase() }</span>
|
||||
{ hasMore && <span>{ visibleRows.length } / { filtered.length }</span> }
|
||||
</Flex> }
|
||||
<div
|
||||
ref={ scrollRef }
|
||||
className="grow overflow-auto rounded border border-black/10 bg-gradient-to-b from-[#f6f8fb] to-[#eaf1f6] shadow-inner">
|
||||
{ !loaded &&
|
||||
<Text center className="mt-2 text-black/60">{ LocalizeText('rarevalues.loading') }</Text> }
|
||||
<div className="p-6 text-center">
|
||||
<Text className="text-black/55">{ LocalizeText('rarevalues.loading') }</Text>
|
||||
</div> }
|
||||
{ (loaded && !filtered.length) &&
|
||||
<Text center className="mt-2 text-black/60">{ LocalizeText('rarevalues.empty') }</Text> }
|
||||
{ filtered.map(row => (
|
||||
<Flex key={ row.spriteId } alignItems="center" gap={ 2 } className="border-b border-black/10 py-1.5 hover:bg-black/5">
|
||||
<LayoutImage imageUrl={ row.iconUrl } className="h-10 w-10 shrink-0 bg-contain bg-center bg-no-repeat" />
|
||||
<Text truncate className="grow text-[#1f2d34]">{ row.name }</Text>
|
||||
<Flex alignItems="center" gap={ 1 } className="shrink-0">
|
||||
<Text bold textEnd className="text-[#2f6f95]">{ LocalizeFormattedNumber(row.value.points) }</Text>
|
||||
<div className="p-6 text-center">
|
||||
<Text className="text-black/55">{ LocalizeText('rarevalues.empty') }</Text>
|
||||
</div> }
|
||||
{ visibleRows.map((row, index) => (
|
||||
<Flex
|
||||
key={ row.spriteId }
|
||||
alignItems="center"
|
||||
gap={ 2 }
|
||||
className={ `border-b border-black/[0.06] px-2 py-1.5 transition-colors hover:bg-[#cfe4f1] ${ index % 2 ? 'bg-white/60' : 'bg-[#e9f1f7]' }` }>
|
||||
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded border border-black/10 bg-white shadow-sm">
|
||||
<LayoutImage imageUrl={ row.iconUrl } className="h-9 w-9 bg-contain bg-center bg-no-repeat" />
|
||||
</div>
|
||||
<Text truncate className="grow text-[13px] font-medium text-[#1f2d34]">{ row.name }</Text>
|
||||
<Flex alignItems="center" gap={ 1 } className="shrink-0 rounded-full bg-white/80 px-2 py-0.5 shadow-sm">
|
||||
<Text bold textEnd className="text-[13px] text-[#2f6f95]">{ LocalizeFormattedNumber(row.value.points) }</Text>
|
||||
<LayoutCurrencyIcon type={ row.value.pointsType } />
|
||||
</Flex>
|
||||
</Flex>
|
||||
)) }
|
||||
</Column>
|
||||
{ hasMore &&
|
||||
<div ref={ sentinelRef } className="flex items-center justify-center py-3">
|
||||
<Text small className="text-black/45">{ LocalizeText('rarevalues.loading.more') }</Text>
|
||||
</div> }
|
||||
</div>
|
||||
</Column>
|
||||
</NitroCard.Content>
|
||||
</NitroCard>
|
||||
|
||||
Reference in New Issue
Block a user