Compare commits

...

33 Commits

Author SHA1 Message Date
a0199f0ceb Merge pull request #349 from ImranR98/dev
Added FR menu option, increment version
2023-03-05 13:07:53 -05:00
0528936e5a Added FR menu option, increment version 2023-03-05 13:07:31 -05:00
4de98b2f36 Merge pull request #348 from sonalder-darlene/main
Add french translation 🇫🇷
2023-03-05 13:03:09 -05:00
dfb5f5596c Add a missing translation 2023-03-05 17:19:04 +00:00
2e706aac47 Add french translation
just added a fr.json with everything translated
2023-03-05 17:16:48 +00:00
24a600e595 Merge pull request #347 from ImranR98/dev
Bugfixes from prev. commit
2023-03-03 23:31:54 -05:00
1596a44ec5 Bugfixes from prev. commit 2023-03-03 23:31:21 -05:00
9ee2be76ca Merge pull request #346 from ImranR98/dev
Icon improvements (#267, #345)
2023-03-03 23:00:47 -05:00
83b770294d Icon improvements (#267, #345) 2023-03-03 23:00:14 -05:00
2679d5a1aa Merge pull request #340 from ImranR98/dev
UI Improvements (#330, #337)
2023-03-01 21:55:47 -05:00
e49c09c0ff Increment version 2023-03-01 21:55:04 -05:00
c9318ef2b5 Merge pull request #336 from markus-gitdev/main
Update de.json
2023-03-01 21:54:05 -05:00
2e88c8eede UI improvements
Update button for individual apps on list is now an icon.
Less clipping on small screens on apps list page.
2023-03-01 21:37:18 -05:00
8648c1bea7 Added icon for non-installed Apps 2023-03-01 20:20:34 -05:00
b22e2bab0c Update de.json
Updated the following strings to a German translation:
- importFromURLsInFile
- versionDetection
- standardVersionDetection
2023-03-01 08:20:04 +01:00
57f7bf44c2 Merge pull request #335 from ImranR98/dev
Language bugfix + package upgrades + incr. ver.
2023-02-27 19:01:20 -05:00
ce526d8d26 Language bugfix + package upgrades + incr. ver. 2023-02-27 19:00:50 -05:00
5f3eeb9971 Merge pull request #333 from ImranR98/dev
Increment version
2023-02-25 15:57:28 -05:00
e67a6b8627 Increment version 2023-02-25 15:57:04 -05:00
f8e99bb0cb Merge pull request #329 from bluefly000/japanese-translation
Update Japanese translation
2023-02-25 15:55:44 -05:00
09b5dd41d3 Merge pull request #331 from gidano/main
Update hu.json
2023-02-25 15:55:38 -05:00
b1bd36408c Merge pull request #332 from mehdijahann/main
Update fa.json
2023-02-25 15:55:26 -05:00
54d8dff32f Update fa.json 2023-02-25 20:52:22 +03:30
7b1416e28e Update hu.json 2023-02-25 11:17:17 +01:00
926e7b89ce Update Japanese translation 2023-02-25 13:57:07 +09:00
43d4f89d61 Merge pull request #328 from ImranR98/dev
Added "URLs in File" import (#326) + UI Improvements (#312, #325)
2023-02-24 23:12:02 -05:00
2190da162d Merge remote-tracking branch 'origin/main' into dev 2023-02-24 23:09:18 -05:00
f10bb5ac91 Increment version, upgrade packages 2023-02-24 23:02:32 -05:00
8e52f9666d UI Bugfix 2023-02-24 22:58:56 -05:00
a8a47bb153 Unified version detection setting 2023-02-24 22:48:30 -05:00
728dafcc28 Added "URLs in file (like OPML)" import 2023-02-24 21:54:27 -05:00
d53b21906c Merge pull request #324 from markus-gitdev/main
Update de.json
2023-02-24 18:26:39 -05:00
d6dcac0f97 Update de.json
Improve readability.
2023-02-24 10:00:15 +01:00
34 changed files with 729 additions and 319 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,46 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="142.129"
android:viewportHeight="142.129"
android:width="503.6066dp"
android:height="503.6066dp">
<group
android:translateX="-30.39437"
android:translateY="-54.68043">
<path
android:pathData="M109.8808 153.22596c-0.73146 -0.38777 -5.00657 -2.75679 -25.032416 -13.87149 -5.57273 -3.09297 -10.93823 -6.06723 -11.92332 -6.60948 -2.23728 -1.23152 -2.58105 -1.53456 -2.58105 -2.27528 0 -0.3879 0.89293 -2.87231 2.98561 -8.30689 1.64209 -4.2644 3.09426 -8.0014 3.22705 -8.30444 0.3024 -0.69008 0.78972 -1.27621 1.26573 -1.52236 0.44558 -0.23042 11.58052 -4.29685 12.14814 -4.43644 0.61355 -0.1509 1.1428 0.13977 1.45487 0.79901 0.14976 0.31638 0.77213 1.94934 1.38303 3.6288 0.6109 1.67945 1.52036 4.16275 2.02104 5.51844 1.14709 3.10604 1.18992 3.54589 0.3912 4.01771 -0.2117 0.12505 -1.58874 0.66539 -3.06009 1.20075 -1.47136 0.53536 -2.87533 1.08982 -3.11993 1.23213 -0.56422 0.32826 -0.64913 0.83523 -0.20815 1.24273 0.17523 0.16193 3.00434 1.77571 6.28691 3.58618 9.174936 5.06035 8.665596 4.83136 9.277626 4.17097 0.29987 -0.32356 5.78141 -14.266 6.09596 -15.50521 0.1344 -0.5295 0.11969 -0.60308 -0.16695 -0.83519 -0.39165 -0.31714 -0.335 -0.33071 -3.93797 0.9431 -3.56937 1.26192 -3.90926 1.28864 -4.38744 0.34488 -0.25108 -0.49556 -4.095796 -11.05481 -4.334456 -11.90432 -0.15438 -0.5495 0.0344 -1.0717 0.49701 -1.37482 0.19228 -0.12598 2.990116 -1.19935 6.217406 -2.38526 4.78924 -1.75986 6.0081 -2.15842 6.63117 -2.16837 0.8037 -0.0128 0.90917 0.0424 15.64514 8.19599 1.02104 0.56495 1.56579 1.15961 1.56579 1.70925 0 0.21814 -3.6538 9.91011 -8.11957 21.53771 -6.2982 16.39877 -8.19916 21.21114 -8.4744 21.45338 -0.46789 0.41179 -0.8512 0.39392 -1.74794 -0.0815z"
android:strokeWidth="0.139">
<aapt:attr
name="android:fillColor">
<gradient
android:startX="76.74697"
android:startY="113.4246"
android:endX="110.6445"
android:endY="152.5006"
android:tileMode="clamp">
<item
android:color="#9B58DC"
android:offset="0" />
<item
android:color="#321C92"
android:offset="1" />
</gradient>
</aapt:attr>
<aapt:attr
name="android:strokeColor">
<gradient
android:startX="76.74697"
android:startY="113.4246"
android:endX="110.6445"
android:endY="152.5006"
android:tileMode="clamp">
<item
android:color="#9B58DC"
android:offset="0" />
<item
android:color="#321C92"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
</group>
</vector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

78
assets/graphics/icon.svg Normal file
View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="142.12897mm"
height="142.12897mm"
viewBox="0 0 142.12897 142.12897"
version="1.1"
id="svg5"
xml:space="preserve"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="icon.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2.4175295"
inkscape:cx="371.03994"
inkscape:cy="273.62644"
inkscape:window-width="2256"
inkscape:window-height="1427"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs
id="defs2"><linearGradient
inkscape:collect="always"
id="linearGradient3657"><stop
style="stop-color:#9b58dc;stop-opacity:1;"
offset="0"
id="stop3653" /><stop
style="stop-color:#321c92;stop-opacity:1;"
offset="1"
id="stop3655" /></linearGradient><linearGradient
inkscape:collect="always"
id="linearGradient945"><stop
style="stop-color:#9b58dc;stop-opacity:1;"
offset="0"
id="stop941" /><stop
style="stop-color:#321c92;stop-opacity:1;"
offset="1"
id="stop943" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient945"
id="linearGradient947"
x1="76.787094"
y1="113.40435"
x2="110.68458"
y2="152.48038"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.04012535,0.02025786)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3657"
id="linearGradient3659"
x1="76.787094"
y1="113.40435"
x2="110.68458"
y2="152.48038"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.04012535,0.02025786)" /></defs><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-30.394373,-54.680428)"><path
style="fill:url(#linearGradient3659);fill-opacity:1;stroke:url(#linearGradient947);stroke-width:0.139;stroke-dasharray:none"
d="m 109.8808,153.22596 c -0.73146,-0.38777 -5.00657,-2.75679 -25.032416,-13.87149 -5.57273,-3.09297 -10.93823,-6.06723 -11.92332,-6.60948 -2.23728,-1.23152 -2.58105,-1.53456 -2.58105,-2.27528 0,-0.3879 0.89293,-2.87231 2.98561,-8.30689 1.64209,-4.2644 3.09426,-8.0014 3.22705,-8.30444 0.3024,-0.69008 0.78972,-1.27621 1.26573,-1.52236 0.44558,-0.23042 11.58052,-4.29685 12.14814,-4.43644 0.61355,-0.1509 1.1428,0.13977 1.45487,0.79901 0.14976,0.31638 0.77213,1.94934 1.38303,3.6288 0.6109,1.67945 1.52036,4.16275 2.02104,5.51844 1.14709,3.10604 1.18992,3.54589 0.3912,4.01771 -0.2117,0.12505 -1.58874,0.66539 -3.06009,1.20075 -1.47136,0.53536 -2.87533,1.08982 -3.11993,1.23213 -0.56422,0.32826 -0.64913,0.83523 -0.20815,1.24273 0.17523,0.16193 3.00434,1.77571 6.28691,3.58618 9.174936,5.06035 8.665596,4.83136 9.277626,4.17097 0.29987,-0.32356 5.78141,-14.266 6.09596,-15.50521 0.1344,-0.5295 0.11969,-0.60308 -0.16695,-0.83519 -0.39165,-0.31714 -0.335,-0.33071 -3.93797,0.9431 -3.56937,1.26192 -3.90926,1.28864 -4.38744,0.34488 -0.25108,-0.49556 -4.095796,-11.05481 -4.334456,-11.90432 -0.15438,-0.5495 0.0344,-1.0717 0.49701,-1.37482 0.19228,-0.12598 2.990116,-1.19935 6.217406,-2.38526 4.78924,-1.75986 6.0081,-2.15842 6.63117,-2.16837 0.8037,-0.0128 0.90917,0.0424 15.64514,8.19599 1.02104,0.56495 1.56579,1.15961 1.56579,1.70925 0,0.21814 -3.6538,9.91011 -8.11957,21.53771 -6.2982,16.39877 -8.19916,21.21114 -8.4744,21.45338 -0.46789,0.41179 -0.8512,0.39392 -1.74794,-0.0815 z"
id="path239" /></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -209,14 +209,17 @@
"language": "Sprache",
"storagePermissionDenied": "Speicherberechtigung verweigert",
"selectedCategorizeWarning": "Dadurch werden alle bestehenden Kategorieeinstellungen für die ausgewählten Apps ersetzt.",
"filterAPKsByRegEx": "APKs mit regulärem Ausdruck (RegEx) filtern",
"filterAPKsByRegEx": "APKs nach regulärem Ausdruck filtern",
"removeFromObtainium": "Aus Obtainium entfernen",
"uninstallFromDevice": "Vom Gerät deinstallieren",
"onlyWorksWithNonVersionDetectApps": "Funktioniert nur bei Apps mit deaktivierter Versionserkennung.",
"useReleaseDateAsVersion": "Veröffentlichungsdatum als Version verwenden",
"releaseDateAsVersion": "Veröffentlichungsdatum als Version verwenden",
"releaseDateAsVersionExplanation": "Diese Option sollte nur für Apps verwendet werden, bei denen die Versionserkennung nicht korrekt funktioniert, aber ein Veröffentlichungsdatum verfügbar ist.",
"changes": "Änderungen",
"releaseDate": "Veröffentlichungsdatum",
"importFromURLsInFile": "Importieren von URLs aus Datei ( z.B. OPML)",
"versionDetection": "Versionserkennung",
"standardVersionDetection": "Standardversionserkennung",
"removeAppQuestion": {
"one": "App entfernen?",
"other": "App entfernen?"

View File

@ -213,10 +213,13 @@
"removeFromObtainium": "Remove from Obtainium",
"uninstallFromDevice": "Uninstall from Device",
"onlyWorksWithNonVersionDetectApps": "Only works for Apps with version detection disabled.",
"useReleaseDateAsVersion": "Use Release Date as Version",
"releaseDateAsVersion": "Use Release Date as Version",
"releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes",
"releaseDate": "Release Date",
"importFromURLsInFile": "Import from URLs in File (like OPML)",
"versionDetection": "Version Detection",
"standardVersionDetection": "Standard version detection",
"removeAppQuestion": {
"one": "Remove App?",
"other": "Remove Apps?"

View File

@ -213,10 +213,13 @@
"removeFromObtainium": "از Obtainium حذف کنید",
"uninstallFromDevice": "حذف نصب از دستگاه",
"onlyWorksWithNonVersionDetectApps": "فقط برای برنامه‌هایی کار می‌کند که تشخیص نسخه غیرفعال است.",
"useReleaseDateAsVersion": "Use Release Date as Version",
"releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes",
"releaseDate": "Release Date",
"releaseDateAsVersion": "از تاریخ انتشار به عنوان نسخه استفاده کنید",
"releaseDateAsVersionExplanation": "این گزینه فقط باید برای برنامه هایی استفاده شود که تشخیص نسخه به درستی کار نمی کند، اما تاریخ انتشار در دسترس است.",
"changes": "تغییرات",
"releaseDate": "تاریخ انتشار",
"importFromURLsInFile": "وارد کردن از آدرس های اینترنتی موجود در فایل (مانند OPML)",
"versionDetection": "تشخیص نسخه",
"standardVersionDetection": "تشخیص نسخه استاندارد",
"removeAppQuestion": {
"one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟"

271
assets/translations/fr.json Normal file
View File

@ -0,0 +1,271 @@
{
"invalidURLForSource": "URL d'application {} invalide",
"noReleaseFound": "Impossible de trouver une version appropriée",
"noVersionFound": "Impossible de déterminer la version de la version",
"urlMatchesNoSource": "L'URL ne correspond pas à une source connue",
"cantInstallOlderVersion": "Impossible d'installer une ancienne version d'une application",
"appIdMismatch": "L'ID de paquet téléchargé ne correspond pas à l'ID de l'application existante",
"functionNotImplemented": "Cette classe n'a pas implémenté cette fonction",
"placeholder": "Espace réservé",
"someErrors": "Des erreurs se sont produites",
"unexpectedError": "Erreur inattendue",
"ok": "Okay",
"and": "et",
"startedBgUpdateTask": "Démarrage de la tâche de vérification de mise à jour en arrière-plan",
"bgUpdateIgnoreAfterIs": "Mise à jour en arrière-plan est ignoré après {}",
"startedActualBGUpdateCheck": "Démarrage de la vérification de la mise à jour en arrière-plan",
"bgUpdateTaskFinished": "Tâche de vérification de la mise à jour en arrière-plan terminée",
"firstRun": "Il s'agit de la toute première exécution d'Obtainium",
"settingUpdateCheckIntervalTo": "Définition de l'intervalle de mise à jour sur {}",
"githubPATLabel": "Jeton d'Accès Personnel GitHub (Augmente la limite de débit)",
"githubPATHint": "Le JAP doit être dans ce format : username:token",
"githubPATFormat": "username:token",
"githubPATLinkText": "À propos des JAP GitHub",
"includePrereleases": "Inclure les avant-premières",
"fallbackToOlderReleases": "Retour aux anciennes versions",
"filterReleaseTitlesByRegEx": "Filtrer les titres de version par expression régulière",
"invalidRegEx": "Expression régulière invalide",
"noDescription": "Pas de description",
"cancel": "Annuler",
"continue": "Continuer",
"requiredInBrackets": "(Requis)",
"dropdownNoOptsError": "ERREUR : LE DÉROULEMENT DOIT AVOIR AU MOINS UNE OPT",
"colour": "Couleur",
"githubStarredRepos": "Dépôts étoilés GitHub",
"uname": "Nom d'utilisateur",
"wrongArgNum": "Mauvais nombre d'arguments fournis",
"xIsTrackOnly": "{} est en 'Suivi uniquement'",
"source": "Source",
"app": "Application",
"appsFromSourceAreTrackOnly": "Les applications de cette source sont en 'Suivi uniquement'.",
"youPickedTrackOnly": "Vous avez sélectionné l'option 'Suivi uniquement'.",
"trackOnlyAppDescription": "L'application sera suivie pour les mises à jour, mais Obtainium ne pourra pas la télécharger ou l'installer.",
"cancelled": "Annulé",
"appAlreadyAdded": "Application déjà ajoutée",
"alreadyUpToDateQuestion": "Application déjà à jour ?",
"addApp": "Ajouter une application",
"appSourceURL": "URL de la source de l'application",
"error": "Erreur",
"add": "Ajoutée",
"searchSomeSourcesLabel": "Rechercher (certaines sources uniquement)",
"search": "Rechercher",
"additionalOptsFor": "Options supplémentaires pour {}",
"supportedSourcesBelow": "Sources prises en charge :",
"trackOnlyInBrackets": "(Suivi uniquement)",
"searchableInBrackets": "(Recherchable)",
"appsString": "Applications",
"noApps": "Aucune application",
"noAppsForFilter": "Aucune application pour le filtre",
"byX": "Par {}",
"percentProgress": "Progrès: {}%",
"pleaseWait": "Veuillez patienter",
"updateAvailable": "Mise à jour disponible",
"estimateInBracketsShort": "(Est.)",
"notInstalled": "Pas installé",
"estimateInBrackets": "(Estimation)",
"selectAll": "Tout sélectionner",
"deselectN": "Déselectionner {}",
"xWillBeRemovedButRemainInstalled": "{} sera supprimé d'Obtainium mais restera installé sur l'appareil.",
"removeSelectedAppsQuestion": "Supprimer les applications sélectionnées ?",
"removeSelectedApps": "Supprimer les applications sélectionnées",
"updateX": "Mise à jour {}",
"installX": "Installer {}",
"markXTrackOnlyAsUpdated": "Marquer {}\n(Suivi uniquement)\nas mis à jour",
"changeX": "Changer {}",
"installUpdateApps": "Installer/Mettre à jour les applications",
"installUpdateSelectedApps": "Installer/Mettre à jour les applications sélectionnées",
"markXSelectedAppsAsUpdated": "Marquer {} les applications sélectionnées comme mises à jour ?",
"no": "Non",
"yes": "Oui",
"markSelectedAppsUpdated": "Marquer les applications sélectionnées comme mises à jour",
"pinToTop": "Épingler en haut",
"unpinFromTop": "Détacher du haut",
"resetInstallStatusForSelectedAppsQuestion": "Réinitialiser l'état d'installation des applications sélectionnées ?",
"installStatusOfXWillBeResetExplanation": "L'état d'installation de toutes les applications sélectionnées sera réinitialisé.\n\nCela peut aider lorsque la version de l'application affichée dans Obtainium est incorrecte en raison d'échecs de mises à jour ou d'autres problèmes.",
"shareSelectedAppURLs": "Partager les URL d'application sélectionnées",
"resetInstallStatus": "Réinitialiser le statut d'installation",
"more": "Plus",
"removeOutdatedFilter": "Supprimer le filtre d'application obsolète",
"showOutdatedOnly": "Afficher uniquement les applications obsolètes",
"filter": "Filtre",
"filterActive": "Filtre *",
"filterApps": "Filtrer les applications",
"appName": "Nom de l'application",
"author": "Auteur",
"upToDateApps": "Applications à jour",
"nonInstalledApps": "Applications non installées",
"importExport": "Importer/Exporter",
"settings": "Paramètres",
"exportedTo": "Exporté vers {}",
"obtainiumExport": "Exportation d'Obtainium",
"invalidInput": "Entrée invalide",
"importedX": "Importé {}",
"obtainiumImport": "Importation d'Obtainium",
"importFromURLList": "Importer à partir de la liste d'URL",
"searchQuery": "Requête de recherche",
"appURLList": "Liste d'URL d'application",
"line": "Queue",
"searchX": "Rechercher {}",
"noResults": "Aucun résultat trouvé",
"importX": "Importer {}",
"importedAppsIdDisclaimer": "Les applications importées peuvent s'afficher à tort comme \"Non installées\".\nPour résoudre ce problème, réinstallez-les via Obtainium.\nCela ne devrait pas affecter les données de l'application.\n\nN'affecte que les URL et les méthodes d'importation tierces.",
"importErrors": "Erreurs d'importation",
"importedXOfYApps": "{} sur {} applications importées.",
"followingURLsHadErrors": "Les URL suivantes comportaient des erreurs :",
"okay": "Okay",
"selectURL": "Sélectionnez l'URL",
"selectURLs": "Sélectionnez les URLs",
"pick": "Prendre",
"theme": "Thème",
"dark": "Sombre",
"light": "Clair",
"followSystem": "Suivre le système",
"obtainium": "Obtainium",
"materialYou": "Material You",
"appSortBy": "Applications triées par",
"authorName": "Auteur/Nom",
"nameAuthor": "Nom/Auteur",
"asAdded": "Comme ajouté",
"appSortOrder": "Ordre de tri des applications",
"ascending": "Ascendant",
"descending": "Descendanr",
"bgUpdateCheckInterval": "Intervalle de vérification des mises à jour en arrière-plan",
"neverManualOnly": "Jamais - Manuel uniquement",
"appearance": "Apparence",
"showWebInAppView": "Afficher la page Web source dans la vue de l'application",
"pinUpdates": "Épingler les mises à jour dans la vue Top des applications",
"updates": "Mises à jour",
"sourceSpecific": "Spécifique à la source",
"appSource": "Source de l'application",
"noLogs": "Aucun journal",
"appLogs": "Journaux d'application",
"close": "Fermer",
"share": "Partager",
"appNotFound": "Application introuvable",
"obtainiumExportHyphenatedLowercase": "obtainium-export",
"pickAnAPK": "Choisissez un APK",
"appHasMoreThanOnePackage": "{} a plus d'un paquet :",
"deviceSupportsXArch": "Votre appareil prend en charge l'architecture de processeur {}.",
"deviceSupportsFollowingArchs": "Votre appareil prend en charge les architectures CPU suivantes :",
"warning": "Avertissement",
"sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais le paquet de version provient de '{}'. Continuer?",
"updatesAvailable": "Mises à jour disponibles",
"updatesAvailableNotifDescription": "Avertit l'utilisateur que des mises à jour sont disponibles pour une ou plusieurs applications suivies par Obtainium",
"noNewUpdates": "Aucune nouvelle mise à jour.",
"xHasAnUpdate": "{} a une mise à jour.",
"appsUpdated": "Applications mises à jour",
"appsUpdatedNotifDescription": "Avertit l'utilisateur que les mises à jour d'une ou plusieurs applications ont été appliquées en arrière-plan",
"xWasUpdatedToY": "{} a été mis à jour pour {}.",
"errorCheckingUpdates": "Erreur lors de la vérification des mises à jour",
"errorCheckingUpdatesNotifDescription": "Une notification qui s'affiche lorsque la vérification de la mise à jour en arrière-plan échoue",
"appsRemoved": "Applications supprimées",
"appsRemovedNotifDescription": "Avertit l'utilisateur qu'une ou plusieurs applications ont été supprimées en raison d'erreurs lors de leur chargement",
"xWasRemovedDueToErrorY": "{} a été supprimé en raison de cette erreur : {}",
"completeAppInstallation": "Installation complète de l'application",
"obtainiumMustBeOpenToInstallApps": "Obtainium doit être ouvert pour installer des applications",
"completeAppInstallationNotifDescription": "Demande à l'utilisateur de retourner sur Obtainium pour terminer l'installation d'une application",
"checkingForUpdates": "Vérification des mises à jour",
"checkingForUpdatesNotifDescription": "Notification transitoire qui apparaît lors de la recherche de mises à jour",
"pleaseAllowInstallPerm": "Veuillez autoriser Obtainium à installer des applications",
"trackOnly": "Suivi uniquement",
"errorWithHttpStatusCode": "Erreur {}",
"versionCorrectionDisabled": "Correction de version désactivée (le plugin ne semble pas fonctionner)",
"unknown": "Inconnu",
"none": "Aucun",
"never": "Jamais",
"latestVersionX": "Dernière version: {}",
"installedVersionX": "Version installée : {}",
"lastUpdateCheckX": "Vérification de la dernière mise à jour : {}",
"remove": "Retirer",
"yesMarkUpdated": "Oui, marquer comme mis à jour",
"fdroid": "F-Droid",
"appIdOrName": "ID ou nom de l'application",
"appWithIdOrNameNotFound": "Aucune application n'a été trouvée avec cet identifiant ou ce nom",
"reposHaveMultipleApps": "Les dépôts peuvent contenir plusieurs applications",
"fdroidThirdPartyRepo": "Dépôt tiers F-Droid",
"steam": "Steam",
"steamMobile": "Steam Mobile",
"steamChat": "Steam Chat",
"install": "Installer",
"markInstalled": "Marquer installée",
"update": "Mettre à jour",
"markUpdated": "Marquer à jour",
"additionalOptions": "Options additionelles",
"disableVersionDetection": "Désactiver la détection de version",
"noVersionDetectionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement.",
"downloadingX": "Téléchargement {}",
"downloadNotifDescription": "Avertit l'utilisateur de la progression du téléchargement d'une application",
"noAPKFound": "Aucun APK trouvé",
"noVersionDetection": "Pas de détection de version",
"categorize": "Catégoriser",
"categories": "Catégories",
"category": "Catégorie",
"noCategory": "No Category",
"noCategories": "Aucune catégorie",
"deleteCategoriesQuestion": "Supprimer les catégories ?",
"categoryDeleteWarning": "Toutes les applications dans les catégories supprimées seront définies sur non catégorisées.",
"addCategory": "Ajouter une catégorie",
"label": "Étiquette",
"language": "Langue",
"storagePermissionDenied": "Autorisation de stockage refusée",
"selectedCategorizeWarning": "Cela remplacera tous les paramètres de catégorie existants pour les applications sélectionnées.",
"filterAPKsByRegEx": "Filtrer les APK par expression régulière",
"removeFromObtainium": "Supprimer d'Obtainium",
"uninstallFromDevice": "Désinstaller de l'appareil",
"onlyWorksWithNonVersionDetectApps": "Fonctionne uniquement pour les applications avec la détection de version désactivée.",
"releaseDateAsVersion": "Utiliser la date de sortie comme version",
"releaseDateAsVersionExplanation": "Cette option ne doit être utilisée que pour les applications où la détection de version ne fonctionne pas correctement, mais une date de sortie est disponible.",
"changes": "Changements",
"releaseDate": "Date de sortie",
"importFromURLsInFile": "Importer à partir d'URL dans un fichier (comme OPML)",
"versionDetection": "Détection des versions",
"standardVersionDetection": "Détection de version standard",
"removeAppQuestion": {
"one": "Supprimer l'application ?",
"other": "Supprimer les applications ?"
},
"tooManyRequestsTryAgainInMinutes": {
"one": "Trop de demandes (taux limité) - réessayez dans {} minute",
"other": "Trop de demandes (taux limité) - réessayez dans {} minutes"
},
"bgUpdateGotErrorRetryInMinutes": {
"one": "La vérification de la mise à jour en arrière-plan a rencontré un {}, planifiera une nouvelle tentative de vérification dans {} minute",
"other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, planifiera une nouvelle tentative de vérification dans {} minutes"
},
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "La vérification des mises à jour en arrière-plan trouvée {} mise à jour - avertira l'utilisateur si nécessaire",
"other": "La vérification des mises à jour en arrière-plan a trouvé {} mises à jour - avertira l'utilisateur si nécessaire"
},
"apps": {
"one": "{} Application",
"other": "{} Applications"
},
"url": {
"one": "{} URL",
"other": "{} URLs"
},
"minute": {
"one": "{} Minute",
"other": "{} Minutes"
},
"hour": {
"one": "{} Heure",
"other": "{} Heures"
},
"day": {
"one": "{} Jour",
"other": "{} Jours"
},
"clearedNLogsBeforeXAfterY": {
"one": "{n} journal effacé (avant = {before}, après = {after})",
"other": "{n} journaux effacés (avant = {before}, après = {after})"
},
"xAndNMoreUpdatesAvailable": {
"one": "{} et 1 autre application ont des mises à jour.",
"other": "{} et {} autres applications ont des mises à jour."
},
"xAndNMoreUpdatesInstalled": {
"one": "{} et 1 autre application ont été mises à jour.",
"other": "{} et {} autres applications ont été mises à jour."
}
}

View File

@ -56,7 +56,7 @@
"appsString": "Appok",
"noApps": "Nincs App",
"noAppsForFilter": "Nincsenek appok a szűrőhöz",
"byX": "{} által",
"byX": "Fejlesztő: {}",
"percentProgress": "Folyamat: {}%",
"pleaseWait": "Kis türelmet",
"updateAvailable": "Frissítés érhető el",
@ -191,7 +191,7 @@
"update": "Frissít",
"markUpdated": "Frissítettnek jelöl",
"additionalOptions": "További lehetőségek",
"disableVersionDetection": "Verzióérzékelés letiltása",
"disableVersionDetection": "Verzió érzékelés letiltása",
"noVersionDetectionExplanation": "Ezt a beállítást csak olyan alkalmazásoknál szabad használni, ahol a verzióérzékelés nem működik megfelelően.",
"downloadingX": "{} letöltés",
"downloadNotifDescription": "Értesíti a felhasználót az app letöltésének előrehaladásáról",
@ -212,10 +212,13 @@
"removeFromObtainium": "Eltávolítás az Obtainiumból",
"uninstallFromDevice": "Eltávolítás a készülékről",
"onlyWorksWithNonVersionDetectApps": "Csak azoknál az alkalmazásoknál működik, amelyeknél a verzióérzékelés le van tiltva.",
"useReleaseDateAsVersion": "Használja a Kiadás dátumát, mint verziót",
"releaseDateAsVersion": "Használja a Kiadás dátumát, mint verziót",
"releaseDateAsVersionExplanation": "Ezt a beállítást csak olyan alkalmazásoknál szabad használni, ahol a verzió érzékelése nem működik megfelelően, de elérhető a kiadás dátuma.",
"changes": "Változtatások",
"releaseDate": "Kiadás dátuma",
"importFromURLsInFile": "Importálás fájlban található URL-ből (mint pl. OPML)",
"versionDetection": "Verzió érzékelés",
"standardVersionDetection": "Alapért. verzió érzékelés",
"removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazást?"

View File

@ -213,10 +213,13 @@
"removeFromObtainium": "Rimuovi da Obtainium",
"uninstallFromDevice": "Disinstalla dal dispositivo",
"onlyWorksWithNonVersionDetectApps": "Funziona solo per le App con il rilevamento della versione disattivato.",
"useReleaseDateAsVersion": "Usa data di rilascio come versione",
"releaseDateAsVersion": "Usa data di rilascio come versione",
"releaseDateAsVersionExplanation": "Questa opzione dovrebbe essere usata solo per le App in cui il rilevamento della versione non funziona correttamente, ma è disponibile una data di rilascio.",
"changes": "Novità",
"releaseDate": "Data di rilascio",
"importFromURLsInFile": "Import from URLs in File (like OPML)",
"versionDetection": "Version Detection",
"standardVersionDetection": "Standard version detection",
"removeAppQuestion": {
"one": "Rimuovere l'App?",
"other": "Rimuovere le App?"

View File

@ -107,7 +107,7 @@
"line": "行",
"searchX": "{}で検索",
"noResults": "結果は見つかりませんでした",
"importX": "{}をインポートする",
"importX": "{}をインポート",
"importedAppsIdDisclaimer": "インポートしたアプリが「未インストール」と表示されることがあります。\nこれを解決するには、Obtainiumから再インストールしてください。\nアプリのデータには影響しません。\n\nURLとサードパーティのインポートメソッドにのみ影響します。",
"importErrors": "インポートエラー",
"importedXOfYApps": "{} / {} アプリをインポートしました",
@ -213,10 +213,13 @@
"removeFromObtainium": "Obtainiumから削除する",
"uninstallFromDevice": "デバイスからアンインストールする",
"onlyWorksWithNonVersionDetectApps": "バージョン検出を無効にしているアプリにのみ動作します。",
"useReleaseDateAsVersion": "リリース日をバージョンとして使用する",
"releaseDateAsVersion": "リリース日をバージョンとして使用する",
"releaseDateAsVersionExplanation": "このオプションは、バージョン検出が正しく機能しないアプリで、リリース日が利用可能な場合にのみ使用する必要があります。",
"changes": "変更点",
"releaseDate": "リリース日",
"importFromURLsInFile": "ファイルOPMLなど内のURLからインポート",
"versionDetection": "バージョン検出",
"standardVersionDetection": "標準のバージョン検出",
"removeAppQuestion": {
"one": "アプリを削除しますか?",
"other": "アプリを削除しますか?"

View File

@ -213,10 +213,13 @@
"filterAPKsByRegEx": "Filter APKs by Regular Expression",
"removeFromObtainium": "Remove from Obtainium",
"uninstallFromDevice": "Uninstall from Device",
"useReleaseDateAsVersion": "Use Release Date as Version",
"releaseDateAsVersion": "Use Release Date as Version",
"releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes",
"releaseDate": "Release Date",
"importFromURLsInFile": "Import from URLs in File (like OPML)",
"versionDetection": "Version Detection",
"standardVersionDetection": "Standard version detection",
"removeAppQuestion": {
"one": "删除应用?",
"other": "删除应用?"

View File

@ -21,7 +21,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart';
// ignore: implementation_imports
import 'package:easy_localization/src/localization.dart';
const String currentVersion = '0.11.2';
const String currentVersion = '0.11.8';
const String currentReleaseTag =
'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES
@ -34,7 +34,8 @@ const supportedLocales = [
Locale('ja'),
Locale('hu'),
Locale('de'),
Locale('fa')
Locale('fa'),
Locale('fr')
];
const fallbackLocale = Locale('en');
const localeDir = 'assets/translations';
@ -211,6 +212,14 @@ class _ObtainiumState extends State<Obtainium> {
false)
]);
}
if (!supportedLocales
.map((e) => e.languageCode)
.contains(context.locale.languageCode) ||
settingsProvider.forcedLocale == null &&
context.deviceLocale.languageCode !=
context.locale.languageCode) {
settingsProvider.resetLocaleSafe(context);
}
// Register the background update task according to the user's setting
if (existingUpdateInterval != settingsProvider.updateInterval) {
if (existingUpdateInterval != -1) {

View File

@ -71,10 +71,6 @@ class _AddAppPageState extends State<AddAppPage> {
var settingsProvider = context.read<SettingsProvider>();
() async {
var userPickedTrackOnly = additionalSettings['trackOnly'] == true;
var userPickedNoVersionDetection =
additionalSettings['noVersionDetection'] == true;
var userPickedReleaseDateAsVersion =
additionalSettings['releaseDateAsVersion'] == true;
var cont = true;
if ((userPickedTrackOnly || pickedSource!.enforceTrackOnly) &&
// ignore: use_build_context_synchronously
@ -95,13 +91,13 @@ class _AddAppPageState extends State<AddAppPage> {
null) {
cont = false;
}
if (userPickedReleaseDateAsVersion && // ignore: use_build_context_synchronously
if (additionalSettings['versionDetection'] == 'releaseDateAsVersion' &&
// ignore: use_build_context_synchronously
await showDialog(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
title: tr('useReleaseDateAsVersion'),
title: tr('releaseDateAsVersion'),
items: const [],
message: tr('releaseDateAsVersionExplanation'),
);
@ -109,8 +105,7 @@ class _AddAppPageState extends State<AddAppPage> {
null) {
cont = false;
}
if (!userPickedReleaseDateAsVersion &&
userPickedNoVersionDetection &&
if (additionalSettings['versionDetection'] == 'noVersionDetection' &&
// ignore: use_build_context_synchronously
await showDialog(
context: context,
@ -129,9 +124,7 @@ class _AddAppPageState extends State<AddAppPage> {
var trackOnly = pickedSource!.enforceTrackOnly || userPickedTrackOnly;
App app = await sourceProvider.getApp(
pickedSource!, userInput, additionalSettings,
trackOnlyOverride: trackOnly,
noVersionDetectionOverride: userPickedNoVersionDetection,
releaseDateAsVersionOverride: userPickedReleaseDateAsVersion);
trackOnlyOverride: trackOnly);
if (!trackOnly) {
await settingsProvider.getInstallPermission();
}

View File

@ -42,8 +42,6 @@ class _AppPageState extends State<AppPage> {
getUpdate(app.app.id);
}
var trackOnly = app?.app.additionalSettings['trackOnly'] == true;
var noVersionDetection =
app?.app.additionalSettings['noVersionDetection'] == true;
var infoColumn = Column(
mainAxisAlignment: MainAxisAlignment.center,
@ -207,7 +205,8 @@ class _AppPageState extends State<AppPage> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (noVersionDetection &&
if (app?.app.additionalSettings['versionDetection'] !=
'standardVersionDetection' &&
!trackOnly &&
app?.app.installedVersion != null &&
app?.app.installedVersion != app?.app.latestVersion)
@ -295,13 +294,11 @@ class _AppPageState extends State<AppPage> {
context);
}
if (app.app.additionalSettings[
'releaseDateAsVersion'] ==
true) {
app.app.additionalSettings[
'noVersionDetection'] = true;
'versionDetection'] ==
'releaseDateAsVersion') {
if (originalSettings[
'releaseDateAsVersion'] !=
true) {
'versionDetection'] !=
'releaseDateAsVersion') {
if (app.app.releaseDate != null) {
bool isUpdated =
app.app.installedVersion ==
@ -318,10 +315,8 @@ class _AppPageState extends State<AppPage> {
}
}
} else if (originalSettings[
'releaseDateAsVersion'] ==
true) {
app.app.additionalSettings[
'noVersionDetection'] = false;
'versionDetection'] ==
'releaseDateAsVersion') {
app.app.installedVersion = app
.installedInfo
?.versionName ??

View File

@ -233,6 +233,31 @@ class AppsPageState extends State<AppsPage> {
.getSource(listedApps[index].app.url)
.changeLogPageFromStandardUrl(listedApps[index].app.url);
var transparent = const Color.fromARGB(0, 0, 0, 0).value;
var hasUpdate = listedApps[index].app.installedVersion != null &&
listedApps[index].app.installedVersion !=
listedApps[index].app.latestVersion;
var updateButton = IconButton(
visualDensity: VisualDensity.compact,
color: Theme.of(context).colorScheme.primary,
tooltip:
listedApps[index].app.additionalSettings['trackOnly'] ==
true
? tr('markUpdated')
: tr('update'),
onPressed: appsProvider.areDownloadsRunning()
? null
: () {
appsProvider.downloadAndInstallLatestApps([
listedApps[index].app.id
], globalNavigatorKey.currentContext).catchError((e) {
showError(e, context);
});
},
icon: Icon(
listedApps[index].app.additionalSettings['trackOnly'] ==
true
? Icons.check_circle_outline
: Icons.install_mobile));
return Container(
decoration: BoxDecoration(
border: Border.symmetric(
@ -264,7 +289,24 @@ class AppsPageState extends State<AppsPage> {
listedApps[index].installedInfo!.icon!,
gaplessPlayback: true,
)
: null,
: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Transform(
alignment: Alignment.center,
transform: Matrix4.rotationZ(0.31),
child: Padding(
padding: const EdgeInsets.all(15),
child: Image(
image: const AssetImage(
'assets/graphics/icon_small.png'),
color: Colors.white.withOpacity(0.1),
colorBlendMode: BlendMode.modulate,
gaplessPlayback: true,
),
)),
]),
title: Text(
maxLines: 1,
listedApps[index].installedInfo?.name ??
@ -278,21 +320,33 @@ class AppsPageState extends State<AppsPage> {
),
subtitle: Text(
tr('byX', args: [listedApps[index].app.author]),
maxLines: 1,
style: TextStyle(
overflow: TextOverflow.ellipsis,
fontWeight: listedApps[index].app.pinned
? FontWeight.bold
: FontWeight.normal)),
trailing: SingleChildScrollView(
reverse: true,
child: listedApps[index].downloadProgress != null
? Text(tr('percentProgress', args: [
listedApps[index]
.downloadProgress
?.toInt()
.toString() ??
'100'
]))
: (Column(
trailing: listedApps[index].downloadProgress != null
? Text(tr('percentProgress', args: [
listedApps[index]
.downloadProgress
?.toInt()
.toString() ??
'100'
]))
: (Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
hasUpdate
? updateButton
: const SizedBox.shrink(),
hasUpdate
? const SizedBox(
width: 10,
)
: const SizedBox.shrink(),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
@ -306,80 +360,38 @@ class AppsPageState extends State<AppsPage> {
'${listedApps[index].app.installedVersion ?? tr('notInstalled')}${listedApps[index].app.additionalSettings['trackOnly'] == true ? ' ${tr('estimateInBrackets')}' : ''}',
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.end,
))
)),
]),
GestureDetector(
onTap: changesUrl == null
? null
: () {
launchUrlString(changesUrl,
mode: LaunchMode
.externalApplication);
},
child: Text(
listedApps[index].app.releaseDate ==
null
? tr('changes')
: DateFormat('yyyy-MM-dd').format(
listedApps[index]
.app
.releaseDate!),
style: const TextStyle(
fontStyle: FontStyle.italic,
decoration:
TextDecoration.underline),
)),
listedApps[index].app.installedVersion !=
null &&
listedApps[index]
.app
.installedVersion !=
listedApps[index]
.app
.latestVersion
? appsProvider.areDownloadsRunning()
? Text(tr('pleaseWait'))
: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.end,
children: [
GestureDetector(
onTap: () {
appsProvider
.downloadAndInstallLatestApps(
[
listedApps[index]
.app
.id
],
globalNavigatorKey
.currentContext).catchError(
(e) {
showError(e, context);
});
},
child: Text(
listedApps[index]
.app
.additionalSettings[
'trackOnly'] ==
true
? tr('markUpdated')
: tr('update'),
style: TextStyle(
color:
Theme.of(context)
.colorScheme
.primary,
fontWeight:
FontWeight.bold),
)),
],
)
: const SizedBox.shrink(),
Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: changesUrl == null
? null
: () {
launchUrlString(changesUrl,
mode: LaunchMode
.externalApplication);
},
child: Text(
listedApps[index].app.releaseDate ==
null
? tr('changes')
: DateFormat('yyyy-MM-dd')
.format(listedApps[index]
.app
.releaseDate!),
style: const TextStyle(
fontStyle: FontStyle.italic,
decoration:
TextDecoration.underline),
))
],
),
],
))),
)
],
)),
onTap: () {
if (selectedApps.isNotEmpty) {
toggleAppSelected(listedApps[index].app);
@ -704,7 +716,7 @@ class AppsPageState extends State<AppsPage> {
onPressed: () {
HapticFeedback.selectionClick();
appsProvider.saveApps(selectedApps.map((a) {
if (a.installedVersion != null && a.additionalSettings['noVersionDetection'] == true) {
if (a.installedVersion != null && a.additionalSettings['versionDetection'] != 'standardVersionDetection') {
a.installedVersion = a.latestVersion;
}
return a;

View File

@ -41,6 +41,66 @@ class _ImportExportPageState extends State<ImportExportPage> {
),
);
urlListImport({String? initValue, bool overrideInitValid = false}) {
showDialog<Map<String, dynamic>?>(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
initValid: overrideInitValid,
title: tr('importFromURLList'),
items: [
[
GeneratedFormTextField('appURLList',
defaultValue: initValue ?? '',
label: tr('appURLList'),
max: 7,
additionalValidators: [
(dynamic value) {
if (value != null && value.isNotEmpty) {
var lines = value.trim().split('\n');
for (int i = 0; i < lines.length; i++) {
try {
sourceProvider.getSource(lines[i]);
} catch (e) {
return '${tr('line')} ${i + 1}: $e';
}
}
}
return null;
}
])
]
],
);
}).then((values) {
if (values != null) {
var urls = (values['appURLList'] as String).split('\n');
setState(() {
importInProgress = true;
});
appsProvider.addAppsByURL(urls).then((errors) {
if (errors.isEmpty) {
showError(tr('importedX', args: [plural('apps', urls.length)]),
context);
} else {
showDialog(
context: context,
builder: (BuildContext ctx) {
return ImportErrorDialog(
urlsLength: urls.length, errors: errors);
});
}
}).catchError((e) {
showError(e, context);
}).whenComplete(() {
setState(() {
importInProgress = false;
});
});
}
});
}
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.surface,
body: CustomScrollView(slivers: <Widget>[
@ -150,88 +210,60 @@ class _ImportExportPageState extends State<ImportExportPage> {
],
)
else
const Divider(
height: 32,
),
TextButton(
onPressed: importInProgress
? null
: () {
showDialog<Map<String, dynamic>?>(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
title: tr('importFromURLList'),
items: [
[
GeneratedFormTextField(
'appURLList',
label: tr('appURLList'),
max: 7,
additionalValidators: [
(dynamic value) {
if (value != null &&
value.isNotEmpty) {
var lines = value
.trim()
.split('\n');
for (int i = 0;
i < lines.length;
i++) {
try {
sourceProvider
.getSource(
lines[i]);
} catch (e) {
return '${tr('line')} ${i + 1}: $e';
}
}
}
return null;
}
])
]
],
);
}).then((values) {
if (values != null) {
var urls =
(values['appURLList'] as String)
.split('\n');
setState(() {
importInProgress = true;
});
appsProvider
.addAppsByURL(urls)
.then((errors) {
if (errors.isEmpty) {
showError(
tr('importedX', args: [
plural('apps', urls.length)
]),
context);
} else {
showDialog(
context: context,
builder: (BuildContext ctx) {
return ImportErrorDialog(
urlsLength: urls.length,
errors: errors);
});
}
}).catchError((e) {
showError(e, context);
}).whenComplete(() {
setState(() {
importInProgress = false;
Column(
children: [
const Divider(
height: 32,
),
TextButton(
onPressed: importInProgress
? null
: () {
urlListImport();
},
child: Text(
tr('importFromURLList'),
)),
const SizedBox(height: 8),
TextButton(
onPressed: importInProgress
? null
: () {
FilePicker.platform
.pickFiles()
.then((result) {
if (result != null) {
urlListImport(
overrideInitValid: true,
initValue:
RegExp('https?://[^"]+')
.allMatches(File(result
.files
.single
.path!)
.readAsStringSync())
.map((e) =>
e.input.substring(
e.start, e.end))
.toSet()
.toList()
.where((url) {
try {
sourceProvider
.getSource(url);
return true;
} catch (e) {
return false;
}
}).join('\n'));
}
});
});
}
});
},
child: Text(
tr('importFromURLList'),
)),
},
child: Text(
tr('importFromURLsInFile'),
)),
],
),
...sourceProvider.sources
.where((element) => element.canSearch)
.map((source) => Column(
@ -280,6 +312,7 @@ class _ImportExportPageState extends State<ImportExportPage> {
if (urlsWithDescriptions
.isNotEmpty) {
var selectedUrls =
// ignore: use_build_context_synchronously
await showDialog<
List<
String>?>(
@ -314,6 +347,7 @@ class _ImportExportPageState extends State<ImportExportPage> {
]),
context);
} else {
// ignore: use_build_context_synchronously
showDialog(
context: context,
builder:
@ -391,6 +425,7 @@ class _ImportExportPageState extends State<ImportExportPage> {
e.toString())
.toList());
var selectedUrls =
// ignore: use_build_context_synchronously
await showDialog<
List<String>?>(
context: context,
@ -418,6 +453,7 @@ class _ImportExportPageState extends State<ImportExportPage> {
]),
context);
} else {
// ignore: use_build_context_synchronously
showDialog(
context: context,
builder:

View File

@ -87,6 +87,7 @@ class _SettingsPageState extends State<SettingsPage> {
});
var sortDropdown = DropdownButtonFormField(
isExpanded: true,
decoration: InputDecoration(labelText: tr('appSortBy')),
value: settingsProvider.sortColumn,
items: [
@ -114,6 +115,7 @@ class _SettingsPageState extends State<SettingsPage> {
});
var orderDropdown = DropdownButtonFormField(
isExpanded: true,
decoration: InputDecoration(labelText: tr('appSortOrder')),
value: settingsProvider.sortOrder,
items: [
@ -150,7 +152,7 @@ class _SettingsPageState extends State<SettingsPage> {
if (value != null) {
context.setLocale(Locale(value));
} else {
context.resetLocale();
settingsProvider.resetLocaleSafe(context);
}
});

View File

@ -467,8 +467,8 @@ class AppsProvider with ChangeNotifier {
App? getCorrectedInstallStatusAppIfPossible(App app, AppInfo? installedInfo) {
var modded = false;
var trackOnly = app.additionalSettings['trackOnly'] == true;
var noVersionDetection =
app.additionalSettings['noVersionDetection'] == true;
var noVersionDetection = app.additionalSettings['versionDetection'] !=
'standardVersionDetection';
if (installedInfo == null && app.installedVersion != null && !trackOnly) {
app.installedVersion = null;
modded = true;

View File

@ -178,4 +178,15 @@ class SettingsProvider with ChangeNotifier {
bool setEqual(Set<String> a, Set<String> b) =>
a.length == b.length && a.union(b).length == a.length;
void resetLocaleSafe(BuildContext context) {
if (context.supportedLocales
.map((e) => e.languageCode)
.contains(context.deviceLocale.languageCode)) {
context.resetLocale();
} else {
context.setLocale(context.fallbackLocale!);
context.deleteSaveLocale();
}
}
}

View File

@ -100,6 +100,20 @@ class App {
additionalSettings['noVersionDetection'] =
json['noVersionDetection'] == 'true' || json['trackOnly'] == true;
}
// Convert bool style version detection options to dropdown style
if (additionalSettings['noVersionDetection'] == true) {
additionalSettings['versionDetection'] = 'noVersionDetection';
}
if (additionalSettings['releaseDateAsVersion'] == true) {
additionalSettings['versionDetection'] = 'releaseDateAsVersion';
additionalSettings.remove('releaseDateAsVersion');
}
if (additionalSettings['noVersionDetection'] != null) {
additionalSettings.remove('noVersionDetection');
}
if (additionalSettings['releaseDateAsVersion'] != null) {
additionalSettings.remove('releaseDateAsVersion');
}
// Ensure additionalSettings are correctly typed
for (var item in formItems) {
if (additionalSettings[item.key] != null) {
@ -234,11 +248,16 @@ class AppSource {
)
],
[
GeneratedFormSwitch('releaseDateAsVersion',
label: tr('useReleaseDateAsVersion'))
],
[
GeneratedFormSwitch('noVersionDetection', label: tr('noVersionDetection'))
GeneratedFormDropdown(
'versionDetection',
[
MapEntry(
'standardVersionDetection', tr('standardVersionDetection')),
MapEntry('releaseDateAsVersion', tr('releaseDateAsVersion')),
MapEntry('noVersionDetection', tr('noVersionDetection'))
],
label: tr('versionDetection'),
defaultValue: 'standardVersionDetection')
],
[
GeneratedFormTextField('apkFilterRegEx',
@ -373,26 +392,15 @@ class SourceProvider {
Future<App> getApp(
AppSource source, String url, Map<String, dynamic> additionalSettings,
{App? currentApp,
bool trackOnlyOverride = false,
bool noVersionDetectionOverride = false,
bool releaseDateAsVersionOverride = false}) async {
{App? currentApp, bool trackOnlyOverride = false}) async {
if (trackOnlyOverride || source.enforceTrackOnly) {
additionalSettings['trackOnly'] = true;
}
if (releaseDateAsVersionOverride) {
additionalSettings['releaseDateAsVersion'] = true;
noVersionDetectionOverride =
true; // Rel. date as version means no ver. det.
}
if (noVersionDetectionOverride) {
additionalSettings['noVersionDetection'] = true;
}
var trackOnly = additionalSettings['trackOnly'] == true;
String standardUrl = source.standardizeURL(preStandardizeUrl(url));
APKDetails apk =
await source.getLatestAPKDetails(standardUrl, additionalSettings);
if (additionalSettings['releaseDateAsVersion'] == true &&
if (additionalSettings['versionDetection'] == 'releaseDateAsVersion' &&
apk.releaseDate != null) {
apk.version = apk.releaseDate!.microsecondsSinceEpoch.toString();
}

View File

@ -25,14 +25,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.7"
archive:
dependency: transitive
description:
name: archive
sha256: d6347d54a2d8028e0437e3c099f66fdb8ae02c4720c1e7534c9f24c10351f85d
url: "https://pub.dev"
source: hosted
version: "3.3.6"
args:
dependency: transitive
description:
@ -65,22 +57,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c"
url: "https://pub.dev"
source: hosted
version: "0.3.5"
clock:
dependency: transitive
description:
@ -97,14 +73,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.17.0"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
cross_file:
dependency: transitive
description:
@ -230,14 +198,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.2"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: ce0e501cfc258907842238e4ca605e74b7fd1cdf04b3b43e86c43f3e40a1592c
url: "https://pub.dev"
source: hosted
version: "0.11.0"
flutter_lints:
dependency: "direct dev"
description:
@ -279,10 +239,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "4bef634684b2c7f3468c77c766c831229af829a0cd2d4ee6c1b99558bd14e5d2"
sha256: c224ac897bed083dabf11f238dd11a239809b446740be0c2044608c50029ffdf
url: "https://pub.dev"
source: hosted
version: "2.0.8"
version: "2.0.9"
flutter_test:
dependency: "direct dev"
description: flutter
@ -305,10 +265,10 @@ packages:
dependency: "direct main"
description:
name: html
sha256: d9793e10dbe0e6c364f4c59bf3e01fb33a9b2a674bc7a1081693dba0614b6269
sha256: "79d498e6d6761925a34ee5ea8fa6dfef38607781d2fa91e37523474282af55cb"
url: "https://pub.dev"
source: hosted
version: "0.15.1"
version: "0.15.2"
http:
dependency: "direct main"
description:
@ -325,14 +285,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image:
dependency: transitive
description:
name: image
sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
url: "https://pub.dev"
source: hosted
version: "3.3.0"
install_plugin_v2:
dependency: "direct main"
description:
@ -365,14 +317,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.5"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317
url: "https://pub.dev"
source: hosted
version: "4.8.0"
lints:
dependency: transitive
description:
@ -557,14 +501,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346
url: "https://pub.dev"
source: hosted
version: "3.6.2"
process:
dependency: transitive
description:
@ -670,10 +606,10 @@ packages:
dependency: "direct main"
description:
name: sqflite
sha256: "78324387dc81df14f78df06019175a86a2ee0437624166c382e145d0a7fd9a4f"
sha256: "851d5040552cf911f4cabda08d003eca76b27da3ed0002978272e27c8fbf8ecc"
url: "https://pub.dev"
source: hosted
version: "2.2.4+1"
version: "2.2.5"
sqflite_common:
dependency: transitive
description:
@ -830,18 +766,18 @@ packages:
dependency: "direct main"
description:
name: webview_flutter
sha256: "9ba213434f13e760ea0f175fbc4d6bb6aeafd7dfc6c7d973f15d3e47a5d6686e"
sha256: b6cd42db3ced5411f3d01599906156885b18e4188f7065a8a351eb84bee347e0
url: "https://pub.dev"
source: hosted
version: "4.0.5"
version: "4.0.6"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: "48c8cfb023168473c0a3a4c21ffea6c23a32cc7156701c39f618b303c6a3c96e"
sha256: "5dd3f32b5c2d8f4bf9d05a349e4a65fa718eb137f396f336c3893d558a58fe84"
url: "https://pub.dev"
source: hosted
version: "3.3.1"
version: "3.3.2"
webview_flutter_platform_interface:
dependency: transitive
description:
@ -854,10 +790,10 @@ packages:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: "283a38c2a2544768033864c698e0133aa9eee0f2c800f494b538a3d1044f7ecb"
sha256: "87b6353b40e04f04d5f895a484ad6d92d682d9cce4d2d5b32d2d8aca2448d46e"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
version: "3.2.0"
win32:
dependency: transitive
description:
@ -882,14 +818,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.2.2"
yaml:
dependency: transitive
description:
name: yaml
sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
sdks:
dart: ">=2.18.2 <3.0.0"
flutter: ">=3.4.0-17.0.pre"

View File

@ -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
# 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.
version: 0.11.2+121 # When changing this, update the tag in main() accordingly
version: 0.11.8+129 # When changing this, update the tag in main() accordingly
environment:
sdk: '>=2.18.2 <3.0.0'
@ -64,7 +64,6 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_launcher_icons: ^0.11.0
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
@ -73,12 +72,6 @@ dev_dependencies:
# rules and activating additional ones.
flutter_lints: ^2.0.1
flutter_icons:
android: true
image_path: "assets/graphics/icon.png"
adaptive_icon_background: "#FFFFFF"
adaptive_icon_foreground: "assets/graphics/icon.png"
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
@ -97,6 +90,7 @@ flutter:
assets:
- assets/translations/
- assets/graphics/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware