mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 23:16:21 +00:00
feat(hooks): permission-driven gating via useHasPermission
Replace the rank-level family (useHasRankLevel + STAFF_LEVELS constants + useIsRank) with a permission-driven family that reads straight from the deployment's `permission_definitions` table — no more hardcoded SecurityLevel/rank-id thresholds on the client. A new rank in permission_ranks or a re-shuffling of permission_definitions rank columns now propagates through the UI automatically. Renderer-side wire shipped in companion commit feat/react19-event-bus@159c5eb (UserPermissionsMapParser + Event, SessionDataManager.getPermissionsSnapshot + USER_PERMISSIONS_UPDATED). New public API in `useSessionSnapshots.ts`: - useUserPermissions(): ReadonlyMap<string, number> — full map - useHasPermission(key): boolean — > 0 ⇒ true - usePermissionValue(key): number — raw 1/2 or 0 - useIsAmbassador() now aliases useHasPermission('acc_ambassador') - useUserRank() kept for PRESENTATIONAL use only (badge, prefix, prefix color) — documented as such in JSDoc; gating must use useHasPermission. Dropped: - src/api/nitro/session/RankLevels.ts (STAFF_LEVELS constants) - useHasRankLevel / useIsRank exports (rank-based gating) 11 consumer migrations, each mapped to the right `permission_definitions.permission_key`: - ToolbarView (mod-only chat-input button) → acc_supporttool - ChooserWidgetView (room-object id column) → acc_supporttool - CatalogClassicView (admin toggles) → acc_catalogfurni - CatalogModernView (admin toggles) → acc_catalogfurni - FurniEditorView (panel access) → acc_catalogfurni - CalendarView (force-open day) → acc_calendar_force - InfoStandWidgetFurniView (mod buildtools btn) → acc_anyroomowner - AvatarInfoWidgetPetView (canPickUp) → acc_anyroomowner - FurnitureMannequinView (controller mode) → acc_anyroomowner - YouTubePlayerView (isMyRoom) → acc_anyroomowner - NavigatorRoomInfoView 'settings' → acc_anyroomowner - NavigatorRoomInfoView 'staff_pick' → acc_staff_pick Test refresh: - useUserRank still tested for the presentational shape. - useHasPermission: true for non-zero, false for absent/zero. - usePermissionValue: raw 1 / 2 / 0 (default). - useUserPermissions: full map exposure. - Runtime promote test: mutate the permissions map + dispatch USER_PERMISSIONS_UPDATED, assert useHasPermission flips false→true. Locks in the new reactive contract. Mock unchanged (the test sets getPermissionsSnapshot via vi.mocked). Verification: yarn typecheck clean, yarn lint:hooks clean, yarn test 214/214 (213 prior + 1 net new for useUserPermissions). Backward compatible: older Arcturus deployments don't ship the map → empty snapshot → every gate is false → mod UI hidden (safe default).
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { CreateLinkEvent, Dispose, DropBounce, EaseOut, JumpBy, Motions, NitroToolbarAnimateIconEvent, PerkAllowancesMessageEvent, PerkEnum, Queue, Wait, YouTubeRoomSettingsEvent } from '@nitrots/nitro-renderer';
|
||||
import { AnimatePresence, motion, Variants } from 'framer-motion';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { GetConfigurationValue, MessengerIconState, OpenMessengerChat, setYoutubeRoomEnabled, STAFF_LEVELS, VisitDesktop } from '../../api';
|
||||
import { GetConfigurationValue, MessengerIconState, OpenMessengerChat, setYoutubeRoomEnabled, VisitDesktop } from '../../api';
|
||||
import { Flex, LayoutAvatarImageView, LayoutItemCountView } from '../../common';
|
||||
import { useAchievements, useFriends, useHasRankLevel, useInventoryUnseenTracker, useMessageEvent, useMessenger, useNitroEvent, useSessionInfo, useWiredTools } from '../../hooks';
|
||||
import { useAchievements, useFriends, useHasPermission, useInventoryUnseenTracker, useMessageEvent, useMessenger, useNitroEvent, useSessionInfo, useWiredTools } from '../../hooks';
|
||||
import { ToolbarItemView } from './ToolbarItemView';
|
||||
import { ToolbarMeView } from './ToolbarMeView';
|
||||
import { YouTubePlayerView } from './YouTubePlayerView';
|
||||
@@ -49,7 +49,7 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
|
||||
const { requests = [] } = useFriends();
|
||||
const { iconState = MessengerIconState.HIDDEN } = useMessenger();
|
||||
const { openMonitor, showToolbarButton } = useWiredTools();
|
||||
const isMod = useHasRankLevel(STAFF_LEVELS.MOD);
|
||||
const isMod = useHasPermission('acc_supporttool');
|
||||
const isVisible = (isToolbarOpen || !isInRoom);
|
||||
const visibilityVariant = isVisible ? 'visible' : 'hidden';
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { ControlYoutubeDisplayPlaybackMessageComposer, YouTubeRoomBroadcastEvent, YouTubeRoomPlayComposer, YouTubeRoomSettingsEvent, YouTubeRoomWatchersEvent, YouTubeRoomWatchingComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useRef, useState } from 'react';
|
||||
import ReactPlayer from 'react-player/youtube';
|
||||
import { GetRoomSession, getYoutubeRoomEnabled, LocalizeText, SendMessageComposer, STAFF_LEVELS, YoutubeVideoPlaybackStateEnum } from '../../api';
|
||||
import { GetRoomSession, getYoutubeRoomEnabled, LocalizeText, SendMessageComposer, YoutubeVideoPlaybackStateEnum } from '../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, LayoutAvatarImageView } from '../../common';
|
||||
import { useFurnitureYoutubeWidget, useHasRankLevel, useMessageEvent } from '../../hooks';
|
||||
import { useFurnitureYoutubeWidget, useHasPermission, useMessageEvent } from '../../hooks';
|
||||
|
||||
const CONTROL_COMMAND_PREVIOUS_VIDEO = 0;
|
||||
const CONTROL_COMMAND_NEXT_VIDEO = 1;
|
||||
@@ -48,7 +48,7 @@ export const YouTubePlayerView: FC<{}> = () =>
|
||||
const [youtubeEnabled, setYoutubeEnabled] = useState(getYoutubeRoomEnabled());
|
||||
// Reactive — must sit above the `if (!isOpen) return null` below
|
||||
// so the hook order stays stable across renders.
|
||||
const isModerator = useHasRankLevel(STAFF_LEVELS.MOD);
|
||||
const isModerator = useHasPermission('acc_anyroomowner');
|
||||
|
||||
useMessageEvent<YouTubeRoomSettingsEvent>(YouTubeRoomSettingsEvent, event =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user