text-input-dialog.html 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html">
  2. <link rel="import" href="../../bower_components/paper-button/paper-button.html">
  3. <link rel="import" href="../../bower_components/neon-animation/animations/scale-up-animation.html">
  4. <link rel="import" href="../../bower_components/neon-animation/animations/fade-out-animation.html">
  5. <link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
  6. <link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html">
  7. <link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
  8. <link rel="import" href="linkify.html">
  9. <link rel="import" href="clipboard-behavior.html">
  10. <link rel="import" href="../sound-notification/sound-notification-behavior.html">
  11. <dom-module id="text-input-dialog">
  12. <template>
  13. <style>
  14. :host {
  15. display: block;
  16. }
  17. #sendDialog,
  18. #receiveDialog {
  19. width: 324px;
  20. z-index: 101;
  21. max-height: 320px;
  22. overflow: hidden;
  23. margin: 16px;
  24. }
  25. @media all and (max-height: 600px) {
  26. #sendDialog {
  27. padding-top: 24px;
  28. top: 0px !important;
  29. }
  30. }
  31. #receivedText {
  32. word-break: break-all;
  33. word-break: break-word;
  34. }
  35. paper-textarea {
  36. max-height: 200px;
  37. width: calc(100% - 48px);
  38. overflow-x: hidden;
  39. overflow-y: auto;
  40. }
  41. #receivedText {
  42. max-height: 200px;
  43. overflow: hidden;
  44. width: calc(100% - 48px);
  45. text-overflow: ellipsis;
  46. -webkit-line-clamp: 9;
  47. clamp: 9;
  48. }
  49. </style>
  50. <paper-dialog id="sendDialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop modal>
  51. <h2>Send Text</h2>
  52. <paper-textarea id="textInput" label="Enter Text" value="{{textToSend}}" autofocus></paper-textarea>
  53. <div class="buttons">
  54. <paper-button dialog-dismiss>Discard</paper-button>
  55. <paper-button dialog-dismiss on-tap="_send">Send</paper-button>
  56. </div>
  57. </paper-dialog>
  58. <paper-dialog id="receiveDialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop modal>
  59. <h2>Text Received</h2>
  60. <div>
  61. <div id="receivedText">
  62. </div>
  63. </div>
  64. <div class="buttons">
  65. <paper-button dialog-dismiss>Close</paper-button>
  66. <paper-button on-tap="_copy" autofocus hidden$="{{!clipboardSupported}}">Copy</paper-button>
  67. <a href="tel:{{tel}}" hidden$="{{!tel}}">
  68. <paper-button autofocus dialog-dismiss>Call</paper-button>
  69. </a>
  70. <a href="{{url}}" hidden$="{{!url}}" target="_blank">
  71. <paper-button autofocus dialog-dismiss>Open</paper-button>
  72. </a>
  73. </div>
  74. </paper-dialog>
  75. </template>
  76. <script>
  77. 'use strict';
  78. (function() {
  79. /*
  80. *
  81. * /^\+?[0-9x]*$/ is the first usuful Text sent via Snapdrop 2015/1/2 5:30
  82. *
  83. */
  84. var phoneNumbers = /^\+?[0-9x/ ]*$/;
  85. var urls = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/;
  86. Polymer({
  87. is: 'text-input-dialog',
  88. behaviors: [Chat.ClipboardBehavior, Chat.SoundNotificationBehavior],
  89. properties: {
  90. textToSend: {
  91. type: String
  92. },
  93. receivedText: {
  94. type: String
  95. },
  96. contact: {
  97. type: Object
  98. },
  99. tel: {
  100. computed: '_isPhoneNumber(receivedText)',
  101. value: false
  102. },
  103. url: {
  104. computed: '_isUrl(receivedText)',
  105. value: false
  106. },
  107. clipboardSupported: {
  108. value: false
  109. },
  110. fallback: {
  111. computed: '_isFallback(url,tel,clipboardSupported)',
  112. value: false
  113. }
  114. },
  115. open: function(contact) {
  116. this.contact = contact;
  117. this.$.sendDialog.open();
  118. },
  119. attached: function() {
  120. // clipboard must be initalized by user interaction
  121. var that = this;
  122. var hackListener = function() {
  123. document.body.removeEventListener('touchstart', hackListener, false);
  124. document.body.removeEventListener('click', hackListener, false);
  125. // wait 1s to tell the ui that copy is supported
  126. that.async(function() {
  127. that.clipboardSupported = document.queryCommandSupported && document.queryCommandSupported('copy');
  128. }, 1000);
  129. };
  130. document.body.addEventListener('touchstart', hackListener, false);
  131. document.body.addEventListener('click', hackListener, false);
  132. this.async(function() {
  133. app.conn.addEventListener('text-received', function(e) {
  134. var receivedText = e.detail.text;
  135. if (!receivedText || receivedText.trim() === '') {
  136. this.playSound();
  137. return;
  138. }
  139. this.receivedText = receivedText;
  140. this.$.receivedText.textContent = receivedText;
  141. window.linkifyElement(this.$.receivedText, {}, document);
  142. this.$.receiveDialog.open();
  143. this.playSound();
  144. }.bind(this), false);
  145. }, 200);
  146. this.$.textInput.addEventListener('keypress', function(e) {
  147. if (e.which === 13 || e.charCode === 13) {
  148. var key;
  149. var isShift;
  150. if (window.event) {
  151. key = window.event.keyCode;
  152. isShift = !!window.event.shiftKey; // typecast to boolean
  153. } else {
  154. key = e.which;
  155. isShift = !!e.shiftKey;
  156. }
  157. if (!isShift) {
  158. e.preventDefault();
  159. e.stopPropagation();
  160. this._send();
  161. }
  162. }
  163. }.bind(this), false);
  164. },
  165. _send: function() {
  166. this.$.sendDialog.close();
  167. app.conn.sendText(this.contact.peerId, this.textToSend);
  168. },
  169. _copy: function() {
  170. this.copyToClipboard(this.receivedText);
  171. this.$.receiveDialog.close();
  172. console.log('text copied', this.receivedText);
  173. },
  174. _isPhoneNumber: function(text) {
  175. if (!text || text.length < 5 || text.length > 100) {
  176. return false;
  177. }
  178. if (phoneNumbers.test(text)) {
  179. return text;
  180. }
  181. },
  182. _isUrl: function(text) {
  183. if (!text) {
  184. return false;
  185. }
  186. if (urls.test(text)) {
  187. return text;
  188. }
  189. },
  190. _isFallback: function(url, tel, clipboardSupported) {
  191. return (!url && !tel && !clipboardSupported);
  192. }
  193. });
  194. }());
  195. </script>
  196. </dom-module>