11// In order to *not* need this ignore, consider extracting the "web" version
22// of your plugin as a separate package, instead of inlining it in the same
33// package as the core of your plugin.
4+ import 'dart:js_interop' ;
5+
46import 'package:flutter/services.dart' ;
57import 'package:flutter_web_plugins/flutter_web_plugins.dart' ;
68
9+ import 'src/posthog_config.dart' ;
710import 'src/posthog_flutter_platform_interface.dart' ;
811import 'src/posthog_flutter_web_handler.dart' ;
912
@@ -13,15 +16,213 @@ class PosthogFlutterWeb extends PosthogFlutterPlatformInterface {
1316 PosthogFlutterWeb ();
1417
1518 static void registerWith (Registrar registrar) {
16- final MethodChannel channel = MethodChannel (
19+ final channel = MethodChannel (
1720 'posthog_flutter' ,
1821 const StandardMethodCodec (),
1922 registrar,
2023 );
21- final PosthogFlutterWeb instance = PosthogFlutterWeb ();
24+ final instance = PosthogFlutterWeb ();
2225 channel.setMethodCallHandler (instance.handleMethodCall);
26+
27+ // Set the platform instance so that Posthog() can call methods directly
28+ // on the web implementation instead of going through the method channel.
29+ // This is required because method channels can only pass serializable data,
30+ // not function callbacks like onFeatureFlags.
31+ PosthogFlutterPlatformInterface .instance = instance;
32+ }
33+
34+ Future <dynamic > handleMethodCall (MethodCall call) async {
35+ // The 'setup' call is now handled by the setup method override.
36+ // Other method calls are delegated to handleWebMethodCall.
37+ if (call.method == 'setup' ) {
38+ // This case should ideally not be hit if Posthog().setup directly calls the overridden setup.
39+ // However, to be safe, we can log or ignore.
40+ // For now, let's assume direct call to overridden setup handles it.
41+ return null ;
42+ }
43+ return handleWebMethodCall (call);
44+ }
45+
46+ @override
47+ Future <void > setup (PostHogConfig config) async {
48+ // It's assumed posthog-js is initialized by the user in their HTML.
49+ // This setup primarily hooks into the existing posthog-js instance.
50+
51+ // If apiKey and host are in config, and posthog.init is to be handled by plugin:
52+ // This is an example if we wanted the plugin to also call posthog.init()
53+ // final jsOptions = <String, dynamic>{
54+ // 'api_host': config.host,
55+ // // Add other relevant options from PostHogConfig if needed for JS init
56+ // }.jsify();
57+ // posthog?.callMethod('init'.toJS, config.apiKey.toJS, jsOptions);
58+
59+ final ph = posthog;
60+ if (config.onFeatureFlags != null && ph != null ) {
61+ final dartCallback = config.onFeatureFlags! ;
62+
63+ // JS SDK calls with: (flags: string[], variants: Record, context?: {errorsLoading})
64+ // We ignore the JS parameters and just invoke the void callback
65+ final jsCallback =
66+ (JSArray jsFlags, JSObject jsFlagVariants, [JSObject ? jsContext]) {
67+ dartCallback ();
68+ }.toJS;
69+
70+ ph.onFeatureFlags (jsCallback);
71+ }
72+ }
73+
74+ @override
75+ Future <void > identify ({
76+ required String userId,
77+ Map <String , Object >? userProperties,
78+ Map <String , Object >? userPropertiesSetOnce,
79+ }) async {
80+ return handleWebMethodCall (MethodCall ('identify' , {
81+ 'userId' : userId,
82+ if (userProperties != null ) 'userProperties' : userProperties,
83+ if (userPropertiesSetOnce != null )
84+ 'userPropertiesSetOnce' : userPropertiesSetOnce,
85+ }));
86+ }
87+
88+ @override
89+ Future <void > capture ({
90+ required String eventName,
91+ Map <String , Object >? properties,
92+ }) async {
93+ return handleWebMethodCall (MethodCall ('capture' , {
94+ 'eventName' : eventName,
95+ if (properties != null ) 'properties' : properties,
96+ }));
97+ }
98+
99+ @override
100+ Future <void > screen ({
101+ required String screenName,
102+ Map <String , Object >? properties,
103+ }) async {
104+ return handleWebMethodCall (MethodCall ('screen' , {
105+ 'screenName' : screenName,
106+ if (properties != null ) 'properties' : properties,
107+ }));
108+ }
109+
110+ @override
111+ Future <void > alias ({required String alias}) async {
112+ return handleWebMethodCall (MethodCall ('alias' , {'alias' : alias}));
113+ }
114+
115+ @override
116+ Future <String > getDistinctId () async {
117+ final result = await handleWebMethodCall (const MethodCall ('distinctId' ));
118+ return result as String ? ?? '' ;
119+ }
120+
121+ @override
122+ Future <void > reset () async {
123+ return handleWebMethodCall (const MethodCall ('reset' ));
124+ }
125+
126+ @override
127+ Future <void > disable () async {
128+ return handleWebMethodCall (const MethodCall ('disable' ));
129+ }
130+
131+ @override
132+ Future <void > enable () async {
133+ return handleWebMethodCall (const MethodCall ('enable' ));
134+ }
135+
136+ @override
137+ Future <bool > isOptOut () async {
138+ final result = await handleWebMethodCall (const MethodCall ('isOptOut' ));
139+ return result as bool ? ?? true ;
23140 }
24141
25- Future <dynamic > handleMethodCall (MethodCall call) =>
26- handleWebMethodCall (call);
142+ @override
143+ Future <void > debug (bool enabled) async {
144+ return handleWebMethodCall (MethodCall ('debug' , {'debug' : enabled}));
145+ }
146+
147+ @override
148+ Future <void > register (String key, Object value) async {
149+ return handleWebMethodCall (
150+ MethodCall ('register' , {'key' : key, 'value' : value}));
151+ }
152+
153+ @override
154+ Future <void > unregister (String key) async {
155+ return handleWebMethodCall (MethodCall ('unregister' , {'key' : key}));
156+ }
157+
158+ @override
159+ Future <bool > isFeatureEnabled (String key) async {
160+ final result =
161+ await handleWebMethodCall (MethodCall ('isFeatureEnabled' , {'key' : key}));
162+ return result as bool ? ?? false ;
163+ }
164+
165+ @override
166+ Future <void > reloadFeatureFlags () async {
167+ return handleWebMethodCall (const MethodCall ('reloadFeatureFlags' ));
168+ }
169+
170+ @override
171+ Future <void > group ({
172+ required String groupType,
173+ required String groupKey,
174+ Map <String , Object >? groupProperties,
175+ }) async {
176+ return handleWebMethodCall (MethodCall ('group' , {
177+ 'groupType' : groupType,
178+ 'groupKey' : groupKey,
179+ if (groupProperties != null ) 'groupProperties' : groupProperties,
180+ }));
181+ }
182+
183+ @override
184+ Future <Object ?> getFeatureFlag ({required String key}) async {
185+ return handleWebMethodCall (MethodCall ('getFeatureFlag' , {'key' : key}));
186+ }
187+
188+ @override
189+ Future <Object ?> getFeatureFlagPayload ({required String key}) async {
190+ return handleWebMethodCall (
191+ MethodCall ('getFeatureFlagPayload' , {'key' : key}));
192+ }
193+
194+ @override
195+ Future <void > flush () async {
196+ return handleWebMethodCall (const MethodCall ('flush' ));
197+ }
198+
199+ @override
200+ Future <void > close () async {
201+ return handleWebMethodCall (const MethodCall ('close' ));
202+ }
203+
204+ @override
205+ Future <String ?> getSessionId () async {
206+ final result = await handleWebMethodCall (const MethodCall ('getSessionId' ));
207+ return result as String ? ;
208+ }
209+
210+ @override
211+ Future <void > openUrl (String url) async {
212+ // Not supported on web
213+ }
214+
215+ @override
216+ Future <void > showSurvey (Map <String , dynamic > survey) async {
217+ // Not supported on web - surveys handled by posthog-js
218+ }
219+
220+ @override
221+ Future <void > captureException ({
222+ required Object error,
223+ StackTrace ? stackTrace,
224+ Map <String , Object >? properties,
225+ }) async {
226+ // Not implemented on web
227+ }
27228}
0 commit comments