version.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /**
  2. * This file is part of Threema Web.
  3. *
  4. * Threema Web is free software: you can redistribute it and/or modify it
  5. * under the terms of the GNU Affero General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or (at
  7. * your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Affero General Public License
  15. * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. export class VersionService {
  18. public static $inject = ['$log', '$http', '$mdDialog', '$translate', '$window'];
  19. private logTag: string = '[VersionService]';
  20. private $log: ng.ILogService;
  21. private $http: ng.IHttpService;
  22. private $mdDialog: ng.material.IDialogService;
  23. private $translate: ng.translate.ITranslateService;
  24. private $window: ng.IWindowService;
  25. private version: string;
  26. private dialogShowing = false;
  27. constructor($log: ng.ILogService,
  28. $http: ng.IHttpService,
  29. $mdDialog: ng.material.IDialogService,
  30. $translate: ng.translate.ITranslateService,
  31. $window: ng.IWindowService) {
  32. this.$log = $log;
  33. this.$http = $http;
  34. this.$mdDialog = $mdDialog;
  35. this.$translate = $translate;
  36. this.$window = $window;
  37. }
  38. /**
  39. * Set the version by fetching the version.txt file.
  40. */
  41. public initVersion(): void {
  42. if (this.version !== undefined) {
  43. this.checkForUpdate();
  44. return;
  45. }
  46. this.fetchVersion()
  47. .then((version: string) => {
  48. this.version = version;
  49. this.$log.info(this.logTag, 'Using Threema Web version', this.version);
  50. })
  51. .catch((error: string) => {
  52. this.$log.error(this.logTag, 'Could not fetch version.txt:', error);
  53. });
  54. }
  55. /**
  56. * Fetch the version.txt file.
  57. */
  58. private fetchVersion(): Promise<string> {
  59. return new Promise((resolve, reject) => {
  60. const cacheBust = Math.floor(Math.random() * 1000000000);
  61. this.$http({
  62. method: 'GET',
  63. url: 'version.txt?' + cacheBust,
  64. cache: false,
  65. responseType: 'text',
  66. transformResponse: (data: string, headersGetter, statusCode) => {
  67. if (statusCode !== 200) {
  68. return reject('HTTP ' + statusCode);
  69. }
  70. return data.trim();
  71. },
  72. }).then(
  73. (successResponse: ng.IHttpPromiseCallbackArg<string>) => {
  74. return resolve(successResponse.data);
  75. },
  76. (error: Error) => {
  77. return reject(error);
  78. },
  79. );
  80. });
  81. }
  82. /**
  83. * Check for a version update. If the version was updated, show a dialog.
  84. */
  85. public checkForUpdate(): void {
  86. this.$log.debug(this.logTag, 'Checking for version update...');
  87. if (this.version === undefined) {
  88. this.$log.error(this.logTag, 'Cannot check for update, version is not initialized');
  89. return;
  90. }
  91. this.fetchVersion()
  92. .then((version: string) => {
  93. if (version !== this.version) {
  94. this.$log.warn(this.logTag,
  95. 'A new version of Threema Web is available:',
  96. this.version, '->', version);
  97. this.notifyNewVersion(version);
  98. }
  99. })
  100. .catch((error: string) => {
  101. this.$log.error('Could not fetch version.txt:', error);
  102. });
  103. }
  104. /**
  105. * A new version is available!
  106. */
  107. private notifyNewVersion(version: string): void {
  108. if (this.dialogShowing === true) {
  109. // Don't show again if dialog is already showing.
  110. return;
  111. }
  112. const confirm = this.$mdDialog.alert()
  113. .title(this.$translate.instant('version.NEW_VERSION', {version: version}))
  114. .textContent(this.$translate.instant('version.NEW_VERSION_BODY', {version: version}))
  115. .ok(this.$translate.instant('common.OK'));
  116. this.dialogShowing = true;
  117. this.$mdDialog.show(confirm).then(() => {
  118. this.$window.location.reload();
  119. }, () => {
  120. this.$window.location.reload();
  121. });
  122. }
  123. }