The frontend/UI server, written in JS using the MarkoJS library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.6 KiB

  1. const moment = require("moment")
  2. const {commentApi} = require("../../../../../rpdata/api/Comment")
  3. const {charactersApi} = require("../../../../../rpdata/api/Character")
  4. module.exports = class {
  5. onCreate(input) {
  6. this.state = {
  7. error: null,
  8. loading: false,
  9. values: {
  10. subject: "",
  11. source: "",
  12. characterName: "",
  13. characterId: "",
  14. fictionalDate: "",
  15. },
  16. characters: [],
  17. opened: false,
  18. placeholder: "(Required)",
  19. }
  20. this.first = false
  21. }
  22. onMount() {
  23. charactersApi.list({author: (this.input.user||{}).name}).then((characters) => {
  24. this.state.characters = characters.sort((a,b) => a.name.localeCompare(b.name))
  25. })
  26. const comments = this.input.chapter.comments || []
  27. const lastComment = comments[comments.length - 1]
  28. let date = lastComment.fictionalDate || chapter.fictionalDate
  29. if (date != null) {
  30. this.change("fictionalDate", {target: {value: moment(date).format("MMM D, YYYY")}})
  31. }
  32. }
  33. change(key, ev) {
  34. this.state.values = Object.assign({}, this.state.values, {[key]: ev.target.value})
  35. if (key === "characterId") {
  36. if (ev.target.value !== "") {
  37. const character = this.state.characters.find(c => c.id === this.state.values.characterId)
  38. if (character != null) {
  39. this.state.placeholder = character.name
  40. } else {
  41. this.state.placeholder = "(Required)"
  42. }
  43. } else {
  44. this.state.placeholder = "(Required)"
  45. }
  46. }
  47. }
  48. open() {
  49. if (!this.state.opened) {
  50. charactersApi.list({author: (this.input.user||{}).name}).then((characters) => {
  51. this.state.characters = characters.sort((a,b) => a.name.localeCompare(b.name))
  52. })
  53. }
  54. }
  55. close() {
  56. this.first = false
  57. this.state.opened = false
  58. this.emit("close")
  59. }
  60. save() {
  61. const values = Object.assign({}, this.state.values)
  62. if (values.source.length == 0) {
  63. this.state.error = "The comment body is empty."
  64. console.warn(values)
  65. return
  66. }
  67. if (this.input.chapter.commentMode !== "Chat" && values.subject.trim().length == 0) {
  68. this.state.error = "The subject is empty."
  69. return
  70. }
  71. if (values.characterName.trim().length < 1) {
  72. const character = this.state.characters.find(c => c.id === this.state.values.characterId)
  73. if (character == null) {
  74. this.state.error = "You need to give a display name for an anonymous character."
  75. return
  76. }
  77. values.characterName = character.name
  78. }
  79. let fictionalDate = new Date(values.fictionalDate + " UTC")
  80. if (values.fictionalDate != "") {
  81. if (Number.isNaN(fictionalDate)) {
  82. this.state.error = `Could not parse ${values.fictionalDate} as date!`
  83. return
  84. }
  85. } else {
  86. fictionalDate = null
  87. }
  88. const input = {
  89. chapterId: this.input.chapter.id,
  90. subject: values.subject,
  91. source: values.source,
  92. characterName: values.characterName,
  93. characterId: values.characterId,
  94. fictionalDate: fictionalDate,
  95. }
  96. if (input.characterId == "") {
  97. input.characterId = null
  98. }
  99. commentApi.addComment(input).then(comment => {
  100. this.emit("add", comment)
  101. this.emit("close")
  102. this.state.values = {
  103. subject: "",
  104. source: "",
  105. characterName: "",
  106. characterId: "",
  107. fictionalDate: "",
  108. }
  109. this.state.opened = false
  110. }).catch(errs => {
  111. console.warn("Failed to add comemnt:", errs)
  112. this.state.error = "Failed to add comemnt: " + (errs[0]||errs||{}).message || errs
  113. }).then(() => {
  114. this.state.loading = false
  115. })
  116. }
  117. }