mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
0f3f190a5a
Now, we write the data recieved to a file when the user drags a file onto the Spice Viewer window. Once complete, the FileExplorer will open with the copied file highlighted.
92 lines
3.5 KiB
C++
92 lines
3.5 KiB
C++
/*
|
|
* Copyright (c) 2023, Caoimhe Byrne <caoimhebyrne06@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include "FileTransferOperation.h"
|
|
#include "SpiceAgent.h"
|
|
#include <AK/URL.h>
|
|
#include <LibCore/StandardPaths.h>
|
|
#include <LibDesktop/Launcher.h>
|
|
#include <LibFileSystem/FileSystem.h>
|
|
|
|
namespace SpiceAgent {
|
|
|
|
ErrorOr<NonnullRefPtr<FileTransferOperation>> FileTransferOperation::create(FileTransferStartMessage& message)
|
|
{
|
|
// Attempt to construct a path.
|
|
StringBuilder destination_builder;
|
|
TRY(destination_builder.try_append(Core::StandardPaths::downloads_directory()));
|
|
TRY(destination_builder.try_append('/'));
|
|
TRY(destination_builder.try_append(message.metadata().name));
|
|
|
|
auto destination_path = TRY(destination_builder.to_string());
|
|
|
|
// Ensure that the file doesn't already exist, and if it does, remove it.
|
|
if (FileSystem::exists(destination_path)) {
|
|
// If that "file" is a directory, we should stop doing anything else.
|
|
if (FileSystem::is_directory(destination_path)) {
|
|
return Error::from_string_literal("The name of the file being transferred is already taken by a directory!");
|
|
}
|
|
|
|
TRY(FileSystem::remove(destination_path, FileSystem::RecursionMode::Disallowed));
|
|
}
|
|
|
|
auto file = TRY(Core::File::open(destination_path, Core::File::OpenMode::ReadWrite));
|
|
return TRY(AK::adopt_nonnull_ref_or_enomem(new (nothrow) FileTransferOperation(message.id(), message.metadata(), move(file))));
|
|
}
|
|
|
|
ErrorOr<void> FileTransferOperation::begin_transfer(SpiceAgent& agent)
|
|
{
|
|
// Ensure that we are in the `Pending` status.
|
|
if (m_status != Status::Pending) {
|
|
return Error::from_string_literal("Attempt to start a file transfer which has already been started!");
|
|
}
|
|
|
|
// Send the CanSendData status to the server.
|
|
auto status_message = FileTransferStatusMessage(m_id, FileTransferStatus::CanSendData);
|
|
TRY(agent.send_message(status_message));
|
|
|
|
// We are now in the transferring stage!
|
|
set_status(Status::Transferring);
|
|
|
|
return {};
|
|
}
|
|
|
|
ErrorOr<void> FileTransferOperation::complete_transfer(SpiceAgent& agent)
|
|
{
|
|
// Ensure that we are in the `Transferring` status.
|
|
if (m_status != Status::Transferring) {
|
|
return Error::from_string_literal("Attempt to call `on_data_received` on a file transfer which has already been completed!");
|
|
}
|
|
|
|
// We are now in the complete stage :^)
|
|
set_status(Status::Complete);
|
|
|
|
// Send the Success status to the server, since we have received the data, and handled it correctly
|
|
auto status_message = FileTransferStatusMessage(m_id, FileTransferStatus::Success);
|
|
TRY(agent.send_message(status_message));
|
|
|
|
// Open the file manager for the user :^)
|
|
// FIXME: This currently opens a new window for each successful file transfer...
|
|
// Is there a way/can we make a way for it to highlight a new file in an already-open window?
|
|
Desktop::Launcher::open(URL::create_with_file_scheme(Core::StandardPaths::downloads_directory(), m_metadata.name.to_deprecated_string()));
|
|
|
|
return {};
|
|
}
|
|
|
|
ErrorOr<void> FileTransferOperation::on_data_received(FileTransferDataMessage& message)
|
|
{
|
|
// Ensure that we are in the `Transferring` status.
|
|
if (m_status != Status::Transferring) {
|
|
return Error::from_string_literal("Attempt to call `on_data_received` on a file transfer which has already been completed!");
|
|
}
|
|
|
|
// Attempt to write more data to the file.
|
|
TRY(m_destination->write_until_depleted(message.contents()));
|
|
|
|
return {};
|
|
}
|
|
|
|
}
|