showBottomModal static method

Future<void> showBottomModal(
  1. BuildContext context, {
  2. double? height,
  3. Color? backgroundColor,
  4. Color? handleColor,
  5. Color? selectedColor,
  6. TextStyle? titleStyle,
  7. TextStyle? languageTextStyle,
  8. BorderRadius? borderRadius,
})

Show a bottom modal to switch languages

Implementation

static Future<void> showBottomModal(
  BuildContext context, {
  double? height,
  Color? backgroundColor,
  Color? handleColor,
  Color? selectedColor,
  TextStyle? titleStyle,
  TextStyle? languageTextStyle,
  BorderRadius? borderRadius,
}) async {
  // Capture navigator state before async operations
  final navigator = Navigator.of(context);

  List<Map<String, String>> list = await getLanguageList();
  Map<String, dynamic>? currentLang = await currentLanguage();

  if (!context.mounted) return;

  final isDark = Theme.of(context).brightness == Brightness.dark;
  final screenHeight = MediaQuery.of(context).size.height;

  showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    backgroundColor: Colors.transparent,
    builder: (BuildContext modalContext) {
      final effectiveBackgroundColor =
          backgroundColor ??
          (isDark ? const Color(0xFF1C1C1E) : Colors.white);
      final effectiveHandleColor =
          handleColor ??
          (isDark ? Colors.grey.shade600 : Colors.grey.shade300);
      final effectiveSelectedColor =
          selectedColor ??
          (isDark ? const Color(0xFF2C2C2E) : const Color(0xFFF2F2F7));
      final effectiveBorderRadius =
          borderRadius ??
          const BorderRadius.vertical(top: Radius.circular(20));

      return Container(
        constraints: BoxConstraints(maxHeight: height ?? screenHeight * 0.6),
        decoration: BoxDecoration(
          color: effectiveBackgroundColor,
          borderRadius: effectiveBorderRadius,
          boxShadow: [
            BoxShadow(
              color: Colors.black.withValues(alpha: 0.15),
              blurRadius: 20,
              offset: const Offset(0, -5),
            ),
          ],
        ),
        child: SafeArea(
          top: false,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              // Drag handle
              Padding(
                padding: const EdgeInsets.only(top: 12, bottom: 8),
                child: Container(
                  width: 36,
                  height: 5,
                  decoration: BoxDecoration(
                    color: effectiveHandleColor,
                    borderRadius: BorderRadius.circular(2.5),
                  ),
                ),
              ),
              // Title
              Padding(
                padding: const EdgeInsets.fromLTRB(24, 8, 24, 16),
                child: Text(
                  "nylo.language_switcher.title".tr(),
                  style:
                      titleStyle ??
                      TextStyle(
                        fontSize: 20,
                        fontWeight: FontWeight.w600,
                        color: isDark ? Colors.white : Colors.black,
                        letterSpacing: -0.5,
                      ),
                ),
              ),
              // Divider
              Divider(
                height: 1,
                thickness: 0.5,
                color: isDark ? Colors.grey.shade800 : Colors.grey.shade200,
              ),
              // Language list
              Flexible(
                child: ListView.builder(
                  padding: const EdgeInsets.symmetric(vertical: 8),
                  shrinkWrap: true,
                  itemCount: list.length,
                  itemBuilder: (context, index) {
                    final meta = list[index];
                    final data = meta.entries.firstOrNull;
                    if (data == null) return const SizedBox.shrink();

                    final isSelected =
                        currentLang != null &&
                        currentLang.entries.isNotEmpty &&
                        data.key == currentLang.entries.first.key;

                    final flagEmoji = getFlagEmoji(data.key);

                    return _LanguageListItem(
                      languageName: data.value,
                      localeCode: data.key,
                      flagEmoji: flagEmoji,
                      isSelected: isSelected,
                      selectedColor: effectiveSelectedColor,
                      textStyle: languageTextStyle,
                      isDark: isDark,
                      onTap: () async {
                        await NyLocalization.instance.setLanguage(
                          modalContext,
                          language: data.key,
                        );

                        // store the language
                        await storeLanguage(object: {data.key: data.value});

                        updateState(
                          state,
                          data: {"action": "refresh-page", "data": {}},
                        );
                        navigator.pop();
                      },
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      );
    },
  );
}