[mirotalk] - feat: add self-hosted avatars and Robohash random avatars to profile dialog

This commit is contained in:
Miroslav Pejic
2026-04-28 02:53:17 +02:00
parent c20adb3f59
commit 78e1e09db8
27 changed files with 64 additions and 0 deletions
+2
View File
@@ -180,6 +180,8 @@ To set up your own instance of `MiroTalk P2P` on a dedicated cloud server, pleas
- ianramzy (html [template](https://cruip.com/demos/neon/))
- vasanthv (webrtc-logic)
- fabric.js (whiteboard)
- [Robohash.org](https://robohash.org) (random avatars)
- [Image by ddraw on Freepik](https://www.freepik.com/free-vector/collection-female-male-avatars_1105371.htm) (avatar illustrations)
</details>
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

+62
View File
@@ -12111,6 +12111,8 @@ async function updateMyPeerName() {
* Update my avatar from URL in-memory only (cleared on page refresh)
*/
async function updateMyPeerAvatarByUrl() {
let selectedAvatarUrl = null;
const result = await Swal.fire({
background: swBg,
title: 'Set avatar URL',
@@ -12127,6 +12129,66 @@ async function updateMyPeerAvatarByUrl() {
if (!isImageURL(value)) return 'Please provide a valid image URL';
return null;
},
didOpen: () => {
const input = document.querySelector('.swal2-input');
if (!input) return;
function makeAvatarImg(url, onClick) {
const img = document.createElement('img');
img.src = url;
img.title = 'Click to use this avatar';
img.style.cssText =
'width:48px;height:48px;border-radius:50%;cursor:pointer;border:2px solid transparent;transition:border-color 0.2s;object-fit:cover;background:#222;flex-shrink:0;';
img.addEventListener('mouseover', () => (img.style.borderColor = '#4caf50'));
img.addEventListener('mouseout', () => (img.style.borderColor = 'transparent'));
img.addEventListener('click', onClick);
return img;
}
// Self-hosted avatars
const localLabel = document.createElement('p');
localLabel.textContent = 'Pick an avatar:';
localLabel.style.cssText = 'color:#aaa;font-size:12px;margin:10px 0 6px;text-align:center;';
const localGrid = document.createElement('div');
localGrid.style.cssText =
'display:flex;flex-wrap:wrap;justify-content:center;gap:8px;max-height:120px;overflow-y:auto;padding:4px 2px;margin-bottom:4px;';
for (let i = 1; i <= 25; i++) {
const url = `${window.location.origin}/images/avatars/avatar_${String(i).padStart(2, '0')}.png`;
localGrid.appendChild(
makeAvatarImg(url, () => {
selectedAvatarUrl = url;
input.value = url;
})
);
}
// Robohash random avatars
const roboLabel = document.createElement('p');
roboLabel.textContent = 'Or pick a random avatar:';
roboLabel.style.cssText = 'color:#aaa;font-size:12px;margin:10px 0 6px;text-align:center;';
const roboGrid = document.createElement('div');
roboGrid.style.cssText = 'display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-bottom:4px;';
for (let i = 0; i < 6; i++) {
const seed = Math.random().toString(36).substring(2, 10);
const url = `https://robohash.org/${seed}.png`;
roboGrid.appendChild(
makeAvatarImg(url, () => {
selectedAvatarUrl = url;
input.value = url;
})
);
}
let insertAfter = input;
for (const el of [localLabel, localGrid, roboLabel, roboGrid]) {
insertAfter.parentNode.insertBefore(el, insertAfter.nextSibling);
insertAfter = el;
}
},
});
if (!result.isConfirmed || !result.value) return;