1document.addEventListener("DOMContentLoaded", function () { 2 Imageslazy(); 3 const token = getTokenCookie("Token"); 4 if (!token) { 5 localStorage.removeItem("savedItems"); 6 localStorage.removeItem("followedItems"); 7 } 8 else { 9 markSavedItems(); 10 markFollowedItems(); 11 } 12 initSaveItemButtons(); 13 initFollowButtons(); 14 registerFormSubmit(); 15 initListSaveButtons(); 16 GeneralFilterStructure(); 17 initSearchSuggestions(); 18 19 const mailGroupCards = document.getElementById("mailGroupCards"); 20 if (mailGroupCards) { 21 const observer = new MutationObserver((_, obs) => { 22 if (mailGroupCards.querySelector(".btn-follow-finance")) { 23 obs.disconnect(); 24 updateFinanceNewsletterStates(); 25 } 26 }); 27 observer.observe(mailGroupCards, { childList: true }); 28 } 29}); 30 31async function Imageslazy() { 32 const lazyImages = document.querySelectorAll("img.lazy"); 33 if ("IntersectionObserver" in window) { 34 const imageObserver = new IntersectionObserver((entries, observer) => { 35 entries.forEach(entry => { 36 if (entry.isIntersecting) { 37 const img = entry.target; 38 img.src = img.dataset.src; 39 img.classList.remove("lazy"); 40 observer.unobserve(img); 41 } 42 }); 43 }, { 44 rootMargin: "300px 0px", 45 threshold: 0.01 46 }); 47 lazyImages.forEach(img => { 48 imageObserver.observe(img); 49 }); 50 } else { 51 lazyImages.forEach(img => { 52 img.src = img.dataset.src; 53 img.classList.remove("lazy"); 54 }); 55 } 56} 57 58function initSaveItemButtons() { 59 const buttons = document.querySelectorAll(".cardSave, .new-save, .lssSave, .authorSave, .npSave, .otc-save, .save"); 60 61 buttons.forEach(btn => { 62 btn.addEventListener("click", async function () { 63 const itemId = parseInt(btn.dataset.saveId, 10); 64 const type = parseInt(btn.dataset.saveType, 10) || (btn.classList.contains("authorSave") ? 2 : 1); 65 const isActive = btn.classList.contains("active"); 66 if (Number.isNaN(itemId)) return; 67 68 try { 69 const url = isActive ? "/followSave/DeleteItem" : "/followSave/SaveItem"; 70 const response = await fetch(url, { 71 method: "POST", 72 headers: { "Content-Type": "application/json" }, 73 body: JSON.stringify({ itemId, type }) 74 }); 75 76 if (!(response.status >= 200 && response.status < 300)) { 77 window.location.href = "/register"; 78 return; 79 } 80 81 const result = await response.json(); 82 if (result?.success) { 83 btn.classList.toggle("active", !isActive); 84 85 if (btn.classList.contains("lssSave") || btn.classList.contains("save") || btn.classList.contains("otc-save") || btn.classList.contains("new-save")) { 86 btn.textContent = !isActive ? "Kaydedildi" : "Kaydet"; 87 } 88 89 // localStorage'den oku 90 let savedItems = getLocal("savedItems") || []; 91 const key = `${type}:${itemId}`; 92 93 if (!isActive) { 94 const exists = savedItems.some(x => `${x.type}:${x.id}` === key); 95 if (!exists) savedItems.push({ id: itemId, type }); 96 } else { 97 savedItems = savedItems.filter(x => `${x.type}:${x.id}` !== key); 98 } 99 100 // localStorage'ye geri yaz 101 setLocal("savedItems", savedItems); 102 } 103 } catch (err) { 104 window.location.href = "/register"; 105 } 106 }); 107 }); 108} 109 110 111async function markSavedItems() { 112 const saveButtons = Array.from(document.querySelectorAll(".cardSave, .new-save, .lssSave, .authorSave, .npSave, .otc-save, .save")); 113 if (!saveButtons.length) return; 114 115 let savedItems = getLocal("savedItems"); 116 117 if (!Array.isArray(savedItems) || !savedItems.length) { 118 try { 119 const response = await fetch("/followSave/GetSavedItems"); 120 if (response.status < 200 || response.status >= 300) return; 121 122 const result = await response.json(); 123 if (result?.success && Array.isArray(result?.savedItems)) { 124 savedItems = result.savedItems; 125 setLocal("savedItems", savedItems); 126 } else { 127 savedItems = []; 128 setLocal("savedItems", savedItems); 129 } 130 } catch (err) { 131 console.error("KaydedilmiŠöÄeler yüklenemedi:", err); 132 return; 133 } 134 } 135 136 const savedKeySet = new Set(savedItems.map(x => `${x.type}:${x.id}`)); 137 138 for (const btn of saveButtons) { 139 const id = parseInt(btn.dataset.saveId, 10); 140 const type = parseInt(btn.dataset.saveType, 10) || (btn.classList.contains("authorSave") ? 2 : 1); 141 if (Number.isNaN(id)) continue; 142
143 const key = `${type}:${id}`; 144 const isSaved = savedKeySet.has(key); 145 btn.classList.toggle("active", isSaved); 146 147 if (btn.classList.contains("lssSave") || btn.classList.contains("save") || btn.classList.contains("otc-save") || btn.classList.contains("new-save")) { 148 btn.textContent = isSaved ? "Kaydedildi" : "Kaydet"; 149 } 150 } 151} 152 153function initFollowButtons() { 154 const followButtons = document.querySelectorAll(".btn-follow[data-follow-id][data-follow-type]:not(.js-follow-bound)"); 155 156 followButtons.forEach(btn => { 157 btn.classList.add("js-follow-bound"); 158 159 btn.addEventListener("click", async function () { 160 const itemId = parseInt(btn.dataset.followId, 10); 161 const type = parseInt(btn.dataset.followType, 10); 162 const arti = btn.querySelector(".arti"); 163 if (Number.isNaN(itemId) || Number.isNaN(type) || !arti) return; 164 const isActive = arti.classList.contains("active"); 165 166 try { 167 const url = isActive ? "/followSave/unfollow" : "/followSave/follow"; 168 const response = await fetch(url, { 169 method: "POST", 170 headers: { "Content-Type": "application/json" }, 171 body: JSON.stringify({ itemId, type }) 172 }); 173 174 if (!(response.status >= 200 && response.status < 300)) { 175 window.location.href = "/register"; 176 return; 177 } 178 179 const result = await response.json(); 180 if (result?.success) { 181 arti.classList.toggle("active", !isActive); 182 btn.innerHTML = ` 183 <span class="arti ${!isActive ? "active" : ""}"></span> 184 ${isActive ? "Takip Et" : "Takip Ediliyor"} 185 `; 186 187 let followedItems = getLocal("followedItems") || []; 188 const key = `${itemId}_${type}`; 189 if (!isActive) { 190 followedItems.push({ itemId, type }); 191 } else { 192 followedItems = followedItems.filter(x => `${x.itemId}_${x.type}` !== key); 193 } 194 195 setLocal("followedItems", followedItems); 196 } 197 } catch (err) { 198 window.location.href = "/register"; 199 } 200 }); 201 }); 202} 203 204 205async function markFollowedItems() { 206 const followButtons = Array.from(document.querySelectorAll(".btn-follow[data-follow-id][data-follow-type]")); 207 if (!followButtons.length) return; 208 209 let followedItems; 210 211 try { 212 const response = await fetch("/followSave/GetFollowedItemsControl"); 213 if (response.status < 200 || response.status >= 300) return; 214 215 const result = await response.json(); 216 if (result?.success && Array.isArray(result?.items)) { 217 followedItems = result.items; 218 setLocal("followedItems", followedItems); 219 } else { 220 followedItems = []; 221 setLocal("followedItems", followedItems); 222 } 223 } catch (err) { 224 followedItems = getLocal("followedItems") || []; 225 } 226 227 const followedMap = new Set(followedItems.map(i => `${i.itemId}_${i.type}`)); 228 229 for (const btn of followButtons) { 230 const id = parseInt(btn.dataset.followId, 10); 231 const type = parseInt(btn.dataset.followType, 10); 232 if (Number.isNaN(id) || Number.isNaN(type)) continue; 233 234 const key = `${id}_${type}`; 235 const isFollowed = followedMap.has(key); 236 237 btn.innerHTML = ` 238 <span class="arti ${isFollowed ? "active" : ""}"></span> 239 ${isFollowed ? "Takip Ediliyor" : "Takip Et"} 240 `; 241 } 242} 243 244function initListSaveButtons() { 245 const saveButtons = document.querySelectorAll(".listSave"); 246 247 saveButtons.forEach(btn => { 248 btn.addEventListener("click", async function () { 249 const itemId = parseInt(btn.dataset.saveId, 10); 250 const type = parseInt(btn.dataset.saveType, 10); 251 const isActive = btn.classList.contains("active"); 252 253 try { 254 const url = isActive ? "/followSave/DeleteItem" : "/followSave/SaveItem"; 255 const response = await fetch(url, { 256 method: "POST", 257 headers: { "Content-Type": "application/json" }, 258 body: JSON.stringify({ itemId, type }) 259 }); 260 261 if (!(response.status >= 200 && response.status < 300)) { 262 window.location.href = "/register"; 263 return; 264 } 265 266 const result = await response.json(); 267 if (result?.success) { 268 if (isActive) { 269 // Kayıttan çıkar â kartı kaldır 270 const card = btn.closest(".mysave-card"); 271 if (card) card.remove(); 272 } else { 273 // KaydedilmemiÅse tekrar kaydet (nadiren gerekebilir) 274 btn.classList.add("active"); 275 } 276 } 277 } catch (err) { 278 window.location.href = "/register"; 279 } 280 }); 281 }); 282} 283 284function setLocal(name, value) { 285 try { 286 localStorage.setItem(name, JSON.stringify(value)); 287 } catch (err) { 288 console.error("localStorage yazma hatası:", err); 289 } 290} 291 292function getLocal(name) { 293 try { 294 const val = localStorage.getItem(name); 295 return val ? JSON.parse(val) : null; 296 } catch { 297 return null; 298 } 299} 300 301function setCookie(name, value, days = 7) { 302 const expires = new Date(Date.now() + days * 864e5).toUTCString(); 303 document.cookie = name + "=" + encodeURIComponent(JSON.stringify(value)) + "; expires=" + expires + "; path=/"; 304} 305 306function getCookie(name) { 307 const value = document.cookie 308 .split("; ") 309 .find(row => row.startsWith(name + "=")) 310 ?.split("=")[1]; 311 312 if (!value) return null; 313 314 const decoded = decodeURIComponent(value); 315 316 try { 317 return JSON.parse(decoded); 318 } catch { 319 return decoded; 320 } 321} 322 323function getTokenCookie(name) { 324 return document.cookie.split("; ").reduce((r, v) => { 325 const parts = v.split("="); 326 return parts[0] === name ? decodeURIComponent(parts[1]) : r; 327 }, null); 328} 329 330function deleteCookie(name) { 331 document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; 332} 333 334 335async function registerFormSubmit() { 336 try { 337 const response = await fetch("/auth/isloggedin"); 338 const result = await response.json(); 339 340 const forms = document.querySelectorAll(".subscribe-form"); 341 if (!forms.length) return; 342 343 let savedItems = getCookie("savedItems") || []; 344 345 // EÄer cookie string olarak tutuluyorsa arrayâe çevirelim 346 if (typeof savedItems === "string") { 347 try { 348 savedItems = JSON.parse(savedItems); 349 } catch { 350 savedItems = []; 351 } 352 } 353 if (result.loggedIn) { 354 // Kullanıcı giriÅ yapmıŠgiriÅ yap yerine follow butonu koy
355 forms.forEach(form => { 356 const followId = "197919"; // Günün özeti 357 const followType = "3"; // tag 358 359 const followBtn = document.createElement("button"); 360 followBtn.type = "button"; 361 followBtn.className = "btn-follow"; 362 followBtn.dataset.followId = followId; 363 followBtn.dataset.followType = followType; 364 // CSS'leri JS üzerinden veriyorum yoksa yapıyı bozuyor 365 Object.assign(followBtn.style, { 366 display: "inline-block", 367 position: "relative", 368 marginLeft: "10px", 369 transform: "translateY(-2px)", 370 border: "1px solid #5e5e6f", 371 fontFamily: '"Roboto", sans-serif', 372 fontSize: ".75rem", 373 lineHeight: "100%", 374 fontWeight: "500", 375 padding: "3px 8px", 376 cursor: "pointer", 377 color: "#5e5e6f", 378 transition: "all .34s ease", 379 }); 380 381 // KaydedilmiŠmi kontrol 382 const isSaved = savedItems.some(item => item.followType == followType && item.id == followId); 383 384 if (isSaved) { 385 // Takip ediliyor durumu 386 followBtn.classList.add("active"); 387 followBtn.innerHTML = '<span class="arti active"></span> <span class="follow-text">Takip Ediliyor</span>'; 388 } else { 389 // Henüz takip edilmiyor 390 followBtn.innerHTML = '<span class="arti"></span> <span class="follow-text">Takip Et</span>'; 391 } 392 393 form.replaceWith(followBtn); 394 }); 395 396 // Takip butonlarını aktif et 397 initFollowButtons(); 398 markFollowedItems(); 399 } else { 400 // Kullanıcı giriŠyapmamıŠform normal 401 forms.forEach(form => { 402 form.addEventListener("submit", async function (e) { 403 e.preventDefault(); 404 const email = form.querySelector("input[type=email]").value; 405 406 try { 407 const response = await fetch("/auth/register", { 408 method: "POST", 409 headers: { "Content-Type": "application/json" }, 410 body: JSON.stringify(email) 411 }); 412 413 const result = await response.json(); 414 415 if (result.success && result.redirectUrl) { 416 window.location.href = result.redirectUrl; 417 } else if (result.message) { 418 alert(result.message); 419 } 420 } catch (err) { 421 console.error("Kayıt hatası:", err); 422 } 423 }); 424 }); 425 } 426 } catch (err) { 427 console.error("Auth kontrol hatası:", err); 428 } 429} 430 431window.dateFilterApplied = window.dateFilterApplied || false; 432window.dynamicFilters = window.dynamicFilters || {}; 433 434function GeneralFilterStructure() { 435 if (!window.dynamicFilters) window.dynamicFilters = {}; 436 437 const autoFilters = document.querySelectorAll(".auto-filter"); 438 autoFilters.forEach(el => { 439 const column = el.dataset.filterColumn; 440 const operator = el.dataset.filterOperator; 441 const value = el.dataset.filterValue; 442 const additionalValue = el.dataset.filterAdditionalValue || null; 443 444 if (column && operator && value !== undefined) { 445 addDynamicFilter(column, operator, value, additionalValue); 446 } 447 }); 448 const container = document.getElementById('filterInputs'); 449 if (!container) return; 450 451 const actionUrl = container.dataset.action || window.location.pathname; 452 453 const getValue = (name) => container.querySelector(`[name="${name}"]`)?.value || ""; 454 const setValue = (name, value) => { 455 const el = container.querySelector(`[name="${name}"]`); 456 if (el) el.value = value; 457 }; 458 459 460 async function submitFilter() { 461 const Start = parseInt(getValue("page")) || 0; 462 const Top = parseInt(getValue("top")) || 10; 463 const OrderBy = getValue("orderBy") || "-Id"; 464 const Filters = {};
465 Object.entries(window.dynamicFilters).forEach(([key, filter]) => { 466 Filters[key] = filter; 467 }); 468 469 // Arama filtresi 470 const searchInputEl = document.getElementById("searchQuery"); 471 const searchQuery = searchInputEl ? searchInputEl.value.trim() : ""; 472 const searchColumn = getValue("searchQueryColumn"); 473 if (searchQuery && searchColumn) { 474 Filters[searchColumn] = { 475 Operator: "Like", 476 Value: "%" + searchQuery + "%" 477 }; 478 } 479 480 // Tarih filtresi 481 const day = document.getElementById("day")?.value; 482 const month = document.getElementById("month")?.value; 483 const year = document.getElementById("year")?.value; 484 const dateColumn = getValue("datetimeFieldColumn"); 485 486 if (dateColumn && (day || month || year) && dateFilterApplied) { 487 const d = day || "01", m = month || "01", y = year || new Date().getFullYear(); 488 489 const startDate = `${y}-${m.padStart(2, "0")}-${d.padStart(2, "0")}T00:00:00`; 490 const endDate = `${y}-${m.padStart(2, "0")}-${d.padStart(2, "0")}T23:59:59`; 491 492 Filters[dateColumn] = { 493 Operator: "Between", 494 Value: startDate, 495 AdditionalValue: endDate 496 }; 497 498 dateFilterApplied = true; // Tarih filtresi uygulandı olarak iÅaretle 499 } 500 501 const body = {Start, Top, OrderBy,Filters}; 502 503 const form = document.createElement("form"); 504 form.method = "POST"; 505 form.action = actionUrl; 506 507 const response = await fetch(actionUrl, { 508 method: "POST", 509 headers: { 510 "Content-Type": "application/json" 511 }, 512 body: JSON.stringify(body) 513 }); 514 515 if (response.ok) { 516 const html = await response.text(); 517 let startDate = null; 518 const dateColumn = getValue("datetimeFieldColumn"); 519 if (dateColumn && Filters[dateColumn] && Filters[dateColumn].Value) { 520 startDate = new Date(Filters[dateColumn].Value); 521 } 522 // Kullanıcının search ve top deÄerlerini kaydet 523 const currentSearchQuery = searchInputEl ? searchInputEl.value : ""; 524 const currentTopValue = getValue("top") || "10"; 525 526 document.open(); 527 document.write(html); 528 document.close(); 529 setTimeout(() => { 530 if (startDate) { 531 const daySel = document.getElementById("day"); 532 const monthSel = document.getElementById("month"); 533 const yearSel = document.getElementById("year"); 534 535 if (daySel) daySel.value = String(startDate.getDate()); 536 if (monthSel) monthSel.value = String(startDate.getMonth() + 1); 537 if (yearSel) yearSel.value = startDate.getFullYear(); 538 } 539 const newSearchInputEl = document.getElementById("searchQuery"); 540 if (newSearchInputEl && currentSearchQuery !== "") { 541 newSearchInputEl.value = currentSearchQuery; 542 } 543 const topInputEl = document.querySelector('[name="top"]'); 544 if (topInputEl) { 545 topInputEl.value = currentTopValue; 546 } 547 548 }, 400); 549 } else { 550 console.error("Filtre gönderimi baÅarısız", response.status); 551 } 552 } 553 554 // Pagination ve page size 555 document.getElementById('paginationContainer')?.addEventListener('click', e => { 556 const btn = e.target.closest('button[data-page]'); 557 if (!btn) return; 558 setValue("page", btn.dataset.page); 559 setValue("top", btn.dataset.pagesize); 560 submitFilter(); 561 }); 562 563 document.querySelectorAll('.show-btn').forEach(btn => { 564 btn.addEventListener('click', () => { 565 setValue("page", 0); 566 setValue("top", btn.dataset.pagesize); 567 submitFilter(); 568 }); 569 }); 570 571 // Tarih seçimi deÄiÅtiÄinde 572 ["day", "month", "year"].forEach(id => { 573 document.getElementById(id)?.addEventListener("change", () => { 574 setValue("page", 0); 575 dateFilterApplied = true; // Tarih filtresi seçildi olarak iÅaretle 576 submitFilter(); 577 }); 578 }); 579 const searchInput = document.getElementById("searchQuery"); 580 if (searchInput) { 581 searchInput.addEventListener("keydown", e => { 582 if (e.key === "Enter") { 583 e.preventDefault(); 584 setValue("page", 0); // arama yapıldıÄında sayfa sıfırlansın 585 submitFilter(); 586 } 587 }); 588 } 589} 590 591 592function addDynamicFilter(column, operator, value, additionalValue = null) { 593 if (!column || !operator) return; 594 window.dynamicFilters[column] = { 595 Operator: operator, 596 Value: value 597 }; 598 if (additionalValue !== null) { 599 window.dynamicFilters[column].AdditionalValue = additionalValue; 600 } 601} 602 603 604function initSearchSuggestions() { 605 const MIN_LENGTH = 3; 606 const searchInput = document.getElementById('search'); 607 const suggestionsBox = document.getElementById('suggestions'); 608 const suggestionsList = suggestionsBox?.querySelector('.suggestions-list'); 609 const searchBtn = document.querySelector('.search-button'); 610 //const mostWantedLinks = suggestionsBox.querySelectorAll('.suggestions-most-wanted a'); 611 612 if (!searchInput || !suggestionsBox) return; 613 614 function showWarning(message) { 615 suggestionsList.innerHTML = `<div class="suggestion-warning">${message}</div>`; 616 suggestionsBox.classList.remove('hidden'); 617 } 618 619 async function doSearch(query) { 620 const q = query.trim(); 621 const len = q.length; 622 suggestionsList.innerHTML = ""; 623 624 if (len < MIN_LENGTH) { 625 const remaining = MIN_LENGTH - len; 626 showWarning(`Lütfen en az ${remaining} karakter giriniz.`); 627 return; 628 } 629 630 try { 631 const params = new URLSearchParams({ 632 keyword: query, 633 sort: "desc", 634 category: -1, 635 date: "", 636 sonDakikaQuery: "" 637 }); 638 const response = await fetch(`/get-articles?keyword=${encodeURIComponent(query)}`, { 639 method: "GET", 640 headers: { 641 "Accept": "application/json" 642 } 643 }); 644 645 646 if (!response.ok) { 647 throw new Error("Sunucudan geçerli bir yanıt alınamadı."); 648 } 649 650 const articles = await response.json(); 651 652 if (!articles || articles.length === 0) { 653 showWarning("AradıÄınız kriterlere uygun sonuç bulunamadı."); 654 return; 655 } 656
657 articles.forEach(item => { 658 const row = document.createElement("div"); 659 row.className = "suggestion-item"; 660 661 const link = document.createElement("a"); 662 link.href = item.url || `/article/${item.id}`; 663 link.textContent = item.title || "BaÅlıksız Makale"; 664 link.className = "suggestion-link"; 665 666 const date = document.createElement("span"); 667 date.className = "suggestion-date"; 668 date.textContent = item.publishDate 669 ? new Date(item.publishDate).toLocaleDateString("tr-TR") 670 : ""; 671 672 row.append(link, date); 673 674 row.addEventListener("click", () => { 675 searchInput.value = item.title; 676 suggestionsBox.classList.add("hidden"); 677 }); 678 679 suggestionsList.appendChild(row); 680 }); 681 682 suggestionsBox.classList.remove("hidden"); 683 684 } catch (error) { 685 console.error("Arama hatası:", error); 686 showWarning("Bir hata oluÅtu, lütfen tekrar deneyin."); 687 } 688 } 689 690 // Canlı arama 691 searchInput.addEventListener('input', () => { 692 doSearch(searchInput.value); 693 }); 694 695 // Arama butonu 696 searchBtn.addEventListener('click', e => { 697 e.preventDefault(); 698 goToSearchPage(); 699 }); 700 701 // Enter tuÅu 702 searchInput.addEventListener("keydown", e => { 703 if (e.key === "Enter") { 704 e.preventDefault(); 705 goToSearchPage(); 706 } 707 }); 708 function goToSearchPage() { 709 const query = searchInput.value.trim(); 710 if (query.length > 2) { 711 window.location.href = `/arama-sonuc?keyword=${encodeURIComponent(query)}`; 712 } 713 } 714 715 // DıŠtıklamada kapat 716 document.addEventListener('click', e => { 717 if (!e.target.closest('.search-container')) { 718 suggestionsBox.classList.add('hidden'); 719 } 720 }); 721} 722 723async function updateFinanceNewsletterStates() { 724 try { 725 const res = await fetch("/followSave/get-subscribed-newsletters"); 726 if (!res.ok) return; 727 const { subscriptions } = await res.json(); 728 const activeTypes = (subscriptions || []) 729 .filter(s => s.status === 1) 730 .map(s => s.mailType); 731 732 document.querySelectorAll(".btn-follow-finance").forEach(btn => { 733 const groupId = parseInt(btn.dataset.groupId); 734 const active = activeTypes.includes(groupId); 735 const arti = btn.querySelector(".arti"); 736 const textEl = btn.querySelector(".follow-text"); 737 738 btn.dataset.active = String(active); 739 if (arti) arti.classList.toggle("active", active); 740 if (textEl) textEl.textContent = active ? "Katıldınız" : "Katıl"; 741 }); 742 } catch (e) { 743 console.error(e); 744 } 745}
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.