Skip to content

Commit bf3778e

Browse files
authored
Merge pull request #3 from lighthx/feat/support-refresh-local-applications
feat: support refresh applications
2 parents e7127fc + 9eff2d4 commit bf3778e

File tree

9 files changed

+202
-120
lines changed

9 files changed

+202
-120
lines changed

.DS_Store

0 Bytes
Binary file not shown.

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ MIT
7171
## TODO
7272

7373
- [ ] Add a management page for matched URLs; currently, deleting/editing matched URLs is not supported.
74-
- [ ] Support refreshing the browser list; currently, the list is fetched from the browser’s app path only during the initial load.
7574
- [ ] Hide the app icon in the dock; currently, it is always shown in the dock due to winit.
7675
- [ ] Improve the ugly UI
7776

src/components/footer.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use iced::{
2+
widget::{center, container, row, text, tooltip, Container, Text},
3+
Alignment, Background, Border, Color, Length,
4+
};
5+
use url::Url;
6+
7+
use crate::components::icon_button::{icon_button, ICON};
8+
9+
pub fn footer<'a, Message: Clone + 'a>(
10+
url: Option<String>,
11+
on_refresh: Message,
12+
) -> Container<'a, Message> {
13+
let url_view = if let Some(url) = url {
14+
let url_cloned = url.clone();
15+
let url = Url::parse(&url).unwrap();
16+
let host = url.host_str().unwrap_or_default().to_string();
17+
18+
container(tooltip(
19+
Text::new(host).size(13).style(|_| text::Style {
20+
color: Some(Color::from_rgb(0.2, 0.2, 0.2)),
21+
}),
22+
container(
23+
Text::new(url_cloned)
24+
.size(13)
25+
.color(Color::from_rgb(0.2, 0.2, 0.2)),
26+
)
27+
.padding(4)
28+
.style(|_| container::Style {
29+
background: Some(Background::Color(Color::from_rgb(0.9, 0.9, 1.0))),
30+
border: Border {
31+
radius: 4.0.into(),
32+
width: 1.0,
33+
color: Color::from_rgb(0.7, 0.7, 0.9),
34+
},
35+
..Default::default()
36+
}),
37+
tooltip::Position::Top,
38+
))
39+
.padding([8, 12])
40+
.style(|_| container::Style {
41+
background: Some(Background::Color(Color::from_rgb(0.95, 0.95, 1.0))),
42+
border: Border {
43+
radius: 8.0.into(),
44+
width: 1.0,
45+
color: Color::from_rgb(0.8, 0.8, 0.9),
46+
},
47+
..Default::default()
48+
})
49+
.center_x(Length::Fill)
50+
} else {
51+
container(Text::new(""))
52+
};
53+
let refresh_button = center(icon_button(
54+
ICON::Refresh,
55+
on_refresh.clone(),
56+
"Refresh applications".to_string(),
57+
))
58+
.width(32.0)
59+
.height(32.0);
60+
let row = row![url_view, refresh_button]
61+
.width(Length::Fill)
62+
.spacing(5.0)
63+
.align_y(Alignment::Center);
64+
container(row).width(Length::Fill)
65+
}

src/components/icon_button.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,48 @@
11
use iced::{
2-
widget::{button, center, Button},
2+
widget::{button, center, container, tooltip, Button, Text},
33
Background, Border, Color, Shadow,
44
};
55

6-
use super::icons::{add_icon, back_icon, profile_icon, remove_icon};
6+
use super::icons::{add_icon, back_icon, profile_icon, refresh_icon, remove_icon};
77

88
pub enum ICON {
99
Profile,
1010
Add,
1111
Remove,
1212
Back,
13+
Refresh,
1314
}
1415

15-
pub fn icon_button<'a, Message: 'a>(icon: ICON, on_press: Message) -> Button<'a, Message> {
16-
button(center(match icon {
17-
ICON::Profile => profile_icon(),
18-
ICON::Add => add_icon(),
19-
ICON::Remove => remove_icon(),
20-
ICON::Back => back_icon(),
21-
}))
16+
pub fn icon_button<'a, Message: Clone + 'a>(
17+
icon: ICON,
18+
on_press: Message,
19+
tip: String,
20+
) -> Button<'a, Message> {
21+
button(tooltip(
22+
center(match icon {
23+
ICON::Profile => profile_icon(),
24+
ICON::Add => add_icon(),
25+
ICON::Remove => remove_icon(),
26+
ICON::Back => back_icon(),
27+
ICON::Refresh => refresh_icon(),
28+
}),
29+
container(
30+
Text::new(tip)
31+
.size(13)
32+
.color(Color::from_rgb(0.2, 0.2, 0.2)),
33+
)
34+
.padding(4)
35+
.style(|_| container::Style {
36+
background: Some(Background::Color(Color::from_rgb(0.9, 0.9, 1.0))),
37+
border: Border {
38+
radius: 4.0.into(),
39+
width: 1.0,
40+
color: Color::from_rgb(0.7, 0.7, 0.9),
41+
},
42+
..Default::default()
43+
}),
44+
tooltip::Position::FollowCursor,
45+
))
2246
.padding(0.0)
2347
.style(|_, _| button::Style {
2448
background: Some(Background::Color(Color::from_rgb(1.0, 1.0, 1.0))),

src/components/icons.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ pub fn remove_icon<'a, Message>() -> Element<'a, Message> {
2121
pub fn back_icon<'a, Message>() -> Element<'a, Message> {
2222
icon('\u{0e700}')
2323
}
24+
pub fn refresh_icon<'a, Message>() -> Element<'a, Message> {
25+
icon('\u{0e796}')
26+
}

src/components/list_item.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub fn list_item<'a, Message: 'a + Clone>(
1515
on_press: Message,
1616
end_icon: ICON,
1717
end_on_press: Message,
18+
end_tip: String,
1819
) -> Button<'a, Message> {
1920
let mut content = row![]
2021
.spacing(12)
@@ -34,7 +35,7 @@ pub fn list_item<'a, Message: 'a + Clone>(
3435
.width(Length::Fill),
3536
);
3637

37-
content = content.push(icon_button(end_icon, end_on_press));
38+
content = content.push(icon_button(end_icon, end_on_press, end_tip));
3839

3940
button(content)
4041
.on_press(on_press)

src/components/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod footer;
12
pub mod icon_button;
23
pub mod icons;
34
pub mod list_item;

src/main.rs

Lines changed: 53 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ mod config;
33
mod icons;
44
mod platform_tools;
55
mod storage;
6+
use components::footer::footer;
67
use components::icon_button::{icon_button, ICON};
78
use components::list_item::list_item;
89
use components::scroll_view::scroll_view;
910
use config::{LOG_DIR, LOG_FILE, WINDOW_HEIGHT, WINDOW_WIDTH};
1011
use iced::keyboard::Modifiers;
11-
use iced::widget::{text_editor, text_input, tooltip};
12+
use iced::widget::{text_editor, text_input};
1213
use iced::window::Position;
13-
use iced::{event, keyboard, Alignment, Event, Font, Subscription};
14+
use iced::{event, keyboard, Alignment, Event, Font, Padding, Subscription};
1415
use iced::{
1516
widget::{button, center, container, image, row, text, Column, Text},
1617
window, Background, Border, Color, Element, Length, Shadow, Size, Task, Theme,
@@ -22,7 +23,6 @@ use std::time::{Duration, Instant};
2223
use storage::{BrowserInfo, BrowserProfile, MatchItem, Storage};
2324
use tracing::info;
2425
use tracing_subscriber::fmt::format::FmtSpan;
25-
use url::Url;
2626

2727
struct Gomi {
2828
is_default_browser: bool,
@@ -77,6 +77,7 @@ enum Message {
7777
MoveWindow(window::Id),
7878
WindowClosed,
7979
WindowUnfocused,
80+
RefreshApplication,
8081
}
8182

8283
impl Gomi {
@@ -323,14 +324,25 @@ impl Gomi {
323324
Task::none()
324325
}
325326
}
327+
Message::RefreshApplication => {
328+
let mut storage = self.storage.clone();
329+
Task::perform(
330+
async move {
331+
storage.delete_all_browsers();
332+
let browsers = platform_tools::get_url_handlers().await;
333+
storage.batch_insert_browsers(browsers.clone());
334+
browsers
335+
},
336+
Message::GoHome,
337+
)
338+
}
326339
}
327340
}
328341

329342
fn view(&self, _: window::Id) -> Element<Message> {
330343
let content = match &self.current_page {
331344
Page::Home => {
332345
let browsers = self.browser_list.clone().unwrap_or_default();
333-
let current_url = self.current_url.clone();
334346
let is_default_browser = self.is_default_browser;
335347
if !is_default_browser {
336348
container(center(
@@ -414,65 +426,23 @@ impl Gomi {
414426
},
415427
ICON::Profile,
416428
Message::ListProfiles(browser.clone()),
429+
"List profiles".to_string(),
417430
));
418431
}
419432

420-
let footer = if let Some(url) = current_url {
421-
let url_cloned = url.clone();
422-
let url = Url::parse(&url).unwrap();
423-
let host = url.host_str().unwrap_or_default().to_string();
424-
425-
container(tooltip(
426-
Text::new(host).size(13).style(|_| text::Style {
427-
color: Some(Color::from_rgb(0.2, 0.2, 0.2)),
428-
}),
429-
container(
430-
Text::new(url_cloned)
431-
.size(13)
432-
.color(Color::from_rgb(0.2, 0.2, 0.2)),
433-
)
434-
.padding(4)
435-
.style(|_| container::Style {
436-
background: Some(Background::Color(Color::from_rgb(0.9, 0.9, 1.0))),
437-
border: Border {
438-
radius: 4.0.into(),
439-
width: 1.0,
440-
color: Color::from_rgb(0.7, 0.7, 0.9),
441-
},
442-
..Default::default()
443-
}),
444-
tooltip::Position::Top,
445-
))
446-
.padding([8, 12])
447-
.style(|_| container::Style {
448-
background: Some(Background::Color(Color::from_rgb(0.95, 0.95, 1.0))),
449-
border: Border {
450-
radius: 8.0.into(),
451-
width: 1.0,
452-
color: Color::from_rgb(0.8, 0.8, 0.9),
453-
},
454-
..Default::default()
455-
})
456-
.center_x(Length::Fill)
457-
} else {
458-
container(Text::new(""))
459-
};
460-
461433
container(
462-
Column::new()
463-
.push(
464-
container(scroll_view(content))
465-
.style(|_| container::Style {
466-
background: Some(Background::Color(Color::from_rgb(
467-
0.98, 0.98, 0.98,
468-
))),
469-
..Default::default()
470-
})
471-
.padding(2)
472-
.width(Length::Fill)
473-
.height(Length::Fill),
474-
)
475-
.push(footer),
434+
Column::new().push(
435+
container(scroll_view(content))
436+
.style(|_| container::Style {
437+
background: Some(Background::Color(Color::from_rgb(
438+
0.98, 0.98, 0.98,
439+
))),
440+
..Default::default()
441+
})
442+
.padding(2)
443+
.width(Length::Fill)
444+
.height(Length::Fill),
445+
),
476446
)
477447
.width(Length::Fill)
478448
.height(Length::Fill)
@@ -483,7 +453,10 @@ impl Gomi {
483453
browser,
484454
profile_text,
485455
} => {
486-
let mut content = Column::new().spacing(20).padding(20).width(Length::Fill);
456+
let mut content = Column::new()
457+
.padding(Padding::new(12.0))
458+
.width(Length::Fill)
459+
.height(Length::Fill);
487460

488461
let profile_list =
489462
profiles
@@ -510,23 +483,29 @@ impl Gomi {
510483
},
511484
ICON::Remove,
512485
Message::DeleteProfile(profile.profile.clone()),
486+
"Delete profile".to_string(),
513487
);
514488
column.push(profile_row)
515489
});
516-
content = content.push(scroll_view(profile_list).height(200.0));
490+
content = content.push(
491+
container(scroll_view(profile_list))
492+
.height(Length::Fill)
493+
.width(Length::Fill),
494+
);
517495

518-
let add_row = row![
519-
icon_button(ICON::Back, Message::Back),
496+
let input_row = row![
497+
icon_button(ICON::Back, Message::Back, "Back to home page".to_string()),
520498
text_input("New Profile", &profile_text)
521499
.on_input(Message::TypeProfileText)
522500
.on_submit(Message::AddProfile)
523501
.width(Length::Fill),
524-
icon_button(ICON::Add, Message::AddProfile)
502+
icon_button(ICON::Add, Message::AddProfile, "Add profile".to_string())
525503
]
526504
.spacing(12)
527-
.align_y(Alignment::Center);
505+
.align_y(Alignment::Center)
506+
.height(30.0);
528507

529-
content = content.push(add_row);
508+
content = content.push(input_row);
530509

531510
container(content)
532511
.width(Length::Fill)
@@ -544,7 +523,11 @@ impl Gomi {
544523
.width(Length::Fill)
545524
.height(Length::Fill);
546525
let footer = row![
547-
icon_button(ICON::Back, Message::Back),
526+
icon_button(
527+
ICON::Back,
528+
Message::Back,
529+
"Back to previous page".to_string()
530+
),
548531
button(Text::new("Save And Open").size(14).style(|_| text::Style {
549532
color: Some(Color::from_rgb(1.0, 1.0, 1.0)),
550533
}))
@@ -569,10 +552,11 @@ impl Gomi {
569552
container(content)
570553
}
571554
};
572-
content.into()
555+
let footer = footer(self.current_url.clone(), Message::RefreshApplication);
556+
Column::new().push(content).push(footer).into()
573557
}
574558

575-
fn theme(&self, window: window::Id) -> Theme {
559+
fn theme(&self, _: window::Id) -> Theme {
576560
Theme::default()
577561
}
578562

0 commit comments

Comments
 (0)