@turnipxenon/pineapple 2.4.14 → 2.4.15
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/.idea/workspace.xml +64 -49
- package/.svelte-kit/__package__/app.postcss +15 -1
- package/.svelte-kit/__package__/components/DialogOverlay.svelte +48 -47
- package/.svelte-kit/__package__/components/dialog_manager/DialogManager.d.ts +8 -3
- package/.svelte-kit/__package__/components/dialog_manager/DialogManager.js +35 -11
- package/.svelte-kit/__package__/components/dialog_manager/DialogManagerStore.js +1 -1
- package/.svelte-kit/__package__/components/layouts/SeaweedBaseLayout.svelte +2 -2
- package/.svelte-kit/__package__/components/pineapple/PineappleBaseLayout.svelte +18 -6
- package/.svelte-kit/__package__/components/pineapple/toast/Toast.svelte +1 -0
- package/.svelte-kit/__package__/scripts/pineapple_fiber/PineappleFiberParser.d.ts +2 -0
- package/.svelte-kit/__package__/scripts/pineapple_fiber/PineappleFiberParser.js +137 -0
- package/.svelte-kit/__package__/scripts/pineapple_fiber/PineappleWeaver.js +3 -134
- package/.svelte-kit/__package__/types/pineapple_fiber/DialogState.d.ts +2 -1
- package/.svelte-kit/__package__/types/pineapple_fiber/DialogState.js +1 -0
- package/.svelte-kit/ambient.d.ts +2 -0
- package/.svelte-kit/generated/server/internal.js +1 -1
- package/dist/app.postcss +15 -1
- package/dist/components/DialogOverlay.svelte +48 -47
- package/dist/components/dialog_manager/DialogManager.d.ts +8 -3
- package/dist/components/dialog_manager/DialogManager.js +35 -11
- package/dist/components/dialog_manager/DialogManagerStore.js +1 -1
- package/dist/components/layouts/SeaweedBaseLayout.svelte +2 -2
- package/dist/components/pineapple/PineappleBaseLayout.svelte +18 -6
- package/dist/components/pineapple/toast/Toast.svelte +1 -0
- package/dist/scripts/pineapple_fiber/PineappleFiberParser.d.ts +2 -0
- package/dist/scripts/pineapple_fiber/PineappleFiberParser.js +137 -0
- package/dist/scripts/pineapple_fiber/PineappleWeaver.js +3 -134
- package/dist/types/pineapple_fiber/DialogState.d.ts +2 -1
- package/dist/types/pineapple_fiber/DialogState.js +1 -0
- package/package.json +1 -1
- package/src/lib/app.postcss +15 -1
- package/src/lib/components/DialogOverlay.svelte +56 -54
- package/src/lib/components/dialog_manager/DialogManager.ts +38 -12
- package/src/lib/components/dialog_manager/DialogManagerStore.ts +1 -1
- package/src/lib/components/layouts/SeaweedBaseLayout.svelte +2 -2
- package/src/lib/components/pineapple/PineappleBaseLayout.svelte +19 -6
- package/src/lib/components/pineapple/toast/Toast.svelte +1 -0
- package/src/lib/scripts/pineapple_fiber/PineappleFiberParser.ts +177 -0
- package/src/lib/scripts/pineapple_fiber/PineappleWeaver.ts +3 -176
- package/src/lib/types/pineapple_fiber/DialogState.ts +2 -1
- package/src/routes/(pineapple)/+page.svelte +2 -2
- package/src/routes/(pineapple)/pineapple/+page.svelte +19 -1
- package/src/routes/(pineapple)/pineapple/TestDialog.yarn +7 -0
- package/vite.config.ts +2 -1
- package/.svelte-kit/__package__/components/pineapple/overlay_manager/OverlayManager.d.ts +0 -0
- package/.svelte-kit/__package__/components/pineapple/overlay_manager/OverlayManager.js +0 -1
- package/dist/components/pineapple/overlay_manager/OverlayManager.d.ts +0 -0
- package/dist/components/pineapple/overlay_manager/OverlayManager.js +0 -1
- package/src/lib/components/pineapple/overlay_manager/OverlayManager.ts +0 -0
|
@@ -4,8 +4,10 @@ import { page } from "$app/stores";
|
|
|
4
4
|
import { enableBackground } from "../../store";
|
|
5
5
|
import AresLogo from "../../assets/characters/ares/ares_logo.webp";
|
|
6
6
|
import FABIcon from "../../assets/placeholder/placeholder_circle.png";
|
|
7
|
-
import
|
|
7
|
+
import CloseIcon from "../../assets/icons/close.svg";
|
|
8
|
+
import { dialogManager, enableDialogueOverlay } from "../dialog_manager/DialogManagerStore";
|
|
8
9
|
import Toast from "./toast/Toast.svelte";
|
|
10
|
+
import DialogOverlay from "../DialogOverlay.svelte";
|
|
9
11
|
let pages = [];
|
|
10
12
|
const updateBreadcrumb = (pathname) => {
|
|
11
13
|
pages = [];
|
|
@@ -40,6 +42,7 @@ let enableDialogueOverlayValue = true;
|
|
|
40
42
|
enableDialogueOverlay.subscribe((value) => {
|
|
41
43
|
enableDialogueOverlayValue = value;
|
|
42
44
|
});
|
|
45
|
+
enableDialogueOverlay.set(false);
|
|
43
46
|
</script>
|
|
44
47
|
|
|
45
48
|
<!-- App Shell -->
|
|
@@ -49,9 +52,13 @@ enableDialogueOverlay.subscribe((value) => {
|
|
|
49
52
|
|
|
50
53
|
<!--todo: turn off hidden when it's time-->
|
|
51
54
|
<button type="button" class="fab" on:click={()=>{
|
|
52
|
-
|
|
55
|
+
dialogManager.toggleDialogOverlay()
|
|
53
56
|
}}>
|
|
54
|
-
|
|
57
|
+
{#if (enableDialogueOverlayValue)}
|
|
58
|
+
<img class="img-icon" src={CloseIcon} alt="interactive floating action button represented as a turnip">
|
|
59
|
+
{:else }
|
|
60
|
+
<img src={FABIcon} alt="interactive floating action button represented as a turnip">
|
|
61
|
+
{/if}
|
|
55
62
|
</button>
|
|
56
63
|
|
|
57
64
|
<AppShell>
|
|
@@ -92,6 +99,8 @@ enableDialogueOverlay.subscribe((value) => {
|
|
|
92
99
|
|
|
93
100
|
<Toast></Toast>
|
|
94
101
|
|
|
102
|
+
<DialogOverlay></DialogOverlay>
|
|
103
|
+
|
|
95
104
|
<div class="default-page-container">
|
|
96
105
|
<slot />
|
|
97
106
|
<div class="footer-space" />
|
|
@@ -111,8 +120,8 @@ enableDialogueOverlay.subscribe((value) => {
|
|
|
111
120
|
|
|
112
121
|
<style>
|
|
113
122
|
:root {
|
|
114
|
-
--dialog-
|
|
115
|
-
--dialog-box-width: min(calc(50em + 4em), calc(100vw - var(--dialog-
|
|
123
|
+
--dialog-start-pad: clamp(0em, 5vw, 2em);
|
|
124
|
+
--dialog-box-width: min(calc(50em + 4em), calc(100vw - var(--dialog-start-pad) - var(--theme-border-base)));
|
|
116
125
|
--dialog-box-height: clamp(15em, 50vw, 18em);
|
|
117
126
|
|
|
118
127
|
/** FAB icon margin/position calculation origin:
|
|
@@ -134,7 +143,6 @@ enableDialogueOverlay.subscribe((value) => {
|
|
|
134
143
|
align-items: center;
|
|
135
144
|
justify-content: center;
|
|
136
145
|
margin-top: 4em;
|
|
137
|
-
margin-left: clamp(1em, 15vw, 10em);
|
|
138
146
|
margin-right: 1em;
|
|
139
147
|
flex-direction: column;
|
|
140
148
|
z-index: 0;
|
|
@@ -222,6 +230,10 @@ enableDialogueOverlay.subscribe((value) => {
|
|
|
222
230
|
border-radius: 50%;
|
|
223
231
|
}
|
|
224
232
|
|
|
233
|
+
.fab > img {
|
|
234
|
+
width: 100%;
|
|
235
|
+
}
|
|
236
|
+
|
|
225
237
|
.fab:dir(ltr) {
|
|
226
238
|
right: var(--fab-margin);
|
|
227
239
|
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { PortraitType } from "../../types/pineapple_fiber/PortraitType";
|
|
2
|
+
const shouldDebug = false;
|
|
3
|
+
export const parseYarn = async (fileContent) => {
|
|
4
|
+
const dialogDetailList = [];
|
|
5
|
+
fileContent.split("===").map((unparsedNode) => {
|
|
6
|
+
// todo: detect empty nodes
|
|
7
|
+
// todo: improve the code readability
|
|
8
|
+
if (unparsedNode.trim() === "") {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const dialogDetails = {
|
|
12
|
+
// todo: dissect the line below and give comments because it is complex
|
|
13
|
+
dialogId: unparsedNode
|
|
14
|
+
.slice(unparsedNode.indexOf("title: "))
|
|
15
|
+
.split("\n")[0]
|
|
16
|
+
.split(" ")
|
|
17
|
+
.pop()
|
|
18
|
+
?.trim(),
|
|
19
|
+
portraitType: PortraitType.AresNeutral,
|
|
20
|
+
textContent: "" // will be filled later below
|
|
21
|
+
};
|
|
22
|
+
let portraitUnset = true;
|
|
23
|
+
// parse the PineappleFiber metatags
|
|
24
|
+
const unparsedBody = unparsedNode.split("---").pop().trim();
|
|
25
|
+
const bodyList = unparsedBody.split("\n");
|
|
26
|
+
let contentIndexStart = 0;
|
|
27
|
+
for (let index = 0; index < bodyList.length; index++) {
|
|
28
|
+
const possibleTagPair = bodyList[index].split(": ");
|
|
29
|
+
const possibleTagName = possibleTagPair[0].toLowerCase();
|
|
30
|
+
if (!["portrait"].includes(possibleTagName)) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
contentIndexStart = index + 1; // increase count for each viable tah
|
|
34
|
+
switch (possibleTagName) {
|
|
35
|
+
case "portrait":
|
|
36
|
+
portraitUnset = false;
|
|
37
|
+
// todo: implement a way to match the appropriate portrait based on the metatag
|
|
38
|
+
// from https://stackoverflow.com/a/17381004/17836168
|
|
39
|
+
dialogDetails.portraitType =
|
|
40
|
+
PortraitType[possibleTagPair[1].trim()];
|
|
41
|
+
if (shouldDebug) {
|
|
42
|
+
console.log("Portrait detected:", possibleTagPair[1], " => ", dialogDetails.portraitType);
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// portrait check
|
|
48
|
+
if (portraitUnset) {
|
|
49
|
+
console.warn(`Portrait missing for node: ${dialogDetails.dialogId}`);
|
|
50
|
+
dialogDetails.portraitType = PortraitType.AresNeutral;
|
|
51
|
+
}
|
|
52
|
+
// remove the metatags from the body
|
|
53
|
+
const unprocessedContent = bodyList.slice(contentIndexStart).join("\n");
|
|
54
|
+
const contentPair = unprocessedContent.split("<ChoiceBreak>");
|
|
55
|
+
if (contentPair.length === 2) {
|
|
56
|
+
// parse for the choice names in the options
|
|
57
|
+
let ChoiceParsingState;
|
|
58
|
+
(function (ChoiceParsingState) {
|
|
59
|
+
ChoiceParsingState[ChoiceParsingState["Free"] = 0] = "Free";
|
|
60
|
+
ChoiceParsingState[ChoiceParsingState["Line"] = 1] = "Line"; // previously detected an option, will try to detect for the next option
|
|
61
|
+
})(ChoiceParsingState || (ChoiceParsingState = {}));
|
|
62
|
+
let parsingState = ChoiceParsingState.Free;
|
|
63
|
+
const currentChoiceDetail = { jumpNode: "", name: "" };
|
|
64
|
+
const choiceList = [];
|
|
65
|
+
let shouldSkipChoices = false;
|
|
66
|
+
const checkChoiceForSave = () => {
|
|
67
|
+
if (currentChoiceDetail.name !== "") {
|
|
68
|
+
choiceList.push({
|
|
69
|
+
name: currentChoiceDetail.name,
|
|
70
|
+
jumpNode: currentChoiceDetail.jumpNode
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
contentPair[1]
|
|
75
|
+
.trim()
|
|
76
|
+
.split("\n")
|
|
77
|
+
.filter((line) => {
|
|
78
|
+
const trimmedLine = line.trim();
|
|
79
|
+
if (shouldSkipChoices) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
if (trimmedLine.startsWith("// ignore the rest")) {
|
|
83
|
+
shouldSkipChoices = true;
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
})
|
|
88
|
+
.map((line) => {
|
|
89
|
+
const trimmedLine = line.trim();
|
|
90
|
+
switch (parsingState) {
|
|
91
|
+
case ChoiceParsingState.Free:
|
|
92
|
+
if (trimmedLine.startsWith("->")) {
|
|
93
|
+
// save previous choice
|
|
94
|
+
checkChoiceForSave();
|
|
95
|
+
// write start of new choice
|
|
96
|
+
currentChoiceDetail.name = trimmedLine.split(" ").pop();
|
|
97
|
+
parsingState = ChoiceParsingState.Line;
|
|
98
|
+
}
|
|
99
|
+
break;
|
|
100
|
+
case ChoiceParsingState.Line:
|
|
101
|
+
if (trimmedLine.startsWith("<<jump")) {
|
|
102
|
+
const jumpNode = trimmedLine.split(" ").pop();
|
|
103
|
+
currentChoiceDetail.jumpNode = jumpNode.slice(0, jumpNode.length - 2); // remove ">>"
|
|
104
|
+
parsingState = ChoiceParsingState.Free;
|
|
105
|
+
}
|
|
106
|
+
break;
|
|
107
|
+
default:
|
|
108
|
+
console.error(`Unimplemented parsing state: ${parsingState}`);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
checkChoiceForSave();
|
|
113
|
+
dialogDetails.textContent = contentPair[0];
|
|
114
|
+
// handle choice start tags to a href
|
|
115
|
+
choiceList.forEach((choiceDetail) => {
|
|
116
|
+
const keyword = `<choice ${choiceDetail.name}>`;
|
|
117
|
+
while (dialogDetails.textContent.includes(keyword)) {
|
|
118
|
+
dialogDetails.textContent = dialogDetails.textContent.replace(keyword, `<a class="choice-${choiceDetail.jumpNode} dialog-choice" title="Click to continue the dialog">`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
const externalKeyword = "<a href=";
|
|
122
|
+
while (dialogDetails.textContent.includes(externalKeyword)) {
|
|
123
|
+
dialogDetails.textContent = dialogDetails.textContent.replace(externalKeyword, "<a target=\"_blank\" class=\"external-link\" href="); // make all external tags with a custom cursor
|
|
124
|
+
}
|
|
125
|
+
const choiceEndKeyword = "</choice>";
|
|
126
|
+
while (dialogDetails.textContent.includes(choiceEndKeyword)) {
|
|
127
|
+
dialogDetails.textContent = dialogDetails.textContent.replace(choiceEndKeyword, "</a>"); // convert all choice end tags to a tags
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
// assume only one which indicates it is choiceless
|
|
132
|
+
dialogDetails.textContent = unprocessedContent;
|
|
133
|
+
}
|
|
134
|
+
dialogDetailList.push(dialogDetails);
|
|
135
|
+
});
|
|
136
|
+
return dialogDetailList;
|
|
137
|
+
};
|
|
@@ -9,147 +9,16 @@
|
|
|
9
9
|
import { getAllFiles } from "../util/FileManagement";
|
|
10
10
|
import fs, { readFileSync } from "fs";
|
|
11
11
|
import { PortraitType } from "../../types/pineapple_fiber/PortraitType";
|
|
12
|
-
|
|
12
|
+
import { parseYarn } from "./PineappleFiberParser";
|
|
13
13
|
const pineappleWeaverRun = () => {
|
|
14
14
|
console.info("Starting Pineapple Weaver.");
|
|
15
15
|
const BASE_PATH = "./src/routes";
|
|
16
16
|
getAllFiles(BASE_PATH, (path) => {
|
|
17
17
|
return path.split(".").pop() === "yarn";
|
|
18
|
-
}).map((filePath) => {
|
|
18
|
+
}).map(async (filePath) => {
|
|
19
19
|
console.info(`Converting: ${filePath}`);
|
|
20
20
|
const fileContent = readFileSync(filePath, "utf-8");
|
|
21
|
-
const dialogDetailList =
|
|
22
|
-
fileContent.split("===").map((unparsedNode) => {
|
|
23
|
-
// todo: detect empty nodes
|
|
24
|
-
// todo: improve the code readability
|
|
25
|
-
if (unparsedNode.trim() === "") {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const dialogDetails = {
|
|
29
|
-
// todo: dissect the line below and give comments because it is complex
|
|
30
|
-
dialogId: unparsedNode
|
|
31
|
-
.slice(unparsedNode.indexOf("title: "))
|
|
32
|
-
.split("\n")[0]
|
|
33
|
-
.split(" ")
|
|
34
|
-
.pop()
|
|
35
|
-
?.trim(),
|
|
36
|
-
portraitType: PortraitType.AresNeutral,
|
|
37
|
-
textContent: "" // will be filled later below
|
|
38
|
-
};
|
|
39
|
-
let portraitUnset = true;
|
|
40
|
-
// parse the PineappleFiber metatags
|
|
41
|
-
const unparsedBody = unparsedNode.split("---").pop().trim();
|
|
42
|
-
const bodyList = unparsedBody.split("\n");
|
|
43
|
-
let contentIndexStart = 0;
|
|
44
|
-
for (let index = 0; index < bodyList.length; index++) {
|
|
45
|
-
const possibleTagPair = bodyList[index].split(": ");
|
|
46
|
-
const possibleTagName = possibleTagPair[0].toLowerCase();
|
|
47
|
-
if (!["portrait"].includes(possibleTagName)) {
|
|
48
|
-
break;
|
|
49
|
-
}
|
|
50
|
-
contentIndexStart = index + 1; // increase count for each viable tah
|
|
51
|
-
switch (possibleTagName) {
|
|
52
|
-
case "portrait":
|
|
53
|
-
portraitUnset = false;
|
|
54
|
-
// todo: implement a way to match the appropriate portrait based on the metatag
|
|
55
|
-
// from https://stackoverflow.com/a/17381004/17836168
|
|
56
|
-
dialogDetails.portraitType =
|
|
57
|
-
PortraitType[possibleTagPair[1].trim()];
|
|
58
|
-
if (shouldDebug) {
|
|
59
|
-
console.log("Portrait detected:", possibleTagPair[1], " => ", dialogDetails.portraitType);
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// portrait check
|
|
65
|
-
if (portraitUnset) {
|
|
66
|
-
console.warn(`Portrait missing for node: ${dialogDetails.dialogId}`);
|
|
67
|
-
dialogDetails.portraitType = PortraitType.AresNeutral;
|
|
68
|
-
}
|
|
69
|
-
// remove the metatags from the body
|
|
70
|
-
const unprocessedContent = bodyList.slice(contentIndexStart).join("\n");
|
|
71
|
-
const contentPair = unprocessedContent.split("<ChoiceBreak>");
|
|
72
|
-
if (contentPair.length === 2) {
|
|
73
|
-
// parse for the choice names in the options
|
|
74
|
-
let ChoiceParsingState;
|
|
75
|
-
(function (ChoiceParsingState) {
|
|
76
|
-
ChoiceParsingState[ChoiceParsingState["Free"] = 0] = "Free";
|
|
77
|
-
ChoiceParsingState[ChoiceParsingState["Line"] = 1] = "Line"; // previously detected an option, will try to detect for the next option
|
|
78
|
-
})(ChoiceParsingState || (ChoiceParsingState = {}));
|
|
79
|
-
let parsingState = ChoiceParsingState.Free;
|
|
80
|
-
const currentChoiceDetail = { jumpNode: "", name: "" };
|
|
81
|
-
const choiceList = [];
|
|
82
|
-
let shouldSkipChoices = false;
|
|
83
|
-
const checkChoiceForSave = () => {
|
|
84
|
-
if (currentChoiceDetail.name !== "") {
|
|
85
|
-
choiceList.push({
|
|
86
|
-
name: currentChoiceDetail.name,
|
|
87
|
-
jumpNode: currentChoiceDetail.jumpNode
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
contentPair[1]
|
|
92
|
-
.trim()
|
|
93
|
-
.split("\n")
|
|
94
|
-
.filter((line) => {
|
|
95
|
-
const trimmedLine = line.trim();
|
|
96
|
-
if (shouldSkipChoices) {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
if (trimmedLine.startsWith("// ignore the rest")) {
|
|
100
|
-
shouldSkipChoices = true;
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
return true;
|
|
104
|
-
})
|
|
105
|
-
.map((line) => {
|
|
106
|
-
const trimmedLine = line.trim();
|
|
107
|
-
switch (parsingState) {
|
|
108
|
-
case ChoiceParsingState.Free:
|
|
109
|
-
if (trimmedLine.startsWith("->")) {
|
|
110
|
-
// save previous choice
|
|
111
|
-
checkChoiceForSave();
|
|
112
|
-
// write start of new choice
|
|
113
|
-
currentChoiceDetail.name = trimmedLine.split(" ").pop();
|
|
114
|
-
parsingState = ChoiceParsingState.Line;
|
|
115
|
-
}
|
|
116
|
-
break;
|
|
117
|
-
case ChoiceParsingState.Line:
|
|
118
|
-
if (trimmedLine.startsWith("<<jump")) {
|
|
119
|
-
const jumpNode = trimmedLine.split(" ").pop();
|
|
120
|
-
currentChoiceDetail.jumpNode = jumpNode.slice(0, jumpNode.length - 2); // remove ">>"
|
|
121
|
-
parsingState = ChoiceParsingState.Free;
|
|
122
|
-
}
|
|
123
|
-
break;
|
|
124
|
-
default:
|
|
125
|
-
console.error(`Unimplemented parsing state: ${parsingState}`);
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
checkChoiceForSave();
|
|
130
|
-
dialogDetails.textContent = contentPair[0];
|
|
131
|
-
// handle choice start tags to a href
|
|
132
|
-
choiceList.forEach((choiceDetail) => {
|
|
133
|
-
const keyword = `<choice ${choiceDetail.name}>`;
|
|
134
|
-
while (dialogDetails.textContent.includes(keyword)) {
|
|
135
|
-
dialogDetails.textContent = dialogDetails.textContent.replace(keyword, `<a class="choice-${choiceDetail.jumpNode} dialog-choice" title="Click to continue the dialog">`);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
const externalKeyword = "<a href=";
|
|
139
|
-
while (dialogDetails.textContent.includes(externalKeyword)) {
|
|
140
|
-
dialogDetails.textContent = dialogDetails.textContent.replace(externalKeyword, '<a target="_blank" class="external-link" href='); // make all external tags with a custom cursor
|
|
141
|
-
}
|
|
142
|
-
const choiceEndKeyword = "</choice>";
|
|
143
|
-
while (dialogDetails.textContent.includes(choiceEndKeyword)) {
|
|
144
|
-
dialogDetails.textContent = dialogDetails.textContent.replace(choiceEndKeyword, "</a>"); // convert all choice end tags to a tags
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
// assume only one which indicates it's choiceless
|
|
149
|
-
dialogDetails.textContent = unprocessedContent;
|
|
150
|
-
}
|
|
151
|
-
dialogDetailList.push(dialogDetails);
|
|
152
|
-
});
|
|
21
|
+
const dialogDetailList = await parseYarn(fileContent);
|
|
153
22
|
const dialogDetailToString = (detail) => {
|
|
154
23
|
if (detail.portraitType === undefined) {
|
|
155
24
|
detail.portraitType = PortraitType.AresNeutral;
|
|
@@ -3,4 +3,5 @@ export var DialogState;
|
|
|
3
3
|
DialogState[DialogState["Invisible"] = 0] = "Invisible";
|
|
4
4
|
DialogState[DialogState["Visible"] = 1] = "Visible";
|
|
5
5
|
DialogState[DialogState["Busy"] = 2] = "Busy";
|
|
6
|
+
DialogState[DialogState["Inherit"] = 3] = "Inherit";
|
|
6
7
|
})(DialogState || (DialogState = {}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turnipxenon/pineapple",
|
|
3
3
|
"description": "personal package for base styling for other personal projects",
|
|
4
|
-
"version": "2.4.
|
|
4
|
+
"version": "2.4.15",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite dev",
|
|
7
7
|
"build": "npm run check-requirements && vite build && yarn package",
|
package/src/lib/app.postcss
CHANGED
|
@@ -92,7 +92,7 @@ ul {
|
|
|
92
92
|
.default-page-container {
|
|
93
93
|
@apply flex justify-center items-center;
|
|
94
94
|
margin-top: 4em;
|
|
95
|
-
margin-left:
|
|
95
|
+
margin-left: 1em;
|
|
96
96
|
margin-right: 1em;
|
|
97
97
|
flex-direction: column;
|
|
98
98
|
z-index: 0;
|
|
@@ -191,3 +191,17 @@ a:active {
|
|
|
191
191
|
background: rgba(var(--color-secondary-500));
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
.dialog-box {
|
|
195
|
+
background-color: rgb(var(--color-surface-500) / 0.9);
|
|
196
|
+
position: fixed;
|
|
197
|
+
bottom: 0;
|
|
198
|
+
width: var(--dialog-box-width); /*75em + 4em padding*/
|
|
199
|
+
height: var(--dialog-box-height);
|
|
200
|
+
max-width: calc(100vw - ((var(--fab-margin) * 2) + 4em));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.dark .dialog-box {
|
|
204
|
+
background-color: rgb(var(--color-surface-900) / 0.95);
|
|
205
|
+
--tw-ring-color: rgb(var(--color-text-400));
|
|
206
|
+
/*background-color: red;*/
|
|
207
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { onMount } from "svelte";
|
|
4
4
|
|
|
5
5
|
import { dialogManager } from "$lib/components/dialog_manager/DialogManagerStore";
|
|
6
|
+
import { DialogState } from "$pkg/types/pineapple_fiber/DialogState";
|
|
6
7
|
|
|
7
8
|
let currentMessage = "";
|
|
8
9
|
dialogManager.currentMessage.subscribe((value) => {
|
|
@@ -21,8 +22,16 @@
|
|
|
21
22
|
});
|
|
22
23
|
|
|
23
24
|
let hidePercent = 100;
|
|
25
|
+
let isHidden = true;
|
|
24
26
|
dialogManager.hidePercent.subscribe((value) => {
|
|
25
27
|
hidePercent = value * 0.4;
|
|
28
|
+
isHidden = false;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
dialogManager.currentReadableState.subscribe((value) => {
|
|
32
|
+
isHidden = value === DialogState.Invisible;
|
|
33
|
+
if (value === DialogState.Invisible) {
|
|
34
|
+
}
|
|
26
35
|
});
|
|
27
36
|
|
|
28
37
|
const onDialogClick = () => {
|
|
@@ -30,7 +39,10 @@
|
|
|
30
39
|
};
|
|
31
40
|
</script>
|
|
32
41
|
|
|
33
|
-
<div class="dialog-elements"
|
|
42
|
+
<div class="dialog-elements"
|
|
43
|
+
hidden={isHidden}
|
|
44
|
+
style="--hidePercentWidth: -{hidePercent}vw;
|
|
45
|
+
--hidePercentHeight: {hidePercent}vh;">
|
|
34
46
|
<img src={currentPortrait} alt="Ares" class="dialog-portrait" />
|
|
35
47
|
<div class="card dialog-box variant-ghost-primary" on:click={onDialogClick}>
|
|
36
48
|
<div class="card dialog-name">
|
|
@@ -44,57 +56,47 @@
|
|
|
44
56
|
</div>
|
|
45
57
|
|
|
46
58
|
<style>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
transform: translateX(clamp(0em, 5vw - 0.5em, 1em)) translateY(-50%);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.dialog-portrait {
|
|
94
|
-
position: fixed;
|
|
95
|
-
bottom: 0;
|
|
96
|
-
left: clamp(-4rem, calc(5vw - 5em), 0rem);
|
|
97
|
-
height: clamp(30rem, 75vw, 40rem);
|
|
98
|
-
width: auto;
|
|
99
|
-
}
|
|
59
|
+
.dialog-elements {
|
|
60
|
+
position: fixed;
|
|
61
|
+
z-index: 10;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.dialog-elements > img {
|
|
65
|
+
transform: translateX(var(--hidePercentWidth));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.dialog-elements > div {
|
|
69
|
+
transform: translateY(var(--hidePercentHeight));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.dialog-box *,
|
|
73
|
+
.dialog-name * {
|
|
74
|
+
font-size: clamp(1em, 5vw, 1.3em);
|
|
75
|
+
line-height: 1.5em;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.dialog-padding :global(p) {
|
|
79
|
+
font-size: clamp(1em, 5vw, 1.3em) !important;
|
|
80
|
+
line-height: 1.5em !important;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.dialog-padding {
|
|
84
|
+
padding: clamp(1.5em, 5vw, 1.75em) clamp(0em, 5vw - 0.5em, 2em) 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.dialog-name {
|
|
88
|
+
@apply pt-2 px-4;
|
|
89
|
+
position: fixed;
|
|
90
|
+
|
|
91
|
+
/* for centering vertically */
|
|
92
|
+
transform: translateX(clamp(0em, 5vw - 0.5em, 1em)) translateY(-50%);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.dialog-portrait {
|
|
96
|
+
position: fixed;
|
|
97
|
+
bottom: 0;
|
|
98
|
+
left: clamp(-4rem, calc(5vw - 5em), 0rem);
|
|
99
|
+
height: clamp(30rem, 75vw, 40rem);
|
|
100
|
+
width: auto;
|
|
101
|
+
}
|
|
100
102
|
</style>
|