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:
@@ -48,11 +48,29 @@ export default function ScreenshotGallery({
|
|||||||
return parseInt(tf) || 999
|
return parseInt(tf) || 999
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract timeframe from filename
|
// Extract layout and timeframe from filename
|
||||||
const extractTimeframeFromFilename = (filename: string) => {
|
const extractInfoFromFilename = (filename: string) => {
|
||||||
const match = filename.match(/_(\d+|D)_/)
|
// Pattern: SYMBOL_TIMEFRAME_LAYOUT_TIMESTAMP.png
|
||||||
if (!match) return 'Unknown'
|
// e.g., SOLUSD_5_ai_1752749431435.png or SOLUSD_15_Diy module_1752749479893.png
|
||||||
const tf = match[1]
|
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 === 'D') return '1D'
|
||||||
if (tf === '5') return '5m'
|
if (tf === '5') return '5m'
|
||||||
if (tf === '15') return '15m'
|
if (tf === '15') return '15m'
|
||||||
@@ -63,26 +81,61 @@ export default function ScreenshotGallery({
|
|||||||
return `${tf}m`
|
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 screenshotData = screenshots.map((screenshot, index) => {
|
||||||
const screenshotUrl = typeof screenshot === 'string'
|
const screenshotUrl = typeof screenshot === 'string'
|
||||||
? screenshot
|
? screenshot
|
||||||
: (screenshot as any)?.url || String(screenshot)
|
: (screenshot as any)?.url || String(screenshot)
|
||||||
const filename = screenshotUrl.split('/').pop() || ''
|
const filename = screenshotUrl.split('/').pop() || ''
|
||||||
const timeframe = timeframes[index] || extractTimeframeFromFilename(filename)
|
const { timeframe, layout } = extractInfoFromFilename(filename)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
screenshot,
|
screenshot,
|
||||||
screenshotUrl,
|
screenshotUrl,
|
||||||
filename,
|
filename,
|
||||||
timeframe,
|
timeframe,
|
||||||
|
layout,
|
||||||
|
displayTimeframe: formatTimeframe(timeframe),
|
||||||
|
displayLayout: formatLayoutName(layout),
|
||||||
index,
|
index,
|
||||||
sortOrder: timeframeToMinutes(timeframe)
|
sortOrder: timeframeToMinutes(formatTimeframe(timeframe))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Sort by timeframe (smallest to largest)
|
// Group by layout and sort within each group
|
||||||
const sortedData = screenshotData.sort((a, b) => a.sortOrder - b.sortOrder)
|
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
|
// Helper function to format screenshot URL
|
||||||
const formatScreenshotUrl = (screenshot: string | any) => {
|
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">
|
<div className="aspect-video bg-gray-800 flex items-center justify-center relative">
|
||||||
<img
|
<img
|
||||||
src={imageUrl}
|
src={imageUrl}
|
||||||
alt={`${symbol} - ${item.timeframe} chart`}
|
alt={`${symbol} - ${item.displayLayout} - ${item.displayTimeframe} chart`}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
onError={(e: any) => {
|
onError={(e: any) => {
|
||||||
const target = e.target as HTMLImageElement
|
const target = e.target as HTMLImageElement
|
||||||
@@ -156,7 +209,8 @@ export default function ScreenshotGallery({
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<div className="text-sm font-medium text-white">{symbol}</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>
|
||||||
<div className="text-xs text-gray-400">
|
<div className="text-xs text-gray-400">
|
||||||
Click to view
|
Click to view
|
||||||
|
|||||||
Reference in New Issue
Block a user