mirror of
https://github.com/HeyPuter/puter
synced 2024-11-15 06:15:47 +00:00
Merge pull request #384 from AtkinsSJ/progress-dialogs
refactor: Replace several existing progress dialogs with one configurable one
This commit is contained in:
commit
3992fe1a45
@ -250,7 +250,7 @@ class FileCacheService extends AdvancedBase {
|
|||||||
const path = this._get_path(tracker.key);
|
const path = this._get_path(tracker.key);
|
||||||
console.log(`precache fetch key I guess?`, tracker.key);
|
console.log(`precache fetch key I guess?`, tracker.key);
|
||||||
const data = this.precache.get(tracker.key);
|
const data = this.precache.get(tracker.key);
|
||||||
console.log(`path and data: ${path} ${data}`);
|
// console.log(`path and data: ${path} ${data}`);
|
||||||
await fs.promises.writeFile(path, data);
|
await fs.promises.writeFile(path, data);
|
||||||
this.precache.delete(tracker.key);
|
this.precache.delete(tracker.key);
|
||||||
tracker.phase = FileTracker.PHASE_DISK;
|
tracker.phase = FileTracker.PHASE_DISK;
|
||||||
|
@ -33,14 +33,15 @@ export default class Button extends Component {
|
|||||||
create_template ({ template }) {
|
create_template ({ template }) {
|
||||||
if ( this.get('style') === 'link' ) {
|
if ( this.get('style') === 'link' ) {
|
||||||
$(template).html(/*html*/`
|
$(template).html(/*html*/`
|
||||||
<button type="submit" class="link-button code-confirm-btn" style="margin-top:10px;" disabled>${
|
<button type="submit" class="link-button" style="margin-top:10px;" disabled>${
|
||||||
html_encode(this.get('label'))
|
html_encode(this.get('label'))
|
||||||
}</button>
|
}</button>
|
||||||
`);
|
`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// TODO: Replace hack for 'small' with a better way to configure button classes.
|
||||||
$(template).html(/*html*/`
|
$(template).html(/*html*/`
|
||||||
<button type="submit" class="button button-block button-${this.get('style')} code-confirm-btn" style="margin-top:10px;" disabled>${
|
<button type="submit" class="button ${this.get('style') !== 'small' ? 'button-block' : ''} button-${this.get('style')}" style="margin-top:10px;" disabled>${
|
||||||
html_encode(this.get('label'))
|
html_encode(this.get('label'))
|
||||||
}</button>
|
}</button>
|
||||||
`);
|
`);
|
||||||
|
@ -2086,6 +2086,7 @@ async function UIWindow(options) {
|
|||||||
html: i18n('empty_trash'),
|
html: i18n('empty_trash'),
|
||||||
disabled: false,
|
disabled: false,
|
||||||
onClick: async function(){
|
onClick: async function(){
|
||||||
|
// TODO: Merge this with window.empty_trash()
|
||||||
const alert_resp = await UIAlert({
|
const alert_resp = await UIAlert({
|
||||||
message: i18n('empty_trash_confirmation'),
|
message: i18n('empty_trash_confirmation'),
|
||||||
buttons:[
|
buttons:[
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2024 Puter Technologies Inc.
|
|
||||||
*
|
|
||||||
* This file is part of Puter.
|
|
||||||
*
|
|
||||||
* Puter is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published
|
|
||||||
* by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import UIWindow from './UIWindow.js'
|
|
||||||
|
|
||||||
// todo do this using uid rather than item_path, since item_path is way mroe expensive on the DB
|
|
||||||
async function UIWindowCopyProgress(options){
|
|
||||||
let h = '';
|
|
||||||
h += `<div data-copy-operation-id="${options.operation_id}">`;
|
|
||||||
h += `<div>`;
|
|
||||||
// spinner
|
|
||||||
h +=`<svg style="float:left; margin-right: 7px;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>`;
|
|
||||||
// Progress report
|
|
||||||
h +=`<div style="margin-bottom:20px; float:left; padding-top:3px; font-size:15px; overflow: hidden; width: calc(100% - 40px); text-overflow: ellipsis; white-space: nowrap;">`;
|
|
||||||
// msg
|
|
||||||
h += `<span class="copy-progress-msg">${i18n('copying')} </span>`;
|
|
||||||
h += `<span class="copy-from" style="font-weight:strong;"></span>`;
|
|
||||||
h += `</div>`;
|
|
||||||
// progress
|
|
||||||
h += `<div class="copy-progress-bar-container" style="clear:both; margin-top:20px; border-radius:3px;">`;
|
|
||||||
h += `<div class="copy-progress-bar"></div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
// cancel
|
|
||||||
// h += `<button style="float:right; margin-top: 15px; margin-right: -2px;" class="button button-small copy-cancel-btn">Cancel</button>`;
|
|
||||||
h +=`</div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
|
|
||||||
const el_window = await UIWindow({
|
|
||||||
title: i18n('copying'),
|
|
||||||
icon: window.icons[`app-icon-copying.svg`],
|
|
||||||
uid: null,
|
|
||||||
is_dir: false,
|
|
||||||
body_content: h,
|
|
||||||
has_head: false,
|
|
||||||
selectable_body: false,
|
|
||||||
draggable_body: true,
|
|
||||||
allow_context_menu: false,
|
|
||||||
is_resizable: false,
|
|
||||||
is_droppable: false,
|
|
||||||
init_center: true,
|
|
||||||
allow_native_ctxmenu: false,
|
|
||||||
allow_user_select: false,
|
|
||||||
window_class: 'window-copy-progress',
|
|
||||||
width: 450,
|
|
||||||
dominant: true,
|
|
||||||
window_css:{
|
|
||||||
height: 'initial',
|
|
||||||
},
|
|
||||||
body_css: {
|
|
||||||
padding: '22px',
|
|
||||||
width: 'initial',
|
|
||||||
'background-color': 'rgba(231, 238, 245, .95)',
|
|
||||||
'backdrop-filter': 'blur(3px)',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(el_window).find('.copy-cancel-btn').on('click', function(e){
|
|
||||||
window.operation_cancelled[options.operation_id] = true;
|
|
||||||
$(el_window).close();
|
|
||||||
})
|
|
||||||
|
|
||||||
return el_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UIWindowCopyProgress
|
|
@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2024 Puter Technologies Inc.
|
|
||||||
*
|
|
||||||
* This file is part of Puter.
|
|
||||||
*
|
|
||||||
* Puter is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published
|
|
||||||
* by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import UIWindow from './UIWindow.js'
|
|
||||||
|
|
||||||
async function UIWindowDownloadDirProg(options){
|
|
||||||
options = options ?? {};
|
|
||||||
|
|
||||||
let h = '';
|
|
||||||
// Loading spinner
|
|
||||||
h +=`<svg style="height: 40px; width: 40px; padding: 10px; display: block; float: left;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>`;
|
|
||||||
h += `<p style="text-align:left; padding-left:20px; padding-right:20px; overflow:hidden; width: 310px; text-overflow: ellipsis; white-space: nowrap; float:left; font-size:14px;" class="dir-dl-status">${options.defaultText ?? i18n('preparing')}</p>`;
|
|
||||||
|
|
||||||
const el_window = await UIWindow({
|
|
||||||
title: 'Download Directory Progress',
|
|
||||||
app: 'instant-login',
|
|
||||||
single_instance: true,
|
|
||||||
icon: null,
|
|
||||||
uid: null,
|
|
||||||
is_dir: false,
|
|
||||||
body_content: h,
|
|
||||||
has_head: false,
|
|
||||||
selectable_body: false,
|
|
||||||
allow_context_menu: false,
|
|
||||||
is_resizable: false,
|
|
||||||
is_droppable: false,
|
|
||||||
init_center: true,
|
|
||||||
allow_native_ctxmenu: false,
|
|
||||||
allow_user_select: false,
|
|
||||||
backdrop: false,
|
|
||||||
width: 460,
|
|
||||||
height: 'auto',
|
|
||||||
dominant: true,
|
|
||||||
show_in_taskbar: false,
|
|
||||||
draggable_body: true,
|
|
||||||
onAppend: function(this_window){
|
|
||||||
},
|
|
||||||
window_class: 'window-qr',
|
|
||||||
body_css: {
|
|
||||||
width: 'initial',
|
|
||||||
height: '100px',
|
|
||||||
'background-color': 'rgb(245 247 249)',
|
|
||||||
'backdrop-filter': 'blur(3px)',
|
|
||||||
'display': 'flex',
|
|
||||||
"flex-direction": 'row',
|
|
||||||
'justify-content': 'center',
|
|
||||||
'align-items': 'center',
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return el_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UIWindowDownloadDirProg
|
|
@ -1,81 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2024 Puter Technologies Inc.
|
|
||||||
*
|
|
||||||
* This file is part of Puter.
|
|
||||||
*
|
|
||||||
* Puter is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published
|
|
||||||
* by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import UIWindow from './UIWindow.js'
|
|
||||||
|
|
||||||
// todo do this using uid rather than item_path, since item_path is way mroe expensive on the DB
|
|
||||||
async function UIWindowDownloadProgress(options){
|
|
||||||
let h = '';
|
|
||||||
h += `<div data-download-operation-id="${options.operation_id}">`;
|
|
||||||
h += `<div>`;
|
|
||||||
// Spinner
|
|
||||||
h +=`<svg style="float:left; margin-right: 7px;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>`;
|
|
||||||
// Progress report
|
|
||||||
h +=`<div style="margin-bottom:20px; float:left; padding-top:3px; font-size:15px; overflow: hidden; width: calc(100% - 40px); text-overflow: ellipsis; white-space: nowrap;">`;
|
|
||||||
// msg
|
|
||||||
h += `<span class="upload-progress-msg">${i18n('downloading')}...<strong>${options.item_name ?? ''}</strong></span>`;
|
|
||||||
h += `</div>`;
|
|
||||||
// Progress
|
|
||||||
h += `<div class="download-progress-bar-container" style="clear:both; margin-top:20px; border-radius:3px;">`;
|
|
||||||
h += `<div class="download-progress-bar"></div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
// Cancel
|
|
||||||
h += `<button style="float:right; margin-top: 15px; margin-right: -2px;" class="button button-small download-cancel-btn">Cancel</button>`;
|
|
||||||
h +=`</div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
|
|
||||||
const el_window = await UIWindow({
|
|
||||||
title: `Upload`,
|
|
||||||
icon: window.icons[`app-icon-uploader.svg`],
|
|
||||||
uid: null,
|
|
||||||
is_dir: false,
|
|
||||||
body_content: h,
|
|
||||||
has_head: false,
|
|
||||||
selectable_body: false,
|
|
||||||
draggable_body: true,
|
|
||||||
allow_context_menu: false,
|
|
||||||
is_resizable: false,
|
|
||||||
is_droppable: false,
|
|
||||||
init_center: true,
|
|
||||||
allow_native_ctxmenu: false,
|
|
||||||
allow_user_select: false,
|
|
||||||
window_class: 'window-upload-progress',
|
|
||||||
width: 450,
|
|
||||||
dominant: true,
|
|
||||||
window_css:{
|
|
||||||
height: 'initial',
|
|
||||||
},
|
|
||||||
body_css: {
|
|
||||||
padding: '22px',
|
|
||||||
width: 'initial',
|
|
||||||
'background-color': 'rgba(231, 238, 245, .95)',
|
|
||||||
'backdrop-filter': 'blur(3px)',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// cancel download button clicked
|
|
||||||
$(el_window).find('.download-cancel-btn').on('click', function(){
|
|
||||||
window.operation_cancelled[options.operation_id] = true;
|
|
||||||
$(el_window).close();
|
|
||||||
})
|
|
||||||
|
|
||||||
return el_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UIWindowDownloadProgress
|
|
@ -1,81 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2024 Puter Technologies Inc.
|
|
||||||
*
|
|
||||||
* This file is part of Puter.
|
|
||||||
*
|
|
||||||
* Puter is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published
|
|
||||||
* by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import UIWindow from './UIWindow.js'
|
|
||||||
|
|
||||||
// todo do this using uid rather than item_path, since item_path is way mroe expensive on the DB
|
|
||||||
async function UIWindowMoveProgress(options){
|
|
||||||
let h = '';
|
|
||||||
h += `<div data-move-operation-id="${html_encode(options.operation_id)}">`;
|
|
||||||
h += `<div>`;
|
|
||||||
// spinner
|
|
||||||
h +=`<svg style="float:left; margin-right: 7px;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>`;
|
|
||||||
// Progress report
|
|
||||||
h +=`<div style="margin-bottom:20px; float:left; padding-top:3px; font-size:15px; overflow: hidden; width: calc(100% - 40px); text-overflow: ellipsis; white-space: nowrap;">`;
|
|
||||||
// msg
|
|
||||||
h += `<span class="move-progress-msg">${i18n('moving')} </span>`;
|
|
||||||
h += `<span class="move-from" style="font-weight:strong;"></span>`;
|
|
||||||
h += `</div>`;
|
|
||||||
// progress
|
|
||||||
h += `<div class="move-progress-bar-container" style="clear:both; margin-top:20px; border-radius:3px;">`;
|
|
||||||
h += `<div class="move-progress-bar"></div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
// cancel
|
|
||||||
// h += `<button style="float:right; margin-top: 15px; margin-right: -2px;" class="button button-small move-cancel-btn">Cancel</button>`;
|
|
||||||
h +=`</div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
|
|
||||||
const el_window = await UIWindow({
|
|
||||||
title: `moveing`,
|
|
||||||
icon: window.icons[`app-icon-moveing.svg`],
|
|
||||||
uid: null,
|
|
||||||
is_dir: false,
|
|
||||||
body_content: h,
|
|
||||||
has_head: false,
|
|
||||||
selectable_body: false,
|
|
||||||
draggable_body: true,
|
|
||||||
allow_context_menu: false,
|
|
||||||
is_resizable: false,
|
|
||||||
is_droppable: false,
|
|
||||||
init_center: true,
|
|
||||||
allow_native_ctxmenu: false,
|
|
||||||
allow_user_select: false,
|
|
||||||
window_class: 'window-move-progress',
|
|
||||||
width: 450,
|
|
||||||
dominant: true,
|
|
||||||
window_css:{
|
|
||||||
height: 'initial',
|
|
||||||
},
|
|
||||||
body_css: {
|
|
||||||
padding: '22px',
|
|
||||||
width: 'initial',
|
|
||||||
'background-color': 'rgba(231, 238, 245, .95)',
|
|
||||||
'backdrop-filter': 'blur(3px)',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(el_window).find('.move-cancel-btn').on('click', function(e){
|
|
||||||
window.operation_cancelled[options.operation_id] = true;
|
|
||||||
$(el_window).close();
|
|
||||||
})
|
|
||||||
|
|
||||||
return el_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UIWindowMoveProgress
|
|
@ -1,74 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2024 Puter Technologies Inc.
|
|
||||||
*
|
|
||||||
* This file is part of Puter.
|
|
||||||
*
|
|
||||||
* Puter is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published
|
|
||||||
* by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import UIWindow from './UIWindow.js'
|
|
||||||
|
|
||||||
// todo do this using uid rather than item_path, since item_path is way mroe expensive on the DB
|
|
||||||
async function UIWindowNewFolderProgress(options){
|
|
||||||
let h = '';
|
|
||||||
h += `<div data-newfolder-operation-id="${html_encode(options.operation_id)}">`;
|
|
||||||
h += `<div>`;
|
|
||||||
// spinner
|
|
||||||
h +=`<svg style="float:left; margin-right: 7px;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>`;
|
|
||||||
// message
|
|
||||||
h +=`<div style="margin-bottom:20px; float:left; padding-top:3px; font-size:15px; overflow: hidden; width: calc(100% - 40px); text-overflow: ellipsis; white-space: nowrap;">`;
|
|
||||||
// text
|
|
||||||
h += `<span class="newfolder-progress-msg">${i18n('taking_longer_than_usual')}</span>`;
|
|
||||||
h += `</div>`;
|
|
||||||
h +=`</div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
|
|
||||||
const el_window = await UIWindow({
|
|
||||||
title: `Creating New Folder`,
|
|
||||||
icon: window.icons[`app-icon-newfolder.svg`],
|
|
||||||
uid: null,
|
|
||||||
is_dir: false,
|
|
||||||
body_content: h,
|
|
||||||
has_head: false,
|
|
||||||
selectable_body: false,
|
|
||||||
draggable_body: true,
|
|
||||||
allow_context_menu: false,
|
|
||||||
is_resizable: false,
|
|
||||||
is_droppable: false,
|
|
||||||
init_center: true,
|
|
||||||
allow_native_ctxmenu: false,
|
|
||||||
allow_user_select: false,
|
|
||||||
window_class: 'window-newfolder-progress',
|
|
||||||
width: 450,
|
|
||||||
dominant: true,
|
|
||||||
window_css:{
|
|
||||||
height: 'initial',
|
|
||||||
},
|
|
||||||
body_css: {
|
|
||||||
padding: '22px',
|
|
||||||
width: 'initial',
|
|
||||||
'background-color': 'rgba(231, 238, 245, .95)',
|
|
||||||
'backdrop-filter': 'blur(3px)',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(el_window).find('.newfolder-cancel-btn').on('click', function(e){
|
|
||||||
window.operation_cancelled[options.operation_id] = true;
|
|
||||||
$(el_window).close();
|
|
||||||
})
|
|
||||||
|
|
||||||
return el_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UIWindowNewFolderProgress
|
|
155
src/UI/UIWindowProgress.js
Normal file
155
src/UI/UIWindowProgress.js
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (C) 2024 Puter Technologies Inc.
|
||||||
|
*
|
||||||
|
* This file is part of Puter.
|
||||||
|
*
|
||||||
|
* Puter is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import UIWindow from './UIWindow.js'
|
||||||
|
import Placeholder from '../util/Placeholder.js';
|
||||||
|
import Button from './Components/Button.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose progress dialog.
|
||||||
|
* @param operation_id If provided, is saved in the data-operation-id attribute, for later lookup.
|
||||||
|
* @param show_progress Enable a progress bar, and display `(foo%)` after the status message
|
||||||
|
* @param on_cancel A callback run when the Cancel button is clicked. Without it, no Cancel button will appear.
|
||||||
|
* @returns {Promise<{set_progress: *, set_status: *, close: *, show_error: *, element: Element}>} Object for managing the progress dialog
|
||||||
|
* @constructor
|
||||||
|
* TODO: Debouncing logic (show only after a delay, then hide only after a delay)
|
||||||
|
*/
|
||||||
|
async function UIWindowProgress({
|
||||||
|
operation_id = null,
|
||||||
|
show_progress = false,
|
||||||
|
on_cancel = null,
|
||||||
|
} = {}){
|
||||||
|
const placeholder_cancel_btn = Placeholder();
|
||||||
|
const placeholder_ok_btn = Placeholder();
|
||||||
|
|
||||||
|
let h = '';
|
||||||
|
h += `<div ${operation_id ? `data-operation-id="${operation_id}"` : ''}>`;
|
||||||
|
h += `<div class="progress-running">`;
|
||||||
|
h += `<div style="display: flex; align-items: center; gap: 7px;">`;
|
||||||
|
// spinner
|
||||||
|
h += `<svg style="overflow: visible;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>`;
|
||||||
|
// Progress report
|
||||||
|
h += `<div style="font-size:15px; overflow: hidden; flex-grow: 1; text-overflow: ellipsis; white-space: nowrap;">
|
||||||
|
<span class="progress-msg">${i18n('preparing')}</span>`;
|
||||||
|
if (show_progress) {
|
||||||
|
h += ` (<span class="progress-percent">0%</span>)`;
|
||||||
|
}
|
||||||
|
h += `</div>`;
|
||||||
|
h +=`</div>`;
|
||||||
|
if (show_progress) {
|
||||||
|
h += `<div class="progress-bar-container" style="margin-top:20px;">`;
|
||||||
|
h += `<div class="progress-bar"></div>`;
|
||||||
|
h += `</div>`;
|
||||||
|
}
|
||||||
|
if (on_cancel) {
|
||||||
|
h += `<div style="display: flex; justify-content: flex-end;">`;
|
||||||
|
h += placeholder_cancel_btn.html;
|
||||||
|
h += `</div>`;
|
||||||
|
}
|
||||||
|
h += `</div>`;
|
||||||
|
h += `<div class="progress-error" style="display: none">`;
|
||||||
|
h += `<div style="display: flex; align-items: center; gap: 7px;">`;
|
||||||
|
// Alert icon
|
||||||
|
h += `<img style="width:24px; height:24px;" src="${html_encode(window.icons['warning-sign.svg'])}" />`;
|
||||||
|
// Progress report
|
||||||
|
h += `<div style="font-size:15px; overflow: hidden; flex-grow: 1; text-overflow: ellipsis; white-space: nowrap;">
|
||||||
|
<span class="progress-error-title"></span>`;
|
||||||
|
h += `</div>`;
|
||||||
|
h += `</div>`;
|
||||||
|
h += `<p class="progress-error-message"></p>`;
|
||||||
|
h += `<div style="display: flex; justify-content: flex-end;">`;
|
||||||
|
h += placeholder_ok_btn.html;
|
||||||
|
h += `</div>`;
|
||||||
|
h += `</div>`;
|
||||||
|
h += `</div>`;
|
||||||
|
|
||||||
|
const el_window = await UIWindow({
|
||||||
|
uid: null,
|
||||||
|
is_dir: false,
|
||||||
|
body_content: h,
|
||||||
|
has_head: false,
|
||||||
|
selectable_body: false,
|
||||||
|
draggable_body: true,
|
||||||
|
allow_context_menu: false,
|
||||||
|
is_resizable: false,
|
||||||
|
is_droppable: false,
|
||||||
|
init_center: true,
|
||||||
|
allow_native_ctxmenu: false,
|
||||||
|
allow_user_select: false,
|
||||||
|
window_class: 'window-progress',
|
||||||
|
width: 450,
|
||||||
|
dominant: true,
|
||||||
|
window_css:{
|
||||||
|
height: 'initial',
|
||||||
|
},
|
||||||
|
body_css: {
|
||||||
|
padding: '22px',
|
||||||
|
width: 'initial',
|
||||||
|
'background-color': `hsla(
|
||||||
|
var(--primary-hue),
|
||||||
|
var(--primary-saturation),
|
||||||
|
var(--primary-lightness),
|
||||||
|
var(--primary-alpha))`,
|
||||||
|
'backdrop-filter': 'blur(3px)',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (on_cancel) {
|
||||||
|
const cancel_btn = new Button({
|
||||||
|
label: i18n('cancel'),
|
||||||
|
style: 'small',
|
||||||
|
on_click: () => {
|
||||||
|
$(el_window).close();
|
||||||
|
on_cancel();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
cancel_btn.attach(placeholder_cancel_btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ok_btn = new Button({
|
||||||
|
label: i18n('ok'),
|
||||||
|
style: 'small',
|
||||||
|
on_click: () => {
|
||||||
|
$(el_window).close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
ok_btn.attach(placeholder_ok_btn);
|
||||||
|
|
||||||
|
return {
|
||||||
|
element: el_window,
|
||||||
|
set_status: (text) => {
|
||||||
|
el_window.querySelector('.progress-msg').innerHTML = text;
|
||||||
|
},
|
||||||
|
set_progress: (percent) => {
|
||||||
|
el_window.querySelector('.progress-bar').style.width = `${percent}%`;
|
||||||
|
el_window.querySelector('.progress-percent').innerText = `${percent}%`;
|
||||||
|
},
|
||||||
|
close: () => {
|
||||||
|
$(el_window).close();
|
||||||
|
},
|
||||||
|
show_error: (title, message) => {
|
||||||
|
el_window.querySelector('.progress-running').style.display = 'none';
|
||||||
|
el_window.querySelector('.progress-error').style.display = 'block';
|
||||||
|
el_window.querySelector('.progress-error-title').innerText = title;
|
||||||
|
el_window.querySelector('.progress-error-message').innerText = message;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default UIWindowProgress;
|
@ -1,74 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2024 Puter Technologies Inc.
|
|
||||||
*
|
|
||||||
* This file is part of Puter.
|
|
||||||
*
|
|
||||||
* Puter is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published
|
|
||||||
* by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import UIWindow from './UIWindow.js'
|
|
||||||
|
|
||||||
// todo do this using uid rather than item_path, since item_path is way mroe expensive on the DB
|
|
||||||
async function UIWindowProgressEmptyTrash(options){
|
|
||||||
let h = '';
|
|
||||||
h += `<div data-newfolder-operation-id="${options.operation_id}">`;
|
|
||||||
h += `<div>`;
|
|
||||||
// spinner
|
|
||||||
h +=`<svg style="float:left; margin-right: 7px;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>`;
|
|
||||||
// message
|
|
||||||
h +=`<div style="margin-bottom:20px; float:left; padding-top:3px; font-size:15px; overflow: hidden; width: calc(100% - 40px); text-overflow: ellipsis; white-space: nowrap;">`;
|
|
||||||
// text
|
|
||||||
h += `<span class="newfolder-progress-msg">${i18n('emptying_trash')}</span>`;
|
|
||||||
h += `</div>`;
|
|
||||||
h +=`</div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
|
|
||||||
const el_window = await UIWindow({
|
|
||||||
title: i18n('emptying_trash'),
|
|
||||||
icon: window.icons[`app-icon-newfolder.svg`],
|
|
||||||
uid: null,
|
|
||||||
is_dir: false,
|
|
||||||
body_content: h,
|
|
||||||
has_head: false,
|
|
||||||
selectable_body: false,
|
|
||||||
draggable_body: true,
|
|
||||||
allow_context_menu: false,
|
|
||||||
is_resizable: false,
|
|
||||||
is_droppable: false,
|
|
||||||
init_center: true,
|
|
||||||
allow_native_ctxmenu: false,
|
|
||||||
allow_user_select: false,
|
|
||||||
window_class: 'window-newfolder-progress',
|
|
||||||
width: 450,
|
|
||||||
dominant: true,
|
|
||||||
window_css:{
|
|
||||||
height: 'initial',
|
|
||||||
},
|
|
||||||
body_css: {
|
|
||||||
padding: '22px',
|
|
||||||
width: 'initial',
|
|
||||||
'background-color': 'rgba(231, 238, 245, .95)',
|
|
||||||
'backdrop-filter': 'blur(3px)',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(el_window).find('.newfolder-cancel-btn').on('click', function(e){
|
|
||||||
window.operation_cancelled[options.operation_id] = true;
|
|
||||||
$(el_window).close();
|
|
||||||
})
|
|
||||||
|
|
||||||
return el_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UIWindowProgressEmptyTrash
|
|
@ -88,14 +88,7 @@ async function UIWindowQR(options){
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
// component_qr.attach(placeholder_qr);
|
|
||||||
component_flexer.attach(placeholder_qr);
|
component_flexer.attach(placeholder_qr);
|
||||||
// placeholder_qr.replaceWith($(`<h1>test</h1>`).get(0));
|
|
||||||
|
|
||||||
$(el_window).find('.qr-code-checkbox input').on('change', () => {
|
|
||||||
const all_checked = $(el_window).find('.qr-code-checkbox input').toArray().every(el => el.checked);
|
|
||||||
$(el_window).find('.code-confirm-btn').prop('disabled', !all_checked);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UIWindowQR
|
export default UIWindowQR
|
@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2024 Puter Technologies Inc.
|
|
||||||
*
|
|
||||||
* This file is part of Puter.
|
|
||||||
*
|
|
||||||
* Puter is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published
|
|
||||||
* by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import UIWindow from './UIWindow.js'
|
|
||||||
|
|
||||||
// todo do this using uid rather than item_path, since item_path is way mroe expensive on the DB
|
|
||||||
async function UIWindowUploadProgress(options){
|
|
||||||
let h = '';
|
|
||||||
h += `<div data-upload-operation-id="${options.operation_id}">`;
|
|
||||||
h += `<div>`;
|
|
||||||
// spinner
|
|
||||||
h +=`<svg style="float:left; margin-right: 7px;" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><title>circle anim</title><g fill="#212121" class="nc-icon-wrapper"><g class="nc-loop-circle-24-icon-f"><path d="M12 24a12 12 0 1 1 12-12 12.013 12.013 0 0 1-12 12zm0-22a10 10 0 1 0 10 10A10.011 10.011 0 0 0 12 2z" fill="#212121" opacity=".4"></path><path d="M24 12h-2A10.011 10.011 0 0 0 12 2V0a12.013 12.013 0 0 1 12 12z" data-color="color-2"></path></g><style>.nc-loop-circle-24-icon-f{--animation-duration:0.5s;transform-origin:12px 12px;animation:nc-loop-circle-anim var(--animation-duration) infinite linear}@keyframes nc-loop-circle-anim{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}</style></g></svg>`;
|
|
||||||
// Progress report
|
|
||||||
h +=`<div style="margin-bottom:20px; float:left; padding-top:3px; font-size:15px; overflow: hidden; width: calc(100% - 40px); text-overflow: ellipsis; white-space: nowrap;">`;
|
|
||||||
// msg
|
|
||||||
h += `<span class="upload-progress-msg">${i18n('preparing_for_upload')}</span>`;
|
|
||||||
h += `</div>`;
|
|
||||||
// progress
|
|
||||||
h += `<div class="upload-progress-bar-container" style="clear:both; margin-top:20px; border-radius:3px;">`;
|
|
||||||
h += `<div class="upload-progress-bar"></div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
// cancel
|
|
||||||
h += `<button style="float:right; margin-top: 15px; margin-right: -2px;" class="button button-small upload-cancel-btn">${i18n('cancel')}</button>`;
|
|
||||||
h +=`</div>`;
|
|
||||||
h += `</div>`;
|
|
||||||
|
|
||||||
const el_window = await UIWindow({
|
|
||||||
title: i18n('upload'),
|
|
||||||
icon: window.icons[`app-icon-uploader.svg`],
|
|
||||||
uid: null,
|
|
||||||
is_dir: false,
|
|
||||||
body_content: h,
|
|
||||||
has_head: false,
|
|
||||||
selectable_body: false,
|
|
||||||
draggable_body: true,
|
|
||||||
allow_context_menu: false,
|
|
||||||
is_resizable: false,
|
|
||||||
is_droppable: false,
|
|
||||||
init_center: true,
|
|
||||||
allow_native_ctxmenu: false,
|
|
||||||
allow_user_select: false,
|
|
||||||
window_class: 'window-upload-progress',
|
|
||||||
width: 450,
|
|
||||||
dominant: true,
|
|
||||||
window_css:{
|
|
||||||
height: 'initial',
|
|
||||||
},
|
|
||||||
body_css: {
|
|
||||||
padding: '22px',
|
|
||||||
width: 'initial',
|
|
||||||
'background-color': 'rgba(231, 238, 245, .95)',
|
|
||||||
'backdrop-filter': 'blur(3px)',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return el_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UIWindowUploadProgress
|
|
@ -2625,16 +2625,6 @@ fieldset[name=number-code] {
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.qr-code-checkbox {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.qr-code-checkbox input[type=checkbox] {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.perm-title {
|
.perm-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@ -2718,17 +2708,19 @@ fieldset[name=number-code] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-progress-bar-container, .download-progress-bar-container {
|
.progress-bar-container {
|
||||||
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 15px;
|
height: 17px;
|
||||||
border: 1px solid rgb(40 109 157);
|
border: 1px solid rgb(40 109 157);
|
||||||
|
border-radius: 3px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
box-shadow: inset -1px 3px 4px #dfdfdf;
|
box-shadow: inset -1px 3px 4px #dfdfdf;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upload-progress-bar, .download-progress-bar {
|
.progress-bar {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 15px;
|
height: 100%;
|
||||||
background-color: rgb(0 137 255);
|
background-color: rgb(0 137 255);
|
||||||
transition: 0.4s width;
|
transition: 0.4s width;
|
||||||
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.05));
|
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.05));
|
||||||
@ -3947,4 +3939,4 @@ fieldset[name=number-code] {
|
|||||||
.taskmgr-task-title {
|
.taskmgr-task-title {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding-left: calc(2.5 * var(--scale));
|
padding-left: calc(2.5 * var(--scale));
|
||||||
}
|
}
|
||||||
|
154
src/helpers.js
154
src/helpers.js
@ -24,16 +24,11 @@ import UIItem from './UI/UIItem.js'
|
|||||||
import UIWindow from './UI/UIWindow.js'
|
import UIWindow from './UI/UIWindow.js'
|
||||||
import UIWindowLogin from './UI/UIWindowLogin.js';
|
import UIWindowLogin from './UI/UIWindowLogin.js';
|
||||||
import UIWindowSaveAccount from './UI/UIWindowSaveAccount.js';
|
import UIWindowSaveAccount from './UI/UIWindowSaveAccount.js';
|
||||||
import UIWindowCopyProgress from './UI/UIWindowCopyProgress.js';
|
|
||||||
import UIWindowMoveProgress from './UI/UIWindowMoveProgress.js';
|
|
||||||
import UIWindowNewFolderProgress from './UI/UIWindowNewFolderProgress.js';
|
|
||||||
import UIWindowUploadProgress from './UI/UIWindowUploadProgress.js';
|
|
||||||
import UIWindowProgressEmptyTrash from './UI/UIWindowProgressEmptyTrash.js';
|
|
||||||
import update_username_in_gui from './helpers/update_username_in_gui.js';
|
import update_username_in_gui from './helpers/update_username_in_gui.js';
|
||||||
import update_title_based_on_uploads from './helpers/update_title_based_on_uploads.js';
|
import update_title_based_on_uploads from './helpers/update_title_based_on_uploads.js';
|
||||||
import content_type_to_icon from './helpers/content_type_to_icon.js';
|
import content_type_to_icon from './helpers/content_type_to_icon.js';
|
||||||
import UIWindowDownloadDirProg from './UI/UIWindowDownloadDirProg.js';
|
|
||||||
import { PROCESS_RUNNING, PortalProcess, PseudoProcess } from "./definitions.js";
|
import { PROCESS_RUNNING, PortalProcess, PseudoProcess } from "./definitions.js";
|
||||||
|
import UIWindowProgress from './UI/UIWindowProgress.js';
|
||||||
|
|
||||||
window.is_auth = ()=>{
|
window.is_auth = ()=>{
|
||||||
if(localStorage.getItem("auth_token") === null || window.auth_token === null)
|
if(localStorage.getItem("auth_token") === null || window.auth_token === null)
|
||||||
@ -1166,7 +1161,14 @@ window.create_folder = async(basedir, appendto_element)=>{
|
|||||||
|
|
||||||
// only show progress window if it takes longer than 500ms to create folder
|
// only show progress window if it takes longer than 500ms to create folder
|
||||||
let progwin_timeout = setTimeout(async () => {
|
let progwin_timeout = setTimeout(async () => {
|
||||||
progwin = await UIWindowNewFolderProgress({operation_id: newfolder_op_id});
|
progwin = await UIWindowProgress({
|
||||||
|
operation_id: newfolder_op_id,
|
||||||
|
// TODO: Implement cancellation.
|
||||||
|
// on_cancel: () => {
|
||||||
|
// window.operation_cancelled[newfolder_op_id] = true;
|
||||||
|
// },
|
||||||
|
});
|
||||||
|
progwin.set_status(i18n('taking_longer_than_usual'));
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
// create folder
|
// create folder
|
||||||
@ -1190,14 +1192,16 @@ window.create_folder = async(basedir, appendto_element)=>{
|
|||||||
|
|
||||||
// done
|
// done
|
||||||
let newfolder_duration = (Date.now() - newfolder_progress_window_init_ts);
|
let newfolder_duration = (Date.now() - newfolder_progress_window_init_ts);
|
||||||
if( progwin && newfolder_duration >= window.copy_progress_hide_delay){
|
if (progwin) {
|
||||||
$(progwin).close();
|
if (newfolder_duration >= window.copy_progress_hide_delay) {
|
||||||
}else if(progwin){
|
progwin.close();
|
||||||
setTimeout(() => {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
setTimeout(() => {
|
||||||
}, Math.abs(window.copy_progress_hide_delay - newfolder_duration));
|
progwin.close();
|
||||||
})
|
}, Math.abs(window.copy_progress_hide_delay - newfolder_duration));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1267,8 +1271,13 @@ window.copy_clipboard_items = async function(dest_path, dest_container_element){
|
|||||||
// only show progress window if it takes longer than 2s to copy
|
// only show progress window if it takes longer than 2s to copy
|
||||||
let progwin;
|
let progwin;
|
||||||
let progwin_timeout = setTimeout(async () => {
|
let progwin_timeout = setTimeout(async () => {
|
||||||
progwin = await UIWindowCopyProgress({operation_id: copy_op_id});
|
progwin = await UIWindowProgress({
|
||||||
}, 2000);
|
operation_id: copy_op_id,
|
||||||
|
on_cancel: () => {
|
||||||
|
window.operation_cancelled[copy_op_id] = true;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, 0);
|
||||||
|
|
||||||
const copied_item_paths = []
|
const copied_item_paths = []
|
||||||
|
|
||||||
@ -1276,7 +1285,8 @@ window.copy_clipboard_items = async function(dest_path, dest_container_element){
|
|||||||
let copy_path = window.clipboard[i].path;
|
let copy_path = window.clipboard[i].path;
|
||||||
let item_with_same_name_already_exists = true;
|
let item_with_same_name_already_exists = true;
|
||||||
let overwrite = overwrite_all;
|
let overwrite = overwrite_all;
|
||||||
$(progwin).find('.copy-from').html(html_encode(copy_path));
|
progwin?.set_status(i18n('copying_file', copy_path));
|
||||||
|
|
||||||
do{
|
do{
|
||||||
if(overwrite)
|
if(overwrite)
|
||||||
item_with_same_name_already_exists = false;
|
item_with_same_name_already_exists = false;
|
||||||
@ -1344,14 +1354,16 @@ window.copy_clipboard_items = async function(dest_path, dest_container_element){
|
|||||||
clearTimeout(progwin_timeout);
|
clearTimeout(progwin_timeout);
|
||||||
|
|
||||||
let copy_duration = (Date.now() - copy_progress_window_init_ts);
|
let copy_duration = (Date.now() - copy_progress_window_init_ts);
|
||||||
if(progwin && copy_duration >= window.copy_progress_hide_delay){
|
if (progwin) {
|
||||||
$(progwin).close();
|
if (copy_duration >= window.copy_progress_hide_delay) {
|
||||||
}else if(progwin){
|
progwin.close();
|
||||||
setTimeout(() => {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
setTimeout(() => {
|
||||||
}, Math.abs(window.copy_progress_hide_delay - copy_duration));
|
progwin.close();
|
||||||
})
|
}, Math.abs(window.copy_progress_hide_delay - copy_duration));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
@ -1371,7 +1383,12 @@ window.copy_items = function(el_items, dest_path){
|
|||||||
// only show progress window if it takes longer than 2s to copy
|
// only show progress window if it takes longer than 2s to copy
|
||||||
let progwin;
|
let progwin;
|
||||||
let progwin_timeout = setTimeout(async () => {
|
let progwin_timeout = setTimeout(async () => {
|
||||||
progwin = await UIWindowCopyProgress({operation_id: copy_op_id});
|
progwin = await UIWindowProgress({
|
||||||
|
operation_id: copy_op_id,
|
||||||
|
on_cancel: () => {
|
||||||
|
window.operation_cancelled[copy_op_id] = true;
|
||||||
|
},
|
||||||
|
});
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
const copied_item_paths = []
|
const copied_item_paths = []
|
||||||
@ -1380,7 +1397,7 @@ window.copy_items = function(el_items, dest_path){
|
|||||||
let copy_path = $(el_items[i]).attr('data-path');
|
let copy_path = $(el_items[i]).attr('data-path');
|
||||||
let item_with_same_name_already_exists = true;
|
let item_with_same_name_already_exists = true;
|
||||||
let overwrite = overwrite_all;
|
let overwrite = overwrite_all;
|
||||||
$(progwin).find('.copy-from').html(html_encode(copy_path));
|
progwin?.set_status(i18n('copying_file', copy_path));
|
||||||
|
|
||||||
do{
|
do{
|
||||||
if(overwrite)
|
if(overwrite)
|
||||||
@ -1449,14 +1466,16 @@ window.copy_items = function(el_items, dest_path){
|
|||||||
clearTimeout(progwin_timeout);
|
clearTimeout(progwin_timeout);
|
||||||
|
|
||||||
let copy_duration = (Date.now() - copy_progress_window_init_ts);
|
let copy_duration = (Date.now() - copy_progress_window_init_ts);
|
||||||
if(progwin && copy_duration >= window.copy_progress_hide_delay){
|
if (progwin) {
|
||||||
$(progwin).close();
|
if (copy_duration >= window.copy_progress_hide_delay) {
|
||||||
}else if(progwin){
|
progwin.close();
|
||||||
setTimeout(() => {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
setTimeout(() => {
|
||||||
}, Math.abs(window.copy_progress_hide_delay - copy_duration));
|
progwin.close();
|
||||||
})
|
}, Math.abs(window.copy_progress_hide_delay - copy_duration));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
}
|
}
|
||||||
@ -2125,7 +2144,12 @@ window.move_items = async function(el_items, dest_path, is_undo = false){
|
|||||||
// only show progress window if it takes longer than 2s to move
|
// only show progress window if it takes longer than 2s to move
|
||||||
let progwin;
|
let progwin;
|
||||||
let progwin_timeout = setTimeout(async () => {
|
let progwin_timeout = setTimeout(async () => {
|
||||||
progwin = await UIWindowMoveProgress({operation_id: move_op_id});
|
progwin = await UIWindowProgress({
|
||||||
|
operation_id: move_op_id,
|
||||||
|
on_cancel: () => {
|
||||||
|
window.operation_cancelled[move_op_id] = true;
|
||||||
|
},
|
||||||
|
});
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
// storing moved items for undo ability
|
// storing moved items for undo ability
|
||||||
@ -2188,6 +2212,8 @@ window.move_items = async function(el_items, dest_path, is_undo = false){
|
|||||||
// indicates whether this is a recycling operation
|
// indicates whether this is a recycling operation
|
||||||
let recycling = false;
|
let recycling = false;
|
||||||
|
|
||||||
|
let status_i18n_string = 'moving_file';
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// Trashing
|
// Trashing
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
@ -2199,6 +2225,8 @@ window.move_items = async function(el_items, dest_path, is_undo = false){
|
|||||||
trashed_ts: Math.round(Date.now() / 1000),
|
trashed_ts: Math.round(Date.now() / 1000),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
status_i18n_string = 'deleting_file';
|
||||||
|
|
||||||
// update other clients
|
// update other clients
|
||||||
if(window.socket)
|
if(window.socket)
|
||||||
window.socket.emit('trash.is_empty', {is_empty: false});
|
window.socket.emit('trash.is_empty', {is_empty: false});
|
||||||
@ -2211,7 +2239,7 @@ window.move_items = async function(el_items, dest_path, is_undo = false){
|
|||||||
|
|
||||||
// moving an item into a trashed directory? deny.
|
// moving an item into a trashed directory? deny.
|
||||||
else if(dest_path.startsWith(window.trash_path)){
|
else if(dest_path.startsWith(window.trash_path)){
|
||||||
$(progwin).close();
|
progwin?.close();
|
||||||
UIAlert('Cannot move items into a deleted folder.');
|
UIAlert('Cannot move items into a deleted folder.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2230,7 +2258,7 @@ window.move_items = async function(el_items, dest_path, is_undo = false){
|
|||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// update progress window with current item being moved
|
// update progress window with current item being moved
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
$(progwin).find('.move-from').html(html_encode(path_to_show_on_progwin));
|
progwin?.set_status(i18n(status_i18n_string, path_to_show_on_progwin));
|
||||||
|
|
||||||
// execute move
|
// execute move
|
||||||
let resp = await puter.fs.move({
|
let resp = await puter.fs.move({
|
||||||
@ -2437,7 +2465,7 @@ window.move_items = async function(el_items, dest_path, is_undo = false){
|
|||||||
|
|
||||||
if(progwin){
|
if(progwin){
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
progwin.close();
|
||||||
}, window.copy_progress_hide_delay);
|
}, window.copy_progress_hide_delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2685,25 +2713,28 @@ window.upload_items = async function(items, dest_path){
|
|||||||
init: async(operation_id, xhr)=>{
|
init: async(operation_id, xhr)=>{
|
||||||
opid = operation_id;
|
opid = operation_id;
|
||||||
// create upload progress window
|
// create upload progress window
|
||||||
upload_progress_window = await UIWindowUploadProgress({operation_id: operation_id});
|
upload_progress_window = await UIWindowProgress({
|
||||||
// cancel btn
|
title: i18n('upload'),
|
||||||
$(upload_progress_window).find('.upload-cancel-btn').on('click', function(e){
|
icon: window.icons[`app-icon-uploader.svg`],
|
||||||
$(upload_progress_window).close();
|
operation_id: operation_id,
|
||||||
window.show_save_account_notice_if_needed();
|
show_progress: true,
|
||||||
xhr.abort();
|
on_cancel: () => {
|
||||||
})
|
window.show_save_account_notice_if_needed();
|
||||||
|
xhr.abort();
|
||||||
|
},
|
||||||
|
});
|
||||||
// add to active_uploads
|
// add to active_uploads
|
||||||
window.active_uploads[opid] = 0;
|
window.active_uploads[opid] = 0;
|
||||||
},
|
},
|
||||||
// start
|
// start
|
||||||
start: async function(){
|
start: async function(){
|
||||||
// change upload progress window message to uploading
|
// change upload progress window message to uploading
|
||||||
$(upload_progress_window).find('.upload-progress-msg').html(`Uploading (<span class="upload-progress-percent">0%</span>)`);
|
upload_progress_window.set_status('Uploading');
|
||||||
|
upload_progress_window.set_progress(0);
|
||||||
},
|
},
|
||||||
// progress
|
// progress
|
||||||
progress: async function(operation_id, op_progress){
|
progress: async function(operation_id, op_progress){
|
||||||
$(`[data-upload-operation-id="${operation_id}"]`).find('.upload-progress-bar').css( 'width', op_progress+'%');
|
upload_progress_window.set_progress(op_progress);
|
||||||
$(`[data-upload-operation-id="${operation_id}"]`).find('.upload-progress-percent').html(op_progress+'%');
|
|
||||||
// update active_uploads
|
// update active_uploads
|
||||||
window.active_uploads[opid] = op_progress;
|
window.active_uploads[opid] = op_progress;
|
||||||
// update title if window is not visible
|
// update title if window is not visible
|
||||||
@ -2731,7 +2762,7 @@ window.upload_items = async function(items, dest_path){
|
|||||||
// close progress window after a bit of delay for a better UX
|
// close progress window after a bit of delay for a better UX
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(upload_progress_window).close();
|
upload_progress_window.close();
|
||||||
window.show_save_account_notice_if_needed();
|
window.show_save_account_notice_if_needed();
|
||||||
}, Math.abs(window.upload_progress_hide_delay));
|
}, Math.abs(window.upload_progress_hide_delay));
|
||||||
})
|
})
|
||||||
@ -2740,8 +2771,7 @@ window.upload_items = async function(items, dest_path){
|
|||||||
},
|
},
|
||||||
// error
|
// error
|
||||||
error: async function(err){
|
error: async function(err){
|
||||||
$(upload_progress_window).close();
|
upload_progress_window.show_error(i18n('error_uploading_files'), err.message);
|
||||||
// UIAlert(err?.message ?? 'An error occurred while uploading.');
|
|
||||||
// remove from active_uploads
|
// remove from active_uploads
|
||||||
delete window.active_uploads[opid];
|
delete window.active_uploads[opid];
|
||||||
},
|
},
|
||||||
@ -2778,7 +2808,8 @@ window.empty_trash = async function(){
|
|||||||
let progwin;
|
let progwin;
|
||||||
let op_id = window.uuidv4();
|
let op_id = window.uuidv4();
|
||||||
let progwin_timeout = setTimeout(async () => {
|
let progwin_timeout = setTimeout(async () => {
|
||||||
progwin = await UIWindowProgressEmptyTrash({operation_id: op_id});
|
progwin = await UIWindowProgress({operation_id: op_id});
|
||||||
|
progwin.set_status(i18n('emptying_trash'));
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
await puter.fs.delete({
|
await puter.fs.delete({
|
||||||
@ -2802,13 +2833,13 @@ window.empty_trash = async function(){
|
|||||||
// close progress window
|
// close progress window
|
||||||
clearTimeout(progwin_timeout);
|
clearTimeout(progwin_timeout);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
progwin?.close();
|
||||||
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - init_ts)));
|
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - init_ts)));
|
||||||
},
|
},
|
||||||
error: async function (err){
|
error: async function (err){
|
||||||
clearTimeout(progwin_timeout);
|
clearTimeout(progwin_timeout);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
progwin?.close();
|
||||||
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - init_ts)));
|
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - init_ts)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -2931,14 +2962,14 @@ window.zipItems = async function(el_items, targetDirPath, download = true) {
|
|||||||
let progwin, progwin_timeout;
|
let progwin, progwin_timeout;
|
||||||
// only show progress window if it takes longer than 500ms to download
|
// only show progress window if it takes longer than 500ms to download
|
||||||
progwin_timeout = setTimeout(async () => {
|
progwin_timeout = setTimeout(async () => {
|
||||||
progwin = await UIWindowDownloadDirProg();
|
progwin = await UIWindowProgress();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
for (const el_item of el_items) {
|
for (const el_item of el_items) {
|
||||||
let targetPath = $(el_item).attr('data-path');
|
let targetPath = $(el_item).attr('data-path');
|
||||||
// if directory, zip the directory
|
// if directory, zip the directory
|
||||||
if($(el_item).attr('data-is_dir') === '1'){
|
if($(el_item).attr('data-is_dir') === '1'){
|
||||||
$(progwin).find('.dir-dl-status').html(`Reading <strong>${html_encode(targetPath)}</strong>`);
|
progwin?.set_status(i18n('reading_file', targetPath));
|
||||||
// Recursively read the directory
|
// Recursively read the directory
|
||||||
let children = await readDirectoryRecursive(targetPath);
|
let children = await readDirectoryRecursive(targetPath);
|
||||||
|
|
||||||
@ -2951,7 +2982,7 @@ window.zipItems = async function(el_items, targetDirPath, download = true) {
|
|||||||
relativePath = path.basename(targetPath) + '/' + child.relativePath;
|
relativePath = path.basename(targetPath) + '/' + child.relativePath;
|
||||||
|
|
||||||
// update progress window
|
// update progress window
|
||||||
$(progwin).find('.dir-dl-status').html(`Zipping <strong>${html_encode(relativePath)}</strong>`);
|
progwin?.set_status(i18n('zipping_file', relativePath));
|
||||||
|
|
||||||
// read file content
|
// read file content
|
||||||
let content = await puter.fs.read(child.path);
|
let content = await puter.fs.read(child.path);
|
||||||
@ -3000,17 +3031,18 @@ window.zipItems = async function(el_items, targetDirPath, download = true) {
|
|||||||
// close progress window
|
// close progress window
|
||||||
clearTimeout(progwin_timeout);
|
clearTimeout(progwin_timeout);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
progwin?.close();
|
||||||
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - start_ts)));
|
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - start_ts)));
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
// close progress window
|
// close progress window
|
||||||
clearTimeout(progwin_timeout);
|
clearTimeout(progwin_timeout);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
progwin?.close();
|
||||||
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - start_ts)));
|
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - start_ts)));
|
||||||
|
|
||||||
// handle errors
|
// handle errors
|
||||||
|
// TODO: Display in progress dialog
|
||||||
console.error("Error in zipping files: ", err);
|
console.error("Error in zipping files: ", err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -3053,7 +3085,7 @@ window.unzipItem = async function(itemPath) {
|
|||||||
let progwin, progwin_timeout;
|
let progwin, progwin_timeout;
|
||||||
// only show progress window if it takes longer than 500ms to download
|
// only show progress window if it takes longer than 500ms to download
|
||||||
progwin_timeout = setTimeout(async () => {
|
progwin_timeout = setTimeout(async () => {
|
||||||
progwin = await UIWindowDownloadDirProg();
|
progwin = await UIWindowProgress();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
const zip = new JSZip();
|
const zip = new JSZip();
|
||||||
@ -3075,7 +3107,7 @@ window.unzipItem = async function(itemPath) {
|
|||||||
// close progress window
|
// close progress window
|
||||||
clearTimeout(progwin_timeout);
|
clearTimeout(progwin_timeout);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
progwin?.close();
|
||||||
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - start_ts)));
|
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - start_ts)));
|
||||||
|
|
||||||
}).catch(function (e) {
|
}).catch(function (e) {
|
||||||
@ -3083,7 +3115,7 @@ window.unzipItem = async function(itemPath) {
|
|||||||
// close progress window
|
// close progress window
|
||||||
clearTimeout(progwin_timeout);
|
clearTimeout(progwin_timeout);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$(progwin).close();
|
progwin?.close();
|
||||||
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - start_ts)));
|
}, Math.max(0, window.copy_progress_hide_delay - (Date.now() - start_ts)));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -109,9 +109,6 @@ const download = function(options){
|
|||||||
let batch_progress = ((batch_download_progress[0].cloud_uploaded + batch_download_progress[0].downloaded)/batch_download_progress[0].total * 100).toFixed(0);
|
let batch_progress = ((batch_download_progress[0].cloud_uploaded + batch_download_progress[0].downloaded)/batch_download_progress[0].total * 100).toFixed(0);
|
||||||
batch_progress = batch_progress > 100 ? 100 : batch_progress;
|
batch_progress = batch_progress > 100 ? 100 : batch_progress;
|
||||||
|
|
||||||
// Update the progress bar
|
|
||||||
$(`[data-download-operation-id="${options.operation_id}"]`).find('.download-progress-bar').css( 'width', batch_progress+'%');
|
|
||||||
|
|
||||||
// If download is finished resolve promise
|
// If download is finished resolve promise
|
||||||
if((item_progress >= 1 || item_progress === 0) && item){
|
if((item_progress >= 1 || item_progress === 0) && item){
|
||||||
// For a better UX, resolve 0.5 second after operation is finished.
|
// For a better UX, resolve 0.5 second after operation is finished.
|
||||||
|
@ -83,7 +83,7 @@ const ar = {
|
|||||||
log_in: "تسجيل الدخول",
|
log_in: "تسجيل الدخول",
|
||||||
log_out: 'تسجيل خروج',
|
log_out: 'تسجيل خروج',
|
||||||
move: 'يتحرك',
|
move: 'يتحرك',
|
||||||
moving: "متحرك ",
|
moving_file: "متحرك %%",
|
||||||
my_websites: "مواقعي الإلكترونية ",
|
my_websites: "مواقعي الإلكترونية ",
|
||||||
name: 'اسم',
|
name: 'اسم',
|
||||||
name_cannot_be_empty: 'لا يمكن أن يكون الاسم فارغًا',
|
name_cannot_be_empty: 'لا يمكن أن يكون الاسم فارغًا',
|
||||||
|
@ -82,7 +82,7 @@ const bn = {
|
|||||||
log_in: "প্রবেশ করুন",
|
log_in: "প্রবেশ করুন",
|
||||||
log_out: 'প্রস্থান',
|
log_out: 'প্রস্থান',
|
||||||
move: 'সরান',
|
move: 'সরান',
|
||||||
moving: "চলন্ত",
|
moving_file: "চলন্ত %%",
|
||||||
my_websites: "আমার ওয়েবসাইট",
|
my_websites: "আমার ওয়েবসাইট",
|
||||||
name: 'নাম',
|
name: 'নাম',
|
||||||
name_cannot_be_empty: 'নাম খালি রাখা যাবে না।',
|
name_cannot_be_empty: 'নাম খালি রাখা যাবে না।',
|
||||||
|
@ -102,7 +102,7 @@ const br = {
|
|||||||
log_into_another_account_anyway: 'Entrar com outra conta de qualquer maneira',
|
log_into_another_account_anyway: 'Entrar com outra conta de qualquer maneira',
|
||||||
log_out: 'Sair',
|
log_out: 'Sair',
|
||||||
move: 'Mover',
|
move: 'Mover',
|
||||||
moving: "Movendo",
|
moving_file: "Movendo %%",
|
||||||
my_websites: "Meus Sites",
|
my_websites: "Meus Sites",
|
||||||
name: 'Nome',
|
name: 'Nome',
|
||||||
name_cannot_be_empty: 'Nome não pode ser vazio.',
|
name_cannot_be_empty: 'Nome não pode ser vazio.',
|
||||||
|
@ -83,7 +83,7 @@ const da = {
|
|||||||
log_in: "Log ind",
|
log_in: "Log ind",
|
||||||
log_out: "Log ud",
|
log_out: "Log ud",
|
||||||
move: "Flyt",
|
move: "Flyt",
|
||||||
moving: "Flytter",
|
moving_file: "Flytter %%",
|
||||||
my_websites: "Mine websteder",
|
my_websites: "Mine websteder",
|
||||||
name: "Navn",
|
name: "Navn",
|
||||||
name_cannot_be_empty: "Navn kan ikke være tomt.",
|
name_cannot_be_empty: "Navn kan ikke være tomt.",
|
||||||
|
@ -83,7 +83,7 @@ const de = {
|
|||||||
log_in: "Einloggen",
|
log_in: "Einloggen",
|
||||||
log_out: 'Ausloggen',
|
log_out: 'Ausloggen',
|
||||||
move: 'Verschieben',
|
move: 'Verschieben',
|
||||||
moving: "Verschiebe",
|
moving_file: "Verschiebe %%",
|
||||||
my_websites: "Meine Webseiten",
|
my_websites: "Meine Webseiten",
|
||||||
name: 'Name',
|
name: 'Name',
|
||||||
name_cannot_be_empty: 'Name kann nicht leer sein.',
|
name_cannot_be_empty: 'Name kann nicht leer sein.',
|
||||||
|
@ -92,7 +92,7 @@ const emoji = {
|
|||||||
log_into_another_account_anyway: '👤🔄',
|
log_into_another_account_anyway: '👤🔄',
|
||||||
log_out: '🔚',
|
log_out: '🔚',
|
||||||
move: '➡️',
|
move: '➡️',
|
||||||
moving: "➡️...",
|
moving_file: "➡️ %%...",
|
||||||
my_websites: "🌐👤",
|
my_websites: "🌐👤",
|
||||||
name: '📛',
|
name: '📛',
|
||||||
name_cannot_be_empty: '📛❌',
|
name_cannot_be_empty: '📛❌',
|
||||||
|
@ -71,6 +71,7 @@ const en = {
|
|||||||
copy: 'Copy',
|
copy: 'Copy',
|
||||||
copy_link: "Copy Link",
|
copy_link: "Copy Link",
|
||||||
copying: "Copying",
|
copying: "Copying",
|
||||||
|
copying_file: "Copying %%",
|
||||||
cover: 'Cover',
|
cover: 'Cover',
|
||||||
create_account: "Create Account",
|
create_account: "Create Account",
|
||||||
create_free_account: "Create Free Account",
|
create_free_account: "Create Free Account",
|
||||||
@ -87,6 +88,7 @@ const en = {
|
|||||||
delete: 'Delete',
|
delete: 'Delete',
|
||||||
delete_account: "Delete Account",
|
delete_account: "Delete Account",
|
||||||
delete_permanently: "Delete Permanently",
|
delete_permanently: "Delete Permanently",
|
||||||
|
deleting_file: "Deleting %%",
|
||||||
deploy_as_app: 'Deploy as app',
|
deploy_as_app: 'Deploy as app',
|
||||||
descending: 'Descending',
|
descending: 'Descending',
|
||||||
desktop_background_fit: "Fit",
|
desktop_background_fit: "Fit",
|
||||||
@ -113,6 +115,7 @@ const en = {
|
|||||||
enlarged_qr_code: "Enlarged QR Code",
|
enlarged_qr_code: "Enlarged QR Code",
|
||||||
enter_password_to_confirm_delete_user: "Enter your password to confirm account deletion",
|
enter_password_to_confirm_delete_user: "Enter your password to confirm account deletion",
|
||||||
error_unknown_cause: "An unknown error occurred.",
|
error_unknown_cause: "An unknown error occurred.",
|
||||||
|
error_uploading_files: "Failed to upload files",
|
||||||
feedback: "Feedback",
|
feedback: "Feedback",
|
||||||
feedback_c2a: "Please use the form below to send us your feedback, comments, and bug reports.",
|
feedback_c2a: "Please use the form below to send us your feedback, comments, and bug reports.",
|
||||||
feedback_sent_confirmation: "Thank you for contacting us. If you have an email associated with your account, you will hear back from us as soon as possible.",
|
feedback_sent_confirmation: "Thank you for contacting us. If you have an email associated with your account, you will hear back from us as soon as possible.",
|
||||||
@ -143,7 +146,7 @@ const en = {
|
|||||||
looks_good: "Looks good!",
|
looks_good: "Looks good!",
|
||||||
manage_sessions: "Manage Sessions",
|
manage_sessions: "Manage Sessions",
|
||||||
move: 'Move',
|
move: 'Move',
|
||||||
moving: "Moving",
|
moving_file: "Moving %%",
|
||||||
my_websites: "My Websites",
|
my_websites: "My Websites",
|
||||||
name: 'Name',
|
name: 'Name',
|
||||||
name_cannot_be_empty: 'Name cannot be empty.',
|
name_cannot_be_empty: 'Name cannot be empty.',
|
||||||
@ -197,6 +200,7 @@ const en = {
|
|||||||
publish_as_website: 'Publish as website',
|
publish_as_website: 'Publish as website',
|
||||||
puter_description: `Puter is a privacy-first personal cloud to keep all your files, apps, and games in one
|
puter_description: `Puter is a privacy-first personal cloud to keep all your files, apps, and games in one
|
||||||
secure place, accessible from anywhere at any time.`,
|
secure place, accessible from anywhere at any time.`,
|
||||||
|
reading_file: "Reading %strong%",
|
||||||
recent: "Recent",
|
recent: "Recent",
|
||||||
recommended: "Recommended",
|
recommended: "Recommended",
|
||||||
recover_password: "Recover Password",
|
recover_password: "Recover Password",
|
||||||
@ -280,6 +284,7 @@ const en = {
|
|||||||
yes_release_it: 'Yes, Release It',
|
yes_release_it: 'Yes, Release It',
|
||||||
you_have_been_referred_to_puter_by_a_friend: "You have been referred to Puter by a friend!",
|
you_have_been_referred_to_puter_by_a_friend: "You have been referred to Puter by a friend!",
|
||||||
zip: "Zip",
|
zip: "Zip",
|
||||||
|
zipping_file: "Zipping %strong%",
|
||||||
|
|
||||||
// === 2FA Setup ===
|
// === 2FA Setup ===
|
||||||
setup2fa_1_step_heading: 'Open your authenticator app',
|
setup2fa_1_step_heading: 'Open your authenticator app',
|
||||||
|
@ -83,7 +83,7 @@ const es = {
|
|||||||
log_in: "Iniciar sesión",
|
log_in: "Iniciar sesión",
|
||||||
log_out: 'Cerrar sesión',
|
log_out: 'Cerrar sesión',
|
||||||
move: 'Mover',
|
move: 'Mover',
|
||||||
moving: "Moviendo",
|
moving_file: "Moviendo %%",
|
||||||
my_websites: "Mis páginas web",
|
my_websites: "Mis páginas web",
|
||||||
name: 'Nombre',
|
name: 'Nombre',
|
||||||
name_cannot_be_empty: 'El nombre no puede estar vacío.',
|
name_cannot_be_empty: 'El nombre no puede estar vacío.',
|
||||||
|
@ -84,7 +84,7 @@ const fa = {
|
|||||||
log_in: "ورود",
|
log_in: "ورود",
|
||||||
log_out: 'خروج',
|
log_out: 'خروج',
|
||||||
move: 'انتقال',
|
move: 'انتقال',
|
||||||
moving: "انتقال",
|
moving_file: "انتقال %%",
|
||||||
my_websites: "وبسایت های من",
|
my_websites: "وبسایت های من",
|
||||||
name: 'نام',
|
name: 'نام',
|
||||||
name_cannot_be_empty: 'نام نمی تواند خالی باشد.',
|
name_cannot_be_empty: 'نام نمی تواند خالی باشد.',
|
||||||
|
@ -116,7 +116,7 @@ const fi = {
|
|||||||
log_in: "Kirjaudu Sisään",
|
log_in: "Kirjaudu Sisään",
|
||||||
log_out: 'Kirjaudu Ulos',
|
log_out: 'Kirjaudu Ulos',
|
||||||
move: 'Siirrä',
|
move: 'Siirrä',
|
||||||
moving: "Siirretään",
|
moving_file: "Siirretään %%",
|
||||||
my_websites: "Verkkosivustoni",
|
my_websites: "Verkkosivustoni",
|
||||||
name: 'Nimi',
|
name: 'Nimi',
|
||||||
name_cannot_be_empty: 'Nimi ei voi olla tyhjä.',
|
name_cannot_be_empty: 'Nimi ei voi olla tyhjä.',
|
||||||
|
@ -82,7 +82,7 @@ const fr = {
|
|||||||
log_in: "Se connecter",
|
log_in: "Se connecter",
|
||||||
log_out: "Se déconnecter",
|
log_out: "Se déconnecter",
|
||||||
move: "Déplacer",
|
move: "Déplacer",
|
||||||
moving: "Déplacement en cours",
|
moving_file: "Déplacement en cours %%",
|
||||||
my_websites: "Mes sites web",
|
my_websites: "Mes sites web",
|
||||||
name: "Nom",
|
name: "Nom",
|
||||||
name_cannot_be_empty: "Le nom ne peut pas être vide.",
|
name_cannot_be_empty: "Le nom ne peut pas être vide.",
|
||||||
|
@ -83,7 +83,7 @@ const hy = {
|
|||||||
log_in: "Մուտք գործել",
|
log_in: "Մուտք գործել",
|
||||||
log_out: "Դուրս գալ",
|
log_out: "Դուրս գալ",
|
||||||
move: "Տեղափոխել",
|
move: "Տեղափոխել",
|
||||||
moving: "Տեղափոխվում է",
|
moving_file: "Տեղափոխվում է %%",
|
||||||
my_websites: "Իմ կայքերը",
|
my_websites: "Իմ կայքերը",
|
||||||
name: "Անուն",
|
name: "Անուն",
|
||||||
name_cannot_be_empty: "Անվան դաշտը չի կառող լինել դատարկ։",
|
name_cannot_be_empty: "Անվան դաշտը չի կառող լինել դատարկ։",
|
||||||
|
@ -126,7 +126,7 @@ const ig = {
|
|||||||
log_out: 'pụọ',
|
log_out: 'pụọ',
|
||||||
manage_sessions: "Jikwaa Oge",
|
manage_sessions: "Jikwaa Oge",
|
||||||
move: 'Bugharịa',
|
move: 'Bugharịa',
|
||||||
moving: "Na Bugharịa",
|
moving_file: "Na Bugharịa %%",
|
||||||
my_websites: "Weebụsaịtị m",
|
my_websites: "Weebụsaịtị m",
|
||||||
name: 'Aha',
|
name: 'Aha',
|
||||||
name_cannot_be_empty: 'Aha enweghị ike ịbụ ihe efu.',
|
name_cannot_be_empty: 'Aha enweghị ike ịbụ ihe efu.',
|
||||||
|
@ -83,7 +83,7 @@ const it = {
|
|||||||
log_in: "Accedi",
|
log_in: "Accedi",
|
||||||
log_out: 'Disconnettiti',
|
log_out: 'Disconnettiti',
|
||||||
move: 'Sposta',
|
move: 'Sposta',
|
||||||
moving: "Spostamento in corso",
|
moving_file: "Spostamento in corso %%",
|
||||||
my_websites: "I miei siti web",
|
my_websites: "I miei siti web",
|
||||||
name: 'Nome',
|
name: 'Nome',
|
||||||
name_cannot_be_empty: 'Il nome non può essere vuoto.',
|
name_cannot_be_empty: 'Il nome non può essere vuoto.',
|
||||||
|
@ -91,7 +91,7 @@ const ko = {
|
|||||||
log_in: "로그인",
|
log_in: "로그인",
|
||||||
log_out: '로그아웃',
|
log_out: '로그아웃',
|
||||||
move: '이동',
|
move: '이동',
|
||||||
moving: "이동 중",
|
moving_file: "이동 중 %%",
|
||||||
my_websites: "내 웹사이트",
|
my_websites: "내 웹사이트",
|
||||||
name: '이름',
|
name: '이름',
|
||||||
name_cannot_be_empty: '이름은 비워둘 수 없습니다.',
|
name_cannot_be_empty: '이름은 비워둘 수 없습니다.',
|
||||||
|
@ -92,7 +92,7 @@ const nb = {
|
|||||||
log_into_another_account_anyway: 'Logg inn på en annen bruker uansett',
|
log_into_another_account_anyway: 'Logg inn på en annen bruker uansett',
|
||||||
log_out: "Logg ut",
|
log_out: "Logg ut",
|
||||||
move: "Flytt",
|
move: "Flytt",
|
||||||
moving: "Flytter",
|
moving_file: "Flytter %%",
|
||||||
my_websites: "Mine nettsteder",
|
my_websites: "Mine nettsteder",
|
||||||
name: "Navn",
|
name: "Navn",
|
||||||
name_cannot_be_empty: "Navn kan ikke være tomt.",
|
name_cannot_be_empty: "Navn kan ikke være tomt.",
|
||||||
|
@ -102,7 +102,7 @@ const nl = {
|
|||||||
log_into_another_account_anyway: 'Alsnog met ander account inloggen',
|
log_into_another_account_anyway: 'Alsnog met ander account inloggen',
|
||||||
log_out: 'Uitloggen',
|
log_out: 'Uitloggen',
|
||||||
move: 'Verplaatsen',
|
move: 'Verplaatsen',
|
||||||
moving: "Aan het verplaatsen",
|
moving_file: "Aan het verplaatsen %%",
|
||||||
my_websites: "Mijn Websites",
|
my_websites: "Mijn Websites",
|
||||||
name: 'Naam',
|
name: 'Naam',
|
||||||
name_cannot_be_empty: 'Naam kan niet leeg zijn.',
|
name_cannot_be_empty: 'Naam kan niet leeg zijn.',
|
||||||
|
@ -83,7 +83,7 @@ const nn = {
|
|||||||
log_in: "Logg inn",
|
log_in: "Logg inn",
|
||||||
log_out: "Logg ut",
|
log_out: "Logg ut",
|
||||||
move: "Flytt",
|
move: "Flytt",
|
||||||
moving: "Flyttar",
|
moving_file: "Flyttar %%",
|
||||||
my_websites: "Mine nettstader",
|
my_websites: "Mine nettstader",
|
||||||
name: "Namn",
|
name: "Namn",
|
||||||
name_cannot_be_empty: "Namn kan ikkje vere tomt.",
|
name_cannot_be_empty: "Namn kan ikkje vere tomt.",
|
||||||
|
@ -92,7 +92,7 @@ const pl = {
|
|||||||
log_into_another_account_anyway: 'Zaloguj się do innego konta mimo wszystko',
|
log_into_another_account_anyway: 'Zaloguj się do innego konta mimo wszystko',
|
||||||
log_out: 'Wyloguj się',
|
log_out: 'Wyloguj się',
|
||||||
move: 'Przenieś',
|
move: 'Przenieś',
|
||||||
moving: "Przenoszenie",
|
moving_file: "Przenoszenie %%",
|
||||||
my_websites: "Moje strony",
|
my_websites: "Moje strony",
|
||||||
name: 'Nazwa',
|
name: 'Nazwa',
|
||||||
name_cannot_be_empty: 'Nazwa nie może być pusta.',
|
name_cannot_be_empty: 'Nazwa nie może być pusta.',
|
||||||
|
@ -106,7 +106,7 @@ const pt = {
|
|||||||
log_into_another_account_anyway: 'Entrar com outra conta na mesma',
|
log_into_another_account_anyway: 'Entrar com outra conta na mesma',
|
||||||
log_out: 'Sair',
|
log_out: 'Sair',
|
||||||
move: 'Mover',
|
move: 'Mover',
|
||||||
moving: "Movendo",
|
moving_file: "Movendo %%",
|
||||||
my_websites: "Meus Sites",
|
my_websites: "Meus Sites",
|
||||||
name: 'Nome',
|
name: 'Nome',
|
||||||
name_cannot_be_empty: 'Nome não pode ser vazio.',
|
name_cannot_be_empty: 'Nome não pode ser vazio.',
|
||||||
|
@ -82,7 +82,7 @@ const ro = {
|
|||||||
log_in: "Loghează-te",
|
log_in: "Loghează-te",
|
||||||
log_out: 'Deconectează-te',
|
log_out: 'Deconectează-te',
|
||||||
move: 'Mută',
|
move: 'Mută',
|
||||||
moving: "Se mută",
|
moving_file: "Se mută %%",
|
||||||
my_websites: "Site-urile mele",
|
my_websites: "Site-urile mele",
|
||||||
name: 'Nume',
|
name: 'Nume',
|
||||||
name_cannot_be_empty: 'Numele nu poate fi necompletat.',
|
name_cannot_be_empty: 'Numele nu poate fi necompletat.',
|
||||||
|
@ -126,7 +126,7 @@ const ru = {
|
|||||||
log_out: 'Выйти',
|
log_out: 'Выйти',
|
||||||
manage_sessions: "Управление Сеансами",
|
manage_sessions: "Управление Сеансами",
|
||||||
move: 'Переместить',
|
move: 'Переместить',
|
||||||
moving: "Перемещается",
|
moving_file: "Перемещается %%",
|
||||||
my_websites: "Мои Сайты",
|
my_websites: "Мои Сайты",
|
||||||
name: 'Имя',
|
name: 'Имя',
|
||||||
name_cannot_be_empty: 'Имя не может быть пустым.',
|
name_cannot_be_empty: 'Имя не может быть пустым.',
|
||||||
|
@ -83,7 +83,7 @@ const sv = {
|
|||||||
log_in: "Logga in",
|
log_in: "Logga in",
|
||||||
log_out: "Logga ut",
|
log_out: "Logga ut",
|
||||||
move: "Flytta",
|
move: "Flytta",
|
||||||
moving: "Flyttar",
|
moving_file: "Flyttar %%",
|
||||||
my_websites: "Mina webbplatser",
|
my_websites: "Mina webbplatser",
|
||||||
name: "Namn",
|
name: "Namn",
|
||||||
name_cannot_be_empty: "Namn kan inte vara tomt.",
|
name_cannot_be_empty: "Namn kan inte vara tomt.",
|
||||||
|
@ -91,7 +91,7 @@ const th = {
|
|||||||
log_into_another_account_anyway: "ต้องการเข้าสู่บัญชีอื่น",
|
log_into_another_account_anyway: "ต้องการเข้าสู่บัญชีอื่น",
|
||||||
log_out: "ออกจากระบบ",
|
log_out: "ออกจากระบบ",
|
||||||
move: "ย้าย",
|
move: "ย้าย",
|
||||||
moving: "กำลังย้าย",
|
moving_file: "กำลังย้าย %%",
|
||||||
my_websites: "เว็บไซต์ของฉัน",
|
my_websites: "เว็บไซต์ของฉัน",
|
||||||
name: "ชื่อ",
|
name: "ชื่อ",
|
||||||
name_cannot_be_empty: "ไม่สามารถปล่อยช่องชื่อให้ว่างได้",
|
name_cannot_be_empty: "ไม่สามารถปล่อยช่องชื่อให้ว่างได้",
|
||||||
|
@ -116,7 +116,7 @@ const tr = {
|
|||||||
log_out: "Çıkış Yap",
|
log_out: "Çıkış Yap",
|
||||||
manage_sessions: "Oturumları Yönet",
|
manage_sessions: "Oturumları Yönet",
|
||||||
move: "Taşı",
|
move: "Taşı",
|
||||||
moving: "Taşınıyor",
|
moving_file: "Taşınıyor %%",
|
||||||
my_websites: "Web Sitelerim",
|
my_websites: "Web Sitelerim",
|
||||||
name: "Ad",
|
name: "Ad",
|
||||||
name_cannot_be_empty: "Ad boş olamaz.",
|
name_cannot_be_empty: "Ad boş olamaz.",
|
||||||
|
@ -83,7 +83,7 @@ const ur = {
|
|||||||
log_in: "لاگ ان",
|
log_in: "لاگ ان",
|
||||||
log_out: 'لاگ آؤٹ',
|
log_out: 'لاگ آؤٹ',
|
||||||
move: 'منتقل کریں',
|
move: 'منتقل کریں',
|
||||||
moving: "منتقل ہو رہا ہے ",
|
moving_file: "منتقل ہو رہا ہے %%",
|
||||||
my_websites: "میری ویب سائٹیں ",
|
my_websites: "میری ویب سائٹیں ",
|
||||||
name: 'نام',
|
name: 'نام',
|
||||||
name_cannot_be_empty: 'نام خالی نہیں ہو سکتا',
|
name_cannot_be_empty: 'نام خالی نہیں ہو سکتا',
|
||||||
|
@ -87,7 +87,7 @@ const zh = {
|
|||||||
log_in: "登录",
|
log_in: "登录",
|
||||||
log_out: '登出',
|
log_out: '登出',
|
||||||
move: '移动',
|
move: '移动',
|
||||||
moving: "移动",
|
moving_file: "移动 %%",
|
||||||
my_websites: "我的网站",
|
my_websites: "我的网站",
|
||||||
name: '名称',
|
name: '名称',
|
||||||
name_cannot_be_empty: '名称不能为空。',
|
name_cannot_be_empty: '名称不能为空。',
|
||||||
|
@ -113,7 +113,7 @@ const zhtw = {
|
|||||||
log_into_another_account_anyway: '無論如何都要登入另一個帳號',
|
log_into_another_account_anyway: '無論如何都要登入另一個帳號',
|
||||||
log_out: '登出',
|
log_out: '登出',
|
||||||
move: '移動',
|
move: '移動',
|
||||||
moving: "正在移動",
|
moving_file: "正在移動 %%",
|
||||||
my_websites: "我的網站",
|
my_websites: "我的網站",
|
||||||
name: '名稱',
|
name: '名稱',
|
||||||
name_cannot_be_empty: '名稱不能為空。',
|
name_cannot_be_empty: '名稱不能為空。',
|
||||||
|
Loading…
Reference in New Issue
Block a user