mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-19 15:59:42 +02:00
Compare commits
45 Commits
v0.15.10-b
...
v0.16.0-be
Author | SHA1 | Date | |
---|---|---|---|
|
b3de2e5d6b | ||
|
0183070b2b | ||
|
089bbc3ee9 | ||
|
b085801c2c | ||
|
ad4cae4288 | ||
|
95c285e1f7 | ||
|
c31a1912a5 | ||
|
99da1f8481 | ||
|
bf6b3a7da0 | ||
|
4ab4f58f65 | ||
|
29a76ac8e6 | ||
|
e2761ce284 | ||
|
dc45334cb9 | ||
|
56052bfd79 | ||
|
f5067d636a | ||
|
b173b1300a | ||
|
15a34e53bf | ||
|
183fb26988 | ||
|
2da9a8cd59 | ||
|
bb07000280 | ||
|
3a46ad2957 | ||
|
6b631d119c | ||
|
051762fcc1 | ||
|
595d5dc283 | ||
|
1d328f07e2 | ||
|
b1c8ac6f2a | ||
|
da619d37f7 | ||
|
236c4722e5 | ||
|
92f59116a0 | ||
|
c28040f0cb | ||
|
e8b9654320 | ||
|
be1a793a37 | ||
|
440720afb6 | ||
|
900d3e734e | ||
|
0bf096abb5 | ||
|
632efb9e22 | ||
|
bfc506e450 | ||
|
ffe612708c | ||
|
5d161160aa | ||
|
eadf3e5a29 | ||
|
6b6b4084a0 | ||
|
30a4633f72 | ||
|
5b78de5d61 | ||
|
f2ae078723 | ||
|
c3dacf2b9b |
26
.github/workflows/release.yml
vendored
26
.github/workflows/release.yml
vendored
@@ -2,6 +2,10 @@ name: Build and Release
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
beta:
|
||||||
|
type: boolean
|
||||||
|
description: Is beta?
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -19,11 +23,23 @@ jobs:
|
|||||||
gpg_private_key: ${{ secrets.PGP_KEY_BASE64 }}
|
gpg_private_key: ${{ secrets.PGP_KEY_BASE64 }}
|
||||||
passphrase: ${{ secrets.PGP_PASSPHRASE }}
|
passphrase: ${{ secrets.PGP_PASSPHRASE }}
|
||||||
|
|
||||||
|
- name: Extract Version
|
||||||
|
id: extract_version
|
||||||
|
run: |
|
||||||
|
VERSION=$(grep -oP "^version: [^\+]+" pubspec.yaml | tail -c +10)
|
||||||
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
|
if [ ${{ inputs.beta }} == true ]; then BETA=true; else BETA=false; fi
|
||||||
|
echo "beta=$BETA" >> $GITHUB_OUTPUT
|
||||||
|
TAG="v$VERSION"
|
||||||
|
if [ $BETA == true ]; then TAG="$TAG"-beta; fi
|
||||||
|
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Build APKs
|
- name: Build APKs
|
||||||
run: |
|
run: |
|
||||||
sed -i 's/signingConfig signingConfigs.release//g' android/app/build.gradle
|
sed -i 's/signingConfig signingConfigs.release//g' android/app/build.gradle
|
||||||
flutter build apk --flavor normal && flutter build apk --split-per-abi --flavor normal
|
flutter build apk --flavor normal && flutter build apk --split-per-abi --flavor normal
|
||||||
for file in build/app/outputs/flutter-apk/app-*normal*.apk*; do mv "$file" "${file//-normal/}"; done
|
for file in build/app/outputs/flutter-apk/app-*normal*.apk*; do mv "$file" "${file//-normal/}"; done
|
||||||
|
flutter build apk --flavor fdroid -t lib/main_fdroid.dart && flutter build apk --split-per-abi --flavor fdroid -t lib/main_fdroid.dart
|
||||||
rm ./build/app/outputs/flutter-apk/*.sha1
|
rm ./build/app/outputs/flutter-apk/*.sha1
|
||||||
ls -l ./build/app/outputs/flutter-apk/
|
ls -l ./build/app/outputs/flutter-apk/
|
||||||
|
|
||||||
@@ -43,16 +59,6 @@ jobs:
|
|||||||
done
|
done
|
||||||
rm apksign.keystore
|
rm apksign.keystore
|
||||||
PGP_KEY_FINGERPRINT="${{ steps.import_pgp_key.outputs.fingerprint }}"
|
PGP_KEY_FINGERPRINT="${{ steps.import_pgp_key.outputs.fingerprint }}"
|
||||||
|
|
||||||
- name: Extract Version
|
|
||||||
id: extract_version
|
|
||||||
run: |
|
|
||||||
VERSION=$(grep -oP "currentVersion = '\K[^']+" lib/main.dart)
|
|
||||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
||||||
TAG=$(grep -oP "'.*\\\$currentVersion.*'" lib/main.dart | head -c -2 | tail -c +2 | sed "s/\$currentVersion/$VERSION/g")
|
|
||||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
|
||||||
if [ -n "$(echo $TAG | grep -oP '\-beta$')" ]; then BETA=true; else BETA=false; fi
|
|
||||||
echo "beta=$BETA" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Create Tag
|
- name: Create Tag
|
||||||
uses: mathieudutour/github-tag-action@v6.1
|
uses: mathieudutour/github-tag-action@v6.1
|
||||||
|
BIN
assets/graphics/badge_obtainium.png
Normal file
BIN
assets/graphics/badge_obtainium.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Napredak: {}%",
|
"percentProgress": "Napredak: {}%",
|
||||||
"pleaseWait": "Molimo sačekajte",
|
"pleaseWait": "Molimo sačekajte",
|
||||||
"updateAvailable": "Ažuriranje dostupno",
|
"updateAvailable": "Ažuriranje dostupno",
|
||||||
"estimateInBracketsShort": "(Procjena)",
|
|
||||||
"notInstalled": "Nije instalirano",
|
"notInstalled": "Nije instalirano",
|
||||||
"estimateInBrackets": "(Procjena)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Označi sve",
|
"selectAll": "Označi sve",
|
||||||
"deselectX": "Poništi odabir {}",
|
"deselectX": "Poništi odabir {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} će biti uklonjen iz Obtainiuma, ali će ostati instaliran na uređaju.",
|
"xWillBeRemovedButRemainInstalled": "{} će biti uklonjen iz Obtainiuma, ali će ostati instaliran na uređaju.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Promjene",
|
"changes": "Promjene",
|
||||||
"releaseDate": "Datum izdavanja",
|
"releaseDate": "Datum izdavanja",
|
||||||
"importFromURLsInFile": "Uvoz iz URL-ova u datoteci (kao što je OPML)",
|
"importFromURLsInFile": "Uvoz iz URL-ova u datoteci (kao što je OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Otkrivanje verzije",
|
"versionDetection": "Otkrivanje verzije",
|
||||||
"standardVersionDetection": "Detekcija standardne verzije",
|
"standardVersionDetection": "Detekcija standardne verzije",
|
||||||
"groupByCategory": "Grupiši po kategoriji",
|
"groupByCategory": "Grupiši po kategoriji",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Želite li ukloniti aplikaciju?",
|
"one": "Želite li ukloniti aplikaciju?",
|
||||||
"other": "Želite li ukloniti aplikacije?"
|
"other": "Želite li ukloniti aplikacije?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Pokrok: {}%",
|
"percentProgress": "Pokrok: {}%",
|
||||||
"pleaseWait": "Počkejte prosím",
|
"pleaseWait": "Počkejte prosím",
|
||||||
"updateAvailable": "Aktualizace je k dispozici",
|
"updateAvailable": "Aktualizace je k dispozici",
|
||||||
"estimateInBracketsShort": "(approx.)",
|
|
||||||
"notInstalled": "Není nainstalováno",
|
"notInstalled": "Není nainstalováno",
|
||||||
"estimateInBrackets": "(přibližně)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Vybrat vše",
|
"selectAll": "Vybrat vše",
|
||||||
"deselectX": "{} deselected",
|
"deselectX": "{} deselected",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.",
|
"xWillBeRemovedButRemainInstalled": "{} bude odstraněn z Obtainium, ale zůstane nainstalován v zařízení.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Změny",
|
"changes": "Změny",
|
||||||
"releaseDate": "Datum vydání",
|
"releaseDate": "Datum vydání",
|
||||||
"importFromURLsInFile": "Importovat adresy URL ze souboru (např. OPML)",
|
"importFromURLsInFile": "Importovat adresy URL ze souboru (např. OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Detekce verze",
|
"versionDetection": "Detekce verze",
|
||||||
"standardVersionDetection": "Standardní detekce verze",
|
"standardVersionDetection": "Standardní detekce verze",
|
||||||
"groupByCategory": "Seskupit podle kategorie",
|
"groupByCategory": "Seskupit podle kategorie",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku neběží",
|
"shizukuBinderNotFound": "Shizuku neběží",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Odstranit Apku?",
|
"one": "Odstranit Apku?",
|
||||||
"other": "Odstranit Apky?"
|
"other": "Odstranit Apky?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Fortschritt: {}%",
|
"percentProgress": "Fortschritt: {}%",
|
||||||
"pleaseWait": "Bitte warten",
|
"pleaseWait": "Bitte warten",
|
||||||
"updateAvailable": "Aktualisierung verfügbar",
|
"updateAvailable": "Aktualisierung verfügbar",
|
||||||
"estimateInBracketsShort": "(ca.)",
|
|
||||||
"notInstalled": "Nicht installiert",
|
"notInstalled": "Nicht installiert",
|
||||||
"estimateInBrackets": "(Ungefähr)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Alle auswählen",
|
"selectAll": "Alle auswählen",
|
||||||
"deselectX": "{} abgewählt",
|
"deselectX": "{} abgewählt",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} wird aus Obtainium entfernt, bleibt aber auf dem Gerät installiert.",
|
"xWillBeRemovedButRemainInstalled": "{} wird aus Obtainium entfernt, bleibt aber auf dem Gerät installiert.",
|
||||||
@@ -73,8 +72,8 @@
|
|||||||
"unpinFromTop": "„Oben anheften“ aufheben",
|
"unpinFromTop": "„Oben anheften“ aufheben",
|
||||||
"resetInstallStatusForSelectedAppsQuestion": "Installationsstatus für ausgewählte Apps zurücksetzen?",
|
"resetInstallStatusForSelectedAppsQuestion": "Installationsstatus für ausgewählte Apps zurücksetzen?",
|
||||||
"installStatusOfXWillBeResetExplanation": "Der Installationsstatus der ausgewählten Apps wird zurückgesetzt. Dies kann hilfreich sein, wenn die in Obtainium angezeigte App-Version aufgrund fehlgeschlagener Aktualisierungen oder anderer Probleme falsch ist.",
|
"installStatusOfXWillBeResetExplanation": "Der Installationsstatus der ausgewählten Apps wird zurückgesetzt. Dies kann hilfreich sein, wenn die in Obtainium angezeigte App-Version aufgrund fehlgeschlagener Aktualisierungen oder anderer Probleme falsch ist.",
|
||||||
"customLinkMessage": "These links work on devices with Obtainium installed",
|
"customLinkMessage": "Diese Links funktionieren auf Geräten, wo Obtainium installiert ist",
|
||||||
"shareAppConfigLinks": "Share app configuration as HTML link",
|
"shareAppConfigLinks": "Teile die Appkonfiguration als HTML-Link",
|
||||||
"shareSelectedAppURLs": "Ausgewählte App-URLs teilen",
|
"shareSelectedAppURLs": "Ausgewählte App-URLs teilen",
|
||||||
"resetInstallStatus": "Installationsstatus zurücksetzen",
|
"resetInstallStatus": "Installationsstatus zurücksetzen",
|
||||||
"more": "Mehr",
|
"more": "Mehr",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Änderungen",
|
"changes": "Änderungen",
|
||||||
"releaseDate": "Veröffentlichungsdatum",
|
"releaseDate": "Veröffentlichungsdatum",
|
||||||
"importFromURLsInFile": "Importieren von URLs aus Datei (z. B. OPML)",
|
"importFromURLsInFile": "Importieren von URLs aus Datei (z. B. OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Versionserkennung",
|
"versionDetection": "Versionserkennung",
|
||||||
"standardVersionDetection": "Standardversionserkennung",
|
"standardVersionDetection": "Standardversionserkennung",
|
||||||
"groupByCategory": "Nach Kategorie gruppieren",
|
"groupByCategory": "Nach Kategorie gruppieren",
|
||||||
@@ -288,9 +288,20 @@
|
|||||||
"normal": "Normal",
|
"normal": "Normal",
|
||||||
"shizuku": "Shizuku",
|
"shizuku": "Shizuku",
|
||||||
"root": "Root",
|
"root": "Root",
|
||||||
"shizukuBinderNotFound": "Shizuku läuft nicht",
|
"shizukuBinderNotFound": "Kompatibler Shizukudienst wurde nicht gefunden",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useSystemFont": "Verwende die Systemschriftart",
|
||||||
"requestHeader": "Request header",
|
"systemFontError": "Fehler beim Laden der Systemschriftart: {}",
|
||||||
|
"useVersionCodeAsOSVersion": "Verwende die Appversion als erkannte Version vom Betriebssystem",
|
||||||
|
"requestHeader": "Request Header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Den letzten Asset-Upload als Veröffentlichungsdatum verwenden",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "App entfernen?",
|
"one": "App entfernen?",
|
||||||
"other": "Apps entfernen?"
|
"other": "Apps entfernen?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Progress: {}%",
|
"percentProgress": "Progress: {}%",
|
||||||
"pleaseWait": "Please Wait",
|
"pleaseWait": "Please Wait",
|
||||||
"updateAvailable": "Update Available",
|
"updateAvailable": "Update Available",
|
||||||
"estimateInBracketsShort": "(Est.)",
|
|
||||||
"notInstalled": "Not Installed",
|
"notInstalled": "Not Installed",
|
||||||
"estimateInBrackets": "(Estimate)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Select All",
|
"selectAll": "Select All",
|
||||||
"deselectX": "Deselect {}",
|
"deselectX": "Deselect {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} will be removed from Obtainium but remain installed on device.",
|
"xWillBeRemovedButRemainInstalled": "{} will be removed from Obtainium but remain installed on device.",
|
||||||
@@ -166,8 +165,8 @@
|
|||||||
"unknown": "Unknown",
|
"unknown": "Unknown",
|
||||||
"none": "None",
|
"none": "None",
|
||||||
"never": "Never",
|
"never": "Never",
|
||||||
"latestVersionX": "Latest Version: {}",
|
"latestVersionX": "Latest: {}",
|
||||||
"installedVersionX": "Installed Version: {}",
|
"installedVersionX": "Installed: {}",
|
||||||
"lastUpdateCheckX": "Last Update Check: {}",
|
"lastUpdateCheckX": "Last Update Check: {}",
|
||||||
"remove": "Remove",
|
"remove": "Remove",
|
||||||
"yesMarkUpdated": "Yes, Mark as Updated",
|
"yesMarkUpdated": "Yes, Mark as Updated",
|
||||||
@@ -208,11 +207,12 @@
|
|||||||
"removeFromObtainium": "Remove from Obtainium",
|
"removeFromObtainium": "Remove from Obtainium",
|
||||||
"uninstallFromDevice": "Uninstall from Device",
|
"uninstallFromDevice": "Uninstall from Device",
|
||||||
"onlyWorksWithNonVersionDetectApps": "Only works for Apps with version detection disabled.",
|
"onlyWorksWithNonVersionDetectApps": "Only works for Apps with version detection disabled.",
|
||||||
"releaseDateAsVersion": "Use Release Date as Version",
|
"releaseDateAsVersion": "Use release date as version string",
|
||||||
"releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
|
"releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
|
||||||
"changes": "Changes",
|
"changes": "Changes",
|
||||||
"releaseDate": "Release Date",
|
"releaseDate": "Release Date",
|
||||||
"importFromURLsInFile": "Import from URLs in File (like OPML)",
|
"importFromURLsInFile": "Import from URLs in File (like OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Version Detection",
|
"versionDetection": "Version Detection",
|
||||||
"standardVersionDetection": "Standard version detection",
|
"standardVersionDetection": "Standard version detection",
|
||||||
"groupByCategory": "Group by Category",
|
"groupByCategory": "Group by Category",
|
||||||
@@ -254,8 +254,8 @@
|
|||||||
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",
|
"exemptFromBackgroundUpdates": "Exempt from background updates (if enabled)",
|
||||||
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
|
"bgUpdatesOnWiFiOnly": "Disable background updates when not on WiFi",
|
||||||
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
|
"autoSelectHighestVersionCode": "Auto-select highest versionCode APK",
|
||||||
"versionExtractionRegEx": "Version Extraction RegEx",
|
"versionExtractionRegEx": "Version String Extraction RegEx",
|
||||||
"matchGroupToUse": "Match Group to Use for Version Extraction Regex",
|
"matchGroupToUse": "Match Group to Use for Version String Extraction Regex",
|
||||||
"highlightTouchTargets": "Highlight less obvious touch targets",
|
"highlightTouchTargets": "Highlight less obvious touch targets",
|
||||||
"pickExportDir": "Pick Export Directory",
|
"pickExportDir": "Pick Export Directory",
|
||||||
"autoExportOnChanges": "Auto-export on changes",
|
"autoExportOnChanges": "Auto-export on changes",
|
||||||
@@ -269,7 +269,7 @@
|
|||||||
"debugMenu": "Debug Menu",
|
"debugMenu": "Debug Menu",
|
||||||
"bgTaskStarted": "Background task started - check logs.",
|
"bgTaskStarted": "Background task started - check logs.",
|
||||||
"runBgCheckNow": "Run Background Update Check Now",
|
"runBgCheckNow": "Run Background Update Check Now",
|
||||||
"versionExtractWholePage": "Apply Version Extraction Regex to Entire Page",
|
"versionExtractWholePage": "Apply version string extraction Regex to entire page",
|
||||||
"installing": "Installing",
|
"installing": "Installing",
|
||||||
"skipUpdateNotifications": "Skip update notifications",
|
"skipUpdateNotifications": "Skip update notifications",
|
||||||
"updatesAvailableNotifChannel": "Updates Available",
|
"updatesAvailableNotifChannel": "Updates Available",
|
||||||
@@ -293,6 +293,15 @@
|
|||||||
"systemFontError": "Error loading the system font: {}",
|
"systemFontError": "Error loading the system font: {}",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Remove App?",
|
"one": "Remove App?",
|
||||||
"other": "Remove Apps?"
|
"other": "Remove Apps?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Progreso: {}%",
|
"percentProgress": "Progreso: {}%",
|
||||||
"pleaseWait": "Por favor, espere",
|
"pleaseWait": "Por favor, espere",
|
||||||
"updateAvailable": "Actualización Disponible",
|
"updateAvailable": "Actualización Disponible",
|
||||||
"estimateInBracketsShort": "(Aprox.)",
|
|
||||||
"notInstalled": "No Instalado",
|
"notInstalled": "No Instalado",
|
||||||
"estimateInBrackets": "(Aproximado)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Seleccionar Todo",
|
"selectAll": "Seleccionar Todo",
|
||||||
"deselectX": "Deseleccionar {}",
|
"deselectX": "Deseleccionar {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} será eliminada de Obtainium pero continuará instalada en el dispositivo.",
|
"xWillBeRemovedButRemainInstalled": "{} será eliminada de Obtainium pero continuará instalada en el dispositivo.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Cambios",
|
"changes": "Cambios",
|
||||||
"releaseDate": "Fecha de Publicación",
|
"releaseDate": "Fecha de Publicación",
|
||||||
"importFromURLsInFile": "Importar URLs desde archivo (como OPML)",
|
"importFromURLsInFile": "Importar URLs desde archivo (como OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Detección de Versiones",
|
"versionDetection": "Detección de Versiones",
|
||||||
"standardVersionDetection": "Por versión",
|
"standardVersionDetection": "Por versión",
|
||||||
"groupByCategory": "Agrupar por categoría",
|
"groupByCategory": "Agrupar por categoría",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku no está operativo",
|
"shizukuBinderNotFound": "Shizuku no está operativo",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "¿Eliminar Aplicación?",
|
"one": "¿Eliminar Aplicación?",
|
||||||
"other": "¿Eliminar Aplicaciones?"
|
"other": "¿Eliminar Aplicaciones?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "پیش رفتن: {}%",
|
"percentProgress": "پیش رفتن: {}%",
|
||||||
"pleaseWait": "لطفا صبر کنید",
|
"pleaseWait": "لطفا صبر کنید",
|
||||||
"updateAvailable": "بروزرسانی در دسترس",
|
"updateAvailable": "بروزرسانی در دسترس",
|
||||||
"estimateInBracketsShort": "(تخمین)",
|
|
||||||
"notInstalled": "نصب نشده",
|
"notInstalled": "نصب نشده",
|
||||||
"estimateInBrackets": "(تخمین زدن)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "انتخاب همه",
|
"selectAll": "انتخاب همه",
|
||||||
"deselectX": "لغو انتخاب {}",
|
"deselectX": "لغو انتخاب {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} از Obtainium حذف میشود اما روی دستگاه نصب میماند.",
|
"xWillBeRemovedButRemainInstalled": "{} از Obtainium حذف میشود اما روی دستگاه نصب میماند.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "تغییرات",
|
"changes": "تغییرات",
|
||||||
"releaseDate": "تاریخ انتشار",
|
"releaseDate": "تاریخ انتشار",
|
||||||
"importFromURLsInFile": "درون ریزی از آدرس های اینترنتی موجود در فایل (مانند OPML)",
|
"importFromURLsInFile": "درون ریزی از آدرس های اینترنتی موجود در فایل (مانند OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "تشخیص نسخه",
|
"versionDetection": "تشخیص نسخه",
|
||||||
"standardVersionDetection": "تشخیص نسخه استاندارد",
|
"standardVersionDetection": "تشخیص نسخه استاندارد",
|
||||||
"groupByCategory": "گروه بر اساس دسته",
|
"groupByCategory": "گروه بر اساس دسته",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku در حال اجرا نیست",
|
"shizukuBinderNotFound": "Shizuku در حال اجرا نیست",
|
||||||
"useVersionCodeAsOSVersion": "استفاده کد نسخه برنامه به جای نسخه شناسایی شده توسط سیستم عامل استفاده کنید",
|
"useVersionCodeAsOSVersion": "استفاده کد نسخه برنامه به جای نسخه شناسایی شده توسط سیستم عامل استفاده کنید",
|
||||||
"requestHeader": "درخواست سطر بالایی",
|
"requestHeader": "درخواست سطر بالایی",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "برنامه حذف شود؟",
|
"one": "برنامه حذف شود؟",
|
||||||
"other": "برنامه ها حذف شوند؟"
|
"other": "برنامه ها حذف شوند؟"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Progrès: {}%",
|
"percentProgress": "Progrès: {}%",
|
||||||
"pleaseWait": "Veuillez patienter",
|
"pleaseWait": "Veuillez patienter",
|
||||||
"updateAvailable": "Mise à jour disponible",
|
"updateAvailable": "Mise à jour disponible",
|
||||||
"estimateInBracketsShort": "(Est.)",
|
|
||||||
"notInstalled": "Pas installé",
|
"notInstalled": "Pas installé",
|
||||||
"estimateInBrackets": "(Estimation)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Tout sélectionner",
|
"selectAll": "Tout sélectionner",
|
||||||
"deselectX": "Déselectionner {}",
|
"deselectX": "Déselectionner {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} sera supprimé d'Obtainium mais restera installé sur l'appareil.",
|
"xWillBeRemovedButRemainInstalled": "{} sera supprimé d'Obtainium mais restera installé sur l'appareil.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Changements",
|
"changes": "Changements",
|
||||||
"releaseDate": "Date de sortie",
|
"releaseDate": "Date de sortie",
|
||||||
"importFromURLsInFile": "Importer à partir d'URL dans un fichier (comme OPML)",
|
"importFromURLsInFile": "Importer à partir d'URL dans un fichier (comme OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Détection des versions",
|
"versionDetection": "Détection des versions",
|
||||||
"standardVersionDetection": "Détection de version standard",
|
"standardVersionDetection": "Détection de version standard",
|
||||||
"groupByCategory": "Group by Category",
|
"groupByCategory": "Group by Category",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Supprimer l'application ?",
|
"one": "Supprimer l'application ?",
|
||||||
"other": "Supprimer les applications ?"
|
"other": "Supprimer les applications ?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Folyamat: {}%",
|
"percentProgress": "Folyamat: {}%",
|
||||||
"pleaseWait": "Kis türelmet",
|
"pleaseWait": "Kis türelmet",
|
||||||
"updateAvailable": "Frissítés érhető el",
|
"updateAvailable": "Frissítés érhető el",
|
||||||
"estimateInBracketsShort": "(Becsült)",
|
|
||||||
"notInstalled": "Nem telepített",
|
"notInstalled": "Nem telepített",
|
||||||
"estimateInBrackets": "(Becslés)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Mindet kiválaszt",
|
"selectAll": "Mindet kiválaszt",
|
||||||
"deselectX": "Törölje {} kijelölését",
|
"deselectX": "Törölje {} kijelölését",
|
||||||
"xWillBeRemovedButRemainInstalled": "A(z) {} el lesz távolítva az Obtainiumból, de továbbra is telepítve marad az eszközön.",
|
"xWillBeRemovedButRemainInstalled": "A(z) {} el lesz távolítva az Obtainiumból, de továbbra is telepítve marad az eszközön.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Változtatások",
|
"changes": "Változtatások",
|
||||||
"releaseDate": "Kiadás dátuma",
|
"releaseDate": "Kiadás dátuma",
|
||||||
"importFromURLsInFile": "Importálás fájlban található URL-ből (mint pl. OPML)",
|
"importFromURLsInFile": "Importálás fájlban található URL-ből (mint pl. OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Verzió érzékelés",
|
"versionDetection": "Verzió érzékelés",
|
||||||
"standardVersionDetection": "Alapért. verzió érzékelés",
|
"standardVersionDetection": "Alapért. verzió érzékelés",
|
||||||
"groupByCategory": "Csoportosítás Kategória alapján",
|
"groupByCategory": "Csoportosítás Kategória alapján",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "A Shizuku nem fut",
|
"shizukuBinderNotFound": "A Shizuku nem fut",
|
||||||
"useVersionCodeAsOSVersion": "Az app versionCode használata a rendszer által észlelt verzióként",
|
"useVersionCodeAsOSVersion": "Az app versionCode használata a rendszer által észlelt verzióként",
|
||||||
"requestHeader": "Kérelem fejléc",
|
"requestHeader": "Kérelem fejléc",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Eltávolítja az alkalmazást?",
|
"one": "Eltávolítja az alkalmazást?",
|
||||||
"other": "Eltávolítja az alkalmazást?"
|
"other": "Eltávolítja az alkalmazást?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Avanzamento: {}%",
|
"percentProgress": "Avanzamento: {}%",
|
||||||
"pleaseWait": "In attesa",
|
"pleaseWait": "In attesa",
|
||||||
"updateAvailable": "Aggiornamento disponibile",
|
"updateAvailable": "Aggiornamento disponibile",
|
||||||
"estimateInBracketsShort": "(stim.)",
|
|
||||||
"notInstalled": "Non installato",
|
"notInstalled": "Non installato",
|
||||||
"estimateInBrackets": "(stimato)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Seleziona tutto",
|
"selectAll": "Seleziona tutto",
|
||||||
"deselectX": "Deseleziona {}",
|
"deselectX": "Deseleziona {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "Verà effettuata la rimozione di {}, ma non la disinstallazione.",
|
"xWillBeRemovedButRemainInstalled": "Verà effettuata la rimozione di {}, ma non la disinstallazione.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Novità",
|
"changes": "Novità",
|
||||||
"releaseDate": "Data di rilascio",
|
"releaseDate": "Data di rilascio",
|
||||||
"importFromURLsInFile": "Importa da URL in file (come OPML)",
|
"importFromURLsInFile": "Importa da URL in file (come OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Rilevamento di versione",
|
"versionDetection": "Rilevamento di versione",
|
||||||
"standardVersionDetection": "Rilevamento di versione standard",
|
"standardVersionDetection": "Rilevamento di versione standard",
|
||||||
"groupByCategory": "Raggruppa per categoria",
|
"groupByCategory": "Raggruppa per categoria",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku non è in esecuzione",
|
"shizukuBinderNotFound": "Shizuku non è in esecuzione",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Rimuovere l'app?",
|
"one": "Rimuovere l'app?",
|
||||||
"other": "Rimuovere le app?"
|
"other": "Rimuovere le app?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "ダウンロード中: {}%",
|
"percentProgress": "ダウンロード中: {}%",
|
||||||
"pleaseWait": "しばらくお待ちください",
|
"pleaseWait": "しばらくお待ちください",
|
||||||
"updateAvailable": "アップデートが利用可能",
|
"updateAvailable": "アップデートが利用可能",
|
||||||
"estimateInBracketsShort": "(推定)",
|
|
||||||
"notInstalled": "未インストール",
|
"notInstalled": "未インストール",
|
||||||
"estimateInBrackets": "(推定)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "すべて選択",
|
"selectAll": "すべて選択",
|
||||||
"deselectX": "{}件の選択を解除",
|
"deselectX": "{}件の選択を解除",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} はObtainiumから削除されますが、デバイスにはインストールされたままです。",
|
"xWillBeRemovedButRemainInstalled": "{} はObtainiumから削除されますが、デバイスにはインストールされたままです。",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "変更点",
|
"changes": "変更点",
|
||||||
"releaseDate": "リリース日",
|
"releaseDate": "リリース日",
|
||||||
"importFromURLsInFile": "ファイル(OPMLなど)内のURLからインポート",
|
"importFromURLsInFile": "ファイル(OPMLなど)内のURLからインポート",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "バージョン検出",
|
"versionDetection": "バージョン検出",
|
||||||
"standardVersionDetection": "標準のバージョン検出",
|
"standardVersionDetection": "標準のバージョン検出",
|
||||||
"groupByCategory": "カテゴリ別にグループ化する",
|
"groupByCategory": "カテゴリ別にグループ化する",
|
||||||
@@ -293,6 +293,15 @@
|
|||||||
"systemFontError": "システムフォントの読み込みエラー: {}",
|
"systemFontError": "システムフォントの読み込みエラー: {}",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "アプリを削除しますか?",
|
"one": "アプリを削除しますか?",
|
||||||
"other": "アプリを削除しますか?"
|
"other": "アプリを削除しますか?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Vooruitgang: {}%",
|
"percentProgress": "Vooruitgang: {}%",
|
||||||
"pleaseWait": "Even geduld",
|
"pleaseWait": "Even geduld",
|
||||||
"updateAvailable": "Update beschikbaar",
|
"updateAvailable": "Update beschikbaar",
|
||||||
"estimateInBracketsShort": "(Ong.)",
|
|
||||||
"notInstalled": "Niet geinstalleerd",
|
"notInstalled": "Niet geinstalleerd",
|
||||||
"estimateInBrackets": "(Ongeveer)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Selecteer alles",
|
"selectAll": "Selecteer alles",
|
||||||
"deselectX": "Deselecteer {}",
|
"deselectX": "Deselecteer {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} zal worden verwijderd uit Obtainium, maar blijft geïnstalleerd op het apparaat.",
|
"xWillBeRemovedButRemainInstalled": "{} zal worden verwijderd uit Obtainium, maar blijft geïnstalleerd op het apparaat.",
|
||||||
@@ -73,8 +72,8 @@
|
|||||||
"unpinFromTop": "Losmaken van de bovenkant",
|
"unpinFromTop": "Losmaken van de bovenkant",
|
||||||
"resetInstallStatusForSelectedAppsQuestion": "Installatiestatus resetten voor geselecteerde apps?",
|
"resetInstallStatusForSelectedAppsQuestion": "Installatiestatus resetten voor geselecteerde apps?",
|
||||||
"installStatusOfXWillBeResetExplanation": "De installatiestatus van alle geselecteerde apps zal worden gereset.\n\nDit kan helpen wanneer de versie van de app die in Obtainium wordt weergegeven onjuist is vanwege mislukte updates of andere problemen.",
|
"installStatusOfXWillBeResetExplanation": "De installatiestatus van alle geselecteerde apps zal worden gereset.\n\nDit kan helpen wanneer de versie van de app die in Obtainium wordt weergegeven onjuist is vanwege mislukte updates of andere problemen.",
|
||||||
"customLinkMessage": "These links work on devices with Obtainium installed",
|
"customLinkMessage": "Deze links werken op apparaten waarop Obtainium is geïnstalleerd",
|
||||||
"shareAppConfigLinks": "Share app configuration as HTML link",
|
"shareAppConfigLinks": "App-configuratie delen als HTML-link",
|
||||||
"shareSelectedAppURLs": "Deel geselecteerde app URL's",
|
"shareSelectedAppURLs": "Deel geselecteerde app URL's",
|
||||||
"resetInstallStatus": "Reset installatiestatus",
|
"resetInstallStatus": "Reset installatiestatus",
|
||||||
"more": "Meer",
|
"more": "Meer",
|
||||||
@@ -213,12 +212,13 @@
|
|||||||
"changes": "Veranderingen",
|
"changes": "Veranderingen",
|
||||||
"releaseDate": "Releasedatum",
|
"releaseDate": "Releasedatum",
|
||||||
"importFromURLsInFile": "Importeren vanaf URL's in een bestand (zoals OPML)",
|
"importFromURLsInFile": "Importeren vanaf URL's in een bestand (zoals OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Versieherkenning",
|
"versionDetection": "Versieherkenning",
|
||||||
"standardVersionDetection": "Standaard versieherkenning",
|
"standardVersionDetection": "Standaard versieherkenning",
|
||||||
"groupByCategory": "Groepeer op categorie",
|
"groupByCategory": "Groepeer op categorie",
|
||||||
"autoApkFilterByArch": "Poging om APK's te filteren op CPU-architectuur indien mogelijk",
|
"autoApkFilterByArch": "Poging om APK's te filteren op CPU-architectuur indien mogelijk",
|
||||||
"overrideSource": "Bron overschrijven",
|
"overrideSource": "Bron overschrijven",
|
||||||
"dontShowAgain": "Don't show this again",
|
"dontShowAgain": "Laat dit niet meer zien",
|
||||||
"dontShowTrackOnlyWarnings": "Geen waarschuwingen voor 'Track-Only' weergeven",
|
"dontShowTrackOnlyWarnings": "Geen waarschuwingen voor 'Track-Only' weergeven",
|
||||||
"dontShowAPKOriginWarnings": "APK-herkomstwaarschuwingen niet weergeven",
|
"dontShowAPKOriginWarnings": "APK-herkomstwaarschuwingen niet weergeven",
|
||||||
"moveNonInstalledAppsToBottom": "Verplaats niet-geïnstalleerde apps naar de onderkant van de apps-weergave",
|
"moveNonInstalledAppsToBottom": "Verplaats niet-geïnstalleerde apps naar de onderkant van de apps-weergave",
|
||||||
@@ -237,7 +237,7 @@
|
|||||||
"addInfoInSettings": "Voeg deze informatie toe in de instellingen.",
|
"addInfoInSettings": "Voeg deze informatie toe in de instellingen.",
|
||||||
"githubSourceNote": "Beperkingen van GitHub kunnen worden vermeden door het gebruik van een API-sleutel.",
|
"githubSourceNote": "Beperkingen van GitHub kunnen worden vermeden door het gebruik van een API-sleutel.",
|
||||||
"gitlabSourceNote": "GitLab APK-extractie werkt mogelijk niet zonder een API-sleutel.",
|
"gitlabSourceNote": "GitLab APK-extractie werkt mogelijk niet zonder een API-sleutel.",
|
||||||
"sortByLastLinkSegment": "Sort by only the last segment of the link",
|
"sortByLastLinkSegment": "Sorteren op alleen het laatste segment van de link",
|
||||||
"filterReleaseNotesByRegEx": "Filter release-opmerkingen met een reguliere expressie.",
|
"filterReleaseNotesByRegEx": "Filter release-opmerkingen met een reguliere expressie.",
|
||||||
"customLinkFilterRegex": "Aangepaste APK-linkfilter met een reguliere expressie (Standaard '.apk$').",
|
"customLinkFilterRegex": "Aangepaste APK-linkfilter met een reguliere expressie (Standaard '.apk$').",
|
||||||
"appsPossiblyUpdated": "Poging tot app-updates",
|
"appsPossiblyUpdated": "Poging tot app-updates",
|
||||||
@@ -247,10 +247,10 @@
|
|||||||
"backgroundUpdateReqsExplanation": "Achtergrondupdates zijn mogelijk niet voor alle apps mogelijk.",
|
"backgroundUpdateReqsExplanation": "Achtergrondupdates zijn mogelijk niet voor alle apps mogelijk.",
|
||||||
"backgroundUpdateLimitsExplanation": "Het succes van een installatie in de achtergrond kan alleen worden bepaald wanneer Obtainium is geopend.",
|
"backgroundUpdateLimitsExplanation": "Het succes van een installatie in de achtergrond kan alleen worden bepaald wanneer Obtainium is geopend.",
|
||||||
"verifyLatestTag": "Verifieer de 'Laatste'-tag",
|
"verifyLatestTag": "Verifieer de 'Laatste'-tag",
|
||||||
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit",
|
"intermediateLinkRegex": "Filter voor een 'Intermediaire' link om te bezoeken",
|
||||||
"filterByLinkText": "Filter links by link text",
|
"filterByLinkText": "Links filteren op linktekst",
|
||||||
"intermediateLinkNotFound": "Tussenliggende link niet gevonden",
|
"intermediateLinkNotFound": "Tussenliggende link niet gevonden",
|
||||||
"intermediateLink": "Intermediate link",
|
"intermediateLink": "Intermediaire link",
|
||||||
"exemptFromBackgroundUpdates": "Vrijgesteld van achtergrondupdates (indien ingeschakeld)",
|
"exemptFromBackgroundUpdates": "Vrijgesteld van achtergrondupdates (indien ingeschakeld)",
|
||||||
"bgUpdatesOnWiFiOnly": "Achtergrondupdates uitschakelen wanneer niet verbonden met WiFi",
|
"bgUpdatesOnWiFiOnly": "Achtergrondupdates uitschakelen wanneer niet verbonden met WiFi",
|
||||||
"autoSelectHighestVersionCode": "Automatisch de APK met de hoogste versiecode selecteren",
|
"autoSelectHighestVersionCode": "Automatisch de APK met de hoogste versiecode selecteren",
|
||||||
@@ -259,13 +259,13 @@
|
|||||||
"highlightTouchTargets": "Markeer minder voor de hand liggende aanraakdoelen.",
|
"highlightTouchTargets": "Markeer minder voor de hand liggende aanraakdoelen.",
|
||||||
"pickExportDir": "Kies de exportmap",
|
"pickExportDir": "Kies de exportmap",
|
||||||
"autoExportOnChanges": "Automatisch exporteren bij wijzigingen",
|
"autoExportOnChanges": "Automatisch exporteren bij wijzigingen",
|
||||||
"includeSettings": "Include settings",
|
"includeSettings": "Instellingen opnemen",
|
||||||
"filterVersionsByRegEx": "Filter versies met een reguliere expressie",
|
"filterVersionsByRegEx": "Filter versies met een reguliere expressie",
|
||||||
"trySelectingSuggestedVersionCode": "Probeer de voorgestelde versiecode APK te selecteren",
|
"trySelectingSuggestedVersionCode": "Probeer de voorgestelde versiecode APK te selecteren",
|
||||||
"dontSortReleasesList": "Volgorde van releases behouden vanuit de API",
|
"dontSortReleasesList": "Volgorde van releases behouden vanuit de API",
|
||||||
"reverseSort": "Sortering omkeren",
|
"reverseSort": "Sortering omkeren",
|
||||||
"takeFirstLink": "Take first link",
|
"takeFirstLink": "Neem de eerste link",
|
||||||
"skipSort": "Skip sorting",
|
"skipSort": "Sorteren overslaan",
|
||||||
"debugMenu": "Debug menu",
|
"debugMenu": "Debug menu",
|
||||||
"bgTaskStarted": "Achtergrondtaak gestart - controleer de logs.",
|
"bgTaskStarted": "Achtergrondtaak gestart - controleer de logs.",
|
||||||
"runBgCheckNow": "Voer nu een achtergrondupdatecontrole uit",
|
"runBgCheckNow": "Voer nu een achtergrondupdatecontrole uit",
|
||||||
@@ -281,16 +281,25 @@
|
|||||||
"completeAppInstallationNotifChannel": "Voltooien van de app-installatie",
|
"completeAppInstallationNotifChannel": "Voltooien van de app-installatie",
|
||||||
"checkingForUpdatesNotifChannel": "Controleren op updates",
|
"checkingForUpdatesNotifChannel": "Controleren op updates",
|
||||||
"onlyCheckInstalledOrTrackOnlyApps": "Alleen geïnstalleerde en Track-Only apps controleren op updates",
|
"onlyCheckInstalledOrTrackOnlyApps": "Alleen geïnstalleerde en Track-Only apps controleren op updates",
|
||||||
"supportFixedAPKURL": "Support fixed APK URLs",
|
"supportFixedAPKURL": "Ondersteuning vaste APK URL's",
|
||||||
"selectX": "Select {}",
|
"selectX": "Selecteer {}",
|
||||||
"parallelDownloads": "Allow parallel downloads",
|
"parallelDownloads": "Parallelle downloads toestaan",
|
||||||
"installMethod": "Installation method",
|
"installMethod": "Installatiemethode",
|
||||||
"normal": "Normal",
|
"normal": "Normaal",
|
||||||
"shizuku": "Shizuku",
|
"shizuku": "Shizuku",
|
||||||
"root": "Root",
|
"root": "Root",
|
||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku draait niet",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Gebruik app versieCode als door OS gedetecteerde versie",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Gebruik laatste upload als releasedatum",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "App verwijderen?",
|
"one": "App verwijderen?",
|
||||||
"other": "Apps verwijderen?"
|
"other": "Apps verwijderen?"
|
||||||
@@ -343,4 +352,4 @@
|
|||||||
"one": "{} en nog 1 app zijn mogelijk bijgewerkt.",
|
"one": "{} en nog 1 app zijn mogelijk bijgewerkt.",
|
||||||
"other": "{} en {} meer apps zijn mogelijk bijgwerkt."
|
"other": "{} en {} meer apps zijn mogelijk bijgwerkt."
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Postęp: {}%",
|
"percentProgress": "Postęp: {}%",
|
||||||
"pleaseWait": "Proszę czekać",
|
"pleaseWait": "Proszę czekać",
|
||||||
"updateAvailable": "Dostępna aktualizacja",
|
"updateAvailable": "Dostępna aktualizacja",
|
||||||
"estimateInBracketsShort": "(Szac.)",
|
|
||||||
"notInstalled": "Nie zainstalowano",
|
"notInstalled": "Nie zainstalowano",
|
||||||
"estimateInBrackets": "(Szacunkowo)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Zaznacz wszystkie",
|
"selectAll": "Zaznacz wszystkie",
|
||||||
"deselectX": "Odznacz {}",
|
"deselectX": "Odznacz {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} zostanie usunięty z Obtainium, ale pozostanie zainstalowany na urządzeniu.",
|
"xWillBeRemovedButRemainInstalled": "{} zostanie usunięty z Obtainium, ale pozostanie zainstalowany na urządzeniu.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Zmiany",
|
"changes": "Zmiany",
|
||||||
"releaseDate": "Data wydania",
|
"releaseDate": "Data wydania",
|
||||||
"importFromURLsInFile": "Importuj z adresów URL w pliku (typu OPML)",
|
"importFromURLsInFile": "Importuj z adresów URL w pliku (typu OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Wykrywanie wersji",
|
"versionDetection": "Wykrywanie wersji",
|
||||||
"standardVersionDetection": "Standardowe wykrywanie wersji",
|
"standardVersionDetection": "Standardowe wykrywanie wersji",
|
||||||
"groupByCategory": "Grupuj według kategorii",
|
"groupByCategory": "Grupuj według kategorii",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Usunąć aplikację?",
|
"one": "Usunąć aplikację?",
|
||||||
"few": "Usunąć aplikacje?",
|
"few": "Usunąć aplikacje?",
|
||||||
|
@@ -54,6 +54,7 @@
|
|||||||
"estimateInBracketsShort": "(Aprox.)",
|
"estimateInBracketsShort": "(Aprox.)",
|
||||||
"notInstalled": "Não instalado",
|
"notInstalled": "Não instalado",
|
||||||
"estimateInBrackets": "(Aproximado)",
|
"estimateInBrackets": "(Aproximado)",
|
||||||
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Selecionar todos",
|
"selectAll": "Selecionar todos",
|
||||||
"deselectX": "Deselecionar {}",
|
"deselectX": "Deselecionar {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} será removido do Obtainium mais permanecerá instalado no dispositivo.",
|
"xWillBeRemovedButRemainInstalled": "{} será removido do Obtainium mais permanecerá instalado no dispositivo.",
|
||||||
@@ -213,7 +214,7 @@
|
|||||||
"changes": "Mudanças",
|
"changes": "Mudanças",
|
||||||
"releaseDate": "Data de lançamento",
|
"releaseDate": "Data de lançamento",
|
||||||
"importFromURLsInFile": "Importar de URLs em arquivo (como OPML)",
|
"importFromURLsInFile": "Importar de URLs em arquivo (como OPML)",
|
||||||
"versionDetection": "Detecção de Versão",
|
"versionDetection": "Detecção de versão",
|
||||||
"standardVersionDetection": "Detecção de versão padrão",
|
"standardVersionDetection": "Detecção de versão padrão",
|
||||||
"groupByCategory": "Agroupar por categoria",
|
"groupByCategory": "Agroupar por categoria",
|
||||||
"autoApkFilterByArch": "Tente filtrar APKs por arquitetura de CPU, se possível",
|
"autoApkFilterByArch": "Tente filtrar APKs por arquitetura de CPU, se possível",
|
||||||
@@ -222,81 +223,91 @@
|
|||||||
"dontShowTrackOnlyWarnings": "Não mostrar avisos 'Apenas Monitorar'",
|
"dontShowTrackOnlyWarnings": "Não mostrar avisos 'Apenas Monitorar'",
|
||||||
"dontShowAPKOriginWarnings": "Não mostrar avisos de origem da APK",
|
"dontShowAPKOriginWarnings": "Não mostrar avisos de origem da APK",
|
||||||
"moveNonInstalledAppsToBottom": "Mover aplicativos não instalados para o fundo da lista de aplicativos",
|
"moveNonInstalledAppsToBottom": "Mover aplicativos não instalados para o fundo da lista de aplicativos",
|
||||||
"gitlabPATLabel": "Token de Acceso Pessoal do Gitlab\n(Ativa Pesquisa e Melhor Descoberta de APKs)",
|
"gitlabPATLabel": "Token de Acesso Pessoal do Gitlab\n(Ativa pesquisa e melhora a descoberta de APKs)",
|
||||||
"about": "Sobre",
|
"about": "Sobre",
|
||||||
"requiresCredentialsInSettings": "{}: Isso requer credenciais adicionais (em Configurações)",
|
"requiresCredentialsInSettings": "{}: Isso requer credenciais adicionais (em Configurações)",
|
||||||
"checkOnStart": "Checar por atualizações ao iniciar ",
|
"checkOnStart": "Verificar se há atualizações ao iniciar",
|
||||||
"tryInferAppIdFromCode": "Tente inferir o ID do aplicativo pelo código-fonte",
|
"tryInferAppIdFromCode": "Tente inferir o ID do aplicativo pelo código-fonte",
|
||||||
"removeOnExternalUninstall": "Remover automaticamente aplicativos desinstalados externamente",
|
"removeOnExternalUninstall": "Remover automaticamente aplicativos desinstalados externamente",
|
||||||
"pickHighestVersionCode": "Auto-selecionar o maior numero de versão do APK",
|
"pickHighestVersionCode": "Auto-selecionar o maior número de versão do APK",
|
||||||
"checkUpdateOnDetailPage": "Checar por atualizações ao abrir a página de detalhes de um aplicativo",
|
"checkUpdateOnDetailPage": "Checar por atualizações ao abrir a página de detalhes de um aplicativo",
|
||||||
"disablePageTransitions": "Desativar animações de transição de pagina",
|
"disablePageTransitions": "Desativar animações de transição de página",
|
||||||
"reversePageTransitions": "Reverter animações de transição de pagina",
|
"reversePageTransitions": "Reverter animações de transição de página",
|
||||||
"minStarCount": "Contagem Minima de Estrelas",
|
"minStarCount": "Contagem mínima de estrelas",
|
||||||
"addInfoBelow": "Adicionar essa informação abaixo.",
|
"addInfoBelow": "Adicionar essa informação abaixo.",
|
||||||
"addInfoInSettings": "Adicionar essa informação nas configurações.",
|
"addInfoInSettings": "Adicionar essa informação nas configurações.",
|
||||||
"githubSourceNote": "A limitação de taxa do GitHub pode ser evitada usando uma chave de API.",
|
"githubSourceNote": "A limitação de taxa do GitHub pode ser evitada usando uma chave de API.",
|
||||||
"gitlabSourceNote": "A extração de APK do GitLab pode não funcionar sem uma chave de API.",
|
"gitlabSourceNote": "A extração de endereço de download do APK no GitLab provavelmente não funcione sem que seja fornecido uma chave de API.",
|
||||||
"sortByLastLinkSegment": "Sort by only the last segment of the link",
|
"sortByLastLinkSegment": "Ordenar apenas usando o último segmento do link",
|
||||||
"filterReleaseNotesByRegEx": "Filtrar Notas de Lançamento por Expressão Regular",
|
"filterReleaseNotesByRegEx": "Filtrar notas de versão usando Regex",
|
||||||
"customLinkFilterRegex": "Filtro de Link Personalizado por Expressão Regular (Padrão '.apk$')",
|
"customLinkFilterRegex": "Filtro de link personalizado usando expressão regular (Padrão '.apk$')",
|
||||||
"appsPossiblyUpdated": "Tentativas de atualização de aplicativos",
|
"appsPossiblyUpdated": "Tentativas de atualização de aplicativos",
|
||||||
"appsPossiblyUpdatedNotifDescription": "Notifica o usuário de que atualizações de um ou mais aplicativos foram potencialmente aplicadas em segundo-plano",
|
"appsPossiblyUpdatedNotifDescription": "Notifica o usuário de que atualizações de um ou mais aplicativos foram potencialmente aplicadas em segundo-plano",
|
||||||
"xWasPossiblyUpdatedToY": "{} pode ter sido atualizado para {}.",
|
"xWasPossiblyUpdatedToY": "{} pode ter sido atualizado para {}.",
|
||||||
"enableBackgroundUpdates": "Ativar atualizações em segundo-plano",
|
"enableBackgroundUpdates": "Ativar atualizações em segundo-plano",
|
||||||
"backgroundUpdateReqsExplanation": "Atualizações em segundo-plano podem não ser possíveis para todos os aplicativos.",
|
"backgroundUpdateReqsExplanation": "Atualizações em segundo-plano podem não ser possíveis para todos os aplicativos.",
|
||||||
"backgroundUpdateLimitsExplanation": "O sucesso de uma instalação em segundo-plano só pode ser determinado quando o Obtainium é aberto.",
|
"backgroundUpdateLimitsExplanation": "O sucesso de uma instalação em segundo-plano só pode ser determinado quando o Obtainium é aberto.",
|
||||||
"verifyLatestTag": "Verifique a 'ultima' etiqueta",
|
"verifyLatestTag": "Verifique a 'última' etiqueta",
|
||||||
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit",
|
"intermediateLinkRegex": "Filter for an 'Intermediate' Link to Visit",
|
||||||
"filterByLinkText": "Filter links by link text",
|
"filterByLinkText": "Filtrar links pelo texto do link",
|
||||||
"intermediateLinkNotFound": "Link intermediário não encontrado",
|
"intermediateLinkNotFound": "Link intermediário não encontrado",
|
||||||
"intermediateLink": "Intermediate link",
|
"intermediateLink": "Link intermediário",
|
||||||
"exemptFromBackgroundUpdates": "Isento de atualizações em segundo-plano (se ativadas)",
|
"exemptFromBackgroundUpdates": "Isento de atualizações em segundo-plano (se ativadas)",
|
||||||
"bgUpdatesOnWiFiOnly": "Desative atualizações em segundo-plano quando não estiver em WiFi",
|
"bgUpdatesOnWiFiOnly": "Desative as atualizações em segundo-plano quando não estiver conectado no Wi-Fi",
|
||||||
"autoSelectHighestVersionCode": "Auto-selecionar o maior codigo de versão",
|
"autoSelectHighestVersionCode": "Auto-selecionar a versão mais recente",
|
||||||
"versionExtractionRegEx": "RegEx para Extração de Versão",
|
"versionExtractionRegEx": "Regex de extração de versão",
|
||||||
"matchGroupToUse": "Grupo de Seleção para Usar",
|
"matchGroupToUse": "Grupo correspondente a ser usado no Regex de extração de versão",
|
||||||
"highlightTouchTargets": "Destaque areas de toque menos óbvias",
|
"highlightTouchTargets": "Realçar áreas sensíveis ao toque que são menos óbvias",
|
||||||
"pickExportDir": "Escolher Diretorio de Exportação",
|
"pickExportDir": "Escolher diretório para a exportação",
|
||||||
"autoExportOnChanges": "Auto-exportar em mudanças",
|
"autoExportOnChanges": "Auto-exportar em mudanças",
|
||||||
"includeSettings": "Include settings",
|
"includeSettings": "Incluir configurações",
|
||||||
"filterVersionsByRegEx": "Filtrar Versões por Expressão Regular",
|
"filterVersionsByRegEx": "Filtrar versões por expressão regular",
|
||||||
"trySelectingSuggestedVersionCode": "Tente selecionar a versão sugerida",
|
"trySelectingSuggestedVersionCode": "Tente selecionar a versão sugerida",
|
||||||
"dontSortReleasesList": "Reter a ordem de lançamento da API",
|
"dontSortReleasesList": "Reter a ordem de lançamento da API",
|
||||||
"reverseSort": "Ordenação reversa",
|
"reverseSort": "Ordenação reversa",
|
||||||
"takeFirstLink": "Take first link",
|
"takeFirstLink": "Obter primeiro link",
|
||||||
"skipSort": "Skip sorting",
|
"skipSort": "Ignorar ordenação",
|
||||||
"debugMenu": "Menu Debug",
|
"debugMenu": "Menu debug",
|
||||||
"bgTaskStarted": "Tarefa em segundo-plano iniciada - verifique os logs.",
|
"bgTaskStarted": "Tarefa em segundo-plano iniciada - verifique os logs.",
|
||||||
"runBgCheckNow": "Execute a verificação de atualização em segundo-plano agora",
|
"runBgCheckNow": "Execute agora em segundo-plano a verificação de atualizações",
|
||||||
"versionExtractWholePage": "Aplicar Regex de Extração de Versão à Página Inteira",
|
"versionExtractWholePage": "Aplicar regex de extração de versão à página inteira",
|
||||||
"installing": "Instalando",
|
"installing": "Instalando",
|
||||||
"skipUpdateNotifications": "Pular notificações de update",
|
"skipUpdateNotifications": "Pular notificações de update",
|
||||||
"updatesAvailableNotifChannel": "Atualizações Disponíveis",
|
"updatesAvailableNotifChannel": "Atualizações disponíveis",
|
||||||
"appsUpdatedNotifChannel": "Aplicativos Atualizados",
|
"appsUpdatedNotifChannel": "Aplicativos atualizados",
|
||||||
"appsPossiblyUpdatedNotifChannel": "Tentativas de atualização de aplicativos",
|
"appsPossiblyUpdatedNotifChannel": "Tentativas de atualização de aplicativos",
|
||||||
"errorCheckingUpdatesNotifChannel": "Erro ao Procurar por Atualizações",
|
"errorCheckingUpdatesNotifChannel": "Erro ao Procurar por Atualizações",
|
||||||
"appsRemovedNotifChannel": "Aplicativos Removidos",
|
"appsRemovedNotifChannel": "Aplicativos removidos",
|
||||||
"downloadingXNotifChannel": "Baixando {}",
|
"downloadingXNotifChannel": "Baixando {}",
|
||||||
"completeAppInstallationNotifChannel": "Instalação completa do aplicativo",
|
"completeAppInstallationNotifChannel": "Instalação completa do aplicativo",
|
||||||
"checkingForUpdatesNotifChannel": "Checando por Atualizações",
|
"checkingForUpdatesNotifChannel": "Checando por Atualizações",
|
||||||
"onlyCheckInstalledOrTrackOnlyApps": "Apenas checar apps instalados e 'Apenas Seguir' por updates",
|
"onlyCheckInstalledOrTrackOnlyApps": "Apenas checar aplicativos instalados e 'Apenas Seguir' por updates",
|
||||||
"supportFixedAPKURL": "Suporte APK com URLs fixas",
|
"supportFixedAPKURL": "Suporte a APK com URLs fixas",
|
||||||
"selectX": "Selecionar {}",
|
"selectX": "Selecionar {}",
|
||||||
"parallelDownloads": "Permitir downloads paralelos",
|
"parallelDownloads": "Permitir downloads paralelos",
|
||||||
"installMethod": "Método de instalação",
|
"installMethod": "Método de instalação",
|
||||||
"normal": "Normal",
|
"normal": "Normal",
|
||||||
"shizuku": "Shizuku",
|
"shizuku": "Shizuku",
|
||||||
"root": "Root",
|
"root": "Root",
|
||||||
"shizukuBinderNotFound": "Shizuku não está rodando",
|
"shizukuBinderNotFound": "O Shizuku não está rodando",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"useSystemFont": "Usar fonte padrão do sistema",
|
||||||
|
"systemFontError": "Erro ao carregar a fonte do sistema: {}",
|
||||||
|
"requestHeader": "Requisitar cabeçalho",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Remover aplicativo?",
|
"one": "Remover aplicativo?",
|
||||||
"other": "Remover aplicativos?"
|
"other": "Remover aplicativos?"
|
||||||
},
|
},
|
||||||
"tooManyRequestsTryAgainInMinutes": {
|
"tooManyRequestsTryAgainInMinutes": {
|
||||||
"one": "Muitas solicitações (taxa limitada) - tente novamente em {} minuto",
|
"one": "Muitas solicitações (taxa de solicitações limitada) - tente novamente em {} minuto",
|
||||||
"other": "Muitas solicitações (taxa limitada) - tente novamente em {} minutos"
|
"other": "Muitas solicitações (taxa limitada) - tente novamente em {} minutos"
|
||||||
},
|
},
|
||||||
"bgUpdateGotErrorRetryInMinutes": {
|
"bgUpdateGotErrorRetryInMinutes": {
|
||||||
@@ -328,19 +339,19 @@
|
|||||||
"other": "{} Dias"
|
"other": "{} Dias"
|
||||||
},
|
},
|
||||||
"clearedNLogsBeforeXAfterY": {
|
"clearedNLogsBeforeXAfterY": {
|
||||||
"one": "Limpo {n} log (antes = {antes}, depois = {depois})",
|
"one": "Foi limpo {n} log (antes = {antes}, depois = {depois})",
|
||||||
"other": "Limpados {n} logs (antes = {antes}, depois = {depois})"
|
"other": "Foram limpos {n} logs (antes = {antes}, depois = {depois})"
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesAvailable": {
|
"xAndNMoreUpdatesAvailable": {
|
||||||
"one": "{} e 1 outro app tem atualizações.",
|
"one": "{} e 1 outro aplicativo possui atualizações.",
|
||||||
"other": "{} e {} outros apps tem atualizações."
|
"other": "{} e {} outros aplicativo possuem atualizações."
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesInstalled": {
|
"xAndNMoreUpdatesInstalled": {
|
||||||
"one": "{} e 1 outro app foi atualizado.",
|
"one": "{} e um outro aplicativo foi atualizado.",
|
||||||
"other": "{} e {} outros apps foram atualizados."
|
"other": "{} e {} outros aplicativos foram atualizados."
|
||||||
},
|
},
|
||||||
"xAndNMoreUpdatesPossiblyInstalled": {
|
"xAndNMoreUpdatesPossiblyInstalled": {
|
||||||
"one": "{} e 1 outro app pode ter sido atualizado.",
|
"one": "{} e 1 outro aplicativo pode ter sido atualizado.",
|
||||||
"other": "{} e {} outros apps podem ter sido atualizados."
|
"other": "{} e {} outros aplicativos podem ter sido atualizados."
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Прогресс: {}%",
|
"percentProgress": "Прогресс: {}%",
|
||||||
"pleaseWait": "Пожалуйста, подождите",
|
"pleaseWait": "Пожалуйста, подождите",
|
||||||
"updateAvailable": "Доступно обновление",
|
"updateAvailable": "Доступно обновление",
|
||||||
"estimateInBracketsShort": "(Оценка)",
|
|
||||||
"notInstalled": "Не установлено",
|
"notInstalled": "Не установлено",
|
||||||
"estimateInBrackets": "(Оценка)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Выбрать всё",
|
"selectAll": "Выбрать всё",
|
||||||
"deselectX": "Отменить выбор {}",
|
"deselectX": "Отменить выбор {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} будет удалено из Obtainium, но останется на устройстве",
|
"xWillBeRemovedButRemainInstalled": "{} будет удалено из Obtainium, но останется на устройстве",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Изменения",
|
"changes": "Изменения",
|
||||||
"releaseDate": "Дата выпуска",
|
"releaseDate": "Дата выпуска",
|
||||||
"importFromURLsInFile": "Импорт из файла URL-адресов (например: OPML)",
|
"importFromURLsInFile": "Импорт из файла URL-адресов (например: OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Определение версии",
|
"versionDetection": "Определение версии",
|
||||||
"standardVersionDetection": "Стандартное",
|
"standardVersionDetection": "Стандартное",
|
||||||
"groupByCategory": "Группировать по категориям",
|
"groupByCategory": "Группировать по категориям",
|
||||||
@@ -293,6 +293,15 @@
|
|||||||
"systemFontError": "Ошибка загрузки системного шрифта: {}",
|
"systemFontError": "Ошибка загрузки системного шрифта: {}",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Удалить приложение?",
|
"one": "Удалить приложение?",
|
||||||
"other": "Удалить приложения?"
|
"other": "Удалить приложения?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Progress: {}%",
|
"percentProgress": "Progress: {}%",
|
||||||
"pleaseWait": "Vänta",
|
"pleaseWait": "Vänta",
|
||||||
"updateAvailable": "Uppdatering Tillgänglig",
|
"updateAvailable": "Uppdatering Tillgänglig",
|
||||||
"estimateInBracketsShort": "(Est.)",
|
|
||||||
"notInstalled": "Inte Installerad",
|
"notInstalled": "Inte Installerad",
|
||||||
"estimateInBrackets": "(Uppskattning)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Välj Alla",
|
"selectAll": "Välj Alla",
|
||||||
"deselectX": "Avmarkera {}",
|
"deselectX": "Avmarkera {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} kommer tas bort från Obtainium men kommer vara fortsatt installerad på enheten.",
|
"xWillBeRemovedButRemainInstalled": "{} kommer tas bort från Obtainium men kommer vara fortsatt installerad på enheten.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Ändringar",
|
"changes": "Ändringar",
|
||||||
"releaseDate": "Releasedatum",
|
"releaseDate": "Releasedatum",
|
||||||
"importFromURLsInFile": "Importera från URL:er i fil (som OPML)",
|
"importFromURLsInFile": "Importera från URL:er i fil (som OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Versionsdetektering",
|
"versionDetection": "Versionsdetektering",
|
||||||
"standardVersionDetection": "Standardversionsdetektering",
|
"standardVersionDetection": "Standardversionsdetektering",
|
||||||
"groupByCategory": "Gruppera via Kategori",
|
"groupByCategory": "Gruppera via Kategori",
|
||||||
@@ -277,6 +277,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Ta Bort App?",
|
"one": "Ta Bort App?",
|
||||||
"other": "Ta Bort Appar?"
|
"other": "Ta Bort Appar?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "İlerleme: {}%",
|
"percentProgress": "İlerleme: {}%",
|
||||||
"pleaseWait": "Lütfen Bekleyin",
|
"pleaseWait": "Lütfen Bekleyin",
|
||||||
"updateAvailable": "Güncelleme Var",
|
"updateAvailable": "Güncelleme Var",
|
||||||
"estimateInBracketsShort": "(Est.)",
|
|
||||||
"notInstalled": "Yüklenmedi",
|
"notInstalled": "Yüklenmedi",
|
||||||
"estimateInBrackets": "(Tahmini)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Hepsini Seç",
|
"selectAll": "Hepsini Seç",
|
||||||
"deselectX": "{}'yi Seçimden Kaldır",
|
"deselectX": "{}'yi Seçimden Kaldır",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} Obtainium'dan kaldırılacak ancak cihazınızda yüklü kalacaktır.",
|
"xWillBeRemovedButRemainInstalled": "{} Obtainium'dan kaldırılacak ancak cihazınızda yüklü kalacaktır.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Değişiklikler",
|
"changes": "Değişiklikler",
|
||||||
"releaseDate": "Yayın Tarihi",
|
"releaseDate": "Yayın Tarihi",
|
||||||
"importFromURLsInFile": "Dosyadaki URL'lerden İçe Aktar",
|
"importFromURLsInFile": "Dosyadaki URL'lerden İçe Aktar",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Sürüm Tespiti",
|
"versionDetection": "Sürüm Tespiti",
|
||||||
"standardVersionDetection": "Standart sürüm tespiti",
|
"standardVersionDetection": "Standart sürüm tespiti",
|
||||||
"groupByCategory": "Kategoriye Göre Grupla",
|
"groupByCategory": "Kategoriye Göre Grupla",
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
"shizukuBinderNotFound": "Shizuku is not running",
|
"shizukuBinderNotFound": "Shizuku is not running",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "Uygulamayı Kaldır?",
|
"one": "Uygulamayı Kaldır?",
|
||||||
"other": "Uygulamaları Kaldır?"
|
"other": "Uygulamaları Kaldır?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "Đang tải {}%",
|
"percentProgress": "Đang tải {}%",
|
||||||
"pleaseWait": "Vui lòng chờ",
|
"pleaseWait": "Vui lòng chờ",
|
||||||
"updateAvailable": "Có sẵn bản cập nhật",
|
"updateAvailable": "Có sẵn bản cập nhật",
|
||||||
"estimateInBracketsShort": "(Ước lượng.)",
|
|
||||||
"notInstalled": "Chưa cài đặt",
|
"notInstalled": "Chưa cài đặt",
|
||||||
"estimateInBrackets": "(Ước lượng)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "Chọn tất cả",
|
"selectAll": "Chọn tất cả",
|
||||||
"deselectX": "Bỏ chọn {}",
|
"deselectX": "Bỏ chọn {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "{} sẽ bị xóa khỏi Obtainium nhưng vẫn còn cài đặt trên thiết bị.",
|
"xWillBeRemovedButRemainInstalled": "{} sẽ bị xóa khỏi Obtainium nhưng vẫn còn cài đặt trên thiết bị.",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "Thay đổi",
|
"changes": "Thay đổi",
|
||||||
"releaseDate": "Ngày phát hành",
|
"releaseDate": "Ngày phát hành",
|
||||||
"importFromURLsInFile": "Nhập từ URL trong Tệp (như OPML)",
|
"importFromURLsInFile": "Nhập từ URL trong Tệp (như OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "Phát hiện phiên bản",
|
"versionDetection": "Phát hiện phiên bản",
|
||||||
"standardVersionDetection": "Phát hiện phiên bản tiêu chuẩn",
|
"standardVersionDetection": "Phát hiện phiên bản tiêu chuẩn",
|
||||||
"groupByCategory": "Nhóm theo thể loại",
|
"groupByCategory": "Nhóm theo thể loại",
|
||||||
@@ -289,6 +289,15 @@
|
|||||||
"shizuku": "Shizuku",
|
"shizuku": "Shizuku",
|
||||||
"root": "Root",
|
"root": "Root",
|
||||||
"shizukuBinderNotFound": "Shizuku chưa khởi động",
|
"shizukuBinderNotFound": "Shizuku chưa khởi động",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion":{
|
"removeAppQuestion":{
|
||||||
"one": "Gỡ ứng dụng?",
|
"one": "Gỡ ứng dụng?",
|
||||||
"other": "Gỡ ứng dụng?"
|
"other": "Gỡ ứng dụng?"
|
||||||
|
@@ -51,9 +51,8 @@
|
|||||||
"percentProgress": "进度:{}%",
|
"percentProgress": "进度:{}%",
|
||||||
"pleaseWait": "请稍候",
|
"pleaseWait": "请稍候",
|
||||||
"updateAvailable": "更新可用",
|
"updateAvailable": "更新可用",
|
||||||
"estimateInBracketsShort": "(推测)",
|
|
||||||
"notInstalled": "未安装",
|
"notInstalled": "未安装",
|
||||||
"estimateInBrackets": "(推测)",
|
"pseudoVersion": "pseudo-version",
|
||||||
"selectAll": "全选",
|
"selectAll": "全选",
|
||||||
"deselectX": "取消选择 {}",
|
"deselectX": "取消选择 {}",
|
||||||
"xWillBeRemovedButRemainInstalled": "“{}”将从 Obtainium 中删除,但仍安装在您的设备中。",
|
"xWillBeRemovedButRemainInstalled": "“{}”将从 Obtainium 中删除,但仍安装在您的设备中。",
|
||||||
@@ -213,6 +212,7 @@
|
|||||||
"changes": "更新日志",
|
"changes": "更新日志",
|
||||||
"releaseDate": "发行日期",
|
"releaseDate": "发行日期",
|
||||||
"importFromURLsInFile": "从文件中的 URL 导入(如 OPML)",
|
"importFromURLsInFile": "从文件中的 URL 导入(如 OPML)",
|
||||||
|
"versionDetectionExplanation": "Reconcile version string with version detected from OS",
|
||||||
"versionDetection": "版本检测",
|
"versionDetection": "版本检测",
|
||||||
"standardVersionDetection": "常规版本检测",
|
"standardVersionDetection": "常规版本检测",
|
||||||
"groupByCategory": "按类别分组显示",
|
"groupByCategory": "按类别分组显示",
|
||||||
@@ -293,6 +293,15 @@
|
|||||||
"systemFontError": "加载系统字体出错:{}",
|
"systemFontError": "加载系统字体出错:{}",
|
||||||
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
"useVersionCodeAsOSVersion": "Use app versionCode as OS-detected version",
|
||||||
"requestHeader": "Request header",
|
"requestHeader": "Request header",
|
||||||
|
"useLatestAssetDateAsReleaseDate": "Use latest asset upload as release date",
|
||||||
|
"defaultPseudoVersioningMethod": "Default Pseudo-Versioning Method",
|
||||||
|
"partialAPKHash": "Partial APK Hash",
|
||||||
|
"APKLinkHash": "APK Link Hash",
|
||||||
|
"directAPKLink": "Direct APK Link",
|
||||||
|
"pseudoVersionInUse": "A Pseudo-Version is in Use",
|
||||||
|
"installed": "Installed",
|
||||||
|
"latest": "Latest",
|
||||||
|
"invertRegEx": "Invert regular expression",
|
||||||
"removeAppQuestion": {
|
"removeAppQuestion": {
|
||||||
"one": "是否删除应用?",
|
"one": "是否删除应用?",
|
||||||
"other": "是否删除应用?"
|
"other": "是否删除应用?"
|
||||||
|
@@ -6,6 +6,7 @@ import 'package:obtainium/providers/source_provider.dart';
|
|||||||
class APKCombo extends AppSource {
|
class APKCombo extends AppSource {
|
||||||
APKCombo() {
|
APKCombo() {
|
||||||
hosts = ['apkcombo.com'];
|
hosts = ['apkcombo.com'];
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -11,6 +11,7 @@ class APKMirror extends AppSource {
|
|||||||
APKMirror() {
|
APKMirror() {
|
||||||
hosts = ['apkmirror.com'];
|
hosts = ['apkmirror.com'];
|
||||||
enforceTrackOnly = true;
|
enforceTrackOnly = true;
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
|
|
||||||
additionalSourceAppSpecificSettingFormItems = [
|
additionalSourceAppSpecificSettingFormItems = [
|
||||||
[
|
[
|
||||||
|
@@ -23,6 +23,7 @@ class APKPure extends AppSource {
|
|||||||
hosts = ['apkpure.net', 'apkpure.com'];
|
hosts = ['apkpure.net', 'apkpure.com'];
|
||||||
allowSubDomains = true;
|
allowSubDomains = true;
|
||||||
naiveStandardVersionDetection = true;
|
naiveStandardVersionDetection = true;
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -10,6 +10,7 @@ class Aptoide extends AppSource {
|
|||||||
name = 'Aptoide';
|
name = 'Aptoide';
|
||||||
allowSubDomains = true;
|
allowSubDomains = true;
|
||||||
naiveStandardVersionDetection = true;
|
naiveStandardVersionDetection = true;
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
44
lib/app_sources/directAPKLink.dart
Normal file
44
lib/app_sources/directAPKLink.dart
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:obtainium/app_sources/html.dart';
|
||||||
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
|
|
||||||
|
class DirectAPKLink extends AppSource {
|
||||||
|
HTML html = HTML();
|
||||||
|
|
||||||
|
DirectAPKLink() {
|
||||||
|
neverAutoSelect = true;
|
||||||
|
name = tr('directAPKLink');
|
||||||
|
additionalSourceAppSpecificSettingFormItems = html
|
||||||
|
.additionalSourceAppSpecificSettingFormItems
|
||||||
|
.where((element) => element
|
||||||
|
.where((element) => element.key == 'requestHeader')
|
||||||
|
.isNotEmpty)
|
||||||
|
.toList();
|
||||||
|
excludeCommonSettingKeys = [
|
||||||
|
'versionExtractionRegEx',
|
||||||
|
'matchGroupToUse',
|
||||||
|
'versionDetection',
|
||||||
|
'useVersionCodeAsOSVersion',
|
||||||
|
'apkFilterRegEx',
|
||||||
|
'autoApkFilterByArch'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<APKDetails> getLatestAPKDetails(
|
||||||
|
String standardUrl,
|
||||||
|
Map<String, dynamic> additionalSettings,
|
||||||
|
) async {
|
||||||
|
var additionalSettingsNew =
|
||||||
|
getDefaultValuesFromFormItems(html.combinedAppSpecificSettingFormItems);
|
||||||
|
for (var s in additionalSettings.keys) {
|
||||||
|
if (additionalSettingsNew.containsKey(s)) {
|
||||||
|
additionalSettingsNew[s] = additionalSettings[s];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
additionalSettingsNew['defaultPseudoVersioningMethod'] = 'partialAPKHash';
|
||||||
|
additionalSettingsNew['directAPKLink'] = true;
|
||||||
|
additionalSettings['versionDetection'] = false;
|
||||||
|
return html.getLatestAPKDetails(standardUrl, additionalSettingsNew);
|
||||||
|
}
|
||||||
|
}
|
@@ -10,6 +10,7 @@ class FDroidRepo extends AppSource {
|
|||||||
canSearch = true;
|
canSearch = true;
|
||||||
excludeFromMassSearch = true;
|
excludeFromMassSearch = true;
|
||||||
neverAutoSelect = true;
|
neverAutoSelect = true;
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
|
|
||||||
additionalSourceAppSpecificSettingFormItems = [
|
additionalSourceAppSpecificSettingFormItems = [
|
||||||
[
|
[
|
||||||
|
@@ -16,6 +16,7 @@ class GitHub extends AppSource {
|
|||||||
GitHub() {
|
GitHub() {
|
||||||
hosts = ['github.com'];
|
hosts = ['github.com'];
|
||||||
appIdInferIsOptional = true;
|
appIdInferIsOptional = true;
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
|
|
||||||
sourceConfigSettingFormItems = [
|
sourceConfigSettingFormItems = [
|
||||||
GeneratedFormTextField('github-creds',
|
GeneratedFormTextField('github-creds',
|
||||||
@@ -76,6 +77,10 @@ class GitHub extends AppSource {
|
|||||||
[
|
[
|
||||||
GeneratedFormSwitch('dontSortReleasesList',
|
GeneratedFormSwitch('dontSortReleasesList',
|
||||||
label: tr('dontSortReleasesList'))
|
label: tr('dontSortReleasesList'))
|
||||||
|
],
|
||||||
|
[
|
||||||
|
GeneratedFormSwitch('useLatestAssetDateAsReleaseDate',
|
||||||
|
label: tr('useLatestAssetDateAsReleaseDate'), defaultValue: false)
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -237,6 +242,8 @@ class GitHub extends AppSource {
|
|||||||
bool verifyLatestTag = additionalSettings['verifyLatestTag'] == true;
|
bool verifyLatestTag = additionalSettings['verifyLatestTag'] == true;
|
||||||
bool dontSortReleasesList =
|
bool dontSortReleasesList =
|
||||||
additionalSettings['dontSortReleasesList'] == true;
|
additionalSettings['dontSortReleasesList'] == true;
|
||||||
|
bool useLatestAssetDateAsReleaseDate =
|
||||||
|
additionalSettings['useLatestAssetDateAsReleaseDate'] == true;
|
||||||
dynamic latestRelease;
|
dynamic latestRelease;
|
||||||
if (verifyLatestTag) {
|
if (verifyLatestTag) {
|
||||||
var temp = requestUrl.split('?');
|
var temp = requestUrl.split('?');
|
||||||
@@ -277,10 +284,31 @@ class GitHub extends AppSource {
|
|||||||
.toList() ??
|
.toList() ??
|
||||||
[];
|
[];
|
||||||
|
|
||||||
DateTime? getReleaseDateFromRelease(dynamic rel) =>
|
DateTime? getPublishDateFromRelease(dynamic rel) =>
|
||||||
rel?['published_at'] != null
|
rel?['published_at'] != null
|
||||||
? DateTime.parse(rel['published_at'])
|
? DateTime.parse(rel['published_at'])
|
||||||
: null;
|
: null;
|
||||||
|
DateTime? getNewestAssetDateFromRelease(dynamic rel) {
|
||||||
|
var t = (rel['assets'] as List<dynamic>?)
|
||||||
|
?.map((e) {
|
||||||
|
return e?['updated_at'] != null
|
||||||
|
? DateTime.parse(e['updated_at'])
|
||||||
|
: null;
|
||||||
|
})
|
||||||
|
.where((e) => e != null)
|
||||||
|
.toList();
|
||||||
|
t?.sort((a, b) => b!.compareTo(a!));
|
||||||
|
if (t?.isNotEmpty == true) {
|
||||||
|
return t!.first;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime? getReleaseDateFromRelease(dynamic rel, bool useAssetDate) =>
|
||||||
|
!useAssetDate
|
||||||
|
? getPublishDateFromRelease(rel)
|
||||||
|
: getNewestAssetDateFromRelease(rel);
|
||||||
|
|
||||||
if (dontSortReleasesList) {
|
if (dontSortReleasesList) {
|
||||||
releases = releases.reversed.toList();
|
releases = releases.reversed.toList();
|
||||||
} else {
|
} else {
|
||||||
@@ -305,8 +333,12 @@ class GitHub extends AppSource {
|
|||||||
(nameA as String).substring(matchA!.start, matchA.end),
|
(nameA as String).substring(matchA!.start, matchA.end),
|
||||||
(nameB as String).substring(matchB!.start, matchB.end));
|
(nameB as String).substring(matchB!.start, matchB.end));
|
||||||
} else {
|
} else {
|
||||||
return (getReleaseDateFromRelease(a) ?? DateTime(1))
|
return (getReleaseDateFromRelease(
|
||||||
.compareTo(getReleaseDateFromRelease(b) ?? DateTime(0));
|
a, useLatestAssetDateAsReleaseDate) ??
|
||||||
|
DateTime(1))
|
||||||
|
.compareTo(getReleaseDateFromRelease(
|
||||||
|
b, useLatestAssetDateAsReleaseDate) ??
|
||||||
|
DateTime(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -350,11 +382,8 @@ class GitHub extends AppSource {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var apkUrls = getReleaseAPKUrls(releases[i]);
|
var apkUrls = getReleaseAPKUrls(releases[i]);
|
||||||
if (additionalSettings['apkFilterRegEx'] != null) {
|
apkUrls = filterApks(apkUrls, additionalSettings['apkFilterRegEx'],
|
||||||
var reg = RegExp(additionalSettings['apkFilterRegEx']);
|
additionalSettings['invertAPKFilter']);
|
||||||
apkUrls =
|
|
||||||
apkUrls.where((element) => reg.hasMatch(element.key)).toList();
|
|
||||||
}
|
|
||||||
if (apkUrls.isEmpty && additionalSettings['trackOnly'] != true) {
|
if (apkUrls.isEmpty && additionalSettings['trackOnly'] != true) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -366,7 +395,8 @@ class GitHub extends AppSource {
|
|||||||
throw NoReleasesError();
|
throw NoReleasesError();
|
||||||
}
|
}
|
||||||
String? version = targetRelease['tag_name'] ?? targetRelease['name'];
|
String? version = targetRelease['tag_name'] ?? targetRelease['name'];
|
||||||
DateTime? releaseDate = getReleaseDateFromRelease(targetRelease);
|
DateTime? releaseDate = getReleaseDateFromRelease(
|
||||||
|
targetRelease, useLatestAssetDateAsReleaseDate);
|
||||||
if (version == null) {
|
if (version == null) {
|
||||||
throw NoVersionError();
|
throw NoVersionError();
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ class GitLab extends AppSource {
|
|||||||
GitLab() {
|
GitLab() {
|
||||||
hosts = ['gitlab.com'];
|
hosts = ['gitlab.com'];
|
||||||
canSearch = true;
|
canSearch = true;
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
|
|
||||||
sourceConfigSettingFormItems = [
|
sourceConfigSettingFormItems = [
|
||||||
GeneratedFormTextField('gitlab-creds',
|
GeneratedFormTextField('gitlab-creds',
|
||||||
|
@@ -108,11 +108,7 @@ class HTML extends AppSource {
|
|||||||
[
|
[
|
||||||
GeneratedFormSwitch('versionExtractWholePage',
|
GeneratedFormSwitch('versionExtractWholePage',
|
||||||
label: tr('versionExtractWholePage'))
|
label: tr('versionExtractWholePage'))
|
||||||
],
|
]
|
||||||
[
|
|
||||||
GeneratedFormSwitch('supportFixedAPKURL',
|
|
||||||
defaultValue: true, label: tr('supportFixedAPKURL')),
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
var commonFormItems = [
|
var commonFormItems = [
|
||||||
[GeneratedFormSwitch('filterByLinkText', label: tr('filterByLinkText'))],
|
[GeneratedFormSwitch('filterByLinkText', label: tr('filterByLinkText'))],
|
||||||
@@ -172,10 +168,18 @@ class HTML extends AppSource {
|
|||||||
'User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36'
|
'User-Agent: Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
GeneratedFormDropdown(
|
||||||
|
'defaultPseudoVersioningMethod',
|
||||||
|
[
|
||||||
|
MapEntry('partialAPKHash', tr('partialAPKHash')),
|
||||||
|
MapEntry('APKLinkHash', tr('APKLinkHash'))
|
||||||
|
],
|
||||||
|
label: tr('defaultPseudoVersioningMethod'),
|
||||||
|
defaultValue: 'partialAPKHash')
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
overrideVersionDetectionFormDefault('noVersionDetection',
|
|
||||||
disableStandard: false, disableRelDate: true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -288,17 +292,21 @@ class HTML extends AppSource {
|
|||||||
currentUrl = intLinks.last.key;
|
currentUrl = intLinks.last.key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var uri = Uri.parse(currentUrl);
|
var uri = Uri.parse(currentUrl);
|
||||||
Response res = await sourceRequest(currentUrl, additionalSettings);
|
List<MapEntry<String, String>> links = [];
|
||||||
var links = await grabLinksCommon(res, additionalSettings);
|
String versionExtractionWholePageString = currentUrl;
|
||||||
|
if (additionalSettings['directAPKLink'] != true) {
|
||||||
if ((additionalSettings['apkFilterRegEx'] as String?)?.isNotEmpty == true) {
|
Response res = await sourceRequest(currentUrl, additionalSettings);
|
||||||
var reg = RegExp(additionalSettings['apkFilterRegEx']);
|
versionExtractionWholePageString =
|
||||||
links = links.where((element) => reg.hasMatch(element.key)).toList();
|
res.body.split('\r\n').join('\n').split('\n').join('\\n');
|
||||||
}
|
links = await grabLinksCommon(res, additionalSettings);
|
||||||
if (links.isEmpty) {
|
links = filterApks(links, additionalSettings['apkFilterRegEx'],
|
||||||
throw NoReleasesError();
|
additionalSettings['invertAPKFilter']);
|
||||||
|
if (links.isEmpty) {
|
||||||
|
throw NoReleasesError();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
links = [MapEntry(currentUrl, currentUrl)];
|
||||||
}
|
}
|
||||||
var rel = links.last.key;
|
var rel = links.last.key;
|
||||||
String? version;
|
String? version;
|
||||||
@@ -306,11 +314,12 @@ class HTML extends AppSource {
|
|||||||
additionalSettings['versionExtractionRegEx'] as String?,
|
additionalSettings['versionExtractionRegEx'] as String?,
|
||||||
additionalSettings['matchGroupToUse'] as String?,
|
additionalSettings['matchGroupToUse'] as String?,
|
||||||
additionalSettings['versionExtractWholePage'] == true
|
additionalSettings['versionExtractWholePage'] == true
|
||||||
? res.body.split('\r\n').join('\n').split('\n').join('\\n')
|
? versionExtractionWholePageString
|
||||||
: rel);
|
: rel);
|
||||||
version ??= additionalSettings['supportFixedAPKURL'] != true
|
version ??=
|
||||||
? rel.hashCode.toString()
|
additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash'
|
||||||
: (await checkDownloadHash(rel)).toString();
|
? rel.hashCode.toString()
|
||||||
|
: (await checkPartialDownloadHashDynamc(rel)).toString();
|
||||||
return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(),
|
return APKDetails(version, [rel].map((e) => MapEntry(e, e)).toList(),
|
||||||
AppNames(uri.host, tr('app')));
|
AppNames(uri.host, tr('app')));
|
||||||
}
|
}
|
||||||
|
@@ -7,8 +7,8 @@ class HuaweiAppGallery extends AppSource {
|
|||||||
HuaweiAppGallery() {
|
HuaweiAppGallery() {
|
||||||
name = 'Huawei AppGallery';
|
name = 'Huawei AppGallery';
|
||||||
hosts = ['appgallery.huawei.com'];
|
hosts = ['appgallery.huawei.com'];
|
||||||
overrideVersionDetectionFormDefault('releaseDateAsVersion',
|
versionDetectionDisallowed = true;
|
||||||
disableStandard: true);
|
showReleaseDateAsVersionToggle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -6,9 +6,9 @@ import 'package:obtainium/providers/source_provider.dart';
|
|||||||
|
|
||||||
class Jenkins extends AppSource {
|
class Jenkins extends AppSource {
|
||||||
Jenkins() {
|
Jenkins() {
|
||||||
overrideVersionDetectionFormDefault('releaseDateAsVersion',
|
versionDetectionDisallowed = true;
|
||||||
disableStandard: true);
|
|
||||||
neverAutoSelect = true;
|
neverAutoSelect = true;
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String trimJobUrl(String url) {
|
String trimJobUrl(String url) {
|
||||||
|
@@ -6,6 +6,7 @@ import 'package:obtainium/providers/source_provider.dart';
|
|||||||
class NeutronCode extends AppSource {
|
class NeutronCode extends AppSource {
|
||||||
NeutronCode() {
|
NeutronCode() {
|
||||||
hosts = ['neutroncode.com'];
|
hosts = ['neutroncode.com'];
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -9,6 +9,7 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
class SourceHut extends AppSource {
|
class SourceHut extends AppSource {
|
||||||
SourceHut() {
|
SourceHut() {
|
||||||
hosts = ['git.sr.ht'];
|
hosts = ['git.sr.ht'];
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
|
|
||||||
additionalSourceAppSpecificSettingFormItems = [
|
additionalSourceAppSpecificSettingFormItems = [
|
||||||
[
|
[
|
||||||
|
@@ -9,6 +9,7 @@ class Uptodown extends AppSource {
|
|||||||
hosts = ['uptodown.com'];
|
hosts = ['uptodown.com'];
|
||||||
allowSubDomains = true;
|
allowSubDomains = true;
|
||||||
naiveStandardVersionDetection = true;
|
naiveStandardVersionDetection = true;
|
||||||
|
showReleaseDateAsVersionToggle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -6,8 +6,7 @@ import 'package:obtainium/providers/source_provider.dart';
|
|||||||
class WhatsApp extends AppSource {
|
class WhatsApp extends AppSource {
|
||||||
WhatsApp() {
|
WhatsApp() {
|
||||||
hosts = ['whatsapp.com'];
|
hosts = ['whatsapp.com'];
|
||||||
overrideVersionDetectionFormDefault('noVersionDetection',
|
versionDetectionDisallowed = true;
|
||||||
disableStandard: true, disableRelDate: true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@@ -96,11 +96,14 @@ class GeneratedFormDropdown extends GeneratedFormItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class GeneratedFormSwitch extends GeneratedFormItem {
|
class GeneratedFormSwitch extends GeneratedFormItem {
|
||||||
|
bool disabled = false;
|
||||||
|
|
||||||
GeneratedFormSwitch(
|
GeneratedFormSwitch(
|
||||||
super.key, {
|
super.key, {
|
||||||
super.label,
|
super.label,
|
||||||
super.belowWidgets,
|
super.belowWidgets,
|
||||||
bool super.defaultValue = false,
|
bool super.defaultValue = false,
|
||||||
|
bool disabled = false,
|
||||||
List<String? Function(bool value)> super.additionalValidators = const [],
|
List<String? Function(bool value)> super.additionalValidators = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -115,6 +118,7 @@ class GeneratedFormSwitch extends GeneratedFormItem {
|
|||||||
label: label,
|
label: label,
|
||||||
belowWidgets: belowWidgets,
|
belowWidgets: belowWidgets,
|
||||||
defaultValue: defaultValue,
|
defaultValue: defaultValue,
|
||||||
|
disabled: false,
|
||||||
additionalValidators: List.from(additionalValidators));
|
additionalValidators: List.from(additionalValidators));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,15 +372,51 @@ class _GeneratedFormState extends State<GeneratedForm> {
|
|||||||
),
|
),
|
||||||
Switch(
|
Switch(
|
||||||
value: values[fieldKey],
|
value: values[fieldKey],
|
||||||
onChanged: (value) {
|
onChanged:
|
||||||
setState(() {
|
(widget.items[r][e] as GeneratedFormSwitch).disabled
|
||||||
values[fieldKey] = value;
|
? null
|
||||||
someValueChanged();
|
: (value) {
|
||||||
});
|
setState(() {
|
||||||
})
|
values[fieldKey] = value;
|
||||||
|
someValueChanged();
|
||||||
|
});
|
||||||
|
})
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else if (widget.items[r][e] is GeneratedFormTagInput) {
|
} else if (widget.items[r][e] is GeneratedFormTagInput) {
|
||||||
|
onAddPressed() {
|
||||||
|
showDialog<Map<String, dynamic>?>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext ctx) {
|
||||||
|
return GeneratedFormModal(
|
||||||
|
title: widget.items[r][e].label,
|
||||||
|
items: [
|
||||||
|
[GeneratedFormTextField('label', label: tr('label'))]
|
||||||
|
]);
|
||||||
|
}).then((value) {
|
||||||
|
String? label = value?['label'];
|
||||||
|
if (label != null) {
|
||||||
|
setState(() {
|
||||||
|
var temp =
|
||||||
|
values[fieldKey] as Map<String, MapEntry<int, bool>>?;
|
||||||
|
temp ??= {};
|
||||||
|
if (temp[label] == null) {
|
||||||
|
var singleSelect =
|
||||||
|
(widget.items[r][e] as GeneratedFormTagInput)
|
||||||
|
.singleSelect;
|
||||||
|
var someSelected = temp.entries
|
||||||
|
.where((element) => element.value.value)
|
||||||
|
.isNotEmpty;
|
||||||
|
temp[label] = MapEntry(generateRandomLightColor().value,
|
||||||
|
!(someSelected && singleSelect));
|
||||||
|
values[fieldKey] = temp;
|
||||||
|
someValueChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
formInputs[r][e] =
|
formInputs[r][e] =
|
||||||
Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
||||||
if ((values[fieldKey] as Map<String, MapEntry<int, bool>>?)
|
if ((values[fieldKey] as Map<String, MapEntry<int, bool>>?)
|
||||||
@@ -402,14 +442,14 @@ class _GeneratedFormState extends State<GeneratedForm> {
|
|||||||
(widget.items[r][e] as GeneratedFormTagInput).alignment,
|
(widget.items[r][e] as GeneratedFormTagInput).alignment,
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
(values[fieldKey] as Map<String, MapEntry<int, bool>>?)
|
// (values[fieldKey] as Map<String, MapEntry<int, bool>>?)
|
||||||
?.isEmpty ==
|
// ?.isEmpty ==
|
||||||
true
|
// true
|
||||||
? Text(
|
// ? Text(
|
||||||
(widget.items[r][e] as GeneratedFormTagInput)
|
// (widget.items[r][e] as GeneratedFormTagInput)
|
||||||
.emptyMessage,
|
// .emptyMessage,
|
||||||
)
|
// )
|
||||||
: const SizedBox.shrink(),
|
// : const SizedBox.shrink(),
|
||||||
...(values[fieldKey] as Map<String, MapEntry<int, bool>>?)
|
...(values[fieldKey] as Map<String, MapEntry<int, bool>>?)
|
||||||
?.entries
|
?.entries
|
||||||
.map((e2) {
|
.map((e2) {
|
||||||
@@ -533,49 +573,26 @@ class _GeneratedFormState extends State<GeneratedForm> {
|
|||||||
tooltip: tr('remove'),
|
tooltip: tr('remove'),
|
||||||
))
|
))
|
||||||
: const SizedBox.shrink(),
|
: const SizedBox.shrink(),
|
||||||
Padding(
|
(values[fieldKey] as Map<String, MapEntry<int, bool>>?)
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
?.isEmpty ==
|
||||||
child: IconButton(
|
true
|
||||||
onPressed: () {
|
? Padding(
|
||||||
showDialog<Map<String, dynamic>?>(
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
context: context,
|
child: TextButton.icon(
|
||||||
builder: (BuildContext ctx) {
|
onPressed: onAddPressed,
|
||||||
return GeneratedFormModal(
|
icon: const Icon(Icons.add),
|
||||||
title: widget.items[r][e].label,
|
label: Text(
|
||||||
items: [
|
(widget.items[r][e] as GeneratedFormTagInput)
|
||||||
[
|
.label),
|
||||||
GeneratedFormTextField('label',
|
))
|
||||||
label: tr('label'))
|
: Padding(
|
||||||
]
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
]);
|
child: IconButton(
|
||||||
}).then((value) {
|
onPressed: onAddPressed,
|
||||||
String? label = value?['label'];
|
icon: const Icon(Icons.add),
|
||||||
if (label != null) {
|
visualDensity: VisualDensity.compact,
|
||||||
setState(() {
|
tooltip: tr('add'),
|
||||||
var temp = values[fieldKey]
|
)),
|
||||||
as Map<String, MapEntry<int, bool>>?;
|
|
||||||
temp ??= {};
|
|
||||||
if (temp[label] == null) {
|
|
||||||
var singleSelect = (widget.items[r][e]
|
|
||||||
as GeneratedFormTagInput)
|
|
||||||
.singleSelect;
|
|
||||||
var someSelected = temp.entries
|
|
||||||
.where((element) => element.value.value)
|
|
||||||
.isNotEmpty;
|
|
||||||
temp[label] = MapEntry(
|
|
||||||
generateRandomLightColor().value,
|
|
||||||
!(someSelected && singleSelect));
|
|
||||||
values[fieldKey] = temp;
|
|
||||||
someValueChanged();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.add),
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
tooltip: tr('add'),
|
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
|
@@ -7,6 +7,7 @@ import 'package:obtainium/providers/apps_provider.dart';
|
|||||||
import 'package:obtainium/providers/logs_provider.dart';
|
import 'package:obtainium/providers/logs_provider.dart';
|
||||||
import 'package:obtainium/providers/notifications_provider.dart';
|
import 'package:obtainium/providers/notifications_provider.dart';
|
||||||
import 'package:obtainium/providers/settings_provider.dart';
|
import 'package:obtainium/providers/settings_provider.dart';
|
||||||
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:dynamic_color/dynamic_color.dart';
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
@@ -18,10 +19,6 @@ import 'package:easy_localization/src/easy_localization_controller.dart';
|
|||||||
// ignore: implementation_imports
|
// ignore: implementation_imports
|
||||||
import 'package:easy_localization/src/localization.dart';
|
import 'package:easy_localization/src/localization.dart';
|
||||||
|
|
||||||
const String currentVersion = '0.15.10';
|
|
||||||
const String currentReleaseTag =
|
|
||||||
'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES
|
|
||||||
|
|
||||||
List<MapEntry<Locale, String>> supportedLocales = const [
|
List<MapEntry<Locale, String>> supportedLocales = const [
|
||||||
MapEntry(Locale('en'), 'English'),
|
MapEntry(Locale('en'), 'English'),
|
||||||
MapEntry(Locale('zh'), '简体中文'),
|
MapEntry(Locale('zh'), '简体中文'),
|
||||||
@@ -143,6 +140,7 @@ class _ObtainiumState extends State<Obtainium> {
|
|||||||
BackgroundFetchConfig(
|
BackgroundFetchConfig(
|
||||||
minimumFetchInterval: 15,
|
minimumFetchInterval: 15,
|
||||||
stopOnTerminate: false,
|
stopOnTerminate: false,
|
||||||
|
startOnBoot: true,
|
||||||
enableHeadless: true,
|
enableHeadless: true,
|
||||||
requiresBatteryNotLow: false,
|
requiresBatteryNotLow: false,
|
||||||
requiresCharging: false,
|
requiresCharging: false,
|
||||||
@@ -173,7 +171,31 @@ class _ObtainiumState extends State<Obtainium> {
|
|||||||
// If this is the first run, ask for notification permissions and add Obtainium to the Apps list
|
// If this is the first run, ask for notification permissions and add Obtainium to the Apps list
|
||||||
Permission.notification.request();
|
Permission.notification.request();
|
||||||
if (!fdroid) {
|
if (!fdroid) {
|
||||||
appsProvider.saveApps([obtainiumApp], onlyIfExists: false);
|
getInstalledInfo(obtainiumId).then((value) {
|
||||||
|
if (value?.versionName != null) {
|
||||||
|
appsProvider.saveApps([
|
||||||
|
App(
|
||||||
|
obtainiumId,
|
||||||
|
obtainiumUrl,
|
||||||
|
'ImranR98',
|
||||||
|
'Obtainium',
|
||||||
|
value!.versionName,
|
||||||
|
value.versionName!,
|
||||||
|
[],
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
'includePrereleases': true,
|
||||||
|
'versionDetection': true,
|
||||||
|
'apkFilterRegEx': 'fdroid',
|
||||||
|
'invertAPKFilter': true
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
false)
|
||||||
|
], onlyIfExists: false);
|
||||||
|
}
|
||||||
|
}).catchError((err) {
|
||||||
|
print(err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!supportedLocales
|
if (!supportedLocales
|
||||||
|
@@ -135,8 +135,7 @@ class AddAppPageState extends State<AddAppPage> {
|
|||||||
|
|
||||||
getReleaseDateAsVersionConfirmationIfNeeded(
|
getReleaseDateAsVersionConfirmationIfNeeded(
|
||||||
bool userPickedTrackOnly) async {
|
bool userPickedTrackOnly) async {
|
||||||
return (!(additionalSettings['versionDetection'] ==
|
return (!(additionalSettings['releaseDateAsVersion'] == true &&
|
||||||
'releaseDateAsVersion' &&
|
|
||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -192,8 +191,7 @@ class AddAppPageState extends State<AddAppPage> {
|
|||||||
throw ObtainiumError(tr('appAlreadyAdded'));
|
throw ObtainiumError(tr('appAlreadyAdded'));
|
||||||
}
|
}
|
||||||
if (app.additionalSettings['trackOnly'] == true ||
|
if (app.additionalSettings['trackOnly'] == true ||
|
||||||
app.additionalSettings['versionDetection'] !=
|
app.additionalSettings['versionDetection'] != true) {
|
||||||
'standardVersionDetection') {
|
|
||||||
app.installedVersion = app.latestVersion;
|
app.installedVersion = app.latestVersion;
|
||||||
}
|
}
|
||||||
app.categories = pickedCategories;
|
app.categories = pickedCategories;
|
||||||
@@ -498,36 +496,61 @@ class AddAppPageState extends State<AddAppPage> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget getSourcesListWidget() => Column(
|
Widget getSourcesListWidget() => Padding(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
padding: const EdgeInsets.all(16),
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
GestureDetector(
|
||||||
tr('supportedSources'),
|
onTap: () {
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
showDialog(
|
||||||
),
|
context: context,
|
||||||
const SizedBox(
|
builder: (context) {
|
||||||
height: 16,
|
return GeneratedFormModal(
|
||||||
),
|
singleNullReturnButton: tr('ok'),
|
||||||
...sourceProvider.sources.map((e) => GestureDetector(
|
title: tr('supportedSources'),
|
||||||
onTap: e.hosts.isNotEmpty
|
items: const [],
|
||||||
? () {
|
additionalWidgets: [
|
||||||
launchUrlString('https://${e.hosts[0]}',
|
...sourceProvider.sources.map(
|
||||||
mode: LaunchMode.externalApplication);
|
(e) => Padding(
|
||||||
}
|
padding:
|
||||||
: null,
|
const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: e.hosts.isNotEmpty
|
||||||
|
? () {
|
||||||
|
launchUrlString(
|
||||||
|
'https://${e.hosts[0]}',
|
||||||
|
mode: LaunchMode
|
||||||
|
.externalApplication);
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
child: Text(
|
||||||
|
'${e.name}${e.enforceTrackOnly ? ' ${tr('trackOnlyInBrackets')}' : ''}${e.canSearch ? ' ${tr('searchableInBrackets')}' : ''}',
|
||||||
|
style: TextStyle(
|
||||||
|
decoration: e.hosts.isNotEmpty
|
||||||
|
? TextDecoration.underline
|
||||||
|
: TextDecoration.none),
|
||||||
|
))),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'${e.name}${e.enforceTrackOnly ? ' ${tr('trackOnlyInBrackets')}' : ''}${e.canSearch ? ' ${tr('searchableInBrackets')}' : ''}',
|
tr('supportedSources'),
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
decoration: e.hosts.isNotEmpty
|
fontWeight: FontWeight.bold,
|
||||||
? TextDecoration.underline
|
decoration: TextDecoration.underline,
|
||||||
: TextDecoration.none,
|
|
||||||
fontStyle: FontStyle.italic),
|
fontStyle: FontStyle.italic),
|
||||||
)))
|
))
|
||||||
]);
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||||
|
bottomNavigationBar:
|
||||||
|
pickedSource == null ? getSourcesListWidget() : null,
|
||||||
body: CustomScrollView(shrinkWrap: true, slivers: <Widget>[
|
body: CustomScrollView(shrinkWrap: true, slivers: <Widget>[
|
||||||
CustomAppBar(title: tr('addApp')),
|
CustomAppBar(title: tr('addApp')),
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
@@ -559,18 +582,7 @@ class AddAppPageState extends State<AddAppPage> {
|
|||||||
: const SizedBox();
|
: const SizedBox();
|
||||||
},
|
},
|
||||||
future: pickedSource?.getSourceNote()),
|
future: pickedSource?.getSourceNote()),
|
||||||
SizedBox(
|
|
||||||
height: pickedSource != null ? 16 : 96,
|
|
||||||
),
|
|
||||||
if (pickedSource != null) getAdditionalOptsCol(),
|
if (pickedSource != null) getAdditionalOptsCol(),
|
||||||
if (pickedSource == null)
|
|
||||||
const Divider(
|
|
||||||
height: 48,
|
|
||||||
),
|
|
||||||
if (pickedSource == null) getSourcesListWidget(),
|
|
||||||
SizedBox(
|
|
||||||
height: pickedSource != null ? 8 : 2,
|
|
||||||
),
|
|
||||||
])),
|
])),
|
||||||
)
|
)
|
||||||
]));
|
]));
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:obtainium/components/generated_form.dart';
|
|
||||||
import 'package:obtainium/components/generated_form_modal.dart';
|
import 'package:obtainium/components/generated_form_modal.dart';
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
import 'package:obtainium/main.dart';
|
import 'package:obtainium/main.dart';
|
||||||
@@ -29,8 +28,18 @@ class _AppPageState extends State<AppPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var appsProvider = context.watch<AppsProvider>();
|
var appsProvider = context.watch<AppsProvider>();
|
||||||
var settingsProvider = context.watch<SettingsProvider>();
|
var settingsProvider = context.watch<SettingsProvider>();
|
||||||
getUpdate(String id) {
|
getUpdate(String id, {bool resetVersion = false}) {
|
||||||
appsProvider.checkUpdate(id).catchError((e) {
|
appsProvider.checkUpdate(id).then((e) {
|
||||||
|
if (resetVersion) {
|
||||||
|
appsProvider.apps[id]?.app.additionalSettings['versionDetection'] =
|
||||||
|
true;
|
||||||
|
if (appsProvider.apps[id]?.app.installedVersion != null) {
|
||||||
|
appsProvider.apps[id]?.app.installedVersion =
|
||||||
|
appsProvider.apps[id]?.app.latestVersion;
|
||||||
|
}
|
||||||
|
appsProvider.saveApps([appsProvider.apps[id]!.app]);
|
||||||
|
}
|
||||||
|
}).catchError((e) {
|
||||||
showError(e, context);
|
showError(e, context);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@@ -54,122 +63,113 @@ class _AppPageState extends State<AppPage> {
|
|||||||
var trackOnly = app?.app.additionalSettings['trackOnly'] == true;
|
var trackOnly = app?.app.additionalSettings['trackOnly'] == true;
|
||||||
|
|
||||||
bool isVersionDetectionStandard =
|
bool isVersionDetectionStandard =
|
||||||
app?.app.additionalSettings['versionDetection'] ==
|
app?.app.additionalSettings['versionDetection'] == true;
|
||||||
'standardVersionDetection';
|
|
||||||
|
|
||||||
bool installedVersionIsEstimate = trackOnly ||
|
bool installedVersionIsEstimate = trackOnly ||
|
||||||
(app?.app.installedVersion != null &&
|
(app?.app.installedVersion != null &&
|
||||||
app?.app.additionalSettings['versionDetection'] ==
|
app?.app.additionalSettings['versionDetection'] != true);
|
||||||
'noVersionDetection');
|
|
||||||
|
|
||||||
getInfoColumn() => Column(
|
getInfoColumn() {
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
String versionLines = '';
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
bool installed = app?.app.installedVersion != null;
|
||||||
children: [
|
bool upToDate = app?.app.installedVersion == app?.app.latestVersion;
|
||||||
GestureDetector(
|
if (installed) {
|
||||||
onTap: () {
|
versionLines = '${app?.app.installedVersion} ${tr('installed')}';
|
||||||
if (app?.app.url != null) {
|
if (upToDate) {
|
||||||
launchUrlString(app?.app.url ?? '',
|
versionLines += '/${tr('latest')}';
|
||||||
mode: LaunchMode.externalApplication);
|
}
|
||||||
}
|
} else {
|
||||||
},
|
versionLines = tr('notInstalled');
|
||||||
onLongPress: () {
|
}
|
||||||
Clipboard.setData(ClipboardData(text: app?.app.url ?? ''));
|
if (!upToDate) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
versionLines += '\n${app?.app.latestVersion} ${tr('latest')}';
|
||||||
content: Text(tr('copiedToClipboard')),
|
}
|
||||||
));
|
String infoLines = tr('lastUpdateCheckX', args: [
|
||||||
},
|
app?.app.lastUpdateCheck == null
|
||||||
child: Text(
|
? tr('never')
|
||||||
app?.app.url ?? '',
|
: '${app?.app.lastUpdateCheck?.toLocal()}'
|
||||||
textAlign: TextAlign.center,
|
]);
|
||||||
style: const TextStyle(
|
if (trackOnly) {
|
||||||
decoration: TextDecoration.underline,
|
infoLines = '${tr('xIsTrackOnly', args: [tr('app')])}\n$infoLines';
|
||||||
fontStyle: FontStyle.italic,
|
}
|
||||||
fontSize: 12),
|
if (installedVersionIsEstimate) {
|
||||||
)),
|
infoLines = '${tr('pseudoVersionInUse')}\n$infoLines';
|
||||||
const SizedBox(
|
}
|
||||||
height: 32,
|
return Column(
|
||||||
),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
Column(
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 24),
|
||||||
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
const SizedBox(
|
||||||
'${tr('latestVersionX', args: [
|
height: 8,
|
||||||
app?.app.latestVersion ?? tr('unknown')
|
),
|
||||||
])}\n${tr('installedVersionX', args: [
|
Text(versionLines,
|
||||||
app?.app.installedVersion ?? tr('none')
|
textAlign: TextAlign.start,
|
||||||
])}${installedVersionIsEstimate ? '\n${tr('estimateInBrackets')}' : ''}',
|
style: Theme.of(context)
|
||||||
textAlign: TextAlign.end,
|
.textTheme
|
||||||
style: Theme.of(context).textTheme.bodyLarge!,
|
.bodyLarge!
|
||||||
|
.copyWith(fontWeight: FontWeight.bold)),
|
||||||
|
app?.app.releaseDate == null
|
||||||
|
? const SizedBox.shrink()
|
||||||
|
: Text(
|
||||||
|
app!.app.releaseDate.toString(),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).textTheme.labelSmall,
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 8,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (app?.app.installedVersion != null &&
|
),
|
||||||
!isVersionDetectionStandard)
|
Text(
|
||||||
Column(
|
infoLines,
|
||||||
children: [
|
textAlign: TextAlign.center,
|
||||||
const SizedBox(
|
style: const TextStyle(fontStyle: FontStyle.italic, fontSize: 12),
|
||||||
height: 16,
|
),
|
||||||
),
|
const SizedBox(
|
||||||
Text(
|
height: 48,
|
||||||
'${trackOnly ? '${tr('xIsTrackOnly', args: [
|
),
|
||||||
tr('app')
|
CategoryEditorSelector(
|
||||||
])}\n' : ''}${tr('noVersionDetection')}',
|
alignment: WrapAlignment.center,
|
||||||
style: Theme.of(context).textTheme.labelSmall,
|
preselected: app?.app.categories != null
|
||||||
|
? app!.app.categories.toSet()
|
||||||
|
: {},
|
||||||
|
onSelected: (categories) {
|
||||||
|
if (app != null) {
|
||||||
|
app.app.categories = categories;
|
||||||
|
appsProvider.saveApps([app.app]);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
if (app?.app.additionalSettings['about'] is String &&
|
||||||
|
app?.app.additionalSettings['about'].isNotEmpty)
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 48,
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onLongPress: () {
|
||||||
|
Clipboard.setData(ClipboardData(
|
||||||
|
text: app?.app.additionalSettings['about'] ?? ''));
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
|
content: Text(tr('copiedToClipboard')),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
app?.app.additionalSettings['about'],
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
)
|
style: const TextStyle(fontStyle: FontStyle.italic),
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 32,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
tr('lastUpdateCheckX', args: [
|
|
||||||
app?.app.lastUpdateCheck == null
|
|
||||||
? tr('never')
|
|
||||||
: '\n${app?.app.lastUpdateCheck?.toLocal()}'
|
|
||||||
]),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: const TextStyle(fontStyle: FontStyle.italic, fontSize: 12),
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 48,
|
|
||||||
),
|
|
||||||
CategoryEditorSelector(
|
|
||||||
alignment: WrapAlignment.center,
|
|
||||||
preselected: app?.app.categories != null
|
|
||||||
? app!.app.categories.toSet()
|
|
||||||
: {},
|
|
||||||
onSelected: (categories) {
|
|
||||||
if (app != null) {
|
|
||||||
app.app.categories = categories;
|
|
||||||
appsProvider.saveApps([app.app]);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
if (app?.app.additionalSettings['about'] is String &&
|
|
||||||
app?.app.additionalSettings['about'].isNotEmpty)
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
const SizedBox(
|
|
||||||
height: 48,
|
|
||||||
),
|
),
|
||||||
GestureDetector(
|
)
|
||||||
onLongPress: () {
|
],
|
||||||
Clipboard.setData(ClipboardData(
|
),
|
||||||
text: app?.app.additionalSettings['about'] ?? ''));
|
],
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
);
|
||||||
content: Text(tr('copiedToClipboard')),
|
}
|
||||||
));
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
app?.app.additionalSettings['about'],
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: const TextStyle(fontStyle: FontStyle.italic),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
getFullInfoColumn() => Column(
|
getFullInfoColumn() => Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@@ -196,11 +196,26 @@ class _AppPageState extends State<AppPage> {
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context).textTheme.displayLarge,
|
style: Theme.of(context).textTheme.displayLarge,
|
||||||
),
|
),
|
||||||
Text(
|
GestureDetector(
|
||||||
tr('byX', args: [app?.app.author ?? tr('unknown')]),
|
onTap: () {
|
||||||
textAlign: TextAlign.center,
|
if (app?.app.url != null) {
|
||||||
style: Theme.of(context).textTheme.headlineMedium,
|
launchUrlString(app?.app.url ?? '',
|
||||||
),
|
mode: LaunchMode.externalApplication);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
Clipboard.setData(ClipboardData(text: app?.app.url ?? ''));
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
|
content: Text(tr('copiedToClipboard')),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
tr('byX', args: [app?.app.author ?? tr('unknown')]),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: Theme.of(context).textTheme.headlineMedium!.copyWith(
|
||||||
|
decoration: TextDecoration.underline,
|
||||||
|
fontStyle: FontStyle.italic),
|
||||||
|
)),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8,
|
height: 8,
|
||||||
),
|
),
|
||||||
@@ -209,16 +224,6 @@ class _AppPageState extends State<AppPage> {
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: Theme.of(context).textTheme.labelSmall,
|
style: Theme.of(context).textTheme.labelSmall,
|
||||||
),
|
),
|
||||||
app?.app.releaseDate == null
|
|
||||||
? const SizedBox.shrink()
|
|
||||||
: Text(
|
|
||||||
app!.app.releaseDate.toString(),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: Theme.of(context).textTheme.labelSmall,
|
|
||||||
),
|
|
||||||
const SizedBox(
|
|
||||||
height: 32,
|
|
||||||
),
|
|
||||||
getInfoColumn(),
|
getInfoColumn(),
|
||||||
const SizedBox(height: 150)
|
const SizedBox(height: 150)
|
||||||
],
|
],
|
||||||
@@ -287,25 +292,6 @@ class _AppPageState extends State<AppPage> {
|
|||||||
return row;
|
return row;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
items = items.map((row) {
|
|
||||||
row = row.map((e) {
|
|
||||||
if (e.key == 'versionDetection' && e is GeneratedFormDropdown) {
|
|
||||||
e.disabledOptKeys ??= [];
|
|
||||||
if (app?.app.installedVersion != null &&
|
|
||||||
app?.app.additionalSettings['versionDetection'] !=
|
|
||||||
'releaseDateAsVersion' &&
|
|
||||||
!appsProvider.isVersionDetectionPossible(app)) {
|
|
||||||
e.disabledOptKeys!.add('standardVersionDetection');
|
|
||||||
}
|
|
||||||
if (app?.app.releaseDate == null) {
|
|
||||||
e.disabledOptKeys!.add('releaseDateAsVersion');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
}).toList();
|
|
||||||
return row;
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
return GeneratedFormModal(
|
return GeneratedFormModal(
|
||||||
title: tr('additionalOptions'), items: items);
|
title: tr('additionalOptions'), items: items);
|
||||||
});
|
});
|
||||||
@@ -320,26 +306,34 @@ class _AppPageState extends State<AppPage> {
|
|||||||
// ignore: use_build_context_synchronously
|
// ignore: use_build_context_synchronously
|
||||||
showMessage(tr('appsFromSourceAreTrackOnly'), context);
|
showMessage(tr('appsFromSourceAreTrackOnly'), context);
|
||||||
}
|
}
|
||||||
if (app.app.additionalSettings['versionDetection'] ==
|
var versionDetectionEnabled =
|
||||||
'releaseDateAsVersion') {
|
app.app.additionalSettings['versionDetection'] == true &&
|
||||||
if (originalSettings['versionDetection'] != 'releaseDateAsVersion') {
|
originalSettings['versionDetection'] != true;
|
||||||
if (app.app.releaseDate != null) {
|
var releaseDateVersionEnabled =
|
||||||
bool isUpdated =
|
app.app.additionalSettings['releaseDateAsVersion'] == true &&
|
||||||
app.app.installedVersion == app.app.latestVersion;
|
originalSettings['releaseDateAsVersion'] != true;
|
||||||
app.app.latestVersion =
|
var releaseDateVersionDisabled =
|
||||||
app.app.releaseDate!.microsecondsSinceEpoch.toString();
|
app.app.additionalSettings['releaseDateAsVersion'] != true &&
|
||||||
if (isUpdated) {
|
originalSettings['releaseDateAsVersion'] == true;
|
||||||
app.app.installedVersion = app.app.latestVersion;
|
if (releaseDateVersionEnabled) {
|
||||||
}
|
if (app.app.releaseDate != null) {
|
||||||
|
bool isUpdated = app.app.installedVersion == app.app.latestVersion;
|
||||||
|
app.app.latestVersion =
|
||||||
|
app.app.releaseDate!.microsecondsSinceEpoch.toString();
|
||||||
|
if (isUpdated) {
|
||||||
|
app.app.installedVersion = app.app.latestVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (originalSettings['versionDetection'] ==
|
} else if (releaseDateVersionDisabled) {
|
||||||
'releaseDateAsVersion') {
|
|
||||||
app.app.installedVersion =
|
app.app.installedVersion =
|
||||||
app.installedInfo?.versionName ?? app.app.installedVersion;
|
app.installedInfo?.versionName ?? app.app.installedVersion;
|
||||||
}
|
}
|
||||||
|
if (versionDetectionEnabled) {
|
||||||
|
app.app.additionalSettings['versionDetection'] = true;
|
||||||
|
app.app.additionalSettings['releaseDateAsVersion'] = false;
|
||||||
|
}
|
||||||
appsProvider.saveApps([app.app]).then((value) {
|
appsProvider.saveApps([app.app]).then((value) {
|
||||||
getUpdate(app.app.id);
|
getUpdate(app.app.id, resetVersion: versionDetectionEnabled);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -421,7 +421,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getVersionText(int appIndex) {
|
getVersionText(int appIndex) {
|
||||||
return '${listedApps[appIndex].app.installedVersion ?? tr('notInstalled')}${listedApps[appIndex].app.additionalSettings['trackOnly'] == true ? ' ${tr('estimateInBrackets')}' : ''}';
|
return '${listedApps[appIndex].app.installedVersion ?? tr('notInstalled')}${listedApps[appIndex].app.additionalSettings['trackOnly'] == true ? ' ${tr('pseudoVersion')}' : ''}';
|
||||||
}
|
}
|
||||||
|
|
||||||
getChangesButtonString(int appIndex, bool hasChangeLogFn) {
|
getChangesButtonString(int appIndex, bool hasChangeLogFn) {
|
||||||
@@ -904,7 +904,7 @@ class AppsPageState extends State<AppsPage> {
|
|||||||
}))}">${a.name}</a></li>\n';
|
}))}">${a.name}</a></li>\n';
|
||||||
}
|
}
|
||||||
urls +=
|
urls +=
|
||||||
'</ul>\n\n<p><a href="${obtainiumApp.url}">${tr('about')}</a></p>';
|
'</ul>\n\n<p><a href="$obtainiumUrl">${tr('about')}</a></p>';
|
||||||
Share.share(urls,
|
Share.share(urls,
|
||||||
subject:
|
subject:
|
||||||
'${tr('obtainium')} - ${tr('appsString')}');
|
'${tr('obtainium')} - ${tr('appsString')}');
|
||||||
|
@@ -416,13 +416,17 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
value: settingsProvider.useSystemFont,
|
value: settingsProvider.useSystemFont,
|
||||||
onChanged: (useSystemFont) {
|
onChanged: (useSystemFont) {
|
||||||
if (useSystemFont) {
|
if (useSystemFont) {
|
||||||
NativeFeatures.loadSystemFont().then((fontLoadRes) {
|
NativeFeatures.loadSystemFont()
|
||||||
|
.then((fontLoadRes) {
|
||||||
if (fontLoadRes == 'ok') {
|
if (fontLoadRes == 'ok') {
|
||||||
settingsProvider.useSystemFont = true;
|
settingsProvider.useSystemFont =
|
||||||
|
true;
|
||||||
} else {
|
} else {
|
||||||
showError(ObtainiumError(
|
showError(
|
||||||
tr('systemFontError', args: [fontLoadRes])
|
ObtainiumError(tr(
|
||||||
), context);
|
'systemFontError',
|
||||||
|
args: [fontLoadRes])),
|
||||||
|
context);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -628,38 +632,9 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||||||
label: Text(tr('appLogs'))),
|
label: Text(tr('appLogs'))),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const Divider(
|
const SizedBox(
|
||||||
height: 32,
|
height: 16,
|
||||||
),
|
)
|
||||||
// Padding(
|
|
||||||
// padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
|
||||||
// child: Column(children: [
|
|
||||||
// Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
// children: [
|
|
||||||
// Flexible(child: Text(tr('debugMenu'))),
|
|
||||||
// Switch(
|
|
||||||
// value: settingsProvider.showDebugOpts,
|
|
||||||
// onChanged: (value) {
|
|
||||||
// settingsProvider.showDebugOpts = value;
|
|
||||||
// })
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// if (settingsProvider.showDebugOpts)
|
|
||||||
// Column(
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
// children: [
|
|
||||||
// height16,
|
|
||||||
// TextButton(
|
|
||||||
// onPressed: () {
|
|
||||||
// bgUpdateCheck('taskId', null);
|
|
||||||
// showMessage(tr('bgTaskStarted'), context);
|
|
||||||
// },
|
|
||||||
// child: Text(tr('runBgCheckNow')))
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ]),
|
|
||||||
// ),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@@ -167,8 +167,24 @@ String hashListOfLists(List<List<int>> data) {
|
|||||||
return hash.hashCode.toString();
|
return hash.hashCode.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> checkDownloadHash(String url,
|
Future<String> checkPartialDownloadHashDynamc(String url,
|
||||||
{int bytesToGrab = 1024, Map<String, String>? headers}) async {
|
{int startingSize = 1024,
|
||||||
|
int lowerLimit = 128,
|
||||||
|
Map<String, String>? headers}) async {
|
||||||
|
for (int i = startingSize; i >= lowerLimit; i -= 256) {
|
||||||
|
List<String> ab = await Future.wait([
|
||||||
|
checkPartialDownloadHash(url, i, headers: headers),
|
||||||
|
checkPartialDownloadHash(url, i, headers: headers)
|
||||||
|
]);
|
||||||
|
if (ab[0] == ab[1]) {
|
||||||
|
return ab[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw NoVersionError();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> checkPartialDownloadHash(String url, int bytesToGrab,
|
||||||
|
{Map<String, String>? headers}) async {
|
||||||
var req = Request('GET', Uri.parse(url));
|
var req = Request('GET', Uri.parse(url));
|
||||||
if (headers != null) {
|
if (headers != null) {
|
||||||
req.headers.addAll(headers);
|
req.headers.addAll(headers);
|
||||||
@@ -234,6 +250,20 @@ Future<File> downloadFile(
|
|||||||
return downloadedFile;
|
return downloadedFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<PackageInfo?> getInstalledInfo(String? packageName,
|
||||||
|
{bool printErr = true}) async {
|
||||||
|
if (packageName != null) {
|
||||||
|
try {
|
||||||
|
return await pm.getPackageInfo(packageName: packageName);
|
||||||
|
} catch (e) {
|
||||||
|
if (printErr) {
|
||||||
|
print(e); // OK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
class AppsProvider with ChangeNotifier {
|
class AppsProvider with ChangeNotifier {
|
||||||
// In memory App state (should always be kept in sync with local storage versions)
|
// In memory App state (should always be kept in sync with local storage versions)
|
||||||
Map<String, AppInMemory> apps = {};
|
Map<String, AppInMemory> apps = {};
|
||||||
@@ -404,7 +434,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
.isNotEmpty;
|
.isNotEmpty;
|
||||||
|
|
||||||
Future<bool> canInstallSilently(App app) async {
|
Future<bool> canInstallSilently(App app) async {
|
||||||
if (app.id == obtainiumApp.id) {
|
if (app.id == obtainiumId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!settingsProvider.enableBackgroundUpdates) {
|
if (!settingsProvider.enableBackgroundUpdates) {
|
||||||
@@ -428,7 +458,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Probably not installed - ignore
|
// Probably not installed - ignore
|
||||||
}
|
}
|
||||||
if (installerPackageName != obtainiumApp.id) {
|
if (installerPackageName != obtainiumId) {
|
||||||
// If we did not install the app (or it isn't installed), silent install is not possible
|
// If we did not install the app (or it isn't installed), silent install is not possible
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -639,6 +669,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
MapEntry<String, String>? apkUrl;
|
MapEntry<String, String>? apkUrl;
|
||||||
var trackOnly = apps[id]!.app.additionalSettings['trackOnly'] == true;
|
var trackOnly = apps[id]!.app.additionalSettings['trackOnly'] == true;
|
||||||
if (!trackOnly) {
|
if (!trackOnly) {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
apkUrl = await confirmApkUrl(apps[id]!.app, context);
|
apkUrl = await confirmApkUrl(apps[id]!.app, context);
|
||||||
}
|
}
|
||||||
if (apkUrl != null) {
|
if (apkUrl != null) {
|
||||||
@@ -673,7 +704,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
|
|
||||||
// Move Obtainium to the end of the line (let all other apps update first)
|
// Move Obtainium to the end of the line (let all other apps update first)
|
||||||
appsToInstall =
|
appsToInstall =
|
||||||
moveStrToEnd(appsToInstall, obtainiumApp.id, strB: obtainiumTempId);
|
moveStrToEnd(appsToInstall, obtainiumId, strB: obtainiumTempId);
|
||||||
|
|
||||||
Future<void> updateFn(String id, {bool skipInstalls = false}) async {
|
Future<void> updateFn(String id, {bool skipInstalls = false}) async {
|
||||||
try {
|
try {
|
||||||
@@ -775,20 +806,6 @@ class AppsProvider with ChangeNotifier {
|
|||||||
return appsDir;
|
return appsDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<PackageInfo?> getInstalledInfo(String? packageName,
|
|
||||||
{bool printErr = true}) async {
|
|
||||||
if (packageName != null) {
|
|
||||||
try {
|
|
||||||
return await pm.getPackageInfo(packageName: packageName);
|
|
||||||
} catch (e) {
|
|
||||||
if (printErr) {
|
|
||||||
print(e); // OK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isVersionDetectionPossible(AppInMemory? app) {
|
bool isVersionDetectionPossible(AppInMemory? app) {
|
||||||
if (app?.app == null) {
|
if (app?.app == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -803,8 +820,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
? app.installedInfo?.versionCode.toString()
|
? app.installedInfo?.versionCode.toString()
|
||||||
: app.installedInfo?.versionName;
|
: app.installedInfo?.versionName;
|
||||||
return app.app.additionalSettings['trackOnly'] != true &&
|
return app.app.additionalSettings['trackOnly'] != true &&
|
||||||
app.app.additionalSettings['versionDetection'] !=
|
app.app.additionalSettings['releaseDateAsVersion'] != true &&
|
||||||
'releaseDateAsVersion' &&
|
|
||||||
realInstalledVersion != null &&
|
realInstalledVersion != null &&
|
||||||
app.app.installedVersion != null &&
|
app.app.installedVersion != null &&
|
||||||
(reconcileVersionDifferences(
|
(reconcileVersionDifferences(
|
||||||
@@ -820,8 +836,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
var modded = false;
|
var modded = false;
|
||||||
var trackOnly = app.additionalSettings['trackOnly'] == true;
|
var trackOnly = app.additionalSettings['trackOnly'] == true;
|
||||||
var versionDetectionIsStandard =
|
var versionDetectionIsStandard =
|
||||||
app.additionalSettings['versionDetection'] ==
|
app.additionalSettings['versionDetection'] == true;
|
||||||
'standardVersionDetection';
|
|
||||||
var naiveStandardVersionDetection =
|
var naiveStandardVersionDetection =
|
||||||
app.additionalSettings['naiveStandardVersionDetection'] == true ||
|
app.additionalSettings['naiveStandardVersionDetection'] == true ||
|
||||||
SourceProvider()
|
SourceProvider()
|
||||||
@@ -875,7 +890,7 @@ class AppsProvider with ChangeNotifier {
|
|||||||
versionDetectionIsStandard &&
|
versionDetectionIsStandard &&
|
||||||
!isVersionDetectionPossible(
|
!isVersionDetectionPossible(
|
||||||
AppInMemory(app, null, installedInfo, null))) {
|
AppInMemory(app, null, installedInfo, null))) {
|
||||||
app.additionalSettings['versionDetection'] = 'noVersionDetection';
|
app.additionalSettings['versionDetection'] = false;
|
||||||
logs.add('Could not reconcile version formats for: ${app.id}');
|
logs.add('Could not reconcile version formats for: ${app.id}');
|
||||||
modded = true;
|
modded = true;
|
||||||
}
|
}
|
||||||
@@ -917,6 +932,17 @@ class AppsProvider with ChangeNotifier {
|
|||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> updateInstallStatusInMemory(AppInMemory app) async {
|
||||||
|
apps[app.app.id]?.installedInfo = await getInstalledInfo(app.app.id);
|
||||||
|
apps[app.app.id]?.icon =
|
||||||
|
await apps[app.app.id]?.installedInfo?.applicationInfo?.getAppIcon();
|
||||||
|
apps[app.app.id]?.app.name = await (apps[app.app.id]
|
||||||
|
?.installedInfo
|
||||||
|
?.applicationInfo
|
||||||
|
?.getAppLabel()) ??
|
||||||
|
app.name;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> loadApps({String? singleId}) async {
|
Future<void> loadApps({String? singleId}) async {
|
||||||
while (loadingApps) {
|
while (loadingApps) {
|
||||||
await Future.delayed(const Duration(microseconds: 1));
|
await Future.delayed(const Duration(microseconds: 1));
|
||||||
@@ -965,19 +991,11 @@ class AppsProvider with ChangeNotifier {
|
|||||||
NotificationsProvider().notify(
|
NotificationsProvider().notify(
|
||||||
AppsRemovedNotification(errors.map((e) => [e[1], e[2]]).toList()));
|
AppsRemovedNotification(errors.map((e) => [e[1], e[2]]).toList()));
|
||||||
}
|
}
|
||||||
|
// Get install status and other OS info for each App (slow)
|
||||||
for (var app in apps.values) {
|
await Future.wait(apps.values.map((app) {
|
||||||
// Get install status and other OS info for each App (slow)
|
return updateInstallStatusInMemory(app);
|
||||||
apps[app.app.id]?.installedInfo = await getInstalledInfo(app.app.id);
|
}));
|
||||||
apps[app.app.id]?.icon =
|
notifyListeners();
|
||||||
await apps[app.app.id]?.installedInfo?.applicationInfo?.getAppIcon();
|
|
||||||
apps[app.app.id]?.app.name = await (apps[app.app.id]
|
|
||||||
?.installedInfo
|
|
||||||
?.applicationInfo
|
|
||||||
?.getAppLabel()) ??
|
|
||||||
app.name;
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
// Reconcile version differences
|
// Reconcile version differences
|
||||||
List<App> modifiedApps = [];
|
List<App> modifiedApps = [];
|
||||||
for (var app in apps.values) {
|
for (var app in apps.values) {
|
||||||
@@ -1000,7 +1018,6 @@ class AppsProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingApps = false;
|
loadingApps = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
@@ -1676,8 +1693,7 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
|
|||||||
}
|
}
|
||||||
if (toInstall.isNotEmpty) {
|
if (toInstall.isNotEmpty) {
|
||||||
logs.add('BG install task: Started (${toInstall.length}).');
|
logs.add('BG install task: Started (${toInstall.length}).');
|
||||||
var tempObtArr =
|
var tempObtArr = toInstall.where((element) => element.key == obtainiumId);
|
||||||
toInstall.where((element) => element.key == obtainiumApp.id);
|
|
||||||
if (tempObtArr.isNotEmpty) {
|
if (tempObtArr.isNotEmpty) {
|
||||||
// Move obtainium to the end of the list as it must always install last
|
// Move obtainium to the end of the list as it must always install last
|
||||||
var obt = tempObtArr.first;
|
var obt = tempObtArr.first;
|
||||||
|
@@ -15,22 +15,8 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|||||||
import 'package:shared_storage/shared_storage.dart' as saf;
|
import 'package:shared_storage/shared_storage.dart' as saf;
|
||||||
|
|
||||||
String obtainiumTempId = 'imranr98_obtainium_${GitHub().hosts[0]}';
|
String obtainiumTempId = 'imranr98_obtainium_${GitHub().hosts[0]}';
|
||||||
|
String obtainiumId = 'dev.imranr.obtainium';
|
||||||
App obtainiumApp = App(
|
String obtainiumUrl = 'https://github.com/ImranR98/Obtainium';
|
||||||
'dev.imranr.obtainium',
|
|
||||||
'https://github.com/ImranR98/Obtainium',
|
|
||||||
'ImranR98',
|
|
||||||
'Obtainium',
|
|
||||||
currentReleaseTag,
|
|
||||||
currentReleaseTag,
|
|
||||||
[],
|
|
||||||
0,
|
|
||||||
{
|
|
||||||
'includePrereleases': true,
|
|
||||||
'versionDetection': 'standardVersionDetection'
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
false);
|
|
||||||
|
|
||||||
enum InstallMethodSettings { normal, shizuku, root }
|
enum InstallMethodSettings { normal, shizuku, root }
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ import 'package:obtainium/app_sources/apkmirror.dart';
|
|||||||
import 'package:obtainium/app_sources/apkpure.dart';
|
import 'package:obtainium/app_sources/apkpure.dart';
|
||||||
import 'package:obtainium/app_sources/aptoide.dart';
|
import 'package:obtainium/app_sources/aptoide.dart';
|
||||||
import 'package:obtainium/app_sources/codeberg.dart';
|
import 'package:obtainium/app_sources/codeberg.dart';
|
||||||
|
import 'package:obtainium/app_sources/directAPKLink.dart';
|
||||||
import 'package:obtainium/app_sources/fdroid.dart';
|
import 'package:obtainium/app_sources/fdroid.dart';
|
||||||
import 'package:obtainium/app_sources/fdroidrepo.dart';
|
import 'package:obtainium/app_sources/fdroidrepo.dart';
|
||||||
import 'package:obtainium/app_sources/github.dart';
|
import 'package:obtainium/app_sources/github.dart';
|
||||||
@@ -103,6 +104,21 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
|
|||||||
additionalSettings.remove('releaseDateAsVersion');
|
additionalSettings.remove('releaseDateAsVersion');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Convert dropdown style version detection options back into bool style
|
||||||
|
if (additionalSettings['versionDetection'] == 'standardVersionDetection') {
|
||||||
|
additionalSettings['versionDetection'] = true;
|
||||||
|
} else if (additionalSettings['versionDetection'] == 'noVersionDetection') {
|
||||||
|
additionalSettings['versionDetection'] = false;
|
||||||
|
} else if (additionalSettings['versionDetection'] == 'releaseDateAsVersion') {
|
||||||
|
additionalSettings['versionDetection'] = false;
|
||||||
|
additionalSettings['releaseDateAsVersion'] = true;
|
||||||
|
}
|
||||||
|
// Convert bool style pseudo version method to dropdown style
|
||||||
|
if (originalAdditionalSettings['supportFixedAPKURL'] == true) {
|
||||||
|
additionalSettings['defaultPseudoVersioningMethod'] = 'partialAPKHash';
|
||||||
|
} else if (originalAdditionalSettings['supportFixedAPKURL'] == false) {
|
||||||
|
additionalSettings['defaultPseudoVersioningMethod'] = 'APKLinkHash';
|
||||||
|
}
|
||||||
// Ensure additionalSettings are correctly typed
|
// Ensure additionalSettings are correctly typed
|
||||||
for (var item in formItems) {
|
for (var item in formItems) {
|
||||||
if (additionalSettings[item.key] != null) {
|
if (additionalSettings[item.key] != null) {
|
||||||
@@ -380,28 +396,24 @@ abstract class AppSource {
|
|||||||
bool allowSubDomains = false;
|
bool allowSubDomains = false;
|
||||||
bool naiveStandardVersionDetection = false;
|
bool naiveStandardVersionDetection = false;
|
||||||
bool neverAutoSelect = false;
|
bool neverAutoSelect = false;
|
||||||
|
bool showReleaseDateAsVersionToggle = false;
|
||||||
|
bool versionDetectionDisallowed = false;
|
||||||
|
List<String> excludeCommonSettingKeys = [];
|
||||||
|
|
||||||
AppSource() {
|
AppSource() {
|
||||||
name = runtimeType.toString();
|
name = runtimeType.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
overrideVersionDetectionFormDefault(String vd,
|
overrideAdditionalAppSpecificSourceAgnosticSettingSwitch(String key,
|
||||||
{bool disableStandard = false, bool disableRelDate = false}) {
|
{bool disabled = true, bool defaultValue = true}) {
|
||||||
additionalAppSpecificSourceAgnosticSettingFormItems =
|
additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly =
|
||||||
additionalAppSpecificSourceAgnosticSettingFormItems.map((e) {
|
additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly
|
||||||
|
.map((e) {
|
||||||
return e.map((e2) {
|
return e.map((e2) {
|
||||||
if (e2.key == 'versionDetection') {
|
if (e2.key == key) {
|
||||||
var item = e2 as GeneratedFormDropdown;
|
var item = e2 as GeneratedFormSwitch;
|
||||||
item.defaultValue = vd;
|
item.disabled = disabled;
|
||||||
item.disabledOptKeys = [];
|
item.defaultValue = defaultValue;
|
||||||
if (disableStandard) {
|
|
||||||
item.disabledOptKeys?.add('standardVersionDetection');
|
|
||||||
}
|
|
||||||
if (disableRelDate) {
|
|
||||||
item.disabledOptKeys?.add('releaseDateAsVersion');
|
|
||||||
}
|
|
||||||
item.disabledOptKeys =
|
|
||||||
item.disabledOptKeys?.where((element) => element != vd).toList();
|
|
||||||
}
|
}
|
||||||
return e2;
|
return e2;
|
||||||
}).toList();
|
}).toList();
|
||||||
@@ -457,7 +469,7 @@ abstract class AppSource {
|
|||||||
|
|
||||||
// Some additional data may be needed for Apps regardless of Source
|
// Some additional data may be needed for Apps regardless of Source
|
||||||
List<List<GeneratedFormItem>>
|
List<List<GeneratedFormItem>>
|
||||||
additionalAppSpecificSourceAgnosticSettingFormItems = [
|
additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly = [
|
||||||
[
|
[
|
||||||
GeneratedFormSwitch(
|
GeneratedFormSwitch(
|
||||||
'trackOnly',
|
'trackOnly',
|
||||||
@@ -475,16 +487,8 @@ abstract class AppSource {
|
|||||||
label: tr('matchGroupToUse'), required: false, hint: '\$0')
|
label: tr('matchGroupToUse'), required: false, hint: '\$0')
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
GeneratedFormDropdown(
|
GeneratedFormSwitch('versionDetection',
|
||||||
'versionDetection',
|
label: tr('versionDetectionExplanation'), defaultValue: true)
|
||||||
[
|
|
||||||
MapEntry(
|
|
||||||
'standardVersionDetection', tr('standardVersionDetection')),
|
|
||||||
MapEntry('releaseDateAsVersion', tr('releaseDateAsVersion')),
|
|
||||||
MapEntry('noVersionDetection', tr('noVersionDetection'))
|
|
||||||
],
|
|
||||||
label: tr('versionDetection'),
|
|
||||||
defaultValue: 'standardVersionDetection')
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
GeneratedFormSwitch('useVersionCodeAsOSVersion',
|
GeneratedFormSwitch('useVersionCodeAsOSVersion',
|
||||||
@@ -500,6 +504,11 @@ abstract class AppSource {
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
GeneratedFormSwitch('invertAPKFilter',
|
||||||
|
label: '${tr('invertRegEx')} (${tr('filterAPKsByRegEx')})',
|
||||||
|
defaultValue: false)
|
||||||
|
],
|
||||||
[
|
[
|
||||||
GeneratedFormSwitch('autoApkFilterByArch',
|
GeneratedFormSwitch('autoApkFilterByArch',
|
||||||
label: tr('autoApkFilterByArch'), defaultValue: true)
|
label: tr('autoApkFilterByArch'), defaultValue: true)
|
||||||
@@ -518,9 +527,48 @@ abstract class AppSource {
|
|||||||
|
|
||||||
// Previous 2 variables combined into one at runtime for convenient usage
|
// Previous 2 variables combined into one at runtime for convenient usage
|
||||||
List<List<GeneratedFormItem>> get combinedAppSpecificSettingFormItems {
|
List<List<GeneratedFormItem>> get combinedAppSpecificSettingFormItems {
|
||||||
|
if (showReleaseDateAsVersionToggle == true) {
|
||||||
|
if (additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly
|
||||||
|
.indexWhere((List<GeneratedFormItem> e) =>
|
||||||
|
e.indexWhere((GeneratedFormItem i) =>
|
||||||
|
i.key == 'releaseDateAsVersion') >=
|
||||||
|
0) <
|
||||||
|
0) {
|
||||||
|
additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly.insert(
|
||||||
|
additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly
|
||||||
|
.indexWhere((List<GeneratedFormItem> e) =>
|
||||||
|
e.indexWhere((GeneratedFormItem i) =>
|
||||||
|
i.key == 'versionDetection') >=
|
||||||
|
0) +
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
GeneratedFormSwitch('releaseDateAsVersion',
|
||||||
|
label:
|
||||||
|
'${tr('releaseDateAsVersion')} (${tr('pseudoVersion')})',
|
||||||
|
defaultValue: false)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly =
|
||||||
|
additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly
|
||||||
|
.map((e) => e
|
||||||
|
.where((ee) => !excludeCommonSettingKeys.contains(ee.key))
|
||||||
|
.toList())
|
||||||
|
.where((e) => e.isNotEmpty)
|
||||||
|
.toList();
|
||||||
|
if (versionDetectionDisallowed) {
|
||||||
|
overrideAdditionalAppSpecificSourceAgnosticSettingSwitch(
|
||||||
|
'versionDetection',
|
||||||
|
disabled: true,
|
||||||
|
defaultValue: false);
|
||||||
|
overrideAdditionalAppSpecificSourceAgnosticSettingSwitch(
|
||||||
|
'useVersionCodeAsOSVersion',
|
||||||
|
disabled: true,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
...additionalSourceAppSpecificSettingFormItems,
|
...additionalSourceAppSpecificSettingFormItems,
|
||||||
...additionalAppSpecificSourceAgnosticSettingFormItems
|
...additionalAppSpecificSourceAgnosticSettingFormItemsNeverUseDirectly
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -665,6 +713,20 @@ String? extractVersion(String? versionExtractionRegEx, String? matchGroupString,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<MapEntry<String, String>> filterApks(
|
||||||
|
List<MapEntry<String, String>> apkUrls,
|
||||||
|
String? apkFilterRegEx,
|
||||||
|
bool? invert) {
|
||||||
|
if (apkFilterRegEx?.isNotEmpty == true) {
|
||||||
|
var reg = RegExp(apkFilterRegEx!);
|
||||||
|
apkUrls = apkUrls.where((element) {
|
||||||
|
var hasMatch = reg.hasMatch(element.key);
|
||||||
|
return invert == true ? !hasMatch : hasMatch;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
return apkUrls;
|
||||||
|
}
|
||||||
|
|
||||||
class SourceProvider {
|
class SourceProvider {
|
||||||
// Add more source classes here so they are available via the service
|
// Add more source classes here so they are available via the service
|
||||||
List<AppSource> get sources => [
|
List<AppSource> get sources => [
|
||||||
@@ -687,6 +749,7 @@ class SourceProvider {
|
|||||||
WhatsApp(),
|
WhatsApp(),
|
||||||
TelegramApp(),
|
TelegramApp(),
|
||||||
NeutronCode(),
|
NeutronCode(),
|
||||||
|
DirectAPKLink(),
|
||||||
HTML() // This should ALWAYS be the last option as they are tried in order
|
HTML() // This should ALWAYS be the last option as they are tried in order
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -708,11 +771,15 @@ class SourceProvider {
|
|||||||
}
|
}
|
||||||
AppSource? source;
|
AppSource? source;
|
||||||
for (var s in sources.where((element) => element.hosts.isNotEmpty)) {
|
for (var s in sources.where((element) => element.hosts.isNotEmpty)) {
|
||||||
if (RegExp(
|
try {
|
||||||
'://${s.allowSubDomains ? '([^\\.]+\\.)*' : '(www\\.)?'}(${getSourceRegex(s.hosts)})(/|\\z)?')
|
if (RegExp(
|
||||||
.hasMatch(url)) {
|
'^${s.allowSubDomains ? '([^\\.]+\\.)*' : '(www\\.)?'}(${getSourceRegex(s.hosts)})\$')
|
||||||
source = s;
|
.hasMatch(Uri.parse(url).host)) {
|
||||||
break;
|
source = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (source == null) {
|
if (source == null) {
|
||||||
@@ -773,15 +840,12 @@ class SourceProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (additionalSettings['versionDetection'] == 'releaseDateAsVersion' &&
|
if (additionalSettings['releaseDateAsVersion'] == true &&
|
||||||
apk.releaseDate != null) {
|
apk.releaseDate != null) {
|
||||||
apk.version = apk.releaseDate!.microsecondsSinceEpoch.toString();
|
apk.version = apk.releaseDate!.microsecondsSinceEpoch.toString();
|
||||||
}
|
}
|
||||||
if (additionalSettings['apkFilterRegEx'] != null) {
|
apk.apkUrls = filterApks(apk.apkUrls, additionalSettings['apkFilterRegEx'],
|
||||||
var reg = RegExp(additionalSettings['apkFilterRegEx']);
|
additionalSettings['invertAPKFilter']);
|
||||||
apk.apkUrls =
|
|
||||||
apk.apkUrls.where((element) => reg.hasMatch(element.key)).toList();
|
|
||||||
}
|
|
||||||
if (apk.apkUrls.isEmpty && !trackOnly) {
|
if (apk.apkUrls.isEmpty && !trackOnly) {
|
||||||
throw NoAPKError();
|
throw NoAPKError();
|
||||||
}
|
}
|
||||||
|
48
pubspec.lock
48
pubspec.lock
@@ -307,10 +307,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_local_notifications
|
name: flutter_local_notifications
|
||||||
sha256: "892ada16046d641263f30c72e7432397088810a84f34479f6677494802a2b535"
|
sha256: "66cc2fe16bf4bca71d795939763ad3f1830ad85772dc3b1561613c501859826d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "16.3.0"
|
version: "16.3.1+1"
|
||||||
flutter_local_notifications_linux:
|
flutter_local_notifications_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -394,10 +394,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
|
sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.2.0"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -450,10 +450,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: markdown
|
name: markdown
|
||||||
sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd
|
sha256: "1b134d9f8ff2da15cb298efe6cd8b7d2a78958c1b00384ebcbdf13fe340a6c90"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.1.1"
|
version: "7.2.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -562,50 +562,50 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: permission_handler
|
name: permission_handler
|
||||||
sha256: "860c6b871c94c78e202dc69546d4d8fd84bd59faeb36f8fb9888668a53ff4f78"
|
sha256: "45ff3fbcb99040fde55c528d5e3e6ca29171298a85436274d49c6201002087d6"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "11.1.0"
|
version: "11.2.0"
|
||||||
permission_handler_android:
|
permission_handler_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_android
|
name: permission_handler_android
|
||||||
sha256: "2f1bec180ee2f5665c22faada971a8f024761f632e93ddc23310487df52dcfa6"
|
sha256: "758284a0976772f9c744d6384fc5dc4834aa61e3f7aa40492927f244767374eb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "12.0.1"
|
version: "12.0.3"
|
||||||
permission_handler_apple:
|
permission_handler_apple:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_apple
|
name: permission_handler_apple
|
||||||
sha256: "1a816084338ada8d574b1cb48390e6e8b19305d5120fe3a37c98825bacc78306"
|
sha256: c6bf440f80acd2a873d3d91a699e4cc770f86e7e6b576dda98759e8b92b39830
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "9.2.0"
|
version: "9.3.0"
|
||||||
permission_handler_html:
|
permission_handler_html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_html
|
name: permission_handler_html
|
||||||
sha256: "11b762a8c123dced6461933a88ea1edbbe036078c3f9f41b08886e678e7864df"
|
sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.0+2"
|
version: "0.1.1"
|
||||||
permission_handler_platform_interface:
|
permission_handler_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_platform_interface
|
name: permission_handler_platform_interface
|
||||||
sha256: d87349312f7eaf6ce0adaf668daf700ac5b06af84338bd8b8574dfbd93ffe1a1
|
sha256: "5c43148f2bfb6d14c5a8162c0a712afe891f2d847f35fcff29c406b37da43c3c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.2"
|
version: "4.1.0"
|
||||||
permission_handler_windows:
|
permission_handler_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: permission_handler_windows
|
name: permission_handler_windows
|
||||||
sha256: "1e8640c1e39121128da6b816d236e714d2cf17fac5a105dd6acdd3403a628004"
|
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -634,10 +634,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pointycastle
|
name: pointycastle
|
||||||
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
|
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.7.3"
|
version: "3.7.4"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -943,10 +943,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: webview_flutter_wkwebview
|
name: webview_flutter_wkwebview
|
||||||
sha256: "4d062ad505390ecef1c4bfb6001cd857a51e00912cc9dfb66edb1886a9ebd80c"
|
sha256: b99ca8d8bae9c6b43d568218691aa537fb0aeae1d7d34eadf112a6aa36d26506
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.10.2"
|
version: "3.11.0"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -988,5 +988,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.2.0 <4.0.0"
|
dart: ">=3.2.3 <4.0.0"
|
||||||
flutter: ">=3.16.0"
|
flutter: ">=3.16.6"
|
||||||
|
@@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 0.15.10+246 # When changing this, update the tag in main() accordingly
|
version: 0.16.0+248 # When changing this, update the tag in main() accordingly
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.0 <4.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
|
Reference in New Issue
Block a user