From 97019379d807eabb7e76b76dccf9718e5997ca0d Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Tue, 12 Jul 2022 17:14:44 +0200 Subject: [PATCH] WIP converting avatar widgets to webcomponent --- api/js/etemplate/Et2Avatar/Et2Avatar.ts | 153 +++++++++++++++++++++++ api/js/etemplate/Et2Avatar/Et2LAvatar.ts | 96 ++++++++++++++ api/js/etemplate/etemplate2.ts | 2 + 3 files changed, 251 insertions(+) create mode 100644 api/js/etemplate/Et2Avatar/Et2Avatar.ts create mode 100644 api/js/etemplate/Et2Avatar/Et2LAvatar.ts diff --git a/api/js/etemplate/Et2Avatar/Et2Avatar.ts b/api/js/etemplate/Et2Avatar/Et2Avatar.ts new file mode 100644 index 0000000000..d4682efc0d --- /dev/null +++ b/api/js/etemplate/Et2Avatar/Et2Avatar.ts @@ -0,0 +1,153 @@ +/** + * EGroupware eTemplate2 - Avatar widget + * + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package etemplate + * @subpackage api + * @link https://www.egroupware.org + * @author Hadi Nategh + */ + +import {Et2Widget} from "../Et2Widget/Et2Widget"; +import {css, SlotMixin} from "@lion/core"; +import {SlAvatar} from "@shoelace-style/shoelace"; +import {et2_IDetachedDOM} from "../et2_core_interfaces"; +import {egw} from "../../jsapi/egw_global"; +import shoelace from "../Styles/shoelace"; + +export class Et2Avatar extends Et2Widget(SlotMixin(SlAvatar)) implements et2_IDetachedDOM +{ + + static get styles() + { + return [ + ...super.styles, + shoelace, + css` + + ` + ]; + } + + static get properties() + { + return { + ...super.properties, + /** + * The label of the image + * Actually not used as label, but we put it as title + * Added here as there's no Lion parent + */ + label: { + type: String + }, + + /** + * Contact id should be either user account_id {account:number} or contact_id {contact:number or number} + */ + contact_id:{type: String}, + + /** + * Image + * Displayed image + */ + src: {type: String}, + + + shape: { + type: String, + reflect: true + }, + + /** + * Make avatar widget editable to be able to crop profile picture or upload a new photo + */ + editable: {type: Boolean}, + + image: { + type: String, + reflect: true + } + } + } + + + + constructor() + { + super(); + this.contact_id = ""; + this.src = ""; + this.label = ""; + } + + /** + * Function to set contact id + * contact id could be in one of these formats: + * 'number', will be consider as contact_id + * 'contact:number', similar to above + * 'account:number', will be consider as account id + * @example: contact_id = "account:4" + * + * @param {string} _contact_id contact id could be as above mentioned formats + */ + set contact_id(_contact_id : string) + { + let params = {}; + let id = 'contact_id'; + + if (!_contact_id) + { + _contact_id = this.egw().user('account_id'); + } + else if(_contact_id.match(/account:/)) + { + id = 'account_id'; + _contact_id = _contact_id.replace('account:',''); + } + else + { + id = 'contact_id'; + _contact_id = _contact_id.replace('contact:', ''); + } + + // 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+"(&|\\$)")) + { + params[id] = _contact_id; + this.src = egw.link('/api/avatar.php',params); + } + } + + set value(_value) + { + this.contact_id = _value; + } + + set src(_value) + { + this.image = _value; + } + + /** + * Implementation of "et2_IDetachedDOM" for fast viewing in gridview + */ + getDetachedAttributes(_attrs : string[]) + { + _attrs.push("contact_id", "label", "href"); + } + + getDetachedNodes() + { + return [this]; + } + + setDetachedAttributes(_nodes, _values) + { + for(let attr in _values) + { + this[attr] = _values[attr]; + } + } +} +customElements.define("et2-avatar", Et2Avatar as any); \ No newline at end of file diff --git a/api/js/etemplate/Et2Avatar/Et2LAvatar.ts b/api/js/etemplate/Et2Avatar/Et2LAvatar.ts new file mode 100644 index 0000000000..cf83969230 --- /dev/null +++ b/api/js/etemplate/Et2Avatar/Et2LAvatar.ts @@ -0,0 +1,96 @@ +/** + * EGroupware eTemplate2 - Letter Avatar widget + * + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package etemplate + * @subpackage api + * @link https://www.egroupware.org + * @author Hadi Nategh + */ + +import {Et2Avatar} from "./Et2Avatar"; +import shoelace from "../Styles/shoelace"; +import {css} from "@lion/core"; + +export class Et2LAvatar extends Et2Avatar +{ + /** + * background color codes + */ + static LAVATAR_BG_COLORS : string[] = [ + '#5a8770', '#b2b7bb', '#6fa9ab', '#f5af29', + '#0088b9', '#f18636', '#d93a37', '#a6b12e', + '#0088b9', '#f18636', '#d93a37', '#a6b12e', + '#5c9bbc', '#f5888d', '#9a89b5', '#407887', + '#9a89b5', '#5a8770', '#d33f33', '#a2b01f', + '#f0b126', '#0087bf', '#f18636', '#0087bf', + '#b2b7bb', '#72acae', '#9c8ab4', '#5a8770', + '#eeb424', '#407887' + ]; + + static get styles() + { + return [ + ...super.styles, + shoelace, + css` + + ` + ]; + } + + static get properties() + { + return { + ...super.properties, + + lname: {type: String}, + + fname: {type: String}, + } + } + + constructor() + { + super(); + this.lname = ""; + this.fname = ""; + this.initials = Et2LAvatar.lavatar(this.fname, this.lname, this.contact_id).initials; + } + + set src(_url) + { + if (_url && decodeURIComponent(_url).match("lavatar=1") && (this.options.fname || this.options.lname) && this.options.contact_id) + { + this.initials = Et2LAvatar.lavatar(this.options.fname, this.options.lname, this.options.contact_id).initials; + return; + } + super.src= _url; + } + + + /** + * Generate letter avatar with given data + * @param {type} _fname + * @param {type} _lname + * @param {type} _id + * @returns {string} return data url + */ + static lavatar(_fname, _lname, _id) + { + let str = _fname + _lname + _id; + let getBgColor = function(_str) + { + let hash = 0; + for (let i=0; i< _str.length; i++) + { + hash = _str[i].charCodeAt(0) + hash; + } + return Et2LAvatar.LAVATAR_BG_COLORS[hash % Et2LAvatar.LAVATAR_BG_COLORS.length]; + }; + let bg = getBgColor(str); + let text = (_fname ? _fname[0].toUpperCase() : "")+(_lname ? _lname[0].toUpperCase() : ""); + return {background: bg, initials: text}; + } +} +customElements.define("et2-lavatar", Et2LAvatar as any); \ No newline at end of file diff --git a/api/js/etemplate/etemplate2.ts b/api/js/etemplate/etemplate2.ts index bceb1b3e72..611904166b 100644 --- a/api/js/etemplate/etemplate2.ts +++ b/api/js/etemplate/etemplate2.ts @@ -24,6 +24,7 @@ import {et2_tabbox} from "./et2_widget_tabs"; import '../jsapi/egw_json.js'; import {egwIsMobile} from "../egw_action/egw_action_common.js"; import './Layout/Et2Box/Et2Box'; +import './Et2Avatar/Et2Avatar'; import './Et2Button/Et2Button'; import './Et2Date/Et2Date'; import './Et2Date/Et2DateDuration'; @@ -42,6 +43,7 @@ import './Expose/Et2ImageExpose'; import './Expose/Et2DescriptionExpose'; import './Et2Favorites/Et2Favorites'; import './Et2Image/Et2Image'; +import './Et2Avatar/Et2LAvatar'; import './Et2Link/Et2Link'; import './Et2Link/Et2LinkAppSelect'; import './Et2Link/Et2LinkEntry';