@turnipxenon/pineapple 5.2.2 → 5.3.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/assets/icons/cursor-chat.svg +46 -0
  2. package/dist/assets/icons/cursor-open-in-new.svg +8 -0
  3. package/dist/assets/icons/icon-open-in-new.svg +1 -0
  4. package/dist/components/dialog_manager/DialogManager.d.ts +8 -2
  5. package/dist/components/dialog_manager/DialogManager.d.ts.map +1 -1
  6. package/dist/components/dialog_manager/DialogManager.js +63 -11
  7. package/dist/components/dialog_manager/DialogManagerStore.d.ts +0 -3
  8. package/dist/components/dialog_manager/DialogManagerStore.d.ts.map +1 -1
  9. package/dist/components/dialog_manager/DialogManagerStore.js +1 -3
  10. package/dist/components/dialog_manager/DialogProcessor.d.ts.map +1 -1
  11. package/dist/components/dialog_manager/DialogProcessor.js +3 -2
  12. package/dist/components/dialog_manager/DialogUtils.js +2 -2
  13. package/dist/components/dialog_manager/IDialogManager.d.ts +4 -2
  14. package/dist/components/dialog_manager/IDialogManager.d.ts.map +1 -1
  15. package/dist/components/dialog_manager/behavior_tree/core/BTreeUtils.d.ts +2 -1
  16. package/dist/components/dialog_manager/behavior_tree/core/BTreeUtils.d.ts.map +1 -1
  17. package/dist/components/dialog_manager/behavior_tree/core/BTreeUtils.js +4 -3
  18. package/dist/components/dialog_manager/behavior_tree/expression/ExpressionArguments.d.ts +2 -0
  19. package/dist/components/dialog_manager/behavior_tree/expression/ExpressionArguments.d.ts.map +1 -1
  20. package/dist/components/dialog_manager/behavior_tree/expression/ExpressionEvaluator.d.ts +4 -2
  21. package/dist/components/dialog_manager/behavior_tree/expression/ExpressionEvaluator.d.ts.map +1 -1
  22. package/dist/components/dialog_manager/behavior_tree/expression/ExpressionEvaluator.js +8 -6
  23. package/dist/components/dialog_manager/behavior_tree/expression/OperandNode.d.ts.map +1 -1
  24. package/dist/components/dialog_manager/behavior_tree/expression/OperandNode.js +1 -1
  25. package/dist/components/dialog_manager/behavior_tree/expression/commands/VisitedCountCommand.d.ts.map +1 -1
  26. package/dist/components/dialog_manager/behavior_tree/expression/commands/VisitedCountCommand.js +1 -2
  27. package/dist/components/dialog_manager/behavior_tree/line_core/LineNodeArguments.d.ts +2 -0
  28. package/dist/components/dialog_manager/behavior_tree/line_core/LineNodeArguments.d.ts.map +1 -1
  29. package/dist/components/dialog_manager/behavior_tree/line_processors/ElseIfNode.js +1 -1
  30. package/dist/components/dialog_manager/behavior_tree/line_processors/IfNode.d.ts.map +1 -1
  31. package/dist/components/dialog_manager/behavior_tree/line_processors/IfNode.js +1 -2
  32. package/dist/components/dialog_manager/behavior_tree/line_processors/NormalLineProcessorNode.d.ts.map +1 -1
  33. package/dist/components/dialog_manager/behavior_tree/line_processors/NormalLineProcessorNode.js +2 -3
  34. package/dist/components/dialog_manager/behavior_tree/line_processors/SetVariableNode.d.ts.map +1 -1
  35. package/dist/components/dialog_manager/behavior_tree/line_processors/SetVariableNode.js +2 -3
  36. package/dist/components/dialog_manager/behavior_tree/line_processors/commands/DeclareCommand.d.ts.map +1 -1
  37. package/dist/components/dialog_manager/behavior_tree/line_processors/commands/DeclareCommand.js +3 -2
  38. package/dist/components/dialog_manager/behavior_tree/line_processors/commands/JumpCommand.d.ts.map +1 -1
  39. package/dist/components/dialog_manager/behavior_tree/line_processors/commands/JumpCommand.js +3 -2
  40. package/dist/components/dialog_manager/behavior_tree/line_processors/commands/UnvisitCommand.d.ts.map +1 -1
  41. package/dist/components/dialog_manager/behavior_tree/line_processors/commands/UnvisitCommand.js +2 -3
  42. package/dist/modules/parsnip/ParsnipBlockChildren.svelte +3 -0
  43. package/dist/modules/parsnip/ParsnipBlockChildren.svelte.d.ts.map +1 -1
  44. package/dist/modules/parsnip/ParsnipPhrasingChildren.svelte +15 -3
  45. package/dist/modules/parsnip/ParsnipPhrasingChildren.svelte.d.ts.map +1 -1
  46. package/dist/modules/parsnip/external-images/ParsnipImage.svelte +111 -0
  47. package/dist/modules/parsnip/external-images/ParsnipImage.svelte.d.ts +9 -0
  48. package/dist/modules/parsnip/external-images/ParsnipImage.svelte.d.ts.map +1 -0
  49. package/dist/modules/parsnip/external-images/ParsnipImageCollection.svelte +62 -0
  50. package/dist/modules/parsnip/external-images/ParsnipImageCollection.svelte.d.ts +9 -0
  51. package/dist/modules/parsnip/external-images/ParsnipImageCollection.svelte.d.ts.map +1 -0
  52. package/dist/modules/parsnip/external-images/externalImages.remote.d.ts +8 -0
  53. package/dist/modules/parsnip/external-images/externalImages.remote.d.ts.map +1 -0
  54. package/dist/modules/parsnip/external-images/externalImages.remote.js +50 -0
  55. package/dist/modules/parsnip/route-util/ParsnipBlog.svelte +2 -1
  56. package/dist/modules/parsnip/route-util/ParsnipBlog.svelte.d.ts.map +1 -1
  57. package/dist/modules/parsnip/route-util/slugPageServerLoad.d.ts.map +1 -1
  58. package/dist/modules/parsnip/route-util/slugPageServerLoad.js +21 -0
  59. package/dist/scripts/pineapple_fiber/PineappleFiberParser.d.ts.map +1 -1
  60. package/dist/scripts/pineapple_fiber/PineappleFiberParser.js +19 -0
  61. package/dist/scripts/pineapple_fiber/TutorialBroken.yarn +143 -0
  62. package/dist/styles/app.css +30 -2
  63. package/dist/test/DialogTestUtility.d.ts +8 -0
  64. package/dist/test/DialogTestUtility.d.ts.map +1 -0
  65. package/dist/test/DialogTestUtility.js +62 -0
  66. package/dist/test/index.d.ts +3 -0
  67. package/dist/test/index.d.ts.map +1 -0
  68. package/dist/test/index.js +2 -0
  69. package/dist/types/pineapple_fiber/DialogDetail.d.ts +1 -0
  70. package/dist/types/pineapple_fiber/DialogDetail.d.ts.map +1 -1
  71. package/dist/types/pineapple_fiber/DialogVariableStore.d.ts.map +1 -1
  72. package/dist/types/pineapple_fiber/DialogVariableStore.js +41 -13
  73. package/dist/ui/elements/TextLink.svelte +1 -1
  74. package/dist/ui/elements/index.d.ts +1 -0
  75. package/dist/ui/elements/index.d.ts.map +1 -1
  76. package/dist/ui/elements/index.js +1 -0
  77. package/dist/ui/modules/NavigationMenu/NavigationControl.svelte +41 -10
  78. package/dist/ui/modules/NavigationMenu/NavigationControl.svelte.d.ts +3 -1
  79. package/dist/ui/modules/NavigationMenu/NavigationControl.svelte.d.ts.map +1 -1
  80. package/dist/ui/modules/NavigationMenu/NavigationMenu.svelte +131 -39
  81. package/dist/ui/modules/NavigationMenu/NavigationMenu.svelte.d.ts +3 -1
  82. package/dist/ui/modules/NavigationMenu/NavigationMenu.svelte.d.ts.map +1 -1
  83. package/dist/ui/modules/modals/general-settings/GeneralSettingsModal.svelte +21 -21
  84. package/dist/ui/modules/modals/general-settings/GeneralSettingsModal.svelte.d.ts +1 -1
  85. package/dist/ui/modules/modals/general-settings/GeneralSettingsModal.svelte.d.ts.map +1 -1
  86. package/dist/ui/modules/universal-overlay/DialogPanel.svelte +80 -6
  87. package/dist/ui/modules/universal-overlay/DialogPanel.svelte.d.ts.map +1 -1
  88. package/dist/ui/modules/universal-overlay/SettingsPanel.svelte +132 -75
  89. package/dist/ui/modules/universal-overlay/SettingsPanel.svelte.d.ts +4 -1
  90. package/dist/ui/modules/universal-overlay/SettingsPanel.svelte.d.ts.map +1 -1
  91. package/dist/ui/templates/SeaweedLayout/SeaweedLayout.svelte +0 -3
  92. package/dist/ui/templates/SeaweedLayout/SeaweedLayout.svelte.d.ts.map +1 -1
  93. package/dist/ui/templates/blog_template/BlogTemplate.svelte +7 -1
  94. package/dist/ui/templates/blog_template/BlogTemplateInner.svelte +33 -1
  95. package/dist/ui/templates/blog_template/BlogTemplateInner.svelte.d.ts.map +1 -1
  96. package/dist/ui/templates/index.d.ts +1 -0
  97. package/dist/ui/templates/index.d.ts.map +1 -1
  98. package/dist/ui/templates/index.js +2 -0
  99. package/dist/util/context/PineappleBaseContext.svelte +6 -2
  100. package/dist/util/context/PineappleBaseContext.svelte.d.ts.map +1 -1
  101. package/dist/util/context/pineappleBaseContextDefinitions.svelte.d.ts +2 -0
  102. package/dist/util/context/pineappleBaseContextDefinitions.svelte.d.ts.map +1 -1
  103. package/dist/util/context/pineappleBaseContextDefinitions.svelte.js +2 -0
  104. package/dist/util/localStore.svelte.d.ts +2 -0
  105. package/dist/util/localStore.svelte.d.ts.map +1 -1
  106. package/dist/util/localStore.svelte.js +2 -0
  107. package/dist/yarn/Tutorial.yarn +141 -0
  108. package/package.json +12 -7
  109. package/src/lib/styles/app.css +30 -2
  110. package/dist/assets/icons/chat-cursor.svg +0 -47
@@ -1,6 +1,7 @@
1
1
  <!-- TODO: Documentation: consider documentation showcase -->
2
2
 
3
3
  <script lang="ts">
4
+ import { page } from "$app/state";
4
5
  import type { ParsnipOverall } from "../../../modules/parsnip/ParsnipOverall";
5
6
  import NavigationControl from "./NavigationControl.svelte";
6
7
  import {
@@ -10,6 +11,7 @@
10
11
  type ParsePageMetaCompareFn
11
12
  } from "./PageMeta";
12
13
  import { PinyaCard } from "../../elements/index";
14
+ import Placeholder from "../../elements/Placeholder.svelte";
13
15
  import { localizeHref } from "../../../external/paraglide/runtime.js";
14
16
 
15
17
  interface Props {
@@ -26,6 +28,8 @@
26
28
  compareFn?: undefined | ParsePageMetaCompareFn;
27
29
  pageSize?: number;
28
30
  currentIndex?: number;
31
+ selectedTags?: string[];
32
+ queryReady?: boolean;
29
33
  parsnipOverall?: ParsnipOverall;
30
34
  parsnipBasePath?: string;
31
35
  }
@@ -41,22 +45,43 @@
41
45
  compareFn = undefined,
42
46
  pageSize = $bindable(5),
43
47
  currentIndex = $bindable(0),
48
+ selectedTags = $bindable([]),
49
+ queryReady = $bindable(false),
44
50
  parsnipOverall = undefined,
45
51
  parsnipBasePath = ""
46
52
  }: Props = $props();
47
53
 
54
+ $effect(() => {
55
+ if (!shouldAllowControl) {
56
+ queryReady = true;
57
+ }
58
+ });
59
+ const hasTagQuery = $derived((() => {
60
+ const repeatedTags = page.url.searchParams.getAll("tags");
61
+ if (repeatedTags.length > 0) {
62
+ return true;
63
+ }
64
+ const inlineTags = page.url.searchParams.get("tags") ?? "";
65
+ return inlineTags.trim().length > 0;
66
+ })());
67
+
48
68
  const fileBasedList = parsePageMeta(fileList, jsonList, imageMap, compareFn);
49
69
  const parsnipBasedList = parsnipOverall?.files.map(pf => {
70
+ let imageUrl = pf.preview;
71
+ if (imageUrl && !imageUrl.includes('https://')) {
72
+ imageUrl = `${parsnipOverall.baseUrl}/${pf.preview}`;
73
+ }
50
74
  const meta: PageMeta = {
51
75
  title: pf.basename,
52
76
  nestedPages: [],
53
77
  relativeLink: `${parsnipBasePath}${pf.slug}`,
54
78
  tags: pf.tags,
55
- imageUrl: pf.preview ? `${parsnipOverall.baseUrl}/${pf.preview}` : undefined,
79
+ imageUrl,
56
80
  imageAlt: pf.previewAlt,
57
81
  datePublished: pf.stat.ctime ? new Date(pf.stat.ctime).toISOString().split("T")[0] : undefined,
58
82
  lastUpdated: pf.stat.mtime ? new Date(pf.stat.mtime).toISOString().split("T")[0] : undefined,
59
- description: pf.tagline
83
+ description: pf.tagline,
84
+ priority: 0
60
85
  };
61
86
  return meta;
62
87
  }) ?? [];
@@ -68,7 +93,33 @@
68
93
  pageFlatList.sort(DefaultPageMetaSorter);
69
94
  }
70
95
 
71
- let visiblePages = $derived(pageFlatList.slice(currentIndex * pageSize, (currentIndex * pageSize) + pageSize));
96
+ const selectedTagsSet = $derived(new Set(selectedTags.map(tag => tag.toLocaleLowerCase())));
97
+ const filteredPageFlatList = $derived(
98
+ selectedTagsSet.size === 0
99
+ ? pageFlatList
100
+ : pageFlatList.filter(pageMeta => {
101
+ if (!pageMeta.tags || pageMeta.tags.length === 0) {
102
+ return false;
103
+ }
104
+ const pageTags = new Set(pageMeta.tags.map(tag => tag.toLocaleLowerCase()));
105
+ for (const selectedTag of selectedTagsSet) {
106
+ if (!pageTags.has(selectedTag)) {
107
+ return false;
108
+ }
109
+ }
110
+ return true;
111
+ })
112
+ );
113
+ const maxIndex = $derived(Math.max(Math.ceil(filteredPageFlatList.length / pageSize) - 1, 0));
114
+ $effect(() => {
115
+ if (currentIndex > maxIndex) {
116
+ currentIndex = maxIndex;
117
+ }
118
+ if (currentIndex < 0) {
119
+ currentIndex = 0;
120
+ }
121
+ });
122
+ let visiblePages = $derived(filteredPageFlatList.slice(currentIndex * pageSize, (currentIndex * pageSize) + pageSize));
72
123
  </script>
73
124
 
74
125
  <div class="navigation-wrapper">
@@ -85,53 +136,78 @@
85
136
  {#if allowUpperControl && shouldAllowControl}
86
137
  <NavigationControl
87
138
  bind:currentIndex={currentIndex}
88
- contentLength={pageFlatList.length}
89
- bind:pageSize={pageSize}></NavigationControl
139
+ contentLength={filteredPageFlatList.length}
140
+ bind:pageSize={pageSize}
141
+ bind:selectedTags={selectedTags}
142
+ bind:queryReady={queryReady}></NavigationControl
90
143
  >
91
144
  {/if}
92
145
 
93
146
  <div class="navigation-component">
94
- <!-- all the misc routes-->
95
- {#each visiblePages as pageMeta (pageMeta.title)}
96
- {@const fullPath = `${parentSubpath}${pageMeta.relativeLink}`}
97
- <!-- thank you so much to https://www.reddit.com/r/sveltejs/comments/yoe6in/comment/jvaj1ez -->
98
- <a href={localizeHref(fullPath)} class="card-anchor a-as-btn" data-sveltekit-reload>
99
- <PinyaCard
100
- widthClass="w-full"
101
- className="navigation-element"
102
- >
103
- {#if pageMeta.imageUrl}
104
- <img src={pageMeta.imageUrl}
105
- alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
106
- {/if}
107
- <section class="blurb-text">
108
- <h2>{pageMeta.title}</h2>
109
- <p>Published: {pageMeta.datePublished ?? "N/A"} | Last updated: {pageMeta.lastUpdated ?? "N/A"}</p>
110
- <p>{pageMeta.description ?? ""}</p>
111
- Tags:
112
- {#if (pageMeta.tags && pageMeta.tags.length !== 0)}
113
- {#each pageMeta.tags as tagValue, idx (idx)}
114
- &nbsp;<span class="badge variant-filled tag-container">{tagValue}</span>
115
- {/each}
116
- {:else}
117
- None
147
+ {#if hasTagQuery && !queryReady}
148
+ <PinyaCard widthClass="w-full" paddingClass="" className="navigation-element">
149
+ <div class="blurb-text">
150
+ <Placeholder classes="h-8 w-2/3 mb-4" />
151
+ <Placeholder classes="h-4 w-1/2 mb-2" />
152
+ <Placeholder classes="h-4 w-full mb-2" />
153
+ <Placeholder classes="h-4 w-5/6 mb-2" />
154
+ </div>
155
+ </PinyaCard>
156
+ <PinyaCard widthClass="w-full" className="navigation-element" paddingClass="">
157
+ <div class="blurb-text">
158
+ <Placeholder classes="h-8 w-2/3 mb-4" />
159
+ <Placeholder classes="h-4 w-1/2 mb-2" />
160
+ <Placeholder classes="h-4 w-full mb-2" />
161
+ <Placeholder classes="h-4 w-5/6 mb-2" />
162
+ </div>
163
+ </PinyaCard>
164
+ {:else}
165
+ <!-- all the misc routes-->
166
+ {#each visiblePages as pageMeta (pageMeta.title)}
167
+ {@const fullPath = `${parentSubpath}${pageMeta.relativeLink}`}
168
+ <!-- thank you so much to https://www.reddit.com/r/sveltejs/comments/yoe6in/comment/jvaj1ez -->
169
+ <a href={localizeHref(fullPath)} class="card-anchor a-as-btn" data-sveltekit-reload>
170
+ <PinyaCard
171
+ widthClass="w-full"
172
+ className="navigation-element"
173
+ paddingClass=""
174
+ >
175
+ {#if pageMeta.imageUrl}
176
+ <img src={pageMeta.imageUrl}
177
+ class="pinya-card-image"
178
+ alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
118
179
  {/if}
119
- </section>
120
- </PinyaCard>
121
- </a>
122
- {/each}
180
+ <section class="blurb-text">
181
+ <h2>{pageMeta.title}</h2>
182
+ <p>Published: {pageMeta.datePublished ?? "N/A"} | Last updated: {pageMeta.lastUpdated ?? "N/A"}</p>
183
+ <p>{pageMeta.description ?? ""}</p>
184
+ Tags:
185
+ {#if (pageMeta.tags && pageMeta.tags.length !== 0)}
186
+ {#each pageMeta.tags as tagValue, idx (idx)}
187
+ &nbsp;<span class="badge tag-container">{tagValue}</span>
188
+ {/each}
189
+ {:else}
190
+ None
191
+ {/if}
192
+ </section>
193
+ </PinyaCard>
194
+ </a>
195
+ {/each}
123
196
 
124
- {#if visiblePages.length === 0}
125
- <PinyaCard>
126
- <p class="default-card">Sorry, no content was found</p>
127
- </PinyaCard>
197
+ {#if visiblePages.length === 0}
198
+ <PinyaCard>
199
+ <p class="default-card">Sorry, no content was found</p>
200
+ </PinyaCard>
201
+ {/if}
128
202
  {/if}
129
203
  </div>
130
204
 
131
205
  {#if shouldAllowControl}
132
206
  <NavigationControl bind:currentIndex={currentIndex}
133
- contentLength={pageFlatList.length}
134
- bind:pageSize={pageSize}></NavigationControl>
207
+ contentLength={filteredPageFlatList.length}
208
+ bind:pageSize={pageSize}
209
+ bind:selectedTags={selectedTags}
210
+ bind:queryReady={queryReady}></NavigationControl>
135
211
  {/if}
136
212
 
137
213
  </div>
@@ -206,6 +282,18 @@
206
282
 
207
283
  .tag-container {
208
284
  margin: 0.25lh 0;
285
+ display: inline-flex;
286
+ align-items: center;
287
+ border-radius: 0.5rem;
288
+ padding: 0.2rem 0.55rem;
289
+ border: 1px solid var(--color-surface-700-600);
290
+ background-color: transparent;
291
+ color: var(--color-surface-900-100);
292
+ transition: border-color 0.15s ease;
293
+ }
294
+
295
+ :global(.navigation-element:hover) .tag-container {
296
+ border-color: var(--color-primary-400-600);
209
297
  }
210
298
 
211
299
  a.card-anchor {
@@ -228,4 +316,8 @@
228
316
  h2 {
229
317
  text-align: start;
230
318
  }
319
+
320
+ .navigation-wrapper .pinya-card-image {
321
+ border-radius: var(--radius-xl);
322
+ }
231
323
  </style>
@@ -14,10 +14,12 @@ interface Props {
14
14
  compareFn?: undefined | ParsePageMetaCompareFn;
15
15
  pageSize?: number;
16
16
  currentIndex?: number;
17
+ selectedTags?: string[];
18
+ queryReady?: boolean;
17
19
  parsnipOverall?: ParsnipOverall;
18
20
  parsnipBasePath?: string;
19
21
  }
20
- declare const NavigationMenu: import("svelte").Component<Props, {}, "currentIndex" | "pageSize">;
22
+ declare const NavigationMenu: import("svelte").Component<Props, {}, "currentIndex" | "pageSize" | "selectedTags" | "queryReady">;
21
23
  type NavigationMenu = ReturnType<typeof NavigationMenu>;
22
24
  export default NavigationMenu;
23
25
  //# sourceMappingURL=NavigationMenu.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationMenu.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/NavigationMenu/NavigationMenu.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAE1E,OAAO,EAIL,KAAK,sBAAsB,EAC3B,MAAM,yCAAyC,CAAC;AAKjD,UAAU,KAAK;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,SAAS,GAAG,sBAAsB,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AA4GF,QAAA,MAAM,cAAc,oEAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"NavigationMenu.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/NavigationMenu/NavigationMenu.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAE1E,OAAO,EAIL,KAAK,sBAAsB,EAC3B,MAAM,yCAAyC,CAAC;AAMjD,UAAU,KAAK;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,SAAS,GAAG,sBAAsB,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAgLF,QAAA,MAAM,cAAc,oGAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -1,29 +1,29 @@
1
1
  <!-- TODO: Documentation: consider documentation showcase -->
2
2
 
3
3
  <script lang="ts">
4
- import type { ModalProps } from 'svelte-modals';
5
- import { setMode, userPrefersMode } from 'mode-watcher';
4
+ import ConstrastIcon from "../../../../assets/icons/icon-contrast.svg";
5
+ import DarkIcon from "../../../../assets/icons/icon-dark-mode.svg";
6
+ import LightIcon from "../../../../assets/icons/icon-light-mode.svg";
6
7
 
7
- import { m } from '../../../../external/paraglide/messages';
8
+ import { m } from "../../../../external/paraglide/messages";
9
+ import ModalBase from "../../../components/ModalBase.svelte";
8
10
  import SettingsPanel from "../../universal-overlay/SettingsPanel.svelte";
9
- import ModalBase from '../../../components/ModalBase.svelte';
10
- import DarkIcon from '../../../../assets/icons/icon-dark-mode.svg';
11
- import LightIcon from '../../../../assets/icons/icon-light-mode.svg';
12
- import ConstrastIcon from '../../../../assets/icons/icon-contrast.svg';
11
+ import { setMode, userPrefersMode } from "mode-watcher";
12
+ import type { ModalProps } from "svelte-modals";
13
13
 
14
14
  let props: ModalProps = $props();
15
15
 
16
16
 
17
17
  interface ToggleItem {
18
- key: 'light' | 'dark' | 'system'
18
+ key: "light" | "dark" | "system"
19
19
  imageSrc: string,
20
20
  label: string,
21
21
  }
22
22
 
23
23
  const modes: ToggleItem[] = [
24
- { key: 'light', imageSrc: LightIcon, label: 'Light' },
25
- { key: 'dark', imageSrc: DarkIcon, label: 'Dark' },
26
- { key: 'system', imageSrc: ConstrastIcon, label: 'System' }
24
+ { key: "light", imageSrc: LightIcon, label: "Light" },
25
+ { key: "dark", imageSrc: DarkIcon, label: "Dark" },
26
+ { key: "system", imageSrc: ConstrastIcon, label: "System" }
27
27
  ];
28
28
 
29
29
  let selectedItem: ToggleItem = $state(modes[0]);
@@ -41,14 +41,14 @@
41
41
  // when mode is changed inside the button, adjust the mode
42
42
  $effect(() => {
43
43
  switch (selectedItem?.key) {
44
- case 'dark':
45
- setMode('dark');
44
+ case "dark":
45
+ setMode("dark");
46
46
  break;
47
- case 'light':
48
- setMode('light');
47
+ case "light":
48
+ setMode("light");
49
49
  break;
50
- case 'system':
51
- setMode('system');
50
+ case "system":
51
+ setMode("system");
52
52
  break;
53
53
  default:
54
54
  break;
@@ -60,11 +60,11 @@
60
60
  <div class="wrapper">
61
61
  <h2>{m.settings()}</h2>
62
62
 
63
- <SettingsPanel />
63
+ <SettingsPanel close={props.close} />
64
64
 
65
65
  <div class="actions">
66
66
  <button class="btn preset-filled-primary-400-600 text-surface-100" onclick={() => props.close()}
67
- title="Close modal">
67
+ title="Close modal">
68
68
  Close
69
69
  </button>
70
70
  </div>
@@ -78,7 +78,6 @@
78
78
  .actions {
79
79
  display: flex;
80
80
  flex-direction: row-reverse;
81
- margin-top: 1.4lh;
82
81
  }
83
82
 
84
83
  .wrapper {
@@ -86,5 +85,6 @@
86
85
  flex-direction: column;
87
86
  justify-content: start;
88
87
  text-align: start;
89
- gap: 1lh;
88
+ overflow: auto;
89
+ max-height: calc(100vh - 3lh);
90
90
  }</style>
@@ -1,4 +1,4 @@
1
- import type { ModalProps } from 'svelte-modals';
1
+ import type { ModalProps } from "svelte-modals";
2
2
  declare const GeneralSettingsModal: import("svelte").Component<ModalProps<any>, {}, "">;
3
3
  type GeneralSettingsModal = ReturnType<typeof GeneralSettingsModal>;
4
4
  export default GeneralSettingsModal;
@@ -1 +1 @@
1
- {"version":3,"file":"GeneralSettingsModal.svelte.d.ts","sourceRoot":"","sources":["../../../../../src/lib/ui/modules/modals/general-settings/GeneralSettingsModal.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAsFhD,QAAA,MAAM,oBAAoB,qDAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"GeneralSettingsModal.svelte.d.ts","sourceRoot":"","sources":["../../../../../src/lib/ui/modules/modals/general-settings/GeneralSettingsModal.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AA8EhD,QAAA,MAAM,oBAAoB,qDAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
@@ -6,14 +6,29 @@ Layout and logic for DialogPanel. Some of the logics for the portraits are in Un
6
6
 
7
7
  <script lang="ts">
8
8
  import { dialogManager } from "../../../components/dialog_manager/DialogManager";
9
- import { onMount } from "svelte";
9
+ import { getAutoScrollPrefContext, getTextSpeedContext } from "../../../util/context/pineappleBaseContextDefinitions.svelte";
10
+ import { onMount, tick } from "svelte";
10
11
 
11
12
  let currentMessage = $state("");
13
+ let textSpeedContext = getTextSpeedContext();
14
+ let autoScrollPrefContext = getAutoScrollPrefContext();
15
+ let dialogPanelElement: HTMLDivElement | null = null;
16
+ let shouldStickToBottom = true;
12
17
 
13
18
  const onDialogClick = () => {
14
19
  dialogManager?.skipAnimation();
15
20
  };
16
21
 
22
+ const onDialogScroll = () => {
23
+ if (!dialogPanelElement) {
24
+ return;
25
+ }
26
+
27
+ const distanceToBottom =
28
+ dialogPanelElement.scrollHeight - dialogPanelElement.scrollTop - dialogPanelElement.clientHeight;
29
+ shouldStickToBottom = distanceToBottom <= 24;
30
+ };
31
+
17
32
  onMount(() => {
18
33
  dialogManager.currentMessage.subscribe((value) => {
19
34
  currentMessage = value;
@@ -21,19 +36,78 @@ Layout and logic for DialogPanel. Some of the logics for the portraits are in Un
21
36
 
22
37
  dialogManager.update(0);
23
38
  });
39
+
40
+ $effect(() => {
41
+ dialogManager.setUpdateRate((16*10) - (textSpeedContext.value*16));
42
+ });
43
+
44
+ $effect(() => {
45
+ currentMessage;
46
+
47
+ tick().then(() => {
48
+ if (!dialogPanelElement || !shouldStickToBottom || !autoScrollPrefContext.value) {
49
+ return;
50
+ }
51
+
52
+ dialogPanelElement.scrollTop = dialogPanelElement.scrollHeight;
53
+ });
54
+ });
24
55
  </script>
25
56
 
26
57
  <div
27
58
  tabindex="0"
28
59
  role="button"
60
+ id="dialog-panel"
61
+ bind:this={dialogPanelElement}
29
62
  onclick={onDialogClick}
63
+ onscroll={onDialogScroll}
30
64
  onkeyup={(e) => {
31
- if (e.key === 'j') {
32
- onDialogClick();
33
- }
34
- }}
65
+ if (e.key === "j") {
66
+ onDialogClick();
67
+ }
68
+ }}
35
69
  >
36
70
  <!-- Made for 140 characters, like the original tweets -->
37
71
  <!-- eslint-disable-next-line svelte/no-at-html-tags -->
38
- {@html currentMessage}
72
+ <div id="reverse-dialog-wrapper">
73
+ {@html currentMessage}
74
+ </div>
39
75
  </div>
76
+
77
+ <style>
78
+ :global {
79
+ :root {
80
+ --color-dialog-bold: #6b8499;
81
+ --color-dialog-italic: #a55332;
82
+ }
83
+
84
+ html.dark {
85
+ --color-dialog-bold: #85a1b6;
86
+ --color-dialog-italic: #f7b67c;
87
+ }
88
+
89
+ #reverse-dialog-wrapper {
90
+ width: 100%;
91
+ }
92
+
93
+ #dialog-panel {
94
+ overflow: auto;
95
+ display: block;
96
+
97
+ img,
98
+ video {
99
+ max-height: 3lh;
100
+ display: inline;
101
+ }
102
+
103
+ b {
104
+ font-weight: bolder;
105
+ color: var(--color-dialog-bold);
106
+ }
107
+
108
+ i {
109
+ color: var(--color-dialog-italic);
110
+ }
111
+ }
112
+ }
113
+ </style>
@@ -1 +1 @@
1
- {"version":3,"file":"DialogPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/universal-overlay/DialogPanel.svelte.ts"],"names":[],"mappings":"AAyCA,4GAA4G;AAC5G,QAAA,MAAM,WAAW,2DAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"DialogPanel.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/ui/modules/universal-overlay/DialogPanel.svelte.ts"],"names":[],"mappings":"AA6EA,4GAA4G;AAC5G,QAAA,MAAM,WAAW,2DAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}