| author | |
| committer | |
| log | 36caf200c2b24c12838570966f5c85786a1fc1f8 |
| tree | b566cf72b7e3acccf5ba19f7498545cb1c4929c6 |
| parent | 8ddd9f7efcdfb6e32b614595242b5986942d37b0 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: maria-rcks <254055478+maria-rcks@users.noreply.github.com>9 files changed, 114 insertions(+), 13 deletions(-)
apps/desktop/src/settings/DesktopClientSettings.test.ts+1| ... | @@ -34,6 +34,7 @@ const clientSettings: ClientSettings = { | ... | @@ -34,6 +34,7 @@ const clientSettings: ClientSettings = { |
| 34 | contextWindowMeterEnabled: false, | 34 | contextWindowMeterEnabled: false, |
| 35 | composerCollapseOnScroll: true, | 35 | composerCollapseOnScroll: true, |
| 36 | dismissedProviderUpdateNotificationKeys: [], | 36 | dismissedProviderUpdateNotificationKeys: [], |
| 37 | diffFilesCollapsed: true, | ||
| 37 | diffIgnoreWhitespace: true, | 38 | diffIgnoreWhitespace: true, |
| 38 | diffLayout: "stacked", | 39 | diffLayout: "stacked", |
| 39 | environmentIdentificationMode: "artwork", | 40 | environmentIdentificationMode: "artwork", |
apps/web/src/clientPersistenceStorage.test.ts+15| ... | @@ -114,6 +114,21 @@ describe("clientPersistenceStorage", () => { | ... | @@ -114,6 +114,21 @@ describe("clientPersistenceStorage", () => { |
| 114 | expect(settings).not.toHaveProperty("diffWordWrap"); | 114 | expect(settings).not.toHaveProperty("diffWordWrap"); |
| 115 | }); | 115 | }); |
| 116 | 116 | ||
| 117 | it("keeps the default diff file state across reloads and defaults it to expanded", async () => { | ||
| 118 | const testWindow = getTestWindow(); | ||
| 119 | const { readBrowserClientSettings, writeBrowserClientSettings } = | ||
| 120 | await import("./clientPersistenceStorage"); | ||
| 121 | |||
| 122 | testWindow.localStorage.setItem("t3code:client-settings:v1", JSON.stringify({})); | ||
| 123 | expect(readBrowserClientSettings()?.diffFilesCollapsed).toBe(false); | ||
| 124 | |||
| 125 | writeBrowserClientSettings({ ...DEFAULT_CLIENT_SETTINGS, diffFilesCollapsed: true }); | ||
| 126 | expect(readBrowserClientSettings()?.diffFilesCollapsed).toBe(true); | ||
| 127 | |||
| 128 | writeBrowserClientSettings({ ...DEFAULT_CLIENT_SETTINGS, diffFilesCollapsed: false }); | ||
| 129 | expect(readBrowserClientSettings()?.diffFilesCollapsed).toBe(false); | ||
| 130 | }); | ||
| 131 | |||
| 117 | it("keeps the diff layout across reloads and defaults it to stacked", async () => { | 132 | it("keeps the diff layout across reloads and defaults it to stacked", async () => { |
| 118 | const testWindow = getTestWindow(); | 133 | const testWindow = getTestWindow(); |
| 119 | const { readBrowserClientSettings, writeBrowserClientSettings } = | 134 | const { readBrowserClientSettings, writeBrowserClientSettings } = |
apps/web/src/components/DiffPanel.tsx+21-10| ... | @@ -226,10 +226,6 @@ export default function DiffPanel({ | ... | @@ -226,10 +226,6 @@ export default function DiffPanel({ |
| 226 | ? `${routeThreadRef.environmentId}:${routeThreadRef.threadId}:${reviewSectionId}` | 226 | ? `${routeThreadRef.environmentId}:${routeThreadRef.threadId}:${reviewSectionId}` |
| 227 | : null; | 227 | : null; |
| 228 | const codeViewMountKey = `${collapseScopeKey ?? reviewSectionId}:${codeViewRevision}`; | 228 | const codeViewMountKey = `${collapseScopeKey ?? reviewSectionId}:${codeViewRevision}`; |
| 229 | const collapsedDiffFileKeys = | ||
| 230 | collapsedDiffFiles.scopeKey === collapseScopeKey | ||
| 231 | ? collapsedDiffFiles.fileKeys | ||
| 232 | : EMPTY_COLLAPSED_DIFF_FILE_KEYS; | ||
| 233 | const reviewSectionTitle = selectedTurn | 229 | const reviewSectionTitle = selectedTurn |
| 234 | ? `Turn ${selectedCheckpointTurnCount ?? "?"}` | 230 | ? `Turn ${selectedCheckpointTurnCount ?? "?"}` |
| 235 | : selectedGitScope === "unstaged" | 231 | : selectedGitScope === "unstaged" |
| ... | @@ -425,6 +421,17 @@ export default function DiffPanel({ | ... | @@ -425,6 +421,17 @@ export default function DiffPanel({ |
| 425 | })), | 421 | })), |
| 426 | [renderableFiles], | 422 | [renderableFiles], |
| 427 | ); | 423 | ); |
| 424 | const defaultCollapsedDiffFileKeys = useMemo( | ||
| 425 | () => | ||
| 426 | settings.diffFilesCollapsed | ||
| 427 | ? new Set(renderableFileEntries.map((file) => file.fileKey)) | ||
| 428 | : EMPTY_COLLAPSED_DIFF_FILE_KEYS, | ||
| 429 | [renderableFileEntries, settings.diffFilesCollapsed], | ||
| 430 | ); | ||
| 431 | const collapsedDiffFileKeys = | ||
| 432 | collapsedDiffFiles.scopeKey === collapseScopeKey | ||
| 433 | ? collapsedDiffFiles.fileKeys | ||
| 434 | : defaultCollapsedDiffFileKeys; | ||
| 428 | const codeViewFiles = useMemo( | 435 | const codeViewFiles = useMemo( |
| 429 | () => | 436 | () => |
| 430 | renderableFileEntries.map(({ fileDiff, fileKey, fileVersion }) => { | 437 | renderableFileEntries.map(({ fileDiff, fileKey, fileVersion }) => { |
| ... | @@ -462,14 +469,16 @@ export default function DiffPanel({ | ... | @@ -462,14 +469,16 @@ export default function DiffPanel({ |
| 462 | if (!file) return; | 469 | if (!file) return; |
| 463 | if (file.collapsed) { | 470 | if (file.collapsed) { |
| 464 | setCollapsedDiffFiles((current) => { | 471 | setCollapsedDiffFiles((current) => { |
| 465 | const next = new Set(current.scopeKey === collapseScopeKey ? current.fileKeys : []); | 472 | const next = new Set( |
| 473 | current.scopeKey === collapseScopeKey ? current.fileKeys : defaultCollapsedDiffFileKeys, | ||
| 474 | ); | ||
| 466 | next.delete(file.fileKey); | 475 | next.delete(file.fileKey); |
| 467 | return { scopeKey: collapseScopeKey, fileKeys: next }; | 476 | return { scopeKey: collapseScopeKey, fileKeys: next }; |
| 468 | }); | 477 | }); |
| 469 | } | 478 | } |
| 470 | requestTreeReveal(file.fileKey); | 479 | requestTreeReveal(file.fileKey); |
| 471 | }, | 480 | }, |
| 472 | [codeViewFiles, collapseScopeKey, requestTreeReveal], | 481 | [codeViewFiles, collapseScopeKey, defaultCollapsedDiffFileKeys, requestTreeReveal], |
| 473 | ); | 482 | ); |
| 474 | 483 | ||
| 475 | const openDiffFile = useCallback( | 484 | const openDiffFile = useCallback( |
| ... | @@ -503,7 +512,9 @@ export default function DiffPanel({ | ... | @@ -503,7 +512,9 @@ export default function DiffPanel({ |
| 503 | const toggleDiffFileCollapsed = useCallback( | 512 | const toggleDiffFileCollapsed = useCallback( |
| 504 | (fileKey: string) => { | 513 | (fileKey: string) => { |
| 505 | setCollapsedDiffFiles((current) => { | 514 | setCollapsedDiffFiles((current) => { |
| 506 | const next = new Set(current.scopeKey === collapseScopeKey ? current.fileKeys : []); | 515 | const next = new Set( |
| 516 | current.scopeKey === collapseScopeKey ? current.fileKeys : defaultCollapsedDiffFileKeys, | ||
| 517 | ); | ||
| 507 | if (next.has(fileKey)) { | 518 | if (next.has(fileKey)) { |
| 508 | next.delete(fileKey); | 519 | next.delete(fileKey); |
| 509 | } else { | 520 | } else { |
| ... | @@ -512,21 +523,21 @@ export default function DiffPanel({ | ... | @@ -512,21 +523,21 @@ export default function DiffPanel({ |
| 512 | return { scopeKey: collapseScopeKey, fileKeys: next }; | 523 | return { scopeKey: collapseScopeKey, fileKeys: next }; |
| 513 | }); | 524 | }); |
| 514 | }, | 525 | }, |
| 515 | [collapseScopeKey], | 526 | [collapseScopeKey, defaultCollapsedDiffFileKeys], |
| 516 | ); | 527 | ); |
| 517 | 528 | ||
| 518 | const toggleDiffFileCollapse = useCallback(() => { | 529 | const toggleDiffFileCollapse = useCallback(() => { |
| 519 | setCodeViewRevision((current) => current + 1); | 530 | setCodeViewRevision((current) => current + 1); |
| 520 | setCollapsedDiffFiles((current) => { | 531 | setCollapsedDiffFiles((current) => { |
| 521 | const currentKeys = | 532 | const currentKeys = |
| 522 | current.scopeKey === collapseScopeKey ? current.fileKeys : EMPTY_COLLAPSED_DIFF_FILE_KEYS; | 533 | current.scopeKey === collapseScopeKey ? current.fileKeys : defaultCollapsedDiffFileKeys; |
| 523 | 534 | ||
| 524 | return { | 535 | return { |
| 525 | scopeKey: collapseScopeKey, | 536 | scopeKey: collapseScopeKey, |
| 526 | fileKeys: toggleAllDiffFiles(diffFileKeys, currentKeys), | 537 | fileKeys: toggleAllDiffFiles(diffFileKeys, currentKeys), |
| 527 | }; | 538 | }; |
| 528 | }); | 539 | }); |
| 529 | }, [collapseScopeKey, diffFileKeys]); | 540 | }, [collapseScopeKey, defaultCollapsedDiffFileKeys, diffFileKeys]); |
| 530 | 541 | ||
| 531 | const selectTurn = (turnId: TurnId) => { | 542 | const selectTurn = (turnId: TurnId) => { |
| 532 | if (!routeThreadRef) return; | 543 | if (!routeThreadRef) return; |
apps/web/src/components/pullRequest/PullRequestCodeTab.tsx+6-1| ... | @@ -485,7 +485,11 @@ function PullRequestCodeTab({ | ... | @@ -485,7 +485,11 @@ function PullRequestCodeTab({ |
| 485 | groupAt(anchor.side, anchor.line).draft = true; | 485 | groupAt(anchor.side, anchor.line).draft = true; |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | const collapsed = isFileDiffCollapsed(fileKey, foldOverride, toggledFiles); | 488 | const collapsed = isFileDiffCollapsed( |
| 489 | fileKey, | ||
| 490 | foldOverride ?? (settings.diffFilesCollapsed ? "folded" : "expanded"), | ||
| 491 | toggledFiles, | ||
| 492 | ); | ||
| 489 | 493 | ||
| 490 | const annotations: ReviewAnnotation[] = [...groups.values()].map((group) => ({ | 494 | const annotations: ReviewAnnotation[] = [...groups.values()].map((group) => ({ |
| 491 | side: toViewerSide(group.side), | 495 | side: toViewerSide(group.side), |
| ... | @@ -538,6 +542,7 @@ function PullRequestCodeTab({ | ... | @@ -538,6 +542,7 @@ function PullRequestCodeTab({ |
| 538 | foldOverride, | 542 | foldOverride, |
| 539 | pendingComments, | 543 | pendingComments, |
| 540 | placedThreadIds, | 544 | placedThreadIds, |
| 545 | settings.diffFilesCollapsed, | ||
| 541 | toggledFiles, | 546 | toggledFiles, |
| 542 | ], | 547 | ], |
| 543 | ); | 548 | ); |
apps/web/src/components/pullRequest/pullRequestDiff.logic.ts+2-2| ... | @@ -30,8 +30,8 @@ export type DiffFoldOverride = "expanded" | "folded" | null; | ... | @@ -30,8 +30,8 @@ export type DiffFoldOverride = "expanded" | "folded" | null; |
| 30 | * A diff arrives a slice at a time, so the reader's own choices are kept as the difference from | 30 | * A diff arrives a slice at a time, so the reader's own choices are kept as the difference from |
| 31 | * what the toolbar last said rather than as the set of folded files: a file that has not loaded | 31 | * what the toolbar last said rather than as the set of folded files: a file that has not loaded |
| 32 | * yet cannot be in a set, and would otherwise land expanded moments after the reader folded | 32 | * yet cannot be in a set, and would otherwise land expanded moments after the reader folded |
| 33 | * everything. Files start expanded so opening the Code tab immediately shows the change; the | 33 | * everything. The caller supplies the saved default until the toolbar overrides it; individual |
| 34 | * reader can still fold individual files or the whole diff from the toolbar. | 34 | * files can still be toggled independently. |
| 35 | */ | 35 | */ |
| 36 | export function isFileDiffCollapsed( | 36 | export function isFileDiffCollapsed( |
| 37 | fileKey: string, | 37 | fileKey: string, |
apps/web/src/components/settings/SettingsPanels.tsx+47| ... | @@ -533,6 +533,9 @@ export function useSettingsRestore(onRestored?: () => void) { | ... | @@ -533,6 +533,9 @@ export function useSettingsRestore(onRestored?: () => void) { |
| 533 | : []), | 533 | : []), |
| 534 | ...(settings.wordWrap !== DEFAULT_UNIFIED_SETTINGS.wordWrap ? ["Word wrap"] : []), | 534 | ...(settings.wordWrap !== DEFAULT_UNIFIED_SETTINGS.wordWrap ? ["Word wrap"] : []), |
| 535 | ...getChangedTypographySettingLabels(settings), | 535 | ...getChangedTypographySettingLabels(settings), |
| 536 | ...(settings.diffFilesCollapsed !== DEFAULT_UNIFIED_SETTINGS.diffFilesCollapsed | ||
| 537 | ? ["Default diff file state"] | ||
| 538 | : []), | ||
| 536 | ...(settings.diffIgnoreWhitespace !== DEFAULT_UNIFIED_SETTINGS.diffIgnoreWhitespace | 539 | ...(settings.diffIgnoreWhitespace !== DEFAULT_UNIFIED_SETTINGS.diffIgnoreWhitespace |
| 537 | ? ["Diff whitespace changes"] | 540 | ? ["Diff whitespace changes"] |
| 538 | : []), | 541 | : []), |
| ... | @@ -608,6 +611,7 @@ export function useSettingsRestore(onRestored?: () => void) { | ... | @@ -608,6 +611,7 @@ export function useSettingsRestore(onRestored?: () => void) { |
| 608 | settings.addProjectBaseDirectory, | 611 | settings.addProjectBaseDirectory, |
| 609 | settings.defaultThreadEnvMode, | 612 | settings.defaultThreadEnvMode, |
| 610 | settings.newWorktreesStartFromOrigin, | 613 | settings.newWorktreesStartFromOrigin, |
| 614 | settings.diffFilesCollapsed, | ||
| 611 | settings.diffIgnoreWhitespace, | 615 | settings.diffIgnoreWhitespace, |
| 612 | settings.diffLayout, | 616 | settings.diffLayout, |
| 613 | settings.proactivePanelsEnabled, | 617 | settings.proactivePanelsEnabled, |
| ... | @@ -706,6 +710,7 @@ export function useSettingsRestore(onRestored?: () => void) { | ... | @@ -706,6 +710,7 @@ export function useSettingsRestore(onRestored?: () => void) { |
| 706 | diffColorScheme: DEFAULT_UNIFIED_SETTINGS.diffColorScheme, | 710 | diffColorScheme: DEFAULT_UNIFIED_SETTINGS.diffColorScheme, |
| 707 | timestampFormat: DEFAULT_UNIFIED_SETTINGS.timestampFormat, | 711 | timestampFormat: DEFAULT_UNIFIED_SETTINGS.timestampFormat, |
| 708 | wordWrap: DEFAULT_UNIFIED_SETTINGS.wordWrap, | 712 | wordWrap: DEFAULT_UNIFIED_SETTINGS.wordWrap, |
| 713 | diffFilesCollapsed: DEFAULT_UNIFIED_SETTINGS.diffFilesCollapsed, | ||
| 709 | diffIgnoreWhitespace: DEFAULT_UNIFIED_SETTINGS.diffIgnoreWhitespace, | 714 | diffIgnoreWhitespace: DEFAULT_UNIFIED_SETTINGS.diffIgnoreWhitespace, |
| 710 | diffLayout: DEFAULT_UNIFIED_SETTINGS.diffLayout, | 715 | diffLayout: DEFAULT_UNIFIED_SETTINGS.diffLayout, |
| 711 | proactivePanelsEnabled: DEFAULT_UNIFIED_SETTINGS.proactivePanelsEnabled, | 716 | proactivePanelsEnabled: DEFAULT_UNIFIED_SETTINGS.proactivePanelsEnabled, |
| ... | @@ -2304,6 +2309,48 @@ export function GeneralSettingsPanel() { | ... | @@ -2304,6 +2309,48 @@ export function GeneralSettingsPanel() { |
| 2304 | /> | 2309 | /> |
| 2305 | } | 2310 | } |
| 2306 | /> | 2311 | /> |
| 2312 | <SettingsRow | ||
| 2313 | {...searchableSetting("default-diff-file-state")} | ||
| 2314 | description="Start with files expanded or collapsed when opening diffs or a pull request's Code tab." | ||
| 2315 | resetAction={ | ||
| 2316 | settings.diffFilesCollapsed !== DEFAULT_UNIFIED_SETTINGS.diffFilesCollapsed ? ( | ||
| 2317 | <SettingResetButton | ||
| 2318 | label="default diff file state" | ||
| 2319 | onClick={() => | ||
| 2320 | updateSettings({ | ||
| 2321 | diffFilesCollapsed: DEFAULT_UNIFIED_SETTINGS.diffFilesCollapsed, | ||
| 2322 | }) | ||
| 2323 | } | ||
| 2324 | /> | ||
| 2325 | ) : null | ||
| 2326 | } | ||
| 2327 | control={ | ||
| 2328 | <Select | ||
| 2329 | value={settings.diffFilesCollapsed ? "collapsed" : "expanded"} | ||
| 2330 | onValueChange={(value) => { | ||
| 2331 | if (value === "expanded" || value === "collapsed") { | ||
| 2332 | updateSettings({ diffFilesCollapsed: value === "collapsed" }); | ||
| 2333 | } | ||
| 2334 | }} | ||
| 2335 | > | ||
| 2336 | <SelectTrigger | ||
| 2337 | size="sm" | ||
| 2338 | className="w-full sm:w-40" | ||
| 2339 | aria-label="Default diff file state" | ||
| 2340 | > | ||
| 2341 | <SelectValue>{settings.diffFilesCollapsed ? "Collapsed" : "Expanded"}</SelectValue> | ||
| 2342 | </SelectTrigger> | ||
| 2343 | <SelectPopup align="end" alignItemWithTrigger={false}> | ||
| 2344 | <SelectItem hideIndicator value="expanded"> | ||
| 2345 | Expanded | ||
| 2346 | </SelectItem> | ||
| 2347 | <SelectItem hideIndicator value="collapsed"> | ||
| 2348 | Collapsed | ||
| 2349 | </SelectItem> | ||
| 2350 | </SelectPopup> | ||
| 2351 | </Select> | ||
| 2352 | } | ||
| 2353 | /> | ||
| 2307 | <SettingsRow | 2354 | <SettingsRow |
| 2308 | {...searchableSetting("diff-layout")} | 2355 | {...searchableSetting("diff-layout")} |
| 2309 | description="Show diffs stacked or side by side. The toggle in the diff toolbar changes this too." | 2356 | description="Show diffs stacked or side by side. The toggle in the diff toolbar changes this too." |
apps/web/src/components/settings/settingsSearch.ts+6| ... | @@ -247,6 +247,12 @@ export const SETTINGS_SEARCH_ITEMS = [ | ... | @@ -247,6 +247,12 @@ export const SETTINGS_SEARCH_ITEMS = [ |
| 247 | to: "/settings/general", | 247 | to: "/settings/general", |
| 248 | searchTerms: ["diff ignore spaces edits default"], | 248 | searchTerms: ["diff ignore spaces edits default"], |
| 249 | }, | 249 | }, |
| 250 | { | ||
| 251 | id: "default-diff-file-state", | ||
| 252 | title: "Default diff file state", | ||
| 253 | to: "/settings/general", | ||
| 254 | searchTerms: ["collapsed expanded collapse expand files pull request pr code tab"], | ||
| 255 | }, | ||
| 250 | { | 256 | { |
| 251 | id: "diff-layout", | 257 | id: "diff-layout", |
| 252 | title: "Diff layout", | 258 | title: "Diff layout", |
packages/contracts/src/settings.test.ts+14| ... | @@ -164,6 +164,20 @@ describe("ClaudeSettings auto-compaction", () => { | ... | @@ -164,6 +164,20 @@ describe("ClaudeSettings auto-compaction", () => { |
| 164 | }); | 164 | }); |
| 165 | }); | 165 | }); |
| 166 | 166 | ||
| 167 | describe("ClientSettings default diff file state", () => { | ||
| 168 | it("keeps files expanded when existing settings omit the preference", () => { | ||
| 169 | expect(decodeClientSettings({}).diffFilesCollapsed).toBe(false); | ||
| 170 | }); | ||
| 171 | |||
| 172 | it.each([true, false])("preserves a saved collapsed preference of %s", (diffFilesCollapsed) => { | ||
| 173 | const settings = decodeClientSettings({ diffFilesCollapsed }); | ||
| 174 | expect(encodeClientSettings(settings).diffFilesCollapsed).toBe(diffFilesCollapsed); | ||
| 175 | expect(decodeClientSettingsPatch({ diffFilesCollapsed }).diffFilesCollapsed).toBe( | ||
| 176 | diffFilesCollapsed, | ||
| 177 | ); | ||
| 178 | }); | ||
| 179 | }); | ||
| 180 | |||
| 167 | describe("ClientSettings diff colors", () => { | 181 | describe("ClientSettings diff colors", () => { |
| 168 | it("keeps red and green for existing settings without a saved palette", () => { | 182 | it("keeps red and green for existing settings without a saved palette", () => { |
| 169 | expect(decodeClientSettings({}).diffColorScheme).toBe("red-green"); | 183 | expect(decodeClientSettings({}).diffColorScheme).toBe("red-green"); |
packages/contracts/src/settings.ts+2| ... | @@ -344,6 +344,7 @@ export const ClientSettingsSchema = Schema.Struct({ | ... | @@ -344,6 +344,7 @@ export const ClientSettingsSchema = Schema.Struct({ |
| 344 | dismissedProviderUpdateNotificationKeys: Schema.Array(TrimmedNonEmptyString).pipe( | 344 | dismissedProviderUpdateNotificationKeys: Schema.Array(TrimmedNonEmptyString).pipe( |
| 345 | Schema.withDecodingDefault(Effect.succeed([])), | 345 | Schema.withDecodingDefault(Effect.succeed([])), |
| 346 | ), | 346 | ), |
| 347 | diffFilesCollapsed: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), | ||
| 347 | diffIgnoreWhitespace: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))), | 348 | diffIgnoreWhitespace: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))), |
| 348 | diffLayout: DiffLayout.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_DIFF_LAYOUT))), | 349 | diffLayout: DiffLayout.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_DIFF_LAYOUT))), |
| 349 | environmentIdentificationMode: EnvironmentIdentificationMode.pipe( | 350 | environmentIdentificationMode: EnvironmentIdentificationMode.pipe( |
| ... | @@ -1432,6 +1433,7 @@ export const ClientSettingsPatch = Schema.Struct({ | ... | @@ -1432,6 +1433,7 @@ export const ClientSettingsPatch = Schema.Struct({ |
| 1432 | confirmThreadArchive: Schema.optionalKey(Schema.Boolean), | 1433 | confirmThreadArchive: Schema.optionalKey(Schema.Boolean), |
| 1433 | confirmThreadDelete: Schema.optionalKey(Schema.Boolean), | 1434 | confirmThreadDelete: Schema.optionalKey(Schema.Boolean), |
| 1434 | confirmThreadUnpin: Schema.optionalKey(Schema.Boolean), | 1435 | confirmThreadUnpin: Schema.optionalKey(Schema.Boolean), |
| 1436 | diffFilesCollapsed: Schema.optionalKey(Schema.Boolean), | ||
| 1435 | diffIgnoreWhitespace: Schema.optionalKey(Schema.Boolean), | 1437 | diffIgnoreWhitespace: Schema.optionalKey(Schema.Boolean), |
| 1436 | diffLayout: Schema.optionalKey(DiffLayout), | 1438 | diffLayout: Schema.optionalKey(DiffLayout), |
| 1437 | environmentIdentificationMode: Schema.optionalKey(EnvironmentIdentificationMode), | 1439 | environmentIdentificationMode: Schema.optionalKey(EnvironmentIdentificationMode), |