diff --git a/types/props.ts b/types/props.ts
index aa6ff0c..fe2b049 100644
--- a/types/props.ts
+++ b/types/props.ts
@@ -9,6 +9,7 @@ export interface MessageProps {
format: "12" | "24",
type: "normal" | "grouped",
marginBottom: boolean,
+ authorColor: string,
last: boolean,
messageId: string,
replyingTo?: boolean,
diff --git a/utils/generateIrcColor.ts b/utils/generateIrcColor.ts
new file mode 100644
index 0000000..d2ed643
--- /dev/null
+++ b/utils/generateIrcColor.ts
@@ -0,0 +1,12 @@
+import xxhash from "xxhash-wasm"
+
+const { h64 } = await xxhash()
+
+export default (seed: string): string => {
+ const lightness = 50
+
+ // this should probably be cached eventually
+ const idHash = h64(seed)
+
+ return `hsl(${idHash % 360n}, 100%, ${lightness}%)`
+}
\ No newline at end of file
From dc786cd42078a89466664f43dda316b9223e175e Mon Sep 17 00:00:00 2001
From: JustTemmie <47639983+JustTemmie@users.noreply.github.com>
Date: Sun, 13 Jul 2025 18:17:01 +0200
Subject: [PATCH 03/10] fix: remove random console log
---
components/Message.vue | 2 --
1 file changed, 2 deletions(-)
diff --git a/components/Message.vue b/components/Message.vue
index e1d3c6c..b6afc7b 100644
--- a/components/Message.vue
+++ b/components/Message.vue
@@ -118,8 +118,6 @@ onMounted(async () => {
// showHover.value = !showHover.value;
//}
-console.log(props.authorColor)
-
const menuItems = [
{ name: "Reply", callback: () => { if (messageElement.value) replyToMessage(messageElement.value, props) } }
]
From 9bfe3310ccd4334e45436a79881c417e98c360c1 Mon Sep 17 00:00:00 2001
From: JustTemmie <47639983+JustTemmie@users.noreply.github.com>
Date: Mon, 14 Jul 2025 19:48:35 +0200
Subject: [PATCH 04/10] fix: comply with es2020 standards
---
utils/generateIrcColor.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/utils/generateIrcColor.ts b/utils/generateIrcColor.ts
index d2ed643..24d4946 100644
--- a/utils/generateIrcColor.ts
+++ b/utils/generateIrcColor.ts
@@ -1,6 +1,9 @@
import xxhash from "xxhash-wasm"
-const { h64 } = await xxhash()
+let h64: CallableFunction;
+(async () => {
+ h64 = (await xxhash()).h64;
+})();
export default (seed: string): string => {
const lightness = 50
From 25cd9a397e5ef5a7cb9396fe5e0ad1d7ec9e3fd7 Mon Sep 17 00:00:00 2001
From: JustTemmie <47639983+JustTemmie@users.noreply.github.com>
Date: Mon, 14 Jul 2025 20:05:31 +0200
Subject: [PATCH 05/10] feat: implement caching for hash function
---
utils/generateIrcColor.ts | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/utils/generateIrcColor.ts b/utils/generateIrcColor.ts
index 24d4946..03a30e7 100644
--- a/utils/generateIrcColor.ts
+++ b/utils/generateIrcColor.ts
@@ -5,11 +5,9 @@ let h64: CallableFunction;
h64 = (await xxhash()).h64;
})();
-export default (seed: string): string => {
- const lightness = 50
-
- // this should probably be cached eventually
- const idHash = h64(seed)
+export default (seed: string, saturation: number = 100, lightness: number = 50): string => {
+ const idHash = useState(`h64Hash-${seed}`, () => h64(seed))
+ const hashValue: bigint = idHash.value
- return `hsl(${idHash % 360n}, 100%, ${lightness}%)`
+ return `hsl(${hashValue % 360n}, ${saturation}%, ${lightness}%)`
}
\ No newline at end of file
From b319a06749199d4baab0e9c085592b33ba0b6bec Mon Sep 17 00:00:00 2001
From: JustTemmie <47639983+JustTemmie@users.noreply.github.com>
Date: Mon, 14 Jul 2025 21:36:41 +0200
Subject: [PATCH 06/10] feat: import function from JOHN OZBAY
---
utils/isCanvasBlocked.ts | 50 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 utils/isCanvasBlocked.ts
diff --git a/utils/isCanvasBlocked.ts b/utils/isCanvasBlocked.ts
new file mode 100644
index 0000000..3bd191e
--- /dev/null
+++ b/utils/isCanvasBlocked.ts
@@ -0,0 +1,50 @@
+//
+// Canvas Blocker &
+// Firefox privacy.resistFingerprinting Detector.
+// (c) 2018 // JOHN OZBAY // CRYPT.EE
+// MIT License
+//
+export default () => {
+ // create a 1px image data
+ var blocked = false;
+ var canvas = document.createElement("canvas");
+ var ctx = canvas.getContext("2d");
+
+ // some blockers just return an undefined ctx. So let's check that first.
+ if (ctx) {
+ var imageData = ctx.createImageData(1,1);
+ var originalImageData = imageData.data;
+
+ // set pixels to RGB 128
+ originalImageData[0]=128;
+ originalImageData[1]=128;
+ originalImageData[2]=128;
+ originalImageData[3]=255;
+
+ // set this to canvas
+ ctx.putImageData(imageData,1,1);
+
+ try {
+ // now get the data back from canvas.
+ var checkData = ctx.getImageData(1, 1, 1, 1).data;
+
+ // If this is firefox, and privacy.resistFingerprinting is enabled,
+ // OR a browser extension blocking the canvas,
+ // This will return RGB all white (255,255,255) instead of the (128,128,128) we put.
+
+ // so let's check the R and G to see if they're 255 or 128 (matching what we've initially set)
+ if (originalImageData[0] !== checkData[0] && originalImageData[1] !== checkData[1]) {
+ blocked = true;
+ console.log("Canvas is blocked. Will display warning.");
+ }
+ } catch (error) {
+ // some extensions will return getImageData null. this is to account for that.
+ blocked = true;
+ console.log("Canvas is blocked. Will display warning.");
+ }
+ } else {
+ blocked = true;
+ console.log("Canvas is blocked. Will display warning.");
+ }
+ return blocked;
+}
\ No newline at end of file
From f4ddcf9d8db61d4c4704514de43cbe186fde9ac8 Mon Sep 17 00:00:00 2001
From: JustTemmie <47639983+JustTemmie@users.noreply.github.com>
Date: Mon, 14 Jul 2025 21:37:45 +0200
Subject: [PATCH 07/10] fix: prop
---
types/props.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/types/props.ts b/types/props.ts
index fe2b049..9a8e642 100644
--- a/types/props.ts
+++ b/types/props.ts
@@ -3,7 +3,7 @@ import type { MessageResponse, UserResponse } from "./interfaces";
export interface MessageProps {
class?: string,
img?: string | null,
- author?: UserResponse
+ author: UserResponse
text: string,
timestamp: number,
format: "12" | "24",
From f98e8c611092e747e267afd029cf87eeebf21cca Mon Sep 17 00:00:00 2001
From: JustTemmie <47639983+JustTemmie@users.noreply.github.com>
Date: Mon, 14 Jul 2025 21:39:00 +0200
Subject: [PATCH 08/10] feat: implement generic
component
---
components/Avatar.vue | 37 ++++++++++++++++++++++++++++++++++
components/User/UserEntry.vue | 8 +++++---
components/User/UserPopup.vue | 3 +--
layouts/client.vue | 2 +-
utils/generateDefaultIcon.ts | 38 +++++++++++++++++++++++++++++++++++
5 files changed, 82 insertions(+), 6 deletions(-)
create mode 100644 components/Avatar.vue
create mode 100644 utils/generateDefaultIcon.ts
diff --git a/components/Avatar.vue b/components/Avatar.vue
new file mode 100644
index 0000000..368316c
--- /dev/null
+++ b/components/Avatar.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/User/UserEntry.vue b/components/User/UserEntry.vue
index b463759..b539f2c 100644
--- a/components/User/UserEntry.vue
+++ b/components/User/UserEntry.vue
@@ -1,8 +1,8 @@
-
-
- {{ props.user.display_name || props.user.username }}
+
+
+ {{ displayName }}
@@ -12,6 +12,8 @@ import type { UserResponse } from '~/types/interfaces';
const props = defineProps<{
user: UserResponse
}>();
+
+const displayName = props.user.display_name || props.user.username