mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-19 00:26:18 +08:00
@@ -91,6 +91,31 @@ Widget imageView(
|
||||
};
|
||||
}
|
||||
|
||||
void onTap(BuildContext context, int index) {
|
||||
if (callback != null) {
|
||||
callback(picArr.map((item) => item.url).toList(), index);
|
||||
} else {
|
||||
onViewImage?.call();
|
||||
context.imageView(
|
||||
initialPage: index,
|
||||
imgList: picArr.map(
|
||||
(item) {
|
||||
bool isLive = item.isLivePhoto && enableLivePhoto;
|
||||
return SourceModel(
|
||||
sourceType:
|
||||
isLive ? SourceType.livePhoto : SourceType.networkImage,
|
||||
url: item.url,
|
||||
liveUrl: isLive ? item.liveUrl : null,
|
||||
width: isLive ? parseSize(item.width) : null,
|
||||
height: isLive ? parseSize(item.height) : null,
|
||||
);
|
||||
},
|
||||
).toList(),
|
||||
onDismissed: onDismissed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return NineGridView(
|
||||
type: NineGridType.weiBo,
|
||||
margin: const EdgeInsets.only(top: 6),
|
||||
@@ -103,30 +128,7 @@ Widget imageView(
|
||||
itemBuilder: (context, index) => Hero(
|
||||
tag: picArr[index].url,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
if (callback != null) {
|
||||
callback(picArr.map((item) => item.url).toList(), index);
|
||||
} else {
|
||||
onViewImage?.call();
|
||||
context.imageView(
|
||||
initialPage: index,
|
||||
imgList: picArr.map(
|
||||
(item) {
|
||||
bool isLive = item.isLivePhoto && enableLivePhoto;
|
||||
return SourceModel(
|
||||
sourceType:
|
||||
isLive ? SourceType.livePhoto : SourceType.networkImage,
|
||||
url: item.url,
|
||||
liveUrl: isLive ? item.liveUrl : null,
|
||||
width: isLive ? parseSize(item.width) : null,
|
||||
height: isLive ? parseSize(item.height) : null,
|
||||
);
|
||||
},
|
||||
).toList(),
|
||||
onDismissed: onDismissed,
|
||||
);
|
||||
}
|
||||
},
|
||||
onTap: () => onTap(context, index),
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: Alignment.center,
|
||||
|
||||
@@ -110,8 +110,9 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
setStatusBar();
|
||||
}
|
||||
|
||||
if (widget.sources[currentIndex.value].sourceType == SourceType.livePhoto) {
|
||||
_onPlay(currentIndex.value);
|
||||
var item = widget.sources[currentIndex.value];
|
||||
if (item.sourceType == SourceType.livePhoto) {
|
||||
_onPlay(item.liveUrl!);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,9 +149,9 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
);
|
||||
}
|
||||
}
|
||||
for (int index = 0; index < widget.sources.length; index++) {
|
||||
if (widget.sources[index].sourceType == SourceType.networkImage) {
|
||||
CachedNetworkImageProvider(_getActualUrl(index)).evict();
|
||||
for (var item in widget.sources) {
|
||||
if (item.sourceType == SourceType.networkImage) {
|
||||
CachedNetworkImageProvider(_getActualUrl(item.url)).evict();
|
||||
}
|
||||
}
|
||||
super.dispose();
|
||||
@@ -209,10 +210,10 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
}
|
||||
}
|
||||
|
||||
void _onPlay(int index) {
|
||||
void _onPlay(String liveUrl) {
|
||||
_player ??= Player();
|
||||
_videoController ??= VideoController(_player!);
|
||||
_player!.open(Media(widget.sources[index].liveUrl!));
|
||||
_player!.open(Media(liveUrl));
|
||||
}
|
||||
|
||||
/// When the page view changed its page, the source will animate back into the
|
||||
@@ -222,8 +223,9 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
void _onPageChanged(int page) {
|
||||
_player?.pause();
|
||||
currentIndex.value = page;
|
||||
if (widget.sources[page].sourceType == SourceType.livePhoto) {
|
||||
_onPlay(page);
|
||||
var item = widget.sources[page];
|
||||
if (item.sourceType == SourceType.livePhoto) {
|
||||
_onPlay(item.liveUrl!);
|
||||
}
|
||||
widget.onPageChanged?.call(page);
|
||||
if (_transformationController!.value != Matrix4.identity()) {
|
||||
@@ -240,10 +242,10 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
}
|
||||
}
|
||||
|
||||
String _getActualUrl(int index) {
|
||||
String _getActualUrl(String url) {
|
||||
return _quality != 100
|
||||
? Utils.thumbnailImgUrl(widget.sources[index].url, _quality)
|
||||
: widget.sources[index].url.http2https;
|
||||
? Utils.thumbnailImgUrl(url, _quality)
|
||||
: url.http2https;
|
||||
}
|
||||
|
||||
void onClose() {
|
||||
@@ -287,6 +289,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
_enablePageView ? null : const NeverScrollableScrollPhysics(),
|
||||
itemCount: widget.sources.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = widget.sources[index];
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: onClose,
|
||||
@@ -294,10 +297,9 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
_doubleTapLocalPosition = details.localPosition;
|
||||
},
|
||||
onDoubleTap: onDoubleTap,
|
||||
onLongPress:
|
||||
widget.sources[index].sourceType == SourceType.fileImage
|
||||
? null
|
||||
: onLongPress,
|
||||
onLongPress: item.sourceType == SourceType.fileImage
|
||||
? null
|
||||
: () => onLongPress(item),
|
||||
child: widget.itemBuilder != null
|
||||
? widget.itemBuilder!(
|
||||
context,
|
||||
@@ -305,7 +307,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
index == currentIndex.value,
|
||||
_enablePageView,
|
||||
)
|
||||
: _itemBuilder(index),
|
||||
: _itemBuilder(index, item),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -356,53 +358,40 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
alignment: Alignment.centerRight,
|
||||
child: PopupMenuButton(
|
||||
itemBuilder: (context) {
|
||||
final item = widget.sources[currentIndex.value];
|
||||
return [
|
||||
PopupMenuItem(
|
||||
onTap: () => DownloadUtils.onShareImg(
|
||||
widget.sources[currentIndex.value].url),
|
||||
onTap: () => DownloadUtils.onShareImg(item.url),
|
||||
child: const Text("分享图片"),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: () {
|
||||
Utils.copyText(
|
||||
widget.sources[currentIndex.value].url);
|
||||
},
|
||||
onTap: () => Utils.copyText(item.url),
|
||||
child: const Text("复制链接"),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: () {
|
||||
DownloadUtils.downloadImg(
|
||||
this.context,
|
||||
[widget.sources[currentIndex.value].url],
|
||||
);
|
||||
},
|
||||
onTap: () => DownloadUtils.downloadImg(
|
||||
this.context,
|
||||
[item.url],
|
||||
),
|
||||
child: const Text("保存图片"),
|
||||
),
|
||||
if (widget.sources.length > 1)
|
||||
PopupMenuItem(
|
||||
onTap: () {
|
||||
DownloadUtils.downloadImg(
|
||||
this.context,
|
||||
widget.sources
|
||||
.map((item) => item.url)
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
onTap: () => DownloadUtils.downloadImg(
|
||||
this.context,
|
||||
widget.sources.map((item) => item.url).toList(),
|
||||
),
|
||||
child: const Text("保存全部"),
|
||||
),
|
||||
if (widget.sources[currentIndex.value].sourceType ==
|
||||
SourceType.livePhoto)
|
||||
if (item.sourceType == SourceType.livePhoto)
|
||||
PopupMenuItem(
|
||||
onTap: () {
|
||||
DownloadUtils.downloadLivePhoto(
|
||||
context: this.context,
|
||||
url: widget.sources[currentIndex.value].url,
|
||||
liveUrl: widget
|
||||
.sources[currentIndex.value].liveUrl!,
|
||||
width:
|
||||
widget.sources[currentIndex.value].width!,
|
||||
height: widget
|
||||
.sources[currentIndex.value].height!,
|
||||
url: item.url,
|
||||
liveUrl: item.liveUrl!,
|
||||
width: item.width!,
|
||||
height: item.height!,
|
||||
);
|
||||
},
|
||||
child: const Text("保存 Live Photo"),
|
||||
@@ -420,25 +409,25 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
);
|
||||
}
|
||||
|
||||
Widget _itemBuilder(index) {
|
||||
Widget _itemBuilder(int index, SourceModel item) {
|
||||
return Center(
|
||||
child: Hero(
|
||||
tag: widget.sources[index].url,
|
||||
child: switch (widget.sources[index].sourceType) {
|
||||
tag: item.url,
|
||||
child: switch (item.sourceType) {
|
||||
SourceType.fileImage => Image(
|
||||
filterQuality: FilterQuality.low,
|
||||
image: FileImage(File(widget.sources[index].url)),
|
||||
image: FileImage(File(item.url)),
|
||||
),
|
||||
SourceType.networkImage => CachedNetworkImage(
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration: Duration.zero,
|
||||
imageUrl: _getActualUrl(index),
|
||||
imageUrl: _getActualUrl(item.url),
|
||||
placeholderFadeInDuration: Duration.zero,
|
||||
placeholder: (context, url) {
|
||||
return CachedNetworkImage(
|
||||
fadeInDuration: Duration.zero,
|
||||
fadeOutDuration: Duration.zero,
|
||||
imageUrl: Utils.thumbnailImgUrl(widget.sources[index].url),
|
||||
imageUrl: Utils.thumbnailImgUrl(item.url),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -502,7 +491,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
.whenComplete(() => _onScaleChanged(targetScale));
|
||||
}
|
||||
|
||||
void onLongPress() {
|
||||
void onLongPress(SourceModel item) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
@@ -514,8 +503,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
children: [
|
||||
ListTile(
|
||||
onTap: () {
|
||||
DownloadUtils.onShareImg(
|
||||
widget.sources[currentIndex.value].url);
|
||||
DownloadUtils.onShareImg(item.url);
|
||||
Get.back();
|
||||
},
|
||||
dense: true,
|
||||
@@ -524,7 +512,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Utils.copyText(widget.sources[currentIndex.value].url);
|
||||
Utils.copyText(item.url);
|
||||
},
|
||||
dense: true,
|
||||
title: const Text('复制链接', style: TextStyle(fontSize: 14)),
|
||||
@@ -534,7 +522,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
Get.back();
|
||||
DownloadUtils.downloadImg(
|
||||
this.context,
|
||||
[widget.sources[currentIndex.value].url],
|
||||
[item.url],
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
@@ -552,17 +540,16 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
dense: true,
|
||||
title: const Text('保存全部图片', style: TextStyle(fontSize: 14)),
|
||||
),
|
||||
if (widget.sources[currentIndex.value].sourceType ==
|
||||
SourceType.livePhoto)
|
||||
if (item.sourceType == SourceType.livePhoto)
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Get.back();
|
||||
DownloadUtils.downloadLivePhoto(
|
||||
context: this.context,
|
||||
url: widget.sources[currentIndex.value].url,
|
||||
liveUrl: widget.sources[currentIndex.value].liveUrl!,
|
||||
width: widget.sources[currentIndex.value].width!,
|
||||
height: widget.sources[currentIndex.value].height!,
|
||||
url: item.url,
|
||||
liveUrl: item.liveUrl!,
|
||||
width: item.width!,
|
||||
height: item.height!,
|
||||
);
|
||||
},
|
||||
dense: true,
|
||||
|
||||
@@ -70,9 +70,7 @@ class PendantAvatar extends StatelessWidget {
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Get.toNamed('/liveRoom?roomid=$roomId');
|
||||
},
|
||||
onTap: () => Get.toNamed('/liveRoom?roomid=$roomId'),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1),
|
||||
decoration: BoxDecoration(
|
||||
|
||||
@@ -593,7 +593,7 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
_positionController
|
||||
.animateTo(1.0 / _kDragSizeFactorLimit,
|
||||
duration: _kIndicatorSnapDuration)
|
||||
.then<void>((void value) {
|
||||
.whenComplete(() {
|
||||
if (mounted && _status == RefreshIndicatorStatus.snap) {
|
||||
setState(() {
|
||||
// Show the indeterminate progress indicator.
|
||||
|
||||
@@ -40,9 +40,7 @@ class VideoCustomActions {
|
||||
Icon(MdiIcons.circleOutline, size: 16),
|
||||
],
|
||||
),
|
||||
() {
|
||||
Utils.copyText(videoItem.bvid!);
|
||||
},
|
||||
() => Utils.copyText(videoItem.bvid!),
|
||||
),
|
||||
VideoCustomAction(
|
||||
'稍后再看',
|
||||
@@ -59,11 +57,9 @@ class VideoCustomActions {
|
||||
'访问:${videoItem.owner.name}',
|
||||
'visit',
|
||||
const Icon(MdiIcons.accountCircleOutline, size: 16),
|
||||
() {
|
||||
Get.toNamed('/member?mid=${videoItem.owner.mid}', arguments: {
|
||||
'heroTag': '${videoItem.owner.mid}',
|
||||
});
|
||||
},
|
||||
() => Get.toNamed('/member?mid=${videoItem.owner.mid}', arguments: {
|
||||
'heroTag': '${videoItem.owner.mid}',
|
||||
}),
|
||||
),
|
||||
if (videoItem is! SpaceArchiveItem)
|
||||
VideoCustomAction(
|
||||
@@ -234,42 +230,40 @@ class VideoCustomActions {
|
||||
'拉黑:${videoItem.owner.name}',
|
||||
'block',
|
||||
const Icon(MdiIcons.cancel, size: 16),
|
||||
() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('提示'),
|
||||
content: Text(
|
||||
'确定拉黑:${videoItem.owner.name}(${videoItem.owner.mid})?'
|
||||
'\n\n注:被拉黑的Up可以在隐私设置-黑名单管理中解除'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Get.back(),
|
||||
child: Text(
|
||||
'点错了',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
() => showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: const Text('提示'),
|
||||
content:
|
||||
Text('确定拉黑:${videoItem.owner.name}(${videoItem.owner.mid})?'
|
||||
'\n\n注:被拉黑的Up可以在隐私设置-黑名单管理中解除'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Get.back,
|
||||
child: Text(
|
||||
'点错了',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
var res = await VideoHttp.relationMod(
|
||||
mid: videoItem.owner.mid!,
|
||||
act: 5,
|
||||
reSrc: 11,
|
||||
);
|
||||
GStorage.setBlackMid(videoItem.owner.mid!);
|
||||
Get.back();
|
||||
SmartDialog.showToast(res['msg'] ?? '成功');
|
||||
},
|
||||
child: const Text('确认'),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
var res = await VideoHttp.relationMod(
|
||||
mid: videoItem.owner.mid!,
|
||||
act: 5,
|
||||
reSrc: 11,
|
||||
);
|
||||
GStorage.setBlackMid(videoItem.owner.mid!);
|
||||
Get.back();
|
||||
SmartDialog.showToast(res['msg'] ?? '成功');
|
||||
},
|
||||
child: const Text('确认'),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
VideoCustomAction(
|
||||
"${MineController.anonymity.value ? '退出' : '进入'}无痕模式",
|
||||
|
||||
Reference in New Issue
Block a user