Skip to content

Commit eb927f4

Browse files
Adam Fiskclaude
andcommitted
review: gate peer-proxy toggle to FFI-supported platforms
Three review comments converged on the same root cause: the toggle was gated to PlatformUtils.isDesktop and the platform-service shims invoked MethodChannel methods that have no native handlers anywhere (Android/iOS/macOS), so on any non-FFI platform the toggle would render but the call would fail with MissingPluginException. * vpn_setting.dart: gate to PlatformUtils.isFFISupported (Windows + Linux), where the FFI path actually drives the toggle. * radiance_settings_providers.dart: skip the isPeerProxyEnabled probe in _refresh on non-FFI platforms so we don't log a failure on every settings init. * lantern_platform_service.dart: replace the MethodChannel passthroughs with explicit "not supported on this platform" stubs. They exist only for LanternCoreService interface conformance; the UI gate prevents them from ever being called. macOS / iOS / Android support requires a native handler (Swift / Kotlin) calling into the Go core; that's a follow-up. flutter analyze: clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d001209 commit eb927f4

3 files changed

Lines changed: 19 additions & 21 deletions

File tree

lib/features/home/provider/radiance_settings_providers.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,22 @@ class RadianceSettings extends _$RadianceSettings {
2929
final routingF = svc.isSmartRoutingEnabled();
3030
final telemetryF = svc.isTelemetryEnabled();
3131
final splitF = PlatformUtils.isIOS ? null : svc.isSplitTunnelingEnabled();
32-
final peerProxyF = svc.isPeerProxyEnabled();
32+
// Peer-proxy probe runs only on platforms with native handlers
33+
// (FFI-supported = Windows + Linux). On other platforms the call would
34+
// fail with MissingPluginException on every settings init.
35+
final peerF = PlatformUtils.isFFISupported ? svc.isPeerProxyEnabled() : null;
3336

3437
final results = await Future.wait([
3538
blockAdsF,
3639
routingF,
3740
telemetryF,
3841
?splitF,
39-
peerProxyF,
42+
?peerF,
4043
]);
4144
if (!ref.mounted) return;
4245

4346
const defaults = RadianceSettingsState();
44-
final peerIdx = splitF == null ? 3 : 4;
47+
final peerIdx = 3 + (splitF == null ? 0 : 1);
4548
state = RadianceSettingsState(
4649
blockAds: results[0].fold((_) => defaults.blockAds, (v) => v),
4750
routingMode: results[1].fold(
@@ -52,7 +55,9 @@ class RadianceSettings extends _$RadianceSettings {
5255
splitTunneling: splitF == null
5356
? defaults.splitTunneling
5457
: results[3].fold((_) => defaults.splitTunneling, (v) => v),
55-
peerProxy: results[peerIdx].fold((_) => defaults.peerProxy, (v) => v),
58+
peerProxy: peerF == null
59+
? defaults.peerProxy
60+
: results[peerIdx].fold((_) => defaults.peerProxy, (v) => v),
5661
);
5762
}
5863

lib/features/setting/vpn_setting.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class VPNSetting extends HookConsumerWidget {
120120
},
121121
),
122122
),
123-
if (PlatformUtils.isDesktop) ...{
123+
if (PlatformUtils.isFFISupported) ...{
124124
SizedBox(height: 16),
125125
AppCard(
126126
padding: EdgeInsets.zero,

lib/lantern/lantern_platform_service.dart

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -288,28 +288,21 @@ class LanternPlatformService implements LanternCoreService {
288288
}
289289
}
290290

291+
// Peer-proxy has no native MethodChannel handler outside the FFI path.
292+
// The toggle is gated to PlatformUtils.isFFISupported in the UI, so these
293+
// implementations exist for interface conformance only and return a clear
294+
// error rather than a MissingPluginException if ever invoked.
291295
@override
292296
Future<Either<Failure, Unit>> setPeerProxyEnabled(bool enabled) async {
293-
try {
294-
await _methodChannel.invokeMethod('setPeerProxyEnabled', {
295-
'enabled': enabled,
296-
});
297-
return right(unit);
298-
} catch (e, st) {
299-
appLogger.error('setPeerProxyEnabled failed', e, st);
300-
return Left(e.toFailure());
301-
}
297+
return Left(Failure(
298+
error: 'peer-proxy not supported on this platform',
299+
localizedErrorMessage: 'peer-proxy not supported on this platform',
300+
));
302301
}
303302

304303
@override
305304
Future<Either<Failure, bool>> isPeerProxyEnabled() async {
306-
try {
307-
final res = await _methodChannel.invokeMethod<bool>('isPeerProxyEnabled');
308-
return right(res ?? false);
309-
} catch (e, st) {
310-
appLogger.error('isPeerProxyEnabled failed', e, st);
311-
return Left(e.toFailure());
312-
}
305+
return right(false);
313306
}
314307

315308
@override

0 commit comments

Comments
 (0)