@rpg-engine/long-bow 0.1.8 → 0.1.11

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 (31) hide show
  1. package/dist/hooks/useEventListener.d.ts +1 -0
  2. package/dist/long-bow.cjs.development.js +44 -4
  3. package/dist/long-bow.cjs.development.js.map +1 -1
  4. package/dist/long-bow.cjs.production.min.js +1 -1
  5. package/dist/long-bow.cjs.production.min.js.map +1 -1
  6. package/dist/long-bow.esm.js +45 -5
  7. package/dist/long-bow.esm.js.map +1 -1
  8. package/dist/space.gif +0 -0
  9. package/package.json +6 -4
  10. package/src/NPCDialog/NPCDialog.tsx +6 -3
  11. package/src/NPCDialog/NPCDialogText.tsx +1 -1
  12. package/src/assets/npcDialog/npcThumbnails/alice.png +0 -0
  13. package/src/assets/npcDialog/npcThumbnails/tile000.png +0 -0
  14. package/src/assets/npcDialog/npcThumbnails/tile001.png +0 -0
  15. package/src/assets/npcDialog/npcThumbnails/tile002.png +0 -0
  16. package/src/assets/npcDialog/npcThumbnails/tile003.png +0 -0
  17. package/src/assets/npcDialog/npcThumbnails/tile004.png +0 -0
  18. package/src/assets/npcDialog/npcThumbnails/tile005.png +0 -0
  19. package/src/assets/npcDialog/npcThumbnails/tile006.png +0 -0
  20. package/src/assets/npcDialog/npcThumbnails/tile007.png +0 -0
  21. package/src/assets/npcDialog/npcThumbnails/tile008.png +0 -0
  22. package/src/assets/npcDialog/npcThumbnails/tile009.png +0 -0
  23. package/src/assets/npcDialog/npcThumbnails/tile010.png +0 -0
  24. package/src/assets/npcDialog/npcThumbnails/tile012.png +0 -0
  25. package/src/assets/npcDialog/npcThumbnails/tile013.png +0 -0
  26. package/src/assets/npcDialog/npcThumbnails/tile014.png +0 -0
  27. package/src/assets/npcDialog/npcThumbnails/tile015.png +0 -0
  28. package/src/assets/npcDialog/npcThumbnails/tile016.png +0 -0
  29. package/src/assets/npcDialog/npcThumbnails/tile017.png +0 -0
  30. package/src/assets/space.gif +0 -0
  31. package/src/hooks/useEventListener.ts +36 -0
@@ -0,0 +1 @@
1
+ export declare function useEventListener(eventName: string, handler: (e: any) => void, element?: Window & typeof globalThis): void;
@@ -9,7 +9,8 @@ var React__default = _interopDefault(React);
9
9
  var styled = _interopDefault(require('styled-components'));
10
10
  require('rpgui/rpgui.css');
11
11
  require('rpgui/rpgui.js');
12
- var useEventListener = _interopDefault(require('@use-it/event-listener'));
12
+
13
+ const img = require('./space.gif');
13
14
 
14
15
  var RPGUI = function RPGUI(_ref) {
15
16
  var children = _ref.children;
@@ -36,6 +37,42 @@ var Container = /*#__PURE__*/styled.div.withConfig({
36
37
  return width;
37
38
  });
38
39
 
40
+ function useEventListener(eventName, handler, element) {
41
+ if (element === void 0) {
42
+ element = window;
43
+ }
44
+
45
+ // Create a ref that stores handler
46
+ var savedHandler = React.useRef(); // Update ref.current value if handler changes.
47
+ // This allows our effect below to always get latest handler ...
48
+ // ... without us needing to pass it in effect deps array ...
49
+ // ... and potentially cause effect to re-run every render.
50
+
51
+ React.useEffect(function () {
52
+ //@ts-ignore
53
+ savedHandler.current = handler;
54
+ }, [handler]);
55
+ React.useEffect(function () {
56
+ // Make sure element supports addEventListener
57
+ // On
58
+ var isSupported = element && element.addEventListener;
59
+ if (!isSupported) return; // Create event listener that calls handler function stored in ref
60
+ //@ts-ignore
61
+
62
+ var eventListener = function eventListener(event) {
63
+ return savedHandler.current(event);
64
+ }; // Add event listener
65
+
66
+
67
+ element.addEventListener(eventName, eventListener); // Remove event listener on cleanup
68
+
69
+ return function () {
70
+ element.removeEventListener(eventName, eventListener);
71
+ };
72
+ }, [eventName, element] // Re-run if eventName or element changes
73
+ );
74
+ }
75
+
39
76
  var chunkString = function chunkString(str, length) {
40
77
  return str.match(new RegExp('.{1,' + length + '}', 'g'));
41
78
  };
@@ -132,7 +169,10 @@ var NPCDialog = function NPCDialog(_ref) {
132
169
 
133
170
  var _useState2 = React.useState(false),
134
171
  showGoNextIndicator = _useState2[0],
135
- setShowGoNextIndicator = _useState2[1];
172
+ setShowGoNextIndicator = _useState2[1]; //dynamically require npc thumbnail
173
+
174
+
175
+ var npcThumbnail = require("../assets/npcDialog/npcThumbnails/" + npcKey + ".png");
136
176
 
137
177
  return isOpen ? React__default.createElement(RPGUI, null, React__default.createElement(RPGUIContainer, {
138
178
  type: "framed-golden"
@@ -154,10 +194,10 @@ var NPCDialog = function NPCDialog(_ref) {
154
194
  }
155
195
  }
156
196
  })), type === exports.NPCDialogType.TextAndThumbnail && React__default.createElement(ThumbnailContainer, null, React__default.createElement(NPCThumbnail, {
157
- src: "/npcDialog/npcThumbnails/" + npcKey + ".png"
197
+ src: npcThumbnail
158
198
  }))), showGoNextIndicator && React__default.createElement(PressSpaceIndicator, {
159
199
  right: type === exports.NPCDialogType.TextOnly ? '1rem' : '10.5rem',
160
- src: "/space.gif"
200
+ src: img
161
201
  }))) : null;
162
202
  };
163
203
  var Container$2 = /*#__PURE__*/styled.div.withConfig({
@@ -1 +1 @@
1
- {"version":3,"file":"long-bow.cjs.development.js","sources":["../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/libs/StringHelpers.ts","../src/typography/DynamicText.tsx","../src/NPCDialog/NPCDialogText.tsx","../src/NPCDialog/NPCDialog.tsx"],"sourcesContent":["import React from 'react';\nimport 'rpgui/rpgui.css';\nimport 'rpgui/rpgui.js';\n\ninterface IProps {\n children: React.ReactNode;\n}\n\nexport const RPGUI: React.FC<IProps> = ({ children }) => {\n return <div className=\"rpgui-content\">{children}</div>;\n};\n","import React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n type: 'framed' | 'framed-golden' | 'framed-golden-2' | 'framed-grey';\n children: React.ReactNode;\n width?: string;\n}\n\nexport const RPGUIContainer: React.FC<IProps> = ({\n children,\n type,\n width = '50%',\n}) => {\n return (\n <Container width={width} className={`rpgui-container ${type}`}>\n {children}\n </Container>\n );\n};\n\ninterface IContainerProps {\n width: string;\n}\n\nconst Container = styled.div<IContainerProps>`\n max-width: ${({ width }) => width};\n`;\n","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\n};\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n text: string;\n onFinish?: () => void;\n onStart?: () => void;\n}\n\nexport const DynamicText: React.FC<IProps> = ({ text, onFinish, onStart }) => {\n const [textState, setTextState] = useState<string>('');\n\n useEffect(() => {\n let i = 0;\n const interval = setInterval(() => {\n // on every interval, show one more character\n\n if (i === 0) {\n if (onStart) {\n onStart();\n }\n }\n\n if (i < text.length) {\n setTextState(text.substring(0, i + 1));\n i++;\n } else {\n clearInterval(interval);\n if (onFinish) {\n onFinish();\n }\n }\n }, 50);\n\n return () => {\n clearInterval(interval);\n };\n }, [text]);\n\n return <TextContainer>{textState}</TextContainer>;\n};\n\nconst TextContainer = styled.p`\n font-size: 0.7rem !important;\n color: white;\n text-shadow: 1px 1px 0px #000000;\n letter-spacing: 1.2px;\n`;\n","import useEventListener from '@use-it/event-listener';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { chunkString } from '../libs/StringHelpers';\nimport { DynamicText } from '../typography/DynamicText';\n\ninterface IProps {\n text: string;\n onClose: () => void;\n onEndStep: () => void;\n onStartStep: () => void;\n}\n\nexport const NPCDialogText: React.FC<IProps> = ({\n text,\n onClose,\n onEndStep,\n onStartStep,\n}) => {\n const textChunks = chunkString(text, 85);\n\n const [chunkIndex, setChunkIndex] = useState<number>(0);\n\n useEventListener('keydown', (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n if (textChunks?.[chunkIndex + 1]) {\n setChunkIndex((prev) => prev + 1);\n } else {\n // if there's no more text chunks, close the dialog\n onClose();\n }\n }\n });\n\n return (\n <Container>\n <DynamicText\n text={textChunks?.[chunkIndex]!}\n onFinish={onEndStep}\n onStart={onStartStep}\n />\n </Container>\n );\n};\n\nconst Container = styled.div``;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport { NPCDialogText } from './NPCDialogText';\n\nexport enum NPCDialogType {\n TextOnly = 'TextOnly',\n TextAndThumbnail = 'TextAndThumbnail',\n}\n\nexport interface INPCDialogProps {\n text: string;\n type: NPCDialogType;\n npcKey: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n npcKey,\n onClose,\n}) => {\n const [isOpen, setIsOpen] = useState<boolean>(true);\n const [showGoNextIndicator, setShowGoNextIndicator] =\n useState<boolean>(false);\n\n return isOpen ? (\n <RPGUI>\n <RPGUIContainer type=\"framed-golden\">\n <Container>\n <TextContainer\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\n >\n <NPCDialogText\n onStartStep={() => setShowGoNextIndicator(false)}\n onEndStep={() => setShowGoNextIndicator(true)}\n text={text}\n onClose={() => {\n if (onClose) {\n onClose();\n setIsOpen(false);\n }\n }}\n />\n </TextContainer>\n {type === NPCDialogType.TextAndThumbnail && (\n <ThumbnailContainer>\n <NPCThumbnail src={`/npcDialog/npcThumbnails/${npcKey}.png`} />\n </ThumbnailContainer>\n )}\n </Container>\n {showGoNextIndicator && (\n <PressSpaceIndicator\n right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}\n src=\"/space.gif\"\n />\n )}\n </RPGUIContainer>\n </RPGUI>\n ) : null;\n};\n\nconst Container = styled.div`\n display: flex;\n width: 100%;\n height: 125px;\n box-sizing: border-box;\n justify-content: center;\n align-items: flex-start;\n position: relative;\n`;\n\ninterface ITextContainerProps {\n flex: string;\n}\n\nconst TextContainer = styled.div<ITextContainerProps>`\n flex: ${({ flex }) => flex} 0 0;\n width: 355px;\n`;\n\nconst ThumbnailContainer = styled.div`\n flex: 30% 0 0;\n display: flex;\n justify-content: flex-end;\n`;\n\nconst NPCThumbnail = styled.img`\n image-rendering: pixelated;\n height: 128px;\n width: 128px;\n`;\n\ninterface IPressSpaceIndicatorProps {\n right: string;\n}\n\nconst PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`\n position: absolute;\n right: ${({ right }) => right};\n bottom: 1rem;\n height: 20.7px;\n image-rendering: -webkit-optimize-contrast;\n`;\n"],"names":["RPGUI","children","React","className","RPGUIContainer","type","width","Container","styled","div","chunkString","str","length","match","RegExp","DynamicText","text","onFinish","onStart","useState","textState","setTextState","useEffect","i","interval","setInterval","substring","clearInterval","TextContainer","p","NPCDialogText","onClose","onEndStep","onStartStep","textChunks","chunkIndex","setChunkIndex","useEventListener","event","code","prev","NPCDialogType","NPCDialog","npcKey","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","flex","TextAndThumbnail","ThumbnailContainer","NPCThumbnail","src","PressSpaceIndicator","right","TextOnly","img"],"mappings":"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"}
1
+ {"version":3,"file":"long-bow.cjs.development.js","sources":["../src/assets/space.gif","../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/hooks/useEventListener.ts","../src/libs/StringHelpers.ts","../src/typography/DynamicText.tsx","../src/NPCDialog/NPCDialogText.tsx","../src/NPCDialog/NPCDialog.tsx"],"sourcesContent":["const img = require('./space.gif'); export default img;","import React from 'react';\nimport 'rpgui/rpgui.css';\nimport 'rpgui/rpgui.js';\n\ninterface IProps {\n children: React.ReactNode;\n}\n\nexport const RPGUI: React.FC<IProps> = ({ children }) => {\n return <div className=\"rpgui-content\">{children}</div>;\n};\n","import React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n type: 'framed' | 'framed-golden' | 'framed-golden-2' | 'framed-grey';\n children: React.ReactNode;\n width?: string;\n}\n\nexport const RPGUIContainer: React.FC<IProps> = ({\n children,\n type,\n width = '50%',\n}) => {\n return (\n <Container width={width} className={`rpgui-container ${type}`}>\n {children}\n </Container>\n );\n};\n\ninterface IContainerProps {\n width: string;\n}\n\nconst Container = styled.div<IContainerProps>`\n max-width: ${({ width }) => width};\n`;\n","import { useEffect, useRef } from 'react';\n\nexport function useEventListener(\n eventName: string,\n handler: (e: any) => void,\n element = window\n) {\n // Create a ref that stores handler\n const savedHandler = useRef();\n // Update ref.current value if handler changes.\n // This allows our effect below to always get latest handler ...\n // ... without us needing to pass it in effect deps array ...\n // ... and potentially cause effect to re-run every render.\n useEffect(() => {\n //@ts-ignore\n savedHandler.current = handler;\n }, [handler]);\n useEffect(\n () => {\n // Make sure element supports addEventListener\n // On\n const isSupported = element && element.addEventListener;\n if (!isSupported) return;\n // Create event listener that calls handler function stored in ref\n //@ts-ignore\n const eventListener = (event: any) => savedHandler.current(event);\n // Add event listener\n element.addEventListener(eventName, eventListener);\n // Remove event listener on cleanup\n return () => {\n element.removeEventListener(eventName, eventListener);\n };\n },\n [eventName, element] // Re-run if eventName or element changes\n );\n}\n","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\n};\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n text: string;\n onFinish?: () => void;\n onStart?: () => void;\n}\n\nexport const DynamicText: React.FC<IProps> = ({ text, onFinish, onStart }) => {\n const [textState, setTextState] = useState<string>('');\n\n useEffect(() => {\n let i = 0;\n const interval = setInterval(() => {\n // on every interval, show one more character\n\n if (i === 0) {\n if (onStart) {\n onStart();\n }\n }\n\n if (i < text.length) {\n setTextState(text.substring(0, i + 1));\n i++;\n } else {\n clearInterval(interval);\n if (onFinish) {\n onFinish();\n }\n }\n }, 50);\n\n return () => {\n clearInterval(interval);\n };\n }, [text]);\n\n return <TextContainer>{textState}</TextContainer>;\n};\n\nconst TextContainer = styled.p`\n font-size: 0.7rem !important;\n color: white;\n text-shadow: 1px 1px 0px #000000;\n letter-spacing: 1.2px;\n`;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { useEventListener } from '../hooks/useEventListener';\nimport { chunkString } from '../libs/StringHelpers';\nimport { DynamicText } from '../typography/DynamicText';\n\ninterface IProps {\n text: string;\n onClose: () => void;\n onEndStep: () => void;\n onStartStep: () => void;\n}\n\nexport const NPCDialogText: React.FC<IProps> = ({\n text,\n onClose,\n onEndStep,\n onStartStep,\n}) => {\n const textChunks = chunkString(text, 85);\n\n const [chunkIndex, setChunkIndex] = useState<number>(0);\n\n useEventListener('keydown', (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n if (textChunks?.[chunkIndex + 1]) {\n setChunkIndex((prev) => prev + 1);\n } else {\n // if there's no more text chunks, close the dialog\n onClose();\n }\n }\n });\n\n return (\n <Container>\n <DynamicText\n text={textChunks?.[chunkIndex]!}\n onFinish={onEndStep}\n onStart={onStartStep}\n />\n </Container>\n );\n};\n\nconst Container = styled.div``;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport pressSpaceGif from '../assets/space.gif';\nimport { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport { NPCDialogText } from './NPCDialogText';\nexport enum NPCDialogType {\n TextOnly = 'TextOnly',\n TextAndThumbnail = 'TextAndThumbnail',\n}\n\nexport interface INPCDialogProps {\n text: string;\n type: NPCDialogType;\n npcKey: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n npcKey,\n onClose,\n}) => {\n const [isOpen, setIsOpen] = useState<boolean>(true);\n const [showGoNextIndicator, setShowGoNextIndicator] =\n useState<boolean>(false);\n\n //dynamically require npc thumbnail\n const npcThumbnail = require(`../assets/npcDialog/npcThumbnails/${npcKey}.png`);\n\n return isOpen ? (\n <RPGUI>\n <RPGUIContainer type=\"framed-golden\">\n <Container>\n <TextContainer\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\n >\n <NPCDialogText\n onStartStep={() => setShowGoNextIndicator(false)}\n onEndStep={() => setShowGoNextIndicator(true)}\n text={text}\n onClose={() => {\n if (onClose) {\n onClose();\n setIsOpen(false);\n }\n }}\n />\n </TextContainer>\n {type === NPCDialogType.TextAndThumbnail && (\n <ThumbnailContainer>\n <NPCThumbnail src={npcThumbnail} />\n </ThumbnailContainer>\n )}\n </Container>\n {showGoNextIndicator && (\n <PressSpaceIndicator\n right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}\n src={pressSpaceGif}\n />\n )}\n </RPGUIContainer>\n </RPGUI>\n ) : null;\n};\n\nconst Container = styled.div`\n display: flex;\n width: 100%;\n height: 125px;\n box-sizing: border-box;\n justify-content: center;\n align-items: flex-start;\n position: relative;\n`;\n\ninterface ITextContainerProps {\n flex: string;\n}\n\nconst TextContainer = styled.div<ITextContainerProps>`\n flex: ${({ flex }) => flex} 0 0;\n width: 355px;\n`;\n\nconst ThumbnailContainer = styled.div`\n flex: 30% 0 0;\n display: flex;\n justify-content: flex-end;\n`;\n\nconst NPCThumbnail = styled.img`\n image-rendering: pixelated;\n height: 128px;\n width: 128px;\n`;\n\ninterface IPressSpaceIndicatorProps {\n right: string;\n}\n\nconst PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`\n position: absolute;\n right: ${({ right }) => right};\n bottom: 1rem;\n height: 20.7px;\n image-rendering: -webkit-optimize-contrast;\n`;\n"],"names":["RPGUI","children","React","className","RPGUIContainer","type","width","Container","styled","div","useEventListener","eventName","handler","element","window","savedHandler","useRef","useEffect","current","isSupported","addEventListener","eventListener","event","removeEventListener","chunkString","str","length","match","RegExp","DynamicText","text","onFinish","onStart","useState","textState","setTextState","i","interval","setInterval","substring","clearInterval","TextContainer","p","NPCDialogText","onClose","onEndStep","onStartStep","textChunks","chunkIndex","setChunkIndex","code","prev","NPCDialogType","NPCDialog","npcKey","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","npcThumbnail","require","flex","TextAndThumbnail","ThumbnailContainer","NPCThumbnail","src","PressSpaceIndicator","right","TextOnly","pressSpaceGif","img"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),n=e(t),i=e(require("styled-components"));require("rpgui/rpgui.css"),require("rpgui/rpgui.js");var r,o=e(require("@use-it/event-listener")),a=function(e){return n.createElement("div",{className:"rpgui-content"},e.children)},l=function(e){var t=e.width;return n.createElement(c,{width:void 0===t?"50%":t,className:"rpgui-container "+e.type},e.children)},c=i.div.withConfig({displayName:"RPGUIContainer__Container",componentId:"sc-3xvrxc-0"})(["max-width:",";"],(function(e){return e.width})),s=function(e){var i=e.text,r=e.onFinish,o=e.onStart,a=t.useState(""),l=a[0],c=a[1];return t.useEffect((function(){var e=0,t=setInterval((function(){0===e&&o&&o(),e<i.length?(c(i.substring(0,e+1)),e++):(clearInterval(t),r&&r())}),50);return function(){clearInterval(t)}}),[i]),n.createElement(p,null,l)},p=i.p.withConfig({displayName:"DynamicText__TextContainer",componentId:"sc-acj2q5-0"})(["font-size:0.7rem !important;color:white;text-shadow:1px 1px 0px #000000;letter-spacing:1.2px;"]),u=function(e){var i=e.onClose,r=e.onEndStep,a=e.onStartStep,l=e.text.match(new RegExp(".{1,85}","g")),c=t.useState(0),p=c[0],u=c[1];return o("keydown",(function(e){"Space"===e.code&&(null!=l&&l[p+1]?u((function(e){return e+1})):i())})),n.createElement(m,null,n.createElement(s,{text:null==l?void 0:l[p],onFinish:r,onStart:a}))},m=i.div.withConfig({displayName:"NPCDialogText__Container",componentId:"sc-ahseq0-0"})([""]);(r=exports.NPCDialogType||(exports.NPCDialogType={})).TextOnly="TextOnly",r.TextAndThumbnail="TextAndThumbnail";var d=i.div.withConfig({displayName:"NPCDialog__Container",componentId:"sc-omm2zk-0"})(["display:flex;width:100%;height:125px;box-sizing:border-box;justify-content:center;align-items:flex-start;position:relative;"]),x=i.div.withConfig({displayName:"NPCDialog__TextContainer",componentId:"sc-omm2zk-1"})(["flex:"," 0 0;width:355px;"],(function(e){return e.flex})),g=i.div.withConfig({displayName:"NPCDialog__ThumbnailContainer",componentId:"sc-omm2zk-2"})(["flex:30% 0 0;display:flex;justify-content:flex-end;"]),f=i.img.withConfig({displayName:"NPCDialog__NPCThumbnail",componentId:"sc-omm2zk-3"})(["image-rendering:pixelated;height:128px;width:128px;"]),h=i.img.withConfig({displayName:"NPCDialog__PressSpaceIndicator",componentId:"sc-omm2zk-4"})(["position:absolute;right:",";bottom:1rem;height:20.7px;image-rendering:-webkit-optimize-contrast;"],(function(e){return e.right}));exports.DynamicText=s,exports.NPCDialog=function(e){var i=e.text,r=e.type,o=e.npcKey,c=e.onClose,s=t.useState(!0),p=s[0],m=s[1],C=t.useState(!1),y=C[0],T=C[1];return p?n.createElement(a,null,n.createElement(l,{type:"framed-golden"},n.createElement(d,null,n.createElement(x,{flex:r===exports.NPCDialogType.TextAndThumbnail?"70%":"100%"},n.createElement(u,{onStartStep:function(){return T(!1)},onEndStep:function(){return T(!0)},text:i,onClose:function(){c&&(c(),m(!1))}})),r===exports.NPCDialogType.TextAndThumbnail&&n.createElement(g,null,n.createElement(f,{src:"/npcDialog/npcThumbnails/"+o+".png"}))),y&&n.createElement(h,{right:r===exports.NPCDialogType.TextOnly?"1rem":"10.5rem",src:"/space.gif"}))):null},exports.RPGUI=a,exports.RPGUIContainer=l;
1
+ "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),n=e(t),i=e(require("styled-components"));require("rpgui/rpgui.css"),require("rpgui/rpgui.js");const r=require("./space.gif");var o,a=function(e){return n.createElement("div",{className:"rpgui-content"},e.children)},l=function(e){var t=e.width;return n.createElement(c,{width:void 0===t?"50%":t,className:"rpgui-container "+e.type},e.children)},c=i.div.withConfig({displayName:"RPGUIContainer__Container",componentId:"sc-3xvrxc-0"})(["max-width:",";"],(function(e){return e.width})),u=function(e){var i=e.text,r=e.onFinish,o=e.onStart,a=t.useState(""),l=a[0],c=a[1];return t.useEffect((function(){var e=0,t=setInterval((function(){0===e&&o&&o(),e<i.length?(c(i.substring(0,e+1)),e++):(clearInterval(t),r&&r())}),50);return function(){clearInterval(t)}}),[i]),n.createElement(s,null,l)},s=i.p.withConfig({displayName:"DynamicText__TextContainer",componentId:"sc-acj2q5-0"})(["font-size:0.7rem !important;color:white;text-shadow:1px 1px 0px #000000;letter-spacing:1.2px;"]),p=function(e){var i=e.onClose,r=e.onEndStep,o=e.onStartStep,a=e.text.match(new RegExp(".{1,85}","g")),l=t.useState(0),c=l[0],s=l[1];return function(e,n,i){void 0===i&&(i=window);var r=t.useRef();t.useEffect((function(){r.current=n}),[n]),t.useEffect((function(){if(i&&i.addEventListener){var e=function(e){return r.current(e)};return i.addEventListener("keydown",e),function(){i.removeEventListener("keydown",e)}}}),["keydown",i])}(0,(function(e){"Space"===e.code&&(null!=a&&a[c+1]?s((function(e){return e+1})):i())})),n.createElement(m,null,n.createElement(u,{text:null==a?void 0:a[c],onFinish:r,onStart:o}))},m=i.div.withConfig({displayName:"NPCDialogText__Container",componentId:"sc-ahseq0-0"})([""]);(o=exports.NPCDialogType||(exports.NPCDialogType={})).TextOnly="TextOnly",o.TextAndThumbnail="TextAndThumbnail";var d=i.div.withConfig({displayName:"NPCDialog__Container",componentId:"sc-omm2zk-0"})(["display:flex;width:100%;height:125px;box-sizing:border-box;justify-content:center;align-items:flex-start;position:relative;"]),f=i.div.withConfig({displayName:"NPCDialog__TextContainer",componentId:"sc-omm2zk-1"})(["flex:"," 0 0;width:355px;"],(function(e){return e.flex})),x=i.div.withConfig({displayName:"NPCDialog__ThumbnailContainer",componentId:"sc-omm2zk-2"})(["flex:30% 0 0;display:flex;justify-content:flex-end;"]),g=i.img.withConfig({displayName:"NPCDialog__NPCThumbnail",componentId:"sc-omm2zk-3"})(["image-rendering:pixelated;height:128px;width:128px;"]),h=i.img.withConfig({displayName:"NPCDialog__PressSpaceIndicator",componentId:"sc-omm2zk-4"})(["position:absolute;right:",";bottom:1rem;height:20.7px;image-rendering:-webkit-optimize-contrast;"],(function(e){return e.right}));exports.DynamicText=u,exports.NPCDialog=function(e){var i=e.text,o=e.type,c=e.npcKey,u=e.onClose,s=t.useState(!0),m=s[0],y=s[1],C=t.useState(!1),v=C[0],w=C[1],T=require("../assets/npcDialog/npcThumbnails/"+c+".png");return m?n.createElement(a,null,n.createElement(l,{type:"framed-golden"},n.createElement(d,null,n.createElement(f,{flex:o===exports.NPCDialogType.TextAndThumbnail?"70%":"100%"},n.createElement(p,{onStartStep:function(){return w(!1)},onEndStep:function(){return w(!0)},text:i,onClose:function(){u&&(u(),y(!1))}})),o===exports.NPCDialogType.TextAndThumbnail&&n.createElement(x,null,n.createElement(g,{src:T}))),v&&n.createElement(h,{right:o===exports.NPCDialogType.TextOnly?"1rem":"10.5rem",src:r}))):null},exports.RPGUI=a,exports.RPGUIContainer=l;
2
2
  //# sourceMappingURL=long-bow.cjs.production.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"long-bow.cjs.production.min.js","sources":["../src/NPCDialog/NPCDialog.tsx","../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/typography/DynamicText.tsx","../src/NPCDialog/NPCDialogText.tsx","../src/libs/StringHelpers.ts"],"sourcesContent":["import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport { NPCDialogText } from './NPCDialogText';\n\nexport enum NPCDialogType {\n TextOnly = 'TextOnly',\n TextAndThumbnail = 'TextAndThumbnail',\n}\n\nexport interface INPCDialogProps {\n text: string;\n type: NPCDialogType;\n npcKey: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n npcKey,\n onClose,\n}) => {\n const [isOpen, setIsOpen] = useState<boolean>(true);\n const [showGoNextIndicator, setShowGoNextIndicator] =\n useState<boolean>(false);\n\n return isOpen ? (\n <RPGUI>\n <RPGUIContainer type=\"framed-golden\">\n <Container>\n <TextContainer\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\n >\n <NPCDialogText\n onStartStep={() => setShowGoNextIndicator(false)}\n onEndStep={() => setShowGoNextIndicator(true)}\n text={text}\n onClose={() => {\n if (onClose) {\n onClose();\n setIsOpen(false);\n }\n }}\n />\n </TextContainer>\n {type === NPCDialogType.TextAndThumbnail && (\n <ThumbnailContainer>\n <NPCThumbnail src={`/npcDialog/npcThumbnails/${npcKey}.png`} />\n </ThumbnailContainer>\n )}\n </Container>\n {showGoNextIndicator && (\n <PressSpaceIndicator\n right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}\n src=\"/space.gif\"\n />\n )}\n </RPGUIContainer>\n </RPGUI>\n ) : null;\n};\n\nconst Container = styled.div`\n display: flex;\n width: 100%;\n height: 125px;\n box-sizing: border-box;\n justify-content: center;\n align-items: flex-start;\n position: relative;\n`;\n\ninterface ITextContainerProps {\n flex: string;\n}\n\nconst TextContainer = styled.div<ITextContainerProps>`\n flex: ${({ flex }) => flex} 0 0;\n width: 355px;\n`;\n\nconst ThumbnailContainer = styled.div`\n flex: 30% 0 0;\n display: flex;\n justify-content: flex-end;\n`;\n\nconst NPCThumbnail = styled.img`\n image-rendering: pixelated;\n height: 128px;\n width: 128px;\n`;\n\ninterface IPressSpaceIndicatorProps {\n right: string;\n}\n\nconst PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`\n position: absolute;\n right: ${({ right }) => right};\n bottom: 1rem;\n height: 20.7px;\n image-rendering: -webkit-optimize-contrast;\n`;\n","import React from 'react';\nimport 'rpgui/rpgui.css';\nimport 'rpgui/rpgui.js';\n\ninterface IProps {\n children: React.ReactNode;\n}\n\nexport const RPGUI: React.FC<IProps> = ({ children }) => {\n return <div className=\"rpgui-content\">{children}</div>;\n};\n","import React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n type: 'framed' | 'framed-golden' | 'framed-golden-2' | 'framed-grey';\n children: React.ReactNode;\n width?: string;\n}\n\nexport const RPGUIContainer: React.FC<IProps> = ({\n children,\n type,\n width = '50%',\n}) => {\n return (\n <Container width={width} className={`rpgui-container ${type}`}>\n {children}\n </Container>\n );\n};\n\ninterface IContainerProps {\n width: string;\n}\n\nconst Container = styled.div<IContainerProps>`\n max-width: ${({ width }) => width};\n`;\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n text: string;\n onFinish?: () => void;\n onStart?: () => void;\n}\n\nexport const DynamicText: React.FC<IProps> = ({ text, onFinish, onStart }) => {\n const [textState, setTextState] = useState<string>('');\n\n useEffect(() => {\n let i = 0;\n const interval = setInterval(() => {\n // on every interval, show one more character\n\n if (i === 0) {\n if (onStart) {\n onStart();\n }\n }\n\n if (i < text.length) {\n setTextState(text.substring(0, i + 1));\n i++;\n } else {\n clearInterval(interval);\n if (onFinish) {\n onFinish();\n }\n }\n }, 50);\n\n return () => {\n clearInterval(interval);\n };\n }, [text]);\n\n return <TextContainer>{textState}</TextContainer>;\n};\n\nconst TextContainer = styled.p`\n font-size: 0.7rem !important;\n color: white;\n text-shadow: 1px 1px 0px #000000;\n letter-spacing: 1.2px;\n`;\n","import useEventListener from '@use-it/event-listener';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { chunkString } from '../libs/StringHelpers';\nimport { DynamicText } from '../typography/DynamicText';\n\ninterface IProps {\n text: string;\n onClose: () => void;\n onEndStep: () => void;\n onStartStep: () => void;\n}\n\nexport const NPCDialogText: React.FC<IProps> = ({\n text,\n onClose,\n onEndStep,\n onStartStep,\n}) => {\n const textChunks = chunkString(text, 85);\n\n const [chunkIndex, setChunkIndex] = useState<number>(0);\n\n useEventListener('keydown', (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n if (textChunks?.[chunkIndex + 1]) {\n setChunkIndex((prev) => prev + 1);\n } else {\n // if there's no more text chunks, close the dialog\n onClose();\n }\n }\n });\n\n return (\n <Container>\n <DynamicText\n text={textChunks?.[chunkIndex]!}\n onFinish={onEndStep}\n onStart={onStartStep}\n />\n </Container>\n );\n};\n\nconst Container = styled.div``;\n","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\n};\n"],"names":["NPCDialogType","RPGUI","React","className","children","RPGUIContainer","width","Container","type","styled","div","DynamicText","text","onFinish","onStart","useState","textState","setTextState","useEffect","i","interval","setInterval","length","substring","clearInterval","TextContainer","p","NPCDialogText","onClose","onEndStep","onStartStep","textChunks","match","RegExp","chunkIndex","setChunkIndex","useEventListener","event","code","prev","flex","ThumbnailContainer","NPCThumbnail","img","PressSpaceIndicator","right","npcKey","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","TextAndThumbnail","src","TextOnly"],"mappings":"mQAMYA,yCCECC,EAA0B,mBAC9BC,uBAAKC,UAAU,mBADkBC,WCC7BC,EAAmC,oBAG9CC,aAGEJ,gBAACK,GAAUD,iBAHL,QAGmBH,+BAJ3BK,QADAJ,WAeIG,EAAYE,EAAOC,mFAAPD,qBACH,qBAAGH,SCjBLK,EAAgC,gBAAGC,IAAAA,KAAMC,IAAAA,SAAUC,IAAAA,UAC5BC,WAAiB,IAA5CC,OAAWC,cAElBC,aAAU,eACJC,EAAI,EACFC,EAAWC,aAAY,WAGjB,IAANF,GACEL,GACFA,IAIAK,EAAIP,EAAKU,QACXL,EAAaL,EAAKW,UAAU,EAAGJ,EAAI,IACnCA,MAEAK,cAAcJ,GACVP,GACFA,OAGH,WAEI,WACLW,cAAcJ,MAEf,CAACR,IAEGV,gBAACuB,OAAeT,IAGnBS,EAAgBhB,EAAOiB,kFAAPjB,oGC7BTkB,EAAkC,gBAE7CC,IAAAA,QACAC,IAAAA,UACAC,IAAAA,YAEMC,IALNnB,KCbWoB,MAAM,IAAIC,OAAO,UAAuB,QDoBflB,WAAiB,GAA9CmB,OAAYC,cAEnBC,EAAiB,WAAW,SAACC,GACR,UAAfA,EAAMC,aACJP,GAAAA,EAAaG,EAAa,GAC5BC,GAAc,SAACI,UAASA,EAAO,KAG/BX,QAMJ1B,gBAACK,OACCL,gBAACS,GACCC,WAAMmB,SAAAA,EAAaG,GACnBrB,SAAUgB,EACVf,QAASgB,MAMXvB,EAAYE,EAAOC,kFAAPD,QJvCNT,EAAAA,wBAAAA,+CAEVA,0CAwDIO,EAAYE,EAAOC,8EAAPD,kIAcZgB,EAAgBhB,EAAOC,kFAAPD,gCACZ,qBAAG+B,QAIPC,EAAqBhC,EAAOC,uFAAPD,0DAMrBiC,EAAejC,EAAOkC,iFAAPlC,0DAUfmC,EAAsBnC,EAAOkC,wFAAPlC,uGAEjB,qBAAGoC,iDAnFsC,gBAClDjC,IAAAA,KACAJ,IAAAA,KACAsC,IAAAA,OACAlB,IAAAA,UAE4Bb,YAAkB,GAAvCgC,OAAQC,SAEbjC,YAAkB,GADbkC,OAAqBC,cAGrBH,EACL7C,gBAACD,OACCC,gBAACG,GAAeG,KAAK,iBACnBN,gBAACK,OACCL,gBAACuB,GACCe,KAAMhC,IAASR,sBAAcmD,iBAAmB,MAAQ,QAExDjD,gBAACyB,GACCG,YAAa,kBAAMoB,GAAuB,IAC1CrB,UAAW,kBAAMqB,GAAuB,IACxCtC,KAAMA,EACNgB,QAAS,WACHA,IACFA,IACAoB,GAAU,QAKjBxC,IAASR,sBAAcmD,kBACtBjD,gBAACuC,OACCvC,gBAACwC,GAAaU,gCAAiCN,aAIpDG,GACC/C,gBAAC0C,GACCC,MAAOrC,IAASR,sBAAcqD,SAAW,OAAS,UAClDD,IAAI,iBAKV"}
1
+ {"version":3,"file":"long-bow.cjs.production.min.js","sources":["../src/assets/space.gif","../src/NPCDialog/NPCDialog.tsx","../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/typography/DynamicText.tsx","../src/NPCDialog/NPCDialogText.tsx","../src/libs/StringHelpers.ts","../src/hooks/useEventListener.ts"],"sourcesContent":["const img = require('./space.gif'); export default img;","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport pressSpaceGif from '../assets/space.gif';\nimport { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport { NPCDialogText } from './NPCDialogText';\nexport enum NPCDialogType {\n TextOnly = 'TextOnly',\n TextAndThumbnail = 'TextAndThumbnail',\n}\n\nexport interface INPCDialogProps {\n text: string;\n type: NPCDialogType;\n npcKey: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n npcKey,\n onClose,\n}) => {\n const [isOpen, setIsOpen] = useState<boolean>(true);\n const [showGoNextIndicator, setShowGoNextIndicator] =\n useState<boolean>(false);\n\n //dynamically require npc thumbnail\n const npcThumbnail = require(`../assets/npcDialog/npcThumbnails/${npcKey}.png`);\n\n return isOpen ? (\n <RPGUI>\n <RPGUIContainer type=\"framed-golden\">\n <Container>\n <TextContainer\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\n >\n <NPCDialogText\n onStartStep={() => setShowGoNextIndicator(false)}\n onEndStep={() => setShowGoNextIndicator(true)}\n text={text}\n onClose={() => {\n if (onClose) {\n onClose();\n setIsOpen(false);\n }\n }}\n />\n </TextContainer>\n {type === NPCDialogType.TextAndThumbnail && (\n <ThumbnailContainer>\n <NPCThumbnail src={npcThumbnail} />\n </ThumbnailContainer>\n )}\n </Container>\n {showGoNextIndicator && (\n <PressSpaceIndicator\n right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}\n src={pressSpaceGif}\n />\n )}\n </RPGUIContainer>\n </RPGUI>\n ) : null;\n};\n\nconst Container = styled.div`\n display: flex;\n width: 100%;\n height: 125px;\n box-sizing: border-box;\n justify-content: center;\n align-items: flex-start;\n position: relative;\n`;\n\ninterface ITextContainerProps {\n flex: string;\n}\n\nconst TextContainer = styled.div<ITextContainerProps>`\n flex: ${({ flex }) => flex} 0 0;\n width: 355px;\n`;\n\nconst ThumbnailContainer = styled.div`\n flex: 30% 0 0;\n display: flex;\n justify-content: flex-end;\n`;\n\nconst NPCThumbnail = styled.img`\n image-rendering: pixelated;\n height: 128px;\n width: 128px;\n`;\n\ninterface IPressSpaceIndicatorProps {\n right: string;\n}\n\nconst PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`\n position: absolute;\n right: ${({ right }) => right};\n bottom: 1rem;\n height: 20.7px;\n image-rendering: -webkit-optimize-contrast;\n`;\n","import React from 'react';\nimport 'rpgui/rpgui.css';\nimport 'rpgui/rpgui.js';\n\ninterface IProps {\n children: React.ReactNode;\n}\n\nexport const RPGUI: React.FC<IProps> = ({ children }) => {\n return <div className=\"rpgui-content\">{children}</div>;\n};\n","import React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n type: 'framed' | 'framed-golden' | 'framed-golden-2' | 'framed-grey';\n children: React.ReactNode;\n width?: string;\n}\n\nexport const RPGUIContainer: React.FC<IProps> = ({\n children,\n type,\n width = '50%',\n}) => {\n return (\n <Container width={width} className={`rpgui-container ${type}`}>\n {children}\n </Container>\n );\n};\n\ninterface IContainerProps {\n width: string;\n}\n\nconst Container = styled.div<IContainerProps>`\n max-width: ${({ width }) => width};\n`;\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n text: string;\n onFinish?: () => void;\n onStart?: () => void;\n}\n\nexport const DynamicText: React.FC<IProps> = ({ text, onFinish, onStart }) => {\n const [textState, setTextState] = useState<string>('');\n\n useEffect(() => {\n let i = 0;\n const interval = setInterval(() => {\n // on every interval, show one more character\n\n if (i === 0) {\n if (onStart) {\n onStart();\n }\n }\n\n if (i < text.length) {\n setTextState(text.substring(0, i + 1));\n i++;\n } else {\n clearInterval(interval);\n if (onFinish) {\n onFinish();\n }\n }\n }, 50);\n\n return () => {\n clearInterval(interval);\n };\n }, [text]);\n\n return <TextContainer>{textState}</TextContainer>;\n};\n\nconst TextContainer = styled.p`\n font-size: 0.7rem !important;\n color: white;\n text-shadow: 1px 1px 0px #000000;\n letter-spacing: 1.2px;\n`;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { useEventListener } from '../hooks/useEventListener';\nimport { chunkString } from '../libs/StringHelpers';\nimport { DynamicText } from '../typography/DynamicText';\n\ninterface IProps {\n text: string;\n onClose: () => void;\n onEndStep: () => void;\n onStartStep: () => void;\n}\n\nexport const NPCDialogText: React.FC<IProps> = ({\n text,\n onClose,\n onEndStep,\n onStartStep,\n}) => {\n const textChunks = chunkString(text, 85);\n\n const [chunkIndex, setChunkIndex] = useState<number>(0);\n\n useEventListener('keydown', (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n if (textChunks?.[chunkIndex + 1]) {\n setChunkIndex((prev) => prev + 1);\n } else {\n // if there's no more text chunks, close the dialog\n onClose();\n }\n }\n });\n\n return (\n <Container>\n <DynamicText\n text={textChunks?.[chunkIndex]!}\n onFinish={onEndStep}\n onStart={onStartStep}\n />\n </Container>\n );\n};\n\nconst Container = styled.div``;\n","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\n};\n","import { useEffect, useRef } from 'react';\n\nexport function useEventListener(\n eventName: string,\n handler: (e: any) => void,\n element = window\n) {\n // Create a ref that stores handler\n const savedHandler = useRef();\n // Update ref.current value if handler changes.\n // This allows our effect below to always get latest handler ...\n // ... without us needing to pass it in effect deps array ...\n // ... and potentially cause effect to re-run every render.\n useEffect(() => {\n //@ts-ignore\n savedHandler.current = handler;\n }, [handler]);\n useEffect(\n () => {\n // Make sure element supports addEventListener\n // On\n const isSupported = element && element.addEventListener;\n if (!isSupported) return;\n // Create event listener that calls handler function stored in ref\n //@ts-ignore\n const eventListener = (event: any) => savedHandler.current(event);\n // Add event listener\n element.addEventListener(eventName, eventListener);\n // Remove event listener on cleanup\n return () => {\n element.removeEventListener(eventName, eventListener);\n };\n },\n [eventName, element] // Re-run if eventName or element changes\n );\n}\n"],"names":["img","require","NPCDialogType","RPGUI","React","className","children","RPGUIContainer","width","Container","type","styled","div","DynamicText","text","onFinish","onStart","useState","textState","setTextState","useEffect","i","interval","setInterval","length","substring","clearInterval","TextContainer","p","NPCDialogText","onClose","onEndStep","onStartStep","textChunks","match","RegExp","chunkIndex","setChunkIndex","eventName","handler","element","window","savedHandler","useRef","current","addEventListener","eventListener","event","removeEventListener","useEventListener","code","prev","flex","ThumbnailContainer","NPCThumbnail","PressSpaceIndicator","right","npcKey","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","npcThumbnail","TextAndThumbnail","src","TextOnly","pressSpaceGif"],"mappings":"+PAAA,MAAMA,EAAMC,QAAQ,mBCMRC,ECECC,EAA0B,mBAC9BC,uBAAKC,UAAU,mBADkBC,WCC7BC,EAAmC,oBAG9CC,aAGEJ,gBAACK,GAAUD,iBAHL,QAGmBH,+BAJ3BK,QADAJ,WAeIG,EAAYE,EAAOC,mFAAPD,qBACH,qBAAGH,SCjBLK,EAAgC,gBAAGC,IAAAA,KAAMC,IAAAA,SAAUC,IAAAA,UAC5BC,WAAiB,IAA5CC,OAAWC,cAElBC,aAAU,eACJC,EAAI,EACFC,EAAWC,aAAY,WAGjB,IAANF,GACEL,GACFA,IAIAK,EAAIP,EAAKU,QACXL,EAAaL,EAAKW,UAAU,EAAGJ,EAAI,IACnCA,MAEAK,cAAcJ,GACVP,GACFA,OAGH,WAEI,WACLW,cAAcJ,MAEf,CAACR,IAEGV,gBAACuB,OAAeT,IAGnBS,EAAgBhB,EAAOiB,kFAAPjB,oGC7BTkB,EAAkC,gBAE7CC,IAAAA,QACAC,IAAAA,UACAC,IAAAA,YAEMC,IALNnB,KCbWoB,MAAM,IAAIC,OAAO,UAAuB,QDoBflB,WAAiB,GAA9CmB,OAAYC,uBElBnBC,EACAC,EACAC,YAAAA,IAAAA,EAAUC,YAGJC,EAAeC,WAKrBvB,aAAU,WAERsB,EAAaE,QAAUL,IACtB,CAACA,IACJnB,aACE,cAGsBoB,GAAWA,EAAQK,sBAIjCC,EAAgB,SAACC,UAAeL,EAAaE,QAAQG,WAE3DP,EAAQK,iBFJK,UEIuBC,GAE7B,WACLN,EAAQQ,oBFPG,UEO4BF,OAG3C,CFVe,UEUHN,IFVdS,CAAiB,GAAW,SAACF,GACR,UAAfA,EAAMG,aACJjB,GAAAA,EAAaG,EAAa,GAC5BC,GAAc,SAACc,UAASA,EAAO,KAG/BrB,QAMJ1B,gBAACK,OACCL,gBAACS,GACCC,WAAMmB,SAAAA,EAAaG,GACnBrB,SAAUgB,EACVf,QAASgB,MAMXvB,EAAYE,EAAOC,kFAAPD,QJvCNT,EAAAA,wBAAAA,+CAEVA,0CA2DIO,EAAYE,EAAOC,8EAAPD,kIAcZgB,EAAgBhB,EAAOC,kFAAPD,gCACZ,qBAAGyC,QAIPC,EAAqB1C,EAAOC,uFAAPD,0DAMrB2C,EAAe3C,EAAOX,iFAAPW,0DAUf4C,EAAsB5C,EAAOX,wFAAPW,uGAEjB,qBAAG6C,iDAtFsC,gBAClD1C,IAAAA,KACAJ,IAAAA,KACA+C,IAAAA,OACA3B,IAAAA,UAE4Bb,YAAkB,GAAvCyC,OAAQC,SAEb1C,YAAkB,GADb2C,OAAqBC,OAItBC,EAAe7D,6CAA6CwD,iBAE3DC,EACLtD,gBAACD,OACCC,gBAACG,GAAeG,KAAK,iBACnBN,gBAACK,OACCL,gBAACuB,GACCyB,KAAM1C,IAASR,sBAAc6D,iBAAmB,MAAQ,QAExD3D,gBAACyB,GACCG,YAAa,kBAAM6B,GAAuB,IAC1C9B,UAAW,kBAAM8B,GAAuB,IACxC/C,KAAMA,EACNgB,QAAS,WACHA,IACFA,IACA6B,GAAU,QAKjBjD,IAASR,sBAAc6D,kBACtB3D,gBAACiD,OACCjD,gBAACkD,GAAaU,IAAKF,MAIxBF,GACCxD,gBAACmD,GACCC,MAAO9C,IAASR,sBAAc+D,SAAW,OAAS,UAClDD,IAAKE,MAKX"}
@@ -1,8 +1,9 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, { useRef, useEffect, useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
  import 'rpgui/rpgui.css';
4
4
  import 'rpgui/rpgui.js';
5
- import useEventListener from '@use-it/event-listener';
5
+
6
+ const img = require('./space.gif');
6
7
 
7
8
  var RPGUI = function RPGUI(_ref) {
8
9
  var children = _ref.children;
@@ -29,6 +30,42 @@ var Container = /*#__PURE__*/styled.div.withConfig({
29
30
  return width;
30
31
  });
31
32
 
33
+ function useEventListener(eventName, handler, element) {
34
+ if (element === void 0) {
35
+ element = window;
36
+ }
37
+
38
+ // Create a ref that stores handler
39
+ var savedHandler = useRef(); // Update ref.current value if handler changes.
40
+ // This allows our effect below to always get latest handler ...
41
+ // ... without us needing to pass it in effect deps array ...
42
+ // ... and potentially cause effect to re-run every render.
43
+
44
+ useEffect(function () {
45
+ //@ts-ignore
46
+ savedHandler.current = handler;
47
+ }, [handler]);
48
+ useEffect(function () {
49
+ // Make sure element supports addEventListener
50
+ // On
51
+ var isSupported = element && element.addEventListener;
52
+ if (!isSupported) return; // Create event listener that calls handler function stored in ref
53
+ //@ts-ignore
54
+
55
+ var eventListener = function eventListener(event) {
56
+ return savedHandler.current(event);
57
+ }; // Add event listener
58
+
59
+
60
+ element.addEventListener(eventName, eventListener); // Remove event listener on cleanup
61
+
62
+ return function () {
63
+ element.removeEventListener(eventName, eventListener);
64
+ };
65
+ }, [eventName, element] // Re-run if eventName or element changes
66
+ );
67
+ }
68
+
32
69
  var chunkString = function chunkString(str, length) {
33
70
  return str.match(new RegExp('.{1,' + length + '}', 'g'));
34
71
  };
@@ -127,7 +164,10 @@ var NPCDialog = function NPCDialog(_ref) {
127
164
 
128
165
  var _useState2 = useState(false),
129
166
  showGoNextIndicator = _useState2[0],
130
- setShowGoNextIndicator = _useState2[1];
167
+ setShowGoNextIndicator = _useState2[1]; //dynamically require npc thumbnail
168
+
169
+
170
+ var npcThumbnail = require("../assets/npcDialog/npcThumbnails/" + npcKey + ".png");
131
171
 
132
172
  return isOpen ? React.createElement(RPGUI, null, React.createElement(RPGUIContainer, {
133
173
  type: "framed-golden"
@@ -149,10 +189,10 @@ var NPCDialog = function NPCDialog(_ref) {
149
189
  }
150
190
  }
151
191
  })), type === NPCDialogType.TextAndThumbnail && React.createElement(ThumbnailContainer, null, React.createElement(NPCThumbnail, {
152
- src: "/npcDialog/npcThumbnails/" + npcKey + ".png"
192
+ src: npcThumbnail
153
193
  }))), showGoNextIndicator && React.createElement(PressSpaceIndicator, {
154
194
  right: type === NPCDialogType.TextOnly ? '1rem' : '10.5rem',
155
- src: "/space.gif"
195
+ src: img
156
196
  }))) : null;
157
197
  };
158
198
  var Container$2 = /*#__PURE__*/styled.div.withConfig({
@@ -1 +1 @@
1
- {"version":3,"file":"long-bow.esm.js","sources":["../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/libs/StringHelpers.ts","../src/typography/DynamicText.tsx","../src/NPCDialog/NPCDialogText.tsx","../src/NPCDialog/NPCDialog.tsx"],"sourcesContent":["import React from 'react';\nimport 'rpgui/rpgui.css';\nimport 'rpgui/rpgui.js';\n\ninterface IProps {\n children: React.ReactNode;\n}\n\nexport const RPGUI: React.FC<IProps> = ({ children }) => {\n return <div className=\"rpgui-content\">{children}</div>;\n};\n","import React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n type: 'framed' | 'framed-golden' | 'framed-golden-2' | 'framed-grey';\n children: React.ReactNode;\n width?: string;\n}\n\nexport const RPGUIContainer: React.FC<IProps> = ({\n children,\n type,\n width = '50%',\n}) => {\n return (\n <Container width={width} className={`rpgui-container ${type}`}>\n {children}\n </Container>\n );\n};\n\ninterface IContainerProps {\n width: string;\n}\n\nconst Container = styled.div<IContainerProps>`\n max-width: ${({ width }) => width};\n`;\n","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\n};\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n text: string;\n onFinish?: () => void;\n onStart?: () => void;\n}\n\nexport const DynamicText: React.FC<IProps> = ({ text, onFinish, onStart }) => {\n const [textState, setTextState] = useState<string>('');\n\n useEffect(() => {\n let i = 0;\n const interval = setInterval(() => {\n // on every interval, show one more character\n\n if (i === 0) {\n if (onStart) {\n onStart();\n }\n }\n\n if (i < text.length) {\n setTextState(text.substring(0, i + 1));\n i++;\n } else {\n clearInterval(interval);\n if (onFinish) {\n onFinish();\n }\n }\n }, 50);\n\n return () => {\n clearInterval(interval);\n };\n }, [text]);\n\n return <TextContainer>{textState}</TextContainer>;\n};\n\nconst TextContainer = styled.p`\n font-size: 0.7rem !important;\n color: white;\n text-shadow: 1px 1px 0px #000000;\n letter-spacing: 1.2px;\n`;\n","import useEventListener from '@use-it/event-listener';\nimport React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { chunkString } from '../libs/StringHelpers';\nimport { DynamicText } from '../typography/DynamicText';\n\ninterface IProps {\n text: string;\n onClose: () => void;\n onEndStep: () => void;\n onStartStep: () => void;\n}\n\nexport const NPCDialogText: React.FC<IProps> = ({\n text,\n onClose,\n onEndStep,\n onStartStep,\n}) => {\n const textChunks = chunkString(text, 85);\n\n const [chunkIndex, setChunkIndex] = useState<number>(0);\n\n useEventListener('keydown', (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n if (textChunks?.[chunkIndex + 1]) {\n setChunkIndex((prev) => prev + 1);\n } else {\n // if there's no more text chunks, close the dialog\n onClose();\n }\n }\n });\n\n return (\n <Container>\n <DynamicText\n text={textChunks?.[chunkIndex]!}\n onFinish={onEndStep}\n onStart={onStartStep}\n />\n </Container>\n );\n};\n\nconst Container = styled.div``;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport { NPCDialogText } from './NPCDialogText';\n\nexport enum NPCDialogType {\n TextOnly = 'TextOnly',\n TextAndThumbnail = 'TextAndThumbnail',\n}\n\nexport interface INPCDialogProps {\n text: string;\n type: NPCDialogType;\n npcKey: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n npcKey,\n onClose,\n}) => {\n const [isOpen, setIsOpen] = useState<boolean>(true);\n const [showGoNextIndicator, setShowGoNextIndicator] =\n useState<boolean>(false);\n\n return isOpen ? (\n <RPGUI>\n <RPGUIContainer type=\"framed-golden\">\n <Container>\n <TextContainer\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\n >\n <NPCDialogText\n onStartStep={() => setShowGoNextIndicator(false)}\n onEndStep={() => setShowGoNextIndicator(true)}\n text={text}\n onClose={() => {\n if (onClose) {\n onClose();\n setIsOpen(false);\n }\n }}\n />\n </TextContainer>\n {type === NPCDialogType.TextAndThumbnail && (\n <ThumbnailContainer>\n <NPCThumbnail src={`/npcDialog/npcThumbnails/${npcKey}.png`} />\n </ThumbnailContainer>\n )}\n </Container>\n {showGoNextIndicator && (\n <PressSpaceIndicator\n right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}\n src=\"/space.gif\"\n />\n )}\n </RPGUIContainer>\n </RPGUI>\n ) : null;\n};\n\nconst Container = styled.div`\n display: flex;\n width: 100%;\n height: 125px;\n box-sizing: border-box;\n justify-content: center;\n align-items: flex-start;\n position: relative;\n`;\n\ninterface ITextContainerProps {\n flex: string;\n}\n\nconst TextContainer = styled.div<ITextContainerProps>`\n flex: ${({ flex }) => flex} 0 0;\n width: 355px;\n`;\n\nconst ThumbnailContainer = styled.div`\n flex: 30% 0 0;\n display: flex;\n justify-content: flex-end;\n`;\n\nconst NPCThumbnail = styled.img`\n image-rendering: pixelated;\n height: 128px;\n width: 128px;\n`;\n\ninterface IPressSpaceIndicatorProps {\n right: string;\n}\n\nconst PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`\n position: absolute;\n right: ${({ right }) => right};\n bottom: 1rem;\n height: 20.7px;\n image-rendering: -webkit-optimize-contrast;\n`;\n"],"names":["RPGUI","children","React","className","RPGUIContainer","type","width","Container","styled","div","chunkString","str","length","match","RegExp","DynamicText","text","onFinish","onStart","useState","textState","setTextState","useEffect","i","interval","setInterval","substring","clearInterval","TextContainer","p","NPCDialogText","onClose","onEndStep","onStartStep","textChunks","chunkIndex","setChunkIndex","useEventListener","event","code","prev","NPCDialogType","NPCDialog","npcKey","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","flex","TextAndThumbnail","ThumbnailContainer","NPCThumbnail","src","PressSpaceIndicator","right","TextOnly","img"],"mappings":"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"}
1
+ {"version":3,"file":"long-bow.esm.js","sources":["../src/assets/space.gif","../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/hooks/useEventListener.ts","../src/libs/StringHelpers.ts","../src/typography/DynamicText.tsx","../src/NPCDialog/NPCDialogText.tsx","../src/NPCDialog/NPCDialog.tsx"],"sourcesContent":["const img = require('./space.gif'); export default img;","import React from 'react';\nimport 'rpgui/rpgui.css';\nimport 'rpgui/rpgui.js';\n\ninterface IProps {\n children: React.ReactNode;\n}\n\nexport const RPGUI: React.FC<IProps> = ({ children }) => {\n return <div className=\"rpgui-content\">{children}</div>;\n};\n","import React from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n type: 'framed' | 'framed-golden' | 'framed-golden-2' | 'framed-grey';\n children: React.ReactNode;\n width?: string;\n}\n\nexport const RPGUIContainer: React.FC<IProps> = ({\n children,\n type,\n width = '50%',\n}) => {\n return (\n <Container width={width} className={`rpgui-container ${type}`}>\n {children}\n </Container>\n );\n};\n\ninterface IContainerProps {\n width: string;\n}\n\nconst Container = styled.div<IContainerProps>`\n max-width: ${({ width }) => width};\n`;\n","import { useEffect, useRef } from 'react';\n\nexport function useEventListener(\n eventName: string,\n handler: (e: any) => void,\n element = window\n) {\n // Create a ref that stores handler\n const savedHandler = useRef();\n // Update ref.current value if handler changes.\n // This allows our effect below to always get latest handler ...\n // ... without us needing to pass it in effect deps array ...\n // ... and potentially cause effect to re-run every render.\n useEffect(() => {\n //@ts-ignore\n savedHandler.current = handler;\n }, [handler]);\n useEffect(\n () => {\n // Make sure element supports addEventListener\n // On\n const isSupported = element && element.addEventListener;\n if (!isSupported) return;\n // Create event listener that calls handler function stored in ref\n //@ts-ignore\n const eventListener = (event: any) => savedHandler.current(event);\n // Add event listener\n element.addEventListener(eventName, eventListener);\n // Remove event listener on cleanup\n return () => {\n element.removeEventListener(eventName, eventListener);\n };\n },\n [eventName, element] // Re-run if eventName or element changes\n );\n}\n","export const chunkString = (str: string, length: number) => {\n return str.match(new RegExp('.{1,' + length + '}', 'g'));\n};\n","import React, { useEffect, useState } from 'react';\nimport styled from 'styled-components';\n\ninterface IProps {\n text: string;\n onFinish?: () => void;\n onStart?: () => void;\n}\n\nexport const DynamicText: React.FC<IProps> = ({ text, onFinish, onStart }) => {\n const [textState, setTextState] = useState<string>('');\n\n useEffect(() => {\n let i = 0;\n const interval = setInterval(() => {\n // on every interval, show one more character\n\n if (i === 0) {\n if (onStart) {\n onStart();\n }\n }\n\n if (i < text.length) {\n setTextState(text.substring(0, i + 1));\n i++;\n } else {\n clearInterval(interval);\n if (onFinish) {\n onFinish();\n }\n }\n }, 50);\n\n return () => {\n clearInterval(interval);\n };\n }, [text]);\n\n return <TextContainer>{textState}</TextContainer>;\n};\n\nconst TextContainer = styled.p`\n font-size: 0.7rem !important;\n color: white;\n text-shadow: 1px 1px 0px #000000;\n letter-spacing: 1.2px;\n`;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { useEventListener } from '../hooks/useEventListener';\nimport { chunkString } from '../libs/StringHelpers';\nimport { DynamicText } from '../typography/DynamicText';\n\ninterface IProps {\n text: string;\n onClose: () => void;\n onEndStep: () => void;\n onStartStep: () => void;\n}\n\nexport const NPCDialogText: React.FC<IProps> = ({\n text,\n onClose,\n onEndStep,\n onStartStep,\n}) => {\n const textChunks = chunkString(text, 85);\n\n const [chunkIndex, setChunkIndex] = useState<number>(0);\n\n useEventListener('keydown', (event: KeyboardEvent) => {\n if (event.code === 'Space') {\n if (textChunks?.[chunkIndex + 1]) {\n setChunkIndex((prev) => prev + 1);\n } else {\n // if there's no more text chunks, close the dialog\n onClose();\n }\n }\n });\n\n return (\n <Container>\n <DynamicText\n text={textChunks?.[chunkIndex]!}\n onFinish={onEndStep}\n onStart={onStartStep}\n />\n </Container>\n );\n};\n\nconst Container = styled.div``;\n","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport pressSpaceGif from '../assets/space.gif';\nimport { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport { NPCDialogText } from './NPCDialogText';\nexport enum NPCDialogType {\n TextOnly = 'TextOnly',\n TextAndThumbnail = 'TextAndThumbnail',\n}\n\nexport interface INPCDialogProps {\n text: string;\n type: NPCDialogType;\n npcKey: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n npcKey,\n onClose,\n}) => {\n const [isOpen, setIsOpen] = useState<boolean>(true);\n const [showGoNextIndicator, setShowGoNextIndicator] =\n useState<boolean>(false);\n\n //dynamically require npc thumbnail\n const npcThumbnail = require(`../assets/npcDialog/npcThumbnails/${npcKey}.png`);\n\n return isOpen ? (\n <RPGUI>\n <RPGUIContainer type=\"framed-golden\">\n <Container>\n <TextContainer\n flex={type === NPCDialogType.TextAndThumbnail ? '70%' : '100%'}\n >\n <NPCDialogText\n onStartStep={() => setShowGoNextIndicator(false)}\n onEndStep={() => setShowGoNextIndicator(true)}\n text={text}\n onClose={() => {\n if (onClose) {\n onClose();\n setIsOpen(false);\n }\n }}\n />\n </TextContainer>\n {type === NPCDialogType.TextAndThumbnail && (\n <ThumbnailContainer>\n <NPCThumbnail src={npcThumbnail} />\n </ThumbnailContainer>\n )}\n </Container>\n {showGoNextIndicator && (\n <PressSpaceIndicator\n right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}\n src={pressSpaceGif}\n />\n )}\n </RPGUIContainer>\n </RPGUI>\n ) : null;\n};\n\nconst Container = styled.div`\n display: flex;\n width: 100%;\n height: 125px;\n box-sizing: border-box;\n justify-content: center;\n align-items: flex-start;\n position: relative;\n`;\n\ninterface ITextContainerProps {\n flex: string;\n}\n\nconst TextContainer = styled.div<ITextContainerProps>`\n flex: ${({ flex }) => flex} 0 0;\n width: 355px;\n`;\n\nconst ThumbnailContainer = styled.div`\n flex: 30% 0 0;\n display: flex;\n justify-content: flex-end;\n`;\n\nconst NPCThumbnail = styled.img`\n image-rendering: pixelated;\n height: 128px;\n width: 128px;\n`;\n\ninterface IPressSpaceIndicatorProps {\n right: string;\n}\n\nconst PressSpaceIndicator = styled.img<IPressSpaceIndicatorProps>`\n position: absolute;\n right: ${({ right }) => right};\n bottom: 1rem;\n height: 20.7px;\n image-rendering: -webkit-optimize-contrast;\n`;\n"],"names":["RPGUI","children","React","className","RPGUIContainer","type","width","Container","styled","div","useEventListener","eventName","handler","element","window","savedHandler","useRef","useEffect","current","isSupported","addEventListener","eventListener","event","removeEventListener","chunkString","str","length","match","RegExp","DynamicText","text","onFinish","onStart","useState","textState","setTextState","i","interval","setInterval","substring","clearInterval","TextContainer","p","NPCDialogText","onClose","onEndStep","onStartStep","textChunks","chunkIndex","setChunkIndex","code","prev","NPCDialogType","NPCDialog","npcKey","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","npcThumbnail","require","flex","TextAndThumbnail","ThumbnailContainer","NPCThumbnail","src","PressSpaceIndicator","right","TextOnly","pressSpaceGif","img"],"mappings":"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"}
package/dist/space.gif ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.1.8",
3
+ "version": "0.1.11",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -44,13 +44,14 @@
44
44
  "trailingComma": "es5"
45
45
  },
46
46
  "author": "Joao Paulo Furtado",
47
+ "module": "dist/long-bow.esm.js",
47
48
  "size-limit": [
48
49
  {
49
- "path": "dist/rpg-engine-long-bow.cjs.production.min.js",
50
+ "path": "dist/long-bow.cjs.production.min.js",
50
51
  "limit": "10 KB"
51
52
  },
52
53
  {
53
- "path": "dist/rpg-engine-long-bow.esm.js",
54
+ "path": "dist/long-bow.esm.js",
54
55
  "limit": "10 KB"
55
56
  }
56
57
  ],
@@ -78,7 +79,8 @@
78
79
  "typescript": "^4.6.2"
79
80
  },
80
81
  "dependencies": {
81
- "@use-it/event-listener": "^0.1.7",
82
+ "@rollup/plugin-image": "^2.1.1",
83
+ "rollup-plugin-image-files": "^1.4.2",
82
84
  "rpgui": "^1.0.3"
83
85
  }
84
86
  }
@@ -1,9 +1,9 @@
1
1
  import React, { useState } from 'react';
2
2
  import styled from 'styled-components';
3
+ import pressSpaceGif from '../assets/space.gif';
3
4
  import { RPGUI } from '../RPGUI/RPGUI';
4
5
  import { RPGUIContainer } from '../RPGUI/RPGUIContainer';
5
6
  import { NPCDialogText } from './NPCDialogText';
6
-
7
7
  export enum NPCDialogType {
8
8
  TextOnly = 'TextOnly',
9
9
  TextAndThumbnail = 'TextAndThumbnail',
@@ -26,6 +26,9 @@ export const NPCDialog: React.FC<INPCDialogProps> = ({
26
26
  const [showGoNextIndicator, setShowGoNextIndicator] =
27
27
  useState<boolean>(false);
28
28
 
29
+ //dynamically require npc thumbnail
30
+ const npcThumbnail = require(`../assets/npcDialog/npcThumbnails/${npcKey}.png`);
31
+
29
32
  return isOpen ? (
30
33
  <RPGUI>
31
34
  <RPGUIContainer type="framed-golden">
@@ -47,14 +50,14 @@ export const NPCDialog: React.FC<INPCDialogProps> = ({
47
50
  </TextContainer>
48
51
  {type === NPCDialogType.TextAndThumbnail && (
49
52
  <ThumbnailContainer>
50
- <NPCThumbnail src={`/npcDialog/npcThumbnails/${npcKey}.png`} />
53
+ <NPCThumbnail src={npcThumbnail} />
51
54
  </ThumbnailContainer>
52
55
  )}
53
56
  </Container>
54
57
  {showGoNextIndicator && (
55
58
  <PressSpaceIndicator
56
59
  right={type === NPCDialogType.TextOnly ? '1rem' : '10.5rem'}
57
- src="/space.gif"
60
+ src={pressSpaceGif}
58
61
  />
59
62
  )}
60
63
  </RPGUIContainer>
@@ -1,6 +1,6 @@
1
- import useEventListener from '@use-it/event-listener';
2
1
  import React, { useState } from 'react';
3
2
  import styled from 'styled-components';
3
+ import { useEventListener } from '../hooks/useEventListener';
4
4
  import { chunkString } from '../libs/StringHelpers';
5
5
  import { DynamicText } from '../typography/DynamicText';
6
6
 
Binary file
@@ -0,0 +1,36 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ export function useEventListener(
4
+ eventName: string,
5
+ handler: (e: any) => void,
6
+ element = window
7
+ ) {
8
+ // Create a ref that stores handler
9
+ const savedHandler = useRef();
10
+ // Update ref.current value if handler changes.
11
+ // This allows our effect below to always get latest handler ...
12
+ // ... without us needing to pass it in effect deps array ...
13
+ // ... and potentially cause effect to re-run every render.
14
+ useEffect(() => {
15
+ //@ts-ignore
16
+ savedHandler.current = handler;
17
+ }, [handler]);
18
+ useEffect(
19
+ () => {
20
+ // Make sure element supports addEventListener
21
+ // On
22
+ const isSupported = element && element.addEventListener;
23
+ if (!isSupported) return;
24
+ // Create event listener that calls handler function stored in ref
25
+ //@ts-ignore
26
+ const eventListener = (event: any) => savedHandler.current(event);
27
+ // Add event listener
28
+ element.addEventListener(eventName, eventListener);
29
+ // Remove event listener on cleanup
30
+ return () => {
31
+ element.removeEventListener(eventName, eventListener);
32
+ };
33
+ },
34
+ [eventName, element] // Re-run if eventName or element changes
35
+ );
36
+ }