diff --git a/apps/settings/lib/Settings/Personal/PersonalInfo.php b/apps/settings/lib/Settings/Personal/PersonalInfo.php index df1608e01d92e..88bfe1ddccb21 100644 --- a/apps/settings/lib/Settings/Personal/PersonalInfo.php +++ b/apps/settings/lib/Settings/Personal/PersonalInfo.php @@ -161,6 +161,7 @@ public function getForm(): TemplateResponse { $personalInfoParameters = [ 'userId' => $uid, + 'avatar' => $this->getProperty($account, IAccountManager::PROPERTY_AVATAR), 'displayName' => $this->getProperty($account, IAccountManager::PROPERTY_DISPLAYNAME), 'twitter' => $this->getProperty($account, IAccountManager::PROPERTY_TWITTER), 'emailMap' => $this->getEmailMap($account), @@ -174,6 +175,7 @@ public function getForm(): TemplateResponse { ]; $accountParameters = [ + 'avatarChangeSupported' => $user->canChangeAvatar(), 'displayNameChangeSupported' => $user->canChangeDisplayName(), 'lookupServerUploadEnabled' => $lookupServerUploadEnabled, ]; diff --git a/apps/settings/src/components/PersonalInfo/AvatarSection.vue b/apps/settings/src/components/PersonalInfo/AvatarSection.vue new file mode 100644 index 0000000000000..da14abdb8c586 --- /dev/null +++ b/apps/settings/src/components/PersonalInfo/AvatarSection.vue @@ -0,0 +1,268 @@ + + + + + + + diff --git a/apps/settings/src/constants/AccountPropertyConstants.js b/apps/settings/src/constants/AccountPropertyConstants.js index 17debe27c5573..9d873c6d5f926 100644 --- a/apps/settings/src/constants/AccountPropertyConstants.js +++ b/apps/settings/src/constants/AccountPropertyConstants.js @@ -47,7 +47,7 @@ export const ACCOUNT_PROPERTY_ENUM = Object.freeze({ /** Enum of account properties to human readable account property names */ export const ACCOUNT_PROPERTY_READABLE_ENUM = Object.freeze({ ADDRESS: t('settings', 'Address'), - AVATAR: t('settings', 'Avatar'), + AVATAR: t('settings', 'Profile picture'), BIOGRAPHY: t('settings', 'About'), DISPLAYNAME: t('settings', 'Full name'), EMAIL_COLLECTION: t('settings', 'Additional email'), diff --git a/apps/settings/src/main-personal-info.js b/apps/settings/src/main-personal-info.js index 1ebaae0fc8ea9..5ee79bc17a48f 100644 --- a/apps/settings/src/main-personal-info.js +++ b/apps/settings/src/main-personal-info.js @@ -26,6 +26,7 @@ import { loadState } from '@nextcloud/initial-state' import { translate as t } from '@nextcloud/l10n' import '@nextcloud/dialogs/styles/toast.scss' +import AvatarSection from './components/PersonalInfo/AvatarSection.vue' import DisplayNameSection from './components/PersonalInfo/DisplayNameSection.vue' import EmailSection from './components/PersonalInfo/EmailSection/EmailSection.vue' import TwitterSection from './components/PersonalInfo/TwitterSection.vue' @@ -47,11 +48,13 @@ Vue.mixin({ }, }) +const AvatarView = Vue.extend(AvatarSection) const DisplayNameView = Vue.extend(DisplayNameSection) const EmailView = Vue.extend(EmailSection) const TwitterView = Vue.extend(TwitterSection) const LanguageView = Vue.extend(LanguageSection) +new AvatarView().$mount('#vue-avatar-section') new DisplayNameView().$mount('#vue-displayname-section') new EmailView().$mount('#vue-email-section') new TwitterView().$mount('#vue-twitter-section') diff --git a/apps/settings/templates/settings/personal/personal.info.php b/apps/settings/templates/settings/personal/personal.info.php index 973c98521f5ce..995f0f03223eb 100644 --- a/apps/settings/templates/settings/personal/personal.info.php +++ b/apps/settings/templates/settings/personal/personal.info.php @@ -47,6 +47,7 @@ data-lookup-server-upload-enabled="">

t('Personal info')); ?>

+

diff --git a/package-lock.json b/package-lock.json index 3ae1eff3252d5..7088577693f85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,6 +71,7 @@ "vue": "^2.6.14", "vue-click-outside": "^1.1.0", "vue-clipboard2": "^0.3.3", + "vue-cropperjs": "^4.2.0", "vue-infinite-loading": "^2.4.5", "vue-localstorage": "^0.6.2", "vue-material-design-icons": "^5.0.0", @@ -11951,6 +11952,11 @@ "sha.js": "^2.4.8" } }, + "node_modules/cropperjs": { + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.5.12.tgz", + "integrity": "sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw==" + }, "node_modules/cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", @@ -30660,6 +30666,14 @@ "tinycolor2": "^1.1.2" } }, + "node_modules/vue-cropperjs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/vue-cropperjs/-/vue-cropperjs-4.2.0.tgz", + "integrity": "sha512-dvwCBtjGMiznkNIK2GFd1SQm1x+wmtWg4g4t+NrJSPj/fpHnubXxAUOIvY7lMFeR2lawRLsigCaGZrcXCzuTKA==", + "dependencies": { + "cropperjs": "^1.5.6" + } + }, "node_modules/vue-eslint-parser": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz", @@ -41302,6 +41316,11 @@ "sha.js": "^2.4.8" } }, + "cropperjs": { + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.5.12.tgz", + "integrity": "sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw==" + }, "cross-fetch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", @@ -55856,6 +55875,14 @@ "tinycolor2": "^1.1.2" } }, + "vue-cropperjs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/vue-cropperjs/-/vue-cropperjs-4.2.0.tgz", + "integrity": "sha512-dvwCBtjGMiznkNIK2GFd1SQm1x+wmtWg4g4t+NrJSPj/fpHnubXxAUOIvY7lMFeR2lawRLsigCaGZrcXCzuTKA==", + "requires": { + "cropperjs": "^1.5.6" + } + }, "vue-eslint-parser": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz", diff --git a/package.json b/package.json index aed03952f03b6..1bff0cc0c9bcd 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "vue": "^2.6.14", "vue-click-outside": "^1.1.0", "vue-clipboard2": "^0.3.3", + "vue-cropperjs": "^4.2.0", "vue-infinite-loading": "^2.4.5", "vue-localstorage": "^0.6.2", "vue-material-design-icons": "^5.0.0",