From e1d61746892e5bdd8c0dd92a4704336b3efdb7e4 Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Wed, 30 Nov 2016 13:39:17 +0100 Subject: Add basic username completion. We need to get users into the store, though. --- .../post_status_form/post_status_form.js | 67 +++++++++++++++++++++- .../post_status_form/post_status_form.vue | 16 ++++++ 2 files changed, 82 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index b17fdaa1..650a9264 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -1,8 +1,10 @@ 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 { reject, map, uniqBy } from 'lodash' +import { merge, reject, map, uniqBy } from 'lodash' const buildMentionsString = ({user, attentions}, currentUser) => { let allAttentions = [...attentions] @@ -19,6 +21,51 @@ 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 `
${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', @@ -44,6 +91,24 @@ const PostStatusForm = { } } }, + 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({ diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index b18e5d80..a6aaf511 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -24,6 +24,22 @@