Compare commits

...

27 Commits

Author SHA1 Message Date
Imran
06cbe74c6c Merge pull request #1672 from ImranR98/dev
- Add release date extraction for track-only GitLab and Codeberg apps (#1664)
- Add a scrollbar to the apps page
2024-06-15 02:00:30 -04:00
Imran Remtulla
f5769b85fe Add release date extraction for track-only GitLab and Codeberg apps (#1664) 2024-06-15 01:58:07 -04:00
Imran Remtulla
875868af47 Added DA to the language menu 2024-06-15 01:21:31 -04:00
Imran Remtulla
24ea15d600 Merge remote-tracking branch 'origin/main' into dev 2024-06-15 01:20:23 -04:00
Imran
87cdc3dcef Merge pull request #1657 from Grooty12/main
Add da.json
2024-06-15 01:20:01 -04:00
Imran
c2f976d7f4 Merge pull request #1670 from AntoninDelFabbro/patch-1
Reworked french translation
2024-06-15 01:19:50 -04:00
Imran Remtulla
ebc46bfd3f Update Flutter submodule 2024-06-15 01:19:33 -04:00
Imran Remtulla
e674f7e89d Merge remote-tracking branch 'origin/main' into dev 2024-06-15 01:19:13 -04:00
Imran Remtulla
86d29b163c Update packages, increment version 2024-06-15 01:19:06 -04:00
Imran Remtulla
a849919799 Add a scrollbar to the apps page 2024-06-15 01:18:50 -04:00
Antonin Del Fabbro
d8c805a6b3 Reworked french translation 2024-06-12 23:07:57 +02:00
Antonin Del Fabbro
8acbd3ef78 "Material You" shouldn't be translated 2024-06-12 20:43:50 +02:00
Rasmus Rosendahl-Kaa
b81088d767 Add danish translation 2024-06-05 14:33:22 +02:00
Imran
7071e34a74 Merge pull request #1643 from ImranR98/dev
- Bugfix: Include GitLab token in APK request (#1622)
- Bugfix: Don't trim trailing slashes when parsing links (#1625)
- Improve contrast of placeholder icon in dark mode (#1637) 
- Improve app loading times
- Revert a previous change to background downloads
- Add a "clear logs" button
2024-05-24 16:27:18 -04:00
Imran Remtulla
6a73ade359 Add a "clear logs" button 2024-05-23 21:18:13 -04:00
Imran Remtulla
6c5e5043a4 Improve icon loading after last commit 2024-05-23 21:02:50 -04:00
Imran Remtulla
5edaf1306d Update packages + Flutter, increment version 2024-05-23 20:17:44 -04:00
Imran Remtulla
5bf7fdb94e Revert a previous change related to BG downloads (did not work as intended) 2024-05-23 20:15:25 -04:00
Imran Remtulla
7808bc5ccb Improve loading time/stability (at the cost of icon flickering) 2024-05-23 20:02:43 -04:00
Imran Remtulla
06a079e452 Attempt to improve load times again + link parsing bugfix (#1625) 2024-05-23 19:35:52 -04:00
Imran Remtulla
de509737e6 Include GitLab token in APK request (#1622) 2024-05-22 19:51:35 -04:00
Imran Remtulla
08a3ba8d13 Merge remote-tracking branch 'origin/main' into dev 2024-05-22 19:37:30 -04:00
Imran
2b27902d5f Merge pull request #1633 from teaminh/main
Update vi.json
2024-05-22 19:37:16 -04:00
Imran Remtulla
62185127c2 Merge remote-tracking branch 'origin/main' into dev 2024-05-22 19:36:53 -04:00
Imran Remtulla
9c46e3f88c Attempt to improve app load time
Slight icon opacity tweak (#1637)
2024-05-22 19:35:51 -04:00
teaminh
daa4de921d Update vi.json 2024-05-19 12:20:28 +07:00
teaminh
bc977e2a5a Update vi.json 2024-05-19 12:09:36 +07:00
14 changed files with 655 additions and 195 deletions

375
assets/translations/da.json Normal file
View File

@@ -0,0 +1,375 @@
{
"invalidURLForSource": "Ikke et gyldigt {} App-URL",
"noReleaseFound": "Kunne ikke finde en passende udgivelse",
"noVersionFound": "Kunne ikke bestemme udgivelsesversionen",
"urlMatchesNoSource": "URL'et matcher ikke en kendt kilde",
"cantInstallOlderVersion": "Kan ikke installere en ældre version af en app",
"appIdMismatch": "Hentet pakke-ID matcher ikke det eksisterende app-ID",
"functionNotImplemented": "Denne klasse har ikke implementeret denne funktion",
"placeholder": "Pladsholder",
"someErrors": "Nogle fejl opstod",
"unexpectedError": "Uvented fejl",
"ok": "Ok",
"and": "og",
"githubPATLabel": "Personlig adgangstoken for GitHub (Øger takstgrænsen)",
"includePrereleases": "Inkluder præ-udgivelser",
"fallbackToOlderReleases": "Fald tilbage til ældre udgaver",
"filterReleaseTitlesByRegEx": "Filtrer udgivelsestitlerne med regulære udtryk",
"invalidRegEx": "Det regulære udtryk var ugyldigt",
"noDescription": "Ingen beskrivelse",
"cancel": "Annuler",
"continue": "Fortsæt",
"requiredInBrackets": "(Påkrævet)",
"dropdownNoOptsError": "FEJL: DROPDOWN SKAL HAVE MINDST ÉN OPT",
"colour": "Farve",
"standard": "Standard",
"custom": "Brugerdefineret",
"useMaterialYou": "Brug Material You",
"githubStarredRepos": "Stjernemarket GitHub-depoter",
"uname": "Brugernavn",
"wrongArgNum": "Forkert antal argumenter angivet",
"xIsTrackOnly": "{} kan kun følges",
"source": "Kilde",
"app": "App",
"appsFromSourceAreTrackOnly": "Apps fra denne kilde er 'Følg kun'.",
"youPickedTrackOnly": "Du har valgt 'Følg kun'-indstillingen.",
"trackOnlyAppDescription": "Appen vil blive følget for opdateringer, men Obtanium vil ikke kunne downloade eller installere den.",
"cancelled": "Annuleret",
"appAlreadyAdded": "Appen er allerede tilføjet",
"alreadyUpToDateQuestion": "Appen er alleret opdateret?",
"addApp": "Tilføj app",
"appSourceURL": "URL til app-kilden",
"error": "Fejl",
"add": "Tilføj",
"searchSomeSourcesLabel": "Søg (Kun visse kilder)",
"search": "Søg",
"additionalOptsFor": "Yderligere indstillinger for {}",
"supportedSources": "Understøttet kilder",
"trackOnlyInBrackets": "(Følg kun)",
"searchableInBrackets": "(Søgbar)",
"appsString": "Apps",
"noApps": "Ingen apps",
"noAppsForFilter": "Ingen apps for filteret",
"byX": "Med {}",
"percentProgress": "Udvikling: {}%",
"pleaseWait": "Vent venligst",
"updateAvailable": "Opdateringer tilgængelige",
"notInstalled": "Ikke installeret",
"pseudoVersion": "pseudo-version",
"selectAll": "Vælg alle",
"deselectX": "Fravælg {}",
"xWillBeRemovedButRemainInstalled": "{} vil blive fjernet fra Obtanium, men vil ikke blive fjernet fra din enhed.",
"removeSelectedAppsQuestion": "Fjern valgte apps?",
"removeSelectedApps": "Fjern valgte apps",
"updateX": "Opdater {}",
"installX": "Installer {}",
"markXTrackOnlyAsUpdated": "Marker {}\n(Følg kun)\nsom opdateret",
"changeX": "Skift {}",
"installUpdateApps": "Installer/Opdater apps",
"installUpdateSelectedApps": "Installer/Opdater valgte apps",
"markXSelectedAppsAsUpdated": "Marker {} valgte apps som opdateret?",
"no": "Nej",
"yes": "Ja",
"markSelectedAppsUpdated": "Marker valgte apps som opdateret",
"pinToTop": "Fastgør til toppen",
"unpinFromTop": "Frigør fra toppen",
"resetInstallStatusForSelectedAppsQuestion": "Nulstil opdateringsstatus for valgte apps?",
"installStatusOfXWillBeResetExplanation": "Opdateringsstatussen af enhver valgt app vil blive nulstillet.\n\nDette kan hjælpe når der vises den forkerte app-version i Obtanium på grund af fejlede opdateringer eller andre fejl.",
"customLinkMessage": "Disse links virker på enheder med Obtanium installeret",
"shareAppConfigLinks": "Del app-konfiguration som HTML-link",
"shareSelectedAppURLs": "Del URL'et af de valgte apps",
"resetInstallStatus": "Nulstil installationsstatus",
"more": "Mere",
"removeOutdatedFilter": "Fjern forældet apps filter",
"showOutdatedOnly": "Vis kun forældet apps",
"filter": "Filtrer",
"filterApps": "Filtrer Apps",
"appName": "Appnavn",
"author": "Forfatter",
"upToDateApps": "Opdaterede apps",
"nonInstalledApps": "Ikke installerede apps",
"importExport": "Importer/Eksporter",
"settings": "Indstillinger",
"exportedTo": "Eksporter til {}",
"obtainiumExport": "Obtainium-eksport",
"invalidInput": "Ugyldigt input",
"importedX": "Importerde {}",
"obtainiumImport": "Obtainium-import",
"importFromURLList": "Importer fra URL-liste",
"searchQuery": "Søgning",
"appURLList": "App-URL-liste",
"line": "Linje",
"searchX": "Søg {}",
"noResults": "Ingen resultater fundet",
"importX": "Importer {}",
"importedAppsIdDisclaimer": "Importerede apps kan ukorrekt vises som \"Ikke installeret\".\nFor at fikse dette, skal du geninstallere dem gennem Obtanium.\nDette burde ikke påvirke appdata.\n\nPåvirker kun URL og tredjeparts importmetoder.",
"importErrors": "Fejl ved import",
"importedXOfYApps": "{} af {} app importeret.",
"followingURLsHadErrors": "Følgende URLs havde fejl::",
"selectURL": "Vælg URL",
"selectURLs": "Vælg URLs",
"pick": "Vælg",
"theme": "Tema",
"dark": "Mørk",
"light": "Lys",
"followSystem": "Følg system",
"followSystemThemeExplanation": "Følg system-temaet er muligt kun ved at bruge tredepartsapplikationer",
"useBlackTheme": "Brug helt sort mørkt tema",
"appSortBy": "Sorter apps ved:",
"authorName": "Forfatter/Navn",
"nameAuthor": "Navn/Forfatter",
"asAdded": "Som tilføjet",
"appSortOrder": "Sorteringsrækkefølge for apps",
"ascending": "Stigende",
"descending": "Faldende",
"bgUpdateCheckInterval": "Interval for baggrundsopdateringer",
"neverManualOnly": "Aldrig - Kun manuelt",
"appearance": "Udseende",
"showWebInAppView": "Vis kildens hjemmeside i app-visning",
"pinUpdates": "Fastgør opdateringer til toppen af app-visning",
"updates": "Opdateringer",
"sourceSpecific": "Kilde-specifikt",
"appSource": "App kilde",
"noLogs": "Ingen logs",
"appLogs": "App-ogs",
"close": "Luk",
"share": "Del",
"appNotFound": "App ikke fundet",
"obtainiumExportHyphenatedLowercase": "obtainium-eksport",
"pickAnAPK": "Vælg en APK",
"appHasMoreThanOnePackage": "{} har mere end én pakke:",
"deviceSupportsXArch": "Din enhed understøtter {} CPU-arkitekturen.",
"deviceSupportsFollowingArchs": "Din enhed understøtter følgende CPU-arkitekture:",
"warning": "Advarsel",
"sourceIsXButPackageFromYPrompt": "App-kilden er '{}' men udgivelsespakken kommer fra '{}'. Fortsæt?",
"updatesAvailable": "Opdateringer tilgængelige",
"updatesAvailableNotifDescription": "Underretter brugeren om, at opdateringer er tilgængelige for flere apps, der spores af Obtanium",
"noNewUpdates": "Ingen nye opdateringer.",
"xHasAnUpdate": "{} har en opdatering.",
"appsUpdated": "Apps opdateret",
"appsNotUpdated": "Kunne ikke opdatere applikationerne",
"appsUpdatedNotifDescription": "Underretter brugeren om, at opdateringer til en eller flere apps blev anvendt i baggrunden",
"xWasUpdatedToY": "{} blev opdateret til {}.",
"xWasNotUpdatedToY": "Kunne ikke opdatere {} til {}.",
"errorCheckingUpdates": "Fejl under opdateringstjek",
"errorCheckingUpdatesNotifDescription": "En notifikation, der viser når baggrundsopdateringstjek fejledr",
"appsRemoved": "Apps fjernet",
"appsRemovedNotifDescription": "Underretter brugeren om, at en eller flere apps blev fjernet på grund af fejl under indlæsningen af dem",
"xWasRemovedDueToErrorY": "{} blev fjernet på grund af denne fejl: {}",
"completeAppInstallation": "Komplet app-installation ",
"obtainiumMustBeOpenToInstallApps": "Obtainium skal være åben for at kunne installere apps",
"completeAppInstallationNotifDescription": "Beder brugeren om at vende tilbage til Obtanium for at afslutte installationen af en app",
"checkingForUpdates": "Tjekker for opdateringer",
"checkingForUpdatesNotifDescription": "Forbigående notifikationer, der vises, når der tjekkes for opdateringer",
"pleaseAllowInstallPerm": "Venligst tillad Obtanium at installere apps",
"trackOnly": "Følg kun",
"errorWithHttpStatusCode": "Fejl {}",
"versionCorrectionDisabled": "Versionkorrektion deaktiveret (plugin ser ikke ud til at virke)",
"unknown": "Ukendt",
"none": "Ingen",
"never": "Aldrig",
"latestVersionX": "Seneste: {}",
"installedVersionX": "Installeret: {}",
"lastUpdateCheckX": "Sidste opdateringstjek: {}",
"remove": "Fjern",
"yesMarkUpdated": "Ja, marker som opdateret",
"fdroid": "F-Droid Officiel",
"appIdOrName": "App-ID eller navn",
"appId": "App-ID",
"appWithIdOrNameNotFound": "Ingen app blev fundet med det ID eller navn",
"reposHaveMultipleApps": "Depoter indeholder muligvis flere apps",
"fdroidThirdPartyRepo": "F-Droid Tredjeparts-depot",
"steamMobile": "Steam Mobil",
"steamChat": "Steam Chat",
"install": "Installer",
"markInstalled": "Marker som installeret",
"update": "Opdater",
"markUpdated": "Marker som opdateret",
"additionalOptions": "Yderligere indstillinger",
"disableVersionDetection": "Slå versiondetektion fra",
"noVersionDetectionExplanation": "Denne indstlling burde kun blive brugt for apps hvor versiondetektion ikke fungerer korrekt.",
"downloadingX": "Downloader {}",
"downloadX": "Download {}",
"downloadedX": "Downloadede {}",
"releaseAsset": "Udgivelsesresource",
"downloadNotifDescription": "Giver brugeren besked om fremgangen i at downloade en app",
"noAPKFound": "Ingen APK fundet",
"noVersionDetection": "Ingen versiondetektion",
"categorize": "Kategoriser",
"categories": "Kategorier",
"category": "Kategori",
"noCategory": "Ingen kategori",
"noCategories": "Ingen kategorier",
"deleteCategoriesQuestion": "Slet kategorier?",
"categoryDeleteWarning": "Alle apps i slettet kategorier vil blive sat som ikke-kategoriseret.",
"addCategory": "Tilføj kategori",
"label": "Mærke",
"language": "Sprog",
"copiedToClipboard": "Kopieret til udklipsholder",
"storagePermissionDenied": "Lagringstilladelse nægtet",
"selectedCategorizeWarning": "Dette vil erstatte alle eksisterende kategoriindstillinger for de valgte apps.",
"filterAPKsByRegEx": "Filtrer APK'er med regulære udtryk",
"removeFromObtainium": "Fjern fra Obtainium",
"uninstallFromDevice": "Afinstaller fra enhed",
"onlyWorksWithNonVersionDetectApps": "Virker kun for apps med versiondetektion slået fra.",
"releaseDateAsVersion": "Bruger udgivelsesdatoen som versionsstreng",
"releaseDateAsVersionExplanation": "Denne indstilling burde kun bruges for apps hvor versiondetektion ikke fungerer korrek, men en udgivelsesdato er tilgængelig.",
"changes": "Ændringer",
"releaseDate": "Udgivelsesdato",
"importFromURLsInFile": "Importer fra URL'er i fil (som OPML)",
"versionDetectionExplanation": "Afstem versionsstreng med versionen registreret fra OS",
"versionDetection": "Versiondetektion",
"standardVersionDetection": "Standard versiondetektion",
"groupByCategory": "Grupper efter kategori",
"autoApkFilterByArch": "Prøv at filtrere APK'er efter CPU-arkitektur hvis muligt",
"overrideSource": "Tilsidesæt kilde",
"dontShowAgain": "Vis ikke denne igen",
"dontShowTrackOnlyWarnings": "Vis ikke 'Følg kun'-advarsler",
"dontShowAPKOriginWarnings": "Vis ikke advarsel om APK-oprindelse",
"moveNonInstalledAppsToBottom": "Flyt ikke-installeret apps til bunden af app-visning",
"gitlabPATLabel": "Personlig adgangstoken for GitHub",
"about": "Om",
"requiresCredentialsInSettings": "{} har brug for yderligere legitimation (i indstillinger)",
"checkOnStart": "Tjek for opdateringer ved start",
"tryInferAppIdFromCode": "Prøv at udlede app-ID fra kildekoden",
"removeOnExternalUninstall": "Fjern automatisk apps afinstalleret eksternt",
"pickHighestVersionCode": "Vælg automatisk APK'en med den højeste versionkode",
"checkUpdateOnDetailPage": "Tjek efter opdateringer, når du åbner en app-side",
"disablePageTransitions": "Slå animationer af sideovergange fra",
"reversePageTransitions": "Animer sideovergange omvendt",
"minStarCount": "Minimums antal af stjerner",
"addInfoBelow": "Tilføj dette info nedenfor.",
"addInfoInSettings": "Tilføj dette info i indstillingerne.",
"githubSourceNote": "GitHub takstgrænser kan undgåes ved at bruge en API-nøgle.",
"sortByLastLinkSegment": "Sort efter kun det sidste segment af linket",
"filterReleaseNotesByRegEx": "Filtrer udgivelsesnoter efter regulære udtryk",
"customLinkFilterRegex": "Brugerdefineret filter for APK-link efter regulære udtryk (Standard '.apk$')",
"appsPossiblyUpdated": "Appopdateringer forsøgt",
"appsPossiblyUpdatedNotifDescription": "Underretter brugeren når opdateringer af en eller flere apps muligvis blev anvendt i baggrunden",
"xWasPossiblyUpdatedToY": "{} blev muligvis opdateret til {}.",
"enableBackgroundUpdates": "Slå baggrundsopdateringer til",
"backgroundUpdateReqsExplanation": "Baggrundsopdateringer er muligvis ikke muligt for alle apps.",
"backgroundUpdateLimitsExplanation": "Successen af baggrundsinstallationer kan kun blive bestemt når Obtanium er åbent.",
"verifyLatestTag": "Verificer 'senest'-tagget",
"intermediateLinkRegex": "Filtrer efter et 'Mellemliggende' link til at besøge",
"filterByLinkText": "Filtrer links efter linktekst",
"intermediateLinkNotFound": "Mellemliggende link ikke fundet",
"intermediateLink": "Mellemliggende link",
"exemptFromBackgroundUpdates": "Fritag fra baggrundsopdateringer (hvis slået til)",
"bgUpdatesOnWiFiOnly": "Slå baggrundsopdateringer fra når du ikke er på WiFi",
"autoSelectHighestVersionCode": "Vælg automatisk APK'en med den højeste versionkode",
"versionExtractionRegEx": "ReGex for versionsstrengs-ekstraktion",
"matchGroupToUse": "Match gruppe til at bruge til ReGex for versionsstrengs-ekstraktion",
"highlightTouchTargets": "Fremhæv mindre åbenlyse berøringsmål",
"pickExportDir": "Vælg eksportmappe",
"autoExportOnChanges": "Eksporter automatisk på ændringer",
"includeSettings": "Inkluder indstillinger",
"filterVersionsByRegEx": "Filtrer versioner efter regulære udtryk",
"trySelectingSuggestedVersionCode": "Prøv at vælge APK'en med den anbefalede version",
"dontSortReleasesList": "Behold udgivelsesodre fra API",
"reverseSort": "Omvendt sortering",
"takeFirstLink": "Tag første link",
"skipSort": "Spring sortering over",
"debugMenu": "Fejlfindingsmenu",
"bgTaskStarted": "Baggrundsopgave startet - tjek logsne.",
"runBgCheckNow": "Kør baggrundsopdateringstjek nu",
"versionExtractWholePage": "Anvend Regex for versionsstrengs-ekstraktion for hele siden",
"installing": "Installerer",
"skipUpdateNotifications": "Spring opdateringsnotifikationer over",
"updatesAvailableNotifChannel": "Opdateringer tilgængelige",
"appsUpdatedNotifChannel": "Apps opdateret",
"appsPossiblyUpdatedNotifChannel": "Appopdateringer prøvet",
"errorCheckingUpdatesNotifChannel": "Fejl ved opdateringstjek",
"appsRemovedNotifChannel": "Apps fjernet",
"downloadingXNotifChannel": "Downloader {}",
"completeAppInstallationNotifChannel": "Færdigør app-installation",
"checkingForUpdatesNotifChannel": "Tjekker for opdateringer",
"onlyCheckInstalledOrTrackOnlyApps": "Tjek kun installeret og Følg kun-apps for opdateringer",
"supportFixedAPKURL": "Understøt fiksede APK-url'er",
"selectX": "Vælg {}",
"parallelDownloads": "Tillad parallelle downloads",
"useShizuku": "Brug Shizuku eller Sui til at installere",
"shizukuBinderNotFound": "Shizuku-tjeneste kører ikke",
"shizukuOld": "Forældet Shizuku-version (<11) - opdater den",
"shizukuOldAndroidWithADB": "Shizuku kører på Android < 8.1 med ADB - opdater Android eller brug Sui istedet",
"shizukuPretendToBeGooglePlay": "Indstilg Google Play som installationskilde (hvis Shizuku bruges)",
"useSystemFont": "Brug systemfonten",
"useVersionCodeAsOSVersion": "Brug app versionkode som OS-identificeret version",
"requestHeader": "Anmodningshovede",
"useLatestAssetDateAsReleaseDate": "Brug seneste resourceupload som udgivelsesdato",
"defaultPseudoVersioningMethod": "Standard Pseudi-version metode",
"partialAPKHash": "Delvis APK-hash",
"APKLinkHash": "Hash for APK-link",
"directAPKLink": "Direkte APK-link",
"pseudoVersionInUse": "En pseudo-version er i brug",
"installed": "Installeret",
"latest": "Seneste",
"invertRegEx": "Inverter regulært udtryk",
"note": "Note",
"selfHostedNote": "\"{}\"dropdownen kan bruges som selv-hostet/brugerdefineret instans af enhver kilde.",
"badDownload": "APK'en kunne ikke analyseres (inkompatikbel eller delvis download)",
"beforeNewInstallsShareToAppVerifier": "Del nye apps med AppVerifier (hvis tilgængeligt)",
"appVerifierInstructionToast": "Del til AppVerifier og returner hertil når færdig.",
"wiki": "Hjælp/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourcede app-konfigurationer (brug på egen risiko)",
"removeAppQuestion": {
"one": "Fjern app?",
"other": "Fjern apps?"
},
"tooManyRequestsTryAgainInMinutes": {
"one": "For mange forespørgsler (takstbegrænset) - prøv igen om {} minut",
"other": "For mange forespørgsler (takstbegrænset) - prøv igen om {} minutter"
},
"bgUpdateGotErrorRetryInMinutes": {
"one": "Baggrundsopdateringstjek stødte på en {} og vil planlægge et nyt tjek om {} minut",
"other": "Baggrundsopdateringstjek stødte på en {} og vil planlægge et nyt tjek om {} minutter"
},
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "Baggrundsopdateringstjekket fandt {} opdatering - vil underrette brugeren hvis nødvendigt",
"other": "Baggrundsopdateringstjekket fandt {} opdateringer - vil underrette brugeren hvis nødvendigt"
},
"apps": {
"one": "{} App",
"other": "{} Apps"
},
"url": {
"one": "{} URL",
"other": "{} URLs"
},
"minute": {
"one": "{} Minut",
"other": "{} Minutter"
},
"hour": {
"one": "{} Time",
"other": "{} Timer"
},
"day": {
"one": "{} Dag",
"other": "{} Dage"
},
"clearedNLogsBeforeXAfterY": {
"one": "Rydede {n} log (før = {before}, efter = {after})",
"other": "Rydede {n} logs (før = {before}, efter = {after})"
},
"xAndNMoreUpdatesAvailable": {
"one": "{} og 1 anden app har opdateringer.",
"other": "{} og {} andre apps har opdateringer."
},
"xAndNMoreUpdatesInstalled": {
"one": "{} og 1 anden app blev opdateret.",
"other": "{} og {} andre apps blev opdateret."
},
"xAndNMoreUpdatesFailed": {
"one": "Kunne ikke opdatere {} og 1 anden app.",
"other": "Kunne ikke opdatere {} og {} andre apps."
},
"xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} og 1 anden app blev muligvis opdateret.",
"other": "{} og {} andre apps blev muligvis opdateret."
},
"apk": {
"one": "{} APK",
"other": "{} APK'er"
}
}

View File

@@ -5,13 +5,13 @@
"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",
"functionNotImplemented": "Cette classe n'a pas implémentée cette fonction",
"placeholder": "Espace réservé",
"someErrors": "Des erreurs se sont produites",
"unexpectedError": "Erreur inattendue",
"ok": "D'accord",
"and": "et",
"githubPATLabel": "Jeton d'Accès Personnel GitHub (Augmente la limite de débit)",
"githubPATLabel": "Jeton d'Accès Personnel GitHub (augmente la limite de débit)",
"includePrereleases": "Inclure les avant-premières",
"fallbackToOlderReleases": "Retour aux anciennes versions",
"filterReleaseTitlesByRegEx": "Filtrer les titres de version par expression régulière",
@@ -24,7 +24,7 @@
"colour": "Couleur",
"standard": "Standard",
"custom": "Sur mesure",
"useMaterialYou": "Utiliser le matériel que vous",
"useMaterialYou": "Utiliser Material You",
"githubStarredRepos": "Dépôts étoilés GitHub",
"uname": "Nom d'utilisateur",
"wrongArgNum": "Mauvais nombre d'arguments fournis",
@@ -46,12 +46,12 @@
"additionalOptsFor": "Options supplémentaires pour {}",
"supportedSources": "Sources prises en charge ",
"trackOnlyInBrackets": "(Suivi uniquement)",
"searchableInBrackets": "(Intérrogeable)",
"searchableInBrackets": "(Interrogeable)",
"appsString": "Applications",
"noApps": "Aucune application",
"noAppsForFilter": "Aucune application pour le filtre",
"byX": "Par {}",
"percentProgress": "Progrès: {}%",
"percentProgress": "Progrès: {}%",
"pleaseWait": "Veuillez patienter",
"updateAvailable": "Mise à jour disponible",
"notInstalled": "Non installé",
@@ -67,18 +67,18 @@
"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 étant à jour ?",
"markXSelectedAppsAsUpdated": "Marquer {} les applications sélectionnées comme étant à jour?",
"no": "Non",
"yes": "Oui",
"markSelectedAppsUpdated": "Marquer les applications sélectionnées comme étant à jour",
"pinToTop": "Épingler en haut",
"unpinFromTop": "Désépingler du haut",
"resetInstallStatusForSelectedAppsQuestion": "Réinitialiser le statu d'installation des applications sélectionnées ?",
"installStatusOfXWillBeResetExplanation": "Le statu 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.",
"resetInstallStatusForSelectedAppsQuestion": "Réinitialiser le statut d'installation des applications sélectionnées?",
"installStatusOfXWillBeResetExplanation": "Le statut 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.",
"customLinkMessage": "Ces liens fonctionnent sur les appareils sur lesquels Obtainium est installé",
"shareAppConfigLinks": "Partager la configuration de l'application sous forme de lien HTML",
"shareSelectedAppURLs": "Partager les URL d'application sélectionnées",
"resetInstallStatus": "Réinitialiser le statu d'installation",
"shareSelectedAppURLs": "Partager les URL d'applications 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",
@@ -98,7 +98,7 @@
"importFromURLList": "Importer à partir de la liste d'URL",
"searchQuery": "Requête",
"appURLList": "Liste d'URL d'application",
"line": "Queue",
"line": "File d'attente",
"searchX": "Rechercher {}",
"noResults": "Aucun résultat trouvé",
"importX": "Importer {}",
@@ -107,14 +107,14 @@
"importedXOfYApps": "{} sur {} applications importées.",
"followingURLsHadErrors": "Les URL suivantes comportaient des erreurs :",
"selectURL": "Sélectionnez l'URL",
"selectURLs": "Sélectionnez les URLs",
"selectURLs": "Sélectionnez les URL",
"pick": "Prendre",
"theme": "Thème",
"dark": "Sombre",
"light": "Clair",
"followSystem": "Suivre le système",
"followSystemThemeExplanation": "Il n'est possible de suivre le thème du système qu'en utilisant des applications tierces.",
"useBlackTheme": "Utilisez le thème noir pur",
"useBlackTheme": "Utiliser le thème noir pur",
"appSortBy": "Applications triées par",
"authorName": "Auteur/Nom",
"nameAuthor": "Nom/Auteur",
@@ -123,10 +123,10 @@
"ascending": "Ascendant",
"descending": "Descendant",
"bgUpdateCheckInterval": "Intervalle de vérification des mises à jour en arrière-plan",
"neverManualOnly": "Jamais - Manuel uniquement",
"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",
"pinUpdates": "Épingler les mises à jour en tête de la vue Applications",
"updates": "Mises à jour",
"sourceSpecific": "Spécifique à la source",
"appSource": "Source de l'application",
@@ -135,13 +135,13 @@
"close": "Fermer",
"share": "Partager",
"appNotFound": "Application introuvable",
"obtainiumExportHyphenatedLowercase": "exportation d'Obtainium",
"obtainiumExportHyphenatedLowercase": "Exportation-Obtainium",
"pickAnAPK": "Choisissez un APK",
"appHasMoreThanOnePackage": "{} a plus d'un paquet :",
"deviceSupportsXArch": "Votre appareil prend en charge l'architecture CPU {}.",
"deviceSupportsFollowingArchs": "Votre appareil prend en charge les architectures CPU suivantes :",
"warning": "Avertissement",
"sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais la version du paquet provient de '{}'. Continuer?",
"sourceIsXButPackageFromYPrompt": "La source de l'application est '{}' mais la version du paquet 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.",
@@ -168,7 +168,7 @@
"unknown": "Inconnu",
"none": "Aucun",
"never": "Jamais",
"latestVersionX": "Dernière version: {}",
"latestVersionX": "Dernière version: {}",
"installedVersionX": "Version installée : {}",
"lastUpdateCheckX": "Vérification de la dernière mise à jour : {}",
"remove": "Retirer",
@@ -179,15 +179,15 @@
"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",
"steamMobile": "Vapeur Mobile",
"steamChat": "Chat sur Steam",
"steamMobile": "Application mobile Steam",
"steamChat": "Steam Chat",
"install": "Installer",
"markInstalled": "Marquer installée",
"markInstalled": "Marquer comme installée",
"update": "Mettre à jour",
"markUpdated": "Marquer à jour",
"markUpdated": "Marquer comme étant à jour",
"additionalOptions": "Options additionnelles",
"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.",
"noVersionDetectionExplanation": "Cette option être utilisée uniquement pour les applications où la détection de version ne fonctionne pas correctement.",
"downloadingX": "Téléchargement {}",
"downloadX": "Télécharger {}",
"downloadedX": "Téléchargé {}",
@@ -199,9 +199,9 @@
"categories": "Catégories",
"category": "Catégorie",
"noCategory": "Aucune catégorie",
"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.",
"noCategories": "Aucune catégories",
"deleteCategoriesQuestion": "Supprimer les catégories?",
"categoryDeleteWarning": "Toutes les applications dans les catégories supprimées ne seront plus catégorisées.",
"addCategory": "Ajouter une catégorie",
"label": "Étiquette",
"language": "Langue",
@@ -221,18 +221,18 @@
"versionDetection": "Détection des versions",
"standardVersionDetection": "Détection de version standard",
"groupByCategory": "Regrouper par catégorie",
"autoApkFilterByArch": "Si possible, essayez de filtrer les APK par architecture CPU",
"autoApkFilterByArch": "Si possible, essayer de filtrer les APK par architecture CPU",
"overrideSource": "Remplacer la source",
"dontShowAgain": "Ne plus montrer",
"dontShowTrackOnlyWarnings": "Ne pas afficher l'avertissement 'Track-Only'",
"dontShowTrackOnlyWarnings": "Ne pas afficher l'avertissement 'Suivi uniquement'",
"dontShowAPKOriginWarnings": "Ne pas afficher les avertissements sur l'origine de l'APK",
"moveNonInstalledAppsToBottom": "Déplacer les applications non installées vers le bas de la vue Applications",
"gitlabPATLabel": "Jeton d'accès personnel GitLab",
"about": "À propos de",
"requiresCredentialsInSettings": "{}: Cela nécessite des identifiants supplémentaires (dans Paramètres)",
"requiresCredentialsInSettings": "{}: Cela nécessite des identifiants supplémentaires (dans Paramètres)",
"checkOnStart": "Vérifier les mises à jour au démarrage",
"tryInferAppIdFromCode": "Essayez de déduire l'ID de l'application à partir du code source",
"removeOnExternalUninstall": "Supprimer automatiquement les applications désinstallées en externe",
"tryInferAppIdFromCode": "Essayer de déduire l'ID de l'application à partir du code source",
"removeOnExternalUninstall": "Supprimer automatiquement les applications désinstallées depuis l'extérieur",
"pickHighestVersionCode": "Sélectionner automatiquement le code de version de l'APK la plus élevée",
"checkUpdateOnDetailPage": "Vérifier les mises à jour lors de l'ouverture de la page détaillée d'une application",
"disablePageTransitions": "Désactiver les animations de transition de page",
@@ -246,18 +246,18 @@
"customLinkFilterRegex": "Filtre du lien APK personnalisé par expression régulière (par défaut '.apk$')",
"appsPossiblyUpdated": "Tentative de mise à jour de l'application",
"appsPossiblyUpdatedNotifDescription": "Avertit l'utilisateur que des mises à jour d'une ou plusieurs applications ont été potentiellement appliquées en arrière-plan",
"xWasPossiblyUpdatedToY": "{} a peut-être été mis à jour vers {}.",
"xWasPossiblyUpdatedToY": "{} pourrait avoir été mis à jour vers {}.",
"enableBackgroundUpdates": "Activer les mises à jour en arrière-plan",
"backgroundUpdateReqsExplanation": "Les mises à jour en arrière-plan peuvent ne pas être possibles pour toutes les applications.",
"backgroundUpdateLimitsExplanation": "Le succès d'une installation en arrière-plan ne peut être déterminé qu'à l'ouverture d'Obtainium.",
"verifyLatestTag": "Vérifiez la balise 'Latest'",
"verifyLatestTag": "Vérifier la balise 'latest'",
"intermediateLinkRegex": " Filtrer un lien \" intermédiaire \" à visiter ",
"filterByLinkText": "Filtrer les liens par le texte du lien",
"intermediateLinkNotFound": "Lien intermédiaire introuvable",
"intermediateLink": "Lien intermédiaire",
"exemptFromBackgroundUpdates": "Exempté des mises à jour en arrière-plan (si activé)",
"bgUpdatesOnWiFiOnly": "Désactiver les mises à jour en arrière-plan lorsque vous n'êtes pas connecté au WiFi",
"autoSelectHighestVersionCode": "Sélection automatique du code de version de l'APK la plus élevée",
"autoSelectHighestVersionCode": "Sélection automatique du code de version le plus élevé de l'APK",
"versionExtractionRegEx": "Expression régulière d'extraction de version",
"matchGroupToUse": "Groupe de correspondance pour l'expression régulière d'extraction de version",
"highlightTouchTargets": "Mettre en évidence les cibles tactiles moins évidentes",
@@ -265,13 +265,13 @@
"autoExportOnChanges": "Exporter automatiquement après modification",
"includeSettings": "Inclure les paramètres",
"filterVersionsByRegEx": "Filtrer les versions par expression régulière",
"trySelectingSuggestedVersionCode": "Essayez de sélectionner le code de la version APK suggérée",
"dontSortReleasesList": "Conserver l'ordre des version de l'API",
"trySelectingSuggestedVersionCode": "Essayer de sélectionner le code de la version suggérée de l'APK",
"dontSortReleasesList": "Conserver l'ordre des versions de l'API",
"reverseSort": "Tri inversé",
"takeFirstLink": "Prendre le premier lien",
"skipSort": "Sauter le tri",
"skipSort": "Éviter le tri",
"debugMenu": "Menu de débogage",
"bgTaskStarted": "Tâche en arrière-plan démarrée - vérifier les journaux.",
"bgTaskStarted": "Tâche en arrière-plan démarrée vérifier les journaux.",
"runBgCheckNow": "Exécuter maintenant la vérification de la mise à jour en arrière-plan",
"versionExtractWholePage": "Appliquer l'expression régulière d'extraction de version sur l'ensemble de la page",
"installing": "Installation",
@@ -284,14 +284,14 @@
"downloadingXNotifChannel": "Téléchargement {}",
"completeAppInstallationNotifChannel": "Installation complète de l'application",
"checkingForUpdatesNotifChannel": "Vérification des mises à jour",
"onlyCheckInstalledOrTrackOnlyApps": "Vérifiez uniquement les mises à jour des applications installées et 'Track-Only'",
"onlyCheckInstalledOrTrackOnlyApps": "Vérifier uniquement les mises à jour des applications installées et 'Suivi uniquement'",
"supportFixedAPKURL": "Prise en charge des URL APK fixes",
"selectX": "Sélectionner {}",
"parallelDownloads": "Autoriser les téléchargements parallèles",
"parallelDownloads": "Autoriser le téléchargement en parallèle",
"useShizuku": "Utiliser Shizuku ou Sui pour l'installation",
"shizukuBinderNotFound": "Service Shizuku compatible non trouvé",
"shizukuOld": "Ancienne version de Shizuku (<11) - la mettre à jour",
"shizukuOldAndroidWithADB": "Shizuku fonctionne sur Android < 8.1 avec ADB - mettre à jour Android ou utiliser Sui à la place",
"shizukuOld": "Ancienne version de Shizuku (<11) la mettre à jour",
"shizukuOldAndroidWithADB": "Shizuku fonctionne sur Android < 8.1 avec ADB mettez à jour Android ou utilisez Sui à la place",
"shizukuPretendToBeGooglePlay": "Définir Google Play comme source d'installation (si Shizuku est utilisé)",
"useSystemFont": "Utiliser la police du système",
"useVersionCodeAsOSVersion": "Utiliser le code de version de l'application comme version détectée par le système d'exploitation",
@@ -311,22 +311,22 @@
"beforeNewInstallsShareToAppVerifier": "Partager les nouvelles applications avec AppVerifier (si disponible)",
"appVerifierInstructionToast": "Partagez avec AppVerifier, puis revenez ici lorsque vous êtes prêt.",
"wiki": "Aide/Wiki",
"crowdsourcedConfigsLabel": "Configurations d'applications par la foule (utilisation à vos risques et périls)",
"crowdsourcedConfigsLabel": "Configurations d'applications participative (utilisation à vos risques et périls)",
"removeAppQuestion": {
"one": "Supprimer l'application ?",
"other": "Supprimer les applications ?"
"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"
"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 {}, une nouvelle tentative de vérification sera planifié dans {} minute",
"other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, une nouvelle tentative de vérification sera planifié dans {} minute"
"other": "La vérification de la mise à jour en arrière-plan a rencontré un {}, une nouvelle tentative de vérification sera planifié dans {} minutes"
},
"bgCheckFoundUpdatesWillNotifyIfNeeded": {
"one": "La vérification des mises à jour en arrière-plan a trouvée {} mise à jour - l'utilisateur sera notifié si nécessaire",
"other": "La vérification des mises à jour en arrière-plan a trouvé {} mises à jour - l'utilisateur sera notifié si nécessaire"
"one": "La vérification des mises à jour en arrière-plan a trouvée {} mise à jour l'utilisateur sera notifié si nécessaire",
"other": "La vérification des mises à jour en arrière-plan a trouvée {} mises à jour  l'utilisateur sera notifié si nécessaire"
},
"apps": {
"one": "{} Application",
@@ -365,8 +365,8 @@
"other": "Échec de la mise à jour de {} et {} autres applications."
},
"xAndNMoreUpdatesPossiblyInstalled": {
"une": "{} et 1 application supplémentaire ont peut-être été mises à jour.",
"other": "{} et {} autres applications peuvent avoir été mises à jour."
"une": "{} et 1 application supplémentaire pourraient avoir été mises à jour.",
"other": "{} et {} autres applications pourraient avoir été mises à jour."
},
"apk": {
"one": "{} APK",

View File

@@ -22,9 +22,9 @@
"requiredInBrackets": "(Yêu cầu)",
"dropdownNoOptsError": "LỖI: TẢI XUỐNG PHẢI CÓ ÍT NHẤT MỘT LỰA CHỌN",
"colour": "Màu sắc",
"standard": "Standard",
"custom": "Custom",
"useMaterialYou": "Use Material You",
"standard": "Mặc định",
"custom": "Tùy chỉnh",
"useMaterialYou": "Sử dụng Material You",
"githubStarredRepos": "Kho lưu trữ có gắn dấu sao GitHub",
"uname": "Tên người dùng",
"wrongArgNum": "Số lượng đối số được cung cấp sai",
@@ -147,10 +147,10 @@
"noNewUpdates": "Không có bản cập nhật mới.",
"xHasAnUpdate": "{} có bản cập nhật.",
"appsUpdated": "Ứng dụng đã cập nhật ",
"appsNotUpdated": "Failed to update applications",
"appsNotUpdated": "Ứng dụng đã cập nhật không thành công",
"appsUpdatedNotifDescription": "Thông báo cho người dùng rằng các bản cập nhật cho một hoặc nhiều Ứng dụng đã được áp dụng trong nền",
"xWasUpdatedToY": "{} đã được cập nhật thành {}.",
"xWasNotUpdatedToY": "Failed to update {} to {}.",
"xWasNotUpdatedToY": "{} đã cập nhật thành {} không thành công.",
"errorCheckingUpdates": "Lỗi kiểm tra bản cập nhật",
"errorCheckingUpdatesNotifDescription": "Thông báo hiển thị khi kiểm tra cập nhật nền không thành công",
"appsRemoved": "Ứng dụng đã loại bỏ",
@@ -189,8 +189,8 @@
"disableVersionDetection": "Tắt tính năng phát hiện phiên bản",
"noVersionDetectionExplanation": "Chỉ nên sử dụng tùy chọn này cho Ứng dụng mà tính năng phát hiện phiên bản không hoạt động chính xác.",
"downloadingX": "Đang tải xuống {}",
"downloadX": "Download {}",
"downloadedX": "Downloaded {}",
"downloadX": "Tải xuống {}",
"downloadedX": "Đã tải xuống {}",
"releaseAsset": "Release Asset",
"downloadNotifDescription": "Thông báo cho người dùng về tiến trình tải xuống Ứng dụng",
"noAPKFound": "Không tìm thấy APK",
@@ -288,10 +288,10 @@
"supportFixedAPKURL": "Hỗ trợ URL APK cố định",
"selectX": "Lựa chọn {}",
"parallelDownloads": "Cho phép tải đa luồng",
"useShizuku": "Use Shizuku or Sui to install",
"useShizuku": "Sử dụng Shizuku hoặc Sui để cài đặt",
"shizukuBinderNotFound": "Shizuku chưa khởi động",
"shizukuOld": "Old Shizuku version (<11) - update it",
"shizukuOldAndroidWithADB": "Shizuku running on Android < 8.1 with ADB - update Android or use Sui instead",
"shizukuOld": "Phiên bản Shizuku lỗi thời (<11) - hãy cập nhật nó",
"shizukuOldAndroidWithADB": "Shizuku chạy trên Android < 8.1 với ADB - hãy cập nhật Android hoặc thay bằng Sui",
"shizukuPretendToBeGooglePlay": "Set Google Play as the installation source (if Shizuku is used)",
"useSystemFont": "Sử dụng phông chữ hệ thống",
"useVersionCodeAsOSVersion": "Sử dụng Mã phiên bản ứng dụng làm phiên bản do hệ điều hành phát hiện",
@@ -310,7 +310,7 @@
"badDownload": "Không thể phân tích cú pháp APK (tải xuống một phần hoặc không tương thích)",
"beforeNewInstallsShareToAppVerifier": "Chia sẻ ứng dụng mới với AppVerifier (nếu có)",
"appVerifierInstructionToast": "Chia sẻ lên AppVerifier, sau đó quay lại đây khi sẵn sàng.",
"wiki": "Help/Wiki",
"wiki": "Trợ giúp/Wiki",
"crowdsourcedConfigsLabel": "Crowdsourced App Configurations (use at your own risk)",
"removeAppQuestion": {
"one": "Gỡ ứng dụng?",
@@ -361,8 +361,8 @@
"other": "{} và {} ứng dụng khác đã được cập nhật."
},
"xAndNMoreUpdatesFailed": {
"one": "Failed to update {} and 1 more app.",
"other": "Failed to update {} and {} more apps."
"one": "{} và 1 ứng dụng khác đã cập nhật không thành công.",
"other": "{} và {} ứng dụng khác đã cập nhật không thảnh công."
},
"xAndNMoreUpdatesPossiblyInstalled": {
"one": "{} và 1 ứng dụng khác có thể đã được cập nhật.",

View File

@@ -285,7 +285,9 @@ class GitHub extends AppSource {
DateTime? getPublishDateFromRelease(dynamic rel) =>
rel?['published_at'] != null
? DateTime.parse(rel['published_at'])
: null;
: rel?['commit']?['created'] != null
? DateTime.parse(rel['commit']['created'])
: null;
DateTime? getNewestAssetDateFromRelease(dynamic rel) {
var t = (rel['assets'] as List<dynamic>?)
?.map((e) {

View File

@@ -111,6 +111,14 @@ class GitLab extends AppSource {
}
}
@override
Future<String> apkUrlPrefetchModifier(String apkUrl, String standardUrl,
Map<String, dynamic> additionalSettings) async {
String? PAT = await getPATIfAny(hostChanged ? additionalSettings : {});
String optionalAuth = (PAT != null) ? 'private_token=$PAT' : '';
return '$apkUrl?$optionalAuth';
}
@override
Future<APKDetails> getLatestAPKDetails(
String standardUrl,
@@ -153,7 +161,8 @@ class GitLab extends AppSource {
.toList();
var apkUrlsSet = apkUrlsFromAssets.toSet();
apkUrlsSet.addAll(uploadedAPKsFromDescription);
var releaseDateString = e['released_at'] ?? e['created_at'];
var releaseDateString =
e['released_at'] ?? e['created_at'] ?? e['commit']?['created_at'];
DateTime? releaseDate =
releaseDateString != null ? DateTime.parse(releaseDateString) : null;
return APKDetails(

View File

@@ -40,6 +40,7 @@ List<MapEntry<Locale, String>> supportedLocales = const [
MapEntry(Locale('vi'), 'Tiếng Việt'),
MapEntry(Locale('tr'), 'Türkçe'),
MapEntry(Locale('uk'), 'Українська'),
MapEntry(Locale('da'), 'Dansk'),
];
const fallbackLocale = Locale('en');
const localeDir = 'assets/translations';
@@ -212,20 +213,23 @@ class _ObtainiumState extends State<Obtainium> {
// Decide on a colour/brightness scheme based on OS and user settings
ColorScheme lightColorScheme;
ColorScheme darkColorScheme;
if (lightDynamic != null && darkDynamic != null && settingsProvider.useMaterialYou) {
if (lightDynamic != null &&
darkDynamic != null &&
settingsProvider.useMaterialYou) {
lightColorScheme = lightDynamic.harmonized();
darkColorScheme = darkDynamic.harmonized();
} else {
lightColorScheme = ColorScheme.fromSeed(seedColor: settingsProvider.themeColor);
lightColorScheme =
ColorScheme.fromSeed(seedColor: settingsProvider.themeColor);
darkColorScheme = ColorScheme.fromSeed(
seedColor: settingsProvider.themeColor, brightness: Brightness.dark);
seedColor: settingsProvider.themeColor,
brightness: Brightness.dark);
}
// set the background and surface colors to pure black in the amoled theme
if (settingsProvider.useBlackTheme) {
darkColorScheme = darkColorScheme
.copyWith(surface: Colors.black)
.harmonized();
darkColorScheme =
darkColorScheme.copyWith(surface: Colors.black).harmonized();
}
if (settingsProvider.useSystemFont) NativeFeatures.loadSystemFont();

View File

@@ -226,18 +226,26 @@ class _AppPageState extends State<AppPage> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 20),
app?.icon != null
? Row(mainAxisAlignment: MainAxisAlignment.center, children: [
GestureDetector(
child: Image.memory(
app!.icon!,
height: 150,
gaplessPlayback: true,
),
onTap: () => pm.openApp(app.app.id),
)
])
: Container(),
FutureBuilder(
future: appsProvider.updateAppIcon(app?.app.id),
builder: (ctx, val) {
return app?.icon != null
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: app == null
? null
: () => pm.openApp(app.app.id),
child: Image.memory(
app!.icon!,
height: 150,
gaplessPlayback: true,
),
)
])
: Container();
}),
const SizedBox(
height: 25,
),

View File

@@ -143,11 +143,14 @@ class AppsPageState extends State<AppsPage> {
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
late final ScrollController scrollController = ScrollController();
var sourceProvider = SourceProvider();
@override
Widget build(BuildContext context) {
var appsProvider = context.watch<AppsProvider>();
var settingsProvider = context.watch<SettingsProvider>();
var sourceProvider = SourceProvider();
var listedApps = appsProvider.getAppValues().toList();
refresh() {
@@ -354,7 +357,11 @@ class AppsPageState extends State<AppsPage> {
SliverFillRemaining(
child: Center(
child: Text(
appsProvider.apps.isEmpty ? tr('noApps') : tr('noAppsForFilter'),
appsProvider.apps.isEmpty
? appsProvider.loadingApps
? tr('pleaseWait')
: tr('noApps')
: tr('noAppsForFilter'),
style: Theme.of(context).textTheme.headlineMedium,
textAlign: TextAlign.center,
))),
@@ -402,29 +409,36 @@ class AppsPageState extends State<AppsPage> {
}
getAppIcon(int appIndex) {
return listedApps[appIndex].icon != null
? Image.memory(
listedApps[appIndex].icon!,
gaplessPlayback: true,
)
: 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.3),
colorBlendMode: BlendMode.modulate,
gaplessPlayback: true,
),
)),
]);
return FutureBuilder(
future: appsProvider.updateAppIcon(listedApps[appIndex].app.id),
builder: (ctx, val) {
return listedApps[appIndex].icon != null
? Image.memory(
listedApps[appIndex].icon!,
gaplessPlayback: true,
)
: 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: Theme.of(context).brightness ==
Brightness.dark
? Colors.white.withOpacity(0.4)
: Colors.white.withOpacity(0.3),
colorBlendMode: BlendMode.modulate,
gaplessPlayback: true,
),
)),
]);
});
}
getVersionText(int appIndex) {
@@ -1087,11 +1101,16 @@ class AppsPageState extends State<AppsPage> {
body: RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: refresh,
child: CustomScrollView(slivers: <Widget>[
CustomAppBar(title: tr('appsString')),
...getLoadingWidgets(),
getDisplayedList()
])),
child: Scrollbar(
interactive: true,
controller: scrollController,
child: CustomScrollView(
controller: scrollController,
slivers: <Widget>[
CustomAppBar(title: tr('appsString')),
...getLoadingWidgets(),
getDisplayedList()
]))),
persistentFooterButtons: appsProvider.apps.isEmpty
? null
: [

View File

@@ -5,6 +5,7 @@ import 'package:flex_color_picker/flex_color_picker.dart';
import 'package:flutter/material.dart';
import 'package:obtainium/components/custom_app_bar.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/components/generated_form_modal.dart';
import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/main.dart';
import 'package:obtainium/providers/apps_provider.dart';
@@ -945,6 +946,25 @@ class _LogsDialogState extends State<LogsDialog> {
],
),
actions: [
TextButton(
onPressed: () async {
var cont = (await showDialog<Map<String, dynamic>?>(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
title: tr('appLogs'),
items: const [],
initValid: true,
message: tr('removeFromObtainium'),
);
})) !=
null;
if (cont) {
logsProvider.clear();
Navigator.of(context).pop();
}
},
child: Text(tr('remove'))),
TextButton(
onPressed: () {
Navigator.of(context).pop();

View File

@@ -329,6 +329,10 @@ Future<Map<String, String>> getHeaders(String url,
return returnHeaders;
}
Future<List<PackageInfo>> getAllInstalledInfo() async {
return await pm.getInstalledPackages() ?? [];
}
Future<PackageInfo?> getInstalledInfo(String? packageName,
{bool printErr = true}) async {
if (packageName != null) {
@@ -364,7 +368,9 @@ class AppsProvider with ChangeNotifier {
foregroundStream = FGBGEvents.stream.asBroadcastStream();
foregroundSubscription = foregroundStream?.listen((event) async {
isForeground = event == FGBGType.foreground;
if (isForeground) loadApps();
if (isForeground) {
await loadApps();
}
});
() async {
await settingsProvider.initializeSettings();
@@ -1160,17 +1166,6 @@ class AppsProvider with ChangeNotifier {
: 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 {
while (loadingApps) {
await Future.delayed(const Duration(microseconds: 1));
@@ -1179,6 +1174,8 @@ class AppsProvider with ChangeNotifier {
notifyListeners();
var sp = SourceProvider();
List<List<String>> errors = [];
var installedAppsData = await getAllInstalledInfo();
List<String> removedAppIds = [];
await Future.wait((await getAppsDir()) // Parse Apps from JSON
.listSync()
.map((item) async {
@@ -1199,43 +1196,53 @@ class AppsProvider with ChangeNotifier {
}
}
if (app != null) {
// Save the app to the in-memory list without grabbing any OS info first
apps.update(
app.id,
(value) => AppInMemory(
app!, value.downloadProgress, value.installedInfo, value.icon),
ifAbsent: () => AppInMemory(app!, null, null, null));
notifyListeners();
try {
// Try getting the app's source to ensure no invalid apps get loaded
sp.getSource(app.url, overrideSource: app.overrideSource);
// If the app is installed, grab its OS data and reconcile install statuses
PackageInfo? installedInfo;
try {
installedInfo =
installedAppsData.firstWhere((i) => i.packageName == app!.id);
} catch (e) {
// If the app isn't installed the above throws an error
}
// Reconcile differences between the installed and recorded install info
var moddedApp =
getCorrectedInstallStatusAppIfPossible(app, installedInfo);
if (moddedApp != null) {
app = moddedApp;
// Note the app ID if it was uninstalled externally
if (moddedApp.installedVersion == null) {
removedAppIds.add(moddedApp.id);
}
}
// Update the app in memory with install info and corrections
apps.update(
app.id,
(value) => AppInMemory(app!, value.downloadProgress,
value.installedInfo, value.icon),
ifAbsent: () => AppInMemory(app!, null, null, null));
(value) => AppInMemory(
app!, value.downloadProgress, installedInfo, value.icon),
ifAbsent: () => AppInMemory(app!, null, installedInfo, null));
notifyListeners();
} catch (e) {
errors.add([app.id, app.finalName, e.toString()]);
errors.add([app!.id, app.finalName, e.toString()]);
}
}
}));
notifyListeners();
if (errors.isNotEmpty) {
removeApps(errors.map((e) => e[0]).toList());
NotificationsProvider().notify(
AppsRemovedNotification(errors.map((e) => [e[1], e[2]]).toList()));
}
// Get install status and other OS info for each App (slow)
List<App> modifiedApps = [];
await Future.wait(apps.values.map((app) async {
await updateInstallStatusInMemory(app);
var moddedApp =
getCorrectedInstallStatusAppIfPossible(app.app, app.installedInfo);
if (moddedApp != null) {
modifiedApps.add(moddedApp);
}
}));
notifyListeners();
// Reconcile version differences
if (modifiedApps.isNotEmpty) {
await saveApps(modifiedApps, attemptToCorrectInstallStatus: false);
var removedAppIds = modifiedApps
.where((a) => a.installedVersion == null)
.map((e) => e.id)
.toList();
// After reconciliation, delete externally uninstalled Apps if needed
// Delete externally uninstalled Apps if needed
if (removedAppIds.isNotEmpty) {
if (removedAppIds.isNotEmpty) {
if (settingsProvider.removeOnExternalUninstall) {
await removeApps(removedAppIds);
@@ -1246,6 +1253,22 @@ class AppsProvider with ChangeNotifier {
notifyListeners();
}
Future<void> updateAppIcon(String? appId) async {
if (apps[appId]?.icon == null) {
var icon =
(await apps[appId]?.installedInfo?.applicationInfo?.getAppIcon());
if (icon != null) {
apps.update(
apps[appId]!.app.id,
(value) => AppInMemory(apps[appId]!.app, value.downloadProgress,
value.installedInfo, icon),
ifAbsent: () => AppInMemory(
apps[appId]!.app, null, apps[appId]?.installedInfo, icon));
notifyListeners();
}
}
}
Future<void> saveApps(List<App> apps,
{bool attemptToCorrectInstallStatus = true,
bool onlyIfExists = true}) async {
@@ -1941,8 +1964,7 @@ Future<void> bgUpdateCheck(String taskId, Map<String, dynamic>? params) async {
await appsProvider.downloadAndInstallLatestApps(
toInstall.map((e) => e.key).toList(), null,
notificationsProvider: notificationsProvider,
forceParallelDownloads: true,
useExisting: false);
forceParallelDownloads: true);
} catch (e) {
if (e is MultiAppMultiError) {
e.idsByErrorString.forEach((key, value) {

View File

@@ -354,11 +354,13 @@ preStandardizeUrl(String url) {
url.toLowerCase().indexOf('https://') != 0) {
url = 'https://$url';
}
var trailingSlash = Uri.tryParse(url)?.path.endsWith('/') ?? false;
url = url
.split('/')
.where((e) => e.isNotEmpty)
.join('/')
.replaceFirst(':/', '://');
.split('/')
.where((e) => e.isNotEmpty)
.join('/')
.replaceFirst(':/', '://') +
(trailingSlash ? '/' : '');
return url;
}
@@ -523,8 +525,7 @@ abstract class AppSource {
[GeneratedFormTextField('appName', label: tr('appName'), required: false)],
[
GeneratedFormSwitch('shizukuPretendToBeGooglePlay',
label: tr('shizukuPretendToBeGooglePlay'),
defaultValue: false)
label: tr('shizukuPretendToBeGooglePlay'), defaultValue: false)
],
[
GeneratedFormSwitch('exemptFromBackgroundUpdates',

View File

@@ -47,18 +47,18 @@ packages:
dependency: "direct main"
description:
name: app_links
sha256: "8c6ef5ba9e26b720d4c9073826befb87df2ab5e7a81c22b6c3145080b5e736c9"
sha256: "96e677810b83707ff5e10fac11e4839daa0ea4e0123c35864c092699165eb3db"
url: "https://pub.dev"
source: hosted
version: "6.0.2"
version: "6.1.1"
archive:
dependency: transitive
description:
name: archive
sha256: ecf4273855368121b1caed0d10d4513c7241dfc813f7d3c8933b36622ae9b265
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
url: "https://pub.dev"
source: hosted
version: "3.5.1"
version: "3.6.1"
args:
dependency: transitive
description:
@@ -79,10 +79,10 @@ packages:
dependency: "direct main"
description:
name: background_fetch
sha256: "2fe367c9be0e256dadb75b8b637b0b58a2a2d2317b7c8420bb1ae8b41e23fde3"
sha256: b5c298c911bc2ce41152668bc72eb0488f0665d75bc6d1e69e7d8367763eddcd
url: "https://pub.dev"
source: hosted
version: "1.3.4"
version: "1.3.5"
boolean_selector:
dependency: transitive
description:
@@ -263,10 +263,10 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: "29c90806ac5f5fb896547720b73b17ee9aed9bba540dc5d91fe29f8c5745b10a"
sha256: "2ca051989f69d1b2ca012b2cf3ccf78c70d40144f0861ff2c063493f7c8c3d45"
url: "https://pub.dev"
source: hosted
version: "8.0.3"
version: "8.0.5"
fixnum:
dependency: transitive
description:
@@ -361,18 +361,18 @@ packages:
dependency: "direct main"
description:
name: flutter_markdown
sha256: "9921f9deda326f8a885e202b1e35237eadfc1345239a0f6f0f1ff287e047547f"
sha256: ff76a9300a06ad1f2b394e54c0b4beaaf6a95f95c98540c918b870221499bb10
url: "https://pub.dev"
source: hosted
version: "0.7.1"
version: "0.7.2"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f"
sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e
url: "https://pub.dev"
source: hosted
version: "2.0.19"
version: "2.0.20"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -387,10 +387,10 @@ packages:
dependency: "direct main"
description:
name: fluttertoast
sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66"
sha256: "7eae679e596a44fdf761853a706f74979f8dd3cd92cf4e23cae161fda091b847"
url: "https://pub.dev"
source: hosted
version: "8.2.5"
version: "8.2.6"
fraction:
dependency: transitive
description:
@@ -443,10 +443,10 @@ packages:
dependency: transitive
description:
name: image
sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8"
url: "https://pub.dev"
source: hosted
version: "4.1.7"
version: "4.2.0"
intl:
dependency: transitive
description:
@@ -571,10 +571,10 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
sha256: "9c96da072b421e98183f9ea7464898428e764bc0ce5567f27ec8693442e72514"
url: "https://pub.dev"
source: hosted
version: "2.2.4"
version: "2.2.5"
path_provider_foundation:
dependency: transitive
description:
@@ -619,18 +619,18 @@ packages:
dependency: transitive
description:
name: permission_handler_android
sha256: "8bb852cd759488893805c3161d0b2b5db55db52f773dbb014420b304055ba2c5"
sha256: b29a799ca03be9f999aa6c39f7de5209482d638e6f857f6b93b0875c618b7e54
url: "https://pub.dev"
source: hosted
version: "12.0.6"
version: "12.0.7"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662
sha256: e6f6d73b12438ef13e648c4ae56bd106ec60d17e90a59c4545db6781229082a0
url: "https://pub.dev"
source: hosted
version: "9.4.4"
version: "9.4.5"
permission_handler_html:
dependency: transitive
description:
@@ -667,10 +667,10 @@ packages:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
version: "3.1.5"
plugin_platform_interface:
dependency: transitive
description:
@@ -715,10 +715,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_android
sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
version: "2.2.3"
shared_preferences_foundation:
dependency: transitive
description:
@@ -881,18 +881,18 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e"
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
url: "https://pub.dev"
source: hosted
version: "6.2.6"
version: "6.3.0"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775"
sha256: ceb2625f0c24ade6ef6778d1de0b2e44f2db71fded235eb52295247feba8c5cf
url: "https://pub.dev"
source: hosted
version: "6.3.1"
version: "6.3.3"
url_launcher_ios:
dependency: transitive
description:
@@ -977,18 +977,18 @@ packages:
dependency: "direct main"
description:
name: webview_flutter
sha256: "25e1b6e839e8cbfbd708abc6f85ed09d1727e24e08e08c6b8590d7c65c9a8932"
sha256: "6869c8786d179f929144b4a1f86e09ac0eddfe475984951ea6c634774c16b522"
url: "https://pub.dev"
source: hosted
version: "4.7.0"
version: "4.8.0"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: dad3313c9ead95517bb1cae5e1c9d20ba83729d5a59e5e83c0a2d66203f27f91
sha256: f42447ca49523f11d8f70abea55ea211b3cafe172dd7a0e7ac007bb35dd356dc
url: "https://pub.dev"
source: hosted
version: "3.16.1"
version: "3.16.4"
webview_flutter_platform_interface:
dependency: transitive
description:

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: 1.1.9+2266
version: 1.1.11+2268
environment:
sdk: '>=3.0.0 <4.0.0'