From c93d0748b2c0040142ed9ae762e12d24c560e773 Mon Sep 17 00:00:00 2001 From: Rimek86 Date: Sat, 14 Mar 2026 23:06:39 +0100 Subject: [PATCH 01/16] Update user with newest tachyon protocol data --- src/main/model/user.ts | 11 ++++++++++- src/renderer/store/db.ts | 4 ++++ src/renderer/store/me.store.ts | 4 +++- src/renderer/store/users.store.ts | 7 +++++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/model/user.ts b/src/main/model/user.ts index 0ce8246c6..6d81b4b12 100644 --- a/src/main/model/user.ts +++ b/src/main/model/user.ts @@ -2,14 +2,23 @@ // // SPDX-License-Identifier: MIT +export type ClanBaseData = { + clanId: string; + name: string; + tag: string; + language: string; +}; + export type User = { userId: string; username: string; displayName: string; - clanId: string | null; + clanBaseData?: ClanBaseData | null; partyId: string | null; countryCode: string; status: "offline" | "menu" | "playing" | "lobby"; + rating?: { value: number }; + roles?: ("contributor" | "admin" | "moderator" | "tournament_winner" | "tournament_caster")[]; // Is the user me? isMe?: 0 | 1; diff --git a/src/renderer/store/db.ts b/src/renderer/store/db.ts index 174d8df08..ccd0762e0 100644 --- a/src/renderer/store/db.ts +++ b/src/renderer/store/db.ts @@ -72,6 +72,10 @@ db.version(1).stores({ users: "userId, username, countryCode, status, displayName, clanId, partyId, scopes, isMe", }); +db.version(2).stores({ + users: "userId, username, countryCode, status, displayName, partyId, scopes, isMe", +}); + db.on("ready", function () { console.debug("Database is ready"); }); diff --git a/src/renderer/store/me.store.ts b/src/renderer/store/me.store.ts index e6db7d787..2afb8a7d0 100644 --- a/src/renderer/store/me.store.ts +++ b/src/renderer/store/me.store.ts @@ -17,11 +17,13 @@ export const me = reactive< >({ isInitialized: false, userId: "0", - clanId: null, + clanBaseData: null, partyId: null, countryCode: "", displayName: "", status: "offline", + rating: { value: 0 }, + roles: [], isAuthenticated: false, username: "Player", battleRoomState: {}, diff --git a/src/renderer/store/users.store.ts b/src/renderer/store/users.store.ts index 454941136..7bcccfea8 100644 --- a/src/renderer/store/users.store.ts +++ b/src/renderer/store/users.store.ts @@ -23,6 +23,7 @@ export function initUsersStore() { console.warn("Received user/updated event with no userId, skipping update."); return; } + const updated = await db.users.update(user.userId, { ...user }); if (updated === 0) { @@ -31,12 +32,14 @@ export function initUsersStore() { userId: user.userId, username: "Unknown User", displayName: "Unknown User", - clanId: null, + clanBaseData: null, partyId: null, countryCode: "??", status: "offline", + roles: [], + rating: undefined, battleRoomState: {}, - ...user, // Override defaults with actual data + ...user, }); } }); From 5eecd71fb9274390786d6f071cb885c561d9ed0d Mon Sep 17 00:00:00 2001 From: Rimek86 Date: Sat, 14 Mar 2026 23:08:43 +0100 Subject: [PATCH 02/16] Update profile page: Hide logo, improve layout, display new data (roles, ratings, id), Show clan-search-button if no clan-member --- src/renderer/assets/languages/en.json | 20 +++- src/renderer/views/profile/[userId].vue | 133 +++++++++++++++++++++++- 2 files changed, 147 insertions(+), 6 deletions(-) diff --git a/src/renderer/assets/languages/en.json b/src/renderer/assets/languages/en.json index 9c0c56157..aa0fb688e 100644 --- a/src/renderer/assets/languages/en.json +++ b/src/renderer/assets/languages/en.json @@ -1896,9 +1896,23 @@ }, "views": { "profile": { - "status": "Status: ", - "clan": "Clan: ", - "userNotFound": "User not found" + "status": "Status", + "userId":"User ID", + "clan": "Clan", + "userNotFound": "User not found", + "myProfile": "My profile", + "findAClan": "Find a clan", + "statusOffline": "Offline", + "statusMenu": "Menu", + "statusPlaying": "Playing", + "statusLobby": "Lobby", + "rating": "Rating", + "roles": "Roles", + "roleContributor": "Contributor", + "roleAdmin": "Admin", + "roleModerator": "Moderator", + "roleTournamentWinner": "Tournament Winner", + "roleTournamentCaster": "Tournament Caster" }, "play": { "comingSoon": "(Coming Soon)", diff --git a/src/renderer/views/profile/[userId].vue b/src/renderer/views/profile/[userId].vue index 9ae121537..7113c2365 100644 --- a/src/renderer/views/profile/[userId].vue +++ b/src/renderer/views/profile/[userId].vue @@ -11,14 +11,43 @@ SPDX-License-Identifier: MIT
- +
@@ -36,6 +65,29 @@ import { db } from "@renderer/store/db"; import { useTypedI18n } from "@renderer/i18n"; const { t } = useTypedI18n(); +type UserRole = "contributor" | "admin" | "moderator" | "tournament_winner" | "tournament_caster"; + +const roleTranslationKeys: Record = { + contributor: "lobby.views.profile.roleContributor", + admin: "lobby.views.profile.roleAdmin", + moderator: "lobby.views.profile.roleModerator", + tournament_winner: "lobby.views.profile.roleTournamentWinner", + tournament_caster: "lobby.views.profile.roleTournamentCaster", +}; + +function formatRoles(roles: string[] | undefined) { + if (!roles?.length) return "—"; + + return roles + .map((role) => { + if (role in roleTranslationKeys) { + return t(roleTranslationKeys[role as UserRole]); + } + return role; + }) + .join(", "); +} + const props = defineProps<{ userId: string; }>(); @@ -77,4 +129,79 @@ const user = useDexieLiveQueryWithDeps([() => props.userId], () => { flex-direction: column; gap: 3px; } + +.profile-info { + display: grid; + grid-template-columns: max-content 1fr; + column-gap: 12px; + row-gap: 4px; + margin: 0; + + dt { + color: rgba(255, 255, 255, 0.5); + white-space: nowrap; + } + + dd { + margin: 0; + display: flex; + align-items: center; + } +} +.my-profile-note { + color: rgba(255, 255, 255, 0.5); +} + +.status-dot { + display: inline-block; + width: 12px; + height: 12px; + margin-right: 3px; + border-radius: 50%; + vertical-align: middle; + position: relative; + top: -1px; + box-sizing: border-box; +} + +.status-dot--offline { + background-color: #8d8d8d; +} + +.status-dot--menu { + border: 2px solid #48c774; + background-color: transparent; +} + +.status-dot--lobby { + background-color: #48c774; +} + +.status-dot--playing { + background-color: #f1c40f; +} +.btn-find-clan { + align-self: center; + font-family: Rajdhani; + font-weight: bold; + font-size: 1rem; + padding: 3px 20px; + border: none; + border-radius: 2px; + text-align: center; + cursor: pointer; + position: relative; + overflow: hidden; + transition: + transform 0.3s ease, + box-shadow 0.3s ease; +} +.btn-find-clan { + color: #fff; + background: linear-gradient(90deg, #22c55e, #16a34a); + box-shadow: 0 0 15px rgba(34, 197, 94, 0.4); +} +.btn-find-clan:hover { + box-shadow: 0 0 25px rgba(34, 197, 94, 0.6); +} From 64f06434ba75a056a458602768d33f211c61ea84 Mon Sep 17 00:00:00 2001 From: Rimek86 Date: Sun, 15 Mar 2026 00:02:24 +0100 Subject: [PATCH 03/16] Bugfix: Show profil of friends works now. --- src/renderer/store/users.store.ts | 10 ++++++++++ src/renderer/views/profile/[userId].vue | 11 +++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/renderer/store/users.store.ts b/src/renderer/store/users.store.ts index 7bcccfea8..dfb134e33 100644 --- a/src/renderer/store/users.store.ts +++ b/src/renderer/store/users.store.ts @@ -47,3 +47,13 @@ export function initUsersStore() { usersStore.isInitialized = true; } + +export async function fetchUserInfo(userId: string) { + try { + const response = await window.tachyon.request("user/info", { userId: userId }); + return response.data; + } catch (error) { + console.error("Error fetching user info:", error); + return null; + } +} diff --git a/src/renderer/views/profile/[userId].vue b/src/renderer/views/profile/[userId].vue index 7113c2365..7a9674907 100644 --- a/src/renderer/views/profile/[userId].vue +++ b/src/renderer/views/profile/[userId].vue @@ -63,6 +63,7 @@ import Panel from "@renderer/components/common/Panel.vue"; import { useDexieLiveQueryWithDeps } from "@renderer/composables/useDexieLiveQuery"; import { db } from "@renderer/store/db"; import { useTypedI18n } from "@renderer/i18n"; +import { fetchUserInfo } from "@renderer/store/users.store"; const { t } = useTypedI18n(); type UserRole = "contributor" | "admin" | "moderator" | "tournament_winner" | "tournament_caster"; @@ -92,8 +93,14 @@ const props = defineProps<{ userId: string; }>(); -const user = useDexieLiveQueryWithDeps([() => props.userId], () => { - return db.users.get(props.userId); +const user = useDexieLiveQueryWithDeps([() => props.userId], async () => { + const retval = await db.users.get(props.userId); + + if (!retval || retval.displayName === "Unknown User") { + return await fetchUserInfo(props.userId); + } + + return retval; }); From 0ef1d421cb3bffb7f00930f1bc2b8fc26edb017d Mon Sep 17 00:00:00 2001 From: Rimek86 Date: Sun, 15 Mar 2026 00:14:20 +0100 Subject: [PATCH 04/16] If it's not the own profil and the user is not in a clan the "find clan"-button is not displayed. (Later maybe a invite-button is displayed if the viewer is a clan-leader.) --- src/renderer/views/profile/[userId].vue | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/renderer/views/profile/[userId].vue b/src/renderer/views/profile/[userId].vue index 7a9674907..9105b6aed 100644 --- a/src/renderer/views/profile/[userId].vue +++ b/src/renderer/views/profile/[userId].vue @@ -16,7 +16,9 @@ SPDX-License-Identifier: MIT

{{ user.displayName }} - [{{ t("lobby.views.profile.myProfile") }}] + [{{ t("lobby.views.profile.myProfile") }}]

{{ t("lobby.views.profile.userId") }}:
@@ -39,9 +41,12 @@ SPDX-License-Identifier: MIT
{{ t("lobby.views.profile.clan") }}:
- - - + +
{{ t("lobby.views.profile.roles") }}:
{{ formatRoles(user.roles) }}
From 0fdd80f27f67e3f52987f14ac7af95d28856e8f7 Mon Sep 17 00:00:00 2001 From: Rimek86 Date: Sun, 15 Mar 2026 22:17:58 +0100 Subject: [PATCH 05/16] Redefinement of userrole removed --- src/renderer/views/profile/[userId].vue | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/renderer/views/profile/[userId].vue b/src/renderer/views/profile/[userId].vue index 9105b6aed..ba7f0490a 100644 --- a/src/renderer/views/profile/[userId].vue +++ b/src/renderer/views/profile/[userId].vue @@ -71,9 +71,7 @@ import { useTypedI18n } from "@renderer/i18n"; import { fetchUserInfo } from "@renderer/store/users.store"; const { t } = useTypedI18n(); -type UserRole = "contributor" | "admin" | "moderator" | "tournament_winner" | "tournament_caster"; - -const roleTranslationKeys: Record = { +const roleTranslationKeys: Record = { contributor: "lobby.views.profile.roleContributor", admin: "lobby.views.profile.roleAdmin", moderator: "lobby.views.profile.roleModerator", @@ -87,7 +85,7 @@ function formatRoles(roles: string[] | undefined) { return roles .map((role) => { if (role in roleTranslationKeys) { - return t(roleTranslationKeys[role as UserRole]); + return t(roleTranslationKeys[role]); } return role; }) From c854c715d6c96a5fab3740d3a3932d1ff2fc0080 Mon Sep 17 00:00:00 2001 From: Rimek86 Date: Sun, 15 Mar 2026 22:19:18 +0100 Subject: [PATCH 06/16] Comment removed --- src/renderer/views/profile/[userId].vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/views/profile/[userId].vue b/src/renderer/views/profile/[userId].vue index ba7f0490a..5eab9b3e4 100644 --- a/src/renderer/views/profile/[userId].vue +++ b/src/renderer/views/profile/[userId].vue @@ -11,7 +11,6 @@ SPDX-License-Identifier: MIT
-