Skip to content
117 linesCodeBlameRaw
1// The launcher's work: ask the app for its server, check that it answers,
2// go there, as the desktop app (`?app=desktop`, which takes someone signed
3// out to the sign-in page rather than the site's landing page). `?change` opens the choice of server instead. Everything it
4// asks is a command in src/bridge.rs, answered only to this page.
5(function () {
6 var sections = { connecting: byId("connecting"), offline: byId("offline"), choose: byId("choose") };
7 var info = null;
8
9 function byId(id) {
10 return document.getElementById(id);
11 }
12
13 function invoke(command, args) {
14 var core = window.__TAURI__ && window.__TAURI__.core;
15 if (core && typeof core.invoke === "function") return core.invoke(command, args || {});
16 return Promise.reject(new Error("the launcher cannot reach the app"));
17 }
18
19 function show(name) {
20 Object.keys(sections).forEach(function (key) {
21 sections[key].hidden = key !== name;
22 });
23 }
24
25 function hostOf(server) {
26 try {
27 return new URL(server).host;
28 } catch (error) {
29 return server;
30 }
31 }
32
33 function appUrl(server) {
34 try {
35 var url = new URL(server);
36 url.searchParams.set("app", "desktop");
37 return url.href;
38 } catch (error) {
39 return server;
40 }
41 }
42
43 function connect(server) {
44 show("connecting");
45 byId("connecting-text").textContent = "Connecting to " + hostOf(server) + "…";
46 invoke("reachable", { url: server })
47 .then(function (ok) {
48 if (ok) location.replace(appUrl(server));
49 else offline(server);
50 })
51 .catch(function () {
52 offline(server);
53 });
54 }
55
56 function offline(server) {
57 byId("offline-title").textContent = "Can't reach " + hostOf(server);
58 var status = byId("status-link");
59 var isDefault = hostOf(server) === "g1t.sh";
60 status.parentElement.hidden = !isDefault;
61 show("offline");
62 byId("retry").onclick = function () {
63 connect(server);
64 };
65 }
66
67 function choose(server) {
68 show("choose");
69 var input = byId("server");
70 input.value = hostOf(server) === "g1t.sh" ? "" : server;
71 byId("server-error").hidden = true;
72 input.focus();
73 }
74
75 function fail(message) {
76 var error = byId("server-error");
77 error.textContent = message;
78 error.hidden = false;
79 }
80
81 byId("change").onclick = function () {
82 choose(info ? info.server : "https://g1t.sh/");
83 };
84 byId("use-default").onclick = function () {
85 invoke("set_server", { url: "https://g1t.sh" }).then(connect, fail);
86 };
87 byId("server-form").onsubmit = function (event) {
88 event.preventDefault();
89 var typed = byId("server").value.trim();
90 if (!typed) return fail("Enter your g1t's address, or use g1t.sh.");
91 invoke("set_server", { url: typed }).then(connect, function (error) {
92 fail(typeof error === "string" ? error : "That address could not be kept.");
93 });
94 };
95 // Links out, in the system's browser (src/bridge.js handles the rest).
96 document.addEventListener("click", function (event) {
97 var anchor = event.target && event.target.closest ? event.target.closest("a[href]") : null;
98 if (!anchor) return;
99 event.preventDefault();
100 invoke("open_url", { url: anchor.href }).catch(function () {});
101 });
102
103 invoke("desktop_info")
104 .then(function (found) {
105 info = found;
106 byId("version").textContent = "g1t " + found.version;
107 if (new URLSearchParams(location.search).has("change")) choose(found.server);
108 else connect(found.server);
109 })
110 .catch(function () {
111 // No app behind the page: a browser opened the file. Nothing to do.
112 show("offline");
113 byId("offline-title").textContent = "This page belongs inside the g1t desktop app";
114 byId("retry").hidden = true;
115 byId("change").hidden = true;
116 });
117})();