🐛 Bug fixes

This commit is contained in:
LittleSheep 2025-02-22 01:33:57 +08:00
parent 30184d08b1
commit 408fd0f35e
8 changed files with 158 additions and 15 deletions

View File

@ -671,5 +671,8 @@
"attachmentBillingDiscount": "Free space",
"attachmentBillingRatio": "Usage",
"attachmentBillingHint": "Sliding Window Pricing®\nFees will only apply if the size of the file uploaded within 24 hours exceeds the free space.",
"postThumbnail": "Post Thumbnail"
"postThumbnail": "Post Thumbnail",
"accountRealms": "Realms",
"postInGlobal": "Global",
"postInGlobalDescription": "Do not link this post with any realm."
}

View File

@ -669,5 +669,8 @@
"attachmentBillingUploaded": "已占用的字节数",
"attachmentBillingDiscount": "免费的字节数",
"attachmentBillingHint": "滑动窗口计价®\n在24小时内上传的文件大小超出免费空间才会适用扣费。",
"postThumbnail": "帖子缩略图"
"postThumbnail": "帖子缩略图",
"accountRealms": "领域",
"postInGlobal": "全站",
"postInGlobalDescription": "不关联此帖子与任何领域。"
}

View File

@ -18,6 +18,7 @@ import 'package:surface/providers/sn_network.dart';
import 'package:surface/types/attachment.dart';
import 'package:surface/types/poll.dart';
import 'package:surface/types/post.dart';
import 'package:surface/types/realm.dart';
import 'package:surface/widgets/dialog.dart';
import 'package:surface/widgets/universal_image.dart';
import 'package:video_compress/video_compress.dart';
@ -197,6 +198,7 @@ class PostWriteController extends ChangeNotifier {
bool isLoading = false, isBusy = false;
double? progress;
SnRealm? realm;
SnPublisher? publisher;
SnPost? editingPost, repostingPost, replyingPost;
@ -625,6 +627,11 @@ class PostWriteController extends ChangeNotifier {
notifyListeners();
}
void setRealm(SnRealm? value) {
realm = value;
notifyListeners();
}
void setProgress(double? value) {
progress = value;
_temporaryPlanSave();

View File

@ -31,6 +31,7 @@ import 'package:surface/providers/post.dart';
import 'package:surface/providers/relationship.dart';
import 'package:surface/providers/sn_attachment.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/providers/sn_realm.dart';
import 'package:surface/providers/sn_sticker.dart';
import 'package:surface/providers/special_day.dart';
import 'package:surface/providers/theme.dart';
@ -159,6 +160,7 @@ class SolianApp extends StatelessWidget {
Provider(create: (ctx) => SnRelationshipProvider(ctx)),
Provider(create: (ctx) => SnLinkPreviewProvider(ctx)),
Provider(create: (ctx) => SnStickerProvider(ctx)),
Provider(create: (ctx) => SnRealmProvider(ctx)),
ChangeNotifierProvider(create: (ctx) => UserProvider(ctx)),
ChangeNotifierProvider(create: (ctx) => WebSocketProvider(ctx)),
ChangeNotifierProvider(create: (ctx) => NotificationProvider(ctx)),

View File

@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/types/realm.dart';
class SnRealmProvider {
late final SnNetworkProvider _sn;
SnRealmProvider(BuildContext context) {
_sn = context.read<SnNetworkProvider>();
}
Future<List<SnRealm>> listAvailableRealms() async {
final resp = await _sn.client.get('/cgi/id/realms/me/available');
final out = List<SnRealm>.from(
resp.data?.map((e) => SnRealm.fromJson(e)) ?? [],
);
return out;
}
Future<SnRealm> getRealm(String alias) async {
final resp = await _sn.client.get('/cgi/id/realms/$alias');
final out = SnRealm.fromJson(resp.data);
return out;
}
}

View File

@ -104,7 +104,7 @@ class _ChannelDetailScreenState extends State<ChannelDetailScreen> {
try {
final sn = context.read<SnNetworkProvider>();
await sn.client.delete(
'/cgi/im/channels/${_channel!.realm?.alias ?? 'global'}/${_channel!.alias}/members/me',
'/cgi/im/channels/${_channel!.realm?.alias ?? 'global'}/${_channel!.alias}/me',
);
if (!mounted) return;
Navigator.pop(context, false);

View File

@ -20,6 +20,7 @@ import 'package:surface/providers/sn_attachment.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/types/attachment.dart';
import 'package:surface/types/post.dart';
import 'package:surface/types/realm.dart';
import 'package:surface/widgets/account/account_image.dart';
import 'package:surface/widgets/attachment/attachment_input.dart';
import 'package:surface/widgets/attachment/attachment_item.dart';
@ -35,6 +36,8 @@ import 'package:provider/provider.dart';
import 'package:surface/widgets/post/post_poll_editor.dart';
import 'package:uuid/uuid.dart';
import '../../providers/sn_realm.dart';
class PostEditorExtra {
final String? text;
final String? title;
@ -79,6 +82,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
bool get _isLoading => _isFetching || _writeController.isLoading;
List<SnPublisher>? _publishers;
List<SnRealm>? _realms;
Future<void> _fetchPublishers() async {
setState(() => _isFetching = true);
@ -101,6 +105,16 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
}
}
Future<void> _fetchRealms() async {
final rels = context.read<SnRealmProvider>();
try {
_realms = await rels.listAvailableRealms();
} catch (err) {
if (!mounted) return;
context.showErrorDialog(err);
}
}
void _updateMeta() {
showModalBottomSheet(
context: context,
@ -144,6 +158,19 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
);
}
void _showRealmPopup() {
showModalBottomSheet(
context: context,
builder: (context) => _PostRealmPopup(
controller: _writeController,
realms: _realms,
onUpdate: () {
_fetchRealms();
},
),
);
}
void _showPollEditorDialog() async {
final poll = await showDialog<dynamic>(
context: context,
@ -194,6 +221,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
} else {
_writeController.setMode(widget.mode);
}
_fetchRealms();
_fetchPublishers();
_writeController.fetchRelatedPost(
context,
@ -335,6 +363,7 @@ class _PostEditorScreenState extends State<PostEditorScreen> {
'stories' => _PostStoryEditor(
controller: _writeController,
onTapPublisher: _showPublisherPopup,
onTapRealm: _showRealmPopup,
),
'articles' => _PostArticleEditor(
controller: _writeController,
@ -575,11 +604,65 @@ class _PostPublisherPopup extends StatelessWidget {
}
}
class _PostRealmPopup extends StatelessWidget {
final PostWriteController controller;
final List<SnRealm>? realms;
final Function onUpdate;
const _PostRealmPopup({required this.controller, this.realms, required this.onUpdate});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Symbols.face, size: 24),
const Gap(16),
Text('accountRealms', style: Theme.of(context).textTheme.titleLarge).tr(),
],
).padding(horizontal: 20, top: 16, bottom: 12),
ListTile(
leading: const Icon(Symbols.close),
title: Text('postInGlobal').tr(),
subtitle: Text('postInGlobalDescription').tr(),
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
onTap: () {
controller.setRealm(null);
Navigator.pop(context, true);
},
),
const Divider(height: 1),
Expanded(
child: ListView.builder(
itemCount: realms?.length ?? 0,
itemBuilder: (context, idx) {
final realm = realms![idx];
return ListTile(
title: Text(realm.name),
subtitle: Text('@${realm.alias}'),
leading: AccountImage(content: realm.avatar, radius: 18),
onTap: () {
controller.setRealm(realm);
Navigator.pop(context, true);
},
);
},
),
),
],
);
}
}
class _PostStoryEditor extends StatelessWidget {
final PostWriteController controller;
final Function? onTapPublisher;
final Function? onTapRealm;
const _PostStoryEditor({required this.controller, this.onTapPublisher});
const _PostStoryEditor({required this.controller, this.onTapPublisher, this.onTapRealm});
@override
Widget build(BuildContext context) {
@ -589,17 +672,36 @@ class _PostStoryEditor extends StatelessWidget {
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Material(
elevation: 2,
borderRadius: const BorderRadius.all(Radius.circular(24)),
child: GestureDetector(
onTap: () {
onTapPublisher?.call();
},
child: AccountImage(
content: controller.publisher?.avatar,
Column(
children: [
Material(
elevation: 2,
borderRadius: const BorderRadius.all(Radius.circular(24)),
child: GestureDetector(
onTap: () {
onTapPublisher?.call();
},
child: AccountImage(
content: controller.publisher?.avatar,
),
),
),
),
const Gap(10),
Material(
elevation: 1,
borderRadius: const BorderRadius.all(Radius.circular(24)),
child: GestureDetector(
onTap: () {
onTapRealm?.call();
},
child: AccountImage(
content: controller.realm?.avatar,
fallbackWidget: const Icon(Symbols.globe, size: 20),
radius: 14,
),
),
),
],
),
Expanded(
child: Column(

View File

@ -365,7 +365,7 @@ class _RealmSettingsWidgetState extends State<_RealmSettingsWidget> {
final sn = context.read<SnNetworkProvider>();
try {
await sn.client.delete('/cgi/id/realms/${widget.realm!.alias}/members/me');
await sn.client.delete('/cgi/id/realms/${widget.realm!.alias}/me');
if (!mounted) return;
Navigator.pop(context, true);
} catch (err) {