Compare commits
No commits in common. "a871b520062c111ee55c2b1678d804957df7ca5e" and "3933954e0945a9191088d217fbee5e98528edea6" have entirely different histories.
a871b52006
...
3933954e09
@ -479,8 +479,7 @@ public class MembreService {
|
|||||||
return clubRepository.findById(input.getClub())
|
return clubRepository.findById(input.getClub())
|
||||||
.call(__ -> repository.count("email LIKE ?1", input.getEmail())
|
.call(__ -> repository.count("email LIKE ?1", input.getEmail())
|
||||||
.invoke(Unchecked.consumer(c -> {
|
.invoke(Unchecked.consumer(c -> {
|
||||||
if (c > 0 && input.getEmail() != null && !input.getEmail().isBlank())
|
if (c > 0) throw new DBadRequestException("Email déjà utilisé");
|
||||||
throw new DBadRequestException("Email déjà utilisé");
|
|
||||||
})))
|
})))
|
||||||
.chain(clubModel -> {
|
.chain(clubModel -> {
|
||||||
MembreModel model = getMembreModel(input, clubModel);
|
MembreModel model = getMembreModel(input, clubModel);
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||||||
import fr.titionfire.ffsaf.data.repository.CompetitionRepository;
|
import fr.titionfire.ffsaf.data.repository.CompetitionRepository;
|
||||||
import fr.titionfire.ffsaf.domain.service.CompetPermService;
|
import fr.titionfire.ffsaf.domain.service.CompetPermService;
|
||||||
import fr.titionfire.ffsaf.net2.MessageType;
|
import fr.titionfire.ffsaf.net2.MessageType;
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleCompetData;
|
|
||||||
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
||||||
import fr.titionfire.ffsaf.ws.data.WelcomeInfo;
|
import fr.titionfire.ffsaf.ws.data.WelcomeInfo;
|
||||||
import fr.titionfire.ffsaf.ws.recv.*;
|
import fr.titionfire.ffsaf.ws.recv.*;
|
||||||
@ -119,13 +118,10 @@ public class CompetitionWS {
|
|||||||
waitingResponse.put(connection, new HashMap<>());
|
waitingResponse.put(connection, new HashMap<>());
|
||||||
})
|
})
|
||||||
.map(cm -> {
|
.map(cm -> {
|
||||||
SimpleCompetData data = SimpleCompetData.fromModel(cm);
|
|
||||||
WelcomeInfo welcomeInfo = new WelcomeInfo();
|
WelcomeInfo welcomeInfo = new WelcomeInfo();
|
||||||
|
|
||||||
welcomeInfo.setName(cm.getName());
|
welcomeInfo.setName(cm.getName());
|
||||||
welcomeInfo.setPerm(connection.userData().get(UserData.TypedKey.forString("prem")));
|
welcomeInfo.setPerm(connection.userData().get(UserData.TypedKey.forString("prem")));
|
||||||
welcomeInfo.setShow_blason(data.isShow_blason());
|
|
||||||
welcomeInfo.setShow_flag(data.isShow_flag());
|
|
||||||
|
|
||||||
return new MessageOut(UUID.randomUUID(), "welcomeInfo", MessageType.NOTIFY, welcomeInfo);
|
return new MessageOut(UUID.randomUUID(), "welcomeInfo", MessageType.NOTIFY, welcomeInfo);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -8,6 +8,4 @@ import lombok.Data;
|
|||||||
public class WelcomeInfo {
|
public class WelcomeInfo {
|
||||||
private String name;
|
private String name;
|
||||||
private String perm;
|
private String perm;
|
||||||
private boolean show_blason;
|
|
||||||
private boolean show_flag;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ function reducer(state, action) {
|
|||||||
country: action.payload.data.country,
|
country: action.payload.data.country,
|
||||||
})
|
})
|
||||||
if (state[comb.id] === undefined || !compareCombs(comb, state[comb.id])) {
|
if (state[comb.id] === undefined || !compareCombs(comb, state[comb.id])) {
|
||||||
//console.debug("Updating comb", comb);
|
console.debug("Updating comb", comb);
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
[comb.id]: comb
|
[comb.id]: comb
|
||||||
@ -49,7 +49,7 @@ function reducer(state, action) {
|
|||||||
for (const o of combs) {
|
for (const o of combs) {
|
||||||
newCombs[o.id] = o;
|
newCombs[o.id] = o;
|
||||||
}
|
}
|
||||||
//console.debug("Updating combs", newCombs);
|
console.debug("Updating combs", newCombs);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|||||||
@ -44,7 +44,6 @@ export function WSProvider({url, onmessage, children}) {
|
|||||||
const {is_authenticated} = useAuth()
|
const {is_authenticated} = useAuth()
|
||||||
const [isReady, setIsReady] = useState(false)
|
const [isReady, setIsReady] = useState(false)
|
||||||
const [doReconnect, setDoReconnect] = useState(false)
|
const [doReconnect, setDoReconnect] = useState(false)
|
||||||
const [welcomeData, setWelcomeData] = useState({name: "", perm: "", show_blason: true, show_flag: false})
|
|
||||||
const [state, dispatch] = useReducer(reducer, {listener: []})
|
const [state, dispatch] = useReducer(reducer, {listener: []})
|
||||||
const ws = useRef(null)
|
const ws = useRef(null)
|
||||||
const listenersRef = useRef([])
|
const listenersRef = useRef([])
|
||||||
@ -59,15 +58,6 @@ export function WSProvider({url, onmessage, children}) {
|
|||||||
listenersRef.current = state.listener
|
listenersRef.current = state.listener
|
||||||
}, [state.listener])
|
}, [state.listener])
|
||||||
|
|
||||||
const welcomeListener = ({data}) => {
|
|
||||||
setWelcomeData({
|
|
||||||
name: data.name,
|
|
||||||
perm: data.perm,
|
|
||||||
show_blason: data.show_blason,
|
|
||||||
show_flag: data.show_flag
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!doReconnect && !is_authenticated && isReady)
|
if (!doReconnect && !is_authenticated && isReady)
|
||||||
return;
|
return;
|
||||||
@ -132,12 +122,6 @@ export function WSProvider({url, onmessage, children}) {
|
|||||||
console.error("Listener callback error:", err)
|
console.error("Listener callback error:", err)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (msg.code === 'welcomeInfo') {
|
|
||||||
welcomeListener({...msg})
|
|
||||||
isHandled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isHandled && onmessage)
|
if (!isHandled && onmessage)
|
||||||
onmessage(JSON.parse(event.data))
|
onmessage(JSON.parse(event.data))
|
||||||
}
|
}
|
||||||
@ -186,7 +170,7 @@ export function WSProvider({url, onmessage, children}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log("WSProvider: sending message", {uuid, code, type, data});
|
console.log("WSProvider: sending message", {uuid, code, type, data});
|
||||||
ws.current?.send(JSON.stringify({
|
ws.current?.send(JSON.stringify({
|
||||||
uuid: uuid,
|
uuid: uuid,
|
||||||
code: code,
|
code: code,
|
||||||
@ -216,19 +200,18 @@ export function WSProvider({url, onmessage, children}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ret = {isReady, dispatch, send, wait_length: callbackRef, welcomeData}
|
const ret = {isReady, dispatch, send, wait_length: callbackRef}
|
||||||
return <WebsocketContext.Provider value={ret}>
|
return <WebsocketContext.Provider value={ret}>
|
||||||
{children}
|
{children}
|
||||||
</WebsocketContext.Provider>
|
</WebsocketContext.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useWS() {
|
export function useWS() {
|
||||||
const {isReady, dispatch, send, wait_length, welcomeData} = useContext(WebsocketContext)
|
const {isReady, dispatch, send, wait_length} = useContext(WebsocketContext)
|
||||||
return {
|
return {
|
||||||
dispatch,
|
dispatch,
|
||||||
isReady,
|
isReady,
|
||||||
wait_length,
|
wait_length,
|
||||||
welcomeData,
|
|
||||||
sendRequest: (code, data) => {
|
sendRequest: (code, data) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
send(uuidv4(), code, "REQUEST", data, resolve, reject);
|
send(uuidv4(), code, "REQUEST", data, resolve, reject);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, {useEffect, useRef, useState} from "react";
|
import React, {useEffect, useRef, useState} from "react";
|
||||||
import {useRequestWS, useWS} from "../../../hooks/useWS.jsx";
|
import {useRequestWS} from "../../../hooks/useWS.jsx";
|
||||||
import {useCombs, useCombsDispatch} from "../../../hooks/useComb.jsx";
|
import {useCombs, useCombsDispatch} from "../../../hooks/useComb.jsx";
|
||||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||||
import {createPortal} from "react-dom";
|
import {createPortal} from "react-dom";
|
||||||
@ -13,6 +13,7 @@ import {CategorieSelect} from "./CMTMatchPanel.jsx";
|
|||||||
import {PointPanel} from "./CMTPoint.jsx";
|
import {PointPanel} from "./CMTPoint.jsx";
|
||||||
import {importOBSConfiguration, OBSProvider, useOBS} from "../../../hooks/useOBS.jsx";
|
import {importOBSConfiguration, OBSProvider, useOBS} from "../../../hooks/useOBS.jsx";
|
||||||
import {SimpleIconsOBS} from "../../../assets/SimpleIconsOBS.ts";
|
import {SimpleIconsOBS} from "../../../assets/SimpleIconsOBS.ts";
|
||||||
|
import {timePrint} from "../../../utils/Tools.js";
|
||||||
import {toast} from "react-toastify";
|
import {toast} from "react-toastify";
|
||||||
|
|
||||||
export function CMTable() {
|
export function CMTable() {
|
||||||
@ -234,7 +235,6 @@ function ObsAutoSyncWhitPubAff() {
|
|||||||
const {connected, setText, setTextAndColor, setDiapo} = useOBS();
|
const {connected, setText, setTextAndColor, setDiapo} = useOBS();
|
||||||
const oldState = useRef({timeColor: "#000000", timeStr: "--:--", c1: null, c2: null, showScore: true, scoreRouge: 0, scoreBleu: 0});
|
const oldState = useRef({timeColor: "#000000", timeStr: "--:--", c1: null, c2: null, showScore: true, scoreRouge: 0, scoreBleu: 0});
|
||||||
const state = usePubAffState();
|
const state = usePubAffState();
|
||||||
const {welcomeData} = useWS();
|
|
||||||
const {getComb} = useCombs();
|
const {getComb} = useCombs();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -242,8 +242,8 @@ function ObsAutoSyncWhitPubAff() {
|
|||||||
const comb = getComb(state.c1);
|
const comb = getComb(state.c1);
|
||||||
setText("comb.rouge", comb ? (comb?.fname + " " + comb?.lname) : "");
|
setText("comb.rouge", comb ? (comb?.fname + " " + comb?.lname) : "");
|
||||||
const files = []
|
const files = []
|
||||||
if (comb?.club_uuid && welcomeData.show_blason) files.push(`club_${comb.club_uuid}.png`)
|
if (comb?.club_uuid) files.push(`club_${comb.club_uuid}.png`)
|
||||||
if (comb?.country && welcomeData.show_flag) files.push(`flag_${comb.country.toLowerCase()}.png`)
|
if (comb?.country) files.push(`flag_${comb.country.toLowerCase()}.png`)
|
||||||
setDiapo("img.rouge", files);
|
setDiapo("img.rouge", files);
|
||||||
oldState.current.c1 = state.c1;
|
oldState.current.c1 = state.c1;
|
||||||
}
|
}
|
||||||
@ -252,8 +252,8 @@ function ObsAutoSyncWhitPubAff() {
|
|||||||
const comb = getComb(state.c2);
|
const comb = getComb(state.c2);
|
||||||
setText("comb.blue", comb ? (comb?.fname + " " + comb?.lname) : "");
|
setText("comb.blue", comb ? (comb?.fname + " " + comb?.lname) : "");
|
||||||
const files = []
|
const files = []
|
||||||
if (comb?.club_uuid && welcomeData.show_blason) files.push(`club_${comb.club_uuid}.png`)
|
if (comb?.club_uuid) files.push(`club_${comb.club_uuid}.png`)
|
||||||
if (comb?.country && welcomeData.show_flag) files.push(`flag_${comb.country.toLowerCase()}.png`)
|
if (comb?.country) files.push(`flag_${comb.country.toLowerCase()}.png`)
|
||||||
setDiapo("img.blue", files);
|
setDiapo("img.blue", files);
|
||||||
oldState.current.c2 = state.c2;
|
oldState.current.c2 = state.c2;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,13 +38,7 @@ export function CategoryContent({cat, catId, setCat, menuActions}) {
|
|||||||
}, [groups]);
|
}, [groups]);
|
||||||
|
|
||||||
function readAndConvertMatch(matches, data, combsToAdd) {
|
function readAndConvertMatch(matches, data, combsToAdd) {
|
||||||
matches.push({
|
matches.push({...data, c1: data.c1?.id, c2: data.c2?.id})
|
||||||
...data,
|
|
||||||
c1: data.c1?.id,
|
|
||||||
c2: data.c2?.id,
|
|
||||||
c1_cacheName: data.c1?.fname + " " + data.c1?.lname,
|
|
||||||
c2_cacheName: data.c2?.fname + " " + data.c2?.lname
|
|
||||||
})
|
|
||||||
if (data.c1)
|
if (data.c1)
|
||||||
combsToAdd.push(data.c1)
|
combsToAdd.push(data.c1)
|
||||||
if (data.c2)
|
if (data.c2)
|
||||||
|
|||||||
@ -75,8 +75,9 @@ function HomeComp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function WSStatus({setPerm}) {
|
function WSStatus({setPerm}) {
|
||||||
|
const [name, setName] = useState("")
|
||||||
const [inWait, setInWait] = useState(false)
|
const [inWait, setInWait] = useState(false)
|
||||||
const {isReady, wait_length, welcomeData} = useWS();
|
const {isReady, wait_length, dispatch} = useWS();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
@ -86,11 +87,16 @@ function WSStatus({setPerm}) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPerm(welcomeData.perm)
|
const welcomeListener = ({data}) => {
|
||||||
}, [welcomeData])
|
setName(data.name)
|
||||||
|
setPerm(data.perm)
|
||||||
|
}
|
||||||
|
dispatch({type: 'addListener', payload: {callback: welcomeListener, code: 'welcomeInfo'}})
|
||||||
|
return () => dispatch({type: 'removeListener', payload: welcomeListener})
|
||||||
|
}, [])
|
||||||
|
|
||||||
return <div className="row" style={{marginRight: "inherit"}}>
|
return <div className="row" style={{marginRight: "inherit"}}>
|
||||||
<h2 className="col">{welcomeData.name}</h2>
|
<h2 className="col">{name}</h2>
|
||||||
<div className="col-auto" style={{margin: "auto 0", padding: 0}}>Serveur: <ColoredCircle
|
<div className="col-auto" style={{margin: "auto 0", padding: 0}}>Serveur: <ColoredCircle
|
||||||
color={isReady ? (inWait ? "#ffad32" : "#00c700") : "#e50000"}/>
|
color={isReady ? (inWait ? "#ffad32" : "#00c700") : "#e50000"}/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import {useCombs} from "../../../hooks/useComb.jsx";
|
|||||||
import {usePubAffState} from "../../../hooks/useExternalWindow.jsx";
|
import {usePubAffState} from "../../../hooks/useExternalWindow.jsx";
|
||||||
import {SmartLogoBackgroundMemo} from "../../../components/SmartLogoBackground.jsx";
|
import {SmartLogoBackgroundMemo} from "../../../components/SmartLogoBackground.jsx";
|
||||||
import {useMemo, useRef} from 'react';
|
import {useMemo, useRef} from 'react';
|
||||||
import {useWS} from "../../../hooks/useWS.jsx";
|
|
||||||
|
|
||||||
const vite_url = import.meta.env.VITE_URL;
|
const vite_url = import.meta.env.VITE_URL;
|
||||||
|
|
||||||
@ -125,7 +124,6 @@ const logoStyle = {width: "6vw", height: "min(11vh, 6vw)", objectFit: "contain",
|
|||||||
function CombDisplay({combId, background, children}) {
|
function CombDisplay({combId, background, children}) {
|
||||||
const {getComb} = useCombs();
|
const {getComb} = useCombs();
|
||||||
const comb = getComb(combId, "");
|
const comb = getComb(combId, "");
|
||||||
const {welcomeData} = useWS();
|
|
||||||
|
|
||||||
const logoAlt = useMemo(() => {
|
const logoAlt = useMemo(() => {
|
||||||
return comb?.club_str
|
return comb?.club_str
|
||||||
@ -144,11 +142,10 @@ function CombDisplay({combId, background, children}) {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
}}>
|
}}>
|
||||||
{comb !== "" && <>
|
{comb !== "" && <>
|
||||||
{welcomeData.show_blason && <SmartLogoBackgroundMemo src={logoSrc} alt={logoAlt} style={logoStyle}/>}
|
<SmartLogoBackgroundMemo src={logoSrc} alt={logoAlt} style={logoStyle}/>
|
||||||
<div style={{fontSize: "min(3.5vw, 6.5vh)"}}>{comb.fname} {comb.lname}</div>
|
<div style={{fontSize: "min(3.5vw, 6.5vh)"}}>{comb.fname} {comb.lname}</div>
|
||||||
{welcomeData.show_flag ? <img src={`/flags/svg/${comb.country.toLowerCase()}.svg`} alt={comb.country}
|
<img src={`/flags/svg/${comb.country.toLowerCase()}.svg`} alt={comb.country}
|
||||||
style={{width: "4vw", height: "8vh", objectFit: "contain", margin: "0 1.25vw"}}/>
|
style={{width: "4vw", height: "8vh", objectFit: "contain", margin: "0 1.25vw"}}/>
|
||||||
: <div style={{width: "4vw", height: "8vh", objectFit: "contain", margin: "0 1.25vw"}}></div>}
|
|
||||||
</>}
|
</>}
|
||||||
<div className="position-absolute top-0 start-0 w-100" style={{...noMP, height: "0.4vh", backgroundColor: "#646464AA"}}/>
|
<div className="position-absolute top-0 start-0 w-100" style={{...noMP, height: "0.4vh", backgroundColor: "#646464AA"}}/>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -243,7 +243,7 @@ export function SelectCombModalContent({data, setGroups}) {
|
|||||||
<div style={{textAlign: "center"}}>Inscrit</div>
|
<div style={{textAlign: "center"}}>Inscrit</div>
|
||||||
<div className="list-group overflow-y-auto" style={{maxHeight: "50vh"}}>
|
<div className="list-group overflow-y-auto" style={{maxHeight: "50vh"}}>
|
||||||
{dispoFiltered && Object.keys(dispoFiltered).length === 0 && <div>Aucun combattant disponible</div>}
|
{dispoFiltered && Object.keys(dispoFiltered).length === 0 && <div>Aucun combattant disponible</div>}
|
||||||
{Object.keys(dispoFiltered).sort((a, b) => nameCompare(data, a, b)).map((id) => (
|
{Object.keys(dispoFiltered).map((id) => (
|
||||||
<button key={id} type="button" className={"list-group-item list-group-item-action " + (dispoFiltered[id] ? "active" : "")}
|
<button key={id} type="button" className={"list-group-item list-group-item-action " + (dispoFiltered[id] ? "active" : "")}
|
||||||
onClick={() => dispoReducer({type: 'TOGGLE_ID', payload: id})}>
|
onClick={() => dispoReducer({type: 'TOGGLE_ID', payload: id})}>
|
||||||
<CombName combId={id}/>
|
<CombName combId={id}/>
|
||||||
@ -262,7 +262,7 @@ export function SelectCombModalContent({data, setGroups}) {
|
|||||||
<div style={{textAlign: "center"}}>Sélectionner</div>
|
<div style={{textAlign: "center"}}>Sélectionner</div>
|
||||||
<div className="list-group overflow-y-auto" style={{maxHeight: "50vh"}}>
|
<div className="list-group overflow-y-auto" style={{maxHeight: "50vh"}}>
|
||||||
{selectFiltered && Object.keys(selectFiltered).length === 0 && <div>Aucun combattant sélectionné</div>}
|
{selectFiltered && Object.keys(selectFiltered).length === 0 && <div>Aucun combattant sélectionné</div>}
|
||||||
{Object.keys(selectFiltered).sort((a, b) => nameCompare(data, a, b)).map((id) => (
|
{Object.keys(selectFiltered).map((id) => (
|
||||||
<button key={id} type="button"
|
<button key={id} type="button"
|
||||||
className={"list-group-item list-group-item-action " + (selectFiltered[id] ? "active" : "")}
|
className={"list-group-item list-group-item-action " + (selectFiltered[id] ? "active" : "")}
|
||||||
onClick={() => selectReducer({type: 'TOGGLE_ID', payload: id})}>
|
onClick={() => selectReducer({type: 'TOGGLE_ID', payload: id})}>
|
||||||
@ -285,9 +285,3 @@ export function SelectCombModalContent({data, setGroups}) {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
function nameCompare(data, a, b) {
|
|
||||||
const combA = data.find(d => d.id === Number(a));
|
|
||||||
const combB = data.find(d => d.id === Number(b));
|
|
||||||
return (combA.fname + " " + combA.lname).toLowerCase().localeCompare((combB.fname + " " + combB.lname).toLowerCase());
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user