nodebb-plugin-niki-loyalty 1.2.6 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/library.js CHANGED
@@ -11,17 +11,17 @@ const Plugin = {};
11
11
  // ⚙️ AYARLAR & KURALLAR (GAME LOGIC)
12
12
  // =========================
13
13
  const SETTINGS = {
14
- dailyCap: 35, // Günlük Maksimum Puan
14
+ dailyCap: 35, // Günlük Maksimum Limit (Ne kadar kazanırsa kazansın buradan fazla alamaz)
15
15
  };
16
16
 
17
- // Puan Tablosu ve Limitleri
17
+ // Puan Tablosu ve Limitleri (Toplam Potansiyel ~45 Puan)
18
18
  const ACTIONS = {
19
- login: { points: 2, limit: 1, name: 'Günlük Giriş 👋' },
20
- new_topic: { points: 7, limit: 1, name: 'Yeni Konu 📝' },
21
- reply: { points: 3.5, limit: 2, name: 'Yorum Yazma 💬' },
22
- read: { points: 1, limit: 8, name: 'Konu Okuma 👀' }, // Heartbeat ile çalışır
23
- like_given: { points: 4, limit: 2, name: 'Beğeni Atma ❤️' }, // 4 puan x 2 = max 8
24
- like_taken: { points: 5, limit: 2, name: 'Beğeni Alma 🌟' } // 5 puan x 2 = max 10
19
+ login: { points: 5, limit: 1, name: 'Günlük Giriş 👋' }, // 5 Puan
20
+ new_topic: { points: 5, limit: 1, name: 'Yeni Konu 📝' }, // 5 Puan
21
+ reply: { points: 5, limit: 2, name: 'Yorum Yazma 💬' }, // 5 x 2 = 10 Puan
22
+ read: { points: 1, limit: 10, name: 'Konu Okuma 👀' }, // 1 x 10 = 10 Puan
23
+ like_given: { points: 2.5, limit: 2, name: 'Beğeni Atma ❤️' }, // 2.5 x 2 = 5 Puan
24
+ like_taken: { points: 5, limit: 2, name: 'Beğeni Alma 🌟' } // 5 x 2 = 10 Puan
25
25
  };
26
26
 
27
27
  // Ödüller
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-niki-loyalty",
3
- "version": "1.2.6",
3
+ "version": "1.2.7",
4
4
  "description": "Niki The Cat Coffee Loyalty System - Earn points while studying on IEU Forum.",
5
5
  "main": "library.js",
6
6
  "nbbpm": {
@@ -195,8 +195,9 @@ $(document).ready(function () {
195
195
 
196
196
  // 30 Saniyede bir tetikle (Günde 8 limit var backendde)
197
197
  heartbeatInterval = setInterval(function () {
198
- // Tarayıcı sekmesi aktif değilse gönderme (opsiyonel optimizasyon)
199
- if (document.hidden) return;
198
+ if (document.hidden) return; // Sekme aktif değilse sayma
199
+
200
+ console.log('[Niki-Loyalty] 10dk doldu. Puan isteniyor...');
200
201
 
201
202
  $.post('/api/niki-loyalty/heartbeat', {}, function (response) {
202
203
  if (response && response.earned) {
@@ -205,9 +206,13 @@ $(document).ready(function () {
205
206
  showNikiToast('Konu okuduğun için <strong style="color:#ffd700">+1 Puan</strong> kazandın! 🐈');
206
207
  }
207
208
  console.log('[Niki-Loyalty] Heartbeat başarılı. Yeni Puan:', response.total);
209
+ // Widget'ı hemen güncelle
210
+ updateSidebarWidget();
211
+ } else {
212
+ console.log('[Niki-Loyalty] Puan gelmedi (Günlük okuma limiti dolmuş olabilir).');
208
213
  }
209
214
  });
210
- }, 30000); // 30.000 ms = 30 Saniye
215
+ }, 600000); // 10 Dakika = 600.000 ms
211
216
  }
212
217
 
213
218
  // ============================================================
@@ -451,4 +456,105 @@ $(document).ready(function () {
451
456
  });
452
457
  });
453
458
  }
459
+ // -------------------------------------------------------------
460
+ // 📢 DUYURU SİSTEMİ (Marquee + Günlük Limit + Kapat Butonu)
461
+ // -------------------------------------------------------------
462
+ try {
463
+ const TARGET_CATEGORY_ID = 1; // Duyuruların çekileceği kategori ID
464
+ const MAX_DAILY_SHOW = 5; // Günde en fazla kaç kere gösterilecek
465
+
466
+ function checkAnnouncements() {
467
+ // Widget elementlerini bul veya oluştur
468
+ let $widget = $('.niki-marquee-widget');
469
+ if ($widget.length === 0) {
470
+ // Henüz yoksa oluştur (Başlangıçta gizli)
471
+ const widgetHtml = `
472
+ <div class="niki-marquee-widget" style="display:none;">
473
+ <div class="nm-content">
474
+ <div class="nm-icon">📢</div>
475
+ <div class="nm-text-container">
476
+ <span class="nm-text" id="niki-marquee-text">Duyuru Yükleniyor...</span>
477
+ </div>
478
+ <button class="nm-close" id="niki-marquee-close" title="Kapat">✖</button>
479
+ </div>
480
+ </div>
481
+ <style>
482
+ .niki-marquee-widget {
483
+ position: fixed; bottom: 85px; right: 20px; z-index: 9999;
484
+ background: #1a1a1a; border: 1px solid #C5A065; border-radius: 50px;
485
+ box-shadow: 0 5px 20px rgba(0,0,0,0.4); padding: 5px 15px;
486
+ width: 320px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
487
+ animation: slideInUp 0.5s ease-out;
488
+ }
489
+ .nm-content { display: flex; align-items: center; justify-content: space-between; height: 36px; }
490
+ .nm-icon { font-size: 18px; margin-right: 10px; animation: pulse 2s infinite; }
491
+ .nm-text-container { flex: 1; overflow: hidden; white-space: nowrap; position: relative; mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); }
492
+ .nm-text {
493
+ display: inline-block; color: #fff; font-size: 13px; font-weight: 500;
494
+ padding-left: 100%; animation: marquee 10s linear infinite;
495
+ }
496
+ .nm-close {
497
+ background: none; border: none; color: #888; cursor: pointer; font-size: 14px;
498
+ margin-left: 10px; padding: 0 5px; transition: 0.2s;
499
+ }
500
+ .nm-close:hover { color: #ff5252; transform: scale(1.1); }
501
+ @keyframes marquee { 0% { transform: translate(0, 0); } 100% { transform: translate(-100%, 0); } }
502
+ @keyframes slideInUp { from { transform: translateY(100px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
503
+ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } }
504
+ </style>
505
+ `;
506
+ $('body').append(widgetHtml);
507
+ $widget = $('.niki-marquee-widget');
508
+
509
+ // Kapatma butonu olayı
510
+ $('#niki-marquee-close').on('click', function () {
511
+ $widget.fadeOut();
512
+ sessionStorage.setItem('niki_session_closed', 'true'); // Bu oturumda bir daha açma
513
+ });
514
+ }
515
+
516
+ // Eğer bu oturumda kullanıcı kapattıysa gösterme
517
+ if (sessionStorage.getItem('niki_session_closed') === 'true') return;
518
+
519
+ // Günlük limit kontrolü
520
+ const today = new Date().toISOString().slice(0, 10);
521
+ const storageKey = 'niki_announce_count_' + today;
522
+ let count = parseInt(localStorage.getItem(storageKey) || '0');
523
+
524
+ if (count >= MAX_DAILY_SHOW) return; // Limit dolmuş
525
+
526
+ // API'den son konuyu çek
527
+ $.getJSON('/api/category/' + TARGET_CATEGORY_ID, function (data) {
528
+ if (data && data.topics && data.topics.length > 0) {
529
+ const topic = data.topics[0]; // En son konu
530
+ const lastTid = localStorage.getItem('niki_last_seen_tid');
531
+
532
+ // Yeni konu varsa veya henüz limit dolmadıysa göster
533
+ // (Kullanıcı "sürekli akmasını istiyorum" dediği için her sayfa yenilemede göstereceğiz, limite kadar)
534
+ const text = topic.title;
535
+ const url = config.relative_path + '/topic/' + topic.slug;
536
+
537
+ $('#niki-marquee-text').html(`<a href="${url}" style="color:#fff;text-decoration:none;">${text}</a>`);
538
+ $widget.fadeIn();
539
+
540
+ // Sayacı artır (Sadece görünür olduğunda)
541
+ if ($widget.is(':visible')) {
542
+ localStorage.setItem(storageKey, count + 1);
543
+ // Yeni konuyu gördü olarak işaretle
544
+ localStorage.setItem('niki_last_seen_tid', topic.tid);
545
+ }
546
+ }
547
+ });
548
+ }
549
+
550
+ // Başlat (Sayfa yüklendikten biraz sonra)
551
+ setTimeout(checkAnnouncements, 2000);
552
+
553
+ // Sayfa geçişlerinde de kontrol et
554
+ $(window).on('action:ajaxify.end', function () {
555
+ setTimeout(checkAnnouncements, 2000);
556
+ });
557
+
558
+ } catch (e) { console.warn("[Niki] Duyuru hatası:", e); }
559
+
454
560
  });
File without changes