Added project avatar

This commit is contained in:
Pavel Laptev 2024-02-28 13:07:48 +01:00 committed by Mattias Granlund
parent ada64ac160
commit 40cc56db9b
3 changed files with 145 additions and 62 deletions

View File

@ -8,7 +8,7 @@
import { navCollapsed } from '$lib/config/config';
import { persisted } from '$lib/persisted/persisted';
import { SETTINGS_CONTEXT, type SettingsStore } from '$lib/settings/userSettings';
import { platform } from '@tauri-apps/api/os';
import { type Platform, platform } from '@tauri-apps/api/os';
import { getContext } from 'svelte';
import type { User } from '$lib/backend/cloud';
import type { Project, ProjectService } from '$lib/backend/projects';
@ -41,11 +41,12 @@
$: isNavCollapsedPersist = navCollapsed();
let isNavCollapsed = $isNavCollapsedPersist;
// Detect is the platform is Mac
let isMacos = false;
// Detect is the platform
let platformName: Platform | undefined;
platform().then((name) => {
isMacos = name === 'darwin';
platformName = name;
console.log('platformName:', platformName);
});
// check if resizing
@ -96,24 +97,29 @@
{#if isNavCollapsed}
<div class="collapsed-nav-wrapper">
<div class="card collapsed-nav">
<div class="collapsed-nav__info">
<h3 class="collapsed-nav__label text-base-13 text-bold">
{project?.title}
</h3>
<DomainButton
href={`/${project.id}/board`}
domain="workspace"
{branchController}
{baseBranchService}
{isNavCollapsed}
></DomainButton>
<BaseBranchCard {project} {baseBranchService} {githubService} {isNavCollapsed} />
{#if platformName}
{#if platformName === 'darwin'}
<div class="drag-region" data-tauri-drag-region />
{/if}
<div class="card collapsed-nav">
<div class="collapsed-nav__info">
<h3 class="collapsed-nav__label text-base-13 text-bold">
{project?.title}
</h3>
<DomainButton
href={`/${project.id}/board`}
domain="workspace"
{branchController}
{baseBranchService}
{isNavCollapsed}
></DomainButton>
<BaseBranchCard {project} {baseBranchService} {githubService} {isNavCollapsed} />
</div>
<div class="collapsed-nav__footer">
<Footer {user} projectId={project.id} {isNavCollapsed} />
</div>
</div>
<div class="collapsed-nav__footer">
<Footer {user} projectId={project.id} {isNavCollapsed} />
</div>
</div>
{/if}
</div>
{:else}
<div
@ -123,24 +129,26 @@
role="menu"
tabindex="0"
>
{#if isMacos}
<div class="drag-region" data-tauri-drag-region />
{/if}
<div class="navigation-top">
<ProjectSelector {project} {projectService} />
<div class="domains">
<BaseBranchCard {project} {baseBranchService} {githubService} {isNavCollapsed} />
<DomainButton
href={`/${project.id}/board`}
domain="workspace"
{branchController}
{baseBranchService}
{isNavCollapsed}
></DomainButton>
{#if platformName}
{#if platformName === 'darwin'}
<div class="drag-region" data-tauri-drag-region />
{/if}
<div class="navigation-top">
<ProjectSelector {project} {projectService} />
<div class="domains">
<BaseBranchCard {project} {baseBranchService} {githubService} {isNavCollapsed} />
<DomainButton
href={`/${project.id}/board`}
domain="workspace"
{branchController}
{baseBranchService}
{isNavCollapsed}
></DomainButton>
</div>
</div>
</div>
<Branches projectId={project.id} {branchService} {githubService} />
<Footer {user} projectId={project.id} {isNavCollapsed} />
<Branches projectId={project.id} {branchService} {githubService} />
<Footer {user} projectId={project.id} {isNavCollapsed} />
{/if}
</div>
{/if}
</aside>
@ -164,6 +172,7 @@
}
}
.navigation {
width: 17.5rem;
display: flex;
flex-direction: column;
position: relative;

View File

@ -0,0 +1,69 @@
<script lang="ts">
export let name: string | undefined;
const gradients = [
'#E78D8D',
'#62CDCD',
'#EC90D2',
'#7DC8D8',
'#F1BC55',
'#6B6B4C',
'#9785DE',
'#99CE63',
'#636ECE',
'#5FD2B0'
];
const stringToGradient = (string: string | undefined) => {
if (!string) {
return `linear-gradient(45deg, ${gradients[0][0]} 15%, ${gradients[0][1]} 90%)`;
}
// trim the string, remove all spaces
const trimmedString = string.trim().replace(/\s/g, '');
// this is how we take the first letter. It works with emojies.
const startHash = trimmedString.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
// Covert the hash number into the number we can
const gradient = startHash % gradients.length;
// and return the linear-gradient
return gradients[gradient];
};
const getFirstLetter = (name: string | undefined) => {
if (!name) return '';
return name[0].toUpperCase();
};
$: firstLetter = getFirstLetter(name);
</script>
<div class="project-avatar" style:background-color={stringToGradient(name)}>
<svg class="avatar-letter" viewBox="0 0 24 24">
<text x="50%" y="52%" text-anchor="middle" alignment-baseline="middle">
{firstLetter.toUpperCase()}
</text>
</svg>
</div>
<style>
.project-avatar {
flex-shrink: 0;
width: var(--space-24);
height: var(--space-24);
border-radius: var(--radius-m);
}
.avatar-letter {
width: 100%;
height: 100%;
}
.avatar-letter text {
font-family: 'Inter', sans-serif;
font-weight: 800;
font-size: 16px;
fill: var(--clr-core-ntrl-100);
}
</style>

View File

@ -1,4 +1,5 @@
<script lang="ts">
import ProjectAvatar from './ProjectAvatar.svelte';
import ProjectsPopup from './ProjectsPopup.svelte';
import { clickOutside } from '$lib/clickOutside';
import Icon from '$lib/components/Icon.svelte';
@ -11,43 +12,44 @@
let visible: boolean = false;
</script>
<div class="wrapper">
<div
class="relative"
use:clickOutside={{
handler: () => {
popup.hide();
visible = false;
},
enabled: visible
<div
class="wrapper"
use:clickOutside={{
handler: () => {
popup.hide();
visible = false;
},
enabled: visible
}}
>
<button
class="button"
on:click={(e) => {
visible = popup.toggle();
e.preventDefault();
}}
>
<button
class="button"
on:click={(e) => {
visible = popup.toggle();
e.preventDefault();
}}
>
<span class="button__label text-base-14 text-bold">{project?.title}</span>
<div class="button__icon">
<Icon name="select-chevron" />
</div>
</button>
<ProjectsPopup bind:this={popup} {projectService} />
</div>
<ProjectAvatar name={project?.title} />
<span class="button__label text-base-14 text-bold">{project?.title}</span>
<div class="button__icon">
<Icon name="select-chevron" />
</div>
</button>
<ProjectsPopup bind:this={popup} {projectService} />
</div>
<style lang="postcss">
.wrapper {
position: relative;
margin-top: var(--space-10);
margin-bottom: var(--space-16);
}
.button {
display: flex;
gap: var(--space-10);
width: 100%;
padding: var(--space-12);
padding: var(--space-10);
border-radius: var(--radius-m);
background-color: var(--clr-theme-container-pale);
@ -75,6 +77,9 @@
flex-grow: 1;
color: var(--clr-theme-scale-ntrl-0);
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.button__icon {