|
148 | 148 |
|
149 | 149 | async function copyModList() { |
150 | 150 | // Generate mod entries |
151 | | - const modList = await Promise.all(Object.keys($manifestMods).map(async (modReference) => { |
| 151 | + const modList = (await Promise.all(Object.keys($manifestMods).map(async (modReference) => { |
152 | 152 | let modName = modReference; |
153 | 153 | if($offline) { |
154 | 154 | modName = (await OfflineGetMod(modReference)).name; |
|
159 | 159 | } |
160 | 160 | } |
161 | 161 |
|
162 | | - // Only return valid info if the mod is enabled |
163 | | - if(!$lockfileMods[modReference]) { |
164 | | - //How to enforce error handling? |
165 | | - $error = `Tried to copy a disabled mod`; |
166 | | - return { |
167 | | - friendlyName: '', |
168 | | - modReference: '', |
169 | | - version: '', |
170 | | - }; |
171 | | - } else { |
| 162 | + // Only return info if the mod is enabled |
| 163 | + if($lockfileMods[modReference]) { |
172 | 164 | return { |
173 | 165 | friendlyName: modName, |
174 | 166 | modReference, |
175 | 167 | version: $lockfileMods[modReference].version, |
176 | 168 | }; |
| 169 | + } else { |
| 170 | + return undefined; |
177 | 171 | } |
178 | | - })); |
| 172 | + }))).filter((mod) => mod !== undefined); |
179 | 173 | // Sort by Friendly Name |
180 | 174 | modList.sort((a, b) => { |
181 | 175 | const x = a.friendlyName.toLowerCase(); |
|
192 | 186 | mod.modReference = mod.modReference.padEnd(maxModReferenceLen, ' '); |
193 | 187 | modListString += `${mod.friendlyName} ${mod.modReference} ${mod.version}\n`; |
194 | 188 | }); |
195 | | - navigator.clipboard.writeText(modListString.trim()); |
| 189 | + const markdownCodeblockFence = '```'; |
| 190 | + navigator.clipboard.writeText(`${markdownCodeblockFence}\n${modListString.trim()}\n${markdownCodeblockFence}`); |
196 | 191 | } |
197 | 192 |
|
198 | 193 | function localeName(locale: string) { |
199 | 194 | if (!locale) return 'N/A'; |
200 | 195 | return new Intl.DisplayNames([locale], { type: 'language' }).of(locale); |
201 | 196 | } |
202 | 197 |
|
| 198 | + // appease svelte "stores must be declared at the top of the file" |
| 199 | + function displayError(err: unknown) { |
| 200 | + $error = err; |
| 201 | + } |
| 202 | +
|
203 | 203 | $: if ($queueAutoStart && $queuedMods.length === 0 && $hasPendingProfileChange) { |
204 | 204 | $hasPendingProfileChange = false; |
205 | 205 | addQueuedModAction('__apply__', 'apply', Apply).catch((e) => error.set(e)); |
|
348 | 348 | </li> |
349 | 349 | <hr class="divider" /> |
350 | 350 | <li> |
351 | | - <button on:click={() => copyModList()}> |
| 351 | + <button |
| 352 | + on:click={() => { |
| 353 | + copyModList().catch((error) => { |
| 354 | + displayError(`failed to copy mod list: ${error}`); |
| 355 | + }); |
| 356 | + }}> |
352 | 357 | <span class="h-5 w-5"/> |
353 | 358 | <span class="flex-auto"> |
354 | 359 | <T defaultValue="Copy mod list" keyName="settings.copy-mod-list"/> |
|
0 commit comments