this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

more fixes

alice 1ec3dd4c 0dc8f24f

+167 -121
+6
bun.lock
··· 4 4 "": { 5 5 "name": "values", 6 6 "dependencies": { 7 + "@types/lodash": "^4.17.16", 8 + "lodash": "^4.17.21", 7 9 "parcel": "^2.14.4", 8 10 "wrangler": "^4.7.0", 9 11 }, ··· 337 339 338 340 "@types/bun": ["@types/bun@1.2.8", "", { "dependencies": { "bun-types": "1.2.7" } }, "sha512-t8L1RvJVUghW5V+M/fL3Thbxcs0HwNsXsnTEBEfEVqGteiJToOlZ/fyOEaR1kZsNqnu+3XA4RI/qmnX4w6+S+w=="], 339 341 342 + "@types/lodash": ["@types/lodash@4.17.16", "", {}, "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g=="], 343 + 340 344 "@types/node": ["@types/node@22.14.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA=="], 341 345 342 346 "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], ··· 484 488 "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], 485 489 486 490 "lmdb": ["lmdb@2.8.5", "", { "dependencies": { "msgpackr": "^1.9.5", "node-addon-api": "^6.1.0", "node-gyp-build-optional-packages": "5.1.1", "ordered-binary": "^1.4.1", "weak-lru-cache": "^1.2.2" }, "optionalDependencies": { "@lmdb/lmdb-darwin-arm64": "2.8.5", "@lmdb/lmdb-darwin-x64": "2.8.5", "@lmdb/lmdb-linux-arm": "2.8.5", "@lmdb/lmdb-linux-arm64": "2.8.5", "@lmdb/lmdb-linux-x64": "2.8.5", "@lmdb/lmdb-win32-x64": "2.8.5" }, "bin": { "download-lmdb-prebuilds": "bin/download-prebuilds.js" } }, "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ=="], 491 + 492 + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], 487 493 488 494 "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], 489 495
+1 -1
index.html
··· 89 89 <section id="part4" class="exercise-part" style="display: none;"> 90 90 <h2>Part 4: Final Statements</h2> 91 91 <div id="finalStatements"></div> 92 - <button id="backToPart3">Back</button> 93 92 <button id="finish">Finish</button> 93 + <button id="backToPart3">Back</button> 94 94 </section> 95 95 96 96 <!-- Review/Export Page -->
+72 -120
index.ts
··· 17 17 18 18 // Import the UndoManager from its own file 19 19 import { UndoManager } from './undoManager'; 20 - 21 - // Top-level constant for default values 22 - const DEFAULT_VALUES = [ 23 - "ACCEPTANCE", 24 - "ACCURACY", 25 - "ACHIEVEMENT", 26 - "ADVENTURE", 27 - "ATTRACTIVENESS", 28 - "AUTHORITY", 29 - "AUTONOMY", 30 - "BEAUTY", 31 - "CARING", 32 - "CHALLENGE", 33 - "CHANGE", 34 - // "COMFORT", 35 - // "COMMITMENT", 36 - // "COMPASSION", 37 - // "CONTRIBUTION", 38 - // "COOPERATION", 39 - // "COURTESY", 40 - // "CREATIVITY", 41 - // "DEPENDABILITY", 42 - // "DUTY", 43 - // "ECOLOGY", 44 - // "EXCITEMENT", 45 - // "FAITHFULNESS", 46 - // "FAME", 47 - // "FAMILY", 48 - // "FITNESS", 49 - // "FLEXIBILITY", 50 - // "FORGIVENESS", 51 - // "FRIENDSHIP", 52 - // "FUN", 53 - // "GENEROSITY", 54 - // "GENUINENESS", 55 - // "GOD'S WILL", 56 - // "GROWTH", 57 - // "HEALTH", 58 - // "HELPFULNESS", 59 - // "HONESTY", 60 - // "HOPE", 61 - // "HUMILITY", 62 - // "HUMOR", 63 - // "INDEPENDENCE", 64 - // "INDUSTRY", 65 - // "INNER PEACE", 66 - // "INTIMACY", 67 - // "JUSTICE", 68 - // "KNOWLEDGE", 69 - // "LEISURE", 70 - // "LOVED", 71 - // "LOVING", 72 - // "MASTERY", 73 - // "MINDFULNESS", 74 - // "MODERATION", 75 - // "MONOGAMY", 76 - // "NONCONFORMITY", 77 - // "NURTURANCE", 78 - // "OPENNESS", 79 - // "ORDER", 80 - // "PASSION", 81 - // "PLEASURE", 82 - // "POPULARITY", 83 - // "POWER", 84 - // "PURPOSE", 85 - // "RATIONALITY", 86 - // "REALISM", 87 - // "RESPONSIBILITY", 88 - // "RISK", 89 - // "ROMANCE", 90 - // "SAFETY", 91 - // "SELF-ACCEPTANCE", 92 - // "SELF-CONTROL", 93 - // "SELF-ESTEEM", 94 - // "SELF-KNOWLEDGE", 95 - // "SERVICE", 96 - // "SEXUALITY", 97 - // "SIMPLICITY", 98 - // "SOLITUDE", 99 - // "SPIRITUALITY", 100 - // "STABILITY", 101 - // "TOLERANCE", 102 - // "TRADITION", 103 - // "VIRTUE", 104 - // "WEALTH", 105 - // "WORLD PEACE", 106 - ]; 20 + // Import the default values from its own file 21 + import { DEFAULT_VALUES } from './values'; 22 + import { debounce } from 'lodash'; // Import debounce from lodash 107 23 108 24 // Main application class 109 25 export class App { 110 26 private state: AppState; 111 27 public undoManager: UndoManager<AppState>; 112 28 private storageKey: string = "valuesExerciseState"; 29 + // Re-add the property to hold the debounced function 30 + private debouncedUpdateFinalStatement: (cardId: number, value: string) => void; 113 31 114 32 constructor() { 115 33 // Load state from localStorage or initialize default state. ··· 124 42 this.state = this.defaultState(); 125 43 } 126 44 this.undoManager = new UndoManager<AppState>(this.state); 45 + 46 + // Re-add initialization using lodash debounce 47 + this.debouncedUpdateFinalStatement = debounce((cardId: number, value: string) => { 48 + const newState = this.undoManager.getState(); 49 + newState.finalStatements[cardId] = value; 50 + this.updateState(newState); 51 + }, 500); 52 + 127 53 this.bindEventListeners(); 128 54 this.render(); 129 55 this.updateUndoRedoButtons(); ··· 322 248 323 249 // Render the UI based on the current state. 324 250 private render() { 251 + // Manage tabindex for global controls based on current part 252 + const isPart4Active = this.state.currentPart === "part4"; 253 + const globalControls = document.querySelectorAll('#global-controls button'); 254 + globalControls.forEach(btn => { 255 + if (isPart4Active) { 256 + (btn as HTMLElement).tabIndex = -1; // Make header buttons non-tabbable during Part 4 257 + } else { 258 + (btn as HTMLElement).removeAttribute('tabindex'); // Restore default tabbability 259 + } 260 + }); 261 + 325 262 // Hide all parts first. 326 263 document.querySelectorAll(".exercise-part").forEach((section) => { 327 264 (section as HTMLElement).style.display = "none"; ··· 400 337 }); 401 338 } else if (this.state.currentPart === "part4") { 402 339 // Render text inputs for each core value. 403 - const finalStatements = document.getElementById("finalStatements"); 404 - if (finalStatements) { 405 - finalStatements.innerHTML = ""; 340 + const finalStatementsContainer = document.getElementById("finalStatements"); 341 + if (finalStatementsContainer) { 406 342 const coreCards = this.state.cards.filter((c) => c.column === "core"); 407 - 408 - // Sort coreCards alphabetically by name for consistent order and tab index 409 - coreCards.sort((a, b) => a.name.localeCompare(b.name)); 410 - 411 - coreCards.forEach((card, index) => { 412 - const wrapper = document.createElement("div"); 413 - wrapper.className = "final-statement"; 414 - const label = document.createElement("label"); 415 - label.htmlFor = `statement-${card.id}`; 416 - label.textContent = `Describe what "${card.name}" means to you:`; 417 - const input = document.createElement("input"); 418 - input.type = "text"; 419 - input.id = `statement-${card.id}`; 420 - input.value = this.state.finalStatements[card.id] || ""; 421 - input.tabIndex = index + 1; // Set explicit tabindex for inputs (1 to N) 422 - input.addEventListener("change", () => { 423 - const newState = this.undoManager.getState(); 424 - newState.finalStatements[card.id] = input.value; 425 - this.updateState(newState); 343 + coreCards.sort((a, b) => a.name.localeCompare(b.name)); // Keep sorting for consistent order 344 + 345 + // Check if inputs matching core cards already exist 346 + const existingInputs = finalStatementsContainer.querySelectorAll<HTMLInputElement>('input[type="text"]'); 347 + let inputsMatch = existingInputs.length === coreCards.length; 348 + if (inputsMatch) { 349 + existingInputs.forEach((input, index) => { 350 + // Verify the input corresponds to the correct card (using id or other attribute if needed) 351 + // For simplicity, we assume order matches due to sorting if length is correct 352 + if (coreCards[index]?.id.toString() !== input.id.replace('statement-', '')) { 353 + inputsMatch = false; 354 + } 355 + }); 356 + } 357 + 358 + if (inputsMatch) { 359 + // Inputs exist and match: Just update their values 360 + existingInputs.forEach((input) => { 361 + const cardId = Number(input.id.replace('statement-', '')); 362 + const currentValue = this.state.finalStatements[cardId] || ""; 363 + if (input.value !== currentValue) { 364 + input.value = currentValue; 365 + } 366 + }); 367 + } else { 368 + // Inputs don't exist or don't match: Clear and recreate them 369 + finalStatementsContainer.innerHTML = ""; 370 + coreCards.forEach((card, index) => { 371 + const wrapper = document.createElement("div"); 372 + wrapper.className = "final-statement"; 373 + const label = document.createElement("label"); 374 + label.htmlFor = `statement-${card.id}`; 375 + label.textContent = `Describe what "${card.name}" means to you:`; 376 + const input = document.createElement("input"); 377 + input.type = "text"; 378 + input.id = `statement-${card.id}`; 379 + input.value = this.state.finalStatements[card.id] || ""; 380 + // Use 'input' event to call the debounced update function 381 + input.addEventListener("input", () => { 382 + // Call the debounced function, passing necessary info 383 + this.debouncedUpdateFinalStatement(card.id, input.value); 384 + }); 385 + wrapper.appendChild(label); 386 + wrapper.appendChild(input); 387 + finalStatementsContainer.appendChild(wrapper); 426 388 }); 427 - wrapper.appendChild(label); 428 - wrapper.appendChild(input); 429 - finalStatements.appendChild(wrapper); 430 - }); 431 - 432 - // Set tabindex for buttons after the inputs 433 - const backBtn = document.getElementById("backToPart3") as HTMLButtonElement | null; 434 - const finishBtn = document.getElementById("finish") as HTMLButtonElement | null; 435 - const nextTabIndex = coreCards.length + 1; 436 - if (finishBtn) finishBtn.tabIndex = nextTabIndex; // Finish button comes next 437 - if (backBtn) backBtn.tabIndex = nextTabIndex + 1; // Back button comes after Finish 389 + } 438 390 } 439 391 } else if (this.state.currentPart === "review") { 440 392 const reviewContent = document.getElementById("reviewContent");
+2
package.json
··· 10 10 "typescript": "^5" 11 11 }, 12 12 "dependencies": { 13 + "@types/lodash": "^4.17.16", 14 + "lodash": "^4.17.21", 13 15 "parcel": "^2.14.4", 14 16 "wrangler": "^4.7.0" 15 17 },
+86
values.ts
··· 1 + // Top-level constant for default values 2 + export const DEFAULT_VALUES = [ 3 + "ACCEPTANCE", 4 + "ACCURACY", 5 + "ACHIEVEMENT", 6 + "ADVENTURE", 7 + "ATTRACTIVENESS", 8 + "AUTHORITY", 9 + "AUTONOMY", 10 + "BEAUTY", 11 + "CARING", 12 + "CHALLENGE", 13 + "CHANGE", 14 + // "COMFORT", 15 + // "COMMITMENT", 16 + // "COMPASSION", 17 + // "CONTRIBUTION", 18 + // "COOPERATION", 19 + // "COURTESY", 20 + // "CREATIVITY", 21 + // "DEPENDABILITY", 22 + // "DUTY", 23 + // "ECOLOGY", 24 + // "EXCITEMENT", 25 + // "FAITHFULNESS", 26 + // "FAME", 27 + // "FAMILY", 28 + // "FITNESS", 29 + // "FLEXIBILITY", 30 + // "FORGIVENESS", 31 + // "FRIENDSHIP", 32 + // "FUN", 33 + // "GENEROSITY", 34 + // "GENUINENESS", 35 + // "GOD'S WILL", 36 + // "GROWTH", 37 + // "HEALTH", 38 + // "HELPFULNESS", 39 + // "HONESTY", 40 + // "HOPE", 41 + // "HUMILITY", 42 + // "HUMOR", 43 + // "INDEPENDENCE", 44 + // "INDUSTRY", 45 + // "INNER PEACE", 46 + // "INTIMACY", 47 + // "JUSTICE", 48 + // "KNOWLEDGE", 49 + // "LEISURE", 50 + // "LOVED", 51 + // "LOVING", 52 + // "MASTERY", 53 + // "MINDFULNESS", 54 + // "MODERATION", 55 + // "MONOGAMY", 56 + // "NONCONFORMITY", 57 + // "NURTURANCE", 58 + // "OPENNESS", 59 + // "ORDER", 60 + // "PASSION", 61 + // "PLEASURE", 62 + // "POPULARITY", 63 + // "POWER", 64 + // "PURPOSE", 65 + // "RATIONALITY", 66 + // "REALISM", 67 + // "RESPONSIBILITY", 68 + // "RISK", 69 + // "ROMANCE", 70 + // "SAFETY", 71 + // "SELF-ACCEPTANCE", 72 + // "SELF-CONTROL", 73 + // "SELF-ESTEEM", 74 + // "SELF-KNOWLEDGE", 75 + // "SERVICE", 76 + // "SEXUALITY", 77 + // "SIMPLICITY", 78 + // "SOLITUDE", 79 + // "SPIRITUALITY", 80 + // "STABILITY", 81 + // "TOLERANCE", 82 + // "TRADITION", 83 + // "VIRTUE", 84 + // "WEALTH", 85 + // "WORLD PEACE", 86 + ];