Skip to content

Commit cea850a

Browse files
feat: add publishGistAsRevision() (#1177)
* feat: add publishGistAsRevision() * chore: add tests to make sure state changes * chore: rename for clarity * chore: update snapshots * chore: add additional test * chore: add param to test * chore: refactor const to private static * chore: update snap * chore: update snap * chore: modify snapshot * chore: fix package.json uploaded as revision * fix * chore: remove log Co-authored-by: Erick Zhao <[email protected]>
1 parent 4b99acc commit cea850a

File tree

8 files changed

+130
-12
lines changed

8 files changed

+130
-12
lines changed

src/renderer/components/commands-action-button.tsx

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
import { IpcEvents } from '../../ipc-events';
2323
import { ensureRequiredFiles } from '../../utils/editor-utils';
2424
import { getOctokit } from '../../utils/octokit';
25+
import { getTemplate } from '../content';
2526
import { ipcRendererManager } from '../ipc';
2627
import { AppState } from '../state';
2728

@@ -120,18 +121,32 @@ export const GistActionButton = observer(
120121
const octo = await getOctokit(appState);
121122
const { gitHubPublishAsPublic } = appState;
122123
const options = { includeDependencies: true, includeElectron: true };
123-
const values = await window.ElectronFiddle.app.getEditorValues(options);
124+
const defaultGistValues = await getTemplate(appState.version);
125+
const currentEditorValues = await window.ElectronFiddle.app.getEditorValues(
126+
options,
127+
);
128+
129+
defaultGistValues['package.json'] = currentEditorValues['package.json'];
124130

125131
try {
132+
const gistFilesList = appState.isPublishingGistAsRevision
133+
? this.gistFilesList(defaultGistValues)
134+
: this.gistFilesList(currentEditorValues);
135+
136+
// TODO: remove as any when octo is fixed
126137
const gist = await octo.gists.create({
127138
public: !!gitHubPublishAsPublic,
128139
description,
129-
files: this.gistFilesList(values) as any, // Note: GitHub messed up, GistsCreateParamsFiles is an incorrect interface
140+
files: gistFilesList as any, // Note: GitHub messed up, GistsCreateParamsFiles is an incorrect interface
130141
});
131142

132143
appState.gistId = gist.data.id;
133144
appState.localPath = undefined;
134145

146+
if (appState.isPublishingGistAsRevision) {
147+
await this.handleUpdate(appState.isPublishingGistAsRevision);
148+
}
149+
135150
console.log(`Publish Button: Publishing complete`, { gist });
136151
this.renderToast({
137152
message: 'Successfully published gist!',
@@ -179,8 +194,9 @@ export const GistActionButton = observer(
179194

180195
/**
181196
* Update an existing GitHub gist.
197+
* silently updates the gist when publishing as a revision
182198
*/
183-
public async handleUpdate() {
199+
public async handleUpdate(silent = false) {
184200
const { appState } = this.props;
185201
const octo = await getOctokit(this.props.appState);
186202
const options = { includeDependencies: true, includeElectron: true };
@@ -206,14 +222,17 @@ export const GistActionButton = observer(
206222

207223
appState.editorMosaic.isEdited = false;
208224
console.log('Updating: Updating done', { gist });
209-
this.renderToast({
210-
message: 'Successfully updated gist!',
211-
action: {
212-
text: 'Copy link',
213-
icon: 'clipboard',
214-
onClick: () => clipboard.writeText(gist.data.html_url),
215-
},
216-
});
225+
226+
if (!silent) {
227+
this.renderToast({
228+
message: 'Successfully updated gist!',
229+
action: {
230+
text: 'Copy link',
231+
icon: 'clipboard',
232+
onClick: () => clipboard.writeText(gist.data.html_url),
233+
},
234+
});
235+
}
217236
} catch (error) {
218237
console.warn(`Could not update gist`, { error });
219238

src/renderer/components/settings-general-github.tsx

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22

3-
import { Button, Callout } from '@blueprintjs/core';
3+
import { Button, Callout, Checkbox, FormGroup } from '@blueprintjs/core';
44
import { observer } from 'mobx-react';
55

66
import { AppState } from '../state';
@@ -21,8 +21,15 @@ export const GitHubSettings = observer(
2121
super(props);
2222

2323
this.signIn = this.signIn.bind(this);
24+
this.handlePublishGistAsRevisionChange = this.handlePublishGistAsRevisionChange.bind(
25+
this,
26+
);
2427
}
2528

29+
private static publishGistAsRevisionInstructions = `
30+
Enable this option to always publish your fiddle as a revision of the
31+
default fiddle gist values.`.trim();
32+
2633
/**
2734
* Render the "logged out" settings experience.
2835
*
@@ -61,8 +68,22 @@ export const GitHubSettings = observer(
6168
);
6269
}
6370

71+
/**
72+
* Handles a change on whether or not the gist should be published
73+
* as a revision on top of the default fiddle gist.
74+
*
75+
* @param {React.FormEvent<HTMLInputElement>} event
76+
*/
77+
public handlePublishGistAsRevisionChange(
78+
event: React.FormEvent<HTMLInputElement>,
79+
) {
80+
const { checked } = event.currentTarget;
81+
this.props.appState.isPublishingGistAsRevision = checked;
82+
}
83+
6484
public render() {
6585
const { gitHubToken } = this.props.appState;
86+
const { isPublishingGistAsRevision } = this.props.appState;
6687

6788
const maybeSignedIn = !!gitHubToken
6889
? this.renderSignedIn()
@@ -72,6 +93,16 @@ export const GitHubSettings = observer(
7293
<div>
7394
<h4>GitHub</h4>
7495
{maybeSignedIn}
96+
<Callout>
97+
<FormGroup>
98+
<p>{GitHubSettings.publishGistAsRevisionInstructions}</p>
99+
<Checkbox
100+
checked={isPublishingGistAsRevision}
101+
label="Publish as revision."
102+
onChange={this.handlePublishGistAsRevisionChange}
103+
/>
104+
</FormGroup>
105+
</Callout>
75106
</div>
76107
);
77108
}

src/renderer/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ export const CONFIG_PATH = path.join(
1313

1414
export const ELECTRON_ORG = 'electron';
1515
export const ELECTRON_REPO = 'electron';
16+
17+
export const FIDDLE_GIST_DESCRIPTION_PLACEHOLDER = 'Electron Fiddle Gist';

src/renderer/state.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ export class AppState {
9191
);
9292
public isClearingConsoleOnRun = !!this.retrieve('isClearingConsoleOnRun');
9393
public isUsingSystemTheme = !!(this.retrieve('isUsingSystemTheme') ?? true);
94+
public isPublishingGistAsRevision = !!(
95+
this.retrieve('isPublishingGistAsRevision') ?? true
96+
);
9497
public executionFlags: Array<string> =
9598
(this.retrieve('executionFlags') as Array<string>) === null
9699
? []
@@ -219,6 +222,7 @@ export class AppState {
219222
isInstallingModules: observable,
220223
isKeepingUserDataDirs: observable,
221224
isOnline: observable,
225+
isPublishingGistAsRevision: observable,
222226
isQuitting: observable,
223227
isRunning: observable,
224228
isSettingsShowing: observable,
@@ -330,6 +334,9 @@ export class AppState {
330334
this.save('isClearingConsoleOnRun', this.isClearingConsoleOnRun),
331335
);
332336
autorun(() => this.save('isUsingSystemTheme', this.isUsingSystemTheme));
337+
autorun(() =>
338+
this.save('isPublishingGistAsRevision', this.isPublishingGistAsRevision),
339+
);
333340
autorun(() => this.save('gitHubAvatarUrl', this.gitHubAvatarUrl));
334341
autorun(() => this.save('gitHubLogin', this.gitHubLogin));
335342
autorun(() => this.save('gitHubName', this.gitHubName));

tests/mocks/state.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export class StateMock {
3838
public isEnablingElectronLogging = false;
3939
public isGenericDialogShowing = false;
4040
public isInstallingModules = false;
41+
public isPublishingGistAsRevision = true;
4142
public isOnline = true;
4243
public isQuitting = false;
4344
public isRunning = false;
@@ -130,6 +131,7 @@ export class StateMock {
130131
isGenericDialogShowing: observable,
131132
isInstallingModules: observable,
132133
isOnline: observable,
134+
isPublishingGistAsRevision: observable,
133135
isQuitting: observable,
134136
isRunning: observable,
135137
isSettingsShowing: observable,

tests/renderer/components/__snapshots__/settings-general-github-spec.tsx.snap

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ exports[`GitHubSettings component renders when not signed in 1`] = `
1515
text="Sign in"
1616
/>
1717
</Blueprint3.Callout>
18+
<Blueprint3.Callout>
19+
<Blueprint3.FormGroup>
20+
<p>
21+
Enable this option to always publish your fiddle as a revision of the
22+
default fiddle gist values.
23+
</p>
24+
<Blueprint3.Checkbox
25+
checked={true}
26+
label="Publish as revision."
27+
onChange={[Function]}
28+
/>
29+
</Blueprint3.FormGroup>
30+
</Blueprint3.Callout>
1831
</div>
1932
`;
2033

@@ -38,5 +51,18 @@ exports[`GitHubSettings component renders when signed in 1`] = `
3851
text="Sign out"
3952
/>
4053
</Blueprint3.Callout>
54+
<Blueprint3.Callout>
55+
<Blueprint3.FormGroup>
56+
<p>
57+
Enable this option to always publish your fiddle as a revision of the
58+
default fiddle gist values.
59+
</p>
60+
<Blueprint3.Checkbox
61+
checked={true}
62+
label="Publish as revision."
63+
onChange={[Function]}
64+
/>
65+
</Blueprint3.FormGroup>
66+
</Blueprint3.Callout>
4167
</div>
4268
`;

tests/renderer/components/commands-publish-button-spec.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ describe('Action button component', () => {
124124
beforeEach(() => {
125125
// create a button that's primed to publish a new gist
126126
({ instance } = createActionButton());
127+
state.isPublishingGistAsRevision = false;
127128
});
128129

129130
it('publishes a gist', async () => {
@@ -175,6 +176,17 @@ describe('Action button component', () => {
175176
const expected = { ...expectedGistOpts, files };
176177
expect(mocktokit.gists.create).toHaveBeenCalledWith(expected);
177178
});
179+
180+
it('calls update() if isPublishingGistAsRevision is true', async () => {
181+
state.isPublishingGistAsRevision = true;
182+
state.showInputDialog = jest.fn().mockResolvedValueOnce(description);
183+
184+
const { instance } = createActionButton();
185+
const spy = jest.spyOn(instance, 'handleUpdate');
186+
187+
await instance.performGistAction();
188+
expect(spy).toHaveBeenCalledWith(true);
189+
});
178190
});
179191

180192
it('handles an error in Gist publishing', async () => {

tests/renderer/components/settings-general-github-spec.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,23 @@ describe('GitHubSettings component', () => {
3131
wrapper.childAt(1).childAt(1).simulate('click');
3232
expect(store.isTokenDialogShowing).toBe(true);
3333
});
34+
35+
describe('Gist publish as revision component', () => {
36+
it('state changes', async () => {
37+
const wrapper = shallow(<GitHubSettings appState={store as any} />);
38+
const instance = wrapper.instance() as any;
39+
40+
await instance.handlePublishGistAsRevisionChange({
41+
currentTarget: { checked: false },
42+
});
43+
44+
expect(store.isPublishingGistAsRevision).toBe(false);
45+
46+
await instance.handlePublishGistAsRevisionChange({
47+
currentTarget: { checked: true },
48+
});
49+
50+
expect(store.isPublishingGistAsRevision).toBe(true);
51+
});
52+
});
3453
});

0 commit comments

Comments
 (0)