mirror of
https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation.git
synced 2026-08-26 23:44:18 +02:00
Better loading state management
- Dedicated state for the UadList (Downloading, Done, Failed) - Some bugfixes introduced by previous commits (not in 0.4 release)
This commit is contained in:
parent
077bf466d6
commit
18cefe3e80
5 changed files with 132 additions and 63 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use crate::core::utils::{format_diff_time_from_now, last_modified_date};
|
||||
use crate::CACHE_DIR;
|
||||
/*use chrono::DateTime;
|
||||
use chrono::Utc;*/
|
||||
use retry::{delay::Fixed, retry, OperationResult};
|
||||
use serde::Deserialize;
|
||||
use serde_json;
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -31,6 +31,31 @@ pub enum UadList {
|
|||
Unlisted,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum UadListState {
|
||||
Downloading,
|
||||
Done,
|
||||
Failed,
|
||||
}
|
||||
|
||||
impl Default for UadListState {
|
||||
fn default() -> Self {
|
||||
UadListState::Downloading
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for UadListState {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let date = last_modified_date(CACHE_DIR.join("uad_lists.json"));
|
||||
let s = match self {
|
||||
UadListState::Downloading => "Checking updates...".to_string(),
|
||||
UadListState::Done => format!("Done (last was {})", format_diff_time_from_now(date)),
|
||||
UadListState::Failed => "Failed to check update!".to_string(),
|
||||
};
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for UadList {
|
||||
fn default() -> UadList {
|
||||
UadList::All
|
||||
|
|
@ -172,26 +197,32 @@ impl std::fmt::Display for Removal {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn load_debloat_lists(remote: bool) -> HashMap<String, Package> {
|
||||
pub async fn load_debloat_lists(remote: bool) -> (Result<HashMap<String, Package>, ()>, bool) {
|
||||
let cached_uad_lists: PathBuf = CACHE_DIR.join("uad_lists.json");
|
||||
|
||||
let mut error = false;
|
||||
let list: Vec<Package> = if remote {
|
||||
let req = ureq::get(
|
||||
"https://raw.githubusercontent.com/0x192/universal-android-debloater/\
|
||||
match retry(Fixed::from_millis(500).take(120), || {
|
||||
match ureq::get(
|
||||
"https://raw.githubusercontent.com/0x192/universal-android-debloater/\
|
||||
main/resources/assets/uad_lists.json",
|
||||
)
|
||||
.call();
|
||||
|
||||
match req {
|
||||
Ok(data) => {
|
||||
let text = data.into_string().unwrap();
|
||||
fs::write(cached_uad_lists, &text).expect("Unable to write file");
|
||||
serde_json::from_str(&text).expect("Unable to parse")
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Could not load remote debloat list: {}", e);
|
||||
get_local_lists()
|
||||
)
|
||||
.call()
|
||||
{
|
||||
Ok(data) => {
|
||||
let text = data.into_string().unwrap();
|
||||
fs::write(cached_uad_lists.clone(), &text).expect("Unable to write file");
|
||||
let list = serde_json::from_str(&text).expect("Unable to parse");
|
||||
OperationResult::Ok(list)
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Could not load remote debloat list: {}", e);
|
||||
error = true;
|
||||
OperationResult::Retry(Vec::<Package>::new())
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Ok(list) => list,
|
||||
Err(_) => vec![],
|
||||
}
|
||||
} else {
|
||||
warn!("Could not load remote debloat list");
|
||||
|
|
@ -204,7 +235,11 @@ pub async fn load_debloat_lists(remote: bool) -> HashMap<String, Package> {
|
|||
let name = p.id.clone();
|
||||
package_lists.insert(name, p);
|
||||
}
|
||||
package_lists
|
||||
if error {
|
||||
(Err(()), remote)
|
||||
} else {
|
||||
(Ok(package_lists), remote)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_local_lists() -> Vec<Package> {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ pub mod views;
|
|||
pub mod widgets;
|
||||
|
||||
pub use crate::core::sync::{get_device_list, Phone};
|
||||
use crate::core::uad_lists::load_debloat_lists;
|
||||
pub use crate::core::uad_lists::Package;
|
||||
use crate::core::uad_lists::{load_debloat_lists, UadListState};
|
||||
use crate::core::update::{get_latest_release, SelfUpdateState, SelfUpdateStatus};
|
||||
use crate::core::utils::{icon, perform_commands};
|
||||
use iced::pure::widget::Text;
|
||||
|
|
@ -70,7 +70,7 @@ pub enum Message {
|
|||
SettingsAction(SettingsMessage),
|
||||
RefreshButtonPressed,
|
||||
RebootButtonPressed,
|
||||
UadListsDownloaded(HashMap<String, Package>),
|
||||
UadListsDownloaded((Result<HashMap<String, Package>, ()>, bool)),
|
||||
InitList,
|
||||
InitDevice(Vec<Phone>),
|
||||
_NewReleaseDownloaded(Result<(PathBuf, PathBuf), ()>),
|
||||
|
|
@ -99,25 +99,41 @@ impl Application for UadGui {
|
|||
fn update(&mut self, message: Message) -> Command<Message> {
|
||||
match message {
|
||||
Message::InitList => {
|
||||
debug!("Trying to download remote UAD list");
|
||||
warn!("Trying to download remote UAD list");
|
||||
self.apps_view.state = ListState::Loading(ListLoadingState::DownloadingList);
|
||||
Command::perform(load_debloat_lists(true), Message::UadListsDownloaded)
|
||||
}
|
||||
Message::UadListsDownloaded(uad_lists) => {
|
||||
self.apps_view.uad_lists = uad_lists;
|
||||
if self.ready {
|
||||
Command::perform(
|
||||
Self::load_phone_packages(self.selected_device.clone().unwrap_or_default()),
|
||||
Message::AppsAction,
|
||||
)
|
||||
} else {
|
||||
self.ready = true;
|
||||
self.apps_view.state = ListState::Loading(ListLoadingState::FindingPhones);
|
||||
Message::UadListsDownloaded((uad_lists, _)) => match uad_lists {
|
||||
Ok(list) => {
|
||||
if !list.is_empty() {
|
||||
self.apps_view.uad_lists = list;
|
||||
}
|
||||
self.settings_view.list_update_state = UadListState::Done;
|
||||
|
||||
if self.ready {
|
||||
Command::perform(
|
||||
Self::load_phone_packages(
|
||||
self.selected_device.clone().unwrap_or_default(),
|
||||
),
|
||||
Message::AppsAction,
|
||||
)
|
||||
} else {
|
||||
self.ready = true;
|
||||
self.apps_view.state = ListState::Loading(ListLoadingState::FindingPhones);
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
self.settings_view.list_update_state = UadListState::Failed;
|
||||
if let ListState::Ready = self.apps_view.state {
|
||||
} else {
|
||||
self.apps_view.state =
|
||||
ListState::Loading(ListLoadingState::DownloadingList);
|
||||
}
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
},
|
||||
Message::InitDevice(device_list) => {
|
||||
self.apps_view.state = ListState::Loading(ListLoadingState::LoadingPackages);
|
||||
self.device_list = device_list;
|
||||
self.settings_view.phone = SettingsPhone::default();
|
||||
|
||||
|
|
@ -141,7 +157,7 @@ impl Application for UadGui {
|
|||
} else {
|
||||
self.selected_device = None;
|
||||
}
|
||||
if self.ready {
|
||||
if self.settings_view.list_update_state != UadListState::Downloading || self.ready {
|
||||
Command::perform(
|
||||
Self::load_phone_packages(self.selected_device.clone().unwrap_or_default()),
|
||||
Message::AppsAction,
|
||||
|
|
@ -160,14 +176,12 @@ impl Application for UadGui {
|
|||
Message::RebootButtonPressed => {
|
||||
self.apps_view.state = ListState::Loading(ListLoadingState::FindingPhones);
|
||||
self.selected_device = None;
|
||||
self.device_list = vec![];
|
||||
self.ready = false;
|
||||
Command::batch([
|
||||
Command::perform(
|
||||
perform_commands("reboot".to_string(), 0, "ADB".to_string()),
|
||||
|_| Message::Nothing,
|
||||
),
|
||||
Command::perform(get_device_list(), Message::InitDevice),
|
||||
])
|
||||
Command::perform(
|
||||
perform_commands("reboot".to_string(), 0, "ADB".to_string()),
|
||||
|_| Message::Nothing,
|
||||
)
|
||||
}
|
||||
Message::AppsPress => {
|
||||
self.view = View::List;
|
||||
|
|
@ -185,7 +199,7 @@ impl Application for UadGui {
|
|||
Message::AppsAction(msg) => self
|
||||
.apps_view
|
||||
.update(
|
||||
&self.settings_view.phone,
|
||||
&mut self.settings_view,
|
||||
&mut self.selected_device.clone().unwrap_or_default(),
|
||||
msg,
|
||||
)
|
||||
|
|
@ -200,6 +214,7 @@ impl Application for UadGui {
|
|||
|
||||
match msg {
|
||||
AboutMessage::UpdateUadLists => {
|
||||
self.settings_view.list_update_state = UadListState::Downloading;
|
||||
Command::perform(Self::download_uad_list(), |_| Message::InitList)
|
||||
}
|
||||
AboutMessage::DoSelfUpdate => {
|
||||
|
|
@ -288,7 +303,7 @@ impl Application for UadGui {
|
|||
}
|
||||
Command::none()
|
||||
}
|
||||
Message::Nothing => Command::none(),
|
||||
Message::Nothing => Command::perform(get_device_list(), Message::InitDevice),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::core::utils::{format_diff_time_from_now, last_modified_date, open_url};
|
||||
use crate::core::utils::{last_modified_date, open_url};
|
||||
use crate::gui::style;
|
||||
use crate::gui::views::settings::Settings;
|
||||
use crate::CACHE_DIR;
|
||||
|
|
@ -47,7 +47,7 @@ impl About {
|
|||
let date = last_modified_date(CACHE_DIR.join("uad_lists.json"));
|
||||
let uad_list_text =
|
||||
text(format!("Documentation: v{}", date.format("%Y%m%d"))).width(Length::Units(250));
|
||||
let last_update_text = text(format!("(last was {})", format_diff_time_from_now(date)))
|
||||
let last_update_text = text(settings.list_update_state.to_string())
|
||||
.color(settings.theme.palette.normal.surface);
|
||||
let uad_lists_btn = button("Update")
|
||||
.on_press(Message::UpdateUadLists)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::core::sync::{action_handler, Phone, User};
|
||||
use crate::core::uad_lists::{
|
||||
load_debloat_lists, Opposite, Package, PackageState, Removal, UadList,
|
||||
load_debloat_lists, Opposite, Package, PackageState, Removal, UadList, UadListState,
|
||||
};
|
||||
use crate::core::utils::{
|
||||
export_selection, fetch_packages, import_selection, perform_commands, update_selection_count,
|
||||
|
|
@ -9,7 +9,7 @@ use crate::gui::style;
|
|||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
||||
use crate::gui::views::settings::{Phone as SettingsPhone, Settings};
|
||||
use crate::gui::views::settings::Settings;
|
||||
use crate::gui::widgets::package_row::{Message as RowMessage, PackageRow};
|
||||
use iced::pure::{
|
||||
button, column, container, pick_list, row, scrollable, text, text_input, Element,
|
||||
|
|
@ -70,7 +70,7 @@ pub enum Message {
|
|||
SearchInputChanged(String),
|
||||
ToggleAllSelected(bool),
|
||||
InitUadList(bool),
|
||||
ListsIsInitialized(HashMap<String, Package>),
|
||||
ListsIsInitialized((Result<HashMap<String, Package>, ()>, bool)),
|
||||
LoadPackages,
|
||||
ListSelected(UadList),
|
||||
UserSelected(User),
|
||||
|
|
@ -88,7 +88,7 @@ pub enum Message {
|
|||
impl List {
|
||||
pub fn update(
|
||||
&mut self,
|
||||
settings: &SettingsPhone,
|
||||
settings: &mut Settings,
|
||||
phone: &mut Phone,
|
||||
message: Message,
|
||||
) -> Command<Message> {
|
||||
|
|
@ -96,18 +96,30 @@ impl List {
|
|||
match message {
|
||||
Message::Nothing => Command::none(),
|
||||
Message::InitUadList(remote) => {
|
||||
self.state = State::Loading(LoadingState::LoadingPackages);
|
||||
self.state = State::Loading(LoadingState::FindingPhones);
|
||||
if remote {
|
||||
Command::perform(load_debloat_lists(true), Message::ListsIsInitialized)
|
||||
} else {
|
||||
Command::perform(load_debloat_lists(false), Message::ListsIsInitialized)
|
||||
}
|
||||
}
|
||||
Message::ListsIsInitialized(uad_lists) => {
|
||||
self.uad_lists = uad_lists;
|
||||
env::set_var("ANDROID_SERIAL", phone.adb_id.clone());
|
||||
Command::perform(Self::do_load_packages(), |_| Message::LoadPackages)
|
||||
}
|
||||
Message::ListsIsInitialized((uad_lists, remote)) => match uad_lists {
|
||||
Ok(list) => {
|
||||
if !remote {
|
||||
settings.list_update_state = UadListState::Failed;
|
||||
} else {
|
||||
settings.list_update_state = UadListState::Done;
|
||||
}
|
||||
self.uad_lists = list;
|
||||
if !phone.adb_id.is_empty() {
|
||||
env::set_var("ANDROID_SERIAL", phone.adb_id.clone());
|
||||
Command::perform(Self::do_load_packages(), |_| Message::LoadPackages)
|
||||
} else {
|
||||
Command::none()
|
||||
}
|
||||
}
|
||||
Err(_) => Command::none(),
|
||||
},
|
||||
Message::LoadPackages => {
|
||||
self.state = State::Loading(LoadingState::LoadingPackages);
|
||||
self.selected_package_state = Some(PackageState::Enabled);
|
||||
|
|
@ -186,7 +198,7 @@ impl List {
|
|||
|
||||
match row_message {
|
||||
RowMessage::ToggleSelection(toggle) => {
|
||||
if package.removal == Removal::Unsafe && !settings.expert_mode {
|
||||
if package.removal == Removal::Unsafe && !settings.phone.expert_mode {
|
||||
package.selected = false;
|
||||
} else {
|
||||
package.selected = toggle;
|
||||
|
|
@ -208,8 +220,12 @@ impl List {
|
|||
}
|
||||
RowMessage::ActionPressed => {
|
||||
let mut commands = vec![];
|
||||
let actions =
|
||||
action_handler(&self.selected_user.unwrap(), package, phone, settings);
|
||||
let actions = action_handler(
|
||||
&self.selected_user.unwrap(),
|
||||
package,
|
||||
phone,
|
||||
&settings.phone,
|
||||
);
|
||||
|
||||
for (i, action) in actions.into_iter().enumerate() {
|
||||
// Only the first command can change the package state
|
||||
|
|
@ -262,7 +278,7 @@ impl List {
|
|||
&self.selected_user.unwrap(),
|
||||
&self.phone_packages[*i_user][i],
|
||||
phone,
|
||||
settings,
|
||||
&settings.phone,
|
||||
);
|
||||
for (j, action) in actions.into_iter().enumerate() {
|
||||
// Only the first command can change the package state
|
||||
|
|
@ -317,14 +333,14 @@ impl List {
|
|||
let package = &mut self.phone_packages[*i_user][i];
|
||||
update_selection_count(&mut self.selection, package.state, false);
|
||||
|
||||
if !settings.multi_user_mode {
|
||||
package.state = package.state.opposite(settings.disable_mode);
|
||||
if !settings.phone.multi_user_mode {
|
||||
package.state = package.state.opposite(settings.phone.disable_mode);
|
||||
package.selected = false;
|
||||
} else {
|
||||
for u in &phone.user_list {
|
||||
self.phone_packages[u.index][i].state = self.phone_packages[u.index][i]
|
||||
.state
|
||||
.opposite(settings.disable_mode);
|
||||
.opposite(settings.phone.disable_mode);
|
||||
self.phone_packages[u.index][i].selected = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::core::config::Config;
|
||||
use crate::core::sync::{get_android_sdk, Phone as CorePhone};
|
||||
use crate::core::theme::Theme;
|
||||
use crate::core::uad_lists::UadListState;
|
||||
use crate::core::update::{Release, SelfUpdateState, SelfUpdateStatus};
|
||||
use crate::core::utils::{open_url, string_to_theme};
|
||||
use crate::gui::style;
|
||||
|
|
@ -16,6 +17,7 @@ pub struct Settings {
|
|||
pub phone: Phone,
|
||||
pub theme: Theme,
|
||||
pub self_update_state: SelfUpdateState,
|
||||
pub list_update_state: UadListState,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -41,6 +43,7 @@ impl Default for Settings {
|
|||
phone: Phone::default(),
|
||||
theme: string_to_theme(IN_FILE_CONFIGURATION.theme.clone()),
|
||||
self_update_state: SelfUpdateState::default(),
|
||||
list_update_state: UadListState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue