🐛 Bug fixes
This commit is contained in:
parent
30184d08b1
commit
408fd0f35e
@ -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."
|
||||
}
|
||||
|
@ -669,5 +669,8 @@
|
||||
"attachmentBillingUploaded": "已占用的字节数",
|
||||
"attachmentBillingDiscount": "免费的字节数",
|
||||
"attachmentBillingHint": "滑动窗口计价®\n在24小时内上传的文件大小超出免费空间才会适用扣费。",
|
||||
"postThumbnail": "帖子缩略图"
|
||||
"postThumbnail": "帖子缩略图",
|
||||
"accountRealms": "领域",
|
||||
"postInGlobal": "全站",
|
||||
"postInGlobalDescription": "不关联此帖子与任何领域。"
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)),
|
||||
|
26
lib/providers/sn_realm.dart
Normal file
26
lib/providers/sn_realm.dart
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user