minor updates

This commit is contained in:
KaraZajac
2026-02-17 22:37:39 -05:00
parent 4bc7bd7beb
commit 77547bb437
16 changed files with 222 additions and 6 deletions
+25
View File
@@ -1119,6 +1119,13 @@ impl App {
}
/// Generate a default export filename (without extension) for a capture
/// Path relative to the import directory for display; falls back to full path if not under import_dir.
fn path_relative_to_import(path: &std::path::Path, import_dir: &std::path::Path) -> String {
path.strip_prefix(import_dir)
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_else(|_| path.to_string_lossy().to_string())
}
fn default_export_filename(capture: &Capture) -> String {
format!(
"{}_{}",
@@ -1387,6 +1394,7 @@ impl App {
// Deduplicate: same signal can decode at multiple stream positions (e.g. Ford V0 across bursts)
let mut seen: std::collections::HashSet<(String, u64, Option<u32>, Option<u8>)> =
std::collections::HashSet::new();
let mut any_decoded_added = false;
for (protocol_name, decoded, segment_pairs) in decoded_list {
let key = (
protocol_name.clone(),
@@ -1427,11 +1435,26 @@ impl App {
if research_mode || capture.protocol.is_some() {
if !self.capture_duplicate_of_existing(&capture) {
self.next_capture_id += 1;
capture.source_file = Some(Self::path_relative_to_import(path, self.storage.import_dir()));
self.captures.push(capture);
imported += 1;
any_decoded_added = true;
}
}
}
// When no protocol decoded the stream, add a single Unknown capture if research_mode (same as live capture).
if !any_decoded_added && research_mode && !raw_pairs.is_empty() {
let mut capture = crate::capture::Capture::from_pairs_with_rf(
self.next_capture_id,
frequency,
raw_pairs.clone(),
None,
);
self.next_capture_id += 1;
capture.source_file = Some(Self::path_relative_to_import(path, self.storage.import_dir()));
self.captures.push(capture);
imported += 1;
}
}
Err(e) => tracing::warn!("Failed to import {:?}: {}", path, e),
}
@@ -1439,6 +1462,7 @@ impl App {
match crate::export::fob::import_fob(path, self.next_capture_id) {
Ok(mut capture) => {
self.next_capture_id += 1;
capture.source_file = Some(Self::path_relative_to_import(path, self.storage.import_dir()));
// Re-run decoder when Unknown and raw_pairs present (same as .sub)
if capture.status == crate::capture::CaptureStatus::Unknown
&& !capture.raw_pairs.is_empty()
@@ -1638,6 +1662,7 @@ impl App {
make: None,
model: None,
region: None,
source_file: None,
};
self.next_capture_id += 1;
self.captures.push(capture);
+4
View File
@@ -76,6 +76,9 @@ pub struct Capture {
/// Region (e.g. NA, EU) for vulnerability lookup and .fob export.
#[serde(default)]
pub region: Option<String>,
/// Source file path when imported from .sub or .fob; None for live captures.
#[serde(default)]
pub source_file: Option<String>,
}
/// Modulation type used by protocol (encoding: PWM vs Manchester)
@@ -154,6 +157,7 @@ impl Capture {
make: None,
model: None,
region: None,
source_file: None,
}
}
+2
View File
@@ -306,6 +306,7 @@ fn import_fob_v2(fob: &FobFile, next_id: u32) -> Result<Capture> {
make: None,
model: None,
region: None,
source_file: None,
})
}
@@ -376,6 +377,7 @@ fn import_fob_v1(fob: &FobFileV1, next_id: u32) -> Result<Capture> {
make: None,
model: None,
region: None,
source_file: None,
})
}
+17
View File
@@ -271,6 +271,23 @@ fn render_signal_detail(frame: &mut Frame, area: Rect, capture: &crate::capture:
Span::styled(raw_info, raw_style),
]));
// Row 8: File path (imported .sub/.fob only; blank for live captures)
let file_display = capture
.source_file
.as_deref()
.unwrap_or("");
left_lines.push(Line::from(vec![
Span::styled(" File: ", label_style),
Span::styled(
file_display,
if file_display.is_empty() {
Style::default().fg(Color::DarkGray)
} else {
value_style
},
),
]));
// Build the title
let title = format!(
" Signal #{:02}{} ",