mnswpr/services/leader-board.service.js
2019-12-08 16:36:29 +08:00

164 lines
6.6 KiB
JavaScript

import { DatabaseService } from "./db.service.js";
import { TimerService } from "./timer.service.js";
import { UserService } from "./user.service.js";
import { LoadingService } from "./loading/loading.js";
const dbService = new DatabaseService();
const timerService = new TimerService();
const loadingService = new LoadingService();
const db = dbService.store;
const user = new UserService();
let previousLevel;
export class LeaderBoardService {
constructor(leaders, all) {
this.leaders = db.collection(leaders);
this.all = db.collection(all);
}
updateTimeStampsLeaders() {
const levels = ['beginner', 'intermediate', 'expert'];
levels.forEach(level => {
const collection = this.leaders.doc(level).collection('games');
collection.get()
.then(res => {
const levelArray = res.docs.map(doc => ({id: doc.id, ...doc.data()}))
// console.log(level+": ", levelArray);
levelArray.forEach(leaderGame => {
// const leaderGame = levelArray[0];
const leaderTime = leaderGame.time;
const browser = leaderGame.browserId;
this.all.doc(browser).collection('games')
.get().then(games => {
const allGames = games.docs.map(doc => ({id: doc.id, games: {...doc.data()}}));
console.log(level + '...........' + browser);
allGames.forEach(day => {
const keys = Object.keys(day.games);
const winningKeys = keys.filter(key => day.games[key].status === 'win');
winningKeys.forEach(key => {
const game = day.games[key];
const dateString = [day.id, key].join(' ').replace(/_/g, ' ');
const newGame = {time_stamp: new Date(dateString), ...leaderGame};
if (game.time === leaderTime) {
console.log('updated', newGame);
// collection.doc(leaderGame.id).get().then(res => console.log(res.data()));
collection.doc(leaderGame.id).set(newGame);
}
})
});
});
})
});
})
}
update(level, displayElement, title) {
if (level !== previousLevel) {
loadingService.addLoading(displayElement);
previousLevel = level;
if (this.unsubscribe) {
this.unsubscribe();
}
this.lastPlace = Number.MAX_SAFE_INTEGER;
this.topList = this.leaders.doc(level)
.collection('games').orderBy('time').limit(10);
this.unsubscribe = this.setListener(this.topList, displayElement, title);
}
}
renderList(displayElement, title, docs) {
if (!displayElement) return;
displayElement.innerHTML = '';
const leaderHeading = document.createElement('h3');
leaderHeading.innerText = title;
leaderHeading.style.borderBottom = '1px solid #c0c0c0';
leaderHeading.style.paddingBottom = '10px';
displayElement.style.maxWidth = '270px';
displayElement.style.margin = '0 auto';
const leaderList = document.createElement('div');
leaderList.innerHTML = '';
leaderList.style.listStyle = 'none';
leaderList.style.textAlign = 'left';
leaderList.style.marginTop = '-15px';
if (docs && docs.length) {
let i = 1;
docs.forEach(game => {
if (game) {
const prettyTime = timerService.pretty(game.data().time);
const name = game.data().name || 'Anonymous';
const item = document.createElement('div');
item.style.display = 'flex';
const nameElement =document.createElement('div'); // `<span class="ellipsis" title="${name}">${name}</span>` ;
nameElement.innerHTML = name;
nameElement.setAttribute('title', name);
nameElement.style.textOverflow = 'ellipsis';
nameElement.style.whiteSpace = 'nowrap';
nameElement.style.overflow = 'hidden';
nameElement.style.padding = '0 5px';
nameElement.style.cursor = 'pointer';
nameElement.style.fontWeight = 'bold';
nameElement.style.fontStyle = 'italic';
const indexElement = document.createElement('div');
indexElement.innerText = `#${i++}`;
const timeElement = document.createElement('div');
timeElement.innerText = prettyTime;
item.append(indexElement, nameElement, timeElement);
leaderList.append(item);
}
})
if (docs.length >= 10) {
this.lastPlace = docs[9].data().time;
}
displayElement.append(leaderHeading, leaderList);
} else {
const message = document.createElement('em');
message.innerText = 'Be the first to the top!';
displayElement.append(leaderHeading, message);
}
}
setListener(collection, displayElement, title) {
return collection.onSnapshot(list => this.renderList(displayElement, title, list.docs));
}
send(game, key) {
const sessionId = new Date().toDateString().replace(/\s/g, '_');
const gameId = new Date().toTimeString().replace(/\s/g, '_');
const data = {};
game = {
time_stamp: new Date(),
...game
}
data[gameId] = game;
this.all.doc(user.browserId).collection('games').doc(sessionId).set(data, {merge: true});
if (game.status === 'win' && game[key] < this.lastPlace) {
let name = window.prompt('Top performance! Enter your name:');
if (!name) {
name = 'Anonymous';
}
const newGame = {
name,
browserId: user.browserId,
...game
}
this.leaders.doc(game.level).collection('games').add(newGame);
}
}
}