diff --git a/dashboard/src/components/ImagePicker.vue b/dashboard/src/components/ImagePicker.vue index eb87e4c05..9120fbad9 100644 --- a/dashboard/src/components/ImagePicker.vue +++ b/dashboard/src/components/ImagePicker.vue @@ -1,24 +1,25 @@ @@ -121,14 +116,11 @@ onMounted(() => {
-
- +
+
- - -
diff --git a/dashboard/src/components/app/Display.vue b/dashboard/src/components/app/Display.vue index 135ff4105..3c519fffd 100644 --- a/dashboard/src/components/app/Display.vue +++ b/dashboard/src/components/app/Display.vue @@ -2,14 +2,14 @@ import { ref, onMounted, useTemplateRef } from 'vue'; import { FormGroup, TextInput, Button, TagInput } from 'pankow'; +import ImagePicker from '../ImagePicker.vue'; import AppsModel from '../../models/AppsModel.js'; const props = defineProps([ 'app' ]); const appsModel = AppsModel.create(); -let iconChanged = false; - +const imagePicker = useTemplateRef('imagePicker'); const busy = ref(false); const labelError = ref(''); const tagsError = ref(''); @@ -17,62 +17,27 @@ const iconError = ref(''); const label = ref(''); const tags = ref([]); const iconUrl = ref(''); -const iconFileInput = useTemplateRef('iconFileInput'); -function onResetIcon() { - const accessToken = localStorage.token; +let newIcon = null; - iconChanged = true; - iconUrl.value = props.app.iconUrl + '&original=true&access_token=' + accessToken; +function onIconChanged(file) { + newIcon = file; } -function onShowIconSelector() { - iconFileInput.value.click(); -} +function getDataURLFromFile(file) { + return new Promise((resolve, reject) => { + const reader = new FileReader(); -function onIconChanged(event) { - const fr = new FileReader(); - fr.onload = function () { - const image = new Image(); - image.onload = function () { - const size = 512; - - const canvas = document.createElement('canvas'); - canvas.width = size; - canvas.height = size; - - const imageDimensionRatio = image.width / image.height; - const canvasDimensionRatio = canvas.width / canvas.height; - let renderableHeight, renderableWidth, xStart, yStart; - - if (imageDimensionRatio > canvasDimensionRatio) { - renderableHeight = canvas.height; - renderableWidth = image.width * (renderableHeight / image.height); - xStart = (canvas.width - renderableWidth) / 2; - yStart = 0; - } else if (imageDimensionRatio < canvasDimensionRatio) { - renderableWidth = canvas.width; - renderableHeight = image.height * (renderableWidth / image.width); - xStart = 0; - yStart = (canvas.height - renderableHeight) / 2; - } else { - renderableHeight = canvas.height; - renderableWidth = canvas.width; - xStart = 0; - yStart = 0; - } - - var ctx = canvas.getContext('2d'); - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.drawImage(image, xStart, yStart, renderableWidth, renderableHeight); - - iconUrl.value = canvas.toDataURL('image/png'); - iconChanged = true; + reader.onload = function(event) { + resolve(event.target.result); }; - image.src = fr.result; - }; - fr.readAsDataURL(event.target.files[0]); + reader.onerror = function(event) { + reject(event.target.error); + }; + + reader.readAsDataURL(file); + }); } async function onSubmit() { @@ -99,12 +64,12 @@ async function onSubmit() { } } - if (iconChanged) { + if (newIcon) { let tmp; - if (iconUrl.value.indexOf('data:image') === 0) { - tmp = iconUrl.value.replace(/^data:image\/[a-z]+;base64,/, ''); - } else { + if (newIcon === 'clear') { tmp = ''; + } else { + tmp = (await getDataURLFromFile(newIcon)).replace(/^data:image\/[a-z]+;base64,/, ''); } const [error] = await appsModel.configure(props.app.id, 'icon', { icon: tmp }); @@ -113,13 +78,16 @@ async function onSubmit() { busy.value = false; return console.error(error); } - - iconChanged = false; } busy.value = false; } +function onClearIcon() { + imagePicker.value.clear(`${iconUrl.value}&original=true`); + newIcon = 'clear'; +} + onMounted(() => { label.value = props.app.label; tags.value = props.app.tags; @@ -147,14 +115,9 @@ onMounted(() => { - -
- - -
-
{{ iconError }}
-
{{ $t('app.display.iconResetAction') }}
- + + +
{{ $t('app.display.iconResetAction') }}
diff --git a/dashboard/src/views/BrandingView.vue b/dashboard/src/views/BrandingView.vue index f8d3070e8..4f9aac1ef 100644 --- a/dashboard/src/views/BrandingView.vue +++ b/dashboard/src/views/BrandingView.vue @@ -11,8 +11,8 @@ import DashboardModel from '../models/DashboardModel.js'; const brandingModel = BrandingModel.create(); const dashboardModel = DashboardModel.create(); -let newBackgroundDataUrl = null; -let newAvatarDataUrl = null; +let newBackground = null; +let newAvatar = null; const busy = ref(false); const name = ref(''); @@ -31,8 +31,8 @@ async function onSubmit() { [error] = await brandingModel.setFooter(footer.value); if (error) return console.error(error); - if (newBackgroundDataUrl) { - const [error] = await brandingModel.setBackground(newBackgroundDataUrl); + if (newBackground) { + const [error] = await brandingModel.setBackground(newBackground); if (error) { // TODO fetch() returns no proper status if entity is too large ?? // if (error.status === 413) { @@ -45,20 +45,20 @@ async function onSubmit() { } } - if (newAvatarDataUrl) { - const [error] = await brandingModel.setAvatar(newAvatarDataUrl); + if (newAvatar) { + const [error] = await brandingModel.setAvatar(newAvatar); if (error) return console.error(error); } busy.value = false; } -function onAvatarChanged(dataUrl) { - newAvatarDataUrl = dataUrl; +function onAvatarChanged(file) { + newAvatar = file; } -function onBackgroundChanged(dataUrl) { - newBackgroundDataUrl = dataUrl; +function onBackgroundChanged(file) { + newBackground = file; } onMounted(async () => { @@ -108,74 +108,3 @@ onMounted(async () => { - -