1/* 2 * Copyright 2020, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17export default { 18 name: 'FocusedDataViewFinder', 19 created() { 20 document.addEventListener('scroll', this.updateFocusedView); 21 }, 22 deleted() { 23 document.removeEventListener('scroll', this.updateFocusedView); 24 }, 25 computed: { 26 timelineFiles() { 27 return this.$store.getters.timelineFiles; 28 }, 29 }, 30 methods: { 31 updateFocusedView() { 32 const positions = this.getDataViewPositions(); 33 const focusedFile = this.findFocusedDataView(positions); 34 35 this.$store.commit('setFocusedFile', focusedFile); 36 }, 37 getDataViewPositions() { 38 const positions = {}; 39 40 for (const file of this.files) { 41 const dataView = this.$refs[file.type]; 42 if (!dataView || dataView.length === 0) { 43 continue; 44 } 45 46 const dataViewEl = dataView[0].$el; 47 positions[file.type] = dataViewEl.getBoundingClientRect(); 48 } 49 50 return positions; 51 }, 52 /** 53 * Returns the file of the DataView that takes up the most of the visible 54 * screen space. 55 * @param {Object} positions A map from filenames to their respective 56 * boundingClientRect. 57 * @return {String} The dataView that is in focus. 58 */ 59 findFocusedDataView(positions) { 60 const visibleHeight = 61 Math.max(document.documentElement.clientHeight || 0, 62 window.innerHeight || 0); 63 64 let maxScreenSpace = 0; 65 let focusedDataView = this.files[0]; 66 for (const file of this.files) { 67 const pos = positions[file.type]; 68 if (!pos) { 69 continue; 70 } 71 72 let screenSpace = 0; 73 if (0 <= pos.top && pos.top <= visibleHeight) { 74 screenSpace = Math.min(visibleHeight, pos.bottom) - pos.top; 75 } else if (0 <= pos.bottom && pos.bottom <= visibleHeight) { 76 screenSpace = pos.bottom - Math.max(0, pos.top); 77 } else if (pos.top <= 0 && pos.bottom >= visibleHeight) { 78 screenSpace = visibleHeight; 79 } 80 81 if (screenSpace >= maxScreenSpace) { 82 maxScreenSpace = screenSpace; 83 focusedDataView = file; 84 } 85 } 86 87 return focusedDataView; 88 }, 89 }, 90}; 91