battery.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. import {NotificationService} from './notification';
  18. export class BatteryStatusService {
  19. // Attributes
  20. private batteryStatus: threema.BatteryStatus = null;
  21. private alertedLow = false;
  22. private alertedCritical = false;
  23. // Constants
  24. private static readonly PERCENT_LOW = 20;
  25. private static readonly PERCENT_CRITICAL = 5;
  26. // Services
  27. private $translate: ng.translate.ITranslateService;
  28. private notificationService: NotificationService;
  29. public static $inject = ['$translate', 'NotificationService'];
  30. constructor($translate: ng.translate.ITranslateService, notificationService: NotificationService) {
  31. this.$translate = $translate;
  32. this.notificationService = notificationService;
  33. }
  34. /**
  35. * Update the battery status.
  36. */
  37. public setStatus(batteryStatus: threema.BatteryStatus): void {
  38. this.batteryStatus = batteryStatus;
  39. // Alert if percent drops below a certain threshold
  40. if (!batteryStatus.isCharging) {
  41. if (!this.alertedCritical && batteryStatus.percent < BatteryStatusService.PERCENT_CRITICAL) {
  42. this.notifyLevel('critical');
  43. this.alertedCritical = true;
  44. } else if (!this.alertedLow && batteryStatus.percent < BatteryStatusService.PERCENT_LOW) {
  45. this.notifyLevel('low');
  46. this.alertedLow = true;
  47. }
  48. }
  49. // Reset alert flag if percentage goes above a certain threshold
  50. const hysteresis = 3;
  51. if (this.alertedLow && batteryStatus.percent > BatteryStatusService.PERCENT_LOW + hysteresis) {
  52. this.alertedLow = false;
  53. this.notificationService.hideNotification('battery-low');
  54. }
  55. if (this.alertedCritical && batteryStatus.percent > BatteryStatusService.PERCENT_CRITICAL + hysteresis) {
  56. this.alertedCritical = false;
  57. this.notificationService.hideNotification('battery-critical');
  58. }
  59. }
  60. /**
  61. * Is battery status information available?
  62. */
  63. public get dataAvailable(): boolean {
  64. return this.batteryStatus !== null;
  65. }
  66. /**
  67. * Return the charge level in percent.
  68. */
  69. public get percent(): number {
  70. return this.batteryStatus.percent;
  71. }
  72. /**
  73. * Return whether the battery is currently charging.
  74. */
  75. public get isCharging(): boolean {
  76. return this.batteryStatus.isCharging;
  77. }
  78. /**
  79. * Return whether the battery level is low (<20%).
  80. */
  81. public get isLow(): boolean {
  82. return this.batteryStatus.percent < BatteryStatusService.PERCENT_LOW;
  83. }
  84. /**
  85. * Return whether the battery level is critical (<20%).
  86. */
  87. public get isCritical(): boolean {
  88. return this.batteryStatus.percent < BatteryStatusService.PERCENT_CRITICAL;
  89. }
  90. /**
  91. * Alert the user about a certain battery level.
  92. */
  93. private notifyLevel(level: 'low' | 'critical'): void {
  94. if (!this.notificationService.getWantsNotifications()) {
  95. // User does not want notifications.
  96. // This flag is also checked in the `showNotification` function, but
  97. // we'll return early to avoid having to do the translations and to
  98. // keep the notification sound from playing without a visible
  99. // notification.
  100. return;
  101. }
  102. const title = this.$translate.instant('common.WARNING');
  103. const avatar = 'img/ic_battery_alert-64x64.png';
  104. let tag: string;
  105. let body: string;
  106. if (level === 'low') {
  107. tag = 'battery-low';
  108. body = this.$translate.instant('battery.LEVEL_LOW', { percent: this.percent });
  109. this.notificationService.hideNotification('battery-critical');
  110. } else if (level === 'critical') {
  111. tag = 'battery-critical';
  112. body = this.$translate.instant('battery.LEVEL_CRITICAL', { percent: this.percent });
  113. this.notificationService.hideNotification('battery-low');
  114. }
  115. this.notificationService.showNotification(tag, title, body, avatar, undefined, true, true);
  116. }
  117. public toString(): string {
  118. if (this.batteryStatus === null) {
  119. return 'No data';
  120. }
  121. return this.percent + '%, ' + (this.isCharging ? 'charging' : 'discharging');
  122. }
  123. }