|
|
|
@ -1,10 +1,9 @@
|
|
|
|
|
import statusPoster from '../../services/status_poster/status_poster.service.js'
|
|
|
|
|
import MediaUpload from '../media_upload/media_upload.vue'
|
|
|
|
|
import fileTypeService from '../../services/file_type/file_type.service.js'
|
|
|
|
|
import Tribute from '../../../node_modules/tributejs/src/Tribute.js'
|
|
|
|
|
require('../../../node_modules/tributejs/scss/tribute.scss')
|
|
|
|
|
import Completion from '../../services/completion/completion.js'
|
|
|
|
|
|
|
|
|
|
import { merge, reject, map, uniqBy } from 'lodash'
|
|
|
|
|
import { take, filter, reject, map, uniqBy } from 'lodash'
|
|
|
|
|
|
|
|
|
|
const buildMentionsString = ({user, attentions}, currentUser) => {
|
|
|
|
|
let allAttentions = [...attentions]
|
|
|
|
@ -21,51 +20,6 @@ const buildMentionsString = ({user, attentions}, currentUser) => {
|
|
|
|
|
return mentions.join(' ') + ' '
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const defaultCollection = {
|
|
|
|
|
// symbol that starts the lookup
|
|
|
|
|
trigger: '@',
|
|
|
|
|
|
|
|
|
|
// element to target for @mentions
|
|
|
|
|
iframe: null,
|
|
|
|
|
|
|
|
|
|
// class added in the flyout menu for active item
|
|
|
|
|
selectClass: 'highlight',
|
|
|
|
|
|
|
|
|
|
// function called on select that returns the content to insert
|
|
|
|
|
selectTemplate: function (item) {
|
|
|
|
|
return '@' + item.original.screen_name
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// template for displaying item in menu
|
|
|
|
|
menuItemTemplate: function (item) {
|
|
|
|
|
return `<img src="${item.original.profile_image_url}"></img> <div class='name'>${item.string}</div>`
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// template for when no match is found (optional),
|
|
|
|
|
// If no template is provided, menu is hidden.
|
|
|
|
|
noMatchTemplate: null,
|
|
|
|
|
|
|
|
|
|
// specify an alternative parent container for the menu
|
|
|
|
|
menuContainer: document.body,
|
|
|
|
|
|
|
|
|
|
// column to search against in the object (accepts function or string)
|
|
|
|
|
lookup: ({name, screen_name}) => `${name} (@${screen_name})`, // eslint-disable-line camelcase
|
|
|
|
|
|
|
|
|
|
// column that contains the content to insert by default
|
|
|
|
|
fillAttr: 'screen_name',
|
|
|
|
|
|
|
|
|
|
// REQUIRED: array of objects to match
|
|
|
|
|
values: [],
|
|
|
|
|
|
|
|
|
|
// specify whether a space is required before the trigger character
|
|
|
|
|
requireLeadingSpace: true,
|
|
|
|
|
|
|
|
|
|
// specify whether a space is allowed in the middle of mentions
|
|
|
|
|
allowSpaces: false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const tribute = new Tribute({ collection: [] })
|
|
|
|
|
|
|
|
|
|
const PostStatusForm = {
|
|
|
|
|
props: [
|
|
|
|
|
'replyTo',
|
|
|
|
@ -89,30 +43,37 @@ const PostStatusForm = {
|
|
|
|
|
newStatus: {
|
|
|
|
|
status: statusText,
|
|
|
|
|
files: []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
caret: 0
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
candidates () {
|
|
|
|
|
if (this.textAtCaret.charAt(0) === '@') {
|
|
|
|
|
const matchedUsers = filter(this.users, (user) => (user.name + user.screen_name).match(this.textAtCaret.slice(1)))
|
|
|
|
|
return map(take(matchedUsers, 5), ({screen_name, name}) => screen_name)
|
|
|
|
|
} else {
|
|
|
|
|
return ['nothing']
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
textAtCaret () {
|
|
|
|
|
return (this.wordAtCaret || {}).word || ''
|
|
|
|
|
},
|
|
|
|
|
wordAtCaret () {
|
|
|
|
|
const word = Completion.wordAtPosition(this.newStatus.status, this.caret - 1) || {}
|
|
|
|
|
return word
|
|
|
|
|
},
|
|
|
|
|
users () {
|
|
|
|
|
return this.$store.state.users.users
|
|
|
|
|
},
|
|
|
|
|
completions () {
|
|
|
|
|
let users = this.users
|
|
|
|
|
users = merge({values: users}, defaultCollection)
|
|
|
|
|
return [users]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
completions () {
|
|
|
|
|
tribute.collection = this.completions
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
mounted () {
|
|
|
|
|
const textarea = this.$el.querySelector('textarea')
|
|
|
|
|
tribute.collection = this.completions
|
|
|
|
|
tribute.attach(textarea)
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
replace (replacement) {
|
|
|
|
|
this.newStatus.status = Completion.replaceWord(this.newStatus.status, this.wordAtCaret, replacement)
|
|
|
|
|
},
|
|
|
|
|
setCaret ({target: {selectionStart}}) {
|
|
|
|
|
this.caret = selectionStart
|
|
|
|
|
},
|
|
|
|
|
postStatus (newStatus) {
|
|
|
|
|
statusPoster.postStatus({
|
|
|
|
|
status: newStatus.status,
|
|
|
|
|