fix: improve app and patches loaders

This commit is contained in:
Alberto Ponces 2022-08-24 16:07:40 +01:00
parent 2a2a386bae
commit 56e85ca7cf
4 changed files with 97 additions and 147 deletions

View File

@ -36,18 +36,29 @@ class _AppSelectorViewState extends State<AppSelectorView> {
child: Padding( child: Padding(
padding: padding:
const EdgeInsets.symmetric(vertical: 4.0, horizontal: 12.0), const EdgeInsets.symmetric(vertical: 4.0, horizontal: 12.0),
child: model.apps.isNotEmpty child: model.noApps
? Column( ? Center(
child: I18nText('appSelectorCard.noAppsLabel'),
)
: model.apps.isEmpty
? Center(
child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
),
)
: Column(
children: [ children: [
SearchBar( SearchBar(
showSelectIcon: false, showSelectIcon: false,
fillColor: fillColor: isDark
isDark ? const Color(0xff1B222B) : Colors.grey[200], ? const Color(0xff1B222B)
: Colors.grey[200],
hintText: FlutterI18n.translate( hintText: FlutterI18n.translate(
context, context,
'appSelectorView.searchBarHint', 'appSelectorView.searchBarHint',
), ),
hintTextColor: Theme.of(context).colorScheme.tertiary, hintTextColor:
Theme.of(context).colorScheme.tertiary,
onQueryChanged: (searchQuery) { onQueryChanged: (searchQuery) {
setState(() { setState(() {
_query = searchQuery; _query = searchQuery;
@ -55,73 +66,29 @@ class _AppSelectorViewState extends State<AppSelectorView> {
}, },
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
_query.isEmpty || _query.length < 2 Expanded(
? _getAllResults(model) child: ListView(
: _getFilteredResults(model) children: model
.getFilteredApps(_query)
.map((app) => InkWell(
onTap: () {
model.selectApp(app);
Navigator.of(context).pop();
},
child: InstalledAppItem(
name: app.appName,
pkgName: app.packageName,
icon: app.icon,
),
))
.toList(),
),
),
], ],
)
: _query.isEmpty || _query.length < 2
? Center(
child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
),
)
: Center(
child: I18nText('appSelectorCard.noAppsLabel'),
), ),
), ),
), ),
), ),
); );
} }
Widget _getAllResults(AppSelectorViewModel model) {
return Expanded(
child: ListView.builder(
itemCount: model.apps.length,
itemBuilder: (context, index) {
model.apps.sort((a, b) => a.appName.compareTo(b.appName));
return InkWell(
onTap: () {
model.selectApp(model.apps[index]);
Navigator.of(context).pop();
},
child: InstalledAppItem(
name: model.apps[index].appName,
pkgName: model.apps[index].packageName,
icon: model.apps[index].icon,
),
);
},
),
);
}
Widget _getFilteredResults(AppSelectorViewModel model) {
return Expanded(
child: ListView.builder(
itemCount: model.apps.length,
itemBuilder: (context, index) {
model.apps.sort((a, b) => a.appName.compareTo(b.appName));
if (model.apps[index].appName.toLowerCase().contains(
_query.toLowerCase(),
)) {
return InkWell(
onTap: () {
model.selectApp(model.apps[index]);
Navigator.of(context).pop();
},
child: InstalledAppItem(
name: model.apps[index].appName,
pkgName: model.apps[index].packageName,
icon: model.apps[index].icon,
),
);
} else {
return const SizedBox();
}
},
),
);
}
} }

View File

@ -14,17 +14,20 @@ import 'package:stacked/stacked.dart';
class AppSelectorViewModel extends BaseViewModel { class AppSelectorViewModel extends BaseViewModel {
final PatcherAPI _patcherAPI = locator<PatcherAPI>(); final PatcherAPI _patcherAPI = locator<PatcherAPI>();
final List<ApplicationWithIcon> apps = []; final List<ApplicationWithIcon> apps = [];
bool noApps = false;
bool _isRooted = false; bool _isRooted = false;
Future<void> initialize() async { Future<void> initialize() async {
apps.addAll(await _patcherAPI.getFilteredInstalledApps()); apps.addAll(await _patcherAPI.getFilteredInstalledApps());
apps.sort((a, b) => a.appName.compareTo(b.appName));
noApps = apps.isEmpty;
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
_isRooted = prefs.getBool('isRooted') ?? false; _isRooted = prefs.getBool('isRooted') ?? false;
notifyListeners(); notifyListeners();
} }
void selectApp(ApplicationWithIcon application) async { void selectApp(ApplicationWithIcon application) async {
PatchedApplication app = PatchedApplication( locator<PatcherViewModel>().selectedApp = PatchedApplication(
name: application.appName, name: application.appName,
packageName: application.packageName, packageName: application.packageName,
version: application.versionName!, version: application.versionName!,
@ -35,7 +38,6 @@ class AppSelectorViewModel extends BaseViewModel {
isFromStorage: false, isFromStorage: false,
appliedPatches: [], appliedPatches: [],
); );
locator<PatcherViewModel>().selectedApp = app;
locator<PatcherViewModel>().selectedPatches.clear(); locator<PatcherViewModel>().selectedPatches.clear();
locator<PatcherViewModel>().notifyListeners(); locator<PatcherViewModel>().notifyListeners();
} }
@ -52,7 +54,7 @@ class AppSelectorViewModel extends BaseViewModel {
await DeviceApps.getAppFromStorage(apkFile.path, true) await DeviceApps.getAppFromStorage(apkFile.path, true)
as ApplicationWithIcon?; as ApplicationWithIcon?;
if (application != null) { if (application != null) {
PatchedApplication app = PatchedApplication( locator<PatcherViewModel>().selectedApp = PatchedApplication(
name: application.appName, name: application.appName,
packageName: application.packageName, packageName: application.packageName,
version: application.versionName!, version: application.versionName!,
@ -63,7 +65,6 @@ class AppSelectorViewModel extends BaseViewModel {
isFromStorage: true, isFromStorage: true,
appliedPatches: [], appliedPatches: [],
); );
locator<PatcherViewModel>().selectedApp = app;
locator<PatcherViewModel>().selectedPatches.clear(); locator<PatcherViewModel>().selectedPatches.clear();
locator<PatcherViewModel>().notifyListeners(); locator<PatcherViewModel>().notifyListeners();
} }
@ -79,4 +80,13 @@ class AppSelectorViewModel extends BaseViewModel {
); );
} }
} }
List<ApplicationWithIcon> getFilteredApps(String query) {
return apps
.where((app) =>
query.isEmpty ||
query.length < 2 ||
app.appName.toLowerCase().contains(query.toLowerCase()))
.toList();
}
} }

View File

@ -14,8 +14,7 @@ class PatchesSelectorView extends StatefulWidget {
} }
class _PatchesSelectorViewState extends State<PatchesSelectorView> { class _PatchesSelectorViewState extends State<PatchesSelectorView> {
final List<PatchItem> _items = []; String _query = '';
String query = '';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -27,8 +26,13 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
child: Padding( child: Padding(
padding: padding:
const EdgeInsets.symmetric(vertical: 4.0, horizontal: 12.0), const EdgeInsets.symmetric(vertical: 4.0, horizontal: 12.0),
child: model.patches.isNotEmpty child: model.patches.isEmpty
? Column( ? Center(
child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
),
)
: Column(
children: [ children: [
SearchBar( SearchBar(
showSelectIcon: true, showSelectIcon: true,
@ -41,15 +45,28 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
hintTextColor: Theme.of(context).colorScheme.tertiary, hintTextColor: Theme.of(context).colorScheme.tertiary,
onQueryChanged: (searchQuery) { onQueryChanged: (searchQuery) {
setState(() { setState(() {
query = searchQuery; _query = searchQuery;
}); });
}, },
onSelectAll: (value) => model.selectAllPatches(value), onSelectAll: (value) => model.selectAllPatches(value),
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
query.isEmpty || query.length < 2 Expanded(
? _getAllResults(model) child: ListView(
: _getFilteredResults(model), children: model
.getFilteredPatches(_query)
.map((patch) => PatchItem(
name: patch.name,
simpleName: patch.simpleName,
version: patch.version,
description: patch.description,
isSelected: model.isSelected(patch),
onChanged: (value) =>
model.selectPatch(patch, value),
))
.toList(),
),
),
MaterialButton( MaterialButton(
textColor: Colors.white, textColor: Colors.white,
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
@ -68,65 +85,10 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
child: I18nText('patchesSelectorView.doneButton'), child: I18nText('patchesSelectorView.doneButton'),
), ),
], ],
)
: Center(
child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
), ),
), ),
), ),
), ),
),
);
}
Widget _getAllResults(PatchesSelectorViewModel model) {
_items.clear();
return Expanded(
child: ListView.builder(
itemCount: model.patches.length,
itemBuilder: (context, index) {
model.patches.sort((a, b) => a.simpleName.compareTo(b.simpleName));
PatchItem item = PatchItem(
name: model.patches[index].name,
simpleName: model.patches[index].simpleName,
version: model.patches[index].version,
description: model.patches[index].description,
isSelected: model.isSelected(index),
onChanged: (value) => model.selectPatch(index, value),
);
_items.add(item);
return item;
},
),
);
}
Widget _getFilteredResults(PatchesSelectorViewModel model) {
_items.clear();
return Expanded(
child: ListView.builder(
itemCount: model.patches.length,
itemBuilder: (context, index) {
model.patches.sort((a, b) => a.simpleName.compareTo(b.simpleName));
if (model.patches[index].simpleName.toLowerCase().contains(
query.toLowerCase(),
)) {
PatchItem item = PatchItem(
name: model.patches[index].name,
simpleName: model.patches[index].simpleName,
version: model.patches[index].version,
description: model.patches[index].description,
isSelected: model.isSelected(index),
onChanged: (value) => model.selectPatch(index, value),
);
_items.add(item);
return item;
} else {
return const SizedBox();
}
},
),
); );
} }
} }

View File

@ -14,6 +14,7 @@ class PatchesSelectorViewModel extends BaseViewModel {
patches.addAll(await _patcherAPI.getFilteredPatches( patches.addAll(await _patcherAPI.getFilteredPatches(
locator<PatcherViewModel>().selectedApp, locator<PatcherViewModel>().selectedApp,
)); ));
patches.sort((a, b) => a.simpleName.compareTo(b.simpleName));
for (Patch p in patches) { for (Patch p in patches) {
if (p.include) { if (p.include) {
selectedPatches.add(p); selectedPatches.add(p);
@ -22,14 +23,13 @@ class PatchesSelectorViewModel extends BaseViewModel {
notifyListeners(); notifyListeners();
} }
bool isSelected(int index) { bool isSelected(Patch patch) {
return selectedPatches.any( return selectedPatches.any(
(element) => element.name == patches[index].name, (element) => element.name == patch.name,
); );
} }
void selectPatch(int index, bool isSelected) { void selectPatch(Patch patch, bool isSelected) {
Patch patch = patches.firstWhere((p) => p.name == patches[index].name);
if (isSelected && !selectedPatches.contains(patch)) { if (isSelected && !selectedPatches.contains(patch)) {
selectedPatches.add(patch); selectedPatches.add(patch);
} else { } else {
@ -50,4 +50,15 @@ class PatchesSelectorViewModel extends BaseViewModel {
locator<PatcherViewModel>().selectedPatches = selectedPatches; locator<PatcherViewModel>().selectedPatches = selectedPatches;
locator<PatcherViewModel>().notifyListeners(); locator<PatcherViewModel>().notifyListeners();
} }
List<Patch> getFilteredPatches(String query) {
return patches
.where((patch) =>
query.isEmpty ||
query.length < 2 ||
patch.simpleName.toLowerCase().contains(
query.toLowerCase(),
))
.toList();
}
} }