2024-06-28 06:19:00 +01:00
|
|
|
<script>
|
2024-06-30 19:57:32 +01:00
|
|
|
import Logo from '$lib/../img/campfire-logo.svg';
|
2024-06-28 06:19:00 +01:00
|
|
|
import Button from './Button.svelte';
|
|
|
|
import Feed from './Feed.svelte';
|
2024-07-01 03:41:02 +01:00
|
|
|
import { client } from '$lib/client/client.js';
|
2024-07-02 20:21:34 +01:00
|
|
|
import { user } from '$lib/stores/user.js';
|
2024-06-29 14:54:03 +01:00
|
|
|
import { play_sound } from '$lib/sound.js';
|
|
|
|
import { getTimeline } from '$lib/timeline.js';
|
2024-07-02 19:38:20 +01:00
|
|
|
import { getNotifications } from '$lib/notifications.js';
|
2024-06-29 16:19:34 +01:00
|
|
|
import { goto } from '$app/navigation';
|
2024-07-02 19:38:20 +01:00
|
|
|
import { page } from '$app/stores';
|
2024-06-29 23:10:29 +01:00
|
|
|
import { get } from 'svelte/store';
|
2024-07-02 19:38:20 +01:00
|
|
|
import { logged_in } from '$lib/stores/user.js';
|
|
|
|
import { unread_notif_count, last_read_notif_id } from '$lib/notifications.js';
|
2024-06-28 06:19:00 +01:00
|
|
|
|
2024-06-30 19:57:32 +01:00
|
|
|
import TimelineIcon from '../../img/icons/timeline.svg';
|
|
|
|
import NotificationsIcon from '../../img/icons/notifications.svg';
|
|
|
|
import ExploreIcon from '../../img/icons/explore.svg';
|
|
|
|
import ListIcon from '../../img/icons/lists.svg';
|
|
|
|
import FavouritesIcon from '../../img/icons/like_fill.svg';
|
|
|
|
import BookmarkIcon from '../../img/icons/bookmark.svg';
|
|
|
|
import HashtagIcon from '../../img/icons/hashtag.svg';
|
|
|
|
import PostIcon from '../../img/icons/post.svg';
|
|
|
|
import InfoIcon from '../../img/icons/info.svg';
|
|
|
|
import SettingsIcon from '../../img/icons/settings.svg';
|
|
|
|
import LogoutIcon from '../../img/icons/logout.svg';
|
|
|
|
|
2024-06-29 14:48:34 +01:00
|
|
|
const VERSION = APP_VERSION;
|
2024-06-28 06:19:00 +01:00
|
|
|
|
2024-07-02 12:36:26 +01:00
|
|
|
function handle_btn(name) {
|
2024-07-02 19:38:20 +01:00
|
|
|
if (!get(logged_in)) return;
|
2024-07-02 12:36:26 +01:00
|
|
|
let route;
|
|
|
|
switch (name) {
|
|
|
|
case "timeline":
|
|
|
|
route = "/";
|
2024-07-02 12:43:58 +01:00
|
|
|
getTimeline(true);
|
2024-07-02 12:36:26 +01:00
|
|
|
break;
|
2024-07-02 19:38:20 +01:00
|
|
|
case "notifications":
|
|
|
|
route = "/notifications";
|
|
|
|
getNotifications();
|
|
|
|
break;
|
2024-07-02 12:36:26 +01:00
|
|
|
case "explore":
|
|
|
|
case "lists":
|
|
|
|
case "favourites":
|
|
|
|
case "bookmarks":
|
|
|
|
case "hashtags":
|
2024-07-02 19:38:20 +01:00
|
|
|
default:
|
2024-07-02 12:36:26 +01:00
|
|
|
return;
|
2024-06-29 14:48:34 +01:00
|
|
|
}
|
2024-07-02 12:36:26 +01:00
|
|
|
if (!route) return;
|
|
|
|
window.scrollTo({
|
|
|
|
top: 0,
|
|
|
|
behavior: "smooth"
|
|
|
|
});
|
|
|
|
goto(route);
|
2024-06-28 06:19:00 +01:00
|
|
|
}
|
|
|
|
|
2024-06-29 23:10:29 +01:00
|
|
|
async function log_out() {
|
2024-06-28 06:19:00 +01:00
|
|
|
if (!confirm("This will log you out. Are you sure?")) return;
|
2024-07-01 03:41:02 +01:00
|
|
|
await get(client).logout();
|
2024-06-29 23:10:29 +01:00
|
|
|
goto("/");
|
2024-06-28 06:19:00 +01:00
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<div id="navigation">
|
2024-07-01 03:41:02 +01:00
|
|
|
<header class="instance-header">
|
|
|
|
<div class="app-logo">
|
|
|
|
<Logo />
|
|
|
|
</div>
|
|
|
|
</header>
|
2024-06-28 06:19:00 +01:00
|
|
|
|
2024-07-02 19:38:20 +01:00
|
|
|
{#if $logged_in}
|
2024-06-28 06:19:00 +01:00
|
|
|
<div id="nav-items">
|
2024-07-02 12:36:26 +01:00
|
|
|
<Button label="Timeline"
|
2024-07-02 12:43:58 +01:00
|
|
|
on:click={() => handle_btn("timeline")}
|
2024-07-02 19:38:20 +01:00
|
|
|
active={$page.url.pathname === "/"}>
|
2024-06-30 19:57:32 +01:00
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<TimelineIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
Timeline
|
|
|
|
</Button>
|
2024-07-02 12:36:26 +01:00
|
|
|
<Button label="Notifications"
|
2024-07-02 12:43:58 +01:00
|
|
|
on:click={() => handle_btn("notifications")}
|
2024-07-02 19:38:20 +01:00
|
|
|
active={$page.url.pathname === "/notifications"}>
|
2024-06-30 19:57:32 +01:00
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<NotificationsIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
Notifications
|
2024-07-02 19:38:20 +01:00
|
|
|
{#if $unread_notif_count}
|
|
|
|
<span class="notification-count">
|
|
|
|
{$unread_notif_count <= 99 ? $unread_notif_count : "99+"}
|
|
|
|
</span>
|
2024-06-28 06:19:00 +01:00
|
|
|
{/if}
|
|
|
|
</Button>
|
2024-06-30 19:57:32 +01:00
|
|
|
<Button label="Explore" disabled>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<ExploreIcon height="auto"/>
|
|
|
|
</svelte:fragment>
|
|
|
|
Explore
|
|
|
|
</Button>
|
|
|
|
<Button label="Lists" disabled>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<ListIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
Lists
|
|
|
|
</Button>
|
2024-06-28 06:19:00 +01:00
|
|
|
|
|
|
|
<div class="flex-row">
|
2024-06-30 19:57:32 +01:00
|
|
|
<Button centered label="Favourites" disabled>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<FavouritesIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
</Button>
|
|
|
|
<Button centered label="Bookmarks" disabled>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<BookmarkIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
</Button>
|
|
|
|
<Button centered label="Hashtags" disabled>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<HashtagIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
</Button>
|
2024-06-28 06:19:00 +01:00
|
|
|
</div>
|
|
|
|
|
2024-06-30 19:57:32 +01:00
|
|
|
<Button filled label="Post" disabled>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<PostIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
Post
|
|
|
|
</Button>
|
2024-06-28 06:19:00 +01:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="account-items">
|
|
|
|
<div class="flex-row">
|
2024-06-30 19:57:32 +01:00
|
|
|
<Button centered label="Profile information" disabled>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<InfoIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
</Button>
|
|
|
|
<Button centered label="Settings" disabled>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<SettingsIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
</Button>
|
|
|
|
<Button centered label="Log out" on:click={() => log_out()}>
|
|
|
|
<svelte:fragment slot="icon">
|
|
|
|
<LogoutIcon/>
|
|
|
|
</svelte:fragment>
|
|
|
|
</Button>
|
2024-06-28 06:19:00 +01:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="account-button">
|
2024-07-02 20:21:34 +01:00
|
|
|
<img src={$user.avatar_url} class="account-avatar" height="64px" alt="" aria-hidden="true" on:click={() => play_sound()}>
|
2024-06-28 06:19:00 +01:00
|
|
|
<div class="account-name" aria-hidden="true">
|
2024-07-02 21:58:46 +01:00
|
|
|
<a href={$user.url} class="nickname" title={$user.nickname}>{@html $user.rich_name}</a>
|
2024-07-02 20:21:34 +01:00
|
|
|
<span class="username" title={`@${$user.username}@${$user.host}`}>
|
|
|
|
{`@${$user.username}@${$user.host}`}
|
2024-06-28 06:19:00 +01:00
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{/if}
|
|
|
|
<span class="version">
|
2024-06-30 17:37:19 +01:00
|
|
|
campfire v{VERSION}
|
2024-06-28 06:19:00 +01:00
|
|
|
<br>
|
|
|
|
<ul>
|
2024-06-30 20:53:51 +01:00
|
|
|
<li><a href="https://git.arimelody.me/blisstown/campfire">source</a></li>
|
|
|
|
<li><a href="https://github.com/blisstown/campfire/issues">issues</a></li>
|
2024-06-28 06:19:00 +01:00
|
|
|
</ul>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
#navigation {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
position: fixed;
|
|
|
|
top: 16px;
|
|
|
|
width: 300px;
|
|
|
|
height: calc(100vh - 32px);
|
|
|
|
border-radius: 8px;
|
|
|
|
background-color: var(--bg-800);
|
|
|
|
}
|
|
|
|
|
2024-06-29 15:24:33 +01:00
|
|
|
.instance-header {
|
2024-06-28 06:19:00 +01:00
|
|
|
width: 100%;
|
|
|
|
height: 172px;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
border-radius: 8px;
|
|
|
|
background-position: center;
|
|
|
|
background-size: cover;
|
|
|
|
background-color: var(--bg-600);
|
|
|
|
background-image: linear-gradient(to top, var(--bg-800), var(--bg-600));
|
|
|
|
}
|
|
|
|
|
|
|
|
.instance-icon {
|
2024-06-29 15:24:33 +01:00
|
|
|
height: 50%;
|
2024-06-28 06:19:00 +01:00
|
|
|
border-radius: 8px;
|
|
|
|
}
|
|
|
|
|
2024-06-30 21:08:14 +01:00
|
|
|
.app-logo {
|
|
|
|
max-width: 70%;
|
|
|
|
max-height: 70%;
|
2024-06-28 06:19:00 +01:00
|
|
|
margin: auto;
|
|
|
|
}
|
|
|
|
|
2024-06-30 21:08:14 +01:00
|
|
|
.app-logo :global(svg) {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
|
2024-06-28 06:19:00 +01:00
|
|
|
#nav-items {
|
|
|
|
margin-bottom: auto;
|
|
|
|
padding: 16px;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
gap: 8px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.notification-count {
|
|
|
|
position: relative;
|
|
|
|
transform: translate(22px, -16px);
|
|
|
|
min-width: 12px;
|
|
|
|
height: 28px;
|
2024-07-02 19:38:20 +01:00
|
|
|
margin-left: auto;
|
2024-06-28 06:19:00 +01:00
|
|
|
padding: 0 8px;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
text-align: right;
|
|
|
|
border-radius: 8px;
|
|
|
|
font-weight: 700;
|
|
|
|
color: var(--bg-1000);
|
|
|
|
background-color: var(--accent);
|
|
|
|
box-shadow: 0 0 32px color-mix(in srgb, transparent, var(--accent) 100%);
|
|
|
|
}
|
|
|
|
|
|
|
|
#account-items {
|
|
|
|
padding: 16px;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
gap: 8px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.version {
|
|
|
|
margin-bottom: 16px;
|
|
|
|
font-style: italic;
|
|
|
|
font-size: .9em;
|
|
|
|
opacity: .6;
|
|
|
|
text-align: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.version ul {
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
display: flex;
|
|
|
|
gap: 8px;
|
|
|
|
justify-content: center;
|
|
|
|
list-style: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.version ul li {
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
.version ul li:not(:first-child):before {
|
|
|
|
content: '•';
|
|
|
|
margin-right: 8px;
|
|
|
|
color: inherit;
|
|
|
|
opacity: .7;
|
|
|
|
}
|
|
|
|
|
|
|
|
.version a {
|
|
|
|
color: inherit;
|
|
|
|
text-decoration: none;
|
|
|
|
opacity: .7;
|
|
|
|
}
|
|
|
|
|
|
|
|
.version a:hover {
|
|
|
|
text-decoration: underline;
|
|
|
|
}
|
|
|
|
|
|
|
|
#account-button {
|
|
|
|
width: calc(100% - 16px);
|
|
|
|
height: 48px;
|
|
|
|
padding: 8px;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
align-items: center;
|
|
|
|
gap: 8px;
|
|
|
|
|
|
|
|
font-family: inherit;
|
|
|
|
font-size: 1rem;
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
background-color: var(--bg-700);
|
|
|
|
color: var(--text);
|
|
|
|
border-color: transparent;
|
|
|
|
|
|
|
|
transition-property: border-color, background-color, color;
|
|
|
|
transition-timing-function: ease-out;
|
|
|
|
transition-duration: .1s;
|
|
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
.account-avatar {
|
|
|
|
width: 48px;
|
|
|
|
height: 48px;
|
|
|
|
border-radius: 8px;
|
|
|
|
transition: transform .1s ease-out, box-shadow .2s;
|
|
|
|
}
|
|
|
|
|
|
|
|
.account-avatar:hover {
|
|
|
|
transform: scale(1.05);
|
|
|
|
box-shadow: 0 0 16px color-mix(in srgb, transparent, var(--accent) 25%);
|
|
|
|
}
|
|
|
|
|
|
|
|
.account-avatar:active {
|
|
|
|
transform: scale(.95);
|
|
|
|
box-shadow: 0 0 16px var(--bg-1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
.account-name {
|
|
|
|
/* width: 152px; */
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
gap: 2px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.username, .nickname {
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
overflow: hidden;
|
|
|
|
white-space: nowrap;
|
|
|
|
font-size: .8em;
|
2024-07-01 03:58:31 +01:00
|
|
|
color: inherit;
|
2024-06-28 06:19:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
.username {
|
|
|
|
opacity: .8;
|
|
|
|
font-size: .65em;
|
|
|
|
}
|
|
|
|
|
2024-07-02 21:58:46 +01:00
|
|
|
.nickname :global(.emoji) {
|
|
|
|
height: 1.2em;
|
|
|
|
margin: -.1em 0;
|
|
|
|
}
|
|
|
|
|
2024-06-28 06:19:00 +01:00
|
|
|
.flex-row {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
gap: 8px;
|
|
|
|
}
|
|
|
|
</style>
|