working acceptance + download
This commit is contained in:
parent
719aded698
commit
1018d05e36
@ -46,6 +46,30 @@ pub struct SharedProfileOverrideHashes {
|
||||
pub sha512: String,
|
||||
}
|
||||
|
||||
// Simplified version of SharedProfile- this is what is returned from the Labrinth API
|
||||
// This is not used, except for requests where we are not a member of the shared profile
|
||||
// (ie: previewing a shared profile from a link, before accepting it)
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct SharedProfileResponse {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub owner_id: String,
|
||||
pub created: DateTime<Utc>,
|
||||
pub updated: DateTime<Utc>,
|
||||
pub icon_url: Option<String>,
|
||||
|
||||
pub loader: ModLoader,
|
||||
pub game : String,
|
||||
|
||||
pub loader_version: String,
|
||||
pub game_version: String,
|
||||
|
||||
// Present only if we are the owner
|
||||
pub share_links: Option<Vec<SharedProfileLink>>,
|
||||
pub users: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
|
||||
// Create a new shared profile from ProfilePathId
|
||||
// This converts the LinkedData to a SharedProfile and uploads it to the Labrinth API
|
||||
#[tracing::instrument]
|
||||
@ -177,27 +201,6 @@ pub async fn get_all() -> crate::Result<Vec<SharedProfile>> {
|
||||
let creds = state.credentials.read().await;
|
||||
let creds = creds.0.as_ref().ok_or_else(|| crate::ErrorKind::NoCredentialsError)?;
|
||||
|
||||
// First, get list of shared profiles the user has access to
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct SharedProfileResponse {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub owner_id: String,
|
||||
pub created: DateTime<Utc>,
|
||||
pub updated: DateTime<Utc>,
|
||||
pub icon_url: Option<String>,
|
||||
|
||||
pub loader: ModLoader,
|
||||
pub game : String,
|
||||
|
||||
pub loader_version: String,
|
||||
pub game_version: String,
|
||||
|
||||
// Present only if we are the owner
|
||||
pub share_links: Option<Vec<SharedProfileLink>>,
|
||||
pub users: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
let response = REQWEST_CLIENT
|
||||
.get(
|
||||
format!("{MODRINTH_API_URL_INTERNAL}client/user"),
|
||||
@ -205,6 +208,7 @@ pub async fn get_all() -> crate::Result<Vec<SharedProfile>> {
|
||||
.header("Authorization", &creds.session)
|
||||
.send().await?.error_for_status()?;
|
||||
|
||||
// First, get list of shared profiles the user has access to
|
||||
let profiles = response.json::<Vec<SharedProfileResponse>>().await?;
|
||||
|
||||
// Next, get files for each shared profile
|
||||
@ -253,8 +257,9 @@ pub async fn get_all() -> crate::Result<Vec<SharedProfile>> {
|
||||
}
|
||||
|
||||
#[tracing::instrument]
|
||||
pub async fn install(shared_profile : SharedProfile) -> crate::Result<ProfilePathId> {
|
||||
pub async fn install(shared_profile_id : String) -> crate::Result<ProfilePathId> {
|
||||
let state = crate::State::get().await?;
|
||||
let shared_profile = get_all().await?.into_iter().find(|x| x.id == shared_profile_id).ok_or_else(|| crate::ErrorKind::OtherError("Profile not found".to_string()))?;
|
||||
|
||||
let linked_data = LinkedData::SharedProfile {
|
||||
profile_id: shared_profile.id,
|
||||
@ -647,10 +652,32 @@ pub async fn accept_share_link(
|
||||
|
||||
REQWEST_CLIENT
|
||||
.post(
|
||||
format!("{MODRINTH_API_URL_INTERNAL}client/profile/share/{link}/accept"),
|
||||
format!("{MODRINTH_API_URL_INTERNAL}client/share/{link}/accept"),
|
||||
)
|
||||
.header("Authorization", &creds.session)
|
||||
.send().await?.error_for_status()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Gets a shared profile from a share link
|
||||
// This is done without accepting it- so would not include any link information, and is only usable for basic info
|
||||
pub async fn get_from_link(
|
||||
link: String
|
||||
) -> crate::Result<SharedProfileResponse> {
|
||||
let state = crate::State::get().await?;
|
||||
|
||||
let creds = state.credentials.read().await;
|
||||
let creds = creds.0.as_ref().ok_or_else(|| crate::ErrorKind::NoCredentialsError)?;
|
||||
|
||||
let response = REQWEST_CLIENT
|
||||
.get(
|
||||
format!("{MODRINTH_API_URL_INTERNAL}client/share/{link}"),
|
||||
)
|
||||
.header("Authorization", &creds.session)
|
||||
.send().await?.error_for_status()?;
|
||||
|
||||
let profile = response.json::<SharedProfileResponse>().await?;
|
||||
|
||||
Ok(profile)
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
use crate::api::Result;
|
||||
use theseus::{prelude::*, shared_profile::SharedProfile};
|
||||
use theseus::{prelude::*, shared_profile::{SharedProfile,SharedProfileResponse}};
|
||||
|
||||
pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
tauri::plugin::Builder::new("profile_share")
|
||||
@ -12,7 +12,8 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
profile_share_generate_share_link,
|
||||
profile_share_accept_share_link,
|
||||
profile_share_remove_users,
|
||||
profile_share_remove_links
|
||||
profile_share_remove_links,
|
||||
profile_share_get_link_id,
|
||||
])
|
||||
.build()
|
||||
}
|
||||
@ -28,9 +29,9 @@ pub async fn profile_share_get_all(
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn profile_share_install(
|
||||
profile: SharedProfile,
|
||||
shared_profile_id: String,
|
||||
) -> Result<ProfilePathId> {
|
||||
let res = shared_profile::install(profile)
|
||||
let res = shared_profile::install(shared_profile_id)
|
||||
.await?;
|
||||
Ok(res)
|
||||
}
|
||||
@ -77,6 +78,17 @@ pub async fn profile_share_accept_share_link(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Gets a shared profile from a share link
|
||||
// This is done without accepting it- so would not include any link information, and is only usable for basic info
|
||||
#[tauri::command]
|
||||
pub async fn profile_share_get_link_id(
|
||||
link : String
|
||||
) -> Result<SharedProfileResponse> {
|
||||
let res = shared_profile::get_from_link(link).await?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn profile_share_remove_users(
|
||||
path : ProfilePathId,
|
||||
|
||||
@ -20,7 +20,8 @@ pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
|
||||
get_opening_command,
|
||||
await_sync,
|
||||
is_offline,
|
||||
refresh_offline
|
||||
refresh_offline,
|
||||
test_command,
|
||||
])
|
||||
.build()
|
||||
}
|
||||
@ -159,6 +160,11 @@ pub async fn get_opening_command() -> Result<Option<CommandPayload>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn test_command(command: String) -> Result<()> {
|
||||
Ok(handle_command(command).await?)
|
||||
}
|
||||
|
||||
// helper function called when redirected by a weblink (ie: modrith://do-something) or when redirected by a .mrpack file (in which case its a filepath)
|
||||
// We hijack the deep link library (which also contains functionality for instance-checking)
|
||||
pub async fn handle_command(command: String) -> Result<()> {
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
<script setup>
|
||||
import { Modal, Button } from 'omorphia'
|
||||
import { ref } from 'vue'
|
||||
import { useFetch } from '@/helpers/fetch.js'
|
||||
import SearchCard from '@/components/ui/SearchCard.vue'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { share_accept, share_install } from '@/helpers/shared_profiles.js'
|
||||
import { share_accept, share_install, share_get_link_id } from '@/helpers/shared_profiles.js'
|
||||
|
||||
const confirmModal = ref(null)
|
||||
const linkId = ref(null)
|
||||
@ -12,13 +10,11 @@ const sharedProfile = ref(null)
|
||||
|
||||
defineExpose({
|
||||
async show(event) {
|
||||
linkId.value = event.id
|
||||
sharedProfile.value = await useFetch(
|
||||
`https://staging-api.modrinth.com/_internal/share/${encodeURIComponent(event.id)}`,
|
||||
'shared profile'
|
||||
)
|
||||
|
||||
console.log('showing accept shared profile modal', event)
|
||||
linkId.value = event.link
|
||||
sharedProfile.value = await share_get_link_id(linkId.value).catch(handleError)
|
||||
confirmModal.value.show()
|
||||
console.log('sharedProfile')
|
||||
},
|
||||
})
|
||||
|
||||
@ -30,18 +26,12 @@ async function install() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal ref="confirmModal" :header="`Install ${project?.title}`">
|
||||
<Modal ref="confirmModal" :header="`Install ${sharedProfile?.name}`">
|
||||
<div class="modal-body">
|
||||
<SearchCard
|
||||
:project="project"
|
||||
class="project-card"
|
||||
:categories="categories"
|
||||
@open="confirmModal.hide()"
|
||||
/>
|
||||
<div class="button-row">
|
||||
<div class="markdown-body">
|
||||
<p>
|
||||
Installing <code>{{ sharedProfile.id }}</code> from user {{ sharedProfile.owner_id }}
|
||||
Installing <code>{{ sharedProfile.name }}</code> from user {{ sharedProfile.owner_id }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="button-group">
|
||||
|
||||
@ -15,9 +15,15 @@ export async function share_generate(path) {
|
||||
return await invoke('plugin:profile_share|profile_share_generate_share_link', { path })
|
||||
}
|
||||
|
||||
/// Gets the shared profile from the link id
|
||||
// This is done without accepting it- so would not include any link information, and is only usable for basic info
|
||||
export async function share_get_link_id(link) {
|
||||
return await invoke('plugin:profile_share|profile_share_get_link_id', { link })
|
||||
}
|
||||
|
||||
/// Accepts a shared profile link
|
||||
export async function share_accept(link) {
|
||||
return await invoke('plugin:profile_share|profile_share_accept', { link })
|
||||
return await invoke('plugin:profile_share|profile_share_accept_share_link', { link })
|
||||
}
|
||||
|
||||
/// Removes users from a shared profile
|
||||
@ -31,8 +37,8 @@ export async function remove_links(path, links) {
|
||||
}
|
||||
|
||||
/// Install a pack from a shared profile id
|
||||
export async function share_install(id) {
|
||||
return await invoke('plugin:profile_share|profile_share_install', { id })
|
||||
export async function share_install(sharedProfileId) {
|
||||
return await invoke('plugin:profile_share|profile_share_install', { sharedProfileId })
|
||||
}
|
||||
|
||||
// get all user profiles that are available to the currentt user
|
||||
|
||||
@ -29,10 +29,15 @@ const raw_invoke = async (plugin, fn, args) => {
|
||||
return await invoke('plugin:' + plugin + '|' + fn, args)
|
||||
}
|
||||
}
|
||||
const test_command = async (command) => {
|
||||
return await raw_invoke('utils', 'test_command', {command })
|
||||
}
|
||||
|
||||
isDev()
|
||||
.then((dev) => {
|
||||
if (dev) {
|
||||
window.raw_invoke = raw_invoke
|
||||
window.test_command = test_command
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
@ -492,9 +492,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="installedSharedProfileData.is_owned" class="adjacent-input">
|
||||
your project
|
||||
{{ props.instance.sync_update_version }}
|
||||
:)
|
||||
<label for="share-sync">
|
||||
<span class="label__title">Sync shared profile</span>
|
||||
<span class="label__description" v-if="props.instance.sync_update_version?.is_synced">
|
||||
@ -511,9 +508,7 @@
|
||||
<GlobeIcon /> Revert
|
||||
</Button>
|
||||
</div>
|
||||
<div v-else>
|
||||
not yours
|
||||
{{ props.instance.sync_update_version }}
|
||||
<div v-else class="adjacent-input">
|
||||
<label for="share-sync">
|
||||
<span class="label__title">Sync shared profile</span>
|
||||
<span class="label__description" v-if="props.instance.sync_update_version?.is_synced">
|
||||
@ -523,10 +518,11 @@
|
||||
You are not up to date with the shared profile. Click the button to update your instance.
|
||||
</span>
|
||||
</label>
|
||||
<Button id="share-sync-sync" @click="inboundSyncSharedProfile">
|
||||
<Button id="share-sync-sync" @click="inboundSyncSharedProfile" :disabled="props.instance.sync_update_version?.is_synced">
|
||||
<GlobeIcon /> Sync
|
||||
</Button>
|
||||
</div>
|
||||
{{ props.instance.sync_update_version }}
|
||||
</Card>
|
||||
<Card>
|
||||
<div class="label">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user