diff --git a/marko/components/modal/style.less b/marko/components/modal/style.less
index 54ee9b2..e833695 100644
--- a/marko/components/modal/style.less
+++ b/marko/components/modal/style.less
@@ -39,9 +39,33 @@ div.overlay {
}
input.big {
font-size: 1.5em;
- padding: 0 0.3333ch;
+ padding: 0 0.3336ch;
}
-
+
+
+ select {
+ display: block;
+ width: 100%;
+ padding: 0 0ch;
+
+ border: none;
+ font-family: inherit;
+ background: none;
+ outline: none;
+ opacity: 0.5;
+
+ option {
+ background-color: black;
+ }
+ }
+ select.big {
+ font-size: 1.5em;
+ margin: 0;
+ }
+ select:focus {
+ opacity: 1;
+ }
+
textarea {
display: block;
width: 100%;
diff --git a/marko/global/colors.less b/marko/global/colors.less
index 2959901..df96e0d 100644
--- a/marko/global/colors.less
+++ b/marko/global/colors.less
@@ -8,10 +8,10 @@ body.theme-story {
.menu-link:hover, .menu > .head-menu > a:hover {
background-color: rgba(17, 187, 255, 0.25);
}
- .color-primary, button, input:focus, textarea:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a {
+ .color-primary, button, input:focus, textarea:focus, select:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a {
color: #4BF;
}
- .color-text, input, textarea {
+ .color-text, input, textarea, select {
color: #ABC;
}
.color-highlight-primary {
@@ -33,10 +33,10 @@ body.theme-logs {
.menu-link:hover, .Menu > .head-menu > a:hover {
background-color: rgba(255, 187, 17, 0.25);
}
- .color-primary, button, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a {
+ .color-primary, button, input:focus, textarea:focus, select:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a {
color: #DA1;
}
- .color-text, input, textarea {
+ .color-text, input, textarea, select {
color: #AAA;
}
.color-highlight-dark {
@@ -58,10 +58,10 @@ body.theme-logs {
.menu-link:hover, .menu > .head-menu > a:hover {
background-color: rgba(35, 255, 128, 0.25);
}
- .color-primary, button, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a {
+ .color-primary, button, input:focus, textarea:focus, select:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a {
color: #1F8;
}
- .color-text, input, textarea {
+ .color-text, input, textarea, select {
color: #ACB;
}
}
diff --git a/marko/page/story-content/components/edit-story-tags-modal/component.js b/marko/page/story-content/components/edit-story-tags-modal/component.js
new file mode 100644
index 0000000..7603a35
--- /dev/null
+++ b/marko/page/story-content/components/edit-story-tags-modal/component.js
@@ -0,0 +1,40 @@
+const moment = require("moment")
+
+const {storyApi} = require("../../../../../rpdata/api/Story")
+
+module.exports = class {
+ onCreate(input) {
+ this.state = {
+ error: null,
+ loading: false,
+ }
+ }
+
+ change(key, ev) {
+ this.state.values[key] = ev.target.value
+ }
+
+ close() {
+ this.emit("close")
+ }
+
+ addTag(tag) {
+ this.state.error = null
+
+ storyApi.addTag({id: this.input.story.id, tag}).then(({tags}) => {
+ this.emit("tags", tags)
+ }).catch(errs => {
+ this.state.error = errs.message || errs[0].message || "Add tag failed"
+ })
+ }
+
+ removeTag(tag) {
+ this.state.error = null
+
+ storyApi.removeTag({id: this.input.story.id, tag}).then(({tags}) => {
+ this.emit("tags", tags)
+ }).catch(errs => {
+ this.state.error = errs.message || errs[0].message || "Remove tag failed"
+ })
+ }
+}
\ No newline at end of file
diff --git a/marko/page/story-content/components/edit-story-tags-modal/index.marko b/marko/page/story-content/components/edit-story-tags-modal/index.marko
new file mode 100644
index 0000000..12b5e66
--- /dev/null
+++ b/marko/page/story-content/components/edit-story-tags-modal/index.marko
@@ -0,0 +1,7 @@
+
+ Edit Tags
+
+ ${state.error}
+
+
+
\ No newline at end of file
diff --git a/marko/page/story-content/components/page/component.js b/marko/page/story-content/components/page/component.js
index 89b7ec6..6d837f8 100644
--- a/marko/page/story-content/components/page/component.js
+++ b/marko/page/story-content/components/page/component.js
@@ -48,8 +48,6 @@ module.exports = class {
}
menuSelect(kind, id) {
- console.log(kind, id)
-
switch (kind) {
case "add":
this.open("chapter.add")
@@ -57,6 +55,11 @@ module.exports = class {
}
}
+ updateStoryTags(tags) {
+ this.state.story.tags = tags
+ this.refreshStory()
+ }
+
refreshStory() {
this.state.story = Object.assign({}, this.state.story)
}
diff --git a/marko/page/story-content/components/page/index.marko b/marko/page/story-content/components/page/index.marko
index 57ca9ff..8a342bf 100644
--- a/marko/page/story-content/components/page/index.marko
+++ b/marko/page/story-content/components/page/index.marko
@@ -2,10 +2,10 @@
${state.story.name}
-
+
-
+
\ No newline at end of file
diff --git a/marko/page/story-content/components/story-tag-options/component.js b/marko/page/story-content/components/story-tag-options/component.js
new file mode 100644
index 0000000..3bbdd0b
--- /dev/null
+++ b/marko/page/story-content/components/story-tag-options/component.js
@@ -0,0 +1,62 @@
+const {tagApi} = require("../../../../../rpdata/api/Tag")
+
+module.exports = class {
+ onCreate() {
+ this.state = {
+ values: {
+ name: "",
+ kind: "Event",
+ },
+ tags: [],
+ suggestions: [],
+ }
+ }
+
+ onMount() {
+ tagApi.list().then(list => {
+ this.state.tags = list
+ }).catch(err => {})
+
+ this.getEl("name").addEventListener("keydown", ev => {
+ setTimeout(() => {
+ const name = this.getEl("name").value
+ const kind = this.getEl("kind").value
+ const search = name.toLowerCase()
+
+ this.state.values = {name, kind}
+ this.state.suggestions = []
+
+ const suggestions = this.state.tags.filter(t => t.name.toLowerCase().includes(search))
+ if (suggestions.length > 0 && suggestions.length < 10) {
+ if (suggestions.length > 1 || suggestions[0].name !== name) {
+ this.state.suggestions = suggestions
+ }
+ }
+ }, 100)
+ })
+ }
+
+ add(tag) {
+ this.state.values = {
+ kind: "Event",
+ name: "",
+ }
+
+ this.emit("add", tag)
+ }
+
+ change(key, ev) {
+ const value = ev.target.value
+
+ this.state.values[key] = value
+ }
+
+ applySuggestion(tag) {
+ this.state.values = {
+ name: tag.name,
+ kind: tag.kind,
+ }
+
+ this.state.suggestions = []
+ }
+}
\ No newline at end of file
diff --git a/marko/page/story-content/components/story-tag-options/index.marko b/marko/page/story-content/components/story-tag-options/index.marko
new file mode 100644
index 0000000..fd60fe3
--- /dev/null
+++ b/marko/page/story-content/components/story-tag-options/index.marko
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/marko/page/story-content/components/story-tag-options/style.less b/marko/page/story-content/components/story-tag-options/style.less
new file mode 100644
index 0000000..9148391
--- /dev/null
+++ b/marko/page/story-content/components/story-tag-options/style.less
@@ -0,0 +1,46 @@
+div.tag-options {
+ div.tag {
+ padding: 0.25em;
+ border-bottom: 1px solid rgba(0, 220, 255, 0.125);
+
+ div.content {
+ width: 80%;
+ display: inline-block;
+ }
+
+ button {
+ width: 20%;
+ display: inline-block;
+ margin: 0;
+ }
+ }
+
+ div.suggestion-list {
+ margin-top: 1em;
+
+ a.tag {
+ display: inline-block;
+ margin: 0.5em 0.5ch;
+ padding: 0.0625em 0.5ch;
+
+ outline: 1px solid;
+ opacity: 0.75;
+
+ user-select: none;
+ }
+ a.tag:hover {
+ opacity: 1;
+ cursor: pointer;
+ }
+
+ div.header {
+ display: inline-block;
+ margin: 0.5em 0.5ch;
+ padding: 0.0625em 0.5ch;
+
+ opacity: 0.5;
+
+ user-select: none;
+ }
+ }
+}
\ No newline at end of file
diff --git a/marko/page/story-content/components/story-tags/component.js b/marko/page/story-content/components/story-tags/component.js
new file mode 100644
index 0000000..723b4e0
--- /dev/null
+++ b/marko/page/story-content/components/story-tags/component.js
@@ -0,0 +1,5 @@
+module.exports = class {
+ select(kind) {
+ this.emit("select", kind)
+ }
+}
\ No newline at end of file
diff --git a/marko/page/story-content/components/story-tags/index.marko b/marko/page/story-content/components/story-tags/index.marko
index 4d7c456..103701d 100644
--- a/marko/page/story-content/components/story-tags/index.marko
+++ b/marko/page/story-content/components/story-tags/index.marko
@@ -1,3 +1,4 @@
\ No newline at end of file
diff --git a/marko/page/story-content/components/story-tags/style.less b/marko/page/story-content/components/story-tags/style.less
index 449d696..a38a201 100644
--- a/marko/page/story-content/components/story-tags/style.less
+++ b/marko/page/story-content/components/story-tags/style.less
@@ -17,4 +17,18 @@ div.story-tags {
opacity: 1;
cursor: pointer;
}
+
+ a.option {
+ display: inline-block;
+ margin: 0.5em 0.5ch;
+ padding: 0.0625em 0.5ch;
+
+ opacity: 0.5;
+
+ user-select: none;
+ }
+ a.option:hover {
+ opacity: 1;
+ cursor: pointer;
+ }
}
\ No newline at end of file
diff --git a/rpdata/api/Story.js b/rpdata/api/Story.js
index 15f7fa5..2196e47 100644
--- a/rpdata/api/Story.js
+++ b/rpdata/api/Story.js
@@ -142,6 +142,48 @@ const storyApi = {
return data.categories
})
},
+
+ /**
+ * Call `addStoryTag(input)` mutation, returns the new tag list.
+ *
+ * @param {{id:string, tag:Tag}} input
+ * @returns {Promise<{tags: Tag[]}>}
+ */
+ addTag(input) {
+ return query(`
+ mutation AddStoryTag($input: StoryTagAddInput!) {
+ addStoryTag(input:$input) {
+ tags {
+ kind
+ name
+ }
+ }
+ }
+ `, {input}, {permissions: ["member", "story.edit"]}).then(({addStoryTag}) => {
+ return addStoryTag
+ })
+ },
+
+ /**
+ * Call `removeStoryTag(input)` mutation, returns the new tag list.
+ *
+ * @param {{id:string, tag:Tag}} input
+ * @returns {Promise<{tags: Tag[]}>}
+ */
+ removeTag(input) {
+ return query(`
+ mutation RemoveStoryTag($input: StoryTagRemoveInput!) {
+ removeStoryTag(input:$input) {
+ tags {
+ kind
+ name
+ }
+ }
+ }
+ `, {input}, {permissions: ["member", "story.edit"]}).then(({removeStoryTag}) => {
+ return removeStoryTag
+ })
+ },
}
module.exports = {storyApi, Story}
\ No newline at end of file
diff --git a/rpdata/api/Tag.js b/rpdata/api/Tag.js
index 9fac33d..d69ab8b 100644
--- a/rpdata/api/Tag.js
+++ b/rpdata/api/Tag.js
@@ -26,7 +26,7 @@ const tagApi = {
}
}
`, {}).then(({tags}) => {
- return tags.map(d => new Tag(d))
+ return tags.map(d => new Tag(d.kind, d.name))
})
},
}