Skip to content

Commit 0db8ae1

Browse files
authored
Add detail page for firmware releases (#206)
1 parent 09e82e3 commit 0db8ae1

File tree

7 files changed

+462
-197
lines changed

7 files changed

+462
-197
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- name: Install Dependencies
1616
run: |
1717
apt update
18-
apt install -y meson libfwupd-dev libgranite-dev libgtk-3-dev libgtop2-dev libhandy-1-dev libswitchboard-2.0-dev valac
18+
apt install -y meson libfwupd-dev libgranite-dev libgtk-3-dev libgtop2-dev libhandy-1-dev libswitchboard-2.0-dev libappstream-dev valac
1919
- name: Build
2020
env:
2121
DESTDIR: out

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ You'll need the following dependencies:
1313
* libgtk-3-dev
1414
* libgtop2-dev
1515
* libhandy-1-dev
16+
* libappstream-dev
1617
* meson
1718
* valac
1819
* switcheroo-control (at runtime)

po/POTFILES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
src/Plug.vala
2+
src/Views/FirmwareReleaseView.vala
23
src/Views/FirmwareView.vala
34
src/Views/HardwareView.vala
45
src/Views/OperatingSystemView.vala

src/Views/FirmwareReleaseView.vala

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/*
2+
* Copyright (c) 2021 elementary, Inc. (https://elementary.io)
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 3 of the License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public
15+
* License along with this program; if not, write to the
16+
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17+
* Boston, MA 02110-1301 USA
18+
*
19+
* Authored by: Marius Meisenzahl <mariusmeisenzahl@gmail.com>
20+
*/
21+
22+
public class About.FirmwareReleaseView : Gtk.Grid {
23+
public signal void update (Fwupd.Device device, Fwupd.Release release);
24+
25+
private Fwupd.Device device;
26+
private Fwupd.Release? release;
27+
private Granite.Widgets.AlertView placeholder;
28+
private Gtk.ScrolledWindow scrolled_window;
29+
private Gtk.Stack content;
30+
private Gtk.Revealer update_button_revealer;
31+
private Gtk.Button update_button;
32+
private Gtk.Label title_label;
33+
private Gtk.Label summary_label;
34+
private Gtk.Label description_label;
35+
private Gtk.Label version_value_label;
36+
private Gtk.Label vendor_value_label;
37+
private Gtk.Label size_value_label;
38+
private Gtk.Label install_duration_value_label;
39+
private Hdy.Deck? deck;
40+
41+
construct {
42+
var back_button = new Gtk.Button.with_label (_("All Updates")) {
43+
halign = Gtk.Align.START,
44+
margin = 6
45+
};
46+
back_button.get_style_context ().add_class (Granite.STYLE_CLASS_BACK_BUTTON);
47+
48+
title_label = new Gtk.Label ("") {
49+
ellipsize = Pango.EllipsizeMode.END,
50+
use_markup = true
51+
};
52+
53+
update_button = new Gtk.Button.with_label ("") {
54+
halign = Gtk.Align.END,
55+
margin = 6,
56+
sensitive = false
57+
};
58+
update_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
59+
60+
update_button_revealer = new Gtk.Revealer ();
61+
update_button_revealer.add (update_button);
62+
63+
var header_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) {
64+
hexpand = true
65+
};
66+
header_box.pack_start (back_button);
67+
header_box.set_center_widget (title_label);
68+
header_box.pack_end (update_button_revealer);
69+
70+
summary_label = new Gtk.Label ("") {
71+
halign = Gtk.Align.START,
72+
wrap = true
73+
};
74+
summary_label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL);
75+
76+
description_label = new Gtk.Label ("") {
77+
halign = Gtk.Align.START,
78+
wrap = true
79+
};
80+
81+
var version_label = new Gtk.Label (_("Version:")) {
82+
xalign = 1
83+
};
84+
85+
version_value_label = new Gtk.Label ("") {
86+
xalign = 0,
87+
hexpand = true
88+
};
89+
90+
var vendor_label = new Gtk.Label (_("Vendor:")) {
91+
xalign = 1
92+
};
93+
94+
vendor_value_label = new Gtk.Label ("") {
95+
xalign = 0,
96+
hexpand = true
97+
};
98+
99+
var size_label = new Gtk.Label (_("Size:")) {
100+
xalign = 1
101+
};
102+
103+
size_value_label = new Gtk.Label ("") {
104+
xalign = 0,
105+
hexpand = true
106+
};
107+
108+
var install_duration_label = new Gtk.Label (_("Estimated time to install:")) {
109+
xalign = 1
110+
};
111+
112+
install_duration_value_label = new Gtk.Label ("") {
113+
xalign = 0,
114+
hexpand = true
115+
};
116+
117+
var key_val_grid = new Gtk.Grid () {
118+
column_homogeneous = true,
119+
column_spacing = 6,
120+
halign = Gtk.Align.CENTER,
121+
margin_top = 12,
122+
row_spacing = 3
123+
};
124+
key_val_grid.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL);
125+
126+
key_val_grid.attach (version_label, 0, 0);
127+
key_val_grid.attach (version_value_label, 1, 0);
128+
key_val_grid.attach (vendor_label, 0, 1);
129+
key_val_grid.attach (vendor_value_label, 1, 1);
130+
key_val_grid.attach (size_label, 0, 2);
131+
key_val_grid.attach (size_value_label, 1, 2);
132+
key_val_grid.attach (install_duration_label, 0, 3);
133+
key_val_grid.attach (install_duration_value_label, 1, 3);
134+
135+
placeholder = new Granite.Widgets.AlertView (
136+
"",
137+
_("There are no releases available for this device."),
138+
""
139+
);
140+
placeholder.get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW);
141+
142+
var grid = new Gtk.Grid () {
143+
halign = Gtk.Align.CENTER,
144+
margin = 12,
145+
orientation = Gtk.Orientation.VERTICAL,
146+
row_spacing = 12,
147+
vexpand = true
148+
};
149+
grid.add (summary_label);
150+
grid.add (description_label);
151+
grid.add (key_val_grid);
152+
153+
scrolled_window = new Gtk.ScrolledWindow (null, null) {
154+
hscrollbar_policy = Gtk.PolicyType.NEVER,
155+
vexpand = true
156+
};
157+
scrolled_window.add (grid);
158+
159+
content = new Gtk.Stack ();
160+
content.add (placeholder);
161+
content.add (scrolled_window);
162+
163+
orientation = Gtk.Orientation.VERTICAL;
164+
get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW);
165+
add (header_box);
166+
add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL));
167+
add (content);
168+
show_all ();
169+
170+
back_button.clicked.connect (() => {
171+
go_back ();
172+
});
173+
174+
update_button.clicked.connect (() => {
175+
go_back ();
176+
update (device, release);
177+
});
178+
}
179+
180+
public void update_view (Fwupd.Device device, Fwupd.Release? release) {
181+
this.device = device;
182+
this.release = release;
183+
184+
var device_name = device.get_name ();
185+
186+
title_label.label = "<b>%s</b>".printf (device_name);
187+
update_button_revealer.reveal_child = release != null;
188+
189+
if (release == null) {
190+
placeholder.title = device_name;
191+
192+
var icons = device.get_icons ();
193+
if (icons.data != null) {
194+
placeholder.icon_name = icons.data[0];
195+
} else {
196+
placeholder.icon_name = "application-x-firmware";
197+
}
198+
199+
content.visible_child = placeholder;
200+
201+
return;
202+
}
203+
204+
content.visible_child = scrolled_window;
205+
206+
var release_version = release.get_version ();
207+
if (release.get_flags () == Fwupd.RELEASE_FLAG_IS_UPGRADE && release_version != device.get_version ()) {
208+
update_button.label = _("Update");
209+
update_button.sensitive = true;
210+
} else {
211+
update_button.label = _("Up to date");
212+
update_button.sensitive = false;
213+
}
214+
215+
summary_label.label = release.get_summary ();
216+
try {
217+
description_label.label = AppStream.markup_convert_simple (release.get_description ());
218+
} catch (Error e) {
219+
description_label.label = "";
220+
warning ("Could not convert markup of release: %s", e.message);
221+
}
222+
version_value_label.label = release_version;
223+
vendor_value_label.label = release.get_vendor ();
224+
size_value_label.label = GLib.format_size (release.get_size ());
225+
226+
uint32 duration_minutes = release.get_install_duration () / 60;
227+
if (duration_minutes < 1) {
228+
install_duration_value_label.label = _("less than a minute");
229+
} else {
230+
install_duration_value_label.label = GLib.ngettext ("%llu minute", "%llu minutes", duration_minutes).printf (duration_minutes);
231+
}
232+
233+
show_all ();
234+
}
235+
236+
private void go_back () {
237+
if (deck == null) {
238+
deck = (Hdy.Deck) get_ancestor (typeof (Hdy.Deck));
239+
}
240+
241+
deck.navigate (Hdy.NavigationDirection.BACK);
242+
}
243+
}

0 commit comments

Comments
 (0)