download piclets
Browse files
src/lib/components/Pages/Pictuary.svelte
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
import { onMount } from 'svelte';
|
3 |
import { getCaughtPiclets, getRosterPiclets, moveToRoster, swapRosterPositions, moveToStorage, getUncaughtPiclets } from '$lib/db/piclets';
|
4 |
import type { PicletInstance } from '$lib/db/schema';
|
|
|
5 |
import PicletCard from '../Piclets/PicletCard.svelte';
|
6 |
import EmptySlotCard from '../Piclets/EmptySlotCard.svelte';
|
7 |
import DraggablePicletCard from '../Piclets/DraggablePicletCard.svelte';
|
@@ -91,6 +92,96 @@
|
|
91 |
}
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
onMount(() => {
|
95 |
loadPiclets();
|
96 |
});
|
@@ -226,7 +317,21 @@
|
|
226 |
<!-- Discovered Section -->
|
227 |
{#if discoveredPiclets.length > 0}
|
228 |
<section class="discovered-section">
|
229 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
<div class="discovered-grid">
|
231 |
{#each discoveredPiclets as piclet}
|
232 |
<PicletCard
|
@@ -398,6 +503,39 @@
|
|
398 |
gap: 12px;
|
399 |
}
|
400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
@keyframes spin {
|
402 |
to { transform: rotate(360deg); }
|
403 |
}
|
|
|
2 |
import { onMount } from 'svelte';
|
3 |
import { getCaughtPiclets, getRosterPiclets, moveToRoster, swapRosterPositions, moveToStorage, getUncaughtPiclets } from '$lib/db/piclets';
|
4 |
import type { PicletInstance } from '$lib/db/schema';
|
5 |
+
import { db } from '$lib/db/database';
|
6 |
import PicletCard from '../Piclets/PicletCard.svelte';
|
7 |
import EmptySlotCard from '../Piclets/EmptySlotCard.svelte';
|
8 |
import DraggablePicletCard from '../Piclets/DraggablePicletCard.svelte';
|
|
|
92 |
}
|
93 |
}
|
94 |
|
95 |
+
async function handleBulkDownload() {
|
96 |
+
try {
|
97 |
+
console.log('Starting bulk download of all Piclets...');
|
98 |
+
|
99 |
+
// Get all piclets (roster + storage + discovered)
|
100 |
+
const allPiclets = [...rosterPiclets, ...storagePiclets, ...discoveredPiclets];
|
101 |
+
|
102 |
+
if (allPiclets.length === 0) {
|
103 |
+
console.log('No Piclets to export');
|
104 |
+
return;
|
105 |
+
}
|
106 |
+
|
107 |
+
// Get trainer scan data for all piclets
|
108 |
+
const trainerScanData = await db.trainerScanProgress
|
109 |
+
.where('status').equals('completed')
|
110 |
+
.toArray();
|
111 |
+
|
112 |
+
// Create a map of piclet ID to trainer data
|
113 |
+
const trainerDataMap = new Map();
|
114 |
+
trainerScanData.forEach(scan => {
|
115 |
+
if (scan.picletInstanceId) {
|
116 |
+
trainerDataMap.set(scan.picletInstanceId, {
|
117 |
+
trainerName: scan.trainerName,
|
118 |
+
imagePath: scan.imagePath,
|
119 |
+
imageIndex: scan.imageIndex,
|
120 |
+
completedAt: scan.completedAt,
|
121 |
+
remoteUrl: scan.remoteUrl
|
122 |
+
});
|
123 |
+
}
|
124 |
+
});
|
125 |
+
|
126 |
+
// Create export data for each piclet
|
127 |
+
const exportData = {
|
128 |
+
exportInfo: {
|
129 |
+
totalPiclets: allPiclets.length,
|
130 |
+
exportedAt: new Date().toISOString(),
|
131 |
+
exportSource: "Pictuary Game - Bulk Export",
|
132 |
+
version: "1.0"
|
133 |
+
},
|
134 |
+
piclets: allPiclets.map(piclet => {
|
135 |
+
const trainerInfo = trainerDataMap.get(piclet.id!);
|
136 |
+
|
137 |
+
return {
|
138 |
+
// Core piclet data (same format as individual download)
|
139 |
+
id: piclet.id,
|
140 |
+
typeId: piclet.typeId,
|
141 |
+
nickname: piclet.nickname,
|
142 |
+
primaryType: piclet.primaryType,
|
143 |
+
secondaryType: piclet.secondaryType,
|
144 |
+
baseStats: piclet.baseStats,
|
145 |
+
nature: piclet.nature,
|
146 |
+
specialAbility: piclet.specialAbility,
|
147 |
+
movepool: piclet.movepool,
|
148 |
+
tier: piclet.tier,
|
149 |
+
description: piclet.description,
|
150 |
+
rosterPosition: piclet.rosterPosition,
|
151 |
+
caughtAt: piclet.caughtAt,
|
152 |
+
imageUrl: piclet.imageUrl,
|
153 |
+
imageData: piclet.imageData,
|
154 |
+
|
155 |
+
// Trainer scanner data (if available)
|
156 |
+
trainerInfo: trainerInfo || null
|
157 |
+
};
|
158 |
+
})
|
159 |
+
};
|
160 |
+
|
161 |
+
// Create and download JSON file
|
162 |
+
const jsonString = JSON.stringify(exportData, null, 2);
|
163 |
+
const blob = new Blob([jsonString], { type: 'application/json' });
|
164 |
+
const url = URL.createObjectURL(blob);
|
165 |
+
|
166 |
+
// Create temporary download link
|
167 |
+
const link = document.createElement('a');
|
168 |
+
link.href = url;
|
169 |
+
link.download = `pictuary-collection-${Date.now()}.json`;
|
170 |
+
|
171 |
+
// Trigger download
|
172 |
+
document.body.appendChild(link);
|
173 |
+
link.click();
|
174 |
+
document.body.removeChild(link);
|
175 |
+
|
176 |
+
// Clean up the blob URL
|
177 |
+
URL.revokeObjectURL(url);
|
178 |
+
|
179 |
+
console.log(`Successfully exported ${allPiclets.length} Piclets with trainer data`);
|
180 |
+
} catch (error) {
|
181 |
+
console.error('Failed to export Piclet collection:', error);
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
onMount(() => {
|
186 |
loadPiclets();
|
187 |
});
|
|
|
317 |
<!-- Discovered Section -->
|
318 |
{#if discoveredPiclets.length > 0}
|
319 |
<section class="discovered-section">
|
320 |
+
<div class="section-header">
|
321 |
+
<h2>Discovered ({discoveredPiclets.length})</h2>
|
322 |
+
<button
|
323 |
+
class="download-button"
|
324 |
+
onclick={handleBulkDownload}
|
325 |
+
title="Download all Piclets with trainer data"
|
326 |
+
>
|
327 |
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
328 |
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
329 |
+
<polyline points="7,10 12,15 17,10"></polyline>
|
330 |
+
<line x1="12" y1="15" x2="12" y2="3"></line>
|
331 |
+
</svg>
|
332 |
+
Download
|
333 |
+
</button>
|
334 |
+
</div>
|
335 |
<div class="discovered-grid">
|
336 |
{#each discoveredPiclets as piclet}
|
337 |
<PicletCard
|
|
|
503 |
gap: 12px;
|
504 |
}
|
505 |
|
506 |
+
.download-button {
|
507 |
+
display: flex;
|
508 |
+
align-items: center;
|
509 |
+
gap: 0.5rem;
|
510 |
+
background: linear-gradient(135deg, #007bff, #0056b3);
|
511 |
+
border: none;
|
512 |
+
color: white;
|
513 |
+
padding: 0.5rem 1rem;
|
514 |
+
border-radius: 8px;
|
515 |
+
font-size: 0.9rem;
|
516 |
+
font-weight: 500;
|
517 |
+
cursor: pointer;
|
518 |
+
transition: all 0.2s ease;
|
519 |
+
box-shadow: 0 2px 4px rgba(0, 123, 255, 0.2);
|
520 |
+
}
|
521 |
+
|
522 |
+
.download-button:hover {
|
523 |
+
background: linear-gradient(135deg, #0056b3, #004085);
|
524 |
+
transform: translateY(-1px);
|
525 |
+
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3);
|
526 |
+
}
|
527 |
+
|
528 |
+
.download-button:active {
|
529 |
+
transform: translateY(0);
|
530 |
+
box-shadow: 0 2px 4px rgba(0, 123, 255, 0.2);
|
531 |
+
}
|
532 |
+
|
533 |
+
.download-button svg {
|
534 |
+
width: 16px;
|
535 |
+
height: 16px;
|
536 |
+
stroke-width: 2.5;
|
537 |
+
}
|
538 |
+
|
539 |
@keyframes spin {
|
540 |
to { transform: rotate(360deg); }
|
541 |
}
|