mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
WIP converting avatar widget to webcomponent
This commit is contained in:
parent
f8f7d1621e
commit
6eed7b5a0e
@ -14,15 +14,19 @@ import {SlAvatar} from "@shoelace-style/shoelace";
|
|||||||
import {et2_IDetachedDOM} from "../et2_core_interfaces";
|
import {et2_IDetachedDOM} from "../et2_core_interfaces";
|
||||||
import {egw} from "../../jsapi/egw_global";
|
import {egw} from "../../jsapi/egw_global";
|
||||||
import shoelace from "../Styles/shoelace";
|
import shoelace from "../Styles/shoelace";
|
||||||
|
import {Et2Dialog} from "../Et2Dialog/Et2Dialog";
|
||||||
|
import "../../../../vendor/bower-asset/cropper/dist/cropper.min.js";
|
||||||
|
import {cropperStyles} from "./cropperStyles";
|
||||||
|
|
||||||
export class Et2Avatar extends Et2Widget(SlotMixin(SlAvatar)) implements et2_IDetachedDOM
|
export class Et2Avatar extends Et2Widget(SlotMixin(SlAvatar)) implements et2_IDetachedDOM
|
||||||
{
|
{
|
||||||
|
private _contact_id;
|
||||||
static get styles()
|
static get styles()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
...super.styles,
|
...super.styles,
|
||||||
shoelace,
|
shoelace,
|
||||||
|
cropperStyles,
|
||||||
css`
|
css`
|
||||||
|
|
||||||
`
|
`
|
||||||
@ -67,18 +71,66 @@ export class Et2Avatar extends Et2Widget(SlotMixin(SlAvatar)) implements et2_IDe
|
|||||||
image: {
|
image: {
|
||||||
type: String,
|
type: String,
|
||||||
reflect: true
|
reflect: true
|
||||||
}
|
},
|
||||||
|
|
||||||
|
crop: {type: Boolean},
|
||||||
|
|
||||||
|
size: {type: String}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.contact_id = "";
|
|
||||||
this.src = "";
|
this.src = "";
|
||||||
this.label = "";
|
this.label = "";
|
||||||
|
this.contact_id = "";
|
||||||
|
this.editable = false;
|
||||||
|
this.crop = false;
|
||||||
|
this.size = "3em";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle changes that have to happen based on changes to properties
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
updated(changedProperties)
|
||||||
|
{
|
||||||
|
super.updated(changedProperties);
|
||||||
|
|
||||||
|
if (changedProperties.has("crop")) {
|
||||||
|
if (this.crop && !this.readonly && this._imageNode)
|
||||||
|
{
|
||||||
|
jQuery(this._imageNode).cropper({aspectRatio: 1/1});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changedProperties.has("size"))
|
||||||
|
{
|
||||||
|
this.getDOMNode().setAttribute('style', `--size:${this.size}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated()
|
||||||
|
{
|
||||||
|
let self = this;
|
||||||
|
if (this.contact_id && this.editable)
|
||||||
|
{
|
||||||
|
egw(window).json(
|
||||||
|
'addressbook.addressbook_ui.ajax_noPhotoExists',
|
||||||
|
[this.contact_id],
|
||||||
|
function(noPhotoExists)
|
||||||
|
{
|
||||||
|
if (noPhotoExists) self.image="";
|
||||||
|
self._buildEditableLayer(noPhotoExists);
|
||||||
|
}
|
||||||
|
).sendRequest(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get contact_id()
|
||||||
|
{
|
||||||
|
return this._contact_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,13 +162,15 @@ export class Et2Avatar extends Et2Widget(SlotMixin(SlAvatar)) implements et2_IDe
|
|||||||
id = 'contact_id';
|
id = 'contact_id';
|
||||||
_contact_id = _contact_id.replace('contact:', '');
|
_contact_id = _contact_id.replace('contact:', '');
|
||||||
}
|
}
|
||||||
|
let oldContactId = this._contact_id;
|
||||||
|
this._contact_id = _contact_id;
|
||||||
// if our src (incl. cache-buster) already includes the correct id, use that one
|
// if our src (incl. cache-buster) already includes the correct id, use that one
|
||||||
if (!this.options.src || !this.options.src.match("(&|\\?)contact_id="+_contact_id+"(&|\\$)"))
|
if (!this.src || !this.src.match("(&|\\?)contact_id="+_contact_id+"(&|\\$)"))
|
||||||
{
|
{
|
||||||
params[id] = _contact_id;
|
params[id] = _contact_id;
|
||||||
this.src = egw.link('/api/avatar.php',params);
|
this.src = egw.link('/api/avatar.php',params);
|
||||||
}
|
}
|
||||||
|
this.requestUpdate("contact_id", oldContactId);
|
||||||
}
|
}
|
||||||
|
|
||||||
set value(_value)
|
set value(_value)
|
||||||
@ -129,8 +183,138 @@ export class Et2Avatar extends Et2Widget(SlotMixin(SlAvatar)) implements et2_IDe
|
|||||||
this.image = _value;
|
this.image = _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get _baseNode()
|
||||||
|
{
|
||||||
|
return this.shadowRoot.querySelector("[part='base']");
|
||||||
|
}
|
||||||
|
|
||||||
|
get _imageNode()
|
||||||
|
{
|
||||||
|
return this.shadowRoot.querySelector("[part='image']");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of "et2_IDetachedDOM" for fast viewing in gridview
|
* Build Editable Mask Layer (EML) in order to show edit/delete actions
|
||||||
|
* on top of profile picture.
|
||||||
|
* @param {boolean} _noDelete disable delete button in initialization
|
||||||
|
*/
|
||||||
|
private _buildEditableLayer(_noDelete : boolean)
|
||||||
|
{
|
||||||
|
let self = this;
|
||||||
|
let editBtn = document.createElement('sl-icon-button');
|
||||||
|
editBtn.setAttribute('name', 'pencil');
|
||||||
|
let delBtn = document.createElement('sl-icon-button');
|
||||||
|
delBtn.setAttribute('name', 'trash');
|
||||||
|
this._baseNode.append(editBtn);
|
||||||
|
this._baseNode.append(delBtn);
|
||||||
|
|
||||||
|
delBtn.disabled = _noDelete;
|
||||||
|
|
||||||
|
editBtn.addEventListener('click', function(){
|
||||||
|
let buttons = [
|
||||||
|
{"button_id": 1, label: self.egw().lang('save'), id: 'save', image: 'check', "default": true},
|
||||||
|
{"button_id": 0, label: self.egw().lang('cancel'), id: 'cancel', image: 'cancelled'}
|
||||||
|
];
|
||||||
|
let dialog = function(_title, _value, _buttons, _egw_or_appname)
|
||||||
|
{
|
||||||
|
let dialog = new Et2Dialog(self.egw());
|
||||||
|
dialog.transformAttributes({
|
||||||
|
callback: function(_buttons, _value)
|
||||||
|
{
|
||||||
|
let widget = document.getElementById('_cropper_image');
|
||||||
|
switch(_buttons)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
let canvas = jQuery(widget._imageNode).cropper('getCroppedCanvas');
|
||||||
|
self.image = canvas.toDataURL("image/jpeg", 1.0)
|
||||||
|
self.egw().json('addressbook.addressbook_ui.ajax_update_photo',
|
||||||
|
[self.getInstanceManager().etemplate_exec_id, canvas.toDataURL("image/jpeg", 1.0)],
|
||||||
|
function(res)
|
||||||
|
{
|
||||||
|
if(res)
|
||||||
|
{
|
||||||
|
delBtn.style.visibility = 'visible';
|
||||||
|
}
|
||||||
|
}).sendRequest();
|
||||||
|
break;
|
||||||
|
case '_rotate_reset':
|
||||||
|
jQuery(widget._imageNode).cropper('reset');
|
||||||
|
return false;
|
||||||
|
case '_rotate_l':
|
||||||
|
jQuery(widget._imageNode).cropper('rotate', -90);
|
||||||
|
return false;
|
||||||
|
case '_rotate_r':
|
||||||
|
jQuery(widget._imageNode).cropper('rotate', 90);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: _title || egw.lang('Input required'),
|
||||||
|
buttons: _buttons || Et2Dialog.BUTTONS_OK_CANCEL,
|
||||||
|
value: {
|
||||||
|
content: _value
|
||||||
|
},
|
||||||
|
width: "90%",
|
||||||
|
height: "450",
|
||||||
|
resizable: false,
|
||||||
|
position: "top+10",
|
||||||
|
template: egw.webserverUrl + '/api/templates/default/avatar_edit.xet'
|
||||||
|
});
|
||||||
|
document.body.appendChild(dialog);
|
||||||
|
return dialog;
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog(egw.lang('Edit avatar'),self.options, buttons, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
delBtn.addEventListener('click', function()
|
||||||
|
{
|
||||||
|
Et2Dialog.show_dialog(function(_btn)
|
||||||
|
{
|
||||||
|
if(_btn == Et2Dialog.YES_BUTTON)
|
||||||
|
{
|
||||||
|
self.egw().json('addressbook.addressbook_ui.ajax_update_photo',
|
||||||
|
[self.getInstanceManager().etemplate_exec_id, null],
|
||||||
|
function(res)
|
||||||
|
{
|
||||||
|
if(res)
|
||||||
|
{
|
||||||
|
self.image = '';
|
||||||
|
delBtn.style.visibility = 'none';
|
||||||
|
egw.refresh('Avatar Deleted.', egw.app_name());
|
||||||
|
}
|
||||||
|
}).sendRequest();
|
||||||
|
}
|
||||||
|
}, egw.lang('Delete this photo?'), egw.lang('Delete'), null, Et2Dialog.BUTTONS_YES_NO);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function runs after uplaod in avatar dialog is finished and it tries to
|
||||||
|
* update image and cropper container.
|
||||||
|
* @param {type} e
|
||||||
|
*/
|
||||||
|
static uploadAvatar_onFinish(e)
|
||||||
|
{
|
||||||
|
let file = e.data.resumable.files[0].file;
|
||||||
|
let reader = new FileReader();
|
||||||
|
reader.onload = function (e)
|
||||||
|
{
|
||||||
|
let widget = document.getElementById('_cropper_image');
|
||||||
|
widget.image = e.target.result;
|
||||||
|
// Wait for everything to complete
|
||||||
|
widget.getUpdateComplete().then(() =>
|
||||||
|
{
|
||||||
|
jQuery(widget._imageNode).cropper('replace',e.target.result)
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
getDetachedAttributes(_attrs : string[])
|
getDetachedAttributes(_attrs : string[])
|
||||||
{
|
{
|
||||||
@ -151,3 +335,8 @@ export class Et2Avatar extends Et2Widget(SlotMixin(SlAvatar)) implements et2_IDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define("et2-avatar", Et2Avatar as any);
|
customElements.define("et2-avatar", Et2Avatar as any);
|
||||||
|
// make et2_avatar publicly available as we need to call it from templates
|
||||||
|
{
|
||||||
|
window['et2_avatar'] = Et2Avatar;
|
||||||
|
window['Et2Avatar'] = Et2Avatar;
|
||||||
|
}
|
@ -55,19 +55,32 @@ export class Et2LAvatar extends Et2Avatar
|
|||||||
super();
|
super();
|
||||||
this.lname = "";
|
this.lname = "";
|
||||||
this.fname = "";
|
this.fname = "";
|
||||||
this.initials = Et2LAvatar.lavatar(this.fname, this.lname, this.contact_id).initials;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set src(_url)
|
/**
|
||||||
|
* Handle changes that have to happen based on changes to properties
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
updated(changedProperties)
|
||||||
{
|
{
|
||||||
if (_url && decodeURIComponent(_url).match("lavatar=1") && (this.options.fname || this.options.lname) && this.options.contact_id)
|
super.updated(changedProperties);
|
||||||
{
|
|
||||||
this.initials = Et2LAvatar.lavatar(this.options.fname, this.options.lname, this.options.contact_id).initials;
|
if (changedProperties.has("lname") || changedProperties.has("fname") || changedProperties.has("contact_id")) {
|
||||||
return;
|
if (!this.src || !decodeURIComponent(this.src).match("lavatar=1") && (this.fname || this.lname) && this.contact_id)
|
||||||
|
{
|
||||||
|
this.initials = Et2LAvatar.lavatar(this.fname, this.lname, this.contact_id).initials;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
super.src= _url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getDetachedAttributes(_attrs : string[])
|
||||||
|
{
|
||||||
|
super.getDetachedAttributes(_attrs);
|
||||||
|
_attrs.push("lname", "fname");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate letter avatar with given data
|
* Generate letter avatar with given data
|
||||||
|
310
api/js/etemplate/Et2Avatar/cropperStyles.ts
Normal file
310
api/js/etemplate/Et2Avatar/cropperStyles.ts
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
/**
|
||||||
|
* Cropper styles constant
|
||||||
|
*/
|
||||||
|
import {css} from "@lion/core";
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Cropper.js v1.5.12
|
||||||
|
* https://fengyuanchen.github.io/cropperjs
|
||||||
|
*
|
||||||
|
* Copyright 2015-present Chen Fengyuan
|
||||||
|
* Released under the MIT license
|
||||||
|
*
|
||||||
|
* Date: 2021-06-12T08:00:11.623Z
|
||||||
|
*/
|
||||||
|
export const cropperStyles = css`
|
||||||
|
.cropper-container {
|
||||||
|
direction: ltr;
|
||||||
|
font-size: 0;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
-ms-touch-action: none;
|
||||||
|
touch-action: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-container img {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
image-orientation: 0deg;
|
||||||
|
max-height: none !important;
|
||||||
|
max-width: none !important;
|
||||||
|
min-height: 0 !important;
|
||||||
|
min-width: 0 !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-wrap-box,
|
||||||
|
.cropper-canvas,
|
||||||
|
.cropper-drag-box,
|
||||||
|
.cropper-crop-box,
|
||||||
|
.cropper-modal {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-wrap-box,
|
||||||
|
.cropper-canvas {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-drag-box {
|
||||||
|
background-color: #fff;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-modal {
|
||||||
|
background-color: #000;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-view-box {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
outline: 1px solid #39f;
|
||||||
|
outline-color: rgba(51, 153, 255, 0.75);
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-dashed {
|
||||||
|
border: 0 dashed #eee;
|
||||||
|
display: block;
|
||||||
|
opacity: 0.5;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-dashed.dashed-h {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
border-top-width: 1px;
|
||||||
|
height: calc(100% / 3);
|
||||||
|
left: 0;
|
||||||
|
top: calc(100% / 3);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-dashed.dashed-v {
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-right-width: 1px;
|
||||||
|
height: 100%;
|
||||||
|
left: calc(100% / 3);
|
||||||
|
top: 0;
|
||||||
|
width: calc(100% / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-center {
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
left: 50%;
|
||||||
|
opacity: 0.75;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-center::before,
|
||||||
|
.cropper-center::after {
|
||||||
|
background-color: #eee;
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-center::before {
|
||||||
|
height: 1px;
|
||||||
|
left: -3px;
|
||||||
|
top: 0;
|
||||||
|
width: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-center::after {
|
||||||
|
height: 7px;
|
||||||
|
left: 0;
|
||||||
|
top: -3px;
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-face,
|
||||||
|
.cropper-line,
|
||||||
|
.cropper-point {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0.1;
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-face {
|
||||||
|
background-color: #fff;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-line {
|
||||||
|
background-color: #39f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-line.line-e {
|
||||||
|
cursor: ew-resize;
|
||||||
|
right: -3px;
|
||||||
|
top: 0;
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-line.line-n {
|
||||||
|
cursor: ns-resize;
|
||||||
|
height: 5px;
|
||||||
|
left: 0;
|
||||||
|
top: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-line.line-w {
|
||||||
|
cursor: ew-resize;
|
||||||
|
left: -3px;
|
||||||
|
top: 0;
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-line.line-s {
|
||||||
|
bottom: -3px;
|
||||||
|
cursor: ns-resize;
|
||||||
|
height: 5px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point {
|
||||||
|
background-color: #39f;
|
||||||
|
height: 5px;
|
||||||
|
opacity: 0.75;
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-e {
|
||||||
|
cursor: ew-resize;
|
||||||
|
margin-top: -3px;
|
||||||
|
right: -3px;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-n {
|
||||||
|
cursor: ns-resize;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -3px;
|
||||||
|
top: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-w {
|
||||||
|
cursor: ew-resize;
|
||||||
|
left: -3px;
|
||||||
|
margin-top: -3px;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-s {
|
||||||
|
bottom: -3px;
|
||||||
|
cursor: s-resize;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-ne {
|
||||||
|
cursor: nesw-resize;
|
||||||
|
right: -3px;
|
||||||
|
top: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-nw {
|
||||||
|
cursor: nwse-resize;
|
||||||
|
left: -3px;
|
||||||
|
top: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-sw {
|
||||||
|
bottom: -3px;
|
||||||
|
cursor: nesw-resize;
|
||||||
|
left: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-se {
|
||||||
|
bottom: -3px;
|
||||||
|
cursor: nwse-resize;
|
||||||
|
height: 20px;
|
||||||
|
opacity: 1;
|
||||||
|
right: -3px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.cropper-point.point-se {
|
||||||
|
height: 15px;
|
||||||
|
width: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.cropper-point.point-se {
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
.cropper-point.point-se {
|
||||||
|
height: 5px;
|
||||||
|
opacity: 0.75;
|
||||||
|
width: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-point.point-se::before {
|
||||||
|
background-color: #39f;
|
||||||
|
bottom: -50%;
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
height: 200%;
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
right: -50%;
|
||||||
|
width: 200%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-invisible {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-bg {
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-hide {
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-move {
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-crop {
|
||||||
|
cursor: crosshair;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropper-disabled .cropper-drag-box,
|
||||||
|
.cropper-disabled .cropper-face,
|
||||||
|
.cropper-disabled .cropper-line,
|
||||||
|
.cropper-disabled .cropper-point {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
`;
|
@ -4,13 +4,13 @@
|
|||||||
<overlay>
|
<overlay>
|
||||||
<template id="etemplate.avatar_edit" template="" lang="" group="0" version="16.2">
|
<template id="etemplate.avatar_edit" template="" lang="" group="0" version="16.2">
|
||||||
<vbox>
|
<vbox>
|
||||||
<avatar crop="true" id="cropper_image" contact_id="$cont[contact_id]" src="$cont[src]" width ="200" height="auto"/>
|
<avatar crop="true" id="cropper_image" contact_id="$cont[contact_id]" src="$cont[src]" size="6em" shape="square"/>
|
||||||
<hbox>
|
<hbox>
|
||||||
<buttononly id="rotate_reset" label="Reset" image="recur" background_image="1" onclick="jQuery('#_cropper_image').cropper('reset');"/>
|
<buttononly id="rotate_reset" label="Reset" image="recur" background_image="1"/>
|
||||||
<buttononly id="rotate_l" label="Rotate Left" image="rotate_l" background_image="1" onclick="jQuery('#_cropper_image').cropper('rotate',-90);"/>
|
<buttononly id="rotate_l" label="Rotate Left" image="rotate_l" background_image="1"/>
|
||||||
<buttononly id="rotate_r" label= "Rotate Right" image="reload" background_image="1" onclick="jQuery('#_cropper_image').cropper('rotate',90);"/>
|
<buttononly id="rotate_r" label= "Rotate Right" image="reload" background_image="1"/>
|
||||||
<hbox>
|
<hbox>
|
||||||
<file id='upload_photo' label="upload new photo" onFinishOne="et2_avatar.uploadAvatar_onFinish"/>
|
<file id='upload_photo' label="upload new photo" onFinishOne="Et2Avatar.uploadAvatar_onFinish"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
Loading…
Reference in New Issue
Block a user