diff --git a/build/eslint-baseline-legacy.json b/build/eslint-baseline-legacy.json index 575c034981e..cce8acafce2 100644 --- a/build/eslint-baseline-legacy.json +++ b/build/eslint-baseline-legacy.json @@ -60,14 +60,6 @@ "count": 1 } }, - "core/src/OC/dialogs.js": { - "camelcase": { - "count": 33 - }, - "no-undef": { - "count": 1 - } - }, "core/src/views/Login.vue": { "vue/multi-word-component-names": { "count": 1 diff --git a/core/src/OC/dialogs.js b/core/src/OC/dialogs.js index 46d97965a3d..49522bf3726 100644 --- a/core/src/OC/dialogs.js +++ b/core/src/OC/dialogs.js @@ -9,14 +9,12 @@ import IconCopy from '@mdi/svg/svg/folder-multiple-outline.svg?raw' import { DialogBuilder, FilePickerType, getFilePickerBuilder } from '@nextcloud/dialogs' import { t } from '@nextcloud/l10n' import { spawnDialog } from '@nextcloud/vue/functions/dialog' -import $ from 'jquery' import { basename } from 'path' import { defineAsyncComponent } from 'vue' import logger from '../logger.js' -import OC from './index.js' /** - * this class to ease the usage of jquery dialogs + * this class to ease the usage of dialogs */ const Dialogs = { // dialog button types @@ -410,396 +408,6 @@ const Dialogs = { } return buttonList }, - - _fileexistsshown: false, - /** - * Displays file exists dialog - * - * @param {object} data upload object - * @param {object} original file with name, size and mtime - * @param {object} replacement file with name, size and mtime - * @param {object} controller with onCancel, onSkip, onReplace and onRename methods - * @return {Promise} jquery promise that resolves after the dialog template was loaded - * - * @deprecated 29.0.0 Use openConflictPicker from the @nextcloud/upload package instead - */ - fileexists: function(data, original, replacement, controller) { - const self = this - const dialogDeferred = new $.Deferred() - - const getCroppedPreview = function(file) { - const deferred = new $.Deferred() - // Only process image files. - const type = file.type && file.type.split('/').shift() - if (window.FileReader && type === 'image') { - const reader = new FileReader() - reader.onload = function(e) { - const blob = new Blob([e.target.result]) - window.URL = window.URL || window.webkitURL - const originalUrl = window.URL.createObjectURL(blob) - const image = new Image() - image.src = originalUrl - image.onload = function() { - const url = crop(image) - deferred.resolve(url) - } - } - reader.readAsArrayBuffer(file) - } else { - deferred.reject() - } - return deferred - } - - /** - * @param img - */ - function crop(img) { - const canvas = document.createElement('canvas') - const targetSize = 96 - const width = img.width - const height = img.height - let x - let y - - // Calculate the width and height, constraining the proportions - if (width > height) { - y = 0 - x = (width - height) / 2 - } else { - y = (height - width) / 2 - x = 0 - } - const size = Math.min(width, height) - - // Set canvas size to the cropped area - canvas.width = size - canvas.height = size - const ctx = canvas.getContext('2d') - ctx.drawImage(img, x, y, size, size, 0, 0, size, size) - - // Resize the canvas to match the destination (right size uses 96px) - resampleHermite(canvas, size, size, targetSize, targetSize) - - return canvas.toDataURL('image/png', 0.7) - } - - /** - * Fast image resize/resample using Hermite filter with JavaScript. - * - * @author ViliusL - * - * @param {*} canvas - * @param {number} W - * @param {number} H - * @param {number} W2 - * @param {number} H2 - */ - function resampleHermite(canvas, W, H, W2, H2) { - W2 = Math.round(W2) - H2 = Math.round(H2) - const img = canvas.getContext('2d').getImageData(0, 0, W, H) - const img2 = canvas.getContext('2d').getImageData(0, 0, W2, H2) - const data = img.data - const data2 = img2.data - const ratio_w = W / W2 - const ratio_h = H / H2 - const ratio_w_half = Math.ceil(ratio_w / 2) - const ratio_h_half = Math.ceil(ratio_h / 2) - - for (let j = 0; j < H2; j++) { - for (let i = 0; i < W2; i++) { - const x2 = (i + j * W2) * 4 - let weight = 0 - let weights = 0 - let weights_alpha = 0 - let gx_r = 0 - let gx_g = 0 - let gx_b = 0 - let gx_a = 0 - const center_y = (j + 0.5) * ratio_h - for (let yy = Math.floor(j * ratio_h); yy < (j + 1) * ratio_h; yy++) { - const dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half - const center_x = (i + 0.5) * ratio_w - const w0 = dy * dy // pre-calc part of w - for (let xx = Math.floor(i * ratio_w); xx < (i + 1) * ratio_w; xx++) { - let dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half - const w = Math.sqrt(w0 + dx * dx) - if (w >= -1 && w <= 1) { - // hermite filter - weight = 2 * w * w * w - 3 * w * w + 1 - if (weight > 0) { - dx = 4 * (xx + yy * W) - // alpha - gx_a += weight * data[dx + 3] - weights_alpha += weight - // colors - if (data[dx + 3] < 255) { - weight = weight * data[dx + 3] / 250 - } - gx_r += weight * data[dx] - gx_g += weight * data[dx + 1] - gx_b += weight * data[dx + 2] - weights += weight - } - } - } - } - data2[x2] = gx_r / weights - data2[x2 + 1] = gx_g / weights - data2[x2 + 2] = gx_b / weights - data2[x2 + 3] = gx_a / weights_alpha - } - } - canvas.getContext('2d').clearRect(0, 0, Math.max(W, W2), Math.max(H, H2)) - canvas.width = W2 - canvas.height = H2 - canvas.getContext('2d').putImageData(img2, 0, 0) - } - - const addConflict = function($conflicts, original, replacement) { - const $conflict = $conflicts.find('.template').clone().removeClass('template').addClass('conflict') - const $originalDiv = $conflict.find('.original') - const $replacementDiv = $conflict.find('.replacement') - - $conflict.data('data', data) - - $conflict.find('.filename').text(original.name) - $originalDiv.find('.size').text(OC.Util.humanFileSize(original.size)) - $originalDiv.find('.mtime').text(OC.Util.formatDate(original.mtime)) - // ie sucks - if (replacement.size && replacement.lastModified) { - $replacementDiv.find('.size').text(OC.Util.humanFileSize(replacement.size)) - $replacementDiv.find('.mtime').text(OC.Util.formatDate(replacement.lastModified)) - } - let path = original.directory + '/' + original.name - const urlSpec = { - file: path, - x: 96, - y: 96, - c: original.etag, - forceIcon: 0, - } - let previewpath = Files.generatePreviewUrl(urlSpec) - // Escaping single quotes - previewpath = previewpath.replace(/'/g, '%27') - $originalDiv.find('.icon').css({ 'background-image': "url('" + previewpath + "')" }) - getCroppedPreview(replacement).then(function(path) { - $replacementDiv.find('.icon').css('background-image', 'url(' + path + ')') - }, function() { - path = OC.MimeType.getIconUrl(replacement.type) - $replacementDiv.find('.icon').css('background-image', 'url(' + path + ')') - }) - // connect checkboxes with labels - const checkboxId = $conflicts.find('.conflict').length - $originalDiv.find('input:checkbox').attr('id', 'checkbox_original_' + checkboxId) - $replacementDiv.find('input:checkbox').attr('id', 'checkbox_replacement_' + checkboxId) - - $conflicts.append($conflict) - - // set more recent mtime bold - // ie sucks - if (replacement.lastModified > original.mtime) { - $replacementDiv.find('.mtime').css('font-weight', 'bold') - } else if (replacement.lastModified < original.mtime) { - $originalDiv.find('.mtime').css('font-weight', 'bold') - } else { - // TODO add to same mtime collection? - } - - // set bigger size bold - if (replacement.size && replacement.size > original.size) { - $replacementDiv.find('.size').css('font-weight', 'bold') - } else if (replacement.size && replacement.size < original.size) { - $originalDiv.find('.size').css('font-weight', 'bold') - } else { - // TODO add to same size collection? - } - - // TODO show skip action for files with same size and mtime in bottom row - - // always keep readonly files - - if (original.status === 'readonly') { - $originalDiv - .addClass('readonly') - .find('input[type="checkbox"]') - .prop('checked', true) - .prop('disabled', true) - $originalDiv.find('.message') - .text(t('core', 'read-only')) - } - } - - const dialogName = 'oc-dialog-fileexists-content' - const dialogId = '#' + dialogName - if (this._fileexistsshown) { - // add conflict - - const $conflicts = $(dialogId + ' .conflicts') - addConflict($conflicts, original, replacement) - - const count = $(dialogId + ' .conflict').length - const title = n( - 'core', - '{count} file conflict', - '{count} file conflicts', - count, - { count }, - ) - $(dialogId).parent().children('.oc-dialog-title').text(title) - - // recalculate dimensions - $(window).trigger('resize') - dialogDeferred.resolve() - } else { - // create dialog - this._fileexistsshown = true - $.when(this._getFileExistsTemplate()).then(function($tmpl) { - const title = t('core', 'One file conflict') - const $dlg = $tmpl.octemplate({ - dialog_name: dialogName, - title, - type: 'fileexists', - - allnewfiles: t('core', 'New Files'), - allexistingfiles: t('core', 'Already existing files'), - - why: t('core', 'Which files do you want to keep?'), - what: t('core', 'If you select both versions, the copied file will have a number added to its name.'), - }) - $('body').append($dlg) - - if (original && replacement) { - const $conflicts = $dlg.find('.conflicts') - addConflict($conflicts, original, replacement) - } - - const buttonlist = [{ - text: t('core', 'Cancel'), - classes: 'cancel', - click: function() { - if (typeof controller.onCancel !== 'undefined') { - controller.onCancel(data) - } - $(dialogId).ocdialog('close') - }, - }, { - text: t('core', 'Continue'), - classes: 'continue', - click: function() { - if (typeof controller.onContinue !== 'undefined') { - controller.onContinue($(dialogId + ' .conflict')) - } - $(dialogId).ocdialog('close') - }, - }] - - $(dialogId).ocdialog({ - width: 500, - closeOnEscape: true, - modal: true, - buttons: buttonlist, - closeButton: null, - close: function() { - self._fileexistsshown = false - try { - $(this).ocdialog('destroy').remove() - } catch { - // ignore - } - }, - }) - - $(dialogId).css('height', 'auto') - - const $primaryButton = $dlg.closest('.oc-dialog').find('button.continue') - $primaryButton.prop('disabled', true) - - /** - * - */ - function updatePrimaryButton() { - const checkedCount = $dlg.find('.conflicts .checkbox:checked').length - $primaryButton.prop('disabled', checkedCount === 0) - } - - // add checkbox toggling actions - $(dialogId).find('.allnewfiles').on('click', function() { - const $checkboxes = $(dialogId).find('.conflict .replacement input[type="checkbox"]') - $checkboxes.prop('checked', $(this).prop('checked')) - }) - $(dialogId).find('.allexistingfiles').on('click', function() { - const $checkboxes = $(dialogId).find('.conflict .original:not(.readonly) input[type="checkbox"]') - $checkboxes.prop('checked', $(this).prop('checked')) - }) - $(dialogId).find('.conflicts').on('click', '.replacement,.original:not(.readonly)', function() { - const $checkbox = $(this).find('input[type="checkbox"]') - $checkbox.prop('checked', !$checkbox.prop('checked')) - }) - $(dialogId).find('.conflicts').on('click', '.replacement input[type="checkbox"],.original:not(.readonly) input[type="checkbox"]', function() { - const $checkbox = $(this) - $checkbox.prop('checked', !$checkbox.prop('checked')) - }) - - // update counters - $(dialogId).on('click', '.replacement,.allnewfiles', function() { - const count = $(dialogId).find('.conflict .replacement input[type="checkbox"]:checked').length - if (count === $(dialogId + ' .conflict').length) { - $(dialogId).find('.allnewfiles').prop('checked', true) - $(dialogId).find('.allnewfiles + .count').text(t('core', '(all selected)')) - } else if (count > 0) { - $(dialogId).find('.allnewfiles').prop('checked', false) - $(dialogId).find('.allnewfiles + .count').text(t('core', '({count} selected)', { count })) - } else { - $(dialogId).find('.allnewfiles').prop('checked', false) - $(dialogId).find('.allnewfiles + .count').text('') - } - updatePrimaryButton() - }) - $(dialogId).on('click', '.original,.allexistingfiles', function() { - const count = $(dialogId).find('.conflict .original input[type="checkbox"]:checked').length - if (count === $(dialogId + ' .conflict').length) { - $(dialogId).find('.allexistingfiles').prop('checked', true) - $(dialogId).find('.allexistingfiles + .count').text(t('core', '(all selected)')) - } else if (count > 0) { - $(dialogId).find('.allexistingfiles').prop('checked', false) - $(dialogId).find('.allexistingfiles + .count') - .text(t('core', '({count} selected)', { count })) - } else { - $(dialogId).find('.allexistingfiles').prop('checked', false) - $(dialogId).find('.allexistingfiles + .count').text('') - } - updatePrimaryButton() - }) - - dialogDeferred.resolve() - }) - .fail(function() { - dialogDeferred.reject() - alert(t('core', 'Error loading file exists template')) - }) - } - // } - return dialogDeferred.promise() - }, - - _getFileExistsTemplate: function() { - const defer = $.Deferred() - if (!this.$fileexistsTemplate) { - const self = this - $.get(OC.filePath('core', 'templates/legacy', 'fileexists.html'), function(tmpl) { - self.$fileexistsTemplate = $(tmpl) - defer.resolve(self.$fileexistsTemplate) - }) - .fail(function() { - defer.reject() - }) - } else { - defer.resolve(this.$fileexistsTemplate) - } - return defer.promise() - }, } export default Dialogs diff --git a/core/templates/legacy/fileexists.html b/core/templates/legacy/fileexists.html deleted file mode 100644 index de213803e0e..00000000000 --- a/core/templates/legacy/fileexists.html +++ /dev/null @@ -1,35 +0,0 @@ - -
| - | - |
|---|