📱 Responsive for desktop
This commit is contained in:
@ -8,7 +8,9 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/post.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/route.gr.dart';
|
||||
import 'package:island/screens/account/me/publishers.dart';
|
||||
import 'package:island/screens/creators/publishers.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/content/cloud_files.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
@ -25,17 +27,69 @@ Future<SnPublisherStats?> publisherStats(Ref ref, String? uname) async {
|
||||
return SnPublisherStats.fromJson(resp.data);
|
||||
}
|
||||
|
||||
@RoutePage()
|
||||
class CreatorHubShellScreen extends StatelessWidget {
|
||||
const CreatorHubShellScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isWide = isWideScreen(context);
|
||||
if (isWide) {
|
||||
return Row(
|
||||
children: [
|
||||
SizedBox(width: 360, child: const CreatorHubScreen(isAside: true)),
|
||||
const VerticalDivider(width: 1),
|
||||
Expanded(child: AutoRouter()),
|
||||
],
|
||||
);
|
||||
}
|
||||
return AutoRouter();
|
||||
}
|
||||
}
|
||||
|
||||
@RoutePage()
|
||||
class CreatorHubScreen extends HookConsumerWidget {
|
||||
const CreatorHubScreen({super.key});
|
||||
final bool isAside;
|
||||
const CreatorHubScreen({super.key, this.isAside = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isWide = isWideScreen(context);
|
||||
if (isWide && !isAside) {
|
||||
return Container(color: Theme.of(context).colorScheme.surface);
|
||||
}
|
||||
|
||||
final publishers = ref.watch(publishersManagedProvider);
|
||||
final currentPublisher = useState<SnPublisher?>(
|
||||
publishers.value?.firstOrNull,
|
||||
);
|
||||
|
||||
void updatePublisher() {
|
||||
context.router
|
||||
.push(EditPublisherRoute(name: currentPublisher.value!.name))
|
||||
.then((value) async {
|
||||
if (value == null) return;
|
||||
final data = await ref.refresh(publishersManagedProvider.future);
|
||||
currentPublisher.value =
|
||||
data
|
||||
.where((e) => e.id == currentPublisher.value!.id)
|
||||
.firstOrNull;
|
||||
});
|
||||
}
|
||||
|
||||
void deletePublisher() {
|
||||
showConfirmAlert('deletePublisherHint'.tr(), 'deletePublisher'.tr()).then(
|
||||
(confirm) {
|
||||
if (confirm) {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
client.delete('/publishers/${currentPublisher.value!.name}');
|
||||
ref.invalidate(publishersManagedProvider);
|
||||
currentPublisher.value = null;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
final List<DropdownMenuItem<SnPublisher>> publishersMenu = publishers.when(
|
||||
data:
|
||||
(data) =>
|
||||
@ -184,23 +238,56 @@ class CreatorHubScreen extends HookConsumerWidget {
|
||||
_PublisherStatsWidget(
|
||||
stats: stats,
|
||||
).padding(vertical: 12, horizontal: 12),
|
||||
if (currentPublisher.value != null)
|
||||
ListTile(
|
||||
minTileHeight: 48,
|
||||
title: Text('stickers').tr(),
|
||||
trailing: Icon(Symbols.chevron_right),
|
||||
leading: const Icon(Symbols.sticky_note),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
),
|
||||
onTap: () {
|
||||
context.router.push(
|
||||
StickersRoute(
|
||||
pubName: currentPublisher.value!.name,
|
||||
),
|
||||
);
|
||||
},
|
||||
ListTile(
|
||||
minTileHeight: 48,
|
||||
title: Text('stickers').tr(),
|
||||
trailing: Icon(Symbols.chevron_right),
|
||||
leading: const Icon(Symbols.ar_stickers),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
),
|
||||
onTap: () {
|
||||
context.router.push(
|
||||
StickersRoute(
|
||||
pubName: currentPublisher.value!.name,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
minTileHeight: 48,
|
||||
title: Text('posts').tr(),
|
||||
trailing: Icon(Symbols.chevron_right),
|
||||
leading: const Icon(Symbols.sticky_note_2),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
),
|
||||
),
|
||||
Divider(height: 1).padding(vertical: 8),
|
||||
ListTile(
|
||||
minTileHeight: 48,
|
||||
title: Text('editPublisher').tr(),
|
||||
trailing: Icon(Symbols.chevron_right),
|
||||
leading: const Icon(Symbols.edit),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
),
|
||||
onTap: () {
|
||||
updatePublisher();
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
minTileHeight: 48,
|
||||
title: Text('deletePublisher').tr(),
|
||||
trailing: Icon(Symbols.chevron_right),
|
||||
leading: const Icon(Symbols.delete),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
),
|
||||
onTap: () {
|
||||
deletePublisher();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
321
lib/screens/creators/publishers.dart
Normal file
321
lib/screens/creators/publishers.dart
Normal file
@ -0,0 +1,321 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:croppy/croppy.dart' hide cropImage;
|
||||
import 'package:dio/dio.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/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/screens/realm/realms.dart';
|
||||
import 'package:island/services/file.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/content/cloud_files.dart';
|
||||
import 'package:island/widgets/realms/selection_dropdown.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
part 'publishers.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<SnPublisher>> publishersManaged(Ref ref) async {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
final resp = await client.get('/publishers');
|
||||
return resp.data
|
||||
.map((e) => SnPublisher.fromJson(e))
|
||||
.cast<SnPublisher>()
|
||||
.toList();
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<SnPublisher?> publisher(Ref ref, String? identifier) async {
|
||||
if (identifier == null) return null;
|
||||
final client = ref.watch(apiClientProvider);
|
||||
final resp = await client.get('/publishers/$identifier');
|
||||
return SnPublisher.fromJson(resp.data);
|
||||
}
|
||||
|
||||
@RoutePage()
|
||||
class NewPublisherScreen extends StatelessWidget {
|
||||
const NewPublisherScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return EditPublisherScreen(key: key);
|
||||
}
|
||||
}
|
||||
|
||||
@RoutePage()
|
||||
class EditPublisherScreen extends HookConsumerWidget {
|
||||
final String? name;
|
||||
const EditPublisherScreen({super.key, @PathParam('id') this.name});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final submitting = useState(false);
|
||||
|
||||
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) {
|
||||
if (context.mounted) hideLoadingModal(context);
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
hideLoadingModal(context);
|
||||
result = await cropImage(
|
||||
context,
|
||||
image: result,
|
||||
allowedAspectRatios: [
|
||||
if (position == 'background')
|
||||
CropAspectRatio(height: 7, width: 16)
|
||||
else
|
||||
CropAspectRatio(height: 1, width: 1),
|
||||
],
|
||||
);
|
||||
if (result == null) {
|
||||
if (context.mounted) hideLoadingModal(context);
|
||||
return;
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
showLoadingModal(context);
|
||||
|
||||
submitting.value = true;
|
||||
try {
|
||||
final baseUrl = ref.watch(serverUrlProvider);
|
||||
final atk = await getFreshAtk(
|
||||
ref.watch(tokenPairProvider),
|
||||
baseUrl,
|
||||
onRefreshed: (atk, rtk) {
|
||||
setTokenPair(ref.watch(sharedPreferencesProvider), atk, rtk);
|
||||
ref.invalidate(tokenPairProvider);
|
||||
},
|
||||
);
|
||||
if (atk == null) throw ArgumentError('Access token is null');
|
||||
final cloudFile =
|
||||
await putMediaToCloud(
|
||||
fileData: result,
|
||||
atk: atk,
|
||||
baseUrl: baseUrl,
|
||||
filename: result.name,
|
||||
mimetype: result.mimeType ?? 'image/jpeg',
|
||||
).future;
|
||||
if (cloudFile == null) {
|
||||
throw ArgumentError('Failed to upload the file...');
|
||||
}
|
||||
switch (position) {
|
||||
case 'picture':
|
||||
picture.value = cloudFile.id;
|
||||
case 'background':
|
||||
background.value = cloudFile.id;
|
||||
}
|
||||
} catch (err) {
|
||||
showErrorAlert(err);
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
if (context.mounted) hideLoadingModal(context);
|
||||
}
|
||||
}
|
||||
|
||||
final publisher = ref.watch(publisherProvider(name));
|
||||
|
||||
final formKey = useMemoized(GlobalKey<FormState>.new, const []);
|
||||
final nameController = useTextEditingController(
|
||||
text: publisher.value?.name,
|
||||
);
|
||||
final nickController = useTextEditingController(
|
||||
text: publisher.value?.nick,
|
||||
);
|
||||
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!.pictureId;
|
||||
background.value = publisher.value!.backgroundId;
|
||||
nameController.text = publisher.value!.name;
|
||||
nickController.text = publisher.value!.nick;
|
||||
bioController.text = publisher.value!.bio;
|
||||
currentRealm.value = joinedRealms.value?.firstWhereOrNull(
|
||||
(realm) => realm.id == publisher.value!.realmId,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}, [publisher]);
|
||||
|
||||
Future<void> performAction() async {
|
||||
if (!formKey.currentState!.validate()) return;
|
||||
|
||||
submitting.value = true;
|
||||
try {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
final resp = await client.request(
|
||||
name == null
|
||||
? currentRealm.value == null
|
||||
? '/publishers/individual'
|
||||
: '/publishers/organization/${currentRealm.value!.slug}'
|
||||
: '/publishers/$name',
|
||||
data: {
|
||||
'name': nameController.text,
|
||||
'nick': nickController.text,
|
||||
'bio': bioController.text,
|
||||
'picture_id': picture.value,
|
||||
'background_id': background.value,
|
||||
},
|
||||
options: Options(method: name == null ? 'POST' : 'PATCH'),
|
||||
);
|
||||
if (context.mounted) {
|
||||
context.maybePop(SnPublisher.fromJson(resp.data));
|
||||
}
|
||||
} catch (err) {
|
||||
showErrorAlert(err);
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
return AppScaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(name == null ? 'createPublisher' : 'editPublisher').tr(),
|
||||
leading: const PageBackButton(),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
RealmSelectionDropdown(
|
||||
value: currentRealm.value,
|
||||
realms: joinedRealms.when(
|
||||
data: (realms) => realms,
|
||||
loading: () => [],
|
||||
error: (_, __) => [],
|
||||
),
|
||||
onChanged: (SnRealm? value) {
|
||||
currentRealm.value = value;
|
||||
},
|
||||
isLoading: joinedRealms.isLoading,
|
||||
error: joinedRealms.error?.toString(),
|
||||
),
|
||||
AspectRatio(
|
||||
aspectRatio: 16 / 7,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
child:
|
||||
background.value != null
|
||||
? CloudImageWidget(
|
||||
fileId: background.value!,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
onTap: () {
|
||||
setPicture('background');
|
||||
},
|
||||
),
|
||||
Positioned(
|
||||
left: 20,
|
||||
bottom: -32,
|
||||
child: GestureDetector(
|
||||
child: ProfilePictureWidget(
|
||||
fileId: picture.value,
|
||||
radius: 40,
|
||||
),
|
||||
onTap: () {
|
||||
setPicture('picture');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
).padding(bottom: 32),
|
||||
Form(
|
||||
key: formKey,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextFormField(
|
||||
controller: nameController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'username'.tr(),
|
||||
helperText: 'usernameCannotChangeHint'.tr(),
|
||||
prefixText: '@',
|
||||
),
|
||||
readOnly: name != null,
|
||||
onTapOutside:
|
||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
TextFormField(
|
||||
controller: nickController,
|
||||
decoration: InputDecoration(labelText: 'nickname'.tr()),
|
||||
onTapOutside:
|
||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
TextFormField(
|
||||
controller: bioController,
|
||||
decoration: InputDecoration(labelText: 'bio'.tr()),
|
||||
minLines: 3,
|
||||
maxLines: null,
|
||||
onTapOutside:
|
||||
(_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
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.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(
|
||||
currentRealm.value == null
|
||||
? 'syncPublisher'
|
||||
: 'syncPublisherRealm',
|
||||
).tr(),
|
||||
icon: const Icon(Symbols.link),
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: submitting.value ? null : performAction,
|
||||
label: Text(name == null ? 'create' : 'saveChanges').tr(),
|
||||
icon: const Icon(Symbols.save),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
).padding(horizontal: 24),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
168
lib/screens/creators/publishers.g.dart
Normal file
168
lib/screens/creators/publishers.g.dart
Normal file
@ -0,0 +1,168 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'publishers.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$publishersManagedHash() => r'1ea611c8d45c46002976c99bf4ee7f60bd6dbf8e';
|
||||
|
||||
/// See also [publishersManaged].
|
||||
@ProviderFor(publishersManaged)
|
||||
final publishersManagedProvider =
|
||||
AutoDisposeFutureProvider<List<SnPublisher>>.internal(
|
||||
publishersManaged,
|
||||
name: r'publishersManagedProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$publishersManagedHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef PublishersManagedRef = AutoDisposeFutureProviderRef<List<SnPublisher>>;
|
||||
String _$publisherHash() => r'd66f2efba7ae449b9b460a4da34ce48cf3b16fe5';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
_SystemHash._();
|
||||
|
||||
static int combine(int hash, int value) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + value);
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||
return hash ^ (hash >> 6);
|
||||
}
|
||||
|
||||
static int finish(int hash) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||
// ignore: parameter_assignments
|
||||
hash = hash ^ (hash >> 11);
|
||||
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||
}
|
||||
}
|
||||
|
||||
/// See also [publisher].
|
||||
@ProviderFor(publisher)
|
||||
const publisherProvider = PublisherFamily();
|
||||
|
||||
/// See also [publisher].
|
||||
class PublisherFamily extends Family<AsyncValue<SnPublisher?>> {
|
||||
/// See also [publisher].
|
||||
const PublisherFamily();
|
||||
|
||||
/// See also [publisher].
|
||||
PublisherProvider call(String? identifier) {
|
||||
return PublisherProvider(identifier);
|
||||
}
|
||||
|
||||
@override
|
||||
PublisherProvider getProviderOverride(covariant PublisherProvider provider) {
|
||||
return call(provider.identifier);
|
||||
}
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||
|
||||
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||
|
||||
@override
|
||||
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'publisherProvider';
|
||||
}
|
||||
|
||||
/// See also [publisher].
|
||||
class PublisherProvider extends AutoDisposeFutureProvider<SnPublisher?> {
|
||||
/// See also [publisher].
|
||||
PublisherProvider(String? identifier)
|
||||
: this._internal(
|
||||
(ref) => publisher(ref as PublisherRef, identifier),
|
||||
from: publisherProvider,
|
||||
name: r'publisherProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$publisherHash,
|
||||
dependencies: PublisherFamily._dependencies,
|
||||
allTransitiveDependencies: PublisherFamily._allTransitiveDependencies,
|
||||
identifier: identifier,
|
||||
);
|
||||
|
||||
PublisherProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.identifier,
|
||||
}) : super.internal();
|
||||
|
||||
final String? identifier;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<SnPublisher?> Function(PublisherRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: PublisherProvider._internal(
|
||||
(ref) => create(ref as PublisherRef),
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
identifier: identifier,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<SnPublisher?> createElement() {
|
||||
return _PublisherProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is PublisherProvider && other.identifier == identifier;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, identifier.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin PublisherRef on AutoDisposeFutureProviderRef<SnPublisher?> {
|
||||
/// The parameter `identifier` of this provider.
|
||||
String? get identifier;
|
||||
}
|
||||
|
||||
class _PublisherProviderElement
|
||||
extends AutoDisposeFutureProviderElement<SnPublisher?>
|
||||
with PublisherRef {
|
||||
_PublisherProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
String? get identifier => (origin as PublisherProvider).identifier;
|
||||
}
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
Reference in New Issue
Block a user