Signed-off-by: Christopher Ng <chrng8@gmail.com> Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com> Signed-off-by: Christopher Ng <chrng8@gmail.com>tags/v26.0.0beta1
@@ -1 +1 @@ | |||
{"version":3,"sourceRoot":"","sources":["styles.scss"],"names":[],"mappings":"AAkBA,yQACC,SACA,UACA,SACA,oBACA,eACA,oBACA,wBACA,eACA,uDACA,qBAGD,6CACC,aAID,kGAEC,gDACA,aAGD,UACC,YAGD,6DACC,cAGD,KACC,gBAGD,MACC,yBACA,iBACA,mBAGD,cACC,gBACA,mBAGD,YACC,sBAGD,EACC,SACA,6BACA,qBACA,eACA,IACC,eAIF,WACC,aACA,0BAGD,MACC,eACA,QACC,eAIF,0BACC,eAGD,GACC,gBAGD,KACC,mBAEA,mCACA,uCACA,6BACA,6BAGD,mBACC,kBAGD,qBACC,kBACA,uBACA,qBACA,2BACA,2DACA,uBAGD,iBACC,qBACA,aACA,gCAGD,eACC,YACA,aAGD,cACC,eACA,MACA,SACA,OACA,YACA,WACA,aACA,kBACA,gDACA,gCACA,iBACA,eACA,kBACC,cACA,kBACA,UACA,QACA,gBAED,gBACC,gCACA,sDACA,4CACC,qCAOH,oBACC,WACA,YAGD,gCACC,+BAGD,0BACC,kCACA,yCACA,+BACA,4BAMD,YACC,8CACA,gCAMD,kBACC,sBAKD,4BAEC,oCACA,kBACA,gBACA,WACA,sDACC,gBAED,sEACC,gBAED,kCACC,mBAED,oHAEC,qBACA,YACA,WACA,mBACA,gcAEC,WAOH,sBACC,WASD,oCACC,kBACA,yBACA,sBACA,qBACA,iBAKD,kBACC,kBACA,UACA,SACA,YAGD,8BACC,WACA,oBACA,wBACA,wBAGD,2EACC,WAED,oGACC,0CACA,UACA,qBAGD,mDACC,6BACA,YACA,WACA,yCACA,4BACA,2BACA,WAOA,qEACC,UAED,qEACC,UAIF,wEACC,aAGD,2CACC,mBAGD,yBACC,kBACA,qBACA,iBAED,qBACC,cACA,QACA,iBACA,kBACA,aAKD,4CACC,eACA,YACA,mCACA,6BACA,qDAIA,2BACC,4BAKD,wBACC,sBACA,4BACA,+BACC,2CACA,qBACA,kBAGF,0BACC,qBACA,gBAIF,YACC,YACA,8BACA,oBACC,sBAIF,eACC,2CAUD,mBACC,kBACA,cACA,2BACC,kBACA,cAIF,UACC,gBAGD,8CACC,UAIA,oGAGC,WAIF,mBACC,WACA,kBACA,QAEA,kDACC,UAIF,WACC,WACA,YAGD,eACC,WAIA,8CACC,UAKD,kDACC,UAKD,0CACC,UAKD,8CACC,8CAIF,KACC,mFAGD,OACC,gBACA,YACA,eACA,qBACA,UACC,qBAIF,2FACC,gBACA,uBAGD,2BACC,yDAGD,2BACC,6DAID,yBACC,gBACA,gBACA,WACA,mCACA,YACA,wBAEA,sKAGC,+BACA,mBAED,2CACC,YACA,eACA,YACA,8CACA,6BAEA,gEACC,cACA,mBAED,oDACC,WAEA,8EACC,yEAED,8EACC,wEAGF,oEACC,UAID,oDACC,mBACA,gCACA,WACA,WACA,YAED,0DACC,yBAGA,+FACC,gDAGD,wOAGC,sCACA,gCACA,iBAGD,yNAEC,gCACA,WAMJ,wCACC,gCACA,wCAKD,yBACC,2BACA,sBACA,mCACA,wBAEA,4CACC,uBAGD,sKAGC,+BACA,mBAED,2CACC,YACA,eACA,YACA,8CACA,6BAEA,gEACC,cACA,mBAIF,qFACC,iBAGA,iDACC,mBACA,gCACA,WACA,yDACC,UACA,WACA,iBAGF,uDACC,yBAGA,0TAIC,sCACA,gCACA,iBAGD,4FACC,gCAGD,qEACC,2CASH,oGACC,aACA,iBACA,8BACA,0GACC,cACA,SACA,YACA,YACA,WACA,aACA,mBACA,uBACA,8GACC,kBACA,kBACA,mBACA,6BACA,cACA,iBACA,WACA,YACA,YACA,eAOJ,8BACC,kBACA,aACA,sBAEA,uCACC,eACA,sBACA,oBAEA,yDACC,uCACA,4BACA,gCAGA,6DACC,eAED,uDACC,iBAED,oEACC,YACA,YAKH,mDACC,kBACA,+BACA,YACA,SACA,aACA,WACA,QACA,MAEA,4KAGC,0CACA,UAIF,iDACC,eACA,YACA,sBACA,oBACA,WACA,gBACA,eACA,8CACA,0CACA,wCACA,kBACA,UACA,QACA,QAEA,gEACC,sCACA,0BACA,WACA,YACA,WACA,WAGD,mDACC,WACA,YACA,gBAGD,uDACC,SACA,gBACA,4DACC,aACA,YAMH,kDACC,sBACA,qBACA,gBACA,OAGA,WACA,kBAED,4CACC,oCACA,kBACA,gBACA,WACA,aAED,wCACC,8CACA,WAED,0DAEC,kBACA,mBAEC,mEACC,4CACA,8CACA,sEACC,UACA,YAIH,0EACC,cACA,aACA,YACA,sBACA,2BACA,sBAED,+EACC,iBACA,iBAGD,6EACC,WACA,WACA,gBACA,qBACA,2BACA,WAED,qQAGC,kBAED,oLAEC,mBAGD,6DACC,aACA,4CAED,2EACC,mBAED,oEACC,gBACA,mBACA,uBACA,qBACA,4BACA,kBACA,4BACA,eAEA,YACA,oFACC,aACA,2FACC,gBACA,gBACA,uBAED,0FACC,gBAIH,oIACC,WAED,oEACC,iBAED,oEAIC,aACA,sBAEA,0EACC,aACA,+CACA,6BACA,aACA,cAEA,6EACC,cACA,kBACA,mCACA,QAhBS,KAiBT,aACA,sBACA,YAGA,gFACC,YACA,UACA,kBACA,mCAEA,yFACC,oBACA,+BACA,wBACA,YA/BU,KAgCV,eACA,yGACC,uBAGF,yFACC,iBACA,WAED,qFACC,aAON,2DACC,gDAIF,WACC,0BAGD,aACC,WACA,sBAMA,0BACC,eACA,iCACC,0BACA,4BACA,0BACA,0BACA,aACA,YAEA,qDACA,gDAGD,iGAGC,qBAKD,mCACC,YAEA,iDACC,6DAMJ,6CAEC,2BACA,iBACA,iBACA,YAEA,2DACC,0BACA,kBACA,iJAEC,qBAIF,sDAEC,kCACA,iBACA,iBACA,gBAEA,8DACC,kBAEA,gEACC,cACA,WACA,eACA,WAKH,sDACC,aACA,kBACA,mBACA,yBAEA,8DACC,YACA,WACA,qBAGD,4DACC,YACA,iBAEA,gEACC,kBACA,WAGD,iJAEC,gBACA,gBACA,mBACA,uBAED,qJACC,oCAIF,4MACC,WACA,YACA,WACA,eAEA,gPACC,aAED,wNACC,wCAGD,6pBAGC,UAIF,2EACC,WAEA,iFACC,2BACA,4CAGD,yFACC,wCAKF,4DACC,SACA,kBAED,0EACC,UAMH,qBACC,wBACA,WACA,YAKD,YACC,6BAMA,qBACC,WACA,aAED,wBACC,cACA,gDACA,WACA,aAED,2BACC,WACA,YACA,6BACC,WAGF,wBACC,wCACA,kBACA,mBACA,gBACA,uBACA,0CACA,kCACA,6DACC,0CAGF,sBACC,UACA,WAKF,YACC,oBAED,UACC,oBACA,kDACA,4BACA,iCACA,YACA,0BACA,cACA,QACA,kBACA,oBACC,QACA,kBACA,sBACC,WAIA,0FACC,cAIF,iCACC,SACA,iBACA,oCACC,iBACA,gBACA,kBACA,kBACA,gEACC,+EAGF,gDACC,aAIH,iBACC,aACA,wBACC,QAGF,2BAEC,kBACA,aACA,WACA,uBACA,mBACA,gBACA,cAEA,gBAEA,kGAGC,oBAGF,0BACC,UACA,WAID,qBACC,iBACA,kBAEA,4BACC,eAGF,mEACC,UAEA,kKAEC,WAOH,QACC,UACA,yCACA,sCACA,qCACA,oCACA,iCACA,oBACC,UAOD,+CACC,SACA,kBAED,mDACC,gBAKF,cACC,mBAMD,mBACC,aACA,QACA,SACA","file":"styles.css"} | |||
{"version":3,"sourceRoot":"","sources":["styles.scss"],"names":[],"mappings":"AAkBA,yQACC,SACA,UACA,SACA,oBACA,eACA,oBACA,wBACA,eACA,uDACA,qBAGD,6CACC,aAID,kGAEC,gDACA,aAGD,UACC,YAGD,6DACC,cAGD,KACC,gBAGD,MACC,yBACA,iBACA,mBAGD,cACC,gBACA,mBAGD,YACC,sBAGD,EACC,SACA,6BACA,qBACA,eACA,IACC,eAIF,WACC,aACA,0BAGD,MACC,eACA,QACC,eAIF,0BACC,eAGD,GACC,gBAGD,KACC,mBAEA,mCACA,uCACA,6BACA,6BAGD,mBACC,kBAGD,qBACC,kBACA,uBACA,qBACA,2BACA,2DACA,uBAGD,iBACC,qBACA,aACA,gCAGD,eACC,YACA,aAGD,cACC,eACA,MACA,SACA,OACA,YACA,WACA,aACA,kBACA,gDACA,gCACA,iBACA,eACA,kBACC,cACA,kBACA,UACA,QACA,gBAED,gBACC,gCACA,sDACA,4CACC,qCAOH,oBACC,WACA,YAGD,gCACC,+BAGD,0BACC,kCACA,yCACA,+BACA,4BAMD,YACC,8CACA,gCAMD,kBACC,sBAKD,4BAEC,oCACA,kBACA,gBACA,WACA,sDACC,gBAED,sEACC,gBAED,kCACC,mBAED,oHAEC,qBACA,YACA,WACA,mBACA,gcAEC,WAOH,sBACC,WASD,oCACC,kBACA,yBACA,sBACA,qBACA,iBAKD,kBACC,kBACA,UACA,SACA,YAGD,8BACC,WACA,oBACA,wBACA,wBAGD,2EACC,WAED,oGACC,0CACA,UACA,qBAGD,mDACC,6BACA,YACA,WACA,yCACA,4BACA,2BACA,WAOA,qEACC,UAED,qEACC,UAIF,wEACC,aAGD,2CACC,mBAGD,yBACC,kBACA,qBACA,iBAED,qBACC,cACA,QACA,iBACA,kBACA,aAKD,4CACC,eACA,YACA,mCACA,6BACA,qDAIA,2BACC,4BAKD,wBACC,sBACA,4BACA,+BACC,2CACA,qBACA,kBAGF,0BACC,qBACA,gBAIF,YACC,YACA,8BACA,oBACC,sBAIF,eACC,2CAUD,mBACC,kBACA,cACA,2BACC,kBACA,cAIF,UACC,gBAGD,8CACC,UAIA,oGAGC,WAIF,mBACC,WACA,kBACA,QAEA,kDACC,UAIF,WACC,WACA,YAGD,eACC,WAIA,8CACC,UAKD,kDACC,UAKD,0CACC,UAKD,8CACC,8CAIF,KACC,mFAGD,OACC,gBACA,YACA,eACA,qBACA,UACC,qBAIF,2FACC,gBACA,uBAGD,2BACC,yDAGD,2BACC,6DAID,yBACC,gBACA,gBACA,WACA,mCACA,YACA,wBAEA,sKAGC,+BACA,mBAED,2CACC,YACA,eACA,YACA,8CACA,6BAEA,gEACC,cACA,mBAED,oDACC,WAEA,8EACC,yEAED,8EACC,wEAGF,oEACC,UAID,oDACC,mBACA,gCACA,WACA,WACA,YAED,0DACC,yBAGA,+FACC,gDAGD,wOAGC,sCACA,gCACA,iBAGD,yNAEC,gCACA,WAMJ,wCACC,gCACA,wCAKD,yBACC,2BACA,sBACA,mCACA,wBAEA,4CACC,uBAGD,sKAGC,+BACA,mBAED,2CACC,YACA,eACA,YACA,8CACA,6BAEA,gEACC,cACA,mBAIF,qFACC,iBAGA,iDACC,mBACA,gCACA,WACA,yDACC,UACA,WACA,iBAGF,uDACC,yBAGA,0TAIC,sCACA,gCACA,iBAGD,4FACC,gCAGD,qEACC,2CASH,oGACC,aACA,iBACA,8BACA,0GACC,cACA,SACA,YACA,YACA,WACA,aACA,mBACA,uBACA,8GACC,kBACA,kBACA,mBACA,6BACA,cACA,iBACA,WACA,YACA,YACA,eAOJ,8BACC,kBACA,aACA,sBAEA,uCACC,eACA,sBACA,oBAEA,yDACC,uCACA,4BACA,gCAGA,6DACC,eAED,uDACC,iBAED,oEACC,YACA,YAKH,mDACC,kBACA,+BACA,YACA,SACA,aACA,WACA,QACA,MAEA,4KAGC,0CACA,UAIF,iDACC,eACA,YACA,sBACA,oBACA,WACA,gBACA,eACA,8CACA,0CACA,wCACA,kBACA,UACA,QACA,QAEA,gEACC,sCACA,0BACA,WACA,YACA,WACA,WAGD,mDACC,WACA,YACA,gBAGD,uDACC,SACA,gBACA,4DACC,aACA,YAMH,kDACC,sBACA,qBACA,gBACA,OAGA,WACA,kBAED,4CACC,oCACA,kBACA,gBACA,WACA,aAED,wCACC,8CACA,WAED,0DAEC,kBACA,mBAEC,mEACC,4CACA,8CACA,sEACC,UACA,YAIH,0EACC,cACA,aACA,YACA,sBACA,2BACA,sBAED,+EACC,iBACA,iBAGD,6EACC,WACA,WACA,gBACA,qBACA,2BACA,WAED,qQAGC,kBAED,oLAEC,mBAGD,6DACC,aACA,4CAED,2EACC,mBAED,oEACC,gBACA,mBACA,uBACA,qBACA,4BACA,kBACA,4BACA,eAEA,YACA,oFACC,aACA,2FACC,gBACA,gBACA,uBAED,0FACC,gBAIH,oIACC,WAED,oEACC,iBAED,oEAIC,aACA,sBAEA,0EACC,aACA,+CACA,6BACA,aACA,cAEA,6EACC,cACA,kBACA,mCACA,QAhBS,KAiBT,aACA,sBACA,YAGA,gFACC,YACA,UACA,kBACA,mCAEA,yFACC,oBACA,+BACA,wBACA,YA/BU,KAgCV,eACA,yGACC,uBAGF,yFACC,iBACA,WAED,qFACC,aAON,2DACC,gDAIF,WACC,0BAGD,aACC,WACA,sBAKD,YACC,6BAMA,qBACC,WACA,aAED,wBACC,cACA,gDACA,WACA,aAED,2BACC,WACA,YACA,6BACC,WAGF,wBACC,wCACA,kBACA,mBACA,gBACA,uBACA,0CACA,kCACA,6DACC,0CAGF,sBACC,UACA,WAKF,YACC,oBAED,UACC,oBACA,kDACA,4BACA,iCACA,YACA,0BACA,cACA,QACA,kBACA,oBACC,QACA,kBACA,sBACC,WAIA,0FACC,cAIF,iCACC,SACA,iBACA,oCACC,iBACA,gBACA,kBACA,kBACA,gEACC,+EAGF,gDACC,aAIH,iBACC,aACA,wBACC,QAGF,2BAEC,kBACA,aACA,WACA,uBACA,mBACA,gBACA,cAEA,gBAEA,kGAGC,oBAGF,0BACC,UACA,WAID,qBACC,iBACA,kBAEA,4BACC,eAGF,mEACC,UAEA,kKAEC,WAOH,QACC,UACA,yCACA,sCACA,qCACA,oCACA,iCACA,oBACC,UAOD,+CACC,SACA,kBAED,mDACC,gBAKF,cACC,mBAMD,mBACC,aACA,QACA,SACA","file":"styles.css"} |
@@ -893,160 +893,6 @@ span.ui-icon { | |||
margin: 3px 7px 30px 0; | |||
} | |||
/* ---- CONTACTS MENU ---- */ | |||
#contactsmenu { | |||
.menutoggle { | |||
cursor: pointer; | |||
&:before { | |||
background-size: 20px 20px; | |||
background-repeat: no-repeat; | |||
background-position-x: 3px; | |||
background-position-y: 4px; | |||
padding: 14px; | |||
content: ' '; | |||
// Force white | |||
background-image: var(--original-icon-contacts-white); | |||
filter: var(--background-image-invert-if-bright); | |||
} | |||
&:hover, | |||
&:focus, | |||
&:active { | |||
opacity: 1 !important; | |||
} | |||
} | |||
#contactsmenu-menu { | |||
a { | |||
padding: 2px; | |||
&:focus-visible { | |||
box-shadow: inset 0 0 0 2px var(--color-main-text) !important; // override rule in core/css/headers.scss #header a:focus-visible | |||
} | |||
} | |||
} | |||
} | |||
#header .header-right > div#contactsmenu > .menu { | |||
/* show 2.5 to 4.5 entries depending on the screen height */ | |||
height: calc(100vh - 50px * 3); | |||
max-height: calc(50px * 6 + 2px); | |||
min-height: calc(50px * 3.5); | |||
width: 350px; | |||
.emptycontent { | |||
margin-top: 5vh !important; | |||
margin-bottom: 2vh; | |||
.icon-loading, | |||
.icon-search { | |||
display: inline-block; | |||
} | |||
} | |||
.content { | |||
/* fixed max height of the parent container without the search input */ | |||
height: calc(100vh - 50px * 3 - 50px); | |||
max-height: calc(50px * 5); | |||
min-height: calc(50px * 3.5 - 50px); | |||
overflow-y: auto; | |||
.footer { | |||
text-align: center; | |||
a { | |||
display: block; | |||
width: 100%; | |||
padding: 12px 0; | |||
opacity: .5; | |||
} | |||
} | |||
} | |||
.contact { | |||
display: flex; | |||
position: relative; | |||
align-items: center; | |||
padding: 3px 3px 3px 10px; | |||
.avatar { | |||
height: 32px; | |||
width: 32px; | |||
display: inline-block; | |||
} | |||
.body { | |||
flex-grow: 1; | |||
padding-left: 8px; | |||
div { | |||
position: relative; | |||
width: 100%; | |||
} | |||
.full-name, .last-message { | |||
/* TODO: don't use fixed width */ | |||
max-width: 204px; | |||
overflow: hidden; | |||
white-space: nowrap; | |||
text-overflow: ellipsis; | |||
} | |||
.last-message, .email-address { | |||
color: var(--color-text-maxcontrast); | |||
} | |||
} | |||
.top-action, .second-action, .other-actions { | |||
width: 16px; | |||
height: 16px; | |||
opacity: .5; | |||
cursor: pointer; | |||
&:not(button) { | |||
padding: 14px; | |||
} | |||
img { | |||
filter: var(--background-invert-if-dark); | |||
} | |||
&:hover, | |||
&:active, | |||
&:focus { | |||
opacity: 1; | |||
} | |||
} | |||
button.other-actions { | |||
width: 44px; | |||
&:focus { | |||
border-color: transparent; | |||
box-shadow: 0 0 0 2px var(--color-main-text); | |||
} | |||
&:focus-visible { | |||
border-radius: var(--border-radius-pill); | |||
} | |||
} | |||
/* actions menu */ | |||
.menu { | |||
top: 47px; | |||
margin-right: 13px; | |||
} | |||
.popovermenu::after { | |||
right: 2px; | |||
} | |||
} | |||
} | |||
#contactsmenu-search { | |||
width: calc(100% - 16px); | |||
margin: 8px; | |||
height: 34px; | |||
} | |||
/* ---- TOOLTIPS ---- */ | |||
.extra-data { |
@@ -32,7 +32,7 @@ describe('Contacts menu', function() { | |||
* @returns {Promise} | |||
*/ | |||
function openMenu() { | |||
return menu._toggleVisibility(true); | |||
return menu.loadContacts(); | |||
} | |||
beforeEach(function(done) { |
@@ -381,8 +381,7 @@ const ContactsMenuView = View.extend({ | |||
/** | |||
* @param {Object} options | |||
* @param {jQuery} options.el | |||
* @param {jQuery} options.trigger | |||
* @param {string} options.el | |||
* @class ContactsMenu | |||
* @memberOf OC | |||
*/ | |||
@@ -391,12 +390,9 @@ const ContactsMenu = function(options) { | |||
} | |||
ContactsMenu.prototype = { | |||
/** @type {jQuery} */ | |||
/** @type {string} */ | |||
$el: undefined, | |||
/** @type {jQuery} */ | |||
_$trigger: undefined, | |||
/** @type {ContactsMenuView} */ | |||
_view: undefined, | |||
@@ -405,41 +401,19 @@ ContactsMenu.prototype = { | |||
/** | |||
* @param {Object} options | |||
* @param {jQuery} options.el - the element to render the menu in | |||
* @param {jQuery} options.trigger - the element to click on to open the menu | |||
* @param {string} options.el - the selector of the element to render the menu in | |||
* @returns {undefined} | |||
*/ | |||
initialize: function(options) { | |||
this.$el = options.el | |||
this._$trigger = options.trigger | |||
this.$el = $(options.el) | |||
this._view = new ContactsMenuView({ | |||
el: this.$el | |||
el: this.$el, | |||
}) | |||
this._view.on('search', function(searchTerm) { | |||
this._loadContacts(searchTerm) | |||
this.loadContacts(searchTerm) | |||
}, this) | |||
OC.registerMenu(this._$trigger, this.$el, function() { | |||
this._toggleVisibility(true) | |||
}.bind(this), true) | |||
this.$el.on('beforeHide', function() { | |||
this._toggleVisibility(false) | |||
}.bind(this)) | |||
}, | |||
/** | |||
* @private | |||
* @param {boolean} show | |||
* @returns {Promise} | |||
*/ | |||
_toggleVisibility: function(show) { | |||
if (show) { | |||
return this._loadContacts() | |||
} else { | |||
this.$el.html('') | |||
return Promise.resolve() | |||
} | |||
}, | |||
/** | |||
@@ -461,7 +435,7 @@ ContactsMenu.prototype = { | |||
* @param {string|undefined} searchTerm | |||
* @returns {undefined} | |||
*/ | |||
_loadContacts: function(searchTerm) { | |||
loadContacts: function(searchTerm) { | |||
var self = this | |||
if (!self._contactsPromise) { |
@@ -2,6 +2,7 @@ | |||
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @author Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* @author Christopher Ng <chrng8@gmail.com> | |||
* @author John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @license AGPL-3.0-or-later | |||
@@ -21,16 +22,20 @@ | |||
* | |||
*/ | |||
import $ from 'jquery' | |||
import OC from '../OC' | |||
import Vue from 'vue' | |||
import ContactsMenu from '../views/ContactsMenu.vue' | |||
/** | |||
* @todo move to contacts menu code https://github.com/orgs/nextcloud/projects/31#card-21213129 | |||
*/ | |||
export const setUp = () => { | |||
// eslint-disable-next-line no-new | |||
new OC.ContactsMenu({ | |||
el: $('#contactsmenu .menu'), | |||
trigger: $('#contactsmenu .menutoggle'), | |||
}) | |||
const mountPoint = document.getElementById('contactsmenu') | |||
if (mountPoint) { | |||
// eslint-disable-next-line no-new | |||
new Vue({ | |||
el: mountPoint, | |||
render: h => h(ContactsMenu), | |||
}) | |||
} | |||
} |
@@ -0,0 +1,198 @@ | |||
<!-- | |||
- @copyright 2023 Christopher Ng <chrng8@gmail.com> | |||
- | |||
- @author Christopher Ng <chrng8@gmail.com> | |||
- | |||
- @license AGPL-3.0-or-later | |||
- | |||
- This program is free software: you can redistribute it and/or modify | |||
- it under the terms of the GNU Affero General Public License as | |||
- published by the Free Software Foundation, either version 3 of the | |||
- License, or (at your option) any later version. | |||
- | |||
- This program is distributed in the hope that it will be useful, | |||
- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
- GNU Affero General Public License for more details. | |||
- | |||
- You should have received a copy of the GNU Affero General Public License | |||
- along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
- | |||
--> | |||
<template> | |||
<NcHeaderMenu id="contactsmenu" | |||
:aria-label="t('core', 'Search contacts')" | |||
@open="handleOpen"> | |||
<template #trigger> | |||
<Contacts :size="20" /> | |||
</template> | |||
<div id="contactsmenu-menu" /> | |||
</NcHeaderMenu> | |||
</template> | |||
<script> | |||
import NcHeaderMenu from '@nextcloud/vue/dist/Components/NcHeaderMenu.js' | |||
import Contacts from 'vue-material-design-icons/Contacts.vue' | |||
import OC from '../OC/index.js' | |||
export default { | |||
name: 'ContactsMenu', | |||
components: { | |||
Contacts, | |||
NcHeaderMenu, | |||
}, | |||
data() { | |||
return { | |||
contactsMenu: null, | |||
} | |||
}, | |||
mounted() { | |||
// eslint-disable-next-line no-new | |||
this.contactsMenu = new OC.ContactsMenu({ | |||
el: '#contactsmenu-menu', | |||
}) | |||
}, | |||
methods: { | |||
handleOpen() { | |||
this.contactsMenu?.loadContacts() | |||
}, | |||
}, | |||
} | |||
</script> | |||
<style lang="scss" scoped> | |||
#contactsmenu-menu { | |||
/* show 2.5 to 4.5 entries depending on the screen height */ | |||
height: calc(100vh - 50px * 3); | |||
max-height: calc(50px * 6 + 2px); | |||
min-height: calc(50px * 3.5); | |||
width: 350px; | |||
&:deep { | |||
.emptycontent { | |||
margin-top: 5vh !important; | |||
margin-bottom: 1.5vh; | |||
.icon-loading, | |||
.icon-search { | |||
display: inline-block; | |||
} | |||
} | |||
#contactsmenu-search { | |||
width: calc(100% - 16px); | |||
margin: 8px; | |||
height: 34px; | |||
} | |||
.content { | |||
/* fixed max height of the parent container without the search input */ | |||
height: calc(100vh - 50px * 3 - 50px); | |||
max-height: calc(50px * 5); | |||
min-height: calc(50px * 3.5 - 50px); | |||
overflow-y: auto; | |||
.footer { | |||
text-align: center; | |||
a { | |||
display: block; | |||
width: 100%; | |||
padding: 12px 0; | |||
opacity: .5; | |||
} | |||
} | |||
} | |||
a { | |||
padding: 2px; | |||
&:focus-visible { | |||
box-shadow: inset 0 0 0 2px var(--color-main-text) !important; // override rule in core/css/headers.scss #header a:focus-visible | |||
} | |||
} | |||
.contact { | |||
display: flex; | |||
position: relative; | |||
align-items: center; | |||
padding: 3px 3px 3px 10px; | |||
.avatar { | |||
height: 32px; | |||
width: 32px; | |||
display: inline-block; | |||
} | |||
.body { | |||
flex-grow: 1; | |||
padding-left: 8px; | |||
div { | |||
position: relative; | |||
width: 100%; | |||
} | |||
.full-name, .last-message { | |||
/* TODO: don't use fixed width */ | |||
max-width: 204px; | |||
overflow: hidden; | |||
white-space: nowrap; | |||
text-overflow: ellipsis; | |||
} | |||
.last-message, .email-address { | |||
color: var(--color-text-maxcontrast); | |||
} | |||
} | |||
.top-action, .second-action, .other-actions { | |||
width: 16px; | |||
height: 16px; | |||
opacity: .5; | |||
cursor: pointer; | |||
&:not(button) { | |||
padding: 14px; | |||
} | |||
img { | |||
filter: var(--background-invert-if-dark); | |||
} | |||
&:hover, | |||
&:active, | |||
&:focus { | |||
opacity: 1; | |||
} | |||
} | |||
button.other-actions { | |||
width: 44px; | |||
&:focus { | |||
border-color: transparent; | |||
box-shadow: 0 0 0 2px var(--color-main-text); | |||
} | |||
&:focus-visible { | |||
border-radius: var(--border-radius-pill); | |||
} | |||
} | |||
/* actions menu */ | |||
.menu { | |||
top: 47px; | |||
margin-right: 13px; | |||
} | |||
.popovermenu::after { | |||
right: 2px; | |||
} | |||
} | |||
} | |||
} | |||
</style> |
@@ -69,14 +69,7 @@ $getUserAvatar = static function (int $size) use ($_): string { | |||
<div class="header-right"> | |||
<div id="unified-search"></div> | |||
<div id="notifications"></div> | |||
<div id="contactsmenu"> | |||
<div class="menutoggle" tabindex="0" role="button" | |||
aria-haspopup="true" aria-controls="contactsmenu-menu" aria-expanded="false"> | |||
<span class="hidden-visually"><?php p($l->t('Contacts'));?></span> | |||
</div> | |||
<div id="contactsmenu-menu" class="menu" | |||
aria-label="<?php p($l->t('Contacts menu'));?>"></div> | |||
</div> | |||
<div id="contactsmenu"></div> | |||
<div id="settings"> | |||
<div id="expand" tabindex="0" role="button" class="menutoggle" | |||
aria-label="<?php p($l->t('Open settings menu'));?>" |
@@ -31,7 +31,7 @@ class ContactsMenuContext implements Context, ActorAwareInterface { | |||
* @return Locator | |||
*/ | |||
public static function contactsMenuButton() { | |||
return Locator::forThe()->xpath("//*[@id = 'header']//*[@id = 'contactsmenu']")-> | |||
return Locator::forThe()->xpath("//*[@id = 'header']//*[@id = 'contactsmenu']//*[@class = 'header-menu__trigger']")-> | |||
describedAs("Contacts menu button"); | |||
} | |||
@@ -39,8 +39,7 @@ class ContactsMenuContext implements Context, ActorAwareInterface { | |||
* @return Locator | |||
*/ | |||
public static function contactsMenu() { | |||
return Locator::forThe()->css(".menu")-> | |||
descendantOf(self::contactsMenuButton())-> | |||
return Locator::forThe()->xpath("//*[@id = 'header']//*[@id = 'contactsmenu']//*[@id = 'contactsmenu-menu']")-> | |||
describedAs("Contacts menu"); | |||
} | |||