Org publishers

This commit is contained in:
LittleSheep 2025-05-12 22:15:51 +08:00
parent 8efd8cd58e
commit ee8d502fc6
7 changed files with 106 additions and 41 deletions

View File

@ -35,6 +35,7 @@
"createPublisherHint": "To create posts, collections, etc.",
"editPublisher": "Edit Publisher",
"syncPublisher": "Use Account Data",
"syncPublisherRealm": "Use Realm Data",
"create": "Create",
"update": "Update",
"edit": "Edit",
@ -179,5 +180,7 @@
"uploading": "Uploading",
"uploadingProgress": "Uploading {} of {}",
"uploadAll": "Upload All",
"stickerCopyPlaceholder": "Copy Placeholder"
"stickerCopyPlaceholder": "Copy Placeholder",
"realmSelection": "Select a Realm",
"publisherIndividual": "Individual Publishers"
}

View File

@ -165,14 +165,6 @@ PODS:
- super_native_extensions (0.0.1):
- Flutter
- SwiftyGif (5.4.5)
- tencent_rtc_sdk (0.0.1):
- Flutter
- TXCustomBeautyProcesserPlugin (= 1.0.2)
- TXLiteAVSDK_Professional (~> 12.3.16995)
- TXCustomBeautyProcesserPlugin (1.0.2)
- TXLiteAVSDK_Professional (12.3.16995):
- TXLiteAVSDK_Professional/Professional (= 12.3.16995)
- TXLiteAVSDK_Professional/Professional (12.3.16995)
- url_launcher_ios (0.0.1):
- Flutter
- volume_controller (0.0.1):
@ -201,7 +193,6 @@ DEPENDENCIES:
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
- tencent_rtc_sdk (from `.symlinks/plugins/tencent_rtc_sdk/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
@ -225,8 +216,6 @@ SPEC REPOS:
- SDWebImage
- sqlite3
- SwiftyGif
- TXCustomBeautyProcesserPlugin
- TXLiteAVSDK_Professional
EXTERNAL SOURCES:
croppy:
@ -267,8 +256,6 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqlite3_flutter_libs/darwin"
super_native_extensions:
:path: ".symlinks/plugins/super_native_extensions/ios"
tencent_rtc_sdk:
:path: ".symlinks/plugins/tencent_rtc_sdk/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
volume_controller:
@ -313,9 +300,6 @@ SPEC CHECKSUMS:
sqlite3_flutter_libs: f6acaa2172e6bb3e2e70c771661905080e8ebcf2
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
tencent_rtc_sdk: 13f066e69b87068b4cf3df90ad04097eb8773ae2
TXCustomBeautyProcesserPlugin: 099393b941cb40eda12b3a80bf6c0319957b1cfd
TXLiteAVSDK_Professional: 6e8fa18eeb0e52e6bbbcd97bab9ec9fbdc828df3
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12
wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556

View File

@ -83,7 +83,7 @@ final apiClientProvider = Provider<Dio>((ref) {
// ignore
}
final userAgent = ref.watch(userAgentProvider);
final userAgent = ref.read(userAgentProvider);
if (userAgent.value != null) {
options.headers['User-Agent'] = userAgent.value;
}

View File

@ -1,17 +1,19 @@
import 'package:auto_route/auto_route.dart';
import 'package:croppy/croppy.dart' hide cropImage;
import 'package:dio/dio.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:image_picker/image_picker.dart';
import 'package:island/models/file.dart';
import 'package:island/models/post.dart';
import 'package:island/models/realm.dart';
import 'package:island/pods/config.dart';
import 'package:island/pods/network.dart';
import 'package:island/pods/userinfo.dart';
import 'package:island/route.gr.dart';
import 'package:island/screens/realm/realms.dart';
import 'package:island/services/file.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/app_scaffold.dart';
@ -173,15 +175,20 @@ class EditPublisherScreen extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final submitting = useState(false);
final picture = useState<SnCloudFile?>(null);
final background = useState<SnCloudFile?>(null);
final picture = useState<String?>(null);
final background = useState<String?>(null);
void setPicture(String position) async {
showLoadingModal(context);
var result = await ref
.read(imagePickerProvider)
.pickImage(source: ImageSource.gallery);
if (result == null) return;
if (result == null) {
if (context.mounted) hideLoadingModal(context);
return;
}
if (!context.mounted) return;
hideLoadingModal(context);
result = await cropImage(
context,
image: result,
@ -194,6 +201,7 @@ class EditPublisherScreen extends HookConsumerWidget {
);
if (result == null) return;
if (!context.mounted) return;
showLoadingModal(context);
submitting.value = true;
try {
@ -220,14 +228,15 @@ class EditPublisherScreen extends HookConsumerWidget {
}
switch (position) {
case 'picture':
picture.value = cloudFile;
picture.value = cloudFile.id;
case 'background':
background.value = cloudFile;
background.value = cloudFile.id;
}
} catch (err) {
showErrorAlert(err);
} finally {
submitting.value = false;
if (context.mounted) hideLoadingModal(context);
}
}
@ -242,10 +251,13 @@ class EditPublisherScreen extends HookConsumerWidget {
);
final bioController = useTextEditingController(text: publisher.value?.bio);
final joinedRealms = ref.watch(realmsJoinedProvider);
final currentRealm = useState<SnRealm?>(null);
useEffect(() {
if (publisher.value != null) {
picture.value = publisher.value!.picture;
background.value = publisher.value!.background;
picture.value = publisher.value!.pictureId;
background.value = publisher.value!.backgroundId;
nameController.text = publisher.value!.name;
nickController.text = publisher.value!.nick;
bioController.text = publisher.value!.bio;
@ -265,8 +277,8 @@ class EditPublisherScreen extends HookConsumerWidget {
'name': nameController.text,
'nick': nickController.text,
'bio': bioController.text,
'picture_id': picture.value?.id,
'background_id': background.value?.id,
'picture_id': picture.value,
'background_id': background.value,
},
options: Options(method: name == null ? 'POST' : 'PATCH'),
);
@ -287,6 +299,55 @@ class EditPublisherScreen extends HookConsumerWidget {
),
body: Column(
children: [
DropdownButtonHideUnderline(
child: DropdownButton2<SnRealm?>(
isExpanded: true,
hint: Text('realmSelection').tr(),
value: currentRealm.value,
items: [
DropdownMenuItem<SnRealm?>(
value: null,
child: Row(
spacing: 12,
children: [
CircleAvatar(radius: 16, child: Icon(Symbols.person)),
Text('publisherIndividual').tr(),
],
),
),
...joinedRealms.when(
data:
(realms) =>
realms
.map(
(realm) => DropdownMenuItem<SnRealm?>(
value: realm,
child: Row(
spacing: 12,
children: [
ProfilePictureWidget(
fileId: realm.pictureId,
fallbackIcon: Symbols.workspaces,
radius: 16,
),
Text(realm.name),
],
),
),
)
.toList(),
loading: () => [],
error: (_, __) => [],
),
],
onChanged: (SnRealm? value) {
currentRealm.value = value;
},
buttonStyleData: ButtonStyleData(
padding: const EdgeInsets.only(left: 4, right: 16),
),
),
),
AspectRatio(
aspectRatio: 16 / 7,
child: Stack(
@ -298,8 +359,8 @@ class EditPublisherScreen extends HookConsumerWidget {
color: Theme.of(context).colorScheme.surfaceContainerHigh,
child:
background.value != null
? CloudFileWidget(
item: background.value!,
? CloudImageWidget(
fileId: background.value!,
fit: BoxFit.cover,
)
: const SizedBox.shrink(),
@ -313,7 +374,7 @@ class EditPublisherScreen extends HookConsumerWidget {
bottom: -32,
child: GestureDetector(
child: ProfilePictureWidget(
fileId: picture.value?.id,
fileId: picture.value,
radius: 40,
),
onTap: () {
@ -360,19 +421,32 @@ class EditPublisherScreen extends HookConsumerWidget {
children: [
TextButton.icon(
onPressed: () {
if (currentRealm.value == null) {
final user = ref.watch(userInfoProvider);
nameController.text = user.value!.name;
nickController.text = user.value!.nick;
bioController.text = user.value!.profile.bio ?? '';
picture.value = user.value!.profile.picture;
background.value = user.value!.profile.background;
picture.value = user.value!.profile.pictureId;
background.value = user.value!.profile.backgroundId;
} else {
nameController.text = currentRealm.value!.slug;
nickController.text = currentRealm.value!.name;
bioController.text = currentRealm.value!.description;
picture.value = currentRealm.value!.pictureId;
background.value = currentRealm.value!.backgroundId;
}
},
label: Text('syncPublisher'.tr()),
label:
Text(
currentRealm.value == null
? 'syncPublisher'
: 'syncPublisherRealm',
).tr(),
icon: const Icon(Symbols.link),
),
TextButton.icon(
onPressed: submitting.value ? null : performAction,
label: Text('saveChanges'.tr()),
label: Text(name == null ? 'create' : 'saveChanges').tr(),
icon: const Icon(Symbols.save),
),
],

View File

@ -32,6 +32,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
.pickImage(source: ImageSource.gallery);
if (result == null) return;
if (!context.mounted) return;
hideLoadingModal(context);
result = await cropImage(
context,
image: result,
@ -47,6 +48,7 @@ class UpdateProfileScreen extends HookConsumerWidget {
return;
}
if (!context.mounted) return;
showLoadingModal(context);
submitting.value = true;
try {

View File

@ -254,7 +254,7 @@ class EditChatScreen extends HookConsumerWidget {
return;
}
if (!context.mounted) return;
hideLoadingModal(context);
result = await cropImage(
context,
image: result,
@ -267,6 +267,7 @@ class EditChatScreen extends HookConsumerWidget {
);
if (result == null) return;
if (!context.mounted) return;
showLoadingModal(context);
submitting.value = true;
try {

View File

@ -165,6 +165,7 @@ class EditRealmScreen extends HookConsumerWidget {
.pickImage(source: ImageSource.gallery);
if (result == null) return;
if (!context.mounted) return;
hideLoadingModal(context);
result = await cropImage(
context,
image: result,
@ -180,7 +181,7 @@ class EditRealmScreen extends HookConsumerWidget {
return;
}
if (!context.mounted) return;
showLoadingModal(context);
submitting.value = true;
try {
final baseUrl = ref.watch(serverUrlProvider);