home_trend_view.dart 5.14 KB
import 'package:cached_network_image/cached_network_image.dart';
import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../health_trend/views/health_trend_content.dart';
import '../../controllers/trend/trend_controller.dart';

class HomeTrendView extends GetView<TrendController> {
  const HomeTrendView({super.key});

  @override
  Widget build(BuildContext context) {
    return const _TrendPageBackground(
      child: Column(
        children: [
          SafeArea(
            bottom: false,
            child: _HomeTrendHeader(),
          ),
          Expanded(child: _HomeTrendBody()),
        ],
      ),
    );
  }
}

class _HomeTrendBody extends GetView<TrendController> {
  const _HomeTrendBody();

  @override
  Widget build(BuildContext context) {
    return Obx(
      () => HealthTrendContent(
        query: controller.query,
        queryForType: controller.queryForType,
        selectedTypeIndex: controller.selectedTypeIndex.value,
        refreshToken: controller.refreshToken.value,
        onTypeChanged: controller.changeType,
        onQueryChanged: controller.changeQuery,
      ),
    );
  }
}

class _HomeTrendHeader extends GetView<TrendController> {
  const _HomeTrendHeader();

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 48,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
        child: Stack(
          alignment: Alignment.center,
          children: [
            const Align(
              alignment: Alignment.centerLeft,
              child: Text(
                '趋势',
                style: TextStyle(
                  color: Color(0xFF0F0F11),
                  fontSize: 24,
                  fontWeight: FontWeight.w600,
                ),
              ),
            ),
            Obx(() {
              final friendAvatar = controller.targetFriendInfo.value?.avatar;
              final selfAvatar = Get.find<UserPreferencesStorage>()
                  .preferences
                  .value
                  .meUserInfo
                  ?.avatar;
              return _TrendHeaderAvatar(
                avatarUrl: friendAvatar?.trim().isNotEmpty == true
                    ? friendAvatar
                    : selfAvatar,
                onTap: controller.canSwitchFriend
                    ? controller.showFriendListBottomSheet
                    : null,
              );
            }),
            Obx(
              () => !controller.canSwitchFriend
                  ? const SizedBox.shrink()
                  : Align(
                      alignment: Alignment.centerRight,
                      child: IconButton(
                        highlightColor: Colors.transparent,
                        padding: EdgeInsets.zero,
                        onPressed: controller.showFriendListBottomSheet,
                        icon: Image.asset(
                          'assets/images/common/ic_replace.png',
                          width: 20,
                          height: 20,
                        ),
                      ),
                    ),
            ),
          ],
        ),
      ),
    );
  }
}

class _TrendHeaderAvatar extends StatelessWidget {
  const _TrendHeaderAvatar({this.avatarUrl, this.onTap});

  final String? avatarUrl;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    final imageUrl = avatarUrl?.trim();
    final avatar = Container(
      width: 36,
      height: 36,
      decoration: ShapeDecoration(
        image: imageUrl?.isNotEmpty == true
            ? DecorationImage(
                image: CachedNetworkImageProvider(imageUrl!),
                fit: BoxFit.cover,
              )
            : null,
        shape: RoundedRectangleBorder(
          side: const BorderSide(width: 0.78, color: Colors.white),
          borderRadius: BorderRadius.circular(35.78),
        ),
      ),
      child: imageUrl?.isNotEmpty == true ? null : const _AvatarFallback(),
    );

    if (onTap == null) return avatar;

    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: onTap,
      child: SizedBox(
        width: 44,
        height: 44,
        child: Center(child: avatar),
      ),
    );
  }
}

class _AvatarFallback extends StatelessWidget {
  const _AvatarFallback();

  @override
  Widget build(BuildContext context) {
    return const Icon(
      Icons.person_rounded,
      color: Colors.white,
      size: 22,
    );
  }
}

class _TrendPageBackground extends StatelessWidget {
  const _TrendPageBackground({required this.child});

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return ColoredBox(
      color: const Color(0xFFF5F2FF),
      child: Stack(
        children: [
          Container(
            height: 300,
            decoration: const BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter,
                colors: [Color(0xFFC5B0FF), Color(0xFFF5F2FF)],
              ),
            ),
          ),
          child,
        ],
      ),
    );
  }
}