commit: cbd113f762e8f24f7b70076d5635a82a4c42b664
parent: e45cb91e24748a1b4235742dec6edc7927de1f97
Author: eal <eal@waifu.club>
Date: Sat, 24 Feb 2018 08:08:41 +0000
Merge branch 'feature/user-picker-keyboard-support' into 'develop'
Add keyboard support for user/emoji picker.
Closes #56
See merge request pleroma/pleroma-fe!200
Diffstat:
2 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
@@ -41,6 +41,7 @@ const PostStatusForm = {
submitDisabled: false,
error: null,
posting: false,
+ highlighted: 0,
newStatus: {
status: statusText,
files: []
@@ -57,23 +58,26 @@ const PostStatusForm = {
return false
}
// eslint-disable-next-line camelcase
- return map(take(matchedUsers, 5), ({screen_name, name, profile_image_url_original}) => ({
+ return map(take(matchedUsers, 5), ({screen_name, name, profile_image_url_original}, index) => ({
// eslint-disable-next-line camelcase
screen_name: `@${screen_name}`,
name: name,
- img: profile_image_url_original
+ img: profile_image_url_original,
+ highlighted: index === this.highlighted
}))
} else if (firstchar === ':') {
+ if (this.textAtCaret === ':') { return }
const matchedEmoji = filter(this.emoji.concat(this.customEmoji), (emoji) => emoji.shortcode.match(this.textAtCaret.slice(1)))
if (matchedEmoji.length <= 0) {
return false
}
- return map(take(matchedEmoji, 5), ({shortcode, image_url, utf}) => ({
+ return map(take(matchedEmoji, 5), ({shortcode, image_url, utf}, index) => ({
// eslint-disable-next-line camelcase
screen_name: `:${shortcode}:`,
name: '',
utf: utf || '',
- img: image_url
+ img: image_url,
+ highlighted: index === this.highlighted
}))
} else {
return false
@@ -118,6 +122,45 @@ const PostStatusForm = {
el.focus()
this.caret = 0
},
+ replaceCandidate (e) {
+ const len = this.candidates.length || 0
+ if (this.textAtCaret === ':' || e.ctrlKey) { return }
+ if (len > 0) {
+ e.preventDefault()
+ const candidate = this.candidates[this.highlighted]
+ const replacement = candidate.utf || (candidate.screen_name + ' ')
+ this.newStatus.status = Completion.replaceWord(this.newStatus.status, this.wordAtCaret, replacement)
+ const el = this.$el.querySelector('textarea')
+ el.focus()
+ this.caret = 0
+ this.highlighted = 0
+ }
+ },
+ cycleBackward (e) {
+ const len = this.candidates.length || 0
+ if (len > 0) {
+ e.preventDefault()
+ this.highlighted -= 1
+ if (this.highlighted < 0) {
+ this.highlighted = this.candidates.length - 1
+ }
+ } else {
+ this.highlighted = 0
+ }
+ },
+ cycleForward (e) {
+ const len = this.candidates.length || 0
+ if (len > 0) {
+ if (e.shiftKey) { return }
+ e.preventDefault()
+ this.highlighted += 1
+ if (this.highlighted >= len) {
+ this.highlighted = 0
+ }
+ } else {
+ this.highlighted = 0
+ }
+ },
setCaret ({target: {selectionStart}}) {
this.caret = selectionStart
},
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
@@ -2,17 +2,21 @@
<div class="post-status-form">
<form @submit.prevent="postStatus(newStatus)">
<div class="form-group base03-border" >
- <textarea @click="setCaret" @keyup="setCaret" v-model="newStatus.status" :placeholder="$t('post_status.default')" rows="1" class="form-control" @keydown.meta.enter="postStatus(newStatus)" @keyup.ctrl.enter="postStatus(newStatus)" @drop="fileDrop" @dragover.prevent="fileDrag" @input="resize" @paste="paste"></textarea>
+ <textarea @click="setCaret" @keyup="setCaret" v-model="newStatus.status" :placeholder="$t('post_status.default')" rows="1" class="form-control" @keydown.down="cycleForward" @keydown.up="cycleBackward" @keydown.shift.tab="cycleBackward" @keydown.tab="cycleForward" @keydown.enter="replaceCandidate" @keydown.meta.enter="postStatus(newStatus)" @keyup.ctrl.enter="postStatus(newStatus)" @drop="fileDrop" @dragover.prevent="fileDrag" @input="resize" @paste="paste"></textarea>
</div>
<div style="position:relative;" v-if="candidates">
<div class="autocomplete-panel base05-background">
- <div v-for="candidate in candidates" @click="replace(candidate.utf || (candidate.screen_name + ' '))" class="autocomplete base02">
- <span v-if="candidate.img"><img :src="candidate.img"></img></span>
- <span v-else>{{candidate.utf}}</span>
- <span>
- {{candidate.screen_name}}
- <small class="base02">{{candidate.name}}</small>
- </span>
+ <div v-for="candidate in candidates" @click="replace(candidate.utf || (candidate.screen_name + ' '))">
+ <div v-if="candidate.highlighted" class="autocomplete base02">
+ <span v-if="candidate.img"><img :src="candidate.img"></span>
+ <span v-else>{{candidate.utf}}</span>
+ <span>{{candidate.screen_name}}<small class="base02">{{candidate.name}}</small></span>
+ </div>
+ <div v-else class="autocomplete base04">
+ <span v-if="candidate.img"><img :src="candidate.img"></img></span>
+ <span v-else>{{candidate.utf}}</span>
+ <span>{{candidate.screen_name}}<small class="base02">{{candidate.name}}</small></span>
+ </div>
</div>
</div>
</div>