Merge pull request #2171 from ImranR98/dev

- Make downloads faster (#580)
- Better sort options for GitHub releases (#2144)
- Enable arch-based auto-filter for intermediate HTML links (#2162)
- GitLab bugfix (#2167)
This commit is contained in:
Imran
2025-03-07 18:13:35 -05:00
committed by GitHub
33 changed files with 243 additions and 103 deletions

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "Tencent App Store",
"name": "Name",
"smartname": "Name (Smart)",
"sortMethod": "Sort Method",
"removeAppQuestion": {
"one": "Želite li ukloniti aplikaciju?",
"other": "Želite li ukloniti aplikacije?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Zůstaňte o jednu verzi pozadu za nejnovější",
"refreshBeforeDownload": "Obnovení údajů o aplikaci před stažením",
"tencentAppStore": "Tencent App Store",
"name": "Název",
"smartname": "Název (Smart)",
"sortMethod": "Metoda třídění",
"removeAppQuestion": {
"one": "Odstranit Apku?",
"other": "Odstranit Apky?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Forbliv én version bagud den seneste",
"refreshBeforeDownload": "Opdater app-detaljer før download",
"tencentAppStore": "Tencent App Store",
"name": "Navn",
"smartname": "Navn (Smart)",
"sortMethod": "Sorteringsmetode",
"removeAppQuestion": {
"one": "Fjern app?",
"other": "Fjern apps?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Eine Version hinter der neuesten Version bleiben",
"refreshBeforeDownload": "App-Details vor dem Download aktualisieren",
"tencentAppStore": "Tencent App Store",
"name": "Name",
"smartname": "Name (Smart)",
"sortMethod": "Sortierverfahren",
"removeAppQuestion": {
"one": "App entfernen?",
"other": "Apps entfernen?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "Tencent App Store",
"name": "Name",
"smartname": "Name (Smart)",
"sortMethod": "Sort Method",
"removeAppQuestion": {
"one": "Forigi la aplikaĵon?",
"other": "Forigi la aplikaĵojn?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "Tencent App Store",
"name": "Name",
"smartname": "Name (Smart)",
"sortMethod": "Sort Method",
"removeAppQuestion": {
"one": "Remove App?",
"other": "Remove Apps?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Mantenerse una versión por detrás de la última",
"refreshBeforeDownload": "Actualiza los datos de la aplicación antes de descargarla",
"tencentAppStore": "Tencent App Store",
"name": "Nombre",
"smartname": "Nombre (Smart)",
"sortMethod": "Método de clasificación",
"removeAppQuestion": {
"one": "¿Eliminar aplicación?",
"other": "¿Eliminar aplicaciones?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "یک نسخه از آخرین نسخه پشت سر بگذارید",
"refreshBeforeDownload": "قبل از دانلود، جزئیات برنامه را بازخوانی کنید",
"tencentAppStore": "Tencent App Store",
"name": "Name",
"smartname": "Name (Smart)",
"sortMethod": "Sort Method",
"removeAppQuestion": {
"one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Rester une version en arrière de la dernière",
"refreshBeforeDownload": "Actualiser les détails de l'application avant de la télécharger",
"tencentAppStore": "Tencent App Store",
"name": "Nom",
"smartname": "Nom (Smart)",
"sortMethod": "Méthode de tri",
"removeAppQuestion": {
"one": "Supprimer l'application ?",
"other": "Supprimer les applications ?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Maradjon egy verzióval a legújabb mögött",
"refreshBeforeDownload": "Az alkalmazás adatainak frissítése a letöltés előtt",
"tencentAppStore": "Tencent Appstore",
"name": "Név",
"smartname": "Név (Smart)",
"sortMethod": "Rendezési módszer",
"removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazásokat?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Tetap satu versi di belakang versi terbaru",
"refreshBeforeDownload": "Segarkan detail aplikasi sebelum mengunduh",
"tencentAppStore": "Tencent App Store",
"name": "Nama",
"smartname": "Nama (Cerdas)",
"sortMethod": "Metode Penyortiran",
"removeAppQuestion": {
"one": "Hapus aplikasi?",
"other": "Hapus aplikasi?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Rimanere una versione indietro rispetto alla più recente",
"refreshBeforeDownload": "Aggiornare i dettagli dell'app prima del download",
"tencentAppStore": "Tencent App Store",
"name": "Nome",
"smartname": "Nome (intelligente)",
"sortMethod": "Metodo di ordinamento",
"removeAppQuestion": {
"one": "Rimuovere l'app?",
"other": "Rimuovere le app?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "最新のバージョンから1つ前のものを使用する",
"refreshBeforeDownload": "ダウンロード前にアプリの詳細を更新する",
"tencentAppStore": "Tencent App Store",
"name": "Name",
"smartname": "名前(スマート)",
"sortMethod": "ソート方法",
"removeAppQuestion": {
"one": "アプリを削除しますか?",
"other": "アプリを削除しますか?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "최신 버전보다 한 버전 뒤에 머무르기",
"refreshBeforeDownload": "다운로드 전에 앱 세부 정보 새로 고침",
"tencentAppStore": "텐센트 앱 스토어",
"name": "이름",
"smartname": "이름(스마트)",
"sortMethod": "정렬 방법",
"removeAppQuestion": {
"one": "앱을 제거하시겠습니까?",
"other": "앱을 제거하시겠습니까?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Blijf een versie achter op de nieuwste",
"refreshBeforeDownload": "Vernieuw app details voor download",
"tencentAppStore": "Tencent App Store",
"name": "Naam",
"smartname": "Naam (Slim)",
"sortMethod": "Sorteermethode",
"removeAppQuestion": {
"one": "App verwijderen?",
"other": "Apps verwijderen?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Pozostań jedną wersję w tyle za najnowszą",
"refreshBeforeDownload": "Odśwież szczegóły aplikacji przed pobraniem",
"tencentAppStore": "Tencent App Store",
"name": "Nazwa",
"smartname": "Nazwa (Smart)",
"sortMethod": "Metoda sortowania",
"removeAppQuestion": {
"one": "Usunąć aplikację?",
"few": "Usunąć aplikacje?",

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Manter-se uma versão atrás da mais recente",
"refreshBeforeDownload": "Atualizar os detalhes da aplicação antes da transferência",
"tencentAppStore": "Tencent App Store",
"name": "Nome",
"smartname": "Nome (Smart)",
"sortMethod": "Método de ordenação",
"removeAppQuestion": {
"one": "Remover aplicativo?",
"other": "Remover aplicativos?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Не отставайте от последней версии",
"refreshBeforeDownload": "Обновляйте информацию о приложении перед загрузкой",
"tencentAppStore": "Tencent App Store",
"name": "Имя",
"smartname": "Имя (умное)",
"sortMethod": "Метод сортировки",
"removeAppQuestion": {
"one": "Удалить приложение?",
"other": "Удалить приложения?"

View File

@ -13,7 +13,10 @@ const neverAutoTranslate = {
obtainiumExportHyphenatedLowercase: ['*'],
theme: ['de'],
appId: ['de'],
placeholder: ['pl']
placeholder: ['pl'],
importExport: ['fr'],
url: ['fr'],
tencentAppStore: ['*']
}
const translateText = async (text, targetLang, authKey) => {
@ -76,40 +79,49 @@ const main = async () => {
const translationKeys = Object.keys(templateTranslation)
for (let j in translationKeys) {
const k = translationKeys[j]
if (JSON.stringify(thisTranslation[k]) == JSON.stringify(templateTranslation[k])) {
const lang = file.split('/').pop().split('.')[0]
if (!neverAutoTranslate[k] || (neverAutoTranslate[k].indexOf('*') < 0 && neverAutoTranslate[k].indexOf(lang) < 0)) {
const reportLine = `${file} :::: ${k} :::: ${JSON.stringify(thisTranslation[k])}`
if (deeplAPIKey) {
const translateFunc = async (str) => {
const response = await translateText(str, lang, deeplAPIKey)
if (response.translations) {
return response.translations[0].text
} else {
throw JSON.stringify(response)
}
}
try {
if (typeof templateTranslation[k] == 'string') {
thisTranslation[k] = await translateFunc(thisTranslation[k])
} else {
const subKeys = Object.keys(templateTranslation[k])
for (let n in subKeys) {
const kk = subKeys[n]
thisTranslation[k][kk] = await translateFunc(thisTranslation[k][kk])
try {
if (JSON.stringify(thisTranslation[k]) == JSON.stringify(templateTranslation[k])) {
const lang = file.split('/').pop().split('.')[0]
if (!neverAutoTranslate[k] || (neverAutoTranslate[k].indexOf('*') < 0 && neverAutoTranslate[k].indexOf(lang) < 0)) {
const reportLine = `${file} :::: ${k} :::: ${JSON.stringify(thisTranslation[k])}`
if (deeplAPIKey) {
const translateFunc = async (str) => {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, Math.random() * 1000); // Try to avoid rate limit
})
const response = await translateText(str, lang, deeplAPIKey)
if (response.translations) {
return response.translations[0].text
} else {
throw JSON.stringify(response)
}
}
} catch (e) {
if (typeof e == 'string') {
console.log(`${reportLine} :::: ${e}`)
} else {
throw e
try {
if (typeof templateTranslation[k] == 'string') {
thisTranslation[k] = await translateFunc(thisTranslation[k])
} else {
const subKeys = Object.keys(templateTranslation[k])
for (let n in subKeys) {
const kk = subKeys[n]
thisTranslation[k][kk] = await translateFunc(thisTranslation[k][kk])
}
}
} catch (e) {
if (typeof e == 'string') {
console.log(`${reportLine} :::: ${e}`)
} else {
throw e
}
}
} else {
console.log(reportLine)
}
} else {
console.log(reportLine)
}
}
} catch (err) {
console.error(err)
}
}
fs.writeFileSync(file, `${JSON.stringify(thisTranslation, null, ' ')}\n`)

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Håll dig en version bakom den senaste",
"refreshBeforeDownload": "Uppdatera appdetaljerna före nedladdning",
"tencentAppStore": "Tencent App Store",
"name": "Namn",
"smartname": "Namn (Smart)",
"sortMethod": "Sorteringsmetod",
"removeAppQuestion": {
"one": "Ta Bort App?",
"other": "Ta Bort Appar?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "En son sürümün bir sürüm gerisinde kalın",
"refreshBeforeDownload": "İndirmeden önce uygulama ayrıntılarını yenileyin",
"tencentAppStore": "Tencent App Store",
"name": "İsim",
"smartname": "İsim (Akıllı)",
"sortMethod": "Sıralama Yöntemi",
"removeAppQuestion": {
"one": "Uygulamayı Kaldır?",
"other": "Uygulamaları Kaldır?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Залишайтеся на одну версію актуальнішою",
"refreshBeforeDownload": "Оновіть інформацію про програму перед завантаженням",
"tencentAppStore": "Tencent App Store",
"name": "Ім'я",
"smartname": "Ім'я (Smart)",
"sortMethod": "Метод сортування",
"removeAppQuestion": {
"one": "Видалити застосунок?",
"other": "Видалити застосунки?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "Tencent App Store",
"name": "Name",
"smartname": "Name (Smart)",
"sortMethod": "Sort Method",
"removeAppQuestion": {
"one": "Gỡ ứng dụng?",
"other": "Gỡ ứng dụng?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "Stay one version behind latest",
"refreshBeforeDownload": "Refresh app details before download",
"tencentAppStore": "騰訊應用寶",
"name": "Name",
"smartname": "Name (Smart)",
"sortMethod": "Sort Method",
"removeAppQuestion": {
"one": "移除應用程式?",
"other": "移除應用程式?"

View File

@ -319,6 +319,9 @@
"stayOneVersionBehind": "比最新版本晚一个版本",
"refreshBeforeDownload": "下载前刷新应用程序详细信息",
"tencentAppStore": "腾讯应用宝",
"name": "名称",
"smartname": "姓名(智能)",
"sortMethod": "排序方法",
"removeAppQuestion": {
"one": "是否删除应用?",
"other": "是否删除应用?"

View File

@ -75,8 +75,18 @@ class GitHub extends AppSource {
],
[GeneratedFormSwitch('verifyLatestTag', label: tr('verifyLatestTag'))],
[
GeneratedFormSwitch('dontSortReleasesList',
label: tr('dontSortReleasesList'))
GeneratedFormDropdown(
'sortMethodChoice',
[
MapEntry('date', tr('releaseDate')),
MapEntry('smartname', tr('smartname')),
MapEntry('none', tr('none')),
MapEntry('smartname-datefallback',
'${tr('smartname')} x ${tr('releaseDate')}'),
MapEntry('name', tr('name')),
],
label: tr('sortMethod'),
defaultValue: 'date')
],
[
GeneratedFormSwitch('useLatestAssetDateAsReleaseDate',
@ -244,10 +254,10 @@ class GitHub extends AppSource {
? additionalSettings['filterReleaseNotesByRegEx']
: null;
bool verifyLatestTag = additionalSettings['verifyLatestTag'] == true;
bool dontSortReleasesList =
additionalSettings['dontSortReleasesList'] == true;
bool useLatestAssetDateAsReleaseDate =
additionalSettings['useLatestAssetDateAsReleaseDate'] == true;
String sortMethod =
additionalSettings['sortMethodChoice'] ?? 'smartname-datefallback';
dynamic latestRelease;
if (verifyLatestTag) {
var temp = requestUrl.split('?');
@ -316,7 +326,7 @@ class GitHub extends AppSource {
? getPublishDateFromRelease(rel)
: getNewestAssetDateFromRelease(rel);
if (dontSortReleasesList) {
if (sortMethod == 'none') {
releases = releases.reversed.toList();
} else {
releases.sort((a, b) {
@ -330,22 +340,30 @@ class GitHub extends AppSource {
} else {
var nameA = a['tag_name'] ?? a['name'];
var nameB = b['tag_name'] ?? b['name'];
var stdFormats = findStandardFormatsForVersion(nameA, true)
.intersection(findStandardFormatsForVersion(nameB, true));
if (stdFormats.isNotEmpty) {
var reg = RegExp(stdFormats.first);
var matchA = reg.firstMatch(nameA);
var matchB = reg.firstMatch(nameB);
return compareAlphaNumeric(
(nameA as String).substring(matchA!.start, matchA.end),
(nameB as String).substring(matchB!.start, matchB.end));
} else {
var stdFormats = findStandardFormatsForVersion(nameA, false)
.intersection(findStandardFormatsForVersion(nameB, false));
if (sortMethod == 'date' ||
(sortMethod == 'smartname-datefallback' &&
stdFormats.isEmpty)) {
return (getReleaseDateFromRelease(
a, useLatestAssetDateAsReleaseDate) ??
DateTime(1))
.compareTo(getReleaseDateFromRelease(
b, useLatestAssetDateAsReleaseDate) ??
DateTime(0));
} else {
if (sortMethod != 'name' && stdFormats.isNotEmpty) {
var reg = RegExp(stdFormats.last);
var matchA = reg.firstMatch(nameA);
var matchB = reg.firstMatch(nameB);
return compareAlphaNumeric(
(nameA as String).substring(matchA!.start, matchA.end),
(nameB as String).substring(matchB!.start, matchB.end));
} else {
// 'name'
return compareAlphaNumeric(
(nameA as String), (nameB as String));
}
}
}
});

View File

@ -120,7 +120,7 @@ class GitLab extends AppSource {
Map<String, dynamic> additionalSettings) async {
String? PAT = await getPATIfAny(hostChanged ? additionalSettings : {});
String optionalAuth = (PAT != null) ? 'private_token=$PAT' : '';
return '$apkUrl?$optionalAuth';
return '$apkUrl${(Uri.parse(apkUrl).query.isEmpty ? '?' : '&')}$optionalAuth';
}
@override

View File

@ -212,6 +212,10 @@ class HTML extends AppSource {
required: true,
additionalValidators: [(value) => regExValidator(value)])
],
[
GeneratedFormSwitch('autoApkFilterByArch',
label: tr('autoApkFilterByArch'), defaultValue: false)
],
];
HTML() {
additionalSourceAppSpecificSettingFormItems = [
@ -315,6 +319,10 @@ class HTML extends AppSource {
if (intLinks.isEmpty) {
throw NoReleasesError(note: currentUrl);
} else {
if (additionalSettings['intermediateLink'][i]['autoApkFilterByArch'] ==
true) {
intLinks = await filterApksByArch(intLinks);
}
currentUrl = intLinks.last.key;
}
}

View File

@ -9,6 +9,7 @@ import 'package:battery_plus/battery_plus.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'package:crypto/crypto.dart';
import 'dart:typed_data';
import 'package:android_intent_plus/flag.dart';
import 'package:android_package_installer/android_package_installer.dart';
@ -345,18 +346,44 @@ Future<File> downloadFile(String url, String fileName, bool fileNameHasExt,
// Perform the download
var received = 0;
double? progress;
DateTime? lastProgressUpdate; // Track last progress update time
if (rangeStart > 0 && fullContentLength != null) {
received = rangeStart;
}
await response.stream.map((s) {
received += s.length;
progress =
(fullContentLength != null ? (received / fullContentLength) * 100 : 30);
if (onProgress != null) {
onProgress(progress);
}
return s;
}).pipe(sink);
const downloadUIUpdateInterval = Duration(milliseconds: 500);
const downloadBufferSize = 32 * 1024; // 32KB
final downloadBuffer = BytesBuilder();
await response.stream
.map((chunk) {
received += chunk.length;
final now = DateTime.now();
if (onProgress != null &&
(lastProgressUpdate == null ||
now.difference(lastProgressUpdate!) >=
downloadUIUpdateInterval)) {
progress = fullContentLength != null
? (received / fullContentLength) * 100
: 30;
onProgress(progress);
lastProgressUpdate = now;
}
return chunk;
})
.transform(StreamTransformer<List<int>, List<int>>.fromHandlers(
handleData: (List<int> data, EventSink<List<int>> s) {
downloadBuffer.add(data);
if (downloadBuffer.length >= downloadBufferSize) {
s.add(downloadBuffer.takeBytes());
}
},
handleDone: (EventSink<List<int>> s) {
if (downloadBuffer.isNotEmpty) {
s.add(downloadBuffer.takeBytes());
}
s.close();
},
))
.pipe(sink);
await sink.close();
progress = null;
if (onProgress != null) {

View File

@ -152,6 +152,10 @@ appJSONCompatibilityModifiers(Map<String, dynamic> json) {
if (additionalSettings['autoApkFilterByArch'] == null) {
additionalSettings['autoApkFilterByArch'] = false;
}
// GitHub "don't sort" option to new dropdown format
if (additionalSettings['dontSortReleasesList'] == true) {
additionalSettings['sortMethodChoice'] = 'none';
}
if (source.runtimeType == HTML().runtimeType) {
// HTML key rename
if (originalAdditionalSettings['sortByFileNamesNotLinks'] != null) {
@ -474,6 +478,23 @@ List<MapEntry<String, String>> getApkUrlsFromUrls(List<String> urls) =>
return MapEntry(apkSegs.isNotEmpty ? apkSegs.last : segments.last, e);
}).toList();
Future<List<MapEntry<String, String>>> filterApksByArch(
List<MapEntry<String, String>> apkUrls) async {
if (apkUrls.length > 1) {
var abis = (await DeviceInfoPlugin().androidInfo).supportedAbis;
for (var abi in abis) {
var urls2 = apkUrls
.where((element) => RegExp('.*$abi.*').hasMatch(element.key))
.toList();
if (urls2.isNotEmpty && urls2.length < apkUrls.length) {
apkUrls = urls2;
break;
}
}
}
return apkUrls;
}
getSourceRegex(List<String> hosts) {
return '(${hosts.join('|').replaceAll('.', '\\.')})';
}
@ -984,18 +1005,8 @@ class SourceProvider {
if (apk.apkUrls.isEmpty && !trackOnly) {
throw NoAPKError();
}
if (apk.apkUrls.length > 1 &&
additionalSettings['autoApkFilterByArch'] == true) {
var abis = (await DeviceInfoPlugin().androidInfo).supportedAbis;
for (var abi in abis) {
var urls2 = apk.apkUrls
.where((element) => RegExp('.*$abi.*').hasMatch(element.key))
.toList();
if (urls2.isNotEmpty && urls2.length < apk.apkUrls.length) {
apk.apkUrls = urls2;
break;
}
}
if (additionalSettings['autoApkFilterByArch'] == true) {
apk.apkUrls = await filterApksByArch(apk.apkUrls);
}
var name = currentApp != null ? currentApp.name.trim() : '';
name = name.isNotEmpty ? name : apk.names.name;

View File

@ -80,10 +80,10 @@ packages:
dependency: transitive
description:
name: archive
sha256: "528579c7e4579719f04b21eeeeddfd73a18b31dabc22766893b7d1be7f49b967"
sha256: "0c64e928dcbefddecd234205422bcfc2b5e6d31be0b86fef0d0dd48d7b4c9742"
url: "https://pub.dev"
source: hosted
version: "4.0.3"
version: "4.0.4"
args:
dependency: transitive
description:
@ -232,10 +232,10 @@ packages:
dependency: "direct main"
description:
name: device_info_plus
sha256: "72d146c6d7098689ff5c5f66bcf593ac11efc530095385356e131070333e64da"
sha256: "306b78788d1bb569edb7c55d622953c2414ca12445b41c9117963e03afc5c513"
url: "https://pub.dev"
source: hosted
version: "11.3.0"
version: "11.3.3"
device_info_plus_platform_interface:
dependency: transitive
description:
@ -304,10 +304,10 @@ packages:
dependency: "direct main"
description:
name: file_picker
sha256: "6f6bfa8797f296965bdc3e1f702574ab49a540c19b9237b401e7c2b25dfe594c"
sha256: "7423298f08f6fc8cce05792bae329f9a93653fc9c08712831b1a55540127995d"
url: "https://pub.dev"
source: hosted
version: "9.0.0"
version: "9.0.2"
fixnum:
dependency: transitive
description:
@ -349,10 +349,10 @@ packages:
dependency: "direct main"
description:
name: flutter_charset_detector
sha256: d7c11a82c2c51cb35a010b42c64001afb8a9e4d7be1f57620604d386d3467ad1
sha256: "21f6fe8172fbfe3ba9d2fe0dba3702ba07f682315e829a68d49185a0c80d5ad0"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
version: "5.0.0"
flutter_charset_detector_android:
dependency: transitive
description:
@ -381,10 +381,10 @@ packages:
dependency: transitive
description:
name: flutter_charset_detector_web
sha256: b547194e97e15d2cca17e957ad7f373b48abf35080e645ac5b6976d129b0265d
sha256: e3ac65f94b12f4887937b21a19365d7927db816840cb93274e3861241cb0e9f2
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "2.0.0"
flutter_fgbg:
dependency: "direct main"
description:
@ -498,10 +498,10 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
sha256: "5a1e6fb2c0561958d7e4c33574674bda7b77caaca7a33b758876956f2902eea3"
url: "https://pub.dev"
source: hosted
version: "2.0.24"
version: "2.0.27"
flutter_test:
dependency: "direct dev"
description: flutter
@ -592,14 +592,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.19.0"
js:
dependency: transitive
description:
name: js
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
url: "https://pub.dev"
source: hosted
version: "0.7.2"
json_annotation:
dependency: transitive
description:
@ -716,10 +708,10 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2"
sha256: "0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12"
url: "https://pub.dev"
source: hosted
version: "2.2.15"
version: "2.2.16"
path_provider_foundation:
dependency: transitive
description:
@ -900,10 +892,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_android
sha256: a768fc8ede5f0c8e6150476e14f38e2417c0864ca36bb4582be8e21925a03c22
sha256: "3ec7210872c4ba945e3244982918e502fa2bfb5230dff6832459ca0e1879b7ad"
url: "https://pub.dev"
source: hosted
version: "2.4.6"
version: "2.4.8"
shared_preferences_foundation:
dependency: transitive
description:
@ -1107,10 +1099,10 @@ packages:
dependency: transitive
description:
name: url_launcher_android
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
sha256: "1d0eae19bd7606ef60fe69ef3b312a437a16549476c42321d5dc1506c9ca3bf4"
url: "https://pub.dev"
source: hosted
version: "6.3.14"
version: "6.3.15"
url_launcher_ios:
dependency: transitive
description:
@ -1187,10 +1179,10 @@ packages:
dependency: transitive
description:
name: web
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.1"
webview_flutter:
dependency: "direct main"
description:
@ -1203,10 +1195,10 @@ packages:
dependency: transitive
description:
name: webview_flutter_android
sha256: "512c26ccc5b8a571fd5d13ec994b7509f142ff6faf85835e243dde3538fdc713"
sha256: "631093a7fbd93e9690ac61d8c8f3e857efbc189fc33f712b9ad6c01a623517ef"
url: "https://pub.dev"
source: hosted
version: "4.3.2"
version: "4.3.3"
webview_flutter_platform_interface:
dependency: transitive
description:
@ -1219,10 +1211,10 @@ packages:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: d7403ef4f042714c9ee2b26eaac4cadae7394cb0d4e608b1dd850c3ff96bd893
sha256: c49a98510080378b1525132f407a92c3dcd3b7145bef04fb8137724aadcf1cf0
url: "https://pub.dev"
source: hosted
version: "3.18.2"
version: "3.18.4"
win32:
dependency: transitive
description:
@ -1235,10 +1227,10 @@ packages:
dependency: transitive
description:
name: win32_registry
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
url: "https://pub.dev"
source: hosted
version: "1.1.5"
version: "2.1.0"
xdg_directories:
dependency: transitive
description:

View File

@ -16,7 +16,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.45+2302
version: 1.1.46+2303
environment:
sdk: ^3.6.0
@ -86,7 +86,7 @@ dependencies:
markdown: any
flutter_typeahead: ^5.2.0
battery_plus: ^6.1.0
flutter_charset_detector: ^4.0.0
flutter_charset_detector: ^5.0.0
dev_dependencies:
flutter_test:
sdk: flutter