From 0a61e93c7f8c9c05713788ae0c448a94de6d1c24 Mon Sep 17 00:00:00 2001 From: Yuto Nishida Date: Fri, 26 Dec 2025 21:24:16 -0800 Subject: [PATCH] [ATMii] Working render --- .../packages/client/src/pages/Profile.tsx | 64 +++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/experimental/atmii/packages/client/src/pages/Profile.tsx b/experimental/atmii/packages/client/src/pages/Profile.tsx index 9a8f324..00ef985 100644 --- a/experimental/atmii/packages/client/src/pages/Profile.tsx +++ b/experimental/atmii/packages/client/src/pages/Profile.tsx @@ -17,8 +17,41 @@ import { getPdsEndpoint } from '@atcute/identity' +import Mii from '@pretendonetwork/mii-js'; + import { useState, useEffect, useMemo } from 'react' +function base64ToArrayBuffer(base64: string): ArrayBuffer { + const binaryString = atob(base64); + const len = binaryString.length; + const bytes = new Uint8Array(len); + + for (let i = 0; i < len; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + + return bytes.buffer; +} + +function base64UrlToUint8Array(base64url: string): Uint8Array { + let base64 = base64url + .replace(/-/g, '+') + .replace(/_/g, '/') + + // pad with '=' + const pad = base64.length % 4 + if (pad) { + base64 += '='.repeat(4 - pad) + } + + const binary = atob(base64) + const bytes = new Uint8Array(binary.length) + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i) + } + return bytes +} + const handleResolver = new CompositeHandleResolver({ methods: { dns: new DohJsonHandleResolver({ dohUrl: 'https://mozilla.cloudflare-dns.com/dns-query' }), @@ -43,7 +76,8 @@ const Profile = () => { const [resolvedActor, setResolvedActor] = useState(null); const [rpc, setRpc] = useState(); const [miiCid, setMiiCid] = useState(null); - const [mii, setMii] = useState(new Uint8Array()) + const [mii, setMii] = useState(new Uint8Array()) + const [renderUrl, setRenderUrl] = useState(null); useEffect(() => { if (!handle || !isActorIdentifier(handle)) return; @@ -90,14 +124,36 @@ const Profile = () => { console.log('blobResult is not ok'); return; } - const miiData = new Uint8Array(blobResult.data); - setMii(miiData); + const data = blobResult.data as Uint8Array; + console.log('data: ', data); + setMii(data); }; fetchMii(); }, [handle]) - return
Profile Page
+ useEffect(() => { + // Convert mii blob to image buffer + const renderMii = async () => { + if (!mii) return; + console.log('mii: ', mii); + const miiData = new Mii(mii.buffer.slice(mii.byteOffset, mii.byteLength) as unknown as Buffer); + + //const miiData = new Mii(mii.buffer); + + //const exampleMiiStr = 'AwAAML1PTlt3fzJUk4gSiED0BxyEoQAAAEDEMOAwrjAAAAAAAAAAAAAAAAAAAEBAAAAhAQJoRBgmNEYUgRIXaA0AACkAUkhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBd'; + //const miiData = new Mii(base64ToArrayBuffer(exampleMiiStr)) + setRenderUrl(miiData.studioUrl()); + }; + renderMii(); + }, [mii]) + + return
+

+ Profile Page +

+ {renderUrl && mii render} +
} export default Profile \ No newline at end of file -- 2.51.2