OneLauncher-Cracked/packages/oneclient_app/src/view/app/skins.rs
Julian Chang 29d1f1c9d2
Bugs
Fixed #492
Fixed #510
Fixed #506
Fixed #568
Fixed #582
Fixed #578
Fixed #567
Fixed #588
Fixed #585
Fixed #571
Fixed #587
Fixed #584
2026-07-15 13:41:43 -04:00

171 lines
5.3 KiB
Rust

use freya::prelude::*;
use crate::components::{Button, ButtonVariant, Icon, IconType, PlayerModel};
use crate::hooks::{try_default_account, use_current_account};
use crate::theme::colors;
use crate::ui::border_all_color;
const ANIMATIONS: &[&str] = &["Idle", "Walking", "Running", "Crouch", "Flying"];
#[derive(PartialEq)]
pub struct AccountSkins;
impl Component for AccountSkins {
fn render(&self) -> impl IntoElement {
let account_uuid = try_default_account(&use_current_account()).map(|a| a.id.to_string());
rect()
.horizontal()
.width(Size::fill())
.height(Size::fill())
.overflow(Overflow::Clip)
.padding(40.)
.spacing(24.)
.child(preview_panel(account_uuid))
.child(side_panel())
}
}
fn preview_panel(account_uuid: Option<String>) -> impl IntoElement {
rect()
.vertical()
.width(Size::px(320.))
.height(Size::fill())
.spacing(16.)
.child(
rect()
.center()
.width(Size::fill())
.height(Size::flex(1.0))
.corner_radius(CornerRadius::new_all(16.))
.background(colors::page_elevated())
.border(border_all_color(1., colors::component_border()))
.child(match account_uuid {
Some(uuid) => PlayerModel::new(uuid)
.width(Size::fill())
.height(Size::fill())
.into_element(),
None => Icon::new(IconType::Users01)
.size(64.)
.color(colors::fg_secondary())
.into_element(),
}),
)
.child(
rect()
.horizontal()
.width(Size::fill())
.main_align(Alignment::Center)
.spacing(8.)
.children(
ANIMATIONS
.iter()
.enumerate()
.map(|(i, name)| anim_chip(name, i == 0).into_element()),
),
)
.into_element()
}
fn anim_chip(name: &'static str, active: bool) -> impl IntoElement {
rect()
.center()
.padding(Gaps::new_symmetric(6., 12.))
.corner_radius(CornerRadius::new_all(8.))
.background(if active {
colors::brand()
} else {
colors::component_bg()
})
.on_pointer_enter(|_| Cursor::set(CursorIcon::Pointer))
.on_pointer_leave(|_| Cursor::set(CursorIcon::default()))
.child(
label()
.text(name)
.font_size(12.)
.color(colors::fg_primary()),
)
.into_element()
}
fn side_panel() -> impl IntoElement {
rect()
.vertical()
.width(Size::flex(1.0))
.height(Size::fill())
.overflow(Overflow::Clip)
.spacing(20.)
.child(
label()
.text("Skins")
.font_size(32.)
.font_weight(FontWeight::BOLD)
.color(colors::fg_primary()),
)
.child(
rect()
.horizontal()
.spacing(12.)
.child(action_button("Import Skin", IconType::Plus, true))
.child(action_button("Download", IconType::Download01, false))
.child(action_button("Remove", IconType::Trash01, false)),
)
.child(section_label("SKIN HISTORY"))
.child(skin_grid(8))
.child(section_label("CAPES"))
.child(skin_grid(4))
.into_element()
}
fn action_button(text: &'static str, icon: IconType, primary: bool) -> impl IntoElement {
Button::new()
.variant(if primary {
ButtonVariant::Primary
} else {
ButtonVariant::Secondary
})
.child(Icon::new(icon).size(16.).color(colors::fg_primary()))
.text(text)
.into_element()
}
fn section_label(text: &'static str) -> impl IntoElement {
label()
.text(text)
.font_size(11.)
.font_weight(FontWeight::SEMI_BOLD)
.color(colors::fg_secondary())
.into_element()
}
fn skin_grid(count: usize) -> impl IntoElement {
rect()
.horizontal()
.width(Size::fill())
.spacing(12.)
.children((0..count).map(|i| {
rect()
.center()
.width(Size::px(64.))
.height(Size::px(80.))
.corner_radius(CornerRadius::new_all(8.))
.background(colors::page_elevated())
.border(border_all_color(
if i == 0 { 2. } else { 1. },
if i == 0 {
colors::brand()
} else {
colors::component_border()
},
))
.on_pointer_enter(|_| Cursor::set(CursorIcon::Pointer))
.on_pointer_leave(|_| Cursor::set(CursorIcon::default()))
.child(
Icon::new(IconType::Users01)
.size(24.)
.color(colors::fg_secondary()),
)
.into_element()
}))
.into_element()
}