Dart Flutter Test License

lib

Playstore

πŸ’ŽEncrypto: Easy File Encryption

Introduction πŸš€

Want to securely encrypt your private and confidential files?

With Encrypto you easily and securely protect all your important files, in an interface that is fun and simple to use.

Demo πŸ‘€

demo.mp4

Key Features πŸ”‘

βœ” Supports all file types (PDF, MP3, MP4, PNG, DOCX,…) βœ” Add files from outside the app βœ” Share the converted file from the app

Algorithm πŸ”’

Everything is encrypted using the strong encryption algorithm: AES with PKCS7 padding

Usage πŸ”Ž

To clone and run this application, you’ll need git and flutter installed on your computer. From your command line:

# Clone this repository
$ git clone https://github.com/Shadow60539/encrypto_app.git

# Go into the repository
$ cd encrypto_app

# Install dependencies
$ flutter packages get

# Run the app
$ flutter run

Packages πŸ“¦

Package Description
file_cryptor FileCryptor is for encryption and decryption files.
file_picker A package that allows you to use the native file explorer to pick single or multiple files, with extensions filtering support.
mockito A mock framework inspired by Mockito with APIs for Fakes, Mocks, behavior verification, and stubbing.
open_file A plug-in that can call native APP to open files with string result in flutter.
path_provider A Flutter plugin for finding commonly used locations on the filesystem
permission_handler This plugin provides a cross-platform (iOS, Android) API to request permissions and check their status.
lottie Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile.
share_plus A Flutter plugin to share content from your Flutter app via the platform’s share dialog.
flutter_archive Create and extract ZIP archive files.
flutter_bloc State management.
freezed Code generation for immutable classes that has a simple syntax/API without compromising on the features.
dartz Functional Programming in Dart.
injectable Injectable is a convenient code generator for get_it.
fancy_text_reveal πŸ’β€β™‚οΈ My package. Fancy way to reveal widgets.
animated_text_kit A flutter package project which contains a collection of cool and beautiful text animations.
flutter_svg An SVG rendering and widget library for Flutter.
package_info_plus Flutter plugin for querying information about the application package, such as CFBundleVersion on iOS or versionCode on Android.
flutter_isolate FlutterIsolate provides a way to launch dart isolate in flutter that work with flutter plugins.
change_app_package_name Change App Package Name with single command.
firebase_core Flutter plugin for Firebase Core, enabling connecting to multiple Firebase apps.
cloud_firestore Flutter plugin for Cloud Firestore, a cloud-hosted, noSQL database with live synchronization and offline support on Android and iOS.
equatable A Dart package that helps to implement value based equality without needing to explicitly override == and hashCode.
countup An flutter plugin that will help you to build animated counter texts.
flutter_keyboard_visibility Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS
flutter_launcher_icons A package which simplifies the task of updating your Flutter app’s launcher icon.
flutter_native_splash Customize Flutter’s default white native splash screen with background color and splash image.
fake_cloud_firestore Fake implementation of Cloud Firestore
in_app_update Enables In App Updates on Android using the official Android APIs.
restart_app A simple package that helps you to restart the whole android app with a single function call.
flutter_lints This package contains a recommended set of lints for Flutter apps, packages, and plugins to encourage good coding practices.
receive_sharing_intent A flutter plugin that enables flutter apps to receive sharing photos, videos, text, urls or any other file types from another app.

Directory Structure 🏒

The lib directory structure is as follows:

β”œβ”€β”€ application
|    β”œβ”€β”€ crypto
|    |    β”œβ”€β”€ crypto_bloc.dart
|    |    β”œβ”€β”€ crypto_event.dart
|    |    β”œβ”€β”€ crypto_state.dart
|    |── save
|    |    β”œβ”€β”€ save_bloc.dart
|    |    β”œβ”€β”€ save_event.dart
|    |    β”œβ”€β”€ save_state.dart
β”œβ”€β”€ core
|    |── enums.dart
|    |── extension.dart
|    |── navigation_service.dart
|    |── usecase.dart
β”œβ”€β”€ domain
|    |── entity
|    |    β”œβ”€β”€ file_count.dart
|    |── failure
|    |    β”œβ”€β”€ crypto_failure.dart
|    |    β”œβ”€β”€ save_failure.dart
|    |── repoitory
|    |    β”œβ”€β”€ i_crypto_repo.dart
|    |    β”œβ”€β”€ i_save_repo.dart
|    |── usecase
|    |    β”œβ”€β”€ decrypt_file.dart
|    |    β”œβ”€β”€ encrypt_file.dart
|    |    β”œβ”€β”€ get_file_count.dart
|    |    β”œβ”€β”€ increment_file_count.dart
|    |    β”œβ”€β”€ save_file.dart
|    |    β”œβ”€β”€ share_file.dart
β”œβ”€β”€ infrastructure
|    |── core
|    |    β”œβ”€β”€ firebase_helper.dart    
|    |    β”œβ”€β”€ injection_module.dart    
|    |    β”œβ”€β”€ permission_handler.dart    
|    |── data
|    |    β”œβ”€β”€ crypto_data_source.dart
|    |    β”œβ”€β”€ save_data_source.dart
|    |── exception
|    |    β”œβ”€β”€ crypto_exception.dart
|    |    β”œβ”€β”€ save_exception.dart
|    |── model
|    |    β”œβ”€β”€ file_count_model.dart
|    |── repository
|    |    β”œβ”€β”€ crypto_repo.dart
|    |    β”œβ”€β”€ save_repo.dart
β”œβ”€β”€ presentation
|    |── core
|    |    β”œβ”€β”€ palette.dart
|    |── pages
|    |    β”œβ”€β”€ home_page.dart
|    |    β”œβ”€β”€ result_page.dart
|    |    β”œβ”€β”€ splash_page.dart
|    |── widgets
|    |    β”œβ”€β”€ add_file_widget.dart
|    |    β”œβ”€β”€ app_version_widget.dart
|    |    β”œβ”€β”€ app_widget.dart
|    |    β”œβ”€β”€ count_animated_widget.dart
|    |    β”œβ”€β”€ key_widget.dart
|    |    β”œβ”€β”€ moon_animated_widget.dart
|    |    β”œβ”€β”€ permission_dialog.dart
|    |    β”œβ”€β”€ title_animated_widget.dart
|    |    β”œβ”€β”€ usecase_button.dart
β”œβ”€β”€ injection.dart
β”œβ”€β”€ main.dart

In App Purchase v3.0.5

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_encrypto/application/ad/ad_bloc.dart';
import 'package:flutter_encrypto/core/navigation_service.dart';
import 'package:in_app_purchase/in_app_purchase.dart';

const String kRemoveAds = "remove_ads";

class PurchaseProvider with ChangeNotifier {
  bool _isAvailable = false;
  final InAppPurchase _iap = InAppPurchase.instance;
  List<ProductDetails> _products = [];
  List<PurchaseDetails> _purchases = [];
  late StreamSubscription _subscription;
  InAppPurchase get iap => _iap;
  bool get isAvailable => _isAvailable;

  Future<void> initialize() async {
    _isAvailable = await _iap.isAvailable();
    _subscription = _iap.purchaseStream.listen(_listener);
    _getProducts();
    _getPastPurchases();
  }

  void _listener(List<PurchaseDetails> purchaseDetails) {
    if (purchaseDetails.isEmpty) {
      return;
    }

    _verifyPurchase(purchaseDetails[0]);
    _purchases.addAll(purchaseDetails);
    notifyListeners();
  }

  Future<void> _verifyPurchase(PurchaseDetails purchaseDetail) async {
    final bool isRemoveAdsPurchase = purchaseDetail.productID == kRemoveAds;

    if (!isRemoveAdsPurchase) {
      return;
    }

    final bool isPurchasePending = purchaseDetail.pendingCompletePurchase;

    if (isPurchasePending) {
      await _iap.completePurchase(purchaseDetail);
    }

    final bool isPurchaseSuccess =
        purchaseDetail.status == PurchaseStatus.purchased ||
            purchaseDetail.status == PurchaseStatus.restored;

    if (!isPurchaseSuccess) {
      return;
    }

    // Remove ads
    BlocProvider.of<AdBloc>(globalContext, listen: false)
        .add(AdEvent.removeAds());
  }

  void cancelSubscription() {
    _subscription.cancel();
  }

  Future<void> _getPastPurchases() async {
    await _iap.restorePurchases();
  }

  Future<void> _getProducts() async {
    final ProductDetailsResponse response =
        await _iap.queryProductDetails({kRemoveAds});

    _products = response.productDetails;
    notifyListeners();
  }

  Future<void> buyRemoveAds() async {
    final PurchaseParam _removeAdParam =
        PurchaseParam(productDetails: _products[0]);
    await _iap.buyNonConsumable(purchaseParam: _removeAdParam);
  }
}

In App Update v3.0.0

  Future<void> _checkForUpdate() async {
    final AppUpdateInfo info = await InAppUpdate.checkForUpdate();
    final bool isUpdateAvailable =
        info.updateAvailability == UpdateAvailability.updateAvailable;
    if (isUpdateAvailable) {
      final result = await InAppUpdate.performImmediateUpdate();
      if (result == AppUpdateResult.userDeniedUpdate ||
          result == AppUpdateResult.inAppUpdateFailed) {
        // close the app
        SystemNavigator.pop();
      }

      if (result == AppUpdateResult.success) {
        Restart.restartApp();
      }
    }
  }

Google Mobile Ads v1.2.0

Inside main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // Include
  MobileAds.instance.initialize();
  // runApp(const MyApp());
}

Declare bannerAd, isBannerAdLoaded, interstitialAd in the state

  late BannerAd bannerAd;
  bool isBannerAdLoaded = false;
  InterstitialAd? interstitialAd;

  @override
  void initState() {
    _createInterstitialAd();
    _createBannerAd();
    super.initState();
  }

  @override
  void dispose() {
    bannerAd.dispose();
    interstitialAd?.dispose();
    super.dispose();
  }

Interstitial Ad setup

  Future<void> _createInterstitialAd({int counter=0}) async {
    if (counter > 3) return;
    await InterstitialAd.load(
      adUnitId: "ca-app-pub-3940256099942544/8691691433",
      request: const AdRequest(),
      adLoadCallback: InterstitialAdLoadCallback(
        onAdLoaded: (ad) {
          interstitialAd = ad;
          setState(() {});
        },
        onAdFailedToLoad: (ad) {
          interstitialAd = null;
          _createInterstitialAd( counter: counter + 1);
          setState(() {});
        },
      ),
    );
  }

    Future<void> _showInterstitialAd() async {
    if (interstitialAd == null) return;
    interstitialAd!.fullScreenContentCallback = FullScreenContentCallback(
      onAdDismissedFullScreenContent: (ad) {
        ad.dispose();
        _createInterstitialAd();
      },
      onAdFailedToShowFullScreenContent: (ad, _) {
        ad.dispose();
        _createInterstitialAd();
      },
    );
    await interstitialAd!.show();
  }

Banner Ad setup

Future<void> _createBannerAd() async {
    bannerAd = BannerAd(
      size: AdSize.banner,
      adUnitId: "ca-app-pub-3940256099942544/6300978111",
      listener: BannerAdListener(
        onAdLoaded: (_) {
          setState(() {
            isBannerAdLoaded = true;
          });
        },
        onAdFailedToLoad: (ad, _) {
          ad.dispose();
        },
      ),
      request: const AdRequest(),
    );

    await bannerAd.load();
  }

GitHub

View Github