fix:对比原型增加功能交互
This commit is contained in:
@@ -5,6 +5,8 @@ import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
|
||||
import '../../data/api/report_data_source.dart';
|
||||
import '../../data/models/models.dart';
|
||||
import '../../data/providers.dart';
|
||||
import '../../data/state/app_interaction_state.dart';
|
||||
import '../../theme/app_icons.dart';
|
||||
import '../../theme/yanting_text.dart';
|
||||
import '../../theme/yanting_tokens.dart';
|
||||
@@ -197,35 +199,132 @@ class _ReportDetailContent extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _ActionBar extends StatelessWidget {
|
||||
class _ActionBar extends ConsumerWidget {
|
||||
const _ActionBar({required this.detail});
|
||||
|
||||
final ReportDetail detail;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final auth = ref.watch(authControllerProvider);
|
||||
final profile = ref.watch(profileControllerProvider);
|
||||
final isFavorite = profile.favorites.contains(detail.id);
|
||||
final isSavedListen = profile.savedListens.contains(detail.id);
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: AppButton(
|
||||
label: '收藏',
|
||||
icon: AppIcons.heart,
|
||||
label: isFavorite ? '已收藏' : '收藏',
|
||||
icon: isFavorite ? AppIcons.heartFill : AppIcons.heart,
|
||||
kind: AppButtonKind.ghost,
|
||||
onPressed: () => showLoginSheet(context, reason: '登录后保存到你的收藏'),
|
||||
onPressed: () => _runLoginRequiredAction(
|
||||
context,
|
||||
ref,
|
||||
auth,
|
||||
PendingLoginAction(
|
||||
action: LoginRequiredAction.favorite,
|
||||
reportId: detail.id,
|
||||
contextText: '登录后保存到你的收藏',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: YantingSpacing.x2),
|
||||
if (detail.hasAudio) ...[
|
||||
Expanded(
|
||||
child: AppButton(
|
||||
label: isSavedListen ? '已存听单' : '听单',
|
||||
icon: isSavedListen
|
||||
? AppIcons.headphonesFill
|
||||
: AppIcons.headphones,
|
||||
kind: AppButtonKind.ghost,
|
||||
onPressed: () => _runLoginRequiredAction(
|
||||
context,
|
||||
ref,
|
||||
auth,
|
||||
PendingLoginAction(
|
||||
action: LoginRequiredAction.saveListen,
|
||||
reportId: detail.id,
|
||||
contextText: '登录后保存到你的听单',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: YantingSpacing.x2),
|
||||
],
|
||||
Expanded(
|
||||
child: AppButton(
|
||||
label: '原文',
|
||||
icon: AppIcons.externalLink,
|
||||
kind: AppButtonKind.ghost,
|
||||
onPressed: () => showOutboundSheet(context, title: detail.titleCn),
|
||||
onPressed: () => _showSourceSheet(context, ref),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _runLoginRequiredAction(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
AuthState auth,
|
||||
PendingLoginAction action,
|
||||
) {
|
||||
if (auth.loggedIn) {
|
||||
_applyPendingAction(ref, action);
|
||||
return;
|
||||
}
|
||||
|
||||
ref.read(authControllerProvider.notifier).requireLogin(action);
|
||||
showLoginSheet(
|
||||
context,
|
||||
reason: action.contextText,
|
||||
onPhoneLogin: () => _loginAndApply(ref, LoginMethod.phone),
|
||||
onSecondaryLogin: () => _loginAndApply(ref, LoginMethod.wechat),
|
||||
);
|
||||
}
|
||||
|
||||
void _loginAndApply(WidgetRef ref, LoginMethod method) {
|
||||
ref.read(authControllerProvider.notifier).login(method).then((pending) {
|
||||
if (pending != null) {
|
||||
_applyPendingAction(ref, pending);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _applyPendingAction(WidgetRef ref, PendingLoginAction action) {
|
||||
final controller = ref.read(profileControllerProvider.notifier);
|
||||
switch (action.action) {
|
||||
case LoginRequiredAction.favorite:
|
||||
controller.toggleFavorite(action.reportId);
|
||||
case LoginRequiredAction.saveListen:
|
||||
controller.toggleSavedListen(action.reportId);
|
||||
}
|
||||
}
|
||||
|
||||
void _showSourceSheet(BuildContext context, WidgetRef ref) {
|
||||
final targetUrl = asString(
|
||||
detail.source['url'],
|
||||
asString(
|
||||
detail.source['source_url'],
|
||||
asString(detail.source['original_url']),
|
||||
),
|
||||
);
|
||||
showOutboundSheet(
|
||||
context,
|
||||
title: detail.titleCn,
|
||||
onConfirm: () => ref
|
||||
.read(outboundRepositoryProvider)
|
||||
.recordOutbound(
|
||||
OutboundEvent(
|
||||
scene: 'report_source',
|
||||
refId: detail.id,
|
||||
targetUrl: targetUrl.isEmpty ? null : targetUrl,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _Toc extends StatelessWidget {
|
||||
|
||||
Reference in New Issue
Block a user