Skip to content

Commit

Permalink
add Jdenticons for a recognizable representation of inproxy ID
Browse files Browse the repository at this point in the history
absolute import style
  • Loading branch information
tmgrask committed Oct 23, 2024
1 parent 2c07228 commit 663d5ac
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 6 deletions.
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"expo-status-bar": "~1.12.1",
"expo-system-ui": "~3.0.7",
"i18next": "^23.15.1",
"jdenticon": "^3.3.0",
"micro-key-producer": "^0.7.0",
"react": "18.2.0",
"react-i18next": "^15.0.2",
Expand Down
8 changes: 8 additions & 0 deletions src/common/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,12 @@ describe("utils", () => {
expect(utils.byteArraysAreEqual(byteArrayA, byteArrayB)).toBe(false);
expect(utils.byteArraysAreEqual(byteArrayA, byteArrayC)).toBe(false);
});

it("hexToHueDegrees", () => {
expect(utils.hexToHueDegrees("#E0E0E0")).toEqual(0);
expect(utils.hexToHueDegrees("#000000")).toEqual(0);
expect(utils.hexToHueDegrees("#d54028")).toEqual(8);
expect(utils.hexToHueDegrees("#3b7a96")).toEqual(198);
expect(utils.hexToHueDegrees("#5d4264")).toEqual(288);
});
});
54 changes: 48 additions & 6 deletions src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ export function uint8ArrayToJsonObject(arr: Uint8Array): any {
return JSON.parse(new TextDecoder().decode(arr));
}

export function niceBytes(bytes: number, errorHandler: (error: Error) => void) {
var units = ["bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"];
var unit = units.shift() as string;
export function niceBytes(
bytes: number,
errorHandler: (error: Error) => void,
): string {
let units = ["bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"];
let unit = units.shift() as string;
try {
while (units.length > 0 && bytes >= 1024) {
bytes /= 1024;
Expand All @@ -33,12 +36,12 @@ export function niceBytes(bytes: number, errorHandler: (error: Error) => void) {
return `${bytes.toFixed(bytes > 0 ? 1 : 0)} ${unit}`;
}

export function bytesToMB(bytes: number) {
export function bytesToMB(bytes: number): number {
"worklet";
return bytes / 1024 / 1024;
}

export function MBToBytes(MB: number) {
export function MBToBytes(MB: number): number {
"worklet";
return MB * 1024 * 1024;
}
Expand All @@ -51,7 +54,7 @@ export function timedLog(message: string) {
console.log(`${now.toISOString()} (+${diff}): ${message}`);
}

export function drawBigFont(win: ScaledSize) {
export function drawBigFont(win: ScaledSize): boolean {
// used to determine if we should scale font size down for smaller screens
// only currently applied to skia-rendered paragraphs
if (win.height * win.scale > 1000) {
Expand All @@ -60,3 +63,42 @@ export function drawBigFont(win: ScaledSize) {
return false;
}
}

// hexToHueDegrees extracts Hue in degrees from a hex string
// https://en.wikipedia.org/wiki/Hue
export function hexToHueDegrees(hex: string): number {
if (hex.length != 7 || !hex.startsWith("#")) {
console.error("Could not convert hex to hsl, invalid hex format");
return 0;
}

let r = parseInt(hex.substring(1, 3), 16);
let g = parseInt(hex.substring(3, 5), 16);
let b = parseInt(hex.substring(5, 8), 16);
(r /= 255), (g /= 255), (b /= 255);
let max = Math.max(r, g, b);
let min = Math.min(r, g, b);

// "Defining hue in terms of RGB" from wikipedia
let h = 0;
if (max === min) {
// leave as zero
} else {
let d = max - min;
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}

h /= 6;
}

return Math.round(360 * h);
}
35 changes: 35 additions & 0 deletions src/components/Jdenticon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Canvas, ImageSVG, Skia } from "@shopify/react-native-skia";
import * as jdenticon from "jdenticon";

import { hexToHueDegrees } from "@/src/common/utils";
import { palette, sharedStyles as ss } from "@/src/styles";

const defaultConfig: jdenticon.JdenticonConfig = {
// use app palette as hues
hues: [
hexToHueDegrees(palette.blue),
hexToHueDegrees(palette.red),
hexToHueDegrees(palette.purple),
],
saturation: {
color: 0.4,
},
};

export function Jdenticon({
value,
size,
config = defaultConfig,
}: {
value: string;
size: number;
config?: jdenticon.JdenticonConfig;
}) {
const svg = Skia.SVG.MakeFromString(jdenticon.toSvg(value, size, config));

return (
<Canvas style={[ss.flex]}>
<ImageSVG svg={svg} x={0} y={0} width={size} height={size} />
</Canvas>
);
}
9 changes: 9 additions & 0 deletions src/components/ProxyID.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Pressable, Text, View } from "react-native";

import { Icon } from "@/src/components/Icon";
import { palette, sharedStyles as ss } from "@/src/styles";
import { Jdenticon } from "@/src/components/Jdenticon";

export function ProxyID({
proxyId,
Expand Down Expand Up @@ -42,6 +43,14 @@ export function ProxyID({
},
]}
>
<View
style={{
width: 34,
height: 34,
}}
>
<Jdenticon value={proxyId} size={34} />
</View>
<Text style={[ss.blackText, ss.bodyFont]}>
{proxyId.substring(0, 4)}...
</Text>
Expand Down

0 comments on commit 663d5ac

Please sign in to comment.