chore(deps): bump iced from 0.12.0 to 0.13.1

This commit is contained in:
iamanaws 2025-10-23 00:00:46 -07:00
commit 369cfaa946
13 changed files with 1882 additions and 1450 deletions

1928
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -31,7 +31,7 @@ toml = "^0"
dirs = "^6"
ureq = { version = "3", features = ["json"] }
retry = "^2.0.0"
iced = { version = "^0.12.0", features = ["advanced", "image"] }
iced = { version = "=0.13.1", features = ["advanced", "image"] }
rfd = "^0.15"
csv = "^1.3"

View file

@ -431,6 +431,7 @@ impl UserInfo {
/// Check if the user was logged-in
/// at the time `pm list users` was invoked
#[must_use]
#[allow(dead_code)]
pub const fn was_running(&self) -> bool {
self.running
}

View file

@ -1,13 +1,12 @@
use crate::core::theme::Theme;
use crate::gui::style;
use iced::Element;
use iced::widget::button;
use iced::widget::button::Button;
use iced::{Element, Renderer};
/// Wrapper function for `iced::widget::button` with padding and style applied
pub fn button_primary<'a, Message>(
content: impl Into<Element<'a, Message, Theme, Renderer>>,
) -> Button<'a, Message, Theme, Renderer> {
content: impl Into<Element<'a, Message, crate::core::theme::Theme>>,
) -> Button<'a, Message, crate::core::theme::Theme> {
button(content)
.padding([5, 10])
.style(style::Button::Primary)

View file

@ -18,10 +18,7 @@ use views::settings::{Message as SettingsMessage, Settings as SettingsView};
use widgets::navigation_menu::nav_menu;
use iced::widget::column;
use iced::{
Alignment, Application, Command, Element, Length, Renderer, Settings,
window::Settings as Window,
};
use iced::{Alignment, Element, Length, Settings, Task, window::Settings as Window};
#[cfg(feature = "self-update")]
use std::path::PathBuf;
@ -77,22 +74,17 @@ pub enum Message {
ADBSatisfied(bool),
}
impl Application for UadGui {
type Theme = Theme;
type Executor = iced::executor::Default;
type Message = Message;
type Flags = ();
fn new(_flags: ()) -> (Self, Command<Message>) {
impl UadGui {
fn new() -> (Self, Task<Message>) {
(
Self::default(),
Command::batch([
Task::batch([
// Used in crate::gui::widgets::navigation_menu::ICONS. Name is `icomoon`.
font::load(include_bytes!("../../resources/assets/icons.ttf").as_slice())
.map(Message::FontLoaded),
Command::perform(initial_load(), Message::ADBSatisfied),
Command::perform(get_devices_list(), Message::LoadDevices),
Command::perform(
Task::perform(initial_load(), Message::ADBSatisfied),
Task::perform(get_devices_list(), Message::LoadDevices),
Task::perform(
async move { get_latest_release() },
Message::GetLatestRelease,
),
@ -100,15 +92,8 @@ impl Application for UadGui {
)
}
fn theme(&self) -> Theme {
string_to_theme(&self.settings_view.general.theme)
}
fn title(&self) -> String {
String::from("Universal Android Debloater Next Generation")
}
#[allow(clippy::too_many_lines)]
fn update(&mut self, msg: Message) -> Command<Message> {
fn update(&mut self, msg: Message) -> Task<Message> {
match msg {
Message::LoadDevices(devices_list) => {
self.selected_device = match &self.selected_device {
@ -132,19 +117,19 @@ impl Application for UadGui {
}
Message::AppsPress => {
self.view = View::List;
Command::none()
Task::none()
}
Message::AboutPressed => {
self.view = View::About;
self.update_state.self_update = SelfUpdateState::default();
Command::perform(
Task::perform(
async move { get_latest_release() },
Message::GetLatestRelease,
)
}
Message::SettingsPressed => {
self.view = View::Settings;
Command::none()
Task::none()
}
Message::RefreshButtonPressed => {
self.apps_view = AppsView::default();
@ -154,7 +139,7 @@ impl Application for UadGui {
self.adb_satisfied,
)));
}
Command::perform(get_devices_list(), Message::LoadDevices)
Task::perform(get_devices_list(), Message::LoadDevices)
}
Message::RebootButtonPressed => {
self.apps_view = AppsView::default();
@ -164,7 +149,7 @@ impl Application for UadGui {
};
self.selected_device = None;
self.devices_list = vec![];
Command::perform(
Task::perform(
async { adb::ACommand::new().shell(serial).reboot() },
|_| Message::Nothing,
)
@ -240,17 +225,17 @@ impl Application for UadGui {
{
self.update_state.self_update.status = SelfUpdateStatus::Updating;
self.apps_view.loading_state = ListLoadingState::_UpdatingUad;
Command::perform(
Task::perform(
download_update_to_temp_file(BIN_NAME, release.clone()),
Message::_NewReleaseDownloaded,
)
} else {
Command::none()
Task::none()
}
#[cfg(not(feature = "self-update"))]
Command::none()
Task::none()
}
AboutMessage::UrlPressed(_) => Command::none(),
AboutMessage::UrlPressed(_) => Task::none(),
}
}
Message::DeviceSelected(s_device) => {
@ -318,7 +303,7 @@ impl Application for UadGui {
self.update_state.self_update.status = SelfUpdateStatus::Failed;
}
}
Command::none()
Task::none()
}
Message::GetLatestRelease(release) => {
match release {
@ -328,14 +313,14 @@ impl Application for UadGui {
}
Err(()) => self.update_state.self_update.status = SelfUpdateStatus::Failed,
}
Command::none()
Task::none()
}
Message::FontLoaded(result) => {
if let Err(error) = result {
error!("Couldn't load font: {error:?}");
}
Command::none()
Task::none()
}
Message::ADBSatisfied(result) => {
self.adb_satisfied = result;
@ -343,11 +328,11 @@ impl Application for UadGui {
self.adb_satisfied,
)))
}
Message::Nothing => Command::none(),
Message::Nothing => Task::none(),
}
}
fn view(&self) -> Element<'_, Self::Message, Self::Theme, Renderer> {
fn view(&self) -> Element<Message, Theme> {
let navigation_container = nav_menu(
&self.devices_list,
self.selected_device.clone(),
@ -373,9 +358,13 @@ impl Application for UadGui {
column![navigation_container, main_container]
.width(Length::Fill)
.align_items(Alignment::Center)
.align_x(Alignment::Center)
.into()
}
fn theme(&self) -> Theme {
string_to_theme(&self.settings_view.general.theme)
}
}
impl UadGui {
@ -390,20 +379,27 @@ impl UadGui {
}
};
Self::run(Settings {
iced::application(
"Universal Android Debloater Next Generation",
UadGui::update,
UadGui::view,
)
.theme(UadGui::theme)
.settings(Settings {
id: Some(String::from(NAME)),
window: Window {
size: iced::Size {
width: 950.0,
height: 700.0,
},
resizable: true,
decorations: true,
icon: icon::from_file_data(logo, Some(ImageFormat::Png)).ok(),
..iced::window::Settings::default()
},
default_text_size: iced::Pixels(16.0),
..Settings::default()
})
.window(Window {
size: iced::Size {
width: 950.0,
height: 700.0,
},
resizable: true,
decorations: true,
icon: icon::from_file_data(logo, Some(ImageFormat::Png)).ok(),
..iced::window::Settings::default()
})
.run_with(UadGui::new)
}
}

File diff suppressed because it is too large Load diff

View file

@ -76,13 +76,13 @@ impl About {
let last_self_update_text = text(self_update_text).style(style::Text::Default);
row![uad_version_text, self_update_btn, last_self_update_text,]
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.spacing(10)
.width(550)
};
let uad_list_row = row![uad_list_text, uad_lists_btn, last_update_text,]
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.spacing(10)
.width(550);
@ -112,20 +112,18 @@ impl About {
}
})
.width(250);
let adb_version_row = row![adb_version_text]
.align_items(Alignment::Center)
.width(550);
let adb_version_row = row![adb_version_text].align_y(Alignment::Center).width(550);
#[cfg(feature = "self-update")]
let update_column = column![uad_list_row, self_update_row, adb_version_row];
#[cfg(not(feature = "self-update"))]
let update_column = column![uad_list_row, adb_version_row];
let update_column = update_column.align_items(Alignment::Center).spacing(10);
let update_column = update_column.align_x(Alignment::Center).spacing(10);
let update_container = container(update_column)
.width(Length::Fill)
.center_x()
.center_x(Length::Fill)
.padding(10)
.style(style::Container::Frame);
@ -156,7 +154,7 @@ impl About {
]
.width(Length::Fill)
.spacing(20)
.align_items(Alignment::Center);
.align_x(Alignment::Center);
container(content)
.width(Length::Fill)

View file

@ -18,7 +18,7 @@ use iced::widget::{
Column, Space, button, checkbox, column, container, horizontal_space, pick_list, radio, row,
scrollable, text_editor, text_input, tooltip, vertical_rule,
};
use iced::{Alignment, Command, Element, Length, Renderer, alignment};
use iced::{Alignment, Element, Length, Renderer, Task, alignment};
#[derive(Debug, Default, Clone)]
pub struct PackageInfo {
@ -120,14 +120,14 @@ impl List {
selected_device: &mut Phone,
list_update_state: &mut UadListState,
message: Message,
) -> Command<Message> {
) -> Task<Message> {
let i_user = self.selected_user.unwrap_or_default().index;
match message {
Message::ModalHide => {
self.selection_modal = false;
self.error_modal = None;
self.export_modal = false;
Command::none()
Task::none()
}
Message::ModalValidate => {
let mut commands = vec![];
@ -142,7 +142,7 @@ impl List {
));
}
self.selection_modal = false;
Command::batch(commands)
Task::batch(commands)
}
Message::RestoringDevice(output) => {
if let Ok(p) = output {
@ -152,7 +152,7 @@ impl List {
} else {
self.loading_state = LoadingState::RestoringDevice("Error [TODO]".to_string());
}
Command::none()
Task::none()
}
Message::LoadUadList(remote) => {
info!("{:-^65}", "-");
@ -162,7 +162,7 @@ impl List {
);
info!("{:-^65}", "-");
self.loading_state = LoadingState::DownloadingList;
Command::perform(
Task::perform(
Self::init_apps_view(remote, selected_device.clone()),
Message::LoadPhonePackages,
)
@ -171,7 +171,7 @@ impl List {
self.loading_state = LoadingState::LoadingPackages;
self.uad_lists.clone_from(&uad_list);
*list_update_state = list_state;
Command::perform(
Task::perform(
Self::load_packages(
uad_list,
selected_device.adb_id.clone(),
@ -189,7 +189,7 @@ impl List {
self.selected_user = Some(User::default());
Self::filter_package_lists(self);
self.loading_state = LoadingState::Ready;
Command::none()
Task::none()
}
Message::ToggleAllSelected(selected) => {
for i in self.filtered_packages.clone() {
@ -204,27 +204,27 @@ impl List {
}
}
self.all_selected = selected;
Command::none()
Task::none()
}
Message::SearchInputChanged(letter) => {
self.input_value = letter;
Self::filter_package_lists(self);
Command::none()
Task::none()
}
Message::ListSelected(list) => {
self.selected_list = Some(list);
Self::filter_package_lists(self);
Command::none()
Task::none()
}
Message::PackageStateSelected(package_state) => {
self.selected_package_state = Some(package_state);
Self::filter_package_lists(self);
Command::none()
Task::none()
}
Message::RemovalSelected(removal) => {
self.selected_removal = Some(removal);
Self::filter_package_lists(self);
Command::none()
Task::none()
}
Message::List(i_package, row_message) => {
#[expect(unused_must_use, reason = "side-effect")]
@ -240,7 +240,7 @@ impl List {
RowMessage::ToggleSelection(toggle) => {
if package.removal == Removal::Unsafe && !settings.general.expert_mode {
package.selected = false;
return Command::none();
return Task::none();
}
if settings.device.multi_user_mode {
@ -272,11 +272,11 @@ impl List {
.retain(|&x| x.1 != i_package || x.0 != i_user);
}
}
Command::none()
Task::none()
}
RowMessage::ActionPressed => {
self.phone_packages[i_user][i_package].selected = true;
Command::batch(build_action_pkg_commands(
Task::batch(build_action_pkg_commands(
&self.phone_packages,
selected_device,
&settings.device,
@ -292,19 +292,19 @@ impl List {
self.phone_packages[i_user][self.current_package_index].current = false;
}
self.current_package_index = i_package;
Command::none()
Task::none()
}
}
}
Message::ApplyActionOnSelection => {
self.selection_modal = true;
Command::none()
Task::none()
}
Message::UserSelected(user) => {
self.selected_user = Some(user);
self.filtered_packages = (0..self.phone_packages[user.index].len()).collect();
Self::filter_package_lists(self);
Command::none()
Task::none()
}
Message::ChangePackageState(res) => {
match res {
@ -320,7 +320,7 @@ impl List {
self.error_modal = Some(err);
}
}
Command::none()
Task::none()
}
Message::ModalUserSelected(user) => {
self.selected_user = Some(user);
@ -333,21 +333,21 @@ impl List {
}
Message::ClearSelectedPackages => {
self.selected_packages = Vec::new();
Command::none()
Task::none()
}
Message::ADBSatisfied(result) => {
self.is_adb_satisfied = result;
Command::none()
Task::none()
}
Message::UpdateFailed => {
self.loading_state = LoadingState::FailedToUpdate;
Command::none()
Task::none()
}
Message::GoToUrl(url) => {
open_url(url);
Command::none()
Task::none()
}
Message::ExportSelection => Command::perform(
Message::ExportSelection => Task::perform(
export_selection(self.phone_packages[i_user].clone()),
Message::SelectionExported,
),
@ -356,9 +356,9 @@ impl List {
Ok(_) => self.export_modal = true,
Err(err) => error!("Failed to export current selection: {err:?}"),
}
Command::none()
Task::none()
}
Message::Nothing => Command::none(),
Message::Nothing => Task::none(),
Message::DescriptionEdit(action) => {
match action {
text_editor::Action::Edit(_) => {
@ -370,13 +370,13 @@ impl List {
self.description_content.perform(action);
}
}
Command::none()
Task::none()
}
Message::CopyError(err) => {
self.copy_confirmation = true;
Command::batch(vec![
Task::batch(vec![
iced::clipboard::write::<Message>(err),
Command::perform(
Task::perform(
// intentional delay
async { std::thread::sleep(std::time::Duration::from_secs(1)) },
|()| Message::HideCopyConfirmation,
@ -385,7 +385,7 @@ impl List {
}
Message::HideCopyConfirmation => {
self.copy_confirmation = false;
Command::none()
Task::none()
}
}
}
@ -448,6 +448,7 @@ impl List {
let select_all_checkbox = checkbox("", self.all_selected)
.on_toggle(Message::ToggleAllSelected)
.size(20)
.style(style::CheckBox::SettingsEnabled)
.spacing(0); // no label, so remove space entirely
@ -473,18 +474,21 @@ impl List {
)
.width(85);
let list_picklist = pick_list(UadList::ALL, self.selected_list, Message::ListSelected);
let list_picklist =
pick_list(UadList::ALL, self.selected_list, Message::ListSelected).width(92);
let package_state_picklist = pick_list(
PackageState::ALL,
self.selected_package_state,
Message::PackageStateSelected,
);
)
.width(115);
let removal_picklist = pick_list(
Removal::ALL,
self.selected_removal,
Message::RemovalSelected,
);
)
.width(140);
row![
col_sel_all,
@ -495,9 +499,14 @@ impl List {
list_picklist,
]
.width(Length::Fill)
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.spacing(6)
.padding([0, 16, 0, 0])
.padding(iced::Padding {
top: 0.0,
right: 16.0,
bottom: 0.0,
left: 0.0,
})
.into()
}
@ -564,7 +573,7 @@ impl List {
]
.width(Length::Fill)
.spacing(10)
.align_items(Alignment::Center);
.align_y(Alignment::Center);
let unavailable = container(
column![
@ -572,13 +581,13 @@ impl List {
.style(style::Text::Danger),
text("The most likely reason is that it is the user of your work profile (also called Secure Folder on Samsung devices). There's really no solution, other than completely disabling your work profile in your device settings.")
.style(style::Text::Commentary)
.horizontal_alignment(alignment::Horizontal::Center),
.align_x(alignment::Horizontal::Center),
]
.spacing(6)
.align_items(Alignment::Center)
.align_x(Alignment::Center)
)
.padding(10)
.center_x()
.center_x(Length::Shrink)
.style(style::Container::BorderedFrame);
let control_panel = self.control_panel(selected_device);
@ -601,12 +610,14 @@ impl List {
} else {
column![
control_panel,
container(unavailable).height(Length::Fill).center_y(),
container(unavailable)
.height(Length::Fill)
.center_y(Length::Fill),
]
}
.width(Length::Fill)
.spacing(10)
.align_items(Alignment::Center);
.align_x(Alignment::Center);
if self.selection_modal {
return Modal::new(
@ -622,12 +633,12 @@ impl List {
}
if self.export_modal {
let title = container(row![text("Success").size(24)].align_items(Alignment::Center))
let title = container(row![text("Success").size(24)].align_y(Alignment::Center))
.width(Length::Fill)
.style(style::Container::Frame)
.padding([10, 0, 10, 0])
.center_y()
.center_x();
.padding([10, 0])
.center_y(Length::Shrink)
.center_x(Length::Shrink);
let text_box = row![
text(format!("Exported current selection into file.\nFile is exported in same directory where {NAME} is located.")).width(Length::Fill),
@ -696,16 +707,16 @@ impl List {
);
let title_ctn =
container(row![text("Review your selection").size(24)].align_items(Alignment::Center))
container(row![text("Review your selection").size(24)].align_y(Alignment::Center))
.width(Length::Fill)
.style(style::Container::Frame)
.padding([10, 0, 10, 0])
.center_y()
.center_x();
.padding([10, 0])
.center_y(Length::Shrink)
.center_x(Length::Shrink);
let users_ctn = container(radio_btn_users)
.padding(10)
.center_x()
.center_x(Length::Shrink)
.style(style::Container::Frame);
let explaination_ctn = container(
@ -716,7 +727,7 @@ impl List {
text("\u{EA0C}")
.font(ICONS)
.width(22)
.horizontal_alignment(alignment::Horizontal::Center)
.align_x(alignment::Horizontal::Center)
.style(style::Text::Commentary),
"Let's say you choose user 0. If a selected package on user 0\n\
is set to be uninstalled and if this same package is disabled on user 10,\n\
@ -729,7 +740,7 @@ impl List {
]
.spacing(10),
)
.center_x()
.center_x(Length::Shrink)
.padding(10)
.style(style::Container::BorderedFrame);
@ -738,7 +749,12 @@ impl List {
horizontal_space(),
button(text("Apply")).on_press(Message::ModalValidate),
]
.padding([0, 15, 10, 10]);
.padding(iced::Padding {
top: 0.0,
right: 15.0,
bottom: 10.0,
left: 10.0,
});
let recap_view = summaries
.iter()
@ -768,11 +784,13 @@ impl List {
row![text(
self.phone_packages[selection.0][selection.1]
.removal
.to_string()
)]
.width(120),
row![text(
self.phone_packages[selection.0][selection.1]
.uad_list
.to_string()
)]
.width(50),
row![text(
@ -810,7 +828,7 @@ impl List {
)
} else {
column![text("No packages selected for this user")]
.align_items(Alignment::Center)
.align_x(Alignment::Center)
.width(Length::Fill)
},
)
@ -824,7 +842,7 @@ impl List {
)
.width(Length::Fill)
.max_height(150)
.padding([0, 10, 0, 10]);
.padding([0, 10]);
container(
if device.user_list.iter().filter(|&u| !u.protected).count() > 1
@ -833,13 +851,13 @@ impl List {
column![
title_ctn,
users_ctn,
row![explaination_ctn].padding([0, 10, 0, 10]),
row![explaination_ctn].padding([0, 10]),
container(recap_view).padding(10),
selected_pkgs_ctn,
modal_btn_row,
]
.spacing(10)
.align_items(Alignment::Center)
.align_x(Alignment::Center)
} else if !settings.device.multi_user_mode {
column![
title_ctn,
@ -849,7 +867,7 @@ impl List {
modal_btn_row,
]
.spacing(10)
.align_items(Alignment::Center)
.align_x(Alignment::Center)
} else {
column![
title_ctn,
@ -858,7 +876,7 @@ impl List {
modal_btn_row,
]
.spacing(10)
.align_items(Alignment::Center)
.align_x(Alignment::Center)
},
)
.width(900)
@ -936,13 +954,13 @@ fn error_view<'a>(
copy_confirmation: bool,
) -> Modal<'a, Message, Theme, Renderer> {
let title_ctn = container(
row![text("Failed to perform ADB operation").size(24)].align_items(Alignment::Center),
row![text("Failed to perform ADB operation").size(24)].align_y(Alignment::Center),
)
.width(Length::Fill)
.style(style::Container::Frame)
.padding([10, 0, 10, 0])
.center_y()
.center_x();
.padding([10, 0])
.center_y(Length::Shrink)
.center_x(Length::Shrink);
let modal_btn_row = row![
button(
@ -952,7 +970,7 @@ fn error_view<'a>(
"Copy error"
})
.width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center),
.align_x(alignment::Horizontal::Center),
)
.width(Length::Fill)
.on_press_maybe(if copy_confirmation {
@ -963,17 +981,22 @@ fn error_view<'a>(
.style(if copy_confirmation {
style::Button::Primary
} else {
style::Button::default()
style::Button::Primary
}),
button(
text("Close")
.width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center),
.align_x(alignment::Horizontal::Center),
)
.width(Length::Fill)
.on_press(Message::ModalHide)
]
.padding([10, 0, 0, 0]);
.padding(iced::Padding {
top: 10.0,
right: 0.0,
bottom: 0.0,
left: 0.0,
});
let text_box = scrollable(text(error).width(Length::Fill)).height(400);
@ -989,11 +1012,11 @@ fn error_view<'a>(
fn waiting_view<'a>(
displayed_text: &(impl ToString + ?Sized),
btn: Option<button::Button<'a, Message, Theme, Renderer>>,
text_style: style::Text,
text_style: impl Fn(&Theme) -> iced::widget::text::Style + 'a,
) -> Element<'a, Message, Theme, Renderer> {
let col = column![]
.spacing(10)
.align_items(Alignment::Center)
.align_x(Alignment::Center)
.push(text(displayed_text.to_string()).style(text_style).size(20));
let col = match btn {
@ -1004,9 +1027,9 @@ fn waiting_view<'a>(
container(col)
.width(Length::Fill)
.height(Length::Fill)
.center_y()
.center_x()
.style(style::Container::default())
.center_y(Length::Fill)
.center_x(Length::Fill)
.style(style::Container::Frame)
.into()
}
@ -1015,7 +1038,7 @@ fn build_action_pkg_commands(
device: &Phone,
settings: &DeviceSettings,
selection: (usize, usize),
) -> Vec<Command<Message>> {
) -> Vec<Task<Message>> {
let pkg = &packages[selection.0][selection.1];
let wanted_state = pkg.state.opposite(settings.disable_mode);
@ -1043,7 +1066,7 @@ fn build_action_pkg_commands(
};
// In the end there is only one package state change
// even if we run multiple adb commands
commands.push(Command::perform(
commands.push(Task::perform(
adb_shell_command(
// this is typically small,
// so it's fine.
@ -1065,7 +1088,9 @@ fn build_action_pkg_commands(
fn recap<'a>(settings: &Settings, recap: &SummaryEntry) -> Element<'a, Message, Theme, Renderer> {
container(
row![
text(recap.category).size(19).width(Length::FillPortion(1)),
text(recap.category.to_string())
.size(19)
.width(Length::FillPortion(1)),
vertical_rule(5),
row![
if settings.device.disable_mode {
@ -1090,9 +1115,14 @@ fn recap<'a>(settings: &Settings, recap: &SummaryEntry) -> Element<'a, Message,
.width(Length::FillPortion(1))
]
.spacing(20)
.padding([0, 10, 0, 0])
.padding(iced::Padding {
top: 0.0,
right: 10.0,
bottom: 0.0,
left: 0.0,
})
.width(Length::Fill)
.align_items(Alignment::Center),
.align_y(Alignment::Center),
)
.padding(10)
.width(Length::Fill)

View file

@ -18,7 +18,7 @@ use crate::gui::{
widgets::text,
};
use iced::widget::{Space, button, checkbox, column, container, pick_list, radio, row, scrollable};
use iced::{Alignment, Element, Length, Renderer, alignment};
use iced::{Alignment, Element, Length, Renderer, Task, alignment};
use std::path::PathBuf;
#[derive(Debug, Clone)]
@ -74,17 +74,17 @@ impl Settings {
nb_running_async_adb_commands: &mut u32,
msg: Message,
selected_user: Option<User>,
) -> iced::Command<Message> {
) -> Task<Message> {
match msg {
Message::ModalHide => {
self.modal = None;
iced::Command::none()
Task::none()
}
Message::ExpertMode(toggled) => {
self.general.expert_mode = toggled;
debug!("Config change: {self:?}");
Config::save_changes(self, &phone.adb_id);
iced::Command::none()
Task::none()
}
Message::DisableMode(toggled) => {
if phone.android_sdk >= 23 {
@ -92,23 +92,23 @@ impl Settings {
debug!("Config change: {self:?}");
Config::save_changes(self, &phone.adb_id);
}
iced::Command::none()
Task::none()
}
Message::MultiUserMode(toggled) => {
self.device.multi_user_mode = toggled;
debug!("Config change: {self:?}");
Config::save_changes(self, &phone.adb_id);
iced::Command::none()
Task::none()
}
Message::ApplyTheme(theme) => {
self.general.theme = theme.to_string();
debug!("Config change: {self:?}");
Config::save_changes(self, &phone.adb_id);
iced::Command::none()
Task::none()
}
Message::UrlPressed(url) => {
open_url(url);
iced::Command::none()
Task::none()
}
Message::LoadDeviceSettings => {
let backups =
@ -138,14 +138,14 @@ impl Settings {
}
}
}
iced::Command::none()
Task::none()
}
Message::BackupSelected(d_path) => {
self.device.backup.selected = Some(d_path.clone());
self.device.backup.users = list_available_backup_user(d_path);
iced::Command::none()
Task::none()
}
Message::BackupDevice => iced::Command::perform(
Message::BackupDevice => Task::perform(
backup_phone(
phone.user_list.clone(),
self.device.device_id.clone(),
@ -166,7 +166,7 @@ impl Settings {
error!("[BACKUP FAILED] Backup creation failed: {err:?}");
}
}
iced::Command::none()
Task::none()
}
Message::RestoreDevice => match restore_backup(phone, packages, &self.device) {
Ok(r_packages) => {
@ -180,7 +180,7 @@ impl Settings {
};
for command in p.commands.clone() {
*nb_running_async_adb_commands += 1;
commands.push(iced::Command::perform(
commands.push(Task::perform(
// This is "safe" thanks to serde:
// https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/issues/760
adb_shell_command(phone.adb_id.clone(), command, p_info.clone()),
@ -200,16 +200,16 @@ impl Settings {
"[RESTORE] Restoring backup {}",
self.device.backup.selected.as_ref().unwrap()
);
iced::Command::batch(commands)
Task::batch(commands)
}
Err(e) => {
self.device.backup.backup_state.clone_from(&e);
error!("{} - {}", self.device.backup.selected.as_ref().unwrap(), e);
iced::Command::none()
Task::none()
}
},
// Trigger an action in mod.rs (Message::SettingsAction(msg))
Message::RestoringDevice(_) => iced::Command::none(),
Message::RestoringDevice(_) => Task::none(),
Message::FolderChosen(result) => {
self.is_loading = false;
@ -227,17 +227,17 @@ impl Settings {
);
}
}
iced::Command::none()
Task::none()
}
Message::ChooseBackUpFolder => {
if self.is_loading {
iced::Command::none()
Task::none()
} else {
self.is_loading = true;
iced::Command::perform(open_folder(), Message::FolderChosen)
Task::perform(open_folder(), Message::FolderChosen)
}
}
Message::ExportPackages => iced::Command::perform(
Message::ExportPackages => Task::perform(
export_packages(selected_user.unwrap_or_default(), packages.to_vec()),
Message::PackagesExported,
),
@ -246,7 +246,7 @@ impl Settings {
Ok(_) => self.modal = Some(PopUpModal::ExportUninstalled),
Err(err) => error!("Failed to export list of uninstalled packages: {err:?}"),
}
iced::Command::none()
Task::none()
}
}
}
@ -281,6 +281,7 @@ impl Settings {
self.general.expert_mode,
)
.on_toggle(Message::ExpertMode)
.size(20)
.style(style::CheckBox::SettingsEnabled);
let expert_mode_descr =
@ -303,7 +304,7 @@ impl Settings {
text(self.general.backup_folder.to_string_lossy())
]
.spacing(10)
.align_items(Alignment::Center);
.align_y(Alignment::Center);
let general_ctn = container(
column![
@ -353,6 +354,7 @@ impl Settings {
self.device.multi_user_mode,
)
.on_toggle(Message::MultiUserMode)
.size(20)
.style(style::CheckBox::SettingsEnabled);
let disable_checkbox_style = if phone.android_sdk >= 23 {
@ -380,6 +382,7 @@ impl Settings {
self.device.disable_mode,
)
.on_toggle(Message::DisableMode)
.size(20)
.style(disable_checkbox_style);
let disable_setting_row = if phone.android_sdk >= 23 {
@ -418,22 +421,21 @@ impl Settings {
)
.padding(6);
let backup_btn =
button_primary(text("Backup").horizontal_alignment(alignment::Horizontal::Center))
.on_press(Message::BackupDevice)
.width(77);
let backup_btn = button_primary(text("Backup").align_x(alignment::Horizontal::Center))
.on_press(Message::BackupDevice)
.width(77);
let restore_btn = |enabled| {
if enabled {
button(text("Restore").horizontal_alignment(alignment::Horizontal::Center))
button(text("Restore").align_x(alignment::Horizontal::Center))
.padding([5, 10])
.on_press(Message::RestoreDevice)
.width(77)
} else {
button(
text("No backup")
.horizontal_alignment(alignment::Horizontal::Center)
.vertical_alignment(alignment::Vertical::Center),
.align_x(alignment::Horizontal::Center)
.align_y(alignment::Vertical::Center),
)
.padding([5, 10])
.width(77)
@ -457,7 +459,7 @@ impl Settings {
locate_backup_btn,
]
.spacing(10)
.align_items(Alignment::Center);
.align_y(Alignment::Center);
let restore_row = if self.device.backup.backups.is_empty() {
row![]
@ -470,7 +472,7 @@ impl Settings {
backup_pick_list,
]
.spacing(10)
.align_items(Alignment::Center)
.align_y(Alignment::Center)
};
let no_device_ctn = || {
@ -504,7 +506,7 @@ impl Settings {
)),
]
.spacing(10)
.align_items(Alignment::Center);
.align_y(Alignment::Center);
let backup_restore_ctn =
container(column![backup_row, restore_row, export_row].spacing(10))
@ -529,12 +531,12 @@ impl Settings {
};
if let Some(PopUpModal::ExportUninstalled) = self.modal {
let title = container(row![text("Success").size(24)].align_items(Alignment::Center))
let title = container(row![text("Success").size(24)].align_y(Alignment::Center))
.width(Length::Fill)
.style(style::Container::Frame)
.padding([10, 0, 10, 0])
.center_y()
.center_x();
.padding([10, 0])
.center_y(Length::Shrink)
.center_x(Length::Shrink);
let text_box = row![
text(format!("Exported uninstalled packages into file.\nFile is exported in same directory where {NAME} is located.")).width(Length::Fill),

View file

@ -144,7 +144,7 @@ where
state: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation,
) {
self.base
.as_widget()
@ -253,7 +253,7 @@ where
&mut self,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation,
) {
self.content.as_widget().operate(
self.tree,

View file

@ -24,7 +24,7 @@ pub fn nav_menu<'a>(
text("\u{E900}")
.font(ICONS)
.width(22)
.horizontal_alignment(alignment::Horizontal::Center),
.align_x(alignment::Horizontal::Center),
)
.on_press(Message::RefreshButtonPressed);
@ -66,7 +66,7 @@ pub fn nav_menu<'a>(
text("\u{E994}")
.font(ICONS)
.width(22)
.horizontal_alignment(alignment::Horizontal::Center),
.align_x(alignment::Horizontal::Center),
)
.on_press(Message::SettingsPressed);
@ -88,7 +88,7 @@ pub fn nav_menu<'a>(
settings_btn,
]
.width(Length::Fill)
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.spacing(10),
None => row![
reboot_btn,
@ -102,7 +102,7 @@ pub fn nav_menu<'a>(
settings_btn,
]
.width(Length::Fill)
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.spacing(10),
};

View file

@ -6,7 +6,7 @@ use crate::gui::views::settings::Settings;
use crate::gui::widgets::text;
use iced::widget::{Space, button, checkbox, row};
use iced::{Alignment, Command, Element, Length, Renderer, alignment};
use iced::{Alignment, Element, Length, Renderer, Task, alignment};
#[derive(Clone, Debug)]
pub struct PackageRow {
@ -47,8 +47,8 @@ impl PackageRow {
}
}
pub fn update(&mut self, _message: &Message) -> Command<Message> {
Command::none()
pub fn update(&mut self, _message: &Message) -> Task<Message> {
Task::none()
}
pub fn view(
@ -58,7 +58,7 @@ impl PackageRow {
) -> Element<'_, Message, Theme, Renderer> {
//let trash_svg = format!("{}/resources/assets/trash.svg", env!("CARGO_MANIFEST_DIR"));
//let restore_svg = format!("{}/resources/assets/rotate.svg", env!("CARGO_MANIFEST_DIR"));
let button_style;
let button_style: fn(&Theme, iced::widget::button::Status) -> iced::widget::button::Style;
let action_text;
let action_btn;
let selection_checkbox;
@ -93,22 +93,24 @@ impl PackageRow {
{
selection_checkbox = checkbox("", self.selected)
.on_toggle(Message::ToggleSelection)
.size(20)
.style(style::CheckBox::PackageEnabled);
action_btn = button(
text(action_text)
.horizontal_alignment(alignment::Horizontal::Center)
.align_x(alignment::Horizontal::Center)
.width(100),
)
.on_press(Message::ActionPressed);
} else {
selection_checkbox = checkbox("", self.selected)
.on_toggle(Message::ToggleSelection)
.size(20)
.style(style::CheckBox::PackageDisabled);
action_btn = button(
text(action_text)
.horizontal_alignment(alignment::Horizontal::Center)
.align_x(alignment::Horizontal::Center)
.width(100),
);
}
@ -120,7 +122,7 @@ impl PackageRow {
text(&self.name).width(Length::FillPortion(8)),
action_btn.style(button_style)
]
.align_items(Alignment::Center)
.align_y(Alignment::Center)
)
.padding(8)
.style(if self.current {
@ -132,7 +134,7 @@ impl PackageRow {
.on_press(Message::PackagePressed),
Space::with_width(15)
]
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.into()
}
}

View file

@ -3,15 +3,10 @@
reason = "this is the replacement that enforces advanced shaping for disallowed [`iced::widget::Text`]"
)]
use std::borrow::Cow;
use iced::widget::Text;
use iced::advanced::text::IntoFragment;
use iced::widget;
// Creates a new Text widget with advanced shaping.
pub fn text<'a, Theme, Renderer>(text: impl Into<Cow<'a, str>>) -> Text<'a, Theme, Renderer>
where
Theme: iced::widget::text::StyleSheet,
Renderer: iced::advanced::text::Renderer,
{
Text::new(text).shaping(iced::widget::text::Shaping::Advanced)
pub fn text<'a>(text: impl IntoFragment<'a>) -> widget::Text<'a, crate::core::theme::Theme> {
widget::Text::new(text).shaping(iced::widget::text::Shaping::Advanced)
}