Fix screenshot gallery layout and timeframe descriptions

- Extract both layout and timeframe information from filenames
- Group screenshots by layout (AI Layout, DIY Module)
- Sort timeframes within each layout group ascending (5m -> 4h)
- Display proper layout names and timeframes in descriptions
- Organize display as: first layout ascending, then second layout ascending
- Improve screenshot alt text with layout and timeframe info

Screenshots now properly show:
Top row: AI Layout (5m, 15m, 30m)
Bottom row: DIY Module (5m, 15m, 30m)
This commit is contained in:
mindesbunister
2025-07-17 13:09:46 +02:00
parent 01f4a9f89a
commit 8372b271cb

View File

@@ -48,11 +48,29 @@ export default function ScreenshotGallery({
return parseInt(tf) || 999
}
// Extract timeframe from filename
const extractTimeframeFromFilename = (filename: string) => {
const match = filename.match(/_(\d+|D)_/)
if (!match) return 'Unknown'
const tf = match[1]
// Extract layout and timeframe from filename
const extractInfoFromFilename = (filename: string) => {
// Pattern: SYMBOL_TIMEFRAME_LAYOUT_TIMESTAMP.png
// e.g., SOLUSD_5_ai_1752749431435.png or SOLUSD_15_Diy module_1752749479893.png
const parts = filename.replace('.png', '').split('_')
if (parts.length >= 4) {
const timeframe = parts[1]
const layout = parts.slice(2, -1).join('_') // Handle "Diy module" with space
return { timeframe, layout }
}
// Fallback: try to extract from anywhere in filename
const timeframeMatch = filename.match(/_(\d+|D)_/)
const layoutMatch = filename.match(/_(ai|Diy module|diy)_/)
return {
timeframe: timeframeMatch ? timeframeMatch[1] : 'Unknown',
layout: layoutMatch ? layoutMatch[1] : 'Unknown'
}
}
// Format timeframe for display
const formatTimeframe = (tf: string): string => {
if (tf === 'D') return '1D'
if (tf === '5') return '5m'
if (tf === '15') return '15m'
@@ -63,26 +81,61 @@ export default function ScreenshotGallery({
return `${tf}m`
}
// Create sorted screenshot data with timeframes
// Format layout name for display
const formatLayoutName = (layout: string): string => {
if (layout === 'ai') return 'AI Layout'
if (layout === 'Diy module') return 'DIY Module'
return layout
}
// Create screenshot data with extracted info
const screenshotData = screenshots.map((screenshot, index) => {
const screenshotUrl = typeof screenshot === 'string'
? screenshot
: (screenshot as any)?.url || String(screenshot)
const filename = screenshotUrl.split('/').pop() || ''
const timeframe = timeframes[index] || extractTimeframeFromFilename(filename)
const { timeframe, layout } = extractInfoFromFilename(filename)
return {
screenshot,
screenshotUrl,
filename,
timeframe,
layout,
displayTimeframe: formatTimeframe(timeframe),
displayLayout: formatLayoutName(layout),
index,
sortOrder: timeframeToMinutes(timeframe)
sortOrder: timeframeToMinutes(formatTimeframe(timeframe))
}
})
// Sort by timeframe (smallest to largest)
const sortedData = screenshotData.sort((a, b) => a.sortOrder - b.sortOrder)
// Group by layout and sort within each group
const groupedData = screenshotData.reduce((acc: any, item) => {
if (!acc[item.layout]) {
acc[item.layout] = []
}
acc[item.layout].push(item)
return acc
}, {})
// Sort each layout group by timeframe and combine
// First layout (ai), then second layout (Diy module)
const layoutOrder = ['ai', 'Diy module']
const sortedData = layoutOrder.reduce((result: any[], layoutKey) => {
if (groupedData[layoutKey]) {
const sortedGroup = groupedData[layoutKey].sort((a: any, b: any) => a.sortOrder - b.sortOrder)
result.push(...sortedGroup)
}
return result
}, [])
// Add any remaining layouts not in the predefined order
Object.keys(groupedData).forEach(layoutKey => {
if (!layoutOrder.includes(layoutKey)) {
const sortedGroup = groupedData[layoutKey].sort((a: any, b: any) => a.sortOrder - b.sortOrder)
sortedData.push(...sortedGroup)
}
})
// Helper function to format screenshot URL
const formatScreenshotUrl = (screenshot: string | any) => {
@@ -124,7 +177,7 @@ export default function ScreenshotGallery({
<div className="aspect-video bg-gray-800 flex items-center justify-center relative">
<img
src={imageUrl}
alt={`${symbol} - ${item.timeframe} chart`}
alt={`${symbol} - ${item.displayLayout} - ${item.displayTimeframe} chart`}
className="w-full h-full object-cover"
onError={(e: any) => {
const target = e.target as HTMLImageElement
@@ -156,7 +209,8 @@ export default function ScreenshotGallery({
<div className="flex items-center justify-between">
<div>
<div className="text-sm font-medium text-white">{symbol}</div>
<div className="text-xs text-purple-300">{item.timeframe} Timeframe</div>
<div className="text-xs text-purple-300">{item.displayLayout}</div>
<div className="text-xs text-gray-400">{item.displayTimeframe} Timeframe</div>
</div>
<div className="text-xs text-gray-400">
Click to view