Files
2025-10-06 16:17:29 -07:00

225 lines
8.4 KiB
JavaScript

/**
* Example FurryPlace Plugin - User State Demo
*
* This demonstrates how to use the FurryPlace SDK to access user state
* including droplets, charges, level, and more.
*
* To use this plugin, add it to your HTML:
* <script src="/plugins/example-user-state.js"></script>
*/
(function() {
'use strict';
// Set this to true to disable this example plugin (for reference only)
const EXAMPLE_DISABLED = true;
// Wait for SDK to be available
function waitForSDK(callback) {
if (window.FurryPlaceSDK) {
callback();
} else {
setTimeout(() => waitForSDK(callback), 100);
}
}
// Example 1: Button that shows user info (only visible when logged in)
function registerUserInfoButton() {
window.FurryPlaceSDK.registerButton({
id: 'user-info-display',
title: 'Show My Stats',
position: 'after-leaderboard',
icon: `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-5">
<path d="M480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-160v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q66 0 130 15.5T736-378q29 15 46.5 43.5T800-272v112H160Zm80-80h480v-32q0-11-5.5-20T700-306q-54-27-109-40.5T480-360q-56 0-111 13.5T260-306q-9 5-14.5 14t-5.5 20v32Zm240-320q33 0 56.5-23.5T560-640q0-33-23.5-56.5T480-720q-33 0-56.5 23.5T400-640q0 33 23.5 56.5T480-560Zm0-80Zm0 400Z"/>
</svg>
`,
onClick: async () => {
const user = await window.FurryPlaceSDK.getUser();
const charges = window.FurryPlaceSDK.getCharges();
const info = `
🎨 Player Stats
━━━━━━━━━━━━━━━━━━
👤 Name: ${user.name}
🏆 Level: ${user.level}
🎯 Pixels Painted: ${user.pixelsPainted}
💧 Droplets: ${user.droplets}
⚡ Paint Charges
━━━━━━━━━━━━━━━━━━
Current: ${charges.current}/${charges.max}
Percentage: ${charges.percentage.toFixed(1)}%
Can Paint: ${window.FurryPlaceSDK.hasChargesToPaint() ? 'Yes ✅' : 'No ❌'}
🏰 Alliance
━━━━━━━━━━━━━━━━━━
In Alliance: ${window.FurryPlaceSDK.isInAlliance() ? 'Yes' : 'No'}
${user.allianceId ? `Alliance ID: ${user.allianceId}\nRole: ${user.allianceRole}` : ''}
`.trim();
alert(info);
console.log('Full user data:', user);
},
condition: (context) => context.user?.isLoggedIn
});
}
// Example 2: Droplet counter button
function registerDropletCounter() {
window.FurryPlaceSDK.registerButton({
id: 'droplet-counter',
title: 'View Droplets',
position: 'before-leaderboard',
icon: `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-5">
<path d="M480-80q-137 0-228.5-94T160-408q0-100 79.5-217.5T480-880q161 137 240.5 254.5T800-408q0 140-91.5 234T480-80Zm0-80q104 0 172-70.5T720-408q0-73-60.5-165T480-774Q361-665 300.5-573T240-408q0 107 68 177.5T480-160Zm0-320Z"/>
</svg>
`,
onClick: () => {
const droplets = window.FurryPlaceSDK.getDroplets();
alert(`💧 You have ${droplets} droplets!`);
},
condition: (context) => context.user?.isLoggedIn
});
}
// Example 3: Charge status indicator
function registerChargeStatus() {
window.FurryPlaceSDK.registerButton({
id: 'charge-status',
title: 'Paint Charge Status',
position: 'bottom',
icon: `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-5">
<path d="M280-360q-100 0-170-70T40-600q0-100 70-170t170-70h400q100 0 170 70t70 170q0 100-70 170t-170 70H280Zm0-80h400q66 0 113-47t47-113q0-66-47-113t-113-47H280q-66 0-113 47t-47 113q0 66 47 113t113 47Zm400-40q42 0 71-29t29-71q0-42-29-71t-71-29q-42 0-71 29t-29 71q0 42 29 71t71 29ZM480-600Z"/>
</svg>
`,
onClick: () => {
const charges = window.FurryPlaceSDK.getCharges();
const canPaint = window.FurryPlaceSDK.hasChargesToPaint();
const statusMsg = `
⚡ Paint Charges Status
━━━━━━━━━━━━━━━━━━
Current: ${charges.current}/${charges.max}
Filled: ${charges.percentage.toFixed(1)}%
Cooldown: ${charges.cooldownMs}ms
Status: ${canPaint ? '✅ Ready to paint!' : '❌ Recharging...'}
`.trim();
alert(statusMsg);
},
condition: (context) => context.user?.isLoggedIn
});
}
// Example 4: Level display button
function registerLevelDisplay() {
window.FurryPlaceSDK.registerButton({
id: 'level-display',
title: 'View Level Progress',
position: 'top',
icon: `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-5">
<path d="m354-287 126-76 126 77-33-144 111-96-146-13-58-136-58 135-146 13 111 97-33 143ZM233-120l65-281L80-590l288-25 112-265 112 265 288 25-218 189 65 281-247-149-247 149Zm247-350Z"/>
</svg>
`,
onClick: () => {
const level = window.FurryPlaceSDK.getLevel();
const pixelsPainted = window.FurryPlaceSDK.getPixelsPainted();
// Calculate next level (based on formula: level = floor(sqrt(pixels/100)) + 1)
const nextLevel = level + 1;
const pixelsForNextLevel = Math.pow(nextLevel - 1, 2) * 100;
const pixelsNeeded = pixelsForNextLevel - pixelsPainted;
const progress = `
🏆 Level Progress
━━━━━━━━━━━━━━━━━━
Current Level: ${level}
Pixels Painted: ${pixelsPainted}
Next Level: ${nextLevel}
Pixels Needed: ${pixelsNeeded > 0 ? pixelsNeeded : 0}
`.trim();
alert(progress);
},
condition: (context) => context.user?.isLoggedIn
});
}
// Example 5: Login status toggle
function registerLoginStatus() {
window.FurryPlaceSDK.registerButton({
id: 'login-status',
title: 'Login Required',
position: 'bottom',
className: 'btn btn-square btn-warning shadow-md',
icon: `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-5">
<path d="M480-120v-80h280v-560H480v-80h280q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H480Zm-80-160-55-58 102-102H120v-80h327L345-622l55-58 200 200-200 200Z"/>
</svg>
`,
onClick: () => {
alert('Please log in to access FurryPlace features!');
},
condition: (context) => !context.user?.isLoggedIn
});
}
// Example 6: Refresh user data button
function registerRefreshButton() {
window.FurryPlaceSDK.registerButton({
id: 'refresh-user-data',
title: 'Refresh User Data',
position: 'after-leaderboard',
icon: `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-5">
<path d="M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z"/>
</svg>
`,
onClick: async () => {
const user = await window.FurryPlaceSDK.refreshUser();
if (user) {
alert(`✅ User data refreshed!\n\nDroplets: ${user.droplets}\nCharges: ${user.charges.count}/${user.charges.max}`);
}
},
condition: (context) => context.user?.isLoggedIn
});
}
// Initialize plugin
waitForSDK(() => {
if (EXAMPLE_DISABLED) {
console.log('[User State Plugin] Disabled - set EXAMPLE_DISABLED to false to enable');
return;
}
console.log('[User State Plugin] Initializing...');
// Register all example buttons
registerUserInfoButton();
registerDropletCounter();
registerChargeStatus();
registerLevelDisplay();
registerLoginStatus();
registerRefreshButton();
console.log('[User State Plugin] Loaded successfully!');
// Log initial user state
setTimeout(async () => {
const isLoggedIn = window.FurryPlaceSDK.isLoggedIn();
console.log('[User State Plugin] User logged in:', isLoggedIn);
if (isLoggedIn) {
console.log('[User State Plugin] Droplets:', window.FurryPlaceSDK.getDroplets());
console.log('[User State Plugin] Charges:', window.FurryPlaceSDK.getCharges());
console.log('[User State Plugin] Level:', window.FurryPlaceSDK.getLevel());
console.log('[User State Plugin] Can paint:', window.FurryPlaceSDK.hasChargesToPaint());
}
}, 1000);
});
})();