zenit_webview_sdk 1.0.0 copy "zenit_webview_sdk: ^1.0.0" to clipboard
zenit_webview_sdk: ^1.0.0 copied to clipboard

PlatformAndroid

Flutter SDK package that embeds Zenit's web app in a WebView with a JavaScript bridge.

example/lib/main.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:zenit_webview_sdk/zenit_webview_sdk.dart';

import 'config/zenit_build_config.dart';

void main() => runApp(const ExampleApp());

class ExampleApp extends StatelessWidget {
  static const Map<String, dynamic> _devDefaultFiltersFallback = {
    'GFORMS': '3554',
  };

  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    final effectiveConfig = _resolveEffectiveConfig();

    if (effectiveConfig.effectiveShowDevLogs) {
      _debugLogEffectiveConfig(effectiveConfig);
    }

    return MaterialApp(
      title: 'Zenit SDK Playground',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Scaffold(
        body: SafeArea(
          child: Column(
            children: [
              if (effectiveConfig.hasMissingTokens)
                _MissingCredentialsWarning(
                  sdkTokenMissing: !effectiveConfig.isSdkTokenSet,
                  accessTokenMissing: !effectiveConfig.isAccessTokenSet,
                ),
              Expanded(
                child: ZenitWebViewSdk(
                  webUrl: effectiveConfig.effectiveWebUrl,
                  runtimeConfig: ZenitRuntimeConfig(
                    baseUrl: effectiveConfig.effectiveBaseUrl,
                    mapId: effectiveConfig.effectiveMapId,
                    defaultFilters: effectiveConfig.effectiveDefaultFilters,
                    accessToken: effectiveConfig.effectiveAccessToken,
                    sdkToken: effectiveConfig.effectiveSdkToken,
                  ),
                  enableLogs: effectiveConfig.effectiveShowDevLogs,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  _EffectiveConfig _resolveEffectiveConfig() {
    final environmentKey = ZenitBuildConfig.environmentKey.trim();
    final resolvedEnvironment = zenitEnvironments[environmentKey];

    if (resolvedEnvironment == null) {
      final availableKeys = zenitEnvironments.keys.join(', ');
      throw ArgumentError.value(
        environmentKey,
        'ZENIT_ENVIRONMENT_KEY',
        'No existe en el registry. Valores válidos: $availableKeys',
      );
    }

    final effectiveShowDevLogs =
        ZenitBuildConfig.showDevLogs || resolvedEnvironment.showDevLogs == true;

    final webUrlOverride = ZenitBuildConfig.webUrlOverride.trim();
    final baseUrlOverride = ZenitBuildConfig.baseUrlOverride.trim();
    final sdkTokenOverride = ZenitBuildConfig.sdkToken.trim();
    final accessTokenOverride = ZenitBuildConfig.accessToken.trim();
    final fallbackEnabled =
        ZenitBuildConfig.enableLocalFiltersFallback && effectiveShowDevLogs;

    final parsedFiltersResolution = _resolveDefaultFilters(
      rawJson: ZenitBuildConfig.defaultFiltersJson,
      debugEnabled: effectiveShowDevLogs,
      fallbackEnabled: fallbackEnabled,
    );

    final effectiveWebUrl =
        webUrlOverride.isNotEmpty ? Uri.parse(webUrlOverride) : resolvedEnvironment.parsedWebUrl;

    final effectiveBaseUrl =
        baseUrlOverride.isNotEmpty ? baseUrlOverride : resolvedEnvironment.baseUrl;

    final effectiveMapId = ZenitBuildConfig.mapIdOverride > 0
        ? ZenitBuildConfig.mapIdOverride
        : resolvedEnvironment.mapId;

    final effectiveDefaultFilters = parsedFiltersResolution.parsedFilters ??
        resolvedEnvironment.defaultFilters;

    final effectiveSdkToken =
        sdkTokenOverride.isNotEmpty ? sdkTokenOverride : resolvedEnvironment.sdkToken;

    final effectiveAccessToken =
        accessTokenOverride.isNotEmpty ? accessTokenOverride : resolvedEnvironment.accessToken;

    final sdkTokenMissing = (effectiveSdkToken ?? '').isEmpty;
    final accessTokenMissing = (effectiveAccessToken ?? '').isEmpty;

    if (effectiveShowDevLogs && (sdkTokenMissing || accessTokenMissing)) {
      debugPrint(
        '⚠️ Configuración incompleta: '
        'sdkTokenSet=${effectiveSdkToken?.isNotEmpty ?? false}, '
        'accessTokenSet=${effectiveAccessToken?.isNotEmpty ?? false}. '
        'El mapa puede quedarse en loading si faltan credenciales.',
      );
    }

    return _EffectiveConfig(
      environmentKey: environmentKey,
      effectiveWebUrl: effectiveWebUrl,
      effectiveBaseUrl: effectiveBaseUrl,
      effectiveMapId: effectiveMapId,
      effectiveDefaultFilters: effectiveDefaultFilters,
      effectiveSdkToken: effectiveSdkToken,
      effectiveAccessToken: effectiveAccessToken,
      effectiveShowDevLogs: effectiveShowDevLogs,
      defaultFiltersRaw: parsedFiltersResolution.rawValue,
      defaultFiltersParseError: parsedFiltersResolution.parseError,
      defaultFiltersFallbackUsed: parsedFiltersResolution.usedFallback,
      defaultFiltersSource: parsedFiltersResolution.source,
    );
  }

  _DefaultFiltersResolution _resolveDefaultFilters({
    required String rawJson,
    required bool debugEnabled,
    required bool fallbackEnabled,
  }) {
    final rawValue = rawJson;
    final trimmed = rawValue.trim();

    if (debugEnabled) {
      debugPrint('ZENIT_DEFAULT_FILTERS raw="$rawValue"');
      debugPrint('ZENIT_DEFAULT_FILTERS trimmed="$trimmed"');
    }

    if (trimmed.isEmpty) {
      if (fallbackEnabled) {
        if (debugEnabled) {
          debugPrint(
            'ZENIT_DEFAULT_FILTERS vacío; aplicando fallback local de prueba: '
            '$_devDefaultFiltersFallback',
          );
        }
        return _DefaultFiltersResolution(
          rawValue: rawValue,
          parsedFilters: _devDefaultFiltersFallback,
          source: 'local-dev-fallback-empty',
          usedFallback: true,
        );
      }

      if (debugEnabled) {
        debugPrint('ZENIT_DEFAULT_FILTERS vacío; se mantiene config del environment.');
      }
      return _DefaultFiltersResolution(
        rawValue: rawValue,
        parsedFilters: null,
        source: 'environment-defaults',
      );
    }

    try {
      final decoded = jsonDecode(trimmed);
      if (decoded is Map<String, dynamic>) {
        if (debugEnabled) {
          debugPrint('ZENIT_DEFAULT_FILTERS parseado correctamente: $decoded');
        }
        return _DefaultFiltersResolution(
          rawValue: rawValue,
          parsedFilters: decoded,
          source: 'dart-define',
        );
      }

      final parseError =
          'El valor debe ser un JSON object y llegó como ${decoded.runtimeType}.';
      if (debugEnabled) {
        debugPrint('ZENIT_DEFAULT_FILTERS inválido. raw="$rawValue". error=$parseError');
      }
      if (fallbackEnabled) {
        if (debugEnabled) {
          debugPrint(
            'Aplicando fallback local de prueba por tipo no soportado: '
            '$_devDefaultFiltersFallback',
          );
        }
        return _DefaultFiltersResolution(
          rawValue: rawValue,
          parsedFilters: _devDefaultFiltersFallback,
          parseError: parseError,
          source: 'local-dev-fallback-invalid',
          usedFallback: true,
        );
      }

      return _DefaultFiltersResolution(
        rawValue: rawValue,
        parsedFilters: null,
        parseError: parseError,
        source: 'environment-defaults',
      );
    } on FormatException catch (error) {
      if (debugEnabled) {
        debugPrint('ZENIT_DEFAULT_FILTERS JSON inválido. raw="$rawValue". error=$error');
      }
      if (fallbackEnabled) {
        if (debugEnabled) {
          debugPrint(
            'Aplicando fallback local de prueba por JSON inválido: '
            '$_devDefaultFiltersFallback',
          );
        }
        return _DefaultFiltersResolution(
          rawValue: rawValue,
          parsedFilters: _devDefaultFiltersFallback,
          parseError: '$error',
          source: 'local-dev-fallback-invalid-json',
          usedFallback: true,
        );
      }

      return _DefaultFiltersResolution(
        rawValue: rawValue,
        parsedFilters: null,
        parseError: '$error',
        source: 'environment-defaults',
      );
    }
  }

  void _debugLogEffectiveConfig(_EffectiveConfig config) {
    debugPrint('Zenit effective config (${config.environmentKey}):');
    debugPrint('  webUrl=${config.effectiveWebUrl}');
    debugPrint('  baseUrl=${config.effectiveBaseUrl}');
    debugPrint('  mapId=${config.effectiveMapId}');
    debugPrint('  defaultFiltersRaw=${config.defaultFiltersRaw}');
    debugPrint('  defaultFiltersFinal=${config.effectiveDefaultFilters}');
    debugPrint('  defaultFiltersSource=${config.defaultFiltersSource}');
    debugPrint('  defaultFiltersFallbackUsed=${config.defaultFiltersFallbackUsed}');
    if (config.defaultFiltersParseError != null) {
      debugPrint('  defaultFiltersParseError=${config.defaultFiltersParseError}');
    }
    debugPrint('  sdkTokenSet=${config.isSdkTokenSet}');
    debugPrint('  accessTokenSet=${config.isAccessTokenSet}');
    debugPrint('  sdkTokenLength=${config.effectiveSdkToken?.length ?? 0}');
    debugPrint('  accessTokenLength=${config.effectiveAccessToken?.length ?? 0}');
    debugPrint(
      '  enableLocalFiltersFallback=${ZenitBuildConfig.enableLocalFiltersFallback}',
    );
    debugPrint('  showDevLogs=${config.effectiveShowDevLogs}');
  }
}

class _MissingCredentialsWarning extends StatelessWidget {
  const _MissingCredentialsWarning({
    required this.sdkTokenMissing,
    required this.accessTokenMissing,
  });

  final bool sdkTokenMissing;
  final bool accessTokenMissing;

  @override
  Widget build(BuildContext context) {
    final missing = <String>[
      if (sdkTokenMissing) 'ZENIT_SDK_TOKEN',
      if (accessTokenMissing) 'ZENIT_ACCESS_TOKEN',
    ].join(', ');

    return Material(
      color: Colors.orange.shade100,
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Icon(Icons.warning_amber_rounded, color: Colors.deepOrange),
            const SizedBox(width: 8),
            Expanded(
              child: Text(
                'Configuración incompleta del example. Faltan credenciales: '
                '$missing. Revisa los --dart-define para evitar loading infinito.',
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _EffectiveConfig {
  const _EffectiveConfig({
    required this.environmentKey,
    required this.effectiveWebUrl,
    required this.effectiveBaseUrl,
    required this.effectiveMapId,
    required this.effectiveDefaultFilters,
    required this.effectiveSdkToken,
    required this.effectiveAccessToken,
    required this.effectiveShowDevLogs,
    required this.defaultFiltersRaw,
    required this.defaultFiltersSource,
    required this.defaultFiltersFallbackUsed,
    this.defaultFiltersParseError,
  });

  final String environmentKey;
  final Uri effectiveWebUrl;
  final String effectiveBaseUrl;
  final int effectiveMapId;
  final Map<String, dynamic>? effectiveDefaultFilters;
  final String? effectiveSdkToken;
  final String? effectiveAccessToken;
  final bool effectiveShowDevLogs;
  final String defaultFiltersRaw;
  final String? defaultFiltersParseError;
  final bool defaultFiltersFallbackUsed;
  final String defaultFiltersSource;

  bool get isSdkTokenSet => (effectiveSdkToken ?? '').isNotEmpty;
  bool get isAccessTokenSet => (effectiveAccessToken ?? '').isNotEmpty;
  bool get hasMissingTokens => !isSdkTokenSet || !isAccessTokenSet;
}

class _DefaultFiltersResolution {
  const _DefaultFiltersResolution({
    required this.rawValue,
    required this.parsedFilters,
    required this.source,
    this.parseError,
    this.usedFallback = false,
  });

  final String rawValue;
  final Map<String, dynamic>? parsedFilters;
  final String? parseError;
  final bool usedFallback;
  final String source;
}
0
likes
140
points
97
downloads

Documentation

API reference

Publisher

verified publishermetag.site

Weekly Downloads

Flutter SDK package that embeds Zenit's web app in a WebView with a JavaScript bridge.

Repository (GitHub)
View/report issues

Topics

#flutter #webview #sdk

License

MIT (license)

Dependencies

flutter, webview_flutter, webview_flutter_android

More

Packages that depend on zenit_webview_sdk