custom_theme_card.dart 5.38 KB
import 'package:flutter/material.dart';
import 'package:get/utils.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';

import '../models/watch_theme_models.dart';
import 'watch_theme_character_avatar.dart';
import 'watch_theme_colors.dart';
import 'watch_theme_pro_badge.dart';
import 'watch_theme_selected_view.dart';
import 'watch_theme_section_card.dart';

class CustomThemeCard extends StatelessWidget {
  const CustomThemeCard({
    super.key,
    required this.isPremium,
    required this.customThemes,
    required this.activeThemeId,
    required this.onCreateTap,
    this.onThemeTap,
  });

  final bool isPremium;
  final List<WatchThemeItem> customThemes;
  final int? activeThemeId;
  final VoidCallback onCreateTap;
  final ValueChanged<WatchThemeItem>? onThemeTap;

  @override
  Widget build(BuildContext context) {
    return WatchThemeSectionCard(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          WatchThemeSectionTitle(
            context.l10n.watchThemeCustomTheme,
            trailing: isPremium ? null : const WatchThemeProBadge(),
          ),
          SizedBox(height: 4),
          Text(
            context.l10n.watchThemeCustomDescription,
            maxLines: 4,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(
              color: WatchThemeColors.textSecondary,
              fontSize: 12,
              fontWeight: FontWeight.w400,
              height: 1.25,
            ),
          ),
          SizedBox(height: 14),
          _CreateThemeButton(onTap: onCreateTap),
          customThemes.isEmpty
              ? SizedBox(height: 0)
              : SizedBox(
                  height: 112,
                  child: ListView.separated(
                      scrollDirection: Axis.horizontal,
                      padding: EdgeInsets.zero,
                      itemBuilder: (context, index) {
                        return _CustomThemeItem(
                          item: customThemes[index],
                          selected: customThemes[index].id != null &&
                              customThemes[index].id == activeThemeId,
                          onTap: onThemeTap == null
                              ? null
                              : () => onThemeTap!(customThemes[index]),
                        );
                      },
                      separatorBuilder: (context, index) {
                        return SizedBox(
                          width: 20,
                        );
                      },
                      itemCount: customThemes.length),
                ).paddingOnly(top: 12),
        ],
      ),
    );
  }
}

class _CreateThemeButton extends StatelessWidget {
  const _CreateThemeButton({required this.onTap});

  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: onTap,
      child: Container(
        height: 48,
        padding: EdgeInsets.symmetric(horizontal: 20),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(12),
          gradient: const LinearGradient(
            begin: Alignment.centerLeft,
            end: Alignment.centerRight,
            colors: [
              Color(0xFFFFFFD0),
              Color(0xFFFFD1DB),
              Color(0xFFF0CDFF),
              Color(0xFFCFE8FF),
            ],
            stops: [0, 0.4, 0.7, 1],
          ),
        ),
        child: Row(
          children: [
            Icon(
              Icons.palette_outlined,
              color: WatchThemeColors.overload,
              size: 28,
            ),
            SizedBox(width: 8),
            Text(
              context.l10n.watchThemeCreateTheme,
              style: TextStyle(
                color: WatchThemeColors.textPrimary,
                fontSize: 14,
                fontWeight: FontWeight.w600,
                height: 1.25,
              ),
            ),
            const Spacer(),
            Icon(
              Icons.chevron_right,
              color: WatchThemeColors.textSecondary,
              size: 20,
            ),
          ],
        ),
      ),
    );
  }
}

class _CustomThemeItem extends StatelessWidget {
  const _CustomThemeItem({
    required this.item,
    required this.selected,
    this.onTap,
  });

  final WatchThemeItem item;
  final bool selected;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: onTap,
      child: SizedBox(
        width: 88,
        child: Column(
          children: [
            WatchThemeSelectedView(
              selected: selected,
              size: 88,
              child: WatchThemeCharacterAvatar(
                size: 88,
                assetPath: item.infoList.firstOrNull?.assetPath,
                imageUrl: item.infoList.firstOrNull?.imgUrl,
                empty: item.infoList.firstOrNull?.image == null,
              ),
            ),
            SizedBox(height: 8),
            Text(
              item.title,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                color: WatchThemeColors.textPrimary,
                fontSize: 12,
                fontWeight: FontWeight.w400,
                height: 1.25,
              ),
            ),
          ],
        ),
      ),
    );
  }
}