✨ Feature flags
This commit is contained in:
parent
fd979c3a35
commit
666a2dfbf5
@ -670,5 +670,10 @@
|
||||
"uriInvalid": "The URI is invalid.",
|
||||
"add": "Add",
|
||||
"addScope": "Add Scope",
|
||||
"scope": "Scope"
|
||||
"scope": "Scope",
|
||||
"publisherFeatures": "Features",
|
||||
"publisherFeatureDevelop": "Developer Program",
|
||||
"publisherFeatureDevelopDescription": "Unlock development abilities for your publisher, including custom apps, API keys, and more.",
|
||||
"publisherFeatureDevelopHint": "Currently, this feature is under active development, you need send a request to unlock this feature.",
|
||||
"learnMore": "Learn More"
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import 'package:island/models/publisher.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/screens/creators/publishers.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
import 'package:island/services/text.dart';
|
||||
import 'package:island/widgets/account/account_picker.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
@ -46,6 +47,14 @@ Future<SnPublisherMember?> publisherIdentity(Ref ref, String uname) async {
|
||||
}
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<Map<String, bool>> publisherFeatures(Ref ref, String? uname) async {
|
||||
if (uname == null) return {};
|
||||
final apiClient = ref.watch(apiClientProvider);
|
||||
final response = await apiClient.get('/publishers/$uname/features');
|
||||
return Map<String, bool>.from(response.data);
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<List<SnPublisherMember>> publisherInvites(Ref ref) async {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
@ -184,6 +193,10 @@ class CreatorHubScreen extends HookConsumerWidget {
|
||||
publisherStatsProvider(currentPublisher.value?.name),
|
||||
);
|
||||
|
||||
final publisherFeatures = ref.watch(
|
||||
publisherFeaturesProvider(currentPublisher.value?.name),
|
||||
);
|
||||
|
||||
return AppScaffold(
|
||||
noBackground: false,
|
||||
appBar: AppBar(
|
||||
@ -374,6 +387,52 @@ class CreatorHubScreen extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
ExpansionTile(
|
||||
title: Text('publisherFeatures').tr(),
|
||||
leading: const Icon(Symbols.flag),
|
||||
tilePadding: EdgeInsets.symmetric(horizontal: 24),
|
||||
minTileHeight: 48,
|
||||
children: [
|
||||
...publisherFeatures.when(
|
||||
data: (data) {
|
||||
return data.entries.map((entry) {
|
||||
final keyPrefix =
|
||||
'publisherFeature${entry.key.capitalizeEachWord()}';
|
||||
return ListTile(
|
||||
minTileHeight: 48,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 24,
|
||||
),
|
||||
leading: Icon(
|
||||
Symbols.circle,
|
||||
color:
|
||||
entry.value
|
||||
? Colors.green
|
||||
: Colors.red,
|
||||
fill: 1,
|
||||
size: 16,
|
||||
).padding(left: 2, top: 4),
|
||||
title: Text(keyPrefix).tr(),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('${keyPrefix}Description').tr(),
|
||||
if (!entry.value)
|
||||
Text(
|
||||
'${keyPrefix}Hint',
|
||||
).tr().bold(),
|
||||
],
|
||||
),
|
||||
isThreeLine: true,
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
error: (_, _) => [],
|
||||
loading: () => [],
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(height: 1).padding(vertical: 8),
|
||||
ListTile(
|
||||
minTileHeight: 48,
|
||||
|
@ -271,6 +271,128 @@ class _PublisherIdentityProviderElement
|
||||
String get uname => (origin as PublisherIdentityProvider).uname;
|
||||
}
|
||||
|
||||
String _$publisherFeaturesHash() => r'34db65d9a4b6b0c6961733ae79e67f25d5d111d3';
|
||||
|
||||
/// See also [publisherFeatures].
|
||||
@ProviderFor(publisherFeatures)
|
||||
const publisherFeaturesProvider = PublisherFeaturesFamily();
|
||||
|
||||
/// See also [publisherFeatures].
|
||||
class PublisherFeaturesFamily extends Family<AsyncValue<Map<String, bool>>> {
|
||||
/// See also [publisherFeatures].
|
||||
const PublisherFeaturesFamily();
|
||||
|
||||
/// See also [publisherFeatures].
|
||||
PublisherFeaturesProvider call(String? uname) {
|
||||
return PublisherFeaturesProvider(uname);
|
||||
}
|
||||
|
||||
@override
|
||||
PublisherFeaturesProvider getProviderOverride(
|
||||
covariant PublisherFeaturesProvider provider,
|
||||
) {
|
||||
return call(provider.uname);
|
||||
}
|
||||
|
||||
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'publisherFeaturesProvider';
|
||||
}
|
||||
|
||||
/// See also [publisherFeatures].
|
||||
class PublisherFeaturesProvider
|
||||
extends AutoDisposeFutureProvider<Map<String, bool>> {
|
||||
/// See also [publisherFeatures].
|
||||
PublisherFeaturesProvider(String? uname)
|
||||
: this._internal(
|
||||
(ref) => publisherFeatures(ref as PublisherFeaturesRef, uname),
|
||||
from: publisherFeaturesProvider,
|
||||
name: r'publisherFeaturesProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$publisherFeaturesHash,
|
||||
dependencies: PublisherFeaturesFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
PublisherFeaturesFamily._allTransitiveDependencies,
|
||||
uname: uname,
|
||||
);
|
||||
|
||||
PublisherFeaturesProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.uname,
|
||||
}) : super.internal();
|
||||
|
||||
final String? uname;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<Map<String, bool>> Function(PublisherFeaturesRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: PublisherFeaturesProvider._internal(
|
||||
(ref) => create(ref as PublisherFeaturesRef),
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
uname: uname,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<Map<String, bool>> createElement() {
|
||||
return _PublisherFeaturesProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is PublisherFeaturesProvider && other.uname == uname;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, uname.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin PublisherFeaturesRef on AutoDisposeFutureProviderRef<Map<String, bool>> {
|
||||
/// The parameter `uname` of this provider.
|
||||
String? get uname;
|
||||
}
|
||||
|
||||
class _PublisherFeaturesProviderElement
|
||||
extends AutoDisposeFutureProviderElement<Map<String, bool>>
|
||||
with PublisherFeaturesRef {
|
||||
_PublisherFeaturesProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
String? get uname => (origin as PublisherFeaturesProvider).uname;
|
||||
}
|
||||
|
||||
String _$publisherInvitesHash() => r'488cd443407895ce11f4edff07cb6ea58f2aa018';
|
||||
|
||||
/// See also [publisherInvites].
|
||||
|
Loading…
x
Reference in New Issue
Block a user