尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
Code partagé entre les apps Files Tech (PDF Tech, Read Files Tech, Pass Tech)
翻譯準備中
正在載入完整 README。
檢視完整 README ↗Code partagé entre les apps Files Tech (PDF Tech, Read Files Tech, Pass Tech). Package local Flutter (path-dependency) — non publié sur pub.dev.
| Module | Rôle |
|---|---|
RecentFile + RecentFilesService | Liste des fichiers récents persistée dans SharedPreferences, robuste aux entrées corrompues |
UpdateService + UpdateInfo | Vérification de mises à jour via GitHub Releases, cache 12h, validation semver + host whitelist |
CloudShareRow + CloudTargets | Boutons de partage cloud (kDrive, Google Drive, Proton Drive) via MethodChannel |
LegalSupportSections | Sections "Aide & support" + "Mentions légales" avec whitelist de schemes (anti intent:/javascript:) |
FormatUtils | Formatage humanisé d'octets (bytes style FR, bytesStorage style EN) |
PathSafe | Validation et sanitisation de noms de fichiers (anti path-traversal) |
Ajouter dans le pubspec.yaml de l'app consommatrice :
dependencies:
files_tech_core:
path: ../files_tech_core
import 'package:files_tech_core/files_tech_core.dart';
final svc = RecentFilesService();
List<RecentFile> recents = await svc.load();
recents = await svc.addOrUpdate(recents, '/storage/emulated/0/Download/foo.pdf');
Configurer un singleton par app :
// app/lib/services/app_update.dart
const appUpdateService = UpdateService(
owner: 'gitubpatrice',
repo: 'PDF-TECH',
currentVersion: '1.8.0',
);
// Usage
final info = await appUpdateService.checkForUpdate();
final manualCheck = await appUpdateService.checkForUpdate(force: true);
Wrapper per-app pour injecter le nom de channel :
// app/lib/widgets/cloud_share_row.dart
import 'package:files_tech_core/files_tech_core.dart' as core;
class CloudShareRow extends StatelessWidget {
final String path;
const CloudShareRow({super.key, required this.path});
@override
Widget build(BuildContext context) => core.CloudShareRow(
path: path,
channelName: 'com.pdftech.pdf_tech/share',
alignment: WrapAlignment.center,
);
}
Côté Kotlin, le channel doit exposer sendToPackage qui prend path, mime, package.
const LegalSupportSections(
appName: 'PDF Tech',
version: '1.8.0',
)
L'app consommatrice doit déclarer dans son pubspec.yaml :
flutter:
assets:
- assets/legal/PRIVACY.fr.md
- assets/legal/TERMS.fr.md
Override possible des chemins via privacyAsset / termsAsset, et de
contactEmail / websiteUrl si nécessaire.
FormatUtils.bytes(1500); // → "1.5 Ko" (FR)
FormatUtils.bytesStorage(1500); // → "1.5 KB" (EN, MB sans décimale)
PathSafe.basename('/foo/bar.pdf'); // → "bar.pdf"
PathSafe.basename('..'); // → throws ArgumentError
PathSafe.sanitizeFileName('my:file*.txt'); // → "my_file_.txt"
PathSafe.sanitizeForFs('hello world'); // → "hello_world" (variante FS-safe)
PathSafe.isValidUserFileName('foo.pdf'); // → true
api.github.com)https, http, mailto (refus de intent:, javascript:, file:, etc.)userInfo (anti credential phishing)LaunchMode.externalApplication (pas de browser-in-app)RecentFilesService.load filtre silencieusement les entrées corrompues (anti DoS)UpdateService valide tag_name en regex semver et whitelist le host de l'APK (github.com / objects.githubusercontent.com)mailto strip CRLF (anti header injection)flutter test
pubspec.yaml,
AboutScreen._version et app_update.dart currentVersion.com.pdftech.pdf_tech/share,
com.readfilestech/open_file, etc.) — déclarés dans le wrapper local.