Преглед изворни кода

Focus trap contacts menu with NcHeaderMenu port

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
Christopher Ng пре 1 година
родитељ
комит
f6aa5224c4

+ 1
- 1
core/css/server.css
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
core/css/server.css.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
core/css/styles.css
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
core/css/styles.css.map Прегледај датотеку

@@ -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"}

+ 0
- 154
core/css/styles.scss Прегледај датотеку

@@ -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 {

+ 1
- 1
core/js/tests/specs/contactsmenuSpec.js Прегледај датотеку

@@ -32,7 +32,7 @@ describe('Contacts menu', function() {
* @returns {Promise}
*/
function openMenu() {
return menu._toggleVisibility(true);
return menu.loadContacts();
}

beforeEach(function(done) {

+ 8
- 34
core/src/OC/contactsmenu.js Прегледај датотеку

@@ -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) {

+ 12
- 7
core/src/components/ContactsMenu.js Прегледај датотеку

@@ -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),
})
}
}

+ 198
- 0
core/src/views/ContactsMenu.vue Прегледај датотеку

@@ -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>

+ 1
- 8
core/templates/layout.user.php Прегледај датотеку

@@ -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'));?>"

+ 2
- 2
dist/core-common.js
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
dist/core-common.js.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 2
- 2
dist/core-login.js
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
dist/core-login.js.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 2
- 2
dist/core-main.js
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 1
- 1
dist/core-main.js.map
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 2
- 3
tests/acceptance/features/bootstrap/ContactsMenuContext.php Прегледај датотеку

@@ -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");
}


Loading…
Откажи
Сачувај