Add AvatarEditor (#84)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2021-08-30 10:17:26 +03:00 committed by GitHub
parent 8b92648ade
commit fbe4f1fb5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 157 additions and 29 deletions

View File

@ -79,6 +79,10 @@ table {
// } // }
/* Common */ /* Common */
* {
--modal-padding: 1.5rem;
}
.flex { display: flex; } .flex { display: flex; }
.flex-nowrap { .flex-nowrap {
display: flex; display: flex;
@ -122,6 +126,35 @@ table {
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;
} }
.abs-lt-content {
position: absolute;
top: var(--modal-padding);
left: var(--modal-padding);
}
.abs-rt-content {
position: absolute;
top: var(--modal-padding);
right: var(--modal-padding);
}
.abs-lb-content {
position: absolute;
bottom: var(--modal-padding);
left: var(--modal-padding);
}
.abs-rb-content {
position: absolute;
bottom: var(--modal-padding);
right: var(--modal-padding);
}
.abs-full-content {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.h-full { height: 100%; } .h-full { height: 100%; }
.square-36 { width: 2.25rem; height: 2.25rem; } .square-36 { width: 2.25rem; height: 2.25rem; }

View File

@ -81,7 +81,7 @@
position: fixed; position: fixed;
background-color: transparent; background-color: transparent;
filter: drop-shadow(0 1.5rem 4rem rgba(0, 0, 0, .35)); filter: drop-shadow(0 1.5rem 4rem rgba(0, 0, 0, .35));
z-index: 1001; z-index: 501;
} }
.modal-overlay { .modal-overlay {
position: fixed; position: fixed;
@ -90,6 +90,6 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
background: transparent; background: transparent;
z-index: 1000; z-index: 500;
} }
</style> </style>

View File

@ -53,6 +53,7 @@ export { default as Popup } from './components/Popup.svelte'
export { default as CircleButton } from './components/CircleButton.svelte' export { default as CircleButton } from './components/CircleButton.svelte'
export { default as IconAdd } from './components/icons/Add.svelte' export { default as IconAdd } from './components/icons/Add.svelte'
export { default as IconClose } from './components/icons/Close.svelte'
export { default as IconSearch } from './components/icons/Search.svelte' export { default as IconSearch } from './components/icons/Search.svelte'
export { default as IconToDo } from './components/icons/ToDo.svelte' export { default as IconToDo } from './components/icons/ToDo.svelte'
export { default as IconComments } from './components/icons/Comments.svelte' export { default as IconComments } from './components/icons/Comments.svelte'

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -0,0 +1,112 @@
<!--
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import type { IntlString } from '@anticrm/platform'
import { createEventDispatcher } from 'svelte'
import { Label, Button, Grid, IconClose } from '@anticrm/ui'
import Avatar from '../../img/avatar.png'
export let label: IntlString
export let okAction: () => void
const dispatch = createEventDispatcher()
</script>
<div class="dialog-container">
<div class="abs-lt-content label">
<Label {label} />
</div>
<div class="abs-rt-content tool" on:click={() => { dispatch('close') }}>
<IconClose size={'small'} />
</div>
<div class="avatar">
<img src={Avatar} />
</div>
<div class="abs-lb-content actions">
<Grid columnGap={.5}>
<Button label={'Edit'} />
<Button label={'Delete'} />
</Grid>
</div>
<div class="abs-rb-content">
<Button label={'Save'} />
</div>
</div>
<style lang="scss">
.dialog-container {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 40rem;
height: 23.75rem;
background-color: var(--theme-bg-color);
border-radius: 1.25rem;
filter: drop-shadow(0 0 4rem rgba(0, 0, 0, .35));
.label {
font-weight: 500;
font-size: 1rem;
color: var(--theme-caption-color);
user-select: none;
}
.avatar {
position: relative;
width: 13.75rem;
height: 13.75rem;
background-color: #fff;
border-radius: 50%;
overflow: hidden;
&::after, &::before {
content: '';
position: absolute;
z-index: 1;
}
&::after {
top: .65rem;
left: .65rem;
bottom: .65rem;
right: .65rem;
border: 1px solid rgba(255, 255, 255, .6);
border-radius: 50%;
}
&::before {
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 13.75rem;
height: 13.75rem;
background-color: rgba(255, 255, 255, .2);
clip-path: path('M110,0C49.2,0,0,49.2,0,110c0,60.8,49.2,110,110,110s110-49.2,110-110C220,49.2,170.8,0,110,0z M110,212 C53.7,212,8,166.3,8,110C8,53.7,53.7,8,110,8s102,45.7,102,102C212,166.3,166.3,212,110,212z');
filter: blur(3px);
}
}
.tool {
opacity: .4;
cursor: pointer;
&:hover { opacity: 1; }
}
}
</style>

View File

@ -21,7 +21,8 @@
import login from '@anticrm/login' import login from '@anticrm/login'
import { createQuery, getClient } from '@anticrm/presentation' import { createQuery, getClient } from '@anticrm/presentation'
import { EditBox, Button, CircleButton, Grid, Label } from '@anticrm/ui' import { EditBox, Button, CircleButton, Grid, Label, showModal } from '@anticrm/ui'
import AvatarEditor from './AvatarEditor.svelte'
import FileUpload from './icons/FileUpload.svelte' import FileUpload from './icons/FileUpload.svelte'
import Edit from './icons/Edit.svelte' import Edit from './icons/Edit.svelte'
import Twitter from './icons/Twitter.svelte' import Twitter from './icons/Twitter.svelte'
@ -78,24 +79,23 @@
on:dragleave={ () => { dragover = false } } on:dragleave={ () => { dragover = false } }
on:drop|preventDefault|stopPropagation={drop}> on:drop|preventDefault|stopPropagation={drop}>
<div class="flex-row-center main-content"> <div class="flex-row-center main-content">
<div class="avatar"><User /></div> <div class="avatar" on:click|stopPropagation={() => showModal(AvatarEditor, { label: 'Profile photo' })}><User /></div>
<div class="flex-col"> <div class="flex-col">
<div class="name"> <div class="name">
<EditBox placeholder="John" /> <EditBox placeholder="John" />
<EditBox placeholder="Appleseed" /> <EditBox placeholder="Appleseed" />
</div> </div>
<!-- <div class="name"><EditBox placeholder="John"/>&nbsp;<EditBox placeholder="Appleseed"/></div> -->
<div class="title"><EditBox placeholder="Los Angeles"/></div> <div class="title"><EditBox placeholder="Los Angeles"/></div>
</div> </div>
</div> </div>
<div class="lb-content"> <div class="abs-lb-content">
<Button label={'Upload resume'} {loading} icon={FileUpload} size={'small'} transparent primary on:click={() => { inputFile.click() }}/> <Button label={'Upload resume'} {loading} icon={FileUpload} size={'small'} transparent primary on:click={() => { inputFile.click() }}/>
<input bind:this={inputFile} type="file" name="file" id="file" style="display: none" on:change={fileSelected}/> <input bind:this={inputFile} type="file" name="file" id="file" style="display: none" on:change={fileSelected}/>
</div> </div>
<div class="rb-content"> <div class="abs-rb-content">
<Button label={'Save'} size={'small'} transparent /> <Button label={'Save'} size={'small'} transparent />
</div> </div>
<div class="rt-content"> <div class="abs-rt-content">
<Grid column={2} columnGap={.5}> <Grid column={2} columnGap={.5}>
<CircleButton icon={Twitter} label={'Twitter'} /> <CircleButton icon={Twitter} label={'Twitter'} />
<CircleButton icon={Edit} label={'Edit'} /> <CircleButton icon={Edit} label={'Edit'} />
@ -106,9 +106,6 @@
<style lang="scss"> <style lang="scss">
.header { .header {
position: relative; position: relative;
// display: flex;
// justify-content: center;
// align-items: center;
padding: 1.5rem 1.5rem 0; padding: 1.5rem 1.5rem 0;
width: 37.5rem; width: 37.5rem;
min-height: 15rem; min-height: 15rem;
@ -135,6 +132,7 @@
background-color: rgba(255, 255, 255, .2); background-color: rgba(255, 255, 255, .2);
backdrop-filter: blur(3px); backdrop-filter: blur(3px);
box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, .3); box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, .3);
cursor: pointer;
} }
.name { .name {
display: flex; display: flex;
@ -156,21 +154,5 @@
color: rgba(255, 255, 255, .6); color: rgba(255, 255, 255, .6);
} }
} }
.lb-content {
position: absolute;
left: 1.5rem;
bottom: 1.5rem;
}
.rb-content {
position: absolute;
right: 1.5rem;
bottom: 1.5rem;
}
.rt-content {
position: absolute;
top: 1.5rem;
right: 1.5rem;
}
} }
</style> </style>

View File

@ -62,7 +62,7 @@
} }
@keyframes showOverlay { @keyframes showOverlay {
from { backdrop-filter: blur(0px); } from { backdrop-filter: blur(0px); }
to { backdrop-filter: blur(3px); } to { backdrop-filter: blur(1px); }
} }
.modal { .modal {
position: fixed; position: fixed;
@ -72,7 +72,7 @@
} }
.modal-overlay { .modal-overlay {
z-index: 1000; z-index: 1000;
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, .5);
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;