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.

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