refactor(dart): rename store provider and screen folder to repo

store_provider.dart -> repo_provider.dart, screens/store/ ->
screens/repo/; Store* classes and storeProvider renamed to Repo*.
Method-channel names in platform_bridge stay unchanged (bridge ABI
matching the Kotlin handler).
This commit is contained in:
zarzet
2026-07-14 09:09:22 +07:00
parent fd4348b803
commit 86d5ae3a2b
5 changed files with 84 additions and 84 deletions
@@ -26,7 +26,7 @@ int compareVersions(String v1, String v2) {
return 0;
}
class StoreCategory {
class RepoCategory {
static const String metadata = 'metadata';
static const String download = 'download';
static const String utility = 'utility';
@@ -59,7 +59,7 @@ class StoreCategory {
}
}
class StoreExtension {
class RepoExtension {
final String id;
final String name;
final String displayName;
@@ -76,7 +76,7 @@ class StoreExtension {
final String? installedVersion;
final bool hasUpdate;
const StoreExtension({
const RepoExtension({
required this.id,
required this.name,
required this.displayName,
@@ -94,8 +94,8 @@ class StoreExtension {
this.hasUpdate = false,
});
factory StoreExtension.fromJson(Map<String, dynamic> json) {
return StoreExtension(
factory RepoExtension.fromJson(Map<String, dynamic> json) {
return RepoExtension(
id: json['id'] as String? ?? '',
name: json['name'] as String? ?? '',
displayName:
@@ -121,8 +121,8 @@ class StoreExtension {
}
}
class StoreState {
final List<StoreExtension> extensions;
class RepoState {
final List<RepoExtension> extensions;
final String? selectedCategory;
final String searchQuery;
final bool isLoading;
@@ -132,7 +132,7 @@ class StoreState {
final bool isInitialized;
final String registryUrl;
const StoreState({
const RepoState({
this.extensions = const [],
this.selectedCategory,
this.searchQuery = '',
@@ -146,8 +146,8 @@ class StoreState {
bool get hasRegistryUrl => registryUrl.isNotEmpty;
StoreState copyWith({
List<StoreExtension>? extensions,
RepoState copyWith({
List<RepoExtension>? extensions,
String? selectedCategory,
bool clearCategory = false,
String? searchQuery,
@@ -160,7 +160,7 @@ class StoreState {
bool? isInitialized,
String? registryUrl,
}) {
return StoreState(
return RepoState(
extensions: extensions ?? this.extensions,
selectedCategory: clearCategory
? null
@@ -177,7 +177,7 @@ class StoreState {
);
}
List<StoreExtension> get filteredExtensions {
List<RepoExtension> get filteredExtensions {
var result = extensions;
if (selectedCategory != null) {
@@ -205,7 +205,7 @@ class StoreState {
}
}
class StoreNotifier extends Notifier<StoreState> {
class RepoNotifier extends Notifier<RepoState> {
/// Serializes install/upgrade so two never race the native VM teardown/reload.
Future<void> _mutationChain = Future<void>.value();
@@ -222,8 +222,8 @@ class StoreNotifier extends Notifier<StoreState> {
}
@override
StoreState build() {
return const StoreState();
RepoState build() {
return const RepoState();
}
Future<void> initialize(String cacheDir) async {
@@ -282,7 +282,7 @@ class StoreNotifier extends Notifier<StoreState> {
state = state.copyWith(
registryUrl: resolvedUrl,
extensions: extensions.map((e) => StoreExtension.fromJson(e)).toList(),
extensions: extensions.map((e) => RepoExtension.fromJson(e)).toList(),
isLoading: false,
);
@@ -332,7 +332,7 @@ class StoreNotifier extends Notifier<StoreState> {
forceRefresh: forceRefresh,
);
state = state.copyWith(
extensions: extensions.map((e) => StoreExtension.fromJson(e)).toList(),
extensions: extensions.map((e) => RepoExtension.fromJson(e)).toList(),
isLoading: false,
);
_log.d('Loaded ${state.extensions.length} extensions from store');
@@ -458,6 +458,6 @@ class StoreNotifier extends Notifier<StoreState> {
}
}
final storeProvider = NotifierProvider<StoreNotifier, StoreState>(
StoreNotifier.new,
final repoProvider = NotifierProvider<RepoNotifier, RepoState>(
RepoNotifier.new,
);
+2 -2
View File
@@ -9,7 +9,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/providers/download_queue_provider.dart';
import 'package:spotiflac_android/providers/settings_provider.dart';
import 'package:spotiflac_android/providers/store_provider.dart';
import 'package:spotiflac_android/providers/repo_provider.dart';
import 'package:spotiflac_android/providers/track_provider.dart';
import 'package:spotiflac_android/providers/preview_player_provider.dart';
import 'package:spotiflac_android/screens/home_tab.dart';
@@ -487,7 +487,7 @@ class _MainShellState extends ConsumerState<MainShell>
showRepoTab: showStore,
);
final repoUpdatesCount = ref.watch(
storeProvider.select((s) => s.updatesAvailableCount),
repoProvider.select((s) => s.updatesAvailableCount),
);
final tabs = <Widget>[
@@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:path_provider/path_provider.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/providers/store_provider.dart';
import 'package:spotiflac_android/providers/repo_provider.dart';
import 'package:spotiflac_android/providers/extension_provider.dart';
import 'package:spotiflac_android/utils/nav_bar_inset.dart';
class ExtensionDetailsScreen extends ConsumerStatefulWidget {
final StoreExtension extension;
final RepoExtension extension;
const ExtensionDetailsScreen({super.key, required this.extension});
@@ -20,7 +20,7 @@ class _ExtensionDetailsScreenState
extends ConsumerState<ExtensionDetailsScreen> {
@override
Widget build(BuildContext context) {
final storeState = ref.watch(storeProvider);
final storeState = ref.watch(repoProvider);
final liveExtension =
storeState.extensions
@@ -80,7 +80,7 @@ class _ExtensionDetailsScreenState
Widget _buildAppBar(
BuildContext context,
StoreExtension ext,
RepoExtension ext,
ColorScheme colorScheme,
) {
return SliverAppBar(
@@ -131,7 +131,7 @@ class _ExtensionDetailsScreenState
}
Widget _buildFallbackIcon(
StoreExtension ext,
RepoExtension ext,
ColorScheme colorScheme,
double size,
) {
@@ -147,7 +147,7 @@ class _ExtensionDetailsScreenState
Widget _buildInfoCard(
BuildContext context,
StoreExtension ext,
RepoExtension ext,
ColorScheme colorScheme,
bool isDownloading,
) {
@@ -315,7 +315,7 @@ class _ExtensionDetailsScreenState
Widget _buildDescription(
BuildContext context,
StoreExtension ext,
RepoExtension ext,
ColorScheme colorScheme,
) {
return SliverToBoxAdapter(
@@ -334,7 +334,7 @@ class _ExtensionDetailsScreenState
Widget _buildTags(
BuildContext context,
StoreExtension ext,
RepoExtension ext,
ColorScheme colorScheme,
) {
return SliverToBoxAdapter(
@@ -365,7 +365,7 @@ class _ExtensionDetailsScreenState
Widget _buildMetadataTable(
BuildContext context,
StoreExtension ext,
RepoExtension ext,
ColorScheme colorScheme,
) {
return SliverPadding(
@@ -406,7 +406,7 @@ class _ExtensionDetailsScreenState
Widget _buildCapabilities(
BuildContext context,
StoreExtension ext,
RepoExtension ext,
ColorScheme colorScheme,
) {
final isMetadataProvider =
@@ -516,13 +516,13 @@ class _ExtensionDetailsScreenState
}
}
Future<void> _installExtension(StoreExtension ext) async {
Future<void> _installExtension(RepoExtension ext) async {
final tempDir = await getTemporaryDirectory();
final appDir = await getApplicationDocumentsDirectory();
final extensionsDir = '${appDir.path}/extensions';
final success = await ref
.read(storeProvider.notifier)
.read(repoProvider.notifier)
.installExtension(ext.id, tempDir.path, extensionsDir);
if (mounted) {
@@ -539,11 +539,11 @@ class _ExtensionDetailsScreenState
}
}
Future<void> _updateExtension(StoreExtension ext) async {
Future<void> _updateExtension(RepoExtension ext) async {
final tempDir = await getTemporaryDirectory();
final success = await ref
.read(storeProvider.notifier)
.read(repoProvider.notifier)
.updateExtension(ext.id, tempDir.path);
if (mounted) {
@@ -560,7 +560,7 @@ class _ExtensionDetailsScreenState
}
}
Future<void> _uninstallExtension(StoreExtension ext) async {
Future<void> _uninstallExtension(RepoExtension ext) async {
final confirm = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
@@ -586,7 +586,7 @@ class _ExtensionDetailsScreenState
if (confirm == true) {
await ref.read(extensionProvider.notifier).removeExtension(ext.id);
await ref.read(storeProvider.notifier).refresh();
await ref.read(repoProvider.notifier).refresh();
if (mounted) {
Navigator.pop(context);
}
+45 -45
View File
@@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:path_provider/path_provider.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/providers/store_provider.dart';
import 'package:spotiflac_android/providers/repo_provider.dart';
import 'package:spotiflac_android/widgets/settings_group.dart';
import 'package:spotiflac_android/widgets/animation_utils.dart';
import 'package:spotiflac_android/screens/store/extension_details_screen.dart';
import 'package:spotiflac_android/screens/repo/extension_details_screen.dart';
import 'package:spotiflac_android/utils/app_bar_layout.dart';
import 'package:spotiflac_android/utils/nav_bar_inset.dart';
@@ -35,7 +35,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
if (!mounted) return;
await ref.read(storeProvider.notifier).initialize(cacheDir.path);
await ref.read(repoProvider.notifier).initialize(cacheDir.path);
}
@override
@@ -48,23 +48,23 @@ class _RepoTabState extends ConsumerState<RepoTab> {
@override
Widget build(BuildContext context) {
final storeFilterState = ref.watch(
storeProvider.select(
repoProvider.select(
(s) => (s.extensions, s.selectedCategory, s.searchQuery),
),
);
final extensions = storeFilterState.$1;
final selectedCategory = storeFilterState.$2;
final searchQuery = storeFilterState.$3;
final isLoading = ref.watch(storeProvider.select((s) => s.isLoading));
final error = ref.watch(storeProvider.select((s) => s.error));
final isLoading = ref.watch(repoProvider.select((s) => s.isLoading));
final error = ref.watch(repoProvider.select((s) => s.error));
final downloadingId = ref.watch(
storeProvider.select((s) => s.downloadingId),
repoProvider.select((s) => s.downloadingId),
);
final hasRegistryUrl = ref.watch(
storeProvider.select((s) => s.hasRegistryUrl),
repoProvider.select((s) => s.hasRegistryUrl),
);
final registryUrl = ref.watch(storeProvider.select((s) => s.registryUrl));
final filteredExtensions = StoreState(
final registryUrl = ref.watch(repoProvider.select((s) => s.registryUrl));
final filteredExtensions = RepoState(
extensions: extensions,
selectedCategory: selectedCategory,
searchQuery: searchQuery,
@@ -82,7 +82,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
return Scaffold(
body: RefreshIndicator(
onRefresh: () =>
ref.read(storeProvider.notifier).refresh(forceRefresh: true),
ref.read(repoProvider.notifier).refresh(forceRefresh: true),
child: CustomScrollView(
slivers: [
SliverAppBar(
@@ -149,7 +149,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
onPressed: () {
_searchController.clear();
ref
.read(storeProvider.notifier)
.read(repoProvider.notifier)
.setSearchQuery('');
},
)
@@ -182,7 +182,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
),
onChanged: (value) {
ref
.read(storeProvider.notifier)
.read(repoProvider.notifier)
.setSearchQuery(value);
},
onTapOutside: (_) {
@@ -208,53 +208,53 @@ class _RepoTabState extends ConsumerState<RepoTab> {
icon: Icons.apps,
isSelected: selectedCategory == null,
onTap: () =>
ref.read(storeProvider.notifier).setCategory(null),
ref.read(repoProvider.notifier).setCategory(null),
),
const SizedBox(width: 8),
_CategoryChip(
label: context.l10n.storeFilterMetadata,
icon: Icons.label_outline,
isSelected: selectedCategory == StoreCategory.metadata,
isSelected: selectedCategory == RepoCategory.metadata,
onTap: () => ref
.read(storeProvider.notifier)
.setCategory(StoreCategory.metadata),
.read(repoProvider.notifier)
.setCategory(RepoCategory.metadata),
),
const SizedBox(width: 8),
_CategoryChip(
label: context.l10n.storeFilterDownload,
icon: Icons.download_outlined,
isSelected: selectedCategory == StoreCategory.download,
isSelected: selectedCategory == RepoCategory.download,
onTap: () => ref
.read(storeProvider.notifier)
.setCategory(StoreCategory.download),
.read(repoProvider.notifier)
.setCategory(RepoCategory.download),
),
const SizedBox(width: 8),
_CategoryChip(
label: context.l10n.storeFilterUtility,
icon: Icons.build_outlined,
isSelected: selectedCategory == StoreCategory.utility,
isSelected: selectedCategory == RepoCategory.utility,
onTap: () => ref
.read(storeProvider.notifier)
.setCategory(StoreCategory.utility),
.read(repoProvider.notifier)
.setCategory(RepoCategory.utility),
),
const SizedBox(width: 8),
_CategoryChip(
label: context.l10n.storeFilterLyrics,
icon: Icons.lyrics_outlined,
isSelected: selectedCategory == StoreCategory.lyrics,
isSelected: selectedCategory == RepoCategory.lyrics,
onTap: () => ref
.read(storeProvider.notifier)
.setCategory(StoreCategory.lyrics),
.read(repoProvider.notifier)
.setCategory(RepoCategory.lyrics),
),
const SizedBox(width: 8),
_CategoryChip(
label: context.l10n.storeFilterIntegration,
icon: Icons.link,
isSelected:
selectedCategory == StoreCategory.integration,
selectedCategory == RepoCategory.integration,
onTap: () => ref
.read(storeProvider.notifier)
.setCategory(StoreCategory.integration),
.read(repoProvider.notifier)
.setCategory(RepoCategory.integration),
),
],
),
@@ -416,7 +416,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
void _submitRepoUrl() {
final url = _repoUrlController.text.trim();
if (url.isEmpty) return;
ref.read(storeProvider.notifier).setRegistryUrl(url);
ref.read(repoProvider.notifier).setRegistryUrl(url);
}
void _showChangeRepoDialog(String currentUrl) {
@@ -489,7 +489,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
TextButton(
onPressed: () {
Navigator.of(context).pop();
ref.read(storeProvider.notifier).removeRegistryUrl();
ref.read(repoProvider.notifier).removeRegistryUrl();
},
style: TextButton.styleFrom(
foregroundColor: Theme.of(context).colorScheme.error,
@@ -505,7 +505,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
final newUrl = changeUrlController.text.trim();
Navigator.of(context).pop();
if (newUrl.isNotEmpty) {
ref.read(storeProvider.notifier).setRegistryUrl(newUrl);
ref.read(repoProvider.notifier).setRegistryUrl(newUrl);
}
},
child: Text(context.l10n.dialogSave),
@@ -539,7 +539,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
const SizedBox(height: 24),
FilledButton.icon(
onPressed: () =>
ref.read(storeProvider.notifier).refresh(forceRefresh: true),
ref.read(repoProvider.notifier).refresh(forceRefresh: true),
icon: const Icon(Icons.refresh),
label: Text(context.l10n.dialogRetry),
),
@@ -576,7 +576,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
TextButton(
onPressed: () {
_searchController.clear();
ref.read(storeProvider.notifier).clearSearch();
ref.read(repoProvider.notifier).clearSearch();
},
child: Text(context.l10n.storeClearFilters),
),
@@ -586,7 +586,7 @@ class _RepoTabState extends ConsumerState<RepoTab> {
);
}
void _showExtensionDetails(StoreExtension ext) {
void _showExtensionDetails(RepoExtension ext) {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (context) => ExtensionDetailsScreen(extension: ext),
@@ -594,13 +594,13 @@ class _RepoTabState extends ConsumerState<RepoTab> {
);
}
Future<void> _installExtension(StoreExtension ext) async {
Future<void> _installExtension(RepoExtension ext) async {
final tempDir = await getTemporaryDirectory();
final appDir = await getApplicationDocumentsDirectory();
final extensionsDir = '${appDir.path}/extensions';
final success = await ref
.read(storeProvider.notifier)
.read(repoProvider.notifier)
.installExtension(ext.id, tempDir.path, extensionsDir);
if (mounted) {
@@ -617,11 +617,11 @@ class _RepoTabState extends ConsumerState<RepoTab> {
}
}
Future<void> _updateExtension(StoreExtension ext) async {
Future<void> _updateExtension(RepoExtension ext) async {
final tempDir = await getTemporaryDirectory();
final success = await ref
.read(storeProvider.notifier)
.read(repoProvider.notifier)
.updateExtension(ext.id, tempDir.path);
if (mounted) {
@@ -673,7 +673,7 @@ class _CategoryChip extends StatelessWidget {
}
class _ExtensionItem extends StatelessWidget {
final StoreExtension extension;
final RepoExtension extension;
final bool showDivider;
final bool isDownloading;
final VoidCallback onInstall;
@@ -691,15 +691,15 @@ class _ExtensionItem extends StatelessWidget {
IconData _getCategoryIcon(String category) {
switch (category) {
case StoreCategory.metadata:
case RepoCategory.metadata:
return Icons.label_outline;
case StoreCategory.download:
case RepoCategory.download:
return Icons.download_outlined;
case StoreCategory.utility:
case RepoCategory.utility:
return Icons.build_outlined;
case StoreCategory.lyrics:
case RepoCategory.lyrics:
return Icons.lyrics_outlined;
case StoreCategory.integration:
case RepoCategory.integration:
return Icons.link;
default:
return Icons.extension;
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/providers/extension_provider.dart';
import 'package:spotiflac_android/providers/store_provider.dart';
import 'package:spotiflac_android/providers/repo_provider.dart';
import 'package:spotiflac_android/services/platform_bridge.dart';
import 'package:spotiflac_android/utils/extension_auth_launcher.dart';
import 'package:spotiflac_android/widgets/settings_group.dart';
@@ -513,7 +513,7 @@ class _ExtensionDetailPageState extends ConsumerState<ExtensionDetailPage> {
.read(extensionProvider.notifier)
.removeExtension(widget.extensionId);
if (success && mounted) {
ref.read(storeProvider.notifier).refresh();
ref.read(repoProvider.notifier).refresh();
Navigator.pop(this.context);
}
}