Skip to content
This repository has been archived by the owner on Jul 21, 2020. It is now read-only.

Commit

Permalink
feat(project): rename unlink dialog to change link, allow unlinking (f…
Browse files Browse the repository at this point in the history
…ixes #118)
  • Loading branch information
connor4312 committed May 25, 2018
1 parent e6ed3c1 commit fa32666
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
"@angular/material": "^5.2.4",
"@angular/platform-browser": "^5.2.8",
"@angular/platform-browser-dynamic": "^5.2.8",
"@mixer/cdk-std": "^0.2.13",
"@mixer/cdk-std": "^0.2.17",
"@ngrx/effects": "^5.2.0",
"@ngrx/entity": "^5.2.0",
"@ngrx/store": "^5.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h4 matLine>{{ game.name }}</h4>
<p matLine>Updated: {{ game.updatedAt | amTimeAgo }}</p>
<button mat-raised-button color="primary" *ngIf="(linkedGame | async)?.id !== game.id "
(click)="link(game)">Link</button>
<button mat-raised-button disabled *ngIf="(linkedGame | async)?.id === game.id">Linked</button>
<button mat-raised-button (click)="unlink()" *ngIf="(linkedGame | async)?.id === game.id">Unlink</button>
</mat-list-item>
</mat-list>
</div>
12 changes: 10 additions & 2 deletions src/app/editor/project/link-dialog/link-dialog.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MatDialogRef } from '@angular/material';
import { Store } from '@ngrx/store';

import * as fromRoot from '../../bedrock.reducers';
import { IInteractiveGame, SetInteractiveGame } from '../project.actions';
import { IInteractiveGame, SetInteractiveGame, UnlinkInteractiveGame } from '../project.actions';
import * as fromProject from '../project.reducer';

/**
Expand Down Expand Up @@ -31,10 +31,18 @@ export class LinkProjectDialogComponent {
) {}

/**
* Deletes a snapshot from the store.
* Unlink a game from the project.
*/
public link(project: IInteractiveGame) {
this.store.dispatch(new SetInteractiveGame(project));
this.dialog.close(project);
}

/**
* Unlinks the linked game from the control.
*/
public unlink() {
this.store.dispatch(new UnlinkInteractiveGame());
this.dialog.close(undefined);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<menu-bar-item
(click)="changeLink()"
*ngIf="linkedProject | async"
text="Unlink from {{ (linkedProject | async)?.name }}">
text="Change Linked Game">
</menu-bar-item>
<menu-bar-item
(click)="changeLink()"
Expand Down
13 changes: 12 additions & 1 deletion src/app/editor/project/project.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export const enum ProjectActionTypes {
TRY_OPEN_PROJECT = '[Project] Attempt to open a directory',
SET_OPEN_PROJECT = '[Project] Set the currently open project',
SET_GAME_LINK = '[Project] Set the linked Interactive version',
UNSET_GAME_LINK = '[Project] Unset the linked Interactive version',
SET_CONFIRM_SCHEMA = '[Project] Set whether to confirm schema upload',
OPEN_DIRECTORY = '[Project] Open directory',
START_CHANGE_LINK = '[Project] Start changing the linked project',
Expand All @@ -78,6 +79,7 @@ export const enum ProjectActionTypes {
export const enum ProjectMethods {
OpenDirectory = '[Project] Open directory',
LinkGameToControls = '[Project] Link game to controls',
UnlinkGameFromControls = '[Project] Unlink game to controls',
GetOwnedGames = '[Project] Get owned games',
RenameProject = '[Project] Rename',
}
Expand Down Expand Up @@ -148,6 +150,14 @@ export class StartChangeLink implements Action {
public readonly type = ProjectActionTypes.START_CHANGE_LINK;
}

/**
* Fired to start the process of changing which project the
* controls are linked to.
*/
export class UnlinkInteractiveGame implements Action {
public readonly type = ProjectActionTypes.UNSET_GAME_LINK;
}

/**
* Fired when the user starts the linking process, loads Interactive games
* that they own.
Expand Down Expand Up @@ -197,4 +207,5 @@ export type ProjectActions =
| LoadOwnedGames
| SetOwnedGames
| RequireLink
| RenameProject;
| RenameProject
| UnlinkInteractiveGame;
15 changes: 15 additions & 0 deletions src/app/editor/project/project.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ export class ProjectEffects {
),
);

/**
* Persists a link to an interactive project to the server.
*/
@Effect({ dispatch: false })
public readonly unsetLinkedVersion = this.actions
.ofType<SetInteractiveGame>(ProjectActionTypes.UNSET_GAME_LINK)
.pipe(
withLatestDirectory(this.store),
switchMap(([, directory]) =>
this.electron
.call(ProjectMethods.UnlinkGameFromControls, { directory })
.catch(RpcError, () => undefined),
),
);

/**
* Updates the name of the project package.json.
*/
Expand Down
8 changes: 8 additions & 0 deletions src/app/editor/project/project.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ export function projectReducer(state: IProjectState = {}, action: ProjectActions
switch (action.type) {
case ProjectActionTypes.SET_GAME_LINK:
return { ...state, project: { ...state.project, interactiveGame: action.game } };
case ProjectActionTypes.UNSET_GAME_LINK:
return {
...state,
project: {
...state.project,
interactiveGame: null,
},
};
case ProjectActionTypes.SET_CONFIRM_SCHEMA:
return { ...state, project: { ...state.project, confirmSchemaUpload: action.confirm } };
case ProjectActionTypes.RENAME_PROJECT:
Expand Down
18 changes: 15 additions & 3 deletions src/server/datastore.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isPlainObject, merge } from 'lodash';
import * as os from 'os';
import * as path from 'path';
import { appendFile, exists, mkdir, readFile, writeFile } from './util';
import { appendFile, exists, mkdir, readFile, unlink, writeFile } from './util';

/**
* IDataStore is a system-aware store for project files and settings.
Expand Down Expand Up @@ -74,13 +74,25 @@ export class FileDataStore implements IDataStore {
}

public async saveGlobal<T>(file: string, value: T): Promise<void> {
const filePath = this.filePath(this.homedir, file);
await this.ensureMiixFolderInDir(this.homedir, false);
await writeFile(this.filePath(this.homedir, file), JSON.stringify(value, null, 2));

if (value === undefined) {
await unlink(filePath);
} else {
await writeFile(filePath, JSON.stringify(value, null, 2));
}
}

public async saveProject<T>(file: string, projectPath: string, value: T): Promise<void> {
const filePath = this.filePath(projectPath, file);
await this.ensureMiixFolderInDir(projectPath, true);
await writeFile(this.filePath(projectPath, file), JSON.stringify(value, null, 2));

if (value === undefined) {
await unlink(filePath);
} else {
await writeFile(filePath, JSON.stringify(value, null, 2));
}
}

private filePath(base: string, file: string) {
Expand Down
7 changes: 7 additions & 0 deletions src/server/electron-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@ const methods: { [methodName: string]: (data: any, server: ElectronServer) => Pr
return new ProjectLinker(new Project(options.directory)).linkGame(options.game);
},

/**
* Links the Interactive game to the set of controls.
*/
[forProject.ProjectMethods.UnlinkGameFromControls]: async (options: { directory: string }) => {
return new ProjectLinker(new Project(options.directory)).unlinkGame();
},

/**
* Links the Interactive game to the set of controls.
*/
Expand Down
7 changes: 7 additions & 0 deletions src/server/project-linker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ export class ProjectLinker {
});
}

/**
* Gets rid of any previous game link.
*/
public async unlinkGame() {
await this.project.saveSetting(storageKey, undefined);
}

/**
* Returns the linked Interactive game if any.
*/
Expand Down
7 changes: 7 additions & 0 deletions src/server/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ export async function readFile(file: string): Promise<string> {
return promiseCallback<string>(callback => fs.readFile(file, 'utf8', callback));
}

/**
* Promisified fs.unlink
*/
export async function unlink(file: string): Promise<void> {
return promiseCallback(callback => fs.unlink(file, callback));
}

/**
* Promisified fs.writeFile
*/
Expand Down
4 changes: 4 additions & 0 deletions test/datastore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ describe('FileDataStore', () => {
expect(await exists(path.join(homedir(), '.miix', 'foo.json'))).to.be.false;
await store.saveGlobal('foo', true);
expect(await readFile(path.join(homedir(), '.miix', 'foo.json'))).to.equal('true');
await store.saveGlobal('foo', undefined);
expect(await exists(path.join(homedir(), '.miix', 'foo.json'))).to.be.false;
});

it('saves project data correctly', async () => {
Expand All @@ -50,6 +52,8 @@ describe('FileDataStore', () => {
await store.saveProject('foo', projdir(), true);
expect(await readFile(path.join(projdir(), '.miix', 'foo.json'))).to.equal('true');
expect(await readFile(path.join(projdir(), '.gitignore'))).to.equal('\n/.miix\n');
await store.saveProject('foo', projdir(), undefined);
expect(await exists(path.join(projdir(), '.miix', 'foo.json'))).to.be.false;
});

it('saves project data correctly', async () => {
Expand Down

0 comments on commit fa32666

Please sign in to comment.