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