Skip to content

Commit

Permalink
[+] add home page
Browse files Browse the repository at this point in the history
  • Loading branch information
heng30 committed Jul 6, 2024
1 parent 2946e5a commit 4b2ca06
Show file tree
Hide file tree
Showing 18 changed files with 393 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/db/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl SerializeAs<TransactionTileStatus> for TranStatus {
let status = match source {
TransactionTileStatus::Success => "Success",
TransactionTileStatus::Pending => "Pending",
TransactionTileStatus::Error => "Error",
_ => "Error",
};

serializer.serialize_str(status)
Expand Down
44 changes: 27 additions & 17 deletions src/logic/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
};
use anyhow::Result;
use cutil::time::local_now;
use slint::{ComponentHandle, Model, SharedString, VecModel, Weak};
use slint::{ComponentHandle, Model, SharedString, VecModel};
use std::str::FromStr;
use uuid::Uuid;
use wallet::{
Expand Down Expand Up @@ -152,24 +152,29 @@ pub fn init(ui: &AppWindow) {

let ui_handle = ui.as_weak();
ui.global::<Logic>()
.on_update_history_status(move |uuid, status| {
.on_update_history_status(move |uuid, status, is_update_db| {
let ui = ui_handle.unwrap();

if let Some((index, mut entry)) = get_entry(&ui, &uuid) {
entry.status = status;
store_history_entries!(ui).set_row_data(index, entry.clone());

_update_entry(entry.into());
if is_update_db {
_update_entry(entry.into());
}
}
});

let ui_handle = ui.as_weak();
ui.global::<Logic>()
.on_refresh_all_pending_and_error_history(move || {
let ui = ui_handle.unwrap();
message_info!(ui, tr("正在刷新..."));
for item in get_pending_and_error_entries(&ui).into_iter() {
_refresh_pending_and_error_history(ui.as_weak(), item);
for (index, item) in get_pending_and_error_entries(&ui).into_iter().enumerate() {
if index == 0 {
message_info!(ui, tr("正在刷新..."));
}

_refresh_pending_and_error_history(&ui, item);
}
});

Expand Down Expand Up @@ -240,8 +245,16 @@ fn _remove_entry(uuid: SharedString) {
});
}

fn _refresh_pending_and_error_history(ui_handle: Weak<AppWindow>, item: UIHistoryEntry) {
fn _refresh_pending_and_error_history(ui: &AppWindow, item: UIHistoryEntry) {
ui.global::<Logic>().invoke_update_history_status(
item.uuid.clone(),
TransactionTileStatus::Loading,
false,
);

let rpc_url_ty = RpcUrlType::from_str(&item.network).unwrap_or(RpcUrlType::Main);

let ui_handle = ui.as_weak();
match Signature::from_str(&item.hash) {
Ok(signature) => {
tokio::spawn(async move {
Expand All @@ -259,17 +272,14 @@ fn _refresh_pending_and_error_history(ui_handle: Weak<AppWindow>, item: UIHistor
}
};

if status != item.status {
let ui_handle = ui_handle.clone();
_ = slint::invoke_from_event_loop(move || {
ui_handle
.unwrap()
.global::<Logic>()
.invoke_update_history_status(item.uuid, status);
});
}
let ui = ui_handle.clone();
_ = slint::invoke_from_event_loop(move || {
ui.unwrap()
.global::<Logic>()
.invoke_update_history_status(item.uuid, status, true);
});

async_message_success(ui_handle, tr("刷新成功"));
async_message_success(ui_handle, tr("刷新完成"));
});
}
Err(e) => message_warn!(ui_handle.unwrap(), e.to_string()),
Expand Down
1 change: 1 addition & 0 deletions src/logic/tr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ pub fn tr(text: &str) -> String {
items.insert("移除账户", "Remove account");
items.insert("更改密码", "Change password");
items.insert("位组记词", "mnemonics");
items.insert("刷新完成", "Refresh finished");

items.insert(
"创建账户和使用组记词恢复账户",
Expand Down
41 changes: 41 additions & 0 deletions ui/base/account-balance.slint
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Theme, Icons } from "../theme.slint";
import { IconBtn } from "icon-btn.slint";
import { TextBtn } from "btn.slint";
import { Label } from "label.slint";
import { Link } from "link.slint";

export component AccountBalance inherits Rectangle {
in-out property account-name <=> account.text;
in-out property balance <=> balance-label.text;

callback account-clicked <=> account.clicked;
callback copy <=> copy-btn.clicked;

VerticalLayout {
padding-top: Theme.padding * 5;
padding-bottom: Theme.padding * 5;
spacing: Theme.spacing * 2;
alignment: LayoutAlignment.start;

HorizontalLayout {
alignment: LayoutAlignment.center;
spacing: Theme.spacing * 2;

account := Link {
horizontal-alignment: TextHorizontalAlignment.center;
font-weight: 0.5;
font-size: Theme.title4-font-size;
}

copy-btn := IconBtn {
icon: Icons.copy;
}
}

balance-label := Label {
horizontal-alignment: TextHorizontalAlignment.center;
font-weight: 0.5;
font-size: Theme.title1-font-size * 2;
}
}
}
2 changes: 1 addition & 1 deletion ui/base/elevated-btn.slint
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export component ElevatedBtn inherits Rectangle {
drop-shadow-color: Theme.secondary-background-drop-shadow;

in-out property icon <=> btn.icon;
in-out property enable-rotation-animation <=> btn.enable-rotation-animation;
in-out property rotation-type <=> btn.rotation-type;

callback clicked <=> btn.clicked;

Expand Down
14 changes: 11 additions & 3 deletions ui/base/icon-btn.slint
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,31 @@ import { Palette } from "std-widgets.slint";
import { Theme } from "../theme.slint";
import { Label } from "./label.slint";

export enum RotationType {
Auto,
Click,
None,
}

export component IconBtn inherits Rectangle {
in-out property icon <=> img.source;
in-out property colorize <=> img.colorize;
in-out property icon-width <=> img.width;
in-out property icon-size <=> img.width;
in-out property icon-rotation-angle <=> img.rotation-angle;
in-out property mouse-cursor <=> touch.mouse-cursor;
in-out property enabled-toucharea<=> touch.enabled;
in-out property enabled-toucharea <=> touch.enabled;
out property has-hover <=> touch.has-hover;

in-out property <bool> show-icon-hover-background: true;
in-out property <bool> is-ltr: true;
in-out property <bool> enable-rotation-animation: false;
in-out property <RotationType> rotation-type: RotationType.None;
in-out property <bool> use-auto-size: false;

in-out property <string> text;
in-out property <length> font-size: Theme.title4-font-size;
in-out property <color> text-color: root.colorize;
in-out property <int> icon-rotation-iteration-count;

callback clicked();

Expand Down Expand Up @@ -65,6 +72,7 @@ export component IconBtn inherits Rectangle {
animate rotation-angle {
duration: Theme.default-animate-duration;
easing: ease-in-out;
iteration-count: root.rotation-type == RotationType.Auto ? -1 : root.icon-rotation-iteration-count;
}
}

Expand All @@ -80,7 +88,7 @@ export component IconBtn inherits Rectangle {
touch := TouchArea {
mouse-cursor: MouseCursor.pointer;
clicked => {
if (enable-rotation-animation) {
if (RotationType.Click == root.rotation-type) {
if (icon-rotation-angle == 0) {
icon-rotation-angle = 360deg;
} else {
Expand Down
1 change: 1 addition & 0 deletions ui/base/list-tile.slint
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Label } from "./label.slint";

export component ListTile inherits Rectangle {
height: vbox.preferred-height;
background: Theme.base-background;

callback left-clicked();
callback right-clicked();
Expand Down
21 changes: 21 additions & 0 deletions ui/base/token-list.slint
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Theme } from "../theme.slint";
import { TokenTile, TokenTileEntry } from "token-tile.slint";
import { SettingDetailInner } from "setting-detail.slint";


export component TokenList inherits SettingDetailInner {
in-out property <[TokenTileEntry]> entries;

vbox-alignment: LayoutAlignment.start;
vbox-spacing: Theme.spacing * 2;

callback clicked(TokenTileEntry);

for item[index] in entries: TokenTile {
entry: item;

clicked => {
root.clicked(item);
}
}
}
105 changes: 105 additions & 0 deletions ui/base/token-tile.slint
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Switch } from "std-widgets.slint";
import { Theme } from "../theme.slint";
import { ListTile } from "list-tile.slint";
import { Label } from "label.slint";
import { IconBtn } from "icon-btn.slint";

export struct TokenTileEntry {
uuid: string,
icon: image,
symbol: string,
mint-address: string,
balance: string,
balance-usdt: string,
}

component Tile inherits Rectangle {
in-out property <TokenTileEntry> entry;

in property <length> icon-size: Theme.icon-size;
in property <color> icon-colorize;

in property <length> symbol-font-size: Theme.title3-font-size;
in property <length> balance-font-size: Theme.default-font-size;
in property <length> balance-usdt-font-size: Theme.title3-font-size;

out property <bool> has-hover: ta.has-hover;

callback clicked <=> ta.clicked;

height: hbox.preferred-height;
background: has-hover ? Theme.base-background.darker(3%) : Theme.base-background;
border-radius: Theme.border-radius;
drop-shadow-blur: Theme.padding * 2;
drop-shadow-color: Theme.base-background-drop-shadow;

ta := TouchArea {
mouse-cursor: MouseCursor.pointer;
}

hbox := HorizontalLayout {
padding: Theme.padding * 2;
spacing: Theme.spacing * 2;
alignment: LayoutAlignment.space-between;

HorizontalLayout {
horizontal-stretch: 1;
spacing: Theme.spacing * 2;

VerticalLayout {
alignment: LayoutAlignment.center;
Rectangle {
width: root.icon-size + Theme.padding * 4;
height: self.width;

img := Image {
height: root.icon-size;
width: self.height;
source: entry.icon;
colorize: root.icon-colorize;
}
}
}

VerticalLayout {
alignment: LayoutAlignment.space-between;
spacing: Theme.spacing * 2;
padding-top: Theme.padding;
padding-bottom: Theme.padding;

Label {
font-size: root.symbol-font-size;
text: entry.symbol;
wrap: TextWrap.no-wrap;
overflow: TextOverflow.elide;
font-weight: 0.5;
}

Label {
font-size: root.balance-font-size;
text: entry.balance;
wrap: TextWrap.no-wrap;
overflow: TextOverflow.elide;
}
}
}

@children
}
}

export component TokenTile inherits Tile {
Label {
font-size: root.balance-usdt-font-size;
text: root.entry.balance-usdt;
}
}

export component TokenTileWithSwitch inherits Rectangle {
in-out property checked <=> sw.checked;

callback toggled <=> sw.toggled;

sw := Switch {
}
}
9 changes: 8 additions & 1 deletion ui/base/transaction-tile.slint
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Theme, Icons } from "../theme.slint";
import { IconBtn } from "./icon-btn.slint";
import { IconBtn, RotationType } from "./icon-btn.slint";
import { Label } from "./label.slint";

export enum TransactionTileStatus {
Success,
Pending,
Error,
Loading,
}

export struct TransactionTileEntry {
Expand Down Expand Up @@ -34,6 +35,8 @@ export component TransactionTile inherits Rectangle {
return Icons.success-big-fill;
} else if (status == TransactionTileStatus.Pending) {
return Icons.pending-fill;
} else if (status == TransactionTileStatus.Loading) {
return Icons.loading;
} else {
return Icons.error-fill;
}
Expand All @@ -44,6 +47,8 @@ export component TransactionTile inherits Rectangle {
return Theme.success-color;
} else if (status == TransactionTileStatus.Pending) {
return Theme.warning-color;
} else if (status == TransactionTileStatus.Loading) {
return Theme.secondary-brand-color;
} else {
return Theme.danger-color;
}
Expand Down Expand Up @@ -102,6 +107,8 @@ export component TransactionTile inherits Rectangle {
icon-size: root.icon-size;
colorize: root.icon-colorize;
icon: root.icon;
rotation-type: TransactionTileStatus.Loading == entry.status ? RotationType.Auto : RotationType.None;
icon-rotation-angle: TransactionTileStatus.Loading == entry.status ? 240deg * animation-tick() / 0.5s : 0;
}
}
}
Expand Down
Loading

0 comments on commit 4b2ca06

Please sign in to comment.