MessageCreate.coffee 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. class MessageCreate extends Class
  2. constructor: ->
  3. @subject = ""
  4. @body = ""
  5. @minimized = true
  6. @sending = false
  7. @just_sent = false
  8. @user_address = {} # Username -> address
  9. @update_usernames = true
  10. @field_to = new Autocomplete @getUsernames, {type: "text", placeholder: "Username", value: ""}
  11. @node = null # Html node of messageCreate
  12. @property 'to',
  13. get: -> @field_to.attrs.value
  14. set: (to) -> @field_to.setValue(to)
  15. isEmpty: =>
  16. return not (@body + @subject + @to)
  17. isFilled: =>
  18. return (@body != "" and @subject != "" and @to != "" and Page.user.data)
  19. setNode: (node) =>
  20. @node = node
  21. setReplyDetails: =>
  22. current_message = Page.message_lists.message_active
  23. if current_message.row.folder == "sent"
  24. @to = current_message.row.to.replace("@zeroid.bit", "")
  25. else
  26. @to = current_message.row.from.replace("@zeroid.bit", "")
  27. @subject = "Re: " + current_message.row.subject.replace("Re: ", "")
  28. getUsernames: =>
  29. return (username.replace("@zeroid.bit", "") for username, address of @user_address)
  30. getTitle: =>
  31. if @just_sent
  32. title = "Message sent!"
  33. else if @isEmpty()
  34. if Page.message_lists.message_active
  35. title = "Reply to this message"
  36. else
  37. title = "New message"
  38. else
  39. if @subject.startsWith "Re:"
  40. title = "Reply to message"
  41. else
  42. title = "New message"
  43. return title
  44. updateUsernames: ->
  45. @update_usernames = false
  46. Page.users.getAll (user_address) =>
  47. @user_address = user_address
  48. show: (to, subject, body) =>
  49. if to then @to = to
  50. if subject then @subject = subject
  51. if body then @body = body
  52. @minimized = false
  53. document.body.classList.add("MessageCreate-opened")
  54. # Set focus to first empty field
  55. if not @to then @node.querySelector(".to").focus()
  56. else if not @subject then @node.querySelector(".subject").focus()
  57. else if not @body then @node.querySelector(".body").focus()
  58. if @update_usernames then @updateUsernames()
  59. return false
  60. hide: =>
  61. document.body.classList.remove("MessageCreate-opened")
  62. @minimized = true
  63. handleTitleClick: (e) =>
  64. e.cancelBubble = true
  65. if @minimized
  66. # Set reply default values
  67. if @isEmpty() and Page.message_lists.message_active
  68. @setReplyDetails()
  69. @show()
  70. else
  71. @hide()
  72. return false
  73. handleCloseClick: (e) =>
  74. e.cancelBubble = true
  75. @hide()
  76. @to = ""
  77. @subject = ""
  78. @body = ""
  79. return false
  80. handleInput: (e) =>
  81. @[e.target.name] = e.target.value
  82. return false
  83. handleSendClick: (e) =>
  84. to = @to
  85. if to.indexOf("@") == -1
  86. to += "@zeroid.bit"
  87. if not @user_address[to]
  88. to = ""
  89. @node.querySelector(".to").focus()
  90. return false
  91. # Text-hiding animation
  92. Animation.scramble @node.querySelector(".to")
  93. Animation.scramble @node.querySelector(".subject")
  94. Animation.scramble @node.querySelector(".body")
  95. @sending = true
  96. Page.user.getSecret @user_address[to], (aes_key) =>
  97. if not aes_key
  98. # User's publickey not found
  99. @sending = false
  100. return false
  101. message = {"subject": @subject, "body": @body, "to": to}
  102. @log "Sending", message
  103. Page.cmd "aesEncrypt", [Text.jsonEncode(message), aes_key], (res) =>
  104. [aes_key, iv, encrypted] = res
  105. Page.user.data.message[Page.user.getNewIndex("message")] = iv+","+encrypted
  106. Page.user.saveData().then (send_res) =>
  107. @sending = false
  108. if send_res
  109. @hide()
  110. @just_sent = true
  111. if @user_address[message.to] == Page.site_info.auth_address
  112. @log "Sent message to myself, reload inbox"
  113. Page.message_lists.inbox.reload = true
  114. setTimeout ( =>
  115. @just_sent = false
  116. @to = ""
  117. @subject = ""
  118. @body = ""
  119. Page.leftbar.reload_contacts = true
  120. Page.projector.scheduleRender()
  121. ), 4000
  122. else
  123. # Failed: Reset scrambled values to normal text
  124. @node.querySelector(".to").value = @to
  125. @node.querySelector(".subject").value = @subject
  126. @node.querySelector(".body").value = @body
  127. return false
  128. render: =>
  129. h("div.MessageCreate", {classes: { minimized: @minimized, empty: @isEmpty(), sent: @just_sent}, afterCreate: @setNode}, [
  130. h("a.titlebar", {"href": "#New+message", onclick: @handleTitleClick}, [
  131. h("span.text", [@getTitle()]),
  132. h("span.buttons", [
  133. h("a.minimize", {href: "#Minimize", onclick: @handleTitleClick}, ["_"]),
  134. h("a.close", {href: "#Close", onclick: @handleCloseClick}, ["×"])
  135. ])
  136. ]),
  137. h("label.label-to", ["To:"]),
  138. @field_to.render(),
  139. h("input.subject", {type: "text", placeholder: "Subject", name: "subject", value: @subject, oninput: @handleInput}),
  140. h("textarea.body", {placeholder: "Message", name: "body", value: @body, oninput: @handleInput}),
  141. h("a.button.button-submit.button-send", {href: "#Send", classes: {"disabled": not @isFilled(), "loading": @sending or @just_sent}, onclick: @handleSendClick}, ["Encrypt & Send message"])
  142. ])
  143. onSiteInfo: (site_info) ->
  144. if site_info.event?[0] == "file_done"
  145. @update_usernames = true
  146. window.MessageCreate = MessageCreate