Skip to content

Commit edef335

Browse files
committed
feat: expose URL
1 parent 4c97d7e commit edef335

5 files changed

Lines changed: 125 additions & 25 deletions

File tree

src/messages/project/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ export {ProjectOpenRequest} from "./project-open-request";
2020
export {ProjectScreenshotRequest} from "./project-screenshot-request";
2121
export {ProjectScreenshotNotification} from "./project-screenshot-notification";
2222
export {ProjectUnlistRequest} from "./project-unlist-request";
23+
export {ProjectUrlRequest} from "./project-url-request";
24+
export {ProjectUrlResponse} from "./project-url-response";
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {Message} from "../message";
2+
3+
export class ProjectUrlRequest extends Message {
4+
static is(input: any) {
5+
return input instanceof ProjectUrlRequest;
6+
}
7+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {Message} from "../message";
2+
3+
export class ProjectUrlResponse extends Message {
4+
public readonly url: string;
5+
6+
static is(input: any) {
7+
return input instanceof ProjectUrlResponse;
8+
}
9+
10+
constructor(tid: string, url: string) {
11+
super(tid);
12+
this.url = url;
13+
}
14+
};

src/renderer/index.tsx

Lines changed: 88 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ async function main() {
8383

8484
match(Msg.UI.ContextMenuResponse, () => {
8585
const project: ProjectViewModel = message.project;
86-
const items = selectItems(project, {userData});
86+
const items = selectItems(project, { userData });
8787
const menu = electron.remote.Menu.buildFromTemplate(items as any);
8888

8989
menu.popup(window, {
@@ -96,10 +96,12 @@ async function main() {
9696

9797
requestOAuthToken(message.url)
9898
.then(response => {
99-
projects.broadcast(new Msg.VCS.VCSCredentialAnswer(message.tid, {
100-
host: parsed.host as string,
101-
token: response.access_token
102-
}))
99+
projects.broadcast(
100+
new Msg.VCS.VCSCredentialAnswer(message.tid, {
101+
host: parsed.host as string,
102+
token: response.access_token
103+
})
104+
);
103105
})
104106
.catch(err => {
105107
console.log(err);
@@ -134,13 +136,13 @@ async function main() {
134136

135137
switch (message.type) {
136138
case "checking-for-update":
137-
return app.setUpdateState(AppUpdatesState.Checking)
139+
return app.setUpdateState(AppUpdatesState.Checking);
138140
case "update-available":
139141
return app.setUpdateState(AppUpdatesState.Available);
140142
case "update-not-available": {
141143
app.setUpdateState(AppUpdatesState.Unavailable);
142144
setTimeout(() => {
143-
return app.setUpdateState(AppUpdatesState.Unknown)
145+
return app.setUpdateState(AppUpdatesState.Unknown);
144146
}, 3000);
145147
return;
146148
}
@@ -187,7 +189,13 @@ async function main() {
187189

188190
try {
189191
ReactDOM.render(
190-
<Provider app={app} start={start} projects={projects} paths={{userData}} port={port}>
192+
<Provider
193+
app={app}
194+
start={start}
195+
projects={projects}
196+
paths={{ userData }}
197+
port={port}
198+
>
191199
<App />
192200
</Provider>,
193201
el
@@ -200,7 +208,13 @@ async function main() {
200208
module.hot.accept("./app", () => {
201209
const NextApp = require("./app").App;
202210
ReactDOM.render(
203-
<Provider app={app} start={start} projects={projects} paths={{userData}} port={port}>
211+
<Provider
212+
app={app}
213+
start={start}
214+
projects={projects}
215+
paths={{ userData }}
216+
port={port}
217+
>
204218
<NextApp />
205219
</Provider>,
206220
el
@@ -234,7 +248,13 @@ function requestOAuthToken(url: string): Promise<OAuthResponse> {
234248
const hostConfig = config.oauth.find(h => h.hostname == parsed.hostname);
235249

236250
if (!hostConfig) {
237-
return Promise.reject(new Error(`Could not authenticate at ${parsed.hostname} via https, please use SSH instead.`));
251+
return Promise.reject(
252+
new Error(
253+
`Could not authenticate at ${
254+
parsed.hostname
255+
} via https, please use SSH instead.`
256+
)
257+
);
238258
}
239259

240260
const state = uuid.v4();
@@ -256,7 +276,11 @@ function requestOAuthToken(url: string): Promise<OAuthResponse> {
256276
.perform(win)
257277
.then((response: OAuthResponse) => {
258278
if (response.state !== state) {
259-
return Promise.reject(new Error(`Authentication at ${parsed.hostname}, states did not match.`));
279+
return Promise.reject(
280+
new Error(
281+
`Authentication at ${parsed.hostname}, states did not match.`
282+
)
283+
);
260284
}
261285

262286
clearTimeout(showTimeout);
@@ -270,15 +294,19 @@ function requestOAuthToken(url: string): Promise<OAuthResponse> {
270294
});
271295
}
272296

273-
const selectItems = (project: ProjectViewModel, paths: {userData: string}): any[] => {
297+
const selectItems = (
298+
project: ProjectViewModel,
299+
paths: { userData: string }
300+
): any[] => {
274301
if (project.editable) {
275302
return [
276303
{
277304
label: "Save",
278-
click: () => project.save({
279-
basePath: paths.userData,
280-
autoStart: true
281-
})
305+
click: () =>
306+
project.save({
307+
basePath: paths.userData,
308+
autoStart: true
309+
})
282310
},
283311
{
284312
label: "Discard",
@@ -308,17 +336,35 @@ const selectItems = (project: ProjectViewModel, paths: {userData: string}): any[
308336
type: "separator"
309337
},
310338
!project.inTransition() &&
311-
!project.isWorking() && {
312-
label: "Sync",
313-
click: () => project.sync()
314-
},
339+
!project.isWorking() && {
340+
label: "Sync",
341+
click: () => project.sync()
342+
},
315343
{
316344
type: "separator"
317345
},
318346
{
319347
label: "Reveal in Finder",
320348
click: () => electron.remote.shell.openItem(project.path)
321349
},
350+
project.isStarted() && {
351+
label: "Reveal in Browser",
352+
click: () => {
353+
const tid = uuid.v4();
354+
355+
project.up.subscribe((message: any) => {
356+
if (message.tid !== tid) {
357+
return;
358+
}
359+
360+
Msg.match(message)(Msg.Project.ProjectUrlResponse, () => {
361+
electron.remote.shell.openExternal(message.url)
362+
});
363+
});
364+
365+
project.down.next(new Msg.Project.ProjectUrlRequest(tid));
366+
}
367+
},
322368
{
323369
type: "separator"
324370
},
@@ -330,13 +376,31 @@ const selectItems = (project: ProjectViewModel, paths: {userData: string}): any[
330376
label: "Copy Git",
331377
click: () => electron.clipboard.writeText(project.url)
332378
},
379+
project.isStarted() && {
380+
label: "Copy URL",
381+
click: () => {
382+
const tid = uuid.v4();
383+
384+
project.up.subscribe((message: any) => {
385+
if (message.tid !== tid) {
386+
return;
387+
}
388+
389+
Msg.match(message)(Msg.Project.ProjectUrlResponse, () => {
390+
electron.clipboard.writeText(message.url);
391+
});
392+
});
393+
394+
project.down.next(new Msg.Project.ProjectUrlRequest(tid));
395+
}
396+
},
333397
{
334398
type: "separator"
335399
},
336400
!project.isWorking() &&
337-
!project.inTransition() && {
338-
label: "Remove",
339-
click: () => project.unlist()
340-
},
401+
!project.inTransition() && {
402+
label: "Remove",
403+
click: () => project.unlist()
404+
}
341405
].filter(Boolean);
342406
};

src/renderer/views/webview.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,20 @@ export class WebView extends React.Component<WebViewProps> {
1919
ref?: any;
2020

2121
componentDidMount() {
22-
if (this.ref) {
22+
this.props.project.down.subscribe((message: any) => {
23+
if (this.ref === null) {
24+
return;
25+
}
26+
27+
const match = Msg.match(message);
28+
29+
match(Msg.Project.ProjectUrlRequest, () => {
30+
const resp = new Msg.Project.ProjectUrlResponse(message.tid, this.ref.getURL());
31+
this.props.project.up.next(resp);
32+
});
33+
});
34+
35+
if (this.ref !== null) {
2336
const tid = uuid.v4();
2437
this.props.project.up.next(new Msg.Project.ProjectOpenNotification(tid, this.props.project.id));
2538

0 commit comments

Comments
 (0)