diff options
author | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2019-03-27 10:37:45 +0100 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2019-03-27 10:44:40 +0100 |
commit | 201ed2ada952b5a587b33ecc4967f025fb2fe77a (patch) | |
tree | 1abd7b5191658fd88fa61414bf1aac6236d4c1cc /src | |
parent | 93a774aabcc507820c93e090db04c04841632446 (diff) |
Properly scroll to contact
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/ContactDetails.vue | 14 | ||||
-rw-r--r-- | src/components/ContactsList.vue | 61 |
2 files changed, 58 insertions, 17 deletions
diff --git a/src/components/ContactDetails.vue b/src/components/ContactDetails.vue index 38533a01..f8b1c1e5 100644 --- a/src/components/ContactDetails.vue +++ b/src/components/ContactDetails.vue @@ -403,7 +403,7 @@ export default { }, /** - * Select a contac, and update the localContact + * Select a contact, and update the localContact * Fetch updated data if necessary * Scroll to the selected contact if exists * @@ -455,18 +455,6 @@ export default { this.localContact = localContact this.loadingData = false } - - // scroll to selected contact if any - let list = document.getElementById('contacts-list') - let item = document.querySelector('#' + btoa(contact.key).slice(0, -2)) - if (item) { - let isAbove = list.scrollTop > item.offsetTop - let isUnder = item.offsetTop + item.offsetHeight > list.scrollTop + list.offsetHeight - // check if contact outside visible list area - if (isAbove || isUnder) { - list.scrollTo(0, item.offsetTop - item.offsetHeight / 2) - } - } } }, diff --git a/src/components/ContactsList.vue b/src/components/ContactsList.vue index 8a95d155..c7bfcb08 100644 --- a/src/components/ContactsList.vue +++ b/src/components/ContactsList.vue @@ -24,13 +24,16 @@ <!-- same uid can coexists between different addressbooks so we need to use the addressbook id as key as well --> <recycle-scroller - id="contacts-list" :class="{'icon-loading': loading, showdetails: selectedContact}" class="app-content-list" + id="contacts-list" + ref="scroller" + :class="{'icon-loading': loading, showdetails: selectedContact}" + class="app-content-list" :items="list" - :item-size="68" + :item-size="itemHeight" key-field="key"> <template v-slot="{ item, index }"> - <contacts-list-item :contact="contacts[item.key]" - :search-query="searchQuery" :index="index" :key="item.key" + <contacts-list-item :key="item.key" + :contact="contacts[item.key]" :search-query="searchQuery" :index="index" @deleted="selectContact" /> </template> </recycle-scroller> @@ -68,6 +71,12 @@ export default { } }, + data() { + return { + itemHeight: 68 + } + }, + computed: { selectedContact() { return this.$route.params.selectedContact @@ -77,6 +86,24 @@ export default { } }, + watch: { + selectedContact: function(key) { + this.$nextTick(() => { + this.scrollToContact(key) + }) + }, + list: function(val, old) { + // we just loaded the list and the url already have a selected contact + // if not, the selectedContact watcher will take over + // to select the first entry + if (val.length !== 0 && old.length === 0 && this.selectedContact) { + this.$nextTick(() => { + this.scrollToContact(this.selectedContact) + }) + } + } + }, + methods: { // Select closest contact on deletion selectContact(oldIndex) { @@ -87,6 +114,32 @@ export default { this.$router.push({ name: 'contact', params: { selectedGroup: this.selectedGroup, selectedContact: newContact.key } }) } } + }, + + /** + * Scroll to the desired contact if in the list and not visible + * + * @param {String} key the contact unique key + */ + scrollToContact(key) { + const item = this.$el.querySelector('#' + btoa(key).slice(0, -2)) + + // if the item is not visible in the list or barely visible + if (!(item && item.getBoundingClientRect().y > 50)) { // header height + const index = this.list.findIndex(contact => contact.key === key) + if (index > -1) { + this.$refs.scroller.scrollToItem(index) + } + } + + // if item is a bit out (bottom) of the list, let's just scroll a bit to the top + if (item) { + const pos = item.getBoundingClientRect().y + this.itemHeight - (this.$el.offsetHeight + 50) + if (pos > 0) { + const scroller = this.$refs.scroller.$el + scroller.scrollTop = scroller.scrollTop + pos + } + } } } } |