mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
opt: msg btn
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pb.dart'
|
||||
show Offset, Session, SessionId, SessionMainReply, SessionPageType;
|
||||
show
|
||||
Offset,
|
||||
Session,
|
||||
SessionId,
|
||||
SessionMainReply,
|
||||
SessionPageType,
|
||||
ThreeDotItem;
|
||||
import 'package:PiliPlus/grpc/im.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/msg.dart';
|
||||
@@ -18,6 +24,9 @@ class WhisperController
|
||||
|
||||
PbMap<int, Offset>? offset;
|
||||
|
||||
Rx<List<ThreeDotItem>?> threeDotItems = Rx<List<ThreeDotItem>?>(null);
|
||||
Rx<List<ThreeDotItem>?> outsideItem = Rx<List<ThreeDotItem>?>(null);
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
@@ -72,6 +81,16 @@ class WhisperController
|
||||
return response.sessions;
|
||||
}
|
||||
|
||||
@override
|
||||
bool customHandleResponse(
|
||||
bool isRefresh, Success<SessionMainReply> response) {
|
||||
if (isRefresh) {
|
||||
threeDotItems.value = response.response.threeDotItems;
|
||||
outsideItem.value = response.response.outsideItem;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState<SessionMainReply>> customGetData() =>
|
||||
ImGrpc.sessionMain(offset: offset);
|
||||
@@ -140,4 +159,14 @@ class WhisperController
|
||||
SmartDialog.showToast(res['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> onDeleteList() async {
|
||||
var res = await ImGrpc.deleteSessionList(
|
||||
pageType: SessionPageType.SESSION_PAGE_TYPE_HOME);
|
||||
if (res['status']) {
|
||||
loadingState.value = LoadingState.success(null);
|
||||
} else {
|
||||
SmartDialog.showToast(res['msg']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import 'package:PiliPlus/common/skeleton/whisper_item.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pb.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/pages/contact/view.dart';
|
||||
import 'package:PiliPlus/pages/whisper/controller.dart';
|
||||
import 'package:PiliPlus/pages/whisper/widgets/item.dart';
|
||||
import 'package:PiliPlus/pages/whisper_settings/view.dart';
|
||||
import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -20,7 +18,7 @@ class WhisperPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _WhisperPageState extends State<WhisperPage> {
|
||||
final _whisperController = Get.put(WhisperController());
|
||||
final _controller = Get.put(WhisperController());
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -28,83 +26,70 @@ class _WhisperPageState extends State<WhisperPage> {
|
||||
appBar: AppBar(
|
||||
title: const Text('消息'),
|
||||
actions: [
|
||||
IconButton(
|
||||
tooltip: '一键已读',
|
||||
Obx(() {
|
||||
if (_controller.outsideItem.value?.isNotEmpty == true) {
|
||||
return Row(
|
||||
children: _controller.outsideItem.value!.map((e) {
|
||||
return IconButton(
|
||||
tooltip: e.hasTitle() ? e.title : null,
|
||||
onPressed: () {
|
||||
showConfirmDialog(
|
||||
e.type.action(
|
||||
context: context,
|
||||
title: '一键已读',
|
||||
content: '是否清除全部新消息提醒?',
|
||||
onConfirm: _whisperController.onClearUnread,
|
||||
);
|
||||
onConfirm: () {
|
||||
switch (e.type) {
|
||||
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_READ_ALL:
|
||||
_controller.onClearUnread();
|
||||
case ThreeDotItemType
|
||||
.THREE_DOT_ITEM_TYPE_CLEAR_LIST:
|
||||
_controller.onDeleteList();
|
||||
default:
|
||||
}
|
||||
});
|
||||
},
|
||||
icon: const Icon(
|
||||
size: 20,
|
||||
Icons.cleaning_services,
|
||||
),
|
||||
),
|
||||
PopupMenuButton(
|
||||
icon: Icon(size: 20, e.type.icon),
|
||||
);
|
||||
}).toList());
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
}),
|
||||
Obx(() {
|
||||
if (_controller.threeDotItems.value?.isNotEmpty == true) {
|
||||
return PopupMenuButton(
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
PopupMenuItem(
|
||||
return _controller.threeDotItems.value!
|
||||
.map((e) => PopupMenuItem(
|
||||
onTap: () {
|
||||
Get.to(const WhisperSettingsPage(
|
||||
imSettingType: IMSettingType.SETTING_TYPE_NEED_ALL,
|
||||
));
|
||||
e.type.action(
|
||||
context: context,
|
||||
onConfirm: () {
|
||||
switch (e.type) {
|
||||
case ThreeDotItemType
|
||||
.THREE_DOT_ITEM_TYPE_READ_ALL:
|
||||
_controller.onClearUnread();
|
||||
case ThreeDotItemType
|
||||
.THREE_DOT_ITEM_TYPE_CLEAR_LIST:
|
||||
_controller.onDeleteList();
|
||||
default:
|
||||
}
|
||||
});
|
||||
},
|
||||
child: const Row(
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(size: 19, Icons.settings),
|
||||
Text(' 消息设置'),
|
||||
Icon(size: 17, e.type.icon),
|
||||
Text(' ${e.title}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: () {
|
||||
Get.toNamed(
|
||||
'/whisperDetail',
|
||||
parameters: {
|
||||
'talkerId': '844424930131966',
|
||||
'name': 'UP主小助手',
|
||||
'face':
|
||||
'https://message.biliimg.com/bfs/im/489a63efadfb202366c2f88853d2217b5ddc7a13.png',
|
||||
))
|
||||
.toList();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(size: 18, Icons.live_tv),
|
||||
Text(' UP主小助手'),
|
||||
],
|
||||
),
|
||||
),
|
||||
// PopupMenuItem(
|
||||
// onTap: () {},
|
||||
// child: const Row(
|
||||
// children: [
|
||||
// Icon(size: 19, Icons.notifications_none),
|
||||
// Text(' 应援团消息助手'),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
PopupMenuItem(
|
||||
onTap: () {
|
||||
Get.to(const ContactPage(isFromSelct: false));
|
||||
},
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(size: 19, Icons.account_box_outlined),
|
||||
Text(' 通讯录'),
|
||||
],
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
),
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
}),
|
||||
],
|
||||
),
|
||||
body: refreshIndicator(
|
||||
onRefresh: _whisperController.onRefresh,
|
||||
onRefresh: _controller.onRefresh,
|
||||
child: CustomScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
@@ -113,8 +98,7 @@ class _WhisperPageState extends State<WhisperPage> {
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.paddingOf(context).bottom + 100,
|
||||
),
|
||||
sliver:
|
||||
Obx(() => _buildBody(_whisperController.loadingState.value)),
|
||||
sliver: Obx(() => _buildBody(_controller.loadingState.value)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -135,15 +119,14 @@ class _WhisperPageState extends State<WhisperPage> {
|
||||
itemCount: loadingState.response!.length,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == loadingState.response!.length - 1) {
|
||||
_whisperController.onLoadMore();
|
||||
_controller.onLoadMore();
|
||||
}
|
||||
return WhisperSessionItem(
|
||||
item: loadingState.response![index],
|
||||
onSetTop: (isTop, id) =>
|
||||
_whisperController.onSetTop(index, isTop, id),
|
||||
onRemove: (talkerId) =>
|
||||
_whisperController.onRemove(index, talkerId),
|
||||
onTap: () => _whisperController.onTap(index),
|
||||
_controller.onSetTop(index, isTop, id),
|
||||
onRemove: (talkerId) => _controller.onRemove(index, talkerId),
|
||||
onTap: () => _controller.onTap(index),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
@@ -154,11 +137,11 @@ class _WhisperPageState extends State<WhisperPage> {
|
||||
),
|
||||
)
|
||||
: HttpError(
|
||||
onReload: _whisperController.onReload,
|
||||
onReload: _controller.onReload,
|
||||
),
|
||||
Error() => HttpError(
|
||||
errMsg: loadingState.errMsg,
|
||||
onReload: _whisperController.onReload,
|
||||
onReload: _controller.onReload,
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -169,8 +152,8 @@ class _WhisperPageState extends State<WhisperPage> {
|
||||
sliver: SliverToBoxAdapter(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: List.generate(_whisperController.msgFeedTopItems.length,
|
||||
(index) {
|
||||
children:
|
||||
List.generate(_controller.msgFeedTopItems.length, (index) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
@@ -183,16 +166,14 @@ class _WhisperPageState extends State<WhisperPage> {
|
||||
children: [
|
||||
Obx(
|
||||
() => Badge(
|
||||
isLabelVisible:
|
||||
_whisperController.unreadCounts[index] > 0,
|
||||
label: Text(
|
||||
" ${_whisperController.unreadCounts[index]} "),
|
||||
isLabelVisible: _controller.unreadCounts[index] > 0,
|
||||
label: Text(" ${_controller.unreadCounts[index]} "),
|
||||
alignment: Alignment.topRight,
|
||||
child: CircleAvatar(
|
||||
radius: 22,
|
||||
backgroundColor: theme.colorScheme.onInverseSurface,
|
||||
child: Icon(
|
||||
_whisperController.msgFeedTopItems[index]['icon'],
|
||||
_controller.msgFeedTopItems[index]['icon'],
|
||||
size: 20,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
@@ -201,20 +182,20 @@ class _WhisperPageState extends State<WhisperPage> {
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
_whisperController.msgFeedTopItems[index]['name'],
|
||||
_controller.msgFeedTopItems[index]['name'],
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (!_whisperController.msgFeedTopItems[index]['enabled']) {
|
||||
if (!_controller.msgFeedTopItems[index]['enabled']) {
|
||||
SmartDialog.showToast('已禁用');
|
||||
return;
|
||||
}
|
||||
_whisperController.unreadCounts[index] = 0;
|
||||
_controller.unreadCounts[index] = 0;
|
||||
Get.toNamed(
|
||||
_whisperController.msgFeedTopItems[index]['route'],
|
||||
_controller.msgFeedTopItems[index]['route'],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pb.dart'
|
||||
show Offset, Session, SessionId, SessionPageType, SessionSecondaryReply;
|
||||
show
|
||||
Offset,
|
||||
Session,
|
||||
SessionId,
|
||||
SessionPageType,
|
||||
SessionSecondaryReply,
|
||||
ThreeDotItem;
|
||||
import 'package:PiliPlus/grpc/im.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/msg.dart';
|
||||
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:protobuf/protobuf.dart' show PbMap;
|
||||
|
||||
class WhisperSecController
|
||||
@@ -15,6 +22,7 @@ class WhisperSecController
|
||||
|
||||
PbMap<int, Offset>? offset;
|
||||
final SessionPageType sessionPageType;
|
||||
Rx<List<ThreeDotItem>?> threeDotItems = Rx<List<ThreeDotItem>?>(null);
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
@@ -33,9 +41,19 @@ class WhisperSecController
|
||||
if (response.paginationParams.hasMore == false) {
|
||||
isEnd = true;
|
||||
}
|
||||
|
||||
return response.sessions;
|
||||
}
|
||||
|
||||
@override
|
||||
bool customHandleResponse(
|
||||
bool isRefresh, Success<SessionSecondaryReply> response) {
|
||||
if (isRefresh) {
|
||||
threeDotItems.value = response.response.threeDotItems;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState<SessionSecondaryReply>> customGetData() =>
|
||||
ImGrpc.sessionSecondary(
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import 'package:PiliPlus/common/skeleton/whisper_item.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pb.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/pages/whisper/widgets/item.dart';
|
||||
import 'package:PiliPlus/pages/whisper_secondary/controller.dart';
|
||||
import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
@@ -35,50 +35,40 @@ class _WhisperSecPageState extends State<WhisperSecPage> {
|
||||
appBar: AppBar(
|
||||
title: Text(widget.name),
|
||||
actions: [
|
||||
PopupMenuButton(
|
||||
Obx(() {
|
||||
if (_controller.threeDotItems.value?.isNotEmpty == true) {
|
||||
return PopupMenuButton(
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
PopupMenuItem(
|
||||
return _controller.threeDotItems.value!
|
||||
.map((e) => PopupMenuItem(
|
||||
onTap: () {
|
||||
showConfirmDialog(
|
||||
e.type.action(
|
||||
context: context,
|
||||
title: '一键已读',
|
||||
content: '是否清除全部新消息提醒?',
|
||||
onConfirm: _controller.onClearUnread,
|
||||
);
|
||||
onConfirm: () {
|
||||
switch (e.type) {
|
||||
case ThreeDotItemType
|
||||
.THREE_DOT_ITEM_TYPE_READ_ALL:
|
||||
_controller.onClearUnread();
|
||||
case ThreeDotItemType
|
||||
.THREE_DOT_ITEM_TYPE_CLEAR_LIST:
|
||||
_controller.onDeleteList();
|
||||
default:
|
||||
}
|
||||
});
|
||||
},
|
||||
child: const Row(
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
size: 17,
|
||||
Icons.cleaning_services,
|
||||
),
|
||||
Text(' 一键已读'),
|
||||
Icon(size: 17, e.type.icon),
|
||||
Text(' ${e.title}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: () {
|
||||
showConfirmDialog(
|
||||
context: context,
|
||||
title: '清空列表',
|
||||
content: '清空后所有消息将被删除,无法恢复',
|
||||
onConfirm: _controller.onDeleteList,
|
||||
))
|
||||
.toList();
|
||||
},
|
||||
);
|
||||
},
|
||||
child: const Row(
|
||||
children: [
|
||||
Icon(
|
||||
size: 19,
|
||||
Icons.delete_forever_outlined,
|
||||
),
|
||||
Text(' 清空列表'),
|
||||
],
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
),
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
}),
|
||||
],
|
||||
),
|
||||
body: refreshIndicator(
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/hero_dialog_route.dart';
|
||||
import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pbenum.dart'
|
||||
show IMSettingType, ThreeDotItemType;
|
||||
import 'package:PiliPlus/models/common/image_preview_type.dart';
|
||||
import 'package:PiliPlus/pages/contact/view.dart';
|
||||
import 'package:PiliPlus/pages/whisper_settings/view.dart';
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
extension ImageExtension on num? {
|
||||
int? cacheSize(BuildContext context) {
|
||||
@@ -150,3 +157,57 @@ extension RationalExt on Rational {
|
||||
return (min <= aspectRatio) && (aspectRatio <= max);
|
||||
}
|
||||
}
|
||||
|
||||
extension ThreeDotItemTypeExt on ThreeDotItemType {
|
||||
IconData get icon => switch (this) {
|
||||
ThreeDotItemType.THREE_DOT_ITEM_TYPE_MSG_SETTING => Icons.settings,
|
||||
ThreeDotItemType.THREE_DOT_ITEM_TYPE_READ_ALL =>
|
||||
Icons.cleaning_services,
|
||||
ThreeDotItemType.THREE_DOT_ITEM_TYPE_CLEAR_LIST =>
|
||||
Icons.delete_forever_outlined,
|
||||
ThreeDotItemType.THREE_DOT_ITEM_TYPE_UP_HELPER => Icons.live_tv,
|
||||
ThreeDotItemType.THREE_DOT_ITEM_TYPE_CONTACTS =>
|
||||
Icons.account_box_outlined,
|
||||
ThreeDotItemType.THREE_DOT_ITEM_TYPE_FANS_GROUP_HELPER =>
|
||||
Icons.notifications_none,
|
||||
_ => MdiIcons.circleMedium,
|
||||
};
|
||||
|
||||
void action(
|
||||
{required BuildContext context, required VoidCallback onConfirm}) {
|
||||
switch (this) {
|
||||
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_READ_ALL:
|
||||
showConfirmDialog(
|
||||
context: context,
|
||||
title: '一键已读',
|
||||
content: '是否清除全部新消息提醒?',
|
||||
onConfirm: onConfirm,
|
||||
);
|
||||
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_CLEAR_LIST:
|
||||
showConfirmDialog(
|
||||
context: context,
|
||||
title: '清空列表',
|
||||
content: '清空后所有消息将被删除,无法恢复',
|
||||
onConfirm: onConfirm,
|
||||
);
|
||||
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_MSG_SETTING:
|
||||
Get.to(const WhisperSettingsPage(
|
||||
imSettingType: IMSettingType.SETTING_TYPE_NEED_ALL,
|
||||
));
|
||||
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_UP_HELPER:
|
||||
Get.toNamed(
|
||||
'/whisperDetail',
|
||||
parameters: {
|
||||
'talkerId': '844424930131966',
|
||||
'name': 'UP主小助手',
|
||||
'face':
|
||||
'https://message.biliimg.com/bfs/im/489a63efadfb202366c2f88853d2217b5ddc7a13.png',
|
||||
},
|
||||
);
|
||||
case ThreeDotItemType.THREE_DOT_ITEM_TYPE_CONTACTS:
|
||||
Get.to(const ContactPage(isFromSelct: false));
|
||||
default:
|
||||
SmartDialog.showToast(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user