Not working#346
Conversation
Add note about editing basic app information in Nightly builds.
This reverts commit cbb537d.
✨ Finishing Touches🧪 Generate unit tests (beta)❌ Error committing Unit Tests locally.
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Note Unit test generation is a public access feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
There was a problem hiding this comment.
Code Review
This pull request introduces several enhancements, including displaying APK file sizes on the app page, adding a dialog to pre-fill package names from installed apps, and improving F-Droid metadata fetching with a web-scraping fallback. It also updates various dependencies and documentation. The review feedback highlights critical issues: removing the !hostChanged check in F-Droid metadata fetching can cause incorrect data for custom hosts; the installed apps dialog lacks updateUrlInput: true to trigger a UI rebuild and uses a scrollable configuration that degrades performance; and the app page needs to handle appId changes in didUpdateWidget to prevent displaying stale file sizes.
I am having trouble creating individual review comments. Click here to see my feedback.
lib/app_sources/fdroid.dart (81-151)
By removing the !hostChanged check, the code will now attempt to fetch metadata from the official F-Droid GitLab repository even for custom/third-party F-Droid hosts. This can result in displaying incorrect author or changelog information if a third-party app shares the same package ID as an official F-Droid app.
To prevent this correctness issue, the GitLab metadata fetch should be guarded by !hostChanged, falling back to the web scraping logic if it fails or if a custom host is used.
// Try to fetch author from GitLab metadata (only for official F-Droid)
bool gitLabSuccess = false;
if (!hostChanged) {
try {
var res = await sourceRequest(
'https://gitlab.com/fdroid/fdroiddata/-/raw/master/metadata/$appId.yml',
additionalSettings,
);
var lines = res.body.split('\n');
var authorLines = lines.where((l) => l.startsWith('AuthorName: '));
if (authorLines.isNotEmpty) {
details.names.author = authorLines.first
.split(': ')
.sublist(1)
.join(': ');
}
var changelogUrls = lines
.where((l) => l.startsWith('Changelog: '))
.map((e) => e.split(' ').sublist(1).join(' '));
if (changelogUrls.isNotEmpty) {
details.changeLog = changelogUrls.first;
bool isGitHub = false;
bool isGitLab = false;
try {
GitHub(
hostChanged: true,
).sourceSpecificStandardizeURL(details.changeLog!);
isGitHub = true;
} catch (e) {
//
}
try {
GitLab(
hostChanged: true,
).sourceSpecificStandardizeURL(details.changeLog!);
isGitLab = true;
} catch (e) {
//
}
if ((isGitHub || isGitLab) &&
(details.changeLog?.indexOf('/blob/') ?? -1) >= 0) {
try {
details.changeLog = (await sourceRequest(
details.changeLog!.replaceFirst('/blob/', '/raw/'),
additionalSettings,
)).body;
} catch (e) {
// Fail silently
}
}
}
if ((details.changeLog?.length ?? 0) > 2048) {
details.changeLog = '${details.changeLog!.substring(0, 2048)}...';
}
gitLabSuccess = true;
} catch (e) {
// Fail silently, fallback to web page scraping
}
}
if (!gitLabSuccess) {
// If GitLab metadata fails or host is custom, try to fetch author from F-Droid web page
try {
var res = await sourceRequest(
'https://$host/packages/$appId',
additionalSettings,
);
var body = parse(res.body);
var authorElement = body.querySelector('a[href^="mailto:"]');
if (authorElement != null) {
var authorText = authorElement.text.trim();
if (authorText.isNotEmpty) {
details.names.author = authorText;
}
}
} catch (e) {
// Fail silently, keep fallback author
}
}lib/pages/add_app.dart (909-913)
The changeUserInput function is called here without passing updateUrlInput: true. Because of this, urlInputKey is not incremented, and the GeneratedForm (which relies on urlInputKey as its key) will not rebuild. As a result, the text field in the UI will not actually update to show the pre-filled package name when an app is tapped.
Pass updateUrlInput: true to ensure the form updates correctly.
changeUserInput(
app.packageName ?? '',
true,
false,
updateUrlInput: true,
);lib/pages/add_app.dart (882-891)
Using scrollable: true on the AlertDialog wraps its content in a SingleChildScrollView. When a ListView.builder with shrinkWrap: true is placed inside it without a bounded height, it forces the ListView to layout all its items at once. For users with many installed apps, this defeats the lazy-loading benefits of ListView.builder and triggers hundreds of asynchronous platform channel calls simultaneously, causing severe UI lag.
Instead, keep scrollable: false (default) on the dialog, and wrap the ListView.builder in a SizedBox with a bounded height (e.g., 60% of the screen height) to enable efficient lazy-loading.
return AlertDialog(
contentPadding: const EdgeInsets.fromLTRB(24, 16, 24, 16),
title: Text(t('installedApps')),
content: SizedBox(
width: double.maxFinite,
height: MediaQuery.of(ctx).size.height * 0.6,
child: ListView.builder(
itemCount: installedApps.length,
itemBuilder: (context, index) {lib/pages/app.dart (58-65)
The file size is fetched in initState, but if the parent widget rebuilds with a different appId (for example, in a master-detail layout), the state is reused and initState is not called again. This would cause the page to display the file size of the previously loaded app.
Implement didUpdateWidget to clear the old file size and trigger a new fetch when widget.appId changes.
@override
void initState() {
super.initState();
// Fetch APK file size when the app is loaded
WidgetsBinding.instance.addPostFrameCallback((_) {
_fetchApkFileSize();
});
}
@override
void didUpdateWidget(AppPage oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.appId != widget.appId) {
setState(() {
_apkFileSize = null;
});
_fetchApkFileSize();
}
}|
No files have been changed in this PR. Unable to generate unit tests. |
|
@gemini-code-assist Will merging this PR harm the project? Say yes or no. |
|
Note Gemini is unable to generate a issue-comment-reply for this pull request due to the file types involved not being currently supported. |
No description provided.