goldenChat base source add
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import {
|
||||
type TradeAlertPopupLayout,
|
||||
type TradeAlertPopupPosition,
|
||||
normalizeTradeAlertGridCols,
|
||||
} from '../utils/tradeAlertPopupLayout';
|
||||
|
||||
export interface ToastPageCapacity {
|
||||
pageSize: number;
|
||||
effectiveCols: number;
|
||||
effectiveRows: number;
|
||||
}
|
||||
|
||||
const MENUBAR_H = 52;
|
||||
const EDGE_PAD = 32;
|
||||
const TOOLBAR_RESERVE = 88;
|
||||
const CARD_GAP = 10;
|
||||
/** 우측 ‹ › 슬라이드 버튼 + 간격 */
|
||||
const NAV_BTN_RESERVE = 80;
|
||||
|
||||
const CARD = {
|
||||
full: { w: 380, h: 158 },
|
||||
compact:{ w: 200, h: 86 },
|
||||
strip: { w: 280, h: 86 },
|
||||
} as const;
|
||||
|
||||
function clamp(n: number, min: number, max: number): number {
|
||||
return Math.min(max, Math.max(min, n));
|
||||
}
|
||||
|
||||
export function computeToastPageCapacity(
|
||||
layout: TradeAlertPopupLayout,
|
||||
position: TradeAlertPopupPosition,
|
||||
gridCols: number,
|
||||
viewportW: number,
|
||||
viewportH: number,
|
||||
): ToastPageCapacity {
|
||||
const availW = position === 'bottom'
|
||||
? viewportW - EDGE_PAD - NAV_BTN_RESERVE
|
||||
: Math.min(420, viewportW - EDGE_PAD - NAV_BTN_RESERVE);
|
||||
const availH = position === 'bottom'
|
||||
? Math.min(viewportH * 0.52, 440) - TOOLBAR_RESERVE
|
||||
: viewportH - MENUBAR_H - EDGE_PAD - TOOLBAR_RESERVE;
|
||||
|
||||
if (layout === 'single') {
|
||||
return { pageSize: 1, effectiveCols: 1, effectiveRows: 1 };
|
||||
}
|
||||
|
||||
if (layout === 'strip') {
|
||||
const cols = clamp(
|
||||
Math.floor((availW + CARD_GAP) / (CARD.strip.w + CARD_GAP)),
|
||||
1,
|
||||
8,
|
||||
);
|
||||
return { pageSize: cols, effectiveCols: cols, effectiveRows: 1 };
|
||||
}
|
||||
|
||||
if (layout === 'grid') {
|
||||
const configured = normalizeTradeAlertGridCols(gridCols);
|
||||
const maxCols = clamp(
|
||||
Math.floor((availW + CARD_GAP) / (CARD.compact.w + CARD_GAP)),
|
||||
1,
|
||||
4,
|
||||
);
|
||||
const cols = Math.min(configured, maxCols);
|
||||
const rows = clamp(
|
||||
Math.floor((availH + CARD_GAP) / (CARD.compact.h + CARD_GAP)),
|
||||
1,
|
||||
6,
|
||||
);
|
||||
return {
|
||||
pageSize: clamp(cols * rows, 1, 24),
|
||||
effectiveCols: cols,
|
||||
effectiveRows: rows,
|
||||
};
|
||||
}
|
||||
|
||||
// stack
|
||||
const rows = clamp(
|
||||
Math.floor((availH + CARD_GAP) / (CARD.full.h + CARD_GAP)),
|
||||
1,
|
||||
8,
|
||||
);
|
||||
return { pageSize: rows, effectiveCols: 1, effectiveRows: rows };
|
||||
}
|
||||
|
||||
export function useToastPageCapacity(
|
||||
layout: TradeAlertPopupLayout,
|
||||
position: TradeAlertPopupPosition,
|
||||
gridCols: number,
|
||||
): ToastPageCapacity {
|
||||
const [capacity, setCapacity] = useState<ToastPageCapacity>(() =>
|
||||
computeToastPageCapacity(
|
||||
layout,
|
||||
position,
|
||||
gridCols,
|
||||
typeof window !== 'undefined' ? window.innerWidth : 1280,
|
||||
typeof window !== 'undefined' ? window.innerHeight : 800,
|
||||
),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const update = () => {
|
||||
setCapacity(computeToastPageCapacity(
|
||||
layout,
|
||||
position,
|
||||
gridCols,
|
||||
window.innerWidth,
|
||||
window.innerHeight,
|
||||
));
|
||||
};
|
||||
update();
|
||||
window.addEventListener('resize', update);
|
||||
return () => window.removeEventListener('resize', update);
|
||||
}, [layout, position, gridCols]);
|
||||
|
||||
return capacity;
|
||||
}
|
||||
Reference in New Issue
Block a user