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.

124 lines
2.9 KiB

  1. const EventEmitter = require("events");
  2. let linkSignal = null;
  3. module.exports = class {
  4. onCreate(input) {
  5. this.state = {
  6. shortName: "",
  7. name: "",
  8. text: "",
  9. nameSuffix: "",
  10. modal: null,
  11. removed: false,
  12. multipart: false,
  13. anchored: false,
  14. prevWasText: false,
  15. dark: false,
  16. }
  17. this.mounted = false;
  18. this.updatePost(input)
  19. }
  20. open(modal) {
  21. this.state.modal = modal
  22. }
  23. close() {
  24. this.state.modal = null
  25. }
  26. move(toPosition) {
  27. this.emit("move", toPosition)
  28. }
  29. remove() {
  30. this.state.removed = true
  31. this.emit("remove")
  32. }
  33. edited(data) {
  34. this.emit("edited", data)
  35. }
  36. onInput(input) {
  37. if (this.state == null) {
  38. return
  39. }
  40. const timediff = Date.parse(input.post.time) - Date.parse(input.prev.time)
  41. this.state.multipart = (!input.post.kind.startsWith("annotation.") && input.post.nick == input.prev.nick && input.prev.multipart !== false) && (Math.abs(timediff) < 60000);
  42. this.state.prevWasText = (input.prev.kind === "text");
  43. this.updatePost(input)
  44. }
  45. onMount() {
  46. this.linkSignalCallback = () => {
  47. this.state.anchored = false
  48. }
  49. if (linkSignal == null) {
  50. linkSignal = new EventEmitter()
  51. linkSignal.setMaxListeners(10000)
  52. }
  53. linkSignal.on("signal", this.linkSignalCallback)
  54. this.state.anchored = window.location.hash.slice(1) === this.input.post.id;
  55. }
  56. onUnmount() {
  57. linkSignal.removeListener("signal", this.linkSignalCallback)
  58. }
  59. link() {
  60. linkSignal.emit("signal")
  61. this.state.anchored = true
  62. }
  63. updatePost(input) {
  64. this.state.shortName = input.post.nick.split("_").shift()
  65. this.state.name = input.post.nick
  66. this.state.nameSuffix = ""
  67. this.state.text = input.post.text
  68. if (input.highlights.length > 0 && (input.post.kind === "action" || input.post.kind === "text")) {
  69. this.state.dark = true
  70. } else {
  71. this.state.dark = false
  72. }
  73. if (!input.post.nick.startsWith("=")) {
  74. const postNick = input.post.nick.replace("'s", "").replace("s'", "s")
  75. for (const character of input.characters) {
  76. for (const nick of character.nicks) {
  77. if (nick === postNick) {
  78. this.state.name = character.name + character.id
  79. this.state.shortName = character.shortName
  80. if (input.post.nick.endsWith("'s") || input.post.nick.endsWith("'")) {
  81. this.state.nameSuffix = (character.shortName.endsWith("s") || character.shortName.endsWith("z")) ? "'" : "'s"
  82. }
  83. if (input.highlights.length > 0) {
  84. this.state.dark = !(input.highlights.includes(character.id))
  85. } else {
  86. this.state.dark = false
  87. }
  88. return
  89. }
  90. }
  91. }
  92. }
  93. }
  94. kindClass(prefix) {
  95. if (this.input.post == null) {
  96. return
  97. }
  98. return `${prefix}${this.input.post.kind.replace(".", "-")}`
  99. }
  100. }