mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-12 10:45:54 +00:00
fix: lazy load kills widget (#157)
* fix: lazy load kills widget * fix: updates for eslint and pr feedback
This commit is contained in:
@@ -14,3 +14,7 @@
|
||||
white-space: pre-line;
|
||||
line-height: 1.2rem;
|
||||
}
|
||||
|
||||
.VirtualScroller {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import React, { useMemo, useRef, useEffect, useState } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { DetailedKill } from '@/hooks/Mapper/types/kills';
|
||||
import { KillRow } from '../components/SystemKillsRow';
|
||||
import { VirtualScroller } from 'primereact/virtualscroller';
|
||||
import { useSystemKillsItemTemplate } from '../hooks/useSystemKillsTemplate';
|
||||
|
||||
interface SystemKillsContentProps {
|
||||
export interface SystemKillsContentProps {
|
||||
kills: DetailedKill[];
|
||||
systemNameMap: Record<string, string>;
|
||||
compact?: boolean;
|
||||
onlyOneSystem?: boolean;
|
||||
autoSize?: boolean;
|
||||
timeRange: number;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export const SystemKillsContent: React.FC<SystemKillsContentProps> = ({
|
||||
@@ -15,36 +19,73 @@ export const SystemKillsContent: React.FC<SystemKillsContentProps> = ({
|
||||
systemNameMap,
|
||||
compact = false,
|
||||
onlyOneSystem = false,
|
||||
autoSize = false,
|
||||
timeRange = 1,
|
||||
limit,
|
||||
}) => {
|
||||
const sortedKills = useMemo(() => {
|
||||
return [...kills].sort((a, b) => {
|
||||
const processedKills = useMemo(() => {
|
||||
const validKills = kills.filter(kill => kill.kill_time);
|
||||
|
||||
const sortedKills = validKills.sort((a, b) => {
|
||||
const timeA = a.kill_time ? new Date(a.kill_time).getTime() : 0;
|
||||
const timeB = b.kill_time ? new Date(b.kill_time).getTime() : 0;
|
||||
return timeB - timeA;
|
||||
});
|
||||
}, [kills]);
|
||||
|
||||
if (limit != null) {
|
||||
return sortedKills.slice(0, limit);
|
||||
} else {
|
||||
const now = Date.now();
|
||||
const cutoff = now - timeRange * 60 * 60 * 1000;
|
||||
return sortedKills.filter(kill => {
|
||||
if (!kill.kill_time) return false;
|
||||
const killTime = new Date(kill.kill_time).getTime();
|
||||
return killTime >= cutoff;
|
||||
});
|
||||
}
|
||||
}, [kills, timeRange, limit]);
|
||||
|
||||
const itemSize = compact ? 35 : 50;
|
||||
const computedHeight = autoSize ? Math.max(processedKills.length, 1) * itemSize + 5 : undefined;
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const scrollerRef = useRef<any>(null);
|
||||
const [containerHeight, setContainerHeight] = useState<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!autoSize && containerRef.current) {
|
||||
const measure = () => {
|
||||
const newHeight = containerRef.current?.clientHeight ?? 0;
|
||||
setContainerHeight(newHeight);
|
||||
scrollerRef.current?.refresh?.();
|
||||
};
|
||||
|
||||
measure();
|
||||
const observer = new ResizeObserver(measure);
|
||||
observer.observe(containerRef.current);
|
||||
window.addEventListener('resize', measure);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
window.removeEventListener('resize', measure);
|
||||
};
|
||||
}
|
||||
}, [autoSize]);
|
||||
|
||||
const itemTemplate = useSystemKillsItemTemplate(systemNameMap, compact, onlyOneSystem);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'flex flex-col w-full text-stone-200 text-xs transition-all duration-300',
|
||||
compact ? 'p-1' : 'p-1'
|
||||
)}
|
||||
>
|
||||
{sortedKills.map(kill => {
|
||||
const systemIdStr = String(kill.solar_system_id);
|
||||
const systemName = systemNameMap[systemIdStr] || `System ${systemIdStr}`;
|
||||
|
||||
return (
|
||||
<KillRow
|
||||
key={kill.killmail_id}
|
||||
killDetails={kill}
|
||||
systemName={systemName}
|
||||
isCompact={compact}
|
||||
onlyOneSystem={onlyOneSystem}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<div ref={autoSize ? undefined : containerRef} className="w-full h-full">
|
||||
<VirtualScroller
|
||||
ref={autoSize ? undefined : scrollerRef}
|
||||
items={processedKills}
|
||||
itemSize={itemSize}
|
||||
itemTemplate={itemTemplate}
|
||||
autoSize={autoSize}
|
||||
style={{ height: autoSize ? `${computedHeight}px` : containerHeight ? `${containerHeight}px` : '100%' }}
|
||||
className={clsx('w-full h-full overflow-x-hidden overflow-y-auto custom-scrollbar select-none')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user