Implement Nexus integration #54
3 changed files with 81 additions and 9 deletions
|
@ -27,12 +27,25 @@ pub(crate) async fn import_mod(state: ActionState, info: FileInfo) -> Result<Mod
|
|||
.wrap_err_with(|| format!("Failed to read file {}", info.path.display()))?;
|
||||
let data = Cursor::new(data);
|
||||
|
||||
let nexus = info
|
||||
let nexus = if let Some((_, id, _, _)) = info
|
||||
.path
|
||||
.file_name()
|
||||
.and_then(|s| s.to_str())
|
||||
.and_then(NexusApi::parse_file_name)
|
||||
.map(|(_, id, version, _)| NexusInfo { id, version });
|
||||
{
|
||||
if !state.nexus_api_key.is_empty() {
|
||||
let api = NexusApi::new(state.nexus_api_key.to_string())?;
|
||||
let mod_info = api
|
||||
.mods_id(id)
|
||||
.await
|
||||
.wrap_err_with(|| format!("Failed to query mod {} from Nexus", id))?;
|
||||
Some(NexusInfo::from(mod_info))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut archive = ZipArchive::new(data).wrap_err("Failed to open ZIP archive")?;
|
||||
|
||||
|
@ -375,13 +388,8 @@ async fn check_mod_update(info: Arc<ModInfo>, api: Arc<NexusApi>) -> Result<Opti
|
|||
.await
|
||||
.wrap_err_with(|| format!("Failed to query mod {} from Nexus", nexus.id))?;
|
||||
|
||||
let updated_nexus = NexusInfo {
|
||||
id: nexus.id,
|
||||
version: updated_info.version,
|
||||
};
|
||||
|
||||
let mut info = Arc::unwrap_or_clone(info);
|
||||
info.nexus = Some(updated_nexus);
|
||||
info.nexus = Some(NexusInfo::from(updated_info));
|
||||
|
||||
Ok(Some(info))
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use std::sync::Arc;
|
|||
use druid::im::{HashMap, Vector};
|
||||
use druid::{Data, ImageBuf, Lens, WindowHandle, WindowId};
|
||||
use dtmt_shared::ModConfig;
|
||||
use nexusmods::Mod as NexusMod;
|
||||
|
||||
use super::SelectedModLens;
|
||||
|
||||
|
@ -72,6 +73,21 @@ impl From<dtmt_shared::ModDependency> for ModDependency {
|
|||
pub(crate) struct NexusInfo {
|
||||
pub id: u64,
|
||||
pub version: String,
|
||||
pub author: String,
|
||||
pub summary: String,
|
||||
pub description: Arc<String>,
|
||||
}
|
||||
|
||||
impl From<NexusMod> for NexusInfo {
|
||||
fn from(value: NexusMod) -> Self {
|
||||
Self {
|
||||
id: value.mod_id,
|
||||
version: value.version,
|
||||
author: value.author,
|
||||
summary: value.summary,
|
||||
description: Arc::new(value.description),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Data, Debug, Lens)]
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||
use druid::im::Vector;
|
||||
use druid::{Data, Lens};
|
||||
|
||||
use super::{ModInfo, State};
|
||||
use super::{ModInfo, NexusInfo, State};
|
||||
|
||||
pub(crate) struct SelectedModLens;
|
||||
|
||||
|
@ -73,3 +73,51 @@ impl<T: Data> Lens<Vector<T>, Vector<(usize, T)>> for IndexedVectorLens {
|
|||
ret
|
||||
}
|
||||
}
|
||||
|
||||
/// A Lens that first checks a key in a mod's `NexusInfo`, then falls back to
|
||||
/// the regular one.
|
||||
pub(crate) struct NexusInfoLens<T, L, R>
|
||||
where
|
||||
L: Lens<NexusInfo, T>,
|
||||
R: Lens<ModInfo, T>,
|
||||
{
|
||||
value: L,
|
||||
fallback: R,
|
||||
_marker: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Data, L, R> NexusInfoLens<T, L, R>
|
||||
where
|
||||
L: Lens<NexusInfo, T>,
|
||||
R: Lens<ModInfo, T>,
|
||||
{
|
||||
pub fn new(value: L, fallback: R) -> Self {
|
||||
Self {
|
||||
value,
|
||||
fallback,
|
||||
_marker: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Data, L, R> Lens<ModInfo, T> for NexusInfoLens<T, L, R>
|
||||
where
|
||||
L: Lens<NexusInfo, T>,
|
||||
R: Lens<ModInfo, T>,
|
||||
{
|
||||
fn with<V, F: FnOnce(&T) -> V>(&self, data: &ModInfo, f: F) -> V {
|
||||
if let Some(nexus) = &data.nexus {
|
||||
self.value.with(nexus, f)
|
||||
} else {
|
||||
self.fallback.with(data, f)
|
||||
}
|
||||
}
|
||||
|
||||
fn with_mut<V, F: FnOnce(&mut T) -> V>(&self, data: &mut ModInfo, f: F) -> V {
|
||||
if let Some(nexus) = &mut data.nexus {
|
||||
self.value.with_mut(nexus, f)
|
||||
} else {
|
||||
self.fallback.with_mut(data, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue