nodebb-plugin-niki-loyalty 1.0.7 → 1.0.8

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.
Files changed (2) hide show
  1. package/library.js +112 -62
  2. package/package.json +1 -1
package/library.js CHANGED
@@ -1,78 +1,128 @@
1
1
  'use strict';
2
2
 
3
- const db = require.main.require('./src/database');
4
- const user = require.main.require('./src/user');
3
+ $(document).ready(function () {
4
+ // --- AYARLAR ---
5
+ // 1. Logo Ayarı (Senin çalışan linkin)
6
+ const NIKI_LOGO_URL = "https://i.ibb.co/nZvtpss/logo-placeholder.png";
5
7
 
6
- const Plugin = {};
8
+ // Widget HTML Şablonu
9
+ const widgetHtml = `
10
+ <div id="niki-floating-widget" class="niki-hidden">
11
+ <div class="niki-widget-content" onclick="ajaxify.go('niki-wallet')">
12
+ <img src="${NIKI_LOGO_URL}" class="niki-widget-logo" alt="Niki">
13
+ <div class="niki-widget-text">
14
+ <span class="niki-lbl">PUANIM</span>
15
+ <span class="niki-val" id="niki-live-points">...</span>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ `;
7
20
 
8
- // --- AYARLAR ---
9
- const SETTINGS = {
10
- pointsPerHeartbeat: 5,
11
- dailyCap: 250
12
- };
21
+ // 1. Widget Başlatma ve Veri Yönetimi
22
+ function initNikiWidget() {
23
+ if (!app.user.uid || app.user.uid <= 0) return;
13
24
 
14
- Plugin.init = async function (params) {
15
- const router = params.router;
16
- const middleware = params.middleware;
17
-
18
- // 1. API: Kalp Atışı (Puan Kazanma - Client.js burayı kullanır)
19
- router.post('/api/niki-loyalty/heartbeat', middleware.ensureLoggedIn, async (req, res) => {
20
- const uid = req.uid;
21
- const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
22
- const dailyKey = `niki:daily:${uid}:${today}`;
23
-
24
- const currentDailyScore = await db.getObjectField(dailyKey, 'score') || 0;
25
+ // Widget yoksa ekle
26
+ if ($('#niki-floating-widget').length === 0) {
27
+ $('body').append(widgetHtml);
28
+ }
25
29
 
26
- if (parseInt(currentDailyScore) >= SETTINGS.dailyCap) {
27
- return res.json({ earned: false, reason: 'daily_cap' });
30
+ // --- HIZLI YÜKLEME (CACHE) ---
31
+ // Önce hafızadaki son puanı hemen göster (Bekletme yapmaz)
32
+ const cachedPoints = localStorage.getItem('niki_last_points');
33
+ if (cachedPoints !== null) {
34
+ $('#niki-live-points').text(cachedPoints);
35
+ $('#niki-floating-widget').removeClass('niki-hidden');
28
36
  }
29
37
 
30
- await user.incrementUserFieldBy(uid, 'niki_points', SETTINGS.pointsPerHeartbeat);
31
- await db.incrObjectFieldBy(dailyKey, 'score', SETTINGS.pointsPerHeartbeat);
38
+ // Logo Kontrolü (Garanti olsun)
39
+ fixLogo();
32
40
 
33
- const newBalance = await user.getUserField(uid, 'niki_points');
34
- return res.json({ earned: true, points: SETTINGS.pointsPerHeartbeat, total: newBalance });
35
- });
41
+ // --- GÜNCEL VERİ ÇEKME ---
42
+ // Arka planda sunucuya sor: "Puan değişti mi?"
43
+ $.get('/api/niki-loyalty/wallet-data', function(data) {
44
+ const freshPoints = data.points || 0;
45
+
46
+ // Puanı güncelle
47
+ $('#niki-live-points').text(freshPoints);
48
+ $('#niki-floating-widget').removeClass('niki-hidden'); // İlk kez açılıyorsa göster
49
+
50
+ // Yeni puanı hafızaya at (Bir sonraki giriş için)
51
+ localStorage.setItem('niki_last_points', freshPoints);
52
+
53
+ // Logoyu tekrar kontrol et (Resim geç yüklendiyse)
54
+ fixLogo();
55
+ }).fail(function() {
56
+ // Hata olursa ve cache yoksa 0 yaz
57
+ if (cachedPoints === null) {
58
+ $('#niki-live-points').text('0');
59
+ $('#niki-floating-widget').removeClass('niki-hidden');
60
+ }
61
+ });
62
+ }
36
63
 
37
- // 2. YENİ API: Cüzdan Verisi Çekme (Custom Page burayı kullanacak)
38
- router.get('/api/niki-loyalty/wallet-data', middleware.ensureLoggedIn, async (req, res) => {
39
- const uid = req.uid;
40
- const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
41
-
42
- const [userData, dailyData] = await Promise.all([
43
- user.getUserFields(uid, ['niki_points']),
44
- db.getObject(`niki:daily:${uid}:${today}`)
45
- ]);
64
+ // Logo Düzeltici (Senin çalışan kodun entegresi)
65
+ function fixLogo() {
66
+ const img = document.querySelector("img.niki-widget-logo");
67
+ if (img && img.src !== NIKI_LOGO_URL) {
68
+ img.src = NIKI_LOGO_URL;
69
+ }
70
+ }
46
71
 
47
- const currentPoints = parseInt(userData.niki_points) || 0;
48
- const dailyScore = parseInt(dailyData ? dailyData.score : 0) || 0;
49
- let dailyPercent = (dailyScore / SETTINGS.dailyCap) * 100;
50
- if (dailyPercent > 100) dailyPercent = 100;
72
+ // Başlat
73
+ initNikiWidget();
51
74
 
52
- res.json({
53
- points: currentPoints,
54
- dailyScore: dailyScore,
55
- dailyCap: SETTINGS.dailyCap,
56
- dailyPercent: dailyPercent
57
- });
75
+ // Sayfa Geçişlerinde Tekrar Çalıştır
76
+ $(window).on('action:ajaxify.end', function () {
77
+ initNikiWidget();
78
+ setTimeout(fixLogo, 500); // 0.5sn sonra son bir kontrol
58
79
  });
59
- };
60
80
 
61
- Plugin.addScripts = async function (scripts) {
62
- scripts.push('plugins/nodebb-plugin-niki-loyalty/static/lib/client.js');
63
- return scripts;
64
- };
81
+ // --- AKTİFLİK SİSTEMİ (Heartbeat) ---
82
+ let activeSeconds = 0;
83
+ let isUserActive = false;
84
+ let idleTimer;
85
+
86
+ function resetIdleTimer() {
87
+ isUserActive = true;
88
+ clearTimeout(idleTimer);
89
+ idleTimer = setTimeout(() => { isUserActive = false; }, 30000);
90
+ }
91
+ $(window).on('mousemove scroll keydown click touchstart', resetIdleTimer);
65
92
 
66
- // Menüye eklemeye devam edelim, Custom Page ile aynı linki vereceğiz
67
- Plugin.addNavigation = async function (nav) {
68
- nav.push({
69
- "route": "/niki-wallet",
70
- "title": "Niki Cüzdan",
71
- "enabled": true,
72
- "iconClass": "fa-coffee",
73
- "text": "Niki Cüzdan"
74
- });
75
- return nav;
76
- };
93
+ setInterval(() => {
94
+ if (ajaxify.data.template.topic && document.visibilityState === 'visible' && isUserActive) {
95
+ activeSeconds++;
96
+ }
97
+ if (activeSeconds >= 60) {
98
+ sendHeartbeat();
99
+ activeSeconds = 0;
100
+ }
101
+ }, 1000);
102
+
103
+ function sendHeartbeat() {
104
+ $.post('/api/niki-loyalty/heartbeat', { _csrf: config.csrf_token }, function(res) {
105
+ if (res.earned) {
106
+ // Puanı güncelle
107
+ $('#niki-live-points').text(res.total);
108
+ // Hafızayı da güncelle
109
+ localStorage.setItem('niki_last_points', res.total);
110
+
111
+ showNikiToast(`+${res.points} Puan Kazandın! ☕`);
112
+ $('#niki-floating-widget').addClass('niki-bounce');
113
+ setTimeout(() => $('#niki-floating-widget').removeClass('niki-bounce'), 500);
114
+ }
115
+ });
116
+ }
77
117
 
78
- module.exports = Plugin;
118
+ function showNikiToast(msg) {
119
+ $('.niki-toast').remove();
120
+ const toast = $(`<div class="niki-toast"><i class="fa fa-paw"></i> ${msg}</div>`);
121
+ $('body').append(toast);
122
+ setTimeout(() => { toast.addClass('show'); }, 100);
123
+ setTimeout(() => {
124
+ toast.removeClass('show');
125
+ setTimeout(() => toast.remove(), 3000);
126
+ }, 3000);
127
+ }
128
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-niki-loyalty",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Niki The Cat Coffee Loyalty System - Earn points while studying on IEU Forum.",
5
5
  "main": "library.js",
6
6
  "nbbpm": {