Skip to content

Commit

Permalink
Add slash command to mail composer
Browse files Browse the repository at this point in the history
Signed-off-by: hamza221 <[email protected]>
  • Loading branch information
hamza221 committed Sep 27, 2023
1 parent fa10297 commit c9d4621
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 2 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"raw-loader": "^4.0.2",
"stream-browserify": "^3.0.0",
"stylelint": "^15.10.3",
"tributejs": "^5.1.3",
"util": "^0.12.5",
"uuid": "^9.0.1",
"v-tooltip": "^2.1.3",
Expand Down
97 changes: 95 additions & 2 deletions src/components/TextEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ import ImagePlugin from '@ckeditor/ckeditor5-image/src/image'
import ImageResizePlugin from '@ckeditor/ckeditor5-image/src/imageresize'
import ImageUploadPlugin from '@ckeditor/ckeditor5-image/src/imageupload'
import MailPlugin from '../ckeditor/mail/MailPlugin'
import Tribute from 'tributejs/dist/tribute.esm.js'
import { searchProvider, getLinkWithPicker } from '@nextcloud/vue/dist/Components/NcRichText'
import { emojiSearch, emojiAddRecent } from '@nextcloud/vue/dist/Functions/emoji'
import { getLanguage } from '@nextcloud/l10n'
import logger from '../logger'
Expand Down Expand Up @@ -131,6 +133,9 @@ export default {
}
return {
linkTribute: null,
emojiTribute: null,
textSmiles: [],
ready: false,
editor: Editor,
config: {
Expand All @@ -147,6 +152,16 @@ export default {
this.loadEditorTranslations(getLanguage())
},
methods: {
getLink(item) {
getLinkWithPicker(item.original.id)
.then(link => {
this.editorInstance.execute('delete')
this.appendToBodyAtCursor(link)
})
.catch((error) => {
console.debug('Smart picker promise rejected:', error)
})
},
async loadEditorTranslations(language) {
if (language === 'en') {
// The default, nothing to fetch
Expand Down Expand Up @@ -179,6 +194,85 @@ export default {
onEditorReady(editor) {
logger.debug('TextEditor is ready', { editor })
this.editorInstance = editor
const linkOptions = {
trigger: '/',
// Don't use the tribute search function at all
// We pass search results as values (see below)
lookup: (result, query) => query,
// Where to inject the menu popup
menuContainer: document.querySelector('.modal-mask'),
// Popup mention autocompletion templates
menuItemTemplate: item => `<img class="tribute-container-link__item__icon" src="${item.original.icon_url}"> <span class="tribute-container-link__item__label">${item.original.title}</span>`,
// Hide if no results
noMatchTemplate: () => t('No link provider found'),
selectTemplate: this.getLink,
// Pass the search results as values
values: (text, cb) => cb(searchProvider(text)),
// Class added to the menu container
containerClass: 'tribute-container-link',
// Class added to each list item
itemClass: 'tribute-container-link__item',
}
const emojiOptions = {
trigger: ':',
// Don't use the tribute search function at all
// We pass search results as values (see below)
lookup: (result, query) => query,
// Where to inject the menu popup
menuContainer: document.querySelector('.modal-mask'),
// Popup mention autocompletion templates
menuItemTemplate: item => {
if (this.textSmiles.includes(item.original)) {
// Display the raw text string for :), :-D, … for non emoji results,
// instead of trying to show an image and their name.
return item.original
}
return `<span class="tribute-container-emoji__item__emoji">${item.original.native}</span> :${item.original.short_name}`
},
// Hide if no results
noMatchTemplate: () => t('No emoji found'),
// Display raw emoji along with its name
selectTemplate: (item) => {
if (this.textSmiles.includes(item.original)) {
// Replace the selection with the raw text string for :), :-D, … for non emoji results
this.editorInstance.execute('delete')
this.appendToBodyAtCursor(item.original)
}
emojiAddRecent(item.original)
this.editorInstance.execute('delete')
this.appendToBodyAtCursor(item.original.native)
},
// Pass the search results as values
values: (text, cb) => {
const emojiResults = emojiSearch(text)
if (this.textSmiles.includes(':' + text)) {
/**
* Prepend text smiles to the search results so that Tribute
* is not interfering with normal writing, aka. "Cocos Island Meme".
* E.g. `:)` and `:-)` got replaced by the flag of Cocos Island,
* when submitting the input with Enter after writing them
*/
emojiResults.unshift(':' + text)
}
cb(emojiResults)
},
// Class added to the menu container
containerClass: 'tribute-container-emoji',
// Class added to each list item
itemClass: 'tribute-container-emoji__item',
}
this.linkTribute = new Tribute(linkOptions)
this.emojiTribute = new Tribute(emojiOptions)
// To solve failing unit test
// [Tribute] Must pass in a DOM node or NodeList.
if (editor.sourceElement) {
this.linkTribute.attach(editor.sourceElement)
this.emojiTribute.attach(editor.sourceElement)
}
if (this.focus) {
logger.debug('focusing TextEditor')
Expand Down Expand Up @@ -215,7 +309,6 @@ export default {
</script>

<style lang="scss" scoped>
:deep(a) {
color: #07d;
}
Expand Down

0 comments on commit c9d4621

Please sign in to comment.