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 { merge, reject, map, uniqBy } from 'lodash' const buildMentionsString = ({user, attentions}, currentUser) => { let allAttentions = [...attentions] allAttentions.unshift(user) allAttentions = uniqBy(allAttentions, 'id') allAttentions = reject(allAttentions, {id: currentUser.id}) let mentions = map(allAttentions, (attention) => { return `@${attention.screen_name}` }) 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 `
${item.string}
` }, // 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', // 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', 'repliedUser', 'attentions' ], components: { MediaUpload }, data () { let statusText = '' if (this.replyTo) { const currentUser = this.$store.state.users.currentUser statusText = buildMentionsString({ user: this.repliedUser, attentions: this.attentions }, currentUser) } return { submitDisabled: false, newStatus: { status: statusText, files: [] } } }, computed: { completions () { let users = map(this.$store.state.statuses.allStatuses, 'user') users = uniqBy(users, 'id') 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: { postStatus (newStatus) { statusPoster.postStatus({ status: newStatus.status, media: newStatus.files, store: this.$store, inReplyToStatusId: this.replyTo }) this.newStatus = { status: '', files: [] } this.$emit('posted') }, addMediaFile (fileInfo) { this.newStatus.files.push(fileInfo) this.enableSubmit() }, removeMediaFile (fileInfo) { let index = this.newStatus.files.indexOf(fileInfo) this.newStatus.files.splice(index, 1) }, disableSubmit () { this.submitDisabled = true }, enableSubmit () { this.submitDisabled = false }, type (fileInfo) { return fileTypeService.fileType(fileInfo.mimetype) } } } export default PostStatusForm