✨ Custom app detail page
This commit is contained in:
131
lib/screens/developers/app_detail.dart
Normal file
131
lib/screens/developers/app_detail.dart
Normal file
@@ -0,0 +1,131 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/custom_app.dart';
|
||||
import 'package:island/screens/developers/app_secrets.dart';
|
||||
import 'package:island/screens/developers/apps.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/content/cloud_files.dart';
|
||||
import 'package:island/widgets/response.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class AppDetailScreen extends HookConsumerWidget {
|
||||
final String publisherName;
|
||||
final String projectId;
|
||||
final String appId;
|
||||
|
||||
const AppDetailScreen({
|
||||
super.key,
|
||||
required this.publisherName,
|
||||
required this.projectId,
|
||||
required this.appId,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final tabController = useTabController(initialLength: 2);
|
||||
final appData = ref.watch(customAppProvider(publisherName, projectId, appId));
|
||||
|
||||
return AppScaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(appData.value?.name ?? 'appDetails'.tr()),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Symbols.edit),
|
||||
onPressed: appData.value == null
|
||||
? null
|
||||
: () {
|
||||
context.pushNamed(
|
||||
'developerAppEdit',
|
||||
pathParameters: {
|
||||
'name': publisherName,
|
||||
'projectId': projectId,
|
||||
'id': appId,
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
bottom: TabBar(
|
||||
controller: tabController,
|
||||
tabs: [Tab(text: 'overview'.tr()), Tab(text: 'secrets'.tr())],
|
||||
),
|
||||
),
|
||||
body: appData.when(
|
||||
data: (app) {
|
||||
return TabBarView(
|
||||
controller: tabController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
_AppOverview(app: app),
|
||||
AppSecretsScreen(
|
||||
publisherName: publisherName,
|
||||
projectId: projectId,
|
||||
appId: appId,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
error: (err, stack) => ResponseErrorWidget(
|
||||
error: err,
|
||||
onRetry: () => ref.invalidate(
|
||||
customAppProvider(publisherName, projectId, appId),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _AppOverview extends StatelessWidget {
|
||||
final CustomApp app;
|
||||
const _AppOverview({required this.app});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
AspectRatio(
|
||||
aspectRatio: 16 / 7,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Container(
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
child: app.background != null
|
||||
? CloudFileWidget(
|
||||
item: app.background!,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
Positioned(
|
||||
left: 20,
|
||||
bottom: -32,
|
||||
child: ProfilePictureWidget(
|
||||
fileId: app.picture?.id,
|
||||
radius: 40,
|
||||
fallbackIcon: Symbols.apps,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
).padding(bottom: 32),
|
||||
ListTile(title: Text('name'.tr()), subtitle: Text(app.name)),
|
||||
ListTile(title: Text('slug'.tr()), subtitle: Text(app.slug)),
|
||||
if (app.description?.isNotEmpty ?? false)
|
||||
ListTile(
|
||||
title: Text('description'.tr()),
|
||||
subtitle: Text(app.description!),
|
||||
),
|
||||
],
|
||||
).padding(bottom: 24),
|
||||
);
|
||||
}
|
||||
}
|
161
lib/screens/developers/app_secrets.dart
Normal file
161
lib/screens/developers/app_secrets.dart
Normal file
@@ -0,0 +1,161 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/custom_app_secret.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:island/widgets/response.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'app_secrets.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<List<CustomAppSecret>> customAppSecrets(
|
||||
Ref ref,
|
||||
String publisherName,
|
||||
String projectId,
|
||||
String appId,
|
||||
) async {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
final resp = await client.get(
|
||||
'/develop/developers/$publisherName/projects/$projectId/apps/$appId/secrets',
|
||||
);
|
||||
return (resp.data as List)
|
||||
.map((e) => CustomAppSecret.fromJson(e))
|
||||
.cast<CustomAppSecret>()
|
||||
.toList();
|
||||
}
|
||||
|
||||
class AppSecretsScreen extends HookConsumerWidget {
|
||||
final String publisherName;
|
||||
final String projectId;
|
||||
final String appId;
|
||||
|
||||
const AppSecretsScreen({
|
||||
super.key,
|
||||
required this.publisherName,
|
||||
required this.projectId,
|
||||
required this.appId,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final secrets = ref.watch(
|
||||
customAppSecretsProvider(publisherName, projectId, appId),
|
||||
);
|
||||
|
||||
Future<void> generateSecret() async {
|
||||
final client = ref.read(apiClientProvider);
|
||||
try {
|
||||
showLoadingModal(context);
|
||||
await client
|
||||
.post(
|
||||
'/develop/developers/$publisherName/projects/$projectId/apps/$appId/secrets',
|
||||
)
|
||||
.then((_) {
|
||||
ref.invalidate(
|
||||
customAppSecretsProvider(publisherName, projectId, appId),
|
||||
);
|
||||
});
|
||||
} catch (err) {
|
||||
showErrorAlert(err);
|
||||
} finally {
|
||||
if (context.mounted) hideLoadingModal(context);
|
||||
}
|
||||
}
|
||||
|
||||
return secrets.when(
|
||||
data: (data) {
|
||||
return RefreshIndicator(
|
||||
onRefresh:
|
||||
() => ref.refresh(
|
||||
customAppSecretsProvider(
|
||||
publisherName,
|
||||
projectId,
|
||||
appId,
|
||||
).future,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Symbols.add),
|
||||
trailing: const Icon(Symbols.chevron_right),
|
||||
title: Text('appSecretsGenerate').tr(),
|
||||
onTap: generateSecret,
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, index) {
|
||||
final secret = data[index];
|
||||
return ListTile(
|
||||
title: Text(secret.id),
|
||||
subtitle: Text(
|
||||
'created_at'.tr(
|
||||
args: [secret.createdAt.toIso8601String()],
|
||||
),
|
||||
),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Symbols.copy_all),
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: secret.secret),
|
||||
);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('secretCopied'.tr())),
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Symbols.delete, color: Colors.red),
|
||||
onPressed: () {
|
||||
showConfirmAlert(
|
||||
'deleteSecretHint'.tr(),
|
||||
'deleteSecret'.tr(),
|
||||
).then((confirm) {
|
||||
if (confirm) {
|
||||
final client = ref.read(apiClientProvider);
|
||||
client
|
||||
.delete(
|
||||
'/develop/developers/$publisherName/projects/$projectId/apps/$appId/secrets/${secret.id}',
|
||||
)
|
||||
.then((_) {
|
||||
ref.invalidate(
|
||||
customAppSecretsProvider(
|
||||
publisherName,
|
||||
projectId,
|
||||
appId,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
loading: () => const Center(child: CircularProgressIndicator()),
|
||||
error:
|
||||
(err, stack) => ResponseErrorWidget(
|
||||
error: err,
|
||||
onRetry:
|
||||
() => ref.invalidate(
|
||||
customAppSecretsProvider(publisherName, projectId, appId),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
188
lib/screens/developers/app_secrets.g.dart
Normal file
188
lib/screens/developers/app_secrets.g.dart
Normal file
@@ -0,0 +1,188 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'app_secrets.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$customAppSecretsHash() => r'1bc62ad812487883ce739793b22a76168d656752';
|
||||
|
||||
/// 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 [customAppSecrets].
|
||||
@ProviderFor(customAppSecrets)
|
||||
const customAppSecretsProvider = CustomAppSecretsFamily();
|
||||
|
||||
/// See also [customAppSecrets].
|
||||
class CustomAppSecretsFamily extends Family<AsyncValue<List<CustomAppSecret>>> {
|
||||
/// See also [customAppSecrets].
|
||||
const CustomAppSecretsFamily();
|
||||
|
||||
/// See also [customAppSecrets].
|
||||
CustomAppSecretsProvider call(
|
||||
String publisherName,
|
||||
String projectId,
|
||||
String appId,
|
||||
) {
|
||||
return CustomAppSecretsProvider(publisherName, projectId, appId);
|
||||
}
|
||||
|
||||
@override
|
||||
CustomAppSecretsProvider getProviderOverride(
|
||||
covariant CustomAppSecretsProvider provider,
|
||||
) {
|
||||
return call(provider.publisherName, provider.projectId, provider.appId);
|
||||
}
|
||||
|
||||
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'customAppSecretsProvider';
|
||||
}
|
||||
|
||||
/// See also [customAppSecrets].
|
||||
class CustomAppSecretsProvider
|
||||
extends AutoDisposeFutureProvider<List<CustomAppSecret>> {
|
||||
/// See also [customAppSecrets].
|
||||
CustomAppSecretsProvider(String publisherName, String projectId, String appId)
|
||||
: this._internal(
|
||||
(ref) => customAppSecrets(
|
||||
ref as CustomAppSecretsRef,
|
||||
publisherName,
|
||||
projectId,
|
||||
appId,
|
||||
),
|
||||
from: customAppSecretsProvider,
|
||||
name: r'customAppSecretsProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$customAppSecretsHash,
|
||||
dependencies: CustomAppSecretsFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
CustomAppSecretsFamily._allTransitiveDependencies,
|
||||
publisherName: publisherName,
|
||||
projectId: projectId,
|
||||
appId: appId,
|
||||
);
|
||||
|
||||
CustomAppSecretsProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.publisherName,
|
||||
required this.projectId,
|
||||
required this.appId,
|
||||
}) : super.internal();
|
||||
|
||||
final String publisherName;
|
||||
final String projectId;
|
||||
final String appId;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<List<CustomAppSecret>> Function(CustomAppSecretsRef provider)
|
||||
create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: CustomAppSecretsProvider._internal(
|
||||
(ref) => create(ref as CustomAppSecretsRef),
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
publisherName: publisherName,
|
||||
projectId: projectId,
|
||||
appId: appId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<List<CustomAppSecret>> createElement() {
|
||||
return _CustomAppSecretsProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is CustomAppSecretsProvider &&
|
||||
other.publisherName == publisherName &&
|
||||
other.projectId == projectId &&
|
||||
other.appId == appId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, publisherName.hashCode);
|
||||
hash = _SystemHash.combine(hash, projectId.hashCode);
|
||||
hash = _SystemHash.combine(hash, appId.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin CustomAppSecretsRef
|
||||
on AutoDisposeFutureProviderRef<List<CustomAppSecret>> {
|
||||
/// The parameter `publisherName` of this provider.
|
||||
String get publisherName;
|
||||
|
||||
/// The parameter `projectId` of this provider.
|
||||
String get projectId;
|
||||
|
||||
/// The parameter `appId` of this provider.
|
||||
String get appId;
|
||||
}
|
||||
|
||||
class _CustomAppSecretsProviderElement
|
||||
extends AutoDisposeFutureProviderElement<List<CustomAppSecret>>
|
||||
with CustomAppSecretsRef {
|
||||
_CustomAppSecretsProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
String get publisherName =>
|
||||
(origin as CustomAppSecretsProvider).publisherName;
|
||||
@override
|
||||
String get projectId => (origin as CustomAppSecretsProvider).projectId;
|
||||
@override
|
||||
String get appId => (origin as CustomAppSecretsProvider).appId;
|
||||
}
|
||||
|
||||
// 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
|
@@ -14,6 +14,20 @@ import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
part 'apps.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<CustomApp> customApp(
|
||||
Ref ref,
|
||||
String publisherName,
|
||||
String projectId,
|
||||
String appId,
|
||||
) async {
|
||||
final client = ref.watch(apiClientProvider);
|
||||
final resp = await client.get(
|
||||
'/develop/developers/$publisherName/projects/$projectId/apps/$appId',
|
||||
);
|
||||
return CustomApp.fromJson(resp.data);
|
||||
}
|
||||
|
||||
@riverpod
|
||||
Future<List<CustomApp>> customApps(
|
||||
Ref ref,
|
||||
@@ -81,98 +95,114 @@ class CustomAppsScreen extends HookConsumerWidget {
|
||||
final app = data[index];
|
||||
return Card(
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (app.background != null)
|
||||
CloudFileWidget(
|
||||
item: app.background!,
|
||||
fit: BoxFit.cover,
|
||||
).clipRRect(topLeft: 8, topRight: 8),
|
||||
if (app.picture != null)
|
||||
Positioned(
|
||||
left: 16,
|
||||
bottom: 16,
|
||||
child: ProfilePictureWidget(
|
||||
fileId: app.picture!.id,
|
||||
radius: 40,
|
||||
fallbackIcon: Symbols.apps,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(app.name),
|
||||
subtitle: Text(
|
||||
app.slug,
|
||||
style: GoogleFonts.robotoMono(fontSize: 12),
|
||||
),
|
||||
contentPadding: EdgeInsets.only(left: 20, right: 12),
|
||||
trailing: PopupMenuButton(
|
||||
itemBuilder:
|
||||
(context) => [
|
||||
PopupMenuItem(
|
||||
value: 'edit',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Symbols.edit),
|
||||
const SizedBox(width: 12),
|
||||
Text('edit').tr(),
|
||||
],
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
context.pushNamed(
|
||||
'developerAppDetail',
|
||||
pathParameters: {
|
||||
'name': publisherName,
|
||||
'projectId': projectId,
|
||||
'appId': app.id,
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (app.background != null)
|
||||
CloudFileWidget(
|
||||
item: app.background!,
|
||||
fit: BoxFit.cover,
|
||||
).clipRRect(topLeft: 8, topRight: 8),
|
||||
if (app.picture != null)
|
||||
Positioned(
|
||||
left: 16,
|
||||
bottom: 16,
|
||||
child: ProfilePictureWidget(
|
||||
fileId: app.picture!.id,
|
||||
radius: 40,
|
||||
fallbackIcon: Symbols.apps,
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 'delete',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Symbols.delete,
|
||||
color: Colors.red,
|
||||
],
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(app.name),
|
||||
subtitle: Text(
|
||||
app.slug,
|
||||
style: GoogleFonts.robotoMono(fontSize: 12),
|
||||
),
|
||||
contentPadding: EdgeInsets.only(left: 20, right: 12),
|
||||
trailing: PopupMenuButton(
|
||||
itemBuilder:
|
||||
(context) => [
|
||||
PopupMenuItem(
|
||||
value: 'edit',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Symbols.edit),
|
||||
const SizedBox(width: 12),
|
||||
Text('edit').tr(),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: 'delete',
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Symbols.delete,
|
||||
color: Colors.red,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'delete',
|
||||
style: TextStyle(color: Colors.red),
|
||||
).tr(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
onSelected: (value) {
|
||||
if (value == 'edit') {
|
||||
context.pushNamed(
|
||||
'developerAppEdit',
|
||||
pathParameters: {
|
||||
'name': publisherName,
|
||||
'projectId': projectId,
|
||||
'id': app.id,
|
||||
},
|
||||
);
|
||||
} else if (value == 'delete') {
|
||||
showConfirmAlert(
|
||||
'deleteCustomAppHint'.tr(),
|
||||
'deleteCustomApp'.tr(),
|
||||
).then((confirm) {
|
||||
if (confirm) {
|
||||
final client = ref.read(apiClientProvider);
|
||||
client.delete(
|
||||
'/develop/developers/$publisherName/projects/$projectId/apps/${app.id}',
|
||||
);
|
||||
ref.invalidate(
|
||||
customAppsProvider(
|
||||
publisherName,
|
||||
projectId,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'delete',
|
||||
style: TextStyle(color: Colors.red),
|
||||
).tr(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
onSelected: (value) {
|
||||
if (value == 'edit') {
|
||||
context.pushNamed(
|
||||
'developerAppEdit',
|
||||
pathParameters: {
|
||||
'name': publisherName,
|
||||
'projectId': projectId,
|
||||
'id': app.id,
|
||||
},
|
||||
);
|
||||
} else if (value == 'delete') {
|
||||
showConfirmAlert(
|
||||
'deleteCustomAppHint'.tr(),
|
||||
'deleteCustomApp'.tr(),
|
||||
).then((confirm) {
|
||||
if (confirm) {
|
||||
final client = ref.read(apiClientProvider);
|
||||
client.delete(
|
||||
'/develop/developers/$publisherName/projects/$projectId/apps/${app.id}',
|
||||
);
|
||||
ref.invalidate(
|
||||
customAppsProvider(publisherName, projectId),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@@ -6,7 +6,7 @@ part of 'apps.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$customAppsHash() => r'450bedaf4220b8963cb44afeb14d4c0e80f01b11';
|
||||
String _$customAppHash() => r'be05431ba8bf06fd20ee988a61c3663a68e15fc9';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
@@ -29,6 +29,148 @@ class _SystemHash {
|
||||
}
|
||||
}
|
||||
|
||||
/// See also [customApp].
|
||||
@ProviderFor(customApp)
|
||||
const customAppProvider = CustomAppFamily();
|
||||
|
||||
/// See also [customApp].
|
||||
class CustomAppFamily extends Family<AsyncValue<CustomApp>> {
|
||||
/// See also [customApp].
|
||||
const CustomAppFamily();
|
||||
|
||||
/// See also [customApp].
|
||||
CustomAppProvider call(String publisherName, String projectId, String appId) {
|
||||
return CustomAppProvider(publisherName, projectId, appId);
|
||||
}
|
||||
|
||||
@override
|
||||
CustomAppProvider getProviderOverride(covariant CustomAppProvider provider) {
|
||||
return call(provider.publisherName, provider.projectId, provider.appId);
|
||||
}
|
||||
|
||||
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'customAppProvider';
|
||||
}
|
||||
|
||||
/// See also [customApp].
|
||||
class CustomAppProvider extends AutoDisposeFutureProvider<CustomApp> {
|
||||
/// See also [customApp].
|
||||
CustomAppProvider(String publisherName, String projectId, String appId)
|
||||
: this._internal(
|
||||
(ref) =>
|
||||
customApp(ref as CustomAppRef, publisherName, projectId, appId),
|
||||
from: customAppProvider,
|
||||
name: r'customAppProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$customAppHash,
|
||||
dependencies: CustomAppFamily._dependencies,
|
||||
allTransitiveDependencies: CustomAppFamily._allTransitiveDependencies,
|
||||
publisherName: publisherName,
|
||||
projectId: projectId,
|
||||
appId: appId,
|
||||
);
|
||||
|
||||
CustomAppProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.publisherName,
|
||||
required this.projectId,
|
||||
required this.appId,
|
||||
}) : super.internal();
|
||||
|
||||
final String publisherName;
|
||||
final String projectId;
|
||||
final String appId;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<CustomApp> Function(CustomAppRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: CustomAppProvider._internal(
|
||||
(ref) => create(ref as CustomAppRef),
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
publisherName: publisherName,
|
||||
projectId: projectId,
|
||||
appId: appId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<CustomApp> createElement() {
|
||||
return _CustomAppProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is CustomAppProvider &&
|
||||
other.publisherName == publisherName &&
|
||||
other.projectId == projectId &&
|
||||
other.appId == appId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, publisherName.hashCode);
|
||||
hash = _SystemHash.combine(hash, projectId.hashCode);
|
||||
hash = _SystemHash.combine(hash, appId.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin CustomAppRef on AutoDisposeFutureProviderRef<CustomApp> {
|
||||
/// The parameter `publisherName` of this provider.
|
||||
String get publisherName;
|
||||
|
||||
/// The parameter `projectId` of this provider.
|
||||
String get projectId;
|
||||
|
||||
/// The parameter `appId` of this provider.
|
||||
String get appId;
|
||||
}
|
||||
|
||||
class _CustomAppProviderElement
|
||||
extends AutoDisposeFutureProviderElement<CustomApp>
|
||||
with CustomAppRef {
|
||||
_CustomAppProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
String get publisherName => (origin as CustomAppProvider).publisherName;
|
||||
@override
|
||||
String get projectId => (origin as CustomAppProvider).projectId;
|
||||
@override
|
||||
String get appId => (origin as CustomAppProvider).appId;
|
||||
}
|
||||
|
||||
String _$customAppsHash() => r'450bedaf4220b8963cb44afeb14d4c0e80f01b11';
|
||||
|
||||
/// See also [customApps].
|
||||
@ProviderFor(customApps)
|
||||
const customAppsProvider = CustomAppsFamily();
|
||||
|
@@ -183,7 +183,7 @@ class ArticlesScreen extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@@ -6,7 +6,7 @@ part of 'articles.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$subscribedFeedsHash() => r'cd2f5d7d4ea49ad00dc731f8fc2ed65450a3f0e4';
|
||||
String _$subscribedFeedsHash() => r'5c0c8c30c5f543f6ea1d39786a6778f77ba5b3df';
|
||||
|
||||
/// See also [subscribedFeeds].
|
||||
@ProviderFor(subscribedFeeds)
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:island/screens/chat/chat.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:island/models/chat.dart';
|
||||
|
Reference in New Issue
Block a user