feat: Tweaks + PlayerHead component

This commit is contained in:
LynithDev 2024-03-17 13:34:29 +01:00
parent f699125c7c
commit 0f5b035e17
7 changed files with 86 additions and 11 deletions

BIN
src/assets/images/steve.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -2,7 +2,7 @@ import { invoke } from '@tauri-apps/api/core';
import { listen } from '@tauri-apps/api/event';
type MicrosoftLoginCallback = (msg: string, stage: number) => never;
async function loginMicrosoft(cb?: MicrosoftLoginCallback): Promise<auth.Account> {
export async function loginMicrosoft(cb?: MicrosoftLoginCallback): Promise<auth.Account> {
if (cb) {
const unlisten = await listen<[string, number, boolean]>('msa:status', (event) => {
cb(event.payload[0], event.payload[1]);
@ -15,6 +15,12 @@ async function loginMicrosoft(cb?: MicrosoftLoginCallback): Promise<auth.Account
return await invoke('plugin:auth|login_msa');
}
export async function getUuidHeadSrc(uuid: string): Promise<string> {
// TODO implement some kind of caching + fallback
return `https://crafatar.com/avatars/${uuid}?size=32`;
}
export default {
loginMicrosoft,
getUuidHeadSrc,
};

View file

@ -1,7 +1,11 @@
import { A } from '@solidjs/router';
import { createSignal } from 'solid-js';
import { Bell01Icon, Cloud01Icon, Settings01Icon, TerminalBrowserIcon, TerminalIcon } from '@untitled-theme/icons-solid';
import useAccount from '../hooks/useAccount';
import PolyfrostFull from './logos/PolyfrostFull';
import AccountPopup from './overlay/AccountPopup';
import PlayerHead from './game/PlayerHead';
import Button from './base/Button';
interface NavbarLinkProps {
path: string;
@ -24,6 +28,8 @@ function NavbarLink(props: NavbarLinkProps) {
function Navbar() {
const [profileMenuOpen, setProfileMenuOpen] = createSignal(false);
const account = useAccount();
let profileButton!: HTMLButtonElement;
return (
@ -36,9 +42,25 @@ function Navbar() {
<NavbarLink path="/browser" label="Browser" />
<NavbarLink path="/updates" label="Updates" />
</div>
<div class="flex flex-row justify-end relative">
<div class="flex flex-row justify-end items-center gap-x-2 relative">
<Button styleType="icon" class="w-8 h-8">
<TerminalBrowserIcon class="w-7 h-7" />
</Button>
<Button styleType="icon" class="w-8 h-8">
<Cloud01Icon class="w-7 h-7" />
</Button>
<Button styleType="icon" class="w-8 h-8">
<Bell01Icon class="w-7 h-7" />
</Button>
<Button styleType="icon" class="w-8 h-8">
<Settings01Icon class="w-7 h-7" />
</Button>
<button ref={profileButton} onClick={() => setProfileMenuOpen(!profileMenuOpen())}>
<img class="w-7 h-7 rounded-md hover:opacity-70" src="https://crafatar.com/avatars/f247be7c5b8241c69148793ded77e71f?size=100" alt="" />
<PlayerHead class="w-[30px] h-[30px] rounded-md hover:opacity-70" uuid={account.uuid} />
</button>
</div>

View file

@ -24,7 +24,19 @@
@apply p-1.5 hover:bg-gray-0.05 active:bg-gray-0.10 aspect-square box-border;
& > * {
@apply w-full h-full;
@apply w-full h-full stroke-fg-primary;
}
&:hover > * {
@apply stroke-fg-primary-hover;
}
&:active > * {
@apply stroke-fg-primary-pressed;
}
&:disabled > * {
@apply stroke-fg-primary-disabled;
}
}
}

View file

@ -0,0 +1,20 @@
import { createResource } from 'solid-js';
import type { JSX } from 'solid-js';
import auth from '../../../bridge/auth';
import steveSrc from '../../../assets/images/steve.png';
type PlayerHeadProps = JSX.IntrinsicElements['img'] & { uuid: string };
async function fetchHeadSrc(uuid: string) {
return await auth.getUuidHeadSrc(uuid);
}
function PlayerHead(props: PlayerHeadProps) {
const [headSrc] = createResource(() => props.uuid, fetchHeadSrc, {
initialValue: steveSrc,
});
return <img src={headSrc()} {...props} />;
}
export default PlayerHead;

View file

@ -1,10 +1,12 @@
import { LogOut01Icon, PlusIcon, Settings01Icon } from '@untitled-theme/icons-solid';
import Button from '../base/Button';
import PlayerHead from '../game/PlayerHead';
import useAccount from '../../hooks/useAccount';
import Popup from './Popup';
interface AccountComponentProps {
username: string;
headSrc: string;
uuid: string;
loggedIn?: boolean;
}
@ -12,7 +14,7 @@ function AccountComponent(props: AccountComponentProps) {
return (
<div class={`flex flex-row justify-between p-2 rounded-lg ${!props.loggedIn && 'hover:bg-gray-0.05 active:bg-gray-0.10 hover:text-fg-primary-hover'}`}>
<div class="flex flex-row justify-start flex-1 gap-x-3">
<img class="w-8 h-8 rounded-md" src={props.headSrc} alt="" />
<PlayerHead class="w-8 h-8 rounded-md" uuid={props.uuid} />
<div class="flex flex-col items-center justify-center">
<div class="flex flex-col items-start justify-between">
<p class="font-semibold h-[18px]">{props.username}</p>
@ -30,17 +32,19 @@ function AccountComponent(props: AccountComponentProps) {
}
function AccountPopup(props: Popup.PopupProps) {
const loggedInAccount = useAccount();
return (
<Popup {...props}>
<div class="bg-component-bg rounded-xl border border-gray-0.10 w-72 p-2 shadow-lg shadow-black/50">
<div class="bg-secondary rounded-xl border border-gray-0.10 w-72 p-2 shadow-lg shadow-black/50">
<div class="flex flex-col gap-y-2 text-fg-primary">
<AccountComponent username="Caledonian" headSrc="https://crafatar.com/avatars/f247be7c5b8241c69148793ded77e71f?size=100" loggedIn />
<AccountComponent username={loggedInAccount.username} uuid={loggedInAccount.uuid} loggedIn />
<div class="w-full h-px bg-gray-0.05 rounded-md" />
<AccountComponent username="Caledonian" headSrc="https://crafatar.com/avatars/f247be7c5b8241c69148793ded77e71f?size=100" />
<AccountComponent username="Caledonian" headSrc="https://crafatar.com/avatars/f247be7c5b8241c69148793ded77e71f?size=100" />
<AccountComponent username="Caledonian" headSrc="https://crafatar.com/avatars/f247be7c5b8241c69148793ded77e71f?size=100" />
<AccountComponent username="Caledonian" uuid="f247be7c5b8241c69148793ded77e71f" />
<AccountComponent username="Caledonian" uuid="069a79f4-44e9-4726-a5be-fca90e38aaf5" />
<AccountComponent username="Caledonian" uuid="f247be7c5b8241c69148793ded77e71f" />
<div class="w-full h-px bg-gray-0.05 rounded-md" />

View file

@ -0,0 +1,11 @@
function useAccount(): auth.Account {
// TODO return the currently logged in account
return {
username: 'Lynith',
uuid: 'f247be7c-5b82-41c6-9148-793ded77e71f',
skins: [],
};
}
export default useAccount;