diff --git a/.gitignore b/.gitignore index 90873b8..3b3e494 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ build js/templates.js js/quicknotes-dashboard.js* +js/quicknotes-talk.js* node_modules vendor translationfiles/ diff --git a/Makefile b/Makefile index c682613..5d18430 100644 --- a/Makefile +++ b/Makefile @@ -121,6 +121,7 @@ appstore: distclean build --exclude=templates/fake.php \ --exclude=translation* \ --exclude=webpack*.js \ + --exclude=*.js.map \ --exclude=psalm.xml \ $(project_dir) $(sign_dir) @echo "Signing…" diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 68bcf8f..7a2f8bd 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -34,6 +34,7 @@ use OCP\IURLGenerator; use OCP\IServerContainer; use OCA\QuickNotes\Search\NoteSearchProvider; +use OCA\QuickNotes\Listeners\BeforeTemplateRenderedListener; class Application extends App implements IBootstrap { diff --git a/lib/AppInfo/BeforeTemplateRenderedListener.php b/lib/Listeners/BeforeTemplateRenderedListener.php similarity index 50% rename from lib/AppInfo/BeforeTemplateRenderedListener.php rename to lib/Listeners/BeforeTemplateRenderedListener.php index b95cedf..cc6f040 100644 --- a/lib/AppInfo/BeforeTemplateRenderedListener.php +++ b/lib/Listeners/BeforeTemplateRenderedListener.php @@ -2,16 +2,23 @@ declare(strict_types=1); -namespace OCA\QuickNotes\AppInfo; +namespace OCA\QuickNotes\Listeners; use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +use OCP\IRequest; +use OCP\Util; class BeforeTemplateRenderedListener implements IEventListener { - public function handle(Event $event): void { + private $request; + public function __construct(IRequest $request) { + $this->request = $request; + } + + public function handle(Event $event): void { if (!($event instanceof BeforeTemplateRenderedEvent)) { return; } @@ -20,7 +27,12 @@ class BeforeTemplateRenderedListener implements IEventListener { return; } - \OCP\Util::addStyle('quicknotes', 'global'); + Util::addStyle('quicknotes', 'global'); + + $pathInfo = $this->request->getPathInfo(); + if (strpos($pathInfo, '/call/') === 0 || strpos($pathInfo, '/apps/spreed') === 0) { + Util::addScript('quicknotes', 'quicknotes-talk'); + } } } \ No newline at end of file diff --git a/src/NotesService.js b/src/NotesService.js index 957767c..fc8dcc0 100644 --- a/src/NotesService.js +++ b/src/NotesService.js @@ -15,7 +15,23 @@ export const getDashboardData = () => { }) .catch(err => { console.error(err) - showError(t('notes', 'Fetching notes for dashboard has failed.')) + showError(t('quicknotes', 'There was an error fetching your notes for the dashboard')) + throw err + }) +} + +export const postNewNote = (title, content) => { + return axios + .post(url('/notes'), { + title: title, + content: content, + }) + .then(response => { + return response.data + }) + .catch(err => { + console.error(err) + showError(t('quicknotes', 'There was an error saving the note')) throw err }) } diff --git a/src/talk.js b/src/talk.js new file mode 100644 index 0000000..9dfe573 --- /dev/null +++ b/src/talk.js @@ -0,0 +1,60 @@ +import Vue from 'vue' + +import axios from '@nextcloud/axios' +import { generateUrl } from '@nextcloud/router' +import { showError, showSuccess } from '@nextcloud/dialogs' + +import { postNewNote } from './NotesService.js' + +Vue.prototype.t = t +Vue.prototype.n = n +Vue.prototype.OC = OC + +window.addEventListener('DOMContentLoaded', () => { + if (!window.OCA?.Talk?.registerMessageAction) { + return + } + + window.OCA.Talk.registerMessageAction({ + label: t('quicknotes', 'Save as a note'), + icon: 'icon-quicknotes', + async callback({message: { message, id: messageId, messageParameters, actorDisplayName }, metadata: { name: conversationName, token: conversationToken }}) { + const parsedMessage = message.replace(/{[a-z0-9-_]+}/gi, function(parameter) { + const parameterName = parameter.substr(1, parameter.length - 2) + if (messageParameters[parameterName]) { + if (messageParameters[parameterName].type === 'file' && messageParameters[parameterName].path) { + return messageParameters[parameterName].path + } + if (messageParameters[parameterName].type === 'user' || messageParameters[parameterName].type === 'call') { + return '@' + messageParameters[parameterName].name + } + if (messageParameters[parameterName].name) { + return messageParameters[parameterName].name + } + } + // Do not replace so insert with curly braces again + return parameter + }) + + const title = t('quicknotes', 'Message from {author} in the call {conversationName}', { + author: actorDisplayName, + conversationName, + }) + + const callLink = window.location.origin + generateUrl('/call/{conversationToken}#message_{messageId}', { conversationToken, messageId }) + + let content = '

' + parsedMessage + '

' + content += '


' + content += '

' + callLink + '

' + + postNewNote(title, content).then(data => { + const noteUrl = generateUrl('apps/quicknotes/?n={noteId}', {noteId: data.id}) + showSuccess(t('quicknotes', 'Message saved as a new note. See that. ↗', { + link: noteUrl, + }), { + isHTML: true, + }) + }) + }, + }) +}) diff --git a/webpack.config.js b/webpack.config.js index 31e3f51..34f7b49 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,7 +2,8 @@ const path = require('path') const webpackConfig = require('@nextcloud/webpack-vue-config') webpackConfig.entry = { - dashboard: { import: path.join(__dirname, 'src', 'dashboard.js') } + dashboard: { import: path.join(__dirname, 'src', 'dashboard.js') }, + talk: { import: path.join(__dirname, 'src', 'talk.js') } } module.exports = webpackConfig