Skip to content

Latest commit

 

History

History
262 lines (228 loc) · 9.11 KB

README.md

File metadata and controls

262 lines (228 loc) · 9.11 KB

Official flutter package for Pensil

pub package Likes Popularity Pub points GitHub last commit Hits

The official Dart client for Pensil communities, a service for building communities applications. This library can be used on any Dart project and on both mobile and web apps with Flutter. You can create your own community from Pensil and use this package to create your customized flutter mobile web application.

🛠 Installation

Install from pub.dev

Next step is to add pensil_community_flutter to your dependencies, to do that just open pubspec.yaml file and add it inside the dependencies section.

dependencies:
  flutter:
    sdk: flutter

  pensil_community_flutter: ^[latest-version]
  

🔌 Usage

Client setup Server-side + Client-side

If you want to use the PensilClient on your web/mobile app you need a community id. usertoken is a google authentication uid which is a optional and can be added later.

Client API init

// Instantiate new client with a communityId and user token
// usertoken is a google authentication token(uid) received during google login.
  final pensilClient = PensilClient(communityId: '<Community id>',usertoken: '<user token>');

Configure rool level widget

Add PensilCommunityApp widget into your rool lavel widget and initialize its bloc with PensilBloc constructor and pass pensilClient in it.

class MyApp extends StatelessWidget {
  const MyApp({required this.pensilClient, Key? key}) : super(key: key);

  final PensilClient pensilClient;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Community Demo',
      builder: (context, child) {
        return PensilCommunityApp(
          bloc: PensilBloc(client: pensilClient),
          child: child!,
        );
      },
      home: const Login(),
    );
  }
}

How to authenticate a user

Currently pensil_community_flutter support google authentication only. To authenticate a user, pass google authentication token (uid) to package and it will return user data on successful authentication other wise it will return error message. Authentication works in such a way that user has no need to signup from any where. If user is a new on platform then authentication will create a new user and returns its profile data received from google.

/// uid is authentication token received from google login
void loginWithGoogle(String uid) async {
  final pensilClient = PensilProvider.of(context).bloc.client;
  final response = await pensilClient.curentUser.loginWithGoogle(uid);
  response.fold((error) {
    /// Display error message when authentication failed
   },
   (user) {
    print(user.name);
    /* 
       // Display success message when login success
       // Navigate to community detail
       Navigator.pushReplacement(context, CommunityDetailPage.getRoute(pensilClient));
    */
  });
}

How to Open community detail page

final pensilClient = PensilProvider.of(context).bloc.client;
Navigator.pushReplacement(context, CommunityDetailPage.getRoute(pensilClient));

Community Detail page

class CommunityDetailPage extends StatelessWidget {
  const CommunityDetailPage({Key? key, this.communityId}) : super(key: key);

  static Route<T> getRoute<T>(PensilClient pensilClient) {
    return MaterialPageRoute(
      builder: (_) {
        return CommunityProvider(
          bloc: CommunityBloc(pensilClient: pensilClient),
          child: CommunityDetailPage(
            communityId: pensilClient.communityId,
          ),
        );
      },
    );
  }

  final String? communityId;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: PensilCommunityBuilder(
        errorBuilder: (_, err) {
          return Center(
            child: Text(err.message),
          );
        },
        builder: (_, Community? community) {
          return PensilGroupListView(
            communityId: communityId!,
            onGroupTileTap: (group) {
              Navigator.push(
                context,
                GroupDetailPage.getRoute(context.communityClient, group!),
              );
            },
          );
        },
      ),
    );
  }
}

How to display sections of a group

/// `group` is a selected group from groups list.
final communityClient = CommunityProvider.of(this).bloc.client;
Navigator.push(context,GroupDetailPage.getRoute(communityClient, group!));                         

Group Detail page

class GroupDetailPage extends StatelessWidget {
  const GroupDetailPage({Key? key, required this.group}) : super(key: key);

  /// Material Route page to open Group detail
  static Route<T> getRoute<T>(CommunityClient communityClient, Group group) {
    return MaterialPageRoute(
      builder: (_) {
        return GroupProvider(
          bloc: GroupBloc(
            communityClient: communityClient,
            groupId: group.id!,
          )..addAllSections(group.sections!),
          child: GroupDetailPage(group: group),
        );
      },
    );
  }

  final Group group;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(group.name!)),
      body: PensilSectionListView(
        groupId: group.id!,
        onSectionTileTap: (section) {
          final bloc = GroupProvider.of(context).bloc;
          Navigator.push(
            context,
            SectionfeedPage.getRoute(bloc.client, section!),
          );
        },
      ),
    );
  }
}

How to display section feed

Navigate to section feed.

  /// `section` is a selected section from sections list
 final groupClient = GroupProvider.of(context).bloc;
 Navigator.push(context,SectionfeedPage.getRoute(groupClient, section!));

Section feed

class SectionfeedPage extends StatelessWidget {
  const SectionfeedPage({Key? key, required this.section}) : super(key: key);

  static Route<T> getRoute<T>(GroupClient groupClient, Section section) {
    return MaterialPageRoute(
      builder: (_) {
        return SectionProvider(
          bloc: SectionBloc(
              groupClient: groupClient,
              sectionId: section.id!,
              type: section.sectionType),
          child: SectionfeedPage(section: section),
        );
      },
    );
  }

  final Section section;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(section.name!)),
      body: PensilSectionFeedBuilder(
        errorBuilder: (_, err) {
          return Center(
            child: Text(err.message),
          );
        },
        builder: (BuildContext context, List<Post>? community) {
          final id = SectionProvider.of(context).bloc.sectionId;
          return PensilPostFeedListView(sectionId: id);
        },
      ),
    );
  }
}

Docs

This package provides two types of components

  1. UI components
  2. Bushiness logic components

UI components

  1. PensilCommunityApp: a root level widget which initialize the pensil client and pensil theme.
  2. PensilCommunityBuilder: a widget designed to get community data to pass it to its children.
  3. PensilGroupListView: a widget to render group list of a community.
  4. PensilSectionListView: a widget to render section list of a group.
  5. PensilSectionFeedBuilder: a widget designed to get section feed and pass it to its children.
  6. PensilPostFeedListView: a widget to render post feed of a section.

Bushiness logic components

  1. PensilBloc: handle root level operations.
  2. PensilProvider: an Inherited widget providing access to PensilBloc in the widget tree.
  3. CommunityBloc: handle community level operations.
  4. CommunityProvider: an Inherited widget providing access to CommunityBloc in the widget tree.
  5. GroupBloc: handle group level operations.
  6. GroupProvider: an Inherited widget providing access to GroupBloc in the widget tree.
  7. SectionBloc: handle section level operations.
  8. SectionProvider: an Inherited widget providing access to SectionBloc in the widget tree.

Dart version requirements

This API Client project requires Dart v2.12 at a minimum.

Example Project

There is a detailed Flutter example project in the example folder. You can directly run and play with it.