Repository navigation
Conversation
Delete global references while the capture thread is still attached and reap every capture thread exactly once, so a loop that exits on its own no longer blocks the next start. Classify TLS/HTTP only on a flow's first payload, notify Java only about TCP flows, and drop the always-false sent flag from the payload callback.
A same-type continuation of a single-object payload such as 21905 now emits the pending payload as its own event rather than silently replacing it. Also remove a quarantine ternary whose null branch was unreachable.
Every store for the same canonical directory now shares one process-wide lock, listing no longer deletes files, and only saving rotates recent history. Saved history no longer borrows the recent-history limit; both stores share one path-safe directory helper, one atomic write utility, and one log-time formatter.
Keep the open batch in memory behind an atomically reserved .partial name and write the deduplicated roster once at protocol completion, so SaveResult.rowCount always matches the published file.
Replace the two copies of the bounded CSV tokenizer and the history envelope split with single implementations, and collapse the repeated decoder field loops into inline helpers that keep zero-allocation skipping of unknown fields.
Move every screen onto ComponentActivity with system-bar and keyboard insets, and add the shared top bar, screen shell, background work, document access, label, dialog, and state-view building blocks used by the redesigned screens.
Replace stringly-typed capture messages with CapturePhase, localized CaptureNotice entries, and one immutable CaptureSnapshot swapped by CAS, so UI and service updates and guided-payload marks can no longer tear or lose writes. Status and pending-Platoon candidates now notify main-looper listeners; read() and readGuidedProgress() remain as deprecated delegates until the UI migrates. The pending store keeps a running payload total instead of summing on every offer.
CaptureVpnService is now main-thread lifecycle glue. One service-lifetime CaptureWorker owns all flow, parser, session, and admission state; native chunks share its bounded budget while teardown and admission tasks are never rejected. Teardown joins the native thread, drains queued chunks, and clears state on that worker, and a start requested meanwhile waits for it. Pending-Platoon confirm and discard therefore also work after capture stopped. Flow routing moves to CaptureFlowEngine, admission to PlatoonAdmissionCoordinator, the notification to CaptureNotifications, counters to CaptureTrafficStats, and the one-time checklist to CaptureRunTracker. Package UIDs are resolved once per session, an unchanged 21905 no longer rewrites the profile registry, the duplicate routing paths and PROFILE checklist marks are merged, and the stale 'not integrated yet' message is replaced.
Manual weekly edits are now merged with stored overrides by a tested policy that reports the invalid field instead of a generic failure.
- Platoon: virtualized roster with search, Active/Withdrawn/All filter, sort chooser, summary tiles, and long-press selection for CSV export. - Member detail: stats card, profile fields that survive recreation and are no longer wiped by history edits, and labelled membership periods. - Member order: drag handles with move up/down accessibility actions and confirmed reset; snapshot comparison moved off the main thread. - All repository work runs through lifecycle-bound background work.
- Sticky day header and frozen member column with synced horizontal scrolling in one virtualized list; 12sp+ cells instead of 8-11sp. - Tapping a cell explains every metric of that day in one sheet; edit mode edits one day at a time with tri-state Login/Patrol choices, highlighted changes, cancel with discard confirmation, and drafts that survive recreation. - Notes are deleted only through an explicit delete action; week navigator, evidence summary, and a live-table action for restored history; exports regenerate content instead of holding it in memory. - History preview renders the native table instead of a bitmap, restore cannot be submitted twice, and cutline settings validate per field. - Shared weekly PNGs use localized evidence text and the app palette.
- Home observes typed capture status through listeners instead of polling English text: localized notices, a one-time checklist, client install state, and one Stop action while busy. Notification permission is requested when capture starts instead of at launch. - Packet history uses Recent/Saved tabs with long-press selection, confirmed deletion, and off-main-thread loading. - Roster CSV import moves into its own flow with a structured preview. - Settings groups Platoon, display, capture, backup, Discord, and about; both backup kinds and restore live there, and diagnostics open as a copyable sheet. The welcome guide can be replayed. - New-Platoon admission prompts follow the pending store directly, keep the chosen server across recreation, and close when resolved. - Packet detail toggles between table and raw text in both directions. - Remove the legacy tree-walking styler and toast helpers.
A roster captured exactly at Sunday 05:00 closes the previous week, and a current roster or membership event is the carried-in baseline of later weeks, but only the capture's own game week was re-recorded. Weekly history refresh now also re-records those listed neighbours within the per-ingest bound.
…egion A complete restore wrote the archived effective region as an explicit override, and a later Platoon-only restore could change the profile region while that override kept the old zone. Restores now restore an archived profile region as automatic, clear the override when a Platoon-only restore changes the region, and journal the exact timezone keys so rollback no longer turns automatic into explicit.
Custom nicknames and private, membership-period, and weekly notes had no length limit below the input fields. Manual edits now trim and reject a name over 256 characters or a note over 1,000 characters before any row is written.
The restore journal rejected a region or zone string that the timezone reader tolerates, so an interrupted restore with such a key could never finish recovering. The journal now replays the raw keys unchanged.
Cleanup deleted the settings snapshot before the PREPARED state, and recovery then required the missing snapshot, so a process death there failed recovery on every launch. Cleanup now deletes the state first and recovery treats a missing snapshot as already rolled back.
Editing Login to no over a stored Daily Patrol yes, or the reverse, produced an attended=false, dailyPatrol=true override that replaceWeeklyOverrides refuses, failing the whole save. The edited choice now settles the contradiction, and contradictory choices in one edit are reported as invalid.
The share projection cut member labels at 128 and private notes at 512 UTF-16 units, which could leave half of a surrogate pair and render a broken glyph. Shortening now stops before a split pair.
…checks The consistency policy dated snapshot and exact boundaries in UTC while manual dates are game-zone calendar dates, and compared instants when a date was missing. A manual stay before a same-day exact join, or a date-only rejoin on the day of an exact withdrawal, was then rejected as an overlap. Missing dates are now derived in the Platoon's game zone.
The history codec never wrote a cell's manual override, so a restored revision lost its MANUAL precision, Clear action, and edited values, and an edit started from it saw no existing overrides. Revisions with overrides now use history format 3 and carry them; revisions without overrides keep format 2 bytes and fingerprints.
Settings reads passed a target package copied unvalidated from the v2.2 store straight to the complete-backup codec, which rejected it, so complete export and restore failed. Reads now fall back to the default package exactly as the legacy migration already did.
seal released the scope claim in its own finally, so after a failed seal runImport rolled the import back unclaimed and then released the claim again, possibly clearing another operation's claim. runImport now holds one claim across apply, seal, and rollback and releases it once.
Drops the unreferenced PlatoonActivityFact and DailyActivity models, the unused MemberRow.observedDays, MemberRow.hasIncompleteEvidence, and DayCell.isGunsmokeActivityUnknown properties, a correlation sort branch excluded by its own WHERE clause, and an always-false solver condition, and reuses ActivityInference.counterDelta in snapshot comparison.
…ivity A roster that joins or withdraws a member can date the boundary to an activity time after the previous roster, in an earlier week, but only the roster's own week was re-recorded. The refresh now also covers the times of the membership events the roster recorded.
… fields - Weekly saves merge with the stored overrides, so a restored table or an off-roster member keeps its values - Nickname and note inputs use the persistence limits; contradictory login/patrol choices get their own message - Follow the weekly PNG state into its export flow in the recreation test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refactor, bug-fix and UI/UX overhaul for 2.5.0. Intended to be squash-merged; see
CHANGELOG.mdfor the full list.Capture
Management data
UI/UX
uitoolkit (screen shell, top bar, controls, dialogs, background work).Dependencies
androidx.activity:activity:1.12.4(only new dependency).2.4.20-Beta1-> stable2.4.21. The CodeQL compatibility pin is unchanged.Testing
:protocol:test,:app:testDebugUnitTest,:app:assembleDebug,:app:compileDebugAndroidTestKotlin,:app:lintDebug(0 errors) pass locally.