🚀 Launch 2.0.0+11

 Album
This commit is contained in:
LittleSheep 2024-11-29 00:26:07 +08:00
parent df6f2af756
commit 997562d174
4 changed files with 126 additions and 6 deletions

View File

@ -1,10 +1,125 @@
import 'package:dismissible_page/dismissible_page.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/types/attachment.dart';
import 'package:surface/widgets/attachment/attachment_detail.dart';
import 'package:surface/widgets/attachment/attachment_item.dart';
import 'package:surface/widgets/dialog.dart';
import 'package:uuid/uuid.dart';
class AlbumScreen extends StatelessWidget { class AlbumScreen extends StatefulWidget {
const AlbumScreen({super.key}); const AlbumScreen({super.key});
@override
State<AlbumScreen> createState() => _AlbumScreenState();
}
class _AlbumScreenState extends State<AlbumScreen> {
final ScrollController _scrollController = ScrollController();
bool _isBusy = false;
int? _totalCount;
final List<SnAttachment> _attachments = List.empty(growable: true);
final List<String> _heroTags = List.empty(growable: true);
Future<void> _fetchAttachments() async {
setState(() => _isBusy = true);
const uuid = Uuid();
try {
final sn = context.read<SnNetworkProvider>();
final resp = await sn.client.get('/cgi/uc/attachments', queryParameters: {
'take': 10,
'offset': _attachments.length,
});
final attachments = List<SnAttachment>.from(
resp.data['data']?.map((e) => SnAttachment.fromJson(e)) ?? [],
).where((e) => e.mimetype.startsWith('image')).toList();
_attachments.addAll(attachments);
_heroTags.addAll(_attachments.map((_) => uuid.v4()));
_totalCount = resp.data['count'] as int?;
} catch (err) {
if (!mounted) return;
context.showErrorDialog(err);
} finally {
setState(() => _isBusy = false);
}
}
@override
void initState() {
super.initState();
_fetchAttachments();
_scrollController.addListener(() {
if (_scrollController.position.atEdge) {
bool isTop = _scrollController.position.pixels == 0;
if (!isTop && !_isBusy) {
if (_totalCount == null || _attachments.length < _totalCount!) {
_fetchAttachments();
}
}
}
});
}
@override
void dispose() {
super.dispose();
_scrollController.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const Placeholder(); return Scaffold(
body: CustomScrollView(
controller: _scrollController,
slivers: [
SliverAppBar(
title: Text('screenAlbum').tr(),
),
SliverMasonryGrid.extent(
childCount: _attachments.length,
maxCrossAxisExtent: 320,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, idx) {
final attachment = _attachments[idx];
return GestureDetector(
child: ClipRRect(
child: AspectRatio(
aspectRatio: attachment.metadata['ratio']?.toDouble() ?? 1,
child: AttachmentItem(
data: attachment,
heroTag: _heroTags[idx],
),
),
),
onTap: () {
context.pushTransparentRoute(
AttachmentZoomView(
data: [attachment],
heroTags: [_heroTags[idx]],
),
backgroundColor: Colors.black.withOpacity(0.7),
rootNavigator: true,
);
},
);
},
),
if (_isBusy)
SliverToBoxAdapter(
child: const CircularProgressIndicator().padding(all: 24),
),
],
),
);
} }
} }

View File

@ -159,6 +159,8 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
.fontSize(17) .fontSize(17)
.tr() .tr()
.padding(horizontal: 20, bottom: 4), .padding(horizontal: 20, bottom: 4),
// TODO add notify level modifier
// TODO impl this
ListTile( ListTile(
leading: AccountImage( leading: AccountImage(
content: content:

View File

@ -95,7 +95,7 @@ class _AttachmentItemSensitiveBlurState
color: Colors.black.withOpacity(0.5), color: Colors.black.withOpacity(0.5),
alignment: Alignment.center, alignment: Alignment.center,
child: Container( child: Container(
constraints: const BoxConstraints(maxWidth: 280), constraints: const BoxConstraints(maxWidth: 180),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@ -105,12 +105,15 @@ class _AttachmentItemSensitiveBlurState
size: 32, size: 32,
), ),
const Gap(8), const Gap(8),
Text('sensitiveContent') Text('sensitiveContent', textAlign: TextAlign.center)
.tr() .tr()
.fontSize(20) .fontSize(20)
.textColor(Colors.white) .textColor(Colors.white)
.bold(), .bold(),
Text('sensitiveContentDescription') Text(
'sensitiveContentDescription',
textAlign: TextAlign.center,
)
.tr() .tr()
.fontSize(14) .fontSize(14)
.textColor(Colors.white.withOpacity(0.8)), .textColor(Colors.white.withOpacity(0.8)),

View File

@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 2.0.0+10 version: 2.0.0+11
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4