-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathapp.js
More file actions
105 lines (86 loc) · 2.64 KB
/
app.js
File metadata and controls
105 lines (86 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// We need to import the CSS so that webpack will load it.
// The MiniCssExtractPlugin is used to separate it out into
// its own CSS file.
import css from "../css/app.css"
// webpack automatically bundles all modules in your
// entry points. Those entry points can be configured
// in "webpack.config.js".
//
// Import dependencies
//
import "phoenix_html"
import { Socket } from 'phoenix'
import { LiveSocket } from "phoenix_live_view"
// Define hooks for LiveView
window.Hooks = {}
window.Hooks.InfiniteScroll = {
mounted() {
this.pending = false
this.observer = new IntersectionObserver((entries) => {
const target = entries[0]
if (target.isIntersecting && !this.pending) {
this.pending = true
this.pushEvent("load-more", {})
}
}, {
root: null,
rootMargin: '100px',
threshold: 0.1
})
this.observer.observe(this.el)
},
destroyed() {
if (this.observer) {
this.observer.disconnect()
}
},
updated() {
this.pending = false
// Check if we're still at the bottom after loading content
// Use requestAnimationFrame to ensure DOM has fully updated
requestAnimationFrame(() => {
const target = this.el
const rect = target.getBoundingClientRect()
const isIntersecting = rect.top <= (window.innerHeight || document.documentElement.clientHeight)
if (isIntersecting && !this.pending) {
this.pending = true
this.pushEvent("load-more", {})
}
})
}
}
let liveSocket = new LiveSocket("/live", Socket, { hooks: window.Hooks })
liveSocket.connect()
/*
Make it possible to click line numbers to update the address bar to a
link directly to that line.
*/
if (location.hash) {
document.getElementById(location.hash.replace('#', '')).classList.add('selected')
}
const lines = document.querySelectorAll('.ghd-line-number')
lines.forEach(line => {
line.addEventListener('click', e => {
const parent = line.parentNode
if (parent && parent.id) {
document.querySelectorAll('.ghd-line.selected').forEach(line => {
line.classList.remove('selected')
})
parent.classList.add('selected')
history.replaceState(null, null, '#' + parent.id)
}
})
})
const fileHeaders = document.querySelectorAll('.ghd-file-header')
fileHeaders.forEach(header => {
header.addEventListener('click', e => {
const parent = header.parentNode
parent.querySelectorAll('.ghd-diff').forEach(diff => {
diff.classList.toggle('hidden')
})
header.classList.toggle('collapsed') && scrollIfNeeded(header)
})
})
const scrollIfNeeded = elem => {
elem.getBoundingClientRect().top < 0 && elem.scrollIntoView(true)
}