14 changed files with 365 additions and 27 deletions
			
			
		- 
					3marko/components/modal/component.js
- 
					7marko/page/story-content/components/chapter-meta/component.js
- 
					4marko/page/story-content/components/chapter-meta/index.marko
- 
					28marko/page/story-content/components/chapter/component.js
- 
					3marko/page/story-content/components/chapter/index.marko
- 
					21marko/page/story-content/components/comment/index.marko
- 
					51marko/page/story-content/components/create-comment-modal/component.js
- 
					10marko/page/story-content/components/create-comment-modal/index.marko
- 
					131marko/page/story-content/components/edit-comment-modal/component.js
- 
					27marko/page/story-content/components/edit-comment-modal/index.marko
- 
					8marko/page/story-content/components/page/component.js
- 
					36marko/page/story-content/components/remove-comment-modal/component.js
- 
					9marko/page/story-content/components/remove-comment-modal/index.marko
- 
					50rpdata/api/Comment.js
| @ -0,0 +1,131 @@ | |||
| const moment = require("moment") | |||
| 
 | |||
| const {commentApi} = require("../../../../../rpdata/api/Comment") | |||
| const {charactersApi} = require("../../../../../rpdata/api/Character") | |||
| 
 | |||
| module.exports = class { | |||
|   onCreate(input) { | |||
|     this.state = { | |||
|       error: null, | |||
|       loading: false, | |||
|       values: { | |||
|         subject: "", | |||
|         source: "", | |||
|         characterName: "", | |||
|         characterId: "", | |||
|         fictionalDate: "", | |||
|       }, | |||
|       characters: [], | |||
|       opened: false, | |||
|       placeholder: "(Required)", | |||
|     } | |||
|   } | |||
| 
 | |||
|   onInput(input) { | |||
|     if (input.comment) { | |||
|       charactersApi.list({author: (input.user||{}).name}).then((characters) => { | |||
|         this.state.characters = characters.sort((a,b) => a.name.localeCompare(b.name)) | |||
|       }) | |||
| 
 | |||
|       const comment = input.comment | |||
|       this.state.values = { | |||
|         subject: comment.subject, | |||
|         characterId: comment.characterId, | |||
|         characterName: comment.characterName, | |||
|         fictionalDate: moment(comment.fictionalDate).format("MMM D, YYYY"), | |||
|         source: comment.source, | |||
|       } | |||
|     } | |||
|   } | |||
| 
 | |||
|   change(key, ev) { | |||
|     this.state.values = Object.assign({}, this.state.values, {[key]: ev.target.value}) | |||
| 
 | |||
|     if (key === "characterId") { | |||
|       if (ev.target.value !== "") { | |||
|         const character = this.state.characters.find(c => c.id === this.state.values.characterId) | |||
|         if (character != null) { | |||
|           this.state.placeholder = character.name | |||
|         } else { | |||
|           this.state.placeholder = "(Required)" | |||
|         } | |||
|       } else { | |||
|         this.state.placeholder = "(Required)" | |||
|       } | |||
|     } | |||
|   } | |||
| 
 | |||
|   close() { | |||
|     this.emit("close") | |||
|   } | |||
| 
 | |||
|   save() { | |||
|     const values = Object.assign({}, this.state.values) | |||
|     let clearFictionalDate = false | |||
| 
 | |||
|     if (values.source.length == 0) { | |||
|       this.state.error = "The comment body is empty." | |||
|       console.warn(values) | |||
|       return | |||
|     } | |||
| 
 | |||
|     if (this.input.chapter.commentMode !== "Chat" && values.subject.trim().length == 0) { | |||
|       this.state.error = "The subject is empty." | |||
|       return | |||
|     } | |||
| 
 | |||
|     if (values.characterName.trim().length < 1) { | |||
|       const character = this.state.characters.find(c => c.id === this.state.values.characterId) | |||
|       if (character == null) { | |||
|         this.state.error = "You need to give a display name for an anonymous character." | |||
|         return | |||
|       } | |||
| 
 | |||
|       values.characterName = character.name | |||
|     } | |||
|      | |||
|     let fictionalDate = new Date(values.fictionalDate + " UTC") | |||
|     if (values.fictionalDate != "") { | |||
|       if (Number.isNaN(fictionalDate)) { | |||
|         this.state.error = `Could not parse ${values.fictionalDate} as date!` | |||
|         return | |||
|       } | |||
|     } else { | |||
|       fictionalDate = null | |||
|       clearFictionalDate = true | |||
|     } | |||
|      | |||
|     const input = { | |||
|       commentId: this.input.comment.id,  | |||
|       subject: values.subject,  | |||
|       source: values.source,  | |||
|       characterName: values.characterName,  | |||
|       characterId: values.characterId, | |||
|       fictionalDate: fictionalDate, | |||
|       clearFictionalDate: clearFictionalDate, | |||
|     } | |||
| 
 | |||
|     if (input.characterId == "") { | |||
|       input.characterId = null | |||
|     } | |||
| 
 | |||
|     commentApi.editComment(input).then(comment => { | |||
|       this.emit("edit", comment) | |||
|       this.close() | |||
| 
 | |||
|       this.state.values = { | |||
|         subject: "", | |||
|         source: "", | |||
|         characterName: "", | |||
|         characterId: "", | |||
|         fictionalDate: "", | |||
|       } | |||
|     }).catch(errs => { | |||
|       console.warn("Failed to add comemnt:", errs) | |||
| 
 | |||
|       this.state.error = "Failed to add comemnt: " + (errs[0]||errs||{}).message || errs | |||
|     }).then(() => { | |||
|       this.state.loading = false | |||
|     }) | |||
|   } | |||
| } | |||
| @ -0,0 +1,27 @@ | |||
| <modal class="modal color-text nolabel" key="modal" enabled=(input.enabled) closable on-close("close") > | |||
|   <h1>Edit Comment</h1> | |||
| 
 | |||
|   <p key="error" class="color-error">${state.error}</p> | |||
| 
 | |||
|   <if(input.chapter.commentMode !== "Chat")> | |||
|     <label>Subject</label> | |||
|     <input key="subject" autofocus placeholder="" class="big" on-change("change", "subject") value=state.values.subject /> | |||
|   </if> | |||
| 
 | |||
|   <label>Character ${state.characterId}</label> | |||
|   <select on-change("change", "characterId")> | |||
|     <option value="" selected=state.values.characterId=="">Anonymous</option> | |||
|     <option for(character in state.characters) value=character.id selected=(state.values.characterId==character.id)>${character.name}</option> | |||
|   </select> | |||
| 
 | |||
|   <label>Display Name</label> | |||
|   <input key="characterName" autofocus placeholder=state.placeholder on-change("change", "characterName") value=state.values.characterName /> | |||
| 
 | |||
|   <label>IC Date</label> | |||
|   <input key="icdate" placeholder="(Optional)" on-change("change", "fictionalDate") value=state.values.fictionalDate /> | |||
| 
 | |||
|   <label>Content</label> | |||
|   <textarea key="source" placeholder="" class="tall" on-change("change", "source") value=state.values.source /> | |||
| 
 | |||
|   <button disabled=state.loading on-click("save")>Save</button> | |||
| </modal> | |||
| @ -0,0 +1,36 @@ | |||
| const {commentApi} = require("../../../../../rpdata/api/Comment") | |||
| 
 | |||
| module.exports = class { | |||
|   onCreate(input) { | |||
|     this.state = { | |||
|       error: null, | |||
|       loading: false, | |||
|       values: { | |||
|         title: "", | |||
|         source: "", | |||
|         fictionalDate: "", | |||
|       }, | |||
|     } | |||
|   } | |||
| 
 | |||
|   change(key, ev) { | |||
|     this.state.values[key] = ev.target.value | |||
|   } | |||
| 
 | |||
|   close() { | |||
|     this.emit("close") | |||
|   } | |||
| 
 | |||
|   doIt() { | |||
|     commentApi.removeComment({commentId: this.input.comment.id}).then(() => { | |||
|       this.emit("remove") | |||
|       this.emit("close") | |||
|     }).catch(errs => { | |||
|       console.warn("Failed to delete:", errs) | |||
| 
 | |||
|       this.state.error = "Failed to delete: " + errs.message || errs[0].message | |||
|     }).then(() => { | |||
|       this.state.loading = false | |||
|     }) | |||
|   } | |||
| } | |||
| @ -0,0 +1,9 @@ | |||
| <modal class="modal color-text nolabel" key="modal" enabled=(input.enabled) notification closable on-close("close") > | |||
|   <h1>Delete Comment</h1> | |||
| 
 | |||
|   <p class="color-error">${state.error}</p> | |||
|    | |||
|   <p class="color-danger">This is irreversible!</p> | |||
| 
 | |||
|   <button disabled=state.loading on-click("doIt")>${Math.random() > 0.99 ? "Deleet" : "Delete"}</button> | |||
| </modal> | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue