Fraser commited on
Commit
b524411
·
1 Parent(s): fd1786e

type logos

Browse files
classes/aquatic.png CHANGED

Git LFS Details

  • SHA256: 71072081acfa176234ba4de6d48b7b5d93835342db7aaaeef13e60d21d0c926f
  • Pointer size: 131 Bytes
  • Size of remote file: 968 kB

Git LFS Details

  • SHA256: b9a903503b2e60c12227bcb3618ba6c289485f3664ca12715e367b08e523ae6c
  • Pointer size: 130 Bytes
  • Size of remote file: 35.8 kB
classes/beast.png CHANGED

Git LFS Details

  • SHA256: ad5a2d36f38255aa64fa66b342ccbd2815d5d57c44878fb689604ffbfbf1fd75
  • Pointer size: 132 Bytes
  • Size of remote file: 1.23 MB

Git LFS Details

  • SHA256: b840ad44419a457e266309cb48b894dc19173ababc3ab6fbae98f5b4a8323e8b
  • Pointer size: 130 Bytes
  • Size of remote file: 42.9 kB
classes/bug.png CHANGED

Git LFS Details

  • SHA256: 99e714469031dc13dca4c425a9c1b32ad11ed325361349759720e28dc9e54123
  • Pointer size: 132 Bytes
  • Size of remote file: 1.85 MB

Git LFS Details

  • SHA256: a35210a36a0e075fbe23c6b4a04f510119c710920ce9c8237ba0a87dabedd58f
  • Pointer size: 130 Bytes
  • Size of remote file: 39.7 kB
classes/cuisine.png CHANGED

Git LFS Details

  • SHA256: 583b2f39481ab5afe47daa1f81058f5cd64b1a32ca4447f16fc447d4eb8fc470
  • Pointer size: 132 Bytes
  • Size of remote file: 1.3 MB

Git LFS Details

  • SHA256: af1d4841cb2ac6d08163d0a3bca6b58ca670d12ae912ced37cdc2a00b10ced7e
  • Pointer size: 130 Bytes
  • Size of remote file: 36.9 kB
classes/culture.png CHANGED

Git LFS Details

  • SHA256: 900674e46d033b3b4d9180560ef33a80d94f14ce123e0b3f5f09abf307535455
  • Pointer size: 132 Bytes
  • Size of remote file: 1.01 MB

Git LFS Details

  • SHA256: 368a9f4a77e00ea92d0af1b28b54cd3e2a67babe824161889bc6300d8383c938
  • Pointer size: 130 Bytes
  • Size of remote file: 34.7 kB
classes/flora.png CHANGED

Git LFS Details

  • SHA256: bb912ccad5f1b766283c5a9afcd5a9c1f228bc4160e950f3f028f41ec8dec41f
  • Pointer size: 132 Bytes
  • Size of remote file: 1.42 MB

Git LFS Details

  • SHA256: 92c21beada719ee13bb8f722124b70381ffb536a2e9504daaccd2b2df999e5ac
  • Pointer size: 130 Bytes
  • Size of remote file: 37.3 kB
classes/machina.png CHANGED

Git LFS Details

  • SHA256: 0e8496ff9ba615ea897331a92a301dc546004246c41a7bda4a38b1c42aea73fd
  • Pointer size: 132 Bytes
  • Size of remote file: 1.09 MB

Git LFS Details

  • SHA256: 155e87a5751ef8187966ffe6c2e41d652701c7ac73e3777b4ed2a40b8d957a76
  • Pointer size: 130 Bytes
  • Size of remote file: 30.6 kB
classes/mineral.png CHANGED

Git LFS Details

  • SHA256: 6e9e07969659d8e1297bb9dad762bf3f9c55eac8ab6decd8097c985db6b72505
  • Pointer size: 132 Bytes
  • Size of remote file: 1.34 MB

Git LFS Details

  • SHA256: 203cd9d747d0bb6042ac6fdc51c416da988ef0fdb71b15b8daf8b1ab874f734c
  • Pointer size: 130 Bytes
  • Size of remote file: 42.7 kB
classes/space.png CHANGED

Git LFS Details

  • SHA256: 4e3c0c48a0bfa2e66eb9f71c86729a09ff3ea7d9424830d5e7cd477af9e1b668
  • Pointer size: 132 Bytes
  • Size of remote file: 1.13 MB

Git LFS Details

  • SHA256: 6b4347ee4aa9ee71658bf7bbc9ed90b4f29704c844bd7ec2d7dc2ee41d5d79d6
  • Pointer size: 130 Bytes
  • Size of remote file: 33.7 kB
classes/structure.png CHANGED

Git LFS Details

  • SHA256: d01417e095943855711b635d0a4efd046d94fd3302f9d8f5979d1eb5ddb96e8b
  • Pointer size: 132 Bytes
  • Size of remote file: 1.42 MB

Git LFS Details

  • SHA256: c5c4e5430b7050711989b1449a64ce14a5cea6a38e6ef0790f7108665348de1d
  • Pointer size: 130 Bytes
  • Size of remote file: 33 kB
src/lib/components/Pages/Pictuary.svelte CHANGED
@@ -11,6 +11,8 @@
11
  import PicletDetail from '../Piclets/PicletDetail.svelte';
12
  import AddToRosterDialog from '../Piclets/AddToRosterDialog.svelte';
13
  import ViewAll from './ViewAll.svelte';
 
 
14
 
15
  let rosterPiclets: PicletInstance[] = $state([]);
16
  let storagePiclets: PicletInstance[] = $state([]);
@@ -31,9 +33,43 @@
31
  });
32
  return map;
33
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  async function loadPiclets() {
36
  try {
 
 
 
37
  const allInstances = await getAllPicletInstances();
38
 
39
  // Filter based on rosterPosition instead of isInRoster
@@ -139,7 +175,7 @@
139
  onBack={() => viewAllMode = null}
140
  />
141
  {:else}
142
- <div class="pictuary-page">
143
  {#if isLoading}
144
  <div class="loading-state">
145
  <div class="spinner"></div>
@@ -247,6 +283,23 @@
247
  overflow-y: auto;
248
  -webkit-overflow-scrolling: touch;
249
  background: white;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  }
251
 
252
 
@@ -259,6 +312,8 @@
259
  height: calc(100% - 100px);
260
  padding: 2rem;
261
  text-align: center;
 
 
262
  }
263
 
264
  .spinner {
@@ -290,6 +345,8 @@
290
 
291
  .content {
292
  padding: 0 1rem 100px;
 
 
293
  }
294
 
295
  section {
 
11
  import PicletDetail from '../Piclets/PicletDetail.svelte';
12
  import AddToRosterDialog from '../Piclets/AddToRosterDialog.svelte';
13
  import ViewAll from './ViewAll.svelte';
14
+ import { migratePicletTypes } from '$lib/utils/typeMigration';
15
+ import { PicletType } from '$lib/types/picletTypes';
16
 
17
  let rosterPiclets: PicletInstance[] = $state([]);
18
  let storagePiclets: PicletInstance[] = $state([]);
 
33
  });
34
  return map;
35
  });
36
+
37
+ // Get the most common type in the roster for background theming
38
+ let dominantType = $derived(() => {
39
+ if (rosterPiclets.length === 0) {
40
+ return PicletType.BEAST; // Default fallback
41
+ }
42
+
43
+ // Count type occurrences
44
+ const typeCounts = new Map<PicletType, number>();
45
+ rosterPiclets.forEach(piclet => {
46
+ if (piclet.primaryType) {
47
+ const count = typeCounts.get(piclet.primaryType) || 0;
48
+ typeCounts.set(piclet.primaryType, count + 1);
49
+ }
50
+ });
51
+
52
+ // Find the most common type
53
+ let maxCount = 0;
54
+ let mostCommonType = PicletType.BEAST;
55
+ typeCounts.forEach((count, type) => {
56
+ if (count > maxCount) {
57
+ maxCount = count;
58
+ mostCommonType = type;
59
+ }
60
+ });
61
+
62
+ return mostCommonType;
63
+ });
64
+
65
+ // Get background image path for the dominant type
66
+ let backgroundImagePath = $derived(`/classes/${dominantType}.png`);
67
 
68
  async function loadPiclets() {
69
  try {
70
+ // Run type migration first time to fix any invalid types
71
+ await migratePicletTypes();
72
+
73
  const allInstances = await getAllPicletInstances();
74
 
75
  // Filter based on rosterPosition instead of isInRoster
 
175
  onBack={() => viewAllMode = null}
176
  />
177
  {:else}
178
+ <div class="pictuary-page" style="--bg-image: url('{backgroundImagePath}')">
179
  {#if isLoading}
180
  <div class="loading-state">
181
  <div class="spinner"></div>
 
283
  overflow-y: auto;
284
  -webkit-overflow-scrolling: touch;
285
  background: white;
286
+ position: relative;
287
+ }
288
+
289
+ .pictuary-page::before {
290
+ content: '';
291
+ position: fixed;
292
+ top: 0;
293
+ left: 0;
294
+ right: 0;
295
+ bottom: 0;
296
+ background-image: var(--bg-image);
297
+ background-size: 300px 300px;
298
+ background-repeat: no-repeat;
299
+ background-position: center bottom;
300
+ opacity: 0.03;
301
+ pointer-events: none;
302
+ z-index: 0;
303
  }
304
 
305
 
 
312
  height: calc(100% - 100px);
313
  padding: 2rem;
314
  text-align: center;
315
+ position: relative;
316
+ z-index: 1;
317
  }
318
 
319
  .spinner {
 
345
 
346
  .content {
347
  padding: 0 1rem 100px;
348
+ position: relative;
349
+ z-index: 1;
350
  }
351
 
352
  section {
src/lib/components/UI/TypeBadge.svelte CHANGED
@@ -1,9 +1,9 @@
1
  <script lang="ts">
2
  import type { PicletType } from '$lib/types/picletTypes';
3
- import { TYPE_DATA } from '$lib/types/picletTypes';
4
 
5
  interface Props {
6
- type: PicletType;
7
  size?: 'small' | 'medium' | 'large';
8
  showIcon?: boolean;
9
  showLabel?: boolean;
@@ -11,16 +11,59 @@
11
 
12
  let { type, size = 'medium', showIcon = true, showLabel = false }: Props = $props();
13
 
14
- const typeInfo = $derived(TYPE_DATA[type]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  const sizeClass = $derived(`size-${size}`);
16
  </script>
17
 
18
- <div class="type-badge {sizeClass}" style="--type-color: {typeInfo.color}">
19
  {#if showIcon}
20
- <span class="type-icon">{typeInfo.icon}</span>
21
  {/if}
22
  {#if showLabel}
23
- <span class="type-label">{typeInfo.name}</span>
24
  {/if}
25
  </div>
26
 
 
1
  <script lang="ts">
2
  import type { PicletType } from '$lib/types/picletTypes';
3
+ import { TYPE_DATA, PicletType as PicletTypeEnum } from '$lib/types/picletTypes';
4
 
5
  interface Props {
6
+ type: PicletType | string | undefined;
7
  size?: 'small' | 'medium' | 'large';
8
  showIcon?: boolean;
9
  showLabel?: boolean;
 
11
 
12
  let { type, size = 'medium', showIcon = true, showLabel = false }: Props = $props();
13
 
14
+ // Safely get type info with fallback for invalid types
15
+ const typeInfo = $derived(() => {
16
+ // Handle undefined or null
17
+ if (!type) {
18
+ return TYPE_DATA[PicletTypeEnum.BEAST]; // Default fallback
19
+ }
20
+
21
+ // Check if type exists in TYPE_DATA
22
+ const typeData = TYPE_DATA[type as PicletType];
23
+ if (typeData) {
24
+ return typeData;
25
+ }
26
+
27
+ // Handle legacy string types by mapping them
28
+ const legacyTypeMap: Record<string, PicletType> = {
29
+ 'normal': PicletTypeEnum.BEAST,
30
+ 'fire': PicletTypeEnum.BEAST,
31
+ 'water': PicletTypeEnum.AQUATIC,
32
+ 'electric': PicletTypeEnum.MACHINA,
33
+ 'grass': PicletTypeEnum.FLORA,
34
+ 'ice': PicletTypeEnum.MINERAL,
35
+ 'fighting': PicletTypeEnum.BEAST,
36
+ 'poison': PicletTypeEnum.FLORA,
37
+ 'ground': PicletTypeEnum.MINERAL,
38
+ 'flying': PicletTypeEnum.BEAST,
39
+ 'psychic': PicletTypeEnum.SPACE,
40
+ 'bug': PicletTypeEnum.BUG,
41
+ 'rock': PicletTypeEnum.MINERAL,
42
+ 'ghost': PicletTypeEnum.SPACE,
43
+ 'dragon': PicletTypeEnum.BEAST,
44
+ 'dark': PicletTypeEnum.SPACE,
45
+ 'steel': PicletTypeEnum.MACHINA,
46
+ 'fairy': PicletTypeEnum.CULTURE
47
+ };
48
+
49
+ const mappedType = legacyTypeMap[type as string];
50
+ if (mappedType) {
51
+ return TYPE_DATA[mappedType];
52
+ }
53
+
54
+ // Final fallback
55
+ return TYPE_DATA[PicletTypeEnum.BEAST];
56
+ });
57
+
58
  const sizeClass = $derived(`size-${size}`);
59
  </script>
60
 
61
+ <div class="type-badge {sizeClass}" style="--type-color: {typeInfo().color}">
62
  {#if showIcon}
63
+ <span class="type-icon">{typeInfo().icon}</span>
64
  {/if}
65
  {#if showLabel}
66
+ <span class="type-label">{typeInfo().name}</span>
67
  {/if}
68
  </div>
69
 
src/lib/utils/typeMigration.ts ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { db } from '../db/index';
2
+ import { PicletType, getTypeFromConcept } from '../types/picletTypes';
3
+ import type { PicletInstance } from '../db/schema';
4
+
5
+ // Migration function to fix piclets with invalid or legacy types
6
+ export async function migratePicletTypes(): Promise<void> {
7
+ console.log('Starting piclet type migration...');
8
+
9
+ try {
10
+ // Get all piclet instances
11
+ const allPiclets = await db.picletInstances.toArray();
12
+ let migratedCount = 0;
13
+
14
+ for (const piclet of allPiclets) {
15
+ let needsUpdate = false;
16
+ let newType: PicletType | undefined;
17
+
18
+ // Check if primaryType is invalid or missing
19
+ if (!piclet.primaryType || !isValidPicletType(piclet.primaryType)) {
20
+ // Try to determine type from concept/caption
21
+ if (piclet.concept) {
22
+ newType = getTypeFromConcept(piclet.concept, piclet.imageCaption);
23
+ needsUpdate = true;
24
+ } else {
25
+ // Fallback to Beast type
26
+ newType = PicletType.BEAST;
27
+ needsUpdate = true;
28
+ }
29
+ }
30
+
31
+ // Check for legacy string types that need mapping
32
+ else if (typeof piclet.primaryType === 'string' && isLegacyType(piclet.primaryType)) {
33
+ newType = mapLegacyType(piclet.primaryType);
34
+ needsUpdate = true;
35
+ }
36
+
37
+ if (needsUpdate && newType && piclet.id) {
38
+ await db.picletInstances.update(piclet.id, {
39
+ primaryType: newType
40
+ });
41
+ migratedCount++;
42
+ console.log(`Migrated piclet ${piclet.nickname || piclet.typeId} from "${piclet.primaryType}" to "${newType}"`);
43
+ }
44
+ }
45
+
46
+ console.log(`Migration complete: Updated ${migratedCount} piclets`);
47
+ } catch (error) {
48
+ console.error('Error during piclet type migration:', error);
49
+ }
50
+ }
51
+
52
+ function isValidPicletType(type: any): type is PicletType {
53
+ return Object.values(PicletType).includes(type);
54
+ }
55
+
56
+ function isLegacyType(type: string): boolean {
57
+ const legacyTypes = [
58
+ 'normal', 'fire', 'water', 'electric', 'grass', 'ice',
59
+ 'fighting', 'poison', 'ground', 'flying', 'psychic', 'bug',
60
+ 'rock', 'ghost', 'dragon', 'dark', 'steel', 'fairy'
61
+ ];
62
+ return legacyTypes.includes(type.toLowerCase());
63
+ }
64
+
65
+ function mapLegacyType(legacyType: string): PicletType {
66
+ const legacyTypeMap: Record<string, PicletType> = {
67
+ 'normal': PicletType.BEAST,
68
+ 'fire': PicletType.BEAST,
69
+ 'water': PicletType.AQUATIC,
70
+ 'electric': PicletType.MACHINA,
71
+ 'grass': PicletType.FLORA,
72
+ 'ice': PicletType.MINERAL,
73
+ 'fighting': PicletType.BEAST,
74
+ 'poison': PicletType.FLORA,
75
+ 'ground': PicletType.MINERAL,
76
+ 'flying': PicletType.BEAST,
77
+ 'psychic': PicletType.SPACE,
78
+ 'bug': PicletType.BUG,
79
+ 'rock': PicletType.MINERAL,
80
+ 'ghost': PicletType.SPACE,
81
+ 'dragon': PicletType.BEAST,
82
+ 'dark': PicletType.SPACE,
83
+ 'steel': PicletType.MACHINA,
84
+ 'fairy': PicletType.CULTURE
85
+ };
86
+
87
+ return legacyTypeMap[legacyType.toLowerCase()] || PicletType.BEAST;
88
+ }