Skip to content

Commit aad9e79

Browse files
Merge pull request #47 from kactus-io/group-files
Group files
2 parents 9cc1f8d + 0fe0c7a commit aad9e79

32 files changed

+806
-242
lines changed

app/src/lib/app-state.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
FileChange,
1111
WorkingDirectoryStatus,
1212
WorkingDirectoryFileChange,
13+
FileType,
1314
} from '../models/status'
1415
import { CloningRepository, IGitHubUser, SignInState } from './dispatcher'
1516
import { ICommitMessage } from './dispatcher/git-store'
@@ -511,6 +512,8 @@ export interface IHistoryState {
511512
readonly changedFiles: ReadonlyArray<FileChange>
512513

513514
readonly diff: IDiff | null
515+
516+
readonly loadingDiff: boolean
514517
}
515518

516519
export interface IKactusState {
@@ -545,4 +548,11 @@ export interface IChangesState {
545548

546549
/** The commit message for a work-in-progress commit in the changes view. */
547550
readonly commitMessage: ICommitMessage | null
551+
552+
readonly loadingDiff: boolean
553+
554+
readonly selectedSketchPart: {
555+
id: string
556+
type: FileType.LayerFile | FileType.PageFile
557+
} | null
548558
}

app/src/lib/dispatcher/app-store.ts

Lines changed: 132 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@ import {
2727
FileChange,
2828
WorkingDirectoryStatus,
2929
WorkingDirectoryFileChange,
30+
TSketchPartChange,
3031
} from '../../models/status'
31-
import { DiffSelection, DiffSelectionType, DiffType } from '../../models/diff'
32+
import {
33+
DiffSelection,
34+
DiffSelectionType,
35+
DiffType,
36+
IDiff,
37+
} from '../../models/diff'
3238
import { matchGitHubRepository } from '../../lib/repository-matching'
3339
import {
3440
API,
@@ -89,6 +95,7 @@ import {
8995
deleteBranch,
9096
getCommitDiff,
9197
getWorkingDirectoryDiff,
98+
getWorkingDirectoryPartDiff,
9299
getChangedFiles,
93100
updateRef,
94101
addRemote,
@@ -396,6 +403,7 @@ export class AppStore {
396403
changedFiles: new Array<FileChange>(),
397404
history: new Array<string>(),
398405
diff: null,
406+
loadingDiff: false,
399407
},
400408
changesState: {
401409
workingDirectory: WorkingDirectoryStatus.fromFiles(
@@ -405,6 +413,8 @@ export class AppStore {
405413
diff: null,
406414
contextualCommitMessage: null,
407415
commitMessage: null,
416+
loadingDiff: false,
417+
selectedSketchPart: null,
408418
},
409419
kactus: {
410420
files: new Array<IKactusFile & {}>(),
@@ -679,7 +689,7 @@ export class AppStore {
679689

680690
const gitStore = this.getGitStore(repository)
681691
const changedFiles = await gitStore.performFailableOperation(() =>
682-
getChangedFiles(repository, currentSHA)
692+
getChangedFiles(repository, state.kactus.files, currentSHA)
683693
)
684694
if (!changedFiles) {
685695
return
@@ -740,15 +750,18 @@ export class AppStore {
740750
): Promise<void> {
741751
this.updateHistoryState(repository, state => {
742752
const selection = { sha: state.selection.sha, file }
743-
const diff = null
744-
return { selection, diff }
753+
return { selection, loadingDiff: true }
745754
})
746755
this.emitUpdate()
747756

748757
const stateBeforeLoad = this.getRepositoryState(repository)
749758
const sha = stateBeforeLoad.historyState.selection.sha
750759

751760
if (!sha) {
761+
this.updateHistoryState(repository, state => {
762+
return { loadingDiff: false }
763+
})
764+
this.emitUpdate()
752765
if (__DEV__) {
753766
throw new Error(
754767
"No currently selected sha yet we've been asked to switch file selection"
@@ -787,7 +800,7 @@ export class AppStore {
787800

788801
this.updateHistoryState(repository, state => {
789802
const selection = { sha: state.selection.sha, file }
790-
return { selection, diff }
803+
return { selection, diff, loadingDiff: false }
791804
})
792805

793806
this.emitUpdate()
@@ -1086,7 +1099,7 @@ export class AppStore {
10861099
}
10871100

10881101
const gitStore = this.getGitStore(repository)
1089-
const status = await gitStore.loadStatus()
1102+
const status = await gitStore.loadStatus(kactusStatus.files)
10901103

10911104
if (!status) {
10921105
this.updateRepositoryState(repository, state => {
@@ -1174,7 +1187,7 @@ export class AppStore {
11741187
): Promise<void> {
11751188
this.updateChangesState(repository, state => ({
11761189
selectedFileID: selectedFile ? selectedFile.id : null,
1177-
diff: null,
1190+
selectedSketchPart: null,
11781191
}))
11791192
this.updateKactusState(repository, state => ({ selectedFileID: null }))
11801193
this.emitUpdate()
@@ -1227,7 +1240,31 @@ export class AppStore {
12271240
this.updateKactusState(repository, state => ({
12281241
selectedFileID: selectedFile ? selectedFile.id : null,
12291242
}))
1230-
this.updateChangesState(repository, state => ({ selectedFileID: null }))
1243+
this.updateChangesState(repository, state => ({
1244+
selectedFileID: null,
1245+
selectedSketchPart: null,
1246+
diff: null,
1247+
}))
1248+
this.emitUpdate()
1249+
1250+
this.updateChangesDiffForCurrentSelection(repository)
1251+
}
1252+
1253+
/** This shouldn't be called directly. See `Dispatcher`. */
1254+
public async _changeSketchPartSelection(
1255+
repository: Repository,
1256+
selectedPart: TSketchPartChange | null
1257+
): Promise<void> {
1258+
this.updateChangesState(repository, state => ({
1259+
selectedFileID: null,
1260+
selectedSketchPart: selectedPart
1261+
? {
1262+
id: selectedPart.id,
1263+
type: selectedPart.type,
1264+
}
1265+
: null,
1266+
}))
1267+
this.updateKactusState(repository, state => ({ selectedFileID: null }))
12311268
this.emitUpdate()
12321269

12331270
this.updateChangesDiffForCurrentSelection(repository)
@@ -1241,75 +1278,113 @@ export class AppStore {
12411278
private async updateChangesDiffForCurrentSelection(
12421279
repository: Repository
12431280
): Promise<void> {
1281+
this.updateChangesState(repository, state => ({ loadingDiff: true }))
1282+
this.emitUpdate()
1283+
12441284
const stateBeforeLoad = this.getRepositoryState(repository)
12451285
const changesStateBeforeLoad = stateBeforeLoad.changesState
12461286
const selectedFileIDBeforeLoad = changesStateBeforeLoad.selectedFileID
1247-
if (!selectedFileIDBeforeLoad) {
1248-
return
1249-
}
1287+
const selectedSketchPartBeforeLoad =
1288+
changesStateBeforeLoad.selectedSketchPart
12501289

1251-
const selectedFileBeforeLoad = changesStateBeforeLoad.workingDirectory.findFileWithID(
1252-
selectedFileIDBeforeLoad
1253-
)
1254-
if (!selectedFileBeforeLoad) {
1290+
let diff: IDiff
1291+
1292+
if (selectedFileIDBeforeLoad) {
1293+
const selectedFileBeforeLoad = changesStateBeforeLoad.workingDirectory.findFileWithID(
1294+
selectedFileIDBeforeLoad
1295+
)
1296+
if (!selectedFileBeforeLoad) {
1297+
this.updateChangesState(repository, state => ({ loadingDiff: false }))
1298+
this.emitUpdate()
1299+
return
1300+
}
1301+
1302+
diff = await getWorkingDirectoryDiff(
1303+
this.sketchPath,
1304+
repository,
1305+
stateBeforeLoad.kactus.files,
1306+
selectedFileBeforeLoad,
1307+
stateBeforeLoad.historyState.history[0]
1308+
)
1309+
} else if (selectedSketchPartBeforeLoad) {
1310+
diff = await getWorkingDirectoryPartDiff(
1311+
this.sketchPath,
1312+
repository,
1313+
stateBeforeLoad.kactus.files,
1314+
selectedSketchPartBeforeLoad,
1315+
stateBeforeLoad.historyState.history[0]
1316+
)
1317+
} else {
1318+
this.updateChangesState(repository, state => ({ loadingDiff: false }))
1319+
this.emitUpdate()
12551320
return
12561321
}
12571322

1258-
const diff = await getWorkingDirectoryDiff(
1259-
this.sketchPath,
1260-
repository,
1261-
stateBeforeLoad.kactus.files,
1262-
selectedFileBeforeLoad,
1263-
stateBeforeLoad.historyState.history[0]
1264-
)
1265-
12661323
const stateAfterLoad = this.getRepositoryState(repository)
12671324
const changesState = stateAfterLoad.changesState
12681325
const selectedFileID = changesState.selectedFileID
1326+
const selectedSketchPart = changesState.selectedSketchPart
12691327

12701328
// A different file could have been selected while we were loading the diff
12711329
// in which case we no longer care about the diff we just loaded.
1272-
if (!selectedFileID) {
1273-
return
1274-
}
1275-
if (selectedFileID !== selectedFileIDBeforeLoad) {
1330+
if (
1331+
(!selectedFileID || selectedFileID !== selectedFileIDBeforeLoad) &&
1332+
(!selectedSketchPart ||
1333+
selectedSketchPart !== selectedSketchPartBeforeLoad)
1334+
) {
1335+
this.updateChangesState(repository, state => ({ loadingDiff: false }))
1336+
this.emitUpdate()
12761337
return
12771338
}
12781339

1279-
const currentlySelectedFile = changesState.workingDirectory.findFileWithID(
1280-
selectedFileID
1281-
)
1282-
if (!currentlySelectedFile) {
1283-
return
1284-
}
1340+
if (selectedFileID) {
1341+
const currentlySelectedFile = changesState.workingDirectory.findFileWithID(
1342+
selectedFileID
1343+
)
1344+
if (!currentlySelectedFile) {
1345+
this.updateChangesState(repository, state => ({ loadingDiff: false }))
1346+
this.emitUpdate()
1347+
return
1348+
}
12851349

1286-
const selectableLines = new Set<number>()
1287-
if (diff.kind === DiffType.Text) {
1288-
// The diff might have changed dramatically since last we loaded it.
1289-
// Ideally we would be more clever about validating that any partial
1290-
// selection state is still valid by ensuring that selected lines still
1291-
// exist but for now we'll settle on just updating the selectable lines
1292-
// such that any previously selected line which now no longer exists or
1293-
// has been turned into a context line isn't still selected.
1294-
diff.hunks.forEach(h => {
1295-
h.lines.forEach((line, index) => {
1296-
if (line.isIncludeableLine()) {
1297-
selectableLines.add(h.unifiedDiffStart + index)
1298-
}
1350+
const selectableLines = new Set<number>()
1351+
if (diff.kind === DiffType.Text) {
1352+
// The diff might have changed dramatically since last we loaded it.
1353+
// Ideally we would be more clever about validating that any partial
1354+
// selection state is still valid by ensuring that selected lines still
1355+
// exist but for now we'll settle on just updating the selectable lines
1356+
// such that any previously selected line which now no longer exists or
1357+
// has been turned into a context line isn't still selected.
1358+
diff.hunks.forEach(h => {
1359+
h.lines.forEach((line, index) => {
1360+
if (line.isIncludeableLine()) {
1361+
selectableLines.add(h.unifiedDiffStart + index)
1362+
}
1363+
})
12991364
})
1300-
})
1301-
}
1365+
}
13021366

1303-
const newSelection = currentlySelectedFile.selection.withSelectableLines(
1304-
selectableLines
1305-
)
1306-
const selectedFile = currentlySelectedFile.withSelection(newSelection)
1307-
const updatedFiles = changesState.workingDirectory.files.map(
1308-
f => (f.id === selectedFile.id ? selectedFile : f)
1309-
)
1310-
const workingDirectory = WorkingDirectoryStatus.fromFiles(updatedFiles)
1367+
const newSelection = currentlySelectedFile.selection.withSelectableLines(
1368+
selectableLines
1369+
)
1370+
const selectedFile = currentlySelectedFile.withSelection(newSelection)
1371+
const updatedFiles = changesState.workingDirectory.files.map(
1372+
f => (f.id === selectedFile.id ? selectedFile : f)
1373+
)
1374+
const workingDirectory = WorkingDirectoryStatus.fromFiles(updatedFiles)
1375+
1376+
this.updateChangesState(repository, state => ({
1377+
diff,
1378+
workingDirectory,
1379+
loadingDiff: false,
1380+
}))
1381+
} else {
1382+
this.updateChangesState(repository, state => ({
1383+
diff,
1384+
loadingDiff: false,
1385+
}))
1386+
}
13111387

1312-
this.updateChangesState(repository, state => ({ diff, workingDirectory }))
13131388
this.emitUpdate()
13141389
}
13151390

app/src/lib/dispatcher/dispatcher.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { Disposable } from 'event-kit'
55

66
import { Account } from '../../models/account'
77
import { Repository } from '../../models/repository'
8-
import { WorkingDirectoryFileChange, FileChange } from '../../models/status'
8+
import {
9+
WorkingDirectoryFileChange,
10+
FileChange,
11+
TSketchPartChange,
12+
} from '../../models/status'
913
import { DiffSelection } from '../../models/diff'
1014
import {
1115
RepositorySection,
@@ -212,6 +216,14 @@ export class Dispatcher {
212216
return this.appStore._changeChangesSelection(repository, selectedFile)
213217
}
214218

219+
/** Change the currently selected sketch part in CHanges. */
220+
public changeSketchPartSelection(
221+
repository: Repository,
222+
selectedPart: TSketchPartChange
223+
): Promise<void> {
224+
return this.appStore._changeSketchPartSelection(repository, selectedPart)
225+
}
226+
215227
/**
216228
* Commit the changes which were marked for inclusion, using the given commit
217229
* summary and description.

app/src/lib/dispatcher/git-store.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { ErrorWithMetadata, IErrorMetadata } from '../error-with-metadata'
1414
import { structuralEquals } from '../../lib/equality'
1515
import { compare } from '../../lib/compare'
1616
import { queueWorkHigh } from '../../lib/queue-work'
17+
import { IKactusFile } from '../../lib/kactus'
1718

1819
import {
1920
reset,
@@ -587,9 +588,11 @@ export class GitStore {
587588
this.emitUpdate()
588589
}
589590

590-
public async loadStatus(): Promise<IStatusResult | null> {
591+
public async loadStatus(
592+
sketchFiles: ReadonlyArray<IKactusFile>
593+
): Promise<IStatusResult | null> {
591594
const status = await this.performFailableOperation(() =>
592-
getStatus(this.repository)
595+
getStatus(this.repository, sketchFiles)
593596
)
594597

595598
if (!status) {

0 commit comments

Comments
 (0)