Update Avatar (#301)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2021-11-10 23:10:11 +03:00 committed by GitHub
parent f4cb89b251
commit 07629bc91e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 82 additions and 156 deletions

View File

@ -21,41 +21,78 @@
export let avatar: string | undefined = undefined export let avatar: string | undefined = undefined
export let size: 'x-small' | 'small' | 'medium' | 'large' | 'x-large' export let size: 'x-small' | 'small' | 'medium' | 'large' | 'x-large'
const url = avatar ? getFileUrl(avatar) : undefined $: url = avatar ? getFileUrl(avatar) : undefined
</script> </script>
<div class="{size} container"> <div class="{size} flex-center container" class:no-img={!url}>
{#if url} {#if url}
<img class={size} src={url} alt={''}/> {#if size === 'large' || size === 'x-large'}
<img class="{size} blur" src={url} alt={''}/>
{/if}
<img class="{size} mask" src={url} alt={''}/>
{:else} {:else}
<Avatar {size}/> <Avatar {size}/>
{/if} {/if}
</div> </div>
<style lang="scss"> <style lang="scss">
@import '../../../../packages/theme/styles/mixins.scss';
.container {
flex-shrink: 0;
position: relative;
overflow: hidden;
border-radius: 50%;
pointer-events: none;
img { object-fit: cover; }
&.no-img {
border: 2px solid var(--theme-avatar-border);
&::after {
content: '';
@include bg-layer(var(--theme-avatar-hover), .5);
}
&::before {
content: '';
@include bg-layer(var(--theme-avatar-bg), .1);
}
}
}
.x-small { .x-small {
width: 1.5rem; width: 1.5rem; // 24
height: 1.5rem; height: 1.5rem;
.mask, &.no-img { border-style: none; }
} }
.small { .small {
width: 2rem; width: 2rem; // 32
height: 2rem; height: 2rem;
.mask, &.no-img { border-style: none; }
} }
.medium { .medium {
width: 2.25rem; width: 2.25rem; // 36
height: 2.25rem; height: 2.25rem;
.mask, &.no-img { border-style: none; }
} }
.large { .large {
width: 5rem; width: 4.5rem; // 72
height: 5rem; height: 4.5rem;
} }
.x-large { .x-large {
width: 10rem; width: 7.5rem; // 120
height: 10rem; height: 7.5rem;
} }
.container {
overflow: hidden; .blur {
border: 50%; position: absolute;
pointer-events: none; filter: blur(32px);
} }
.mask {
position: absolute;
border: 2px solid var(--theme-avatar-border);
border-radius: 50%;
}
// .shadow { filter: drop-shadow(0px 14px 44px rgba(74, 67, 64, .8)); }
</style> </style>

View File

@ -20,7 +20,7 @@
const fill: string = 'var(--theme-caption-color)' const fill: string = 'var(--theme-caption-color)'
</script> </script>
<svg class="svg-avatar svg-{size}" {fill} viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg"> <svg class="svg-avatar {size}" {fill} viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
<circle class="op" cx="20" cy="13.6" r="6.4"/> <circle class="op" cx="20" cy="13.6" r="6.4"/>
<path d="M33.1,33.3c-0.8-2.2-2.5-4.2-4.9-5.5c-2.3-1.3-5.2-2.1-8.2-2.1s-5.8,0.7-8.2,2.1c-2.4,1.4-4.1,3.3-4.9,5.5 c-0.1,0.4,0.1,0.8,0.5,1c0.4,0.1,0.8-0.1,1-0.5c0.7-1.9,2.2-3.5,4.2-4.7c2.1-1.2,4.7-1.9,7.4-1.9c2.7,0,5.3,0.7,7.4,1.9 c2.1,1.2,3.6,2.9,4.2,4.7c0.1,0.3,0.4,0.5,0.7,0.5c0.1,0,0.2,0,0.3,0C33,34.1,33.2,33.7,33.1,33.3z"/> <path d="M33.1,33.3c-0.8-2.2-2.5-4.2-4.9-5.5c-2.3-1.3-5.2-2.1-8.2-2.1s-5.8,0.7-8.2,2.1c-2.4,1.4-4.1,3.3-4.9,5.5 c-0.1,0.4,0.1,0.8,0.5,1c0.4,0.1,0.8-0.1,1-0.5c0.7-1.9,2.2-3.5,4.2-4.7c2.1-1.2,4.7-1.9,7.4-1.9c2.7,0,5.3,0.7,7.4,1.9 c2.1,1.2,3.6,2.9,4.2,4.7c0.1,0.3,0.4,0.5,0.7,0.5c0.1,0,0.2,0,0.3,0C33,34.1,33.2,33.7,33.1,33.3z"/>
<path d="M20,20.8c3.9,0,7.1-3.2,7.1-7.1S23.9,6.5,20,6.5c-3.9,0-7.1,3.2-7.1,7.1S16.1,20.8,20,20.8z M20,8 c3.1,0,5.6,2.5,5.6,5.6s-2.5,5.6-5.6,5.6c-3.1,0-5.6-2.5-5.6-5.6S16.9,8,20,8z"/> <path d="M20,20.8c3.9,0,7.1-3.2,7.1-7.1S23.9,6.5,20,6.5c-3.9,0-7.1,3.2-7.1,7.1S16.1,20.8,20,20.8z M20,8 c3.1,0,5.6,2.5,5.6,5.6s-2.5,5.6-5.6,5.6c-3.1,0-5.6-2.5-5.6-5.6S16.9,8,20,8z"/>
@ -28,9 +28,27 @@
<style lang="scss"> <style lang="scss">
.svg-avatar { .svg-avatar {
width: 1.25rem;
height: 1.25rem;
fill: var(--theme-caption-color); fill: var(--theme-caption-color);
.op { opacity: .05; } .op { opacity: .05; }
} }
.x-small {
width: 1rem;
height: 1rem;
}
.small {
width: 1.25rem;
height: 1.25rem;
}
.medium {
width: 1.5rem;
height: 1.5rem;
}
.large {
width: 1.75rem;
height: 1.75rem;
}
.x-large {
width: 3rem;
height: 3rem;
}
</style> </style>

View File

@ -76,7 +76,7 @@
--theme-card-divider: rgba(255, 255, 255, .1); --theme-card-divider: rgba(255, 255, 255, .1);
--theme-card-shadow: 0px 34px 74px rgba(0, 0, 0, 0.55); --theme-card-shadow: 0px 34px 74px rgba(0, 0, 0, 0.55);
--theme-avatar-bg: #E0DAD5; --theme-avatar-bg: #E0DAD5;
--theme-avatar-hover: radial-gradient(86.62% 86.62% at 50% 13.38%, rgba(196, 196, 204, 0.4) 0%, rgba(137, 140, 150, 0.4) 100%); --theme-avatar-hover: rgba(195, 195, 204, .2);
--theme-avatar-border: rgba(255, 255, 255, .1); --theme-avatar-border: rgba(255, 255, 255, .1);
--theme-avatar-shadow: drop-shadow(0px 14px 44px rgba(74, 67, 64, .8)); --theme-avatar-shadow: drop-shadow(0px 14px 44px rgba(74, 67, 64, .8));
--theme-msgbox-bg: rgba(170, 170, 191, .25); --theme-msgbox-bg: rgba(170, 170, 191, .25);

View File

@ -163,6 +163,8 @@ table {
.ml-2 { margin-left: .5rem; } .ml-2 { margin-left: .5rem; }
.mr-1 { margin-right: .25rem; } .mr-1 { margin-right: .25rem; }
.mr-4 { margin-right: 1rem; }
.mr-8 { margin-right: 2rem; }
.mt-5 { margin-top: 1.25rem; } .mt-5 { margin-top: 1.25rem; }
.mb-1 { margin-bottom: .25rem; } .mb-1 { margin-bottom: .25rem; }

View File

@ -31,7 +31,6 @@ async function onClick() {
const editor = await getResource(editorMixin.editor) const editor = await getResource(editorMixin.editor)
showPopup(editor, { _id: value._id }, 'full') showPopup(editor, { _id: value._id }, 'full')
} }
</script> </script>
<div class="flex-row-center user-container" on:click={onClick}> <div class="flex-row-center user-container" on:click={onClick}>

View File

@ -20,7 +20,7 @@
import { setPlatformStatus, unknownError, Severity } from '@anticrm/platform' import { setPlatformStatus, unknownError, Severity } from '@anticrm/platform'
import type { Status } from '@anticrm/platform' import type { Status } from '@anticrm/platform'
import { getClient, Card, Channels, PDFViewer } from '@anticrm/presentation' import { getClient, Card, Channels, PDFViewer, Avatar } from '@anticrm/presentation'
import { uploadFile } from '../utils' import { uploadFile } from '../utils'
import recruit from '../plugin' import recruit from '../plugin'
@ -30,15 +30,10 @@
import { EditBox, Link, showPopup, Component, CircleButton, IconFile as FileIcon, IconAdd, Spinner, Label, Status as StatusComponent } from '@anticrm/ui' import { EditBox, Link, showPopup, Component, CircleButton, IconFile as FileIcon, IconAdd, Spinner, Label, Status as StatusComponent } from '@anticrm/ui'
import FileUpload from './icons/FileUpload.svelte' import FileUpload from './icons/FileUpload.svelte'
import Avatar from './icons/Avatar.svelte'
import Edit from './icons/Edit.svelte' import Edit from './icons/Edit.svelte'
import SocialEditor from './SocialEditor.svelte' import SocialEditor from './SocialEditor.svelte'
import YesNo from './YesNo.svelte' import YesNo from './YesNo.svelte'
import Girl from '../../img/girl.png'
import Elon from '../../img/elon.png'
import Bond from '../../img/bond.png'
import { combineName } from '@anticrm/contact'; import { combineName } from '@anticrm/contact';
export let space: Ref<Space> export let space: Ref<Space>
@ -126,8 +121,6 @@
const file = inputFile.files?.[0] const file = inputFile.files?.[0]
if (file !== undefined) { createAttachment(file) } if (file !== undefined) { createAttachment(file) }
} }
let kl: number = 0
</script> </script>
<!-- <DialogHeader {space} {object} {newValue} {resume} create={true} on:save={createCandidate}/> --> <!-- <DialogHeader {space} {object} {newValue} {resume} create={true} on:save={createCandidate}/> -->
@ -143,32 +136,9 @@
<!-- <StatusComponent slot="error" status={{ severity: Severity.ERROR, code: 'Cant save the object because it already exists' }} /> --> <!-- <StatusComponent slot="error" status={{ severity: Severity.ERROR, code: 'Cant save the object because it already exists' }} /> -->
<div class="flex-row-center"> <div class="flex-row-center">
<div class="avatar-container"> <div class="mr-4">
<div class="flex-center avatar-shadow"> <Avatar avatar={object.avatar} size={'large'} />
{#if kl === 0}
<div class="bg-avatar"><Avatar /></div>
{:else if kl === 1}
<div class="bg-avatar"><img src={Girl} alt="Avatar" /></div>
{:else if kl === 2}
<div class="bg-avatar"><img src={Elon} alt="Avatar" /></div>
{:else}
<div class="bg-avatar"><img src={Bond} alt="Avatar" /></div>
{/if}
</div>
<div class="flex-center avatar" on:click={() => { (kl < 3) ? kl++ : kl = 0 }}>
<div class="border"/>
{#if kl === 0}
<Avatar />
{:else if kl === 1}
<img width="100%" src={Girl} alt="Avatar" />
{:else if kl === 2}
<img width="100%" src={Elon} alt="Avatar" />
{:else}
<img width="100%" src={Bond} alt="Avatar" />
{/if}
</div>
</div> </div>
<div class="flex-col"> <div class="flex-col">
<div class="fs-title"><EditBox placeholder="John" maxWidth="10rem" bind:value={firstName}/></div> <div class="fs-title"><EditBox placeholder="John" maxWidth="10rem" bind:value={firstName}/></div>
<div class="fs-title mb-1"><EditBox placeholder="Appleseed" maxWidth="10rem" bind:value={lastName}/></div> <div class="fs-title mb-1"><EditBox placeholder="Appleseed" maxWidth="10rem" bind:value={lastName}/></div>
@ -216,53 +186,6 @@
</Card> </Card>
<style lang="scss"> <style lang="scss">
@import '../../../../packages/theme/styles/mixins.scss';
.avatar-container {
flex-shrink: 0;
position: relative;
margin-right: 1rem;
width: 4.5rem;
height: 4.5rem;
user-select: none;
}
.avatar-shadow {
position: absolute;
width: 4.5rem;
height: 4.5rem;
.bg-avatar {
filter: blur(10px);
opacity: .25;
}
}
.avatar {
overflow: hidden;
position: absolute;
width: 4.5rem;
height: 4.5rem;
border-radius: 50%;
filter: var(--theme-avatar-shadow);
cursor: pointer;
&::after {
content: '';
@include bg-layer(var(--theme-avatar-hover), .5);
z-index: -1;
}
&::before {
content: '';
@include bg-layer(var(--theme-avatar-bg), .1);
backdrop-filter: blur(25px);
z-index: -2;
}
.border {
@include bg-fullsize;
border: 2px solid var(--theme-avatar-border);
border-radius: 50%;
}
}
.channels { .channels {
margin-top: 1.25rem; margin-top: 1.25rem;
span { margin-left: .5rem; } span { margin-left: .5rem; }

View File

@ -19,11 +19,11 @@
import { CircleButton, EditBox, Link, showPopup, IconFile as FileIcon, IconAdd, Label } from '@anticrm/ui' import { CircleButton, EditBox, Link, showPopup, IconFile as FileIcon, IconAdd, Label } from '@anticrm/ui'
import type { Attachment } from '@anticrm/chunter' import type { Attachment } from '@anticrm/chunter'
import FileUpload from './icons/FileUpload.svelte' import FileUpload from './icons/FileUpload.svelte'
import { getClient, createQuery, Channels, AttributeEditor, PDFViewer } from '@anticrm/presentation' import { getClient, createQuery, Channels, AttributeEditor, PDFViewer, Avatar } from '@anticrm/presentation'
import { Panel } from '@anticrm/panel' import { Panel } from '@anticrm/panel'
import type { Candidate } from '@anticrm/recruit' import type { Candidate } from '@anticrm/recruit'
import Contact from './icons/Contact.svelte' import Contact from './icons/Contact.svelte'
import Avatar from './icons/Avatar.svelte' import IconAvatar from './icons/Avatar.svelte'
import Attachments from './Attachments.svelte' import Attachments from './Attachments.svelte'
import Edit from './icons/Edit.svelte' import Edit from './icons/Edit.svelte'
import SocialEditor from './SocialEditor.svelte' import SocialEditor from './SocialEditor.svelte'
@ -60,7 +60,6 @@
function lastNameChange() { function lastNameChange() {
client.updateDoc(recruit.class.Candidate, object.space, object._id, { name: combineName(getFirstName(object.name), lastName) }) client.updateDoc(recruit.class.Candidate, object.space, object._id, { name: combineName(getFirstName(object.name), lastName) })
} }
</script> </script>
{#if object !== undefined} {#if object !== undefined}
@ -68,9 +67,8 @@
<AttributesBar {object} keys={['city', 'onsite', 'remote']} slot="subtitle" /> <AttributesBar {object} keys={['city', 'onsite', 'remote']} slot="subtitle" />
<div class="flex-row-center"> <div class="flex-row-center">
<div class="avatar"> <div class="mr-8">
<div class="border"/> <Avatar avatar={object.avatar} size={'x-large'} />
<Avatar />
</div> </div>
<div class="flex-col"> <div class="flex-col">
<div class="name"><EditBox placeholder="John" maxWidth="20rem" bind:value={firstName} on:change={ firstNameChange }/></div> <div class="name"><EditBox placeholder="John" maxWidth="20rem" bind:value={firstName} on:change={ firstNameChange }/></div>
@ -114,40 +112,6 @@
{/if} {/if}
<style lang="scss"> <style lang="scss">
@import '../../../../packages/theme/styles/mixins.scss';
.avatar {
flex-shrink: 0;
overflow: hidden;
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-right: 1.5rem;
width: 6rem;
height: 6rem;
border-radius: 50%;
filter: drop-shadow(0px 14px 44px rgba(28, 23, 22, .8));
cursor: pointer;
&::after {
content: '';
@include bg-layer(var(--theme-avatar-hover), .5);
z-index: -1;
}
&::before {
content: '';
@include bg-layer(var(--theme-avatar-bg), .1);
backdrop-filter: blur(25px);
z-index: -2;
}
.border {
@include bg-fullsize;
border: 2px solid var(--theme-avatar-border);
border-radius: 50%;
}
}
.name { .name {
font-weight: 500; font-weight: 500;
font-size: 1.25rem; font-size: 1.25rem;
@ -171,21 +135,4 @@
color: var(--theme-caption-color); color: var(--theme-caption-color);
} }
} }
// .container {
// display: flex;
// flex-direction: column;
// height: 100%;
// background-color: var(--theme-bg-color);
// border-radius: 1.25rem;
// box-shadow: 0px 3.125rem 7.5rem rgba(0, 0, 0, .4);
// .tabs-container {
// flex-grow: 1;
// display: flex;
// flex-direction: column;
// height: fit-content;
// padding: 0 2.5rem 2.5rem;
// }
// }
</style> </style>