mediabox.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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 {saveAs} from 'file-saver';
  18. import {bufferToUrl, logAdapter} from '../helpers';
  19. import {MediaboxService} from '../services/mediabox';
  20. export default [
  21. '$rootScope',
  22. '$document',
  23. '$log',
  24. 'MediaboxService',
  25. function($rootScope: ng.IRootScopeService,
  26. $document: ng.IDocumentService,
  27. $log: ng.ILogService,
  28. mediaboxService: MediaboxService) {
  29. return {
  30. restrict: 'E',
  31. scope: {},
  32. bindToController: {},
  33. controllerAs: 'ctrl',
  34. controller: [function() {
  35. this.logTag = '[MediaboxDirective]';
  36. // Data attributes
  37. this.imageDataUrl = null;
  38. this.caption = '';
  39. // Close and save
  40. this.close = ($event?: Event) => {
  41. if ($event !== undefined) {
  42. // If this was triggered by a click event, only close the box
  43. // if the click was directly on the target element.
  44. if ($event.target === $event.currentTarget) {
  45. this.imageDataUrl = null;
  46. }
  47. } else {
  48. this.imageDataUrl = null;
  49. }
  50. };
  51. this.save = () => {
  52. saveAs(new Blob([mediaboxService.data]), mediaboxService.filename || 'image.jpg');
  53. };
  54. // Listen to Mediabox service events
  55. mediaboxService.evtMediaChanged.attach((dataAvailable: boolean) => {
  56. $rootScope.$apply(() => {
  57. if (dataAvailable) {
  58. this.imageDataUrl = bufferToUrl(
  59. mediaboxService.data,
  60. mediaboxService.mimetype,
  61. logAdapter($log.debug, this.logTag),
  62. );
  63. this.caption = mediaboxService.caption || mediaboxService.filename;
  64. } else {
  65. this.close();
  66. }
  67. });
  68. });
  69. }],
  70. link($scope: any, $element: ng.IAugmentedJQuery, attrs) {
  71. // Register event handler for ESC key
  72. $document.on('keyup', (e: Event) => {
  73. const ke = e as KeyboardEvent;
  74. if (ke.key === 'Escape' && $scope.ctrl.imageDataUrl !== null) {
  75. $scope.$apply($scope.ctrl.close);
  76. }
  77. });
  78. },
  79. // tslint:disable:max-line-length
  80. template: `
  81. <div class="box" ng-if="ctrl.imageDataUrl !== null">
  82. <md-icon class="save material-icons md-24" ng-click="ctrl.save()" aria-label="Save" translate-attr="{'aria-label': 'common.SAVE', 'title': 'common.SAVE'}">save</md-icon>
  83. <md-icon class="close material-icons md-24" ng-click="ctrl.close()" aria-label="Close" translate-attr="{'aria-label': 'common.CLOSE', 'title': 'common.CLOSE'}">close</md-icon>
  84. <div class="inner" ng-click="ctrl.close($event)">
  85. <img ng-src="{{ ctrl.imageDataUrl }}">
  86. <div class="caption" title="{{ ctrl.caption | escapeHtml}}">
  87. <span ng-bind-html="ctrl.caption | escapeHtml | markify | emojify"></span>
  88. </div>
  89. </div>
  90. </div>
  91. `,
  92. };
  93. },
  94. ];