1import { validateEmail } from "../components/form.js"; 2import { init } from "../index.js"; 3import analytics from "../services/an/index.js"; 4import userPost from "../services/user-post.js"; 5let posts = []; 6let lastLoadedIndex = 0; 7let bottomContainer = document.querySelector("#news-posts-bottom"); 8let topContainer = document.querySelector("#news-posts-top"); 9let trendingContainer = document.querySelector(".news-trending-flex-posts"); 10 11const errorTypes = { 12 empty: "empty", 13 validation: "validation", 14}; 15 16window.onload = () => { 17 init(); 18 addEventsToLoadMoreButton(); 19 getPosts(); 20 addEventsToSubscribe(); 21 createPostsOnload(trendingContainer); 22}; 23 24const addAnalyticsClickEventToPost = (post, url) => { 25 post.addEventListener("click", () => { 26 analytics.sendAmplitudeAnalyticsEvent(analytics.events.newsClicked, { name: url }); 27 }); 28}; 29 30const createPostsOnload = (container) => { 31 const elements = container.querySelectorAll(".news-post-hidden"); 32 elements.forEach((hiddenPost) => { 33 container.removeChild(hiddenPost); 34 const component = createItem(hiddenPost); 35 container.appendChild(component); 36 }); 37}; 38 39const getPosts = () => { 40 const elements = topContainer.querySelectorAll(".news-post-hidden"); 41 elements.forEach((hiddenPost, index) => { 42 hiddenPost.id = index; 43 posts.push(hiddenPost); 44 topContainer.removeChild(hiddenPost); 45 }); 46 loadMore(12); 47}; 48 49const hideLoadMorebtn = () => { 50 const btn = document.querySelector("#load-more-posts"); 51 btn.style.display = "none"; 52}; 53 54const loadMore = (amount) => { 55 const elements = posts.slice(lastLoadedIndex, lastLoadedIndex + amount); 56 elements.forEach((element) => { 57 const component = createItem(element); 58 if (element.id <= 5) { 59 topContainer.appendChild(component); 60 } else { 61 bottomContainer.appendChild(component); 62 } 63 }); 64 lastLoadedIndex += amount; 65 if (lastLoadedIndex >= posts.length) { 66 hideLoadMorebtn(); 67 } 68}; 69 70 71const createItem = (element) => { 72 const props = JSON.parse(element.getAttribute("data-component")); 73 try { 74 const { date, image, url, body, logo } = props; 75 const post = document.createElement("li"); 76 post.classList.add("news-post"); 77 post.id = element.id; 78 79 const html = ` 80 <a href='${url}' class='news-post-link' target='_blank'> 81 <img src=${image} class='news-post-img' /> 82 <div class='news-post-content'> 83 <div class='news-post-content-flex'> 84 <div class='news-post-logo'> 85 <img src="${logo}" /> 86 </div> 87 <div class='news-post-date'> 88 ${date} 89 </div> 90 </div> 91 <div class='news-post-body'>${body}</div> 92 93 </div> 94 </a>`; 95 addAnalyticsClickEventToPost(post, url); 96 post.innerHTML = html; 97 return post; 98 } catch (error) { 99 } 100}; 101 102const addEventsToLoadMoreButton = () => { 103 const btn = document.querySelector("#load-more-posts"); 104 btn.addEventListener("click", loadMore.bind(null, 6)); 105}; 106 107const addEventsToSubscribe = () => { 108 const submitButton = document.querySelector(".news-subscribe-submit"); 109 const input = document.querySelector(".news-subscribe-input"); 110 input.addEventListener("focus", setError); 111 submitButton.addEventListener("click", validateAndSubmit); 112}; 113 114const validateAndSubmit = async () => { 115 const input = document.querySelector(".news-subscribe-input"); 116 const { value } = input; 117 if (!value) { 118 return setError(errorTypes.empty); 119 } 120 if (!validateEmail(value)) { 121 return setError(errorTypes.validation); 122 } 123 const body = { 124 fisrtName: "", 125 email: value, 126 }; 127 setSubscribeLoading(true); 128 await userPost.subscribe(body); 129 setSubscribeLoading(false); 130 input.value = ""; 131}; 132 133const setError = (type) => { 134 switch (type) { 135 case errorTypes.empty: 136 const emptyElement = document.querySelector(".news-subscribe-empty"); 137 emptyElement.style.display = "block"; 138 break; 139 case errorTypes.validation: 140 const validationElement = document.querySelector( 141 ".news-subscribe-invalid" 142 ); 143 validationElement.style.display = "block"; 144 break; 145 146 default: 147 const errors = document.querySelectorAll(".news-subscribe-error");
148 errors.forEach((err) => { 149 err.style.display = "none"; 150 }); 151 break; 152 } 153}; 154 155const setSubscribeLoading = (loading) => { 156 const submitButton = document.querySelector(".news-subscribe-submit"); 157 const loader = document.querySelector(".news-subscribe-submit .loader"); 158 loader.style.display = loading ? "block" : "none"; 159 submitButton.style.color = loading ? "transparent" : ""; 160};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.