Вопрос или проблема
Я пытаюсь заставить tinyMCE загружать изображение в облачное хранилище при составлении электронной почты в своем приложении. Я разрабатываю с использованием Angular 18, @angular/fire 18 модульный (Firestore, Storage, Functions, Auth).
Все, похоже, работает нормально. Изображение загружается, и я получаю URL изображения, но диалоговое окно изображения не закрывается, и я не вижу никаких ошибок в консоли.
это мой код:
images_upload_handler: (blobInfo) => {
const file = blobInfo.blob();
const filePath = `${Date.now()}-${blobInfo.filename()}`;
// Инициализируйте Firebase Storage и создайте ссылку на путь файла
const storage = getStorage();
const storageRef = ref(storage, filePath);
// Начните загрузку файла
const uploadTask = uploadBytesResumable(storageRef, file);
// Верните Promise, который разрешится с URL для загрузки после завершения загрузки
return new Promise<string>((resolve, reject) => {
uploadTask.on(
'state_changed',
(snapshot) => {
// Необязательно: логгируйте или обрабатывайте прогресс загрузки при необходимости
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log(`Прогресс загрузки: ${progress}%`);
},
(error) => {
// Обработка неудачных загрузок
console.error('Ошибка загрузки:', error);
reject('Ошибка загрузки изображения');
},
async () => {
// Получите URL для загрузки после завершения загрузки
try {
const downloadURL = await getDownloadURL(storageRef);
resolve(downloadURL);
} catch (error) {
console.error('Не удалось получить URL загрузки:', error);
reject('Не удалось получить URL загрузки');
}
}
);
});
},
Я даже использовал код из примера на github tinymce, и получаю тот же результат: https://github.com/EbukaPeter55/Angular-TinyMCE/blob/master/src/app/app.component.ts
images_upload_handler: (blobInfo) => {
const file = blobInfo.blob();
const filePath = `${Date.now()}-${blobInfo.filename()}`;
const ref = this.storage.ref(filePath);
const task = this.storage.upload(filePath, file);
const promise = new Promise<string>((resolve, reject) => {
task
.snapshotChanges()
.pipe(
finalize(() =>
ref
.getDownloadURL()
.pipe(last())
.subscribe((url) => {
resolve(url);
})
)
)
.subscribe((_) => {
// ничего не делать
});
});
return promise;
},
};
Я не вижу, почему это происходит или как вызвать закрытие диалогового окна, когда изображение загружено и я получаю downloadUrl.
Может кто-нибудь прояснить, в чем может быть проблема, пожалуйста?
Ответ или решение
Использование TinyMCE для загрузки изображений в облачное хранилище: диагностика проблемы с диалогом
Вы столкнулись с проблемой, при которой диалоговое окно загрузки изображений в TinyMCE не закрывается после того, как изображение успешно загружено в облачное хранилище. Данная проблема может быть связана с несколькими факторами. Давайте подробно разберем ваш код и возможные источники проблемы.
Основные компоненты кода
Ваш код загрузчика изображений выглядит следующим образом:
images_upload_handler: (blobInfo) => {
const file = blobInfo.blob();
const filePath = `${Date.now()}-${blobInfo.filename()}`;
const storage = getStorage();
const storageRef = ref(storage, filePath);
const uploadTask = uploadBytesResumable(storageRef, file);
return new Promise<string>((resolve, reject) => {
uploadTask.on(
'state_changed',
(snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log(`Upload progress: ${progress}%`);
},
(error) => {
console.error('Upload failed:', error);
reject('Image upload failed');
},
async () => {
try {
const downloadURL = await getDownloadURL(storageRef);
resolve(downloadURL);
} catch (error) {
console.error('Failed to retrieve download URL:', error);
reject('Failed to retrieve download URL');
}
}
);
});
}
Возможные проблемы и решения
-
Отсутствие вызова для закрытия диалога: За закрытие диалогового окна отвечает метод
resolve
вашего промиса. Убедитесь, что TinyMCE корректно обрабатывает URL, который вы возвращаете. Если он не знает, что делать с разрешением, диалог не закроется. Вам нужно убедиться, что вы возвращаете URL правильно и ваш код не содержит ошибок. -
Неправильные версии библиотек: Возможные несовместимости могут возникнуть из-за версий Angular или библиотек, связанных с Firebase. Убедитесь, что все библиотеки обновлены до последних стабильных версий.
-
Проблемы с обработчиком загрузки: Рассмотрите вариант использования другого подхода для получения URL. К примеру, вы можете использовать
getDownloadURL
после того, какuploadBytesResumable
завершит работу. Убедитесь, что все операторы RxJS на месте, если вы используете этот подход. -
Установка TinyMCE и конфигурация: Проверьте, правильно ли инициализирован TinyMCE и ваши настройки. Возможно, ошибка кроется в ошибке конфигурации самого редактора.
Как закрыть диалог
Если вы получили URL, но диалоговое окно все еще не закрыто, не забудьте вызвать метод закрытия диалога. В TinyMCE это можно сделать через editor.execCommand('mceInsertContent', false, '<img src="' + url + '" />');
. Вот как это может выглядеть в вашем коде:
async () => {
try {
const downloadURL = await getDownloadURL(storageRef);
resolve(downloadURL);
editor.execCommand('mceInsertContent', false, '<img src="' + downloadURL + '" />'); // Закрытие диалога
} catch (error) {
console.error('Failed to retrieve download URL:', error);
reject('Failed to retrieve download URL');
}
}
Заключение
Важным шагом в решении данной проблемы является внимательный анализ кода и убедительная проверка всех этапов загрузки изображения. Обязательно перепроверьте настройки вашего проекта и версию библиотеки. Обратите внимание на правильность выполнения и возврата URL, а также убедитесь, что в вашем коде есть логика для завершения работы диалога после успешной загрузки изображения.
Решив указанную проблему, вы сможете улучшить пользовательский опыт в вашем приложении и обеспечить корректную функциональность TinyMCE.