opt gesture

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-10-07 13:52:06 +08:00
parent 2bfa1bb6c2
commit 904756b6ea
38 changed files with 449 additions and 304 deletions

View File

@@ -316,6 +316,7 @@ class ListTile extends StatelessWidget {
/// Requires one of its ancestors to be a [Material] widget.
const ListTile({
super.key,
this.safeArea = false,
this.leading,
this.title,
this.subtitle,
@@ -335,6 +336,7 @@ class ListTile extends StatelessWidget {
this.enabled = true,
this.onTap,
this.onLongPress,
this.onSecondaryTap,
this.onFocusChange,
this.mouseCursor,
this.selected = false,
@@ -355,6 +357,8 @@ class ListTile extends StatelessWidget {
this.statesController,
}) : assert(isThreeLine != true || subtitle != null);
final bool safeArea;
/// A widget to display before the title.
///
/// Typically an [Icon] or a [CircleAvatar] widget.
@@ -563,6 +567,8 @@ class ListTile extends StatelessWidget {
/// Inoperative if [enabled] is false.
final GestureLongPressCallback? onLongPress;
final GestureTapCallback? onSecondaryTap;
/// {@macro flutter.material.inkwell.onFocusChange}
final ValueChanged<bool>? onFocusChange;
@@ -922,10 +928,64 @@ class ListTile extends StatelessWidget {
? ListTileTitleAlignment.threeLine
: ListTileTitleAlignment.titleHeight);
Widget child = IconTheme.merge(
data: iconThemeData,
child: IconButtonTheme(
data: iconButtonThemeData,
child: _ListTile(
leading: leadingIcon,
title: titleText,
subtitle: subtitleText,
trailing: trailingIcon,
isDense: _isDenseLayout(theme, tileTheme),
visualDensity:
visualDensity ?? tileTheme.visualDensity ?? theme.visualDensity,
isThreeLine:
isThreeLine ??
tileTheme.isThreeLine ??
theme.listTileTheme.isThreeLine ??
false,
textDirection: textDirection,
titleBaselineType:
titleStyle.textBaseline ?? defaults.titleTextStyle!.textBaseline!,
subtitleBaselineType:
subtitleStyle?.textBaseline ??
defaults.subtitleTextStyle!.textBaseline!,
horizontalTitleGap:
horizontalTitleGap ?? tileTheme.horizontalTitleGap ?? 16,
minVerticalPadding:
minVerticalPadding ??
tileTheme.minVerticalPadding ??
defaults.minVerticalPadding!,
minLeadingWidth:
minLeadingWidth ??
tileTheme.minLeadingWidth ??
defaults.minLeadingWidth!,
minTileHeight: minTileHeight ?? tileTheme.minTileHeight,
titleAlignment: effectiveTitleAlignment,
),
),
);
if (safeArea) {
child = SafeArea(
top: false,
bottom: false,
minimum: resolvedContentPadding,
child: child,
);
} else {
child = Padding(
padding: resolvedContentPadding,
child: child,
);
}
return InkWell(
customBorder: shape ?? tileTheme.shape,
onTap: enabled ? onTap : null,
onLongPress: enabled ? onLongPress : null,
onSecondaryTap: enabled ? onSecondaryTap : null,
onFocusChange: onFocusChange,
mouseCursor: effectiveMouseCursor,
canRequestFocus: enabled,
@@ -947,50 +1007,7 @@ class ListTile extends StatelessWidget {
shape: shape ?? tileTheme.shape ?? const Border(),
color: _tileBackgroundColor(theme, tileTheme, defaults),
),
child: Padding(
padding: resolvedContentPadding,
child: IconTheme.merge(
data: iconThemeData,
child: IconButtonTheme(
data: iconButtonThemeData,
child: _ListTile(
leading: leadingIcon,
title: titleText,
subtitle: subtitleText,
trailing: trailingIcon,
isDense: _isDenseLayout(theme, tileTheme),
visualDensity:
visualDensity ??
tileTheme.visualDensity ??
theme.visualDensity,
isThreeLine:
isThreeLine ??
tileTheme.isThreeLine ??
theme.listTileTheme.isThreeLine ??
false,
textDirection: textDirection,
titleBaselineType:
titleStyle.textBaseline ??
defaults.titleTextStyle!.textBaseline!,
subtitleBaselineType:
subtitleStyle?.textBaseline ??
defaults.subtitleTextStyle!.textBaseline!,
horizontalTitleGap:
horizontalTitleGap ?? tileTheme.horizontalTitleGap ?? 16,
minVerticalPadding:
minVerticalPadding ??
tileTheme.minVerticalPadding ??
defaults.minVerticalPadding!,
minLeadingWidth:
minLeadingWidth ??
tileTheme.minLeadingWidth ??
defaults.minLeadingWidth!,
minTileHeight: minTileHeight ?? tileTheme.minTileHeight,
titleAlignment: effectiveTitleAlignment,
),
),
),
),
child: child,
),
),
);

View File

@@ -138,6 +138,9 @@ class _AboutPageState extends State<AboutPage> {
ListTile(
onTap: () => Update.checkUpdate(false),
onLongPress: () => Utils.copyText(currentVersion),
onSecondaryTap: Utils.isMobile
? null
: () => Utils.copyText(currentVersion),
title: const Text('当前版本'),
leading: const Icon(Icons.commit_outlined),
trailing: Text(
@@ -157,6 +160,9 @@ Commit Hash: ${BuildConfig.commitHash}''',
'${Constants.sourceCodeUrl}/commit/${BuildConfig.commitHash}',
),
onLongPress: () => Utils.copyText(BuildConfig.commitHash),
onSecondaryTap: Utils.isMobile
? null
: () => Utils.copyText(BuildConfig.commitHash),
),
Divider(
thickness: 1,
@@ -194,6 +200,7 @@ Commit Hash: ${BuildConfig.commitHash}''',
ListTile(
onTap: () => Get.toNamed('/logs'),
onLongPress: LoggerUtils.clearLogs,
onSecondaryTap: Utils.isMobile ? null : LoggerUtils.clearLogs,
leading: const Icon(Icons.bug_report_outlined),
title: const Text('错误日志'),
subtitle: Text('长按清除日志', style: subTitleStyle),

View File

@@ -29,6 +29,7 @@ import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' hide TabBarView;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -414,6 +415,12 @@ class _EpisodePanelState extends State<EpisodePanel>
}
late final Color primary = theme.colorScheme.primary;
void onLongPress() {
if (cover?.isNotEmpty == true) {
imageSaveDialog(title: title, cover: cover, bvid: bvid);
}
}
return Padding(
padding: const EdgeInsets.only(bottom: 2),
child: SizedBox(
@@ -450,11 +457,8 @@ class _EpisodePanelState extends State<EpisodePanel>
}
});
},
onLongPress: () {
if (cover?.isNotEmpty == true) {
imageSaveDialog(title: title, cover: cover, bvid: bvid);
}
},
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -12,6 +12,7 @@ import 'package:PiliPlus/pages/fav_detail/controller.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -35,6 +36,21 @@ class FavVideoCardH extends StatelessWidget {
final isOwner = !isSort && ctr!.isOwner;
late final enableMultiSelect = ctr?.enableMultiSelect.value ?? false;
final theme = Theme.of(context);
final onLongPress = isSort || enableMultiSelect
? null
: isOwner && !enableMultiSelect
? () {
ctr!
..enableMultiSelect.value = true
..onSelect(item);
}
: () => imageSaveDialog(
title: item.title,
cover: item.cover,
bvid: item.bvid,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -59,19 +75,8 @@ class FavVideoCardH extends StatelessWidget {
ctr!.onViewFav(item, index);
},
onLongPress: isSort || enableMultiSelect
? null
: isOwner && !enableMultiSelect
? () {
ctr!
..enableMultiSelect.value = true
..onSelect(item);
}
: () => imageSaveDialog(
title: item.title,
cover: item.cover,
bvid: item.bvid,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -12,6 +12,7 @@ import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -37,6 +38,13 @@ class HistoryItem extends StatelessWidget {
String bvid = item.history.bvid ?? IdUtils.av2bv(aid);
final business = item.history.business;
final enableMultiSelect = ctr.enableMultiSelect.value;
final onLongPress = enableMultiSelect
? null
: () => ctr
..enableMultiSelect.value = true
..onSelect(item);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -88,11 +96,8 @@ class HistoryItem extends StatelessWidget {
}
}
},
onLongPress: enableMultiSelect
? null
: () => ctr
..enableMultiSelect.value = true
..onSelect(item),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Stack(
clipBehavior: Clip.none,
children: [

View File

@@ -13,6 +13,7 @@ import 'package:PiliPlus/models_new/later/list.dart';
import 'package:PiliPlus/pages/later/controller.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -41,14 +42,18 @@ class VideoCardHLater extends StatelessWidget {
}
final theme = Theme.of(context);
final enableMultiSelect = ctr.enableMultiSelect.value;
final onLongPress = enableMultiSelect
? null
: () => ctr
..enableMultiSelect.value = true
..onSelect(videoItem);
return Material(
type: MaterialType.transparency,
child: InkWell(
onLongPress: enableMultiSelect
? null
: () => ctr
..enableMultiSelect.value = true
..onSelect(videoItem),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
onTap: enableMultiSelect
? () => ctr.onSelect(videoItem)
: () async {

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models_new/live/live_feed_index/card_data_list_item.dart';
import 'package:PiliPlus/utils/num_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -17,14 +18,16 @@ class LiveCardVApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Card(
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => PageUtils.toLiveRoom(item.roomid),
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Column(
children: [
AspectRatio(

View File

@@ -3,6 +3,7 @@ import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models_new/live/live_follow/item.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -16,14 +17,16 @@ class LiveCardVFollow extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: liveItem.title,
cover: liveItem.roomCover,
);
return Card(
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => PageUtils.toLiveRoom(liveItem.roomid),
onLongPress: () => imageSaveDialog(
title: liveItem.title,
cover: liveItem.roomCover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Column(
children: [
AspectRatio(

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models_new/live/live_search/room_item.dart';
import 'package:PiliPlus/utils/num_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -17,14 +18,16 @@ class LiveCardVSearch extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Card(
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => PageUtils.toLiveRoom(item.roomid),
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/stat/stat.dart';
import 'package:PiliPlus/models/common/stat_type.dart';
import 'package:PiliPlus/models_new/space/space_article/item.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
class MemberArticleItem extends StatelessWidget {
@@ -16,6 +17,10 @@ class MemberArticleItem extends StatelessWidget {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final outline = theme.colorScheme.outline;
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.originImageUrls?.firstOrNull,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -24,10 +29,8 @@ class MemberArticleItem extends StatelessWidget {
PiliScheme.routePushFromUrl(item.uri!);
}
},
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.originImageUrls?.firstOrNull,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/models/common/stat_type.dart';
import 'package:PiliPlus/models_new/space/space_audio/item.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -19,6 +20,7 @@ class MemberAudioItem extends StatelessWidget {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final hasStat = item.statistic != null;
void onLongPress() => imageSaveDialog(title: item.title, cover: item.cover);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -35,8 +37,8 @@ class MemberAudioItem extends StatelessWidget {
SmartDialog.showToast('没有MV');
return;
},
onLongPress: () =>
imageSaveDialog(title: item.title, cover: item.cover),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models_new/space/space_cheese/item.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
class MemberCheeseItem extends StatelessWidget {
@@ -72,12 +73,13 @@ class MemberCheeseItem extends StatelessWidget {
],
);
}
void onLongPress() => imageSaveDialog(title: item.title, cover: item.cover);
return Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () => PageUtils.viewPugv(seasonId: item.seasonId),
onLongPress: () =>
imageSaveDialog(title: item.title, cover: item.cover),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -11,6 +11,7 @@ import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
class MemberCoinLikeItem extends StatelessWidget {
@@ -23,6 +24,11 @@ class MemberCoinLikeItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
aid: item.param,
);
return Card(
clipBehavior: Clip.hardEdge,
child: InkWell(
@@ -46,11 +52,8 @@ class MemberCoinLikeItem extends StatelessWidget {
}
}
},
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
aid: item.param,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

View File

@@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models_new/space/space_archive/item.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -17,6 +18,7 @@ class MemberComicItem extends StatelessWidget {
fontSize: 13,
color: theme.colorScheme.onSurfaceVariant,
);
void onLongPress() => imageSaveDialog(title: item.title, cover: item.cover);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -28,8 +30,8 @@ class MemberComicItem extends StatelessWidget {
},
);
},
onLongPress: () =>
imageSaveDialog(title: item.title, cover: item.cover),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -19,6 +19,10 @@ class MemberFavItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -44,10 +48,8 @@ class MemberFavItem extends StatelessWidget {
);
}
},
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -13,6 +13,10 @@ class MemberFavItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -25,10 +29,8 @@ class MemberFavItem extends StatelessWidget {
},
);
},
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -9,6 +9,7 @@ import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -62,16 +63,18 @@ class VideoCardVMemberHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: videoItem.title,
cover: videoItem.cover,
aid: videoItem.param,
bvid: videoItem.bvid,
);
return Card(
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: onPushDetail,
onLongPress: () => imageSaveDialog(
title: videoItem.title,
cover: videoItem.cover,
aid: videoItem.param,
bvid: videoItem.bvid,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

View File

@@ -3,6 +3,7 @@ import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models_new/space/space_archive/item.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -16,15 +17,17 @@ class PgcCardVMemberPgc extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Card(
shape: const RoundedRectangleBorder(borderRadius: StyleString.mdRadius),
child: InkWell(
borderRadius: StyleString.mdRadius,
onTap: () => PageUtils.viewPgc(seasonId: item.param),
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models_new/space/space_season_series/season.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
class SeasonSeriesCard extends StatelessWidget {
@@ -17,13 +18,15 @@ class SeasonSeriesCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.meta!.name,
cover: item.meta!.cover,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
onLongPress: () => imageSaveDialog(
title: item.meta!.name,
cover: item.meta!.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
onTap: onTap,
child: Padding(
padding: const EdgeInsets.symmetric(

View File

@@ -11,6 +11,7 @@ import 'package:PiliPlus/models_new/space/space_archive/item.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -31,17 +32,19 @@ class VideoCardHMemberVideo extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
void onLongPress() => imageSaveDialog(
title: videoItem.title,
cover: videoItem.cover,
bvid: videoItem.bvid,
);
return Material(
type: MaterialType.transparency,
child: Stack(
clipBehavior: Clip.none,
children: [
InkWell(
onLongPress: () => imageSaveDialog(
title: videoItem.title,
cover: videoItem.cover,
bvid: videoItem.bvid,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
onTap:
onTap ??
() async {

View File

@@ -1,6 +1,7 @@
import 'package:PiliPlus/common/skeleton/msg_feed_top.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/list_tile.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.pbenum.dart'
@@ -12,7 +13,8 @@ import 'package:PiliPlus/pages/msg_feed_top/at_me/controller.dart';
import 'package:PiliPlus/pages/whisper_settings/view.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:flutter/material.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart' hide ListTile;
import 'package:get/get.dart';
class AtMePage extends StatefulWidget {
@@ -91,7 +93,13 @@ class _AtMePageState extends State<AtMePage> {
_atMeController.onLoadMore();
}
final item = response[index];
void onLongPress() => showConfirmDialog(
context: context,
title: '确定删除该通知?',
onConfirm: () => _atMeController.onRemove(item.id, index),
);
return ListTile(
safeArea: true,
onTap: () {
String? nativeUri = item.item?.nativeUri;
if (nativeUri == null ||
@@ -101,11 +109,8 @@ class _AtMePageState extends State<AtMePage> {
}
PiliScheme.routePushFromUrl(nativeUri);
},
onLongPress: () => showConfirmDialog(
context: context,
title: '确定删除该通知?',
onConfirm: () => _atMeController.onRemove(item.id, index),
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
leading: GestureDetector(
onTap: () => Get.toNamed('/member?mid=${item.user?.mid}'),
child: NetworkImgLayer(

View File

@@ -1,6 +1,7 @@
import 'package:PiliPlus/common/skeleton/msg_feed_top.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/list_tile.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/pair.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
@@ -13,7 +14,8 @@ import 'package:PiliPlus/pages/msg_feed_top/like_me/controller.dart';
import 'package:PiliPlus/pages/whisper_settings/view.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:flutter/material.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart' hide ListTile;
import 'package:get/get.dart';
class LikeMePage extends StatefulWidget {
@@ -162,7 +164,60 @@ class _LikeMePageState extends State<LikeMePage> {
MsgLikeItem item,
ValueChanged<int?> onRemove,
) {
void onLongPress() => showDialog(
context: context,
builder: (context) {
final isNotice = item.noticeState == 0;
return AlertDialog(
clipBehavior: Clip.hardEdge,
contentPadding: const EdgeInsets.symmetric(vertical: 12),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
onTap: () {
Get.back();
showConfirmDialog(
context: context,
title: '删除',
content: '该条通知删除后,当有新点赞时会重新出现在列表,是否继续?',
onConfirm: () => onRemove(item.id),
);
},
dense: true,
title: const Text(
'删除',
style: TextStyle(fontSize: 14),
),
),
ListTile(
onTap: () {
Get.back();
if (isNotice) {
showConfirmDialog(
context: context,
title: '不再通知',
content: '这条内容的点赞将不再通知,但仍可在列表内查看,是否继续?',
onConfirm: () =>
_likeMeController.onSetNotice(item, isNotice),
);
} else {
_likeMeController.onSetNotice(item, isNotice);
}
},
dense: true,
title: Text(
isNotice ? '不再通知' : '接收通知',
style: const TextStyle(fontSize: 14),
),
),
],
),
);
},
);
return ListTile(
safeArea: true,
onTap: () {
String? nativeUri = item.item?.nativeUri;
bool isInvalid =
@@ -183,58 +238,8 @@ class _LikeMePageState extends State<LikeMePage> {
}
PiliScheme.routePushFromUrl(nativeUri);
},
onLongPress: () => showDialog(
context: context,
builder: (context) {
final isNotice = item.noticeState == 0;
return AlertDialog(
clipBehavior: Clip.hardEdge,
contentPadding: const EdgeInsets.symmetric(vertical: 12),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
onTap: () {
Get.back();
showConfirmDialog(
context: context,
title: '删除',
content: '该条通知删除后,当有新点赞时会重新出现在列表,是否继续?',
onConfirm: () => onRemove(item.id),
);
},
dense: true,
title: const Text(
'删除',
style: TextStyle(fontSize: 14),
),
),
ListTile(
onTap: () {
Get.back();
if (isNotice) {
showConfirmDialog(
context: context,
title: '不再通知',
content: '这条内容的点赞将不再通知,但仍可在列表内查看,是否继续?',
onConfirm: () =>
_likeMeController.onSetNotice(item, isNotice),
);
} else {
_likeMeController.onSetNotice(item, isNotice);
}
},
dense: true,
title: Text(
isNotice ? '不再通知' : '接收通知',
style: const TextStyle(fontSize: 14),
),
),
],
),
);
},
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
leading: Column(
children: [
const Spacer(),

View File

@@ -1,6 +1,7 @@
import 'package:PiliPlus/common/skeleton/msg_feed_top.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/list_tile.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.pbenum.dart'
@@ -12,7 +13,8 @@ import 'package:PiliPlus/pages/msg_feed_top/reply_me/controller.dart';
import 'package:PiliPlus/pages/whisper_settings/view.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:flutter/material.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart' hide ListTile;
import 'package:get/get.dart';
class ReplyMePage extends StatefulWidget {
@@ -92,7 +94,16 @@ class _ReplyMePageState extends State<ReplyMePage> {
}
MsgReplyItem item = response[index];
void onLongPress() => showConfirmDialog(
context: context,
title: '确定删除该通知?',
onConfirm: () =>
_replyMeController.onRemove(item.id, index),
);
return ListTile(
safeArea: true,
onTap: () {
String? nativeUri = item.item?.nativeUri;
if (nativeUri == null ||
@@ -106,12 +117,8 @@ class _ReplyMePageState extends State<ReplyMePage> {
oid: item.item?.subjectId,
);
},
onLongPress: () => showConfirmDialog(
context: context,
title: '确定删除该通知?',
onConfirm: () =>
_replyMeController.onRemove(item.id, index),
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
leading: GestureDetector(
onTap: () => Get.toNamed('/member?mid=${item.user?.mid}'),
child: NetworkImgLayer(

View File

@@ -1,5 +1,6 @@
import 'package:PiliPlus/common/skeleton/msg_feed_sys_msg_.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/list_tile.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/loading_state.dart';
@@ -10,7 +11,7 @@ import 'package:PiliPlus/utils/id_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' hide ListTile;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -78,13 +79,15 @@ class _SysMsgPageState extends State<SysMsgPage> {
_sysMsgController.onLoadMore();
}
final item = response[index];
void onLongPress() => showConfirmDialog(
context: context,
title: '确定删除该通知?',
onConfirm: () => _sysMsgController.onRemove(item.id, index),
);
return ListTile(
onLongPress: () => showConfirmDialog(
context: context,
title: '确定删除该通知?',
onConfirm: () =>
_sysMsgController.onRemove(item.id, index),
),
safeArea: true,
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
title: Text(
"${item.title}",
style: theme.textTheme.titleMedium,

View File

@@ -10,6 +10,7 @@ import 'package:PiliPlus/models/common/stat_type.dart';
import 'package:PiliPlus/models_new/music/bgm_recommend_list.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
class MusicVideoCardH extends StatelessWidget {
@@ -22,6 +23,11 @@ class MusicVideoCardH extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: videoItem.title,
cover: videoItem.cover,
bvid: videoItem.bvid,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -37,11 +43,8 @@ class MusicVideoCardH extends StatelessWidget {
);
}
},
onLongPress: () => imageSaveDialog(
title: videoItem.title,
cover: videoItem.cover,
bvid: videoItem.bvid,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models_new/fav/fav_pgc/list.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -18,14 +19,16 @@ class PgcCardV extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Card(
shape: const RoundedRectangleBorder(borderRadius: StyleString.mdRadius),
child: InkWell(
borderRadius: StyleString.mdRadius,
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
onTap: () => PageUtils.viewPgc(seasonId: item.seasonId),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models_new/pgc/pgc_timeline/episode.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -18,14 +19,16 @@ class PgcCardVTimeline extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Card(
shape: const RoundedRectangleBorder(borderRadius: StyleString.mdRadius),
child: InkWell(
borderRadius: StyleString.mdRadius,
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
onTap: () =>
PageUtils.viewPgc(seasonId: item.seasonId, epId: item.episodeId),
child: Column(

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models_new/pgc/pgc_index_result/list.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -18,15 +19,17 @@ class PgcCardVPgcIndex extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Card(
shape: const RoundedRectangleBorder(borderRadius: StyleString.mdRadius),
child: InkWell(
borderRadius: StyleString.mdRadius,
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onTap: () => PageUtils.viewPgc(seasonId: item.seasonId),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/stat/stat.dart';
import 'package:PiliPlus/models/common/stat_type.dart';
import 'package:PiliPlus/models_new/pgc/pgc_rank/pgc_rank_item_model.dart';
import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
class PgcRankItem extends StatelessWidget {
@@ -14,6 +15,10 @@ class PgcRankItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -22,10 +27,8 @@ class PgcRankItem extends StatelessWidget {
PiliScheme.routePushFromUrl(item.url!);
}
},
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/search/result.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 视频卡片 - 垂直布局
@@ -17,14 +18,16 @@ class PgcCardVSearch extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: item.title.map((e) => e.text).join(),
cover: item.cover,
);
return Card(
shape: const RoundedRectangleBorder(borderRadius: StyleString.mdRadius),
child: InkWell(
borderRadius: StyleString.mdRadius,
onLongPress: () => imageSaveDialog(
title: item.title.map((e) => e.text).join(),
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
onTap: () => PageUtils.viewPgc(seasonId: item.seasonId),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,

View File

@@ -3,6 +3,7 @@ import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/search/result.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -18,6 +19,10 @@ class SearchArticleItem extends StatelessWidget {
fontSize: theme.textTheme.labelSmall!.fontSize,
color: theme.colorScheme.outline,
);
void onLongPress() => imageSaveDialog(
title: item.title.map((item) => item.text).join(),
cover: item.imageUrls?.firstOrNull,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -28,10 +33,8 @@ class SearchArticleItem extends StatelessWidget {
'type': 'read',
},
),
onLongPress: () => imageSaveDialog(
title: item.title.map((item) => item.text).join(),
cover: item.imageUrls?.firstOrNull,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -3,6 +3,7 @@ import 'package:PiliPlus/common/widgets/image/image_save.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/search/result.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
class LiveItem extends StatelessWidget {
@@ -13,14 +14,16 @@ class LiveItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
void onLongPress() => imageSaveDialog(
title: liveItem.title.map((item) => item.text).join(),
cover: liveItem.cover,
);
return Card(
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: () => PageUtils.toLiveRoom(liveItem.roomid),
onLongPress: () => imageSaveDialog(
title: liveItem.title.map((item) => item.text).join(),
cover: liveItem.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

View File

@@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/search/result.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
class SearchPgcItem extends StatelessWidget {
@@ -19,14 +20,16 @@ class SearchPgcItem extends StatelessWidget {
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
const TextStyle style = TextStyle(fontSize: 13);
void onLongPress() => imageSaveDialog(
title: item.title.map((item) => item.text).join(),
cover: item.cover,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () => PageUtils.viewPgc(seasonId: item.seasonId),
onLongPress: () => imageSaveDialog(
title: item.title.map((item) => item.text).join(),
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -26,6 +26,10 @@ class SubItem extends StatelessWidget {
21 => '合集',
_ => '其它(${item.type})',
};
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -50,10 +54,8 @@ class SubItem extends StatelessWidget {
);
}
},
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
child: Row(

View File

@@ -10,6 +10,7 @@ import 'package:PiliPlus/models_new/sub/sub_detail/media.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
// 收藏视频卡片 - 水平布局
@@ -25,6 +26,11 @@ class SubVideoCardH extends StatelessWidget {
@override
Widget build(BuildContext context) {
void onLongPress() => imageSaveDialog(
title: videoItem.title,
cover: videoItem.cover,
bvid: videoItem.bvid,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
@@ -39,11 +45,8 @@ class SubVideoCardH extends StatelessWidget {
);
}
},
onLongPress: () => imageSaveDialog(
title: videoItem.title,
cover: videoItem.cover,
bvid: videoItem.bvid,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -11,6 +11,7 @@ import 'package:PiliPlus/models_new/media_list/media_list.dart';
import 'package:PiliPlus/models_new/video/video_detail/episode.dart';
import 'package:PiliPlus/pages/common/slide/common_slide_page.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart' hide RefreshCallback;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -154,6 +155,12 @@ class _MediaListPanelState extends State<MediaListPanel>
bool isCurr,
bool showDelBtn,
) {
void onLongPress() => imageSaveDialog(
title: item.title,
cover: item.cover,
aid: item.aid,
bvid: item.bvid,
);
return Padding(
padding: const EdgeInsets.only(bottom: 2),
child: SizedBox(
@@ -169,12 +176,8 @@ class _MediaListPanelState extends State<MediaListPanel>
Get.back();
widget.onChangeEpisode(item);
},
onLongPress: () => imageSaveDialog(
title: item.title,
cover: item.cover,
aid: item.aid,
bvid: item.bvid,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Stack(
clipBehavior: Clip.none,
children: [

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/models/common/reply/reply_search_type.dart';
import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -47,14 +48,16 @@ class ReplySearchItem extends StatelessWidget {
cover = article.covers.firstOrNull ?? '';
upNickname = article.upNickname;
}
void onLongPress() => imageSaveDialog(
title: title,
cover: cover,
);
return Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () => Get.back(result: (title: title, url: item.url)),
onLongPress: () => imageSaveDialog(
title: title,
cover: cover,
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: StyleString.safeSpace,

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:PiliPlus/common/widgets/badge.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/list_tile.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
import 'package:PiliPlus/grpc/bilibili/app/im/v1.pb.dart'
show Session, SessionId, SessionPageType, SessionType, UnreadStyle;
@@ -9,8 +10,9 @@ import 'package:PiliPlus/models/common/badge_type.dart';
import 'package:PiliPlus/pages/whisper_secondary/view.dart';
import 'package:PiliPlus/utils/date_utils.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/utils.dart';
import 'package:fixnum/fixnum.dart';
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' hide ListTile;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
@@ -41,60 +43,65 @@ class WhisperSessionItem extends StatelessWidget {
? jsonDecode(item.sessionInfo.vipInfo)
: null;
final ThemeData theme = Theme.of(context);
void onLongPress() => showDialog(
context: context,
builder: (context) {
return AlertDialog(
clipBehavior: Clip.hardEdge,
contentPadding: const EdgeInsets.symmetric(vertical: 12),
content: DefaultTextStyle(
style: const TextStyle(fontSize: 14),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
dense: true,
onTap: () {
Get.back();
onSetTop(item.isPinned, item.id);
},
title: Text(item.isPinned ? '移除置顶' : '置顶'),
),
if (item.id.privateId.hasTalkerUid())
ListTile(
dense: true,
onTap: () {
Get.back();
onSetMute(item.isMuted, item.id.privateId.talkerUid);
},
title: Text('${item.isMuted ? '关闭' : '开启'}免打扰'),
),
if (item.id.privateId.hasTalkerUid())
ListTile(
dense: true,
onTap: () {
Get.back();
showConfirmDialog(
context: context,
title: '确定删除该对话?',
onConfirm: () =>
onRemove(item.id.privateId.talkerUid.toInt()),
);
},
title: const Text('删除'),
),
],
),
),
);
},
);
return ListTile(
safeArea: true,
tileColor: item.isPinned
? theme.colorScheme.onInverseSurface.withValues(
alpha: Get.isDarkMode ? 0.4 : 0.8,
)
: null,
onLongPress: () => showDialog(
context: context,
builder: (context) {
return AlertDialog(
clipBehavior: Clip.hardEdge,
contentPadding: const EdgeInsets.symmetric(vertical: 12),
content: DefaultTextStyle(
style: const TextStyle(fontSize: 14),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
dense: true,
onTap: () {
Get.back();
onSetTop(item.isPinned, item.id);
},
title: Text(item.isPinned ? '移除置顶' : '置顶'),
),
if (item.id.privateId.hasTalkerUid())
ListTile(
dense: true,
onTap: () {
Get.back();
onSetMute(item.isMuted, item.id.privateId.talkerUid);
},
title: Text('${item.isMuted ? '关闭' : '开启'}免打扰'),
),
if (item.id.privateId.hasTalkerUid())
ListTile(
dense: true,
onTap: () {
Get.back();
showConfirmDialog(
context: context,
title: '确定删除该对话?',
onConfirm: () =>
onRemove(item.id.privateId.talkerUid.toInt()),
);
},
title: const Text('删除'),
),
],
),
),
);
},
),
onLongPress: onLongPress,
onSecondaryTap: Utils.isMobile ? null : onLongPress,
onTap: () {
if (item.hasUnread()) {
item.clearUnread();