initial profile implementation!

This commit is contained in:
ari melody 2025-07-14 00:19:42 +01:00
parent 667b11f2f4
commit 449a11ee55
Signed by: ari
GPG key ID: CF99829C92678188
14 changed files with 212 additions and 57 deletions

View file

@ -27,7 +27,12 @@ export function parseAccount(data) {
account.username = data.username;
account.name = account.nickname || account.username;
account.avatar_url = data.avatar;
account.banner_url = data.header;
account.url = data.url;
account.followers_count = data.followers_count;
account.following_count = data.following_count;
account.posts_count = data.statuses_count;
account.bio = data.note;
if (data.acct.includes('@'))
account.host = data.acct.split('@')[1];

View file

@ -1,3 +1,7 @@
const errors = {
AUTHENTICATION_FAILED: "AUTHENTICATION_FAILED",
};
/**
* GET /api/v1/instance
* @param {string} host - The domain of the target server.
@ -421,3 +425,26 @@ export async function getUser(host, token, user_id) {
return data;
}
/**
* GET /api/v1/accounts/lookup?acct={handle}
* @param {string} host - The domain of the target server.
* @param {string} token - The application token.
* @param {string} handle - The handle of the user to fetch.
*/
export async function lookupUser(host, token, handle) {
let url = `https://${host}/api/v1/accounts/lookup?acct=${handle}`;
const res = await fetch(url, {
method: 'GET',
headers: { "Authorization": token ? `Bearer ${token}` : null }
});
if (!res.ok) {
const json = await res.json();
if (json.error = errors.AUTHENTICATION_FAILED)
throw new Error("This method requires authentication");
}
const data = await res.json();
return data;
}

View file

@ -2,6 +2,9 @@ import * as api from '$lib/api.js';
import { writable } from 'svelte/store';
import { app_name } from '$lib/config.js';
import { browser } from "$app/environment";
import Lang from '$lib/lang';
const lang = Lang('en_GB');
const server_types = {
UNSUPPORTED: "unsupported",

View file

@ -18,9 +18,21 @@
function click() {
if (disabled) return;
if (href) {
location = href;
const link = document.createElement('a');
link.href = href;
link.dispatchEvent(new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
ctrlKey: event.ctrlKey,
metaKey: event.metaKey,
shiftKey: event.shiftKey,
altKey: event.altKey,
button: event.button,
}));
return;
}
playSound(sound);
dispatch('click');
}

View file

@ -90,7 +90,8 @@
<div class="composer">
<div class="composer-header-container">
<a href={$account.url} target="_blank" class="composer-avatar-container" on:mouseup|stopPropagation>
<!-- TODO: account switcher in composer -->
<a href="" class="composer-avatar-container" on:mouseup|stopPropagation>
<img src={$account.avatar_url} type={$account.avatar_type} alt="" width="48" height="48" class="composer-avatar" loading="lazy" decoding="async">
</a>
<header class="composer-header">

View file

@ -61,6 +61,16 @@
goto(route);
}
function gotoProfile() {
if (!$account) return;
playSound();
window.scrollTo({
top: 0,
behavior: "smooth"
});
goto(`/${$server.host}/${$account.username}`);
}
async function log_out() {
if (!confirm("This will log you out. Are you sure?")) return;
@ -171,9 +181,9 @@
</div>
<div id="account-button">
<img src={$account.avatar_url} class="account-avatar" height="64px" alt="" aria-hidden="true" on:click={() => playSound()}>
<img src={$account.avatar_url} class="account-avatar" height="64px" alt="" aria-hidden="true" on:click={() => gotoProfile()}>
<div class="account-name" aria-hidden="true">
<a href={$account.url} class="nickname" title={$account.nickname}>{@html $account.rich_name}</a>
<a href="/{$server.host}/{$account.username}" class="nickname" title={$account.nickname}>{@html $account.rich_name}</a>
<span class="username" title={`@${$account.username}@${$account.host}`}>
{$account.fqn}
</span>

View file

@ -1,5 +1,6 @@
<script>
import { shorthand as short_time } from '$lib/time.js';
import { server } from '$lib/client/server';
import Lang from '$lib/lang';
const lang = Lang('en_GB');
@ -14,7 +15,7 @@
<span class="post-context-action">
{ @html
lang.string('post.boosted',
`<a href={${post.account.url}} target="_blank"><span class="name">${post.account.rich_name}</span></a>`)
`<a href="/${$server.host}/${post.account.fqn}"><span class="name">${post.account.rich_name}</span></a>`)
}
</span>
<span class="post-context-time">

View file

@ -1,5 +1,6 @@
<script>
import { shorthand as short_time } from '$lib/time.js';
import { server } from '$lib/client/server';
import Lang from '$lib/lang';
const lang = Lang('en_GB');
@ -11,12 +12,12 @@
</script>
<div class={"post-header-container" + (reply ? " reply" : "")}>
<a href={post.account.url} target="_blank" class="post-avatar-container" on:mouseup|stopPropagation>
<a href="/{$server.host}/{post.account.fqn}" class="post-avatar-container" on:mouseup|stopPropagation>
<img src={post.account.avatar_url} type={post.account.avatar_type} alt="" width="48" height="48" class="post-avatar" loading="lazy" decoding="async">
</a>
<header class="post-header">
<div class="post-user-info" on:mouseup|stopPropagation>
<a href={post.account.url} target="_blank" class="name">{@html post.account.rich_name}</a>
<a href="/{$server.host}/{post.account.fqn}" class="name">{@html post.account.rich_name}</a>
<span class="username">{post.account.mention}</span>
</div>
<div class="post-info" on:mouseup|stopPropagation>