Skip to content

Remove team color dependency from drawings#71

Merged
SunkenInTime merged 25 commits into
mainfrom
agent-team-color-removal
May 10, 2026
Merged

Remove team color dependency from drawings#71
SunkenInTime merged 25 commits into
mainfrom
agent-team-color-removal

Conversation

@SunkenInTime
Copy link
Copy Markdown
Owner

Summary

  • Reworks drawing serialization to store ARGB color integers instead of stringified colors, while keeping backward compatibility with older saved data.
  • Adds custom Hive adapters and registration for drawing types to preserve persisted drawings across the color format change.
  • Introduces neutral team color support plus a customizable color library and updated color picker/settings UI.
  • Expands app preferences to persist custom colors and default team-size/color settings for new strategies.

Testing

  • Not run (not requested).
  • Added/updated unit coverage for color persistence and strategy settings behavior.
  • Manual verification not performed in this turn.

SunkenInTime and others added 6 commits April 21, 2026 20:20
- Migrate drawing elements and serializers from `Color` strings to `colorValue`
- Preserve legacy JSON and Hive payloads during read
- Add regression tests for JSON and Hive color persistence
- Register source-owned adapters for free, line, rectangle, and ellipse drawings
- Preserve legacy color fields while writing the current colorValue field
- Update generated Hive metadata and registrar outputs
- Introduce a reusable BetterColorPicker style and palette
- Update color picker consumers to use the new custom styling
- Persist custom swatch colors in app preferences
- Replace hardcoded color pickers with shared color library UI
- Allow adding, editing, and deleting custom colors
- Persist neutral team colors in strategy settings and app defaults
- Apply neutral marker styling across strategy pages and agent widgets
- Add coverage for strategy settings JSON and shade conversion
Copilot AI review requested due to automatic review settings May 1, 2026 03:37
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the drawing “team color” dependency by standardizing color persistence around ARGB integers (colorValue) across JSON + Hive, while adding UI/support for neutral team colors and a reusable/customizable color library.

Changes:

  • Migrates drawing serialization/deserialization to persist ARGB ints (colorValue) with backward compatibility for legacy string/Color payloads.
  • Adds neutral team color support plus strategy/global default settings (agent size, ability size, neutral colors) persisted via AppPreferences.
  • Replaces flutter_colorpicker usage with an in-repo BetterColorPicker and updates color-picking UI to use the new shared ColorLibrary.

Reviewed changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/strategy_settings_provider_test.dart Adds unit coverage for useNeutralTeamColors JSON default/persistence and neutral shading behavior.
test/drawing_provider_test.dart Updates drawing JSON tests to assert colorValue is emitted and restored.
test/color_persistence_test.dart Adds JSON + Hive regression tests for int color persistence and legacy payload compatibility.
pubspec.yaml Removes flutter_colorpicker dependency.
pubspec.lock Removes flutter_colorpicker lock entry and updates transitive versions.
lib/widgets/sidebar_widgets/text_tools.dart Switches text tag color selection to shared ColorLibrary.
lib/widgets/sidebar_widgets/drawing_tools.dart Switches pen color selection to shared ColorLibrary.
lib/widgets/sidebar_widgets/custom_shape_tools.dart Switches custom shape color selection to shared ColorLibrary.
lib/widgets/sidebar_widgets/color_library.dart Adds a reusable palette widget with custom color add/edit/delete via dialog.
lib/widgets/settings_tab.dart Adds strategy vs global settings modes; introduces neutral team colors + new-strategy defaults UI.
lib/widgets/map_theme_settings_section.dart Replaces flutter_colorpicker dialog content with BetterColorPicker.
lib/widgets/icarus_color_picker_style.dart Defines shared styling for BetterColorPicker across dialogs.
lib/widgets/folder_edit_dialog.dart Replaces folder color custom picker with BetterColorPicker.
lib/widgets/draggable_widgets/shared/framed_ability_icon_shell.dart Applies neutral team shading to ally/enemy outlines when enabled.
lib/widgets/draggable_widgets/image/placed_image_builder.dart Replaces hardcoded tag palette with colorLibraryProvider entries.
lib/widgets/draggable_widgets/agents/agent_widget.dart Applies neutral team coloring to agent background/outline when enabled.
lib/widgets/draggable_widgets/agents/agent_feedback_widget.dart Applies neutral team coloring to drag feedback background/outline when enabled.
lib/widgets/dialogs/upload_image_dialog.dart Switches image tag color selection to shared ColorLibrary.
lib/widgets/better_color_picker.dart Introduces in-repo color picker widget (replacing external dependency usage).
lib/providers/strategy_settings_provider.g.dart Adds JSON field for useNeutralTeamColors.
lib/providers/strategy_settings_provider.dart Adds useNeutralTeamColors to model/provider state.
lib/providers/strategy_provider.dart Writes drawing elements using colorValue; applies neutral colors across pages; uses app defaults for new strategies.
lib/providers/map_theme_provider.dart Extends AppPreferences to persist defaults + custom colors; adds setters.
lib/providers/drawing_provider.dart Writes colorValue to JSON and reads legacy formats via _readDrawingColorValue.
lib/providers/color_library_provider.dart Adds providers/controller for default + custom color library persisted in AppPreferences.
lib/hive/hive_registration.dart Ensures new custom drawing adapters are registered for Hive + isolated Hive.
lib/hive/hive_registrar.g.dart Removes drawing adapters from generated registrar (now registered explicitly).
lib/hive/hive_adapters.g.yaml Updates Hive type schemas for new/changed fields and removes generated drawing adapters.
lib/hive/hive_adapters.g.dart Updates Hive adapters for updated fields (StrategySettings/AppPreferences) and removes generated drawing adapters.
lib/hive/hive_adapters.dart Adds explicit drawing adapters persisting int colors + legacy read support.
lib/const/settings.dart Adds neutralTeamShade helper.
lib/const/drawing_element.g.dart Updates JSON serialization to use colorValue.
lib/const/drawing_element.dart Reworks drawing element color storage to colorValue with derived color getter + legacy JSON read support.
AGENTS.md Adds guidance about not manually editing generated files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 21 to 31
StrategySettings copyWith({
double? agentSize,
double? abilitySize,
bool? useNeutralTeamColors,
bool? isOpen,
}) {
return StrategySettings(
agentSize: agentSize ?? this.agentSize,
abilitySize: abilitySize ?? this.abilitySize,
useNeutralTeamColors: useNeutralTeamColors ?? this.useNeutralTeamColors,
);
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StrategySettings.copyWith accepts an isOpen parameter but StrategySettings has no isOpen field and the returned instance never uses this value. This makes isOpen a no-op and potentially misleading. Either remove isOpen from copyWith (and any callers) or add a persisted isOpen field if it's intended to be part of the model/state.

Copilot uses AI. Check for mistakes.
Comment thread AGENTS.md
- **Linux build deps.** `clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-14-dev` must be installed for Linux desktop builds.
- **Code generation.** After changing Hive models, Riverpod providers, or JSON-serializable classes, regenerate with: `fvm flutter pub run build_runner build --delete-conflicting-outputs`.
- **Generated files are outputs, not edit targets.** Never manually edit generated files like `*.g.dart`, `*.g.yaml`, or registrar outputs. Make changes in the source files that drive generation, or replace generated behavior with explicit source-owned code such as a custom adapter, then regenerate.
- **No automated tests exist** in this codebase. `flutter test` will find nothing.
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENTS.md now says “No automated tests exist … flutter test will find nothing”, but the repo has a substantial test/ suite (and this PR adds/updates tests). This guidance is now misleading—please update/remove that bullet so contributors run the tests instead of skipping them.

Suggested change
- **No automated tests exist** in this codebase. `flutter test` will find nothing.
- **Tests.** Run `fvm flutter test` to execute the automated test suite.

Copilot uses AI. Check for mistakes.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 1, 2026

Greptile Summary

This PR migrates drawing element color storage from Color objects / hex strings to ARGB integer values, adds hand-written Hive adapters with backward-compat reading, introduces a user-customizable color library, and extends AppPreferences and StrategySettings with per-strategy neutral-team-color and size defaults.

  • P1 — stale state in applyNeutralTeamColorsToAllPages: the method writes all-page settings to Hive but never updates StrategyProvider.state; switching to another page after toggling the setting will re-initialize strategySettingsProvider from the stale in-memory pages and silently revert the toggle for every non-active page.
  • P2 — _readDrawingColorValue throws on missing color keys instead of defaulting to white, diverging from the Hive path's silent fallback and risking a crash on corrupt drawing data.

Confidence Score: 3/5

Not safe to merge as-is; the neutral-color setting silently reverts for non-active pages after a page switch.

One clear P1 defect: applyNeutralTeamColorsToAllPages writes all-page settings to Hive but leaves StrategyProvider.state stale, so switching pages undoes the change in memory. The rest of the color migration (Hive adapters, JSON backward compat, color library) looks correct and well-tested.

lib/providers/strategy_provider.dart — missing state update in applyNeutralTeamColorsToAllPages.

Important Files Changed

Filename Overview
lib/providers/strategy_provider.dart New applyNeutralTeamColorsToAllPages method writes to Hive for all pages but does not update in-memory state, causing stale useNeutralTeamColors on page switches; all other changes are mechanical colorValue renames.
lib/providers/drawing_provider.dart Manual JSON serialisation switched to colorValue int; _readDrawingColorValue helper adds backward compat for legacy string colors but throws on null rather than defaulting, inconsistent with the Hive path.
lib/hive/hive_adapters.dart Adds hand-written TypeAdapters for FreeDrawing, Line, RectangleDrawing, and EllipseDrawing that write colorValue as int; backward compat handled via switch case over Color vs int; field counts and indices verified correct.
lib/hive/hive_registration.dart Drawing adapters moved from auto-generated registration to conditional manual registration via isAdapterRegistered guards; pattern is correct and safe.
lib/const/drawing_element.dart Replaces Color color field with int colorValue across all drawing element subclasses; backward-compat JSON reading via custom @JsonKey converters handling both int and legacy String color formats.
lib/providers/color_library_provider.dart New provider for a per-user custom color library (max 15) backed by AppPreferences.customColorValues; CRUD operations are correct and immutable list semantics are maintained.
lib/providers/map_theme_provider.dart AppPreferences extended with custom color list and per-strategy defaults (agent size, ability size, neutral team colors); new Hive fields correctly appended with optional reads and defaults.
lib/providers/strategy_settings_provider.dart Adds useNeutralTeamColors field with JSON round-trip support; generated _$StrategySettingsFromJson correctly defaults to false.
lib/widgets/settings_tab.dart Settings panel refactored to a two-mode (Strategy / Global) tab switcher; neutral team color toggle added with paired provider updates via addPostFrameCallback.
test/color_persistence_test.dart Comprehensive new tests covering JSON round-trip, Hive write/read for all four drawing types, and legacy Color payload backward compat; registers a local _TestColorAdapter absent in production.

Sequence Diagram

sequenceDiagram
    participant UI as SettingsTab (UI)
    participant SSP as strategySettingsProvider
    participant SP as StrategyProvider
    participant Hive as Hive Box

    UI->>SSP: updateNeutralTeamColors(value)
    SSP->>SSP: state = state.copyWith(useNeutralTeamColors: value)

    UI->>SP: applyNeutralTeamColorsToAllPages(value)
    SP->>SP: _syncCurrentPageToHive()
    SP->>Hive: box.get(state.id)
    Hive-->>SP: StrategyData (all pages)
    SP->>SP: newPages = pages.map(p => p.copyWith(settings(...value)))
    SP->>Hive: box.put(updated.id, updated)
    Note over SP: state NOT updated with newPages
    SP->>SP: setUnsaved()

    Note over UI,SP: User switches page
    UI->>SSP: reads strategySettingsProvider
    SSP->>SP: reads state.pages[newPage].settings
    Note over SP,SSP: stale state — useNeutralTeamColors = old value
Loading

Reviews (1): Last reviewed commit: "Add neutral team color settings" | Re-trigger Greptile

Comment on lines 3672 to 3707
setUnsaved();
}

Future<void> applyNeutralTeamColorsToAllPages(bool value) async {
if (state.stratName == null) return;

await _syncCurrentPageToHive();

final box = Hive.box<StrategyData>(HiveBoxNames.strategiesBox);
final strat = box.get(state.id);
if (strat == null || strat.pages.isEmpty) return;

final newPages = [
for (final page in strat.pages)
page.copyWith(
settings: page.settings.copyWith(useNeutralTeamColors: value),
),
];

final strategyTheme = ref.read(strategyThemeProvider);
final updated = strat.copyWith(
pages: newPages,
mapData: ref.read(mapProvider).currentMap,
themeProfileId: strategyTheme.profileId,
clearThemeProfileId: strategyTheme.profileId == null,
themeOverridePalette: strategyTheme.overridePalette,
clearThemeOverridePalette: strategyTheme.overridePalette == null,
lastEdited: DateTime.now(),
);
await box.put(updated.id, updated);
setUnsaved();
}

void moveToFolder({required String strategyID, required String? parentID}) {
final strategyBox = Hive.box<StrategyData>(HiveBoxNames.strategiesBox);
final strategy = strategyBox.get(strategyID);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 state not updated after writing to Hive

applyNeutralTeamColorsToAllPages writes updated pages to Hive but never updates the in-memory state. strategySettingsProvider is derived from the current page's settings in state, so switching to any other page after calling this method will cause strategySettingsProvider to re-initialize with the stale (un-updated) useNeutralTeamColors = false value from state.pages, silently reverting the setting for every non-active page.

The newPages list already has the correct values; the state just needs to be updated alongside Hive:

    await box.put(updated.id, updated);
+   state = state.copyWith(/* rebuild state pages from newPages */);
    setUnsaved();

Comment on lines 915 to +924
}
}

int _readDrawingColorValue(Map<String, dynamic> json) {
final value = json['colorValue'] ?? json['color'];
if (value is int) return value;
if (value is num) return value.toInt();
if (value is String) {
return const ColorConverter().fromJson(value).toARGB32();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Hard throw on null color inconsistent with Hive path

When both 'colorValue' and 'color' keys are absent (e.g., a corrupt or partially-migrated JSON blob), value is null and throw UnsupportedError(...) is reached. The Hive path in _readDrawingHiveColorValue quietly falls through to the _ => 0xFFFFFFFF default rather than crashing. A defensive fallback here would match that behaviour and prevent a potential crash on malformed data.

int _readDrawingColorValue(Map<String, dynamic> json) {
  final value = json['colorValue'] ?? json['color'];
  if (value is int) return value;
  if (value is num) return value.toInt();
  if (value is String) {
    return const ColorConverter().fromJson(value).toARGB32();
  }
  return 0xFFFFFFFF; // default to opaque white instead of throwing
}

SunkenInTime and others added 19 commits May 1, 2026 00:15
- Tighten sidebar and segmented tab corner radii
- Adjust settings dialog padding and simplify mode switcher
- Add a PowerShell watcher script for Flutter hot reload
- Render the active page name in the lower-left corner
- Pass page names through the save/load screenshot flow
- Add a widget test covering the new label
- Reduce bar and row corner radii for a cleaner fit
- Adjust expanded panel spacing and resize handle height
- Refresh row action buttons with compact icon spacing
- Store pages bar width in app preferences
- Add horizontal resize handle and clamp width
- Keep existing height resize behavior intact
- Track source and target page IDs through transition state
- Ease the overlay progress curve and drive row fill indicators
- Clear transition page IDs when the animation completes
- Extract lineup visuals into a reusable overlay
- Show lineup overlay while page transitions hide the map
- Use a consistent easing curve for transition progress
- Watch canvas resize changes in persistent lineup widgets
- Add regression test for overlay repositioning and rescaling
- Remove extra button spacing in the collapsed and expanded bars
- Hide row actions until hover or active state
- Disable outer scrollbars for the reorder list
- Centralize pages bar corner radii constants
- Read custom color library entries from `ColorLibraryController`
- Stop watching preferences directly in the controller build
- Keep controller state in sync before persisting preference updates
- Duplicate abilities on modifier-assisted drag
- Track dragged IDs through drop handlers
- Update ability widget tests for the new callback signature
- Add the impeccable skill docs, commands, and references
- Update map theme and settings UI to match the new design flow
- Refresh strategy folder import test expectations
- Replace the plain title/description block with a compact scope pill
- Simplify the strategy object styling description copy
- Store custom keybinds in app preferences
- Add a settings section to edit, reset, and search bindings
- Scope text fields with shortcut overrides and add binding tests
- Move map theme state into `user_preferences_provider`
- Update imports across app and tests
- Add spawn barrier, ult orb, and region name flags to app preferences
- Sync map visibility state with saved preferences and archive exports
- Show draggable agent abilities in the context menu
- Switch the marker sync banner action to a solid button
- Switch to a raw menu item with tighter spacing
- Remove the tooltip wrapper from ability buttons
@SunkenInTime SunkenInTime merged commit 55e479b into main May 10, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants