ident
All repositories: gitoria
2.4 KB
// avatar.js — the avatar upload of ident's identity form (ticket #15). A picked image file is// cut to a centred square, scaled to 128×128 and written into the form's hidden #favatar as a// data URL (WebP; JPEG when the browser cannot make WebP and PNG would be too big); an `input`// event hands it to the page, which sends it with the other fields. Idempotent: hl:webex may// run a page script again when it recreates a view (hybriel #32), so the listener sits on the// document once.(function () {if (window.__identAvatar) return;window.__identAvatar = true;const SIDE = 128, MAX_FILE = 20 * 1024 * 1024, MAX_URL = 60000;function note(text) {const n = document.querySelector('#avatarnote');if (n) n.textContent = text;}function encode(canvas) {let url = canvas.toDataURL('image/webp', 0.85);if (!url.startsWith('data:image/webp') && url.length > MAX_URL) url = canvas.toDataURL('image/jpeg', 0.85);return url;}document.addEventListener('change', function (ev) {const input = ev.target;if (!input || input.id !== 'favatarfile') return;const file = input.files && input.files[0];if (!file) return;note('');if (!/^image\/(png|jpeg|webp|gif)$/.test(file.type)) { note('That is not a picture (PNG, JPEG, WebP or GIF).'); input.value = ''; return; }if (file.size > MAX_FILE) { note('That picture is too big (at most 20 MB).'); input.value = ''; return; }const src = URL.createObjectURL(file);const img = new Image();img.onload = function () {URL.revokeObjectURL(src);const side = Math.min(img.naturalWidth, img.naturalHeight);if (!side) { note('That picture could not be read.'); return; }const canvas = document.createElement('canvas');canvas.width = SIDE; canvas.height = SIDE;const cx = canvas.getContext('2d');cx.drawImage(img, (img.naturalWidth - side) / 2, (img.naturalHeight - side) / 2, side, side, 0, 0, SIDE, SIDE);const url = encode(canvas);if (url.length > MAX_URL) { note('That picture is too complex — try another one.'); return; }const field = document.querySelector('#favatar');if (!field) return;field.value = url;field.dispatchEvent(new Event('input', { bubbles: true }));input.value = '';};img.onerror = function () { URL.revokeObjectURL(src); note('That picture could not be read.'); input.value = ''; };img.src = src;});})();
Branches
- mainmain branch
Latest commits
- ff78726cident: Hybriel master 190aa11d (fc838894 GC correctness, #127, #126 closure scopes); gates all greenmre
- a3a7d21aident: Hybriel master 8efba065 (#126 GC by bytes, #48 lambda params copy); session-writing lambdas take &sessionmre
- 98226b41antcolony#40: mission references point to the moved missionsmre
- ff805b9aantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
- 51a7bcdfident: Hybriel master 73267707 (#122); /code uses the new page() signature; pending address passed as parameter; once-checksmre
- 836f644fident#24: installable app (manifest, service worker, data-free offline /start), own iconmre
- 8bebbbf2deploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- cc063ea2deploy.sh: never send .git or .gitignore to Byrodinmre
- 81b15b7bState of 2026-09-27, before the move to gitoriamre