Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions src/components/ConversationSettings/ConversationAvatarEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
hideUserStatus />
<div v-else class="icon-loading" />
</div>
<VueCropper
<component
:is="cropperComponent"
v-show="showCropper"
ref="cropper"
class="avatar__cropper"
Expand Down Expand Up @@ -114,7 +115,7 @@
import { t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import { useIsDarkTheme } from '@nextcloud/vue/composables/useIsDarkTheme'
import VueCropper from 'vue-cropperjs'
import { markRaw } from 'vue'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcColorPicker from '@nextcloud/vue/components/NcColorPicker'
import NcEmojiPicker from '@nextcloud/vue/components/NcEmojiPicker'
Expand All @@ -127,7 +128,15 @@
import IconFileUpload from '../../../img/material-icons/file-upload.svg?raw'
import { AVATAR } from '../../constants.ts'

import 'cropperjs/dist/cropper.css'
// Asynchronous loader for VueCropper component
let vueCropper = null
function getCropperAsyncComponent() {

Check warning on line 133 in src/components/ConversationSettings/ConversationAvatarEditor.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Missing JSDoc comment
vueCropper ??= Promise.all([
import('vue-cropperjs'),
import('cropperjs/dist/cropper.css'),
]).then(([module]) => module.default)
return vueCropper
}

const validMimeTypes = ['image/png', 'image/jpeg']

Expand All @@ -140,7 +149,6 @@
NcColorPicker,
NcEmojiPicker,
NcIconSvgWrapper,
VueCropper,
// Icons
IconTrashCanOutline,
IconEmoticonOutline,
Expand Down Expand Up @@ -187,6 +195,7 @@

data() {
return {
cropperComponent: null,
showCropper: false,
loading: false,
cropperOptions: {
Expand Down Expand Up @@ -239,7 +248,14 @@

methods: {
t,

async waitForCropper() {
this.cropperComponent ??= markRaw(await getCropperAsyncComponent())
},

activateLocalFilePicker() {
// Async request to load and set up component, while user picks the file
getCropperAsyncComponent()
// Set to null so that selecting the same file will trigger the change event
this.$refs.input.value = null
this.$refs.input.click()
Expand All @@ -255,14 +271,17 @@
}

const reader = new FileReader()
reader.onload = (e) => {
reader.onload = async (e) => {
await this.waitForCropper()
this.$refs.cropper.replace(e.target.result)
this.showCropper = true
}
reader.readAsDataURL(file)
},

async showFilePicker() {
// Async request to load and set up component, while user picks the file
getCropperAsyncComponent()
const filePicker = getFilePickerBuilder(t('spreed', 'Choose your conversation picture'))
.setContainer('#vue-avatar-section')
.setMultiSelect(false)
Expand All @@ -284,6 +303,7 @@
}

try {
await this.waitForCropper()
const tempAvatar = generateUrl(`/core/preview?fileId=${fileid}&x=512&y=512&a=1`)
this.$refs.cropper.replace(tempAvatar)
this.showCropper = true
Expand Down Expand Up @@ -325,6 +345,8 @@
},

async getPictureFormData() {
// Cropper should be ready by this moment, so just a safeguard
await this.waitForCropper()
const canvasData = this.$refs.cropper.getCroppedCanvas()
const scaleFactor = canvasData.width > 512 ? 512 / canvasData.width : 1

Expand Down
Loading