@gamepark/react-game 7.7.4 → 7.7.6

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.
Files changed (99) hide show
  1. package/dist/components/GameProvider/GameErrorBoundary.js +108 -108
  2. package/dist/components/GameProvider/GameInternalProviders.d.ts +6 -0
  3. package/dist/components/GameProvider/GameInternalProviders.js +10 -0
  4. package/dist/components/GameProvider/GameInternalProviders.js.map +1 -0
  5. package/dist/components/GameProvider/LogHistoryBridge.d.ts +7 -0
  6. package/dist/components/GameProvider/LogHistoryBridge.js +23 -0
  7. package/dist/components/GameProvider/LogHistoryBridge.js.map +1 -0
  8. package/dist/components/JournalTabs/History/History.js +52 -13
  9. package/dist/components/JournalTabs/History/History.js.map +1 -1
  10. package/dist/components/JournalTabs/History/LazyLogItem.d.ts +10 -0
  11. package/dist/components/JournalTabs/History/LazyLogItem.js +35 -0
  12. package/dist/components/JournalTabs/History/LazyLogItem.js.map +1 -0
  13. package/dist/components/JournalTabs/History/SetupLogItem.js +19 -19
  14. package/dist/components/JournalTabs/History/SharedIntersectionContext.d.ts +9 -0
  15. package/dist/components/JournalTabs/History/SharedIntersectionContext.js +36 -0
  16. package/dist/components/JournalTabs/History/SharedIntersectionContext.js.map +1 -0
  17. package/dist/components/JournalTabs/History/VirtualizedLogItem.d.ts +12 -0
  18. package/dist/components/JournalTabs/History/VirtualizedLogItem.js +6 -0
  19. package/dist/components/JournalTabs/History/VirtualizedLogItem.js.map +1 -0
  20. package/dist/components/Log/LogHistoryProvider.d.ts +7 -0
  21. package/dist/components/Log/LogHistoryProvider.js +22 -0
  22. package/dist/components/Log/LogHistoryProvider.js.map +1 -0
  23. package/dist/components/material/Dices/OctahedralDiceDescription.d.ts +48 -0
  24. package/dist/components/material/Dices/OctahedralDiceDescription.js +142 -0
  25. package/dist/components/material/Dices/OctahedralDiceDescription.js.map +1 -0
  26. package/dist/components/material/GameTable/DevToolEntry.d.ts +17 -0
  27. package/dist/components/material/GameTable/DevToolEntry.js +13 -0
  28. package/dist/components/material/GameTable/DevToolEntry.js.map +1 -0
  29. package/dist/components/material/GameTable/DevTools/BotTool.d.ts +8 -0
  30. package/dist/components/material/GameTable/DevTools/BotTool.js +13 -0
  31. package/dist/components/material/GameTable/DevTools/BotTool.js.map +1 -0
  32. package/dist/components/material/GameTable/DevTools/DevToolsStyles.d.ts +58 -0
  33. package/dist/components/material/GameTable/DevTools/DevToolsStyles.js +706 -0
  34. package/dist/components/material/GameTable/DevTools/DevToolsStyles.js.map +1 -0
  35. package/dist/components/material/GameTable/DevTools/GamePanel.d.ts +1 -0
  36. package/dist/components/material/GameTable/DevTools/GamePanel.js +7 -179
  37. package/dist/components/material/GameTable/DevTools/GamePanel.js.map +1 -1
  38. package/dist/components/material/GameTable/DevTools/NewGameTool.d.ts +9 -0
  39. package/dist/components/material/GameTable/DevTools/NewGameTool.js +64 -0
  40. package/dist/components/material/GameTable/DevTools/NewGameTool.js.map +1 -0
  41. package/dist/components/material/GameTable/DevTools/SwitchPlayerTool.d.ts +8 -0
  42. package/dist/components/material/GameTable/DevTools/SwitchPlayerTool.js +9 -0
  43. package/dist/components/material/GameTable/DevTools/SwitchPlayerTool.js.map +1 -0
  44. package/dist/components/material/GameTable/DevTools/TutorialTool.d.ts +8 -0
  45. package/dist/components/material/GameTable/DevTools/TutorialTool.js +4 -0
  46. package/dist/components/material/GameTable/DevTools/TutorialTool.js.map +1 -0
  47. package/dist/components/material/GameTable/DevTools/UndoTool.d.ts +8 -0
  48. package/dist/components/material/GameTable/DevTools/UndoTool.js +9 -0
  49. package/dist/components/material/GameTable/DevTools/UndoTool.js.map +1 -0
  50. package/dist/components/material/GameTable/DevTools/devtools.css.d.ts +24 -0
  51. package/dist/components/material/GameTable/DevTools/devtools.css.js +183 -0
  52. package/dist/components/material/GameTable/DevTools/devtools.css.js.map +1 -0
  53. package/dist/components/material/GameTable/DevToolsHub.d.ts +4 -21
  54. package/dist/components/material/GameTable/DevToolsHub.js +24 -830
  55. package/dist/components/material/GameTable/DevToolsHub.js.map +1 -1
  56. package/dist/components/material/GameTable/DevToolsStyles.d.ts +67 -0
  57. package/dist/components/material/GameTable/DevToolsStyles.js +752 -0
  58. package/dist/components/material/GameTable/DevToolsStyles.js.map +1 -0
  59. package/dist/components/material/GameTable/JsonHighlighter.d.ts +3 -0
  60. package/dist/components/material/GameTable/JsonHighlighter.js +37 -0
  61. package/dist/components/material/GameTable/JsonHighlighter.js.map +1 -0
  62. package/dist/components/material/sound/bellSound.d.ts +1 -0
  63. package/dist/components/material/sound/bellSound.js +2 -0
  64. package/dist/components/material/sound/bellSound.js.map +1 -0
  65. package/dist/components/material/sound/useYourTurnSound.d.ts +4 -0
  66. package/dist/components/material/sound/useYourTurnSound.js +34 -0
  67. package/dist/components/material/sound/useYourTurnSound.js.map +1 -0
  68. package/dist/css/backgroundCss.js +3 -3
  69. package/dist/css/cursorCss.js +6 -6
  70. package/dist/css/fadeIn.js +6 -6
  71. package/dist/css/shineEffect.js +28 -28
  72. package/dist/css/transformCss.js +4 -4
  73. package/dist/hooks/LogHistoryContext.d.ts +6 -0
  74. package/dist/hooks/LogHistoryContext.js +4 -0
  75. package/dist/hooks/LogHistoryContext.js.map +1 -0
  76. package/dist/hooks/flatHistoryEngine.d.ts +37 -0
  77. package/dist/hooks/flatHistoryEngine.js +101 -0
  78. package/dist/hooks/flatHistoryEngine.js.map +1 -0
  79. package/dist/hooks/useBackgroundTabHandler.d.ts +1 -0
  80. package/dist/hooks/useBackgroundTabHandler.js +38 -0
  81. package/dist/hooks/useBackgroundTabHandler.js.map +1 -0
  82. package/dist/hooks/useFastAnimationsOnReturn.d.ts +1 -0
  83. package/dist/hooks/useFastAnimationsOnReturn.js +38 -0
  84. package/dist/hooks/useFastAnimationsOnReturn.js.map +1 -0
  85. package/dist/hooks/useFlatHistory.js +120 -44
  86. package/dist/hooks/useFlatHistory.js.map +1 -1
  87. package/dist/locators/PileLocator.d.ts +5 -0
  88. package/dist/locators/PileLocator.js +9 -1
  89. package/dist/locators/PileLocator.js.map +1 -1
  90. package/package.json +80 -79
  91. package/dist/components/material/Wheel/WheelContent.d.ts +0 -13
  92. package/dist/components/material/Wheel/WheelContent.js +0 -37
  93. package/dist/components/material/Wheel/WheelContent.js.map +0 -1
  94. package/dist/hooks/useFailures.d.ts +0 -1
  95. package/dist/hooks/useFailures.js +0 -11
  96. package/dist/hooks/useFailures.js.map +0 -1
  97. package/dist/hooks/useWebP.d.ts +0 -1
  98. package/dist/hooks/useWebP.js +0 -13
  99. package/dist/hooks/useWebP.js.map +0 -1
@@ -20,124 +20,124 @@ export class GameErrorBoundary extends Component {
20
20
  return (_jsx("div", { css: containerCss, children: _jsxs("div", { css: cardCss, children: [_jsx("div", { css: iconContainerCss, children: _jsx(FontAwesomeIcon, { icon: faTriangleExclamation, css: iconCss }) }), _jsx("p", { css: messageCss, children: _jsx(Trans, { defaults: "A technical error has occurred. The error has been sent to the Game Park team.", i18nKey: "error.crash", ns: "common" }) }), _jsx("p", { css: hintCss, children: _jsx(Trans, { defaults: "You can refresh the page to continue your game.", i18nKey: "error.refresh.hint", ns: "common" }) }), _jsx("button", { css: buttonCss, onClick: () => window.location.reload(), children: _jsx(Trans, { defaults: "Refresh the page", i18nKey: "error.refresh.button", ns: "common" }) }), _jsx("div", { css: dividerCss }), _jsx("p", { css: secondaryMessageCss, children: _jsx(Trans, { defaults: "If the problem persists despite refreshing and the game is corrupted, please let us know on Discord.", i18nKey: "error.discord.hint", ns: "common" }) }), _jsxs("a", { css: discordLinkCss, href: "https://discord.gg/ZMCX5reQm8", target: "_blank", rel: "noopener noreferrer", children: [_jsx("svg", { css: discordIconCss, viewBox: "0 0 127.14 96.36", fill: "currentColor", children: _jsx("path", { d: "M107.7 8.07A105.15 105.15 0 0 0 81.47 0a72.06 72.06 0 0 0-3.36 6.83 97.68 97.68 0 0 0-29.11 0A72.37 72.37 0 0 0 45.64 0a105.89 105.89 0 0 0-26.25 8.09C2.79 32.65-1.71 56.6.54 80.21a105.73 105.73 0 0 0 32.17 16.15 77.7 77.7 0 0 0 6.89-11.11 68.42 68.42 0 0 1-10.85-5.18c.91-.66 1.8-1.34 2.66-2.04a75.57 75.57 0 0 0 64.32 0c.87.71 1.76 1.39 2.66 2.04a68.68 68.68 0 0 1-10.87 5.19 77.28 77.28 0 0 0 6.89 11.1 105.45 105.45 0 0 0 32.19-16.14c2.64-27.38-4.51-51.11-18.9-72.15ZM42.45 65.69C36.18 65.69 31 60 31 53.05c0-6.94 5.04-12.67 11.45-12.67S53.99 46.1 53.9 53.05c0 6.94-5.08 12.64-11.45 12.64Zm42.24 0C78.41 65.69 73.25 60 73.25 53.05c0-6.94 5.04-12.67 11.44-12.67s11.51 5.73 11.44 12.67c0 6.94-5.04 12.64-11.44 12.64Z" }) }), _jsx(Trans, { defaults: "Join the Game Park Discord", i18nKey: "error.discord.button", ns: "common" })] })] }) }));
21
21
  }
22
22
  }
23
- const fadeIn = keyframes `
24
- from {
25
- opacity: 0;
26
- transform: translateY(16px);
27
- }
28
- to {
29
- opacity: 1;
30
- transform: translateY(0);
31
- }
23
+ const fadeIn = keyframes `
24
+ from {
25
+ opacity: 0;
26
+ transform: translateY(16px);
27
+ }
28
+ to {
29
+ opacity: 1;
30
+ transform: translateY(0);
31
+ }
32
32
  `;
33
- const containerCss = css `
34
- display: flex;
35
- align-items: center;
36
- justify-content: center;
37
- height: 100%;
38
- width: 100%;
39
- padding: 2em;
40
- box-sizing: border-box;
41
- font-family: "Mulish", sans-serif;
33
+ const containerCss = css `
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ height: 100%;
38
+ width: 100%;
39
+ padding: 2em;
40
+ box-sizing: border-box;
41
+ font-family: "Mulish", sans-serif;
42
42
  `;
43
- const cardCss = css `
44
- display: flex;
45
- flex-direction: column;
46
- align-items: center;
47
- max-width: 460px;
48
- padding: 2.5em 2.5em 2em;
49
- border-radius: 1.2em;
50
- background: #002448;
51
- color: #eee;
52
- text-align: center;
53
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
54
- animation: ${fadeIn} 0.4s ease-out;
43
+ const cardCss = css `
44
+ display: flex;
45
+ flex-direction: column;
46
+ align-items: center;
47
+ max-width: 460px;
48
+ padding: 2.5em 2.5em 2em;
49
+ border-radius: 1.2em;
50
+ background: #002448;
51
+ color: #eee;
52
+ text-align: center;
53
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
54
+ animation: ${fadeIn} 0.4s ease-out;
55
55
  `;
56
- const iconContainerCss = css `
57
- display: flex;
58
- align-items: center;
59
- justify-content: center;
60
- width: 64px;
61
- height: 64px;
62
- border-radius: 50%;
63
- background: rgba(40, 184, 206, 0.15);
64
- margin-bottom: 1.2em;
56
+ const iconContainerCss = css `
57
+ display: flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ width: 64px;
61
+ height: 64px;
62
+ border-radius: 50%;
63
+ background: rgba(40, 184, 206, 0.15);
64
+ margin-bottom: 1.2em;
65
65
  `;
66
- const iconCss = css `
67
- font-size: 32px;
68
- color: #28B8CE;
66
+ const iconCss = css `
67
+ font-size: 32px;
68
+ color: #28B8CE;
69
69
  `;
70
- const messageCss = css `
71
- font-size: 1.05em;
72
- font-weight: 600;
73
- line-height: 1.5;
74
- margin: 0 0 0.3em;
70
+ const messageCss = css `
71
+ font-size: 1.05em;
72
+ font-weight: 600;
73
+ line-height: 1.5;
74
+ margin: 0 0 0.3em;
75
75
  `;
76
- const hintCss = css `
77
- font-size: 0.95em;
78
- line-height: 1.5;
79
- margin: 0;
80
- opacity: 0.8;
76
+ const hintCss = css `
77
+ font-size: 0.95em;
78
+ line-height: 1.5;
79
+ margin: 0;
80
+ opacity: 0.8;
81
81
  `;
82
- const buttonCss = css `
83
- margin-top: 1.5em;
84
- padding: 0.65em 2.2em;
85
- font-size: 1em;
86
- font-family: inherit;
87
- font-weight: 700;
88
- border: none;
89
- border-radius: 0.6em;
90
- background: #28B8CE;
91
- color: white;
92
- cursor: pointer;
93
- transition: background 0.2s, transform 0.1s;
94
- letter-spacing: 0.02em;
95
-
96
- &:hover {
97
- background: #24a5b9;
98
- }
99
-
100
- &:active {
101
- background: #2092a3;
102
- transform: scale(0.97);
103
- }
82
+ const buttonCss = css `
83
+ margin-top: 1.5em;
84
+ padding: 0.65em 2.2em;
85
+ font-size: 1em;
86
+ font-family: inherit;
87
+ font-weight: 700;
88
+ border: none;
89
+ border-radius: 0.6em;
90
+ background: #28B8CE;
91
+ color: white;
92
+ cursor: pointer;
93
+ transition: background 0.2s, transform 0.1s;
94
+ letter-spacing: 0.02em;
95
+
96
+ &:hover {
97
+ background: #24a5b9;
98
+ }
99
+
100
+ &:active {
101
+ background: #2092a3;
102
+ transform: scale(0.97);
103
+ }
104
104
  `;
105
- const dividerCss = css `
106
- width: 60%;
107
- height: 1px;
108
- background: rgba(255, 255, 255, 0.12);
109
- margin: 1.8em 0 1.2em;
105
+ const dividerCss = css `
106
+ width: 60%;
107
+ height: 1px;
108
+ background: rgba(255, 255, 255, 0.12);
109
+ margin: 1.8em 0 1.2em;
110
110
  `;
111
- const secondaryMessageCss = css `
112
- font-size: 0.85em;
113
- line-height: 1.6;
114
- margin: 0 0 1em;
115
- opacity: 0.65;
111
+ const secondaryMessageCss = css `
112
+ font-size: 0.85em;
113
+ line-height: 1.6;
114
+ margin: 0 0 1em;
115
+ opacity: 0.65;
116
116
  `;
117
- const discordLinkCss = css `
118
- display: inline-flex;
119
- align-items: center;
120
- gap: 0.5em;
121
- padding: 0.5em 1.4em;
122
- font-size: 0.9em;
123
- font-family: inherit;
124
- font-weight: 600;
125
- color: white;
126
- background: #5865F2;
127
- border-radius: 0.5em;
128
- text-decoration: none;
129
- transition: background 0.2s, transform 0.1s;
130
-
131
- &:hover {
132
- background: #4752C4;
133
- }
134
-
135
- &:active {
136
- transform: scale(0.97);
137
- }
117
+ const discordLinkCss = css `
118
+ display: inline-flex;
119
+ align-items: center;
120
+ gap: 0.5em;
121
+ padding: 0.5em 1.4em;
122
+ font-size: 0.9em;
123
+ font-family: inherit;
124
+ font-weight: 600;
125
+ color: white;
126
+ background: #5865F2;
127
+ border-radius: 0.5em;
128
+ text-decoration: none;
129
+ transition: background 0.2s, transform 0.1s;
130
+
131
+ &:hover {
132
+ background: #4752C4;
133
+ }
134
+
135
+ &:active {
136
+ transform: scale(0.97);
137
+ }
138
138
  `;
139
- const discordIconCss = css `
140
- width: 20px;
141
- height: 20px;
139
+ const discordIconCss = css `
140
+ width: 20px;
141
+ height: 20px;
142
142
  `;
143
143
  //# sourceMappingURL=GameErrorBoundary.js.map
@@ -0,0 +1,6 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ /**
3
+ * Internal providers that need access to the Redux store (i.e. must be inside Remote/LocalGameProvider).
4
+ * Keeps GameProvider clean — add future internal providers here.
5
+ */
6
+ export declare const GameInternalProviders: FC<PropsWithChildren>;
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "@emotion/react/jsx-runtime";
2
+ import { LogHistoryProvider } from '../Log/LogHistoryProvider';
3
+ /**
4
+ * Internal providers that need access to the Redux store (i.e. must be inside Remote/LocalGameProvider).
5
+ * Keeps GameProvider clean — add future internal providers here.
6
+ */
7
+ export const GameInternalProviders = ({ children }) => {
8
+ return (_jsx(LogHistoryProvider, { children: children }));
9
+ };
10
+ //# sourceMappingURL=GameInternalProviders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GameInternalProviders.js","sourceRoot":"","sources":["../../../src/components/GameProvider/GameInternalProviders.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAE9D;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC3E,OAAO,CACL,KAAC,kBAAkB,cAChB,QAAQ,GACU,CACtB,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ /**
3
+ * Bridge component that computes the log history and injects it into the existing gameContext.
4
+ * Only activates when logs are configured. Sits inside Remote/LocalGameProvider
5
+ * so it has access to the Redux store.
6
+ */
7
+ export declare const LogHistoryBridge: FC<PropsWithChildren>;
@@ -0,0 +1,23 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "@emotion/react/jsx-runtime";
2
+ import { useContext, useMemo } from 'react';
3
+ import { useLogHistoryProvider } from '../../hooks/useFlatHistory';
4
+ import { gameContext } from './GameContext';
5
+ /**
6
+ * Bridge component that computes the log history and injects it into the existing gameContext.
7
+ * Only activates when logs are configured. Sits inside Remote/LocalGameProvider
8
+ * so it has access to the Redux store.
9
+ */
10
+ export const LogHistoryBridge = ({ children }) => {
11
+ const parentContext = useContext(gameContext);
12
+ if (!parentContext.logs) {
13
+ return _jsx(_Fragment, { children: children });
14
+ }
15
+ return _jsx(LogHistoryBridgeInternal, { children: children });
16
+ };
17
+ const LogHistoryBridgeInternal = ({ children }) => {
18
+ const parentContext = useContext(gameContext);
19
+ const logHistory = useLogHistoryProvider();
20
+ const enrichedContext = useMemo(() => ({ ...parentContext, logHistory }), [parentContext, logHistory]);
21
+ return (_jsx(gameContext.Provider, { value: enrichedContext, children: children }));
22
+ };
23
+ //# sourceMappingURL=LogHistoryBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogHistoryBridge.js","sourceRoot":"","sources":["../../../src/components/GameProvider/LogHistoryBridge.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAyB,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,EAAe,WAAW,EAAE,MAAM,eAAe,CAAA;AAExD;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IACtE,MAAM,aAAa,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QACxB,OAAO,4BAAG,QAAQ,GAAI,CAAA;IACxB,CAAC;IACD,OAAO,KAAC,wBAAwB,cAAE,QAAQ,GAA4B,CAAA;AACxE,CAAC,CAAA;AAED,MAAM,wBAAwB,GAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IACvE,MAAM,aAAa,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IAC7C,MAAM,UAAU,GAAG,qBAAqB,EAAE,CAAA;IAE1C,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,aAAa,EAAE,UAAU,EAAE,CAAC,EACxC,CAAC,aAAa,EAAE,UAAU,CAAC,CAC5B,CAAA;IAED,OAAO,CACL,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,eAAe,YACzC,QAAQ,GACY,CACxB,CAAA;AACH,CAAC,CAAA"}
@@ -1,37 +1,55 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
2
- import { css, ThemeProvider, useTheme } from '@emotion/react';
2
+ import { css, keyframes, ThemeProvider, useTheme } from '@emotion/react';
3
3
  import { useGameSelector } from '@gamepark/react-client';
4
4
  import { useContext, useEffect, useMemo, useRef } from 'react';
5
+ import { useTranslation } from 'react-i18next';
5
6
  import { linkButtonCss } from '../../../css';
6
7
  import { useFlatHistory } from '../../../hooks/useFlatHistory';
7
- import { gameContext, LogItem } from '../../index';
8
+ import { gameContext } from '../../index';
8
9
  import { GameOverHistory } from './GameOverHistory';
10
+ import { LazyLogItem } from './LazyLogItem';
9
11
  import { SetupLogItem } from './SetupLogItem';
12
+ import { SharedIntersectionContext, useSharedObserver } from './SharedIntersectionContext';
10
13
  import { StartGameHistory } from './StartGameHistory';
11
14
  export const History = (props) => {
15
+ const { t } = useTranslation('common');
12
16
  const theme = useTheme();
13
17
  const context = useContext(gameContext);
14
18
  const setup = useGameSelector((state) => state.setup) ?? {};
15
- const { history } = useFlatHistory();
19
+ const { history, isLoaded } = useFlatHistory();
16
20
  const { open, ...rest } = props;
17
21
  const scrollRef = useRef(null);
22
+ const sharedObserver = useSharedObserver(scrollRef.current);
18
23
  const setupLogs = useMemo(() => {
19
24
  if (!context.logs?.getSetupLogDescriptions)
20
25
  return [];
21
26
  return context.logs.getSetupLogDescriptions(setup);
22
27
  }, [setup]);
28
+ // Scroll to bottom when loaded or when opening
23
29
  useEffect(() => {
24
- if (!scrollRef.current)
30
+ if (!scrollRef.current || !open || !isLoaded)
25
31
  return;
26
- const { scrollHeight, clientHeight } = scrollRef.current;
27
- scrollRef.current.scrollTo({ top: scrollHeight - clientHeight });
28
- }, [open]);
29
- return (_jsx(ThemeProvider, { theme: theme => ({ ...theme, buttons: historyButtonCss }), children: _jsx("div", { css: scrollCss, ref: scrollRef, ...rest, children: _jsxs("div", { css: scrollContentCss, children: [_jsx(StartGameHistory, {}), setupLogs.map((log, index) => _jsx(SetupLogItem, { log: log, game: setup, index: index, css: itemCss, customEntryCss: [customEntryCss, theme.journal?.historyEntry] }, `setup_${index}`)), history.map((h) => {
30
- if (!h.action.id)
31
- return null; // wait for server action.id
32
- const key = h.consequenceIndex !== undefined ? `${h.action.id}_${h.consequenceIndex}` : h.action.id;
33
- return _jsx(LogItem, { history: h, css: itemCss, customEntryCss: [customEntryCss, theme.journal?.historyEntry] }, key);
34
- }), _jsx(GameOverHistory, {})] }) }) }));
32
+ const el = scrollRef.current;
33
+ const scrollToBottom = () => el.scrollTo({ top: el.scrollHeight - el.clientHeight });
34
+ scrollToBottom();
35
+ const content = el.firstElementChild;
36
+ if (!content)
37
+ return;
38
+ const observer = new ResizeObserver(scrollToBottom);
39
+ observer.observe(content);
40
+ // Stop auto-scrolling as soon as the user scrolls manually
41
+ const onUserScroll = () => { observer.disconnect(); el.removeEventListener('wheel', onUserScroll); el.removeEventListener('touchmove', onUserScroll); };
42
+ el.addEventListener('wheel', onUserScroll, { once: true });
43
+ el.addEventListener('touchmove', onUserScroll, { once: true });
44
+ const timeout = setTimeout(() => { observer.disconnect(); onUserScroll(); }, 2000);
45
+ return () => { observer.disconnect(); clearTimeout(timeout); onUserScroll(); };
46
+ }, [open, isLoaded]);
47
+ return (_jsx(ThemeProvider, { theme: theme => ({ ...theme, buttons: historyButtonCss }), children: _jsx(SharedIntersectionContext.Provider, { value: sharedObserver, children: _jsx("div", { css: scrollCss, ref: scrollRef, ...rest, children: _jsxs("div", { css: scrollContentCss, children: [_jsx(StartGameHistory, {}), setupLogs.map((log, index) => _jsx(SetupLogItem, { log: log, game: setup, index: index, css: itemCss, customEntryCss: [customEntryCss, theme.journal?.historyEntry] }, `setup_${index}`)), !isLoaded && (_jsxs("div", { css: loaderCss, children: [_jsx("div", { css: spinnerCss }), t('history.loading', { defaultValue: 'Loading history...' })] })), history.map((h) => {
48
+ if (!h.action.id)
49
+ return null;
50
+ const key = h.consequenceIndex !== undefined ? `${h.action.id}_${h.consequenceIndex}` : h.action.id;
51
+ return _jsx(LazyLogItem, { history: h, itemCss: itemCss, customEntryCss: [customEntryCss, theme.journal?.historyEntry] }, key);
52
+ }), _jsx(GameOverHistory, {})] }) }) }) }));
35
53
  };
36
54
  const scrollCss = css `
37
55
  overflow-x: hidden;
@@ -74,4 +92,25 @@ const customEntryCss = css `
74
92
  background-color: rgba(0, 0, 0, 0.8);
75
93
  color: white;
76
94
  `;
95
+ const spin = keyframes `
96
+ to { transform: rotate(360deg); }
97
+ `;
98
+ const loaderCss = css `
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ gap: 1em;
103
+ padding: 2em;
104
+ color: rgba(255, 255, 255, 0.5);
105
+ font-size: 1.5em;
106
+ font-style: italic;
107
+ `;
108
+ const spinnerCss = css `
109
+ width: 1.2em;
110
+ height: 1.2em;
111
+ border: 2px solid rgba(255, 255, 255, 0.15);
112
+ border-top-color: rgba(255, 255, 255, 0.5);
113
+ border-radius: 50%;
114
+ animation: ${spin} 0.8s linear infinite;
115
+ `;
77
116
  //# sourceMappingURL=History.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"History.js","sourceRoot":"","sources":["../../../../src/components/JournalTabs/History/History.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"History.js","sourceRoot":"","sources":["../../../../src/components/JournalTabs/History/History.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Interpolation, Theme } from '@emotion/react';
2
+ import { FC } from 'react';
3
+ import { MoveHistory } from '../../../hooks/useFlatHistory';
4
+ type LazyLogItemProps = {
5
+ history: MoveHistory;
6
+ itemCss: Interpolation<Theme>;
7
+ customEntryCss: Interpolation<Theme>[];
8
+ };
9
+ export declare const LazyLogItem: FC<LazyLogItemProps>;
10
+ export {};
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx } from "@emotion/react/jsx-runtime";
2
+ import { memo, useCallback, useEffect, useRef, useState } from 'react';
3
+ import { LogItem } from '../../Log';
4
+ import { useSharedIntersection } from './SharedIntersectionContext';
5
+ export const LazyLogItem = memo(({ history, itemCss, customEntryCss }) => {
6
+ const ref = useRef(null);
7
+ const [isVisible, setIsVisible] = useState(false);
8
+ const measuredHeight = useRef(undefined);
9
+ const shared = useSharedIntersection();
10
+ const handleIntersection = useCallback((isIntersecting) => {
11
+ if (isIntersecting) {
12
+ setIsVisible(true);
13
+ }
14
+ else if (measuredHeight.current !== undefined) {
15
+ setIsVisible(false);
16
+ }
17
+ }, []);
18
+ useEffect(() => {
19
+ const el = ref.current;
20
+ if (!el || !shared)
21
+ return;
22
+ shared.observe(el, handleIntersection);
23
+ return () => shared.unobserve(el);
24
+ }, [shared, handleIntersection]);
25
+ useEffect(() => {
26
+ if (isVisible && ref.current) {
27
+ measuredHeight.current = ref.current.offsetHeight;
28
+ }
29
+ }, [isVisible]);
30
+ if (!isVisible) {
31
+ return _jsx("div", { ref: ref, style: { height: measuredHeight.current != null ? `${measuredHeight.current}px` : '2.8em' } });
32
+ }
33
+ return (_jsx("div", { ref: ref, children: _jsx(LogItem, { history: history, css: itemCss, customEntryCss: customEntryCss }) }));
34
+ });
35
+ //# sourceMappingURL=LazyLogItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LazyLogItem.js","sourceRoot":"","sources":["../../../../src/components/JournalTabs/History/LazyLogItem.tsx"],"names":[],"mappings":";AACA,OAAO,EAAM,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAE1E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AAQnE,MAAM,CAAC,MAAM,WAAW,GAAyB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE;IAC7F,MAAM,GAAG,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAA;IACxC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACjD,MAAM,cAAc,GAAG,MAAM,CAAqB,SAAS,CAAC,CAAA;IAC5D,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAA;IAEtC,MAAM,kBAAkB,GAAG,WAAW,CAAC,CAAC,cAAuB,EAAE,EAAE;QACjE,IAAI,cAAc,EAAE,CAAC;YACnB,YAAY,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;aAAM,IAAI,cAAc,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChD,YAAY,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAA;QACtB,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM;YAAE,OAAM;QAC1B,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAA;QACtC,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;IACnC,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAA;IAEhC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,SAAS,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAC7B,cAAc,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,CAAA;QACnD,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;IAEf,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,cAAK,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,cAAc,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAA;IACtH,CAAC;IAED,OAAO,CACL,cAAK,GAAG,EAAE,GAAG,YACX,KAAC,OAAO,IAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,GAAG,GACtE,CACP,CAAA;AACH,CAAC,CAAC,CAAA"}
@@ -3,24 +3,24 @@ import { css } from '@emotion/react';
3
3
  export const SetupLogItem = ({ log, game, index, customEntryCss, ...rest }) => {
4
4
  return (_jsx("div", { ...rest, children: _jsx("div", { css: [entryCss, customEntryCss, log.css], children: _jsx("div", { children: _jsx(log.Component, { game: game, index: index }) }) }) }));
5
5
  };
6
- const entryCss = css `
7
- width: 100%;
8
- background-color: rgba(0, 0, 0, 0.7);
9
- border-radius: 1em;
10
- margin-bottom: 0.5em;
11
- min-height: 1em;
12
- padding-left: 1em;
13
- margin-left: 0.05em;
14
- margin-top: 0.05em;
15
- padding-top: 0.5em;
16
- padding-bottom: 0.5em;
17
- display: flex;
18
- align-items: center;
19
- font-size: 2em;
20
- white-space: pre-wrap;
21
-
22
- img, picture {
23
- vertical-align: middle;
24
- }
6
+ const entryCss = css `
7
+ width: 100%;
8
+ background-color: rgba(0, 0, 0, 0.7);
9
+ border-radius: 1em;
10
+ margin-bottom: 0.5em;
11
+ min-height: 1em;
12
+ padding-left: 1em;
13
+ margin-left: 0.05em;
14
+ margin-top: 0.05em;
15
+ padding-top: 0.5em;
16
+ padding-bottom: 0.5em;
17
+ display: flex;
18
+ align-items: center;
19
+ font-size: 2em;
20
+ white-space: pre-wrap;
21
+
22
+ img, picture {
23
+ vertical-align: middle;
24
+ }
25
25
  `;
26
26
  //# sourceMappingURL=SetupLogItem.js.map
@@ -0,0 +1,9 @@
1
+ type ObserverCallback = (isIntersecting: boolean) => void;
2
+ export type SharedObserver = {
3
+ observe: (el: HTMLElement, callback: ObserverCallback) => void;
4
+ unobserve: (el: HTMLElement) => void;
5
+ };
6
+ export declare const SharedIntersectionContext: import("react").Context<SharedObserver | null>;
7
+ export declare const useSharedObserver: (root: HTMLElement | null) => SharedObserver | null;
8
+ export declare const useSharedIntersection: () => SharedObserver | null;
9
+ export {};
@@ -0,0 +1,36 @@
1
+ import { createContext, useContext, useEffect, useRef, useState } from 'react';
2
+ export const SharedIntersectionContext = createContext(null);
3
+ export const useSharedObserver = (root) => {
4
+ const callbacksRef = useRef(new Map());
5
+ const [observer, setObserver] = useState(null);
6
+ useEffect(() => {
7
+ if (!root)
8
+ return;
9
+ const io = new IntersectionObserver((entries) => {
10
+ for (const entry of entries) {
11
+ const cb = callbacksRef.current.get(entry.target);
12
+ if (cb)
13
+ cb(entry.isIntersecting);
14
+ }
15
+ }, { root, rootMargin: '300px 0px' });
16
+ const shared = {
17
+ observe: (el, callback) => {
18
+ callbacksRef.current.set(el, callback);
19
+ io.observe(el);
20
+ },
21
+ unobserve: (el) => {
22
+ callbacksRef.current.delete(el);
23
+ io.unobserve(el);
24
+ }
25
+ };
26
+ setObserver(shared);
27
+ return () => {
28
+ io.disconnect();
29
+ callbacksRef.current.clear();
30
+ setObserver(null);
31
+ };
32
+ }, [root]);
33
+ return observer;
34
+ };
35
+ export const useSharedIntersection = () => useContext(SharedIntersectionContext);
36
+ //# sourceMappingURL=SharedIntersectionContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SharedIntersectionContext.js","sourceRoot":"","sources":["../../../../src/components/JournalTabs/History/SharedIntersectionContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAS9E,MAAM,CAAC,MAAM,yBAAyB,GAAG,aAAa,CAAwB,IAAI,CAAC,CAAA;AAEnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAwB,EAAyB,EAAE;IACnF,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,EAA6B,CAAC,CAAA;IACjE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAwB,IAAI,CAAC,CAAA;IAErE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,MAAM,EAAE,GAAG,IAAI,oBAAoB,CACjC,CAAC,OAAO,EAAE,EAAE;YACV,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;gBACjD,IAAI,EAAE;oBAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;YAClC,CAAC;QACH,CAAC,EACD,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,CAClC,CAAA;QAED,MAAM,MAAM,GAAmB;YAC7B,OAAO,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE;gBACxB,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;gBACtC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;YAChB,CAAC;YACD,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE;gBAChB,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;gBAC/B,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YAClB,CAAC;SACF,CAAA;QAED,WAAW,CAAC,MAAM,CAAC,CAAA;QAEnB,OAAO,GAAG,EAAE;YACV,EAAE,CAAC,UAAU,EAAE,CAAA;YACf,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;YAC5B,WAAW,CAAC,IAAI,CAAC,CAAA;QACnB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { Interpolation, Theme } from '@emotion/react';
2
+ import { CSSProperties, FC } from 'react';
3
+ import { MoveHistory } from '../../../hooks/useFlatHistory';
4
+ export type VirtualizedLogItemProps = {
5
+ history: MoveHistory;
6
+ itemCss: Interpolation<Theme>;
7
+ customEntryCss: Interpolation<Theme>[];
8
+ };
9
+ export declare const VirtualizedLogItem: FC<VirtualizedLogItemProps & {
10
+ index: number;
11
+ style: CSSProperties;
12
+ }>;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "@emotion/react/jsx-runtime";
2
+ import { LogItem } from '../../Log';
3
+ export const VirtualizedLogItem = ({ history, itemCss, customEntryCss, style }) => {
4
+ return (_jsx("div", { style: style, children: _jsx(LogItem, { history: history, css: itemCss, customEntryCss: customEntryCss }) }));
5
+ };
6
+ //# sourceMappingURL=VirtualizedLogItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualizedLogItem.js","sourceRoot":"","sources":["../../../../src/components/JournalTabs/History/VirtualizedLogItem.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC,MAAM,CAAC,MAAM,kBAAkB,GAA0E,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE;IACvJ,OAAO,CACL,cAAK,KAAK,EAAE,KAAK,YACf,KAAC,OAAO,IAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,GAAG,GACtE,CACP,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ /**
3
+ * Provides log history via a dedicated context, isolated from gameContext.
4
+ * Only mounts the history processing when logs are configured.
5
+ * Changes to the log history only re-render components that consume logHistoryContext.
6
+ */
7
+ export declare const LogHistoryProvider: FC<PropsWithChildren>;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
2
+ import { useContext } from 'react';
3
+ import { logHistoryContext } from '../../hooks/LogHistoryContext';
4
+ import { useLogHistoryProvider } from '../../hooks/useFlatHistory';
5
+ import { gameContext } from '../GameProvider';
6
+ const LogHistoryProviderInternal = ({ children }) => {
7
+ const state = useLogHistoryProvider();
8
+ return (_jsx(logHistoryContext.Provider, { value: state, children: children }));
9
+ };
10
+ /**
11
+ * Provides log history via a dedicated context, isolated from gameContext.
12
+ * Only mounts the history processing when logs are configured.
13
+ * Changes to the log history only re-render components that consume logHistoryContext.
14
+ */
15
+ export const LogHistoryProvider = ({ children }) => {
16
+ const context = useContext(gameContext);
17
+ if (!context.logs) {
18
+ return _jsx(_Fragment, { children: children });
19
+ }
20
+ return (_jsx(LogHistoryProviderInternal, { children: children }));
21
+ };
22
+ //# sourceMappingURL=LogHistoryProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogHistoryProvider.js","sourceRoot":"","sources":["../../../src/components/Log/LogHistoryProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAyB,UAAU,EAAE,MAAM,OAAO,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7C,MAAM,0BAA0B,GAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IACzE,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAA;IACrC,OAAO,CACL,KAAC,iBAAiB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACrC,QAAQ,GACkB,CAC9B,CAAA;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IACxE,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACvC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,4BAAG,QAAQ,GAAI,CAAA;IACxB,CAAC;IACD,OAAO,CACL,KAAC,0BAA0B,cACxB,QAAQ,GACkB,CAC9B,CAAA;AACH,CAAC,CAAA"}