mirror of
https://github.com/modrinth/code.git
synced 2026-08-26 01:26:23 +00:00
feat: instance sharing thru shared-instances service (#6569)
* feat: implement instance share page + search_users backend call * feat: invite players modal * feat: use tanstack queries for friends sync across app pages * feat: base shared instances implementation * fix: admon style * feat: impl instance admonitions like server panel * fix: impl get + del usage * feat: support modpack links * feat: invite notif accepting * fix: lint + fmt * feat: impl install to play * feat: impl usage of UpdateToPlayModal * feat: warnings on deleting/disabling shared-instance version content * fix: send instance name * feat: align with backend * feat: shared instances qa * feat: wrong account protection * feat: qa * fix: smartly apply updates * fix: install bug * fix: 401/404 differentiation * fix: fmt+prepr * feat: qa * feat: qa * fix: signing out messes up revoke/deleted checks * feat: qa * fix: fmt + lint * feat: lock content if part of shared instance * fix: lint * [do not merge] feat: rough invite links impl temp (#6666) * fix: wrong cmd * feat: invite page * fix: server-manager DTO mismatch * fix: drop anonymous invite link acceptance * refactor: structured shared-instance unavailable errors * refactor: centralise error presentations * refactor: dedupe shared instance diff detection * fix: logging in reqwests * refactor: move app.vue shared instances into handler * refactor: break up Share.vue * refactor: split up shared instances state outside of instance index * refactor: dedicated shared instances install/update modals + split up page * refactor: centralized managed content * refactor: split up install shared to own runner + shared.rs split up * refactor: dedupe sql for instance metadata enrichmnt * refactor: friends composable + dedupe friends logic across usages * chore: reduced unused code * fix: align with backend * fix: lint * fix: file sha changes * fix: invite links not working due to icon signed * feat: qa * feat: reporting frontend dummy * fix: try use header * remove: file hash field * fix: pin box * feat: malware warning for shared instances * fix: cache rule * feat: config files syncing * feat: disable config sharing * fix: header * fix: use mark ready * fix: dont cause push update for configs * fix: lint * feat: sharing page in settings * feat: move config + change flow * fix: qa * fix: lint prepr * feat: proxy file upload thru shared instances backend * fix: use collapisible * fix: push config * fix: config * feat: swap out sign in modal for new one * fix: report flow * fix: exclude configs.zip from external warnings * fix: nuxi init * fix: config bundle downloading * fix: error notif * fix: polling * fix: qa * fix: lint + prepr * feat: shared instances moderation frontend + hook up report flow * fix: report copy * fix: lint * fix: lint * fix: modrinth ids being undefined * feat: instance quarantining * fix: prepr + fmt * fix: quarantined -> locked terminology * fix: missing endpoint impls + fmt * fix: missing api in build.rs * fix: share tab jittery * fix: fmt *PT bug * fix: invites count as users even if pending * fix: prepr * fix: invite page owner in users list * fix: lint * fix: qa * fix: lint * fix: members stale not clearing * fix: invite use joined_at field * fix: lint * fix: qa --------- Co-authored-by: sychic <47618543+Sychic@users.noreply.github.com>
This commit is contained in:
+147
-19
@@ -10,6 +10,8 @@ use theseus::data::{
|
||||
EditInstance as CoreEditInstance, InstanceInstallCandidate,
|
||||
InstanceInstallTarget, InstanceLaunchOverridesPatch,
|
||||
InstanceLink as CoreInstanceLink, InstanceMetadata, LinkedModpackInfo,
|
||||
SharedInstanceAttachment as CoreSharedInstanceAttachment,
|
||||
SharedInstanceRole,
|
||||
};
|
||||
use theseus::instance::InstallProjectWithDependenciesRequest;
|
||||
use theseus::instance::QuickPlayType;
|
||||
@@ -50,6 +52,15 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
instance_kill,
|
||||
instance_edit,
|
||||
instance_edit_icon,
|
||||
instance_share_can_current_user_use,
|
||||
instance_share_get_users,
|
||||
instance_share_invite_users,
|
||||
instance_share_create_invite_link,
|
||||
instance_share_remove_users,
|
||||
instance_share_get_publish_preview,
|
||||
instance_share_publish,
|
||||
instance_share_unlink,
|
||||
instance_share_unpublish,
|
||||
instance_export_mrpack,
|
||||
instance_get_pack_export_candidates,
|
||||
])
|
||||
@@ -70,6 +81,8 @@ pub struct Instance {
|
||||
pub loader_version: Option<String>,
|
||||
pub groups: Vec<String>,
|
||||
pub link: Option<InstanceLink>,
|
||||
pub shared_instance: Option<SharedInstanceAttachment>,
|
||||
pub quarantined: bool,
|
||||
pub update_channel: ReleaseChannel,
|
||||
pub created: chrono::DateTime<chrono::Utc>,
|
||||
pub modified: chrono::DateTime<chrono::Utc>,
|
||||
@@ -115,10 +128,40 @@ pub enum InstanceLink {
|
||||
active_instance_id: Option<String>,
|
||||
},
|
||||
SharedInstance {
|
||||
shared_instance_id: String,
|
||||
modpack_project_id: Option<String>,
|
||||
modpack_version_id: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Clone)]
|
||||
pub struct SharedInstanceAttachment {
|
||||
pub id: String,
|
||||
pub role: SharedInstanceRole,
|
||||
pub manager_id: Option<String>,
|
||||
pub server_manager_name: Option<String>,
|
||||
pub server_manager_icon_url: Option<String>,
|
||||
pub linked_user_id: Option<String>,
|
||||
pub status: String,
|
||||
pub applied_version: Option<i32>,
|
||||
pub latest_version: Option<i32>,
|
||||
}
|
||||
|
||||
impl From<CoreSharedInstanceAttachment> for SharedInstanceAttachment {
|
||||
fn from(attachment: CoreSharedInstanceAttachment) -> Self {
|
||||
Self {
|
||||
id: attachment.id.to_string(),
|
||||
role: attachment.role,
|
||||
manager_id: attachment.manager_id,
|
||||
server_manager_name: attachment.server_manager_name,
|
||||
server_manager_icon_url: attachment.server_manager_icon_url,
|
||||
linked_user_id: attachment.linked_user_id,
|
||||
status: attachment.status.as_str().to_string(),
|
||||
applied_version: attachment.applied_version,
|
||||
latest_version: attachment.latest_version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct EditInstance {
|
||||
pub name: Option<String>,
|
||||
@@ -201,6 +244,8 @@ impl From<InstanceMetadata> for Instance {
|
||||
loader_version: metadata.applied_content_set.loader_version,
|
||||
groups: metadata.groups,
|
||||
link: InstanceLink::from_core(metadata.link),
|
||||
shared_instance: metadata.shared_instance.map(Into::into),
|
||||
quarantined: metadata.quarantined,
|
||||
update_channel: metadata.instance.update_channel,
|
||||
created: metadata.instance.created,
|
||||
modified: metadata.instance.modified,
|
||||
@@ -268,11 +313,13 @@ impl InstanceLink {
|
||||
.collect(),
|
||||
active_instance_id: active_instance_id.map(|id| id.to_string()),
|
||||
}),
|
||||
CoreInstanceLink::SharedInstance { shared_instance_id } => {
|
||||
Some(Self::SharedInstance {
|
||||
shared_instance_id: shared_instance_id.to_string(),
|
||||
})
|
||||
}
|
||||
CoreInstanceLink::SharedInstance {
|
||||
modpack_project_id,
|
||||
modpack_version_id,
|
||||
} => Some(Self::SharedInstance {
|
||||
modpack_project_id,
|
||||
modpack_version_id,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,19 +392,13 @@ impl InstanceLink {
|
||||
})
|
||||
.transpose()?,
|
||||
}),
|
||||
Self::SharedInstance { shared_instance_id } => {
|
||||
Ok(CoreInstanceLink::SharedInstance {
|
||||
shared_instance_id: shared_instance_id.parse().map_err(
|
||||
|err| {
|
||||
theseus::Error::from(
|
||||
theseus::ErrorKind::InputError(format!(
|
||||
"Invalid shared instance id: {err}"
|
||||
)),
|
||||
)
|
||||
},
|
||||
)?,
|
||||
})
|
||||
}
|
||||
Self::SharedInstance {
|
||||
modpack_project_id,
|
||||
modpack_version_id,
|
||||
} => Ok(CoreInstanceLink::SharedInstance {
|
||||
modpack_project_id,
|
||||
modpack_version_id,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -744,3 +785,90 @@ pub async fn instance_edit_icon(
|
||||
theseus::instance::edit_icon(instance_id, icon_path).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_can_current_user_use() -> Result<bool> {
|
||||
Ok(theseus::instance::can_active_user_use_shared_instances().await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_get_users(
|
||||
instance_id: &str,
|
||||
) -> Result<theseus::instance::SharedInstanceUsers> {
|
||||
Ok(theseus::instance::get_shared_instance_users(instance_id).await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_invite_users(
|
||||
instance_id: &str,
|
||||
user_ids: Vec<String>,
|
||||
) -> Result<theseus::instance::SharedInstanceUsers> {
|
||||
Ok(
|
||||
theseus::instance::invite_shared_instance_users(instance_id, user_ids)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_create_invite_link(
|
||||
instance_id: &str,
|
||||
max_age_seconds: Option<i32>,
|
||||
max_uses: Option<i32>,
|
||||
replace_invite_id: Option<String>,
|
||||
) -> Result<theseus::instance::SharedInstanceInviteLink> {
|
||||
Ok(theseus::instance::create_shared_instance_invite_link(
|
||||
instance_id,
|
||||
max_age_seconds,
|
||||
max_uses,
|
||||
replace_invite_id,
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_remove_users(
|
||||
instance_id: &str,
|
||||
user_ids: Vec<String>,
|
||||
has_pending_recipients: bool,
|
||||
) -> Result<theseus::instance::SharedInstanceUsers> {
|
||||
Ok(theseus::instance::remove_shared_instance_users(
|
||||
instance_id,
|
||||
user_ids,
|
||||
has_pending_recipients,
|
||||
)
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_get_publish_preview(
|
||||
instance_id: &str,
|
||||
) -> Result<Option<theseus::instance::SharedInstancePublishPreview>> {
|
||||
Ok(
|
||||
theseus::instance::get_shared_instance_publish_preview(instance_id)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_publish(
|
||||
instance_id: &str,
|
||||
config_paths: Vec<String>,
|
||||
) -> Result<SharedInstanceAttachment> {
|
||||
Ok(
|
||||
theseus::instance::publish_shared_instance(instance_id, config_paths)
|
||||
.await?
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_unlink(instance_id: &str) -> Result<()> {
|
||||
theseus::instance::unlink_shared_instance(instance_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn instance_share_unpublish(instance_id: &str) -> Result<()> {
|
||||
theseus::instance::unpublish_shared_instance(instance_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user