Schnellzugriff Mobile: max 2 Zeilen, horizontal wischbar mit Snap
This commit is contained in:
@@ -485,20 +485,65 @@ function QuickLinks({ toast, mobile }) {
|
||||
{/* Link-Grid */}
|
||||
{links.length === 0 && !editMode
|
||||
? <div style={{ color:'rgba(255,255,255,0.5)', fontSize:11, fontFamily:'monospace', padding:'6px 0' }}>Links können unter Einstellungen → Dashboard hinzugefügt werden.</div>
|
||||
: mobile ? (() => {
|
||||
// Mobile: max 2 Zeilen, dann horizontal scrollbar
|
||||
// Berechne Icons pro Zeile anhand der Viewport-Breite
|
||||
const iconW = 58 + 6; // minWidth + gap
|
||||
const containerW = window.innerWidth - 28 - 28; // padding links+rechts (S.card=14px*2)
|
||||
const perRow = Math.max(3, Math.floor(containerW / iconW));
|
||||
const maxVisible = perRow * 2;
|
||||
const needsScroll = links.length > maxVisible;
|
||||
const pages = needsScroll
|
||||
? Math.ceil(links.length / maxVisible)
|
||||
: 1;
|
||||
// Gruppen zu je maxVisible Icons
|
||||
const groups = [];
|
||||
for (let i = 0; i < links.length; i += maxVisible) groups.push(links.slice(i, i + maxVisible));
|
||||
return (
|
||||
<div style={{ overflowX:'auto', scrollSnapType:'x mandatory',
|
||||
display:'flex', gap:0, marginInline:-14, paddingInline:14,
|
||||
scrollbarWidth:'none', WebkitOverflowScrolling:'touch' }}>
|
||||
{groups.map((group, gi) => (
|
||||
<div key={gi} style={{
|
||||
display:'grid',
|
||||
gridTemplateColumns:`repeat(${perRow}, ${iconW-6}px)`,
|
||||
gridTemplateRows:'repeat(2, auto)',
|
||||
gap:6,
|
||||
flexShrink:0,
|
||||
scrollSnapAlign:'start',
|
||||
paddingRight: gi < groups.length-1 ? 14 : 0,
|
||||
}}>
|
||||
{group.map(l => (
|
||||
<div key={l.id}>
|
||||
<a href={l.url} target="_blank" rel="noopener noreferrer"
|
||||
style={{ display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:3,
|
||||
padding:'4px 2px', background:'rgba(255,255,255,0.04)',
|
||||
border:'1px solid rgba(255,255,255,0.08)', borderRadius:10,
|
||||
textDecoration:'none', height:48, cursor:'pointer', width:'100%' }}>
|
||||
{l.icon && l.icon.startsWith('http')
|
||||
? <img src={l.icon} alt="" style={{width:16,height:16,objectFit:'contain'}} onError={e=>e.target.style.display='none'}/>
|
||||
: <span style={{ fontSize:16 }}>{l.icon}</span>}
|
||||
<span style={{ color:'rgba(255,255,255,0.65)', fontSize:8, fontFamily:'monospace',
|
||||
maxWidth:52, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{l.title}</span>
|
||||
</a>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})()
|
||||
: <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill,minmax(58px,1fr))', gap:6 }}>
|
||||
{links.map(l => (
|
||||
<div key={l.id} style={{ position:'relative' }}>
|
||||
|
||||
<a href={l.url} target="_blank" rel="noopener noreferrer"
|
||||
|
||||
style={{ display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:3,
|
||||
padding: mobile?'4px 2px':'6px 4px',
|
||||
background:'rgba(255,255,255,0.04)',
|
||||
padding:'6px 4px', background:'rgba(255,255,255,0.04)',
|
||||
border:'1px solid rgba(255,255,255,0.08)', borderRadius:10,
|
||||
textDecoration:'none', height: mobile?48:58, cursor:'pointer' }}>
|
||||
textDecoration:'none', height:58, cursor:'pointer' }}>
|
||||
{l.icon && l.icon.startsWith('http')
|
||||
? <img src={l.icon} alt="" style={{width:mobile?16:20,height:mobile?16:20,objectFit:'contain'}} onError={e=>e.target.style.display='none'}/>
|
||||
: <span style={{ fontSize:mobile?16:18 }}>{l.icon}</span>}
|
||||
? <img src={l.icon} alt="" style={{width:20,height:20,objectFit:'contain'}} onError={e=>e.target.style.display='none'}/>
|
||||
: <span style={{ fontSize:18 }}>{l.icon}</span>}
|
||||
<span style={{ color:'rgba(255,255,255,0.65)', fontSize:8, fontFamily:'monospace',
|
||||
maxWidth:52, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{l.title}</span>
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user