aptof_core 0.4.2 copy "aptof_core: ^0.4.2" to clipboard
aptof_core: ^0.4.2 copied to clipboard

A reusable package for core functionality.

To Use utility: #

import 'package/aptof_core/utility.dart'

Click here for details doc

To use 'ui' #

import 'package/aptof_core/ui.dart'

Authentication #

import 'package/aptof_core/auth.dart'

And follow the below steps

Setup firebase to your project #

  • Create a firebase project with Authentication and Firestore
  • Read official documentation and setup firebase to flutter app.
  • Then use product firebase auth and cloud firestore
  • Authentication: Use Email/Password provider only and add an user. Disable signup.
  • Firestore: Add collection updater and add a document of id = 1 with and fields version, androidLink and windowsLink.
  • In cloud firestore rules use the following
rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
  	match /updater/{document} {
      // Only signed-in users can read
      allow read: if request.auth != null;

      // No one can write (create, update, delete)
      allow write: if false;
    }
  
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Use l10n in your project #

  • Create an l10n.yaml file in root of your project with the following content.
arb-dir: lib/l10n/arb
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-dir: lib/l10n/gen
nullable-getter: false

# Needed to ensure the formatter does not run on the generated files.
# See https://github.com/dart-lang/dart_style/issues/864 for more information
header: "// dart format off\n// coverage:ignore-file"
  • Create a lib/l10n/l10n.dart with following content
import 'package:flutter/widgets.dart';
import 'package:<your_app_name>/l10n/gen/app_localizations.dart';

export 'package:<your_app_name>/l10n/gen/app_localizations.dart';

extension AppLocalizationsX on BuildContext {
  AppLocalizations get l10n => AppLocalizations.of(this);
}
  • Create lib/l10n/arb/app_en.arb with following content
{
  "@@locale": "en"
}
  • Add following to pubspec.yaml
...
dependencies:
  flutter_localizations:
    sdk: flutter
...

flutter:
  use-material-design: true
  generate: true
  • Run flutter gen-l10n

Create lib/router.dart with following content #

There are two version of router, Shell and Non-shell. The shell router uses a bottom navigation bar and shell branch of go_router.

ShellRouter should be used like this #

import 'package:aptof_core/auth/router.dart';
import 'package:aptof_core/auth/routes.dart';
import 'package:aptof_core/ui.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:<your_app_name>/home/home.dart';

class AppRouter extends AptofShellRouter {
  AppRouter(super.authRepository);

  @override
  List<StatefulShellBranch> branches() {
    return [
      StatefulShellBranch(
        routes: [
          GoRoute(
            path: AptofRoutes.home,
            builder: (context, state) => const HomeView(),
          ),
        ],
      ),
      StatefulShellBranch(
        routes: [
          GoRoute(
            path: '/home2',
            builder: (context, state) => const PlaceholderView(title: 'Home 2'),
          ),
        ],
      ),
      StatefulShellBranch(
        routes: [
          GoRoute(
            path: '/home3',
            builder: (context, state) => const PlaceholderView(title: 'Home 3'),
          ),
        ],
      ),
    ];
  }

  @override
  List<NavigationDestination> destinations(BuildContext context) {
    return [
      const NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
      const NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
      const NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
    ];
  }
}

NonShellRouter should be used like this #

Non shell router no bottom barred is used. Home view is the root and all other routes or child to the Home. You should add a button to the home view which will navigate to the profile route.

import 'package:aptof_core/auth/router.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:<your_app_name>/home/home.dart';
import 'package:<your_app_name>/routes.dart';

class AppRouter extends AptofRouter {
  AppRouter(super.authRepository);

  @override
  List<GoRoute> get routes => [
    GoRoute(
      path: Routes.chaptersRelative,
      builder: (context, state) =>
          ChaptersView(subjectId: state.pathParameters['subjectId']!),
      routes: [
        GoRoute(
          path: Routes.addChapterRelative,
          builder: (context, state) =>
              ChapterAddView(subjectId: state.pathParameters['subjectId']!),
        ),
      ],
    ),
  ];

  @override
  Widget homeBuilder(BuildContext context, GoRouterState state) {
    return const HomeView();
  }
}

Create a HomeView #

  • Create lib/home/home_view.dart with following content
import 'package:flutter/material.dart';


class HomeView extends StatelessWidget {
  const HomeView({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),

      // Use this body while you are not using shell router
      body: Center(
        child: FilledButton(
          onPressed: () => context.go(AptofRoutes.profile),
          child: const Text('Profile'),
        ),
      ),
    );
  }
}
  • Create lib/home/home.dart with following content
export 'home_view.dart';

Replace content of lib/main.dart with following #

import 'package:aptof_core/auth.dart';
import 'package:aptof_core/l10n/l10n.dart';
import 'package:aptof_core/updater.dart';
import 'package:aptof_core/utility.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:<your_package_name>/firebase_options.dart';
import 'package:<your_package_name>/l10n/gen/app_localizations.dart';
import 'package:<your_package_name>/router.dart';
import 'package:provider/provider.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  runApp(const MainApp());
}

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  List<SingleChildWidget> get providers => [
    Provider.value(value: FirebaseAuth.instance),
    Provider.value(value: FirebaseFirestore.instance),
    Provider(create: (_) => UrlLauncher()),
    Provider(create: (_) => PackageInfoProvider()),
    Provider(
      create: (context) => AuthRepository(firebaseAuth: context.read()),
        dispose: (_, provider) => provider.dispose(),
      ),
    Provider(create: (context) => UpdaterApi(context.read())),
    Provider(
      create: (context) =>
        UpdaterRepository(context.read(), context.read()),
    ),
  ]

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: providers,
      child: _AppView(),
    );
  }
}

class _AppView extends StatelessWidget {
  const _AppView();

  @override
  Widget build(BuildContext context) {
    final theme = AptofTheme(seedColor: Colors.green);
    final router = AppRouter(context.read());

    return MaterialApp.router(
      theme: theme.light,
      darkTheme: theme.dark,
      localizationsDelegates: const [
        ...AppLocalizations.localizationsDelegates,
        ...AptofLocalizations.localizationsDelegates,
      ],
      supportedLocales: {
        ...AppLocalizations.supportedLocales,
        ...AptofLocalizations.supportedLocales,
      }.toList(),
      routerConfig: router.createRouter(),
    );
  }
}

Finally run app #