@turnipxenon/pineapple 5.2.2 → 5.3.0-alpha.1

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 +130 -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,77 @@
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" 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">
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
+ >
174
+ {#if pageMeta.imageUrl}
175
+ <img src={pageMeta.imageUrl}
176
+ class="pinya-card-image"
177
+ alt={pageMeta.imageAlt ?? "placeholder alt text please replace me or report me!"} />
118
178
  {/if}
119
- </section>
120
- </PinyaCard>
121
- </a>
122
- {/each}
179
+ <section class="blurb-text">
180
+ <h2>{pageMeta.title}</h2>
181
+ <p>Published: {pageMeta.datePublished ?? "N/A"} | Last updated: {pageMeta.lastUpdated ?? "N/A"}</p>
182
+ <p>{pageMeta.description ?? ""}</p>
183
+ Tags:
184
+ {#if (pageMeta.tags && pageMeta.tags.length !== 0)}
185
+ {#each pageMeta.tags as tagValue, idx (idx)}
186
+ &nbsp;<span class="badge tag-container">{tagValue}</span>
187
+ {/each}
188
+ {:else}
189
+ None
190
+ {/if}
191
+ </section>
192
+ </PinyaCard>
193
+ </a>
194
+ {/each}
123
195
 
124
- {#if visiblePages.length === 0}
125
- <PinyaCard>
126
- <p class="default-card">Sorry, no content was found</p>
127
- </PinyaCard>
196
+ {#if visiblePages.length === 0}
197
+ <PinyaCard>
198
+ <p class="default-card">Sorry, no content was found</p>
199
+ </PinyaCard>
200
+ {/if}
128
201
  {/if}
129
202
  </div>
130
203
 
131
204
  {#if shouldAllowControl}
132
205
  <NavigationControl bind:currentIndex={currentIndex}
133
- contentLength={pageFlatList.length}
134
- bind:pageSize={pageSize}></NavigationControl>
206
+ contentLength={filteredPageFlatList.length}
207
+ bind:pageSize={pageSize}
208
+ bind:selectedTags={selectedTags}
209
+ bind:queryReady={queryReady}></NavigationControl>
135
210
  {/if}
136
211
 
137
212
  </div>
@@ -206,6 +281,18 @@
206
281
 
207
282
  .tag-container {
208
283
  margin: 0.25lh 0;
284
+ display: inline-flex;
285
+ align-items: center;
286
+ border-radius: 0.5rem;
287
+ padding: 0.2rem 0.55rem;
288
+ border: 1px solid var(--color-surface-700-600);
289
+ background-color: transparent;
290
+ color: var(--color-surface-900-100);
291
+ transition: border-color 0.15s ease;
292
+ }
293
+
294
+ :global(.navigation-element:hover) .tag-container {
295
+ border-color: var(--color-primary-400-600);
209
296
  }
210
297
 
211
298
  a.card-anchor {
@@ -228,4 +315,8 @@
228
315
  h2 {
229
316
  text-align: start;
230
317
  }
318
+
319
+ .navigation-wrapper .pinya-card-image {
320
+ border-radius: var(--radius-xl);
321
+ }
231
322
  </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"}