Skip to content
CAI
Software that uses CAICheck a score

deckerst/aves

67.8

Adequate · 23 September 2026

126.6k

lines of production code

Dart

with Kotlin

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Aves is a Flutter-based Android gallery application that catalogs, views, and manages local media files. It provides robust image and video playback with extensive metadata extraction, editing, and geolocation features. The system supports multiple distribution flavors and includes native Android components for background analysis, widgets, and system integration.

How it got here

2019–2020 — Android platform migration and architecture overhaul

29 changes.

The project underwent a comprehensive migration of its Android native layer from Java to Kotlin, introducing a robust model layer for media entries and metadata extraction. This period also saw the removal of iOS support and the restructuring of the application into distinct distribution flavors, accompanied by a significant upgrade to the Gradle build system and the introduction of Material 3 theming.

2021–2023 — Service architecture and plugin expansion

33 changes.

The project refactored its core architecture by splitting metadata and media operations into dedicated service layers and introducing a suite of new Flutter plugins for video playback, error reporting, and gesture handling. This period also focused on expanding platform capabilities, including Android widgets, screen savers, and map integrations, while enhancing image processing utilities and geographic data features.

2024–2026 — database migration and media parsing enhancements

16 changes.

This period focused on migrating the local database to Sqflite with comprehensive version support and introducing a custom ExifInterface fork to resolve stability issues with large or malformed media files. Significant feature work included expanding metadata parsing for GeoTIFF, Panorama, and video formats, while also implementing advanced filtering, grouping, and video playback capabilities.

Features

Added Android signing key template and updated gitignore

The android module now includes a key\_template.properties file to guide developers in configuring keystore credentials (store file, passwords, alias) and the Google API key, alongside an updated .gitignore that explicitly excludes these sensitive files and standard build artifacts to prevent accidental commits.

android · high confidence

Added Arabic, Azerbaijani, Belarusian, Bulgarian, Bengali, Catalan, Kurdish (Sorani), and Czech translations

The app now supports Arabic, Azerbaijani, Belarusian, Bulgarian, Bengali, Catalan, Kurdish (Sorani), and Czech languages. These new localization files provide the interface strings for the welcome screen, viewer actions, settings, and system dialogs in these languages, expanding the app's internationalization coverage.

lib/l10n · high confidence

Added data models for video playback state and viewer viewport state

New immutable data classes have been introduced to track viewer state: \VideoPlaybackRow\ stores video entry IDs and resume times for database serialization, while \ViewState\ manages the viewer's zoom level, viewport dimensions, and pan position, including logic to calculate the transformation matrix for rendering.

lib/model/viewer · high confidence

Added metadata parsing constants for EXIF, XMP, IPTC, and GeoTIFF

The library now includes dedicated constant definitions for parsing image metadata, specifically adding the \Exif\ class with tag descriptions, \XmpNamespaces\ and related XMP element/attribute constants, \IPTC\ tag definitions, and \GeoTiff\ tag/constant definitions. These additions provide the foundational data structures required for interpreting EXIF, XMP, IPTC, and GeoTIFF metadata within image files.

lib/ref/metadata · high confidence

Added support for GeoTIFF and Panorama image metadata

The media model now includes dedicated parsing for GeoTIFF and Panorama image formats. GeoTIFF support enables mapping geotagged images onto map overlays by extracting coordinate systems and projecting image regions to map tiles. Panorama support handles metadata for 360-degree images, including logic to correct inconsistent sizing and orientation data often found in files from specific camera apps (e.g., Samsung, OnePlus), ensuring accurate display of cropped areas and full panorama dimensions.

lib/model/media · high confidence

Android screen state monitoring via native broadcast receiver

The \aves\_screen\_state\ plugin now exposes a \screenStateStream\ on Android that emits events when the device screen turns on, turns off, or is unlocked. This capability is implemented by registering a native Android \BroadcastReceiver\ for \ACTION\_SCREEN\_ON\, \ACTION\_SCREEN\_OFF\, and \ACTION\_USER\_PRESENT\ intents, which forwards the action strings to the Dart layer via an \EventChannel\. The plugin throws an exception if accessed on non-Android platforms, as this specific native integration is Android-only.

_plugins/aves\_screen\state · high confidence

Automated build, release, and documentation scripts

Added a suite of shell scripts to automate the generation of application flavors (Play, Libre, IzzyOnDroid), version bumps, changelog creation, APK extraction from Android App Bundles, and post-processing of screenshots for various store and documentation requirements.

scripts · high confidence

Bundled Flutter SDK and project scaffolding

The project now bundles the Flutter SDK as a git submodule (referenced in .flutter and .gitmodules) and provides a \flutterw\ wrapper script to ensure consistent builds across environments. This change introduces standard project configuration files including \analysis\_options.yaml\ for linting, \l10n.yaml\ for localization, \devtools\_options.yaml\ for debugging, and a comprehensive \.gitignore\. It also updates the \README.md\ with full project documentation, badges, and setup instructions, and adds a \LICENSE\ file.

(repo-wide) · high confidence

Console-based error reporting implementation for the Aves Report plugin

The Aves Report plugin now includes a console-based platform implementation that logs errors and events to the standard debug output instead of sending them to a remote service. This change introduces the \PlatformReportService\ class, which implements the \ReportService\ interface by printing messages, exceptions, and Flutter error details via \debugPrint\, and exposes a state indicating the reporter is 'Console'. Additionally, project configuration files such as \.gitignore\ and \analysis\_options.yaml\ have been added to standardize build exclusions and linting rules for this plugin.

_plugins/aves\_report\console · high confidence

Enhanced video metadata display with detailed codec and audio layout info

The video information view now provides richer technical details for media files. This includes human-readable names for audio channel layouts (such as 5.1 surround or 7.1 wide) and specific codec profiles for H.264, HEVC, and AAC, allowing users to see precise encoding settings like 'High Profile, Level 4.1' instead of generic identifiers. Additionally, the metadata parser has been improved to handle a wider variety of date formats found in video files, ensuring more accurate creation dates are displayed in the catalog.

lib/model/media/video · high confidence

Expanded metadata support for DNG, multi-page images, and motion photos

The metadata module now includes comprehensive support for DNG-specific tags (DngTags.kt) and additional Exif tags missing from the standard extractor (ExifTags.kt). It introduces MultiPage.kt to handle multi-page HEIC and JPEG MPF files, including Samsung HEIC motion photos with embedded video in the SEFD box, and MultiTrackMedia.kt to extract images from multi-track media. New capabilities include parsing Spherical Video V1 metadata (SphericalVideo.kt) and handling Google Device Container items for motion photos (GoogleDeviceContainer.kt). Metadata editing and removal are now supported via PixyMetaHelper.kt for XMP and IPTC data.

android/app/src/main/kotlin/deckers/thibault/aves/metadata · high confidence

Initial release of the aves\_report plugin

This change introduces the new aves\_report plugin, providing a unified interface for application error and event reporting. The plugin defines a ReportService abstract class that standardizes how errors, Flutter errors, and custom logs are recorded, including specific logic to reconstruct stack traces for better segmentation in Crashlytics. It also includes standard Flutter plugin configuration files (analysis options, metadata) and a .gitignore to manage build artifacts and private files.

_plugins/aves\report · high confidence

Introduces structured filter containers for groups, tags, and dynamic albums

The filter system now supports structured container types that allow users to organize and combine filters more flexibly. New \GroupBaseFilter\, \TagGroupFilter\, and \AlbumGroupFilter\ classes enable grouping logic for albums and tags, while \DynamicAlbumFilter\ allows creating dynamic albums based on custom filter criteria. Additionally, \SetOrFilter\ and \SetAndFilter\ provide logical OR and AND operations to combine multiple filters, enabling more complex and precise media filtering capabilities.

lib/model/filters/container · high confidence

New Android platform components for widgets, screen saver, search, and wallpaper

This change introduces several new Kotlin components in the Android app to support specific features. A new \AnalysisWorker\ replaces the previous foreground service for background media analysis, using WorkManager and a dedicated notification channel. Home widget support is expanded with a new \HomeWidgetConfigureActivity\ for settings and an updated \HomeWidgetProvider\ that handles responsive sizing and async image updates. A \ScreenSaverService\ is added to display photos as a system dream, along with a settings activity. Global search integration is implemented via a \SearchSuggestionsProvider\ content provider, and a \WallpaperActivity\ handles setting images as the device wallpaper. Additionally, a dummy \MediaPlaybackService\ is added to handle media button events when no active session exists, and \RouteNames\ are centralized.

android/app/src/main/kotlin/deckers/thibault/aves · high confidence

New AvesMagnifier plugin for pan and scale gesture handling

The \plugins/aves\_magnifier\ directory now contains a new Flutter plugin that provides a reusable \AvesMagnifier\ widget and associated controller logic for handling pan and scale gestures on content. This component, adapted from \photo\_view\ but generalized for any widget, manages zoom boundaries, scale states (initial, covering, original, zoomed in/out), and gesture recognition. It includes custom gesture recognizers to correctly handle gesture precedence when the magnifier is nested inside scrollable containers like \PageView\, supporting features such as edge-hit detection, fling gestures to escape edges, and single-finger quick scaling. The plugin also exposes configuration for minimum/maximum scales, initial scale references, and custom scroll physics to tune touch slop sensitivity.

_plugins/aves\magnifier · high confidence

New ExoPlayer-backed video controller plugin

A new video playback implementation has been added to the Aves ecosystem, introducing the \aves\_video\_exo\ plugin. This component provides an \ExoVideoController\ that wraps the Flutter \video\_player\ package, which in turn utilizes the Android ExoPlayer engine for video rendering. The plugin includes a factory (\ExoVideoControllerFactory\) to instantiate these controllers and exposes standard playback capabilities such as play, pause, seek, and speed control, along with status and event streams for integration into the main application's video viewing logic.

_plugins/aves\_video\exo · high confidence

New Glide module for robust video thumbnail generation

A new VideoThumbnailGlideModule has been added to handle video thumbnail loading via Glide. This module implements a custom ModelLoader and DataFetcher that attempts to extract thumbnails by first checking for embedded pictures, then falling back to extracting video frames at optimal times (middle for short videos, first for very short ones). It includes logic to handle video rotation, scale frames to target dimensions, and manages API-level differences in MediaMetadataRetriever usage to prevent crashes on older Android versions.

android/app/src/main/kotlin/deckers/thibault/aves/glide · high confidence

New MPV-based video playback plugin

The \plugins/aves\_video\_mpv\ directory introduces a new video controller implementation backed by the \media\_kit\ library (using the MPV engine). This plugin provides the core playback logic, including support for A-B repeat, slow-motion speed adjustment, external subtitle loading, and video chapter metadata. It also handles specific playback fixes such as preventing incorrect video looping and managing hardware acceleration settings, serving as the concrete player implementation for the video viewer.

_plugins/aves\_video\mpv · high confidence

New app metadata and support model files

Added new model files in lib/model/app to centralize application metadata and capabilities. contributors.dart now lists all translators and contributors with their contact details. dependencies.dart defines the app's third-party dependencies, licenses, and source URLs, organized by platform (Android vs Flutter) and build flavor (Izzy, Libre, Play). intent.dart defines constants for app intent actions and data keys. permissions.dart specifies the required Android permissions for storage and media access. support.dart provides logic to determine which file formats can be decoded and which metadata types (EXIF, IPTC, XMP) can be edited or removed for specific MIME types.

lib/model/app · high confidence

New geo library for country detection, state data, and URI handling

The lib/geo directory now contains the core logic for geographic features. countries.dart implements reverse geocoding to identify countries from coordinates using a TopoJSON asset, processing the data in an isolate to avoid blocking the UI. states.dart provides a mapping of emoji codes to state/province names for Australia, Brazil, India, Mexico, the UK, and the US. topojson.dart adds a parser for TopoJSON geometry data to support the country detection. uri.dart introduces support for parsing and generating geo: URIs, enabling the app to handle location links.

lib/geo · high confidence

New location, tag, and album filters with custom cover colors

Users can now filter their media library by location (country, state, or place), by tags, and by stored albums. These new filters support custom cover colors, allowing users to visually distinguish albums and other filtered groups within the library view.

lib/model/filters/covered · high confidence

New location-based filtering and geocoding infrastructure

The application now includes a new backend layer for managing location data, introducing mixins for Country, State, and Place filtering within the collection source. This change adds the ability to reverse-geocode entries to determine their country, state, and place, caching these results to optimize performance. It also implements filter summaries (entry counts, sizes, and recent entries) for these location attributes, enabling users to browse and filter their media library by geographic location.

lib/model/source/location · high confidence

New metadata model classes for cataloging, address, and date editing

The metadata layer introduces several new data models to support enhanced cataloging and editing capabilities. \CatalogMetadata\ now tracks specific media attributes such as HDR, slow motion, motion photos, and 360-degree content via bit flags, while also handling geolocation validation. \AddressDetails\ provides structured storage for geographic data, including state codes for countries like Brazil, Australia, the UK, and the US. \DateModifier\ defines the logic for editing EXIF dates, including copying from other fields, extracting from filenames, and shifting by seconds. Additionally, \OverlayMetadata\ stores camera shooting details (aperture, ISO, etc.) for display, and \TrashDetails\ manages metadata for deleted items.

lib/model/metadata · high confidence

New platform-channel service layer for Android capabilities

The app introduces a comprehensive set of new Dart service classes in lib/services that act as a platform-channel bridge to native Android capabilities. These services enable the app to query and control device-specific features such as accessibility settings (animation removal, bold fonts, long-press timeouts), media analysis and background scanning, global search integration, geocoding, storage permissions (SAF and MediaStore), app profile switching (work profiles), and window management (HDR, wide color gamut, multi-window, cutout awareness). This refactoring centralizes platform interactions, allowing the Flutter UI to reliably access native Android APIs for performance, accessibility, and system integration.

lib/services · high confidence

New platform-channel service layer for media operations

The app introduces a set of new Dart service classes in lib/services/media that act as a platform-channel bridge for core media functionality. These services enable the app to request EXIF thumbnails, extract embedded items (such as Google Camera portrait-mode data, motion-photo images/videos, JPEG MPF items, and video cover art), and parse XMP properties via the embedded\_data\_service. It also adds a media\_edit\_service to handle file operations like delete, move, copy, rename, and bulk export/conversion with configurable name-conflict strategies, while the media\_fetch\_service manages image decoding (full, region, and thumbnail) and byte streaming. Additionally, a media\_session\_service synchronizes playback state and handles remote commands (play, pause, skip, seek), and a media\_store\_service monitors media store changes and scans files. Together, these services centralize native platform interactions for media retrieval, editing, and playback control.

lib/services/media · high confidence

New plugin model layer for actions, settings, and metadata

The \plugins/aves\_model\ directory has been introduced as a dedicated Flutter package to centralize the application's core data model and configuration. This change adds a comprehensive set of enums and classes that define available user actions (such as entry editing, collection management, and video controls), standardize metadata field handling (including EXIF, XMP, and MP4 metadata), and manage application settings (covering themes, accessibility, and video playback options). It also establishes the foundational types for storage volumes and relative directories, providing a structured, type-safe interface for the rest of the app to interact with media entries and user preferences.

_plugins/aves\model · high confidence

New reference library for app-specific metadata and constants

A new \lib/ref\ directory has been introduced to centralize reference data and constants used across the application. This includes mappings for known app directory names (such as Google Photos, Instagram, and WhatsApp) to improve album detection, regex patterns for identifying burst photo sequences from manufacturers like Sony, Samsung, and Motorola, and a comprehensive list of ISO 639-2 language codes. The library also provides MIME type definitions and normalization logic for various image and video formats, MP4 brand identifiers, UPnP protocol constants, and locale-specific rules for Arabic numeral display and text direction.

lib/ref · high confidence

New thumbnail and TIFF region fetching implementations

The decoding module now includes dedicated classes for fetching thumbnails and specific regions of TIFF images. ThumbnailFetcher handles thumbnail generation by prioritizing native Android APIs (ContentResolver or MediaStore) for standard images and videos, falling back to Glide for custom formats like SVG, TIFF, or multi-page documents, and includes logic to only rescale bitmaps when the size reduction is significant to optimize memory usage. TiffRegionFetcher enables efficient decoding of specific rectangular regions within TIFF files using the TiffBitmapFactory, allowing for targeted image processing without loading the entire image into memory.

android/app/src/main/kotlin/deckers/thibault/aves/decoding · high confidence

New utility library for Android file handling, date parsing, and XMP metadata

This change introduces a new set of utility classes in the \lib/utils\ directory to support core application functions. \AndroidFileUtils\ manages storage volumes, standard directory paths (DCIM, Downloads, etc.), and album type detection for Android. \time\_utils\ provides robust date parsing from various formats and handles timestamp overflow, while \xmp\_utils\ adds capabilities to read, write, and manage XMP metadata in XML. Additional utilities include \file\_utils\ for localized file size formatting, \mime\_utils\ for display type conversion, \emoji\_utils\ for country code flags, and \debouncer\ for UI event handling.

lib/utils · high confidence

New utility library for color extraction, collections, and platform channels

The \aves\_utils\ plugin has been introduced to provide shared utilities for the application. It includes a \ColorExtractor\ class that derives dynamic color schemes from images using the \material\_color\_utilities\ package, replacing previous color generation logic. The library also adds collection extensions for replacing items in lists and sets, and handling nullable map keys/values, alongside helper classes for \ChangeNotifier\ and \ValueListenableBuilder\ to improve state management flexibility. Additionally, it provides an \OptionalEventChannel\ for safer platform channel communication and various math and vector utility extensions.

_plugins/aves\utils · high confidence

New utility library for image processing, compatibility, and file operations

The app introduces a new set of utility classes in the utils package to enhance image handling and system compatibility. BitmapConversion now supports advanced color space transformations, including conversion between ARGB\_8888, RGBA\_1010102, and RGBA\_F16, as well as HDR gain map processing for improved image display. BmpWriter provides a custom implementation for exporting images to BMP format. Compatibility wrappers (Compat, Compat33) ensure correct behavior across Android versions, particularly for APIs introduced in Android 13 (Tiramisu) and Android 14 (UpsideDownCake). Additional utilities include HashUtils for MD5/SHA-1/SHA-256 hashing, FileUtils for efficient file operations, and MemoryUtils for heap and RAM monitoring.

android/app/src/main/kotlin/deckers/thibault/aves/utils · high confidence

Support for MPF (Multi-Picture Format) metadata extraction

The app now extracts and displays metadata from Multi-Picture Format (MPF) JPEG segments, enabling visibility into specific tags such as MPF Version, Number of Images, MP Entry details, Image UID List, and Total Frames. This allows users to view structured information for images containing multiple embedded pictures or complex multi-image structures.

android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor/mpf · high confidence

Vaults now support custom lock types and automatic recovery of untracked items

Vaults can now be configured with a custom lock type (e.g., pattern lock) instead of relying solely on the system default, and this setting is persisted in the vault details. Additionally, when unlocking a vault, the system automatically scans for and recovers any untracked media items found in the vault directory, adding them to the collection and database while cleaning up invalid directory entries.

lib/model/vaults · high confidence

Removals

Removal of legacy Java utility classes

The \Constants\ and \Utils\ Java classes in the \aves.utils\ package have been removed. This eliminates hardcoded MIME type definitions (video, JPEG, PNG, GIF) and the \createLogTag\ helper method that shortened class names for logging, indicating a shift away from these specific Java-based utilities within the application's utility layer.

android/app/src/main/java/deckers/thibault/aves/utils · high confidence

Removal of legacy MediaStore image provider

The \MediaStoreImageProvider\ class, which previously handled fetching image and video entries from the Android MediaStore via direct URI queries, has been removed. This change eliminates the legacy implementation that relied on specific MediaStore projections and direct file path resolution, indicating a shift toward a different mechanism for media retrieval within the application.

android/app/src/main/java/deckers/thibault/aves/model/provider · high confidence

Removed iOS platform support

The iOS build configuration and source files have been completely removed from the project. This includes the Xcode project, workspace, schemes, and all native iOS assets such as the app icon, launch screen, and storyboard files. The app will no longer be buildable or distributable on iOS devices.

ios · high confidence

Architecture

Android platform code migrated to Kotlin

The Android native layer has been rewritten in Kotlin, replacing the previous Java implementation. This migration introduces a new architecture for platform communication, utilizing dedicated stream and method channel handlers (such as ImageByteStreamHandler and ActivityResultStreamHandler) to manage image decoding, file operations, and system events more efficiently within the Flutter engine.

app · high confidence

App restructured into Play, Izzy, and Libre flavors with dedicated entry points

The application has been refactored to support three distinct distribution flavors: Play, Izzy, and Libre. This is implemented by introducing an \AppFlavor\ enum and dedicated entry-point files (\main\_play.dart\, \main\_izzy.dart\, \main\_libre.dart\) that initialize a shared \mainCommon\ logic. The flavor configuration controls specific behavioral differences, such as enabling error reporting only for the Play flavor and disabling default map styles for Izzy and Libre. The previous single \main.dart\ entry point and associated legacy widget files have been removed to accommodate this multi-flavor architecture.

lib · high confidence

Metadata operations are now handled by a split service architecture

The metadata logic has been split into dedicated services: \MetadataEditService\ now manages write operations (rotate, flip, date editing, metadata removal) via platform channels, while \MetadataFetchService\ handles all read operations (catalog, overlay, IPTC, XMP, GeoTiff, multi-page, and panorama info). A new \SvgMetadataService\ provides native Dart parsing for SVG dimensions and metadata, and \AvesXmp\ models XMP data structures. This separation isolates edit and fetch concerns, improves error handling for specific MP4 issues, and adds native SVG support.

lib/services/metadata · high confidence

Refactored collection source into modular mixins and dedicated lens

The \lib/model/source\ package has been restructured to improve maintainability and separation of concerns. The monolithic source logic is now split into focused mixins: \AlbumMixin\ handles album directory tracking and filter summaries, \TagMixin\ manages tag cataloging and updates, and \TrashMixin\ handles bin recovery and expiration. A new \CollectionLens\ class now acts as the central coordinator for filtering, sorting, and sectioning entries, listening to source events to keep the view state in sync. Additionally, an \AnalysisController\ was introduced to manage the analysis service lifecycle and memory leak tracking, while \CollectionSource\ now orchestrates these components to load entries from the media store and apply hidden filters.

lib/model/source · high confidence

Refactored media entry logic into dedicated extension files

The monolithic entry logic in \lib/model/entry/extensions\ has been reorganized into distinct, single-responsibility extension files: \catalog.dart\ (handling metadata fetching and heap management), \favourites.dart\ (managing favorite toggling), \images.dart\ (providing thumbnail and full-image caching keys), \info.dart\ (formatting metadata directories and video chapters), \keys.dart\ (defining platform field constants), \location.dart\ (geocoding and country detection), \metadata\_edition.dart\ (editing EXIF/XMP dates, locations, and rotation), \multipage.dart\ (handling stacked and multi-page media), and \props.dart\ (defining media type checks, trash status, and edit permissions). This change improves code maintainability and separation of concerns without altering user-facing features.

lib/model/entry/extensions · high confidence

Settings configuration extracted into dedicated defaults and storage modules

The application's settings logic has been reorganized to improve maintainability and separation of concerns. A new \defaults.dart\ file centralizes all default configuration values for features such as navigation, viewer overlays, collection sorting, and accessibility, ensuring consistent initial states. The main \settings.dart\ class now acts as a unified interface that aggregates these defaults and manages persistence, while a new \store\_shared\_pref.dart\ module explicitly handles the underlying \SharedPreferences\ storage operations. This change decouples the storage implementation from the settings logic, allowing for easier testing and future migration of the persistence layer.

lib/model/settings · high confidence

Settings model refactored into modular mixins

The application's settings storage has been restructured from a monolithic implementation into a set of focused mixins (such as AppSettings, CollectionSettings, NavigationSettings, and ViewerSettings) located in lib/model/settings/modules. This change organizes configuration options by domain—covering app behavior, display themes, collection layouts, navigation, privacy, and widgets—improving maintainability and separation of concerns without altering the user-facing settings interface.

lib/model/settings/modules · high confidence

Behavioural changes

About page layout and TV navigation overhaul

The About page has been restructured to use a dedicated mobile layout (lib/widgets/about/about\_mobile\_page.dart) that presents app references, bug reporting, data usage, credits, and translators in a single scrollable list. For TV devices, the page now features a dedicated layout (lib/widgets/about/about\_tv\_page.dart) with a side navigation rail that allows users to switch between sections like links, credits, translators, and licenses, improving navigation and focus management on large screens.

lib/widgets · high confidence

Added Firebase configuration and ProGuard rules for app optimization

The app now includes a google-services.json file configuring Firebase services for the main, debug, and profile build variants, enabling features like crash reporting. Additionally, a new proguard-rules.pro file has been added to optimize the release build by preserving specific classes from libraries such as TiffBitmapFactory, MP4Parser, and EXIF metadata handling, ensuring these components are not stripped during code shrinking.

android/app · high confidence

Added stub implementation for map services on non-mobile platforms

The \aves\_services\_none\ plugin now includes a concrete \PlatformMobileServices\ class that implements the \MobileServices\ interface. This implementation provides no-op behavior for initialization and explicitly returns empty lists for map styles and a null default style. Crucially, the \buildMap\ method now returns an empty \SizedBox\ widget instead of throwing or being unimplemented, ensuring that map-related UI components render safely without errors on platforms where native map services are not available.

_plugins/aves\_services\none · high confidence

Adopts intl4x for decimal number formatting and date formatting

The locale layer now uses the intl4x library for formatting decimal numbers and dates, replacing the previous intl-based approach for these specific tasks. This change enables support for preferred numbering systems (such as Western Arabic numerals) and improves date formatting consistency across different calendar systems, including the newly supported Persian calendar.

lib/locale · high confidence

Android activity implementation migrated from Java to Kotlin

The native Android activity file for the app has been removed and replaced with a Kotlin implementation. This change updates the underlying platform code language while maintaining the existing method channel interface for media store access and thumbnail fetching.

android/app/src/main/java/deckers/thibault/aves · high confidence

Centralized view-layer extensions for UI labels and icons

This change introduces a comprehensive set of view-layer extensions in the \lib/view\ package to handle the display logic for various model enums. These new files provide localized text labels and corresponding icons for actions (such as entry, collection, and map actions), settings (including theme, calendar, and video playback options), metadata fields, and source configurations (like sorting and layout). By centralizing this mapping, the application ensures consistent presentation of UI elements across different contexts, such as the viewer, explorer, and settings screens.

lib/view · high confidence

Custom ExifInterface fork added to prevent OOM and crash issues

A new \ExifInterfaceFork\ class has been introduced in the \android/exifinterface\ module, forked from \androidx.exifinterface:exifinterface:1.4.2\. This custom implementation is designed to address stability issues such as OutOfMemory errors when processing large thumbnails or RAW files, and crashes caused by invalid Exif offsets or large PNG metadata. The fork includes specific safeguards, such as an \ATTRIBUTE\_SIZE\_DANGER\_THRESHOLD\ to limit memory allocation during attribute parsing, ensuring more robust handling of malformed or large media files during cataloging.

exifinterface · high confidence

Database layer refactored to Sqflite with comprehensive migration support

The local media database implementation has been rewritten to use Sqflite, introducing a new schema (version 16) that supports dynamic albums, vaults, and high-precision date metadata. This change includes a robust upgrade path from previous versions (v1–v15) to ensure data integrity during updates, along with a new table existence check mechanism for safer initialization on older Android devices.

lib/model/db · high confidence

Google Maps plugin now supports Android API levels below 23

The Google Maps service implementation in the \aves\_services\_google\ plugin has been updated to ensure compatibility with older Android devices. The platform initialization logic now detects the Android SDK version and automatically falls back to Hybrid Composition (\useAndroidViewSurface = true\) for devices running API level 22 or lower, preventing rendering failures that occurred with the default Texture Layer Hybrid Composition. This change allows the map feature to function correctly on a wider range of hardware without requiring users to upgrade their operating system.

_plugins/aves\_services\google · high confidence

Introduces background isolate support for platform channels

The \lib/services/common\ module now includes \channel\_isolate.dart\, which provides a \ChannelIsolate\ class that routes platform channel method calls to a background isolate. This prevents platform communication from blocking the main isolate, improving UI responsiveness during operations like geocoding, media session updates, and metadata fetching. The change also introduces \channel.dart\ with debug-enabled method and stream channels, \service\_policy.dart\ for prioritized task queuing, and \decoding.dart\ for optimized pixel format conversions.

lib/services/common · high confidence

Map plugin refactored with new internal architecture and style definitions

The map plugin has been restructured to use a new internal architecture, introducing dedicated modules for the map controller, geographic data models (GeoEntry, GeoTrack), and marker generation. This change includes the addition of a new map style definition system (EntryMapStyle) that supports custom URL templates, subdomains, and user agents, alongside updated default tile providers such as OpenTopoMap and OSM HOT. The plugin also now includes a new AvesDot UI component for marker rendering and implements memory leak tracking for the map controller.

_plugins/aves\map · high confidence

New Kotlin platform channel handlers for accessibility, analysis, and device capabilities

The Android native layer now includes a suite of new Kotlin handlers in the \channel/calls\ directory to replace or supplement previous implementations. \AccessibilityHandler\ exposes system accessibility settings (animation removal, long-press timeout, bold font preference) to the Flutter UI. \AnalysisHandler\ manages background media analysis tasks using Android WorkManager, storing entry IDs in shared preferences to bypass data limits. \AppProfileHandler\ enables switching between work and personal profiles on supported devices. \DeviceHandler\ provides device capabilities, locale configuration, media performance class, and memory information. \EmbeddedDataHandler\ handles extraction of thumbnails, XMP data, and motion photo components. \GeocodingHandler\ performs reverse geocoding using the native Android Geocoder. \GlobalSearchHandler\ registers callbacks for OS-level search integration. \HomeWidgetHandler\ triggers updates for the app widget. \MediaEditHandler\ manages file operation cancellation and video frame capture. \Coresult\ provides a safe wrapper for MethodChannel results to ensure they are delivered on the main thread. These changes improve stability, accessibility compliance, and integration with modern Android features.

android/app/src/main/kotlin/deckers/thibault/aves/channel · high confidence

New filter model architecture with dedicated filter types

The filter system has been restructured into a modular, serializable model. A new \CollectionFilter\ base class in \filters.dart\ defines the interface for all filters, including \fromJson\/\toJsonMap\ for persistence. New dedicated filter classes have been added for specific criteria: \AspectRatioFilter\ (landscape/portrait), \CoordinateFilter\ (geographic bounds), \DateFilter\ (with multi-level granularity and calendar support), \FavouriteFilter\, \MimeFilter\ (replacing specific GIF/video filters with a flexible MIME type approach), \MissingFilter\ (for missing date, address, or title metadata), \PathFilter\, \PlaceholderFilter\ (for country/state/place tags), \QueryFilter\ (supporting regex, field-based queries like ID/year/size, and NOT logic), \RatingFilter\ (with range operators), \RecentlyAddedFilter\, \TrashFilter\, \TypeFilter\ (for specialized formats like HDR, RAW, motion photos, panoramas), and \WeekDayFilter\. This change centralizes filter logic, improves serialization reliability, and expands the range of searchable attributes.

lib/model/filters · high confidence

New model layer for album grouping, dynamic albums, and app-based album detection

The \lib/model\ directory has been refactored to introduce a new model layer that powers album grouping, dynamic albums, and improved app album detection. A new \AppInventory\ service now tracks installed launcher packages and their potential directories to identify app-specific albums, while \DynamicAlbums\ and \Covers\ manage the lifecycle and cover images for these dynamic and grouped collections. Supporting this are new \Device\ capabilities checks, \Favourites\ management, \MultiPageInfo\ for handling multipage media, and \NamingPattern\ processors for bulk renaming.

lib/model · high confidence

New model layer for media entries and metadata extraction

The app introduces a new Kotlin model layer in the \aves.model\ package to handle media entry data and metadata retrieval. This includes \AvesEntry\ for representing cataloged items with properties like URI, dimensions, rotation, and trash status, and \SourceEntry\ for initial metadata extraction from files using multiple strategies (MediaMetadataRetriever, MetadataExtractor, ExifInterface, and bitmap decoding) to ensure robust handling of various formats including videos, TIFFs, and images with large EXIF data. Supporting classes like \EntryFields\ define the data schema, \ExifOrientationOp\ handles rotation/flip operations, and \NameConflictStrategy\ manages file operation conflicts. This refactoring centralizes entry logic and improves stability during cataloging.

android/app/src/main/kotlin/deckers/thibault/aves/model · high confidence

New settings enum extensions for animations, transitions, and widget shapes

The app now includes dedicated logic files for several settings enums, enabling more granular control over the user experience. Users can now configure viewer transitions (slide, parallax, fade, zoom, random, or none) and customize home screen widget shapes (including bumpy rows/columns, tear rects, wavy circles, and hearts). Accessibility is improved with configurable animation states (system, enabled, disabled) and snack bar timeouts (1s to 30s). Additional settings allow controlling display refresh rate, subtitle vertical position, theme brightness, screen-on behavior, and widget outline colors (including dynamic system colors and high-contrast variants).

lib/model/settings/enums · high confidence

New theme system with dynamic color modes and Material 3 styling

The application introduces a new theming architecture in lib/theme that replaces the previous color and style definitions. Users now have access to distinct color modes including monochrome, neon (dark), and pastel (light), with dynamic accent colors derived from app icons or system settings. The visual style has been updated to follow Material 3 design principles, featuring updated typography, iconography using Material Symbols, and refined component themes for navigation, dialogs, and overlays. Animation durations and delays are now centrally managed for consistent performance and accessibility, including options to disable animations for users who prefer reduced motion.

lib/theme · high confidence

New unified grouping model for albums and tags

The application introduces a new \FilterGrouping\ system in \lib/model/grouping\ that manages hierarchical groupings for both albums and tags. This change adds a centralized mechanism to organize media items into nested groups, automatically sanitizing obsolete or empty groups when source data changes (such as entry moves or removals). It also implements URI-based serialization and deserialization logic to convert between internal filter objects and persistent URI strings, enabling consistent grouping structures across album and tag contexts.

lib/model/grouping · high confidence

Prevents crashes and out-of-memory errors when cataloging images with large XMP metadata

The metadata extraction layer now safely handles images (JPEG, PNG, GIF, PSD, MP4, TIFF) containing excessively large XMP data or chunks that previously caused the app to crash or run out of memory. Custom readers now detect oversized metadata segments—such as extended XMP in JPEGs, large PNG chunks, or bloated Photoshop resource blocks—and skip them with a warning instead of attempting to load them into memory. Additionally, the XMP parser now enforces node limits on specific fields like 'crs:Dabs' and 'DocumentAncestors' to prevent excessive memory allocation during parsing.

android/app/src/main/kotlin/deckers/thibault/aves/metadata/metadataextractor · high confidence

Refactored entry model with new caching, directory resolution, and sorting logic

The entry model layer has been restructured to improve performance and reliability. A new \EntryCache\ class manages image provider keys to ensure cached images are correctly evicted when file URIs change, addressing previous cache eviction issues. Directory path handling now includes an \EntryDirRepo\ that resolves ambiguous case-sensitive paths on Android, ensuring the correct file system casing is used. Additionally, a dedicated \AvesEntrySort\ class centralizes sorting logic, supporting new sort options such as by storage path and duration, alongside existing methods like name, date, rating, and size.

lib/model/entry · high confidence

Refactored image loading to use raw image descriptors for improved performance

The image provider layer in \lib/image\_providers\ has been rewritten to fetch raw image descriptors from the platform (Android) and instantiate codecs directly within Flutter. This change applies to all image types—thumbnails, full images, regions, and app icons—by introducing new providers (\ThumbnailProvider\, \FullImageProvider\, \RegionProvider\, \AppIconImageProvider\, and \DescriptorImageProvider\) that leverage the \mediaFetchService\ to obtain descriptors. This approach replaces previous decoding strategies, aiming to improve image streaming performance and pixel format selection by handling the heavy lifting of image decoding more efficiently at the platform boundary.

_lib/image\providers · high confidence

Refactored media provider architecture to Kotlin with improved URI handling

The media provider layer has been rewritten in Kotlin, introducing a new \ImageProviderFactory\ that routes URI requests to specific providers (\MediaStoreImageProvider\, \FileImageProvider\, \AvesEmbeddedMediaProvider\, and \UnknownContentProvider\). This change enhances how the app handles different media sources, including safer parsing of content URIs, better support for embedded media via the app's file provider, and more robust file-based image fetching with MIME type detection. The refactoring also improves handling of obsolete Media Store entries and fixes issues with accessing files in restricted directories on Android R+.

android/app/src/main/kotlin/deckers/thibault/aves/model/provider · high confidence

Removal of legacy ImageEntry model class

The \ImageEntry\ class, which previously served as the core data model for representing media items (including methods for retrieving file streams, URIs, and metadata), has been removed from the application. This change eliminates the legacy intermediate model structure in favor of the updated data handling approach implemented in the surrounding codebase.

android/app/src/main/java/deckers/thibault/aves/model · high confidence

Updated Gradle daemon JVM to Adoptium JDK 21

The Android build system now uses Adoptium (Temurin) JDK 21 for the Gradle daemon, configured via a new \gradle-daemon-jvm.properties\ file that specifies download URLs for various platforms. This change updates the underlying Java runtime used for the build process, which may affect build performance and compatibility with existing build scripts or plugins.

android/gradle · high confidence

Video playback plugin introduces A-B repeat, slow-motion range control, and hardware acceleration defaults

The video playback plugin now supports A-B repeat functionality, allowing users to loop a specific segment of a video, and provides controls to define a slow-motion range with adjustable speed factors. Additionally, the default hardware acceleration mode has been changed to 'forced' to improve playback performance, and the plugin exposes settings for subtitle styling (font size, color, alignment) and video loop modes (never, short only, always).

_plugins/aves\video · high confidence

Fixes

Crashlytics plugin now handles Firebase initialization failures gracefully

The \aves\_report\_crashlytics\ plugin has been updated to prevent crashes when the Firebase SDK is not yet initialized. The new \PlatformReportService\ implementation wraps calls to \Firebase.app()\ and \FirebaseCrashlytics.instance\ in try-catch blocks, logging errors via \debugPrint\ instead of throwing exceptions. This ensures that reporting methods (such as logging, setting custom keys, or recording errors) fail silently or return null when Firebase is unavailable, rather than causing a black screen or app crash during launch if Firebase initialization fails.

_plugins/aves\_report\crashlytics · high confidence

Fixes for storage access during settings export and moving items out of app media directories

This update resolves two specific storage access issues. First, it fixes the automatic export of settings, ensuring that storage permissions are correctly handled so that configuration data can be saved without interruption. Second, it corrects the behavior when moving media items out of the app's internal media directories; previously, such moves might have failed or behaved unexpectedly due to permission restrictions, but the new logic in the storage permission delegates (FilePermissions, MediaStorePermissions, and SafPermissions) now properly validates and grants the necessary access for these operations.

android/app/src/main/kotlin/deckers/thibault/aves/storage · high confidence

Test coverage

Added test infrastructure and unit tests for core services and models; Added unit tests for image provider timezone handling and math utilities; Automated screenshot generation driver for IzzyOnDroid releases.

Dependencies

Added local ExifInterface fork module to resolve dependency conflicts

The project now includes a local copy of the ExifInterface library (forked from androidx.exifinterface:exifinterface:1.4.2) within the android/exifinterface directory. This module, named with a 'Fork' suffix (e.g., ExifInterfaceUtilsFork), is designed to be loaded as a sub-dependency, allowing the application to bypass potential classpath conflicts or version mismatches with the standard AndroidX library while retaining the core EXIF parsing utilities.

android/exifinterface · high confidence

Android build system migrated to Gradle Kotlin DSL and version catalogs

The Android build configuration has been completely rewritten from Groovy to Kotlin DSL (\.kts\), introducing a centralized version catalog (\libs.versions.toml\) to manage dependencies. This migration upgrades the Android Gradle Plugin to version 9.4.1 and the Kotlin compiler to 2.4.10, while enforcing a JDK 21 toolchain via the Adoptium vendor. The build now supports three distinct store flavors (Play, IzzyOnDroid, and F-Droid/libre) with specific packaging rules, such as compressed native libraries for the Izzy flavor. Additionally, the project now includes a custom \exifinterface\ module to handle metadata extraction, and build optimizations like R8 full mode and parallel execution are enabled.

(dependencies) · high confidence

Gradle wrapper upgraded to version 9.7.1

The Android build system now uses Gradle 9.7.1 (previously 5.1.1) via the wrapper configuration. This upgrade updates the underlying build toolchain used to compile and package the Android application.

android/gradle/wrapper · high confidence

Housekeeping

Added placeholder for l10ngen directory; Release notes for v1.15.4 highlight calendar, layout, and Thai language support.

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 68.

Lenses

  • Code Health 83
  • Architecture 97
  • Maturity 59
  • Readiness 76
  • Security 67
  • Domain Modelling 100

Changes since last survey

  • 300 commits — 243 feature/other, 57 fixes

By area

  • lib/widgets — 88 commits
  • .github/workflows — 53 commits
  • (root) — 49 commits
  • lib/model — 35 commits
  • android/app — 30 commits
  • fastlane/metadata — 10 commits
  • lib/l10n — 8 commits
  • lib/services — 5 commits
  • android/gradle — 4 commits
  • lib/locale — 3 commits
  • lib/utils — 3 commits
  • scripts/extract_apks_libre.sh — 2 commits
  • (repo) — 1 commit
  • .github/dependabot.yml — 1 commit
  • android/exifinterface — 1 commit
  • android/gradle.properties — 1 commit
  • lib/geo — 1 commit
  • lib/main_common.dart — 1 commit
  • lib/theme — 1 commit
  • plugins/aves_magnifier — 1 commit

Notable commits

  • fix: #1489 fixed image cache and region decoder eviction on change while in background
  • fix: #1516 fix for intl4x in profile/release modes
  • fix: #1688 #1273 fixed opening transient images from camera apps
  • fix: #1688 viewer: fixed showing other items in directory when opening item is known but not at provided path
  • fix: #2063 fixed video thumbnail loading on Android 17
  • fix: #2102 fixed parsing XMP from images with a ton of dabs
  • fix: #2119 panorama: fixed orientation jumps at 360 degree limit
  • fix: #2128 l10n: fixed kmr feature graphic
  • fix: #2143 fixed empty Info page when animations are disabled
  • fix: #2196 fixed permission check for Samsung Dual Messenger
  • fix: #2227 fixed HEIC thumbnail rotation
  • fix: #2228 viewer: fixed obsolete description in overlay
  • fix: #2251 fixed album app detection
  • fix: #2253 fixed storage access for automatic settings export
  • fix: #2263 fixed moving items out of app media directories
  • fix: #2266 fixed editing date with alternate calendar
  • fix: #585: fixed slow motion video displayed duration
  • fix: #769 #1923 slideshow: fixed transition when animations are disabled
  • fix: collection: fixed post-op snack bar not showing
  • fix: extent change fixes
  • …and 280 more

Architecture

  • 0 containers · 2 bounded contexts · 0 dependency edges (baseline)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

deckerst/aves was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 6785e82d65cb50fe7e2313dcf452e09e3aed8575 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.