Selfies: Difference between revisions
From Treeverse
More actions
No edit summary |
No edit summary |
||
| Line 27: | Line 27: | ||
#m-photo{padding:8px;border:1px solid #ccc;border-radius:6px;font-size:15px;background:#fff} | #m-photo{padding:8px;border:1px solid #ccc;border-radius:6px;font-size:15px;background:#fff} | ||
#toast{position:fixed;top:10px;left:50%;transform:translateX(-50%); | #toast{position:fixed;top:10px;left:50%;transform:translateX(-50%); | ||
| Line 37: | Line 34: | ||
.tv-popup .leaflet-popup-content{margin:10px 12px; width:380px !important; max-width:380px !important} | .tv-popup .leaflet-popup-content{margin:10px 12px; width:380px !important; max-width:380px !important} | ||
.tv-popup .leaflet-popup-content img{display:block;width: | .tv-popup .leaflet-popup-content img{display:block;width:50%;height:auto;border-radius:6px;margin-top:6px} | ||
@media (max-width:520px){ | @media (max-width:520px){ | ||
.tv-popup .leaflet-popup-content{width:72vw !important; max-width:72vw !important} | .tv-popup .leaflet-popup-content{width:72vw !important; max-width:72vw !important} | ||
| Line 47: | Line 44: | ||
<div class="tv-panel" id="tv-panel"> | <div class="tv-panel" id="tv-panel"> | ||
<h3> | <h3>Upload Your Selfie</h3> | ||
<input id="m-title" class="tv-input tv-text" placeholder="Enter Player Username *" required> | <input id="m-title" class="tv-input tv-text" placeholder="Enter Player Username *" required> | ||
<textarea id="m-desc" class="tv-input tv-text" rows="2" placeholder="Add description"></textarea> | <textarea id="m-desc" class="tv-input tv-text" rows="2" placeholder="Add description"></textarea> | ||
<input type="file" id="m-photo" class="tv-input" accept="image/jpeg,image/png,image/webp"> | <input type="file" id="m-photo" class="tv-input" accept="image/jpeg,image/png,image/webp"> | ||
<button id="m-add" class="tv-btn btn-add">Add to Map</button> | <button id="m-add" class="tv-btn btn-add">Add to Map</button> | ||
| Line 80: | Line 71: | ||
function toast(msg="Saved ✅"){ const t=document.getElementById('toast'); t.textContent=msg; t.classList.add('show'); setTimeout(()=>t.classList.remove('show'),1500); } | function toast(msg="Saved ✅"){ const t=document.getElementById('toast'); t.textContent=msg; t.classList.add('show'); setTimeout(()=>t.classList.remove('show'),1500); } | ||
function icon(){ return L.divIcon({ className:'tv-icon', html:'<span>📸</span>', iconSize:[30,30], iconAnchor:[15,30], popupAnchor:[0,-24] }); } | function icon(){ return L.divIcon({ className:'tv-icon', html:'<span>📸</span>', iconSize:[30,30], iconAnchor:[15,30], popupAnchor:[0,-24] }); } | ||
function popupHtml(title,desc,imgUrl | function popupHtml(title,desc,imgUrl){ | ||
const t=(title||'').trim(); | const t=(title||'').trim(); | ||
const d=(desc||'').trim().replace(/</g,'<').replace(/>/g,'>'); | const d=(desc||'').trim().replace(/</g,'<').replace(/>/g,'>'); | ||
const img = imgUrl ? `<img src="${imgUrl}" alt="">` : ''; | |||
const img = imgUrl ? ` | |||
return `<b>${t||'Untitled'}</b>${d?`<div style="margin-top:6px">${d}</div>`:''}${img}`; | return `<b>${t||'Untitled'}</b>${d?`<div style="margin-top:6px">${d}</div>`:''}${img}`; | ||
} | } | ||
| Line 106: | Line 96: | ||
delBtn.onclick=()=>{ deleteMode=!deleteMode; delBtn.textContent='Delete mode: '+(deleteMode?'ON':'OFF'); delBtn.classList.toggle('on', deleteMode); }; | delBtn.onclick=()=>{ deleteMode=!deleteMode; delBtn.textContent='Delete mode: '+(deleteMode?'ON':'OFF'); delBtn.classList.toggle('on', deleteMode); }; | ||
function addMarker(latlng, title, desc, imgUrl | function addMarker(latlng, title, desc, imgUrl){ | ||
const m = L.marker(latlng,{icon:icon(), title:title||'Selfie', desc:desc||'', imgUrl:imgUrl||null | const m = L.marker(latlng,{icon:icon(), title:title||'Selfie', desc:desc||'', imgUrl:imgUrl||null}).addTo(selfies); | ||
m.bindPopup(popupHtml(title,desc,imgUrl | m.bindPopup(popupHtml(title,desc,imgUrl), popupOpts); | ||
m.on('click', () => m.openPopup()); | m.on('click', () => m.openPopup()); | ||
m.on('contextmenu', () => { if(deleteMode){ selfies.removeLayer(m); saveShared().catch(console.warn); } }); | m.on('contextmenu', () => { if(deleteMode){ selfies.removeLayer(m); saveShared().catch(console.warn); } }); | ||
| Line 116: | Line 106: | ||
function collectMarkers(){ | function collectMarkers(){ | ||
const all=[]; selfies.eachLayer(l=>{ const ll=l.getLatLng(); | const all=[]; selfies.eachLayer(l=>{ const ll=l.getLatLng(); | ||
all.push({ type:'selfie', y:ll.lat, x:ll.lng, title:l.options.title||'Selfie', desc:l.options.desc||'', img:l.options.imgUrl||null | all.push({ type:'selfie', y:ll.lat, x:ll.lng, title:l.options.title||'Selfie', desc:l.options.desc||'', img:l.options.imgUrl||null }); | ||
}); return all; | }); return all; | ||
} | } | ||
| Line 127: | Line 117: | ||
} | } | ||
function applyMarkers(arr){ arr.forEach(m => addMarker([m.y,m.x], m.title||'Selfie', m.desc||'', m.img||null | function applyMarkers(arr){ arr.forEach(m => addMarker([m.y,m.x], m.title||'Selfie', m.desc||'', m.img||null)); } | ||
const tI=document.getElementById('m-title'), | const tI=document.getElementById('m-title'), | ||
dI=document.getElementById('m-desc'), | dI=document.getElementById('m-desc'), | ||
pI=document.getElementById('m-photo'), | pI=document.getElementById('m-photo'), | ||
addBtn=document.getElementById('m-add'); | addBtn=document.getElementById('m-add'); | ||
function validateInputs(){ | function validateInputs(){ | ||
| Line 161: | Line 147: | ||
addBtn.onclick = () => { | addBtn.onclick = () => { | ||
if(!validateInputs()) return; | if(!validateInputs()) return; | ||
placing = { title: tI.value, desc: dI.value | placing = { title: tI.value, desc: dI.value }; | ||
addBtn.textContent='Click map…'; addBtn.disabled=true; map.getContainer().style.cursor='crosshair'; | addBtn.textContent='Click map…'; addBtn.disabled=true; map.getContainer().style.cursor='crosshair'; | ||
| Line 170: | Line 156: | ||
try{ | try{ | ||
const imgUrl = await uploadPhotoIfAny(); | const imgUrl = await uploadPhotoIfAny(); | ||
addMarker([e.latlng.lat,e.latlng.lng], placing.title, placing.desc, imgUrl | addMarker([e.latlng.lat,e.latlng.lng], placing.title, placing.desc, imgUrl); | ||
await saveShared(); | await saveShared(); | ||
}catch(err){ alert('Could not add selfie: ' + err.message); } | }catch(err){ alert('Could not add selfie: ' + err.message); } | ||
finally{ cancel(); tI.value=''; dI.value=''; pI.value=' | finally{ cancel(); tI.value=''; dI.value=''; pI.value=''; } | ||
}); | }); | ||
}; | }; | ||