@rpg-engine/long-bow 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/NPCDialog/NPCDialog.d.ts +1 -1
- package/{src/assets/npcDialog/npcThumbnails → dist}/alice.png +0 -0
- package/dist/long-bow.cjs.development.js +9 -10
- package/dist/long-bow.cjs.development.js.map +1 -1
- package/dist/long-bow.cjs.production.min.js +1 -1
- package/dist/long-bow.cjs.production.min.js.map +1 -1
- package/dist/long-bow.esm.js +9 -10
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/NPCDialog/NPCDialog.tsx +5 -7
- package/src/NPCDialog/img/npcDialog/npcThumbnails/alice.png +0 -0
- package/src/{assets → NPCDialog/img}/space.gif +0 -0
- package/src/types/index.d.ts +1 -0
- package/src/assets/npcDialog/npcThumbnails/tile000.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile001.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile002.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile003.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile004.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile005.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile006.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile007.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile008.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile009.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile010.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile012.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile013.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile014.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile015.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile016.png +0 -0
- package/src/assets/npcDialog/npcThumbnails/tile017.png +0 -0
|
File without changes
|
|
@@ -10,8 +10,6 @@ var styled = _interopDefault(require('styled-components'));
|
|
|
10
10
|
require('rpgui/rpgui.css');
|
|
11
11
|
require('rpgui/rpgui.js');
|
|
12
12
|
|
|
13
|
-
const img = require('./space.gif');
|
|
14
|
-
|
|
15
13
|
var RPGUI = function RPGUI(_ref) {
|
|
16
14
|
var children = _ref.children;
|
|
17
15
|
return React__default.createElement("div", {
|
|
@@ -37,6 +35,10 @@ var Container = /*#__PURE__*/styled.div.withConfig({
|
|
|
37
35
|
return width;
|
|
38
36
|
});
|
|
39
37
|
|
|
38
|
+
const img = require('./alice.png');
|
|
39
|
+
|
|
40
|
+
const img$1 = require('./space.gif');
|
|
41
|
+
|
|
40
42
|
function useEventListener(eventName, handler, element) {
|
|
41
43
|
if (element === void 0) {
|
|
42
44
|
element = window;
|
|
@@ -160,8 +162,8 @@ var Container$1 = /*#__PURE__*/styled.div.withConfig({
|
|
|
160
162
|
var NPCDialog = function NPCDialog(_ref) {
|
|
161
163
|
var text = _ref.text,
|
|
162
164
|
type = _ref.type,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
+
_onClose = _ref.onClose,
|
|
166
|
+
imagePath = _ref.imagePath;
|
|
165
167
|
|
|
166
168
|
var _useState = React.useState(true),
|
|
167
169
|
isOpen = _useState[0],
|
|
@@ -169,10 +171,7 @@ var NPCDialog = function NPCDialog(_ref) {
|
|
|
169
171
|
|
|
170
172
|
var _useState2 = React.useState(false),
|
|
171
173
|
showGoNextIndicator = _useState2[0],
|
|
172
|
-
setShowGoNextIndicator = _useState2[1];
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
var npcThumbnail = require("../assets/npcDialog/npcThumbnails/" + npcKey + ".png");
|
|
174
|
+
setShowGoNextIndicator = _useState2[1];
|
|
176
175
|
|
|
177
176
|
return isOpen ? React__default.createElement(RPGUI, null, React__default.createElement(RPGUIContainer, {
|
|
178
177
|
type: "framed-golden"
|
|
@@ -194,10 +193,10 @@ var NPCDialog = function NPCDialog(_ref) {
|
|
|
194
193
|
}
|
|
195
194
|
}
|
|
196
195
|
})), type === exports.NPCDialogType.TextAndThumbnail && React__default.createElement(ThumbnailContainer, null, React__default.createElement(NPCThumbnail, {
|
|
197
|
-
src:
|
|
196
|
+
src: imagePath || img
|
|
198
197
|
}))), showGoNextIndicator && React__default.createElement(PressSpaceIndicator, {
|
|
199
198
|
right: type === exports.NPCDialogType.TextOnly ? '1rem' : '10.5rem',
|
|
200
|
-
src: img
|
|
199
|
+
src: img$1
|
|
201
200
|
}))) : null;
|
|
202
201
|
};
|
|
203
202
|
var Container$2 = /*#__PURE__*/styled.div.withConfig({
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"version":3,"file":"long-bow.cjs.development.js","sources":["../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/NPCDialog/img/npcDialog/npcThumbnails/alice.png","../src/NPCDialog/img/space.gif","../src/hooks/useEventListener.ts","../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","const img = require('./alice.png'); export default img;","const img = require('./space.gif'); export default img;","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 { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport aliceDefaultThumbnail from './img/npcDialog/npcThumbnails/alice.png';\nimport pressSpaceGif from './img/space.gif';\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 imagePath?: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n onClose,\n imagePath,\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={imagePath || aliceDefaultThumbnail} />\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","img","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","imagePath","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","flex","TextAndThumbnail","ThumbnailContainer","NPCThumbnail","src","aliceDefaultThumbnail","PressSpaceIndicator","right","TextOnly","pressSpaceGif"],"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");
|
|
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=function(e){return n.createElement("div",{className:"rpgui-content"},e.children)},o=function(e){var t=e.width;return n.createElement(a,{width:void 0===t?"50%":t,className:"rpgui-container "+e.type},e.children)},a=i.div.withConfig({displayName:"RPGUIContainer__Container",componentId:"sc-3xvrxc-0"})(["max-width:",";"],(function(e){return e.width}));const l=require("./alice.png"),c=require("./space.gif");var u,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;"]),m=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],u=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]?u((function(e){return e+1})):i())})),n.createElement(d,null,n.createElement(s,{text:null==a?void 0:a[c],onFinish:r,onStart:o}))},d=i.div.withConfig({displayName:"NPCDialogText__Container",componentId:"sc-ahseq0-0"})([""]);(u=exports.NPCDialogType||(exports.NPCDialogType={})).TextOnly="TextOnly",u.TextAndThumbnail="TextAndThumbnail";var f=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;"]),h=i.img.withConfig({displayName:"NPCDialog__NPCThumbnail",componentId:"sc-omm2zk-3"})(["image-rendering:pixelated;height:128px;width:128px;"]),C=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,a=e.type,u=e.onClose,s=e.imagePath,p=t.useState(!0),d=p[0],y=p[1],v=t.useState(!1),w=v[0],N=v[1];return d?n.createElement(r,null,n.createElement(o,{type:"framed-golden"},n.createElement(f,null,n.createElement(x,{flex:a===exports.NPCDialogType.TextAndThumbnail?"70%":"100%"},n.createElement(m,{onStartStep:function(){return N(!1)},onEndStep:function(){return N(!0)},text:i,onClose:function(){u&&(u(),y(!1))}})),a===exports.NPCDialogType.TextAndThumbnail&&n.createElement(g,null,n.createElement(h,{src:s||l}))),w&&n.createElement(C,{right:a===exports.NPCDialogType.TextOnly?"1rem":"10.5rem",src:c}))):null},exports.RPGUI=r,exports.RPGUIContainer=o;
|
|
2
2
|
//# sourceMappingURL=long-bow.cjs.production.min.js.map
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"version":3,"file":"long-bow.cjs.production.min.js","sources":["../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/NPCDialog/img/npcDialog/npcThumbnails/alice.png","../src/NPCDialog/img/space.gif","../src/NPCDialog/NPCDialog.tsx","../src/typography/DynamicText.tsx","../src/NPCDialog/NPCDialogText.tsx","../src/libs/StringHelpers.ts","../src/hooks/useEventListener.ts"],"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","const img = require('./alice.png'); export default img;","const img = require('./space.gif'); export default img;","import React, { useState } from 'react';\nimport styled from 'styled-components';\nimport { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport aliceDefaultThumbnail from './img/npcDialog/npcThumbnails/alice.png';\nimport pressSpaceGif from './img/space.gif';\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 imagePath?: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n onClose,\n imagePath,\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={imagePath || aliceDefaultThumbnail} />\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, { 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":["RPGUI","React","className","children","RPGUIContainer","width","Container","type","styled","div","img","require","NPCDialogType","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","imagePath","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","TextAndThumbnail","src","aliceDefaultThumbnail","TextOnly","pressSpaceGif"],"mappings":"mQAQaA,EAA0B,mBAC9BC,uBAAKC,UAAU,mBADkBC,WCC7BC,EAAmC,oBAG9CC,aAGEJ,gBAACK,GAAUD,iBAHL,QAGmBH,+BAJ3BK,QADAJ,WAeIG,EAAYE,EAAOC,mFAAPD,qBACH,qBAAGH,SC1BlB,MAAMK,EAAMC,QAAQ,eCAdD,EAAMC,QAAQ,mBCORC,ECECC,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,IAEGb,gBAAC0B,OAAeT,IAGnBS,EAAgBnB,EAAOoB,kFAAPpB,oGC7BTqB,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,QAMJ7B,gBAACK,OACCL,gBAACY,GACCC,WAAMmB,SAAAA,EAAaG,GACnBrB,SAAUgB,EACVf,QAASgB,MAMX1B,EAAYE,EAAOC,kFAAPD,QFtCNI,EAAAA,wBAAAA,+CAEVA,0CAwDIN,EAAYE,EAAOC,8EAAPD,kIAcZmB,EAAgBnB,EAAOC,kFAAPD,gCACZ,qBAAG4C,QAIPC,EAAqB7C,EAAOC,uFAAPD,0DAMrB8C,EAAe9C,EAAOE,iFAAPF,0DAUf+C,EAAsB/C,EAAOE,wFAAPF,uGAEjB,qBAAGgD,iDAnFsC,gBAClD1C,IAAAA,KACAP,IAAAA,KACAuB,IAAAA,QACA2B,IAAAA,YAE4BxC,YAAkB,GAAvCyC,OAAQC,SAEb1C,YAAkB,GADb2C,OAAqBC,cAGrBH,EACLzD,gBAACD,OACCC,gBAACG,GAAeG,KAAK,iBACnBN,gBAACK,OACCL,gBAAC0B,GACCyB,KAAM7C,IAASK,sBAAckD,iBAAmB,MAAQ,QAExD7D,gBAAC4B,GACCG,YAAa,kBAAM6B,GAAuB,IAC1C9B,UAAW,kBAAM8B,GAAuB,IACxC/C,KAAMA,EACNgB,QAAS,WACHA,IACFA,IACA6B,GAAU,QAKjBpD,IAASK,sBAAckD,kBACtB7D,gBAACoD,OACCpD,gBAACqD,GAAaS,IAAKN,GAAaO,MAIrCJ,GACC3D,gBAACsD,GACCC,MAAOjD,IAASK,sBAAcqD,SAAW,OAAS,UAClDF,IAAKG,MAKX"}
|
package/dist/long-bow.esm.js
CHANGED
|
@@ -3,8 +3,6 @@ import styled from 'styled-components';
|
|
|
3
3
|
import 'rpgui/rpgui.css';
|
|
4
4
|
import 'rpgui/rpgui.js';
|
|
5
5
|
|
|
6
|
-
const img = require('./space.gif');
|
|
7
|
-
|
|
8
6
|
var RPGUI = function RPGUI(_ref) {
|
|
9
7
|
var children = _ref.children;
|
|
10
8
|
return React.createElement("div", {
|
|
@@ -30,6 +28,10 @@ var Container = /*#__PURE__*/styled.div.withConfig({
|
|
|
30
28
|
return width;
|
|
31
29
|
});
|
|
32
30
|
|
|
31
|
+
const img = require('./alice.png');
|
|
32
|
+
|
|
33
|
+
const img$1 = require('./space.gif');
|
|
34
|
+
|
|
33
35
|
function useEventListener(eventName, handler, element) {
|
|
34
36
|
if (element === void 0) {
|
|
35
37
|
element = window;
|
|
@@ -155,8 +157,8 @@ var NPCDialogType;
|
|
|
155
157
|
var NPCDialog = function NPCDialog(_ref) {
|
|
156
158
|
var text = _ref.text,
|
|
157
159
|
type = _ref.type,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
+
_onClose = _ref.onClose,
|
|
161
|
+
imagePath = _ref.imagePath;
|
|
160
162
|
|
|
161
163
|
var _useState = useState(true),
|
|
162
164
|
isOpen = _useState[0],
|
|
@@ -164,10 +166,7 @@ var NPCDialog = function NPCDialog(_ref) {
|
|
|
164
166
|
|
|
165
167
|
var _useState2 = useState(false),
|
|
166
168
|
showGoNextIndicator = _useState2[0],
|
|
167
|
-
setShowGoNextIndicator = _useState2[1];
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
var npcThumbnail = require("../assets/npcDialog/npcThumbnails/" + npcKey + ".png");
|
|
169
|
+
setShowGoNextIndicator = _useState2[1];
|
|
171
170
|
|
|
172
171
|
return isOpen ? React.createElement(RPGUI, null, React.createElement(RPGUIContainer, {
|
|
173
172
|
type: "framed-golden"
|
|
@@ -189,10 +188,10 @@ var NPCDialog = function NPCDialog(_ref) {
|
|
|
189
188
|
}
|
|
190
189
|
}
|
|
191
190
|
})), type === NPCDialogType.TextAndThumbnail && React.createElement(ThumbnailContainer, null, React.createElement(NPCThumbnail, {
|
|
192
|
-
src:
|
|
191
|
+
src: imagePath || img
|
|
193
192
|
}))), showGoNextIndicator && React.createElement(PressSpaceIndicator, {
|
|
194
193
|
right: type === NPCDialogType.TextOnly ? '1rem' : '10.5rem',
|
|
195
|
-
src: img
|
|
194
|
+
src: img$1
|
|
196
195
|
}))) : null;
|
|
197
196
|
};
|
|
198
197
|
var Container$2 = /*#__PURE__*/styled.div.withConfig({
|
package/dist/long-bow.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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":";;;;;AAAA,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC;;ICQrBA,KAAK,GAAqB,SAA1BA,KAA0B;MAAGC,gBAAAA;AACxC,SAAOC,mBAAA,MAAA;AAAKC,IAAAA,SAAS,EAAC;GAAf,EAAgCF,QAAhC,CAAP;AACD,CAFM;;ICCMG,cAAc,GAAqB,SAAnCA,cAAmC;MAC9CH,gBAAAA;MACAI,YAAAA;wBACAC;MAAAA,gCAAQ;AAER,SACEJ,mBAAA,CAACK,SAAD;AAAWD,IAAAA,KAAK,EAAEA;AAAOH,IAAAA,SAAS,uBAAqBE;GAAvD,EACGJ,QADH,CADF;AAKD,CAVM;AAgBP,IAAMM,SAAS,gBAAGC,MAAM,CAACC,GAAV;AAAA;AAAA;AAAA,wBACA;AAAA,MAAGH,KAAH,SAAGA,KAAH;AAAA,SAAeA,KAAf;AAAA,CADA,CAAf;;SCvBgBI,iBACdC,WACAC,SACAC;MAAAA;AAAAA,IAAAA,UAAUC;;;AAEV;AACA,MAAMC,YAAY,GAAGC,MAAM,EAA3B;AAEA;AACA;AACA;;AACAC,EAAAA,SAAS,CAAC;AACR;AACAF,IAAAA,YAAY,CAACG,OAAb,GAAuBN,OAAvB;AACD,GAHQ,EAGN,CAACA,OAAD,CAHM,CAAT;AAIAK,EAAAA,SAAS,CACP;AACE;AACA;AACA,QAAME,WAAW,GAAGN,OAAO,IAAIA,OAAO,CAACO,gBAAvC;AACA,QAAI,CAACD,WAAL,EAAkB;AAElB;;AACA,QAAME,aAAa,GAAG,SAAhBA,aAAgB,CAACC,KAAD;AAAA,aAAgBP,YAAY,CAACG,OAAb,CAAqBI,KAArB,CAAhB;AAAA,KAAtB;;;AAEAT,IAAAA,OAAO,CAACO,gBAAR,CAAyBT,SAAzB,EAAoCU,aAApC;;AAEA,WAAO;AACLR,MAAAA,OAAO,CAACU,mBAAR,CAA4BZ,SAA5B,EAAuCU,aAAvC;AACD,KAFD;AAGD,GAfM,EAgBP,CAACV,SAAD,EAAYE,OAAZ,CAhBO;AAAA,GAAT;AAkBD;;ACnCM,IAAMW,WAAW,GAAG,SAAdA,WAAc,CAACC,GAAD,EAAcC,MAAd;AACzB,SAAOD,GAAG,CAACE,KAAJ,CAAU,IAAIC,MAAJ,CAAW,SAASF,MAAT,GAAkB,GAA7B,EAAkC,GAAlC,CAAV,CAAP;AACD,CAFM;;ICSMG,WAAW,GAAqB,SAAhCA,WAAgC;MAAGC,YAAAA;MAAMC,gBAAAA;MAAUC,eAAAA;;AAC9D,kBAAkCC,QAAQ,CAAS,EAAT,CAA1C;AAAA,MAAOC,SAAP;AAAA,MAAkBC,YAAlB;;AAEAlB,EAAAA,SAAS,CAAC;AACR,QAAImB,CAAC,GAAG,CAAR;AACA,QAAMC,QAAQ,GAAGC,WAAW,CAAC;AAC3B;AAEA,UAAIF,CAAC,KAAK,CAAV,EAAa;AACX,YAAIJ,OAAJ,EAAa;AACXA,UAAAA,OAAO;AACR;AACF;;AAED,UAAII,CAAC,GAAGN,IAAI,CAACJ,MAAb,EAAqB;AACnBS,QAAAA,YAAY,CAACL,IAAI,CAACS,SAAL,CAAe,CAAf,EAAkBH,CAAC,GAAG,CAAtB,CAAD,CAAZ;AACAA,QAAAA,CAAC;AACF,OAHD,MAGO;AACLI,QAAAA,aAAa,CAACH,QAAD,CAAb;;AACA,YAAIN,QAAJ,EAAc;AACZA,UAAAA,QAAQ;AACT;AACF;AACF,KAlB2B,EAkBzB,EAlByB,CAA5B;AAoBA,WAAO;AACLS,MAAAA,aAAa,CAACH,QAAD,CAAb;AACD,KAFD;AAGD,GAzBQ,EAyBN,CAACP,IAAD,CAzBM,CAAT;AA2BA,SAAO5B,mBAAA,CAACuC,aAAD,MAAA,EAAgBP,SAAhB,CAAP;AACD,CA/BM;AAiCP,IAAMO,aAAa,gBAAGjC,MAAM,CAACkC,CAAV;AAAA;AAAA;AAAA,qGAAnB;;AC7BO,IAAMC,aAAa,GAAqB,SAAlCA,aAAkC;MAC7Cb,YAAAA;MACAc,eAAAA;MACAC,iBAAAA;MACAC,mBAAAA;AAEA,MAAMC,UAAU,GAAGvB,WAAW,CAACM,IAAD,EAAO,EAAP,CAA9B;;AAEA,kBAAoCG,QAAQ,CAAS,CAAT,CAA5C;AAAA,MAAOe,UAAP;AAAA,MAAmBC,aAAnB;;AAEAvC,EAAAA,gBAAgB,CAAC,SAAD,EAAY,UAACY,KAAD;AAC1B,QAAIA,KAAK,CAAC4B,IAAN,KAAe,OAAnB,EAA4B;AAC1B,UAAIH,UAAJ,YAAIA,UAAU,CAAGC,UAAU,GAAG,CAAhB,CAAd,EAAkC;AAChCC,QAAAA,aAAa,CAAC,UAACE,IAAD;AAAA,iBAAUA,IAAI,GAAG,CAAjB;AAAA,SAAD,CAAb;AACD,OAFD,MAEO;AACL;AACAP,QAAAA,OAAO;AACR;AACF;AACF,GATe,CAAhB;AAWA,SACE1C,mBAAA,CAACK,WAAD,MAAA,EACEL,mBAAA,CAAC2B,WAAD;AACEC,IAAAA,IAAI,EAAEiB,UAAF,oBAAEA,UAAU,CAAGC,UAAH;AAChBjB,IAAAA,QAAQ,EAAEc;AACVb,IAAAA,OAAO,EAAEc;GAHX,CADF,CADF;AASD,CA9BM;AAgCP,IAAMvC,WAAS,gBAAGC,MAAM,CAACC,GAAV;AAAA;AAAA;AAAA,QAAf;;ICvCY2C,aAAZ;;AAAA,WAAYA;AACVA,EAAAA,yBAAA,aAAA;AACAA,EAAAA,iCAAA,qBAAA;AACD,CAHD,EAAYA,aAAa,KAAbA,aAAa,KAAA,CAAzB;;AAYA,IAAaC,SAAS,GAA8B,SAAvCA,SAAuC;MAClDvB,YAAAA;MACAzB,YAAAA;MACAiD,cAAAA;MACAV,gBAAAA;;AAEA,kBAA4BX,QAAQ,CAAU,IAAV,CAApC;AAAA,MAAOsB,MAAP;AAAA,MAAeC,SAAf;;AACA,mBACEvB,QAAQ,CAAU,KAAV,CADV;AAAA,MAAOwB,mBAAP;AAAA,MAA4BC,sBAA5B;;;AAIA,MAAMC,YAAY,GAAGC,OAAO,wCAAsCN,MAAtC,UAA5B;;AAEA,SAAOC,MAAM,GACXrD,mBAAA,CAACF,KAAD,MAAA,EACEE,mBAAA,CAACE,cAAD;AAAgBC,IAAAA,IAAI,EAAC;GAArB,EACEH,mBAAA,CAACK,WAAD,MAAA,EACEL,mBAAA,CAACuC,eAAD;AACEoB,IAAAA,IAAI,EAAExD,IAAI,KAAK+C,aAAa,CAACU,gBAAvB,GAA0C,KAA1C,GAAkD;GAD1D,EAGE5D,mBAAA,CAACyC,aAAD;AACEG,IAAAA,WAAW,EAAE;AAAA,aAAMY,sBAAsB,CAAC,KAAD,CAA5B;AAAA;AACbb,IAAAA,SAAS,EAAE;AAAA,aAAMa,sBAAsB,CAAC,IAAD,CAA5B;AAAA;AACX5B,IAAAA,IAAI,EAAEA;AACNc,IAAAA,OAAO,EAAE;AACP,UAAIA,QAAJ,EAAa;AACXA,QAAAA,QAAO;;AACPY,QAAAA,SAAS,CAAC,KAAD,CAAT;AACD;AACF;GATH,CAHF,CADF,EAgBGnD,IAAI,KAAK+C,aAAa,CAACU,gBAAvB,IACC5D,mBAAA,CAAC6D,kBAAD,MAAA,EACE7D,mBAAA,CAAC8D,YAAD;AAAcC,IAAAA,GAAG,EAAEN;GAAnB,CADF,CAjBJ,CADF,EAuBGF,mBAAmB,IAClBvD,mBAAA,CAACgE,mBAAD;AACEC,IAAAA,KAAK,EAAE9D,IAAI,KAAK+C,aAAa,CAACgB,QAAvB,GAAkC,MAAlC,GAA2C;AAClDH,IAAAA,GAAG,EAAEI;GAFP,CAxBJ,CADF,CADW,GAiCT,IAjCJ;AAkCD,CA/CM;AAiDP,IAAM9D,WAAS,gBAAGC,MAAM,CAACC,GAAV;AAAA;AAAA;AAAA,mIAAf;AAcA,IAAMgC,eAAa,gBAAGjC,MAAM,CAACC,GAAV;AAAA;AAAA;AAAA,mCACT;AAAA,MAAGoD,IAAH,SAAGA,IAAH;AAAA,SAAcA,IAAd;AAAA,CADS,CAAnB;AAKA,IAAME,kBAAkB,gBAAGvD,MAAM,CAACC,GAAV;AAAA;AAAA;AAAA,2DAAxB;AAMA,IAAMuD,YAAY,gBAAGxD,MAAM,CAAC8D,GAAV;AAAA;AAAA;AAAA,2DAAlB;AAUA,IAAMJ,mBAAmB,gBAAG1D,MAAM,CAAC8D,GAAV;AAAA;AAAA;AAAA,0GAEd;AAAA,MAAGH,KAAH,SAAGA,KAAH;AAAA,SAAeA,KAAf;AAAA,CAFc,CAAzB;;;;"}
|
|
1
|
+
{"version":3,"file":"long-bow.esm.js","sources":["../src/RPGUI/RPGUI.tsx","../src/RPGUI/RPGUIContainer.tsx","../src/NPCDialog/img/npcDialog/npcThumbnails/alice.png","../src/NPCDialog/img/space.gif","../src/hooks/useEventListener.ts","../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","const img = require('./alice.png'); export default img;","const img = require('./space.gif'); export default img;","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 { RPGUI } from '../RPGUI/RPGUI';\nimport { RPGUIContainer } from '../RPGUI/RPGUIContainer';\nimport aliceDefaultThumbnail from './img/npcDialog/npcThumbnails/alice.png';\nimport pressSpaceGif from './img/space.gif';\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 imagePath?: string;\n onClose?: () => void;\n}\n\nexport const NPCDialog: React.FC<INPCDialogProps> = ({\n text,\n type,\n onClose,\n imagePath,\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={imagePath || aliceDefaultThumbnail} />\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","img","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","imagePath","isOpen","setIsOpen","showGoNextIndicator","setShowGoNextIndicator","flex","TextAndThumbnail","ThumbnailContainer","NPCThumbnail","src","aliceDefaultThumbnail","PressSpaceIndicator","right","TextOnly","pressSpaceGif"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
|
-
import pressSpaceGif from '../assets/space.gif';
|
|
4
3
|
import { RPGUI } from '../RPGUI/RPGUI';
|
|
5
4
|
import { RPGUIContainer } from '../RPGUI/RPGUIContainer';
|
|
5
|
+
import aliceDefaultThumbnail from './img/npcDialog/npcThumbnails/alice.png';
|
|
6
|
+
import pressSpaceGif from './img/space.gif';
|
|
6
7
|
import { NPCDialogText } from './NPCDialogText';
|
|
7
8
|
export enum NPCDialogType {
|
|
8
9
|
TextOnly = 'TextOnly',
|
|
@@ -12,23 +13,20 @@ export enum NPCDialogType {
|
|
|
12
13
|
export interface INPCDialogProps {
|
|
13
14
|
text: string;
|
|
14
15
|
type: NPCDialogType;
|
|
15
|
-
|
|
16
|
+
imagePath?: string;
|
|
16
17
|
onClose?: () => void;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export const NPCDialog: React.FC<INPCDialogProps> = ({
|
|
20
21
|
text,
|
|
21
22
|
type,
|
|
22
|
-
npcKey,
|
|
23
23
|
onClose,
|
|
24
|
+
imagePath,
|
|
24
25
|
}) => {
|
|
25
26
|
const [isOpen, setIsOpen] = useState<boolean>(true);
|
|
26
27
|
const [showGoNextIndicator, setShowGoNextIndicator] =
|
|
27
28
|
useState<boolean>(false);
|
|
28
29
|
|
|
29
|
-
//dynamically require npc thumbnail
|
|
30
|
-
const npcThumbnail = require(`../assets/npcDialog/npcThumbnails/${npcKey}.png`);
|
|
31
|
-
|
|
32
30
|
return isOpen ? (
|
|
33
31
|
<RPGUI>
|
|
34
32
|
<RPGUIContainer type="framed-golden">
|
|
@@ -50,7 +48,7 @@ export const NPCDialog: React.FC<INPCDialogProps> = ({
|
|
|
50
48
|
</TextContainer>
|
|
51
49
|
{type === NPCDialogType.TextAndThumbnail && (
|
|
52
50
|
<ThumbnailContainer>
|
|
53
|
-
<NPCThumbnail src={
|
|
51
|
+
<NPCThumbnail src={imagePath || aliceDefaultThumbnail} />
|
|
54
52
|
</ThumbnailContainer>
|
|
55
53
|
)}
|
|
56
54
|
</Container>
|
|
Binary file
|
|
File without changes
|
package/src/types/index.d.ts
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|