feat: bind/unbind by id, video streaming proxy, unmute default, library refresh, hamburger click-outside
- Core API: bind/unbind accept id (integer PK) when face_id is null - Tauri proxy: stream video responses instead of buffering for seek bar - VideoPlayer: remove muted attribute, unmute by default - LibraryView: call invalidateFiles() before ensureFiles() on register/unregister - PeopleView: close sort panel on click-outside, not just hamburger toggle - bind_face: prefer face_id, fallback to id when face_id is null
This commit is contained in:
44
src/directives/vObserve.ts
Normal file
44
src/directives/vObserve.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Directive } from 'vue'
|
||||
|
||||
const vObserve: Directive<HTMLElement> = {
|
||||
mounted(el, binding) {
|
||||
if (typeof binding.value !== 'function') return
|
||||
|
||||
const callback = binding.value
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
if (!entries.length) return
|
||||
if (entries[0].isIntersecting) {
|
||||
callback()
|
||||
observer.disconnect()
|
||||
}
|
||||
},
|
||||
{ rootMargin: '200px 0px' }
|
||||
)
|
||||
|
||||
observer.observe(el)
|
||||
;(el as any)._io = observer
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const rect = el.getBoundingClientRect()
|
||||
if (
|
||||
rect.top < window.innerHeight + 200 &&
|
||||
rect.bottom > -200 &&
|
||||
rect.width > 0
|
||||
) {
|
||||
callback()
|
||||
observer.disconnect()
|
||||
;(el as any)._io = undefined
|
||||
}
|
||||
})
|
||||
},
|
||||
unmounted(el) {
|
||||
if ((el as any)._io) {
|
||||
;(el as any)._io.disconnect()
|
||||
;(el as any)._io = undefined
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default vObserve
|
||||
Reference in New Issue
Block a user