Fix performance, add screenshots, make banner scrollable

- Make detail view banner scroll with content instead of staying fixed,
  preventing tall banners from eating screen space
- Optimize squashfs offset scanning with buffered 256KB chunk reading
  instead of loading entire file into memory (critical for 1.5GB+ files)
- Add screenshot URL parsing from AppStream XML and async image display
  with carousel in the overview tab
- Fix infinite re-analysis bug: has_appstream check caused every app
  without AppStream data to be re-analyzed on every startup. Now handled
  via one-time migration reset in v10
- Database migration v10: add screenshot_urls column, reset analysis
  status for one-time re-scan with new parser
This commit is contained in:
lashman
2026-02-27 18:44:50 +02:00
parent 1bb7a3bdc0
commit 8362e066f7
8 changed files with 231 additions and 34 deletions

View File

@@ -26,6 +26,7 @@ pub struct AppStreamMetadata {
pub content_rating_summary: Option<String>,
pub releases: Vec<ReleaseInfo>,
pub mime_types: Vec<String>,
pub screenshot_urls: Vec<String>,
}
#[derive(Debug, Clone)]
@@ -64,6 +65,8 @@ pub fn parse_appstream_xml(xml: &str) -> Option<AppStreamMetadata> {
let mut in_content_rating = false;
let mut current_content_attr_id = String::new();
let mut in_developer = false;
let mut in_screenshots = false;
let mut in_screenshot_image = false;
let mut depth = 0u32;
let mut description_depth = 0u32;
let mut release_desc_depth = 0u32;
@@ -161,6 +164,14 @@ pub fn parse_appstream_xml(xml: &str) -> Option<AppStreamMetadata> {
"category" if in_categories => {
current_tag = "category".to_string();
}
"screenshots" if in_component => {
in_screenshots = true;
}
"image" if in_screenshots => {
// Prefer "source" type, but accept any <image>
in_screenshot_image = true;
current_tag = "screenshot_image".to_string();
}
"developer" if in_component => {
in_developer = true;
}
@@ -252,6 +263,12 @@ pub fn parse_appstream_xml(xml: &str) -> Option<AppStreamMetadata> {
"categories" => {
in_categories = false;
}
"screenshots" => {
in_screenshots = false;
}
"image" if in_screenshot_image => {
in_screenshot_image = false;
}
"developer" => {
in_developer = false;
}
@@ -301,6 +318,11 @@ pub fn parse_appstream_xml(xml: &str) -> Option<AppStreamMetadata> {
"category" => {
meta.categories.push(text);
}
"screenshot_image" => {
if text.starts_with("http") && meta.screenshot_urls.len() < 10 {
meta.screenshot_urls.push(text);
}
}
"developer_name" => {
if meta.developer.is_none() {
meta.developer = Some(text);