mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
better banning, new deter mute, replay discord fixes.
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
listUsers,
|
||||
removeSignal,
|
||||
setDeterrence,
|
||||
setMuted,
|
||||
setVerified,
|
||||
updateFeatureState,
|
||||
} from './identityDatabaseApi.js';
|
||||
@@ -30,6 +31,7 @@ const FILTERS = [
|
||||
{ key: 'all', label: 'All' },
|
||||
{ key: 'verified', label: 'Verified' },
|
||||
{ key: 'deterred', label: 'Deterred' },
|
||||
{ key: 'muted', label: 'Muted' },
|
||||
{ key: 'unverified', label: 'Unverified' },
|
||||
];
|
||||
|
||||
@@ -85,6 +87,7 @@ function UserListCard({ users, selectedUserId, query, filter, loading, onQuery,
|
||||
<span className="flex flex-col items-end gap-0.25">
|
||||
<StatusPill active={user.verified?.enabled}>verified</StatusPill>
|
||||
<StatusPill active={user.deterrence?.enabled}>deterred</StatusPill>
|
||||
<StatusPill active={user.deterrence?.muted}>muted</StatusPill>
|
||||
</span>
|
||||
</button>
|
||||
)) : (
|
||||
@@ -164,7 +167,7 @@ function SignalsCard({ user, onAddSignal, onRemoveSignal }) {
|
||||
);
|
||||
}
|
||||
|
||||
function StatusCard({ user, onVerified, onDeterrence }) {
|
||||
function StatusCard({ user, onVerified, onDeterrence, onMuted }) {
|
||||
const [reason, setReason] = useState(user?.deterrence?.reason || '');
|
||||
|
||||
useEffect(() => {
|
||||
@@ -206,6 +209,23 @@ function StatusCard({ user, onVerified, onDeterrence }) {
|
||||
<button type="button" className="button-dark text-xs" onClick={() => onDeterrence(Boolean(user?.deterrence?.enabled), reason)}>
|
||||
Save Reason
|
||||
</button>
|
||||
<div className="border-t border-slate-700/70 pt-0.5">
|
||||
<label className="flex items-center gap-0.5 text-slate-100">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="h-3.5 w-3.5 accent-amber-500"
|
||||
checked={Boolean(user?.deterrence?.muted)}
|
||||
onChange={(event) => onMuted(event.target.checked)}
|
||||
/>
|
||||
<span>Muted</span>
|
||||
</label>
|
||||
{/*
|
||||
Mute is intentionally presented inside deterrence status because
|
||||
it is a narrower moderation action, while its own timestamp makes
|
||||
it clear that toggling mute does not toggle full deterrence.
|
||||
*/}
|
||||
<p className="text-xs text-slate-500">Updated {formatDateTime(user?.deterrence?.mutedAt)}</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardFrame>
|
||||
);
|
||||
@@ -358,6 +378,8 @@ export default function IdentityDatabasePanel() {
|
||||
runMutation((userId) => setVerified(socket, userId, enabled), 'Verification updated.');
|
||||
const handleDeterrence = (enabled, reason) =>
|
||||
runMutation((userId) => setDeterrence(socket, userId, enabled, reason), 'Deterrence updated.');
|
||||
const handleMuted = (enabled) =>
|
||||
runMutation((userId) => setMuted(socket, userId, enabled), 'Mute updated.');
|
||||
const handleSaveFeature = (namespace, value) =>
|
||||
runMutation((userId) => updateFeatureState(socket, userId, namespace, value), 'Feature state saved.');
|
||||
const handleDeleteFeature = (namespace) =>
|
||||
@@ -393,7 +415,7 @@ export default function IdentityDatabasePanel() {
|
||||
<SignalsCard user={selectedUser} onAddSignal={handleAddSignal} onRemoveSignal={handleRemoveSignal} />
|
||||
</TabPanel>
|
||||
<TabPanel id="status">
|
||||
<StatusCard user={selectedUser} onVerified={handleVerified} onDeterrence={handleDeterrence} />
|
||||
<StatusCard user={selectedUser} onVerified={handleVerified} onDeterrence={handleDeterrence} onMuted={handleMuted} />
|
||||
</TabPanel>
|
||||
<TabPanel id="features">
|
||||
<FeatureStateCard user={selectedUser} onSaveFeature={handleSaveFeature} onDeleteFeature={handleDeleteFeature} />
|
||||
|
||||
@@ -37,6 +37,10 @@ export function setDeterrence(socket, userId, enabled, reason) {
|
||||
return emitIdentityAdmin(socket, 'identityAdmin:setDeterrence', { userId, enabled, reason });
|
||||
}
|
||||
|
||||
export function setMuted(socket, userId, enabled) {
|
||||
return emitIdentityAdmin(socket, 'identityAdmin:setMuted', { userId, enabled });
|
||||
}
|
||||
|
||||
export function updateFeatureState(socket, userId, namespace, value) {
|
||||
return emitIdentityAdmin(socket, 'identityAdmin:updateFeatureState', { userId, namespace, value });
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ export function userMatchesQuery(user, query) {
|
||||
export function userMatchesFilter(user, filter) {
|
||||
if (filter === 'verified') return Boolean(user?.verified?.enabled);
|
||||
if (filter === 'deterred') return Boolean(user?.deterrence?.enabled);
|
||||
if (filter === 'muted') return Boolean(user?.deterrence?.muted);
|
||||
if (filter === 'unverified') return !user?.verified?.enabled;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user