Connected Devices: fixed UI settings. fixed pairing protocol
This commit is contained in:
+63
-15
@@ -67,48 +67,70 @@ fn draw_settings_rows(frame: &mut Frame, area: Rect, state: &AppState) {
|
||||
}
|
||||
|
||||
y = y.saturating_add(1);
|
||||
let connected_devices_enabled = state.connected_devices_enabled();
|
||||
draw_section(frame, area, &mut y, "Connected Devices");
|
||||
let disabled_value = "enable federation first".to_string();
|
||||
let devices = state.federation.devices.as_ref();
|
||||
draw_row(
|
||||
draw_row_enabled(
|
||||
frame,
|
||||
area,
|
||||
&mut y,
|
||||
cursor,
|
||||
state.settings_cursor,
|
||||
"This device name",
|
||||
devices
|
||||
.map(|status| status.this_device_name.clone())
|
||||
.unwrap_or_else(|| "loading…".to_string()),
|
||||
if connected_devices_enabled {
|
||||
devices
|
||||
.map(|status| status.this_device_name.clone())
|
||||
.unwrap_or_else(|| "loading…".to_string())
|
||||
} else {
|
||||
disabled_value.clone()
|
||||
},
|
||||
connected_devices_enabled,
|
||||
);
|
||||
cursor += 1;
|
||||
draw_row(
|
||||
draw_row_enabled(
|
||||
frame,
|
||||
area,
|
||||
&mut y,
|
||||
cursor,
|
||||
state.settings_cursor,
|
||||
"Generate device invite",
|
||||
"↵".to_string(),
|
||||
if connected_devices_enabled {
|
||||
"↵".to_string()
|
||||
} else {
|
||||
disabled_value.clone()
|
||||
},
|
||||
connected_devices_enabled,
|
||||
);
|
||||
cursor += 1;
|
||||
draw_row(
|
||||
draw_row_enabled(
|
||||
frame,
|
||||
area,
|
||||
&mut y,
|
||||
cursor,
|
||||
state.settings_cursor,
|
||||
"Connect device by invite…",
|
||||
"↵".to_string(),
|
||||
if connected_devices_enabled {
|
||||
"↵".to_string()
|
||||
} else {
|
||||
disabled_value.clone()
|
||||
},
|
||||
connected_devices_enabled,
|
||||
);
|
||||
cursor += 1;
|
||||
draw_row(
|
||||
draw_row_enabled(
|
||||
frame,
|
||||
area,
|
||||
&mut y,
|
||||
cursor,
|
||||
state.settings_cursor,
|
||||
"Sync devices now",
|
||||
"↵".to_string(),
|
||||
if connected_devices_enabled {
|
||||
"↵".to_string()
|
||||
} else {
|
||||
disabled_value.clone()
|
||||
},
|
||||
connected_devices_enabled,
|
||||
);
|
||||
cursor += 1;
|
||||
if let Some(status) = devices {
|
||||
@@ -125,12 +147,15 @@ fn draw_settings_rows(frame: &mut Frame, area: Rect, state: &AppState) {
|
||||
} else {
|
||||
format!("v{}", device.client_version)
|
||||
};
|
||||
let value = if device.is_self || device.revoked {
|
||||
let can_revoke = connected_devices_enabled && !device.is_self && !device.revoked;
|
||||
let value = if can_revoke {
|
||||
format!("{version} · revoke ↵")
|
||||
} else if connected_devices_enabled {
|
||||
version
|
||||
} else {
|
||||
format!("{version} · revoke ↵")
|
||||
disabled_value.clone()
|
||||
};
|
||||
draw_row(
|
||||
draw_row_enabled(
|
||||
frame,
|
||||
area,
|
||||
&mut y,
|
||||
@@ -138,6 +163,7 @@ fn draw_settings_rows(frame: &mut Frame, area: Rect, state: &AppState) {
|
||||
state.settings_cursor,
|
||||
&label,
|
||||
value,
|
||||
connected_devices_enabled,
|
||||
);
|
||||
cursor += 1;
|
||||
}
|
||||
@@ -234,6 +260,19 @@ fn draw_row(
|
||||
cursor: usize,
|
||||
label: &str,
|
||||
value: String,
|
||||
) {
|
||||
draw_row_enabled(frame, area, y, row_index, cursor, label, value, true);
|
||||
}
|
||||
|
||||
fn draw_row_enabled(
|
||||
frame: &mut Frame,
|
||||
area: Rect,
|
||||
y: &mut u16,
|
||||
row_index: usize,
|
||||
cursor: usize,
|
||||
label: &str,
|
||||
value: String,
|
||||
enabled: bool,
|
||||
) {
|
||||
if *y >= area.y + area.height {
|
||||
return;
|
||||
@@ -248,10 +287,19 @@ fn draw_row(
|
||||
let marker = if selected { "▶ " } else { " " };
|
||||
let label_width = 48usize;
|
||||
let line = Line::from(vec![
|
||||
Span::styled(marker, theme::accent()),
|
||||
Span::styled(
|
||||
marker,
|
||||
if enabled {
|
||||
theme::accent()
|
||||
} else {
|
||||
theme::dim()
|
||||
},
|
||||
),
|
||||
Span::styled(
|
||||
format!("{label:<label_width$}"),
|
||||
if selected {
|
||||
if !enabled {
|
||||
theme::dim()
|
||||
} else if selected {
|
||||
theme::accent()
|
||||
} else {
|
||||
ratatui::style::Style::default()
|
||||
|
||||
+3
-9
@@ -847,7 +847,7 @@ fn draw_search(frame: &mut Frame, area: Rect, state: &AppState, cursor: usize) {
|
||||
index += 1;
|
||||
}
|
||||
for fed in &state.search.fed_tracks {
|
||||
let heart = if state.fed_likes.contains(&fed.item_id) {
|
||||
let heart = if state.fed_track_liked(fed) {
|
||||
Span::styled("♥ ", theme::accent())
|
||||
} else {
|
||||
Span::raw(" ")
|
||||
@@ -1090,10 +1090,7 @@ fn draw_fed_appearance_row(
|
||||
visual_selected: bool,
|
||||
) {
|
||||
let track = &appearance.track;
|
||||
let liked = track
|
||||
.sources
|
||||
.iter()
|
||||
.any(|(_, item_id)| state.fed_likes.contains(item_id));
|
||||
let liked = state.fed_card_track_liked(track);
|
||||
let heart = if liked {
|
||||
Span::styled("♥ ", theme::accent())
|
||||
} else {
|
||||
@@ -1276,10 +1273,7 @@ fn draw_fed_release(frame: &mut Frame, area: Rect, state: &AppState, index: usiz
|
||||
duration
|
||||
};
|
||||
let in_selection = state.track_selection.contains(&scope, position);
|
||||
let liked = track
|
||||
.sources
|
||||
.iter()
|
||||
.any(|(_, item_id)| state.fed_likes.contains(item_id));
|
||||
let liked = state.fed_card_track_liked(track);
|
||||
let heart = if liked {
|
||||
Span::styled("♥ ", theme::accent())
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ pub(crate) fn track_row(
|
||||
let fed_liked = track
|
||||
.fed
|
||||
.as_ref()
|
||||
.is_some_and(|fed| state.fed_likes.contains(&fed.item_id));
|
||||
.is_some_and(|fed| state.fed_track_liked(fed));
|
||||
let heart = if state.likes.contains(&track.id) || fed_liked {
|
||||
Span::styled("♥ ", theme::accent())
|
||||
} else {
|
||||
|
||||
+59
-6
@@ -40,8 +40,17 @@ pub fn draw(frame: &mut Frame, state: &AppState) {
|
||||
device_id,
|
||||
name,
|
||||
client_version,
|
||||
requester_group_id,
|
||||
requester_group_active_devices,
|
||||
..
|
||||
}) => draw_device_pairing(frame, device_id, name, client_version),
|
||||
}) => draw_device_pairing(
|
||||
frame,
|
||||
device_id,
|
||||
name,
|
||||
client_version,
|
||||
requester_group_id.as_deref(),
|
||||
*requester_group_active_devices,
|
||||
),
|
||||
Some(Popup::ConfirmDeviceRevoke { device_id, name }) => {
|
||||
draw_device_revoke(frame, device_id, name)
|
||||
}
|
||||
@@ -136,8 +145,20 @@ fn draw_fed_text(frame: &mut Frame, title: &str, text: &str) {
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_device_pairing(frame: &mut Frame, device_id: &str, name: &str, client_version: &str) {
|
||||
let area = centered(frame.area(), 64, 8);
|
||||
fn draw_device_pairing(
|
||||
frame: &mut Frame,
|
||||
device_id: &str,
|
||||
name: &str,
|
||||
client_version: &str,
|
||||
requester_group_id: Option<&str>,
|
||||
requester_group_active_devices: usize,
|
||||
) {
|
||||
let group_conflict = requester_group_id.is_some() && requester_group_active_devices > 1;
|
||||
let area = centered(
|
||||
frame.area(),
|
||||
if group_conflict { 76 } else { 64 },
|
||||
if group_conflict { 12 } else { 8 },
|
||||
);
|
||||
let block = Block::bordered()
|
||||
.title(" Pair device ")
|
||||
.title_style(theme::header())
|
||||
@@ -145,7 +166,7 @@ fn draw_device_pairing(frame: &mut Frame, device_id: &str, name: &str, client_ve
|
||||
let inner = block.inner(area);
|
||||
frame.render_widget(Clear, area);
|
||||
frame.render_widget(block, area);
|
||||
let lines = vec![
|
||||
let mut lines = vec![
|
||||
Line::from(vec![
|
||||
Span::styled("Name ", theme::dim()),
|
||||
Span::raw(name.to_string()),
|
||||
@@ -158,9 +179,41 @@ fn draw_device_pairing(frame: &mut Frame, device_id: &str, name: &str, client_ve
|
||||
Span::styled("Device ", theme::dim()),
|
||||
Span::raw(device_id.chars().take(24).collect::<String>()),
|
||||
]),
|
||||
Line::default(),
|
||||
Line::styled("y accept · n/esc deny", theme::dim()),
|
||||
];
|
||||
if let Some(group_id) = requester_group_id.filter(|_| group_conflict) {
|
||||
lines.extend([
|
||||
Line::from(vec![
|
||||
Span::styled("Group ", theme::dim()),
|
||||
Span::raw(format!(
|
||||
"{} · {requester_group_active_devices} active devices",
|
||||
group_id.chars().take(24).collect::<String>()
|
||||
)),
|
||||
]),
|
||||
Line::default(),
|
||||
Line::styled(
|
||||
"Recommended joins that group and keeps its peers syncing.",
|
||||
theme::dim(),
|
||||
),
|
||||
Line::styled(
|
||||
"Cancel keeps this group; that device will switch groups and its peers may stop syncing.",
|
||||
theme::dim(),
|
||||
),
|
||||
Line::default(),
|
||||
Line::from(vec![
|
||||
Span::styled(" Recommended ", theme::tab_active()),
|
||||
Span::raw(" "),
|
||||
Span::styled(" Cancel ", theme::danger_button()),
|
||||
])
|
||||
.alignment(Alignment::Center),
|
||||
Line::styled("y recommended · c cancel · n/esc deny", theme::dim())
|
||||
.alignment(Alignment::Center),
|
||||
]);
|
||||
} else {
|
||||
lines.extend([
|
||||
Line::default(),
|
||||
Line::styled("y accept · n/esc deny", theme::dim()),
|
||||
]);
|
||||
}
|
||||
frame.render_widget(Paragraph::new(lines), inner);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user