mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-19 15:41:31 +03:00
Added project avatar
This commit is contained in:
parent
ada64ac160
commit
40cc56db9b
@ -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;
|
||||
|
69
gitbutler-ui/src/lib/components/ProjectAvatar.svelte
Normal file
69
gitbutler-ui/src/lib/components/ProjectAvatar.svelte
Normal 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>
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user