mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-08-11 17:40:15 +02:00
Apps bottom bar tweaks (#216)
This commit is contained in:
@@ -348,8 +348,9 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
selectedApps.isEmpty
|
selectedApps.isEmpty
|
||||||
? IconButton(
|
? TextButton.icon(
|
||||||
visualDensity: VisualDensity.compact,
|
style:
|
||||||
|
const ButtonStyle(visualDensity: VisualDensity.compact),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
selectThese(sortedApps.map((e) => e.app).toList());
|
selectThese(sortedApps.map((e) => e.app).toList());
|
||||||
},
|
},
|
||||||
@@ -357,7 +358,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
Icons.select_all_outlined,
|
Icons.select_all_outlined,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
tooltip: tr('selectAll'))
|
label: Text(sortedApps.length.toString()))
|
||||||
: TextButton.icon(
|
: TextButton.icon(
|
||||||
style:
|
style:
|
||||||
const ButtonStyle(visualDensity: VisualDensity.compact),
|
const ButtonStyle(visualDensity: VisualDensity.compact),
|
||||||
@@ -375,376 +376,415 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
label: Text(selectedApps.length.toString())),
|
label: Text(selectedApps.length.toString())),
|
||||||
const VerticalDivider(),
|
const VerticalDivider(),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: SingleChildScrollView(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
scrollDirection: Axis.horizontal,
|
||||||
children: [
|
child: Row(
|
||||||
selectedApps.isEmpty
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
? const SizedBox()
|
children: [
|
||||||
: IconButton(
|
IconButton(
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
onPressed: () {
|
onPressed: selectedApps.isEmpty
|
||||||
showDialog<Map<String, dynamic>?>(
|
? null
|
||||||
context: context,
|
: () {
|
||||||
builder: (BuildContext ctx) {
|
showDialog<Map<String, dynamic>?>(
|
||||||
return GeneratedFormModal(
|
|
||||||
title: tr('removeSelectedAppsQuestion'),
|
|
||||||
items: const [],
|
|
||||||
initValid: true,
|
|
||||||
message: tr(
|
|
||||||
'xWillBeRemovedButRemainInstalled',
|
|
||||||
args: [
|
|
||||||
plural('apps', selectedApps.length)
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}).then((values) {
|
|
||||||
if (values != null) {
|
|
||||||
appsProvider.removeApps(
|
|
||||||
selectedApps.map((e) => e.id).toList());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
tooltip: tr('removeSelectedApps'),
|
|
||||||
icon: const Icon(Icons.delete_outline_outlined),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
onPressed: appsProvider.areDownloadsRunning() ||
|
|
||||||
(existingUpdateIdsAllOrSelected.isEmpty &&
|
|
||||||
newInstallIdsAllOrSelected.isEmpty &&
|
|
||||||
trackOnlyUpdateIdsAllOrSelected.isEmpty)
|
|
||||||
? null
|
|
||||||
: () {
|
|
||||||
HapticFeedback.heavyImpact();
|
|
||||||
List<GeneratedFormItem> formItems = [];
|
|
||||||
if (existingUpdateIdsAllOrSelected.isNotEmpty) {
|
|
||||||
formItems.add(GeneratedFormSwitch('updates',
|
|
||||||
label: tr('updateX', args: [
|
|
||||||
plural('apps',
|
|
||||||
existingUpdateIdsAllOrSelected.length)
|
|
||||||
]),
|
|
||||||
defaultValue: true));
|
|
||||||
}
|
|
||||||
if (newInstallIdsAllOrSelected.isNotEmpty) {
|
|
||||||
formItems.add(GeneratedFormSwitch('installs',
|
|
||||||
label: tr('installX', args: [
|
|
||||||
plural('apps',
|
|
||||||
newInstallIdsAllOrSelected.length)
|
|
||||||
]),
|
|
||||||
defaultValue: existingUpdateIdsAllOrSelected
|
|
||||||
.isNotEmpty));
|
|
||||||
}
|
|
||||||
if (trackOnlyUpdateIdsAllOrSelected.isNotEmpty) {
|
|
||||||
formItems.add(GeneratedFormSwitch('trackonlies',
|
|
||||||
label: tr('markXTrackOnlyAsUpdated', args: [
|
|
||||||
plural('apps',
|
|
||||||
trackOnlyUpdateIdsAllOrSelected.length)
|
|
||||||
]),
|
|
||||||
defaultValue: existingUpdateIdsAllOrSelected
|
|
||||||
.isNotEmpty ||
|
|
||||||
newInstallIdsAllOrSelected.isNotEmpty));
|
|
||||||
}
|
|
||||||
showDialog<Map<String, dynamic>?>(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext ctx) {
|
|
||||||
var totalApps = existingUpdateIdsAllOrSelected
|
|
||||||
.length +
|
|
||||||
newInstallIdsAllOrSelected.length +
|
|
||||||
trackOnlyUpdateIdsAllOrSelected.length;
|
|
||||||
return GeneratedFormModal(
|
|
||||||
title: tr('changeX',
|
|
||||||
args: [plural('apps', totalApps)]),
|
|
||||||
items: formItems.map((e) => [e]).toList(),
|
|
||||||
initValid: true,
|
|
||||||
);
|
|
||||||
}).then((values) {
|
|
||||||
if (values != null) {
|
|
||||||
if (values.isEmpty) {
|
|
||||||
values = getDefaultValuesFromFormItems(
|
|
||||||
[formItems]);
|
|
||||||
}
|
|
||||||
bool shouldInstallUpdates =
|
|
||||||
values['updates'] == true;
|
|
||||||
bool shouldInstallNew =
|
|
||||||
values['installs'] == true;
|
|
||||||
bool shouldMarkTrackOnlies =
|
|
||||||
values['trackonlies'] == true;
|
|
||||||
(() async {
|
|
||||||
if (shouldInstallNew ||
|
|
||||||
shouldInstallUpdates) {
|
|
||||||
await settingsProvider
|
|
||||||
.getInstallPermission();
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
.then((_) {
|
|
||||||
List<String> toInstall = [];
|
|
||||||
if (shouldInstallUpdates) {
|
|
||||||
toInstall
|
|
||||||
.addAll(existingUpdateIdsAllOrSelected);
|
|
||||||
}
|
|
||||||
if (shouldInstallNew) {
|
|
||||||
toInstall
|
|
||||||
.addAll(newInstallIdsAllOrSelected);
|
|
||||||
}
|
|
||||||
if (shouldMarkTrackOnlies) {
|
|
||||||
toInstall.addAll(
|
|
||||||
trackOnlyUpdateIdsAllOrSelected);
|
|
||||||
}
|
|
||||||
appsProvider
|
|
||||||
.downloadAndInstallLatestApps(toInstall,
|
|
||||||
globalNavigatorKey.currentContext)
|
|
||||||
.catchError((e) {
|
|
||||||
showError(e, context);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
tooltip: selectedApps.isEmpty
|
|
||||||
? tr('installUpdateApps')
|
|
||||||
: tr('installUpdateSelectedApps'),
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.file_download_outlined,
|
|
||||||
)),
|
|
||||||
selectedApps.isEmpty
|
|
||||||
? const SizedBox()
|
|
||||||
: IconButton(
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
onPressed: () async {
|
|
||||||
try {
|
|
||||||
Set<String>? preselected;
|
|
||||||
var showPrompt = false;
|
|
||||||
for (var element in selectedApps) {
|
|
||||||
var currentCats = element.categories.toSet();
|
|
||||||
if (preselected == null) {
|
|
||||||
preselected = currentCats;
|
|
||||||
} else {
|
|
||||||
if (!settingsProvider.setEqual(
|
|
||||||
currentCats, preselected)) {
|
|
||||||
showPrompt = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var cont = true;
|
|
||||||
if (showPrompt) {
|
|
||||||
cont = await showDialog<Map<String, dynamic>?>(
|
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext ctx) {
|
builder: (BuildContext ctx) {
|
||||||
return GeneratedFormModal(
|
return GeneratedFormModal(
|
||||||
title: tr('categorize'),
|
title:
|
||||||
|
tr('removeSelectedAppsQuestion'),
|
||||||
items: const [],
|
items: const [],
|
||||||
initValid: true,
|
initValid: true,
|
||||||
message:
|
message: tr(
|
||||||
tr('selectedCategorizeWarning'),
|
'xWillBeRemovedButRemainInstalled',
|
||||||
|
args: [
|
||||||
|
plural(
|
||||||
|
'apps', selectedApps.length)
|
||||||
|
]),
|
||||||
);
|
);
|
||||||
}) !=
|
}).then((values) {
|
||||||
null;
|
if (values != null) {
|
||||||
}
|
appsProvider.removeApps(selectedApps
|
||||||
if (cont) {
|
.map((e) => e.id)
|
||||||
await showDialog<Map<String, dynamic>?>(
|
.toList());
|
||||||
context: context,
|
}
|
||||||
builder: (BuildContext ctx) {
|
|
||||||
return GeneratedFormModal(
|
|
||||||
title: tr('categorize'),
|
|
||||||
items: const [],
|
|
||||||
initValid: true,
|
|
||||||
singleNullReturnButton: tr('continue'),
|
|
||||||
additionalWidgets: [
|
|
||||||
CategoryEditorSelector(
|
|
||||||
preselected: !showPrompt
|
|
||||||
? preselected ?? {}
|
|
||||||
: {},
|
|
||||||
showLabelWhenNotEmpty: false,
|
|
||||||
onSelected: (categories) {
|
|
||||||
appsProvider
|
|
||||||
.saveApps(selectedApps.map((e) {
|
|
||||||
e.categories = categories;
|
|
||||||
return e;
|
|
||||||
}).toList());
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
} catch (err) {
|
tooltip: tr('removeSelectedApps'),
|
||||||
showError(err, context);
|
icon: const Icon(Icons.delete_outline_outlined),
|
||||||
}
|
),
|
||||||
},
|
IconButton(
|
||||||
tooltip: tr('categorize'),
|
visualDensity: VisualDensity.compact,
|
||||||
icon: const Icon(Icons.category_outlined),
|
onPressed: appsProvider.areDownloadsRunning() ||
|
||||||
),
|
(existingUpdateIdsAllOrSelected.isEmpty &&
|
||||||
selectedApps.isEmpty
|
newInstallIdsAllOrSelected.isEmpty &&
|
||||||
? const SizedBox()
|
trackOnlyUpdateIdsAllOrSelected.isEmpty)
|
||||||
: IconButton(
|
? null
|
||||||
visualDensity: VisualDensity.compact,
|
: () {
|
||||||
onPressed: () {
|
HapticFeedback.heavyImpact();
|
||||||
showDialog(
|
List<GeneratedFormItem> formItems = [];
|
||||||
context: context,
|
if (existingUpdateIdsAllOrSelected
|
||||||
builder: (BuildContext ctx) {
|
.isNotEmpty) {
|
||||||
return AlertDialog(
|
formItems.add(GeneratedFormSwitch(
|
||||||
scrollable: true,
|
'updates',
|
||||||
content: Padding(
|
label: tr('updateX', args: [
|
||||||
padding: const EdgeInsets.only(top: 6),
|
plural(
|
||||||
child: Row(
|
'apps',
|
||||||
mainAxisAlignment:
|
existingUpdateIdsAllOrSelected
|
||||||
MainAxisAlignment.spaceAround,
|
.length)
|
||||||
children: [
|
]),
|
||||||
IconButton(
|
defaultValue: true));
|
||||||
onPressed:
|
}
|
||||||
appsProvider
|
if (newInstallIdsAllOrSelected.isNotEmpty) {
|
||||||
.areDownloadsRunning()
|
formItems.add(GeneratedFormSwitch(
|
||||||
? null
|
'installs',
|
||||||
: () {
|
label: tr('installX', args: [
|
||||||
showDialog(
|
plural(
|
||||||
context: context,
|
'apps',
|
||||||
builder:
|
newInstallIdsAllOrSelected
|
||||||
(BuildContext
|
.length)
|
||||||
ctx) {
|
]),
|
||||||
return AlertDialog(
|
defaultValue:
|
||||||
title: Text(tr(
|
existingUpdateIdsAllOrSelected
|
||||||
'markXSelectedAppsAsUpdated',
|
.isNotEmpty));
|
||||||
args: [
|
}
|
||||||
selectedApps
|
if (trackOnlyUpdateIdsAllOrSelected
|
||||||
.length
|
.isNotEmpty) {
|
||||||
.toString()
|
formItems.add(GeneratedFormSwitch(
|
||||||
])),
|
'trackonlies',
|
||||||
content: Text(
|
label: tr('markXTrackOnlyAsUpdated',
|
||||||
tr('onlyWorksWithNonEVDApps'),
|
args: [
|
||||||
style: const TextStyle(
|
plural(
|
||||||
fontWeight:
|
'apps',
|
||||||
FontWeight
|
trackOnlyUpdateIdsAllOrSelected
|
||||||
.bold,
|
.length)
|
||||||
fontStyle:
|
]),
|
||||||
FontStyle.italic),
|
defaultValue:
|
||||||
),
|
existingUpdateIdsAllOrSelected
|
||||||
actions: [
|
.isNotEmpty ||
|
||||||
TextButton(
|
newInstallIdsAllOrSelected
|
||||||
onPressed:
|
.isNotEmpty));
|
||||||
() {
|
}
|
||||||
Navigator.of(context)
|
showDialog<Map<String, dynamic>?>(
|
||||||
.pop();
|
context: context,
|
||||||
},
|
builder: (BuildContext ctx) {
|
||||||
child: Text(
|
var totalApps =
|
||||||
tr('no'))),
|
existingUpdateIdsAllOrSelected.length +
|
||||||
TextButton(
|
newInstallIdsAllOrSelected
|
||||||
onPressed:
|
.length +
|
||||||
() {
|
trackOnlyUpdateIdsAllOrSelected
|
||||||
HapticFeedback
|
.length;
|
||||||
.selectionClick();
|
return GeneratedFormModal(
|
||||||
appsProvider
|
title: tr('changeX', args: [
|
||||||
.saveApps(selectedApps.map((a) {
|
plural('apps', totalApps)
|
||||||
if (a.installedVersion !=
|
]),
|
||||||
null) {
|
items: formItems
|
||||||
a.installedVersion = a.latestVersion;
|
.map((e) => [e])
|
||||||
}
|
.toList(),
|
||||||
return a;
|
initValid: true,
|
||||||
}).toList());
|
);
|
||||||
|
}).then((values) {
|
||||||
|
if (values != null) {
|
||||||
|
if (values.isEmpty) {
|
||||||
|
values =
|
||||||
|
getDefaultValuesFromFormItems(
|
||||||
|
[formItems]);
|
||||||
|
}
|
||||||
|
bool shouldInstallUpdates =
|
||||||
|
values['updates'] == true;
|
||||||
|
bool shouldInstallNew =
|
||||||
|
values['installs'] == true;
|
||||||
|
bool shouldMarkTrackOnlies =
|
||||||
|
values['trackonlies'] == true;
|
||||||
|
(() async {
|
||||||
|
if (shouldInstallNew ||
|
||||||
|
shouldInstallUpdates) {
|
||||||
|
await settingsProvider
|
||||||
|
.getInstallPermission();
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
.then((_) {
|
||||||
|
List<String> toInstall = [];
|
||||||
|
if (shouldInstallUpdates) {
|
||||||
|
toInstall.addAll(
|
||||||
|
existingUpdateIdsAllOrSelected);
|
||||||
|
}
|
||||||
|
if (shouldInstallNew) {
|
||||||
|
toInstall.addAll(
|
||||||
|
newInstallIdsAllOrSelected);
|
||||||
|
}
|
||||||
|
if (shouldMarkTrackOnlies) {
|
||||||
|
toInstall.addAll(
|
||||||
|
trackOnlyUpdateIdsAllOrSelected);
|
||||||
|
}
|
||||||
|
appsProvider
|
||||||
|
.downloadAndInstallLatestApps(
|
||||||
|
toInstall,
|
||||||
|
globalNavigatorKey
|
||||||
|
.currentContext)
|
||||||
|
.catchError((e) {
|
||||||
|
showError(e, context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
tooltip: selectedApps.isEmpty
|
||||||
|
? tr('installUpdateApps')
|
||||||
|
: tr('installUpdateSelectedApps'),
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.file_download_outlined,
|
||||||
|
)),
|
||||||
|
IconButton(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
onPressed: selectedApps.isEmpty
|
||||||
|
? null
|
||||||
|
: () async {
|
||||||
|
try {
|
||||||
|
Set<String>? preselected;
|
||||||
|
var showPrompt = false;
|
||||||
|
for (var element in selectedApps) {
|
||||||
|
var currentCats =
|
||||||
|
element.categories.toSet();
|
||||||
|
if (preselected == null) {
|
||||||
|
preselected = currentCats;
|
||||||
|
} else {
|
||||||
|
if (!settingsProvider.setEqual(
|
||||||
|
currentCats, preselected)) {
|
||||||
|
showPrompt = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var cont = true;
|
||||||
|
if (showPrompt) {
|
||||||
|
cont = await showDialog<
|
||||||
|
Map<String, dynamic>?>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext ctx) {
|
||||||
|
return GeneratedFormModal(
|
||||||
|
title: tr('categorize'),
|
||||||
|
items: const [],
|
||||||
|
initValid: true,
|
||||||
|
message: tr(
|
||||||
|
'selectedCategorizeWarning'),
|
||||||
|
);
|
||||||
|
}) !=
|
||||||
|
null;
|
||||||
|
}
|
||||||
|
if (cont) {
|
||||||
|
await showDialog<Map<String, dynamic>?>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext ctx) {
|
||||||
|
return GeneratedFormModal(
|
||||||
|
title: tr('categorize'),
|
||||||
|
items: const [],
|
||||||
|
initValid: true,
|
||||||
|
singleNullReturnButton:
|
||||||
|
tr('continue'),
|
||||||
|
additionalWidgets: [
|
||||||
|
CategoryEditorSelector(
|
||||||
|
preselected: !showPrompt
|
||||||
|
? preselected ?? {}
|
||||||
|
: {},
|
||||||
|
showLabelWhenNotEmpty: false,
|
||||||
|
onSelected: (categories) {
|
||||||
|
appsProvider.saveApps(
|
||||||
|
selectedApps.map((e) {
|
||||||
|
e.categories = categories;
|
||||||
|
return e;
|
||||||
|
}).toList());
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
showError(err, context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: tr('categorize'),
|
||||||
|
icon: const Icon(Icons.category_outlined),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
onPressed: selectedApps.isEmpty
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext ctx) {
|
||||||
|
return AlertDialog(
|
||||||
|
scrollable: true,
|
||||||
|
content: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.only(top: 6),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment
|
||||||
|
.spaceAround,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: appsProvider
|
||||||
|
.areDownloadsRunning()
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
showDialog(
|
||||||
|
context:
|
||||||
|
context,
|
||||||
|
builder:
|
||||||
|
(BuildContext
|
||||||
|
ctx) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(tr(
|
||||||
|
'markXSelectedAppsAsUpdated',
|
||||||
|
args: [
|
||||||
|
selectedApps.length.toString()
|
||||||
|
])),
|
||||||
|
content:
|
||||||
|
Text(
|
||||||
|
tr('onlyWorksWithNonEVDApps'),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontWeight:
|
||||||
|
FontWeight.bold,
|
||||||
|
fontStyle: FontStyle.italic),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed:
|
||||||
|
() {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child:
|
||||||
|
Text(tr('no'))),
|
||||||
|
TextButton(
|
||||||
|
onPressed:
|
||||||
|
() {
|
||||||
|
HapticFeedback.selectionClick();
|
||||||
|
appsProvider.saveApps(selectedApps.map((a) {
|
||||||
|
if (a.installedVersion != null) {
|
||||||
|
a.installedVersion = a.latestVersion;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}).toList());
|
||||||
|
|
||||||
Navigator.of(context)
|
Navigator.of(context).pop();
|
||||||
.pop();
|
},
|
||||||
},
|
child:
|
||||||
child: Text(
|
Text(tr('yes')))
|
||||||
tr('yes')))
|
],
|
||||||
],
|
);
|
||||||
);
|
}).whenComplete(() {
|
||||||
}).whenComplete(() {
|
Navigator.of(
|
||||||
Navigator.of(
|
context)
|
||||||
context)
|
.pop();
|
||||||
.pop();
|
});
|
||||||
});
|
},
|
||||||
},
|
tooltip: tr(
|
||||||
tooltip:
|
'markSelectedAppsUpdated'),
|
||||||
tr('markSelectedAppsUpdated'),
|
icon: const Icon(
|
||||||
icon: const Icon(Icons.done)),
|
Icons.done)),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
var pinStatus = selectedApps
|
var pinStatus =
|
||||||
.where((element) =>
|
selectedApps
|
||||||
element.pinned)
|
.where((element) =>
|
||||||
.isEmpty;
|
element
|
||||||
appsProvider.saveApps(
|
.pinned)
|
||||||
selectedApps.map((e) {
|
.isEmpty;
|
||||||
e.pinned = pinStatus;
|
appsProvider.saveApps(
|
||||||
return e;
|
selectedApps.map((e) {
|
||||||
}).toList());
|
e.pinned = pinStatus;
|
||||||
Navigator.of(context).pop();
|
return e;
|
||||||
},
|
}).toList());
|
||||||
tooltip: selectedApps
|
Navigator.of(context)
|
||||||
.where((element) =>
|
.pop();
|
||||||
element.pinned)
|
},
|
||||||
.isEmpty
|
tooltip: selectedApps
|
||||||
? tr('pinToTop')
|
.where((element) =>
|
||||||
: tr('unpinFromTop'),
|
element.pinned)
|
||||||
icon: Icon(selectedApps
|
.isEmpty
|
||||||
.where((element) =>
|
? tr('pinToTop')
|
||||||
element.pinned)
|
: tr('unpinFromTop'),
|
||||||
.isEmpty
|
icon: Icon(selectedApps
|
||||||
? Icons.bookmark_outline_rounded
|
.where((element) =>
|
||||||
: Icons
|
element.pinned)
|
||||||
.bookmark_remove_outlined),
|
.isEmpty
|
||||||
|
? Icons
|
||||||
|
.bookmark_outline_rounded
|
||||||
|
: Icons
|
||||||
|
.bookmark_remove_outlined),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
String urls = '';
|
||||||
|
for (var a
|
||||||
|
in selectedApps) {
|
||||||
|
urls += '${a.url}\n';
|
||||||
|
}
|
||||||
|
urls = urls.substring(
|
||||||
|
0, urls.length - 1);
|
||||||
|
Share.share(urls,
|
||||||
|
subject: tr(
|
||||||
|
'selectedAppURLsFromObtainium'));
|
||||||
|
Navigator.of(context)
|
||||||
|
.pop();
|
||||||
|
},
|
||||||
|
tooltip: tr(
|
||||||
|
'shareSelectedAppURLs'),
|
||||||
|
icon:
|
||||||
|
const Icon(Icons.share),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext
|
||||||
|
ctx) {
|
||||||
|
return GeneratedFormModal(
|
||||||
|
title: tr(
|
||||||
|
'resetInstallStatusForSelectedAppsQuestion'),
|
||||||
|
items: const [],
|
||||||
|
initValid: true,
|
||||||
|
message: tr(
|
||||||
|
'installStatusOfXWillBeResetExplanation',
|
||||||
|
args: [
|
||||||
|
plural(
|
||||||
|
'app',
|
||||||
|
selectedApps
|
||||||
|
.length)
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}).then((values) {
|
||||||
|
if (values != null) {
|
||||||
|
appsProvider.saveApps(
|
||||||
|
selectedApps
|
||||||
|
.map((e) {
|
||||||
|
e.installedVersion =
|
||||||
|
null;
|
||||||
|
return e;
|
||||||
|
}).toList());
|
||||||
|
}
|
||||||
|
}).whenComplete(() {
|
||||||
|
Navigator.of(context)
|
||||||
|
.pop();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
tooltip: tr(
|
||||||
|
'resetInstallStatus'),
|
||||||
|
icon: const Icon(Icons
|
||||||
|
.restore_page_outlined),
|
||||||
|
),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
IconButton(
|
);
|
||||||
onPressed: () {
|
});
|
||||||
String urls = '';
|
},
|
||||||
for (var a in selectedApps) {
|
tooltip: tr('more'),
|
||||||
urls += '${a.url}\n';
|
icon: const Icon(Icons.more_horiz),
|
||||||
}
|
),
|
||||||
urls = urls.substring(
|
],
|
||||||
0, urls.length - 1);
|
))),
|
||||||
Share.share(urls,
|
|
||||||
subject: tr(
|
|
||||||
'selectedAppURLsFromObtainium'));
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
tooltip: tr('shareSelectedAppURLs'),
|
|
||||||
icon: const Icon(Icons.share),
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext ctx) {
|
|
||||||
return GeneratedFormModal(
|
|
||||||
title: tr(
|
|
||||||
'resetInstallStatusForSelectedAppsQuestion'),
|
|
||||||
items: const [],
|
|
||||||
initValid: true,
|
|
||||||
message: tr(
|
|
||||||
'installStatusOfXWillBeResetExplanation',
|
|
||||||
args: [
|
|
||||||
plural(
|
|
||||||
'app',
|
|
||||||
selectedApps
|
|
||||||
.length)
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}).then((values) {
|
|
||||||
if (values != null) {
|
|
||||||
appsProvider.saveApps(
|
|
||||||
selectedApps.map((e) {
|
|
||||||
e.installedVersion = null;
|
|
||||||
return e;
|
|
||||||
}).toList());
|
|
||||||
}
|
|
||||||
}).whenComplete(() {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
tooltip: tr('resetInstallStatus'),
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.restore_page_outlined),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
tooltip: tr('more'),
|
|
||||||
icon: const Icon(Icons.more_horiz),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
const VerticalDivider(),
|
const VerticalDivider(),
|
||||||
IconButton(
|
IconButton(
|
||||||
visualDensity: VisualDensity.compact,
|
visualDensity: VisualDensity.compact,
|
||||||
|
Reference in New Issue
Block a user