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.
- package/library.js +112 -62
- package/package.json +1 -1
package/library.js
CHANGED
|
@@ -1,78 +1,128 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
31
|
-
|
|
38
|
+
// Logo Kontrolü (Garanti olsun)
|
|
39
|
+
fixLogo();
|
|
32
40
|
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
//
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
let dailyPercent = (dailyScore / SETTINGS.dailyCap) * 100;
|
|
50
|
-
if (dailyPercent > 100) dailyPercent = 100;
|
|
72
|
+
// Başlat
|
|
73
|
+
initNikiWidget();
|
|
51
74
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
});
|
|
75
|
-
|
|
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
|
-
|
|
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
|
+
});
|