@turnipxenon/pineapple 2.4.13 → 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/discord.xml +1 -1
- package/.idea/workspace.xml +179 -149
- package/.svelte-kit/__package__/app.postcss +43 -3
- package/.svelte-kit/__package__/assets/icons/close.svg +1 -0
- package/.svelte-kit/__package__/components/Card.svelte +1 -1
- package/.svelte-kit/__package__/components/Chip.svelte +1 -0
- 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/{layouts → pineapple}/PineappleBaseLayout.svelte +66 -30
- package/.svelte-kit/__package__/components/pineapple/toast/DefaultToastBody.d.ts +8 -0
- package/.svelte-kit/__package__/components/pineapple/toast/DefaultToastBody.js +1 -0
- package/.svelte-kit/__package__/components/pineapple/toast/DefaultToastBody.svelte +48 -0
- package/.svelte-kit/__package__/components/pineapple/toast/DefaultToastBody.svelte.d.ts +20 -0
- package/.svelte-kit/__package__/components/pineapple/toast/Toast.d.ts +27 -0
- package/.svelte-kit/__package__/components/pineapple/toast/Toast.js +37 -0
- package/.svelte-kit/__package__/components/pineapple/toast/Toast.svelte +90 -0
- package/.svelte-kit/__package__/components/pineapple/toast/Toast.svelte.d.ts +14 -0
- package/.svelte-kit/__package__/components/pineapple/toast/custom-toast/TestCustomToast.d.ts +5 -0
- package/.svelte-kit/__package__/components/pineapple/toast/custom-toast/TestCustomToast.js +1 -0
- package/.svelte-kit/__package__/components/pineapple/toast/custom-toast/TestCustomToast.svelte +1 -0
- package/.svelte-kit/__package__/components/pineapple/toast/custom-toast/TestCustomToast.svelte.d.ts +23 -0
- package/.svelte-kit/__package__/index.d.ts +1 -1
- package/.svelte-kit/__package__/index.js +1 -1
- 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/client/app.js +1 -1
- package/.svelte-kit/generated/client/nodes/5.js +1 -1
- package/.svelte-kit/generated/server/internal.js +1 -1
- package/.svelte-kit/types/route_meta_data.json +1 -1
- package/.svelte-kit/types/src/routes/$types.d.ts +1 -1
- package/.svelte-kit/types/src/routes/(pineapple)/$types.d.ts +1 -1
- package/.svelte-kit/types/src/routes/(pineapple)/{personal → pineapple}/$types.d.ts +1 -1
- package/dist/app.postcss +43 -3
- package/dist/assets/icons/close.svg +1 -0
- package/dist/components/Card.svelte +1 -1
- package/dist/components/Chip.svelte +1 -0
- 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/{layouts → pineapple}/PineappleBaseLayout.svelte +66 -30
- package/dist/components/pineapple/toast/DefaultToastBody.d.ts +8 -0
- package/dist/components/pineapple/toast/DefaultToastBody.js +1 -0
- package/dist/components/pineapple/toast/DefaultToastBody.svelte +48 -0
- package/dist/components/pineapple/toast/DefaultToastBody.svelte.d.ts +20 -0
- package/dist/components/pineapple/toast/Toast.d.ts +27 -0
- package/dist/components/pineapple/toast/Toast.js +37 -0
- package/dist/components/pineapple/toast/Toast.svelte +90 -0
- package/dist/components/pineapple/toast/Toast.svelte.d.ts +14 -0
- package/dist/components/pineapple/toast/custom-toast/TestCustomToast.d.ts +5 -0
- package/dist/components/pineapple/toast/custom-toast/TestCustomToast.js +1 -0
- package/dist/components/pineapple/toast/custom-toast/TestCustomToast.svelte +1 -0
- package/dist/components/pineapple/toast/custom-toast/TestCustomToast.svelte.d.ts +23 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- 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/docs/OverlaySpec.md +23 -0
- package/docs/pull_request_template.md +34 -0
- package/package.json +1 -1
- package/src/lib/app.postcss +43 -3
- package/src/lib/assets/icons/close.svg +1 -0
- package/src/lib/components/Card.svelte +1 -1
- package/src/lib/components/Chip.svelte +1 -0
- 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 +220 -0
- package/src/lib/components/pineapple/toast/DefaultToastBody.svelte +43 -0
- package/src/lib/components/pineapple/toast/DefaultToastBody.ts +10 -0
- package/src/lib/components/pineapple/toast/Toast.svelte +114 -0
- package/src/lib/components/pineapple/toast/Toast.ts +57 -0
- package/src/lib/components/pineapple/toast/custom-toast/TestCustomToast.svelte +1 -0
- package/src/lib/components/pineapple/toast/custom-toast/TestCustomToast.ts +6 -0
- package/src/lib/index.ts +1 -1
- 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)/+layout.svelte +1 -1
- package/src/routes/(pineapple)/+page.svelte +3 -3
- package/src/routes/(pineapple)/pineapple/+page.svelte +62 -0
- package/src/routes/(pineapple)/pineapple/TestDialog.yarn +7 -0
- package/vite.config.ts +2 -1
- package/src/lib/components/layouts/PineappleBaseLayout.svelte +0 -182
- package/src/routes/(pineapple)/personal/+page.svelte +0 -37
- /package/.svelte-kit/__package__/components/{layouts → pineapple}/PineappleBaseLayout.svelte.d.ts +0 -0
- /package/dist/components/{layouts → pineapple}/PineappleBaseLayout.svelte.d.ts +0 -0
|
@@ -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/.svelte-kit/ambient.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ declare module '$env/static/private' {
|
|
|
46
46
|
export const HOMEDRIVE: string;
|
|
47
47
|
export const HOMEPATH: string;
|
|
48
48
|
export const IDEA_INITIAL_DIRECTORY: string;
|
|
49
|
+
export const IJ_RESTARTER_LOG: string;
|
|
49
50
|
export const INIT_CWD: string;
|
|
50
51
|
export const JAVA_HOME: string;
|
|
51
52
|
export const LOCALAPPDATA: string;
|
|
@@ -239,6 +240,7 @@ declare module '$env/dynamic/private' {
|
|
|
239
240
|
HOMEDRIVE: string;
|
|
240
241
|
HOMEPATH: string;
|
|
241
242
|
IDEA_INITIAL_DIRECTORY: string;
|
|
243
|
+
IJ_RESTARTER_LOG: string;
|
|
242
244
|
INIT_CWD: string;
|
|
243
245
|
JAVA_HOME: string;
|
|
244
246
|
LOCALAPPDATA: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as component } from "../../../../src/routes/(pineapple)/
|
|
1
|
+
export { default as component } from "../../../../src/routes/(pineapple)/pineapple/+page.svelte";
|
|
@@ -21,7 +21,7 @@ export const options = {
|
|
|
21
21
|
app: ({ head, body, assets, nonce, env }) => "<!DOCTYPE html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" href=\"" + assets + "/favicon.png\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width\" />\n\t\t" + head + "\n\t</head>\n\n\t<body data-sveltekit-preload-data=\"hover\" data-theme=\"crimson\">\n\t\t<div style=\"display: contents\" class=\"h-full overflow-hidden\">" + body + "</div>\n\t</body>\n</html>\n",
|
|
22
22
|
error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>" + message + "</title>\n\n\t\t<style>\n\t\t\tbody {\n\t\t\t\t--bg: white;\n\t\t\t\t--fg: #222;\n\t\t\t\t--divider: #ccc;\n\t\t\t\tbackground: var(--bg);\n\t\t\t\tcolor: var(--fg);\n\t\t\t\tfont-family:\n\t\t\t\t\tsystem-ui,\n\t\t\t\t\t-apple-system,\n\t\t\t\t\tBlinkMacSystemFont,\n\t\t\t\t\t'Segoe UI',\n\t\t\t\t\tRoboto,\n\t\t\t\t\tOxygen,\n\t\t\t\t\tUbuntu,\n\t\t\t\t\tCantarell,\n\t\t\t\t\t'Open Sans',\n\t\t\t\t\t'Helvetica Neue',\n\t\t\t\t\tsans-serif;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.error {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tmax-width: 32rem;\n\t\t\t\tmargin: 0 1rem;\n\t\t\t}\n\n\t\t\t.status {\n\t\t\t\tfont-weight: 200;\n\t\t\t\tfont-size: 3rem;\n\t\t\t\tline-height: 1;\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -0.05rem;\n\t\t\t}\n\n\t\t\t.message {\n\t\t\t\tborder-left: 1px solid var(--divider);\n\t\t\t\tpadding: 0 0 0 1rem;\n\t\t\t\tmargin: 0 0 0 1rem;\n\t\t\t\tmin-height: 2.5rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.message h1 {\n\t\t\t\tfont-weight: 400;\n\t\t\t\tfont-size: 1em;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\t--bg: #222;\n\t\t\t\t\t--fg: #ddd;\n\t\t\t\t\t--divider: #666;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"error\">\n\t\t\t<span class=\"status\">" + status + "</span>\n\t\t\t<div class=\"message\">\n\t\t\t\t<h1>" + message + "</h1>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>\n"
|
|
23
23
|
},
|
|
24
|
-
version_hash: "
|
|
24
|
+
version_hash: "1nwz0uu"
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
export async function get_hooks() {
|
|
@@ -11,7 +11,7 @@ type OutputDataShape<T> = MaybeWithVoid<Omit<App.PageData, RequiredKeys<T>> & Pa
|
|
|
11
11
|
type EnsureDefined<T> = T extends null | undefined ? {} : T;
|
|
12
12
|
type OptionalUnion<U extends Record<string, any>, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude<A, keyof U>]?: never } & U : never;
|
|
13
13
|
export type Snapshot<T = any> = Kit.Snapshot<T>;
|
|
14
|
-
type LayoutRouteId = RouteId | "/(pineapple)" | "/(pineapple)/
|
|
14
|
+
type LayoutRouteId = RouteId | "/(pineapple)" | "/(pineapple)/pineapple" | "/(seaweed)/portfolio" | "/(seaweed)/portfolio/actual" | null
|
|
15
15
|
type LayoutParams = RouteParams & { }
|
|
16
16
|
type LayoutParentData = EnsureDefined<{}>;
|
|
17
17
|
|
|
@@ -12,7 +12,7 @@ type EnsureDefined<T> = T extends null | undefined ? {} : T;
|
|
|
12
12
|
type OptionalUnion<U extends Record<string, any>, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude<A, keyof U>]?: never } & U : never;
|
|
13
13
|
export type Snapshot<T = any> = Kit.Snapshot<T>;
|
|
14
14
|
type PageParentData = Omit<EnsureDefined<import('../$types.js').LayoutData>, keyof LayoutData> & EnsureDefined<LayoutData>;
|
|
15
|
-
type LayoutRouteId = RouteId | "/(pineapple)" | "/(pineapple)/
|
|
15
|
+
type LayoutRouteId = RouteId | "/(pineapple)" | "/(pineapple)/pineapple"
|
|
16
16
|
type LayoutParams = RouteParams & { }
|
|
17
17
|
type LayoutParentData = EnsureDefined<import('../$types.js').LayoutData>;
|
|
18
18
|
|
|
@@ -4,7 +4,7 @@ type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
|
|
|
4
4
|
// @ts-ignore
|
|
5
5
|
type MatcherParam<M> = M extends (param : string) => param is infer U ? U extends string ? U : string : string;
|
|
6
6
|
type RouteParams = { };
|
|
7
|
-
type RouteId = '/(pineapple)/
|
|
7
|
+
type RouteId = '/(pineapple)/pineapple';
|
|
8
8
|
type MaybeWithVoid<T> = {} extends T ? T | void : T;
|
|
9
9
|
export type RequiredKeys<T> = { [K in keyof T]-?: {} extends { [P in K]: T[K] } ? never : K; }[keyof T];
|
|
10
10
|
type OutputDataShape<T> = MaybeWithVoid<Omit<App.PageData, RequiredKeys<T>> & Partial<Pick<App.PageData, keyof T & keyof App.PageData>> & Record<string, any>>
|
package/dist/app.postcss
CHANGED
|
@@ -41,11 +41,11 @@ html, body {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/* todo: add some hues to the icon that should be in sync with primary and make them not pure darkness */
|
|
44
|
-
.turnip-button > img {
|
|
44
|
+
.turnip-button > img, .img-icon {
|
|
45
45
|
filter: grayscale(100%) brightness(0%) invert(25%);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
.dark .turnip-button > img {
|
|
48
|
+
.dark .turnip-button > img, .dark .img-icon {
|
|
49
49
|
filter: grayscale(100%) brightness(0%) invert(100%);
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -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;
|
|
@@ -164,4 +164,44 @@ a:active {
|
|
|
164
164
|
.accordion-item {
|
|
165
165
|
@apply variant-filled-primary rounded-md;
|
|
166
166
|
}
|
|
167
|
+
|
|
167
168
|
/* endregion Accordion css for handling missing styles in package */
|
|
169
|
+
|
|
170
|
+
:root {
|
|
171
|
+
--shadow-color: rgba(91, 79, 54, 0.5);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* todo: adjust shadow for each component + change depending on dark mode or not */
|
|
175
|
+
.fab, #shell-header {
|
|
176
|
+
box-shadow: 3px 3px 3px var(--shadow-color);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
#toast-progress {
|
|
180
|
+
position: relative;
|
|
181
|
+
top: 5px;
|
|
182
|
+
left: 6px;
|
|
183
|
+
width: calc(100% - 12px);
|
|
184
|
+
border-radius: 8px;
|
|
185
|
+
background: transparent;
|
|
186
|
+
height: 10px;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
#toast-progress::-moz-progress-bar {
|
|
190
|
+
/*background-color: red;*/
|
|
191
|
+
background: rgba(var(--color-secondary-500));
|
|
192
|
+
}
|
|
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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"/></svg>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script>import AresHappy from "../assets/characters/ares/ares_happy.webp";
|
|
2
2
|
import { onMount } from "svelte";
|
|
3
3
|
import { dialogManager } from "./dialog_manager/DialogManagerStore";
|
|
4
|
+
import { DialogState } from "../types/pineapple_fiber/DialogState";
|
|
4
5
|
let currentMessage = "";
|
|
5
6
|
dialogManager.currentMessage.subscribe((value) => {
|
|
6
7
|
currentMessage = value;
|
|
@@ -15,15 +16,25 @@ onMount(() => {
|
|
|
15
16
|
dialogManager.update(0);
|
|
16
17
|
});
|
|
17
18
|
let hidePercent = 100;
|
|
19
|
+
let isHidden = true;
|
|
18
20
|
dialogManager.hidePercent.subscribe((value) => {
|
|
19
21
|
hidePercent = value * 0.4;
|
|
22
|
+
isHidden = false;
|
|
23
|
+
});
|
|
24
|
+
dialogManager.currentReadableState.subscribe((value) => {
|
|
25
|
+
isHidden = value === DialogState.Invisible;
|
|
26
|
+
if (value === DialogState.Invisible) {
|
|
27
|
+
}
|
|
20
28
|
});
|
|
21
29
|
const onDialogClick = () => {
|
|
22
30
|
dialogManager.skipAnimation();
|
|
23
31
|
};
|
|
24
32
|
</script>
|
|
25
33
|
|
|
26
|
-
<div class="dialog-elements"
|
|
34
|
+
<div class="dialog-elements"
|
|
35
|
+
hidden={isHidden}
|
|
36
|
+
style="--hidePercentWidth: -{hidePercent}vw;
|
|
37
|
+
--hidePercentHeight: {hidePercent}vh;">
|
|
27
38
|
<img src={currentPortrait} alt="Ares" class="dialog-portrait" />
|
|
28
39
|
<div class="card dialog-box variant-ghost-primary" on:click={onDialogClick}>
|
|
29
40
|
<div class="card dialog-name">
|
|
@@ -37,59 +48,49 @@ const onDialogClick = () => {
|
|
|
37
48
|
</div>
|
|
38
49
|
|
|
39
50
|
<style>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
.dialog-elements > img {
|
|
46
|
-
transform: translateX(var(--hidePercentWidth));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
.dialog-elements > div {
|
|
50
|
-
transform: translateY(var(--hidePercentHeight));
|
|
51
|
-
}
|
|
51
|
+
.dialog-elements {
|
|
52
|
+
position: fixed;
|
|
53
|
+
z-index: 10;
|
|
54
|
+
}
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
bottom: 0;
|
|
57
|
-
left: var(--dialog-left-pad);
|
|
56
|
+
.dialog-elements > img {
|
|
57
|
+
transform: translateX(var(--hidePercentWidth));
|
|
58
|
+
}
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
.dialog-elements > div {
|
|
61
|
+
transform: translateY(var(--hidePercentHeight));
|
|
62
|
+
}
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
.dialog-box *,
|
|
65
|
+
.dialog-name * {
|
|
66
|
+
font-size: clamp(1em, 5vw, 1.3em);
|
|
67
|
+
line-height: 1.5em;
|
|
68
|
+
}
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
.dialog-padding :global(p) {
|
|
71
|
+
font-size: clamp(1em, 5vw, 1.3em) !important;
|
|
72
|
+
line-height: 1.5em !important;
|
|
73
|
+
}
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
.dialog-padding {
|
|
76
|
+
padding: clamp(1.5em, 5vw, 1.75em) clamp(0em, 5vw - 0.5em, 2em) 0;
|
|
77
|
+
}
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
.dialog-name {
|
|
80
|
+
padding-left: 1rem;
|
|
81
|
+
padding-right: 1rem;
|
|
82
|
+
padding-top: 0.5rem;
|
|
83
|
+
position: fixed;
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
/* for centering vertically */
|
|
86
|
+
transform: translateX(clamp(0em, 5vw - 0.5em, 1em)) translateY(-50%);
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
.dialog-portrait {
|
|
90
|
+
position: fixed;
|
|
91
|
+
bottom: 0;
|
|
92
|
+
left: clamp(-4rem, calc(5vw - 5em), 0rem);
|
|
93
|
+
height: clamp(30rem, 75vw, 40rem);
|
|
94
|
+
width: auto;
|
|
95
|
+
}
|
|
95
96
|
</style>
|
|
@@ -8,7 +8,7 @@ import { DialogProcessor } from "./DialogProcessor";
|
|
|
8
8
|
export type OnSetDialogChoiceCallback = (newMessage: DialogDetail) => void;
|
|
9
9
|
export declare class DialogManager {
|
|
10
10
|
dialogMessageMap: Map<string, DialogDetail>;
|
|
11
|
-
|
|
11
|
+
currentDialogTree: DialogDetail[];
|
|
12
12
|
fullCurrentMessage: string;
|
|
13
13
|
currentMessageMeta: DialogDetail;
|
|
14
14
|
currentMessage: import("svelte/store").Writable<string>;
|
|
@@ -18,12 +18,14 @@ export declare class DialogManager {
|
|
|
18
18
|
currentPortrait: import("svelte/store").Writable<unknown>;
|
|
19
19
|
portraitMap: Map<string, any>;
|
|
20
20
|
currentState: DialogState;
|
|
21
|
+
currentReadableState: import("svelte/store").Writable<DialogState>;
|
|
21
22
|
hidePercent: import("svelte/motion").Tweened<number>;
|
|
22
23
|
skipNextActiveTime: number;
|
|
23
24
|
dialogProcessor: DialogProcessor;
|
|
24
25
|
_setDialogChoiceQueue: DialogDetail[];
|
|
25
26
|
_setDialogChoiceMutex: boolean;
|
|
26
27
|
onSetDialogListeners: OnSetDialogChoiceCallback[];
|
|
28
|
+
enableDialogueOverlayCache: boolean;
|
|
27
29
|
constructor();
|
|
28
30
|
/**
|
|
29
31
|
* when users interact with the dialog, they can skip the transition like in a game
|
|
@@ -39,9 +41,9 @@ export declare class DialogManager {
|
|
|
39
41
|
* sets the possible dialog that might appear on the Dialog UI
|
|
40
42
|
* note that it overwrites the previous tree and does not append on it due to the possibility
|
|
41
43
|
* of node name conflicts
|
|
42
|
-
* @param
|
|
44
|
+
* @param newDialogTree
|
|
43
45
|
*/
|
|
44
|
-
setDialogTree: (
|
|
46
|
+
setDialogTree: (newDialogTree: DialogDetail[]) => void;
|
|
45
47
|
/**
|
|
46
48
|
* Remember to call this before SetDialogTree
|
|
47
49
|
* and unsubscribe during onDestroy
|
|
@@ -74,4 +76,7 @@ export declare class DialogManager {
|
|
|
74
76
|
* ISSUE #81 https://github.com/TurnipXenon/pineapple/issues/81
|
|
75
77
|
*/
|
|
76
78
|
update: (timestamp: number) => void;
|
|
79
|
+
enableDialogOverlay(enable: boolean): void;
|
|
80
|
+
toggleDialogOverlay(): void;
|
|
81
|
+
parseAndSetDialogTree(dialogYarn: string): Promise<DialogDetail[]>;
|
|
77
82
|
}
|