@articles-media/articles-dev-box 1.1.6 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,6 +51,9 @@ npm run dev
51
51
  | SettingsModal | All in one component to handle game settings UI across multiple games. | |
52
52
  | CreditsModal | All in one component to handle game credits UI across multiple games. | |
53
53
  | InfoModal | All in one component to handle game info modal across multiple games. | USA Tycoon |
54
+ | FriendsList | List and Modal for showing friends. | Auto imported via GlobalClientModals |
55
+ | InviteModal | Modal for showing FriendsList with allowInvite | Normally used via GlobalClientModals |
56
+ | ReusedSocketLogicHandler | Sets up a lot of common websocket logic | Catching Game, Ocean Rings |
54
57
  | DarkModeHandler | Consumes a Zustand store, detects prefers-color-scheme, sets data-bs-theme on body element. | |
55
58
  | ToontownModeHandler | Handles setting zustand state from url params if toontownMode is passed. | |
56
59
  | SocketServerUrlHandler | Handles setting socket server state from url params if socketServerUrl is passed. | |
@@ -2,6 +2,7 @@ import { t as ArticlesButton } from "./Button-DvEZjsVV.js";
2
2
  import useUserDetails from "./useUserDetails.js";
3
3
  import useUserToken from "./useUserToken.js";
4
4
  import useUserFriends from "./useUserFriends.js";
5
+ import { useMemo } from "react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  import { Modal } from "react-bootstrap";
7
8
  //#region src/components/Friends/FriendsList.jsx
@@ -14,16 +15,47 @@ function FriendsList({ show, setShow, componentType, className, style = {}, id =
14
15
  user_id: userDetails?.user_id,
15
16
  user_token: userToken
16
17
  });
17
- if (!componentType || componentType == "list") {
18
- if (!friendsLoading && friends && friends.length > 0) return /* @__PURE__ */ jsx("ul", {
19
- className,
20
- style,
21
- children: friends.map((friend) => /* @__PURE__ */ jsxs("li", { children: [
18
+ const friendsWrapped = useMemo(() => {
19
+ return /* @__PURE__ */ jsx("div", { children: friends?.map((friend) => /* @__PURE__ */ jsxs("div", {
20
+ className: "d-flex align-items-center justify-content-between border p-1",
21
+ children: [/* @__PURE__ */ jsxs("div", { children: [
22
+ /* @__PURE__ */ jsx("img", {
23
+ src: friend?.populated_user?.photo_url,
24
+ alt: `${friend?.populated_user?.username}'s avatar`,
25
+ width: 32,
26
+ height: 32,
27
+ className: "me-2"
28
+ }),
22
29
  friend?.populated_user?.username,
23
30
  " - ",
24
31
  friend?.populated_user?.display_name || "No Display Name"
25
- ] }, friend.friend_id))
26
- });
32
+ ] }), /* @__PURE__ */ jsxs("div", { children: [
33
+ allowInvite && /* @__PURE__ */ jsxs(ArticlesButton, {
34
+ variant: "articles",
35
+ onClick: () => {
36
+ allowInvite(friend);
37
+ },
38
+ children: [/* @__PURE__ */ jsx("i", { className: "fad fa-paper-plane me-2" }), /* @__PURE__ */ jsx("span", { children: "Invite" })]
39
+ }),
40
+ /* @__PURE__ */ jsx(ArticlesButton, {
41
+ variant: "articles",
42
+ onClick: () => {
43
+ console.log("View friend details for ", friend);
44
+ },
45
+ children: /* @__PURE__ */ jsx("i", { className: "fad fa-info me-0" })
46
+ }),
47
+ /* @__PURE__ */ jsx(ArticlesButton, {
48
+ variant: "articles",
49
+ onClick: () => {
50
+ console.log("Start Message");
51
+ },
52
+ children: /* @__PURE__ */ jsx("i", { className: "fad fa-envelope me-0" })
53
+ })
54
+ ] })]
55
+ }, friend.friend_id)) });
56
+ }, [friends]);
57
+ if (!componentType || componentType == "list") {
58
+ if (!friendsLoading && friends && friends.length > 0) return friendsWrapped;
27
59
  }
28
60
  if (componentType.toLowerCase() == "modal") return /* @__PURE__ */ jsxs(Modal, {
29
61
  show,
@@ -42,27 +74,7 @@ function FriendsList({ show, setShow, componentType, className, style = {}, id =
42
74
  children: [/* @__PURE__ */ jsx("i", { className: "fad fa-spinner-third fa-spin fa-2x" }), /* @__PURE__ */ jsx("div", { children: "Loading..." })]
43
75
  }),
44
76
  !friendsLoading && friends && friends.length == 0 && /* @__PURE__ */ jsx("div", { children: "No friends to show." }),
45
- !friendsLoading && friends && friends.length > 0 && /* @__PURE__ */ jsx("div", { children: friends.map((friend) => /* @__PURE__ */ jsxs("div", {
46
- className: "d-flex align-items-center justify-content-between border p-1",
47
- children: [
48
- friend?.populated_user?.username,
49
- " - ",
50
- friend?.populated_user?.display_name || "No Display Name",
51
- /* @__PURE__ */ jsxs("div", { children: [allowInvite && /* @__PURE__ */ jsx(ArticlesButton, {
52
- variant: "articles",
53
- onClick: () => {
54
- allowInvite(friend);
55
- },
56
- children: /* @__PURE__ */ jsx("i", { className: "fad fa-comment-check" })
57
- }), /* @__PURE__ */ jsx(ArticlesButton, {
58
- variant: "articles",
59
- onClick: () => {
60
- console.log("View friend details for ", friend);
61
- },
62
- children: /* @__PURE__ */ jsx("i", { className: "fad fa-info me-0" })
63
- })] })
64
- ]
65
- }, friend.friend_id)) })
77
+ !friendsLoading && friends && friends.length > 0 && friendsWrapped
66
78
  ] }),
67
79
  /* @__PURE__ */ jsxs(Modal.Footer, {
68
80
  className: "justify-content-between",
@@ -8,7 +8,7 @@ function MobileMenu({ useStore, LeftPanelContent, menuBarConfig }) {
8
8
  const showMenu = useStore((state) => state.showMenu);
9
9
  const setShowMenu = useStore((state) => state.setShowMenu);
10
10
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
11
- className: (0, import_classnames.default)(`menu-bar ${menuBarConfig.menuBarClassName || ""}`, {
11
+ className: (0, import_classnames.default)(`dev-box-game-menu menu-bar ${menuBarConfig.menuBarClassName || ""}`, {
12
12
  "card card-articles p-1 justify-content-center": menuBarConfig.style == "Bar",
13
13
  [menuBarConfig.style.replaceAll(" ", "_")]: menuBarConfig.style,
14
14
  [menuBarConfig.menuBarButtonPosition]: menuBarConfig.menuBarButtonPosition
@@ -44,7 +44,7 @@ function MobileMenu({ useStore, LeftPanelContent, menuBarConfig }) {
44
44
  ]
45
45
  })
46
46
  }), /* @__PURE__ */ jsx("div", {
47
- className: `mobile-menu ${showMenu && "show"}`,
47
+ className: `dev-box-game-menu mobile-menu ${showMenu && "show"}`,
48
48
  onClick: () => setShowMenu(false),
49
49
  style: {
50
50
  ...menuBarConfig.style == "Bar" && { bottom: "50px" },
@@ -121,7 +121,7 @@ function GameMenu(props) {
121
121
  LeftPanelContent,
122
122
  menuBarConfig: { ...menuBarConfig }
123
123
  }), /* @__PURE__ */ jsx("div", {
124
- className: `panel-left card rounded-0 ${convertedSidebarStyle} ${sidebarConfig?.className || ""}`,
124
+ className: `dev-box-game-menu panel-left card rounded-0 ${convertedSidebarStyle} ${sidebarConfig?.className || ""}`,
125
125
  style: {
126
126
  ...sidebarConfig?.cssStyle,
127
127
  ...convertedSidebarStyle == "Floating_Panel" && {
package/dist/GameMenu.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as GameMenu } from "./GameMenu-BSfKeM4b.js";
1
+ import { t as GameMenu } from "./GameMenu-CBn1r9Cq.js";
2
2
  export { GameMenu as default };
@@ -8,6 +8,7 @@ var InfoModal = lazy(() => import("./InfoModal.js"));
8
8
  var CreditsModal = lazy(() => import("./CreditsModal.js"));
9
9
  var FriendsList = lazy(() => import("./FriendsList.js"));
10
10
  var SettingsModal = lazy(() => import("./SettingsModal.js"));
11
+ var InviteModal = lazy(() => import("./InviteModal.js"));
11
12
  function GlobalClientModals({ useStore, useAudioStore, useTouchControlsStore, useSocketStore, packageInfo, settingsModalConfig, infoModalConfig }) {
12
13
  const showInfoModal = useStore((state) => state.showInfoModal);
13
14
  const setShowInfoModal = useStore((state) => state.setShowInfoModal);
@@ -17,6 +18,8 @@ function GlobalClientModals({ useStore, useAudioStore, useTouchControlsStore, us
17
18
  const setShowCreditsModal = useStore((state) => state.setShowCreditsModal);
18
19
  const showFriendsModal = useStore((state) => state.showFriendsModal);
19
20
  const setShowFriendsModal = useStore((state) => state.setShowFriendsModal);
21
+ const showInviteModal = useStore((state) => state.showInviteModal);
22
+ const setShowInviteModal = useStore((state) => state.setShowInviteModal);
20
23
  const { data: userToken, error: userTokenError, isLoading: userTokenLoading, mutate: userTokenMutate } = useUserToken(process.env.NEXT_PUBLIC_GAME_PORT);
21
24
  const { data: userDetails, error: userDetailsError, isLoading: userDetailsLoading, mutate: userDetailsMutate } = useUserDetails({ token: userToken });
22
25
  if (!settingsModalConfig) {
@@ -47,9 +50,12 @@ function GlobalClientModals({ useStore, useAudioStore, useTouchControlsStore, us
47
50
  showFriendsModal && /* @__PURE__ */ jsx(FriendsList, {
48
51
  componentType: "modal",
49
52
  show: showFriendsModal,
50
- setShow: setShowFriendsModal,
51
- user_id: userDetails ? userDetails.user_id : null,
52
- user_token: userToken ? userToken : null
53
+ setShow: setShowFriendsModal
54
+ }),
55
+ showInviteModal && /* @__PURE__ */ jsx(InviteModal, {
56
+ show: showInviteModal,
57
+ setShow: setShowInviteModal,
58
+ useSocketStore
53
59
  })
54
60
  ] });
55
61
  }
@@ -0,0 +1,56 @@
1
+ import { t as ArticlesButton } from "./Button-DvEZjsVV.js";
2
+ import { lazy, useState } from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { Modal } from "react-bootstrap";
5
+ //#region src/components/Games/InviteModal.jsx
6
+ var FriendsList = lazy(() => import("./FriendsList.js"));
7
+ function InviteModal({ show, setShow, useSocketStore }) {
8
+ const socket = useSocketStore((state) => state?.socket);
9
+ const [showModal, setShowModal] = useState(true);
10
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Modal, {
11
+ className: "articles-modal games-invite-modal",
12
+ size: "md",
13
+ show: showModal,
14
+ centered: true,
15
+ scrollable: true,
16
+ onExited: () => {
17
+ setShow(false);
18
+ },
19
+ onHide: () => {
20
+ setShowModal(false);
21
+ },
22
+ children: [
23
+ /* @__PURE__ */ jsx(Modal.Header, {
24
+ closeButton: true,
25
+ children: /* @__PURE__ */ jsx(Modal.Title, { children: "Invite Players" })
26
+ }),
27
+ /* @__PURE__ */ jsx(Modal.Body, {
28
+ className: "flex-column p-0",
29
+ children: /* @__PURE__ */ jsx("div", {
30
+ className: "p-3",
31
+ children: /* @__PURE__ */ jsx(FriendsList, {
32
+ componentType: "list",
33
+ show,
34
+ setShow,
35
+ allowInvite: () => {
36
+ socket.emit("invitePlayer", { ...show });
37
+ }
38
+ })
39
+ })
40
+ }),
41
+ /* @__PURE__ */ jsxs(Modal.Footer, {
42
+ className: "justify-content-between",
43
+ children: [/* @__PURE__ */ jsx("div", {}), /* @__PURE__ */ jsx(ArticlesButton, {
44
+ variant: "outline-dark",
45
+ onClick: () => {
46
+ setShow(false);
47
+ },
48
+ className: "d-flex align-items-center",
49
+ children: "Close"
50
+ })]
51
+ })
52
+ ]
53
+ }) });
54
+ }
55
+ //#endregion
56
+ export { InviteModal as default };
@@ -18,7 +18,7 @@ function PageTemplateLandingPage({ useStore, useSocketStore, RotatingMascot, Lin
18
18
  const lobbyDetails = useStore((state) => state.lobbyDetails);
19
19
  const landingAnimation = useStore((state) => state.landingAnimation);
20
20
  return /* @__PURE__ */ jsxs("div", {
21
- className: "landing-page",
21
+ className: "landing-page dev-box-template-landing-page",
22
22
  children: [
23
23
  AdditionalContent && AdditionalContent,
24
24
  /* @__PURE__ */ jsx("div", {
@@ -91,7 +91,8 @@ function PageTemplateLandingPage({ useStore, useSocketStore, RotatingMascot, Lin
91
91
  }), /* @__PURE__ */ jsx("div", {
92
92
  className: "servers",
93
93
  children: Array.from({ length: multiplayerConfig?.defaultServers }).map((_, id) => {
94
- let lobbyLookup = lobbyDetails?.games?.find((lobby) => parseInt(lobby.server_id) == id);
94
+ const serverNumber = id + 1;
95
+ let lobbyLookup = lobbyDetails?.games?.find((lobby) => parseInt(lobby.server_id) == serverNumber);
95
96
  return /* @__PURE__ */ jsxs("div", {
96
97
  className: "server",
97
98
  children: [
@@ -100,7 +101,7 @@ function PageTemplateLandingPage({ useStore, useSocketStore, RotatingMascot, Lin
100
101
  children: [/* @__PURE__ */ jsx("div", {
101
102
  className: "mb-0",
102
103
  style: { fontSize: "0.9rem" },
103
- children: /* @__PURE__ */ jsxs("b", { children: ["Server ", id] })
104
+ children: /* @__PURE__ */ jsxs("b", { children: ["Server ", serverNumber] })
104
105
  }), /* @__PURE__ */ jsxs("div", {
105
106
  className: "mb-0",
106
107
  children: [lobbyLookup?.players?.length || 0, "/4"]
@@ -131,7 +132,7 @@ function PageTemplateLandingPage({ useStore, useSocketStore, RotatingMascot, Lin
131
132
  className: ``,
132
133
  href: {
133
134
  pathname: `/play`,
134
- query: { server: id }
135
+ query: { server: serverNumber }
135
136
  },
136
137
  style: { ...multiplayerConfig?.comingSoon ? { pointerEvents: "none" } : {} },
137
138
  children: /* @__PURE__ */ jsx(ArticlesButton, {
@@ -0,0 +1,151 @@
1
+ import useUserDetails from "./useUserDetails.js";
2
+ import useUserToken from "./useUserToken.js";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { jsxs } from "react/jsx-runtime";
5
+ //#region src/components/Games/Socket/ReusedSocketLogicHandler.jsx
6
+ function ReusedSocketLogicHandler({ pathname, useStore, useGameStore, useSocketStore, debugConfig, landingConfig, gameConfig, server }) {
7
+ const initialized = useRef(false);
8
+ const [isVisible, setIsVisible] = useState(true);
9
+ const socket = useSocketStore((state) => state.socket);
10
+ const connectSocket = useSocketStore((state) => state.connectSocket);
11
+ const loginSocket = useSocketStore((state) => state.loginSocket);
12
+ const connected = useSocketStore((state) => state.connected);
13
+ const setConnected = useSocketStore((state) => state.setConnected);
14
+ const authenticated = useSocketStore((state) => state.authenticated);
15
+ const setAuthenticated = useSocketStore((state) => state.setAuthenticated);
16
+ const setLobbyDetails = useStore((state) => state.setLobbyDetails);
17
+ const debug = useStore((state) => state.debug);
18
+ const nickname = useStore((state) => state.nickname);
19
+ const { data: userToken, error: userTokenError, isLoading: userTokenLoading, mutate: userTokenMutate } = useUserToken(process.env.NEXT_PUBLIC_GAME_PORT);
20
+ const { data: userDetails, error: userDetailsError, isLoading: userDetailsLoading, mutate: userDetailsMutate } = useUserDetails({ token: userToken });
21
+ function debugLog(...args) {
22
+ if (debug) console.log("[📶ReusedSocketLogicHandler]", ...args);
23
+ }
24
+ useEffect(() => {
25
+ if (!initialized.current) {
26
+ initialized.current = true;
27
+ connectSocket();
28
+ }
29
+ socket.on("connect", () => {
30
+ debugLog("Connected to server!");
31
+ setConnected(true);
32
+ });
33
+ socket.on("disconnect", () => {
34
+ debugLog("Disconnected from server!");
35
+ setConnected(false);
36
+ setAuthenticated(false);
37
+ });
38
+ socket.on("force-page", (data) => {
39
+ debugLog("You are being forced to a new page!", data);
40
+ window.location.href = data.page;
41
+ });
42
+ socket.on("authenticated", (data) => {
43
+ debugLog("Socket authenticated with server!");
44
+ setAuthenticated(true);
45
+ });
46
+ socket.on(`landing-details`, function(msg) {
47
+ debugLog(`landing-details`, msg);
48
+ if (landingConfig?.onLandingDetails) landingConfig.onLandingDetails(msg);
49
+ const currentLobbyDetails = useStore.getState().lobbyDetails;
50
+ if (JSON.stringify(msg) !== JSON.stringify(currentLobbyDetails)) setLobbyDetails(msg);
51
+ });
52
+ socket.on(`game-update`, function(msg) {
53
+ debugLog(`game-update`, msg);
54
+ if (gameConfig?.onGameUpdate) gameConfig.onGameUpdate(msg);
55
+ const currentGameState = useGameStore.getState().gameState;
56
+ const setGameState = useGameStore.getState().setGameState;
57
+ if (JSON.stringify(msg) !== JSON.stringify(currentGameState)) {
58
+ debugLog("Updating game state with new data from server");
59
+ setGameState(msg);
60
+ }
61
+ });
62
+ return () => {
63
+ socket.off("connect");
64
+ socket.off("disconnect");
65
+ socket.off("force-page");
66
+ socket.off("authenticated");
67
+ socket.off(`landing-details`);
68
+ socket.off(`game-update`);
69
+ };
70
+ }, [socket]);
71
+ useEffect(() => {
72
+ if (pathname == "/" && landingConfig?.handleLandingDetails) {
73
+ if (socket.connected) socket.emit("join-room", `game:${process.env.NEXT_PUBLIC_GAME_KEY}-landing`);
74
+ return function cleanup() {
75
+ socket.emit("leave-room", `game:${process.env.NEXT_PUBLIC_GAME_KEY}-landing`);
76
+ setLobbyDetails({
77
+ players: [],
78
+ games: []
79
+ });
80
+ };
81
+ }
82
+ }, [
83
+ connected,
84
+ landingConfig?.handleLandingDetails,
85
+ pathname
86
+ ]);
87
+ useEffect(() => {
88
+ if (server && connected && gameConfig?.handleGameUpdates && pathname == "/play") {
89
+ const roomName = `game:${process.env.NEXT_PUBLIC_GAME_KEY}-room-${server}`;
90
+ debugLog("Joining game room: ", roomName);
91
+ socket.emit("join-room", roomName, {
92
+ game_id: server,
93
+ nickname,
94
+ client_version: "1"
95
+ });
96
+ return function cleanup() {
97
+ socket.emit("leave-room", roomName);
98
+ };
99
+ }
100
+ }, [
101
+ server,
102
+ connected,
103
+ nickname,
104
+ gameConfig?.handleGameUpdates,
105
+ pathname
106
+ ]);
107
+ useEffect(() => {
108
+ if (connected && !authenticated && userDetails?.user_id) {
109
+ debugLog("Socket is now connected and not authenticated with a logged in user!");
110
+ loginSocket({
111
+ user_id: userDetails?.user_id,
112
+ socket_id: socket.id,
113
+ token: userToken
114
+ });
115
+ }
116
+ }, [
117
+ connected,
118
+ authenticated,
119
+ userDetails?.user_id
120
+ ]);
121
+ useEffect(() => {
122
+ if (debugConfig.enabled && debugConfig.autoHide) {
123
+ const timer = setTimeout(() => {
124
+ setIsVisible(false);
125
+ }, debugConfig.autoHideDelay);
126
+ return () => clearTimeout(timer);
127
+ }
128
+ }, [debugConfig.enabled]);
129
+ if (debugConfig.enabled && isVisible && process.env.NODE_ENV !== "production") return /* @__PURE__ */ jsxs("div", {
130
+ style: {
131
+ position: "fixed",
132
+ bottom: 0,
133
+ left: 0,
134
+ color: "white",
135
+ fontSize: "11px",
136
+ zIndex: 9999,
137
+ backgroundColor: "rgba(0,0,0,0.5)",
138
+ padding: "2px",
139
+ display: "flex",
140
+ gap: "8px"
141
+ },
142
+ children: [
143
+ /* @__PURE__ */ jsxs("div", { children: ["Connected: ", connected ? "Yes" : "No"] }),
144
+ /* @__PURE__ */ jsxs("div", { children: ["Authenticated: ", authenticated ? "Yes" : "No"] }),
145
+ /* @__PURE__ */ jsxs("div", { children: ["ID: ", socket.id] }),
146
+ /* @__PURE__ */ jsxs("div", { children: ["Host: ", socket.io.uri] })
147
+ ]
148
+ });
149
+ }
150
+ //#endregion
151
+ export { ReusedSocketLogicHandler as default };
@@ -246,7 +246,7 @@ function OtherTab({ useStore, config }) {
246
246
  var package_default = {
247
247
  name: "@articles-media/articles-dev-box",
248
248
  description: "Shared code, functions, and components for different Articles Media projects.",
249
- version: "1.1.6",
249
+ version: "1.3.0",
250
250
  type: "module",
251
251
  sideEffects: false,
252
252
  imports: { "#root/src/*": "./src/*" },
@@ -281,6 +281,8 @@ var package_default = {
281
281
  "./SocketServerUrlHandler": "./dist/SocketServerUrlHandler.js",
282
282
  "./HasNoMouseHandler": "./dist/HasNoMouseHandler.js",
283
283
  "./FriendsList": "./dist/FriendsList.js",
284
+ "./InviteModal": "./dist/InviteModal.js",
285
+ "./ReusedSocketLogicHandler": "./dist/ReusedSocketLogicHandler.js",
284
286
  "./useUserDetails": "./dist/useUserDetails.js",
285
287
  "./useUserToken": "./dist/useUserToken.js",
286
288
  "./useUserFriends": "./dist/useUserFriends.js",
@@ -1,2 +1,2 @@
1
- import { t as SettingsModal } from "./SettingsModal-CZvPy5hf.js";
1
+ import { t as SettingsModal } from "./SettingsModal-DIMbVw4n.js";
2
2
  export { SettingsModal as default };
@@ -257,17 +257,17 @@
257
257
  }
258
258
 
259
259
  @media (min-width: 992px) {
260
- .show-sidebar .menu-bar {
260
+ .show-sidebar .menu-bar.dev-box-game-menu {
261
261
  display: none;
262
262
  }
263
- .show-sidebar .panel-left {
263
+ .show-sidebar .panel-left.dev-box-game-menu {
264
264
  display: flex !important;
265
265
  }
266
266
  }
267
- .menu-bar {
267
+ .menu-bar.dev-box-game-menu {
268
268
  border-radius: 0;
269
269
  }
270
- .menu-bar.Bar {
270
+ .menu-bar.dev-box-game-menu.Bar {
271
271
  position: fixed;
272
272
  bottom: 0;
273
273
  left: 0;
@@ -275,12 +275,12 @@
275
275
  height: 50px;
276
276
  z-index: 3;
277
277
  }
278
- .menu-bar.Bar .btn {
278
+ .menu-bar.dev-box-game-menu.Bar .btn {
279
279
  display: flex;
280
280
  align-items: center;
281
281
  justify-content: center;
282
282
  }
283
- .menu-bar.Corner_Button {
283
+ .menu-bar.dev-box-game-menu.Corner_Button {
284
284
  position: fixed;
285
285
  bottom: 0;
286
286
  width: 100%;
@@ -289,7 +289,7 @@
289
289
  height: 50px;
290
290
  z-index: 3;
291
291
  }
292
- .menu-bar.Corner_Button .btn {
292
+ .menu-bar.dev-box-game-menu.Corner_Button .btn {
293
293
  width: 100%;
294
294
  height: 100%;
295
295
  border-radius: 0;
@@ -299,12 +299,12 @@
299
299
  justify-content: center;
300
300
  flex-direction: column;
301
301
  }
302
- .menu-bar.Corner_Button .btn i {
302
+ .menu-bar.dev-box-game-menu.Corner_Button .btn i {
303
303
  margin-right: 0;
304
304
  font-size: 1.25rem;
305
305
  }
306
306
  @media (min-width: 992px) {
307
- .menu-bar .menu-bar-container .Center {
307
+ .menu-bar.dev-box-game-menu .menu-bar-container .Center {
308
308
  position: absolute;
309
309
  top: 50%;
310
310
  left: 50%;
@@ -312,7 +312,7 @@
312
312
  }
313
313
  }
314
314
 
315
- .mobile-menu {
315
+ .mobile-menu.dev-box-game-menu {
316
316
  position: fixed;
317
317
  left: 0;
318
318
  width: 100%;
@@ -326,7 +326,7 @@
326
326
  align-items: flex-end;
327
327
  justify-content: center;
328
328
  }
329
- .mobile-menu.Bar {
329
+ .mobile-menu.dev-box-game-menu.Bar {
330
330
  position: fixed;
331
331
  bottom: 0;
332
332
  left: 0;
@@ -334,23 +334,23 @@
334
334
  height: 50px;
335
335
  z-index: 3;
336
336
  }
337
- .mobile-menu.show {
337
+ .mobile-menu.dev-box-game-menu.show {
338
338
  transform: translateY(0);
339
339
  }
340
340
 
341
- .panel-left,
342
- .panel-right {
341
+ .panel-left.dev-box-game-menu,
342
+ .panel-right.dev-box-game-menu {
343
343
  width: 300px;
344
344
  height: calc(100vh - 0px);
345
345
  overflow-y: auto;
346
346
  flex-shrink: 0;
347
347
  }
348
348
 
349
- .panel-left {
349
+ .panel-left.dev-box-game-menu {
350
350
  display: none !important;
351
351
  }
352
352
 
353
- .panel-right {
353
+ .panel-right.dev-box-game-menu {
354
354
  display: flex;
355
355
  justify-content: center;
356
356
  align-items: center;
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import useUserFriends from "./useUserFriends.js";
8
8
  import FriendsList from "./FriendsList.js";
9
9
  import { t as SessionButton } from "./SessionButton-DsXEzmff.js";
10
10
  import ArticlesAd from "./ArticlesAd.js";
11
- import { t as GameMenu } from "./GameMenu-BSfKeM4b.js";
11
+ import { t as GameMenu } from "./GameMenu-CBn1r9Cq.js";
12
12
  import useFullscreen from "./useFullscreen.js";
13
13
  import PrimaryButtonGroup from "./GameMenuPrimaryButtonGroup.js";
14
14
  import NicknameInput from "./NicknameInput.js";
@@ -16,17 +16,19 @@ import { t as GameScoreboard } from "./GameScoreboard-CYuTBE_E.js";
16
16
  import PageTemplateLandingPage from "./PageTemplateLandingPage.js";
17
17
  import GlobalHead from "./GlobalHead.js";
18
18
  import GlobalBody_default from "./GlobalBody.js";
19
- import { t as SettingsModal } from "./SettingsModal-CZvPy5hf.js";
19
+ import { t as SettingsModal } from "./SettingsModal-DIMbVw4n.js";
20
20
  import CreditsModal from "./CreditsModal.js";
21
21
  import InfoModal from "./InfoModal.js";
22
22
  import DarkModeHandler from "./DarkModeHandler.js";
23
23
  import ToontownModeHandler from "./ToontownModeHandler.js";
24
24
  import SocketServerUrlHandler from "./SocketServerUrlHandler.js";
25
25
  import HasNoMouseHandler from "./HasNoMouseHandler.js";
26
+ import InviteModal from "./InviteModal.js";
27
+ import ReusedSocketLogicHandler from "./ReusedSocketLogicHandler.js";
26
28
  import typicalZustandStoreExcludes from "./typicalZustandStoreExcludes.js";
27
29
  import typicalZustandStoreStateSlice from "./typicalZustandStoreStateSlice.js";
28
30
  import defaultGameNextConfig from "./defaultGameNextConfig.js";
29
31
  import getTheme from "./defaultGameThemeConfig.js";
30
32
  import getSignOutRedirectUrl from "./getSignOutRedirectUrl.js";
31
33
  import generateRandomNickname from "./generateRandomNickname.js";
32
- export { Ad_default as Ad, ArticlesAd, CreditsModal, DarkModeHandler, FriendsList, GameMenu, PrimaryButtonGroup as GameMenuPrimaryButtonGroup, GameScoreboard, GlobalBody_default as GlobalBody, GlobalHead, HasNoMouseHandler, InfoModal, NicknameInput, PageTemplateLandingPage, ReturnToLauncherButton, SessionButton, SettingsModal, SignInButton, SocketServerUrlHandler, ToontownModeHandler, ViewUserModal, defaultGameNextConfig, getTheme as defaultGameThemeConfig, generateRandomNickname, getSignOutRedirectUrl, typicalZustandStoreExcludes, typicalZustandStoreStateSlice, useFullscreen, useUserDetails, useUserFriends, useUserToken };
34
+ export { Ad_default as Ad, ArticlesAd, CreditsModal, DarkModeHandler, FriendsList, GameMenu, PrimaryButtonGroup as GameMenuPrimaryButtonGroup, GameScoreboard, GlobalBody_default as GlobalBody, GlobalHead, HasNoMouseHandler, InfoModal, InviteModal, NicknameInput, PageTemplateLandingPage, ReturnToLauncherButton, ReusedSocketLogicHandler, SessionButton, SettingsModal, SignInButton, SocketServerUrlHandler, ToontownModeHandler, ViewUserModal, defaultGameNextConfig, getTheme as defaultGameThemeConfig, generateRandomNickname, getSignOutRedirectUrl, typicalZustandStoreExcludes, typicalZustandStoreStateSlice, useFullscreen, useUserDetails, useUserFriends, useUserToken };
@@ -8,7 +8,8 @@ var typicalZustandStoreExcludes = [
8
8
  "showMenu",
9
9
  "lobbyDetails",
10
10
  "sceneKey",
11
- "showFriendsModal"
11
+ "showFriendsModal",
12
+ "showInviteModal"
12
13
  ];
13
14
  //#endregion
14
15
  export { typicalZustandStoreExcludes as default };
@@ -66,6 +66,10 @@ var typicalZustandStoreStateSlice = (set, get, generateRandomNickname) => ({
66
66
  setShowFriendsModal: (newValue) => {
67
67
  set((prev) => ({ showFriendsModal: newValue }));
68
68
  },
69
+ showInviteModal: false,
70
+ setShowInviteModal: (newValue) => {
71
+ set((prev) => ({ showInviteModal: newValue }));
72
+ },
69
73
  graphicsQuality: "High",
70
74
  setGraphicsQuality: (value) => set({ graphicsQuality: value }),
71
75
  lobbyDetails: {
@@ -12,7 +12,8 @@ var useUserDetails = (params) => {
12
12
  revalidateOnFocus: false,
13
13
  revalidateOnReconnect: false,
14
14
  shouldRetryOnError: false,
15
- errorRetryInterval: 1e3 * 60 * 1
15
+ errorRetryInterval: 1e3 * 60 * 1,
16
+ dedupingInterval: 1e3 * 60 * 5
16
17
  });
17
18
  return {
18
19
  data,
@@ -14,7 +14,7 @@ var options = {
14
14
  revalidateOnFocus: false,
15
15
  revalidateIfStale: false,
16
16
  shouldRetryOnError: false,
17
- errorRetryInterval: 1e3 * 60 * 1
17
+ errorRetryInterval: 1e3 * 60 * 2
18
18
  };
19
19
  var useUserFriends = (params) => {
20
20
  const { data, error, isLoading, isValidating, mutate } = useSWR(params?.user_id && params?.user_token ? {
@@ -9,7 +9,8 @@ var useUserToken = (port) => {
9
9
  revalidateOnFocus: false,
10
10
  revalidateOnReconnect: false,
11
11
  shouldRetryOnError: false,
12
- errorRetryInterval: 1e3 * 60 * 1
12
+ errorRetryInterval: 1e3 * 60 * 1,
13
+ dedupingInterval: 1e3 * 60 * 5
13
14
  });
14
15
  return {
15
16
  data,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@articles-media/articles-dev-box",
3
3
  "description": "Shared code, functions, and components for different Articles Media projects.",
4
- "version": "1.1.6",
4
+ "version": "1.3.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "imports": {
@@ -40,6 +40,8 @@
40
40
  "./SocketServerUrlHandler": "./dist/SocketServerUrlHandler.js",
41
41
  "./HasNoMouseHandler": "./dist/HasNoMouseHandler.js",
42
42
  "./FriendsList": "./dist/FriendsList.js",
43
+ "./InviteModal": "./dist/InviteModal.js",
44
+ "./ReusedSocketLogicHandler": "./dist/ReusedSocketLogicHandler.js",
43
45
  "./useUserDetails": "./dist/useUserDetails.js",
44
46
  "./useUserToken": "./dist/useUserToken.js",
45
47
  "./useUserFriends": "./dist/useUserFriends.js",