User:Docmoates/Social: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 47: | Line 47: | ||
.sf-empty-text { font-size: 18px; font-weight: 500; } | .sf-empty-text { font-size: 18px; font-weight: 500; } | ||
.sf-empty-sub { font-size: 14px; margin-top: 8px; color: #8a8d91; } | .sf-empty-sub { font-size: 14px; margin-top: 8px; color: #8a8d91; } | ||
.sf-stories { display: flex; gap: 12px; padding: 16px; background: white; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); margin-bottom: 20px; } | .sf-stories { display: flex; gap: 12px; padding: 16px; background: white; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); margin-bottom: 20px; overflow-x: auto; } | ||
.sf-story-item { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 80px; } | |||
.sf-story-ring { width: 68px; height: 68px; border-radius: 50%; padding: 3px; background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); } | |||
.sf-story-ring.no-story { background: #e4e6eb; } | |||
.sf-story-avatar { width: 100%; height: 100%; border-radius: 50%; border: 3px solid white; object-fit: cover; cursor: pointer; background: linear-gradient(135deg, #667eea, #764ba2); display: flex; align-items: center; justify-content: center; color: white; font-weight: 600; font-size: 20px; } | |||
.sf-story-avatar img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; } | |||
.sf-story-name { font-size: 12px; color: #65676b; max-width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } | |||
.sf-create-story { width: 68px; height: 68px; border-radius: 50%; background: #e4e6eb; display: flex; align-items: center; justify-content: center; font-size: 28px; color: #1877f2; cursor: pointer; border: none; } | .sf-create-story { width: 68px; height: 68px; border-radius: 50%; background: #e4e6eb; display: flex; align-items: center; justify-content: center; font-size: 28px; color: #1877f2; cursor: pointer; border: none; } | ||
.sf-modal { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(255,255,255,0.8); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); z-index: 9999; align-items: center; justify-content: center; } | .sf-modal { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(255,255,255,0.8); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); z-index: 9999; align-items: center; justify-content: center; } | ||
.sf-modal.active { display: flex; } | .sf-modal.active { display: flex; } | ||
.sf-modal-content { background: white; border-radius: 12px; padding: 24px; max-width: 450px; width: 90%; } | .sf-modal-content { background: white; border-radius: 12px; padding: 24px; max-width: 450px; width: 90%; box-shadow: 0 8px 32px rgba(0,0,0,0.12); } | ||
.sf-modal-title { font-size: 20px; font-weight: 600; margin-bottom: 16px; } | .sf-modal-title { font-size: 20px; font-weight: 600; margin-bottom: 16px; } | ||
.sf-modal-input { width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 8px; font-size: 14px; margin-bottom: 12px; } | .sf-modal-input { width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 8px; font-size: 14px; margin-bottom: 12px; } | ||
| Line 83: | Line 89: | ||
.sf-emoji-tab { background: none; border: none; font-size: 18px; padding: 6px 10px; cursor: pointer; border-radius: 6px; opacity: 0.5; } | .sf-emoji-tab { background: none; border: none; font-size: 18px; padding: 6px 10px; cursor: pointer; border-radius: 6px; opacity: 0.5; } | ||
.sf-emoji-tab:hover, .sf-emoji-tab.active { opacity: 1; background: #f0f2f5; } | .sf-emoji-tab:hover, .sf-emoji-tab.active { opacity: 1; background: #f0f2f5; } | ||
.sf-story-viewer { display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: #000; z-index: 10000; } | |||
.sf-story-viewer.active { display: flex; align-items: center; justify-content: center; } | |||
.sf-story-viewer img { max-width: 100%; max-height: 100%; object-fit: contain; } | |||
.sf-story-close { position: absolute; top: 20px; right: 20px; background: rgba(255,255,255,0.2); border: none; color: white; font-size: 24px; width: 40px; height: 40px; border-radius: 50%; cursor: pointer; } | |||
.sf-story-progress { position: absolute; top: 10px; left: 10px; right: 10px; height: 3px; background: rgba(255,255,255,0.3); border-radius: 2px; } | |||
.sf-story-progress-fill { height: 100%; background: white; border-radius: 2px; animation: storyProgress 5s linear forwards; } | |||
@keyframes storyProgress { from { width: 0%; } to { width: 100%; } } | |||
</style> | </style> | ||
<div class="sf-stories"><div class="sf-story"><button class="sf-create-story" id="add-story-btn">+</button><span | <div class="sf-stories" id="stories-container"> | ||
<div class="sf-story-item"> | |||
<button class="sf-create-story" id="add-story-btn">+</button> | |||
<span class="sf-story-name">Add Story</span> | |||
</div> | |||
</div> | |||
<div class="sf-composer"> | <div class="sf-composer"> | ||
| Line 124: | Line 142: | ||
<div class="sf-modal-content"> | <div class="sf-modal-content"> | ||
<div class="sf-modal-title">Set Profile Photo</div> | <div class="sf-modal-title">Set Profile Photo</div> | ||
< | <div class="sf-tabs"> | ||
<p style="font-size:12px;color:#65676b;margin- | <div class="sf-tab active" data-ptab="pupload">Upload</div> | ||
<div class="sf-tab" data-ptab="purl">From URL</div> | |||
</div> | |||
<div class="sf-tab-content active" id="tab-pupload"> | |||
<div class="sf-upload-zone" id="profile-upload-zone"> | |||
<div class="sf-upload-icon">📸</div> | |||
<div class="sf-upload-text">Click to select or drag photo here</div> | |||
<input type="file" id="profile-file-input" accept="image/*" style="display:none"> | |||
</div> | |||
<div class="sf-upload-progress" id="profile-upload-progress"> | |||
<div class="sf-progress-bar"><div class="sf-progress-fill" id="profile-progress-fill"></div></div> | |||
<p style="font-size:12px;color:#65676b;margin-top:8px;" id="profile-upload-status">Uploading...</p> | |||
</div> | |||
<img class="sf-preview-thumb" id="profile-upload-preview" style="display:none"> | |||
</div> | |||
<div class="sf-tab-content" id="tab-purl"> | |||
<input type="text" class="sf-modal-input" id="profile-url-input" placeholder="Paste image URL..."> | |||
<img class="sf-preview-thumb" id="profile-url-preview" style="display:none"> | |||
</div> | |||
<div class="sf-modal-buttons"> | <div class="sf-modal-buttons"> | ||
<button class="sf-modal-btn sf-modal-btn-cancel" id="profile-cancel-btn">Cancel</button> | <button class="sf-modal-btn sf-modal-btn-cancel" id="profile-cancel-btn">Cancel</button> | ||
<button class="sf-modal-btn sf-modal-btn-save" id="profile-save-btn">Save</button> | <button class="sf-modal-btn sf-modal-btn-save" id="profile-save-btn">Save</button> | ||
</div> | |||
</div> | |||
</div> | |||
<div class="sf-modal" id="story-modal"> | |||
<div class="sf-modal-content"> | |||
<div class="sf-modal-title">Add Story</div> | |||
<div class="sf-tabs"> | |||
<div class="sf-tab active" data-stab="supload">Upload</div> | |||
<div class="sf-tab" data-stab="surl">From URL</div> | |||
</div> | |||
<div class="sf-tab-content active" id="tab-supload"> | |||
<div class="sf-upload-zone" id="story-upload-zone"> | |||
<div class="sf-upload-icon">📷</div> | |||
<div class="sf-upload-text">Click to select or drag image here</div> | |||
<input type="file" id="story-file-input" accept="image/*" style="display:none"> | |||
</div> | |||
<div class="sf-upload-progress" id="story-upload-progress"> | |||
<div class="sf-progress-bar"><div class="sf-progress-fill" id="story-progress-fill"></div></div> | |||
<p style="font-size:12px;color:#65676b;margin-top:8px;" id="story-upload-status">Uploading...</p> | |||
</div> | |||
<img class="sf-preview-thumb" id="story-upload-preview" style="display:none"> | |||
</div> | |||
<div class="sf-tab-content" id="tab-surl"> | |||
<input type="text" class="sf-modal-input" id="story-url-input" placeholder="Paste image URL..."> | |||
<img class="sf-preview-thumb" id="story-url-preview" style="display:none"> | |||
</div> | |||
<div class="sf-modal-buttons"> | |||
<button class="sf-modal-btn sf-modal-btn-cancel" id="story-cancel-btn">Cancel</button> | |||
<button class="sf-modal-btn sf-modal-btn-save" id="story-add-btn">Add Story</button> | |||
</div> | </div> | ||
</div> | </div> | ||
| Line 204: | Line 270: | ||
</div> | </div> | ||
</div> | </div> | ||
</div> | |||
<div class="sf-story-viewer" id="story-viewer"> | |||
<div class="sf-story-progress"><div class="sf-story-progress-fill" id="story-progress-bar"></div></div> | |||
<button class="sf-story-close" id="story-close-btn">✕</button> | |||
<img id="story-viewer-img" src=""> | |||
</div> | </div> | ||
| Line 212: | Line 284: | ||
var csrfToken=''; | var csrfToken=''; | ||
try{if(window.mw)user=mw.config.get('wgUserName') | try{if(window.mw){user=mw.config.get('wgUserName');if(!user)user='Guest';}}catch(e){} | ||
var photo=localStorage.getItem('sf_photo_'+user)||''; | var photo=localStorage.getItem('sf_photo_'+user)||''; | ||
| Line 225: | Line 297: | ||
gestures:['👋','🤚','🖐️','✋','🖖','👌','🤌','🤏','✌️','🤞','🤟','🤘','🤙','👈','👉','👆','👇','☝️','👍','👎','✊','👊','🤛','🤜','👏','🙌','👐','🤲','🤝','🙏','✍️','💪','🦵','🦶','👂','👃','🧠','🫀','🫁','🦷','🦴','👀','👁️','👅','👄'], | gestures:['👋','🤚','🖐️','✋','🖖','👌','🤌','🤏','✌️','🤞','🤟','🤘','🤙','👈','👉','👆','👇','☝️','👍','👎','✊','👊','🤛','🤜','👏','🙌','👐','🤲','🤝','🙏','✍️','💪','🦵','🦶','👂','👃','🧠','🫀','🫁','🦷','🦴','👀','👁️','👅','👄'], | ||
animals:['🐶','🐱','🐭','🐹','🐰','🦊','🐻','🐼','🐨','🐯','🦁','🐮','🐷','🐸','🐵','🐔','🐧','🐦','🐤','🦆','🦅','🦉','🦇','🐺','🐗','🐴','🦄','🐝','🐛','🦋','🐌','🐞','🐜','🦟','🐢','🐍','🦎','🦂','🦀','🦑','🐙','🦐','🐠','🐟','🐬','🐳','🦈','🐊','🐅','🐆','🦓','🦍','🐘','🦛','🦏'], | animals:['🐶','🐱','🐭','🐹','🐰','🦊','🐻','🐼','🐨','🐯','🦁','🐮','🐷','🐸','🐵','🐔','🐧','🐦','🐤','🦆','🦅','🦉','🦇','🐺','🐗','🐴','🦄','🐝','🐛','🦋','🐌','🐞','🐜','🦟','🐢','🐍','🦎','🦂','🦀','🦑','🐙','🦐','🐠','🐟','🐬','🐳','🦈','🐊','🐅','🐆','🦓','🦍','🐘','🦛','🦏'], | ||
food:['🍎','🍊','🍋','🍌','🍉','🍇','🍓','🫐','🍈','🍒','🍑','🥭','🍍','🥥','🥝','🍅','🥑','🥦','🥬','🥒','🌶️','🫑','🌽','🥕','🫒','🧄','🧅','🥔','🍠','🥐','🥯','🍞','🥖','🥨','🧀','🥚','🍳','🧈','🥞','🧇','🥓','🥩','🍗','🍖 | food:['🍎','🍊','🍋','🍌','🍉','🍇','🍓','🫐','🍈','🍒','🍑','🥭','🍍','🥥','🥝','🍅','🥑','🥦','🥬','🥒','🌶️','🫑','🌽','🥕','🫒','🧄','🧅','🥔','🍠','🥐','🥯','🍞','🥖','🥨','🧀','🥚','🍳','🧈','🥞','🧇','🥓','🥩','🍗','🍖','🌭','🍔','🍟','🍕','🥪','🥙','🌮','🌯','🥗','🍝','🍜','🍲','🍛','🍣','🍱','🥟','🍤','🍙','🍚','🍘','🍥','🍢','🍡','🍧','🍨','🍦','🥧','🧁','🍰','🎂','🍮','🍭','🍬','🍫','🍿','🍩','🍪'], | ||
activities:['⚽','🏀','🏈','⚾','🥎','🎾','🏐','🏉','🥏','🎱',' | activities:['⚽','🏀','🏈','⚾','🥎','🎾','🏐','🏉','🥏','🎱','🏓','🏸','🏒','🏑','🥍','🏏','🥅','⛳','🏹','🎣','🥊','🥋','🎽','🛹','🛷','⛸️','🥌','🎿','⛷️','🏂','🏋️','🤼','🤸','🤺','⛹️','🤾','🏌️','🏇','🧘','🏄','🏊','🤽','🚣','🧗','🚴','🚵','🎖️','🏆','🥇','🥈','🥉','🏅','🎪','🤹','🎭','🎨','🎬','🎤','🎧','🎼','🎹','🥁','🎷','🎺','🎸','🎻','🎲','♟️','🎯','🎳','🎮','🎰'], | ||
objects:['💡','🔦','🕯️ | objects:['💡','🔦','🕯️','📱','💻','🖥️','🖨️','⌨️','🖱️','💾','💿','📀','📷','📸','📹','🎥','📽️','📞','☎️','📟','📠','📺','📻','🎙️','🎚️','🎛️','🧭','⏱️','⏲️','⏰','🕰️','⌛','⏳','📡','🔋','🔌','💰','💵','💴','💶','💷','💳','💎','⚖️','🧰','🔧','🔨','🛠️','⛏️','🔩','⚙️','🧱','🔫','💣','🔪','🗡️','⚔️','🛡️','🚬','⚰️','⚱️','🏺','🔮','📿','🧿','💈','⚗️','🔭','🔬','🕳️','🩹','🩺','💊','💉','🧬','🦠','🧫','🧪','🌡️','🧹','🧺','🧻','🚽','🚿','🛁','🧼','🧽','🧴','🛎️','🔑','🗝️','🚪','🛋️','🛏️','🧸','🖼️','🛍️','🛒','🎁','🎈','🎏','🎀','🎊','🎉','🎎','🏮','🎐','🧧','✉️','📩','📨','📧','💌','📥','📤','📦','🏷️','📪','📫','📬','📭','📮','📯','📜','📃','📄','📑','🧾','📊','📈','📉','📆','📅','🗑️','📋','📁','📂','📰','📓','📔','📒','📕','📗','📘','📙','📚','📖','🔖','🔗','📎','📐','📏','🧮','📌','📍','✂️','🖊️','🖋️','✒️','🖌️','🖍️','📝','✏️','🔍','🔎','🔏','🔐','🔒','🔓'], | ||
symbols:['❤️','🧡','💛','💚','💙','💜','🖤','🤍','🤎','💔','❣️','💕','💞','💓','💗','💖','💘','💝','💟','☮️','✝️','☪️','🕉️','☸️','✡️','🔯','🕎','☯️','☦️','🛐','⛎','♈','♉','♊','♋','♌','♍','♎','♏','♐','♑','♒','♓','🆔','⚛️','☢️','☣️','📴','📳','✴️','🆚','💮','㊙️','㊗️','🅰️','🅱️','🆎','🆑','🅾️','🆘','❌','⭕','🛑','⛔','📛','🚫','💯','💢','♨️','🚷','🚯','🚳','🚱','🔞','📵','🚭','❗','❕','❓','❔','‼️','⁉️','🔅','🔆','〽️','⚠️','🚸','🔱','⚜️','🔰','♻️','✅','💹','❇️','✳️','❎','🌐','💠','Ⓜ️','🌀','💤','🏧','🚾','♿','🅿️','🈳','🈂️','🛂','🛃','🛄','🛅','🚹','🚺','🚼','⚧️','🚻','🚮','🎦','📶','🔣','ℹ️','🔤','🔡','🔠','🆖','🆗','🆙','🆒','🆕','🆓','0️⃣','1️⃣','2️⃣','3️⃣','4️⃣','5️⃣','6️⃣','7️⃣','8️⃣','9️⃣','🔟','🔢','#️⃣','*️⃣','⏏️','▶️','⏸️','⏯️','⏹️','⏺️','⏭️','⏮️','⏩','⏪','⏫','⏬','◀️','🔼','🔽','➡️','⬅️','⬆️','⬇️','↗️','↘️','↙️','↖️','↕️','↔️','↪️','↩️','⤴️','⤵️','🔀','🔁','🔂','🔄','🔃','🎵','🎶','➕','➖','➗','✖️','🟰','♾️','💲','💱','™️','©️','®️','〰️','➰','➿','🔚','🔙','🔛','🔝','🔜','✔️','☑️','🔘','🔴','🟠','🟡','🟢','🔵','🟣','⚫','⚪','🟤','🔺','🔻','🔸','🔹','🔶','🔷','🔳','🔲','▪️','▫️','◾','◽','◼️','◻️','🟥','🟧','🟨','🟩','🟦','🟪','⬛','⬜','🟫','🔈','🔇','🔉','🔊','🔔','🔕','📣','📢','💬','💭','🗯️','♠️','♣️','♥️','♦️','🃏','🎴','🀄'] | |||
}; | }; | ||
| Line 253: | Line 325: | ||
csrfToken=d.query.tokens.csrftoken; | csrfToken=d.query.tokens.csrftoken; | ||
return csrfToken; | return csrfToken; | ||
}); | |||
} | |||
function uploadFile(file,prefix,onProgress,onDone,onError){ | |||
getToken().then(function(token){ | |||
var filename=prefix+'_'+user+'_'+Date.now()+'.'+file.name.split('.').pop(); | |||
var formData=new FormData(); | |||
formData.append('action','upload'); | |||
formData.append('filename',filename); | |||
formData.append('file',file); | |||
formData.append('token',token); | |||
formData.append('format','json'); | |||
formData.append('ignorewarnings','1'); | |||
var xhr=new XMLHttpRequest(); | |||
xhr.open('POST',apiBase,true); | |||
xhr.withCredentials=true; | |||
xhr.upload.onprogress=function(e){if(e.lengthComputable)onProgress(Math.round((e.loaded/e.total)*100));}; | |||
xhr.onload=function(){ | |||
if(xhr.status===200){ | |||
var resp=JSON.parse(xhr.responseText); | |||
if(resp.upload){ | |||
if(resp.upload.imageinfo){onDone(resp.upload.imageinfo.url);} | |||
else if(resp.upload.warnings){onError('Warning: '+JSON.stringify(resp.upload.warnings));} | |||
else{onError('Upload issue');} | |||
}else if(resp.error){onError(resp.error.info);} | |||
else{onError('Unknown error');} | |||
}else{onError('Upload failed');} | |||
}; | |||
xhr.onerror=function(){onError('Upload failed');}; | |||
xhr.send(formData); | |||
}); | }); | ||
} | } | ||
| Line 265: | Line 368: | ||
var postContent=gel('post-content'); | var postContent=gel('post-content'); | ||
if(postContent)postContent.placeholder='What is on your mind, '+user+'?'; | if(postContent)postContent.placeholder='What is on your mind, '+user+'?'; | ||
// Profile modal tabs | |||
var uploadedProfileFile=null; | |||
document.querySelectorAll('[data-ptab]').forEach(function(tab){ | |||
tab.addEventListener('click',function(){ | |||
document.querySelectorAll('[data-ptab]').forEach(function(t){t.classList.remove('active');}); | |||
document.querySelectorAll('#profile-modal .sf-tab-content').forEach(function(c){c.classList.remove('active');}); | |||
tab.classList.add('active'); | |||
gel('tab-'+tab.dataset.ptab).classList.add('active'); | |||
}); | |||
}); | |||
gel('composer-avatar').addEventListener('click',function(){ | gel('composer-avatar').addEventListener('click',function(){ | ||
gel('profile-url-input').value=photo; | gel('profile-url-input').value=photo; | ||
gel('profile-upload-preview').style.display='none'; | |||
gel('profile-url-preview').style.display='none'; | |||
gel('profile-upload-progress').style.display='none'; | |||
uploadedProfileFile=null; | |||
gel('profile-modal').classList.add('active'); | gel('profile-modal').classList.add('active'); | ||
}); | }); | ||
gel('profile-cancel-btn').addEventListener('click',function(){gel('profile-modal').classList.remove('active');}); | gel('profile-cancel-btn').addEventListener('click',function(){gel('profile-modal').classList.remove('active');}); | ||
var profileUploadZone=gel('profile-upload-zone'); | |||
var profileFileInput=gel('profile-file-input'); | |||
profileUploadZone.addEventListener('click',function(){profileFileInput.click();}); | |||
profileUploadZone.addEventListener('dragover',function(e){e.preventDefault();profileUploadZone.classList.add('dragover');}); | |||
profileUploadZone.addEventListener('dragleave',function(){profileUploadZone.classList.remove('dragover');}); | |||
profileUploadZone.addEventListener('drop',function(e){ | |||
e.preventDefault(); | |||
profileUploadZone.classList.remove('dragover'); | |||
if(e.dataTransfer.files.length>0)handleProfileFile(e.dataTransfer.files[0]); | |||
}); | |||
profileFileInput.addEventListener('change',function(){ | |||
if(profileFileInput.files.length>0)handleProfileFile(profileFileInput.files[0]); | |||
}); | |||
function handleProfileFile(file){ | |||
if(!file.type.startsWith('image/')){alert('Please select an image file');return;} | |||
uploadedProfileFile=file; | |||
var reader=new FileReader(); | |||
reader.onload=function(e){ | |||
gel('profile-upload-preview').src=e.target.result; | |||
gel('profile-upload-preview').style.display='block'; | |||
}; | |||
reader.readAsDataURL(file); | |||
} | |||
gel('profile-url-input').addEventListener('input',function(){ | |||
var url=this.value.trim(); | |||
if(url){ | |||
gel('profile-url-preview').src=url; | |||
gel('profile-url-preview').style.display='block'; | |||
}else{ | |||
gel('profile-url-preview').style.display='none'; | |||
} | |||
}); | |||
gel('profile-save-btn').addEventListener('click',function(){ | gel('profile-save-btn').addEventListener('click',function(){ | ||
var activeTab=document.querySelector('[data-ptab].active').dataset.ptab; | |||
if(activeTab==='purl'){ | |||
photo=gel('profile-url-input').value.trim(); | photo=gel('profile-url-input').value.trim(); | ||
localStorage.setItem('sf_photo_'+user,photo); | localStorage.setItem('sf_photo_'+user,photo); | ||
setAv(); | setAv(); | ||
gel('profile-modal').classList.remove('active'); | gel('profile-modal').classList.remove('active'); | ||
}else{ | |||
if(uploadedProfileFile){ | |||
gel('profile-upload-progress').style.display='block'; | |||
gel('profile-progress-fill').style.width='10%'; | |||
gel('profile-upload-status').textContent='Uploading...'; | |||
uploadFile(uploadedProfileFile,'ProfilePhoto',function(pct){ | |||
gel('profile-progress-fill').style.width=pct+'%'; | |||
},function(url){ | |||
gel('profile-progress-fill').style.width='100%'; | |||
gel('profile-upload-status').textContent='Done!'; | |||
photo=url; | |||
localStorage.setItem('sf_photo_'+user,photo); | |||
setAv(); | |||
setTimeout(function(){gel('profile-modal').classList.remove('active');},500); | |||
},function(err){ | |||
gel('profile-upload-status').textContent='Error: '+err; | |||
}); | |||
}else{ | |||
alert('Please select an image to upload'); | |||
} | |||
} | |||
}); | |||
// Story modal tabs | |||
var uploadedStoryFile=null; | |||
document.querySelectorAll('[data-stab]').forEach(function(tab){ | |||
tab.addEventListener('click',function(){ | |||
document.querySelectorAll('[data-stab]').forEach(function(t){t.classList.remove('active');}); | |||
document.querySelectorAll('#story-modal .sf-tab-content').forEach(function(c){c.classList.remove('active');}); | |||
tab.classList.add('active'); | |||
gel('tab-'+tab.dataset.stab).classList.add('active'); | |||
}); | |||
}); | }); | ||
gel('add-story-btn').addEventListener('click',function(){ | |||
gel('story-url-input').value=''; | |||
gel('story-upload-preview').style.display='none'; | |||
gel('story-url-preview').style.display='none'; | |||
gel('story-upload-progress').style.display='none'; | |||
uploadedStoryFile=null; | |||
gel('story-modal').classList.add('active'); | |||
}); | |||
gel('story-cancel-btn').addEventListener('click',function(){gel('story-modal').classList.remove('active');}); | |||
var storyUploadZone=gel('story-upload-zone'); | |||
var storyFileInput=gel('story-file-input'); | |||
storyUploadZone.addEventListener('click',function(){storyFileInput.click();}); | |||
storyUploadZone.addEventListener('dragover',function(e){e.preventDefault();storyUploadZone.classList.add('dragover');}); | |||
storyUploadZone.addEventListener('dragleave',function(){storyUploadZone.classList.remove('dragover');}); | |||
storyUploadZone.addEventListener('drop',function(e){ | |||
e.preventDefault(); | |||
storyUploadZone.classList.remove('dragover'); | |||
if(e.dataTransfer.files.length>0)handleStoryFile(e.dataTransfer.files[0]); | |||
}); | |||
storyFileInput.addEventListener('change',function(){ | |||
if(storyFileInput.files.length>0)handleStoryFile(storyFileInput.files[0]); | |||
}); | |||
function handleStoryFile(file){ | |||
if(!file.type.startsWith('image/')){alert('Please select an image file');return;} | |||
uploadedStoryFile=file; | |||
var reader=new FileReader(); | |||
reader.onload=function(e){ | |||
gel('story-upload-preview').src=e.target.result; | |||
gel('story-upload-preview').style.display='block'; | |||
}; | |||
reader.readAsDataURL(file); | |||
} | |||
gel('story-url-input').addEventListener('input',function(){ | |||
var url=this.value.trim(); | |||
if(url){ | |||
gel('story-url-preview').src=url; | |||
gel('story-url-preview').style.display='block'; | |||
}else{ | |||
gel('story-url-preview').style.display='none'; | |||
} | |||
}); | |||
gel('story-add-btn').addEventListener('click',function(){ | |||
var activeTab=document.querySelector('[data-stab].active').dataset.stab; | |||
if(activeTab==='surl'){ | |||
var url=gel('story-url-input').value.trim(); | |||
if(url){ | |||
createStory(url); | |||
}else{ | |||
alert('Please enter an image URL'); | |||
} | |||
}else{ | |||
if(uploadedStoryFile){ | |||
gel('story-upload-progress').style.display='block'; | |||
gel('story-progress-fill').style.width='10%'; | |||
gel('story-upload-status').textContent='Uploading...'; | |||
uploadFile(uploadedStoryFile,'Story',function(pct){ | |||
gel('story-progress-fill').style.width=pct+'%'; | |||
},function(url){ | |||
gel('story-progress-fill').style.width='100%'; | |||
gel('story-upload-status').textContent='Done!'; | |||
setTimeout(function(){ | |||
gel('story-modal').classList.remove('active'); | |||
createStory(url); | |||
},500); | |||
},function(err){ | |||
gel('story-upload-status').textContent='Error: '+err; | |||
}); | |||
}else{ | |||
alert('Please select an image to upload'); | |||
} | |||
} | |||
}); | |||
function createStory(imageUrl){ | |||
getToken().then(function(token){ | |||
return apiPost({action:'socialfeed',sfaction:'createstory',image_url:imageUrl,token:token}); | |||
}).then(function(d){ | |||
if(d.error){alert('Error: '+d.error.info);return;} | |||
loadStories(); | |||
gel('story-modal').classList.remove('active'); | |||
}).catch(function(e){alert('Error creating story');}); | |||
} | |||
function loadStories(){ | |||
apiGet({action:'socialfeed',sfaction:'getstories'}).then(function(d){ | |||
renderStories((d.socialfeed?d.socialfeed.stories:[])||[]); | |||
}).catch(function(){}); | |||
} | |||
function renderStories(stories){ | |||
var container=gel('stories-container'); | |||
var h='<div class="sf-story-item"><button class="sf-create-story" id="add-story-btn">+</button><span class="sf-story-name">Add Story</span></div>'; | |||
stories.forEach(function(s){ | |||
var pic=localStorage.getItem('sf_photo_'+s.username)||''; | |||
var av=pic?'<img src="'+pic+'">':init(s.username); | |||
h+='<div class="sf-story-item"><div class="sf-story-ring"><div class="sf-story-avatar" data-story="'+s.image_url+'">'+av+'</div></div><span class="sf-story-name">'+esc(s.username)+'</span></div>'; | |||
}); | |||
container.innerHTML=h; | |||
gel('add-story-btn').addEventListener('click',function(){ | |||
gel('story-url-input').value=''; | |||
gel('story-upload-preview').style.display='none'; | |||
gel('story-url-preview').style.display='none'; | |||
gel('story-upload-progress').style.display='none'; | |||
uploadedStoryFile=null; | |||
gel('story-modal').classList.add('active'); | |||
}); | |||
container.querySelectorAll('[data-story]').forEach(function(el){ | |||
el.addEventListener('click',function(){ | |||
gel('story-viewer-img').src=el.dataset.story; | |||
gel('story-viewer').classList.add('active'); | |||
gel('story-progress-bar').style.animation='none'; | |||
setTimeout(function(){gel('story-progress-bar').style.animation='storyProgress 5s linear forwards';},10); | |||
setTimeout(function(){gel('story-viewer').classList.remove('active');},5000); | |||
}); | |||
}); | |||
} | |||
gel('story-close-btn').addEventListener('click',function(){gel('story-viewer').classList.remove('active');}); | |||
gel('story-viewer').addEventListener('click',function(e){if(e.target===this)this.classList.remove('active');}); | |||
// Emoji picker | // Emoji picker | ||
| Line 360: | Line 674: | ||
gel('video-upload-preview').src=url; | gel('video-upload-preview').src=url; | ||
gel('video-upload-preview').style.display='block'; | gel('video-upload-preview').style.display='block'; | ||
} | } | ||
| Line 446: | Line 700: | ||
}else{ | }else{ | ||
if(uploadedVideoFile){ | if(uploadedVideoFile){ | ||
gel('video-upload-progress').style.display='block'; | |||
gel('video-progress-fill').style.width='10%'; | |||
gel('video-upload-status').textContent='Uploading...'; | |||
uploadFile(uploadedVideoFile,'SocialVideo',function(pct){ | |||
gel('video-progress-fill').style.width=pct+'%'; | |||
},function(url){ | |||
gel('video-progress-fill').style.width='100%'; | |||
gel('video-upload-status').textContent='Done!'; | |||
pendingVideo=url; | |||
pendingImg=''; | |||
mediaType='video'; | |||
gel('preview-img').style.display='none'; | |||
gel('preview-video').src=url; | |||
gel('preview-video').style.display='block'; | |||
gel('image-preview').style.display='block'; | |||
setTimeout(function(){gel('video-modal').classList.remove('active');},500); | |||
},function(err){ | |||
gel('video-upload-status').textContent='Error: '+err; | |||
}); | |||
}else{ | }else{ | ||
alert('Please select a video to upload'); | alert('Please select a video to upload'); | ||
| Line 498: | Line 770: | ||
// Image modal tabs | // Image modal tabs | ||
document.querySelectorAll(' | document.querySelectorAll('[data-tab]').forEach(function(tab){ | ||
tab.addEventListener('click',function(){ | tab.addEventListener('click',function(){ | ||
document.querySelectorAll(' | document.querySelectorAll('[data-tab]').forEach(function(t){t.classList.remove('active');}); | ||
document.querySelectorAll('.sf-tab-content').forEach(function(c){c.classList.remove('active');}); | document.querySelectorAll('#image-modal .sf-tab-content').forEach(function(c){c.classList.remove('active');}); | ||
tab.classList.add('active'); | tab.classList.add('active'); | ||
gel('tab-'+tab.dataset.tab).classList.add('active'); | gel('tab-'+tab.dataset.tab).classList.add('active'); | ||
| Line 556: | Line 828: | ||
gel('image-add-btn').addEventListener('click',function(){ | gel('image-add-btn').addEventListener('click',function(){ | ||
var activeTab=document.querySelector(' | var activeTab=document.querySelector('[data-tab].active').dataset.tab; | ||
if(activeTab==='url'){ | if(activeTab==='url'){ | ||
var url=gel('image-url-input').value.trim(); | var url=gel('image-url-input').value.trim(); | ||
| Line 573: | Line 845: | ||
}else{ | }else{ | ||
if(uploadedFile){ | if(uploadedFile){ | ||
gel('upload-progress').style.display='block'; | gel('upload-progress').style.display='block'; | ||
gel('progress-fill').style.width='10%'; | gel('progress-fill').style.width='10%'; | ||
gel('upload-status').textContent='Uploading...'; | |||
uploadFile(uploadedFile,'SocialFeed',function(pct){ | |||
gel('upload-status').textContent='Uploading | |||
gel('progress-fill').style.width=pct+'%'; | gel('progress-fill').style.width=pct+'%'; | ||
} | },function(url){ | ||
gel('progress-fill').style.width='100%'; | gel('progress-fill').style.width='100%'; | ||
gel('upload-status').textContent=' | gel('upload-status').textContent='Done!'; | ||
pendingImg= | pendingImg=url; | ||
pendingVideo=''; | pendingVideo=''; | ||
mediaType='image'; | mediaType='image'; | ||
gel('preview-img').src= | gel('preview-img').src=url; | ||
gel('preview-img').style.display='block'; | gel('preview-img').style.display='block'; | ||
gel('preview-video').style.display='none'; | gel('preview-video').style.display='none'; | ||
gel('image-preview').style.display='block'; | gel('image-preview').style.display='block'; | ||
setTimeout(function(){gel('image-modal').classList.remove('active');},500); | setTimeout(function(){gel('image-modal').classList.remove('active');},500); | ||
} | },function(err){ | ||
gel('upload-status').textContent=' | gel('upload-status').textContent='Error: '+err; | ||
}); | |||
}else{ | |||
alert('Please select an image to upload'); | |||
} | } | ||
} | } | ||
}); | }); | ||
gel('remove-image-btn').addEventListener('click',function(){ | gel('remove-image-btn').addEventListener('click',function(){ | ||
| Line 671: | Line 901: | ||
apiGet({action:'socialfeed',sfaction:'getposts',limit:20}).then(function(d){ | apiGet({action:'socialfeed',sfaction:'getposts',limit:20}).then(function(d){ | ||
if(d.socialfeed)render(d.socialfeed.posts||[]); | if(d.socialfeed)render(d.socialfeed.posts||[]); | ||
}).catch(function(){ | else render([]); | ||
gel('timeline-container').innerHTML='<div class="sf-empty"><div class="sf-empty-icon"> | }).catch(function(err){ | ||
console.log('Load error:',err); | |||
gel('timeline-container').innerHTML='<div class="sf-empty"><div class="sf-empty-icon">📝</div><div class="sf-empty-text">No posts yet</div><div class="sf-empty-sub">Be the first to share something!</div></div>'; | |||
}); | }); | ||
} | } | ||
| Line 724: | Line 956: | ||
load(); | load(); | ||
loadStories(); | |||
}); | }); | ||
</script> | </script> | ||
</div> | </div> | ||
</html> | </html> | ||
Revision as of 03:10, 3 February 2026
Uploading...
Uploading...
Uploading...
Uploading...
Supports YouTube, Vimeo, or direct video URLs
— or —