"Registered" icon to session accordion

- Merges "Recent logins" functionality to session accordion
This commit is contained in:
Rsl1122 2019-08-14 16:33:56 +03:00
parent df26710e47
commit d3b7ffe499
6 changed files with 20 additions and 136 deletions

View File

@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* DataContainer for information about a player's play session.
@ -41,6 +42,7 @@ public class Session extends DynamicDataContainer implements DateHolder {
private int mobKills;
private int deaths;
private long afkTime;
private boolean firstSession;
/**
* Creates a new session based on a join event.
@ -116,6 +118,7 @@ public class Session extends DynamicDataContainer implements DateHolder {
putSupplier(SessionKeys.MOB_KILL_COUNT, this::getMobKills);
putSupplier(SessionKeys.DEATH_COUNT, this::getDeaths);
putSupplier(SessionKeys.AFK_TIME, this::getAfkTime);
putSupplier(SessionKeys.FIRST_SESSION, this::isFirstSession);
putSupplier(SessionKeys.PLAYER_KILL_COUNT, () -> getUnsafe(SessionKeys.PLAYER_KILLS).size());
putSupplier(SessionKeys.LENGTH, () ->
@ -203,6 +206,16 @@ public class Session extends DynamicDataContainer implements DateHolder {
putRawData(SessionKeys.DB_ID, sessionID);
}
public void setAsFirstSessionIfMatches(Long registerDate) {
if (registerDate != null && Math.abs(sessionStart - registerDate) < TimeUnit.SECONDS.toMillis(5L)) {
this.firstSession = true;
}
}
public boolean isFirstSession() {
return firstSession;
}
public List<PlayerKill> getPlayerKills() {
return playerKills;
}

View File

@ -48,6 +48,7 @@ public class SessionKeys {
public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT;
public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT;
public static final Key<Integer> DEATH_COUNT = CommonKeys.DEATH_COUNT;
public static final Key<Boolean> FIRST_SESSION = new Key<>(Boolean.class, "first_session");
@Deprecated
public static final Key<List<PlayerDeath>> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS;

View File

@ -305,6 +305,7 @@ public class SessionsMutator {
return killMap;
}
).collect(Collectors.toList()));
sessionMap.put("first_session", session.getValue(SessionKeys.FIRST_SESSION).orElse(false));
WorldPie worldPie = graphs.pie().worldPie(session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()));
sessionMap.put("world_series", worldPie.getSlices());
sessionMap.put("gm_series", worldPie.toHighChartsDrillDownMaps());

View File

@ -54,6 +54,7 @@ public class SessionQueries {
"s." + SessionsTable.USER_UUID + ',' +
"s." + SessionsTable.SERVER_UUID + ',' +
"u." + UsersTable.USER_NAME + " as name," +
"u_info." + UsersTable.REGISTERED + " as registered," +
"server." + ServerTable.NAME + " as server_name," +
SessionsTable.SESSION_START + ',' +
SessionsTable.SESSION_END + ',' +
@ -72,6 +73,7 @@ public class SessionQueries {
FROM + SessionsTable.TABLE_NAME + " s" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=s." + SessionsTable.USER_UUID +
INNER_JOIN + ServerTable.TABLE_NAME + " server on server." + ServerTable.SERVER_UUID + "=s." + SessionsTable.SERVER_UUID +
LEFT_JOIN + UserInfoTable.TABLE_NAME + " u_info on u_info." + UserInfoTable.USER_UUID + "=s." + SessionsTable.USER_UUID + AND + "u_info." + UserInfoTable.SERVER_UUID + "=s." + SessionsTable.SERVER_UUID +
LEFT_JOIN + KillsTable.TABLE_NAME + " ON " + "s." + SessionsTable.ID + '=' + KillsTable.TABLE_NAME + '.' + KillsTable.SESSION_ID +
LEFT_JOIN + UsersTable.TABLE_NAME + " v on v." + UsersTable.USER_UUID + '=' + KillsTable.VICTIM_UUID +
INNER_JOIN + WorldTimesTable.TABLE_NAME + " ON s." + SessionsTable.ID + '=' + WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.SESSION_ID +
@ -248,6 +250,8 @@ public class SessionQueries {
session.putRawData(SessionKeys.NAME, set.getString("name"));
session.putRawData(SessionKeys.SERVER_NAME, set.getString("server_name"));
session.setAsFirstSessionIfMatches(set.getLong("registered"));
playerSessions.put(sessionStart, session);
serverSessions.put(playerUUID, playerSessions);
tempSessionMap.put(serverUUID, serverSessions);

View File

@ -1,133 +0,0 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.utilities.html.structure;
import com.djrapitops.plan.api.PlanAPI;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.store.containers.PlayerContainer;
import com.djrapitops.plan.data.store.keys.PlayerKeys;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.utilities.comparators.SessionStartComparator;
import com.djrapitops.plan.utilities.formatting.Formatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* Utility class for creating recent login list html.
* <p>
* This item can be seen on the Information tab on Server page.
*
* @author Rsl1122
*/
public class RecentLoginList {
private final List<PlayerContainer> players;
private final Formatter<Long> secondLongFormatter;
public RecentLoginList(List<PlayerContainer> players, Formatter<Long> secondLongFormatter) {
this.players = players;
this.secondLongFormatter = secondLongFormatter;
}
public String toHtml() {
List<RecentLogin> recentLogins = getMostRecentLogins();
if (recentLogins.isEmpty()) {
return "<li>No Recent Logins</li>";
}
StringBuilder html = new StringBuilder();
int i = 0;
for (RecentLogin recentLogin : recentLogins) {
if (i >= 20) {
break;
}
String name = recentLogin.name;
String url = PlanAPI.getInstance().getPlayerInspectPageLink(name);
boolean isNew = recentLogin.isNew;
String start = secondLongFormatter.apply(recentLogin.date);
html.append("<li><a class=\"col-").append(isNew ? "light-green" : "blue").append(" font-bold\" href=\"").append(url)
.append("\">").append(name).append("</a><span class=\"pull-right\">").append(start).append("</span></li>");
i++;
}
return html.toString();
}
private List<RecentLogin> getMostRecentLogins() {
List<RecentLogin> recentLogins = new ArrayList<>();
for (PlayerContainer player : players) {
if (!player.supports(PlayerKeys.NAME)
|| !player.supports(PlayerKeys.SESSIONS)) {
continue;
}
String name = player.getUnsafe(PlayerKeys.NAME);
long registerDate = player.getValue(PlayerKeys.REGISTERED).orElse(0L);
List<Session> sessions = player.getValue(PlayerKeys.SESSIONS).orElse(Collections.emptyList());
if (sessions.isEmpty()) {
continue;
}
sessions.sort(new SessionStartComparator());
Session session = sessions.get(0);
if (!session.supports(SessionKeys.START)) {
continue;
}
long mostRecentStart = session.getUnsafe(SessionKeys.START);
boolean isFirstSession = Math.abs(registerDate - mostRecentStart) < TimeUnit.SECONDS.toMillis(10L);
recentLogins.add(new RecentLogin(mostRecentStart, isFirstSession, name));
}
return recentLogins;
}
class RecentLogin {
final long date;
final boolean isNew;
final String name;
RecentLogin(long date, boolean isNew, String name) {
this.date = date;
this.isNew = isNew;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RecentLogin)) return false;
RecentLogin that = (RecentLogin) o;
return date == that.date &&
isNew == that.isNew &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(date, isNew, name);
}
}
}

View File

@ -66,15 +66,13 @@ function loadPlayerDeaths(json, error) {
function createAccordionTitle(i, session) {
return '<tr id="session_h_' + i + '" aria-controls="session_t_' + i + '" aria-expanded="false" class="clickable collapsed bg-teal" data-target="#session_t_' + i + '" data-toggle="collapse"><td>'
+ session.name + '</td>'
+ session.name + (session.first_session ? ' <i title="Registered (First session)" class="far fa-calendar-plus"></i>' : '') + '</td>'
+ '<td>' + session.start + '</td>'
+ '<td>' + session.length + '</td>'
+ '<td>' + session.most_used_world + '</td></tr>'
}
function createAccordionBody(i, session) {
return '<tr class="collapse" data-parent="#tableAccordion" id="session_t_' + i + '">' +
'<td colspan="4">' +
'<div class="collapse row" data-parent="#tableAccordion" id="session_t_' + i + '">' +