diff --git a/data/user.png b/data/user.png new file mode 100644 index 0000000..1db461c Binary files /dev/null and b/data/user.png differ diff --git a/data/user.svg b/data/user.svg new file mode 100644 index 0000000..251707f --- /dev/null +++ b/data/user.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/webui-src/app/mail/mail.css b/webui-src/app/mail/mail.css index cb8e37a..3d1348a 100644 --- a/webui-src/app/mail/mail.css +++ b/webui-src/app/mail/mail.css @@ -67,7 +67,7 @@ input.star-check:checked + label.star-check { } .truncate { display: flex; - width: 70vw; + width: 65vw; height: 1rem; flex-wrap: wrap; gap: 4px; @@ -115,3 +115,12 @@ iframe.msg { margin-left: 200px; animation: fadein 0.5s; } + +.msgHeader { + display: flex; +} + +.msgHeaderDetails { + display: flex; + flex-direction: column; +} diff --git a/webui-src/app/mail/mail_util.js b/webui-src/app/mail/mail_util.js index 748375d..9c7419d 100644 --- a/webui-src/app/mail/mail_util.js +++ b/webui-src/app/mail/mail_util.js @@ -1,6 +1,7 @@ const m = require('mithril'); const rs = require('rswebui'); const widget = require('widgets'); +const peopleUtil = require('people/people_util'); // rsmsgs.h const RS_MSG_BOXMASK = 0x000f; @@ -151,6 +152,15 @@ const MessageView = () => { } }); } + rs.rsJsonApiRequest( + '/rsIdentity/getIdDetails', + { + id: details.from._addr_string, + }, + (data) => { + details = { ...details, avatar: data.details.mAvatar }; + } + ); }, view: (v) => m( @@ -170,46 +180,52 @@ const MessageView = () => { m('i.fas.fa-arrow-left') ), m('h3', details.title), - details.from && - m('from', { style: { display: 'block ruby' } }, [ - m('p', { style: { fontWeight: 'bold' } }, 'From: '), - rs.userList.userMap[details.from._addr_string], - ]), - toList && - Object.keys(toList).length > 0 && - // TODO: optimize javascript for show-more and show-less working - m('to', { style: { display: 'block ruby' } }, [ - m('p', { style: { fontWeight: 'bold' } }, 'To: '), - m('div.truncate[id=truncate]', - Object.keys(toList).map((key, index) => m('p', rs.userList.userMap[key] + ', ')), - ), - m('button[id=show-more]', { - style: { display: Object.keys(toList).length > 10 ? 'block' : 'none' }, - onclick: () => { - document.querySelector('#show-more').style.display = 'none'; - document.querySelector('#truncate').style.height = 'max-content'; - document.querySelector('#show-less').style.display = 'block'; - } - }, 'Show More'), - m('button[id=show-less][style="display: none;"]', { - onclick: () => { - document.querySelector('#show-more').style.display = 'block'; - document.querySelector('#truncate').style.height = '1rem'; - document.querySelector('#show-less').style.display = 'none'; - } - }, 'Show Less'), - ]), - ccList && - Object.keys(ccList).length > 0 && - m('cc', { style: { display: 'block ruby' } }, [ - m('p', { style: { fontWeight: 'bold' } }, 'CC: '), - Object.keys(ccList).map((key, index) => m('p', rs.userList.userMap[key] + ', ')), - ]), - bccList && - Object.keys(bccList).length > 0 && - m('bcc', { style: { display: 'block ruby' } }, [ - m('p', { style: { fontWeight: 'bold' } }, 'BCC: '), - Object.keys(bccList).map((key, index) => m('p', rs.userList.userMap[key] + ', ')), + m('.msgHeader', [ + details.from && + m(peopleUtil.UserAvatar, { avatar: details.avatar, firstLetter: rs.userList.userMap[details.from._addr_string] ? rs.userList.userMap[details.from._addr_string].slice(0, 1).toUpperCase() : '' }), + m('.msgHeaderDetails', [ + details.from && + m('from', { style: { display: 'block ruby' } }, [ + m('p', { style: { fontWeight: 'bold' } }, 'From: '), + rs.userList.userMap[details.from._addr_string], + ]), + toList && + Object.keys(toList).length > 0 && + // TODO: optimize javascript for show-more and show-less working + m('to', { style: { display: 'block ruby' } }, [ + m('p', { style: { fontWeight: 'bold' } }, 'To: '), + m('div.truncate[id=truncate]', + Object.keys(toList).map((key, index) => m('p', rs.userList.userMap[key] + ', ')), + ), + m('button[id=show-more]', { + style: { display: Object.keys(toList).length > 10 ? 'block' : 'none' }, + onclick: () => { + document.querySelector('#show-more').style.display = 'none'; + document.querySelector('#truncate').style.height = 'max-content'; + document.querySelector('#show-less').style.display = 'block'; + } + }, 'Show More'), + m('button[id=show-less][style="display: none;"]', { + onclick: () => { + document.querySelector('#show-more').style.display = 'block'; + document.querySelector('#truncate').style.height = '1rem'; + document.querySelector('#show-less').style.display = 'none'; + } + }, 'Show Less'), + ]), + ccList && + Object.keys(ccList).length > 0 && + m('cc', { style: { display: 'block ruby' } }, [ + m('p', { style: { fontWeight: 'bold' } }, 'CC: '), + Object.keys(ccList).map((key, index) => m('p', rs.userList.userMap[key] + ', ')), + ]), + bccList && + Object.keys(bccList).length > 0 && + m('bcc', { style: { display: 'block ruby' } }, [ + m('p', { style: { fontWeight: 'bold' } }, 'BCC: '), + Object.keys(bccList).map((key, index) => m('p', rs.userList.userMap[key] + ', ')), + ]), + ]) ]), m('button', 'Reply'), m('button', 'Reply All'), diff --git a/webui-src/app/people/people.css b/webui-src/app/people/people.css index 11297c3..f87c2d5 100644 --- a/webui-src/app/people/people.css +++ b/webui-src/app/people/people.css @@ -17,10 +17,26 @@ font-size: 0.9em; } +.defaultAvatar { + width: 50px; + height: max-content; + aspect-ratio: 1; + background: lightsteelblue; + border-radius: 50%; + display: grid; + place-items: center; +} +.defaultAvatar p { + font-weight: 900; + color: #666F7F; + transform: translateY(1px); +} img.avatar { - float: left; - height: 100px; + display: block; + width: 50px; + aspect-ratio: 1; margin-right: 0.3em; + border-radius: 50%; } .identity .details { diff --git a/webui-src/app/people/people_ownids.js b/webui-src/app/people/people_ownids.js index c33bb2e..cf41404 100644 --- a/webui-src/app/people/people_ownids.js +++ b/webui-src/app/people/people_ownids.js @@ -29,26 +29,26 @@ const SignedIdentiy = () => { owns.ids.length > 0 ? rs.rsJsonApiRequest( - '/rsIdentity/createIdentity', - { - id: owns.ids[0], - name: v.attrs.name, - pseudonimous: false, - pgpPassword: passphase, - }, - (data) => { - const message = data.retval - ? 'Successfully created identity.' - : 'An error occured while creating identity.'; - console.log(message); - widget.popupMessage([m('h3', 'Create new Identity'), m('hr'), message]); - } - ) + '/rsIdentity/createIdentity', + { + id: owns.ids[0], + name: v.attrs.name, + pseudonimous: false, + pgpPassword: passphase, + }, + (data) => { + const message = data.retval + ? 'Successfully created identity.' + : 'An error occured while creating identity.'; + console.log(message); + widget.popupMessage([m('h3', 'Create new Identity'), m('hr'), message]); + } + ) : widget.popupMessage([ - m('h3', 'Create new Identity'), - m('hr'), - 'An error occured while creating identity.', - ]); + m('h3', 'Create new Identity'), + m('hr'), + 'An error occured while creating identity.', + ]); }); }, }, @@ -99,10 +99,10 @@ const CreateIdentity = () => { m( 'p', 'You can have one or more identities. ' + - 'They are used when you chat in lobbies, ' + - 'forums and channel comments. ' + - 'They act as the destination for distant chat and ' + - 'the Retroshare distant mail system.' + 'They are used when you chat in lobbies, ' + + 'forums and channel comments. ' + + 'They act as the destination for distant chat and ' + + 'the Retroshare distant mail system.' ), m( 'button', @@ -111,18 +111,18 @@ const CreateIdentity = () => { !pseudonimous ? widget.popupMessage(m(SignedIdentiy, { name })) : rs.rsJsonApiRequest( - '/rsIdentity/createIdentity', - { - name, - pseudonimous, - }, - (data) => { - const message = data.retval - ? 'Successfully created identity.' - : 'An error occured while creating identity.'; - widget.popupMessage([m('h3', 'Create new Identity'), m('hr'), message]); - } - ); + '/rsIdentity/createIdentity', + { + name, + pseudonimous, + }, + (data) => { + const message = data.retval + ? 'Successfully created identity.' + : 'An error occured while creating identity.'; + widget.popupMessage([m('h3', 'Create new Identity'), m('hr'), message]); + } + ); }, }, 'Create' @@ -192,28 +192,28 @@ const EditIdentity = () => { onclick: () => { !peopleUtil.checksudo(v.attrs.details.mPgpId) ? widget.popupMessage([ - m(SignedEditIdentity, { - name, - details: v.attrs.details, - }), - ]) + m(SignedEditIdentity, { + name, + details: v.attrs.details, + }), + ]) : rs.rsJsonApiRequest( - '/rsIdentity/updateIdentity', - { - id: v.attrs.details.mId, + '/rsIdentity/updateIdentity', + { + id: v.attrs.details.mId, - name, + name, - // avatar: v.attrs.details.mAvatar.mData.base64, - pseudonimous: true, - }, - (data) => { - const message = data.retval - ? 'Successfully Updated identity.' - : 'An error occured while updating identity.'; - widget.popupMessage([m('h3', 'Update Identity'), m('hr'), message]); - } - ); + // avatar: v.attrs.details.mAvatar.mData.base64, + pseudonimous: true, + }, + (data) => { + const message = data.retval + ? 'Successfully Updated identity.' + : 'An error occured while updating identity.'; + widget.popupMessage([m('h3', 'Update Identity'), m('hr'), message]); + } + ); }, }, 'Save' @@ -276,7 +276,8 @@ const Identity = () => { }, [ m('h4', details.mNickname), - m(peopleUtil.UserAvatar, { avatar: details.mAvatar }), + details.mNickname && + m(peopleUtil.UserAvatar, { avatar: details.mAvatar, firstLetter: details.mNickname.slice(0, 1).toUpperCase() }), m('.details', [ m('p', 'ID:'), m('p', details.mId), diff --git a/webui-src/app/people/people_util.js b/webui-src/app/people/people_util.js index 93ddd32..957247e 100644 --- a/webui-src/app/people/people_util.js +++ b/webui-src/app/people/people_util.js @@ -10,10 +10,15 @@ const UserAvatar = () => ({ const imageURI = v.attrs.avatar; console.log(imageURI); return imageURI === undefined || imageURI.mData.base64 === '' - ? [] + ? m('div.defaultAvatar', { + // image isn't getting loaded + // ? m('img.defaultAvatar', { + // src: '../data/user.png' + // }) + }, m('p', v.attrs.firstLetter)) : m('img.avatar', { - src: 'data:image/png;base64,' + imageURI.mData.base64, - }); + src: 'data:image/png;base64,' + imageURI.mData.base64, + }); }, }); @@ -55,7 +60,7 @@ function sortIds(list) { return list; } -async function ownIds(consumer = (list) => {}, onlySigned = false) { +async function ownIds(consumer = (list) => { }, onlySigned = false) { await rs.rsJsonApiRequest('/rsIdentity/getOwnSignedIds', {}, (owns) => { if (onlySigned) { consumer(sortIds(owns.ids)); @@ -113,7 +118,8 @@ const regularcontactInfo = () => { }, [ m('h4', details.mNickname), - m(UserAvatar, { avatar: details.mAvatar }), + details.mNickname && + m(UserAvatar, { avatar: details.mAvatar, firstLetter: details.mNickname.slice(0, 1).toUpperCase() }), m('.details', [ m('p', 'ID:'), m('p', details.mId), diff --git a/webui-src/app/theme.css b/webui-src/app/theme.css index d8b24c6..d4f4403 100644 --- a/webui-src/app/theme.css +++ b/webui-src/app/theme.css @@ -2,6 +2,12 @@ General site-wide rules ******************************/ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + /* Main base div for tabs used by m.route */ .content { height: 100%; @@ -156,19 +162,20 @@ hr { font-size: 0.8rem; border-radius: 5px; display: flex; - justify-content: start; + justify-content: center; align-items: center; + gap: 0.5rem; color: black; border-radius: 5px; border: 1px solid black; - padding: 0px 10px; + padding: 10px 14px; cursor: pointer; } .webhelp > i { - margin-right: 1.2px; font-size: 1.2rem; } .webhelp > p { + margin-bottom: -4px; font-weight: 600; } .retroshareID { @@ -360,7 +367,7 @@ Target specific sections /* Navbar */ .nav-logo { - width: 9rem; + width: 130px; padding: 1.2rem 0; display: flex; gap: 0.3rem; @@ -383,22 +390,22 @@ nav.tab-menu { flex-direction: column; align-items: center; height: 100%; - padding: 0.5rem 0.4rem; + padding: 8px 6px; margin-right: 0rem; } .tab-menu-item { width: 10rem; - border-radius: 8px; + border-radius: 6px; display: flex; align-items: center; } a.tab-menu-item { - margin: 0.2rem; - padding: 0.7rem 0.4rem; + margin: 4px; + padding: 10px; text-align: center; text-decoration: none; color: #ccc; - font-size: 1em; + font-size: 0.875em; /* CSS capitalization is magical! */ text-transform: capitalize; transition: all 300ms; @@ -411,8 +418,8 @@ a.tab-menu-item { } .tab-menu-item.selected-tab-item { - color: white; - background-color: #FFFFFF20; + color: #99DEFF; + background-color: #89BEFA20; font-weight: medium; } .sidebar {