+
Skip to content
This repository was archived by the owner on Sep 17, 2024. It is now read-only.

fix catalog install flow #330

Merged
merged 1 commit into from
Nov 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions crates/core/src/addon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,39 @@ impl Addon {
}
}
}

pub fn update_addon_folders(&mut self, folders: &[AddonFolder]) {
let mut folders = folders.to_vec();

if !folders.is_empty() {
folders.sort_by(|a, b| a.id.cmp(&b.id));

// Assign the primary folder id based on the first folder alphabetically with
// a matching repository identifier otherwise just the first
// folder alphabetically
let primary_folder_id = if let Some(folder) = folders.iter().find(|f| {
if let Some(repo) = self.active_repository {
match repo {
Repository::Curse => {
self.repository_id()
== f.repository_identifiers.curse.as_ref().map(u32::to_string)
}
Repository::Tukui => self.repository_id() == f.repository_identifiers.tukui,
Repository::WowI => self.repository_id() == f.repository_identifiers.wowi,
}
} else {
false
}
}) {
folder.id.clone()
} else {
// Wont fail since we already checked if vec is empty
folders.get(0).map(|f| f.id.clone()).unwrap()
};
self.primary_folder_id = primary_folder_id;
self.folders = folders;
}
}
}

impl PartialEq for Addon {
Expand Down
39 changes: 37 additions & 2 deletions crates/core/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ pub async fn load_addon_cache() -> Result<AddonCache> {
AddonCache::load_or_default()
}

/// Update the cache with input entry. If an entry already exists in the cache,
/// with the same folder names as the input entry, that entry will be deleted
/// before inserting the input entry.
pub async fn update_addon_cache(
addon_cache: Arc<Mutex<AddonCache>>,
entry: AddonCacheEntry,
Expand All @@ -85,7 +88,7 @@ pub async fn update_addon_cache(
let entries = addon_cache.get_mut_for_flavor(flavor);

// Remove old entry, if it exists
entries.retain(|e| e.title != entry.title);
entries.retain(|e| e.folder_names != entry.folder_names);

// Add new entry
entries.push(entry.clone());
Expand All @@ -96,6 +99,35 @@ pub async fn update_addon_cache(
Ok(entry)
}

/// Remove the cache entry that has the same folder names
/// as the input entry. Will return the removed entry, if applicable.
pub async fn remove_addon_cache_entry(
addon_cache: Arc<Mutex<AddonCache>>,
entry: AddonCacheEntry,
flavor: Flavor,
) -> Option<AddonCacheEntry> {
// Lock mutex to get mutable access and block other tasks from trying to update
let mut addon_cache = addon_cache.lock().await;

// Get entries for flavor
let entries = addon_cache.get_mut_for_flavor(flavor);

// Remove old entry, if it exists
if let Some(idx) = entries
.iter()
.position(|e| e.folder_names == entry.folder_names)
{
let entry = entries.remove(idx);

// Persist changes to filesystem
let _ = addon_cache.save();

Some(entry)
} else {
None
}
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct AddonCacheEntry {
pub title: String,
Expand All @@ -113,12 +145,15 @@ impl TryFrom<&Addon> for AddonCacheEntry {
if let (Some(repository), Some(repository_id)) =
(addon.active_repository, addon.repository_id())
{
let mut folder_names: Vec<_> = addon.folders.iter().map(|a| a.id.clone()).collect();
folder_names.sort();

Ok(AddonCacheEntry {
title: addon.title().to_owned(),
repository,
repository_id,
primary_folder_id: addon.primary_folder_id.clone(),
folder_names: addon.folders.iter().map(|a| a.id.clone()).collect(),
folder_names,
modified: Utc::now(),
})
} else {
Expand Down
3 changes: 2 additions & 1 deletion crates/core/src/fs/addon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ pub async fn install_addon(
// Cleanup
std::fs::remove_file(&zip_path)?;

let addon_folders = toc_files.iter().filter_map(parse_toc_path).collect();
let mut addon_folders: Vec<_> = toc_files.iter().filter_map(parse_toc_path).collect();
addon_folders.sort();

Ok(addon_folders)
}
15 changes: 5 additions & 10 deletions src/gui/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
use {
super::{
style, AddonVersionKey, BackupState, CatalogColumnKey, CatalogColumnSettings,
CatalogColumnState, CatalogInstallStatus, CatalogRow, Changelog, ColumnKey, ColumnSettings,
ColumnState, DirectoryType, ExpandType, Interaction, Message, Mode, ReleaseChannel,
ScaleState, SelfUpdateState, SortDirection, State, ThemeState,
CatalogColumnState, CatalogInstallAddon, CatalogInstallStatus, CatalogRow, Changelog,
ColumnKey, ColumnSettings, ColumnState, DirectoryType, ExpandType, Interaction, Message,
Mode, ReleaseChannel, ScaleState, SelfUpdateState, SortDirection, State, ThemeState,
},
crate::VERSION,
ajour_core::{
Expand Down Expand Up @@ -1816,7 +1816,7 @@ pub fn catalog_data_cell<'a, 'b>(
addon: &'a mut CatalogRow,
column_config: &'b [(CatalogColumnKey, Length, bool)],
installed_for_flavor: bool,
statuses: Vec<(Flavor, CatalogInstallStatus)>,
install_addon: Option<&CatalogInstallAddon>,
) -> Container<'a, Message> {
let default_height = Length::Units(26);

Expand All @@ -1843,19 +1843,14 @@ pub fn catalog_data_cell<'a, 'b>(
})
.next()
{
let status = statuses
.iter()
.find(|(f, _)| *f == config.wow.flavor)
.map(|(_, status)| *status);
let status = install_addon.map(|a| a.status);

let install_text = Text::new(if !flavor_exists_for_addon {
"N/A"
} else {
match status {
Some(CatalogInstallStatus::Downloading) => "Downloading",
Some(CatalogInstallStatus::Unpacking) => "Unpacking",
Some(CatalogInstallStatus::Fingerprint) => "Hashing",
Some(CatalogInstallStatus::Completed) => "Installed",
Some(CatalogInstallStatus::Retry) => "Retry",
Some(CatalogInstallStatus::Unavilable) => "Unavailable",
None => {
Expand Down
27 changes: 15 additions & 12 deletions src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub enum Message {
None(()),
Parse(()),
ParsedAddons((Flavor, Result<Vec<Addon>>)),
UpdateFingerprint((DownloadReason, Flavor, String, Result<()>)),
UpdateFingerprint((Flavor, String, Result<()>)),
ThemeSelected(String),
ReleaseChannelSelected(ReleaseChannel),
ThemesLoaded(Vec<Theme>),
Expand All @@ -128,6 +128,7 @@ pub enum Message {
FetchedChangelog((Addon, AddonVersionKey, Result<(String, String)>)),
AjourUpdateDownloaded(Result<(String, PathBuf)>),
AddonCacheUpdated(Result<AddonCacheEntry>),
AddonCacheEntryRemoved(Option<AddonCacheEntry>),
}

pub struct Ajour {
Expand Down Expand Up @@ -163,7 +164,7 @@ pub struct Ajour {
catalog_column_settings: CatalogColumnSettings,
onboarding_directory_btn_state: button::State,
catalog: Option<Catalog>,
catalog_install_statuses: Vec<(Flavor, u32, CatalogInstallStatus)>,
catalog_install_addons: HashMap<Flavor, Vec<CatalogInstallAddon>>,
catalog_search_state: CatalogSearchState,
catalog_header_state: CatalogHeaderState,
website_btn_state: button::State,
Expand Down Expand Up @@ -210,7 +211,7 @@ impl Default for Ajour {
catalog_column_settings: Default::default(),
onboarding_directory_btn_state: Default::default(),
catalog: None,
catalog_install_statuses: vec![],
catalog_install_addons: Default::default(),
catalog_search_state: Default::default(),
catalog_header_state: Default::default(),
website_btn_state: Default::default(),
Expand Down Expand Up @@ -523,27 +524,24 @@ impl Application for Ajour {
&mut self.catalog_search_state.scrollable_state,
);

let install_addons = self.catalog_install_addons.entry(flavor).or_default();

for addon in self.catalog_search_state.catalog_rows.iter_mut() {
// TODO: We should make this prettier with new sources coming in.
let installed_for_flavor = addons.iter().any(|a| {
a.curse_id() == Some(addon.addon.id)
|| a.tukui_id() == Some(&addon.addon.id.to_string())
});

let statuses = self
.catalog_install_statuses
.iter()
.filter(|(_, i, _)| addon.addon.id == *i)
.map(|(flavor, _, status)| (*flavor, *status))
.collect();
let install_addon = install_addons.iter().find(|a| addon.addon.id == a.id);

let catalog_data_cell = element::catalog_data_cell(
color_palette,
&self.config,
addon,
&catalog_column_config,
installed_for_flavor,
statuses,
install_addon,
);

catalog_scrollable = catalog_scrollable.push(catalog_data_cell);
Expand Down Expand Up @@ -1241,12 +1239,17 @@ impl From<CatalogAddon> for CatalogRow {
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct CatalogInstallAddon {
id: u32,
status: CatalogInstallStatus,
addon: Option<Addon>,
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum CatalogInstallStatus {
Downloading,
Unpacking,
Fingerprint,
Completed,
Retry,
Unavilable,
}
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载