Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import com.softwaremagico.kt.core.converters.models.DuelConverterRequest;
import com.softwaremagico.kt.core.converters.models.FightConverterRequest;
import com.softwaremagico.kt.core.converters.models.TournamentConverterRequest;
import com.softwaremagico.kt.core.exceptions.FightNotFoundException;
import com.softwaremagico.kt.core.exceptions.ParticipantNotFoundException;
import com.softwaremagico.kt.core.exceptions.TournamentNotFoundException;
import com.softwaremagico.kt.core.exceptions.ValidateBadRequestException;
Expand Down Expand Up @@ -68,6 +67,7 @@ public class DuelController extends BasicInsertableController<Duel, DuelDTO, Due

private final Set<ShiaijoFinishedListener> shiaijoFinishedListeners = new HashSet<>();
private final Set<FightUpdatedListener> fightsUpdatedListeners = new HashSet<>();
private final Set<UntieUpdatedListener> untiesUpdatedListeners = new HashSet<>();

public interface ShiaijoFinishedListener {
void finished(TournamentDTO tournament, Integer shiaijo);
Expand All @@ -77,6 +77,10 @@ public interface FightUpdatedListener {
void finished(TournamentDTO tournament, FightDTO fight, DuelDTO duel, String actor, String session);
}

public interface UntieUpdatedListener {
void finished(TournamentDTO tournament, DuelDTO duel, String actor, String session);
}

@Autowired
public DuelController(DuelProvider provider,
DuelConverter converter,
Expand All @@ -100,6 +104,10 @@ public void addFightUpdatedListener(FightUpdatedListener listener) {
fightsUpdatedListeners.add(listener);
}

public void addUntieUpdatedListener(UntieUpdatedListener listener) {
untiesUpdatedListeners.add(listener);
}

@Override
protected DuelConverterRequest createConverterRequest(Duel entity) {
return new DuelConverterRequest(entity);
Expand Down Expand Up @@ -127,27 +135,34 @@ public DuelDTO update(DuelDTO duel, String username, String session) {
} finally {
new Thread(() -> {
//If a shiaijo has finished, send a message to all computers.
final Fight fight = fightProvider.findByDuels(reverse(duel)).orElseThrow(() ->
new FightNotFoundException(this.getClass(), "No fight found for duel '" + duel + "'"));
final Fight fight = fightProvider.findByDuels(reverse(duel)).orElse(null);

final FightDTO fightDTO = fightConverter.convert(new FightConverterRequest(fight));

final Tournament tournament = tournamentProvider.get(fight.getTournament().getId()).orElseThrow(()
final Tournament tournament = tournamentProvider.get(duel.getTournament().getId()).orElseThrow(()
-> new TournamentNotFoundException(this.getClass(), "No tournament found for duel '" + duel + "'."));

final TournamentDTO tournamentDTO = tournamentConverter.convert(new TournamentConverterRequest(tournament));

//Fight is updated, refresh screens.
fightsUpdatedListeners.forEach(fightUpdatedListener ->
fightUpdatedListener.finished(tournamentDTO, fightDTO, duel, username, session));

if (tournament.getShiaijos() > 1) {
final List<Fight> fightsOfShiaijo = fightProvider.findByTournamentAndShiaijo(tournament, fight.getShiaijo());
final long fightsNotOver = fightsOfShiaijo.stream().filter(fightOfShiaijo -> !fightOfShiaijo.isOver()).count();
if (fightsNotOver == 0) {
shiaijoFinishedListeners.forEach(shiaijoFinishedListener
-> shiaijoFinishedListener.finished(tournamentDTO, fight.getShiaijo()));
//Standard fight.
if (fight != null) {
final FightDTO fightDTO = fightConverter.convert(new FightConverterRequest(fight));

//Fight is updated, refresh screens.
fightsUpdatedListeners.forEach(fightUpdatedListener ->
fightUpdatedListener.finished(tournamentDTO, fightDTO, duel, username, session));

if (tournament.getShiaijos() > 1) {
final List<Fight> fightsOfShiaijo = fightProvider.findByTournamentAndShiaijo(tournament, fight.getShiaijo());
final long fightsNotOver = fightsOfShiaijo.stream().filter(fightOfShiaijo -> !fightOfShiaijo.isOver()).count();
if (fightsNotOver == 0) {
shiaijoFinishedListeners.forEach(shiaijoFinishedListener
-> shiaijoFinishedListener.finished(tournamentDTO, fight.getShiaijo()));
}
}
} else {
//It is an untie duel!
untiesUpdatedListeners.forEach(untieUpdatedListener ->
untieUpdatedListener.finished(tournamentDTO, duel, username, session));
}
}).start();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
import com.softwaremagico.kt.core.providers.DuelProvider;
import com.softwaremagico.kt.core.providers.FightProvider;
import com.softwaremagico.kt.core.providers.GroupProvider;
import com.softwaremagico.kt.core.providers.TournamentExtraPropertyProvider;
import com.softwaremagico.kt.core.providers.TournamentProvider;
import com.softwaremagico.kt.core.tournaments.TournamentHandlerSelector;
import com.softwaremagico.kt.logger.ExceptionType;
import com.softwaremagico.kt.persistence.entities.Group;
import com.softwaremagico.kt.persistence.entities.Tournament;
import com.softwaremagico.kt.persistence.repositories.GroupRepository;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -64,21 +64,24 @@ public class GroupController extends BasicInsertableController<Group, GroupDTO,
private final DuelConverter duelConverter;
private final TeamConverter teamConverter;
private final TournamentHandlerSelector tournamentHandlerSelector;
private final TournamentExtraPropertyProvider tournamentExtraPropertyProvider;

private final Set<UntieUpdatedListener> untiesUpdatedListeners = new HashSet<>();
private final Set<GroupsUpdatedListener> groupsUpdatedListeners = new HashSet<>();


public interface GroupsUpdatedListener {
void updated(TournamentDTO tournament, String actor, String session);
}

public interface UntieUpdatedListener {
void finished(TournamentDTO tournament, DuelDTO duel, String actor, String session);
}


@Autowired
public GroupController(GroupProvider provider, GroupConverter converter, TournamentConverter tournamentConverter,
TournamentProvider tournamentProvider, FightProvider fightProvider, FightConverter fightConverter,
DuelProvider duelProvider, DuelConverter duelConverter, TeamConverter teamConverter,
TournamentHandlerSelector tournamentHandlerSelector, TournamentExtraPropertyProvider tournamentExtraPropertyProvider) {
TournamentHandlerSelector tournamentHandlerSelector) {
super(provider, converter);
this.tournamentConverter = tournamentConverter;
this.tournamentProvider = tournamentProvider;
Expand All @@ -88,14 +91,17 @@ public GroupController(GroupProvider provider, GroupConverter converter, Tournam
this.duelConverter = duelConverter;
this.teamConverter = teamConverter;
this.tournamentHandlerSelector = tournamentHandlerSelector;
this.tournamentExtraPropertyProvider = tournamentExtraPropertyProvider;
}


public void addGroupUpdatedListeners(GroupsUpdatedListener listener) {
groupsUpdatedListeners.add(listener);
}

public void addUntieUpdatedListener(UntieUpdatedListener listener) {
untiesUpdatedListeners.add(listener);
}


@Override
protected GroupConverterRequest createConverterRequest(Group group) {
Expand Down Expand Up @@ -203,6 +209,9 @@ public GroupDTO update(GroupDTO groupDTO, String username, String session) {
groupsUpdatedListeners.forEach(groupsUpdatedListener ->
groupsUpdatedListener.updated(groupDTO.getTournament(), username, session))
).start();
if (!unties.isEmpty()) {
sendUntieChangeMessageThroughWebsocket(unties, username, session);
}
}
}

Expand Down Expand Up @@ -289,15 +298,32 @@ public GroupDTO setTeams(List<TeamDTO> teams, String username, String session) {
}


public GroupDTO addUnties(Integer groupId, List<DuelDTO> duelDTOS, String username) {
public GroupDTO addUnties(Integer groupId, List<DuelDTO> duelDTOS, String username, String session) {
final GroupDTO groupDTO = get(groupId);
duelDTOS.forEach(duelDTO -> {
duelDTO.setCreatedBy(username);
duelDTO.setTournament(groupDTO.getTournament());
});
groupDTO.getUnties().addAll(duelDTOS);
groupDTO.setUpdatedBy(username);
return convert(getProvider().save(reverse(groupDTO)));
try {
return convert(getProvider().save(reverse(groupDTO)));
} finally {
//Send update information to all devices.
sendUntieChangeMessageThroughWebsocket(duelDTOS, username, session);
}
}

private void sendUntieChangeMessageThroughWebsocket(List<DuelDTO> duelDTOS, String username, String session) {
new Thread(() -> {
for (DuelDTO duelDTO : duelDTOS) {
final Tournament tournament = tournamentProvider.get(duelDTO.getTournament().getId()).orElseThrow(()
-> new TournamentNotFoundException(this.getClass(), "No tournament found for duel '" + duelDTO + "'."));
final TournamentDTO tournamentDTO = tournamentConverter.convert(new TournamentConverterRequest(tournament));
untiesUpdatedListeners.forEach(untieUpdatedListener ->
untieUpdatedListener.finished(tournamentDTO, duelDTO, username, session));
}
}).start();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,10 @@ public GroupDTO updateTeam(@RequestBody List<TeamDTO> teamsDto,
@PutMapping(value = "/{groupId}/unties", produces = MediaType.APPLICATION_JSON_VALUE)
public GroupDTO addUnties(@Parameter(description = "Id of the group to update", required = true) @PathVariable("groupId") Integer groupId,
@RequestBody List<DuelDTO> duelDTOs,
@RequestHeader(value = AuthApi.SESSION_HEADER, required = false) String session,
Authentication authentication,
HttpServletRequest request) {
return getController().addUnties(groupId, duelDTOs, authentication.getName());
return getController().addUnties(groupId, duelDTOs, authentication.getName(), session);
}

@PreAuthorize("hasAnyAuthority(@securityService.viewerPrivilege, @securityService.editorPrivilege, @securityService.adminPrivilege)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.softwaremagico.kt.core.controller.models.DuelDTO;
import com.softwaremagico.kt.core.controller.models.ElementDTO;
import com.softwaremagico.kt.core.controller.models.FightDTO;
import com.softwaremagico.kt.core.controller.models.TournamentDTO;
import com.softwaremagico.kt.logger.WebsocketsLogger;
import com.softwaremagico.kt.persistence.entities.Duel;
import com.softwaremagico.kt.persistence.entities.Fight;
import com.softwaremagico.kt.persistence.entities.Group;
import com.softwaremagico.kt.websockets.models.MessageContent;
Expand All @@ -45,6 +47,7 @@
public class WebSocketController {

public static final String FIGHTS_MAPPING = "/fights";
public static final String UNTIES_MAPPING = "/unties";
public static final String GROUPS_MAPPING = "/groups";
public static final String CREATING_MAPPING = "/creates";
public static final String UPDATING_MAPPING = "/updates";
Expand Down Expand Up @@ -142,6 +145,21 @@ public void fightsCreated(@Payload List<FightDTO> fights, String actor, String s
}
}

/**
* Sends a duelDTO to {@value com.softwaremagico.kt.websockets.WebSocketConfiguration#SOCKET_SEND_PREFIX} + {@value #UNTIES_MAPPING}.
*
* @param duelDTO the duelDTO to send.
*/
public void untieUpdated(@Payload DuelDTO duelDTO, String actor, String session) {
try {
WebsocketsLogger.debug(this.getClass(), "Sending duelDTO '{}'.", duelDTO);
this.messagingTemplate.convertAndSend(WebSocketConfiguration.SOCKET_SEND_PREFIX + UNTIES_MAPPING,
new MessageContent(Duel.class.getSimpleName(), toJson(duelDTO), MessageContentType.UPDATED, actor, session));
} catch (Exception e) {
WebsocketsLogger.errorMessage(this.getClass(), e);
}
}

/**
* Advise that the groups of a tournament has been updated {@value com.softwaremagico.kt.websockets.WebSocketConfiguration#SOCKET_SEND_PREFIX}
* + {@value #GROUPS_MAPPING}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public WebsocketFights(DuelController duelController, FightController fightContr
//Refresh screens when a duel is updated.
duelController.addFightUpdatedListener(((tournament, fight, duel, actor, session) ->
webSocketController.fightUpdated(fight, actor, session)));
duelController.addUntieUpdatedListener(((tournament, duel, actor, session) ->
webSocketController.untieUpdated(duel, actor, session)));
fightController.addFightsAddedListeners((webSocketController::fightsCreated));

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public WebsocketGroups(GroupController groupController, WebSocketController webS

//Refresh screens when a group is updated.
groupController.addGroupUpdatedListeners(webSocketController::groupsUpdated);

groupController.addUntieUpdatedListener((tournament, duel, actor, session)
-> webSocketController.untieUpdated(duel, actor, session));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
(click)="selectDuel(duel)"
(keydown)="selectDuel(duel)"
[selected]="selected" [swapTeams]="swapTeams"
[projectMode]="projectMode"
class="duel"></duel>
</div>
<div [class.red-ribbon]="swapColors" [class.white-ribbon]="!swapColors" class="right-team ribbon-icon">
Expand Down
45 changes: 30 additions & 15 deletions frontend/src/app/components/untie-fight/untie-fight.component.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

.untie-container {
display: flex;
padding-bottom: 10px;
padding-bottom: 2vh
}

.untie {
border-width: 2px;
border-width: 2px 0 2px 0;
border-color: #011d4a;
border-style: solid;
padding: 5px;
Expand All @@ -20,35 +20,49 @@
transform: rotate(180deg);
text-align: center;
padding: 20px;
border-width: 2px;
border-color: white;
border-style: solid;
color: red;
background-color: #011d4a;
//background-color: var(--ribbon-background);
text-transform: uppercase;
border-width: 2px 2px 2px 0;
border-color: var(--fight-border-color);
line-height: 25px;
max-width: 56px;
overflow: clip;
}

.right-team {
writing-mode: vertical-rl;
text-align: center;
padding: 20px;
border-width: 2px;
border-color: white;
border-style: solid;
color: white;
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
background-color: #011d4a;
//text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
//background-color: var(--ribbon-background);
text-transform: uppercase;
border-width: 2px 2px 2px 0;
border-color: var(--fight-border-color);
line-height: 25px;
max-width: 56px;
overflow: clip;
}

.red-ribbon {
color: red;
color: var(--ribbon-background);
//To be below the timer
z-index: -1;
background-color: var(--red-team-color);
border-width: 2px 0 2px 2px;
}

.ribbon-icon {
transform: rotate(0deg);
}

.white-ribbon {
color: white;
color: var(--ribbon-background);
//To be below the timer
z-index: -1;
background-color: var(--white-team-color);
border-width: 2px 2px 2px 0;
}

.duel {
Expand All @@ -73,7 +87,8 @@
border-width: 1px;
border-color: #777;
border-style: solid;
box-shadow: 0 5px 10px 0 rgba(0, 18, 57, 0.5);
box-shadow: 0 5px 10px 0 var(--shadow);
transition: transform .2s; /* Animation */
background: white;
//Transform causes problem with the timer component z-index.
//transform: scale(1.03);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export class UntieFightComponent extends KendoComponent implements OnInit {
@Input()
swapTeams: boolean;

@Input()
projectMode: boolean;

@Output() onSelectedDuel: EventEmitter<any> = new EventEmitter();

constructor(private duelChangedService: DuelChangedService) {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/models/tournament-score.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class TournamentScore extends Element {

constructor() {
super();
this.scoreType = ScoreType.INTERNATIONAL;
this.scoreType = ScoreType.EUROPEAN;
this.pointsByVictory = 1;
this.pointsByDraw = 0;
}
Expand Down
Loading
Loading