mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-22 21:26:04 +00:00
Add file column to worker table and enable file path launching
This commit is contained in:
@@ -285,6 +285,7 @@
|
||||
<tr>
|
||||
<th><input type="checkbox" class="select-all-workers" style="width: 20px; height: 20px; margin-left:3px;"></th>
|
||||
<th class="sort th-name" data-column="name" style="padding-left: 10px !important;">Worker<span class="sort-arrow sort-arrow-desc">▼</span><span class="sort-arrow sort-arrow-asc">▲</span></th>
|
||||
<th class="sort th-file" data-column="file">File<span class="sort-arrow sort-arrow-desc">▼</span><span class="sort-arrow sort-arrow-asc">▲</span></th>
|
||||
<th class="sort th-created sorted" data-column="created_at">Created<span class="sort-arrow sort-arrow-desc" style="display:inline;">▼</span><span class="sort-arrow sort-arrow-asc">▲</span></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
@@ -220,6 +220,7 @@ function generate_worker_card(worker) {
|
||||
<input type="checkbox" class="worker-checkbox" data-worker-name="${worker.name}">
|
||||
</td>
|
||||
<td style="font-family: monospace; font-size: 14px; vertical-align: middle;">${worker.name}</td>
|
||||
<td style="font-family: monospace; font-size: 14px; vertical-align: middle;"><span class="file-path" data-file-path="${html_encode(worker.file_path)}">${worker.file_path}</span></td>
|
||||
<td style="font-size: 14px; vertical-align: middle;">${worker.created_at}</td>
|
||||
<td style="vertical-align: middle;"><img class="options-icon options-icon-worker" data-worker-name="${worker.name}" src="./img/options.svg"></td>
|
||||
</tr>
|
||||
@@ -373,4 +374,19 @@ async function attempt_delete_worker(worker_name) {
|
||||
}
|
||||
}
|
||||
|
||||
$(document).on('click', '.file-path', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
const file_path = $(this).attr('data-file-path');
|
||||
|
||||
if(file_path){
|
||||
puter.ui.launchApp({
|
||||
name: 'editor',
|
||||
file_paths: [file_path],
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
export default init_workers;
|
||||
@@ -48,7 +48,8 @@ export class ExecService extends Service {
|
||||
}
|
||||
|
||||
// This method is exposed to apps via IPCService.
|
||||
async launchApp ({ app_name, args, pseudonym }, { ipc_context, msg_id } = {}) {
|
||||
async launchApp ({ app_name, args, pseudonym, file_paths }, { ipc_context, msg_id } = {}) {
|
||||
console.log('launchApp', { app_name, args, pseudonym, file_paths });
|
||||
const app = ipc_context?.caller?.app;
|
||||
const process = ipc_context?.caller?.process;
|
||||
|
||||
@@ -68,8 +69,8 @@ export class ExecService extends Service {
|
||||
Object.assign(params, provider());
|
||||
}
|
||||
|
||||
// The "body" of this method is in a separate file
|
||||
const child_process = await launch_app({
|
||||
// Handle file paths if provided and caller is in godmode
|
||||
let launch_options = {
|
||||
launched_by_exec_service: true,
|
||||
name: app_name,
|
||||
pseudonym,
|
||||
@@ -80,7 +81,63 @@ export class ExecService extends Service {
|
||||
...(connection ? {
|
||||
parent_pseudo_id: connection.backward.uuid,
|
||||
} : {}),
|
||||
});
|
||||
};
|
||||
|
||||
// Check if file_paths are provided and caller has godmode permissions
|
||||
if (file_paths && Array.isArray(file_paths) && file_paths.length > 0 && process) {
|
||||
console.log('file_paths', file_paths);
|
||||
try {
|
||||
// Get caller app info to check godmode status
|
||||
const caller_app_name = process.name;
|
||||
const caller_app_info = await window.get_apps(caller_app_name);
|
||||
|
||||
// Check if caller is in godmode
|
||||
if (caller_app_info && caller_app_info.godmode === 1) {
|
||||
this.log.info(`⚠️ GODMODE app ${caller_app_name} launching ${app_name} with files:`, file_paths);
|
||||
|
||||
// Get target app info to create file signatures
|
||||
const target_app_info = await puter.apps.get(app_name);
|
||||
|
||||
// For the first file, create a file signature and set it up like opening a file
|
||||
if (file_paths.length > 0) {
|
||||
const first_file_path = file_paths[0];
|
||||
|
||||
try {
|
||||
// Get file stats to verify it exists
|
||||
const file_stat = await puter.fs.stat(first_file_path);
|
||||
|
||||
// Create file signature for the target app
|
||||
const file_signature_result = await puter.fs.sign(target_app_info.uuid, {
|
||||
path: first_file_path,
|
||||
action: 'write'
|
||||
});
|
||||
|
||||
// Set up launch options with file information
|
||||
launch_options.file_signature = file_signature_result.items;
|
||||
launch_options.file_path = first_file_path;
|
||||
launch_options.token = file_signature_result.token;
|
||||
|
||||
// Add all file paths to args for the target app
|
||||
launch_options.args.file_paths = file_paths;
|
||||
|
||||
} catch (file_error) {
|
||||
this.log.warn(`Failed to process file ${first_file_path}:`, file_error);
|
||||
// Continue with launch but without file signature
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log(`⚠️ App ${caller_app_name} attempted to launch ${app_name} with files but does not have godmode permissions`);
|
||||
// Continue with normal launch, ignoring file_paths
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Error checking godmode permissions:', error);
|
||||
// Continue with normal launch
|
||||
}
|
||||
}
|
||||
|
||||
// The "body" of this method is in a separate file
|
||||
const child_process = await launch_app(launch_options);
|
||||
|
||||
const send_child_launched_msg = (...a) => {
|
||||
if ( ! process ) return;
|
||||
|
||||
@@ -1047,7 +1047,19 @@ class UI extends EventListener {
|
||||
// Returns a Promise<AppConnection>
|
||||
launchApp = async function launchApp(app_name, args, callback) {
|
||||
let pseudonym = undefined;
|
||||
if ( app_name.includes('#(as)') ) {
|
||||
let file_paths = undefined;
|
||||
|
||||
// Handle case where app_name is an options object
|
||||
if (typeof app_name === 'object' && app_name !== null) {
|
||||
const options = app_name;
|
||||
app_name = options.name || options.app_name;
|
||||
file_paths = options.file_paths;
|
||||
args = args || options.args;
|
||||
callback = callback || options.callback;
|
||||
pseudonym = options.pseudonym;
|
||||
}
|
||||
|
||||
if ( app_name && app_name.includes('#(as)') ) {
|
||||
[app_name, pseudonym] = app_name.split('#(as)');
|
||||
}
|
||||
const app_info = await this.#ipc_stub({
|
||||
@@ -1055,6 +1067,7 @@ class UI extends EventListener {
|
||||
callback,
|
||||
parameters: {
|
||||
app_name,
|
||||
file_paths,
|
||||
pseudonym,
|
||||
args,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user