mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2024-11-10 01:01:56 +01:00
feat: CustomScrollView in app and patches selector views (#208)
This commit is contained in:
parent
9bdccb3c9d
commit
2b7287c04c
4 changed files with 190 additions and 169 deletions
|
@ -66,11 +66,13 @@
|
|||
"widgetSubtitle": "We are online!"
|
||||
},
|
||||
"appSelectorView": {
|
||||
"viewTitle": "Select application",
|
||||
"searchBarHint": "Search applications",
|
||||
"storageButton": "Storage",
|
||||
"errorMessage": "Unable to use selected application."
|
||||
},
|
||||
"patchesSelectorView": {
|
||||
"viewTitle": "Select patches",
|
||||
"searchBarHint": "Search patches",
|
||||
"doneButton": "Done",
|
||||
"noPatchesFound": "No patches found for the selected app."
|
||||
|
|
|
@ -31,53 +31,62 @@ class _AppSelectorViewState extends State<AppSelectorView> {
|
|||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 4.0, horizontal: 12.0),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SearchBar(
|
||||
showSelectIcon: false,
|
||||
hintText: FlutterI18n.translate(
|
||||
context,
|
||||
'appSelectorView.searchBarHint',
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
floating: true,
|
||||
snap: false,
|
||||
title: I18nText('appSelectorView.viewTitle'),
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(64.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0, horizontal: 12.0),
|
||||
child: SearchBar(
|
||||
showSelectIcon: false,
|
||||
hintText: FlutterI18n.translate(
|
||||
context,
|
||||
'appSelectorView.searchBarHint',
|
||||
),
|
||||
onQueryChanged: (searchQuery) {
|
||||
setState(() {
|
||||
_query = searchQuery;
|
||||
});
|
||||
},
|
||||
),
|
||||
onQueryChanged: (searchQuery) {
|
||||
setState(() {
|
||||
_query = searchQuery;
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Expanded(
|
||||
child: model.noApps
|
||||
? Center(
|
||||
child: I18nText('appSelectorCard.noAppsLabel'),
|
||||
)
|
||||
: model.apps.isEmpty
|
||||
? const AppSkeletonLoader()
|
||||
: ListView(
|
||||
padding: const EdgeInsets.only(bottom: 80),
|
||||
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(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: model.noApps
|
||||
? Center(
|
||||
child: I18nText('appSelectorCard.noAppsLabel'),
|
||||
)
|
||||
: model.apps.isEmpty
|
||||
? const AppSkeletonLoader()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 80).add(
|
||||
const EdgeInsets.symmetric(horizontal: 12.0)),
|
||||
child: Column(
|
||||
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(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -33,144 +33,153 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
|
|||
},
|
||||
),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 4.0, horizontal: 12.0),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
SearchBar(
|
||||
showSelectIcon: true,
|
||||
hintText: FlutterI18n.translate(
|
||||
context,
|
||||
'patchesSelectorView.searchBarHint',
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
floating: true,
|
||||
snap: false,
|
||||
title: I18nText('patchesSelectorView.viewTitle'),
|
||||
bottom: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(64.0),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8.0, horizontal: 12.0),
|
||||
child: SearchBar(
|
||||
showSelectIcon: true,
|
||||
hintText: FlutterI18n.translate(
|
||||
context,
|
||||
'patchesSelectorView.searchBarHint',
|
||||
),
|
||||
onQueryChanged: (searchQuery) {
|
||||
setState(() {
|
||||
_query = searchQuery;
|
||||
});
|
||||
},
|
||||
onSelectAll: (value) => model.selectAllPatches(value),
|
||||
),
|
||||
onQueryChanged: (searchQuery) {
|
||||
setState(() {
|
||||
_query = searchQuery;
|
||||
});
|
||||
},
|
||||
onSelectAll: (value) => model.selectAllPatches(value),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Expanded(
|
||||
child: model.patches.isEmpty
|
||||
? Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: I18nText(
|
||||
'patchesSelectorView.noPatchesFound',
|
||||
child: Text(
|
||||
'',
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: model.patches.isEmpty
|
||||
? Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
child: I18nText(
|
||||
'patchesSelectorView.noPatchesFound',
|
||||
child: Text(
|
||||
'',
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
)
|
||||
: ListView(
|
||||
padding: const EdgeInsets.only(bottom: 80),
|
||||
children: model
|
||||
.getQueriedPatches(_query)
|
||||
.map(
|
||||
(patch) => PatchItem(
|
||||
name: patch.name,
|
||||
simpleName: patch.getSimpleName(),
|
||||
version: patch.version,
|
||||
description: patch.description,
|
||||
packageVersion: model.getAppVersion(),
|
||||
supportedPackageVersions:
|
||||
model.getSupportedVersions(patch),
|
||||
isUnsupported: !model.isPatchSupported(patch),
|
||||
isSelected: model.isSelected(patch),
|
||||
onChanged: (value) =>
|
||||
model.selectPatch(patch, value),
|
||||
),
|
||||
/* TODO: Enable this and make use of new Patch Options implementation
|
||||
patch.hasOptions ? ExpandablePanel(
|
||||
controller: expController,
|
||||
theme: const ExpandableThemeData(
|
||||
hasIcon: false,
|
||||
tapBodyToExpand: true,
|
||||
tapBodyToCollapse: true,
|
||||
tapHeaderToExpand: true,
|
||||
),
|
||||
header: Column(
|
||||
children: <Widget>[
|
||||
GestureDetector(
|
||||
onLongPress: () =>
|
||||
expController.toggle(),
|
||||
child: PatchItem(
|
||||
name: patch.name,
|
||||
simpleName: patch.getSimpleName(),
|
||||
description: patch.description,
|
||||
version: patch.version,
|
||||
packageVersion:
|
||||
model.getAppVersion(),
|
||||
supportedPackageVersions: model
|
||||
.getSupportedVersions(patch),
|
||||
isUnsupported: !model
|
||||
.isPatchSupported(patch),
|
||||
isSelected:
|
||||
model.isSelected(patch),
|
||||
onChanged: (value) => model
|
||||
.selectPatch(patch, value),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
),
|
||||
child: Text(
|
||||
'Long press for additional options.',
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 80)
|
||||
.add(const EdgeInsets.symmetric(horizontal: 12.0)),
|
||||
child: Column(
|
||||
children: model
|
||||
.getQueriedPatches(_query)
|
||||
.map(
|
||||
(patch) => PatchItem(
|
||||
name: patch.name,
|
||||
simpleName: patch.getSimpleName(),
|
||||
version: patch.version,
|
||||
description: patch.description,
|
||||
packageVersion: model.getAppVersion(),
|
||||
supportedPackageVersions:
|
||||
model.getSupportedVersions(patch),
|
||||
isUnsupported: !model.isPatchSupported(patch),
|
||||
isSelected: model.isSelected(patch),
|
||||
onChanged: (value) =>
|
||||
model.selectPatch(patch, value),
|
||||
),
|
||||
/* TODO: Enable this and make use of new Patch Options implementation
|
||||
patch.hasOptions ? ExpandablePanel(
|
||||
controller: expController,
|
||||
theme: const ExpandableThemeData(
|
||||
hasIcon: false,
|
||||
tapBodyToExpand: true,
|
||||
tapBodyToCollapse: true,
|
||||
tapHeaderToExpand: true,
|
||||
),
|
||||
header: Column(
|
||||
children: <Widget>[
|
||||
GestureDetector(
|
||||
onLongPress: () =>
|
||||
expController.toggle(),
|
||||
child: PatchItem(
|
||||
name: patch.name,
|
||||
simpleName: patch.getSimpleName(),
|
||||
description: patch.description,
|
||||
version: patch.version,
|
||||
packageVersion:
|
||||
model.getAppVersion(),
|
||||
supportedPackageVersions: model
|
||||
.getSupportedVersions(patch),
|
||||
isUnsupported: !model
|
||||
.isPatchSupported(patch),
|
||||
isSelected:
|
||||
model.isSelected(patch),
|
||||
onChanged: (value) => model
|
||||
.selectPatch(patch, value),
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
),
|
||||
child: Text(
|
||||
'Long press for additional options.',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
expanded: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10.0,
|
||||
horizontal: 10,
|
||||
),
|
||||
expanded: Padding(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10.0,
|
||||
horizontal: 10,
|
||||
vertical: 8,
|
||||
horizontal: 8,
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
horizontal: 8,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.tertiary
|
||||
.withOpacity(0.1),
|
||||
borderRadius:
|
||||
BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'Patch options',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.tertiary
|
||||
.withOpacity(0.1),
|
||||
borderRadius:
|
||||
BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'Patch options',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
const OptionsTextField(
|
||||
hint: 'App name'),
|
||||
const OptionsFilePicker(
|
||||
optionName: 'Choose a logo',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const OptionsTextField(
|
||||
hint: 'App name'),
|
||||
const OptionsFilePicker(
|
||||
optionName: 'Choose a logo',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
collapsed: Container(),
|
||||
) */
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
collapsed: Container(),
|
||||
) */
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -10,6 +10,7 @@ class AppSkeletonLoader extends StatelessWidget {
|
|||
return Skeleton(
|
||||
isLoading: true,
|
||||
skeleton: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: 7,
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8.0),
|
||||
|
|
Loading…
Reference in a new issue