You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
6.4 KiB

4 years ago
const fflogsBase = "https://www.fflogs.com:443/v1/report/";
const fflogsFightsAPI = fflogsBase + "fights/"
const fflogsEventsAPI = fflogsBase + "events/"
4 years ago
const api = "?api_key=";
4 years ago
// ?end=1591130148287&sourceid=5
4 years ago
var indexViewModel;
4 years ago
var classColors = {
"Scholar": "#4c49b2",
"WhiteMage": "#c7bf8e",
"Astrologian": "#8c501e",
"Paladin": "#8aa8a8",
"Gunbreaker": "#6c6433",
"Warrior": "#610e0a",
"DarkKnight": "#241011",
"Ninja": "#b30000",
"Dragoon": "#3b4ba0",
"Monk": "#c58d1c",
"Samurai": "#9e6d35",
"RedMage": "#47132a",
"BlackMage": "#261947",
"Summoner": "#59922b",
"Dancer": "#ceb8ab",
"Machinist": "#6c6433",
"Barde": "#6d8432"
4 years ago
};
var trackedCooldowns = {
7436: {name: "Chain Stratagem", cooldown: 120000},
16536: {name: "Temperance", cooldown: 180000},
2258: {name: "Trick Attack", cooldown: 60000}
4 years ago
};
4 years ago
// Do stuff when HTML parsing is ready
$(() => {
ko.components.register('fight-timeline', {
viewModel: function(params) {
var self = this;
// Data: value is either null, 'like', or 'dislike'
this.fight = params.value.fight();
this.actors = params.value.actors;
console.log("fight-timeline: Got ",params.value);
// Behaviors
self.calculateDivStyle = function(timestamp, ability) {
var fight_length = self.fight.end_time - self.fight.start_time;
console.log("Fight was "+fight_length);
var cooldown = window.trackedCooldowns[ability.guid].cooldown;
console.log("Use was at "+timestamp+" and cd is "+cooldown);
var startpct = timestamp / fight_length * 100;
var widthpct = cooldown / fight_length * 100;
console.log("Cooldown started at "+startpct+"% and endured "+widthpct+"%");
var res = {color: "teal", "margin-left": startpct+"%", width:widthpct+"%"};
return res;
};
},
template:
'<div class="timeline-container" data-bind="foreach: actors">\
<!-- ko foreach: trackedEvents -->\
<span class="timeline-used" data-bind="style: $component.calculateDivStyle(timestamp, ability)"><span data-bind="text: ability.name"></span></span>\
<!-- /ko -->\
</div>'
});
4 years ago
// Document is ready
function IndexViewModel() {
var self = this;
self.apiKey = ko.observable(localStorage.getItem("apikey"));
4 years ago
self.logID = ko.observable(localStorage.getItem("fflogid"));
4 years ago
self.fights = ko.observableArray();
self.friendlies = ko.observableArray();
4 years ago
self.enemies = ko.observableArray();
self.trackedActors = ko.observableArray();
4 years ago
self.displayFightPicker = ko.observable(false);
self.selectedFight = ko.observable();
self.getLog = async function() {
var log = await fetchLog(self.logID());
self.fights(log["fights"]);
self.friendlies(log["friendlies"]);
4 years ago
self.enemies(log["enemies"]);
4 years ago
self.displayFightPicker(true);
};
self.formatFightTime = function(fight) {
return self.formatTime(fight.end_time - fight.start_time);
};
self.formatTime = function(time) {
let secs = time/1000;
4 years ago
let mins = Math.floor(secs / 60);
let rest = Math.floor(secs % 60);
return mins+"m"+rest+"s";
};
self.apiKeyChanged = function() {
console.log("Setting apiKey to ",self.apiKey());
localStorage.setItem("apikey",self.apiKey());
4 years ago
localStorage.setItem("fflogid", self.logID());
4 years ago
};
4 years ago
self.fightChanged = async function() {
console.log("Fight has changed to ",self.selectedFight());
var events = await fetchEvents(self.selectedFight());
var actors = await filterEvents(self.selectedFight(),events);
/*
for(var actor of actors) {
var updated = false;
for(var oldactor of self.trackedActors()) {
if(actor.id === oldactor.id) {
oldactor.trackedEvents(actor.trackedEvents());
oldactor.trackedEvents.valueHasMutated();
updated = true;
}
}
if(!updated) {
self.trackedActors.push(actor);
}
}*/
//FIXME: This is a hack, we should instead somehow update the trackedEvents observable so only this part is rerendered
self.trackedActors([]);
self.trackedActors(actors);
console.log("trackedActors: ",self.trackedActors());
4 years ago
};
4 years ago
self.textColor = function(job) {
return classColors[job.type];
4 years ago
};
self.actorIDToName = function(id) {
for(var actor of self.friendlies()) {
if(id == actor.id) {
return actor.name;
}
}
for(var actor of self.enemies()) {
if(id == actor.id) {
return actor.name;
}
}
return null;
};
self.getActorByID = function(id) {
for(var actor of self.friendlies()) {
if(id == actor.id) {
return actor;
}
}
for(var actor of self.enemies()) {
if(id == actor.id) {
return actor;
}
}
return null;
};
4 years ago
};
indexViewModel = new IndexViewModel();
ko.applyBindings(indexViewModel);
});
async function filterEvents(fight, events) {
var result = [];
for(var event of events) {
// Do we even care about this cast?
if(!(event.ability.guid in trackedCooldowns)) {
continue;
}
var found = false;
for(var actor of result) {
if(actor.id == event.sourceID) {
found = true;
break;
}
}
if(!found) {
console.log("Found new actor: "+event.sourceID);
var actor = indexViewModel.getActorByID(event.sourceID);
actor.trackedEvents = ko.observableArray();
result.push(actor);
}
event.timestamp = event.timestamp - fight.start_time;
actor.trackedEvents.push(event);
console.log(event);
}
console.log("Generated arrays: ",result);
return result;
}
async function fetchEvents(fight) {
4 years ago
let baseUrl = fflogsEventsAPI + "casts/" + indexViewModel.logID() + api + indexViewModel.apiKey() + "&translate=true" + "&end=" + fight.end_time;
let start_time = fight.start_time;
let result = [];
let snip = {};
do {
let url = baseUrl + "&start=" + start_time;
console.log("Requesting "+url);
snip = await fetchEventsSnippet(url);
4 years ago
for(var e of snip.events) {
result.push(e);
}
//result = result.concat(snip.events);
start_time = snip.nextPageTimestamp;
} while(snip.nextPageTimestamp)
return result;
}
async function fetchEventsSnippet(url) {
4 years ago
var res = await fetch(url);
if (!res.ok) {
console.log(res);
throw Error(res.text);
}
var events = await res.json();
4 years ago
console.log(events);
return events;
4 years ago
}
4 years ago
// API request um JSON zu erhalten
4 years ago
async function fetchLog(logId) {
let url = fflogsFightsAPI + logId + api + indexViewModel.apiKey();
4 years ago
4 years ago
console.log("Requesting "+logId);
4 years ago
var res = await fetch(url);
if (!res.ok) {
console.log(res);
throw Error(res.text);
}
var log = await res.json();
//get specific fight data
console.log(log);
return log;
4 years ago
}