offline_page.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // TODO: This file was created by bulk-decaffeinate.
  2. // Sanity-check the conversion and remove this comment.
  3. /*
  4. * decaffeinate suggestions:
  5. * DS002: Fix invalid constructor
  6. * DS101: Remove unnecessary use of Array.from
  7. * DS102: Remove unnecessary code created because of implicit returns
  8. * DS206: Consider reworking classes to avoid initClass
  9. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
  10. */
  11. app.views.OfflinePage = class OfflinePage extends app.View {
  12. constructor(...args) {
  13. this.onClick = this.onClick.bind(this);
  14. super(...args);
  15. }
  16. static initClass() {
  17. this.className = "_static";
  18. this.events = {
  19. click: "onClick",
  20. change: "onChange",
  21. };
  22. }
  23. deactivate() {
  24. if (super.deactivate(...arguments)) {
  25. this.empty();
  26. }
  27. }
  28. render() {
  29. if (app.cookieBlocked) {
  30. this.html(this.tmpl("offlineError", "cookie_blocked"));
  31. return;
  32. }
  33. app.docs.getInstallStatuses((statuses) => {
  34. if (!this.activated) {
  35. return;
  36. }
  37. if (statuses === false) {
  38. this.html(this.tmpl("offlineError", app.db.reason, app.db.error));
  39. } else {
  40. let html = "";
  41. for (var doc of Array.from(app.docs.all())) {
  42. html += this.renderDoc(doc, statuses[doc.slug]);
  43. }
  44. this.html(this.tmpl("offlinePage", html));
  45. this.refreshLinks();
  46. }
  47. });
  48. }
  49. renderDoc(doc, status) {
  50. return app.templates.render("offlineDoc", doc, status);
  51. }
  52. getTitle() {
  53. return "Offline";
  54. }
  55. refreshLinks() {
  56. for (var action of ["install", "update", "uninstall"]) {
  57. this.find(`[data-action-all='${action}']`).classList[
  58. this.find(`[data-action='${action}']`) ? "add" : "remove"
  59. ]("_show");
  60. }
  61. }
  62. docByEl(el) {
  63. let slug;
  64. while (!(slug = el.getAttribute("data-slug"))) {
  65. el = el.parentNode;
  66. }
  67. return app.docs.findBy("slug", slug);
  68. }
  69. docEl(doc) {
  70. return this.find(`[data-slug='${doc.slug}']`);
  71. }
  72. onRoute(context) {
  73. this.render();
  74. }
  75. onClick(event) {
  76. let action;
  77. let el = $.eventTarget(event);
  78. if ((action = el.getAttribute("data-action"))) {
  79. const doc = this.docByEl(el);
  80. if (action === "update") {
  81. action = "install";
  82. }
  83. doc[action](
  84. this.onInstallSuccess.bind(this, doc),
  85. this.onInstallError.bind(this, doc),
  86. this.onInstallProgress.bind(this, doc),
  87. );
  88. el.parentNode.innerHTML = `${el.textContent.replace(/e$/, "")}ing…`;
  89. } else if (
  90. (action =
  91. el.getAttribute("data-action-all") ||
  92. el.parentElement.getAttribute("data-action-all"))
  93. ) {
  94. if (action === "uninstall" && !window.confirm("Uninstall all docs?")) {
  95. return;
  96. }
  97. app.db.migrate();
  98. for (el of Array.from(this.findAll(`[data-action='${action}']`))) {
  99. $.click(el);
  100. }
  101. }
  102. }
  103. onInstallSuccess(doc) {
  104. if (!this.activated) {
  105. return;
  106. }
  107. doc.getInstallStatus((status) => {
  108. let el;
  109. if (!this.activated) {
  110. return;
  111. }
  112. if ((el = this.docEl(doc))) {
  113. el.outerHTML = this.renderDoc(doc, status);
  114. $.highlight(el, { className: "_highlight" });
  115. this.refreshLinks();
  116. }
  117. });
  118. }
  119. onInstallError(doc) {
  120. let el;
  121. if (!this.activated) {
  122. return;
  123. }
  124. if ((el = this.docEl(doc))) {
  125. el.lastElementChild.textContent = "Error";
  126. }
  127. }
  128. onInstallProgress(doc, event) {
  129. let el;
  130. if (!this.activated || !event.lengthComputable) {
  131. return;
  132. }
  133. if ((el = this.docEl(doc))) {
  134. const percentage = Math.round((event.loaded * 100) / event.total);
  135. el.lastElementChild.textContent = el.lastElementChild.textContent.replace(
  136. /(\s.+)?$/,
  137. ` (${percentage}%)`,
  138. );
  139. }
  140. }
  141. onChange(event) {
  142. if (event.target.name === "autoUpdate") {
  143. app.settings.set("manualUpdate", !event.target.checked);
  144. }
  145. }
  146. };
  147. app.views.OfflinePage.initClass();