✨ Publisher selection
This commit is contained in:
parent
a4e27e57a3
commit
1b790baee1
@ -46,5 +46,7 @@
|
|||||||
"postCreateAccountTitle": "Thanks for joining!",
|
"postCreateAccountTitle": "Thanks for joining!",
|
||||||
"postCreateAccountNext": "What's next?",
|
"postCreateAccountNext": "What's next?",
|
||||||
"postCreateAccountNext1": "Go to your email inbox and receive the account activation email.",
|
"postCreateAccountNext1": "Go to your email inbox and receive the account activation email.",
|
||||||
"postCreateAccountNext2": "Log in to your account and start exploring the Solar Network!"
|
"postCreateAccountNext2": "Log in to your account and start exploring the Solar Network!",
|
||||||
|
"publishersEmpty": "No publishers yet",
|
||||||
|
"publishersEmptyDescription": "You can need to create a publisher to start publishing your posts."
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ class EditPublisherScreen extends HookConsumerWidget {
|
|||||||
try {
|
try {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
final resp = await client.request(
|
final resp = await client.request(
|
||||||
name == null ? '/publishers' : '/publishers/$name',
|
name == null ? '/publishers/individual' : '/publishers/$name',
|
||||||
data: {
|
data: {
|
||||||
'name': nameController.text,
|
'name': nameController.text,
|
||||||
'nick': nickController.text,
|
'nick': nickController.text,
|
||||||
|
@ -18,7 +18,9 @@ import 'package:island/services/file.dart';
|
|||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:island/widgets/post/publishers_modal.dart';
|
||||||
import 'package:lucide_icons/lucide_icons.dart';
|
import 'package:lucide_icons/lucide_icons.dart';
|
||||||
|
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
@ -94,6 +96,7 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
final result = await ref
|
final result = await ref
|
||||||
.watch(imagePickerProvider)
|
.watch(imagePickerProvider)
|
||||||
.pickMultiImage(requestFullMetadata: true);
|
.pickMultiImage(requestFullMetadata: true);
|
||||||
|
if (result.isEmpty) return;
|
||||||
attachments.value = [
|
attachments.value = [
|
||||||
...attachments.value,
|
...attachments.value,
|
||||||
...result.map(
|
...result.map(
|
||||||
@ -106,6 +109,7 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
final result = await ref
|
final result = await ref
|
||||||
.watch(imagePickerProvider)
|
.watch(imagePickerProvider)
|
||||||
.pickVideo(source: ImageSource.gallery);
|
.pickVideo(source: ImageSource.gallery);
|
||||||
|
if (result == null) return;
|
||||||
attachments.value = [
|
attachments.value = [
|
||||||
...attachments.value,
|
...attachments.value,
|
||||||
UniversalFile(data: result, type: UniversalFileType.video),
|
UniversalFile(data: result, type: UniversalFileType.video),
|
||||||
@ -241,9 +245,19 @@ class PostComposeScreen extends HookConsumerWidget {
|
|||||||
spacing: 12,
|
spacing: 12,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ProfilePictureWidget(
|
GestureDetector(
|
||||||
item: currentPublisher.value?.picture,
|
child: ProfilePictureWidget(
|
||||||
radius: 24,
|
item: currentPublisher.value?.picture,
|
||||||
|
radius: 24,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
showCupertinoModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => PublisherModal(),
|
||||||
|
).then((value) {
|
||||||
|
if (value is SnPublisher) currentPublisher.value = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
).padding(top: 16),
|
).padding(top: 16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
|
import 'package:flutter_platform_alert/flutter_platform_alert.dart';
|
||||||
|
|
||||||
String _parseRemoteError(DioException err) {
|
String _parseRemoteError(DioException err) {
|
||||||
|
log('${err.requestOptions.method} ${err.requestOptions.uri} ${err.message}');
|
||||||
if (err.response?.data is String) return err.response?.data;
|
if (err.response?.data is String) return err.response?.data;
|
||||||
if (err.response?.data?['errors'] != null) {
|
if (err.response?.data?['errors'] != null) {
|
||||||
final errors = err.response?.data['errors'] as Map<String, dynamic>;
|
final errors = err.response?.data['errors'] as Map<String, dynamic>;
|
||||||
@ -15,7 +16,7 @@ String _parseRemoteError(DioException err) {
|
|||||||
)
|
)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
}
|
}
|
||||||
return jsonEncode(err.response?.data);
|
return err.message ?? err.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void showErrorAlert(dynamic err) async {
|
void showErrorAlert(dynamic err) async {
|
||||||
|
@ -3,7 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/post.dart';
|
import 'package:island/models/post.dart';
|
||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/pods/userinfo.dart';
|
import 'package:island/pods/userinfo.dart';
|
||||||
@ -16,7 +16,7 @@ import 'package:lucide_icons/lucide_icons.dart';
|
|||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:super_context_menu/super_context_menu.dart';
|
import 'package:super_context_menu/super_context_menu.dart';
|
||||||
|
|
||||||
class PostItem extends ConsumerWidget {
|
class PostItem extends HookConsumerWidget {
|
||||||
final SnPost item;
|
final SnPost item;
|
||||||
final EdgeInsets? padding;
|
final EdgeInsets? padding;
|
||||||
final bool isOpenable;
|
final bool isOpenable;
|
||||||
|
@ -7,7 +7,9 @@ import 'package:island/pods/network.dart';
|
|||||||
import 'package:island/screens/account/me/publishers.dart';
|
import 'package:island/screens/account/me/publishers.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:island/widgets/post/publishers_modal.dart';
|
||||||
import 'package:lucide_icons/lucide_icons.dart';
|
import 'package:lucide_icons/lucide_icons.dart';
|
||||||
|
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
class PostQuickReply extends HookConsumerWidget {
|
class PostQuickReply extends HookConsumerWidget {
|
||||||
@ -62,9 +64,19 @@ class PostQuickReply extends HookConsumerWidget {
|
|||||||
(data) => Row(
|
(data) => Row(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
children: [
|
children: [
|
||||||
ProfilePictureWidget(
|
GestureDetector(
|
||||||
item: currentPublisher.value?.picture,
|
child: ProfilePictureWidget(
|
||||||
radius: 16,
|
item: currentPublisher.value?.picture,
|
||||||
|
radius: 16,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
showCupertinoModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => PublisherModal(),
|
||||||
|
).then((value) {
|
||||||
|
if (value is SnPublisher) currentPublisher.value = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
).padding(right: 4),
|
).padding(right: 4),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
91
lib/widgets/post/publishers_modal.dart
Normal file
91
lib/widgets/post/publishers_modal.dart
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/route.gr.dart';
|
||||||
|
import 'package:island/screens/account/me/publishers.dart';
|
||||||
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
|
class PublisherModal extends HookConsumerWidget {
|
||||||
|
const PublisherModal({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final publishers = ref.watch(publishersManagedProvider);
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
height: math.min(MediaQuery.of(context).size.height * 0.4, 480),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: publishers.when(
|
||||||
|
data:
|
||||||
|
(value) =>
|
||||||
|
value.isEmpty
|
||||||
|
? ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(maxWidth: 280),
|
||||||
|
child:
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'publishersEmpty',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).tr().fontSize(17).bold(),
|
||||||
|
Text(
|
||||||
|
'publishersEmptyDescription',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).tr(),
|
||||||
|
const Gap(12),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.router
|
||||||
|
.push(NewPublisherRoute())
|
||||||
|
.then((value) {
|
||||||
|
if (value != null) {
|
||||||
|
ref.invalidate(
|
||||||
|
publishersManagedProvider,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Text('createPublisher').tr(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).center(),
|
||||||
|
)
|
||||||
|
: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
for (final publisher in value)
|
||||||
|
ListTile(
|
||||||
|
leading: ProfilePictureWidget(
|
||||||
|
item: publisher.picture,
|
||||||
|
),
|
||||||
|
title: Text(publisher.nick),
|
||||||
|
subtitle: Text('@${publisher.name}'),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context, publisher);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
|
error: (e, _) => Text('Error: $e'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user