Skip to content

Commit d537cc2

Browse files
committed
feat: upload custom icons for actions (Edge, apps, etc)
- Added file upload button in action form - Converts image to base64 data URL (no server needed) - Supports data: URLs in tile rendering - Removed forced white filter so color icons display correctly
1 parent 775b06a commit d537cc2

2 files changed

Lines changed: 32 additions & 4 deletions

File tree

‎apps/server/public/index.html‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
.tile:active { transform:scale(0.88); background:var(--glass-strong); border-color:var(--glass-border-active); box-shadow:0 0 24px var(--glass-glow); }
120120
.tile .tile-icon { width:32px; height:32px; display:flex; align-items:center; justify-content:center; flex-shrink:0; color:var(--accent); }
121121
.tile .tile-icon svg { width:28px; height:28px; }
122-
.tile .tile-icon img { width:32px; height:32px; border-radius:6px; object-fit:contain; filter:brightness(0) invert(1); }
122+
.tile .tile-icon img { width:32px; height:32px; border-radius:6px; object-fit:contain; }
123123
.tile span { font-size:12px; font-weight:500; text-align:center; line-height:1.3; word-break:break-word; max-width:100%; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; color:var(--text); opacity:.85; }
124124
.tile-widget { font-size:18px; font-weight:700; color:var(--accent); font-family:-apple-system,system-ui,monospace; }
125125

@@ -257,6 +257,8 @@ <h3 id="modal-title">Add action</h3>
257257
<input id="mf-label" placeholder="" required>
258258
<input id="mf-value" required>
259259
<input id="mf-icon" placeholder="">
260+
<input id="mf-icon-file" type="file" accept="image/*" style="display:none">
261+
<button type="button" id="mf-icon-upload" style="padding:8px 12px;border-radius:8px;border:1px solid var(--glass-border);background:var(--glass);color:var(--text-dim);font-size:11px;cursor:pointer;margin-bottom:8px">📎 Upload icon</button>
260262
<input id="mf-category" placeholder="">
261263
<label style="display:flex;align-items:center;gap:8px;padding:8px 0;font-size:12px;color:var(--text-dim);cursor:pointer"><input type="checkbox" id="mf-confirm" style="width:16px;height:16px;accent-color:var(--accent)"> <span id="mf-confirm-label"></span></label>
262264
<button type="submit" class="submit-btn" id="mf-submit-btn"></button>
@@ -492,7 +494,7 @@ <h3 id="modal-title">Add action</h3>
492494

493495
// Tile icon: custom image URL only if set, otherwise Lucide
494496
function getTileIcon(a) {
495-
if (a.icon && a.icon.startsWith('http')) return `<div class="tile-icon"><img src="${a.icon}" alt="" onerror="this.style.display='none'"></div>`;
497+
if (a.icon && (a.icon.startsWith('http') || a.icon.startsWith('data:'))) return `<div class="tile-icon"><img src="${a.icon}" alt="" onerror="this.style.display='none'"></div>`;
496498
const lucideMap = { url: 'globe', copy: 'clipboard', command: 'terminal', shortcut: 'keyboard', macro: 'layers' };
497499
return `<div class="tile-icon"><i data-lucide="${lucideMap[a.type] || 'zap'}"></i></div>`;
498500
}
@@ -925,12 +927,24 @@ <h3 id="modal-title">Add action</h3>
925927
save();
926928
document.getElementById('mf-label').value = '';
927929
document.getElementById('mf-icon').value = '';
930+
document.getElementById('mf-icon-file').value = '';
931+
document.getElementById('mf-icon-upload').textContent = '📎 Upload icon';
928932
document.getElementById('mf-value').value = '';
929933
document.getElementById('mf-category').value = '';
930934
document.getElementById('mf-confirm').checked = false;
931935
closeModal();
932936
};
933937

938+
// Icon upload handler
939+
document.getElementById('mf-icon-upload').onclick = () => document.getElementById('mf-icon-file').click();
940+
document.getElementById('mf-icon-file').onchange = (e) => {
941+
const file = e.target.files[0];
942+
if (!file) return;
943+
const reader = new FileReader();
944+
reader.onload = () => { document.getElementById('mf-icon').value = reader.result; document.getElementById('mf-icon-upload').textContent = '✓ ' + file.name; };
945+
reader.readAsDataURL(file);
946+
};
947+
934948
renderGrid();
935949
</script>
936950
</body>

‎electron/public/index.html‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
.tile:active { transform:scale(0.88); background:var(--glass-strong); border-color:var(--glass-border-active); box-shadow:0 0 24px var(--glass-glow); }
120120
.tile .tile-icon { width:32px; height:32px; display:flex; align-items:center; justify-content:center; flex-shrink:0; color:var(--accent); }
121121
.tile .tile-icon svg { width:28px; height:28px; }
122-
.tile .tile-icon img { width:32px; height:32px; border-radius:6px; object-fit:contain; filter:brightness(0) invert(1); }
122+
.tile .tile-icon img { width:32px; height:32px; border-radius:6px; object-fit:contain; }
123123
.tile span { font-size:12px; font-weight:500; text-align:center; line-height:1.3; word-break:break-word; max-width:100%; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; color:var(--text); opacity:.85; }
124124
.tile-widget { font-size:18px; font-weight:700; color:var(--accent); font-family:-apple-system,system-ui,monospace; }
125125

@@ -257,6 +257,8 @@ <h3 id="modal-title">Add action</h3>
257257
<input id="mf-label" placeholder="" required>
258258
<input id="mf-value" required>
259259
<input id="mf-icon" placeholder="">
260+
<input id="mf-icon-file" type="file" accept="image/*" style="display:none">
261+
<button type="button" id="mf-icon-upload" style="padding:8px 12px;border-radius:8px;border:1px solid var(--glass-border);background:var(--glass);color:var(--text-dim);font-size:11px;cursor:pointer;margin-bottom:8px">📎 Upload icon</button>
260262
<input id="mf-category" placeholder="">
261263
<label style="display:flex;align-items:center;gap:8px;padding:8px 0;font-size:12px;color:var(--text-dim);cursor:pointer"><input type="checkbox" id="mf-confirm" style="width:16px;height:16px;accent-color:var(--accent)"> <span id="mf-confirm-label"></span></label>
262264
<button type="submit" class="submit-btn" id="mf-submit-btn"></button>
@@ -492,7 +494,7 @@ <h3 id="modal-title">Add action</h3>
492494

493495
// Tile icon: custom image URL only if set, otherwise Lucide
494496
function getTileIcon(a) {
495-
if (a.icon && a.icon.startsWith('http')) return `<div class="tile-icon"><img src="${a.icon}" alt="" onerror="this.style.display='none'"></div>`;
497+
if (a.icon && (a.icon.startsWith('http') || a.icon.startsWith('data:'))) return `<div class="tile-icon"><img src="${a.icon}" alt="" onerror="this.style.display='none'"></div>`;
496498
const lucideMap = { url: 'globe', copy: 'clipboard', command: 'terminal', shortcut: 'keyboard', macro: 'layers' };
497499
return `<div class="tile-icon"><i data-lucide="${lucideMap[a.type] || 'zap'}"></i></div>`;
498500
}
@@ -925,12 +927,24 @@ <h3 id="modal-title">Add action</h3>
925927
save();
926928
document.getElementById('mf-label').value = '';
927929
document.getElementById('mf-icon').value = '';
930+
document.getElementById('mf-icon-file').value = '';
931+
document.getElementById('mf-icon-upload').textContent = '📎 Upload icon';
928932
document.getElementById('mf-value').value = '';
929933
document.getElementById('mf-category').value = '';
930934
document.getElementById('mf-confirm').checked = false;
931935
closeModal();
932936
};
933937

938+
// Icon upload handler
939+
document.getElementById('mf-icon-upload').onclick = () => document.getElementById('mf-icon-file').click();
940+
document.getElementById('mf-icon-file').onchange = (e) => {
941+
const file = e.target.files[0];
942+
if (!file) return;
943+
const reader = new FileReader();
944+
reader.onload = () => { document.getElementById('mf-icon').value = reader.result; document.getElementById('mf-icon-upload').textContent = '✓ ' + file.name; };
945+
reader.readAsDataURL(file);
946+
};
947+
934948
renderGrid();
935949
</script>
936950
</body>

0 commit comments

Comments
 (0)