diff --git a/apps/comments/js/comments-app.js b/apps/comments/js/comments-app.js
index 7841a8f7ec28d0f47184d2ddf9d9bb48bc6cae1a..c8a3d229d046fd3e041f741457f40ca91d97eacd 100644
Binary files a/apps/comments/js/comments-app.js and b/apps/comments/js/comments-app.js differ
diff --git a/apps/comments/js/comments-app.js.map b/apps/comments/js/comments-app.js.map
index b4790ebf247470241409cadae196da790c37afb7..ac63137c9d95523032a86d2cc346c1eabc55fb01 100644
Binary files a/apps/comments/js/comments-app.js.map and b/apps/comments/js/comments-app.js.map differ
diff --git a/apps/comments/js/comments-tab.js b/apps/comments/js/comments-tab.js
index 9ad144fae5e778ea4176811a350cb6cb1ba85096..b001c970d84385071f4f547be93995f16a669dff 100644
Binary files a/apps/comments/js/comments-tab.js and b/apps/comments/js/comments-tab.js differ
diff --git a/apps/comments/js/comments-tab.js.map b/apps/comments/js/comments-tab.js.map
index 09b6a01c61a8ece3946d1aa0cbeb661b9659cea0..d31a6dea8c51818af3726dd2b03dbc178da6f6e1 100644
Binary files a/apps/comments/js/comments-tab.js.map and b/apps/comments/js/comments-tab.js.map differ
diff --git a/apps/comments/js/comments.js b/apps/comments/js/comments.js
index 282c71d4a5bffaf837e95cde499bbfd4036be3c2..d7d7524aece29c8fa09367a2c2c32164b7cc47c5 100644
Binary files a/apps/comments/js/comments.js and b/apps/comments/js/comments.js differ
diff --git a/apps/comments/js/comments.js.map b/apps/comments/js/comments.js.map
index 1b126d99fe60ebccd0cb8de3e6e899dd194d1dee..391fd998f3c2da627ee5e92c497787e2a747de91 100644
Binary files a/apps/comments/js/comments.js.map and b/apps/comments/js/comments.js.map differ
diff --git a/apps/comments/src/components/Comment.vue b/apps/comments/src/components/Comment.vue
index edcaeafb7b6e9ce89e3ee019602a0c6988ad3371..a8a46ba031ff6f5a06a90d3c73b3ebcdf1c5b664 100644
--- a/apps/comments/src/components/Comment.vue
+++ b/apps/comments/src/components/Comment.vue
@@ -66,8 +66,9 @@
 		</div>
 
 		<!-- Message editor -->
-		<div class="comment__message" v-if="editor || editing">
-			<RichContenteditable v-model="localMessage"
+		<div class="comment__editor " v-if="editor || editing">
+			<RichContenteditable ref="editor"
+				v-model="localMessage"
 				:auto-complete="autoComplete"
 				:contenteditable="!loading"
 				@submit="onSubmit" />
@@ -83,7 +84,11 @@
 		<!-- Message content -->
 		<!-- The html is escaped and sanitized before rendering -->
 		<!-- eslint-disable-next-line vue/no-v-html-->
-		<div v-else class="comment__message" v-html="renderedContent" />
+		<div v-else
+			:class="{'comment__message--expanded': expanded}"
+			class="comment__message"
+			@click="onExpand"
+			v-html="renderedContent" />
 	</div>
 </template>
 
@@ -117,10 +122,6 @@ export default {
 	inheritAttrs: false,
 
 	props: {
-		source: {
-			type: Object,
-			default: () => ({}),
-		},
 		actorDisplayName: {
 			type: String,
 			required: true,
@@ -153,6 +154,7 @@ export default {
 
 	data() {
 		return {
+			expanded: false,
 			// Only change data locally and update the original
 			// parent data when the request is sent and resolved
 			localMessage: '',
@@ -215,11 +217,24 @@ export default {
 		 * Dispatch message between edit and create
 		 */
 		onSubmit() {
+			// Do not submit if message is empty
+			if (this.localMessage.trim() === '') {
+				return
+			}
+
 			if (this.editor) {
-				this.onNewComment(this.localMessage)
+				this.onNewComment(this.localMessage.trim())
+				this.$nextTick(() => {
+					// Focus the editor again
+					this.$refs.editor.$el.focus()
+				})
 				return
 			}
-			this.onEditComment(this.localMessage)
+			this.onEditComment(this.localMessage.trim())
+		},
+
+		onExpand() {
+			this.expanded = true
 		},
 	},
 
@@ -258,6 +273,7 @@ $comment-padding: 10px;
 		color: var(--color-text-maxcontrast);
 	}
 
+	&__editor,
 	&__message {
 		position: relative;
 		// Avatar size, align with author name
@@ -287,12 +303,23 @@ $comment-padding: 10px;
 			opacity: 1;
 		}
 	}
+
+	&__message {
+		white-space: pre-wrap;
+		word-break: break-word;
+		max-height: 70px;
+		overflow: hidden;
+		&--expanded {
+			max-height: none;
+			overflow: visible;
+		}
+	}
 }
 
 .rich-contenteditable__input {
+	min-height: 44px;
 	margin: 0;
 	padding: $comment-padding;
-	min-height: 44px;
 }
 
 </style>
diff --git a/apps/comments/src/mixins/CommentMixin.js b/apps/comments/src/mixins/CommentMixin.js
index 03f5db0846fd05939af2bbe221b5a9a213fddcbc..7b6e7a9b0a0515b91dc7162761a6366646b9e725 100644
--- a/apps/comments/src/mixins/CommentMixin.js
+++ b/apps/comments/src/mixins/CommentMixin.js
@@ -32,8 +32,7 @@ export default {
 			default: null,
 		},
 		message: {
-			// GenFileInfo can convert message as numbers if they doesn't contains text
-			type: [String, Number],
+			type: String,
 			default: '',
 		},
 		ressourceId: {
@@ -103,6 +102,7 @@ export default {
 				const newComment = await NewComment(this.commentsType, this.ressourceId, message)
 				this.logger.debug('New comment posted', { commentsType: this.commentsType, ressourceId: this.ressourceId, newComment })
 				this.$emit('new', newComment)
+
 				// Clear old content
 				this.$emit('update:message', '')
 				this.localMessage = ''
diff --git a/apps/comments/src/services/GetComments.js b/apps/comments/src/services/GetComments.js
index 66bdbff4503f5f2a462c741c7a4896d19ed639de..4d2c4d21425b513b14f596a8b5bd4eca2b466992 100644
--- a/apps/comments/src/services/GetComments.js
+++ b/apps/comments/src/services/GetComments.js
@@ -23,7 +23,6 @@
 import { parseXML, prepareFileFromProps } from 'webdav/dist/node/interface/dav'
 import { processResponsePayload } from 'webdav/dist/node/response'
 import client from './DavClient'
-import { genFileInfo } from '../utils/fileUtils'
 
 export const DEFAULT_LIMIT = 20
 /**
@@ -61,7 +60,7 @@ export default async function({ commentsType, ressourceId }, options = {}) {
 		.then(parseXML)
 		.then(xml => processMultistatus(xml, true))
 		.then(comments => processResponsePayload(response, comments, true))
-		.then(response => response.data.map(genFileInfo))
+		.then(response => response.data)
 }
 
 // https://github.com/perry-mitchell/webdav-client/blob/9de2da4a2599e06bd86c2778145b7ade39fe0b3c/source/interface/directoryContents.js#L32
diff --git a/apps/comments/src/services/NewComment.js b/apps/comments/src/services/NewComment.js
index 96aee85e0101e0c7864c9789b41caa18c3650419..5bf200d1c8e31aea5720c97e3cdad35d1fd98912 100644
--- a/apps/comments/src/services/NewComment.js
+++ b/apps/comments/src/services/NewComment.js
@@ -20,7 +20,6 @@
  *
  */
 
-import { genFileInfo } from '../utils/fileUtils'
 import { getCurrentUser } from '@nextcloud/auth'
 import { getRootPath } from '../utils/davUtils'
 import axios from '@nextcloud/axios'
@@ -56,5 +55,5 @@ export default async function(commentsType, ressourceId, message) {
 		details: true,
 	})
 
-	return genFileInfo(comment)
+	return comment.data
 }
diff --git a/apps/comments/src/utils/fileUtils.js b/apps/comments/src/utils/fileUtils.js
deleted file mode 100644
index 298732c8af090e5545b2a3cf8a5e69e4e1d0b331..0000000000000000000000000000000000000000
--- a/apps/comments/src/utils/fileUtils.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-import camelcase from 'camelcase'
-import { isNumber } from './numberUtil'
-
-/**
- * Get an url encoded path
- *
- * @param {String} path the full path
- * @returns {string} url encoded file path
- */
-const encodeFilePath = function(path) {
-	const pathSections = (path.startsWith('/') ? path : `/${path}`).split('/')
-	let relativePath = ''
-	pathSections.forEach((section) => {
-		if (section !== '') {
-			relativePath += '/' + encodeURIComponent(section)
-		}
-	})
-	return relativePath
-}
-
-/**
- * Extract dir and name from file path
- *
- * @param {String} path the full path
- * @returns {String[]} [dirPath, fileName]
- */
-const extractFilePaths = function(path) {
-	const pathSections = path.split('/')
-	const fileName = pathSections[pathSections.length - 1]
-	const dirPath = pathSections.slice(0, pathSections.length - 1).join('/')
-	return [dirPath, fileName]
-}
-
-/**
- * Sorting comparison function
- *
- * @param {Object} fileInfo1 file 1 fileinfo
- * @param {Object} fileInfo2 file 2 fileinfo
- * @param {string} key key to sort with
- * @param {boolean} [asc=true] sort ascending?
- * @returns {number}
- */
-const sortCompare = function(fileInfo1, fileInfo2, key, asc = true) {
-
-	if (fileInfo1.isFavorite && !fileInfo2.isFavorite) {
-		return -1
-	} else if (!fileInfo1.isFavorite && fileInfo2.isFavorite) {
-		return 1
-	}
-
-	// if this is a number, let's sort by integer
-	if (isNumber(fileInfo1[key]) && isNumber(fileInfo2[key])) {
-		return Number(fileInfo1[key]) - Number(fileInfo2[key])
-	}
-
-	// else we sort by string, so let's sort directories first
-	if (fileInfo1.type === 'directory' && fileInfo2.type !== 'directory') {
-		return -1
-	} else if (fileInfo1.type !== 'directory' && fileInfo2.type === 'directory') {
-		return 1
-	}
-
-	// finally sort by name
-	return asc
-		? fileInfo1[key].localeCompare(fileInfo2[key], OC.getLanguage())
-		: -fileInfo1[key].localeCompare(fileInfo2[key], OC.getLanguage())
-}
-
-/**
- * Generate a fileinfo object based on the full dav properties
- * It will flatten everything and put all keys to camelCase
- *
- * @param {Object} obj the object
- * @returns {Object}
- */
-const genFileInfo = function(obj) {
-	const fileInfo = {}
-
-	Object.keys(obj).forEach(key => {
-		const data = obj[key]
-
-		// flatten object if any
-		if (!!data && typeof data === 'object' && !Array.isArray(data)) {
-			Object.assign(fileInfo, genFileInfo(data))
-		} else {
-			// format key and add it to the fileInfo
-			if (data === 'false') {
-				fileInfo[camelcase(key)] = false
-			} else if (data === 'true') {
-				fileInfo[camelcase(key)] = true
-			} else {
-				fileInfo[camelcase(key)] = isNumber(data)
-					? Number(data)
-					: data
-			}
-		}
-	})
-	return fileInfo
-}
-
-export { encodeFilePath, extractFilePaths, sortCompare, genFileInfo }
diff --git a/apps/comments/src/views/Comments.vue b/apps/comments/src/views/Comments.vue
index b58f3359304482b72033c3112726e767db121d2f..586a12ed8d6913a7bc66e9574535d177cbd5f981 100644
--- a/apps/comments/src/views/Comments.vue
+++ b/apps/comments/src/views/Comments.vue
@@ -38,11 +38,12 @@
 			<!-- Comments -->
 			<Comment v-for="comment in comments"
 				v-else
-				:key="comment.id"
-				v-bind="comment"
+				:key="comment.props.id"
+				v-bind="comment.props"
 				:auto-complete="autoComplete"
+				:message.sync="comment.props.message"
 				:ressource-id="ressourceId"
-				:message.sync="comment.message"
+				:user-data="genMentionsData(comment.props.mentions)"
 				class="comments__list"
 				@delete="onDelete" />
 
@@ -148,6 +149,26 @@ export default {
 			this.getComments()
 		},
 
+		/**
+		 * Make sure we have all mentions as Array of objects
+		 * @param {Array} mentions the mentions list
+		 * @returns {Object[]}
+		 */
+		genMentionsData(mentions) {
+			const list = Object.values(mentions).flat()
+			return list.reduce((mentions, mention) => {
+				mentions[mention.mentionId] = {
+					// TODO: support groups
+					icon: 'icon-user',
+					id: mention.mentionId,
+					label: mention.mentionDisplayName,
+					source: 'users',
+					primary: getCurrentUser().uid === mention.mentionId,
+				}
+				return mentions
+			}, {})
+		},
+
 		/**
 		 * Get the existing shares infos
 		 */
@@ -224,7 +245,7 @@ export default {
 		 * @param {number} id the deleted comment
 		 */
 		onDelete(id) {
-			const index = this.comments.findIndex(comment => comment.id === id)
+			const index = this.comments.findIndex(comment => comment.props.id === id)
 			if (index > -1) {
 				this.comments.splice(index, 1)
 			} else {
diff --git a/apps/files/js/dist/personal-settings.js b/apps/files/js/dist/personal-settings.js
index f28580bdcf5f6adfb901d8e150160b7643af2ebd..c0e335a838fe2939f76fdf1f9ebc3d427c7375be 100644
Binary files a/apps/files/js/dist/personal-settings.js and b/apps/files/js/dist/personal-settings.js differ
diff --git a/apps/files/js/dist/personal-settings.js.map b/apps/files/js/dist/personal-settings.js.map
index af5ddd5d21e0b0c20eb38f92af624f2f2d99ede8..10afea44bd4457576155c6026140b42a22a8555f 100644
Binary files a/apps/files/js/dist/personal-settings.js.map and b/apps/files/js/dist/personal-settings.js.map differ
diff --git a/apps/user_status/js/user-status-menu.js b/apps/user_status/js/user-status-menu.js
index 757424f9c4d624bafc771cf9bcd4fd139b4f6e02..0917a43a38b72ac84e42c35605a9742f0937d303 100644
Binary files a/apps/user_status/js/user-status-menu.js and b/apps/user_status/js/user-status-menu.js differ
diff --git a/apps/user_status/js/user-status-menu.js.map b/apps/user_status/js/user-status-menu.js.map
index 78e9c0e647008e2e8a38248b16a74d12e3e0b091..f831aa9885457c450e3546c3ebb94721b7beea6c 100644
Binary files a/apps/user_status/js/user-status-menu.js.map and b/apps/user_status/js/user-status-menu.js.map differ
diff --git a/apps/weather_status/js/weather-status.js b/apps/weather_status/js/weather-status.js
index ab390aa2749dbd856feab4a941ff32b03064f143..13535bce5bb4cedfd338c16dd3c938b78d907cd9 100644
Binary files a/apps/weather_status/js/weather-status.js and b/apps/weather_status/js/weather-status.js differ
diff --git a/apps/weather_status/js/weather-status.js.map b/apps/weather_status/js/weather-status.js.map
index 56f8c63e8e2b0052c038613c5d76751b97fcf8f0..d833515e9a9816b080c2a4c11d57f9e3087f05d5 100644
Binary files a/apps/weather_status/js/weather-status.js.map and b/apps/weather_status/js/weather-status.js.map differ
diff --git a/apps/workflowengine/js/workflowengine.js b/apps/workflowengine/js/workflowengine.js
index 7c438d53e8db56819ddc2f4b9cc540181d6f916d..3c92d2d91e4d523c80c54a7f3e7cf4908ec3e6dc 100644
Binary files a/apps/workflowengine/js/workflowengine.js and b/apps/workflowengine/js/workflowengine.js differ
diff --git a/apps/workflowengine/js/workflowengine.js.map b/apps/workflowengine/js/workflowengine.js.map
index b6de8d477183832010d5a829dd5fda71fb3e073d..cc2294cf3f3d20b0924d61a31ddfe273d912b69d 100644
Binary files a/apps/workflowengine/js/workflowengine.js.map and b/apps/workflowengine/js/workflowengine.js.map differ
diff --git a/core/js/dist/install.js b/core/js/dist/install.js
index 5a662eb8bb0b000d78329b8a2616899277395109..b4b8667f01775b5e2e6ab132ab58255ea8611e07 100644
Binary files a/core/js/dist/install.js and b/core/js/dist/install.js differ
diff --git a/core/js/dist/install.js.map b/core/js/dist/install.js.map
index 9c82e88cfe72f6ebd07912c37e8d2a2eb9f802a7..bd7bde9cea2ea17c02c497d3e45c3b5b0ddb8067 100644
Binary files a/core/js/dist/install.js.map and b/core/js/dist/install.js.map differ
diff --git a/core/js/dist/login.js b/core/js/dist/login.js
index 4fdc9c3f7672dae8817f998ed9f194343d08a948..eacc4937620900892d88afef5bf7f649b25dadd5 100644
Binary files a/core/js/dist/login.js and b/core/js/dist/login.js differ
diff --git a/core/js/dist/login.js.map b/core/js/dist/login.js.map
index 08c3cb0ab40a1865dfad7ce4fb5af72fb7e791c3..214d325248cb229d44a2cb536873f76afd652782 100644
Binary files a/core/js/dist/login.js.map and b/core/js/dist/login.js.map differ
diff --git a/core/js/dist/main.js b/core/js/dist/main.js
index 17d11b226a10b423f83cf592b331f2f04fff150f..db622338c1e825deefb113d22b15d94881196a74 100644
Binary files a/core/js/dist/main.js and b/core/js/dist/main.js differ
diff --git a/core/js/dist/main.js.map b/core/js/dist/main.js.map
index a88d695ad1cee567f97b8c66339a6037dc3e6da7..1aaba65e6cda2baf22a83120d7a1785e11d714d1 100644
Binary files a/core/js/dist/main.js.map and b/core/js/dist/main.js.map differ
diff --git a/core/js/dist/maintenance.js b/core/js/dist/maintenance.js
index 5f93099c9a6a5ee924eaee21a4a1d44c1edbd094..4f8b3b58c0bf2fe4b860ae1449b5a3a41b1e809b 100644
Binary files a/core/js/dist/maintenance.js and b/core/js/dist/maintenance.js differ
diff --git a/core/js/dist/maintenance.js.map b/core/js/dist/maintenance.js.map
index 1b46f6e766c6b907fd6320cde3003aac22389a0a..5214e7709f7294755771c37256fae2a8e262aaf8 100644
Binary files a/core/js/dist/maintenance.js.map and b/core/js/dist/maintenance.js.map differ
diff --git a/core/js/dist/recommendedapps.js b/core/js/dist/recommendedapps.js
index c24f73a191844e20ff44a1f8b25773350d9ac2ab..16ead761f3d9527cf03226ac642ca398da88ff58 100644
Binary files a/core/js/dist/recommendedapps.js and b/core/js/dist/recommendedapps.js differ
diff --git a/core/js/dist/recommendedapps.js.map b/core/js/dist/recommendedapps.js.map
index cfdcbbf4e4dbe96ae6fe9e96163f49adc62e68d6..8ec34b243b5f6ffba0e4ab3f310e31ee01dde51e 100644
Binary files a/core/js/dist/recommendedapps.js.map and b/core/js/dist/recommendedapps.js.map differ
diff --git a/core/js/dist/unified-search.js b/core/js/dist/unified-search.js
index 2c72eb8cd3a313a28c65c48208d988dff94d1651..89294867302c1900c09317a7180568c64ad2f93b 100644
Binary files a/core/js/dist/unified-search.js and b/core/js/dist/unified-search.js differ
diff --git a/core/js/dist/unified-search.js.map b/core/js/dist/unified-search.js.map
index bdf1661feba6428c900ace837b0e5c710daf1fdb..4d2207551218f6df562f25b39f47ec5dab04a211 100644
Binary files a/core/js/dist/unified-search.js.map and b/core/js/dist/unified-search.js.map differ
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 062bf1a94dff1b3beb594c38a6770a2bcbd10fd5..13a8d4a0494d0b6c4c3a6fd7cd6777e1fa65162b 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -640,7 +640,7 @@ describe('Core base tests', function() {
 				expect($row.length).toEqual(0);
 			});
 			it('hides itself after a given time', function() {
-				OC.Notification.showTemporary('', {timeout: 10});
+				OC.Notification.showTemporary('', {timeout: 10000});
 
 				var $row = $('body .toastify');
 				expect($row.length).toEqual(1);
@@ -660,7 +660,7 @@ describe('Core base tests', function() {
 		});
 		describe('show', function() {
 			it('hides itself after a given time', function() {
-				OC.Notification.show('', {timeout: 10});
+				OC.Notification.show('', {timeout: 10000});
 
 				var $row = $('body .toastify');
 				expect($row.length).toEqual(1);
@@ -685,7 +685,7 @@ describe('Core base tests', function() {
 		});
 		describe('showHtml', function() {
 			it('hides itself after a given time', function() {
-				OC.Notification.showHtml('<p></p>', {timeout: 10});
+				OC.Notification.showHtml('<p></p>', {timeout: 10000});
 
 				var $row = $('body .toastify');
 				expect($row.length).toEqual(1);
@@ -730,7 +730,7 @@ describe('Core base tests', function() {
 			it('hides a notification before its timeout expires', function() {
 				var hideCallback = sinon.spy();
 
-				var notification = OC.Notification.show('', {timeout: 10});
+				var notification = OC.Notification.show('', {timeout: 10000});
 
 				var $row = $('body .toastify');
 				expect($row.length).toEqual(1);
@@ -766,7 +766,7 @@ describe('Core base tests', function() {
 		});
 		it('cumulates several notifications', function() {
 			var $row1 = OC.Notification.showTemporary('One');
-			var $row2 = OC.Notification.showTemporary('Two', {timeout: 2});
+			var $row2 = OC.Notification.showTemporary('Two', {timeout: 2000});
 			var $row3 = OC.Notification.showTemporary('Three');
 
 			var $el = $('body');
diff --git a/core/src/OC/notification.js b/core/src/OC/notification.js
index 6207331150f2cd884b431fefe9faf18c63a3ca78..adac95f1d37dbe5df07f121c27126e46fc9fa18c 100644
--- a/core/src/OC/notification.js
+++ b/core/src/OC/notification.js
@@ -21,7 +21,7 @@
 
 import _ from 'underscore'
 import $ from 'jquery'
-import { showMessage } from '@nextcloud/dialogs'
+import { showMessage, TOAST_DEFAULT_TIMEOUT, TOAST_PERMANENT_TIMEOUT } from '@nextcloud/dialogs'
 
 /**
  * @todo Write documentation
@@ -98,7 +98,7 @@ export default {
 	showHtml(html, options) {
 		options = options || {}
 		options.isHTML = true
-		options.timeout = (!options.timeout) ? -1 : options.timeout
+		options.timeout = (!options.timeout) ? TOAST_PERMANENT_TIMEOUT : options.timeout
 		const toast = showMessage(html, options)
 		toast.toastElement.toastify = toast
 		return $(toast.toastElement)
@@ -116,7 +116,7 @@ export default {
 	 */
 	show(text, options) {
 		options = options || {}
-		options.timeout = (!options.timeout) ? -1 : options.timeout
+		options.timeout = (!options.timeout) ? TOAST_PERMANENT_TIMEOUT : options.timeout
 		const toast = showMessage(text, options)
 		toast.toastElement.toastify = toast
 		return $(toast.toastElement)
@@ -133,7 +133,7 @@ export default {
 		if (this.updatableNotification) {
 			this.updatableNotification.hideToast()
 		}
-		this.updatableNotification = showMessage(text, { timeout: -1 })
+		this.updatableNotification = showMessage(text, { timeout: TOAST_PERMANENT_TIMEOUT })
 		this.updatableNotification.toastElement.toastify = this.updatableNotification
 		return $(this.updatableNotification.toastElement)
 	},
@@ -152,7 +152,7 @@ export default {
 	 */
 	showTemporary(text, options) {
 		options = options || {}
-		options.timeout = options.timeout || 7
+		options.timeout = options.timeout || TOAST_DEFAULT_TIMEOUT
 		const toast = showMessage(text, options)
 		toast.toastElement.toastify = toast
 		return $(toast.toastElement)
diff --git a/package-lock.json b/package-lock.json
index 265fa714856adf7efb14011736408b9e59ed5741..8a759a7bd0e79c220103b9cbca1f89a6d88364f3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1761,14 +1761,24 @@
       }
     },
     "@nextcloud/dialogs": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-2.0.1.tgz",
-      "integrity": "sha512-Bme8vcs8n4XT5spBgkDEv1z9zNOE23AIbr5jF1WJ1A2XNMNj5Zvy29RosIh0k7H+1lN0PlU38u+eMV1Ets3E4A==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-3.0.0.tgz",
+      "integrity": "sha512-5FVP0RSxIpKTKdSUlQ4osDDz/oCx2/4+InliB5MX2EcrjDe6q3fZMabSGnFTnIAu0CXRTzBk7RpneaIFGv+d5A==",
       "requires": {
         "@nextcloud/l10n": "^1.3.0",
-        "@nextcloud/typings": "^0.2.2",
+        "@nextcloud/typings": "^1.0.0",
         "core-js": "^3.6.4",
         "toastify-js": "^1.9.1"
+      },
+      "dependencies": {
+        "@nextcloud/typings": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/@nextcloud/typings/-/typings-1.0.0.tgz",
+          "integrity": "sha512-r8SRvXszWTyKWEhVd3gx7eBAcCKwdoLlr+ZrR8hrSxs2nfH00de/QoGdo0n/Rcv/9mMtX/haJNd71KwODM2+uQ==",
+          "requires": {
+            "@types/jquery": "2.0.54"
+          }
+        }
       }
     },
     "@nextcloud/eslint-config": {
diff --git a/package.json b/package.json
index 76c99b221ac49aac7dcfb0eab1ab7ba592fa9bf8..7c76c09ee5bac8bc858ea57b6a2ed84985a5fd83 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
     "@nextcloud/auth": "^1.3.0",
     "@nextcloud/axios": "^1.3.3",
     "@nextcloud/capabilities": "^1.0.2",
-    "@nextcloud/dialogs": "^2.0.1",
+    "@nextcloud/dialogs": "^3.0.0",
     "@nextcloud/event-bus": "^1.2.0",
     "@nextcloud/files": "^1.1.0",
     "@nextcloud/initial-state": "^1.2.0",