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.

302 lines
7.8 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. const {query} = require("../client")
  2. const {Tag} = require("./Tag")
  3. const {Chapter} = require("./Chapter")
  4. class Story {
  5. /**
  6. * Construct a story object. You should use the API instead of calling this.
  7. *
  8. * @param {string} id
  9. * @param {string} name
  10. * @param {string} author
  11. * @param {"Info"|"News"|"Document"|"Background"|"Story"} category Story's category
  12. * @param {boolean} listed
  13. * @param {boolean} open
  14. * @param {string} createdDate
  15. * @param {string} updatedDate
  16. * @param {string} fictionalDate
  17. * @param {{kind:string, name:string}[]} tags
  18. * @param {Chapter[]} chapters
  19. */
  20. constructor(id, name, author, category, listed, open, createdDate, updatedDate, fictionalDate, tags, chapters) {
  21. this.id = id
  22. this.name = name
  23. this.author = author
  24. this.category = category
  25. this.listed = listed
  26. this.open = open
  27. this.createdDate = new Date(createdDate)
  28. this.updatedDate = new Date(updatedDate)
  29. this.fictionalDate = fictionalDate != null ? new Date(fictionalDate) : null
  30. this.tags = tags.map(dt => new Tag(dt.kind, dt.name))
  31. this.chapters = chapters != null ? chapters.map(c => new Chapter(c.id, c.title, c.author, c.source, c.createdDate, c.fictionalDate, c.editedDate, c.canComment, c.commentMode, c.commentsLocked, c.comments)) : null
  32. }
  33. }
  34. class StoryCategory {
  35. constructor(name, description) {
  36. this.name = name
  37. this.description = description
  38. }
  39. }
  40. const data = {
  41. categories: null
  42. }
  43. /**
  44. * storyApi contains the API queries
  45. */
  46. const storyApi = {
  47. /**
  48. * Call `stories(filter)` query
  49. *
  50. * @param {{author:string, category:string, tags:Tag[]|Tag, unlisted: boolean, open: boolean, earliestFictionalDate:Date|string, latestFictionalDate:Date|string, limit:number}} filter
  51. * @returns {Promise<Story[]>}
  52. */
  53. list(filter = {}, options = {}) {
  54. if (filter.earliestFictionalDate != null && typeof(filter.earliestFictionalDate) !== "string") {
  55. filter.earliestFictionalDate = filter.earliestFictionalDate.toISOString()
  56. }
  57. if (filter.latestFictionalDate != null && typeof(filter.latestFictionalDate) !== "string") {
  58. filter.latestFictionalDate = filter.latestFictionalDate.toISOString()
  59. }
  60. return query(`
  61. query ListStories($filter: StoriesFilter) {
  62. stories(filter: $filter) {
  63. id
  64. name
  65. author
  66. category
  67. tags {
  68. kind
  69. name
  70. }
  71. listed
  72. open
  73. createdDate
  74. fictionalDate
  75. updatedDate
  76. }
  77. }
  78. `, {filter}, options).then(({stories}) => {
  79. return stories.map(d => new Story(d.id, d.name, d.author, d.category, d.listed, d.open, d.createdDate, d.updatedDate, d.fictionalDate, d.tags))
  80. })
  81. },
  82. /**
  83. * @param {string} id
  84. * @returns {Promise<Story>}
  85. */
  86. find(id) {
  87. return query(`
  88. query FindStory($id: String!) {
  89. story(id: $id) {
  90. id
  91. name
  92. author
  93. category
  94. tags {
  95. kind
  96. name
  97. }
  98. listed
  99. open
  100. createdDate
  101. fictionalDate
  102. updatedDate
  103. chapters {
  104. id
  105. title
  106. author
  107. source
  108. createdDate
  109. fictionalDate
  110. editedDate
  111. canComment
  112. commentMode
  113. commentsLocked
  114. comments {
  115. id
  116. subject
  117. author
  118. characterName
  119. character {
  120. id
  121. name
  122. author
  123. description
  124. }
  125. fictionalDate
  126. createdDate
  127. editedDate
  128. source
  129. }
  130. }
  131. }
  132. }
  133. `, {id}).then(({story}) => {
  134. return new Story(
  135. story.id, story.name, story.author, story.category,
  136. story.listed, story.open,
  137. story.createdDate, story.updatedDate, story.fictionalDate,
  138. story.tags, story.chapters
  139. )
  140. })
  141. },
  142. /**
  143. * Call `__type(name: "StoryCategory")` query and extracts the catogires from it
  144. *
  145. * @returns {Promise<StoryCategory[]>}
  146. */
  147. categories() {
  148. if (data.categories !== null) {
  149. return data.categories
  150. }
  151. return query(`
  152. query ListStoryCategories {
  153. categoryType: __type(name: "StoryCategory") {
  154. enumValues {
  155. name
  156. description
  157. }
  158. }
  159. }
  160. `, {}).then(({categoryType}) => {
  161. data.categories = categoryType.enumValues.map(d => new StoryCategory(d.name, d.description))
  162. return data.categories
  163. })
  164. },
  165. /**
  166. * Call `addStoryTag(input)` mutation, returns the new tag list.
  167. *
  168. * @param {{id:string, tag:Tag}} input
  169. * @returns {Promise<{tags: Tag[]}>}
  170. */
  171. addTag(input) {
  172. return query(`
  173. mutation AddStoryTag($input: StoryTagAddInput!) {
  174. addStoryTag(input:$input) {
  175. tags {
  176. kind
  177. name
  178. }
  179. }
  180. }
  181. `, {input}, {permissions: ["member", "story.edit"]}).then(({addStoryTag}) => {
  182. return addStoryTag
  183. })
  184. },
  185. /**
  186. * Call `removeStoryTag(input)` mutation, returns the new tag list.
  187. *
  188. * @param {{id:string, tag:Tag}} input
  189. * @returns {Promise<{tags: Tag[]}>}
  190. */
  191. removeTag(input) {
  192. return query(`
  193. mutation RemoveStoryTag($input: StoryTagRemoveInput!) {
  194. removeStoryTag(input:$input) {
  195. tags {
  196. kind
  197. name
  198. }
  199. }
  200. }
  201. `, {input}, {permissions: ["member", "story.edit"]}).then(({removeStoryTag}) => {
  202. return removeStoryTag
  203. })
  204. },
  205. /**
  206. * Call `addStory(input)` mutation, returns the ID.
  207. *
  208. * @param {{name:string, category:string, author:string, open:boolean, listed:boolean, fictionalDate:Date, tags:Tag[]}} input
  209. * @returns {Promise<Story>}
  210. */
  211. add(input) {
  212. return query(`
  213. mutation AddStory($input: StoryAddInput!) {
  214. addStory(input:$input) {
  215. id
  216. name
  217. author
  218. category
  219. tags {
  220. kind
  221. name
  222. }
  223. listed
  224. open
  225. createdDate
  226. fictionalDate
  227. updatedDate
  228. chapters {
  229. id
  230. title
  231. author
  232. source
  233. createdDate
  234. fictionalDate
  235. editedDate
  236. }
  237. }
  238. }
  239. `, {input}, {permissions: ["member", "story.edit"]}).then(({addStory}) => {
  240. return new Story(
  241. addStory.id, addStory.name, addStory.author, addStory.category,
  242. addStory.listed, addStory.open,
  243. addStory.createdDate, addStory.updatedDate, addStory.fictionalDate,
  244. addStory.tags, addStory.chapters
  245. )
  246. })
  247. },
  248. /**
  249. * Call `editStory(input)` mutation, returns the changable fields.
  250. *
  251. * @param {{id:string, name:string, category:string, author:string, open:boolean, listed:boolean, fictionalDate:Date, clearFictionalDate:boolean}} input
  252. * @returns {Promise<{id:string, name:string, category:string, author:string, open:boolean, listed:boolean, fictionalDate:Date}>}
  253. */
  254. edit(input) {
  255. return query(`
  256. mutation EditStory($input: StoryEditInput!) {
  257. editStory(input:$input) {
  258. id
  259. name
  260. category
  261. author
  262. open
  263. listed
  264. fictionalDate
  265. }
  266. }
  267. `, {input}, {permissions: ["member", "story.edit"]}).then(({editStory}) => {
  268. return editStory
  269. })
  270. },
  271. /**
  272. * Call `removeStory(input)` mutation, returns the id.
  273. *
  274. * @param {{id:string}} input
  275. * @returns {Promise<{id:string}>}
  276. */
  277. remove(input) {
  278. return query(`
  279. mutation RemoveStory($input: StoryRemoveInput!) {
  280. removeStory(input:$input) {
  281. id
  282. }
  283. }
  284. `, {input}, {permissions: ["member", "story.remove"]}).then(({removeStory}) => {
  285. return removeStory
  286. })
  287. },
  288. }
  289. module.exports = {storyApi, Story}