Merge pull request #509 from ericszimmermann/ez_maps_high_contrast_PR

add High Contrast filter for maps
This commit is contained in:
zjs81
2026-08-09 19:35:15 -07:00
committed by GitHub
6 changed files with 103 additions and 24 deletions
+2 -4
View File
@@ -76,8 +76,7 @@ class Cyr2LatProfile {
class AppSettings { class AppSettings {
static const Object _unset = Object(); static const Object _unset = Object();
static const String stadiaDemo = static const String stadiaDemo = '51bd0381-4685-4666-bae8-48940f6d77c0';
'51bd0381-4685-4666-bae8-48940f6d77c0';
final bool clearPathOnMaxRetry; final bool clearPathOnMaxRetry;
final bool mapShowRepeaters; final bool mapShowRepeaters;
@@ -137,8 +136,7 @@ class AppSettings {
return apiKey; return apiKey;
} }
bool get usesstadiaDemo => bool get usesstadiaDemo => effectiveMapTileApiKey == stadiaDemo;
effectiveMapTileApiKey == stadiaDemo;
Map<String, String> get cyr2latCharMap { Map<String, String> get cyr2latCharMap {
final profile = cyr2latProfiles.firstWhere( final profile = cyr2latProfiles.firstWhere(
+3 -9
View File
@@ -1214,25 +1214,19 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
decoration: InputDecoration( decoration: InputDecoration(
hintText: context.l10n.chat_typeMessage, hintText: context.l10n.chat_typeMessage,
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(MeshRadii.md),
MeshRadii.md,
),
borderSide: BorderSide( borderSide: BorderSide(
color: scheme.outlineVariant, color: scheme.outlineVariant,
), ),
), ),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(MeshRadii.md),
MeshRadii.md,
),
borderSide: BorderSide( borderSide: BorderSide(
color: scheme.outlineVariant, color: scheme.outlineVariant,
), ),
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(MeshRadii.md),
MeshRadii.md,
),
borderSide: BorderSide( borderSide: BorderSide(
color: scheme.primary, color: scheme.primary,
width: 1.5, width: 1.5,
+2 -1
View File
@@ -412,7 +412,8 @@ class _ChannelsScreenState extends State<ChannelsScreen>
final messages = connector.getChannelMessages(channel); final messages = connector.getChannelMessages(channel);
final lastMessage = messages.isNotEmpty ? messages.last : null; final lastMessage = messages.isNotEmpty ? messages.last : null;
final lastMessageText = lastMessage?.text ?? ''; final lastMessageText = lastMessage?.text ?? '';
final lastPreview = lastMessageText.isNotEmpty && final lastPreview =
lastMessageText.isNotEmpty &&
GifHelper.parseGif(lastMessageText) != null GifHelper.parseGif(lastMessageText) != null
? context.l10n.chat_receivedGif ? context.l10n.chat_receivedGif
: lastMessageText; : lastMessageText;
+83 -2
View File
@@ -12,12 +12,15 @@ enum MapRasterSourcePreset {
osmAuto('osm_auto'), osmAuto('osm_auto'),
osmStandard('osm_standard'), osmStandard('osm_standard'),
osmDark('osm_dark'), osmDark('osm_dark'),
osmDarkHC('osm_darkHC'),
stamenTerrain('stamen_terrain'), stamenTerrain('stamen_terrain'),
alidadeSmoothDark('alidade_smooth_dark'), alidadeSmoothDark('alidade_smooth_dark'),
outdoors('outdoors'), outdoors('outdoors'),
osmBright('osm_bright'), osmBright('osm_bright'),
outdoorsDark('outdoors_dark'), outdoorsDark('outdoors_dark'),
osmBrightDark('osm_bright_dark'); outdoorsDarkHC('outdoors_darkHC'),
osmBrightDark('osm_bright_dark'),
osmBrightDarkHC('osm_bright_darkHC');
const MapRasterSourcePreset(this.id); const MapRasterSourcePreset(this.id);
@@ -101,6 +104,12 @@ class MapRasterSourceCatalog {
label: 'OpenStreetMap Dark', label: 'OpenStreetMap Dark',
description: 'Standard OpenStreetMap tiles with an inverted dark filter', description: 'Standard OpenStreetMap tiles with an inverted dark filter',
); );
static const MapRasterSourceDefinition osmDarkHC = MapRasterSourceDefinition(
id: 'osm_darkHC',
label: 'OpenStreetMap Dark High Contrast',
description:
'Standard OpenStreetMap tiles with an inverted high contrast dark filter',
);
static const MapRasterSourceDefinition stamenTerrain = static const MapRasterSourceDefinition stamenTerrain =
MapRasterSourceDefinition( MapRasterSourceDefinition(
id: 'stamen_terrain', id: 'stamen_terrain',
@@ -139,6 +148,14 @@ class MapRasterSourceCatalog {
isStadia: true, isStadia: true,
allowsBulkDownload: true, allowsBulkDownload: true,
); );
static const MapRasterSourceDefinition outdoorsDarkHC =
MapRasterSourceDefinition(
id: 'outdoors',
label: 'Outdoors Dark High Contrast',
description: 'High contrast dark version of the Outdoors map style',
isStadia: true,
allowsBulkDownload: true,
);
static const MapRasterSourceDefinition osmBrightDark = static const MapRasterSourceDefinition osmBrightDark =
MapRasterSourceDefinition( MapRasterSourceDefinition(
id: 'osm_bright', id: 'osm_bright',
@@ -147,6 +164,14 @@ class MapRasterSourceCatalog {
isStadia: true, isStadia: true,
allowsBulkDownload: true, allowsBulkDownload: true,
); );
static const MapRasterSourceDefinition osmBrightDarkHC =
MapRasterSourceDefinition(
id: 'osm_bright',
label: 'OSM Bright Dark High Contrast',
description: 'High contrast dark version of the OSM Bright map style',
isStadia: true,
allowsBulkDownload: true,
);
static MapRasterSourceDefinition fromPreset(MapRasterSourcePreset preset) { static MapRasterSourceDefinition fromPreset(MapRasterSourcePreset preset) {
switch (preset) { switch (preset) {
@@ -156,16 +181,22 @@ class MapRasterSourceCatalog {
return osmStandard; return osmStandard;
case MapRasterSourcePreset.osmDark: case MapRasterSourcePreset.osmDark:
return osmDark; return osmDark;
case MapRasterSourcePreset.osmDarkHC:
return osmDarkHC;
case MapRasterSourcePreset.alidadeSmoothDark: case MapRasterSourcePreset.alidadeSmoothDark:
return alidadeSmoothDark; return alidadeSmoothDark;
case MapRasterSourcePreset.outdoors: case MapRasterSourcePreset.outdoors:
return outdoors; return outdoors;
case MapRasterSourcePreset.outdoorsDark: case MapRasterSourcePreset.outdoorsDark:
return outdoorsDark; return outdoorsDark;
case MapRasterSourcePreset.outdoorsDarkHC:
return outdoorsDarkHC;
case MapRasterSourcePreset.osmBright: case MapRasterSourcePreset.osmBright:
return osmBright; return osmBright;
case MapRasterSourcePreset.osmBrightDark: case MapRasterSourcePreset.osmBrightDark:
return osmBrightDark; return osmBrightDark;
case MapRasterSourcePreset.osmBrightDarkHC:
return osmBrightDarkHC;
case MapRasterSourcePreset.stamenTerrain: case MapRasterSourcePreset.stamenTerrain:
return stamenTerrain; return stamenTerrain;
} }
@@ -335,8 +366,11 @@ class MapTileCacheService extends ChangeNotifier {
) { ) {
switch (MapRasterSourcePreset.fromId(settings.mapRasterSourceId)) { switch (MapRasterSourcePreset.fromId(settings.mapRasterSourceId)) {
case MapRasterSourcePreset.osmDark: case MapRasterSourcePreset.osmDark:
case MapRasterSourcePreset.osmDarkHC:
case MapRasterSourcePreset.outdoorsDark: case MapRasterSourcePreset.outdoorsDark:
case MapRasterSourcePreset.outdoorsDarkHC:
case MapRasterSourcePreset.osmBrightDark: case MapRasterSourcePreset.osmBrightDark:
case MapRasterSourcePreset.osmBrightDarkHC:
return true; return true;
case MapRasterSourcePreset.osmAuto: case MapRasterSourcePreset.osmAuto:
return brightness == Brightness.dark; return brightness == Brightness.dark;
@@ -349,6 +383,25 @@ class MapTileCacheService extends ChangeNotifier {
} }
} }
static bool _isHighContrastDarkPreset(MapRasterSourcePreset preset) {
switch (preset) {
case MapRasterSourcePreset.osmDarkHC:
case MapRasterSourcePreset.outdoorsDarkHC:
case MapRasterSourcePreset.osmBrightDarkHC:
return true;
case MapRasterSourcePreset.osmAuto:
case MapRasterSourcePreset.osmStandard:
case MapRasterSourcePreset.osmDark:
case MapRasterSourcePreset.stamenTerrain:
case MapRasterSourcePreset.alidadeSmoothDark:
case MapRasterSourcePreset.outdoors:
case MapRasterSourcePreset.outdoorsDark:
case MapRasterSourcePreset.osmBright:
case MapRasterSourcePreset.osmBrightDark:
return false;
}
}
static const ColorFilter _darkMapFilter = ColorFilter.matrix([ static const ColorFilter _darkMapFilter = ColorFilter.matrix([
-0.0850, -0.0850,
-0.2861, -0.2861,
@@ -371,6 +424,28 @@ class MapTileCacheService extends ChangeNotifier {
1, 1,
0, 0,
]); ]);
static const ColorFilter _darkHCMapFilter = ColorFilter.matrix([
0.7634200013,
-1.9008999332,
-0.1915199924,
0,
338.15,
-0.5665799987,
-0.5720999709,
-0.1915199924,
0,
338.15,
-0.5665799987,
-1.9008999332,
1.1384799335,
0,
338.15,
0,
0,
0,
1,
0,
]);
CacheManager get _concreteCacheManager => cacheManager as CacheManager; CacheManager get _concreteCacheManager => cacheManager as CacheManager;
@@ -393,7 +468,13 @@ class MapTileCacheService extends ChangeNotifier {
); );
if (shouldApplyDarkFilter) { if (shouldApplyDarkFilter) {
layer = ColorFiltered(colorFilter: _darkMapFilter, child: layer); final activePreset = MapRasterSourcePreset.fromId(
appSettingsService.settings.mapRasterSourceId,
);
final filter = _isHighContrastDarkPreset(activePreset)
? _darkHCMapFilter
: _darkMapFilter;
layer = ColorFiltered(colorFilter: filter, child: layer);
} }
if (opacity < 1) { if (opacity < 1) {
-1
View File
@@ -643,7 +643,6 @@ void main() {
expect(contacts.first.path, equals(Uint8List.fromList([0x11, 0x22]))); expect(contacts.first.path, equals(Uint8List.fromList([0x11, 0x22])));
}, },
); );
}); });
group('AppSettingsService — gps interval fallback', () { group('AppSettingsService — gps interval fallback', () {
+10 -4
View File
@@ -22,7 +22,8 @@ class _FakeStorageService extends StorageService {
ContactPathHistory history, ContactPathHistory history,
) async {} ) async {}
@override @override
Future<ContactPathHistory?> loadPathHistory(String contactPubKeyHex) async => null; Future<ContactPathHistory?> loadPathHistory(String contactPubKeyHex) async =>
null;
@override @override
Future<void> clearPathHistory(String contactPubKeyHex) async {} Future<void> clearPathHistory(String contactPubKeyHex) async {}
} }
@@ -71,13 +72,18 @@ Widget _buildTestApp({
required MeshCoreConnector connector, required MeshCoreConnector connector,
required Widget child, required Widget child,
}) { }) {
final appSettingsService = AppSettingsService();
return MultiProvider( return MultiProvider(
providers: [ providers: [
ChangeNotifierProvider<MeshCoreConnector>.value(value: connector), ChangeNotifierProvider<MeshCoreConnector>.value(value: connector),
ChangeNotifierProvider<AppSettingsService>( ChangeNotifierProvider<AppSettingsService>.value(
create: (_) => AppSettingsService(), value: appSettingsService,
),
ChangeNotifierProvider<MapTileCacheService>(
create: (_) =>
MapTileCacheService(appSettingsService: appSettingsService),
), ),
Provider<MapTileCacheService>(create: (_) => MapTileCacheService()),
ChangeNotifierProvider<PathHistoryService>( ChangeNotifierProvider<PathHistoryService>(
create: (_) => PathHistoryService(_FakeStorageService()), create: (_) => PathHistoryService(_FakeStorageService()),
), ),