mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-19 08:36:17 +08:00
@@ -43,16 +43,17 @@ class PendantAvatar extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isMemberAvatar = size == 80;
|
||||
return Stack(
|
||||
alignment: Alignment.bottomCenter,
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
onTap == null
|
||||
? _buildAvatar(colorScheme)
|
||||
? _buildAvatar(colorScheme, isMemberAvatar)
|
||||
: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: onTap,
|
||||
child: _buildAvatar(colorScheme),
|
||||
child: _buildAvatar(colorScheme, isMemberAvatar),
|
||||
),
|
||||
if (showDynDecorate && !garbPendantImage.isNullOrEmpty)
|
||||
Positioned(
|
||||
@@ -100,12 +101,13 @@ class PendantAvatar extends StatelessWidget {
|
||||
),
|
||||
)
|
||||
else if (_badgeType != BadgeType.none)
|
||||
_buildBadge(colorScheme),
|
||||
_buildBadge(colorScheme, isMemberAvatar),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAvatar(ColorScheme colorScheme) => size == 80
|
||||
Widget _buildAvatar(ColorScheme colorScheme, bool isMemberAvatar) =>
|
||||
isMemberAvatar
|
||||
? DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
@@ -131,7 +133,7 @@ class PendantAvatar extends StatelessWidget {
|
||||
type: ImageType.avatar,
|
||||
);
|
||||
|
||||
Widget _buildBadge(ColorScheme colorScheme) {
|
||||
Widget _buildBadge(ColorScheme colorScheme, bool isMemberAvatar) {
|
||||
final child = switch (_badgeType) {
|
||||
BadgeType.vip => Image.asset(
|
||||
'assets/images/big-vip.png',
|
||||
@@ -146,8 +148,8 @@ class PendantAvatar extends StatelessWidget {
|
||||
),
|
||||
};
|
||||
return Positioned(
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
right: isMemberAvatar ? 2 : 0,
|
||||
bottom: isMemberAvatar ? 2 : 0,
|
||||
child: IgnorePointer(
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
|
||||
@@ -2,17 +2,11 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math' show max;
|
||||
|
||||
import 'package:PiliPlus/http/msg.dart';
|
||||
import 'package:PiliPlus/models/common/publish_panel_type.dart';
|
||||
import 'package:PiliPlus/models_new/upload_bfs/data.dart';
|
||||
import 'package:PiliPlus/utils/context_ext.dart';
|
||||
import 'package:PiliPlus/utils/feed_back.dart';
|
||||
import 'package:chat_bottom_container/chat_bottom_container.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart' hide ContextExtensionss;
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
abstract class CommonPublishPage<T> extends StatefulWidget {
|
||||
const CommonPublishPage({
|
||||
@@ -40,10 +34,6 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
|
||||
late final RxBool readOnly = false.obs;
|
||||
late final RxBool enablePublish = false.obs;
|
||||
|
||||
late final imagePicker = ImagePicker();
|
||||
late final RxList<String> pathList = <String>[].obs;
|
||||
int get limit => widget.imageLengthLimit ?? 9;
|
||||
|
||||
bool? hasPub;
|
||||
void initPubState();
|
||||
|
||||
@@ -87,7 +77,8 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
if (mounted &&
|
||||
widget.autofocus &&
|
||||
panelType.value == PanelType.keyboard) {
|
||||
(panelType.value == PanelType.keyboard ||
|
||||
panelType.value == PanelType.none)) {
|
||||
controller.restoreChatPanel();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (focusNode.hasFocus) {
|
||||
@@ -211,42 +202,7 @@ abstract class CommonPublishPageState<T extends CommonPublishPage>
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> onPublish() async {
|
||||
feedBack();
|
||||
List<Map<String, dynamic>>? pictures;
|
||||
if (pathList.isNotEmpty) {
|
||||
SmartDialog.showLoading(msg: '正在上传图片...');
|
||||
final cancelToken = CancelToken();
|
||||
try {
|
||||
pictures = await Future.wait<Map<String, dynamic>>(
|
||||
pathList.map((path) async {
|
||||
Map result = await MsgHttp.uploadBfs(
|
||||
path: path,
|
||||
category: 'daily',
|
||||
biz: 'new_dyn',
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
if (!result['status']) throw HttpException(result['msg']);
|
||||
UploadBfsResData data = result['data'];
|
||||
return {
|
||||
'img_width': data.imageWidth,
|
||||
'img_height': data.imageHeight,
|
||||
'img_size': data.imgSize,
|
||||
'img_src': data.imageUrl,
|
||||
};
|
||||
}),
|
||||
eagerError: true,
|
||||
);
|
||||
SmartDialog.dismiss();
|
||||
} on HttpException catch (e) {
|
||||
cancelToken.cancel();
|
||||
SmartDialog.dismiss();
|
||||
SmartDialog.showToast(e.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
onCustomPublish(pictures: pictures);
|
||||
}
|
||||
Future<void> onPublish();
|
||||
|
||||
Future<void> onCustomPublish({List? pictures});
|
||||
|
||||
|
||||
@@ -4,14 +4,18 @@ import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/button/toolbar_icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/text_field/controller.dart';
|
||||
import 'package:PiliPlus/common/widgets/text_field/text_field.dart';
|
||||
import 'package:PiliPlus/http/msg.dart';
|
||||
import 'package:PiliPlus/models/common/image_preview_type.dart';
|
||||
import 'package:PiliPlus/models/common/publish_panel_type.dart';
|
||||
import 'package:PiliPlus/models_new/dynamic/dyn_mention/item.dart';
|
||||
import 'package:PiliPlus/models_new/emote/emote.dart' as e;
|
||||
import 'package:PiliPlus/models_new/live/live_emote/emoticon.dart';
|
||||
import 'package:PiliPlus/models_new/upload_bfs/data.dart';
|
||||
import 'package:PiliPlus/pages/common/publish/common_publish_page.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_mention/view.dart';
|
||||
import 'package:PiliPlus/utils/feed_back.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:dio/dio.dart' show CancelToken;
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -36,6 +40,9 @@ abstract class CommonRichTextPubPage
|
||||
abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
|
||||
extends CommonPublishPageState<T> {
|
||||
final key = GlobalKey<RichTextFieldState>();
|
||||
late final imagePicker = ImagePicker();
|
||||
late final RxList<String> pathList = <String>[].obs;
|
||||
int get limit => widget.imageLengthLimit ?? 9;
|
||||
|
||||
@override
|
||||
late final RichTextEditingController editController =
|
||||
@@ -380,9 +387,7 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
|
||||
}
|
||||
|
||||
@override
|
||||
void onSave() {
|
||||
widget.onSave?.call(editController.items);
|
||||
}
|
||||
void onSave() => widget.onSave?.call(editController.items);
|
||||
|
||||
Widget get emojiBtn => Obx(
|
||||
() {
|
||||
@@ -430,4 +435,42 @@ abstract class CommonRichTextPubPageState<T extends CommonRichTextPubPage>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> onPublish() async {
|
||||
feedBack();
|
||||
List<Map<String, dynamic>>? pictures;
|
||||
if (pathList.isNotEmpty) {
|
||||
SmartDialog.showLoading(msg: '正在上传图片...');
|
||||
final cancelToken = CancelToken();
|
||||
try {
|
||||
pictures = await Future.wait<Map<String, dynamic>>(
|
||||
pathList.map((path) async {
|
||||
Map result = await MsgHttp.uploadBfs(
|
||||
path: path,
|
||||
category: 'daily',
|
||||
biz: 'new_dyn',
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
if (!result['status']) throw HttpException(result['msg']);
|
||||
UploadBfsResData data = result['data'];
|
||||
return {
|
||||
'img_width': data.imageWidth,
|
||||
'img_height': data.imageHeight,
|
||||
'img_size': data.imgSize,
|
||||
'img_src': data.imageUrl,
|
||||
};
|
||||
}),
|
||||
eagerError: true,
|
||||
);
|
||||
SmartDialog.dismiss();
|
||||
} on HttpException catch (e) {
|
||||
cancelToken.cancel();
|
||||
SmartDialog.dismiss();
|
||||
SmartDialog.showToast(e.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
onCustomPublish(pictures: pictures);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:PiliPlus/pages/common/publish/common_publish_page.dart';
|
||||
import 'package:PiliPlus/utils/feed_back.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class CommonTextPubPage extends CommonPublishPage<String> {
|
||||
@@ -24,7 +25,11 @@ abstract class CommonTextPubPageState<T extends CommonTextPubPage>
|
||||
}
|
||||
|
||||
@override
|
||||
void onSave() {
|
||||
widget.onSave?.call(editController.text);
|
||||
void onSave() => widget.onSave?.call(editController.text);
|
||||
|
||||
@override
|
||||
Future<void> onPublish() {
|
||||
feedBack();
|
||||
return onCustomPublish();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:PiliPlus/utils/feed_back.dart';
|
||||
import 'package:PiliPlus/utils/reply_utils.dart';
|
||||
import 'package:PiliPlus/utils/request_utils.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -181,7 +182,10 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
settings: RouteSettings(arguments: Get.arguments),
|
||||
settings: RouteSettings(
|
||||
arguments: Get.arguments,
|
||||
name: '${Get.currentRoute}-copy-${Utils.generateRandomString(3)}',
|
||||
),
|
||||
),
|
||||
)
|
||||
.then(
|
||||
|
||||
@@ -41,7 +41,7 @@ class _FavPgcPageState extends State<FavPgcPage>
|
||||
children: [
|
||||
Expanded(
|
||||
child: TabBar(
|
||||
overlayColor: WidgetStatePropertyAll(Colors.transparent),
|
||||
overlayColor: const WidgetStatePropertyAll(Colors.transparent),
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
isScrollable: true,
|
||||
tabAlignment: TabAlignment.start,
|
||||
|
||||
@@ -59,14 +59,10 @@ class _MemberPageState extends State<MemberPage> {
|
||||
controller: _userController.scrollController,
|
||||
onlyOneScrollInBody: true,
|
||||
pinnedHeaderSliverHeightBuilder: () =>
|
||||
kToolbarHeight + padding.top,
|
||||
kToolbarHeight + MediaQuery.viewPaddingOf(context).top,
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||
return [
|
||||
_buildUserInfo(
|
||||
theme,
|
||||
padding,
|
||||
_userController.loadingState.value,
|
||||
),
|
||||
_buildUserInfo(theme, _userController.loadingState.value),
|
||||
];
|
||||
},
|
||||
body: _userController.tab2?.isNotEmpty == true
|
||||
@@ -91,11 +87,7 @@ class _MemberPageState extends State<MemberPage> {
|
||||
);
|
||||
}
|
||||
return Center(
|
||||
child: _buildUserInfo(
|
||||
theme,
|
||||
padding,
|
||||
_userController.loadingState.value,
|
||||
),
|
||||
child: _buildUserInfo(theme, _userController.loadingState.value),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -316,7 +308,6 @@ class _MemberPageState extends State<MemberPage> {
|
||||
|
||||
Widget _buildUserInfo(
|
||||
ThemeData theme,
|
||||
EdgeInsets padding,
|
||||
LoadingState<SpaceData?> userState,
|
||||
) {
|
||||
switch (userState) {
|
||||
@@ -338,7 +329,6 @@ class _MemberPageState extends State<MemberPage> {
|
||||
onFollow: () => _userController.onFollow(context),
|
||||
live: _userController.live,
|
||||
silence: _userController.silence,
|
||||
padding: padding,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||
import 'package:PiliPlus/models/common/image_preview_type.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
import 'package:PiliPlus/models_new/space/space/card.dart';
|
||||
@@ -29,7 +30,6 @@ class UserInfoCard extends StatelessWidget {
|
||||
required this.onFollow,
|
||||
this.live,
|
||||
this.silence,
|
||||
required this.padding,
|
||||
});
|
||||
|
||||
final bool isOwner;
|
||||
@@ -39,7 +39,6 @@ class UserInfoCard extends StatelessWidget {
|
||||
final VoidCallback onFollow;
|
||||
final Live? live;
|
||||
final int? silence;
|
||||
final EdgeInsets padding;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -420,7 +419,7 @@ class UserInfoCard extends StatelessWidget {
|
||||
child: PendantAvatar(
|
||||
avatar: card.face,
|
||||
size: 80,
|
||||
badgeSize: 22,
|
||||
badgeSize: 20,
|
||||
officialType: card.officialVerify?.type,
|
||||
isVip: (card.vip?.status ?? -1) > 0,
|
||||
garbPendantImage: card.pendant!.image!,
|
||||
@@ -531,12 +530,8 @@ class UserInfoCard extends StatelessWidget {
|
||||
children: [
|
||||
// _buildHeader(context),
|
||||
const SizedBox(height: 56),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: padding.top,
|
||||
left: padding.left,
|
||||
right: padding.right,
|
||||
),
|
||||
ViewSafeArea(
|
||||
top: true,
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(width: 20),
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
||||
import 'package:PiliPlus/http/pgc.dart';
|
||||
import 'package:PiliPlus/pages/common/slide/common_collapse_slide_page.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class PgcReviewPostPanel extends CommonCollapseSlidePage {
|
||||
class PgcReviewPostPanel extends StatefulWidget {
|
||||
const PgcReviewPostPanel({
|
||||
super.key,
|
||||
required this.name,
|
||||
@@ -28,8 +27,7 @@ class PgcReviewPostPanel extends CommonCollapseSlidePage {
|
||||
State<PgcReviewPostPanel> createState() => _PgcReviewPostPanelState();
|
||||
}
|
||||
|
||||
class _PgcReviewPostPanelState
|
||||
extends CommonCollapseSlidePageState<PgcReviewPostPanel> {
|
||||
class _PgcReviewPostPanelState extends State<PgcReviewPostPanel> {
|
||||
late final _controller = TextEditingController(text: widget.content);
|
||||
late final RxInt _score = (widget.score ?? 0).obs;
|
||||
late final RxBool _shareFeed = false.obs;
|
||||
@@ -49,7 +47,7 @@ class _PgcReviewPostPanelState
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildPage(ThemeData theme) {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -84,7 +82,7 @@ class _PgcReviewPostPanelState
|
||||
),
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 20, bottom: 10),
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 8),
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onHorizontalDragUpdate: (details) =>
|
||||
@@ -139,7 +137,8 @@ class _PgcReviewPostPanelState
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
Flexible(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: TextField(
|
||||
maxLength: 100,
|
||||
@@ -152,6 +151,7 @@ class _PgcReviewPostPanelState
|
||||
textInputAction: TextInputAction.done,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!_isMod)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, bottom: 12),
|
||||
|
||||
@@ -515,9 +515,9 @@ class _SavePanelState extends State<SavePanel> {
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: padding.left,
|
||||
right: padding.right,
|
||||
bottom: 25 + padding.bottom,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: DecoratedBox(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
@@ -529,6 +529,12 @@ class _SavePanelState extends State<SavePanel> {
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: padding.left,
|
||||
right: padding.right,
|
||||
bottom: 25 + padding.bottom,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
@@ -546,7 +552,9 @@ class _SavePanelState extends State<SavePanel> {
|
||||
size: 42,
|
||||
tooltip: showBottom ? '隐藏' : '显示',
|
||||
context: context,
|
||||
icon: showBottom ? Icons.visibility_off : Icons.visibility,
|
||||
icon: showBottom
|
||||
? Icons.visibility_off
|
||||
: Icons.visibility,
|
||||
onPressed: () => setState(() {
|
||||
showBottom = !showBottom;
|
||||
}),
|
||||
@@ -571,6 +579,7 @@ class _SavePanelState extends State<SavePanel> {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -43,14 +43,17 @@ class PageUtils {
|
||||
ValueChanged<int>? onDismissed,
|
||||
int? quality,
|
||||
}) {
|
||||
bool isMemberPage = Get.currentRoute.startsWith('/member?');
|
||||
final currentRoute = Get.currentRoute;
|
||||
bool noneSet =
|
||||
currentRoute.startsWith('/videoV') ||
|
||||
currentRoute.startsWith('/member?');
|
||||
return Navigator.of(Get.context!).push(
|
||||
HeroDialogRoute(
|
||||
builder: (context) => InteractiveviewerGallery(
|
||||
sources: imgList,
|
||||
initIndex: initialPage,
|
||||
onDismissed: onDismissed,
|
||||
setStatusBar: !isMemberPage,
|
||||
setStatusBar: !noneSet,
|
||||
quality: quality ?? GlobalData().imgQuality,
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user