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.

101 lines
2.4 KiB

  1. const moment = require("moment")
  2. const {postApi} = require("../../../../../rpdata/api/Post")
  3. module.exports = class {
  4. onCreate(input) {
  5. this.state = {
  6. log: input.log,
  7. modal: null,
  8. }
  9. }
  10. open(modal) {
  11. this.state.modal = modal
  12. }
  13. close() {
  14. this.state.modal = null
  15. }
  16. /**
  17. * Patch the posts
  18. *
  19. * @param {{id:string, [x:string]: any}[]} patches
  20. */
  21. patch(patches) {
  22. const posts = this.state.log.posts.slice()
  23. for (const patch of patches) {
  24. const index = posts.findIndex(p => p.id === patch.id)
  25. if (index == -1) {
  26. console.warn("Post not found for patch:", patch)
  27. // TODO: Force full refresh
  28. continue
  29. }
  30. posts[index] = Object.assign(Object.assign({}, posts[index]), patch)
  31. }
  32. // Sort posts and look for continuity issues (duplicate or skipped positions)
  33. posts.sort((a, b) => a.position - b.position)
  34. for (let i = 1; i < posts.length; ++i) {
  35. if (posts[i].position !== posts[i - 1].position + 1) {
  36. console.warn("Discontinuity detected!")
  37. // TODO: Force full refresh
  38. }
  39. }
  40. this.state.log.posts = posts
  41. this.state.log = Object.assign({}, this.state.log)
  42. }
  43. movePost(post, toPosition, relative) {
  44. if (relative) {
  45. toPosition = post.position + toPosition
  46. }
  47. postApi.move({id: post.id, toPosition}).then(patches => {
  48. this.patch(patches)
  49. }).catch(err => {
  50. console.warn(err)
  51. })
  52. }
  53. removePost(post) {
  54. postApi.remove({id: post.id}).then(() => {
  55. this.state.log.posts = this.state.log.posts.filter(p => p.id !== post.id)
  56. for (const p of this.state.log.posts) {
  57. if (p.position > post.position) {
  58. p.position--
  59. }
  60. }
  61. this.state.log = Object.assign({}, this.state.log)
  62. }).catch(errs => {
  63. console.warn("Failed to delete:", errs)
  64. this.state.error = "Failed to delete: " + (errs.message || errs[0].message)
  65. })
  66. }
  67. postEdited(patch) {
  68. this.patch([patch])
  69. }
  70. logEdited(patch) {
  71. this.state.log = Object.assign(Object.assign({}, this.state.log), patch)
  72. }
  73. postAdded(post) {
  74. this.state.log.posts = this.state.log.posts.concat([post])
  75. this.state.log = Object.assign({}, this.state.log)
  76. }
  77. get title() {
  78. if (this.state.log.title) {
  79. return this.state.log.title
  80. }
  81. return `${this.state.log.channel.name}${moment(this.state.log.date).format("MMMM D, YYYY")}`
  82. }
  83. }