The News page was a hardcoded "under construction" stub, and the Friends/ Alerts header icons did nothing -- both replaced with real Vue pages/ widgets backed by the server's existing news/notifications/community APIs, reached through a generic authenticated REST bridge (community_api.rs: api_get/api_post/api_delete) and a websocket bridge for live chat/presence (community_ws.rs, mirrors the reqwest_websocket pattern remote.rs already uses for the auth-code exchange). - News: GET /api/v1/client/news, rendered with micromark, with real loading/empty/error states. - Alerts: GET/POST /api/v1/notifications/*, polled (not the notifications websocket -- see notifications.ts for why), unread badge + mark one/all read. - Friends: full friends composable (list/requests/search/presence) plus a header dropdown and a /community/friends management page. - Chat: /community/chat, rooms (server/global/title/DM) over the live community websocket with a REST history/read-state load on room switch. - Achievements: per-game card on the library detail page and a per-user summary on the new read-only profile page (/community/profile/:username). - The Community tab's "opens in your system browser" page is gone; /community is now a real in-app hub (activity feed + server list) linking into friends/chat. Also fixes a real auth gap found by actually running the built client against the live server: notifications/community routes are gated by aclManager.getUserIdACL, which only accepts a session cookie or an opaque Bearer APIToken -- never the client's own short-lived signed JWT (generate_authorization_header). The client already had a bridge for this (POST /api/v1/client/user/webtoken, JWT-authenticated, mints an opaque token), but CLIENT_WEBTOKEN_ACLS never granted it the notifications/ community scopes, so the exchange succeeded and the minted token still got 403'd on every one of these routes. Extended that ACL list (04.auth-init.ts) and switched community_api.rs/community_ws.rs to mint and use that webtoken instead of the JWT for these specific calls. Client version bumped to 0.4.2 (tauri.conf.json).
26 lines
653 B
Vue
26 lines
653 B
Vue
<template>
|
|
<img
|
|
v-if="url"
|
|
:src="useObject(url)"
|
|
:class="['rounded-sm bg-zinc-800 object-cover shrink-0', sizeClass]"
|
|
/>
|
|
<div
|
|
v-else
|
|
:class="['rounded-sm bg-zinc-800 flex items-center justify-center text-zinc-500 shrink-0', sizeClass]"
|
|
>
|
|
<UserIcon class="h-1/2 w-1/2" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { UserIcon } from "@heroicons/vue/20/solid";
|
|
|
|
const props = withDefaults(
|
|
defineProps<{ url?: string | null; size?: "sm" | "md" | "lg" }>(),
|
|
{ size: "sm" },
|
|
);
|
|
|
|
const sizeClass = computed(() =>
|
|
props.size === "lg" ? "w-16 h-16" : props.size === "md" ? "w-10 h-10" : "w-7 h-7",
|
|
);
|
|
</script>
|