Skip to content

Commit bc798b5

Browse files
committed
fix: pictique groups
1 parent d0931dc commit bc798b5

File tree

40 files changed

+1227
-636
lines changed

40 files changed

+1227
-636
lines changed

infrastructure/eid-wallet/src-tauri/gen/android/.idea/gradle.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 Bytes
Binary file not shown.

infrastructure/eid-wallet/src/routes/(app)/settings/+page.svelte

Lines changed: 118 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,100 @@
11
<script lang="ts">
2-
import { goto } from "$app/navigation";
3-
import { SettingsNavigationBtn } from "$lib/fragments";
4-
import type { GlobalState } from "$lib/global";
5-
import { runtime } from "$lib/global/runtime.svelte";
6-
import { ButtonAction, Drawer } from "$lib/ui";
7-
import {
8-
Key01Icon,
9-
LanguageSquareIcon,
10-
Link02Icon,
11-
PinCodeIcon,
12-
Shield01Icon,
13-
} from "@hugeicons/core-free-icons";
14-
import { getContext } from "svelte";
15-
16-
const globalState = getContext<() => GlobalState>("globalState")();
17-
18-
let isDeleteConfirmationOpen = $state(false);
19-
let isFinalConfirmationOpen = $state(false);
20-
21-
function showDeleteConfirmation() {
22-
isDeleteConfirmationOpen = true;
23-
}
24-
25-
function confirmDelete() {
26-
isDeleteConfirmationOpen = false;
27-
isFinalConfirmationOpen = true;
28-
}
29-
30-
function nukeWallet() {
31-
globalState.userController.user = undefined;
32-
globalState.securityController.clearPin();
33-
isFinalConfirmationOpen = false;
34-
goto("/onboarding");
35-
}
36-
37-
function cancelDelete() {
38-
isDeleteConfirmationOpen = false;
39-
isFinalConfirmationOpen = false;
40-
}
41-
42-
$effect(() => {
43-
runtime.header.title = "Settings";
44-
});
2+
import { goto } from "$app/navigation";
3+
import { SettingsNavigationBtn } from "$lib/fragments";
4+
import type { GlobalState } from "$lib/global";
5+
import { runtime } from "$lib/global/runtime.svelte";
6+
import { ButtonAction, Drawer } from "$lib/ui";
7+
import {
8+
Key01Icon,
9+
LanguageSquareIcon,
10+
Link02Icon,
11+
PinCodeIcon,
12+
Shield01Icon,
13+
} from "@hugeicons/core-free-icons";
14+
import { getContext } from "svelte";
15+
16+
const globalState = getContext<() => GlobalState>("globalState")();
17+
18+
let isDeleteConfirmationOpen = $state(false);
19+
let isFinalConfirmationOpen = $state(false);
20+
21+
// Hidden eVault profile retry functionality
22+
let tapCount = $state(0);
23+
let lastTapTime = $state(0);
24+
let isRetrying = $state(false);
25+
let retryMessage = $state("");
26+
27+
function showDeleteConfirmation() {
28+
isDeleteConfirmationOpen = true;
29+
}
30+
31+
function confirmDelete() {
32+
isDeleteConfirmationOpen = false;
33+
isFinalConfirmationOpen = true;
34+
}
35+
36+
function nukeWallet() {
37+
globalState.userController.user = undefined;
38+
globalState.securityController.clearPin();
39+
isFinalConfirmationOpen = false;
40+
goto("/onboarding");
41+
}
42+
43+
function cancelDelete() {
44+
isDeleteConfirmationOpen = false;
45+
isFinalConfirmationOpen = false;
46+
}
47+
48+
async function handleVersionTap() {
49+
const now = Date.now();
50+
51+
// Reset counter if more than 3 seconds between taps
52+
if (now - lastTapTime > 3000) {
53+
tapCount = 0;
54+
}
55+
56+
tapCount++;
57+
lastTapTime = now;
58+
59+
// Show tap count feedback (only visible to user)
60+
if (tapCount >= 5) {
61+
retryMessage = `Taps: ${tapCount}/10`;
62+
}
63+
64+
// Trigger eVault profile retry after 10 taps
65+
if (tapCount === 10) {
66+
isRetrying = true;
67+
retryMessage = "Retrying eVault profile setup...";
68+
69+
try {
70+
await globalState.vaultController.retryProfileCreation();
71+
retryMessage =
72+
"✅ eVault profile setup completed successfully!";
73+
74+
// Reset after success
75+
setTimeout(() => {
76+
tapCount = 0;
77+
retryMessage = "";
78+
isRetrying = false;
79+
}, 3000);
80+
} catch (error) {
81+
console.error("Failed to retry eVault profile setup:", error);
82+
retryMessage =
83+
"❌ Failed to setup eVault profile. Check console for details.";
84+
85+
// Reset after error
86+
setTimeout(() => {
87+
tapCount = 0;
88+
retryMessage = "";
89+
isRetrying = false;
90+
}, 5000);
91+
}
92+
}
93+
}
94+
95+
$effect(() => {
96+
runtime.header.title = "Settings";
97+
});
4598
</script>
4699

47100
<main>
@@ -66,7 +119,28 @@ $effect(() => {
66119
>Delete Account</ButtonAction
67120
>
68121

69-
<p class="w-full py-10 text-center">Version v0.1.8.1</p>
122+
<!-- Hidden eVault profile retry - tap version 10 times -->
123+
<div class="w-full py-10 text-center">
124+
<button
125+
class="text-gray-500 hover:text-gray-700 transition-colors cursor-pointer select-none"
126+
on:click={handleVersionTap}
127+
disabled={isRetrying}
128+
>
129+
Version v0.1.8.1
130+
</button>
131+
132+
{#if retryMessage}
133+
<div
134+
class="mt-2 text-sm {isRetrying
135+
? 'text-blue-600'
136+
: retryMessage.includes('')
137+
? 'text-green-600'
138+
: 'text-red-600'}"
139+
>
140+
{retryMessage}
141+
</div>
142+
{/if}
143+
</div>
70144
</main>
71145

72146
<!-- First Confirmation Drawer -->

infrastructure/evault-core/src/evault.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class EVault {
3131
this.w3id = process.env.W3ID || null;
3232
const dbService = new DbService(driver);
3333
this.logService = new LogService(driver);
34-
this.graphqlServer = new GraphQLServer(dbService, this.publicKey, this.w3id);
34+
this.graphqlServer = new GraphQLServer(dbService, this.publicKey, this.w3id, this);
3535
this.server = fastify({
3636
logger: true,
3737
});

infrastructure/evault-core/src/protocol/graphql-server.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ export class GraphQLServer {
1919
server?: Server;
2020
private evaultPublicKey: string | null;
2121
private evaultW3ID: string | null;
22+
private evaultInstance: any; // Reference to the eVault instance
2223

23-
constructor(db: DbService, evaultPublicKey?: string | null, evaultW3ID?: string | null) {
24+
constructor(db: DbService, evaultPublicKey?: string | null, evaultW3ID?: string | null, evaultInstance?: any) {
2425
this.db = db;
2526
this.accessGuard = new VaultAccessGuard(db);
2627
this.evaultPublicKey = evaultPublicKey || process.env.EVAULT_PUBLIC_KEY || null;
2728
this.evaultW3ID = evaultW3ID || process.env.W3ID || null;
29+
this.evaultInstance = evaultInstance;
2830
}
2931

3032
public getSchema(): GraphQLSchema {
@@ -110,6 +112,17 @@ export class GraphQLServer {
110112
}
111113
}
112114

115+
/**
116+
* Gets the current eVault W3ID dynamically from the eVault instance
117+
* @returns string | null - The current eVault W3ID
118+
*/
119+
private getCurrentEvaultW3ID(): string | null {
120+
if (this.evaultInstance && this.evaultInstance.w3id) {
121+
return this.evaultInstance.w3id;
122+
}
123+
return this.evaultW3ID;
124+
}
125+
113126
init() {
114127
const resolvers = {
115128
JSON: require("graphql-type-json"),
@@ -170,7 +183,7 @@ export class GraphQLServer {
170183
context.tokenPayload?.platform || null;
171184
const webhookPayload = {
172185
id: result.metaEnvelope.id,
173-
w3id: this.evaultW3ID,
186+
w3id: this.getCurrentEvaultW3ID(),
174187
evaultPublicKey: this.evaultPublicKey,
175188
data: input.payload,
176189
schemaId: input.ontology,
@@ -228,7 +241,7 @@ export class GraphQLServer {
228241
context.tokenPayload?.platform || null;
229242
const webhookPayload = {
230243
id: id,
231-
w3id: this.evaultW3ID,
244+
w3id: this.getCurrentEvaultW3ID(),
232245
evaultPublicKey: this.evaultPublicKey,
233246
data: input.payload,
234247
schemaId: input.ontology,

infrastructure/web3-adapter/src/evault/evault.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,10 @@ export class EVaultClient {
247247

248248
private async resolveEndpoint(w3id: string): Promise<string> {
249249
try {
250+
const enrichedW3id = w3id.startsWith("@") ? w3id : `@${w3id}`
251+
console.log("fetching endpoint for :", enrichedW3id)
250252
const response = await fetch(
251-
new URL(`/resolve?w3id=${w3id}`, this.registryUrl).toString(),
253+
new URL(`/resolve?w3id=${enrichedW3id}`, this.registryUrl).toString(),
252254
);
253255

254256
if (!response.ok) {
@@ -280,6 +282,7 @@ export class EVaultClient {
280282
},
281283
});
282284
}
285+
console.log('sending to endpoint', this.endpoint)
283286
return this.client;
284287
}
285288

@@ -290,6 +293,7 @@ export class EVaultClient {
290293
});
291294
if (!client) return v4();
292295

296+
console.log("sending to eVault: ", envelope.w3id)
293297
console.log("sending payload", envelope);
294298

295299
const response = await client

platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ type Tweet = {
4343

4444
type Chat = {
4545
id: string;
46-
type: "direct" | "group";
46+
type: "direct" | "group"; // Always set by webhook based on participant count
4747
name?: string;
4848
participants: string[];
4949
createdAt: Timestamp;
@@ -269,13 +269,17 @@ export class WebhookController {
269269
}
270270

271271
private mapChatData(data: any, now: Timestamp): Partial<Chat> {
272+
const participants = data.participants.map(
273+
(p: string) => p.split("(")[1].split(")")[0],
274+
) || [];
275+
276+
// Derive type from participant count
277+
const type = participants.length > 2 ? "group" : "direct";
278+
272279
return {
273-
type: data.type || "direct",
280+
type,
274281
name: data.name,
275-
participants:
276-
data.participants.map(
277-
(p: string) => p.split("(")[1].split(")")[0],
278-
) || [],
282+
participants,
279283
createdAt: data.createdAt
280284
? Timestamp.fromDate(new Date(data.createdAt))
281285
: now,

platforms/blabsy/src/components/chat/add-members.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,20 +240,17 @@ export function AddMembers({
240240
selectedUsers
241241
);
242242

243-
// Determine if this should be a direct or group chat
244-
const isGroupChat = selectedUsers.length > 1;
245-
const chatType = isGroupChat ? 'group' : 'direct';
246-
247243
// Get all participant IDs (including current user)
248244
const participantIds = [
249245
user.id,
250246
...selectedUsers.map((u) => u.id)
251247
];
252248

253249
console.log('Participant IDs:', participantIds);
254-
console.log('Chat type:', chatType);
255250

256251
let chatName: string | undefined;
252+
const isGroupChat = participantIds.length > 2;
253+
257254
if (isGroupChat) {
258255
// For group chats, use the custom name or create from selected users
259256
chatName =
@@ -264,10 +261,10 @@ export function AddMembers({
264261
}
265262

266263
console.log('Chat name:', chatName);
264+
console.log('Is group chat:', isGroupChat);
267265

268266
// Create the new chat
269267
const chatId = await createNewChat(
270-
chatType,
271268
participantIds,
272269
chatName
273270
);
@@ -277,7 +274,6 @@ export function AddMembers({
277274
// Set the new chat as current
278275
setCurrentChat({
279276
id: chatId,
280-
type: chatType,
281277
participants: participantIds,
282278
name: chatName,
283279
owner: isGroupChat ? user.id : undefined,

platforms/blabsy/src/components/chat/chat-list.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useChat } from '@lib/context/chat-context';
88
import { db } from '@lib/firebase/app';
99
import { Loading } from '@components/ui/loading';
1010
import type { Chat } from '@lib/types/chat';
11+
import { getChatType } from '@lib/types/chat';
1112
import type { User } from '@lib/types/user';
1213
import { AddMembers } from './add-members';
1314

@@ -127,7 +128,7 @@ export function ChatList(): JSX.Element {
127128
</div>
128129
<div className='flex-1 overflow-hidden text-left'>
129130
<p className='truncate font-medium'>
130-
{chat.type === 'direct'
131+
{getChatType(chat) === 'direct'
131132
? participant?.name ||
132133
participant?.username ||
133134
otherParticipant
@@ -185,7 +186,7 @@ function ChatListItem({
185186
onClick={onClick}
186187
>
187188
<div className='flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-gray-200 dark:bg-gray-700'>
188-
{chat.type === 'group' ? (
189+
{getChatType(chat) === 'group' ? (
189190
<svg
190191
className='h-6 w-6 text-gray-500'
191192
fill='none'

0 commit comments

Comments
 (0)