Files
galaxy/app/src/drive/folders/mod.rs
T

177 lines
5.1 KiB
Rust

use std::sync::Arc;
use super::items::folder::WarpDriveFolder;
use super::items::WarpDriveItem;
use super::CloudObjectTypeAndId;
use crate::server::cloud_objects::update_manager::InitiatedBy;
use crate::{
appearance::Appearance,
cloud_object::{
CloudModelType, CloudObjectEventEntrypoint, CreateCloudObjectResult, CreateObjectRequest,
GenericCloudObject, GenericServerObject, ObjectType, Revision, ServerCloudObject, Space,
UpdateCloudObjectResult,
},
persistence::ModelEvent,
server::{
ids::{ServerId, SyncId},
server_api::object::ObjectClient,
sync_queue::{QueueItem, SerializedModel},
},
};
use anyhow::Result;
use async_trait::async_trait;
// Re-exported from galaxy_server_client.
pub use galaxy_server_client::ids::FolderId;
/// The model for a `CloudFolder`.
#[derive(Clone, Debug, PartialEq)]
pub struct CloudFolderModel {
pub name: String,
// TODO: since this is local only state, we should consider only surfacing it as part of the
// CloudViewModel. Right now, every server folder uses CloudFolderModel, which means it
// hardcodes a value of `false` for this property since it can't know what the local state is.
pub is_open: bool,
pub is_warp_pack: bool,
}
impl CloudFolderModel {
pub fn new(name: &str, is_warp_pack: bool) -> Self {
Self {
name: name.to_owned(),
is_open: false,
is_warp_pack,
}
}
}
/// `CloudFolder` is a folder retrieved from the server.
pub type CloudFolder = GenericCloudObject<FolderId, CloudFolderModel>;
#[cfg_attr(not(target_family = "wasm"), async_trait)]
#[cfg_attr(target_family = "wasm", async_trait(?Send))]
impl CloudModelType for CloudFolderModel {
type CloudObjectType = CloudFolder;
type IdType = FolderId;
fn model_type_name(&self) -> &'static str {
"Folder"
}
fn object_type(&self) -> ObjectType {
ObjectType::Folder
}
fn cloud_object_type_and_id(&self, id: SyncId) -> CloudObjectTypeAndId {
CloudObjectTypeAndId::Folder(id)
}
fn display_name(&self) -> String {
self.name.clone()
}
fn upsert_event(&self, folder: &CloudFolder) -> ModelEvent {
ModelEvent::UpsertFolder {
folder: folder.clone(),
}
}
fn bulk_upsert_event(objects: &[CloudFolder]) -> ModelEvent {
ModelEvent::UpsertFolders(objects.to_vec())
}
fn create_object_queue_item(
&self,
folder: &CloudFolder,
entrypoint: CloudObjectEventEntrypoint,
initiated_by: InitiatedBy,
) -> Option<QueueItem> {
if let SyncId::ClientId(client_id) = folder.id {
return Some(QueueItem::CreateObject {
object_type: self.object_type(),
serialized_model: Some(Arc::new(folder.model().name.clone().into())),
title: None,
owner: folder.permissions.owner,
id: client_id,
initial_folder_id: folder.metadata.folder_id,
entrypoint,
initiated_by,
});
}
None
}
fn update_object_queue_item(
&self,
_revision_ts: Option<Revision>,
folder: &CloudFolder,
) -> QueueItem {
QueueItem::UpdateFolder {
id: folder.id,
model: folder.model().clone().into(),
}
}
fn should_update_after_server_conflict(&self) -> bool {
false
}
fn serialized(&self) -> SerializedModel {
SerializedModel::new(self.name.to_owned())
}
fn new_from_server_update(&self, server_cloud_object: &ServerCloudObject) -> Option<Self> {
if let ServerCloudObject::Folder(server_folder) = server_cloud_object {
return Some(CloudFolderModel {
name: server_folder.model.name.clone(),
is_open: self.is_open,
is_warp_pack: server_folder.model.is_warp_pack,
});
}
None
}
fn can_move_to_space(&self, current_space: Space, new_space: Space) -> bool {
// We don't currently support moving folders across spaces.
current_space == new_space
}
fn supports_linking(&self) -> bool {
true
}
async fn send_create_request(
object_client: Arc<dyn ObjectClient>,
request: CreateObjectRequest,
) -> Result<CreateCloudObjectResult> {
object_client.create_folder(request).await
}
async fn send_update_request(
&self,
object_client: Arc<dyn ObjectClient>,
server_id: ServerId,
_revision: Option<Revision>,
) -> Result<UpdateCloudObjectResult<GenericServerObject<FolderId, Self>>> {
object_client
.update_folder(server_id.into(), self.name.clone().into())
.await
}
fn renders_in_warp_drive(&self) -> bool {
true
}
fn to_warp_drive_item(
&self,
id: SyncId,
_appearance: &Appearance,
folder: &CloudFolder,
) -> Option<Box<dyn WarpDriveItem>> {
Some(Box::new(WarpDriveFolder::new(
self.cloud_object_type_and_id(id),
folder.clone(),
)))
}
}