Skip to content
Open
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
3 changes: 3 additions & 0 deletions core/modules/WebServer/webSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ export default class WebSocket {
socket.emit(room.eventName, room.initialData());
}

//Standalone events (not tied to a room)
socket.emit('banTemplatesUpdate', txConfig.banlist.templates);

//General events
socket.on('disconnect', (reason) => {
// console.verbose.debug('SocketIO', `Client disconnected with reason: ${reason}`);
Expand Down
3 changes: 3 additions & 0 deletions core/routes/banTemplates/saveBanTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export default async function SaveBanTemplates(ctx: AuthedCtx) {
});
}

//Pushing update to all connected clients
txCore.webServer.webSocket.pushEvent('banTemplatesUpdate', txConfig.banlist.templates);

//Sending output
return sendTypedResp({ success: true });
};
2 changes: 1 addition & 1 deletion core/routes/player/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export default async function PlayerModal(ctx: AuthedCtx) {
// console.dir(playerData);
return sendTypedResp({
serverTime: now(),
banTemplates: txConfig.banlist.templates, //TODO: move this to websocket push
banTemplates: txConfig.banlist.templates, //NOTE: kept for NUI compatibility, panel uses websocket push
player: playerData
});
};
6 changes: 3 additions & 3 deletions panel/src/components/BanForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { forwardRef, useImperativeHandle, useMemo, useRef, useState } from "reac
import { DropDownSelect, DropDownSelectContent, DropDownSelectItem, DropDownSelectTrigger } from "@/components/dropDownSelect";
import { banDurationToShortString, banDurationToString, cn } from "@/lib/utils";
import { Link, useLocation } from "wouter";
import type { BanTemplatesDataType } from "@shared/otherTypes";
import { useBanTemplates } from "@/hooks/banTemplates";

// Consts
const reasonTruncateLength = 150;
Expand All @@ -25,15 +25,15 @@ export type BanFormType = HTMLDivElement & {
getData: () => BanFormRespType;
}
type BanFormProps = {
banTemplates?: BanTemplatesDataType[]; //undefined = loading
disabled?: boolean;
onNavigateAway?: () => void;
};

/**
* A form to set ban reason and duration.
*/
export default forwardRef(function BanForm({ banTemplates, disabled, onNavigateAway }: BanFormProps, ref) {
export default forwardRef(function BanForm({ disabled, onNavigateAway }: BanFormProps, ref) {
const banTemplates = useBanTemplates();
const reasonRef = useRef<HTMLInputElement>(null);
const customMultiplierRef = useRef<HTMLInputElement>(null);
const setLocation = useLocation()[1];
Expand Down
20 changes: 20 additions & 0 deletions panel/src/hooks/banTemplates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { BanTemplatesDataType } from "@shared/otherTypes";
import { atom, useAtomValue, useSetAtom } from "jotai";


/**
* Atoms
*/
const banTemplatesAtom = atom<BanTemplatesDataType[] | undefined>(undefined);


/**
* Hooks
*/
export const useSetBanTemplates = () => {
return useSetAtom(banTemplatesAtom);
};

export const useBanTemplates = () => {
return useAtomValue(banTemplatesAtom);
};
6 changes: 6 additions & 0 deletions panel/src/layout/MainSocket.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useExpireAuthData, useSetAuthData } from '@/hooks/auth';
import { useSetGlobalStatus } from '@/hooks/status';
import { useProcessUpdateAvailableEvent, useSetOfflineWarning } from '@/hooks/useWarningBar';
import { useProcessPlayerlistEvents } from '@/hooks/playerlist';
import { useSetBanTemplates } from '@/hooks/banTemplates';
import { LogoutReasonHash } from '@/pages/auth/Login';


Expand All @@ -19,6 +20,7 @@ export default function MainSocket() {
const setGlobalStatus = useSetGlobalStatus();
const processPlayerlistEvents = useProcessPlayerlistEvents();
const processUpdateAvailableEvent = useProcessUpdateAvailableEvent();
const setBanTemplates = useSetBanTemplates();

//Runing on mount only
useEffect(() => {
Expand Down Expand Up @@ -67,11 +69,15 @@ export default function MainSocket() {
console.warn('Got updateAuthData from websocket', authData);
setAuthData(authData);
});
socket.on('banTemplatesUpdate', function (templates) {
setBanTemplates(templates);
});

return () => {
socket.removeAllListeners();
socket.disconnect();
setGlobalStatus(null);
setBanTemplates(undefined);
}
}, []);

Expand Down
5 changes: 1 addition & 4 deletions panel/src/layout/PlayerModal/PlayerBanTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ import { useRef, useState } from "react";
import { useBackendApi } from "@/hooks/fetch";
import { GenericApiOkResp } from "@shared/genericApiTypes";
import ModalCentralMessage from "@/components/ModalCentralMessage";
import type { BanTemplatesDataType } from "@shared/otherTypes";
import BanForm, { BanFormType } from "@/components/BanForm";
import { txToast } from "@/components/TxToaster";


type PlayerBanTabProps = {
banTemplates: BanTemplatesDataType[];
playerRef: PlayerModalRefType;
};

export default function PlayerBanTab({ playerRef, banTemplates }: PlayerBanTabProps) {
export default function PlayerBanTab({ playerRef }: PlayerBanTabProps) {
const banFormRef = useRef<BanFormType>(null);
const [isSaving, setIsSaving] = useState(false);
const { hasPerm } = useAdminPerms();
Expand Down Expand Up @@ -65,7 +63,6 @@ export default function PlayerBanTab({ playerRef, banTemplates }: PlayerBanTabPr
<div className="grid gap-4 p-1">
<BanForm
ref={banFormRef}
banTemplates={banTemplates}
disabled={isSaving}
onNavigateAway={() => { closeModal(); }}
/>
Expand Down
1 change: 0 additions & 1 deletion panel/src/layout/PlayerModal/PlayerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ export default function PlayerModal() {
refreshModalData={refreshModalData}
/>}
{selectedTab === 'Ban' && <PlayerBanTab
banTemplates={modalData.banTemplates}
playerRef={playerRef!}
/>}
</>
Expand Down
16 changes: 1 addition & 15 deletions panel/src/pages/AddLegacyBanPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import InlineCode from "@/components/InlineCode";
import { useAdminPerms } from "@/hooks/auth";
import { useRef, useState } from "react";
import { ApiAddLegacyBanReqSchema, GetBanTemplatesSuccessResp, SaveBanTemplatesReq } from "@shared/otherTypes";
import { ApiAddLegacyBanReqSchema } from "@shared/otherTypes";
import { useBackendApi } from "@/hooks/fetch";
import { Loader2Icon } from "lucide-react";
import { Button } from "@/components/ui/button";
Expand All @@ -10,7 +10,6 @@ import { Textarea } from "@/components/ui/textarea";
import BanForm, { BanFormType } from "@/components/BanForm";
import { txToast } from "@/components/TxToaster";
import { GenericApiOkResp } from "@shared/genericApiTypes";
import useSWR from "swr";


export default function AddLegacyBanPage() {
Expand All @@ -19,12 +18,6 @@ export default function AddLegacyBanPage() {
const [isSaving, setIsSaving] = useState(false);
const { hasPerm } = useAdminPerms();

const getBanTemplatesApi = useBackendApi<GetBanTemplatesSuccessResp>({
method: 'GET',
path: `/settings/banTemplates`,
throwGenericErrors: true,
});

const legacyBanApi = useBackendApi<GenericApiOkResp, ApiAddLegacyBanReqSchema>({
method: 'POST',
path: `/history/addLegacyBan`,
Expand Down Expand Up @@ -77,12 +70,6 @@ export default function AddLegacyBanPage() {
});
};

const swrBanTemplates = useSWR('/settings/banTemplates', async () => {
const data = await getBanTemplatesApi({});
if (!data) throw new Error('No data returned');
return data;
});

const canBan = hasPerm('players.ban');
return (
<div className="space-y-4 w-full max-w-screen-lg mx-auto px-2 md:px-0">
Expand Down Expand Up @@ -112,7 +99,6 @@ export default function AddLegacyBanPage() {
</div>
<BanForm
ref={banFormRef}
banTemplates={swrBanTemplates.data}
disabled={isSaving || !canBan}
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion shared/playerApiTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export type PlayerModalPlayerData = {

export type PlayerModalSuccess = {
serverTime: number; //required to calculate if bans have expired on frontend
banTemplates: BanTemplatesDataType[]; //TODO: move this to websocket push
banTemplates: BanTemplatesDataType[]; //NOTE: kept for NUI compatibility, panel uses websocket push
player: PlayerModalPlayerData;
}
export type PlayerModalResp = PlayerModalSuccess | GenericApiErrorResp;
Expand Down
5 changes: 3 additions & 2 deletions shared/socketioTypes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SvRtPerfThreadNamesType } from "@core/modules/Metrics/svRuntime/config";
import { SvRtNodeMemoryType, SvRtPerfBoundariesType } from "@core/modules/Metrics/svRuntime/perfSchemas";
import type { ReactAuthDataType } from "./authApiTypes";
import type { UpdateDataType } from "./otherTypes";
import type { BanTemplatesDataType, UpdateDataType } from "./otherTypes";
import { DiscordBotStatus, TxConfigState, type FxMonitorHealth } from "./enums";

/**
Expand Down Expand Up @@ -115,5 +115,6 @@ export type ListenEventsMap = {
dashboard: (data: DashboardDataEventType) => void;

//Standalone events
updateAvailable: (event: UpdateAvailableEventType) => void
updateAvailable: (event: UpdateAvailableEventType) => void;
banTemplatesUpdate: (templates: BanTemplatesDataType[]) => void;
};