Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/Jennys-Drumste / leaderboard-social.js |
| Date | Not specified in source |
| Repository | Janady13/Jennys-Drumste |
| Revision | 01c36ac1a180916e11864b4573b8c1999e2c5db3 |
| Branch | claude/complete-integration-feature-011CUkTzyyk8bKmXaRXJAR61 |
| Path or archive member | leaderboard-social.js |
| Original SHA-256 | fe614123384b44de8ce38adcd181781d2f5152b6ef53feb32fb4371c371c8a4d |
| Git blob SHA | 5eb357dd00eba19288355fed2c9245062fe3ee62 |
| Reading-copy SHA-256 | fe614123384b44de8ce38adcd181781d2f5152b6ef53feb32fb4371c371c8a4d |
Recovered source transcript
Download complete source text ↓443 lines · 12.7 KB
/**
* LEADERBOARD & SOCIAL FEATURES
* Real-time competitive features and community engagement
*/
class LeaderboardSystem {
constructor(apiUrl = '/api') {
this.apiUrl = apiUrl;
this.currentUser = null;
this.leaderboard = [];
this.challenges = [];
this.friends = [];
this.updateInterval = 30000; // Update every 30 seconds
console.log('🏆 Leaderboard System initialized');
}
/**
* Set current user
*/
setUser(user) {
this.currentUser = user;
}
/**
* Get global leaderboard
*/
async getGlobalLeaderboard(category = 'overall', limit = 100) {
try {
const response = await fetch(`${this.apiUrl}/leaderboard?category=${category}&limit=${limit}`);
const data = await response.json();
this.leaderboard = data;
return data;
} catch (error) {
console.error('Failed to fetch leaderboard:', error);
return this.getMockLeaderboard();
}
}
/**
* Get user rank
*/
async getUserRank(userId) {
try {
const response = await fetch(`${this.apiUrl}/rank/${userId}`);
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch rank:', error);
return { rank: '-', percentile: 0 };
}
}
/**
* Submit score to leaderboard
*/
async submitScore(scoreData) {
const {
userId,
score,
accuracy,
combo,
level,
drumType,
sessionDuration
} = scoreData;
try {
const response = await fetch(`${this.apiUrl}/scores`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId,
score,
accuracy,
combo,
level,
drumType,
sessionDuration,
timestamp: Date.now()
})
});
const result = await response.json();
return result;
} catch (error) {
console.error('Failed to submit score:', error);
return { success: false };
}
}
/**
* Get daily challenges
*/
async getDailyChallenges() {
try {
const response = await fetch(`${this.apiUrl}/challenges/daily`);
const data = await response.json();
this.challenges = data;
return data;
} catch (error) {
console.error('Failed to fetch challenges:', error);
return this.getMockChallenges();
}
}
/**
* Complete a challenge
*/
async completeChallenge(challengeId, result) {
try {
const response = await fetch(`${this.apiUrl}/challenges/${challengeId}/complete`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: this.currentUser.id,
result,
timestamp: Date.now()
})
});
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to complete challenge:', error);
return { success: false };
}
}
/**
* Get friends leaderboard
*/
async getFriendsLeaderboard() {
try {
const response = await fetch(`${this.apiUrl}/leaderboard/friends/${this.currentUser.id}`);
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch friends leaderboard:', error);
return [];
}
}
/**
* Send friend request
*/
async sendFriendRequest(friendId) {
try {
const response = await fetch(`${this.apiUrl}/friends/request`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
fromUser: this.currentUser.id,
toUser: friendId
})
});
return await response.json();
} catch (error) {
console.error('Failed to send friend request:', error);
return { success: false };
}
}
/**
* Get achievements
*/
async getAchievements(userId) {
try {
const response = await fetch(`${this.apiUrl}/achievements/${userId}`);
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch achievements:', error);
return this.getMockAchievements();
}
}
/**
* Unlock achievement
*/
async unlockAchievement(achievementId) {
try {
const response = await fetch(`${this.apiUrl}/achievements/unlock`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: this.currentUser.id,
achievementId,
timestamp: Date.now()
})
});
return await response.json();
} catch (error) {
console.error('Failed to unlock achievement:', error);
return { success: false };
}
}
/**
* Create multiplayer session
*/
async createMultiplayerSession(config) {
try {
const response = await fetch(`${this.apiUrl}/multiplayer/create`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
hostId: this.currentUser.id,
mode: config.mode,
maxPlayers: config.maxPlayers,
songId: config.songId,
difficulty: config.difficulty
})
});
return await response.json();
} catch (error) {
console.error('Failed to create multiplayer session:', error);
return { success: false };
}
}
/**
* Join multiplayer session
*/
async joinMultiplayerSession(sessionId) {
try {
const response = await fetch(`${this.apiUrl}/multiplayer/${sessionId}/join`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: this.currentUser.id
})
});
return await response.json();
} catch (error) {
console.error('Failed to join multiplayer session:', error);
return { success: false };
}
}
/**
* Get weekly tournament
*/
async getWeeklyTournament() {
try {
const response = await fetch(`${this.apiUrl}/tournaments/weekly`);
return await response.json();
} catch (error) {
console.error('Failed to fetch tournament:', error);
return this.getMockTournament();
}
}
/**
* Share achievement to social media
*/
shareAchievement(achievement, platform = 'twitter') {
const text = `I just unlocked "${achievement.name}" in DrumMaster Pro! 🥁🔥`;
const hashtags = 'DrumMasterPro,DrumLearning,MusicEducation';
const url = 'https://drummasterpro.com';
let shareUrl;
switch (platform) {
case 'twitter':
shareUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&hashtags=${hashtags}&url=${url}`;
break;
case 'facebook':
shareUrl = `https://www.facebook.com/sharer/sharer.php?u=${url}"e=${encodeURIComponent(text)}`;
break;
case 'linkedin':
shareUrl = `https://www.linkedin.com/sharing/share-offsite/?url=${url}`;
break;
}
if (shareUrl) {
window.open(shareUrl, '_blank', 'width=600,height=400');
}
}
/**
* Get live stats comparison
*/
async getLiveComparison(friendId) {
try {
const response = await fetch(`${this.apiUrl}/compare/${this.currentUser.id}/${friendId}`);
return await response.json();
} catch (error) {
console.error('Failed to fetch comparison:', error);
return null;
}
}
// ========== MOCK DATA FOR TESTING ==========
getMockLeaderboard() {
return Array.from({ length: 100 }, (_, i) => ({
rank: i + 1,
userId: `user_${i}`,
username: `Drummer${i + 1}`,
score: 100000 - (i * 1000),
level: Math.floor(50 - (i * 0.5)),
accuracy: Math.floor(100 - (i * 0.3)),
country: ['US', 'UK', 'CA', 'AU', 'DE'][i % 5],
avatar: `https://i.pravatar.cc/50?img=${i + 1}`
}));
}
getMockChallenges() {
return [
{
id: 'daily_1',
name: 'Speed Demon',
description: 'Play 200 consecutive hits at 180 BPM',
reward: 1000,
difficulty: 'hard',
icon: '⚡',
timeRemaining: 12 * 60 * 60 * 1000, // 12 hours
progress: 0,
total: 200
},
{
id: 'daily_2',
name: 'Accuracy Master',
description: 'Achieve 95% accuracy in any song',
reward: 500,
difficulty: 'medium',
icon: '🎯',
timeRemaining: 12 * 60 * 60 * 1000,
progress: 87,
total: 95
},
{
id: 'daily_3',
name: 'Combo King',
description: 'Build a 100-hit combo',
reward: 750,
difficulty: 'medium',
icon: '🔥',
timeRemaining: 12 * 60 * 60 * 1000,
progress: 0,
total: 100
}
];
}
getMockAchievements() {
return [
{
id: 'first_hit',
name: 'First Steps',
description: 'Hit your first drum',
icon: '👶',
unlocked: true,
rarity: 'common'
},
{
id: 'hundred_hours',
name: '100 Hour Warrior',
description: 'Practice for 100 hours',
icon: '🏆',
unlocked: false,
progress: 25,
total: 100,
rarity: 'legendary'
},
{
id: 'perfect_song',
name: 'Perfectionist',
description: 'Complete a song with 100% accuracy',
icon: '💎',
unlocked: false,
rarity: 'epic'
},
{
id: 'all_drums',
name: 'Kit Master',
description: 'Master all drum pieces',
icon: '🥁',
unlocked: false,
progress: 5,
total: 8,
rarity: 'rare'
}
];
}
getMockTournament() {
return {
id: 'weekly_tournament_1',
name: 'Week 42 Championship',
startDate: Date.now() - (3 * 24 * 60 * 60 * 1000),
endDate: Date.now() + (4 * 24 * 60 * 60 * 1000),
prizePool: 10000,
participants: 1247,
top10: this.getMockLeaderboard().slice(0, 10),
userRank: 156,
requirements: {
minLevel: 5,
song: 'Seven Nation Army'
}
};
}
/**
* Format time remaining
*/
formatTimeRemaining(ms) {
const hours = Math.floor(ms / (60 * 60 * 1000));
const minutes = Math.floor((ms % (60 * 60 * 1000)) / (60 * 1000));
if (hours > 24) {
return `${Math.floor(hours / 24)}d ${hours % 24}h`;
} else if (hours > 0) {
return `${hours}h ${minutes}m`;
} else {
return `${minutes}m`;
}
}
/**
* Auto-update leaderboard
*/
startAutoUpdate() {
setInterval(() => {
this.getGlobalLeaderboard();
}, this.updateInterval);
}
stopAutoUpdate() {
clearInterval(this.updateInterval);
}
}
// Export
if (typeof module !== 'undefined' && module.exports) {
module.exports = LeaderboardSystem;
}