Added Drag and drop and a export feature
Signed-off-by: AvaLilac <amyshimplays@gmail.com>
This commit is contained in:
parent
7110c2202f
commit
34fd294be9
1 changed files with 102 additions and 4 deletions
|
|
@ -27,6 +27,26 @@
|
||||||
return {name,author,version,description};
|
return {name,author,version,description};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sanitizeFilename(name) {
|
||||||
|
return name
|
||||||
|
.replace(/[<>:"/\\|?*\x00-\x1f]/g, "")
|
||||||
|
.replace(/\s+/g, "_")
|
||||||
|
.replace(/\.+$/, "")
|
||||||
|
.trim() || "theme";
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadTheme(theme) {
|
||||||
|
const name = parseMeta(theme.css).name;
|
||||||
|
const filename = sanitizeFilename(name) + ".css";
|
||||||
|
const blob = new Blob([theme.css], { type: "text/css" });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
a.download = filename;
|
||||||
|
a.click();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
function applyThemes(){
|
function applyThemes(){
|
||||||
document.querySelectorAll(".avia-theme-style").forEach(e=>e.remove());
|
document.querySelectorAll(".avia-theme-style").forEach(e=>e.remove());
|
||||||
const themes = getThemes();
|
const themes = getThemes();
|
||||||
|
|
@ -242,12 +262,77 @@
|
||||||
gap:"8px"
|
gap:"8px"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const dropOverlay=document.createElement("div");
|
||||||
|
dropOverlay.textContent="Drop .css or .txt files here";
|
||||||
|
Object.assign(dropOverlay.style,{
|
||||||
|
position:"absolute",
|
||||||
|
inset:"0",
|
||||||
|
background:"rgba(0,0,0,0.6)",
|
||||||
|
display:"flex",
|
||||||
|
alignItems:"center",
|
||||||
|
justifyContent:"center",
|
||||||
|
fontSize:"18px",
|
||||||
|
fontWeight:"600",
|
||||||
|
color:"#fff",
|
||||||
|
opacity:"0",
|
||||||
|
pointerEvents:"none",
|
||||||
|
transition:"opacity 0.15s ease",
|
||||||
|
borderRadius:"16px"
|
||||||
|
});
|
||||||
|
|
||||||
panel.appendChild(header);
|
panel.appendChild(header);
|
||||||
panel.appendChild(close);
|
panel.appendChild(close);
|
||||||
panel.appendChild(btnRow);
|
panel.appendChild(btnRow);
|
||||||
panel.appendChild(list);
|
panel.appendChild(list);
|
||||||
|
panel.appendChild(dropOverlay);
|
||||||
document.body.appendChild(panel);
|
document.body.appendChild(panel);
|
||||||
|
|
||||||
|
let dragDepth = 0;
|
||||||
|
|
||||||
|
panel.addEventListener("dragenter", e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
dragDepth++;
|
||||||
|
dropOverlay.style.opacity = "1";
|
||||||
|
panel.style.border = "1px dashed rgba(255,255,255,0.4)";
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.addEventListener("dragover", e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.addEventListener("dragleave", e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
dragDepth--;
|
||||||
|
if (dragDepth <= 0) {
|
||||||
|
dropOverlay.style.opacity = "0";
|
||||||
|
panel.style.border = "1px solid rgba(255,255,255,0.08)";
|
||||||
|
dragDepth = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.addEventListener("drop", async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
dropOverlay.style.opacity = "0";
|
||||||
|
panel.style.border = "1px solid rgba(255,255,255,0.08)";
|
||||||
|
dragDepth = 0;
|
||||||
|
|
||||||
|
const files = [...e.dataTransfer.files].filter(f => f.name.endsWith(".css") || f.name.endsWith(".txt"));
|
||||||
|
if (!files.length) return;
|
||||||
|
|
||||||
|
const themes = getThemes();
|
||||||
|
for (const file of files) {
|
||||||
|
const css = await file.text();
|
||||||
|
themes.push({ id: crypto.randomUUID(), css, enabled: true });
|
||||||
|
}
|
||||||
|
setThemes(themes);
|
||||||
|
applyThemes();
|
||||||
|
render();
|
||||||
|
});
|
||||||
|
|
||||||
function render(){
|
function render(){
|
||||||
list.innerHTML="";
|
list.innerHTML="";
|
||||||
const themes=getThemes();
|
const themes=getThemes();
|
||||||
|
|
@ -312,6 +397,15 @@
|
||||||
styleBtn(edit, "rgba(100,160,255,0.15)");
|
styleBtn(edit, "rgba(100,160,255,0.15)");
|
||||||
edit.onclick=()=>openThemeEditor(theme);
|
edit.onclick=()=>openThemeEditor(theme);
|
||||||
|
|
||||||
|
const dlBtn=document.createElement("button");
|
||||||
|
dlBtn.textContent="Export";
|
||||||
|
styleBtn(dlBtn, "rgba(80,200,120,0.15)");
|
||||||
|
dlBtn.title="Download theme as .css";
|
||||||
|
dlBtn.onclick=(e)=>{
|
||||||
|
e.stopPropagation();
|
||||||
|
downloadTheme(theme);
|
||||||
|
};
|
||||||
|
|
||||||
const del=document.createElement("button");
|
const del=document.createElement("button");
|
||||||
del.textContent="✕";
|
del.textContent="✕";
|
||||||
styleBtn(del, "rgba(255,80,80,0.15)");
|
styleBtn(del, "rgba(255,80,80,0.15)");
|
||||||
|
|
@ -324,6 +418,7 @@
|
||||||
|
|
||||||
controls.appendChild(toggle);
|
controls.appendChild(toggle);
|
||||||
controls.appendChild(edit);
|
controls.appendChild(edit);
|
||||||
|
controls.appendChild(dlBtn);
|
||||||
controls.appendChild(del);
|
controls.appendChild(del);
|
||||||
card.appendChild(left);
|
card.appendChild(left);
|
||||||
card.appendChild(controls);
|
card.appendChild(controls);
|
||||||
|
|
@ -337,12 +432,15 @@
|
||||||
const input=document.createElement("input");
|
const input=document.createElement("input");
|
||||||
input.type="file";
|
input.type="file";
|
||||||
input.accept=".css,.txt";
|
input.accept=".css,.txt";
|
||||||
|
input.multiple=true;
|
||||||
input.onchange=async()=>{
|
input.onchange=async()=>{
|
||||||
const file=input.files[0];
|
const files=[...input.files];
|
||||||
if(!file) return;
|
if(!files.length) return;
|
||||||
const css=await file.text();
|
|
||||||
const themes=getThemes();
|
const themes=getThemes();
|
||||||
themes.push({id:crypto.randomUUID(),css,enabled:true});
|
for(const file of files){
|
||||||
|
const css=await file.text();
|
||||||
|
themes.push({id:crypto.randomUUID(),css,enabled:true});
|
||||||
|
}
|
||||||
setThemes(themes);
|
setThemes(themes);
|
||||||
applyThemes();
|
applyThemes();
|
||||||
render();
|
render();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue