Skip to content

Commit 6b0865e

Browse files
committed
feat: add copy mode save
Adds a 'copy' mode to showSaveFilePicker. In this mode, a source file is copied to the target file. The file may not exist in another apps AppData directory. Unlike the 'move' mode, the file can be outside of the app's AppData directory (a "user" file); in this situation the user will be prompted to grant permission for the copy action. The app will have access to the newly-created copy.
1 parent 483ba14 commit 6b0865e

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

src/gui/src/IPC.js

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,32 +1382,68 @@ const ipc_listener = async (event, handled) => {
13821382
$(el_filedialog_window).find('.window-disable-mask, .busy-indicator').hide();
13831383
};
13841384

1385-
const handle_move_save = async ({ source_path, target_path, el_filedialog_window }) => {
1385+
const handle_move_save = async ({
1386+
// when 'source_path' has a value, 'save_type' is checked to determine
1387+
// if a fs.move() or fs.copy() needs to be performed.
1388+
save_type,
1389+
1390+
source_path, target_path, el_filedialog_window,
1391+
}) => {
13861392
// source path must be in appdata directory
13871393
const stat_info = await puter.fs.stat(source_path);
1388-
if ( ! stat_info.appdata_app ) {
1389-
await puter.ui.alert(`the app ${app_uuid} attempted to ` +
1390-
`move data owned by the user illegaly`);
1391-
return;
1392-
}
1393-
1394-
if ( stat_info.appdata_app !== app_uuid ) {
1395-
await puter.ui.alert(`the app ${app_uuid} attempted to ` +
1396-
`move data owned by ${stat_info.appdata_app}`);
1397-
return;
1394+
if ( ! stat_info.appdata_app || stat_info.appdata_app !== app_uuid ) {
1395+
const source_file_owner = stat_info?.appdata_app ?? 'the user';
1396+
if ( stat_info.appdata_app && stat_info.appdata_app !== app_uuid ) {
1397+
await UIAlert({
1398+
message: `apps are prohibited from accessing AppData of other apps`
1399+
});
1400+
return;
1401+
}
1402+
if ( save_type === 'move' ) {
1403+
await UIAlert({
1404+
message: `the app <b>${app_name}</b> tried to illegally move a file owned by ${source_file_owner}`,
1405+
});
1406+
return;
1407+
}
1408+
1409+
const alert_resp = await UIAlert({
1410+
message: `the app ${app_name} is trying to copy ${source_path}; is this okay?`,
1411+
buttons: [
1412+
{
1413+
label: i18n('yes'),
1414+
value: true,
1415+
type: 'primary',
1416+
},
1417+
{
1418+
label: i18n('no'),
1419+
value: false,
1420+
type: 'secondary',
1421+
},
1422+
]
1423+
});
1424+
1425+
// `alert_resp` will be `"false"`, but this check is forward-compatible
1426+
// with a version of UIAlert that returns `false`.
1427+
if ( ! alert_resp || alert_resp === 'false' ) return;
13981428
}
13991429

1400-
console.log('supposedly we\'re writing this file now');
1401-
14021430
let node;
14031431
const written = await window.handle_same_name_exists({
14041432
action: async ({ overwrite }) => {
14051433
if ( overwrite ) {
14061434
await puter.fs.delete(target_path);
14071435
}
1408-
await puter.fs.move(source_path, target_path);
1436+
1437+
if ( save_type === 'copy' ) {
1438+
const target_dir = path.dirname(target_path);
1439+
const new_name = path.basename(target_path);
1440+
await puter.fs.copy(source_path, target_dir, {
1441+
newName: new_name,
1442+
});
1443+
} else {
1444+
await puter.fs.move(source_path, target_path);
1445+
}
14091446
node = await puter.fs.stat(target_path);
1410-
console.log('the move operation just happened', { node });
14111447
},
14121448
parent_uuid: $(el_filedialog_window).attr('data-element_uuid'),
14131449
});
@@ -1441,6 +1477,7 @@ const ipc_listener = async (event, handled) => {
14411477
done = await handle_url_save({ target_path });
14421478
} else if ( event.data.source_path ) {
14431479
done = await handle_move_save({
1480+
save_type: event.data.save_type,
14441481
source_path: event.data.source_path,
14451482
target_path,
14461483
});

src/puter-js/src/modules/UI.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,13 +735,14 @@ class UI extends EventListener {
735735
type = 'url';
736736
}
737737
const url = type === 'url' ? content.toString() : undefined;
738-
const source_path = type === 'move' ? content : undefined;
739-
738+
const source_path = ['move','copy'].includes(type) ? content : undefined;
739+
740740
if(this.env === 'app'){
741741
this.messageTarget?.postMessage({
742742
msg: "showSaveFilePicker",
743743
appInstanceID: this.appInstanceID,
744744
content: url ? undefined : content,
745+
save_type: type,
745746
url,
746747
source_path,
747748
suggestedName: suggestedName ?? '',

0 commit comments

Comments
 (0)