friend_interact_click_view.dart 4.73 KB
import 'dart:async';

import 'package:doublefeel_flutter/app/modules/interact/widgets/friend_interaction_dialog.dart';
import 'package:doublefeel_flutter/app/modules/interact/widgets/friend_interaction_content.dart';
import 'package:doublefeel_flutter/app/modules/report_common/widgets/health_report_subject_scope.dart';
import 'package:doublefeel_flutter/core/network/api/interaction_api.dart';
import 'package:doublefeel_flutter/core/util/size_extensions.dart';
import 'package:doublefeel_flutter/data/models/interaction/interaction_models.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class FriendInteractClickView extends StatelessWidget {
  const FriendInteractClickView({
    super.key,
    this.onAction,
    this.interactionContext,
    this.interactionType = FriendInteractionType.defaultInteraction,
    this.content,
    this.enabled = true,
    this.size = 24,
    this.padding = EdgeInsets.zero,
  });

  final VoidCallback? onAction;
  final FriendInteractionContext? interactionContext;
  final FriendInteractionType interactionType;
  final FriendInteractionContent? content;
  final bool enabled;
  final double size;
  final EdgeInsets padding;

  @override
  Widget build(BuildContext context) => Opacity(
    opacity: enabled ? 1 : .4,
    child: GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: enabled
          ? () {
              onAction?.call();
              final interaction = _interactionContextOf(context);
              FriendInteractionDialog.show<void>(
                context,
                avatar: _avatar(interaction),
                content:
                    content ??
                    FriendInteractionContent.forType(context, interactionType),
                onMiss: interaction == null
                    ? null
                    : () => unawaited(
                        _sendInteraction(
                          interaction,
                          FriendInteractionActionType.miss,
                        ),
                      ),
                onPoke: interaction == null
                    ? null
                    : () => unawaited(
                        _sendInteraction(
                          interaction,
                          FriendInteractionActionType.poke,
                        ),
                      ),
                onPunch: interaction == null
                    ? null
                    : () => unawaited(
                        _sendInteraction(
                          interaction,
                          FriendInteractionActionType.punch,
                        ),
                      ),
              );
            }
          : null,
      child: Padding(
        padding: padding,
        child: SizedBox(
          width: size.dp,
          height: size.dp,
          child: Image.asset(
            'assets/images/interact/ic_friend_interact_click.png',
            width: double.infinity,
            height: double.infinity,
          ),
        ),
      ),
    ),
  );

  FriendInteractionContext? _interactionContextOf(BuildContext context) {
    if (interactionContext != null) return interactionContext;
    final friendUserId = HealthReportSubjectScope.friendUserIdOf(context);
    if (friendUserId == null) return null;
    return FriendInteractionContext(
      friendUserId: friendUserId,
      type: interactionType,
      avatarUrl: HealthReportSubjectScope.friendAvatarUrlOf(context),
    );
  }

  ImageProvider _avatar(FriendInteractionContext? interaction) {
    final url = interaction?.avatarUrl?.trim();
    return url?.isNotEmpty == true
        ? NetworkImage(url!)
        : const AssetImage('assets/images/interact/unpaired_avatar.png');
  }

  Future<void> _sendInteraction(
    FriendInteractionContext interaction,
    FriendInteractionActionType action,
  ) async {
    await Get.find<InteractionApi>().sendInteraction(
      InteractionData(
        friendUserId: interaction.friendUserId,
        interactionType: interaction.type.value,
        actionType: action.value,
      ),
    );
  }
}

class FriendInteractCardOverlay extends StatelessWidget {
  const FriendInteractCardOverlay({
    super.key,
    required this.showInteraction,
    required this.child,
    this.interactionType = FriendInteractionType.defaultInteraction,
    this.content,
  });

  final bool showInteraction;
  final Widget child;
  final FriendInteractionType interactionType;
  final FriendInteractionContent? content;

  @override
  Widget build(BuildContext context) => Stack(
    children: [
      child,
      if (showInteraction)
        Positioned(
          top: 20,
          right: 20,
          child: FriendInteractClickView(
            interactionType: interactionType,
            content: content,
          ),
        ),
    ],
  );
}