mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: like live room
Closes #963 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -24,6 +24,7 @@ import 'package:canvas_danmaku/canvas_danmaku.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class LiveRoomController extends GetxController {
|
||||
@@ -256,6 +257,7 @@ class LiveRoomController extends GetxController {
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
cancelLikeTimer();
|
||||
cancelLiveTimer();
|
||||
savedDanmaku?.clear();
|
||||
savedDanmaku = null;
|
||||
@@ -330,4 +332,43 @@ class LiveRoomController extends GetxController {
|
||||
})
|
||||
..init();
|
||||
}
|
||||
|
||||
final RxInt likeClickTime = 0.obs;
|
||||
Timer? likeClickTimer;
|
||||
|
||||
void cancelLikeTimer() {
|
||||
likeClickTimer?.cancel();
|
||||
likeClickTimer = null;
|
||||
}
|
||||
|
||||
void onLikeTapDown([_]) {
|
||||
cancelLikeTimer();
|
||||
likeClickTime.value++;
|
||||
}
|
||||
|
||||
void onLikeTapUp([_]) {
|
||||
likeClickTimer ??= Timer(
|
||||
const Duration(milliseconds: 800),
|
||||
onLike,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> onLike() async {
|
||||
if (!Accounts.heartbeat.isLogin) {
|
||||
likeClickTime.value = 0;
|
||||
return;
|
||||
}
|
||||
var res = await LiveHttp.liveLikeReport(
|
||||
clickTime: likeClickTime.value,
|
||||
roomId: roomId,
|
||||
uid: accountService.mid,
|
||||
anchorId: roomInfoH5.value?.roomInfo?.uid,
|
||||
);
|
||||
if (res['status']) {
|
||||
SmartDialog.showToast('点赞成功');
|
||||
} else {
|
||||
SmartDialog.showToast(res['msg']);
|
||||
}
|
||||
likeClickTime.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,6 +578,60 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
style: TextStyle(color: _color),
|
||||
),
|
||||
),
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final theme = Theme.of(context).colorScheme;
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
InkWell(
|
||||
overlayColor: overlayColor(theme),
|
||||
customBorder: const CircleBorder(),
|
||||
onTapDown: _liveRoomController.onLikeTapDown,
|
||||
onTapUp: _liveRoomController.onLikeTapUp,
|
||||
onTapCancel: _liveRoomController.onLikeTapUp,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Icon(Icons.thumb_up_off_alt, color: _color),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: -12,
|
||||
top: -12,
|
||||
child: Obx(() {
|
||||
final likeClickTime =
|
||||
_liveRoomController.likeClickTime.value;
|
||||
if (likeClickTime == 0) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 160),
|
||||
transitionBuilder: (child, animation) {
|
||||
return ScaleTransition(
|
||||
scale: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
key: ValueKey(likeClickTime),
|
||||
'x$likeClickTime',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: theme.brightness.isDark
|
||||
? theme.primary
|
||||
: theme.inversePrimary,
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => onSendDanmaku(true),
|
||||
icon: Icon(Icons.emoji_emotions_outlined, color: _color),
|
||||
@@ -588,8 +642,33 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
),
|
||||
);
|
||||
|
||||
WidgetStateProperty<Color?>? overlayColor(ColorScheme theme) =>
|
||||
WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
if (states.contains(WidgetState.pressed)) {
|
||||
return theme.primary.withValues(alpha: 0.1);
|
||||
}
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return theme.primary.withValues(alpha: 0.08);
|
||||
}
|
||||
if (states.contains(WidgetState.focused)) {
|
||||
return theme.primary.withValues(alpha: 0.1);
|
||||
}
|
||||
}
|
||||
if (states.contains(WidgetState.pressed)) {
|
||||
return theme.onSurfaceVariant.withValues(alpha: 0.1);
|
||||
}
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return theme.onSurfaceVariant.withValues(alpha: 0.08);
|
||||
}
|
||||
if (states.contains(WidgetState.focused)) {
|
||||
return theme.onSurfaceVariant.withValues(alpha: 0.1);
|
||||
}
|
||||
return Colors.transparent;
|
||||
});
|
||||
|
||||
void onSendDanmaku([bool fromEmote = false]) {
|
||||
if (!_liveRoomController.accountService.isLogin.value) {
|
||||
if (!_liveRoomController.isLogin) {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class BottomControl extends StatelessWidget {
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () {
|
||||
if (liveRoomCtr.accountService.isLogin.value) {
|
||||
if (liveRoomCtr.isLogin) {
|
||||
Get.toNamed(
|
||||
'/liveDmBlockPage',
|
||||
parameters: {
|
||||
|
||||
Reference in New Issue
Block a user